diff --git a/plugins/default/model/components/ModelRenderer.ts b/plugins/default/model/components/ModelRenderer.ts index 950211e70..0e36afeaf 100644 --- a/plugins/default/model/components/ModelRenderer.ts +++ b/plugins/default/model/components/ModelRenderer.ts @@ -21,6 +21,13 @@ interface Animation { keyFrames: AnimationKeyFrames; } +interface AnimationItem { + name: string; + time?: number; + looping?: boolean; + ignoreBoneNameFilter?: RegExp; +} + function getInterpolationData(keyFrames: any[], time: number) { let prevKeyFrame = keyFrames[keyFrames.length - 1]; @@ -287,6 +294,24 @@ export default class ModelRenderer extends SupEngine.ActorComponent { return; } + setMultipleAnimations(newAnimationItemList: Array) { + for (let i = 0; i < newAnimationItemList.length; i++) { + let newAnimationItem = newAnimationItemList[i]; + let newAnimation = this.animationsByName[newAnimationItem.name]; + if (newAnimation == null) throw new Error(`Animation ${newAnimationItem.name} doesn't exist`); + this.animation = newAnimation; + this.animationLooping = newAnimationItem.looping ? true : false; + let time = newAnimationItem.time; + if (typeof time === "number") { + if (time < 0 || time > this.getAnimationDuration()) throw new Error("Invalid time"); + this.animationTimer = time * this.actor.gameInstance.framesPerSecond; + } + this.isAnimationPlaying = true; + this.updatePose(newAnimationItem.ignoreBoneNameFilter); + } + return; + } + getAnimation(): string { return (this.animation != null) ? this.animation.name : null; } setAnimationTime(time: number) { @@ -341,7 +366,7 @@ export default class ModelRenderer extends SupEngine.ActorComponent { return { position, orientation, scale }; } - updatePose() { + updatePose(ignoreBoneNameFilter?: RegExp) { this.hasPoseBeenUpdated = true; // TODO: this.asset.speedMultiplier @@ -361,7 +386,7 @@ export default class ModelRenderer extends SupEngine.ActorComponent { for (let i = 0; i < (this.threeMesh).skeleton.bones.length; i++) { let bone = (this.threeMesh).skeleton.bones[i]; let boneKeyFrames = this.animation.keyFrames[bone.name]; - if (boneKeyFrames == null) continue; + if (boneKeyFrames == null || (ignoreBoneNameFilter && ignoreBoneNameFilter.test(bone.name))) continue; if (boneKeyFrames.translation != null) { let { prevKeyFrame, nextKeyFrame, t } = getInterpolationData(boneKeyFrames.translation, time); diff --git a/plugins/default/model/typescriptAPI/Sup.ModelRenderer.d.ts.txt b/plugins/default/model/typescriptAPI/Sup.ModelRenderer.d.ts.txt index 66012747a..78f007ddb 100644 --- a/plugins/default/model/typescriptAPI/Sup.ModelRenderer.d.ts.txt +++ b/plugins/default/model/typescriptAPI/Sup.ModelRenderer.d.ts.txt @@ -1,3 +1,10 @@ +interface AnimationItem { + name: string; + time?: number; + looping?: boolean; + ignoreBoneNameFilter?: RegExp; +} + declare namespace Sup { class ModelRenderer extends ActorComponent { constructor(actor: Actor, pathOrAsset?: string|Model); @@ -23,6 +30,7 @@ declare namespace Sup { setAnimationTime(time: number): ModelRenderer; getAnimationTime(): number; getAnimationDuration(): number; + setMultipleAnimations(animationItemList: Array): ModelRenderer; isAnimationPlaying(): boolean; playAnimation(looping?: boolean): ModelRenderer; diff --git a/plugins/default/model/typescriptAPI/Sup.ModelRenderer.ts.txt b/plugins/default/model/typescriptAPI/Sup.ModelRenderer.ts.txt index f9433628f..8e23b3a7a 100644 --- a/plugins/default/model/typescriptAPI/Sup.ModelRenderer.ts.txt +++ b/plugins/default/model/typescriptAPI/Sup.ModelRenderer.ts.txt @@ -64,6 +64,7 @@ namespace Sup { } setAnimation(animationName, looping) { this.__inner.setAnimation(animationName, looping); return this } + setMultipleAnimations(animationItemList) { this.__inner.setMultipleAnimations(animationItemList); return this } getAnimation() { return this.__inner.getAnimation() } setAnimationTime(time) { this.__inner.setAnimationTime(time); return this } getAnimationTime() { return this.__inner.getAnimationTime() }