UNPKG

babylon-mmd

Version:
316 lines (315 loc) 11.9 kB
/** * MMD WASM animation track base class */ export class MmdWasmAnimationTrack { /** * Track type */ trackType; /** * Track name for bind to model's bone/morph */ name; _frameNumbers; /** * Frame numbers of this track * * The frame numbers must be sorted in ascending order * * Repr: [..., frameNumber, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get frameNumbers() { return this._frameNumbers.array; } /** * Create a new `MmdWasmAnimationTrack` instance * @param trackType Track type * @param trackName Track name for bind to model * @param frameCount Frame count of this track * @param wasmInstance MMD WASM instance * @param byteOffset Byte offset of frame numbers in wasm memory */ constructor(trackType, trackName, frameCount, wasmInstance, byteOffset) { this.trackType = trackType; this.name = trackName; this._frameNumbers = wasmInstance.createTypedArray(Uint32Array, byteOffset, frameCount); } /** * The start frame of this animation */ get startFrame() { const frameNumbers = this._frameNumbers.array; if (frameNumbers.length === 0) return 0; return frameNumbers[0]; } /** * The end frame of this animation * * If mmdAnimationTrack.validate() is false, the return value is not valid */ get endFrame() { const frameNumbers = this._frameNumbers.array; if (frameNumbers.length === 0) return 0; return frameNumbers[frameNumbers.length - 1]; } } /** * MMD WASM bone animation track * * Contains bone rotation and rotation cubic interpolation data */ export class MmdWasmBoneAnimationTrack extends MmdWasmAnimationTrack { _rotations; /** * Bone rotation data in quaternion * * The rotation data must be sorted by frame number in ascending order * * Repr: [..., x, y, z, w, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get rotations() { return this._rotations.array; } _rotationInterpolations; /** * Rotation cubic interpolation data * * The rotation interpolation data must be sorted by frame number in ascending order * * Repr: [..., x1, x2, y1, y2, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get rotationInterpolations() { return this._rotationInterpolations.array; } _physicsToggles; /** * Physics toggle data * * The physics toggle data must be sorted by frame number in ascending order * * If the value is 1, the bone will be driven by physics, * if the value is 0, the bone will not be driven by animation * * Repr: [..., physicsToggle, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get physicsToggles() { return this._physicsToggles.array; } /** * Create a new `MmdBoneAnimationTrack` instance * @param trackName track name for bind to model's bone * @param frameCount frame count of this track * @param wasmInstance MMD WASM instance * @param frameNumberByteOffset Byte offset of frame numbers in wasm memory * @param rotationByteOffset Byte offset of rotations in wasm memory * @param rotationInterpolationByteOffset Byte offset of rotation interpolations in wasm memory * @param physicsToggleByteOffset Byte offset of physics toggles in wasm memory */ constructor(trackName, frameCount, wasmInstance, frameNumberByteOffset, rotationByteOffset, rotationInterpolationByteOffset, physicsToggleByteOffset) { super("bone", trackName, frameCount, wasmInstance, frameNumberByteOffset); this._rotations = wasmInstance.createTypedArray(Float32Array, rotationByteOffset, frameCount * 4); this._rotationInterpolations = wasmInstance.createTypedArray(Uint8Array, rotationInterpolationByteOffset, frameCount * 4); this._physicsToggles = wasmInstance.createTypedArray(Uint8Array, physicsToggleByteOffset, frameCount); } } /** * MMD WASM movable bone animation track * * Contains bone position, rotation and position/rotation cubic interpolation data */ export class MmdWasmMovableBoneAnimationTrack extends MmdWasmAnimationTrack { _positions; /** * Bone position data in vector3 * * The position data must be sorted by frame number in ascending order * * Repr: [..., x, y, z, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get positions() { return this._positions.array; } _positionInterpolations; /** * Position cubic interpolation data * * The position interpolation data must be sorted by frame number in ascending order * * Repr: [..., x_x1, x_x2, x_y1, x_y2, y_x1, y_x2, y_y1, y_y2, z_x1, z_x2, z_y1, z_y2, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get positionInterpolations() { return this._positionInterpolations.array; } _rotations; /** * Bone rotation data in quaternion * * The rotation data must be sorted by frame number in ascending order * * Repr: [..., x, y, z, w, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get rotations() { return this._rotations.array; } _rotationInterpolations; /** * Rotation cubic interpolation data * * The rotation interpolation data must be sorted by frame number in ascending order * * Repr: [..., x1, x2, y1, y2, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get rotationInterpolations() { return this._rotationInterpolations.array; } _physicsToggles; /** * Physics toggle data * * The physics toggle data must be sorted by frame number in ascending order * * If the value is 1, the bone will be driven by physics, * if the value is 0, the bone will not be driven by animation * * Repr: [..., physicsToggle, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get physicsToggles() { return this._physicsToggles.array; } /** * Create a new `MmdMovableBoneAnimationTrack` instance * @param trackName Track name for bind to model's bone * @param frameCount Frame count of this track * @param wasmInstance MMD WASM instance * @param frameNumberByteOffset Byte offset of frame numbers in wasm memory * @param positionByteOffset Byte offset of positions in wasm memory * @param positionInterpolationByteOffset Byte offset of position interpolations in wasm memory * @param rotationByteOffset Byte offset of rotations in wasm memory * @param rotationInterpolationByteOffset Byte offset of rotation interpolations in wasm memory * @param physicsToggleByteOffset Byte offset of physics toggles in wasm memory */ constructor(trackName, frameCount, wasmInstance, frameNumberByteOffset, positionByteOffset, positionInterpolationByteOffset, rotationByteOffset, rotationInterpolationByteOffset, physicsToggleByteOffset) { super("movableBone", trackName, frameCount, wasmInstance, frameNumberByteOffset); this._positions = wasmInstance.createTypedArray(Float32Array, positionByteOffset, frameCount * 3); this._positionInterpolations = wasmInstance.createTypedArray(Uint8Array, positionInterpolationByteOffset, frameCount * 12); this._rotations = wasmInstance.createTypedArray(Float32Array, rotationByteOffset, frameCount * 4); this._rotationInterpolations = wasmInstance.createTypedArray(Uint8Array, rotationInterpolationByteOffset, frameCount * 4); this._physicsToggles = wasmInstance.createTypedArray(Uint8Array, physicsToggleByteOffset, frameCount); } } /** * MMD WASM morph animation track * * Contains morph weight data * * Weight data will be linear interpolated so there is no interpolation data */ export class MmdWasmMorphAnimationTrack extends MmdWasmAnimationTrack { _weights; /** * Morph weight data * * The weight data must be sorted by frame number in ascending order * * Repr: [..., weight, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ get weights() { return this._weights.array; } /** * Create a new `MmdMorphAnimationTrack` instance * @param trackName Track name for bind to model's morph * @param frameCount Frame count of this track * @param wasmInstance MMD WASM instance * @param frameNumberByteOffset Byte offset of frame numbers in arrayBuffer * @param weightByteOffset Byte offset of weights in arrayBuffer */ constructor(trackName, frameCount, wasmInstance, frameNumberByteOffset, weightByteOffset) { super("morph", trackName, frameCount, wasmInstance, frameNumberByteOffset); this._weights = wasmInstance.createTypedArray(Float32Array, weightByteOffset, frameCount); } } /** * MMD WASM property animation track * * Contains visibility and ik state data * * Visibility and ik state will be step interpolated */ export class MmdWasmPropertyAnimationTrack extends MmdWasmAnimationTrack { /** * Visibility data * * The visibility data must be sorted by frame number in ascending order * * Repr: [..., visible, ...] */ visibles; /** * IK bone names * * Repr: [..., ikBoneName, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope */ ikBoneNames; _ikStates; /** * Create a new `MmdPropertyAnimationTrack` instance * @param frameCount Frame count of this track * @param ikBoneCount IK bone count of this track * @param wasmInstance MMD WASM instance * @param frameNumberByteOffset Byte offset of frame numbers in wasm memory * @param visibles Visibilities data * @param ikStateByteOffsets Byte offsets of IK states in wasm memory */ constructor(frameCount, ikBoneNames, wasmInstance, frameNumberByteOffset, visibles, ikStateByteOffsets) { super("property", "propertyTrack", frameCount, wasmInstance, frameNumberByteOffset); if (visibles.length !== frameCount) throw new Error("visibles.length !== frameCount"); this.visibles = visibles; this.ikBoneNames = ikBoneNames; this._ikStates = new Array(ikBoneNames.length); if (ikStateByteOffsets === undefined) ikStateByteOffsets = new Array(ikBoneNames.length); for (let i = 0; i < ikBoneNames.length; ++i) { this._ikStates[i] = wasmInstance.createTypedArray(Uint8Array, ikStateByteOffsets[i], frameCount); } } /** * Get nth bone IK state data * * The IK state data must be sorted by frame number in ascending order * * Repr: [..., ikState, ...] * * This array reference should not be copied elsewhere and must be read and written with minimal scope * @param n Ik bone index * @returns IK state key frame values */ getIkState(n) { return this._ikStates[n].array; } }