react-native-cesium 1.0.1

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 (129) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +12 -0
  3. package/README.md +308 -0
  4. package/ReactNativeCesium.podspec +54 -0
  5. package/android/CMakeLists.txt +146 -0
  6. package/android/build.gradle +178 -0
  7. package/android/fix-prefab.gradle +51 -0
  8. package/android/gradle.properties +5 -0
  9. package/android/src/main/AndroidManifest.xml +5 -0
  10. package/android/src/main/assets/cacert.pem +3529 -0
  11. package/android/src/main/cpp/CesiumBridgeAndroid.cpp +487 -0
  12. package/android/src/main/cpp/CesiumBridgeAndroid.h +94 -0
  13. package/android/src/main/cpp/cpp-adapter.cpp +17 -0
  14. package/android/src/main/cpp/vulkan/VulkanBackend.cpp +1781 -0
  15. package/android/src/main/cpp/vulkan/VulkanBackend.h +190 -0
  16. package/android/src/main/cpp/vulkan/shaders/sky.frag +86 -0
  17. package/android/src/main/cpp/vulkan/shaders/sky.vert +9 -0
  18. package/android/src/main/cpp/vulkan/shaders/terrain.frag +144 -0
  19. package/android/src/main/cpp/vulkan/shaders/terrain.vert +25 -0
  20. package/android/src/main/java/com/margelo/nitro/reactnativecesium/CesiumBridgeJNI.kt +84 -0
  21. package/android/src/main/java/com/margelo/nitro/reactnativecesium/HybridCesiumView.kt +225 -0
  22. package/android/src/main/java/com/reactnativecesium/ReactNativeCesiumPackage.kt +28 -0
  23. package/cpp/engine/CesiumEngine.cpp +413 -0
  24. package/cpp/engine/CesiumEngine.hpp +90 -0
  25. package/cpp/engine/DeletionQueue.cpp +28 -0
  26. package/cpp/engine/DeletionQueue.hpp +28 -0
  27. package/cpp/engine/GlobeCamera.cpp +181 -0
  28. package/cpp/engine/GlobeCamera.hpp +64 -0
  29. package/cpp/engine/GltfToMesh.cpp +154 -0
  30. package/cpp/engine/GltfToMesh.hpp +20 -0
  31. package/cpp/engine/ResourcePreparer.cpp +224 -0
  32. package/cpp/engine/ResourcePreparer.hpp +96 -0
  33. package/cpp/engine/TaskProcessor.cpp +61 -0
  34. package/cpp/engine/TaskProcessor.hpp +43 -0
  35. package/cpp/engine/TileLifecycleManager.cpp +30 -0
  36. package/cpp/engine/TileLifecycleManager.hpp +25 -0
  37. package/cpp/fmt/format.h +9 -0
  38. package/cpp/renderer/IGPUBackend.hpp +22 -0
  39. package/cpp/renderer/RenderTypes.hpp +112 -0
  40. package/cpp/renderer/ShaderTypes.hpp +29 -0
  41. package/example/README.md +43 -0
  42. package/example/react-native-cesium-example.jpg +0 -0
  43. package/ios/CesiumBridge.h +55 -0
  44. package/ios/CesiumBridge.mm +393 -0
  45. package/ios/HybridCesiumView.swift +299 -0
  46. package/ios/ReactNativeCesium-umbrella.h +16 -0
  47. package/ios/metal/MetalBackend.h +82 -0
  48. package/ios/metal/MetalBackend.mm +839 -0
  49. package/ios/react_native_cesium_ensure_native.rb +12 -0
  50. package/ios/react_native_cesium_post_install.rb +30 -0
  51. package/lib/commonjs/CesiumView.js +13 -0
  52. package/lib/commonjs/CesiumView.js.map +1 -0
  53. package/lib/commonjs/index.js +13 -0
  54. package/lib/commonjs/index.js.map +1 -0
  55. package/lib/commonjs/package.json +1 -0
  56. package/lib/commonjs/specs/cesium-view.nitro.js +6 -0
  57. package/lib/commonjs/specs/cesium-view.nitro.js.map +1 -0
  58. package/lib/module/CesiumView.js +9 -0
  59. package/lib/module/CesiumView.js.map +1 -0
  60. package/lib/module/index.js +4 -0
  61. package/lib/module/index.js.map +1 -0
  62. package/lib/module/specs/cesium-view.nitro.js +4 -0
  63. package/lib/module/specs/cesium-view.nitro.js.map +1 -0
  64. package/lib/typescript/src/CesiumView.d.ts +5 -0
  65. package/lib/typescript/src/CesiumView.d.ts.map +1 -0
  66. package/lib/typescript/src/index.d.ts +3 -0
  67. package/lib/typescript/src/index.d.ts.map +1 -0
  68. package/lib/typescript/src/specs/cesium-view.nitro.d.ts +43 -0
  69. package/lib/typescript/src/specs/cesium-view.nitro.d.ts.map +1 -0
  70. package/nitro.json +30 -0
  71. package/nitrogen/generated/.gitattributes +1 -0
  72. package/nitrogen/generated/android/ReactNativeCesium+autolinking.cmake +83 -0
  73. package/nitrogen/generated/android/ReactNativeCesium+autolinking.gradle +27 -0
  74. package/nitrogen/generated/android/ReactNativeCesiumOnLoad.cpp +58 -0
  75. package/nitrogen/generated/android/ReactNativeCesiumOnLoad.hpp +34 -0
  76. package/nitrogen/generated/android/c++/JCameraState.hpp +81 -0
  77. package/nitrogen/generated/android/c++/JCesiumMetrics.hpp +81 -0
  78. package/nitrogen/generated/android/c++/JFunc_void_CesiumMetrics.hpp +78 -0
  79. package/nitrogen/generated/android/c++/JHybridCesiumViewSpec.cpp +178 -0
  80. package/nitrogen/generated/android/c++/JHybridCesiumViewSpec.hpp +83 -0
  81. package/nitrogen/generated/android/c++/views/JHybridCesiumViewStateUpdater.cpp +92 -0
  82. package/nitrogen/generated/android/c++/views/JHybridCesiumViewStateUpdater.hpp +49 -0
  83. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/CameraState.kt +56 -0
  84. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/CesiumMetrics.kt +56 -0
  85. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/Func_void_CesiumMetrics.kt +80 -0
  86. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/HybridCesiumViewSpec.kt +126 -0
  87. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/ReactNativeCesiumOnLoad.kt +35 -0
  88. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/views/HybridCesiumViewManager.kt +80 -0
  89. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/views/HybridCesiumViewStateUpdater.kt +23 -0
  90. package/nitrogen/generated/ios/ReactNativeCesium+autolinking.rb +60 -0
  91. package/nitrogen/generated/ios/ReactNativeCesium-Swift-Cxx-Bridge.cpp +57 -0
  92. package/nitrogen/generated/ios/ReactNativeCesium-Swift-Cxx-Bridge.hpp +164 -0
  93. package/nitrogen/generated/ios/ReactNativeCesium-Swift-Cxx-Umbrella.hpp +53 -0
  94. package/nitrogen/generated/ios/ReactNativeCesiumAutolinking.mm +33 -0
  95. package/nitrogen/generated/ios/ReactNativeCesiumAutolinking.swift +26 -0
  96. package/nitrogen/generated/ios/c++/HybridCesiumViewSpecSwift.cpp +11 -0
  97. package/nitrogen/generated/ios/c++/HybridCesiumViewSpecSwift.hpp +157 -0
  98. package/nitrogen/generated/ios/c++/views/HybridCesiumViewComponent.mm +167 -0
  99. package/nitrogen/generated/ios/swift/CameraState.swift +59 -0
  100. package/nitrogen/generated/ios/swift/CesiumMetrics.swift +59 -0
  101. package/nitrogen/generated/ios/swift/Func_void_CameraState.swift +46 -0
  102. package/nitrogen/generated/ios/swift/Func_void_CesiumMetrics.swift +46 -0
  103. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
  104. package/nitrogen/generated/ios/swift/HybridCesiumViewSpec.swift +65 -0
  105. package/nitrogen/generated/ios/swift/HybridCesiumViewSpec_cxx.swift +306 -0
  106. package/nitrogen/generated/shared/c++/CameraState.hpp +107 -0
  107. package/nitrogen/generated/shared/c++/CesiumMetrics.hpp +107 -0
  108. package/nitrogen/generated/shared/c++/HybridCesiumViewSpec.cpp +42 -0
  109. package/nitrogen/generated/shared/c++/HybridCesiumViewSpec.hpp +90 -0
  110. package/nitrogen/generated/shared/c++/views/HybridCesiumViewComponent.cpp +182 -0
  111. package/nitrogen/generated/shared/c++/views/HybridCesiumViewComponent.hpp +122 -0
  112. package/nitrogen/generated/shared/json/CesiumViewConfig.json +19 -0
  113. package/package.json +140 -0
  114. package/react-native.config.js +16 -0
  115. package/scripts/cesium/build.mjs +901 -0
  116. package/scripts/cesium/clean.mjs +35 -0
  117. package/scripts/cesium/clone.mjs +32 -0
  118. package/scripts/cesium/ensure-native.mjs +116 -0
  119. package/scripts/cesium/vcpkg-ports/zstd/fix-emscripten-and-clang-cl.patch +31 -0
  120. package/scripts/cesium/vcpkg-ports/zstd/fix-windows-rc-compile.patch +13 -0
  121. package/scripts/cesium/vcpkg-ports/zstd/no-static-suffix.patch +13 -0
  122. package/scripts/cesium/vcpkg-ports/zstd/portfile.cmake +77 -0
  123. package/scripts/cesium/vcpkg-ports/zstd/usage +4 -0
  124. package/scripts/cesium/vcpkg-ports/zstd/vcpkg.json +23 -0
  125. package/scripts/cesium/vcpkg-triplets/arm64-ios-simulator.cmake +10 -0
  126. package/scripts/cesium/vcpkg-triplets/arm64-ios.cmake +14 -0
  127. package/src/CesiumView.tsx +13 -0
  128. package/src/index.ts +7 -0
  129. package/src/specs/cesium-view.nitro.ts +51 -0
@@ -0,0 +1,190 @@
1
+ #pragma once
2
+
3
+ #include "renderer/IGPUBackend.hpp"
4
+
5
+ #define VK_USE_PLATFORM_ANDROID_KHR
6
+ #include <vulkan/vulkan.h>
7
+
8
+ #include <cstddef>
9
+ #include <cstdint>
10
+ #include <deque>
11
+ #include <mutex>
12
+ #include <vector>
13
+
14
+ namespace reactnativecesium {
15
+
16
+ struct VulkanTexture {
17
+ VkImage image = VK_NULL_HANDLE;
18
+ VkDeviceMemory memory = VK_NULL_HANDLE;
19
+ VkImageView imageView = VK_NULL_HANDLE;
20
+ VkSampler sampler = VK_NULL_HANDLE;
21
+ VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
22
+ };
23
+
24
+ class VulkanBackend : public IGPUBackend {
25
+ public:
26
+ VulkanBackend();
27
+ ~VulkanBackend() override;
28
+
29
+ void initialize(void* nativeSurface, int width, int height) override;
30
+ void resize(int width, int height) override;
31
+ void shutdown() override;
32
+
33
+ void beginFrame(const FrameParams& params) override;
34
+ void drawScene(const FrameResult& frame) override;
35
+ void endFrame() override;
36
+
37
+ void* createRasterTexture(const uint8_t* pixels, int32_t width, int32_t height);
38
+ void freeRasterTexture(void* tex);
39
+
40
+ // Water mask textures — same pixel format but allocated from a separate pool
41
+ // so they can be bound at descriptor set 2 (vs imagery at set 1).
42
+ void* createWaterMaskTexture(const uint8_t* pixels, int32_t width, int32_t height);
43
+ void freeWaterMaskTexture(void* tex);
44
+
45
+ void setMsaaSampleCount(int sampleCount);
46
+
47
+ private:
48
+ void createInstance();
49
+ void pickPhysicalDevice();
50
+ void createDevice();
51
+ void createSwapchain();
52
+ void createRenderPass();
53
+ void createDepthResources();
54
+ void createFramebuffers();
55
+ void createCommandPool();
56
+ void createCommandBuffers();
57
+ void createSyncObjects();
58
+ void createDescriptorSetLayout();
59
+ void createPipelineLayout();
60
+ void createSkyPipeline();
61
+ void createTerrainPipeline();
62
+ void createFallbackTexture();
63
+ void createDescriptorPool();
64
+ void createWaterMaskPool();
65
+ void createWaterMaskFallback();
66
+
67
+ void cleanupSwapchain();
68
+ void recreateSwapchain();
69
+
70
+ VkFormat pickDepthFormat() const;
71
+
72
+ uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags props);
73
+ void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
74
+ VkMemoryPropertyFlags props, VkBuffer& buffer,
75
+ VkDeviceMemory& memory);
76
+ void ensureBuffer(VkBuffer& buffer, VkDeviceMemory& memory, size_t& capacity,
77
+ size_t needed, const void* data, VkBufferUsageFlags usage);
78
+ VkCommandBuffer beginSingleTimeCommands();
79
+ void endSingleTimeCommands(VkCommandBuffer commandBuffer);
80
+
81
+ // Upload pixel data from a staging buffer into image, transitioning layout
82
+ // UNDEFINED → TRANSFER_DST → SHADER_READ_ONLY in a single command buffer.
83
+ void uploadToImage(VkBuffer staging, VkImage image, uint32_t width, uint32_t height);
84
+
85
+ void* window_ = nullptr; // ANativeWindow*
86
+
87
+ VkInstance instance_ = VK_NULL_HANDLE;
88
+ VkPhysicalDevice physicalDevice_ = VK_NULL_HANDLE;
89
+ VkDevice device_ = VK_NULL_HANDLE;
90
+ VkQueue graphicsQueue_ = VK_NULL_HANDLE;
91
+ VkQueue presentQueue_ = VK_NULL_HANDLE;
92
+ uint32_t graphicsFamily_ = 0;
93
+ VkSurfaceKHR surface_ = VK_NULL_HANDLE;
94
+ VkSwapchainKHR swapchain_ = VK_NULL_HANDLE;
95
+ VkFormat swapchainFormat_ = VK_FORMAT_UNDEFINED;
96
+ VkFormat depthFormat_ = VK_FORMAT_D32_SFLOAT;
97
+ VkExtent2D swapchainExtent_ = {0, 0};
98
+ std::vector<VkImage> swapchainImages_;
99
+ std::vector<VkImageView> swapchainImageViews_;
100
+
101
+ VkRenderPass renderPass_ = VK_NULL_HANDLE;
102
+ std::vector<VkFramebuffer> framebuffers_;
103
+
104
+ VkImage depthImage_ = VK_NULL_HANDLE;
105
+ VkDeviceMemory depthMemory_ = VK_NULL_HANDLE;
106
+ VkImageView depthImageView_ = VK_NULL_HANDLE;
107
+
108
+ VkCommandPool commandPool_ = VK_NULL_HANDLE;
109
+ std::vector<VkCommandBuffer> commandBuffers_;
110
+
111
+ VkDescriptorSetLayout terrainDescSetLayout_ = VK_NULL_HANDLE; // set 0: UBO
112
+ VkDescriptorSetLayout terrainTexLayout_ = VK_NULL_HANDLE; // set 1: texture
113
+ VkDescriptorSetLayout skyDescSetLayout_ = VK_NULL_HANDLE;
114
+ VkPipelineLayout terrainPipelineLayout_ = VK_NULL_HANDLE;
115
+ VkPipelineLayout skyPipelineLayout_ = VK_NULL_HANDLE;
116
+ VkPipeline terrainPipeline_ = VK_NULL_HANDLE;
117
+ VkPipeline skyPipeline_ = VK_NULL_HANDLE;
118
+
119
+ VkDescriptorPool descriptorPool_ = VK_NULL_HANDLE;
120
+ VkDescriptorPool waterMaskPool_ = VK_NULL_HANDLE;
121
+
122
+ VulkanTexture fallbackTexture_;
123
+ VkDescriptorSet fallbackTexDescSet_ = VK_NULL_HANDLE;
124
+ VulkanTexture fallbackWaterMaskTex_;
125
+ VkDescriptorSet fallbackWaterMaskDescSet_ = VK_NULL_HANDLE;
126
+
127
+ // Sky UBO — persistently mapped
128
+ VkBuffer skyUboBuffer_ = VK_NULL_HANDLE;
129
+ VkDeviceMemory skyUboMemory_ = VK_NULL_HANDLE;
130
+ void* skyUboMapped_ = nullptr;
131
+ VkDescriptorSet skyDescSet_ = VK_NULL_HANDLE;
132
+
133
+ static constexpr int kMaxFramesInFlight = 3;
134
+ // Upper bound on simultaneously live raster overlay textures.
135
+ // Cesium can cache many hundreds of tiles at high zoom; 2048 gives headroom.
136
+ static constexpr int kMaxRasterTextures = 2048;
137
+
138
+ std::vector<VkSemaphore> imageAvailableSemaphores_;
139
+ std::vector<VkSemaphore> renderFinishedSemaphores_;
140
+ std::vector<VkFence> inFlightFences_;
141
+ int frameIndex_ = 0;
142
+ uint32_t imageIndex_ = 0;
143
+ bool frameBegan_ = false;
144
+
145
+ // Triple-buffered persistent vertex/index/UV/altitude buffers
146
+ VkBuffer vtxBufs_[kMaxFramesInFlight] = {};
147
+ VkDeviceMemory vtxMems_[kMaxFramesInFlight] = {};
148
+ size_t vtxCaps_[kMaxFramesInFlight] = {};
149
+
150
+ VkBuffer idxBufs_[kMaxFramesInFlight] = {};
151
+ VkDeviceMemory idxMems_[kMaxFramesInFlight] = {};
152
+ size_t idxCaps_[kMaxFramesInFlight] = {};
153
+
154
+ VkBuffer uvBufs_[kMaxFramesInFlight] = {};
155
+ VkDeviceMemory uvMems_[kMaxFramesInFlight] = {};
156
+ size_t uvCaps_[kMaxFramesInFlight] = {};
157
+
158
+ VkBuffer altBufs_[kMaxFramesInFlight] = {}; // float altitude per vertex
159
+ VkDeviceMemory altMems_[kMaxFramesInFlight] = {};
160
+ size_t altCaps_[kMaxFramesInFlight] = {};
161
+
162
+ // Per-frame UBO: just cameraEcef (fragment stage, used for lighting vd).
163
+ // MVP is now per-draw via push constants.
164
+ VkBuffer terrainUboBufs_[kMaxFramesInFlight] = {};
165
+ VkDeviceMemory terrainUboMems_[kMaxFramesInFlight] = {};
166
+ void* terrainUboMapped_[kMaxFramesInFlight] = {};
167
+ VkDescriptorSet terrainDescSets_[kMaxFramesInFlight] = {};
168
+
169
+ int viewportWidth_ = 0;
170
+ int viewportHeight_ = 0;
171
+ bool needsSwapchainRecreate_ = false;
172
+
173
+ // Deferred texture deletion — freeRasterTexture enqueues here so no GPU stall
174
+ // on eviction; beginFrame flushes entries old enough to be safe.
175
+ // pool identifies which VkDescriptorPool owns the descriptor set; if
176
+ // VK_NULL_HANDLE the fallback / UBO pool (descriptorPool_) is used.
177
+ struct PendingDelete {
178
+ VulkanTexture* tex;
179
+ uint64_t frameIndex;
180
+ VkDescriptorPool pool = VK_NULL_HANDLE;
181
+ };
182
+ std::deque<PendingDelete> pendingDeletes_;
183
+ std::mutex pendingDeletesMutex_;
184
+ uint64_t totalFrameCount_ = 0;
185
+
186
+ void flushPendingDeletes();
187
+ void destroyTexture(VulkanTexture* tex, VkDescriptorPool pool);
188
+ };
189
+
190
+ } // namespace reactnativecesium
@@ -0,0 +1,86 @@
1
+ #version 450
2
+
3
+ layout(set = 0, binding = 0) uniform SkyUniforms {
4
+ mat4 invVP;
5
+ vec4 cameraEcef;
6
+ vec4 lightDir;
7
+ } u;
8
+
9
+ layout(location = 0) in vec2 ndc;
10
+ layout(location = 0) out vec4 outColor;
11
+
12
+ const float ER = 6371000.0, AR = ER + 111000.0;
13
+ const vec3 RAY = vec3(3.2e-6, 8.5e-6, 38e-6), MIE3 = vec3(1.8e-6, 1.8e-6, 1.8e-6);
14
+ const float MG = 0.76, LINT = 18.0;
15
+
16
+ vec2 rsi(vec3 o, vec3 d, float r) {
17
+ float a = dot(d, d), b = 2.0 * dot(d, o), c = dot(o, o) - r * r, disc = b * b - 4.0 * a * c;
18
+ if (disc < 0.0) return vec2(-1.0);
19
+ float sq = sqrt(disc);
20
+ return vec2((-b - sq) / (2.0 * a), (-b + sq) / (2.0 * a));
21
+ }
22
+
23
+ void main() {
24
+ vec4 wn = u.invVP * vec4(ndc, -1, 1), wf = u.invVP * vec4(ndc, 1, 1);
25
+ vec3 near3 = wn.xyz / wn.w, far3 = wf.xyz / wf.w;
26
+ vec3 rd = normalize(far3 - near3);
27
+ vec3 org = u.cameraEcef.xyz;
28
+
29
+ vec2 at = rsi(org, rd, AR);
30
+ if (at.y < 0.0) { outColor = vec4(0, 0, 0, 1); return; }
31
+
32
+ vec2 er = rsi(org, rd, ER);
33
+ float tmax = at.y;
34
+ if (er.x > 0.0) tmax = min(tmax, er.x);
35
+ float tmin = max(at.x, 0.0);
36
+ if (tmin >= tmax) { outColor = vec4(0, 0, 0, 1); return; }
37
+
38
+ const int S = 16, L = 4;
39
+ float ss = (tmax - tmin) / float(S);
40
+ vec3 rayl = vec3(0), miel = vec3(0);
41
+ float oR = 0.0, oM = 0.0;
42
+
43
+ for (int i = 0; i < S; ++i) {
44
+ float t = tmin + (float(i) + 0.5) * ss;
45
+ vec3 sp = org + rd * t;
46
+ float h = length(sp) - ER;
47
+ float hr = exp(-h / 10000.0) * ss, hm = exp(-h / 3200.0) * ss;
48
+ oR += hr; oM += hm;
49
+
50
+ vec2 lh = rsi(sp, u.lightDir.xyz, AR);
51
+ if (lh.y > 0.0) {
52
+ float ls = lh.y / float(L);
53
+ float lR = 0.0, lM = 0.0;
54
+ bool bl = false;
55
+ for (int j = 0; j < L; ++j) {
56
+ vec3 lsp = sp + u.lightDir.xyz * ((float(j) + 0.5) * ls);
57
+ float lh2 = length(lsp) - ER;
58
+ if (lh2 < 0.0) { bl = true; break; }
59
+ lR += exp(-lh2 / 10000.0) * ls;
60
+ lM += exp(-lh2 / 3200.0) * ls;
61
+ }
62
+ if (!bl) {
63
+ vec3 tau = RAY * (oR + lR) + MIE3 * 1.1 * (oM + lM);
64
+ vec3 att = exp(-tau);
65
+ rayl += hr * att;
66
+ miel += hm * att;
67
+ }
68
+ }
69
+ }
70
+
71
+ float cosT = dot(rd, u.lightDir.xyz), cos2 = cosT * cosT;
72
+ float rPh = 0.75 * (1.0 + cos2);
73
+ float g2 = MG * MG;
74
+ float mPh = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + cos2) / pow(1.0 + g2 - 2.0 * MG * cosT, 1.5);
75
+ vec3 col = LINT * (rayl * RAY * rPh + miel * MIE3 * mPh);
76
+ col = 1.0 - exp(-col * 1.1);
77
+ col *= vec3(0.18, 0.45, 1.0);
78
+
79
+ vec3 nu = normalize(org);
80
+ float up = clamp(dot(rd, nu), 0.0, 1.0);
81
+ float camH = max(0.0, length(org) - ER);
82
+ float hStr = clamp(1.0 - camH / 35000.0, 0.0, 1.0);
83
+ col = mix(col, vec3(0.40, 0.62, 0.96), (1.0 - smoothstep(0.05, 0.45, up)) * 0.40 * hStr);
84
+
85
+ outColor = vec4(col, 1.0);
86
+ }
@@ -0,0 +1,9 @@
1
+ #version 450
2
+
3
+ layout(location = 0) out vec2 ndc;
4
+
5
+ void main() {
6
+ vec2 ps[3] = vec2[](vec2(-1, -1), vec2(3, -1), vec2(-1, 3));
7
+ gl_Position = vec4(ps[gl_VertexIndex], 0, 1);
8
+ ndc = ps[gl_VertexIndex];
9
+ }
@@ -0,0 +1,144 @@
1
+ #version 450
2
+
3
+ // Per-frame UBO (set 0): just the camera position in ECEF.
4
+ // Vertex-stage MVP is now in push constants, so the UBO is fragment-only.
5
+ layout(set = 0, binding = 0) uniform TerrainUBO {
6
+ vec4 cameraEcef; // xyz = camera ECEF (float), w unused
7
+ } u;
8
+
9
+ // Push constants — 128 bytes split between vertex (bytes 0-63) and fragment
10
+ // (bytes 64-127). The leading mat4 mirrors the vertex-shader declaration so
11
+ // both stages agree on the std430 layout; only the fragment-specific fields
12
+ // after it are actually read here.
13
+ layout(push_constant) uniform PC {
14
+ mat4 _mvp; // bytes 0-63 (vertex only, ignored here)
15
+ uint hasOverlay; // byte 64
16
+ uint isEllipsoidFallback;// byte 68
17
+ uint isOnlyWater; // byte 72
18
+ uint hasWaterMask; // byte 76
19
+ float wmWest; // byte 80
20
+ float wmSouth; // byte 84
21
+ float wmEast; // byte 88
22
+ float wmNorth; // byte 92
23
+ float rtcCenterX; // byte 96
24
+ float rtcCenterY; // byte 100
25
+ float rtcCenterZ; // byte 104
26
+ float translationX; // byte 108
27
+ float translationY; // byte 112
28
+ float scaleX; // byte 116
29
+ float scaleY; // byte 120
30
+ float _pad; // byte 124
31
+ } pc;
32
+
33
+ layout(set = 1, binding = 0) uniform sampler2D overlayTex;
34
+ layout(set = 2, binding = 0) uniform sampler2D waterMaskTex;
35
+
36
+ layout(location = 0) in vec3 localPos;
37
+ layout(location = 1) in vec2 fragUV;
38
+ layout(location = 2) in float fragAltitude;
39
+
40
+ layout(location = 0) out vec4 outColor;
41
+
42
+ vec3 hypsometricColor(float alt, float steep) {
43
+ vec3 cDeep = vec3(0.03, 0.20, 0.46), cShallow = vec3(0.08, 0.44, 0.78);
44
+ vec3 cLow = vec3(0.46, 0.54, 0.30), cFoot = vec3(0.62, 0.55, 0.32);
45
+ vec3 cHigh = vec3(0.48, 0.38, 0.28), cAlp = vec3(0.52, 0.50, 0.48);
46
+ vec3 cSnow = vec3(0.90, 0.92, 0.94);
47
+ if (alt < 0.0) return mix(cDeep, cShallow, smoothstep(-4500.0, -20.0, alt));
48
+ vec3 c = cLow;
49
+ c = mix(c, cFoot, smoothstep( 120.0, 900.0, alt));
50
+ c = mix(c, cHigh, smoothstep( 750.0, 2000.0, alt));
51
+ c = mix(c, cAlp, smoothstep(1700.0, 3600.0, alt));
52
+ c = mix(c, cSnow, smoothstep(3200.0, 5200.0, alt));
53
+ vec3 scree = vec3(0.38, 0.35, 0.32);
54
+ float rock = clamp(steep * 1.08, 0.0, 1.0) * smoothstep(35.0, 140.0, alt);
55
+ return mix(c, scree, rock);
56
+ }
57
+
58
+ void main() {
59
+ // ── World position (RTC reconstruction) ────────────────────────────────────
60
+ // wp = tile-local pos + RTC centre (both float32 at ~6.4 Mm scale).
61
+ // ~0.75 m ULP — far better than eyeRelPos + cameraEcef at altitude.
62
+ vec3 rtcCentre = vec3(pc.rtcCenterX, pc.rtcCenterY, pc.rtcCenterZ);
63
+ vec3 wp = localPos + rtcCentre;
64
+ float pxy = sqrt(wp.x * wp.x + wp.y * wp.y);
65
+ float lon = atan(wp.y, wp.x);
66
+
67
+ // Geodetic latitude (Bowring iteration, float32 — good to ~0.1 m for UV).
68
+ const float a_e = 6378137.0, b_e = 6356752.31424518;
69
+ const float ep2 = (a_e * a_e - b_e * b_e) / (b_e * b_e);
70
+ const float e2 = 1.0 - (b_e * b_e) / (a_e * a_e);
71
+ float theta_g = atan(wp.z * a_e, pxy * b_e);
72
+ float sg = sin(theta_g), cg = cos(theta_g);
73
+ float lat = atan(wp.z + ep2 * b_e * sg * sg * sg,
74
+ pxy - e2 * a_e * cg * cg * cg);
75
+
76
+ // ── Water-mask UV from geographic lat/lon + tile bounds ───────────────────
77
+ float wmU = (lon - pc.wmWest) / max(pc.wmEast - pc.wmWest, 1e-7);
78
+ float v_geo = (lat - pc.wmSouth) / max(pc.wmNorth - pc.wmSouth, 1e-7);
79
+ // Flip V: Cesium geographic convention (V=0 south) vs texture (V=0 north).
80
+ vec2 wmUV = clamp(vec2(wmU, 1.0 - v_geo), 0.0, 1.0);
81
+
82
+ float waterVal = (pc.isOnlyWater != 0u) ? 1.0 : texture(waterMaskTex, wmUV).r;
83
+
84
+ // ── Imagery overlay path ──────────────────────────────────────────────────
85
+ if (pc.hasOverlay != 0u) {
86
+ vec2 texUV = fragUV * vec2(pc.scaleX, pc.scaleY)
87
+ + vec2(pc.translationX, pc.translationY);
88
+ texUV.y = 1.0 - texUV.y;
89
+ outColor = texture(overlayTex, texUV);
90
+ return;
91
+ }
92
+
93
+ // ── Hypsometric path ──────────────────────────────────────────────────────
94
+ vec3 dpdx_v = dFdx(localPos), dpdy_v = dFdy(localPos);
95
+ vec3 rawN = cross(dpdx_v, dpdy_v);
96
+ float nLen = length(rawN);
97
+ vec3 n = (nLen > 1e-8) ? rawN / nLen : vec3(0.0, 0.0, 1.0);
98
+
99
+ // View direction in tile-local space.
100
+ // Camera-in-tile-space = cameraEcef − rtcCentre (float32, acceptable for lighting).
101
+ vec3 cameraTilespace = u.cameraEcef.xyz - rtcCentre;
102
+ vec3 vd = normalize(cameraTilespace - localPos);
103
+ if (dot(n, vd) < 0.0) n = -n;
104
+
105
+ vec3 gu = normalize(wp);
106
+ vec3 sun = normalize(gu + vec3(0.3, 0.2, 0.1));
107
+ float diff = clamp(dot(n, sun), 0.0, 1.0);
108
+ float amb = 0.18;
109
+ float rim = clamp(1.0 - dot(n, vd), 0.0, 1.0) * 0.06;
110
+ float steep = 1.0 - clamp(abs(dot(n, gu)), 0.0, 1.0);
111
+
112
+ // Use vertex altitude directly — computed on the CPU in double (sub-mm).
113
+ // Avoids the ±50 m catastrophic cancellation of float32 pxy/cos(lat) − N.
114
+ float rawAlt = fragAltitude;
115
+ vec3 oceanBlue = vec3(0.04, 0.26, 0.52);
116
+ float landAlt = (pc.hasWaterMask != 0u) ? max(rawAlt, 0.0) : rawAlt;
117
+ vec3 landLit = hypsometricColor(landAlt, steep) * (amb + diff * 0.72 + rim);
118
+ vec3 lit = mix(landLit, oceanBlue, waterVal);
119
+
120
+ // 1 km lat/lon grid — fades when sub-pixel to suppress Moiré.
121
+ const float gridLat = 1000.0 / 6371000.0;
122
+ float cosLat = max(cos(lat), 0.001);
123
+ float gridLon = gridLat / cosLat;
124
+ float wLat = fwidth(lat) * 1.5, wLon = fwidth(lon) * 1.5;
125
+ float gridVis = clamp(min(gridLat / max(wLat, 1e-9),
126
+ gridLon / max(wLon, 1e-9)), 0.0, 1.0);
127
+ float latCell = lat - gridLat * floor(lat / gridLat);
128
+ float lonCell = lon - gridLon * floor(lon / gridLon);
129
+ float dLat = min(latCell, gridLat - latCell);
130
+ float dLon = min(lonCell, gridLon - lonCell);
131
+ float gridA = max(1.0 - smoothstep(0.0, wLat, dLat),
132
+ 1.0 - smoothstep(0.0, wLon, dLon)) * gridVis;
133
+ lit = mix(lit, vec3(0.15, 0.15, 0.15), gridA * 0.6);
134
+
135
+ // Coastline outline from water mask.
136
+ if (pc.isEllipsoidFallback == 0u) {
137
+ float dWater = fwidth(waterVal);
138
+ float coastPx = abs(waterVal - 0.5) / max(dWater * 0.5, 0.01);
139
+ float coastA = 1.0 - smoothstep(0.0, 1.5, coastPx);
140
+ lit = mix(lit, vec3(0.18, 0.14, 0.10), coastA * 0.7);
141
+ }
142
+
143
+ outColor = vec4(lit, 1.0);
144
+ }
@@ -0,0 +1,25 @@
1
+ #version 450
2
+
3
+ // RTC vertex shader.
4
+ // Vertex positions are tile-local (relative to the tile's RTC centre).
5
+ // The per-tile MVP matrix is computed on the CPU entirely in double precision,
6
+ // then cast to float32. This eliminates the large camera↔tile-centre float32
7
+ // subtraction that caused ±1.6 m vertex precision errors at altitude.
8
+ layout(push_constant) uniform PC {
9
+ mat4 mvpMatrix; // per-draw RTC MVP (bytes 0-63)
10
+ } vpc;
11
+
12
+ layout(location = 0) in vec3 inPosition; // tile-local position (float)
13
+ layout(location = 1) in vec2 inUV;
14
+ layout(location = 2) in float inAltitude; // ellipsoid height metres (double source)
15
+
16
+ layout(location = 0) out vec3 localPos;
17
+ layout(location = 1) out vec2 fragUV;
18
+ layout(location = 2) out float fragAltitude;
19
+
20
+ void main() {
21
+ gl_Position = vpc.mvpMatrix * vec4(inPosition, 1.0);
22
+ localPos = inPosition;
23
+ fragUV = inUV;
24
+ fragAltitude = inAltitude;
25
+ }
@@ -0,0 +1,84 @@
1
+ package com.margelo.nitro.reactnativecesium
2
+
3
+ import android.view.Surface
4
+
5
+ /**
6
+ * JNI bridge to the C++ CesiumBridgeAndroid. Each instance owns a native pointer
7
+ * managed via [nativeCreate] / [nativeDestroy].
8
+ */
9
+ class CesiumBridgeJNI {
10
+ private var nativePtr: Long = nativeCreate()
11
+
12
+ fun init(surface: Surface, width: Int, height: Int, cacheDir: String, cacertPath: String) {
13
+ nativeInit(nativePtr, surface, width, height, cacheDir, cacertPath)
14
+ }
15
+
16
+ fun shutdown() = nativeShutdown(nativePtr)
17
+
18
+ fun destroy() {
19
+ nativeDestroy(nativePtr)
20
+ nativePtr = 0
21
+ }
22
+
23
+ fun resize(w: Int, h: Int) = nativeResize(nativePtr, w, h)
24
+ fun updateIonAccessToken(token: String, assetId: Long) = nativeUpdateIonAccessToken(nativePtr, token, assetId)
25
+ fun updateImageryAssetId(assetId: Long) = nativeUpdateImageryAssetId(nativePtr, assetId)
26
+ fun updateCamera(lat: Double, lon: Double, alt: Double, heading: Double, pitch: Double, roll: Double) =
27
+ nativeUpdateCamera(nativePtr, lat, lon, alt, heading, pitch, roll)
28
+ fun setVerticalFovDeg(deg: Double) = nativeSetVerticalFovDeg(nativePtr, deg)
29
+ fun setMaxSSE(v: Double) = nativeSetMaxSSE(nativePtr, v)
30
+ fun setMaxSimLoads(v: Int) = nativeSetMaxSimLoads(nativePtr, v)
31
+ fun setLoadDescLim(v: Int) = nativeSetLoadDescLim(nativePtr, v)
32
+ fun setMsaa(v: Int) = nativeSetMsaa(nativePtr, v)
33
+
34
+ fun markNeedsRender() = nativeMarkNeedsRender(nativePtr)
35
+ fun shouldRenderNextFrame(): Boolean = nativeShouldRenderNextFrame(nativePtr)
36
+ fun renderFrame(dt: Double) = nativeRenderFrame(nativePtr, dt)
37
+
38
+ fun getCameraLat(): Double = nativeGetCameraLat(nativePtr)
39
+ fun getCameraLon(): Double = nativeGetCameraLon(nativePtr)
40
+ fun getCameraAlt(): Double = nativeGetCameraAlt(nativePtr)
41
+ fun getCameraHeading(): Double = nativeGetCameraHeading(nativePtr)
42
+ fun getCameraPitch(): Double = nativeGetCameraPitch(nativePtr)
43
+ fun getCameraRoll(): Double = nativeGetCameraRoll(nativePtr)
44
+ fun getVerticalFovDeg(): Double = nativeGetVerticalFovDeg(nativePtr)
45
+
46
+ fun getMetricsFps(): Double = nativeGetMetricsFps(nativePtr)
47
+ fun getMetricsTilesRendered(): Int = nativeGetMetricsTilesRendered(nativePtr)
48
+ fun getMetricsTilesLoading(): Int = nativeGetMetricsTilesLoading(nativePtr)
49
+ fun getMetricsTilesVisited(): Int = nativeGetMetricsTilesVisited(nativePtr)
50
+ fun getMetricsIonTokenConfigured(): Boolean = nativeGetMetricsIonTokenConfigured(nativePtr)
51
+ fun getMetricsTilesetReady(): Boolean = nativeGetMetricsTilesetReady(nativePtr)
52
+ fun getMetricsCreditsPlainText(): String = nativeGetMetricsCreditsPlainText(nativePtr)
53
+
54
+ private external fun nativeCreate(): Long
55
+ private external fun nativeInit(ptr: Long, surface: Surface, w: Int, h: Int, cacheDir: String, cacertPath: String)
56
+ private external fun nativeShutdown(ptr: Long)
57
+ private external fun nativeDestroy(ptr: Long)
58
+ private external fun nativeResize(ptr: Long, w: Int, h: Int)
59
+ private external fun nativeUpdateIonAccessToken(ptr: Long, token: String, assetId: Long)
60
+ private external fun nativeUpdateImageryAssetId(ptr: Long, assetId: Long)
61
+ private external fun nativeUpdateCamera(ptr: Long, lat: Double, lon: Double, alt: Double, heading: Double, pitch: Double, roll: Double)
62
+ private external fun nativeSetVerticalFovDeg(ptr: Long, deg: Double)
63
+ private external fun nativeSetMaxSSE(ptr: Long, v: Double)
64
+ private external fun nativeSetMaxSimLoads(ptr: Long, v: Int)
65
+ private external fun nativeSetLoadDescLim(ptr: Long, v: Int)
66
+ private external fun nativeSetMsaa(ptr: Long, v: Int)
67
+ private external fun nativeMarkNeedsRender(ptr: Long)
68
+ private external fun nativeShouldRenderNextFrame(ptr: Long): Boolean
69
+ private external fun nativeRenderFrame(ptr: Long, dt: Double)
70
+ private external fun nativeGetCameraLat(ptr: Long): Double
71
+ private external fun nativeGetCameraLon(ptr: Long): Double
72
+ private external fun nativeGetCameraAlt(ptr: Long): Double
73
+ private external fun nativeGetCameraHeading(ptr: Long): Double
74
+ private external fun nativeGetCameraPitch(ptr: Long): Double
75
+ private external fun nativeGetCameraRoll(ptr: Long): Double
76
+ private external fun nativeGetVerticalFovDeg(ptr: Long): Double
77
+ private external fun nativeGetMetricsFps(ptr: Long): Double
78
+ private external fun nativeGetMetricsTilesRendered(ptr: Long): Int
79
+ private external fun nativeGetMetricsTilesLoading(ptr: Long): Int
80
+ private external fun nativeGetMetricsTilesVisited(ptr: Long): Int
81
+ private external fun nativeGetMetricsIonTokenConfigured(ptr: Long): Boolean
82
+ private external fun nativeGetMetricsTilesetReady(ptr: Long): Boolean
83
+ private external fun nativeGetMetricsCreditsPlainText(ptr: Long): String
84
+ }