diff --git a/src/GPUTileHandler.cs b/src/GPUTileHandler.cs index 5d0c6ef..0ec16c9 100644 --- a/src/GPUTileHandler.cs +++ b/src/GPUTileHandler.cs @@ -14,6 +14,7 @@ using Wkx; namespace i3dm.export; + public static class GPUTileHandler { public static void SaveGPUTile(string filePath, List instances, bool UseScaleNonUniform, bool keepProjection = false) @@ -119,12 +120,25 @@ private static SceneBuilder AddModels(IEnumerable instances, Point tra foreach (var model in distinctModels) { var modelPath = (string)model; - var modelRoot = ModelRoot.Load(modelPath); - ExternalTextureHelper.CollectExternalTextures(externalTextures, modelPath, modelRoot); + try + { + var modelRoot = ModelRoot.Load(modelPath); + + ExternalTextureHelper.CollectExternalTextures(externalTextures, modelPath, modelRoot); + + var meshNodeCount = AddModelInstancesToScene(sceneBuilder, instances, UseScaleNonUniform, translation, modelPath, modelRoot, keepProjection); + if (meshNodeCountsByModel != null) meshNodeCountsByModel[modelPath] = meshNodeCount; + } + catch (SharpGLTF.Validation.LinkException ex) + { + if (ex.Message.Contains("draco")) + { + throw new InvalidOperationException($"The model '{modelPath}' uses Draco compression, which is not supported for GPU instancing. Please re-export the model without Draco compression and try again.", ex); + } - var meshNodeCount = AddModelInstancesToScene(sceneBuilder, instances, UseScaleNonUniform, translation, modelPath, modelRoot, keepProjection); - if (meshNodeCountsByModel != null) meshNodeCountsByModel[modelPath] = meshNodeCount; + throw ex; + } } return sceneBuilder; @@ -195,19 +209,19 @@ private static AffineTransform GetInstanceTransform(Instance instance, bool UseS { // Cartesian mode: positions are in local XYZ coordinates (X=East, Y=North, Z=Up) // Transform to glTF Y-up space - + // Position: transform from Cartesian XYZ to Y-up, then compute offset from RTC var cartesianPos = new Vector3( - (float)point.X, - (float)point.Y, + (float)point.X, + (float)point.Y, (float)point.Z.GetValueOrDefault()); - + var cartesianPosYUp = ToYUp(cartesianPos); - + // translation is already in Y-up format (ToYUp applied in BuildGpuModel) position2 = new Vector3( cartesianPosYUp.X - (float)translation.X, - cartesianPosYUp.Y - (float)translation.Y, + cartesianPosYUp.Y - (float)translation.Y, cartesianPosYUp.Z - (float)translation.Z); // Rotation: apply yaw/pitch/roll in local Cartesian frame