Buckets:
| import { Mesh, MathUtils } from "three"; | |
| class MorphBlendMesh extends Mesh { | |
| constructor(geometry, material) { | |
| super(geometry, material); | |
| this.animationsMap = {}; | |
| this.animationsList = []; | |
| const numFrames = Object.keys(this.morphTargetDictionary).length; | |
| const name = "__default"; | |
| const startFrame = 0; | |
| const endFrame = numFrames - 1; | |
| const fps = numFrames / 1; | |
| this.createAnimation(name, startFrame, endFrame, fps); | |
| this.setAnimationWeight(name, 1); | |
| } | |
| createAnimation(name, start, end, fps) { | |
| const animation = { | |
| start, | |
| end, | |
| length: end - start + 1, | |
| fps, | |
| duration: (end - start) / fps, | |
| lastFrame: 0, | |
| currentFrame: 0, | |
| active: false, | |
| time: 0, | |
| direction: 1, | |
| weight: 1, | |
| directionBackwards: false, | |
| mirroredLoop: false | |
| }; | |
| this.animationsMap[name] = animation; | |
| this.animationsList.push(animation); | |
| } | |
| autoCreateAnimations(fps) { | |
| const pattern = /([a-z]+)_?(\d+)/i; | |
| let firstAnimation; | |
| const frameRanges = {}; | |
| let i = 0; | |
| for (const key in this.morphTargetDictionary) { | |
| const chunks = key.match(pattern); | |
| if (chunks && chunks.length > 1) { | |
| const name = chunks[1]; | |
| if (!frameRanges[name]) | |
| frameRanges[name] = { start: Infinity, end: -Infinity }; | |
| const range = frameRanges[name]; | |
| if (i < range.start) | |
| range.start = i; | |
| if (i > range.end) | |
| range.end = i; | |
| if (!firstAnimation) | |
| firstAnimation = name; | |
| } | |
| i++; | |
| } | |
| for (const name in frameRanges) { | |
| const range = frameRanges[name]; | |
| this.createAnimation(name, range.start, range.end, fps); | |
| } | |
| this.firstAnimation = firstAnimation; | |
| } | |
| setAnimationDirectionForward(name) { | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| animation.direction = 1; | |
| animation.directionBackwards = false; | |
| } | |
| } | |
| setAnimationDirectionBackward(name) { | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| animation.direction = -1; | |
| animation.directionBackwards = true; | |
| } | |
| } | |
| setAnimationFPS(name, fps) { | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| animation.fps = fps; | |
| animation.duration = (animation.end - animation.start) / animation.fps; | |
| } | |
| } | |
| setAnimationDuration(name, duration) { | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| animation.duration = duration; | |
| animation.fps = (animation.end - animation.start) / animation.duration; | |
| } | |
| } | |
| setAnimationWeight(name, weight) { | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| animation.weight = weight; | |
| } | |
| } | |
| setAnimationTime(name, time) { | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| animation.time = time; | |
| } | |
| } | |
| getAnimationTime(name) { | |
| let time = 0; | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| time = animation.time; | |
| } | |
| return time; | |
| } | |
| getAnimationDuration(name) { | |
| let duration = -1; | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| duration = animation.duration; | |
| } | |
| return duration; | |
| } | |
| playAnimation(name) { | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| animation.time = 0; | |
| animation.active = true; | |
| } else { | |
| console.warn("THREE.MorphBlendMesh: animation[" + name + "] undefined in .playAnimation()"); | |
| } | |
| } | |
| stopAnimation(name) { | |
| const animation = this.animationsMap[name]; | |
| if (animation) { | |
| animation.active = false; | |
| } | |
| } | |
| update(delta) { | |
| for (let i = 0, il = this.animationsList.length; i < il; i++) { | |
| const animation = this.animationsList[i]; | |
| if (!animation.active) | |
| continue; | |
| const frameTime = animation.duration / animation.length; | |
| animation.time += animation.direction * delta; | |
| if (animation.mirroredLoop) { | |
| if (animation.time > animation.duration || animation.time < 0) { | |
| animation.direction *= -1; | |
| if (animation.time > animation.duration) { | |
| animation.time = animation.duration; | |
| animation.directionBackwards = true; | |
| } | |
| if (animation.time < 0) { | |
| animation.time = 0; | |
| animation.directionBackwards = false; | |
| } | |
| } | |
| } else { | |
| animation.time = animation.time % animation.duration; | |
| if (animation.time < 0) | |
| animation.time += animation.duration; | |
| } | |
| const keyframe = animation.start + MathUtils.clamp(Math.floor(animation.time / frameTime), 0, animation.length - 1); | |
| const weight = animation.weight; | |
| if (keyframe !== animation.currentFrame) { | |
| this.morphTargetInfluences[animation.lastFrame] = 0; | |
| this.morphTargetInfluences[animation.currentFrame] = 1 * weight; | |
| this.morphTargetInfluences[keyframe] = 0; | |
| animation.lastFrame = animation.currentFrame; | |
| animation.currentFrame = keyframe; | |
| } | |
| let mix = animation.time % frameTime / frameTime; | |
| if (animation.directionBackwards) | |
| mix = 1 - mix; | |
| if (animation.currentFrame !== animation.lastFrame) { | |
| this.morphTargetInfluences[animation.currentFrame] = mix * weight; | |
| this.morphTargetInfluences[animation.lastFrame] = (1 - mix) * weight; | |
| } else { | |
| this.morphTargetInfluences[animation.currentFrame] = weight; | |
| } | |
| } | |
| } | |
| } | |
| export { | |
| MorphBlendMesh | |
| }; | |
| //# sourceMappingURL=MorphBlendMesh.js.map | |
Xet Storage Details
- Size:
- 5.58 kB
- Xet hash:
- 3574fc3b9819400a08c6544337c12c82ff11bfd026cdaab66ae4ed4e59311543
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.