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.
- package/LICENSE +21 -0
- package/NOTICE +12 -0
- package/README.md +308 -0
- package/ReactNativeCesium.podspec +54 -0
- package/android/CMakeLists.txt +146 -0
- package/android/build.gradle +178 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +5 -0
- package/android/src/main/assets/cacert.pem +3529 -0
- package/android/src/main/cpp/CesiumBridgeAndroid.cpp +487 -0
- package/android/src/main/cpp/CesiumBridgeAndroid.h +94 -0
- package/android/src/main/cpp/cpp-adapter.cpp +17 -0
- package/android/src/main/cpp/vulkan/VulkanBackend.cpp +1781 -0
- package/android/src/main/cpp/vulkan/VulkanBackend.h +190 -0
- package/android/src/main/cpp/vulkan/shaders/sky.frag +86 -0
- package/android/src/main/cpp/vulkan/shaders/sky.vert +9 -0
- package/android/src/main/cpp/vulkan/shaders/terrain.frag +144 -0
- package/android/src/main/cpp/vulkan/shaders/terrain.vert +25 -0
- package/android/src/main/java/com/margelo/nitro/reactnativecesium/CesiumBridgeJNI.kt +84 -0
- package/android/src/main/java/com/margelo/nitro/reactnativecesium/HybridCesiumView.kt +225 -0
- package/android/src/main/java/com/reactnativecesium/ReactNativeCesiumPackage.kt +28 -0
- package/cpp/engine/CesiumEngine.cpp +413 -0
- package/cpp/engine/CesiumEngine.hpp +90 -0
- package/cpp/engine/DeletionQueue.cpp +28 -0
- package/cpp/engine/DeletionQueue.hpp +28 -0
- package/cpp/engine/GlobeCamera.cpp +181 -0
- package/cpp/engine/GlobeCamera.hpp +64 -0
- package/cpp/engine/GltfToMesh.cpp +154 -0
- package/cpp/engine/GltfToMesh.hpp +20 -0
- package/cpp/engine/ResourcePreparer.cpp +224 -0
- package/cpp/engine/ResourcePreparer.hpp +96 -0
- package/cpp/engine/TaskProcessor.cpp +61 -0
- package/cpp/engine/TaskProcessor.hpp +43 -0
- package/cpp/engine/TileLifecycleManager.cpp +30 -0
- package/cpp/engine/TileLifecycleManager.hpp +25 -0
- package/cpp/fmt/format.h +9 -0
- package/cpp/renderer/IGPUBackend.hpp +22 -0
- package/cpp/renderer/RenderTypes.hpp +112 -0
- package/cpp/renderer/ShaderTypes.hpp +29 -0
- package/example/README.md +43 -0
- package/example/react-native-cesium-example.jpg +0 -0
- package/ios/CesiumBridge.h +55 -0
- package/ios/CesiumBridge.mm +393 -0
- package/ios/HybridCesiumView.swift +299 -0
- package/ios/ReactNativeCesium-umbrella.h +16 -0
- package/ios/metal/MetalBackend.h +82 -0
- package/ios/metal/MetalBackend.mm +839 -0
- package/ios/react_native_cesium_ensure_native.rb +12 -0
- package/ios/react_native_cesium_post_install.rb +30 -0
- package/lib/commonjs/CesiumView.js +13 -0
- package/lib/commonjs/CesiumView.js.map +1 -0
- package/lib/commonjs/index.js +13 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/specs/cesium-view.nitro.js +6 -0
- package/lib/commonjs/specs/cesium-view.nitro.js.map +1 -0
- package/lib/module/CesiumView.js +9 -0
- package/lib/module/CesiumView.js.map +1 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/specs/cesium-view.nitro.js +4 -0
- package/lib/module/specs/cesium-view.nitro.js.map +1 -0
- package/lib/typescript/src/CesiumView.d.ts +5 -0
- package/lib/typescript/src/CesiumView.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/specs/cesium-view.nitro.d.ts +43 -0
- package/lib/typescript/src/specs/cesium-view.nitro.d.ts.map +1 -0
- package/nitro.json +30 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/ReactNativeCesium+autolinking.cmake +83 -0
- package/nitrogen/generated/android/ReactNativeCesium+autolinking.gradle +27 -0
- package/nitrogen/generated/android/ReactNativeCesiumOnLoad.cpp +58 -0
- package/nitrogen/generated/android/ReactNativeCesiumOnLoad.hpp +34 -0
- package/nitrogen/generated/android/c++/JCameraState.hpp +81 -0
- package/nitrogen/generated/android/c++/JCesiumMetrics.hpp +81 -0
- package/nitrogen/generated/android/c++/JFunc_void_CesiumMetrics.hpp +78 -0
- package/nitrogen/generated/android/c++/JHybridCesiumViewSpec.cpp +178 -0
- package/nitrogen/generated/android/c++/JHybridCesiumViewSpec.hpp +83 -0
- package/nitrogen/generated/android/c++/views/JHybridCesiumViewStateUpdater.cpp +92 -0
- package/nitrogen/generated/android/c++/views/JHybridCesiumViewStateUpdater.hpp +49 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/CameraState.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/CesiumMetrics.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/Func_void_CesiumMetrics.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/HybridCesiumViewSpec.kt +126 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/ReactNativeCesiumOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/views/HybridCesiumViewManager.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativecesium/views/HybridCesiumViewStateUpdater.kt +23 -0
- package/nitrogen/generated/ios/ReactNativeCesium+autolinking.rb +60 -0
- package/nitrogen/generated/ios/ReactNativeCesium-Swift-Cxx-Bridge.cpp +57 -0
- package/nitrogen/generated/ios/ReactNativeCesium-Swift-Cxx-Bridge.hpp +164 -0
- package/nitrogen/generated/ios/ReactNativeCesium-Swift-Cxx-Umbrella.hpp +53 -0
- package/nitrogen/generated/ios/ReactNativeCesiumAutolinking.mm +33 -0
- package/nitrogen/generated/ios/ReactNativeCesiumAutolinking.swift +26 -0
- package/nitrogen/generated/ios/c++/HybridCesiumViewSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridCesiumViewSpecSwift.hpp +157 -0
- package/nitrogen/generated/ios/c++/views/HybridCesiumViewComponent.mm +167 -0
- package/nitrogen/generated/ios/swift/CameraState.swift +59 -0
- package/nitrogen/generated/ios/swift/CesiumMetrics.swift +59 -0
- package/nitrogen/generated/ios/swift/Func_void_CameraState.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_CesiumMetrics.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridCesiumViewSpec.swift +65 -0
- package/nitrogen/generated/ios/swift/HybridCesiumViewSpec_cxx.swift +306 -0
- package/nitrogen/generated/shared/c++/CameraState.hpp +107 -0
- package/nitrogen/generated/shared/c++/CesiumMetrics.hpp +107 -0
- package/nitrogen/generated/shared/c++/HybridCesiumViewSpec.cpp +42 -0
- package/nitrogen/generated/shared/c++/HybridCesiumViewSpec.hpp +90 -0
- package/nitrogen/generated/shared/c++/views/HybridCesiumViewComponent.cpp +182 -0
- package/nitrogen/generated/shared/c++/views/HybridCesiumViewComponent.hpp +122 -0
- package/nitrogen/generated/shared/json/CesiumViewConfig.json +19 -0
- package/package.json +140 -0
- package/react-native.config.js +16 -0
- package/scripts/cesium/build.mjs +901 -0
- package/scripts/cesium/clean.mjs +35 -0
- package/scripts/cesium/clone.mjs +32 -0
- package/scripts/cesium/ensure-native.mjs +116 -0
- package/scripts/cesium/vcpkg-ports/zstd/fix-emscripten-and-clang-cl.patch +31 -0
- package/scripts/cesium/vcpkg-ports/zstd/fix-windows-rc-compile.patch +13 -0
- package/scripts/cesium/vcpkg-ports/zstd/no-static-suffix.patch +13 -0
- package/scripts/cesium/vcpkg-ports/zstd/portfile.cmake +77 -0
- package/scripts/cesium/vcpkg-ports/zstd/usage +4 -0
- package/scripts/cesium/vcpkg-ports/zstd/vcpkg.json +23 -0
- package/scripts/cesium/vcpkg-triplets/arm64-ios-simulator.cmake +10 -0
- package/scripts/cesium/vcpkg-triplets/arm64-ios.cmake +14 -0
- package/src/CesiumView.tsx +13 -0
- package/src/index.ts +7 -0
- 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,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
|
+
}
|