From 9aa3029c0551d9e108eaff6fad621ab8d8b31a27 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Mon, 25 Apr 2022 23:29:09 +0800 Subject: [PATCH 1/2] fix: animator play error when blendShape count 1 --- .../loader/src/gltf/parser/AnimationParser.ts | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/packages/loader/src/gltf/parser/AnimationParser.ts b/packages/loader/src/gltf/parser/AnimationParser.ts index 819eea27a1..c20bb7db0b 100644 --- a/packages/loader/src/gltf/parser/AnimationParser.ts +++ b/packages/loader/src/gltf/parser/AnimationParser.ts @@ -4,6 +4,7 @@ import { Component, Entity, InterpolableKeyframe, + InterpolableValueType, InterpolationType, SkinnedMeshRenderer, Transform, @@ -88,27 +89,32 @@ export class AnimationParser extends Parser { let compType: new (entity: Entity) => Component; let propertyName: string; + let interpolableValueType: InterpolableValueType; switch (target.path) { case AnimationChannelTargetPath.TRANSLATION: compType = Transform; propertyName = "position"; + interpolableValueType = InterpolableValueType.Vector3; break; case AnimationChannelTargetPath.ROTATION: compType = Transform; propertyName = "rotation"; + interpolableValueType = InterpolableValueType.Quaternion; break; case AnimationChannelTargetPath.SCALE: compType = Transform; propertyName = "scale"; + interpolableValueType = InterpolableValueType.Vector3; break; case AnimationChannelTargetPath.WEIGHTS: compType = SkinnedMeshRenderer; propertyName = "blendShapeWeights"; + interpolableValueType = InterpolableValueType.FloatArray; break; default: } - const curve = this._addCurve(gltfChannel, sampleDataCollection); + const curve = this._addCurve(interpolableValueType, gltfChannel, sampleDataCollection); animationClip.addCurveBinding(relativePath, compType, propertyName, curve); } @@ -123,42 +129,54 @@ export class AnimationParser extends Parser { context._animationsIndices = animationsIndices; } - private _addCurve(gltfChannel: IAnimationChannel, sampleDataCollection: SampleData[]): AnimationCurve { + private _addCurve( + interpolableValueType: InterpolableValueType, + gltfChannel: IAnimationChannel, + sampleDataCollection: SampleData[] + ): AnimationCurve { const curve = new AnimationCurve(); const sampleData = sampleDataCollection[gltfChannel.sampler]; - const { type, input, output, outputSize } = sampleData; + const { input, output, outputSize } = sampleData; curve.interpolation = sampleData.interpolation; for (let j = 0, n = input.length; j < n; j++) { const offset = j * outputSize; - if (type === AccessorType.SCALAR) { - let keyframe = - outputSize > 1 - ? new InterpolableKeyframe() - : new InterpolableKeyframe(); + if (interpolableValueType === InterpolableValueType.Float) { + let keyframe = new InterpolableKeyframe(); keyframe.time = input[j]; keyframe.inTangent = 0; keyframe.outTangent = 0; - keyframe.value = outputSize > 1 ? output.subarray(offset, offset + outputSize) : output[offset]; + keyframe.value = output[offset]; curve.addKey(keyframe); - } - if (type === AccessorType.VEC2) { + } else if (interpolableValueType === InterpolableValueType.FloatArray) { + let keyframe = new InterpolableKeyframe(); + keyframe.time = input[j]; + keyframe.inTangent = new Float32Array(outputSize); + keyframe.outTangent = new Float32Array(outputSize); + keyframe.value = output.subarray(offset, offset + outputSize); + curve.addKey(keyframe); + } else if (interpolableValueType === InterpolableValueType.Vector2) { const keyframe = new InterpolableKeyframe(); keyframe.time = input[j]; keyframe.value = new Vector2(output[offset], output[offset + 1]); keyframe.inTangent = new Vector2(); keyframe.outTangent = new Vector2(); curve.addKey(keyframe); - } - if (type === AccessorType.VEC3) { + } else if (interpolableValueType === InterpolableValueType.Vector3) { const keyframe = new InterpolableKeyframe(); keyframe.time = input[j]; keyframe.value = new Vector3(output[offset], output[offset + 1], output[offset + 2]); keyframe.inTangent = new Vector3(); keyframe.outTangent = new Vector3(); curve.addKey(keyframe); - } - if (type === AccessorType.VEC4) { + } else if (interpolableValueType === InterpolableValueType.Vector4) { + const keyframe = new InterpolableKeyframe(); + keyframe.time = input[j]; + keyframe.value = new Vector4(output[offset], output[offset + 1], output[offset + 2], output[offset + 3]); + keyframe.inTangent = new Vector4(); + keyframe.outTangent = new Vector4(); + curve.addKey(keyframe); + } else if (interpolableValueType === InterpolableValueType.Quaternion) { const keyframe = new InterpolableKeyframe(); keyframe.time = input[j]; keyframe.value = new Quaternion(output[offset], output[offset + 1], output[offset + 2], output[offset + 3]); @@ -170,7 +188,6 @@ export class AnimationParser extends Parser { return curve; } } - interface SampleData { type: AccessorType; input: TypedArray; From 3bdd5d55bbe0050394f1c0b792c4c7122d5b1ebc Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Tue, 26 Apr 2022 10:51:22 +0800 Subject: [PATCH 2/2] types: use const instead let --- packages/loader/src/gltf/parser/AnimationParser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/loader/src/gltf/parser/AnimationParser.ts b/packages/loader/src/gltf/parser/AnimationParser.ts index c20bb7db0b..5adf2b23d4 100644 --- a/packages/loader/src/gltf/parser/AnimationParser.ts +++ b/packages/loader/src/gltf/parser/AnimationParser.ts @@ -142,14 +142,14 @@ export class AnimationParser extends Parser { for (let j = 0, n = input.length; j < n; j++) { const offset = j * outputSize; if (interpolableValueType === InterpolableValueType.Float) { - let keyframe = new InterpolableKeyframe(); + const keyframe = new InterpolableKeyframe(); keyframe.time = input[j]; keyframe.inTangent = 0; keyframe.outTangent = 0; keyframe.value = output[offset]; curve.addKey(keyframe); } else if (interpolableValueType === InterpolableValueType.FloatArray) { - let keyframe = new InterpolableKeyframe(); + const keyframe = new InterpolableKeyframe(); keyframe.time = input[j]; keyframe.inTangent = new Float32Array(outputSize); keyframe.outTangent = new Float32Array(outputSize);