From ddb5cb62fce210162960220b2010455edde1e279 Mon Sep 17 00:00:00 2001 From: Onur Er Date: Sat, 28 Jun 2025 22:21:19 -0700 Subject: [PATCH 1/2] Calculated the bounds of the imported SkinnedMeshRenderer. --- Runtime/Scripts/GLTFSceneImporter.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Runtime/Scripts/GLTFSceneImporter.cs b/Runtime/Scripts/GLTFSceneImporter.cs index 1022a8850..b4cd94bf3 100644 --- a/Runtime/Scripts/GLTFSceneImporter.cs +++ b/Runtime/Scripts/GLTFSceneImporter.cs @@ -1008,7 +1008,18 @@ protected virtual async Task ConstructNode(Node node, int nodeIndex, Cancellatio nodeObj.transform.localRotation = rotation; nodeObj.transform.localScale = scale; - + Bounds TransformBounds(Matrix4x4 matrix, Bounds bounds) + { + var extents = bounds.extents; + var ax = matrix.MultiplyVector(new Vector3(extents.x, 0, 0)); + var ay = matrix.MultiplyVector(new Vector3(0, extents.y, 0)); + var az = matrix.MultiplyVector(new Vector3(0, 0, extents.z)); + var x = Mathf.Abs(ax.x) + Mathf.Abs(ay.x) + Mathf.Abs(az.x); + var y = Mathf.Abs(ax.y) + Mathf.Abs(ay.y) + Mathf.Abs(az.y); + var z = Mathf.Abs(ax.z) + Mathf.Abs(ay.z) + Mathf.Abs(az.z); + + return new Bounds(matrix.MultiplyPoint3x4(bounds.center), new Vector3(x, y, z) * 2f); + } async Task CreateNodeComponentsAndChilds(bool ignoreMesh = false, bool onlyMesh = false) { @@ -1048,8 +1059,10 @@ async Task CreateNodeComponentsAndChilds(bool ignoreMesh = false, bool onlyMesh if (node.Skin != null) await SetupBones(node.Skin.Value, renderer, cancellationToken); - // morph target weights - if (weights != null) + renderer.localBounds = renderer.rootBone == null ? unityMesh.bounds : TransformBounds(renderer.rootBone.worldToLocalMatrix * renderer.transform.localToWorldMatrix, unityMesh.bounds); + + // morph target weights + if (weights != null) { for (int i = 0; i < weights.Count; ++i) { From 8e47bb07011c36491225d68fa900e9bb8c68de8d Mon Sep 17 00:00:00 2001 From: Onur Er Date: Thu, 8 Jan 2026 00:33:48 -0800 Subject: [PATCH 2/2] Fixed SkinnedMeshRenderer bounding box calculation. --- Editor/Scripts/GLTFImporter.cs | 1 + Runtime/Scripts/GLTFSceneImporter.cs | 49 ++++++++++++++++++---------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Editor/Scripts/GLTFImporter.cs b/Editor/Scripts/GLTFImporter.cs index 44310c44b..9069b8ba0 100644 --- a/Editor/Scripts/GLTFImporter.cs +++ b/Editor/Scripts/GLTFImporter.cs @@ -956,6 +956,7 @@ private void CreateGLTFScene(GLTFImportContext context, out GameObject scene, BlendShapeFrameWeight = _blendShapeFrameWeight, CameraImport = _importCamera, DeduplicateResources = _deduplicateResources, + ScaleFactor = _scaleFactor, }; using (var stream = File.OpenRead(projectFilePath)) diff --git a/Runtime/Scripts/GLTFSceneImporter.cs b/Runtime/Scripts/GLTFSceneImporter.cs index b4cd94bf3..2aec26644 100644 --- a/Runtime/Scripts/GLTFSceneImporter.cs +++ b/Runtime/Scripts/GLTFSceneImporter.cs @@ -62,11 +62,12 @@ public class ImportOptions public CameraImportOption CameraImport = CameraImportOption.ImportAndCameraDisabled; public RuntimeTextureCompression RuntimeTextureCompression = RuntimeTextureCompression.None; public BlendShapeFrameWeightSetting BlendShapeFrameWeight = new BlendShapeFrameWeightSetting(BlendShapeFrameWeightSetting.MultiplierOption.Multiplier1); + public float ScaleFactor = 1; #if UNITY_EDITOR public GLTFImportContext ImportContext = new GLTFImportContext(null, GLTFSettings.GetOrCreateSettings()); #else - public GLTFImportContext ImportContext = new GLTFImportContext(GLTFSettings.GetOrCreateSettings()); + public GLTFImportContext ImportContext = new GLTFImportContext(GLTFSettings.GetOrCreateSettings()); #endif [NonSerialized] @@ -1008,19 +1009,6 @@ protected virtual async Task ConstructNode(Node node, int nodeIndex, Cancellatio nodeObj.transform.localRotation = rotation; nodeObj.transform.localScale = scale; - Bounds TransformBounds(Matrix4x4 matrix, Bounds bounds) - { - var extents = bounds.extents; - var ax = matrix.MultiplyVector(new Vector3(extents.x, 0, 0)); - var ay = matrix.MultiplyVector(new Vector3(0, extents.y, 0)); - var az = matrix.MultiplyVector(new Vector3(0, 0, extents.z)); - var x = Mathf.Abs(ax.x) + Mathf.Abs(ay.x) + Mathf.Abs(az.x); - var y = Mathf.Abs(ax.y) + Mathf.Abs(ay.y) + Mathf.Abs(az.y); - var z = Mathf.Abs(ax.z) + Mathf.Abs(ay.z) + Mathf.Abs(az.z); - - return new Bounds(matrix.MultiplyPoint3x4(bounds.center), new Vector3(x, y, z) * 2f); - } - async Task CreateNodeComponentsAndChilds(bool ignoreMesh = false, bool onlyMesh = false) { // If we're creating a really large node, we need it to not be visible in partial stages. So we hide it while we create it @@ -1059,7 +1047,21 @@ async Task CreateNodeComponentsAndChilds(bool ignoreMesh = false, bool onlyMesh if (node.Skin != null) await SetupBones(node.Skin.Value, renderer, cancellationToken); - renderer.localBounds = renderer.rootBone == null ? unityMesh.bounds : TransformBounds(renderer.rootBone.worldToLocalMatrix * renderer.transform.localToWorldMatrix, unityMesh.bounds); + // calculate SkinnedMeshRenderer local bounds by applying bone transforms to make it consistent with Unity's FBX importer effectively fixing: https://github.com/KhronosGroup/UnityGLTF/issues/876 + if (renderer.rootBone == null) renderer.localBounds = unityMesh.bounds; + else + { + var bakedMesh = new Mesh(); + renderer.BakeMesh(bakedMesh, true); + + var bounds = TransformBounds(renderer.rootBone.worldToLocalMatrix * renderer.transform.localToWorldMatrix, bakedMesh.bounds); + bounds.center *= _options.ScaleFactor; + bounds.size *= _options.ScaleFactor; + + renderer.localBounds = bounds; + + Object.DestroyImmediate(bakedMesh); + } // morph target weights if (weights != null) @@ -1219,8 +1221,21 @@ async Task CreateNodeComponentsAndChilds(bool ignoreMesh = false, bool onlyMesh progressStatus.NodeLoaded++; progress?.Report(progressStatus); } - - private async Task ConstructBufferData(Node node, CancellationToken cancellationToken) + + Bounds TransformBounds(Matrix4x4 matrix, Bounds bounds) + { + var extents = bounds.extents; + var ax = matrix.MultiplyVector(new Vector3(extents.x, 0, 0)); + var ay = matrix.MultiplyVector(new Vector3(0, extents.y, 0)); + var az = matrix.MultiplyVector(new Vector3(0, 0, extents.z)); + var x = Mathf.Abs(ax.x) + Mathf.Abs(ay.x) + Mathf.Abs(az.x); + var y = Mathf.Abs(ax.y) + Mathf.Abs(ay.y) + Mathf.Abs(az.y); + var z = Mathf.Abs(ax.z) + Mathf.Abs(ay.z) + Mathf.Abs(az.z); + + return new Bounds(matrix.MultiplyPoint3x4(bounds.center), new Vector3(x, y, z) * 2f); + } + + private async Task ConstructBufferData(Node node, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested();