diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index f6bee0ee3..00b5e604c 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -842,19 +842,33 @@ static void loadPrimitive( const std::vector& max = positionAccessor.max; glm::dvec3 minPosition{std::numeric_limits::max()}; glm::dvec3 maxPosition{std::numeric_limits::lowest()}; - if (min.size() != 3 || max.size() != 3) { - for (int32_t i = 0; i < positionView.size(); ++i) { - minPosition.x = glm::min(minPosition.x, positionView[i].X); - minPosition.y = glm::min(minPosition.y, positionView[i].Y); - minPosition.z = glm::min(minPosition.z, positionView[i].Z); - - maxPosition.x = glm::max(maxPosition.x, positionView[i].X); - maxPosition.y = glm::max(maxPosition.y, positionView[i].Y); - maxPosition.z = glm::max(maxPosition.z, positionView[i].Z); + if (!options.sharedPositions) { + if (min.size() != 3 || max.size() != 3) { + for (int32_t i = 0; i < positionView.size(); ++i) { + minPosition.x = glm::min(minPosition.x, positionView[i].X); + minPosition.y = glm::min(minPosition.y, positionView[i].Y); + minPosition.z = glm::min(minPosition.z, positionView[i].Z); + + maxPosition.x = glm::max(maxPosition.x, positionView[i].X); + maxPosition.y = glm::max(maxPosition.y, positionView[i].Y); + maxPosition.z = glm::max(maxPosition.z, positionView[i].Z); + } + } else { + minPosition = glm::dvec3(min[0], min[1], min[2]); + maxPosition = glm::dvec3(max[0], max[1], max[2]); } } else { - minPosition = glm::dvec3(min[0], min[1], min[2]); - maxPosition = glm::dvec3(max[0], max[1], max[2]); + for (int32_t i = 0; i < indicesView.size(); ++i) { + const uint32 index = indicesView[i]; + + minPosition.x = glm::min(minPosition.x, positionView[index].X); + minPosition.y = glm::min(minPosition.y, positionView[index].Y); + minPosition.z = glm::min(minPosition.z, positionView[index].Z); + + maxPosition.x = glm::max(maxPosition.x, positionView[index].X); + maxPosition.y = glm::max(maxPosition.y, positionView[index].Y); + maxPosition.z = glm::max(maxPosition.z, positionView[index].Z); + } } #if ENGINE_MAJOR_VERSION >= 5 @@ -1387,7 +1401,39 @@ static void loadMesh( result = LoadMeshResult(); result->primitiveResults.reserve(mesh.primitives.size()); for (const CesiumGltf::MeshPrimitive& primitive : mesh.primitives) { - CreatePrimitiveOptions primitiveOptions = {&options, &*result, &primitive}; + bool sharedPositions = false; + + if (primitive.indices >= 0) { + auto positionAccessorIt = primitive.attributes.find("POSITION"); + if (positionAccessorIt == primitive.attributes.end()) { + // This primitive doesn't have a POSITION semantic, ignore it. + continue; + } + + int positionAccessorID = positionAccessorIt->second; + + for (const CesiumGltf::MeshPrimitive& otherPrimitive : mesh.primitives) { + if (&primitive == &otherPrimitive) { + continue; + } + + auto otherPositionAccessorIt = + otherPrimitive.attributes.find("POSITION"); + if (otherPositionAccessorIt == otherPrimitive.attributes.end()) { + // This primitive doesn't have a POSITION semantic, ignore it. + continue; + } + + int otherPositionAccessorID = otherPositionAccessorIt->second; + + if (positionAccessorID == otherPositionAccessorID) { + sharedPositions = true; + break; + } + } + } + + CreatePrimitiveOptions primitiveOptions = {&options, &*result, &primitive, sharedPositions}; auto& primitiveResult = result->primitiveResults.emplace_back(); loadPrimitive(primitiveResult, transform, primitiveOptions); @@ -1913,8 +1959,10 @@ static void loadPrimitiveGameThreadPart( RF_Transient | RF_DuplicateTransient | RF_TextExportTransient); pMesh->pModel = loadResult.pModel; pMesh->pMeshPrimitive = loadResult.pMeshPrimitive; - pMesh->boundingVolume = boundingVolume; pMesh->SetRenderCustomDepth(pGltf->CustomDepthParameters.RenderCustomDepth); + if (!createNavCollision) { + pMesh->boundingVolume = boundingVolume; + } pMesh->SetCustomDepthStencilWriteMask( pGltf->CustomDepthParameters.CustomDepthStencilWriteMask); pMesh->SetCustomDepthStencilValue( diff --git a/Source/CesiumRuntime/Private/CreateGltfOptions.h b/Source/CesiumRuntime/Private/CreateGltfOptions.h index 8949db19b..0c8dff9b7 100644 --- a/Source/CesiumRuntime/Private/CreateGltfOptions.h +++ b/Source/CesiumRuntime/Private/CreateGltfOptions.h @@ -40,5 +40,6 @@ struct CreatePrimitiveOptions { const CreateMeshOptions* pMeshOptions = nullptr; const LoadGltfResult::LoadMeshResult* pHalfConstructedMeshResult = nullptr; const CesiumGltf::MeshPrimitive* pPrimitive = nullptr; + const bool sharedPositions = false; }; } // namespace CreateGltfOptions