@aguacerowx/react-native 0.0.21 → 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (404) hide show
  1. package/README.md +126 -126
  2. package/aguacerowx-react-native.podspec +53 -53
  3. package/android/build.gradle +107 -107
  4. package/android/src/main/AndroidManifest.xml +6 -6
  5. package/android/src/main/java/com/aguacerowx/reactnative/AguaceroPackage.java +33 -33
  6. package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +664 -657
  7. package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +304 -304
  8. package/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +125 -125
  9. package/android/src/main/java/com/aguacerowx/reactnative/InspectorModule.java +71 -71
  10. package/android/src/main/java/com/aguacerowx/reactnative/ShaderUtils.java +106 -106
  11. package/android/src/main/java/com/aguacerowx/reactnative/WeatherFrameProcessorModule.java +151 -151
  12. package/android/src/main/res/raw/debug_fragment_shader.glsl +12 -12
  13. package/android/src/main/res/raw/debug_vertex_shader.glsl +12 -12
  14. package/android/src/main/res/raw/fragment_shader.glsl +161 -151
  15. package/android/src/main/res/raw/vertex_shader.glsl +19 -19
  16. package/index.js +2 -2
  17. package/ios/AguaceroPackage.m +18 -18
  18. package/ios/FragmentUniforms.swift +15 -14
  19. package/ios/GridRenderLayer.swift +1003 -995
  20. package/ios/GridRenderLayerBridge.swift +29 -29
  21. package/ios/GridRenderLayerManager.mm +157 -157
  22. package/ios/GridRenderLayerView.h +16 -16
  23. package/ios/GridRenderLayerView.m +204 -204
  24. package/ios/InspectorDataCache.swift +65 -65
  25. package/ios/InspectorModule.m +9 -9
  26. package/ios/InspectorModule.swift +63 -63
  27. package/ios/Shaders.metal +190 -178
  28. package/ios/WeatherFrameProcessorModule.m +15 -15
  29. package/ios/WeatherFrameProcessorModule.swift +103 -103
  30. package/ios/compiled-shaders/Shaders-device.metallib +0 -0
  31. package/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  32. package/lib/commonjs/README.md +126 -126
  33. package/lib/commonjs/aguacerowx-react-native.podspec +53 -53
  34. package/lib/commonjs/android/build.gradle +107 -107
  35. package/lib/commonjs/android/src/main/AndroidManifest.xml +6 -6
  36. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/AguaceroPackage.java +33 -33
  37. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +664 -657
  38. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +304 -304
  39. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +125 -125
  40. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/InspectorModule.java +71 -71
  41. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/ShaderUtils.java +106 -106
  42. package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/WeatherFrameProcessorModule.java +151 -151
  43. package/lib/commonjs/android/src/main/res/raw/debug_fragment_shader.glsl +12 -12
  44. package/lib/commonjs/android/src/main/res/raw/debug_vertex_shader.glsl +12 -12
  45. package/lib/commonjs/android/src/main/res/raw/fragment_shader.glsl +161 -151
  46. package/lib/commonjs/android/src/main/res/raw/vertex_shader.glsl +19 -19
  47. package/lib/commonjs/babel.config.js.map +1 -1
  48. package/lib/commonjs/index.js.map +1 -1
  49. package/lib/commonjs/ios/AguaceroPackage.m +18 -18
  50. package/lib/commonjs/ios/FragmentUniforms.swift +15 -14
  51. package/lib/commonjs/ios/GridRenderLayer.swift +1003 -995
  52. package/lib/commonjs/ios/GridRenderLayerBridge.swift +29 -29
  53. package/lib/commonjs/ios/GridRenderLayerManager.mm +157 -157
  54. package/lib/commonjs/ios/GridRenderLayerView.h +16 -16
  55. package/lib/commonjs/ios/GridRenderLayerView.m +204 -204
  56. package/lib/commonjs/ios/InspectorDataCache.swift +65 -65
  57. package/lib/commonjs/ios/InspectorModule.m +9 -9
  58. package/lib/commonjs/ios/InspectorModule.swift +63 -63
  59. package/lib/commonjs/ios/Shaders.metal +190 -178
  60. package/lib/commonjs/ios/WeatherFrameProcessorModule.m +15 -15
  61. package/lib/commonjs/ios/WeatherFrameProcessorModule.swift +103 -103
  62. package/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
  63. package/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  64. package/lib/commonjs/package.json +72 -72
  65. package/lib/commonjs/react-native-builder-bob.config.js.map +1 -1
  66. package/lib/commonjs/scripts/compile-shaders.js.map +1 -1
  67. package/lib/commonjs/scripts/compile-shaders.sh +38 -38
  68. package/lib/commonjs/src/AguaceroContext.js.map +1 -1
  69. package/lib/commonjs/src/GridRenderLayer.js.map +1 -1
  70. package/lib/commonjs/src/GridRenderLayerNativeComponent.js.map +1 -1
  71. package/lib/commonjs/src/MapManager.js.map +1 -1
  72. package/lib/commonjs/src/MapRegistry.js.map +1 -1
  73. package/lib/commonjs/src/StyleApplicator.js +6 -6
  74. package/lib/commonjs/src/StyleApplicator.js.map +1 -1
  75. package/lib/commonjs/src/WeatherLayerManager.js +34 -5
  76. package/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
  77. package/lib/commonjs/tsconfig.json +23 -23
  78. package/lib/module/README.md +126 -126
  79. package/lib/module/aguacerowx-react-native.podspec +53 -53
  80. package/lib/module/android/build.gradle +107 -107
  81. package/lib/module/android/src/main/AndroidManifest.xml +6 -6
  82. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/AguaceroPackage.java +33 -33
  83. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +664 -657
  84. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +304 -304
  85. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +125 -125
  86. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/InspectorModule.java +71 -71
  87. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/ShaderUtils.java +106 -106
  88. package/lib/module/android/src/main/java/com/aguacerowx/reactnative/WeatherFrameProcessorModule.java +151 -151
  89. package/lib/module/android/src/main/res/raw/debug_fragment_shader.glsl +12 -12
  90. package/lib/module/android/src/main/res/raw/debug_vertex_shader.glsl +12 -12
  91. package/lib/module/android/src/main/res/raw/fragment_shader.glsl +161 -151
  92. package/lib/module/android/src/main/res/raw/vertex_shader.glsl +19 -19
  93. package/lib/module/babel.config.js.map +1 -1
  94. package/lib/module/index.js.map +1 -1
  95. package/lib/module/ios/AguaceroPackage.m +18 -18
  96. package/lib/module/ios/FragmentUniforms.swift +15 -14
  97. package/lib/module/ios/GridRenderLayer.swift +1003 -995
  98. package/lib/module/ios/GridRenderLayerBridge.swift +29 -29
  99. package/lib/module/ios/GridRenderLayerManager.mm +157 -157
  100. package/lib/module/ios/GridRenderLayerView.h +16 -16
  101. package/lib/module/ios/GridRenderLayerView.m +204 -204
  102. package/lib/module/ios/InspectorDataCache.swift +65 -65
  103. package/lib/module/ios/InspectorModule.m +9 -9
  104. package/lib/module/ios/InspectorModule.swift +63 -63
  105. package/lib/module/ios/Shaders.metal +190 -178
  106. package/lib/module/ios/WeatherFrameProcessorModule.m +15 -15
  107. package/lib/module/ios/WeatherFrameProcessorModule.swift +103 -103
  108. package/lib/module/ios/compiled-shaders/Shaders-device.metallib +0 -0
  109. package/lib/module/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  110. package/lib/module/lib/commonjs/README.md +126 -126
  111. package/lib/module/lib/commonjs/aguacerowx-react-native.podspec +53 -53
  112. package/lib/module/lib/commonjs/babel.config.js.map +1 -1
  113. package/lib/module/lib/commonjs/index.js.map +1 -1
  114. package/lib/module/lib/commonjs/ios/AguaceroPackage.m +18 -18
  115. package/lib/module/lib/commonjs/package.json +72 -72
  116. package/lib/module/lib/commonjs/react-native-builder-bob.config.js.map +1 -1
  117. package/lib/module/lib/commonjs/scripts/compile-shaders.js.map +1 -1
  118. package/lib/module/lib/commonjs/src/AguaceroContext.js.map +1 -1
  119. package/lib/module/lib/commonjs/src/GridRenderLayer.js.map +1 -1
  120. package/lib/module/lib/commonjs/src/GridRenderLayerNativeComponent.js.map +1 -1
  121. package/lib/module/lib/commonjs/src/MapManager.js.map +1 -1
  122. package/lib/module/lib/commonjs/src/MapRegistry.js.map +1 -1
  123. package/lib/module/lib/commonjs/src/StyleApplicator.js +6 -6
  124. package/lib/module/lib/commonjs/src/StyleApplicator.js.map +1 -1
  125. package/lib/module/lib/commonjs/src/WeatherLayerManager.js +34 -5
  126. package/lib/module/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
  127. package/lib/module/lib/commonjs/tsconfig.json +23 -23
  128. package/lib/module/package.json +72 -72
  129. package/lib/module/react-native-builder-bob.config.js.map +1 -1
  130. package/lib/module/scripts/compile-shaders.js.map +1 -1
  131. package/lib/module/scripts/compile-shaders.sh +38 -38
  132. package/lib/module/src/AguaceroContext.js.map +1 -1
  133. package/lib/module/src/GridRenderLayer.js.map +1 -1
  134. package/lib/module/src/GridRenderLayerNativeComponent.js.map +1 -1
  135. package/lib/module/src/MapManager.js.map +1 -1
  136. package/lib/module/src/MapRegistry.js.map +1 -1
  137. package/lib/module/src/StyleApplicator.js +6 -6
  138. package/lib/module/src/StyleApplicator.js.map +1 -1
  139. package/lib/module/src/WeatherLayerManager.js +34 -5
  140. package/lib/module/src/WeatherLayerManager.js.map +1 -1
  141. package/lib/module/tsconfig.json +23 -23
  142. package/lib/typescript/src/WeatherLayerManager.d.ts.map +1 -1
  143. package/package.json +72 -72
  144. package/src/AguaceroContext.js +3 -3
  145. package/src/GridRenderLayer.js +217 -217
  146. package/src/GridRenderLayerNativeComponent.ts +15 -15
  147. package/src/MapManager.js +155 -155
  148. package/src/MapRegistry.js +34 -34
  149. package/src/StyleApplicator.js +240 -240
  150. package/src/WeatherLayerManager.js +920 -891
  151. package/android/build/.transforms/42e9b8fa82d77a1c205db5bf0d0ed519/results.bin +0 -1
  152. package/android/build/.transforms/42e9b8fa82d77a1c205db5bf0d0ed519/transformed/classes/classes_dex/classes.dex +0 -0
  153. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/results.bin +0 -1
  154. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/AguaceroPackage.dex +0 -0
  155. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/BuildConfig.dex +0 -0
  156. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.dex +0 -0
  157. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderLayer.dex +0 -0
  158. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderLayerView.dex +0 -0
  159. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/GridRenderManager.dex +0 -0
  160. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/InspectorModule.dex +0 -0
  161. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/ShaderUtils.dex +0 -0
  162. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/aguacerowx/reactnative/WeatherFrameProcessorModule.dex +0 -0
  163. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.dex +0 -0
  164. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.dex +0 -0
  165. package/android/build/.transforms/c8ab78b63f2cc835ac936d58e29a17ab/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  166. package/android/build/generated/source/buildConfig/debug/com/aguacerowx/reactnative/BuildConfig.java +0 -10
  167. package/android/build/generated/source/codegen/java/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.java +0 -43
  168. package/android/build/generated/source/codegen/java/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.java +0 -22
  169. package/android/build/generated/source/codegen/jni/AguaceroWxReactNativeSpec-generated.cpp +0 -22
  170. package/android/build/generated/source/codegen/jni/AguaceroWxReactNativeSpec.h +0 -24
  171. package/android/build/generated/source/codegen/jni/CMakeLists.txt +0 -28
  172. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/AguaceroWxReactNativeSpecJSI-generated.cpp +0 -17
  173. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/AguaceroWxReactNativeSpecJSI.h +0 -19
  174. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ComponentDescriptors.cpp +0 -22
  175. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ComponentDescriptors.h +0 -24
  176. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/EventEmitters.cpp +0 -16
  177. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/EventEmitters.h +0 -23
  178. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/Props.cpp +0 -62
  179. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/Props.h +0 -40
  180. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ShadowNodes.cpp +0 -17
  181. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ShadowNodes.h +0 -32
  182. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/States.cpp +0 -16
  183. package/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/States.h +0 -20
  184. package/android/build/generated/source/codegen/schema.json +0 -1
  185. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -8
  186. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
  187. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
  188. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
  189. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  190. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  191. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -4
  192. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_debug_fragment_shader.glsl.flat +0 -0
  193. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_debug_vertex_shader.glsl.flat +0 -0
  194. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  195. package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_vertex_shader.glsl.flat +0 -0
  196. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -5
  197. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
  198. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
  199. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
  200. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
  201. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/AguaceroPackage.class +0 -0
  202. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/BuildConfig.class +0 -0
  203. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  204. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  205. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayerView.class +0 -0
  206. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderManager.class +0 -0
  207. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/InspectorModule.class +0 -0
  208. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/ShaderUtils.class +0 -0
  209. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/WeatherFrameProcessorModule.class +0 -0
  210. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.class +0 -0
  211. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.class +0 -0
  212. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -6
  213. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -8
  214. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -8
  215. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
  216. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
  217. package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/debug_fragment_shader.glsl +0 -13
  218. package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/debug_vertex_shader.glsl +0 -13
  219. package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +0 -152
  220. package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/vertex_shader.glsl +0 -20
  221. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/AguaceroPackage.class +0 -0
  222. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/BuildConfig.class +0 -0
  223. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  224. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  225. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayerView.class +0 -0
  226. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderManager.class +0 -0
  227. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/InspectorModule.class +0 -0
  228. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/ShaderUtils.class +0 -0
  229. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/WeatherFrameProcessorModule.class +0 -0
  230. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.class +0 -0
  231. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.class +0 -0
  232. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  233. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -5
  234. package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -17
  235. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
  236. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
  237. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId2 +0 -0
  238. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  239. package/lib/commonjs/android/build/generated/source/buildConfig/debug/com/aguacerowx/reactnative/BuildConfig.java +0 -10
  240. package/lib/commonjs/android/build/generated/source/codegen/java/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.java +0 -43
  241. package/lib/commonjs/android/build/generated/source/codegen/java/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.java +0 -22
  242. package/lib/commonjs/android/build/generated/source/codegen/jni/AguaceroWxReactNativeSpec-generated.cpp +0 -22
  243. package/lib/commonjs/android/build/generated/source/codegen/jni/AguaceroWxReactNativeSpec.h +0 -24
  244. package/lib/commonjs/android/build/generated/source/codegen/jni/CMakeLists.txt +0 -28
  245. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/AguaceroWxReactNativeSpecJSI-generated.cpp +0 -17
  246. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/AguaceroWxReactNativeSpecJSI.h +0 -19
  247. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ComponentDescriptors.cpp +0 -22
  248. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ComponentDescriptors.h +0 -24
  249. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/EventEmitters.cpp +0 -16
  250. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/EventEmitters.h +0 -23
  251. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/Props.cpp +0 -62
  252. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/Props.h +0 -40
  253. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ShadowNodes.cpp +0 -17
  254. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ShadowNodes.h +0 -32
  255. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/States.cpp +0 -16
  256. package/lib/commonjs/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/States.h +0 -20
  257. package/lib/commonjs/android/build/generated/source/codegen/schema.json +0 -1
  258. package/lib/commonjs/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -8
  259. package/lib/commonjs/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
  260. package/lib/commonjs/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
  261. package/lib/commonjs/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
  262. package/lib/commonjs/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  263. package/lib/commonjs/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  264. package/lib/commonjs/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -4
  265. package/lib/commonjs/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_debug_fragment_shader.glsl.flat +0 -0
  266. package/lib/commonjs/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_debug_vertex_shader.glsl.flat +0 -0
  267. package/lib/commonjs/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  268. package/lib/commonjs/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_vertex_shader.glsl.flat +0 -0
  269. package/lib/commonjs/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -5
  270. package/lib/commonjs/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
  271. package/lib/commonjs/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
  272. package/lib/commonjs/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
  273. package/lib/commonjs/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
  274. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/AguaceroPackage.class +0 -0
  275. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/BuildConfig.class +0 -0
  276. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  277. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  278. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayerView.class +0 -0
  279. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderManager.class +0 -0
  280. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/InspectorModule.class +0 -0
  281. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/ShaderUtils.class +0 -0
  282. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/WeatherFrameProcessorModule.class +0 -0
  283. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.class +0 -0
  284. package/lib/commonjs/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.class +0 -0
  285. package/lib/commonjs/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -6
  286. package/lib/commonjs/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -8
  287. package/lib/commonjs/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -8
  288. package/lib/commonjs/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
  289. package/lib/commonjs/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
  290. package/lib/commonjs/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/debug_fragment_shader.glsl +0 -13
  291. package/lib/commonjs/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/debug_vertex_shader.glsl +0 -13
  292. package/lib/commonjs/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +0 -152
  293. package/lib/commonjs/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/vertex_shader.glsl +0 -20
  294. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/AguaceroPackage.class +0 -0
  295. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/BuildConfig.class +0 -0
  296. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  297. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  298. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayerView.class +0 -0
  299. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderManager.class +0 -0
  300. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/InspectorModule.class +0 -0
  301. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/ShaderUtils.class +0 -0
  302. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/WeatherFrameProcessorModule.class +0 -0
  303. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.class +0 -0
  304. package/lib/commonjs/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.class +0 -0
  305. package/lib/commonjs/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  306. package/lib/commonjs/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -5
  307. package/lib/commonjs/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -17
  308. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
  309. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
  310. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId2 +0 -0
  311. package/lib/commonjs/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  312. package/lib/module/android/build/generated/source/buildConfig/debug/com/aguacerowx/reactnative/BuildConfig.java +0 -10
  313. package/lib/module/android/build/generated/source/codegen/java/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.java +0 -43
  314. package/lib/module/android/build/generated/source/codegen/java/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.java +0 -22
  315. package/lib/module/android/build/generated/source/codegen/jni/AguaceroWxReactNativeSpec-generated.cpp +0 -22
  316. package/lib/module/android/build/generated/source/codegen/jni/AguaceroWxReactNativeSpec.h +0 -24
  317. package/lib/module/android/build/generated/source/codegen/jni/CMakeLists.txt +0 -28
  318. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/AguaceroWxReactNativeSpecJSI-generated.cpp +0 -17
  319. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/AguaceroWxReactNativeSpecJSI.h +0 -19
  320. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ComponentDescriptors.cpp +0 -22
  321. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ComponentDescriptors.h +0 -24
  322. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/EventEmitters.cpp +0 -16
  323. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/EventEmitters.h +0 -23
  324. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/Props.cpp +0 -62
  325. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/Props.h +0 -40
  326. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ShadowNodes.cpp +0 -17
  327. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/ShadowNodes.h +0 -32
  328. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/States.cpp +0 -16
  329. package/lib/module/android/build/generated/source/codegen/jni/react/renderer/components/AguaceroWxReactNativeSpec/States.h +0 -20
  330. package/lib/module/android/build/generated/source/codegen/schema.json +0 -1
  331. package/lib/module/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -8
  332. package/lib/module/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
  333. package/lib/module/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
  334. package/lib/module/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
  335. package/lib/module/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  336. package/lib/module/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  337. package/lib/module/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -4
  338. package/lib/module/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_debug_fragment_shader.glsl.flat +0 -0
  339. package/lib/module/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_debug_vertex_shader.glsl.flat +0 -0
  340. package/lib/module/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_fragment_shader.glsl.flat +0 -0
  341. package/lib/module/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_vertex_shader.glsl.flat +0 -0
  342. package/lib/module/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -5
  343. package/lib/module/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
  344. package/lib/module/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
  345. package/lib/module/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
  346. package/lib/module/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
  347. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/AguaceroPackage.class +0 -0
  348. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/BuildConfig.class +0 -0
  349. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  350. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  351. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderLayerView.class +0 -0
  352. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/GridRenderManager.class +0 -0
  353. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/InspectorModule.class +0 -0
  354. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/ShaderUtils.class +0 -0
  355. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/aguacerowx/reactnative/WeatherFrameProcessorModule.class +0 -0
  356. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.class +0 -0
  357. package/lib/module/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.class +0 -0
  358. package/lib/module/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -6
  359. package/lib/module/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -8
  360. package/lib/module/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -8
  361. package/lib/module/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
  362. package/lib/module/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
  363. package/lib/module/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/debug_fragment_shader.glsl +0 -13
  364. package/lib/module/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/debug_vertex_shader.glsl +0 -13
  365. package/lib/module/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/fragment_shader.glsl +0 -152
  366. package/lib/module/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/vertex_shader.glsl +0 -20
  367. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/AguaceroPackage.class +0 -0
  368. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/BuildConfig.class +0 -0
  369. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer$VertexInfo.class +0 -0
  370. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayer.class +0 -0
  371. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderLayerView.class +0 -0
  372. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/GridRenderManager.class +0 -0
  373. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/InspectorModule.class +0 -0
  374. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/ShaderUtils.class +0 -0
  375. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/aguacerowx/reactnative/WeatherFrameProcessorModule.class +0 -0
  376. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/facebook/react/viewmanagers/GridRenderLayerManagerDelegate.class +0 -0
  377. package/lib/module/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/facebook/react/viewmanagers/GridRenderLayerManagerInterface.class +0 -0
  378. package/lib/module/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  379. package/lib/module/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -5
  380. package/lib/module/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -17
  381. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer$VertexInfo.class.uniqueId0 +0 -0
  382. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayer.class.uniqueId1 +0 -0
  383. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/GridRenderLayerView.class.uniqueId2 +0 -0
  384. package/lib/module/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  385. package/lib/module/lib/commonjs/android/build.gradle +0 -108
  386. package/lib/module/lib/commonjs/android/src/main/AndroidManifest.xml +0 -7
  387. package/lib/module/lib/commonjs/ios/FragmentUniforms.swift +0 -15
  388. package/lib/module/lib/commonjs/ios/GridRenderLayer.swift +0 -995
  389. package/lib/module/lib/commonjs/ios/GridRenderLayerBridge.swift +0 -30
  390. package/lib/module/lib/commonjs/ios/GridRenderLayerManager.mm +0 -158
  391. package/lib/module/lib/commonjs/ios/GridRenderLayerView.h +0 -17
  392. package/lib/module/lib/commonjs/ios/GridRenderLayerView.m +0 -205
  393. package/lib/module/lib/commonjs/ios/InspectorDataCache.swift +0 -66
  394. package/lib/module/lib/commonjs/ios/InspectorModule.m +0 -10
  395. package/lib/module/lib/commonjs/ios/InspectorModule.swift +0 -64
  396. package/lib/module/lib/commonjs/ios/Shaders.metal +0 -179
  397. package/lib/module/lib/commonjs/ios/WeatherFrameProcessorModule.m +0 -16
  398. package/lib/module/lib/commonjs/ios/WeatherFrameProcessorModule.swift +0 -104
  399. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
  400. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
  401. package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
  402. package/lib/module/lib/commonjs/ios/generated/AguaceroWxReactNativeSpec-generated.mm +0 -0
  403. package/lib/module/lib/commonjs/ios/generated/AguaceroWxReactNativeSpec.h +0 -0
  404. package/lib/module/lib/commonjs/scripts/compile-shaders.sh +0 -39
@@ -1,995 +1,1003 @@
1
- import Foundation
2
- import MapboxMaps
3
- import Metal
4
- import libzstd
5
- import simd
6
-
7
- // MARK: - Swift-only wrapper for CustomLayerHost conformance
8
- @objc internal final class GridRenderLayerHost: NSObject, CustomLayerHost {
9
- weak var layer: GridRenderLayer?
10
-
11
- init(layer: GridRenderLayer) {
12
- self.layer = layer
13
- super.init()
14
- }
15
-
16
- func renderingWillStart(_ metalDevice: MTLDevice, colorPixelFormat: UInt, depthStencilPixelFormat: UInt) {
17
- layer?.internalRenderingWillStart(metalDevice, colorPixelFormat: colorPixelFormat, depthStencilPixelFormat: depthStencilPixelFormat)
18
- }
19
-
20
- func render(_ parameters: CustomLayerRenderParameters, mtlCommandBuffer: MTLCommandBuffer, mtlRenderPassDescriptor: MTLRenderPassDescriptor) {
21
- layer?.internalRender(parameters, mtlCommandBuffer: mtlCommandBuffer, mtlRenderPassDescriptor: mtlRenderPassDescriptor)
22
- }
23
-
24
- func renderingWillEnd() {
25
- layer?.internalRenderingWillEnd()
26
- }
27
- }
28
-
29
- @objc(GridRenderLayer)
30
- public class GridRenderLayer: NSObject {
31
-
32
- // MARK: - Properties
33
-
34
- public var id: String
35
- @objc internal var hostWrapper: GridRenderLayerHost!
36
-
37
- // Metal objects
38
- private var device: MTLDevice!
39
- private var commandQueue: MTLCommandQueue!
40
- private var pipelineState: MTLRenderPipelineState!
41
- private var vertexBuffer: MTLBuffer?
42
- private var indexBuffer: MTLBuffer?
43
- private var dataTexture: MTLTexture?
44
- private var colormapTexture: MTLTexture?
45
- private var dataSamplerState: MTLSamplerState!
46
- private var colormapSamplerState: MTLSamplerState!
47
- private var isDataSamplerLinear: Bool = false
48
-
49
- private var pendingColormapUpdate: String?
50
- private var pendingDataUpdate: (data: String, nx: NSNumber, ny: NSNumber, scale: NSNumber, offset: NSNumber, missing: NSNumber, scaleType: String)?
51
- private var pendingGeometryUpdate: (corners: [String: Any], gridDef: [String: Any])?
52
-
53
- // Layer state
54
- private var indexCount: Int = 0
55
- private var uniforms = FragmentUniforms(
56
- opacity: 1.0,
57
- dataRange: SIMD2<Float>(0.0, 1.0),
58
- scale: 1.0,
59
- offset: 0.0,
60
- missingQuantized: 127.0,
61
- textureSize: SIMD2<Float>(0.0, 0.0),
62
- smoothing: 1,
63
- scaleType: 0,
64
- isPtype: 0 // ADD THIS
65
- )
66
- private var isVisible = false
67
- private var pendingActiveFrameKey: String?
68
- private let inspectorCache = InspectorDataCache.shared
69
- private struct FrameMetadata {
70
- let texture: MTLTexture
71
- let scale: Float
72
- let offset: Float
73
- let missing: Float
74
- let scaleType: Int
75
- let nx: Float
76
- let ny: Float
77
- let filePath: String
78
- let originalScale: Float // ADD THIS
79
- let originalOffset: Float // ADD THIS
80
- }
81
- private var frameCache: [String: FrameMetadata] = [:]
82
- private let highPriorityTextureQueue = DispatchQueue(label: "com.aguacero.texture-processing-high-priority", qos: .userInitiated)
83
-
84
- // The concurrent queue for background preloading all other frames.
85
- private let backgroundTextureQueue = DispatchQueue(label: "com.aguacero.texture-processing-background", qos: .utility, attributes: .concurrent)
86
- // MARK: - Initializer
87
- private struct VertexInfo {
88
- var mercX: Float
89
- var mercY: Float
90
- var texU: Float
91
- var texV: Float
92
- var index: UInt16
93
- }
94
- @objc
95
- public init(id: String) {
96
- self.id = id
97
- super.init()
98
- self.hostWrapper = GridRenderLayerHost(layer: self)
99
- print("🟢 [GridRenderLayer] Initialized with ID: \(id)")
100
- }
101
-
102
- @objc public func getHostWrapper() -> Any {
103
- return self.hostWrapper as Any
104
- }
105
-
106
- // MARK: - Public Methods (called from Manager)
107
-
108
- @objc public func setOpacity(value: Float) {
109
- self.uniforms.opacity = value
110
- print("🟢 [GridRenderLayer] Set opacity: \(value)")
111
- // ADD THIS: Force the map to repaint to show the opacity change immediately.
112
- NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
113
- }
114
-
115
- @objc public func setDataRange(value: [NSNumber]) {
116
- self.uniforms.dataRange = SIMD2<Float>(value[0].floatValue, value[1].floatValue)
117
- print("🟢 [GridRenderLayer] Set data range: \(value)")
118
- // ADD THIS: Force the map to repaint to show the data range change immediately.
119
- NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
120
- }
121
-
122
- @objc public func setSmoothing(value: Bool) {
123
- self.uniforms.smoothing = value ? 1 : 0
124
- print("🟢 [GridRenderLayer] Set smoothing: \(value)")
125
- // ADD THIS: Force the map to repaint to show the smoothing change immediately.
126
- NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
127
- }
128
-
129
- // ADD THIS METHOD
130
- @objc(setVariableWithVariable:)
131
- public func setVariable(variable: String) {
132
- let isPtypeVar = (variable == "ptypeRefl" || variable == "ptypeRate")
133
- self.uniforms.isPtype = isPtypeVar ? 1 : 0
134
- print("🟢 [GridRenderLayer] Set variable: \(variable), isPtype set to: \(self.uniforms.isPtype)")
135
- NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
136
- }
137
-
138
- @objc public func clear() {
139
- self.isVisible = false
140
- self.inspectorCache.clear()
141
- print("🟢 [GridRenderLayer] Cleared")
142
- }
143
-
144
- @objc public func updateDataParameters(scale: NSNumber, offset: NSNumber, missing: NSNumber, scaleType: NSNumber) { // ADD scaleType parameter
145
- // Update both the inspector cache AND the rendering uniforms
146
- self.uniforms.scale = scale.floatValue
147
- self.uniforms.offset = offset.floatValue
148
- self.uniforms.missingQuantized = missing.floatValue
149
- self.uniforms.scaleType = Int32(scaleType.intValue) // ADD THIS
150
-
151
- inspectorCache.update(
152
- data: inspectorCache.lastDecompressedData,
153
- nx: inspectorCache.nx,
154
- ny: inspectorCache.ny,
155
- scale: scale.floatValue,
156
- offset: offset.floatValue,
157
- missing: missing.floatValue,
158
- scaleType: scaleType.intValue // ADD THIS
159
- )
160
-
161
- print("🟢 [GridRenderLayer] Updated data parameters - scale: \(scale), offset: \(offset), missing: \(missing), scaleType: \(scaleType)")
162
- }
163
-
164
- @objc public func updateColormapTexture(colormapAsBase64: String) {
165
- guard let device = self.device else {
166
- pendingColormapUpdate = colormapAsBase64
167
- return
168
- }
169
- guard let data = Data(base64Encoded: colormapAsBase64) else { return }
170
- let textureDescriptor = MTLTextureDescriptor()
171
- textureDescriptor.pixelFormat = .rgba8Unorm
172
- textureDescriptor.width = 256
173
- textureDescriptor.height = 1
174
- textureDescriptor.usage = .shaderRead
175
- guard let texture = device.makeTexture(descriptor: textureDescriptor) else { return }
176
- texture.replace(
177
- region: MTLRegionMake2D(0, 0, 256, 1),
178
- mipmapLevel: 0,
179
- withBytes: (data as NSData).bytes,
180
- bytesPerRow: 256 * 4
181
- )
182
- self.colormapTexture = texture
183
- }
184
-
185
- @objc(clearGpuCache) // Explicitly name the Obj-C selector
186
- public func clearGpuCache() {
187
- backgroundTextureQueue.async {
188
- self.frameCache.removeAll()
189
- print("🟢 [GridRenderLayer] GPU frame cache cleared.")
190
- }
191
- }
192
-
193
- private func processRawData(fileData: Data) -> Data? {
194
- guard let decompressedDeltas = self.decompressZstd(data: fileData) else {
195
- print("❌ [GridRenderLayer] Failed to decompress zstd data")
196
- return nil
197
- }
198
- let reconstructedData = self.reconstructData(decompressedDeltas: decompressedDeltas)
199
- let finalTextureBytes = self.transformData(finalData: reconstructedData)
200
- return finalTextureBytes
201
- }
202
-
203
- private func createTextureFromBytes(bytes: Data, nx: Int, ny: Int) -> MTLTexture? {
204
- guard let device = self.device else { return nil }
205
- let textureDescriptor = MTLTextureDescriptor()
206
- textureDescriptor.pixelFormat = .r8Unorm
207
- textureDescriptor.width = nx
208
- textureDescriptor.height = ny
209
- textureDescriptor.usage = .shaderRead
210
-
211
- guard let texture = device.makeTexture(descriptor: textureDescriptor) else { return nil }
212
- texture.replace(
213
- region: MTLRegionMake2D(0, 0, nx, ny),
214
- mipmapLevel: 0,
215
- withBytes: (bytes as NSData).bytes,
216
- bytesPerRow: nx
217
- )
218
- return texture
219
- }
220
-
221
- private func updateInspectorCache(filePath: String, nx: Int, ny: Int, scale: Float, offset: Float, missing: Float, scaleType: Int) {
222
- highPriorityTextureQueue.async {
223
-
224
- guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
225
- print("❌ [Inspector] FATAL: Failed to read file data from path.")
226
- self.inspectorCache.clear()
227
- return
228
- }
229
- print("💡 [Inspector] 2. Successfully read \(fileData.count) bytes from file.")
230
-
231
- guard let decompressedDeltas = self.decompressZstd(data: fileData) else {
232
- print("❌ [Inspector] FATAL: Failed to decompress Zstd data.")
233
- self.inspectorCache.clear()
234
- return
235
- }
236
- print("💡 [Inspector] 3. Successfully decompressed data.")
237
-
238
- let reconstructedData = self.reconstructData(decompressedDeltas: decompressedDeltas)
239
- print("💡 [Inspector] 4. Reconstructed data with \(reconstructedData.count) bytes.")
240
-
241
- self.inspectorCache.update(
242
- data: reconstructedData,
243
- nx: nx,
244
- ny: ny,
245
- scale: scale,
246
- offset: offset,
247
- missing: missing,
248
- scaleType: scaleType
249
- )
250
-
251
- print("💡 [Inspector] 5. ✅ Cache updated successfully with scaleType=\(scaleType)")
252
- }
253
- }
254
-
255
- @objc(setActiveFrameWithCacheKey:)
256
- public func setActiveFrame(cacheKey: String) {
257
- // First, check if the frame is already in the cache.
258
- if let frame = frameCache[cacheKey] {
259
- print("⚡️ [GridRenderLayer] Cache HIT for key: \(cacheKey). Swapping texture.")
260
-
261
- self.dataTexture = frame.texture
262
- self.uniforms.scale = frame.scale
263
- self.uniforms.offset = frame.offset
264
- self.uniforms.missingQuantized = frame.missing
265
- self.uniforms.textureSize = SIMD2<Float>(frame.nx, frame.ny)
266
- self.uniforms.scaleType = Int32(frame.scaleType)
267
-
268
- self.isVisible = true
269
- self.pendingActiveFrameKey = nil // Clear any pending key
270
- NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
271
-
272
- // --- ADD THIS ---
273
- // Now that the frame is active, update the inspector cache with its data.
274
- self.updateInspectorCache(
275
- filePath: frame.filePath,
276
- nx: Int(frame.nx),
277
- ny: Int(frame.ny),
278
- scale: frame.scale,
279
- offset: frame.offset,
280
- missing: frame.missing,
281
- scaleType: frame.scaleType
282
- )
283
-
284
- } else {
285
- // --- FIX: If it's a miss, store the key and wait for it to be primed. ---
286
- print("⚠️ [GridRenderLayer] setActiveFrame cache MISS for key: \(cacheKey). Will apply when primed.")
287
- self.pendingActiveFrameKey = cacheKey
288
- self.isVisible = false // Hide the layer until the frame is ready
289
- }
290
- }
291
-
292
- @objc(primeGpuCacheWithFrameInfo:)
293
- public func primeGpuCache(frameInfo: [String: [String: Any]]) {
294
- let group = DispatchGroup()
295
-
296
- if (frameInfo.count > 1) {
297
- print("🟡 [GridRenderLayer] Starting to prime \(frameInfo.count) textures concurrently...")
298
- }
299
-
300
- for (cacheKey, info) in frameInfo {
301
- group.enter()
302
-
303
- backgroundTextureQueue.async {
304
- defer { group.leave() }
305
- if self.frameCache[cacheKey] != nil { return }
306
-
307
- guard let filePath = info["filePath"] as? String,
308
- let nx = info["nx"] as? NSNumber,
309
- let ny = info["ny"] as? NSNumber,
310
- let scale = info["scale"] as? NSNumber,
311
- let offset = info["offset"] as? NSNumber,
312
- let missing = info["missing"] as? NSNumber,
313
- let scaleTypeStr = info["scaleType"] as? String,
314
- let originalScale = info["originalScale"] as? NSNumber, // ADD THIS
315
- let originalOffset = info["originalOffset"] as? NSNumber, // ADD THIS
316
- let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)),
317
- let finalTextureBytes = self.processRawData(fileData: fileData)
318
- else {
319
- print("❌ [GridRenderLayer] Skipping prime for \(cacheKey), missing data.")
320
- return
321
- }
322
-
323
- DispatchQueue.main.sync {
324
- if let texture = self.createTextureFromBytes(bytes: finalTextureBytes, nx: nx.intValue, ny: ny.intValue) {
325
- let metadata = FrameMetadata(
326
- texture: texture,
327
- scale: scale.floatValue,
328
- offset: offset.floatValue,
329
- missing: missing.floatValue,
330
- scaleType: (scaleTypeStr == "sqrt") ? 1 : 0,
331
- nx: nx.floatValue,
332
- ny: ny.floatValue,
333
- filePath: filePath,
334
- originalScale: originalScale.floatValue, // ADD THIS
335
- originalOffset: originalOffset.floatValue // ADD THIS
336
- )
337
- self.frameCache[cacheKey] = metadata
338
- print(" ✅ [GridRenderLayer] Primed and cached frame for key: \(cacheKey)")
339
-
340
- if let pendingKey = self.pendingActiveFrameKey, pendingKey == cacheKey {
341
- print("👍 [GridRenderLayer] The pending frame is now ready. Activating it.")
342
- self.setActiveFrame(cacheKey: pendingKey)
343
- }
344
- }
345
- }
346
- }
347
- }
348
-
349
- group.notify(queue: .main) {
350
- if (frameInfo.count > 1) {
351
- print("🎉 [GridRenderLayer] All \(frameInfo.count) frames have been processed and cached to the GPU.")
352
- }
353
- }
354
- }
355
-
356
- @objc public func updateDataTexture(data: String, nx: NSNumber, ny: NSNumber, scale: NSNumber, offset: NSNumber, missing: NSNumber, scaleType: String) {
357
- print("🚀 [GridRenderLayer] FAST LANE: updateDataTexture called for initial frame...")
358
-
359
- let filePath = data // Assuming 'data' is always the file path for this method.
360
-
361
- // USE THE HIGH-PRIORITY QUEUE
362
- highPriorityTextureQueue.async {
363
- guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else { return }
364
-
365
- guard let finalTextureBytes = self.processRawData(fileData: fileData) else {
366
- print("❌ [GridRenderLayer] FAST LANE: Failed to process initial frame data.")
367
- return
368
- }
369
-
370
- DispatchQueue.main.async {
371
- guard let texture = self.createTextureFromBytes(bytes: finalTextureBytes, nx: nx.intValue, ny: ny.intValue) else {
372
- return
373
- }
374
-
375
- self.dataTexture = texture
376
- self.uniforms.scale = scale.floatValue
377
- self.uniforms.offset = offset.floatValue
378
- self.uniforms.missingQuantized = missing.floatValue
379
- self.uniforms.scaleType = Int32((scaleType == "sqrt") ? 1 : 0)
380
- self.uniforms.textureSize = SIMD2<Float>(nx.floatValue, ny.floatValue)
381
-
382
- self.isVisible = true
383
- print("✅ [GridRenderLayer] FAST LANE: Initial frame processed and displayed.")
384
- NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
385
-
386
- // --- ADD THIS ---
387
- // Update the inspector cache for the initial frame.
388
- self.updateInspectorCache(
389
- filePath: filePath,
390
- nx: nx.intValue,
391
- ny: ny.intValue,
392
- scale: scale.floatValue,
393
- offset: offset.floatValue,
394
- missing: missing.floatValue,
395
- scaleType: (scaleType == "sqrt") ? 1 : 0
396
- )
397
- }
398
- }
399
- }
400
-
401
- @objc public func updateGeometry(corners: [String: Any], gridDef: [String: Any]) {
402
- print("🟢 [GridRenderLayer] updateGeometry called")
403
- print(" device: \(self.device != nil)")
404
-
405
- guard self.device != nil else {
406
- print("⚠️ [GridRenderLayer] Device not ready yet, storing geometry for later")
407
- pendingGeometryUpdate = (corners: corners, gridDef: gridDef)
408
- return
409
- }
410
-
411
- print(" Device is ready, processing geometry immediately")
412
-
413
- DispatchQueue.global(qos: .userInitiated).async {
414
- print(" 🔄 Generating geometry on background thread")
415
-
416
- var vertices: [Float] = []
417
- var indices: [UInt16] = []
418
-
419
- self.generateGeometryData(gridDef: gridDef, vertices: &vertices, indices: &indices)
420
-
421
- if vertices.isEmpty || indices.isEmpty {
422
- print(" [GridRenderLayer] No geometry generated")
423
- return
424
- }
425
-
426
- print(" ✅ Generated \(vertices.count/4) vertices, \(indices.count/3) triangles")
427
-
428
- self.indexCount = indices.count
429
-
430
- DispatchQueue.main.async {
431
- print(" 🎨 Creating buffers on main thread")
432
-
433
- self.vertexBuffer = self.device.makeBuffer(bytes: vertices, length: vertices.count * MemoryLayout<Float>.size, options: [])
434
- self.indexBuffer = self.device.makeBuffer(bytes: indices, length: indices.count * MemoryLayout<UInt16>.size, options: [])
435
-
436
- print("🟢 [GridRenderLayer] Geometry updated: \(vertices.count/4) vertices, \(indices.count/3) triangles")
437
- print(" vertexBuffer: \(self.vertexBuffer != nil)")
438
- print(" indexBuffer: \(self.indexBuffer != nil)")
439
- print(" indexCount: \(self.indexCount)")
440
-
441
- // TRIGGER A REPAINT - ADD THIS:
442
- NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
443
- }
444
- }
445
- }
446
-
447
- private func decompressZstd(data: Data) -> Data? {
448
- let decompressedSize = data.withUnsafeBytes { ptr in
449
- ZSTD_getFrameContentSize(ptr.baseAddress, data.count)
450
- }
451
-
452
- guard Int64(bitPattern: decompressedSize) > 0 else {
453
- print("❌ [GridRenderLayer] Could not determine decompressed size")
454
- return nil
455
- }
456
-
457
- var decompressedData = Data(count: Int(decompressedSize))
458
-
459
- let result = decompressedData.withUnsafeMutableBytes { decompressedPtr -> Int in
460
- data.withUnsafeBytes { compressedPtr -> Int in
461
- let returnValue = ZSTD_decompress(
462
- decompressedPtr.baseAddress,
463
- Int(decompressedSize),
464
- compressedPtr.baseAddress,
465
- data.count
466
- )
467
- return Int(returnValue)
468
- }
469
- }
470
-
471
- guard result > 0 && result == decompressedData.count else {
472
- if result > 0 {
473
- let size_t_result = size_t(result)
474
- if let errorName = ZSTD_getErrorName(size_t_result) {
475
- let errorString = String(cString: errorName)
476
- print("❌ [GridRenderLayer] Zstd decompression failed: \(errorString)")
477
- }
478
- }
479
- return nil
480
- }
481
- return decompressedData
482
- }
483
-
484
- // MARK: - Private Helper Methods
485
-
486
- private func reconstructData(decompressedDeltas: Data) -> Data {
487
- guard !decompressedDeltas.isEmpty else { return Data() }
488
- var reconstructedData = Data(count: decompressedDeltas.count)
489
- reconstructedData[0] = decompressedDeltas[0]
490
- for i in 1..<decompressedDeltas.count {
491
- reconstructedData[i] = UInt8(Int8(bitPattern: reconstructedData[i-1]) &+ Int8(bitPattern: decompressedDeltas[i]))
492
- }
493
- return reconstructedData
494
- }
495
-
496
- private func transformData(finalData: Data) -> Data {
497
- var transformedData = Data(count: finalData.count)
498
- for i in 0..<finalData.count {
499
- transformedData[i] = UInt8(Int16(Int8(bitPattern: finalData[i])) + 128)
500
- }
501
- return transformedData
502
- }
503
-
504
- private func isLCCType(gridDef: [String: Any]) -> Bool {
505
- if let type = gridDef["type"] as? String {
506
- return type == "lambert_conformal_conic"
507
- }
508
- return false
509
- }
510
-
511
- private func generateLCCGeometry(gridDef: [String: Any], vertices: inout [Float], indices: inout [UInt16]) {
512
- guard let gridParams = gridDef["grid_params"] as? [String: Any],
513
- let projParams = gridDef["proj_params"] as? [String: Any],
514
- let nx = gridParams["nx"] as? Int,
515
- let ny = gridParams["ny"] as? Int,
516
- let dx = gridParams["dx"] as? Double,
517
- let dy = gridParams["dy"] as? Double,
518
- let x_origin = gridParams["x_origin"] as? Double,
519
- let y_origin = gridParams["y_origin"] as? Double else {
520
- return
521
- }
522
-
523
- let subdivisions = 60
524
- let TILE_SIZE: Double = 512.0
525
-
526
- let x_min = x_origin
527
- let y_max = y_origin
528
- let x_max = x_origin + Double(nx - 1) * dx
529
- let y_min = y_origin + Double(ny - 1) * dy
530
-
531
- var vertexGrid: [[VertexInfo?]] = Array(repeating: Array(repeating: nil, count: subdivisions + 1), count: subdivisions + 1)
532
- var validVertexCount: UInt16 = 0
533
-
534
- // Generate vertices
535
- for row in 0...subdivisions {
536
- for col in 0...subdivisions {
537
- let t_x = Double(col) / Double(subdivisions)
538
- let t_y = Double(row) / Double(subdivisions)
539
-
540
- let proj_x = x_min + t_x * (x_max - x_min)
541
- let proj_y = y_max + t_y * (y_min - y_max)
542
-
543
- // Convert LCC projection coordinates to lat/lon
544
- if let (lon, lat) = lccToLonLat(i: proj_x, j: proj_y, gridDef: gridDef) {
545
- // Convert lat/lon to Mercator
546
- let mercX_normalized = (lon + 180.0) / 360.0
547
- let clampedLat = max(-85.05112878, min(85.05112878, lat))
548
- let sinLatitude = sin(clampedLat * .pi / 180.0)
549
- let mercY_normalized = 0.5 - log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * .pi)
550
-
551
- let mercX = mercX_normalized * TILE_SIZE
552
- let mercY = mercY_normalized * TILE_SIZE
553
-
554
- // Check for invalid values
555
- if !mercX.isFinite || !mercY.isFinite {
556
- vertexGrid[row][col] = nil
557
- continue
558
- }
559
-
560
- let tex_u = Float(t_x)
561
- let tex_v = Float(t_y)
562
-
563
- let vInfo = VertexInfo(
564
- mercX: Float(mercX),
565
- mercY: Float(mercY),
566
- texU: tex_u,
567
- texV: tex_v,
568
- index: validVertexCount
569
- )
570
-
571
- vertexGrid[row][col] = vInfo
572
-
573
- vertices.append(Float(mercX))
574
- vertices.append(Float(mercY))
575
- vertices.append(tex_u)
576
- vertices.append(tex_v)
577
-
578
- validVertexCount += 1
579
- } else {
580
- vertexGrid[row][col] = nil
581
- }
582
- }
583
- }
584
-
585
- if vertices.isEmpty {
586
- print("❌ [LCC Geometry] No valid vertices generated")
587
- return
588
- }
589
-
590
- // Generate indices
591
- for row in 0..<subdivisions {
592
- for col in 0..<subdivisions {
593
- guard let topLeft = vertexGrid[row][col],
594
- let topRight = vertexGrid[row][col + 1],
595
- let bottomLeft = vertexGrid[row + 1][col],
596
- let bottomRight = vertexGrid[row + 1][col + 1] else {
597
- continue
598
- }
599
-
600
- indices.append(topLeft.index)
601
- indices.append(bottomLeft.index)
602
- indices.append(topRight.index)
603
-
604
- indices.append(topRight.index)
605
- indices.append(bottomLeft.index)
606
- indices.append(bottomRight.index)
607
- }
608
- }
609
- }
610
-
611
- private func lccToLonLat(i: Double, j: Double, gridDef: [String: Any]) -> (lon: Double, lat: Double)? {
612
- guard let projParams = gridDef["proj_params"] as? [String: Any],
613
- let lat_0 = projParams["lat_0"] as? Double, // latitude of origin
614
- let lon_0 = projParams["lon_0"] as? Double, // longitude of origin
615
- let lat_1 = projParams["lat_1"] as? Double, // first standard parallel
616
- let lat_2 = projParams["lat_2"] as? Double, // second standard parallel (HRRR uses two!)
617
- let r_earth = projParams["R"] as? Double else {
618
- print("❌ [LCC Geometry] Failed to extract LCC parameters.")
619
- return nil
620
- }
621
-
622
- let π = Double.pi
623
- let toRad = π / 180.0
624
- let toDeg = 180.0 / π
625
-
626
- let lat1_rad = lat_1 * toRad
627
- let lat2_rad = lat_2 * toRad
628
- let lat0_rad = lat_0 * toRad
629
- let lon0_rad = lon_0 * toRad
630
-
631
- // Calculate cone constant (n) using two standard parallels
632
- let n: Double
633
- if abs(lat_1 - lat_2) < 1e-10 {
634
- n = sin(lat1_rad) // Single parallel case
635
- } else {
636
- n = log(cos(lat1_rad) / cos(lat2_rad)) / log(tan(π/4.0 + lat2_rad/2.0) / tan(π/4.0 + lat1_rad/2.0))
637
- }
638
-
639
- let F = cos(lat1_rad) * pow(tan(π/4.0 + lat1_rad/2.0), n) / n
640
- let rho_0 = r_earth * F * pow(tan(π/4.0 + lat0_rad/2.0), -n)
641
-
642
- // i, j are the x, y projection coordinates
643
- let x = i
644
- let y = j
645
-
646
- let rho = sqrt(x * x + (rho_0 - y) * (rho_0 - y))
647
- if rho < 1e-10 {
648
- return (lon: lon_0, lat: lat_0)
649
- }
650
-
651
- let theta = atan2(x, rho_0 - y)
652
-
653
- let lon = lon0_rad + theta / n
654
- let lat = 2.0 * atan(pow(r_earth * F / rho, 1.0 / n)) - π/2.0
655
-
656
- let lonDeg = lon * toDeg
657
- let latDeg = lat * toDeg
658
-
659
- if !lonDeg.isFinite || !latDeg.isFinite {
660
- return nil
661
- }
662
-
663
- return (lon: lonDeg, lat: latDeg)
664
- }
665
-
666
- private func generateGeometryData(gridDef: [String: Any], vertices: inout [Float], indices: inout [UInt16]) {
667
- guard let gridParams = gridDef["grid_params"] as? [String: Any] else {
668
- return
669
- }
670
-
671
- // GFS Global Grid Path
672
- if isGFSType(gridParams: gridParams) {
673
- let subdivisions = 120
674
- let verticesPerRow = (subdivisions * 3) + 1
675
- let TILE_SIZE: Double = 512.0
676
-
677
- for row in 0...subdivisions {
678
- for col in 0...(subdivisions * 3) {
679
- let v_interp = Float(row) / Float(subdivisions)
680
- let u_interp = Float(col) / Float(subdivisions)
681
- let lon = -540.0 + Double(u_interp) * 1080.0
682
- let lat = -90.0 + Double(v_interp) * 180.0
683
-
684
- let merc = lonLatToMercator(lon: lon, lat: lat, tileSize: TILE_SIZE)
685
- vertices.append(contentsOf: [merc.x, merc.y])
686
-
687
- let tex_u = Float((lon + 180.0) / 360.0)
688
- let tex_v = 1.0 - v_interp
689
- vertices.append(contentsOf: [tex_u, tex_v])
690
- }
691
- }
692
-
693
- for row in 0..<subdivisions {
694
- for col in 0..<(subdivisions * 3) {
695
- let tl = UInt16(row * verticesPerRow + col)
696
- let tr = tl + 1
697
- let bl = UInt16((row + 1) * verticesPerRow + col)
698
- let br = bl + 1
699
- indices.append(contentsOf: [tl, bl, tr, tr, bl, br])
700
- }
701
- }
702
- return
703
- }
704
- if isLCCType(gridDef: gridDef) {
705
- generateLCCGeometry(gridDef: gridDef, vertices: &vertices, indices: &indices)
706
- return
707
- }
708
-
709
- // Generic Grid Path (MRMS, etc.)
710
- let nx = gridParams["nx"] as? Int ?? 0
711
- let ny = gridParams["ny"] as? Int ?? 0
712
- let lon_first = gridParams["lon_first"] as? Double ?? 0.0
713
- let lat_first = gridParams["lat_first"] as? Double ?? 90.0
714
- let dx = gridParams["dx_degrees"] as? Double ?? 0.0
715
- let dy = gridParams["dy_degrees"] as? Double ?? 0.0
716
- let lon_last = gridParams["lon_last"] as? Double ?? (lon_first + Double(nx - 1) * dx)
717
- let lat_last = gridParams["lat_last"] as? Double ?? (lat_first + Double(ny - 1) * dy)
718
- let lat_span = lat_last - lat_first
719
- let isSouthToNorth = lat_span > 0
720
-
721
- let data_lon_first_180 = lon_first > 180 ? lon_first - 360 : lon_first
722
- let data_lon_last_180 = lon_last > 180 ? lon_last - 360 : lon_last
723
- let data_lon_range = data_lon_last_180 - data_lon_first_180
724
-
725
- let subdivisions_x = 120
726
- let subdivisions_y = 60
727
- let verticesPerRow = subdivisions_x + 1
728
- let TILE_SIZE: Double = 512.0
729
-
730
- // 🔑 FIX: Only create ONE world copy for regional data, THREE for global data
731
- let worldCopies = (data_lon_range > 300) ? [-1, 0, 1] : [0] // Only wrap if nearly global
732
-
733
- for world_copy in worldCopies {
734
- let vertexStartIndex = UInt16(vertices.count / 4)
735
- let lon_offset = Double(world_copy) * 360.0
736
-
737
- // Generate vertices for this world copy
738
- for row in 0...subdivisions_y {
739
- for col in 0...subdivisions_x {
740
- let v_interp = Float(row) / Float(subdivisions_y)
741
- let u_interp = Float(col) / Float(subdivisions_x)
742
-
743
- let vertex_lon = data_lon_first_180 + (Double(u_interp) * data_lon_range)
744
- let vertex_lat = lat_first + (Double(v_interp) * lat_span)
745
-
746
- let mercX_normalized = ((vertex_lon + lon_offset) + 180.0) / 360.0
747
- let clampedLat = max(-85.05112878, min(85.05112878, vertex_lat))
748
- let sinLatitude = sin(clampedLat * .pi / 180.0)
749
- let mercY_normalized = 0.5 - log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * .pi)
750
- let mercX = mercX_normalized * TILE_SIZE
751
- let mercY = mercY_normalized * TILE_SIZE
752
-
753
- vertices.append(contentsOf: [Float(mercX), Float(mercY)])
754
-
755
- let tex_u = u_interp
756
- let tex_v = isSouthToNorth ? (1.0 - v_interp) : v_interp
757
-
758
- vertices.append(contentsOf: [tex_u, tex_v])
759
- }
760
- }
761
-
762
- // Generate indices (same as before)
763
- for row in 0..<UInt16(subdivisions_y) {
764
- for col in 0..<UInt16(subdivisions_x) {
765
- let tl = vertexStartIndex + row * UInt16(verticesPerRow) + col
766
- let tr = tl + 1
767
- let bl = vertexStartIndex + (row + 1) * UInt16(verticesPerRow) + col
768
- let br = bl + 1
769
-
770
- if isSouthToNorth {
771
- indices.append(contentsOf: [tl, bl, tr, tr, bl, br])
772
- } else {
773
- indices.append(contentsOf: [tl, tr, bl, bl, tr, br])
774
- }
775
- }
776
- }
777
- }
778
- }
779
-
780
- private func isGFSType(gridParams: [String: Any]) -> Bool {
781
- return (gridParams["lon_first"] as? Double) == 0.0 &&
782
- abs((gridParams["lat_first"] as? Double) ?? -1) == 90.0
783
- }
784
-
785
- private func lonLatToMercator(lon: Double, lat: Double, tileSize: Double) -> (x: Float, y: Float) {
786
- let mercX_normalized = (lon + 180.0) / 360.0
787
- let clampedLat = max(-85.05112878, min(85.05112878, lat))
788
- let sinLatitude = sin(clampedLat * .pi / 180.0)
789
- let mercY_normalized = 0.5 - log((1.0 + sinLatitude) / (1.0 - sinLatitude)) / (4.0 * .pi)
790
-
791
- return (x: Float(mercX_normalized * tileSize), y: Float(mercY_normalized * tileSize))
792
- }
793
-
794
- // MARK: - Internal methods for CustomLayerHost (called by wrapper)
795
-
796
- internal func internalRenderingWillStart(_ metalDevice: MTLDevice, colorPixelFormat: UInt, depthStencilPixelFormat: UInt) {
797
- print("🟢 [GridRenderLayer] renderingWillStart called")
798
- self.device = metalDevice
799
- self.commandQueue = metalDevice.makeCommandQueue()
800
-
801
- let bundle = Bundle(for: GridRenderLayer.self)
802
-
803
- // Determine if we're running on simulator or device
804
- #if targetEnvironment(simulator)
805
- let metallibName = "Shaders-simulator"
806
- #else
807
- let metallibName = "Shaders-device"
808
- #endif
809
-
810
- // Try to load pre-compiled metallib for the current platform
811
- let defaultLibrary: MTLLibrary?
812
- if let metallibUrl = bundle.url(forResource: metallibName, withExtension: "metallib"),
813
- let library = try? metalDevice.makeLibrary(URL: metallibUrl) {
814
- print("✅ [GridRenderLayer] Loaded pre-compiled metallib (\(metallibName))")
815
- defaultLibrary = library
816
- }
817
- // Fall back to compiling from .metal source (for development with npm link)
818
- else if let metalUrl = bundle.url(forResource: "Shaders", withExtension: "metal"),
819
- let source = try? String(contentsOf: metalUrl),
820
- let library = try? metalDevice.makeLibrary(source: source, options: nil) {
821
- print("✅ [GridRenderLayer] Compiled Metal shader from source")
822
- defaultLibrary = library
823
- }
824
- // Neither worked
825
- else {
826
- print("❌ [GridRenderLayer] Could not find or compile Metal shaders")
827
- print(" Bundle path: \(bundle.bundlePath)")
828
- return
829
- }
830
-
831
- guard let library = defaultLibrary else {
832
- print("❌ [GridRenderLayer] Failed to create Metal library")
833
- return
834
- }
835
-
836
- let vertexFunction = library.makeFunction(name: "vertex_main")
837
- let fragmentFunction = library.makeFunction(name: "fragment_main")
838
-
839
- // Set up vertex descriptor
840
- let vertexDescriptor = MTLVertexDescriptor()
841
- vertexDescriptor.attributes[0].format = .float2 // position (x, y)
842
- vertexDescriptor.attributes[0].offset = 0
843
- vertexDescriptor.attributes[0].bufferIndex = 0
844
-
845
- vertexDescriptor.attributes[1].format = .float2 // texCoord (u, v)
846
- vertexDescriptor.attributes[1].offset = MemoryLayout<Float>.size * 2
847
- vertexDescriptor.attributes[1].bufferIndex = 0
848
-
849
- vertexDescriptor.layouts[0].stride = MemoryLayout<Float>.size * 4 // 2 floats for pos + 2 for texCoord
850
- vertexDescriptor.layouts[0].stepFunction = .perVertex
851
-
852
- let pipelineDescriptor = MTLRenderPipelineDescriptor()
853
- pipelineDescriptor.vertexDescriptor = vertexDescriptor
854
- pipelineDescriptor.vertexFunction = vertexFunction
855
- pipelineDescriptor.fragmentFunction = fragmentFunction
856
-
857
- pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat(rawValue: colorPixelFormat) ?? .bgra8Unorm
858
- pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
859
- pipelineDescriptor.stencilAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
860
-
861
- pipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
862
- pipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
863
- pipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
864
- pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
865
- pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
866
- pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
867
- pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
868
-
869
- do {
870
- self.pipelineState = try metalDevice.makeRenderPipelineState(descriptor: pipelineDescriptor)
871
- } catch {
872
- print("❌ [GridRenderLayer] Failed to create pipeline state: \(error)")
873
- return
874
- }
875
-
876
- let dataSamplerDesc = MTLSamplerDescriptor()
877
- dataSamplerDesc.minFilter = .nearest
878
- dataSamplerDesc.magFilter = .nearest
879
- self.dataSamplerState = metalDevice.makeSamplerState(descriptor: dataSamplerDesc)
880
-
881
- let colormapSamplerDesc = MTLSamplerDescriptor()
882
- colormapSamplerDesc.minFilter = .nearest
883
- colormapSamplerDesc.magFilter = .nearest
884
- colormapSamplerDesc.sAddressMode = .clampToEdge
885
- self.colormapSamplerState = metalDevice.makeSamplerState(descriptor: colormapSamplerDesc)
886
-
887
- print("🟢 [GridRenderLayer] Metal setup complete")
888
-
889
- // Process any pending updates that came in before Metal was ready
890
- if let pendingGeometry = pendingGeometryUpdate {
891
- print("🟡 [GridRenderLayer] Processing pending geometry update")
892
- updateGeometry(corners: pendingGeometry.corners, gridDef: pendingGeometry.gridDef)
893
- pendingGeometryUpdate = nil
894
- }
895
-
896
- if let pendingColormap = pendingColormapUpdate {
897
- print("🟡 [GridRenderLayer] Processing pending colormap update")
898
- updateColormapTexture(colormapAsBase64: pendingColormap)
899
- pendingColormapUpdate = nil
900
- }
901
-
902
- if let pendingData = pendingDataUpdate {
903
- print("🟡 [GridRenderLayer] Processing pending data update")
904
- updateDataTexture(data: pendingData.data, nx: pendingData.nx, ny: pendingData.ny,
905
- scale: pendingData.scale, offset: pendingData.offset,
906
- missing: pendingData.missing, scaleType: pendingData.scaleType)
907
- pendingDataUpdate = nil
908
- }
909
- }
910
- internal func internalRender(_ parameters: CustomLayerRenderParameters, mtlCommandBuffer: MTLCommandBuffer, mtlRenderPassDescriptor: MTLRenderPassDescriptor) {
911
- guard isVisible,
912
- let pipeline = pipelineState,
913
- let vertices = vertexBuffer,
914
- let indices = indexBuffer,
915
- let dataTex = dataTexture,
916
- let colormapTex = colormapTexture,
917
- indexCount > 0,
918
- let encoder = mtlCommandBuffer.makeRenderCommandEncoder(descriptor: mtlRenderPassDescriptor) else {
919
-
920
- // OPTIMIZATION: Change log message to be more informative and less alarming.
921
- // This is an expected state during initial load.
922
- if (pipelineState != nil) { // Only log if Metal is set up
923
- print("🟡 [GridRenderLayer] internalRender: Waiting for all resources to be ready before drawing.")
924
- }
925
- return
926
- }
927
-
928
- print("✅ [GridRenderLayer] Past guards, about to render!")
929
- print(" 🎨 About to draw \(indexCount) indices (\(indexCount/3) triangles)")
930
-
931
- let needsLinear = (uniforms.smoothing != 0)
932
- if isDataSamplerLinear != needsLinear {
933
- let samplerDesc = MTLSamplerDescriptor()
934
- samplerDesc.minFilter = needsLinear ? .linear : .nearest
935
- samplerDesc.magFilter = needsLinear ? .linear : .nearest
936
- dataSamplerState = device.makeSamplerState(descriptor: samplerDesc)
937
- isDataSamplerLinear = needsLinear
938
- }
939
-
940
- // Apply zoom scale transformation
941
- let zoom = parameters.zoom
942
- let scale = Float(pow(2.0, zoom))
943
-
944
- let matrixArray = parameters.projectionMatrix
945
- var floatArray = matrixArray.map { $0.floatValue }
946
-
947
- floatArray[0] *= scale // X scale
948
- floatArray[1] *= scale // X rotation
949
- floatArray[4] *= scale // Y rotation
950
- floatArray[5] *= scale
951
-
952
- let mvp = matrix_float4x4(
953
- SIMD4<Float>(floatArray[0], floatArray[1], floatArray[2], floatArray[3]),
954
- SIMD4<Float>(floatArray[4], floatArray[5], floatArray[6], floatArray[7]),
955
- SIMD4<Float>(floatArray[8], floatArray[9], floatArray[10], floatArray[11]),
956
- SIMD4<Float>(floatArray[12], floatArray[13], floatArray[14], floatArray[15])
957
- )
958
-
959
- print(" 📐 MVP matrix after scaling: \(mvp)")
960
- print(" 📍 Zoom: \(zoom), Scale factor: \(scale)")
961
-
962
- // Add depth state
963
- let depthStencilDescriptor = MTLDepthStencilDescriptor()
964
- depthStencilDescriptor.depthCompareFunction = .always
965
- depthStencilDescriptor.isDepthWriteEnabled = false
966
- let depthStencilState = device.makeDepthStencilState(descriptor: depthStencilDescriptor)
967
-
968
- encoder.setRenderPipelineState(pipeline)
969
- encoder.setDepthStencilState(depthStencilState!)
970
- encoder.setVertexBuffer(vertices, offset: 0, index: 0)
971
- encoder.setVertexBytes([mvp], length: MemoryLayout<matrix_float4x4>.size, index: 1)
972
-
973
- var mutableUniforms = uniforms
974
- encoder.setFragmentBytes(&mutableUniforms, length: MemoryLayout<FragmentUniforms>.stride, index: 0)
975
- encoder.setFragmentTexture(dataTex, index: 0)
976
- encoder.setFragmentTexture(colormapTex, index: 1)
977
- encoder.setFragmentSamplerState(dataSamplerState, index: 0)
978
- encoder.setFragmentSamplerState(colormapSamplerState, index: 1)
979
-
980
- print(" 🎨 Drawing indexed primitives now...")
981
- encoder.drawIndexedPrimitives(type: .triangle, indexCount: indexCount, indexType: .uint16, indexBuffer: indices, indexBufferOffset: 0)
982
- print(" ✅ Draw call completed")
983
-
984
- encoder.endEncoding()
985
- print(" ✅ Encoder ended")
986
- }
987
-
988
- internal func internalRenderingWillEnd() {
989
- print("🟢 [GridRenderLayer] renderingWillEnd called")
990
- vertexBuffer = nil
991
- indexBuffer = nil
992
- dataTexture = nil
993
- colormapTexture = nil
994
- }
995
- }
1
+ import Foundation
2
+ import MapboxMaps
3
+ import Metal
4
+ import libzstd
5
+ import simd
6
+
7
+ // MARK: - Swift-only wrapper for CustomLayerHost conformance
8
+ @objc internal final class GridRenderLayerHost: NSObject, CustomLayerHost {
9
+ weak var layer: GridRenderLayer?
10
+
11
+ init(layer: GridRenderLayer) {
12
+ self.layer = layer
13
+ super.init()
14
+ }
15
+
16
+ func renderingWillStart(_ metalDevice: MTLDevice, colorPixelFormat: UInt, depthStencilPixelFormat: UInt) {
17
+ layer?.internalRenderingWillStart(metalDevice, colorPixelFormat: colorPixelFormat, depthStencilPixelFormat: depthStencilPixelFormat)
18
+ }
19
+
20
+ func render(_ parameters: CustomLayerRenderParameters, mtlCommandBuffer: MTLCommandBuffer, mtlRenderPassDescriptor: MTLRenderPassDescriptor) {
21
+ layer?.internalRender(parameters, mtlCommandBuffer: mtlCommandBuffer, mtlRenderPassDescriptor: mtlRenderPassDescriptor)
22
+ }
23
+
24
+ func renderingWillEnd() {
25
+ layer?.internalRenderingWillEnd()
26
+ }
27
+ }
28
+
29
+ @objc(GridRenderLayer)
30
+ public class GridRenderLayer: NSObject {
31
+
32
+ // MARK: - Properties
33
+
34
+ public var id: String
35
+ @objc internal var hostWrapper: GridRenderLayerHost!
36
+
37
+ // Metal objects
38
+ private var device: MTLDevice!
39
+ private var commandQueue: MTLCommandQueue!
40
+ private var pipelineState: MTLRenderPipelineState!
41
+ private var vertexBuffer: MTLBuffer?
42
+ private var indexBuffer: MTLBuffer?
43
+ private var dataTexture: MTLTexture?
44
+ private var colormapTexture: MTLTexture?
45
+ private var dataSamplerState: MTLSamplerState!
46
+ private var colormapSamplerState: MTLSamplerState!
47
+ private var isDataSamplerLinear: Bool = false
48
+
49
+ private var pendingColormapUpdate: String?
50
+ private var pendingDataUpdate: (data: String, nx: NSNumber, ny: NSNumber, scale: NSNumber, offset: NSNumber, missing: NSNumber, scaleType: String)?
51
+ private var pendingGeometryUpdate: (corners: [String: Any], gridDef: [String: Any])?
52
+
53
+ // Layer state
54
+ private var indexCount: Int = 0
55
+ private var uniforms = FragmentUniforms(
56
+ opacity: 1.0,
57
+ dataRange: SIMD2<Float>(0.0, 1.0),
58
+ scale: 1.0,
59
+ offset: 0.0,
60
+ missingQuantized: 127.0,
61
+ textureSize: SIMD2<Float>(0.0, 0.0),
62
+ smoothing: 1,
63
+ scaleType: 0,
64
+ isPtype: 0,
65
+ isMRMS: 0
66
+ )
67
+ private var isVisible = false
68
+ private var pendingActiveFrameKey: String?
69
+ private let inspectorCache = InspectorDataCache.shared
70
+ private struct FrameMetadata {
71
+ let texture: MTLTexture
72
+ let scale: Float
73
+ let offset: Float
74
+ let missing: Float
75
+ let scaleType: Int
76
+ let nx: Float
77
+ let ny: Float
78
+ let filePath: String
79
+ let originalScale: Float
80
+ let originalOffset: Float
81
+ }
82
+ private var frameCache: [String: FrameMetadata] = [:]
83
+ private let highPriorityTextureQueue = DispatchQueue(label: "com.aguacero.texture-processing-high-priority", qos: .userInitiated)
84
+
85
+ // The concurrent queue for background preloading all other frames.
86
+ private let backgroundTextureQueue = DispatchQueue(label: "com.aguacero.texture-processing-background", qos: .utility, attributes: .concurrent)
87
+ // MARK: - Initializer
88
+ private struct VertexInfo {
89
+ var mercX: Float
90
+ var mercY: Float
91
+ var texU: Float
92
+ var texV: Float
93
+ var index: UInt16
94
+ }
95
+ @objc
96
+ public init(id: String) {
97
+ self.id = id
98
+ super.init()
99
+ self.hostWrapper = GridRenderLayerHost(layer: self)
100
+ print("🟢 [GridRenderLayer] Initialized with ID: \(id)")
101
+ }
102
+
103
+ @objc public func getHostWrapper() -> Any {
104
+ return self.hostWrapper as Any
105
+ }
106
+
107
+ // MARK: - Public Methods (called from Manager)
108
+
109
+ @objc public func setOpacity(value: Float) {
110
+ self.uniforms.opacity = value
111
+ print("🟢 [GridRenderLayer] Set opacity: \(value)")
112
+ // ADD THIS: Force the map to repaint to show the opacity change immediately.
113
+ NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
114
+ }
115
+
116
+ @objc public func setDataRange(value: [NSNumber]) {
117
+ self.uniforms.dataRange = SIMD2<Float>(value[0].floatValue, value[1].floatValue)
118
+ print("🟢 [GridRenderLayer] Set data range: \(value)")
119
+ // ADD THIS: Force the map to repaint to show the data range change immediately.
120
+ NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
121
+ }
122
+
123
+ @objc public func setSmoothing(value: Bool) {
124
+ self.uniforms.smoothing = value ? 1 : 0
125
+ print("🟢 [GridRenderLayer] Set smoothing: \(value)")
126
+ // ADD THIS: Force the map to repaint to show the smoothing change immediately.
127
+ NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
128
+ }
129
+
130
+ @objc(setIsMRMSWithIsMRMS:)
131
+ public func setIsMRMS(isMRMS: Bool) {
132
+ self.uniforms.isMRMS = isMRMS ? 1 : 0
133
+ print("🟢 [GridRenderLayer] Set isMRMS: \(isMRMS)")
134
+ NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
135
+ }
136
+
137
+ // ADD THIS METHOD
138
+ @objc(setVariableWithVariable:)
139
+ public func setVariable(variable: String) {
140
+ let isPtypeVar = (variable == "ptypeRefl" || variable == "ptypeRate")
141
+ self.uniforms.isPtype = isPtypeVar ? 1 : 0
142
+ print("🟢 [GridRenderLayer] Set variable: \(variable), isPtype set to: \(self.uniforms.isPtype)")
143
+ NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
144
+ }
145
+
146
+ @objc public func clear() {
147
+ self.isVisible = false
148
+ self.inspectorCache.clear()
149
+ print("🟢 [GridRenderLayer] Cleared")
150
+ }
151
+
152
+ @objc public func updateDataParameters(scale: NSNumber, offset: NSNumber, missing: NSNumber, scaleType: NSNumber) { // ADD scaleType parameter
153
+ // Update both the inspector cache AND the rendering uniforms
154
+ self.uniforms.scale = scale.floatValue
155
+ self.uniforms.offset = offset.floatValue
156
+ self.uniforms.missingQuantized = missing.floatValue
157
+ self.uniforms.scaleType = Int32(scaleType.intValue) // ADD THIS
158
+
159
+ inspectorCache.update(
160
+ data: inspectorCache.lastDecompressedData,
161
+ nx: inspectorCache.nx,
162
+ ny: inspectorCache.ny,
163
+ scale: scale.floatValue,
164
+ offset: offset.floatValue,
165
+ missing: missing.floatValue,
166
+ scaleType: scaleType.intValue // ADD THIS
167
+ )
168
+
169
+ print("🟢 [GridRenderLayer] Updated data parameters - scale: \(scale), offset: \(offset), missing: \(missing), scaleType: \(scaleType)")
170
+ }
171
+
172
+ @objc public func updateColormapTexture(colormapAsBase64: String) {
173
+ guard let device = self.device else {
174
+ pendingColormapUpdate = colormapAsBase64
175
+ return
176
+ }
177
+ guard let data = Data(base64Encoded: colormapAsBase64) else { return }
178
+ let textureDescriptor = MTLTextureDescriptor()
179
+ textureDescriptor.pixelFormat = .rgba8Unorm
180
+ textureDescriptor.width = 256
181
+ textureDescriptor.height = 1
182
+ textureDescriptor.usage = .shaderRead
183
+ guard let texture = device.makeTexture(descriptor: textureDescriptor) else { return }
184
+ texture.replace(
185
+ region: MTLRegionMake2D(0, 0, 256, 1),
186
+ mipmapLevel: 0,
187
+ withBytes: (data as NSData).bytes,
188
+ bytesPerRow: 256 * 4
189
+ )
190
+ self.colormapTexture = texture
191
+ }
192
+
193
+ @objc(clearGpuCache) // Explicitly name the Obj-C selector
194
+ public func clearGpuCache() {
195
+ backgroundTextureQueue.async {
196
+ self.frameCache.removeAll()
197
+ print("🟢 [GridRenderLayer] GPU frame cache cleared.")
198
+ }
199
+ }
200
+
201
+ private func processRawData(fileData: Data) -> Data? {
202
+ guard let decompressedDeltas = self.decompressZstd(data: fileData) else {
203
+ print("❌ [GridRenderLayer] Failed to decompress zstd data")
204
+ return nil
205
+ }
206
+ let reconstructedData = self.reconstructData(decompressedDeltas: decompressedDeltas)
207
+ let finalTextureBytes = self.transformData(finalData: reconstructedData)
208
+ return finalTextureBytes
209
+ }
210
+
211
+ private func createTextureFromBytes(bytes: Data, nx: Int, ny: Int) -> MTLTexture? {
212
+ guard let device = self.device else { return nil }
213
+ let textureDescriptor = MTLTextureDescriptor()
214
+ textureDescriptor.pixelFormat = .r8Unorm
215
+ textureDescriptor.width = nx
216
+ textureDescriptor.height = ny
217
+ textureDescriptor.usage = .shaderRead
218
+
219
+ guard let texture = device.makeTexture(descriptor: textureDescriptor) else { return nil }
220
+ texture.replace(
221
+ region: MTLRegionMake2D(0, 0, nx, ny),
222
+ mipmapLevel: 0,
223
+ withBytes: (bytes as NSData).bytes,
224
+ bytesPerRow: nx
225
+ )
226
+ return texture
227
+ }
228
+
229
+ private func updateInspectorCache(filePath: String, nx: Int, ny: Int, scale: Float, offset: Float, missing: Float, scaleType: Int) {
230
+ highPriorityTextureQueue.async {
231
+
232
+ guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
233
+ print("❌ [Inspector] FATAL: Failed to read file data from path.")
234
+ self.inspectorCache.clear()
235
+ return
236
+ }
237
+ print("💡 [Inspector] 2. Successfully read \(fileData.count) bytes from file.")
238
+
239
+ guard let decompressedDeltas = self.decompressZstd(data: fileData) else {
240
+ print("❌ [Inspector] FATAL: Failed to decompress Zstd data.")
241
+ self.inspectorCache.clear()
242
+ return
243
+ }
244
+ print("💡 [Inspector] 3. Successfully decompressed data.")
245
+
246
+ let reconstructedData = self.reconstructData(decompressedDeltas: decompressedDeltas)
247
+ print("💡 [Inspector] 4. Reconstructed data with \(reconstructedData.count) bytes.")
248
+
249
+ self.inspectorCache.update(
250
+ data: reconstructedData,
251
+ nx: nx,
252
+ ny: ny,
253
+ scale: scale,
254
+ offset: offset,
255
+ missing: missing,
256
+ scaleType: scaleType
257
+ )
258
+
259
+ print("💡 [Inspector] 5. ✅ Cache updated successfully with scaleType=\(scaleType)")
260
+ }
261
+ }
262
+
263
+ @objc(setActiveFrameWithCacheKey:)
264
+ public func setActiveFrame(cacheKey: String) {
265
+ // First, check if the frame is already in the cache.
266
+ if let frame = frameCache[cacheKey] {
267
+ print("⚡️ [GridRenderLayer] Cache HIT for key: \(cacheKey). Swapping texture.")
268
+
269
+ self.dataTexture = frame.texture
270
+ self.uniforms.scale = frame.scale
271
+ self.uniforms.offset = frame.offset
272
+ self.uniforms.missingQuantized = frame.missing
273
+ self.uniforms.textureSize = SIMD2<Float>(frame.nx, frame.ny)
274
+ self.uniforms.scaleType = Int32(frame.scaleType)
275
+
276
+ self.isVisible = true
277
+ self.pendingActiveFrameKey = nil // Clear any pending key
278
+ NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
279
+
280
+ // --- ADD THIS ---
281
+ // Now that the frame is active, update the inspector cache with its data.
282
+ self.updateInspectorCache(
283
+ filePath: frame.filePath,
284
+ nx: Int(frame.nx),
285
+ ny: Int(frame.ny),
286
+ scale: frame.scale,
287
+ offset: frame.offset,
288
+ missing: frame.missing,
289
+ scaleType: frame.scaleType
290
+ )
291
+
292
+ } else {
293
+ // --- FIX: If it's a miss, store the key and wait for it to be primed. ---
294
+ print("⚠️ [GridRenderLayer] setActiveFrame cache MISS for key: \(cacheKey). Will apply when primed.")
295
+ self.pendingActiveFrameKey = cacheKey
296
+ self.isVisible = false // Hide the layer until the frame is ready
297
+ }
298
+ }
299
+
300
+ @objc(primeGpuCacheWithFrameInfo:)
301
+ public func primeGpuCache(frameInfo: [String: [String: Any]]) {
302
+ let group = DispatchGroup()
303
+
304
+ if (frameInfo.count > 1) {
305
+ print("🟡 [GridRenderLayer] Starting to prime \(frameInfo.count) textures concurrently...")
306
+ }
307
+
308
+ for (cacheKey, info) in frameInfo {
309
+ group.enter()
310
+
311
+ backgroundTextureQueue.async {
312
+ defer { group.leave() }
313
+ if self.frameCache[cacheKey] != nil { return }
314
+
315
+ guard let filePath = info["filePath"] as? String,
316
+ let nx = info["nx"] as? NSNumber,
317
+ let ny = info["ny"] as? NSNumber,
318
+ let scale = info["scale"] as? NSNumber,
319
+ let offset = info["offset"] as? NSNumber,
320
+ let missing = info["missing"] as? NSNumber,
321
+ let scaleTypeStr = info["scaleType"] as? String,
322
+ let originalScale = info["originalScale"] as? NSNumber, // ADD THIS
323
+ let originalOffset = info["originalOffset"] as? NSNumber, // ADD THIS
324
+ let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)),
325
+ let finalTextureBytes = self.processRawData(fileData: fileData)
326
+ else {
327
+ print("❌ [GridRenderLayer] Skipping prime for \(cacheKey), missing data.")
328
+ return
329
+ }
330
+
331
+ DispatchQueue.main.sync {
332
+ if let texture = self.createTextureFromBytes(bytes: finalTextureBytes, nx: nx.intValue, ny: ny.intValue) {
333
+ let metadata = FrameMetadata(
334
+ texture: texture,
335
+ scale: scale.floatValue,
336
+ offset: offset.floatValue,
337
+ missing: missing.floatValue,
338
+ scaleType: (scaleTypeStr == "sqrt") ? 1 : 0,
339
+ nx: nx.floatValue,
340
+ ny: ny.floatValue,
341
+ filePath: filePath,
342
+ originalScale: originalScale.floatValue, // ADD THIS
343
+ originalOffset: originalOffset.floatValue // ADD THIS
344
+ )
345
+ self.frameCache[cacheKey] = metadata
346
+ print(" ✅ [GridRenderLayer] Primed and cached frame for key: \(cacheKey)")
347
+
348
+ if let pendingKey = self.pendingActiveFrameKey, pendingKey == cacheKey {
349
+ print("👍 [GridRenderLayer] The pending frame is now ready. Activating it.")
350
+ self.setActiveFrame(cacheKey: pendingKey)
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+
357
+ group.notify(queue: .main) {
358
+ if (frameInfo.count > 1) {
359
+ print("🎉 [GridRenderLayer] All \(frameInfo.count) frames have been processed and cached to the GPU.")
360
+ }
361
+ }
362
+ }
363
+
364
+ @objc public func updateDataTexture(data: String, nx: NSNumber, ny: NSNumber, scale: NSNumber, offset: NSNumber, missing: NSNumber, scaleType: String) {
365
+ print("🚀 [GridRenderLayer] FAST LANE: updateDataTexture called for initial frame...")
366
+
367
+ let filePath = data // Assuming 'data' is always the file path for this method.
368
+
369
+ // USE THE HIGH-PRIORITY QUEUE
370
+ highPriorityTextureQueue.async {
371
+ guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else { return }
372
+
373
+ guard let finalTextureBytes = self.processRawData(fileData: fileData) else {
374
+ print("❌ [GridRenderLayer] FAST LANE: Failed to process initial frame data.")
375
+ return
376
+ }
377
+
378
+ DispatchQueue.main.async {
379
+ guard let texture = self.createTextureFromBytes(bytes: finalTextureBytes, nx: nx.intValue, ny: ny.intValue) else {
380
+ return
381
+ }
382
+
383
+ self.dataTexture = texture
384
+ self.uniforms.scale = scale.floatValue
385
+ self.uniforms.offset = offset.floatValue
386
+ self.uniforms.missingQuantized = missing.floatValue
387
+ self.uniforms.scaleType = Int32((scaleType == "sqrt") ? 1 : 0)
388
+ self.uniforms.textureSize = SIMD2<Float>(nx.floatValue, ny.floatValue)
389
+
390
+ self.isVisible = true
391
+ print("✅ [GridRenderLayer] FAST LANE: Initial frame processed and displayed.")
392
+ NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
393
+
394
+ // --- ADD THIS ---
395
+ // Update the inspector cache for the initial frame.
396
+ self.updateInspectorCache(
397
+ filePath: filePath,
398
+ nx: nx.intValue,
399
+ ny: ny.intValue,
400
+ scale: scale.floatValue,
401
+ offset: offset.floatValue,
402
+ missing: missing.floatValue,
403
+ scaleType: (scaleType == "sqrt") ? 1 : 0
404
+ )
405
+ }
406
+ }
407
+ }
408
+
409
+ @objc public func updateGeometry(corners: [String: Any], gridDef: [String: Any]) {
410
+ print("🟢 [GridRenderLayer] updateGeometry called")
411
+ print(" device: \(self.device != nil)")
412
+
413
+ guard self.device != nil else {
414
+ print("⚠️ [GridRenderLayer] Device not ready yet, storing geometry for later")
415
+ pendingGeometryUpdate = (corners: corners, gridDef: gridDef)
416
+ return
417
+ }
418
+
419
+ print(" Device is ready, processing geometry immediately")
420
+
421
+ DispatchQueue.global(qos: .userInitiated).async {
422
+ print(" 🔄 Generating geometry on background thread")
423
+
424
+ var vertices: [Float] = []
425
+ var indices: [UInt16] = []
426
+
427
+ self.generateGeometryData(gridDef: gridDef, vertices: &vertices, indices: &indices)
428
+
429
+ if vertices.isEmpty || indices.isEmpty {
430
+ print("❌ [GridRenderLayer] No geometry generated")
431
+ return
432
+ }
433
+
434
+ print(" ✅ Generated \(vertices.count/4) vertices, \(indices.count/3) triangles")
435
+
436
+ self.indexCount = indices.count
437
+
438
+ DispatchQueue.main.async {
439
+ print(" 🎨 Creating buffers on main thread")
440
+
441
+ self.vertexBuffer = self.device.makeBuffer(bytes: vertices, length: vertices.count * MemoryLayout<Float>.size, options: [])
442
+ self.indexBuffer = self.device.makeBuffer(bytes: indices, length: indices.count * MemoryLayout<UInt16>.size, options: [])
443
+
444
+ print("🟢 [GridRenderLayer] Geometry updated: \(vertices.count/4) vertices, \(indices.count/3) triangles")
445
+ print(" vertexBuffer: \(self.vertexBuffer != nil)")
446
+ print(" indexBuffer: \(self.indexBuffer != nil)")
447
+ print(" indexCount: \(self.indexCount)")
448
+
449
+ // TRIGGER A REPAINT - ADD THIS:
450
+ NotificationCenter.default.post(name: NSNotification.Name("TriggerMapRepaint"), object: nil)
451
+ }
452
+ }
453
+ }
454
+
455
+ private func decompressZstd(data: Data) -> Data? {
456
+ let decompressedSize = data.withUnsafeBytes { ptr in
457
+ ZSTD_getFrameContentSize(ptr.baseAddress, data.count)
458
+ }
459
+
460
+ guard Int64(bitPattern: decompressedSize) > 0 else {
461
+ print("❌ [GridRenderLayer] Could not determine decompressed size")
462
+ return nil
463
+ }
464
+
465
+ var decompressedData = Data(count: Int(decompressedSize))
466
+
467
+ let result = decompressedData.withUnsafeMutableBytes { decompressedPtr -> Int in
468
+ data.withUnsafeBytes { compressedPtr -> Int in
469
+ let returnValue = ZSTD_decompress(
470
+ decompressedPtr.baseAddress,
471
+ Int(decompressedSize),
472
+ compressedPtr.baseAddress,
473
+ data.count
474
+ )
475
+ return Int(returnValue)
476
+ }
477
+ }
478
+
479
+ guard result > 0 && result == decompressedData.count else {
480
+ if result > 0 {
481
+ let size_t_result = size_t(result)
482
+ if let errorName = ZSTD_getErrorName(size_t_result) {
483
+ let errorString = String(cString: errorName)
484
+ print("❌ [GridRenderLayer] Zstd decompression failed: \(errorString)")
485
+ }
486
+ }
487
+ return nil
488
+ }
489
+ return decompressedData
490
+ }
491
+
492
+ // MARK: - Private Helper Methods
493
+
494
+ private func reconstructData(decompressedDeltas: Data) -> Data {
495
+ guard !decompressedDeltas.isEmpty else { return Data() }
496
+ var reconstructedData = Data(count: decompressedDeltas.count)
497
+ reconstructedData[0] = decompressedDeltas[0]
498
+ for i in 1..<decompressedDeltas.count {
499
+ reconstructedData[i] = UInt8(Int8(bitPattern: reconstructedData[i-1]) &+ Int8(bitPattern: decompressedDeltas[i]))
500
+ }
501
+ return reconstructedData
502
+ }
503
+
504
+ private func transformData(finalData: Data) -> Data {
505
+ var transformedData = Data(count: finalData.count)
506
+ for i in 0..<finalData.count {
507
+ transformedData[i] = UInt8(Int16(Int8(bitPattern: finalData[i])) + 128)
508
+ }
509
+ return transformedData
510
+ }
511
+
512
+ private func isLCCType(gridDef: [String: Any]) -> Bool {
513
+ if let type = gridDef["type"] as? String {
514
+ return type == "lambert_conformal_conic"
515
+ }
516
+ return false
517
+ }
518
+
519
+ private func generateLCCGeometry(gridDef: [String: Any], vertices: inout [Float], indices: inout [UInt16]) {
520
+ guard let gridParams = gridDef["grid_params"] as? [String: Any],
521
+ let projParams = gridDef["proj_params"] as? [String: Any],
522
+ let nx = gridParams["nx"] as? Int,
523
+ let ny = gridParams["ny"] as? Int,
524
+ let dx = gridParams["dx"] as? Double,
525
+ let dy = gridParams["dy"] as? Double,
526
+ let x_origin = gridParams["x_origin"] as? Double,
527
+ let y_origin = gridParams["y_origin"] as? Double else {
528
+ return
529
+ }
530
+
531
+ let subdivisions = 60
532
+ let TILE_SIZE: Double = 512.0
533
+
534
+ let x_min = x_origin
535
+ let y_max = y_origin
536
+ let x_max = x_origin + Double(nx - 1) * dx
537
+ let y_min = y_origin + Double(ny - 1) * dy
538
+
539
+ var vertexGrid: [[VertexInfo?]] = Array(repeating: Array(repeating: nil, count: subdivisions + 1), count: subdivisions + 1)
540
+ var validVertexCount: UInt16 = 0
541
+
542
+ // Generate vertices
543
+ for row in 0...subdivisions {
544
+ for col in 0...subdivisions {
545
+ let t_x = Double(col) / Double(subdivisions)
546
+ let t_y = Double(row) / Double(subdivisions)
547
+
548
+ let proj_x = x_min + t_x * (x_max - x_min)
549
+ let proj_y = y_max + t_y * (y_min - y_max)
550
+
551
+ // Convert LCC projection coordinates to lat/lon
552
+ if let (lon, lat) = lccToLonLat(i: proj_x, j: proj_y, gridDef: gridDef) {
553
+ // Convert lat/lon to Mercator
554
+ let mercX_normalized = (lon + 180.0) / 360.0
555
+ let clampedLat = max(-85.05112878, min(85.05112878, lat))
556
+ let sinLatitude = sin(clampedLat * .pi / 180.0)
557
+ let mercY_normalized = 0.5 - log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * .pi)
558
+
559
+ let mercX = mercX_normalized * TILE_SIZE
560
+ let mercY = mercY_normalized * TILE_SIZE
561
+
562
+ // Check for invalid values
563
+ if !mercX.isFinite || !mercY.isFinite {
564
+ vertexGrid[row][col] = nil
565
+ continue
566
+ }
567
+
568
+ let tex_u = Float(t_x)
569
+ let tex_v = Float(t_y)
570
+
571
+ let vInfo = VertexInfo(
572
+ mercX: Float(mercX),
573
+ mercY: Float(mercY),
574
+ texU: tex_u,
575
+ texV: tex_v,
576
+ index: validVertexCount
577
+ )
578
+
579
+ vertexGrid[row][col] = vInfo
580
+
581
+ vertices.append(Float(mercX))
582
+ vertices.append(Float(mercY))
583
+ vertices.append(tex_u)
584
+ vertices.append(tex_v)
585
+
586
+ validVertexCount += 1
587
+ } else {
588
+ vertexGrid[row][col] = nil
589
+ }
590
+ }
591
+ }
592
+
593
+ if vertices.isEmpty {
594
+ print("❌ [LCC Geometry] No valid vertices generated")
595
+ return
596
+ }
597
+
598
+ // Generate indices
599
+ for row in 0..<subdivisions {
600
+ for col in 0..<subdivisions {
601
+ guard let topLeft = vertexGrid[row][col],
602
+ let topRight = vertexGrid[row][col + 1],
603
+ let bottomLeft = vertexGrid[row + 1][col],
604
+ let bottomRight = vertexGrid[row + 1][col + 1] else {
605
+ continue
606
+ }
607
+
608
+ indices.append(topLeft.index)
609
+ indices.append(bottomLeft.index)
610
+ indices.append(topRight.index)
611
+
612
+ indices.append(topRight.index)
613
+ indices.append(bottomLeft.index)
614
+ indices.append(bottomRight.index)
615
+ }
616
+ }
617
+ }
618
+
619
+ private func lccToLonLat(i: Double, j: Double, gridDef: [String: Any]) -> (lon: Double, lat: Double)? {
620
+ guard let projParams = gridDef["proj_params"] as? [String: Any],
621
+ let lat_0 = projParams["lat_0"] as? Double, // latitude of origin
622
+ let lon_0 = projParams["lon_0"] as? Double, // longitude of origin
623
+ let lat_1 = projParams["lat_1"] as? Double, // first standard parallel
624
+ let lat_2 = projParams["lat_2"] as? Double, // second standard parallel (HRRR uses two!)
625
+ let r_earth = projParams["R"] as? Double else {
626
+ print("❌ [LCC Geometry] Failed to extract LCC parameters.")
627
+ return nil
628
+ }
629
+
630
+ let π = Double.pi
631
+ let toRad = π / 180.0
632
+ let toDeg = 180.0 / π
633
+
634
+ let lat1_rad = lat_1 * toRad
635
+ let lat2_rad = lat_2 * toRad
636
+ let lat0_rad = lat_0 * toRad
637
+ let lon0_rad = lon_0 * toRad
638
+
639
+ // Calculate cone constant (n) using two standard parallels
640
+ let n: Double
641
+ if abs(lat_1 - lat_2) < 1e-10 {
642
+ n = sin(lat1_rad) // Single parallel case
643
+ } else {
644
+ n = log(cos(lat1_rad) / cos(lat2_rad)) / log(tan(π/4.0 + lat2_rad/2.0) / tan(π/4.0 + lat1_rad/2.0))
645
+ }
646
+
647
+ let F = cos(lat1_rad) * pow(tan(π/4.0 + lat1_rad/2.0), n) / n
648
+ let rho_0 = r_earth * F * pow(tan(π/4.0 + lat0_rad/2.0), -n)
649
+
650
+ // i, j are the x, y projection coordinates
651
+ let x = i
652
+ let y = j
653
+
654
+ let rho = sqrt(x * x + (rho_0 - y) * (rho_0 - y))
655
+ if rho < 1e-10 {
656
+ return (lon: lon_0, lat: lat_0)
657
+ }
658
+
659
+ let theta = atan2(x, rho_0 - y)
660
+
661
+ let lon = lon0_rad + theta / n
662
+ let lat = 2.0 * atan(pow(r_earth * F / rho, 1.0 / n)) - π/2.0
663
+
664
+ let lonDeg = lon * toDeg
665
+ let latDeg = lat * toDeg
666
+
667
+ if !lonDeg.isFinite || !latDeg.isFinite {
668
+ return nil
669
+ }
670
+
671
+ return (lon: lonDeg, lat: latDeg)
672
+ }
673
+
674
+ private func generateGeometryData(gridDef: [String: Any], vertices: inout [Float], indices: inout [UInt16]) {
675
+ guard let gridParams = gridDef["grid_params"] as? [String: Any] else {
676
+ return
677
+ }
678
+
679
+ // GFS Global Grid Path
680
+ if isGFSType(gridParams: gridParams) {
681
+ let subdivisions = 120
682
+ let verticesPerRow = (subdivisions * 3) + 1
683
+ let TILE_SIZE: Double = 512.0
684
+
685
+ for row in 0...subdivisions {
686
+ for col in 0...(subdivisions * 3) {
687
+ let v_interp = Float(row) / Float(subdivisions)
688
+ let u_interp = Float(col) / Float(subdivisions)
689
+ let lon = -540.0 + Double(u_interp) * 1080.0
690
+ let lat = -90.0 + Double(v_interp) * 180.0
691
+
692
+ let merc = lonLatToMercator(lon: lon, lat: lat, tileSize: TILE_SIZE)
693
+ vertices.append(contentsOf: [merc.x, merc.y])
694
+
695
+ let tex_u = Float((lon + 180.0) / 360.0)
696
+ let tex_v = 1.0 - v_interp
697
+ vertices.append(contentsOf: [tex_u, tex_v])
698
+ }
699
+ }
700
+
701
+ for row in 0..<subdivisions {
702
+ for col in 0..<(subdivisions * 3) {
703
+ let tl = UInt16(row * verticesPerRow + col)
704
+ let tr = tl + 1
705
+ let bl = UInt16((row + 1) * verticesPerRow + col)
706
+ let br = bl + 1
707
+ indices.append(contentsOf: [tl, bl, tr, tr, bl, br])
708
+ }
709
+ }
710
+ return
711
+ }
712
+ if isLCCType(gridDef: gridDef) {
713
+ generateLCCGeometry(gridDef: gridDef, vertices: &vertices, indices: &indices)
714
+ return
715
+ }
716
+
717
+ // Generic Grid Path (MRMS, etc.)
718
+ let nx = gridParams["nx"] as? Int ?? 0
719
+ let ny = gridParams["ny"] as? Int ?? 0
720
+ let lon_first = gridParams["lon_first"] as? Double ?? 0.0
721
+ let lat_first = gridParams["lat_first"] as? Double ?? 90.0
722
+ let dx = gridParams["dx_degrees"] as? Double ?? 0.0
723
+ let dy = gridParams["dy_degrees"] as? Double ?? 0.0
724
+ let lon_last = gridParams["lon_last"] as? Double ?? (lon_first + Double(nx - 1) * dx)
725
+ let lat_last = gridParams["lat_last"] as? Double ?? (lat_first + Double(ny - 1) * dy)
726
+ let lat_span = lat_last - lat_first
727
+ let isSouthToNorth = lat_span > 0
728
+
729
+ let data_lon_first_180 = lon_first > 180 ? lon_first - 360 : lon_first
730
+ let data_lon_last_180 = lon_last > 180 ? lon_last - 360 : lon_last
731
+ let data_lon_range = data_lon_last_180 - data_lon_first_180
732
+
733
+ let subdivisions_x = 120
734
+ let subdivisions_y = 60
735
+ let verticesPerRow = subdivisions_x + 1
736
+ let TILE_SIZE: Double = 512.0
737
+
738
+ // 🔑 FIX: Only create ONE world copy for regional data, THREE for global data
739
+ let worldCopies = (data_lon_range > 300) ? [-1, 0, 1] : [0] // Only wrap if nearly global
740
+
741
+ for world_copy in worldCopies {
742
+ let vertexStartIndex = UInt16(vertices.count / 4)
743
+ let lon_offset = Double(world_copy) * 360.0
744
+
745
+ // Generate vertices for this world copy
746
+ for row in 0...subdivisions_y {
747
+ for col in 0...subdivisions_x {
748
+ let v_interp = Float(row) / Float(subdivisions_y)
749
+ let u_interp = Float(col) / Float(subdivisions_x)
750
+
751
+ let vertex_lon = data_lon_first_180 + (Double(u_interp) * data_lon_range)
752
+ let vertex_lat = lat_first + (Double(v_interp) * lat_span)
753
+
754
+ let mercX_normalized = ((vertex_lon + lon_offset) + 180.0) / 360.0
755
+ let clampedLat = max(-85.05112878, min(85.05112878, vertex_lat))
756
+ let sinLatitude = sin(clampedLat * .pi / 180.0)
757
+ let mercY_normalized = 0.5 - log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * .pi)
758
+ let mercX = mercX_normalized * TILE_SIZE
759
+ let mercY = mercY_normalized * TILE_SIZE
760
+
761
+ vertices.append(contentsOf: [Float(mercX), Float(mercY)])
762
+
763
+ let tex_u = u_interp
764
+ let tex_v = isSouthToNorth ? (1.0 - v_interp) : v_interp
765
+
766
+ vertices.append(contentsOf: [tex_u, tex_v])
767
+ }
768
+ }
769
+
770
+ // Generate indices (same as before)
771
+ for row in 0..<UInt16(subdivisions_y) {
772
+ for col in 0..<UInt16(subdivisions_x) {
773
+ let tl = vertexStartIndex + row * UInt16(verticesPerRow) + col
774
+ let tr = tl + 1
775
+ let bl = vertexStartIndex + (row + 1) * UInt16(verticesPerRow) + col
776
+ let br = bl + 1
777
+
778
+ if isSouthToNorth {
779
+ indices.append(contentsOf: [tl, bl, tr, tr, bl, br])
780
+ } else {
781
+ indices.append(contentsOf: [tl, tr, bl, bl, tr, br])
782
+ }
783
+ }
784
+ }
785
+ }
786
+ }
787
+
788
+ private func isGFSType(gridParams: [String: Any]) -> Bool {
789
+ return (gridParams["lon_first"] as? Double) == 0.0 &&
790
+ abs((gridParams["lat_first"] as? Double) ?? -1) == 90.0
791
+ }
792
+
793
+ private func lonLatToMercator(lon: Double, lat: Double, tileSize: Double) -> (x: Float, y: Float) {
794
+ let mercX_normalized = (lon + 180.0) / 360.0
795
+ let clampedLat = max(-85.05112878, min(85.05112878, lat))
796
+ let sinLatitude = sin(clampedLat * .pi / 180.0)
797
+ let mercY_normalized = 0.5 - log((1.0 + sinLatitude) / (1.0 - sinLatitude)) / (4.0 * .pi)
798
+
799
+ return (x: Float(mercX_normalized * tileSize), y: Float(mercY_normalized * tileSize))
800
+ }
801
+
802
+ // MARK: - Internal methods for CustomLayerHost (called by wrapper)
803
+
804
+ internal func internalRenderingWillStart(_ metalDevice: MTLDevice, colorPixelFormat: UInt, depthStencilPixelFormat: UInt) {
805
+ print("🟢 [GridRenderLayer] renderingWillStart called")
806
+ self.device = metalDevice
807
+ self.commandQueue = metalDevice.makeCommandQueue()
808
+
809
+ let bundle = Bundle(for: GridRenderLayer.self)
810
+
811
+ // Determine if we're running on simulator or device
812
+ #if targetEnvironment(simulator)
813
+ let metallibName = "Shaders-simulator"
814
+ #else
815
+ let metallibName = "Shaders-device"
816
+ #endif
817
+
818
+ // Try to load pre-compiled metallib for the current platform
819
+ let defaultLibrary: MTLLibrary?
820
+ if let metallibUrl = bundle.url(forResource: metallibName, withExtension: "metallib"),
821
+ let library = try? metalDevice.makeLibrary(URL: metallibUrl) {
822
+ print("✅ [GridRenderLayer] Loaded pre-compiled metallib (\(metallibName))")
823
+ defaultLibrary = library
824
+ }
825
+ // Fall back to compiling from .metal source (for development with npm link)
826
+ else if let metalUrl = bundle.url(forResource: "Shaders", withExtension: "metal"),
827
+ let source = try? String(contentsOf: metalUrl),
828
+ let library = try? metalDevice.makeLibrary(source: source, options: nil) {
829
+ print("✅ [GridRenderLayer] Compiled Metal shader from source")
830
+ defaultLibrary = library
831
+ }
832
+ // Neither worked
833
+ else {
834
+ print("❌ [GridRenderLayer] Could not find or compile Metal shaders")
835
+ print(" Bundle path: \(bundle.bundlePath)")
836
+ return
837
+ }
838
+
839
+ guard let library = defaultLibrary else {
840
+ print("❌ [GridRenderLayer] Failed to create Metal library")
841
+ return
842
+ }
843
+
844
+ let vertexFunction = library.makeFunction(name: "vertex_main")
845
+ let fragmentFunction = library.makeFunction(name: "fragment_main")
846
+
847
+ // Set up vertex descriptor
848
+ let vertexDescriptor = MTLVertexDescriptor()
849
+ vertexDescriptor.attributes[0].format = .float2 // position (x, y)
850
+ vertexDescriptor.attributes[0].offset = 0
851
+ vertexDescriptor.attributes[0].bufferIndex = 0
852
+
853
+ vertexDescriptor.attributes[1].format = .float2 // texCoord (u, v)
854
+ vertexDescriptor.attributes[1].offset = MemoryLayout<Float>.size * 2
855
+ vertexDescriptor.attributes[1].bufferIndex = 0
856
+
857
+ vertexDescriptor.layouts[0].stride = MemoryLayout<Float>.size * 4 // 2 floats for pos + 2 for texCoord
858
+ vertexDescriptor.layouts[0].stepFunction = .perVertex
859
+
860
+ let pipelineDescriptor = MTLRenderPipelineDescriptor()
861
+ pipelineDescriptor.vertexDescriptor = vertexDescriptor
862
+ pipelineDescriptor.vertexFunction = vertexFunction
863
+ pipelineDescriptor.fragmentFunction = fragmentFunction
864
+
865
+ pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat(rawValue: colorPixelFormat) ?? .bgra8Unorm
866
+ pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
867
+ pipelineDescriptor.stencilAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
868
+
869
+ pipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
870
+ pipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
871
+ pipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
872
+ pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
873
+ pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
874
+ pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
875
+ pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
876
+
877
+ do {
878
+ self.pipelineState = try metalDevice.makeRenderPipelineState(descriptor: pipelineDescriptor)
879
+ } catch {
880
+ print("❌ [GridRenderLayer] Failed to create pipeline state: \(error)")
881
+ return
882
+ }
883
+
884
+ let dataSamplerDesc = MTLSamplerDescriptor()
885
+ dataSamplerDesc.minFilter = .nearest
886
+ dataSamplerDesc.magFilter = .nearest
887
+ self.dataSamplerState = metalDevice.makeSamplerState(descriptor: dataSamplerDesc)
888
+
889
+ let colormapSamplerDesc = MTLSamplerDescriptor()
890
+ colormapSamplerDesc.minFilter = .nearest
891
+ colormapSamplerDesc.magFilter = .nearest
892
+ colormapSamplerDesc.sAddressMode = .clampToEdge
893
+ self.colormapSamplerState = metalDevice.makeSamplerState(descriptor: colormapSamplerDesc)
894
+
895
+ print("🟢 [GridRenderLayer] Metal setup complete")
896
+
897
+ // Process any pending updates that came in before Metal was ready
898
+ if let pendingGeometry = pendingGeometryUpdate {
899
+ print("🟡 [GridRenderLayer] Processing pending geometry update")
900
+ updateGeometry(corners: pendingGeometry.corners, gridDef: pendingGeometry.gridDef)
901
+ pendingGeometryUpdate = nil
902
+ }
903
+
904
+ if let pendingColormap = pendingColormapUpdate {
905
+ print("🟡 [GridRenderLayer] Processing pending colormap update")
906
+ updateColormapTexture(colormapAsBase64: pendingColormap)
907
+ pendingColormapUpdate = nil
908
+ }
909
+
910
+ if let pendingData = pendingDataUpdate {
911
+ print("🟡 [GridRenderLayer] Processing pending data update")
912
+ updateDataTexture(data: pendingData.data, nx: pendingData.nx, ny: pendingData.ny,
913
+ scale: pendingData.scale, offset: pendingData.offset,
914
+ missing: pendingData.missing, scaleType: pendingData.scaleType)
915
+ pendingDataUpdate = nil
916
+ }
917
+ }
918
+ internal func internalRender(_ parameters: CustomLayerRenderParameters, mtlCommandBuffer: MTLCommandBuffer, mtlRenderPassDescriptor: MTLRenderPassDescriptor) {
919
+ guard isVisible,
920
+ let pipeline = pipelineState,
921
+ let vertices = vertexBuffer,
922
+ let indices = indexBuffer,
923
+ let dataTex = dataTexture,
924
+ let colormapTex = colormapTexture,
925
+ indexCount > 0,
926
+ let encoder = mtlCommandBuffer.makeRenderCommandEncoder(descriptor: mtlRenderPassDescriptor) else {
927
+
928
+ // OPTIMIZATION: Change log message to be more informative and less alarming.
929
+ // This is an expected state during initial load.
930
+ if (pipelineState != nil) { // Only log if Metal is set up
931
+ print("🟡 [GridRenderLayer] internalRender: Waiting for all resources to be ready before drawing.")
932
+ }
933
+ return
934
+ }
935
+
936
+ print("✅ [GridRenderLayer] Past guards, about to render!")
937
+ print(" 🎨 About to draw \(indexCount) indices (\(indexCount/3) triangles)")
938
+
939
+ let needsLinear = (uniforms.smoothing != 0)
940
+ if isDataSamplerLinear != needsLinear {
941
+ let samplerDesc = MTLSamplerDescriptor()
942
+ samplerDesc.minFilter = needsLinear ? .linear : .nearest
943
+ samplerDesc.magFilter = needsLinear ? .linear : .nearest
944
+ dataSamplerState = device.makeSamplerState(descriptor: samplerDesc)
945
+ isDataSamplerLinear = needsLinear
946
+ }
947
+
948
+ // Apply zoom scale transformation
949
+ let zoom = parameters.zoom
950
+ let scale = Float(pow(2.0, zoom))
951
+
952
+ let matrixArray = parameters.projectionMatrix
953
+ var floatArray = matrixArray.map { $0.floatValue }
954
+
955
+ floatArray[0] *= scale // X scale
956
+ floatArray[1] *= scale // X rotation
957
+ floatArray[4] *= scale // Y rotation
958
+ floatArray[5] *= scale
959
+
960
+ let mvp = matrix_float4x4(
961
+ SIMD4<Float>(floatArray[0], floatArray[1], floatArray[2], floatArray[3]),
962
+ SIMD4<Float>(floatArray[4], floatArray[5], floatArray[6], floatArray[7]),
963
+ SIMD4<Float>(floatArray[8], floatArray[9], floatArray[10], floatArray[11]),
964
+ SIMD4<Float>(floatArray[12], floatArray[13], floatArray[14], floatArray[15])
965
+ )
966
+
967
+ print(" 📐 MVP matrix after scaling: \(mvp)")
968
+ print(" 📍 Zoom: \(zoom), Scale factor: \(scale)")
969
+
970
+ // Add depth state
971
+ let depthStencilDescriptor = MTLDepthStencilDescriptor()
972
+ depthStencilDescriptor.depthCompareFunction = .always
973
+ depthStencilDescriptor.isDepthWriteEnabled = false
974
+ let depthStencilState = device.makeDepthStencilState(descriptor: depthStencilDescriptor)
975
+
976
+ encoder.setRenderPipelineState(pipeline)
977
+ encoder.setDepthStencilState(depthStencilState!)
978
+ encoder.setVertexBuffer(vertices, offset: 0, index: 0)
979
+ encoder.setVertexBytes([mvp], length: MemoryLayout<matrix_float4x4>.size, index: 1)
980
+
981
+ var mutableUniforms = uniforms
982
+ encoder.setFragmentBytes(&mutableUniforms, length: MemoryLayout<FragmentUniforms>.stride, index: 0)
983
+ encoder.setFragmentTexture(dataTex, index: 0)
984
+ encoder.setFragmentTexture(colormapTex, index: 1)
985
+ encoder.setFragmentSamplerState(dataSamplerState, index: 0)
986
+ encoder.setFragmentSamplerState(colormapSamplerState, index: 1)
987
+
988
+ print(" 🎨 Drawing indexed primitives now...")
989
+ encoder.drawIndexedPrimitives(type: .triangle, indexCount: indexCount, indexType: .uint16, indexBuffer: indices, indexBufferOffset: 0)
990
+ print(" ✅ Draw call completed")
991
+
992
+ encoder.endEncoding()
993
+ print(" ✅ Encoder ended")
994
+ }
995
+
996
+ internal func internalRenderingWillEnd() {
997
+ print("🟢 [GridRenderLayer] renderingWillEnd called")
998
+ vertexBuffer = nil
999
+ indexBuffer = nil
1000
+ dataTexture = nil
1001
+ colormapTexture = nil
1002
+ }
1003
+ }