Pārlūkot izejas kodu

Fix returnToRest() for glTF imported Skeletons (#8589)

* This change modifies the gltf loader to now properly initialize a Bone's rest pose transform on gltfLoader._updateBoneMatrices(), and exposes a setter for Bone.restPose

* what's new

* Add additional logic to `Skeleton.returnToRest()` to reset each bone's linked transform nodes. Modify `Bone.returnToMesh()` to no longer modify absolute matrices

* Fix linting error
Nicholas Barlow 5 gadi atpakaļ
vecāks
revīzija
d0fc663ed7

+ 1 - 0
dist/preview release/what's new.md

@@ -266,6 +266,7 @@
 - Fix crash with CSG when no uvs defined ([Popov72](https://github.com/Popov72))
 - Fix an issue causing views to render blank when scene rendering is skipped for a given iteration of the render loop ([elInfidel](https://github.com/elInfidel))
 - Fix docs Matrix.RotationYawPitchRoll and Matrix.RotationYawPitchRollToRef ([VSerain](https://github.com/VSerain))
+- Fix issue in `GLTFLoader._updateBoneMatrices()` where bone rest position was not set. ([drigax](https://github.com/drigax))
 
 ## Breaking changes
 

+ 1 - 0
loaders/src/glTF/2.0/glTFLoader.ts

@@ -1125,6 +1125,7 @@ export class GLTFLoader implements IGLTFLoader {
                 baseMatrix.multiplyToRef(babylonParentBone.getInvertedAbsoluteTransform(), baseMatrix);
             }
 
+            babylonBone.setRestPose(baseMatrix);
             babylonBone.updateMatrix(baseMatrix, false, false);
             babylonBone._updateDifferenceMatrix(undefined, false);
         }

+ 9 - 1
src/Bones/bone.ts

@@ -205,6 +205,14 @@ export class Bone extends Node {
     }
 
     /**
+     * Sets the rest pose matrix
+     * @param matrix the local-space rest pose to set for this bone
+     */
+    public setRestPose(matrix: Matrix): void {
+        this._restPose.copyFrom(matrix);
+    }
+
+    /**
      * Gets a matrix used to store world matrix (ie. the matrix sent to shaders)
      */
     public getWorldMatrix(): Matrix {
@@ -215,7 +223,7 @@ export class Bone extends Node {
      * Sets the local matrix to rest pose matrix
      */
     public returnToRest(): void {
-        this.updateMatrix(this._restPose.clone());
+        this.updateMatrix(this._restPose.clone(), false, false);
     }
 
     /**

+ 16 - 1
src/Bones/skeleton.ts

@@ -354,8 +354,23 @@ export class Skeleton implements IAnimatable {
      * Forces the skeleton to go to rest pose
      */
     public returnToRest(): void {
+        const _localScaling = TmpVectors.Vector3[0];
+        const _localRotation = TmpVectors.Quaternion[0];
+        const _localPosition = TmpVectors.Vector3[1];
+
         for (var index = 0; index < this.bones.length; index++) {
-            this.bones[index].returnToRest();
+            const bone = this.bones[index];
+
+            if (bone._index !== -1) {
+                bone.returnToRest();
+                if (bone._linkedTransformNode) {
+                    bone.getRestPose().decompose(_localScaling, _localRotation, _localPosition);
+
+                    bone._linkedTransformNode.position = _localPosition.clone();
+                    bone._linkedTransformNode.rotationQuaternion = _localRotation.clone();
+                    bone._linkedTransformNode.scaling = _localScaling.clone();
+                }
+            }
         }
     }