From 2d36729ef5723504e8e008830a442d66d38e8a54 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Sat, 21 Dec 2024 01:09:11 +1100 Subject: [PATCH 1/4] Fix logic for copying colors to duplicated vertices. --- native~/Runtime/src/UnityPrepareRendererResources.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/native~/Runtime/src/UnityPrepareRendererResources.cpp b/native~/Runtime/src/UnityPrepareRendererResources.cpp index 28645189..51adfccb 100644 --- a/native~/Runtime/src/UnityPrepareRendererResources.cpp +++ b/native~/Runtime/src/UnityPrepareRendererResources.cpp @@ -161,11 +161,11 @@ template struct CopyVertexColors { bool success = true; if (duplicateVertices) { for (size_t i = 0; success && i < vertexCount; ++i) { - if (i >= colorView.size()) { + TIndex vertexIndex = indices[i]; + if (vertexIndex < 0 || vertexIndex >= colorView.size()) { success = false; } else { Color32& packedColor = *reinterpret_cast(pWritePos); - TIndex vertexIndex = indices[i]; success = CopyVertexColors::convertColor( colorView[vertexIndex], packedColor); From 966a5e966260f3468d56acd503171a9908a7e654 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 23 Dec 2024 17:45:21 +1100 Subject: [PATCH 2/4] Upgrade to UINT32 indices when necessary. --- CHANGES.md | 2 + Tests/TestCesium3DTileset.cs | 43 +++++++++++++++ .../src/UnityPrepareRendererResources.cpp | 55 +++++++++++++------ native~/extern/cesium-native | 2 +- 4 files changed, 83 insertions(+), 19 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 51d33e96..8d2ca5b0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,8 @@ ##### Fixes :wrench: - Fixed a bug that could cause a crash or incorrect textures when multiple `Cesium3DTileset` tiles referenced the same image by URL. +- Fixed a bug that could cause incorrect colors in a model that did have vertex colors but did not have normals. +- Fixed a bug that could cause a hang when attempting to load a model with UINT16 indices where generating flat normals required more than 2^16 vertices. ## v1.14.0 - 2024-12-02 diff --git a/Tests/TestCesium3DTileset.cs b/Tests/TestCesium3DTileset.cs index 3a174a4c..df440ab7 100644 --- a/Tests/TestCesium3DTileset.cs +++ b/Tests/TestCesium3DTileset.cs @@ -156,4 +156,47 @@ public IEnumerator SampleHeightMostDetailedFailsIfTilesetFailsToLoad() Assert.IsTrue(result.warnings[0].Contains("failed to load")); } + + [UnityTest] + public IEnumerator UpgradeToLargerIndexType() + { + // This tileset has no normals, so we need to generate flat normals for it. + // When we do that, an index buffer will need to change from uint16 to uint32. + GameObject goGeoreference = new GameObject(); + goGeoreference.name = "Georeference"; + CesiumGeoreference georeference = goGeoreference.AddComponent(); + + GameObject goTileset = new GameObject(); + goTileset.name = "Snowdon Towers No Normals"; + goTileset.transform.parent = goGeoreference.transform; + + Cesium3DTileset tileset = goTileset.AddComponent(); + CesiumCameraManager cameraManager = goTileset.AddComponent(); + tileset.ionAccessToken = Environment.GetEnvironmentVariable("CESIUM_ION_TOKEN_FOR_TESTS") ?? ""; + tileset.ionAssetID = 2887128; + + georeference.SetOriginLongitudeLatitudeHeight(-79.88602625, 40.02228799, 222.65); + + GameObject goCamera = new GameObject(); + goCamera.name = "Camera"; + goCamera.transform.parent = goGeoreference.transform; + + Camera camera = goCamera.AddComponent(); + CesiumGlobeAnchor cameraAnchor = goCamera.AddComponent(); + + cameraManager.useMainCamera = false; + cameraManager.useSceneViewCameraInEditor = false; + cameraManager.additionalCameras.Add(camera); + + camera.pixelRect = new Rect(0, 0, 128, 96); + camera.fieldOfView = 60.0f; + cameraAnchor.longitudeLatitudeHeight = new double3(-79.88593359, 40.02255615, 242.0224); + camera.transform.LookAt(new Vector3(0.0f, 0.0f, 0.0f)); + + // Make sure we can load all tiles successfully. + while (tileset.ComputeLoadProgress() < 100.0f) + { + yield return null; + } + } } \ No newline at end of file diff --git a/native~/Runtime/src/UnityPrepareRendererResources.cpp b/native~/Runtime/src/UnityPrepareRendererResources.cpp index 51adfccb..141c921c 100644 --- a/native~/Runtime/src/UnityPrepareRendererResources.cpp +++ b/native~/Runtime/src/UnityPrepareRendererResources.cpp @@ -347,6 +347,43 @@ void loadPrimitive( return; } + const CesiumGltf::Material* pMaterial = + Model::getSafe(&gltf.materials, primitive.material); + + primitiveInfo.isUnlit = + pMaterial && pMaterial->hasExtension(); + + bool hasNormals = false; + bool computeFlatNormals = false; + auto normalAccessorIt = primitive.attributes.find("NORMAL"); + AccessorView normalView; + if (normalAccessorIt != primitive.attributes.end()) { + normalView = + AccessorView(gltf, normalAccessorIt->second); + hasNormals = normalView.status() == AccessorViewStatus::Valid; + } else if ( + !primitiveInfo.isUnlit && primitive.mode != MeshPrimitive::Mode::POINTS) { + computeFlatNormals = hasNormals = true; + } + + // Check if we need to upgrade to a large index type to accommodate the + // larger number of vertices we need for flat normals. + if (computeFlatNormals && indexFormat == IndexFormat::UInt16 && + indexCount >= std::numeric_limits::max()) { + loadPrimitive( + meshData, + primitiveInfo, + gltf, + node, + mesh, + primitive, + transform, + indicesView, + IndexFormat::UInt32, + positionView); + return; + } + meshData.SetIndexBufferParams(indexCount, indexFormat); const Unity::Collections::NativeArray1& dest = meshData.GetIndexData(); @@ -399,25 +436,7 @@ void loadPrimitive( descriptor[numberOfAttributes].stream = streamIndex; ++numberOfAttributes; - const CesiumGltf::Material* pMaterial = - Model::getSafe(&gltf.materials, primitive.material); - - primitiveInfo.isUnlit = - pMaterial && pMaterial->hasExtension(); - // Add the NORMAL attribute, if it exists. - bool hasNormals = false; - bool computeFlatNormals = false; - auto normalAccessorIt = primitive.attributes.find("NORMAL"); - AccessorView normalView; - if (normalAccessorIt != primitive.attributes.end()) { - normalView = - AccessorView(gltf, normalAccessorIt->second); - hasNormals = normalView.status() == AccessorViewStatus::Valid; - } else if ( - !primitiveInfo.isUnlit && primitive.mode != MeshPrimitive::Mode::POINTS) { - computeFlatNormals = hasNormals = true; - } if (hasNormals) { assert(numberOfAttributes < MAX_ATTRIBUTES); descriptor[numberOfAttributes].attribute = VertexAttribute::Normal; diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index 1ece56de..bf99d52e 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit 1ece56deca0cb068e720ae67ae716fe80ec231ac +Subproject commit bf99d52e650469b29fca9674c40524fb6c06adba From 850b9bca369649712b1ac40309aa325fb8278a3f Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 23 Dec 2024 18:27:14 +1100 Subject: [PATCH 3/4] Update cesium-native. --- native~/extern/cesium-native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index bf99d52e..07fcaf62 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit bf99d52e650469b29fca9674c40524fb6c06adba +Subproject commit 07fcaf620381874ef936d0a8ae0296f24e5bcc9d From 79030397346ceb8e393a9399dd7079bedfc54d52 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Wed, 1 Jan 2025 23:17:02 +1100 Subject: [PATCH 4/4] Update cesium-native. --- native~/extern/cesium-native | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native~/extern/cesium-native b/native~/extern/cesium-native index 07fcaf62..3f1ea268 160000 --- a/native~/extern/cesium-native +++ b/native~/extern/cesium-native @@ -1 +1 @@ -Subproject commit 07fcaf620381874ef936d0a8ae0296f24e5bcc9d +Subproject commit 3f1ea268763eff1ce4e6e8409c9adc477c5e0564