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,224 @@
|
|
|
1
|
+
#include "ResourcePreparer.hpp"
|
|
2
|
+
|
|
3
|
+
#include <Cesium3DTilesSelection/Tile.h>
|
|
4
|
+
#include <CesiumGltf/ImageAsset.h>
|
|
5
|
+
#include <CesiumGltf/Model.h>
|
|
6
|
+
#include <CesiumUtility/JsonValue.h>
|
|
7
|
+
|
|
8
|
+
#include <cstring>
|
|
9
|
+
#include <spdlog/spdlog.h>
|
|
10
|
+
|
|
11
|
+
namespace reactnativecesium {
|
|
12
|
+
|
|
13
|
+
ResourcePreparer::ResourcePreparer(TileLifecycleManager& lifecycle)
|
|
14
|
+
: lifecycle_(lifecycle) {}
|
|
15
|
+
|
|
16
|
+
CesiumAsync::Future<Cesium3DTilesSelection::TileLoadResultAndRenderResources>
|
|
17
|
+
ResourcePreparer::prepareInLoadThread(
|
|
18
|
+
const CesiumAsync::AsyncSystem& asyncSystem,
|
|
19
|
+
Cesium3DTilesSelection::TileLoadResult&& tileLoadResult,
|
|
20
|
+
const glm::dmat4& transform,
|
|
21
|
+
const std::any& /*rendererOptions*/) {
|
|
22
|
+
|
|
23
|
+
const CesiumGltf::Model* pModel =
|
|
24
|
+
std::get_if<CesiumGltf::Model>(&tileLoadResult.contentKind);
|
|
25
|
+
|
|
26
|
+
TileGPUResources* res = new TileGPUResources();
|
|
27
|
+
if (pModel) {
|
|
28
|
+
res->primitives = GltfToMesh::convert(*pModel, transform);
|
|
29
|
+
|
|
30
|
+
if (!pModel->meshes.empty() && !pModel->meshes[0].primitives.empty()) {
|
|
31
|
+
const CesiumGltf::MeshPrimitive& prim = pModel->meshes[0].primitives[0];
|
|
32
|
+
const CesiumUtility::JsonValue& ex = prim.extras;
|
|
33
|
+
|
|
34
|
+
const auto* onlyWater = ex.getValuePtrForKey("OnlyWater");
|
|
35
|
+
const auto* onlyLand = ex.getValuePtrForKey("OnlyLand");
|
|
36
|
+
const bool isOnlyWater = onlyWater && onlyWater->getBool();
|
|
37
|
+
const bool isOnlyLand = onlyLand && onlyLand->getBool();
|
|
38
|
+
|
|
39
|
+
const auto* texIdPtr = ex.getValuePtrForKey("WaterMaskTex");
|
|
40
|
+
const int64_t texId = texIdPtr ? texIdPtr->getSafeNumber<int64_t>().value_or(-2) : -3;
|
|
41
|
+
|
|
42
|
+
const auto* wmTxPtr = ex.getValuePtrForKey("WaterMaskTranslationX");
|
|
43
|
+
const auto* wmTyPtr = ex.getValuePtrForKey("WaterMaskTranslationY");
|
|
44
|
+
const auto* wmSPtr = ex.getValuePtrForKey("WaterMaskScale");
|
|
45
|
+
res->wmTranslation.x = wmTxPtr ? (float)wmTxPtr->getSafeNumber<double>().value_or(0.0) : 0.0f;
|
|
46
|
+
res->wmTranslation.y = wmTyPtr ? (float)wmTyPtr->getSafeNumber<double>().value_or(0.0) : 0.0f;
|
|
47
|
+
res->wmScale = wmSPtr ? (float)wmSPtr->getSafeNumber<double>().value_or(1.0) : 1.0f;
|
|
48
|
+
res->isOnlyWater = isOnlyWater;
|
|
49
|
+
|
|
50
|
+
if (!isOnlyWater && !isOnlyLand) {
|
|
51
|
+
if (texIdPtr && texId >= 0 &&
|
|
52
|
+
static_cast<size_t>(texId) < pModel->textures.size()) {
|
|
53
|
+
const int32_t srcId = pModel->textures[static_cast<size_t>(texId)].source;
|
|
54
|
+
if (srcId >= 0 && static_cast<size_t>(srcId) < pModel->images.size()) {
|
|
55
|
+
const auto& img = pModel->images[static_cast<size_t>(srcId)];
|
|
56
|
+
const bool assetOk = img.pAsset &&
|
|
57
|
+
img.pAsset->width == 256 &&
|
|
58
|
+
img.pAsset->height == 256 &&
|
|
59
|
+
img.pAsset->channels == 1 &&
|
|
60
|
+
img.pAsset->bytesPerChannel == 1 &&
|
|
61
|
+
img.pAsset->pixelData.size() == 65536;
|
|
62
|
+
if (assetOk) {
|
|
63
|
+
res->waterMaskPixels.resize(256 * 256 * 4);
|
|
64
|
+
const auto* src =
|
|
65
|
+
reinterpret_cast<const uint8_t*>(img.pAsset->pixelData.data());
|
|
66
|
+
for (int i = 0; i < 256 * 256; ++i) {
|
|
67
|
+
const uint8_t v = src[i];
|
|
68
|
+
res->waterMaskPixels[i * 4 + 0] = v;
|
|
69
|
+
res->waterMaskPixels[i * 4 + 1] = v;
|
|
70
|
+
res->waterMaskPixels[i * 4 + 2] = v;
|
|
71
|
+
res->waterMaskPixels[i * 4 + 3] = 255;
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
spdlog::warn("[WM] tile srcId={} has unexpected image format", srcId);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return asyncSystem.createResolvedFuture(
|
|
83
|
+
Cesium3DTilesSelection::TileLoadResultAndRenderResources{
|
|
84
|
+
std::move(tileLoadResult), res});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
void* ResourcePreparer::prepareInMainThread(
|
|
88
|
+
Cesium3DTilesSelection::Tile& /*tile*/, void* pLoadThreadResult) {
|
|
89
|
+
auto* res = static_cast<TileGPUResources*>(pLoadThreadResult);
|
|
90
|
+
if (res) {
|
|
91
|
+
res->lastUsedFrame = lifecycle_.currentFrame();
|
|
92
|
+
if (!res->waterMaskPixels.empty() && waterMaskCreator_) {
|
|
93
|
+
res->waterMaskTexture = waterMaskCreator_(
|
|
94
|
+
res->waterMaskPixels.data(), 256, 256);
|
|
95
|
+
res->waterMaskPixels.clear();
|
|
96
|
+
res->waterMaskPixels.shrink_to_fit();
|
|
97
|
+
} else if (!res->waterMaskPixels.empty() && !waterMaskCreator_) {
|
|
98
|
+
spdlog::error("[WM] waterMaskCreator_ is null — water mask will not be uploaded");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return pLoadThreadResult;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
void ResourcePreparer::free(Cesium3DTilesSelection::Tile& /*tile*/,
|
|
105
|
+
void* pLoadThreadResult,
|
|
106
|
+
void* pMainThreadResult) noexcept {
|
|
107
|
+
TileGPUResources* res = pLoadThreadResult
|
|
108
|
+
? static_cast<TileGPUResources*>(pLoadThreadResult)
|
|
109
|
+
: static_cast<TileGPUResources*>(pMainThreadResult);
|
|
110
|
+
if (res) {
|
|
111
|
+
if (res->waterMaskTexture && waterMaskDeleter_) {
|
|
112
|
+
waterMaskDeleter_(res->waterMaskTexture);
|
|
113
|
+
}
|
|
114
|
+
delete res;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ── Raster overlay pipeline ─────────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
void* ResourcePreparer::prepareRasterInLoadThread(CesiumGltf::ImageAsset& image,
|
|
121
|
+
const std::any&) {
|
|
122
|
+
if (image.pixelData.empty() || image.width <= 0 || image.height <= 0) {
|
|
123
|
+
return nullptr;
|
|
124
|
+
}
|
|
125
|
+
if (image.compressedPixelFormat != CesiumGltf::GpuCompressedPixelFormat::NONE) {
|
|
126
|
+
return nullptr;
|
|
127
|
+
}
|
|
128
|
+
if (image.bytesPerChannel != 1) return nullptr;
|
|
129
|
+
|
|
130
|
+
auto* data = new RasterPixelData();
|
|
131
|
+
data->width = image.width;
|
|
132
|
+
data->height = image.height;
|
|
133
|
+
|
|
134
|
+
const size_t pixelCount = static_cast<size_t>(image.width) *
|
|
135
|
+
static_cast<size_t>(image.height);
|
|
136
|
+
data->pixels.resize(pixelCount * 4);
|
|
137
|
+
|
|
138
|
+
const auto* src = reinterpret_cast<const uint8_t*>(image.pixelData.data());
|
|
139
|
+
|
|
140
|
+
if (image.channels == 4) {
|
|
141
|
+
std::memcpy(data->pixels.data(), src, pixelCount * 4);
|
|
142
|
+
} else if (image.channels == 3) {
|
|
143
|
+
for (size_t i = 0; i < pixelCount; ++i) {
|
|
144
|
+
data->pixels[i * 4 + 0] = src[i * 3 + 0];
|
|
145
|
+
data->pixels[i * 4 + 1] = src[i * 3 + 1];
|
|
146
|
+
data->pixels[i * 4 + 2] = src[i * 3 + 2];
|
|
147
|
+
data->pixels[i * 4 + 3] = 255;
|
|
148
|
+
}
|
|
149
|
+
} else if (image.channels == 1) {
|
|
150
|
+
for (size_t i = 0; i < pixelCount; ++i) {
|
|
151
|
+
uint8_t v = src[i];
|
|
152
|
+
data->pixels[i * 4 + 0] = v;
|
|
153
|
+
data->pixels[i * 4 + 1] = v;
|
|
154
|
+
data->pixels[i * 4 + 2] = v;
|
|
155
|
+
data->pixels[i * 4 + 3] = 255;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
std::fill(data->pixels.begin(), data->pixels.end(), uint8_t(255));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return data;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
void* ResourcePreparer::prepareRasterInMainThread(
|
|
165
|
+
CesiumRasterOverlays::RasterOverlayTile& /*rasterTile*/,
|
|
166
|
+
void* pLoadThreadResult) {
|
|
167
|
+
auto* pixelData = static_cast<RasterPixelData*>(pLoadThreadResult);
|
|
168
|
+
if (!pixelData) return nullptr;
|
|
169
|
+
|
|
170
|
+
void* texture = nullptr;
|
|
171
|
+
if (gpuTextureCreator_) {
|
|
172
|
+
texture = gpuTextureCreator_(
|
|
173
|
+
pixelData->pixels.data(), pixelData->width, pixelData->height);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
delete pixelData;
|
|
177
|
+
return texture;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
void ResourcePreparer::freeRaster(
|
|
181
|
+
const CesiumRasterOverlays::RasterOverlayTile& /*rasterTile*/,
|
|
182
|
+
void* pLoadThreadResult,
|
|
183
|
+
void* pMainThreadResult) noexcept {
|
|
184
|
+
if (pLoadThreadResult) {
|
|
185
|
+
delete static_cast<RasterPixelData*>(pLoadThreadResult);
|
|
186
|
+
}
|
|
187
|
+
if (pMainThreadResult && gpuTextureDeleter_) {
|
|
188
|
+
gpuTextureDeleter_(pMainThreadResult);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
void ResourcePreparer::attachRasterInMainThread(
|
|
193
|
+
const Cesium3DTilesSelection::Tile& tile,
|
|
194
|
+
int32_t /*overlayTextureCoordinateID*/,
|
|
195
|
+
const CesiumRasterOverlays::RasterOverlayTile& /*rasterTile*/,
|
|
196
|
+
void* pMainThreadRendererResources,
|
|
197
|
+
const glm::dvec2& translation,
|
|
198
|
+
const glm::dvec2& scale) {
|
|
199
|
+
const auto* renderContent = tile.getContent().getRenderContent();
|
|
200
|
+
if (!renderContent) return;
|
|
201
|
+
auto* res = static_cast<TileGPUResources*>(renderContent->getRenderResources());
|
|
202
|
+
if (res) {
|
|
203
|
+
res->overlayTexture = pMainThreadRendererResources;
|
|
204
|
+
res->overlayTranslation = glm::vec2(translation);
|
|
205
|
+
res->overlayScale = glm::vec2(scale);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
void ResourcePreparer::detachRasterInMainThread(
|
|
210
|
+
const Cesium3DTilesSelection::Tile& tile,
|
|
211
|
+
int32_t /*overlayTextureCoordinateID*/,
|
|
212
|
+
const CesiumRasterOverlays::RasterOverlayTile& /*rasterTile*/,
|
|
213
|
+
void* /*pMainThreadRendererResources*/) noexcept {
|
|
214
|
+
const auto* renderContent = tile.getContent().getRenderContent();
|
|
215
|
+
if (!renderContent) return;
|
|
216
|
+
auto* res = static_cast<TileGPUResources*>(renderContent->getRenderResources());
|
|
217
|
+
if (res) {
|
|
218
|
+
res->overlayTexture = nullptr;
|
|
219
|
+
res->overlayTranslation = {0.0f, 0.0f};
|
|
220
|
+
res->overlayScale = {1.0f, 1.0f};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
} // namespace reactnativecesium
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "../renderer/RenderTypes.hpp"
|
|
4
|
+
#include "GltfToMesh.hpp"
|
|
5
|
+
#include "TileLifecycleManager.hpp"
|
|
6
|
+
|
|
7
|
+
#include <Cesium3DTilesSelection/IPrepareRendererResources.h>
|
|
8
|
+
|
|
9
|
+
#include <functional>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
namespace reactnativecesium {
|
|
13
|
+
|
|
14
|
+
// Raw decoded pixel data produced on the background load thread.
|
|
15
|
+
// Converted to a platform texture on the main thread via GPUTextureCreator.
|
|
16
|
+
struct RasterPixelData {
|
|
17
|
+
std::vector<uint8_t> pixels; // RGBA8 decoded image
|
|
18
|
+
int32_t width = 0;
|
|
19
|
+
int32_t height = 0;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Factory: called on the MAIN THREAD to create a native GPU texture
|
|
23
|
+
// (id<MTLTexture> on iOS, VulkanTexture* on Android) from decoded RGBA8 pixels.
|
|
24
|
+
// Set from the platform bridge before any overlays are activated.
|
|
25
|
+
using GPUTextureCreator =
|
|
26
|
+
std::function<void*(const uint8_t* pixels, int32_t width, int32_t height)>;
|
|
27
|
+
|
|
28
|
+
// Destructor: called to free a GPU texture previously created by GPUTextureCreator.
|
|
29
|
+
// On iOS: CFRelease(tex). On Android: VulkanBackend::freeRasterTexture(tex).
|
|
30
|
+
using GPUTextureDeleter = std::function<void(void* tex)>;
|
|
31
|
+
|
|
32
|
+
class ResourcePreparer
|
|
33
|
+
: public Cesium3DTilesSelection::IPrepareRendererResources {
|
|
34
|
+
public:
|
|
35
|
+
explicit ResourcePreparer(TileLifecycleManager& lifecycle);
|
|
36
|
+
~ResourcePreparer() override = default;
|
|
37
|
+
|
|
38
|
+
void setGPUTextureCreator(GPUTextureCreator creator) {
|
|
39
|
+
gpuTextureCreator_ = std::move(creator);
|
|
40
|
+
}
|
|
41
|
+
void setGPUTextureDeleter(GPUTextureDeleter deleter) {
|
|
42
|
+
gpuTextureDeleter_ = std::move(deleter);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Water mask texture lifecycle — identical signature to the imagery callbacks
|
|
46
|
+
// but the platform allocates from a different descriptor pool (Vulkan Set 2).
|
|
47
|
+
void setWaterMaskTextureCreator(GPUTextureCreator creator) {
|
|
48
|
+
waterMaskCreator_ = std::move(creator);
|
|
49
|
+
}
|
|
50
|
+
void setWaterMaskTextureDeleter(GPUTextureDeleter deleter) {
|
|
51
|
+
waterMaskDeleter_ = std::move(deleter);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
CesiumAsync::Future<Cesium3DTilesSelection::TileLoadResultAndRenderResources>
|
|
55
|
+
prepareInLoadThread(
|
|
56
|
+
const CesiumAsync::AsyncSystem& asyncSystem,
|
|
57
|
+
Cesium3DTilesSelection::TileLoadResult&& tileLoadResult,
|
|
58
|
+
const glm::dmat4& transform,
|
|
59
|
+
const std::any& rendererOptions) override;
|
|
60
|
+
|
|
61
|
+
void* prepareInMainThread(Cesium3DTilesSelection::Tile& tile,
|
|
62
|
+
void* pLoadThreadResult) override;
|
|
63
|
+
|
|
64
|
+
void free(Cesium3DTilesSelection::Tile& tile, void* pLoadThreadResult,
|
|
65
|
+
void* pMainThreadResult) noexcept override;
|
|
66
|
+
|
|
67
|
+
void* prepareRasterInLoadThread(CesiumGltf::ImageAsset& image,
|
|
68
|
+
const std::any& rendererOptions) override;
|
|
69
|
+
void* prepareRasterInMainThread(
|
|
70
|
+
CesiumRasterOverlays::RasterOverlayTile& rasterTile,
|
|
71
|
+
void* pLoadThreadResult) override;
|
|
72
|
+
void freeRaster(const CesiumRasterOverlays::RasterOverlayTile& rasterTile,
|
|
73
|
+
void* pLoadThreadResult,
|
|
74
|
+
void* pMainThreadResult) noexcept override;
|
|
75
|
+
void attachRasterInMainThread(
|
|
76
|
+
const Cesium3DTilesSelection::Tile& tile,
|
|
77
|
+
int32_t overlayTextureCoordinateID,
|
|
78
|
+
const CesiumRasterOverlays::RasterOverlayTile& rasterTile,
|
|
79
|
+
void* pMainThreadRendererResources,
|
|
80
|
+
const glm::dvec2& translation,
|
|
81
|
+
const glm::dvec2& scale) override;
|
|
82
|
+
void detachRasterInMainThread(
|
|
83
|
+
const Cesium3DTilesSelection::Tile& tile,
|
|
84
|
+
int32_t overlayTextureCoordinateID,
|
|
85
|
+
const CesiumRasterOverlays::RasterOverlayTile& rasterTile,
|
|
86
|
+
void* pMainThreadRendererResources) noexcept override;
|
|
87
|
+
|
|
88
|
+
private:
|
|
89
|
+
TileLifecycleManager& lifecycle_;
|
|
90
|
+
GPUTextureCreator gpuTextureCreator_;
|
|
91
|
+
GPUTextureDeleter gpuTextureDeleter_;
|
|
92
|
+
GPUTextureCreator waterMaskCreator_;
|
|
93
|
+
GPUTextureDeleter waterMaskDeleter_;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
} // namespace reactnativecesium
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#include "TaskProcessor.hpp"
|
|
2
|
+
|
|
3
|
+
namespace reactnativecesium {
|
|
4
|
+
|
|
5
|
+
TaskProcessor::TaskProcessor(uint32_t numThreads) {
|
|
6
|
+
workers_.reserve(numThreads);
|
|
7
|
+
for (uint32_t i = 0; i < numThreads; ++i) {
|
|
8
|
+
workers_.emplace_back(&TaskProcessor::workerLoop, this);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
TaskProcessor::~TaskProcessor() {
|
|
13
|
+
shutdown_.store(true, std::memory_order_release);
|
|
14
|
+
cv_.notify_all();
|
|
15
|
+
for (auto& t : workers_) {
|
|
16
|
+
if (t.joinable()) {
|
|
17
|
+
t.join();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void TaskProcessor::startTask(std::function<void()> f) {
|
|
23
|
+
{
|
|
24
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
25
|
+
tasks_.push(std::move(f));
|
|
26
|
+
}
|
|
27
|
+
cv_.notify_one();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void TaskProcessor::waitUntilIdle() {
|
|
31
|
+
std::unique_lock<std::mutex> lock(mutex_);
|
|
32
|
+
idleCv_.wait(lock, [this] {
|
|
33
|
+
return tasks_.empty() && activeTasks_ == 0;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
void TaskProcessor::workerLoop() {
|
|
38
|
+
while (true) {
|
|
39
|
+
std::function<void()> task;
|
|
40
|
+
{
|
|
41
|
+
std::unique_lock<std::mutex> lock(mutex_);
|
|
42
|
+
cv_.wait(lock, [this] {
|
|
43
|
+
return shutdown_.load(std::memory_order_acquire) || !tasks_.empty();
|
|
44
|
+
});
|
|
45
|
+
if (shutdown_.load(std::memory_order_acquire) && tasks_.empty()) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
task = std::move(tasks_.front());
|
|
49
|
+
tasks_.pop();
|
|
50
|
+
++activeTasks_; // increment under the lock so waitUntilIdle sees it
|
|
51
|
+
}
|
|
52
|
+
task();
|
|
53
|
+
{
|
|
54
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
55
|
+
--activeTasks_;
|
|
56
|
+
}
|
|
57
|
+
idleCv_.notify_all(); // wake any thread waiting in waitUntilIdle
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
} // namespace reactnativecesium
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <CesiumAsync/ITaskProcessor.h>
|
|
4
|
+
|
|
5
|
+
#include <atomic>
|
|
6
|
+
#include <condition_variable>
|
|
7
|
+
#include <functional>
|
|
8
|
+
#include <mutex>
|
|
9
|
+
#include <queue>
|
|
10
|
+
#include <thread>
|
|
11
|
+
#include <vector>
|
|
12
|
+
|
|
13
|
+
namespace reactnativecesium {
|
|
14
|
+
|
|
15
|
+
class TaskProcessor : public CesiumAsync::ITaskProcessor {
|
|
16
|
+
public:
|
|
17
|
+
explicit TaskProcessor(uint32_t numThreads = 4);
|
|
18
|
+
~TaskProcessor() override;
|
|
19
|
+
|
|
20
|
+
TaskProcessor(const TaskProcessor&) = delete;
|
|
21
|
+
TaskProcessor& operator=(const TaskProcessor&) = delete;
|
|
22
|
+
|
|
23
|
+
void startTask(std::function<void()> f) override;
|
|
24
|
+
|
|
25
|
+
// Block the calling thread until the task queue is empty and every
|
|
26
|
+
// in-flight task has returned. Worker tasks may post main-thread
|
|
27
|
+
// callbacks (via the AsyncSystem) and return without waiting for them,
|
|
28
|
+
// so this does not deadlock when called from the main thread.
|
|
29
|
+
void waitUntilIdle();
|
|
30
|
+
|
|
31
|
+
private:
|
|
32
|
+
void workerLoop();
|
|
33
|
+
|
|
34
|
+
std::vector<std::thread> workers_;
|
|
35
|
+
std::queue<std::function<void()>> tasks_;
|
|
36
|
+
std::mutex mutex_;
|
|
37
|
+
std::condition_variable cv_;
|
|
38
|
+
std::condition_variable idleCv_; // signalled when queue + active reach 0
|
|
39
|
+
std::atomic<bool> shutdown_{false};
|
|
40
|
+
uint32_t activeTasks_{0}; // guarded by mutex_
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
} // namespace reactnativecesium
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#include "TileLifecycleManager.hpp"
|
|
2
|
+
|
|
3
|
+
#include <Cesium3DTilesSelection/TileContent.h>
|
|
4
|
+
#include <Cesium3DTilesSelection/TileSelectionState.h>
|
|
5
|
+
|
|
6
|
+
namespace reactnativecesium {
|
|
7
|
+
|
|
8
|
+
void TileLifecycleManager::stampTileUsed(TileGPUResources* resources) {
|
|
9
|
+
if (resources) {
|
|
10
|
+
resources->lastUsedFrame = frameNumber_;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
bool TileLifecycleManager::shouldDeferFree(
|
|
15
|
+
const TileGPUResources* resources) const {
|
|
16
|
+
if (!resources)
|
|
17
|
+
return false;
|
|
18
|
+
return resources->lastUsedFrame >= frameNumber_;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
bool TileLifecycleManager::isRefinementLocked(
|
|
22
|
+
const Cesium3DTilesSelection::Tile& /*tile*/) const {
|
|
23
|
+
// Cesium Native guarantees that free() is not called on tiles that are
|
|
24
|
+
// currently needed for rendering (including refined parent tiles whose
|
|
25
|
+
// children are loading). Therefore, explicit refinement locking is not
|
|
26
|
+
// required here.
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
} // namespace reactnativecesium
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "../renderer/RenderTypes.hpp"
|
|
4
|
+
|
|
5
|
+
#include <Cesium3DTilesSelection/Tile.h>
|
|
6
|
+
|
|
7
|
+
#include <cstdint>
|
|
8
|
+
|
|
9
|
+
namespace reactnativecesium {
|
|
10
|
+
|
|
11
|
+
class TileLifecycleManager {
|
|
12
|
+
public:
|
|
13
|
+
uint64_t currentFrame() const { return frameNumber_; }
|
|
14
|
+
void advanceFrame() { ++frameNumber_; }
|
|
15
|
+
|
|
16
|
+
void stampTileUsed(TileGPUResources* resources);
|
|
17
|
+
|
|
18
|
+
bool shouldDeferFree(const TileGPUResources* resources) const;
|
|
19
|
+
bool isRefinementLocked(const Cesium3DTilesSelection::Tile& tile) const;
|
|
20
|
+
|
|
21
|
+
private:
|
|
22
|
+
uint64_t frameNumber_ = 0;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
} // namespace reactnativecesium
|
package/cpp/fmt/format.h
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Shadow header: must appear on the include path before Cesium Native's bundled fmt.
|
|
2
|
+
// Apple Clang rejects fmt's default FMT_STRING (consteval / FMT_COMPILE_STRING) in some
|
|
3
|
+
// spdlog helpers; runtime format strings are sufficient for this library.
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include_next <fmt/format.h>
|
|
7
|
+
|
|
8
|
+
#undef FMT_STRING
|
|
9
|
+
#define FMT_STRING(s) ::fmt::runtime(s)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "RenderTypes.hpp"
|
|
4
|
+
|
|
5
|
+
#include <glm/glm.hpp>
|
|
6
|
+
|
|
7
|
+
namespace reactnativecesium {
|
|
8
|
+
|
|
9
|
+
class IGPUBackend {
|
|
10
|
+
public:
|
|
11
|
+
virtual ~IGPUBackend() = default;
|
|
12
|
+
|
|
13
|
+
virtual void initialize(void* nativeSurface, int width, int height) = 0;
|
|
14
|
+
virtual void resize(int width, int height) = 0;
|
|
15
|
+
virtual void shutdown() = 0;
|
|
16
|
+
|
|
17
|
+
virtual void beginFrame(const FrameParams& params) = 0;
|
|
18
|
+
virtual void drawScene(const FrameResult& frame) = 0;
|
|
19
|
+
virtual void endFrame() = 0;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
} // namespace reactnativecesium
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cstdint>
|
|
4
|
+
#include <vector>
|
|
5
|
+
#include <glm/glm.hpp>
|
|
6
|
+
|
|
7
|
+
namespace reactnativecesium {
|
|
8
|
+
|
|
9
|
+
// ── CPU-side tile resources ─────────────────────────────────────────────────
|
|
10
|
+
// RTC (Relative-to-Center) layout:
|
|
11
|
+
// • rtcCenter – tile centre in absolute ECEF (double precision)
|
|
12
|
+
// • localPositions – vertex positions relative to rtcCenter (float32)
|
|
13
|
+
// Keeping positions small (~tile radius) preserves float32 precision even
|
|
14
|
+
// at planetary scale. The large camera-to-centre offset is baked into the
|
|
15
|
+
// per-tile MVP matrix using double-precision arithmetic on the CPU; only the
|
|
16
|
+
// final cast to float32 (which happens at the end of double-precision maths)
|
|
17
|
+
// introduces rounding, not the original position data.
|
|
18
|
+
// • altitudes – ellipsoid height in metres per vertex, computed on the CPU
|
|
19
|
+
// in double precision (Bowring formula in double gives sub-mm accuracy).
|
|
20
|
+
// Passed as a vertex attribute so the fragment shader never has to call
|
|
21
|
+
// ellipsoidHeightMeters(wp) — that path catastrophically cancels two ~6.4 Mm
|
|
22
|
+
// float32 values and produces ±50 m errors.
|
|
23
|
+
|
|
24
|
+
struct TilePrimitive {
|
|
25
|
+
glm::dvec3 rtcCenter; // tile RTC centre in absolute ECEF (double)
|
|
26
|
+
std::vector<glm::vec3> localPositions; // vertex positions relative to rtcCenter (float)
|
|
27
|
+
std::vector<float> altitudes; // ellipsoid height metres per vertex (float, from double)
|
|
28
|
+
std::vector<glm::vec2> uvs; // overlay UV coords (_CESIUMOVERLAY_0); empty if unavailable
|
|
29
|
+
std::vector<uint32_t> indices; // triangle list (uint32)
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
struct TileGPUResources {
|
|
33
|
+
std::vector<TilePrimitive> primitives;
|
|
34
|
+
uint64_t lastUsedFrame = 0;
|
|
35
|
+
void* overlayTexture = nullptr;
|
|
36
|
+
glm::vec2 overlayTranslation{0.0f, 0.0f};
|
|
37
|
+
glm::vec2 overlayScale{1.0f, 1.0f};
|
|
38
|
+
|
|
39
|
+
// Water mask — extracted from GLTF extras in the load thread, then converted
|
|
40
|
+
// to a GPU texture on the main thread by the platform waterMaskCreator_.
|
|
41
|
+
std::vector<uint8_t> waterMaskPixels;
|
|
42
|
+
void* waterMaskTexture = nullptr;
|
|
43
|
+
bool isOnlyWater = false;
|
|
44
|
+
glm::vec2 wmTranslation{0.0f, 0.0f};
|
|
45
|
+
float wmScale = 1.0f;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// ── Per-frame result passed from engine to renderer ─────────────────────────
|
|
49
|
+
|
|
50
|
+
struct DrawPrimitive {
|
|
51
|
+
uint32_t indexByteOffset = 0;
|
|
52
|
+
uint32_t indexCount = 0;
|
|
53
|
+
bool hasUVs = false;
|
|
54
|
+
bool isEllipsoidFallback = false;
|
|
55
|
+
void* overlayTexture = nullptr;
|
|
56
|
+
glm::vec2 overlayTranslation{0.0f, 0.0f};
|
|
57
|
+
glm::vec2 overlayScale{1.0f, 1.0f};
|
|
58
|
+
void* waterMaskTexture = nullptr;
|
|
59
|
+
bool isOnlyWater = false;
|
|
60
|
+
glm::vec4 wmTileBounds{0.0f, 0.0f, 0.0f, 0.0f};
|
|
61
|
+
glm::vec2 wmTranslation{0.0f, 0.0f};
|
|
62
|
+
float wmScale = 1.0f;
|
|
63
|
+
|
|
64
|
+
// RTC: per-tile MVP matrix (computed in double precision on the CPU,
|
|
65
|
+
// then cast to float32). Used by the vertex shader instead of the global
|
|
66
|
+
// rotation-only VP, so that the large camera↔tile-centre offset is encoded
|
|
67
|
+
// accurately without a float32 subtraction in the vertex shader.
|
|
68
|
+
glm::mat4 mvpMatrix{1.0f};
|
|
69
|
+
|
|
70
|
+
// Tile RTC centre in ECEF (float3). Passed to the fragment shader so it can
|
|
71
|
+
// reconstruct the world position as wp = localPos + rtcCenterEcef, which
|
|
72
|
+
// avoids the catastrophic cancellation of eyeRelPos + cameraEcef at altitude.
|
|
73
|
+
glm::vec3 rtcCenterEcef{0.0f};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
struct FrameResult {
|
|
77
|
+
// Merged geometry — one flat buffer, globally-offset indices.
|
|
78
|
+
// localPositions: vertex positions relative to each tile's RTC centre (float).
|
|
79
|
+
// altitudes: ellipsoid height metres per vertex (float, double-precision source).
|
|
80
|
+
std::vector<float> localPositions; // xyz per vertex (tile-local float)
|
|
81
|
+
std::vector<float> altitudes; // 1 float per vertex, ellipsoid height metres
|
|
82
|
+
std::vector<float> uvs; // uv per vertex (2 floats)
|
|
83
|
+
std::vector<uint32_t> indices;
|
|
84
|
+
|
|
85
|
+
std::vector<DrawPrimitive> draws;
|
|
86
|
+
|
|
87
|
+
// Global rotation-only VP (no translation) — used by the sky shader and for
|
|
88
|
+
// reference. Terrain tiles use per-draw mvpMatrix instead.
|
|
89
|
+
glm::mat4 vpMatrix;
|
|
90
|
+
glm::vec3 cameraEcef; // camera ECEF (float) — for sky shader
|
|
91
|
+
glm::mat4 invVP;
|
|
92
|
+
|
|
93
|
+
int tilesRendered = 0;
|
|
94
|
+
int tilesLoading = 0;
|
|
95
|
+
int tilesVisited = 0;
|
|
96
|
+
double cameraLat = 0.0;
|
|
97
|
+
double cameraLon = 0.0;
|
|
98
|
+
double cameraAlt = 0.0;
|
|
99
|
+
|
|
100
|
+
bool ionTokenConfigured = false;
|
|
101
|
+
bool tilesetActive = false;
|
|
102
|
+
double verticalFovDeg = 60.0;
|
|
103
|
+
std::vector<std::string> creditHtmlLines;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// ── Frame setup ─────────────────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
struct FrameParams {
|
|
109
|
+
glm::vec4 clearColor{0.0f, 0.0f, 0.0f, 1.0f};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
} // namespace reactnativecesium
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <glm/glm.hpp>
|
|
4
|
+
|
|
5
|
+
namespace reactnativecesium {
|
|
6
|
+
|
|
7
|
+
// NOTE: Metal float3 has 16-byte alignment in structs (same as float4).
|
|
8
|
+
// To avoid C++/Metal layout mismatch, each vec3+float pair is packed into vec4.
|
|
9
|
+
struct SceneUniforms {
|
|
10
|
+
glm::mat4 viewProjection;
|
|
11
|
+
glm::vec4 cameraPositionF; // w = earthRadius
|
|
12
|
+
glm::vec4 sunDirection; // w = atmosphereHeight
|
|
13
|
+
glm::vec4 atmosphereColor; // w = (unused, pad)
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Metal float3x3 columns are each 16 bytes (same as float4).
|
|
17
|
+
// Store matrices as three float4 columns to avoid C++/Metal layout mismatch.
|
|
18
|
+
struct TileUniforms {
|
|
19
|
+
glm::vec4 rtcCenterHigh; // .w = 0 (pad)
|
|
20
|
+
glm::vec4 rtcCenterLow; // .w = 0 (pad)
|
|
21
|
+
glm::vec4 rotCol0; // rotation matrix col 0, .w = 0
|
|
22
|
+
glm::vec4 rotCol1; // rotation matrix col 1, .w = 0
|
|
23
|
+
glm::vec4 rotCol2; // rotation matrix col 2, .w = 0
|
|
24
|
+
glm::vec4 normalCol0; // normalMatrix col 0, .w = 0
|
|
25
|
+
glm::vec4 normalCol1; // normalMatrix col 1, .w = 0
|
|
26
|
+
glm::vec4 normalCol2; // normalMatrix col 2, .w = 0
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
} // namespace reactnativecesium
|