babylon-mmd
Version:
babylon.js mmd loader and runtime
316 lines (315 loc) • 11.9 kB
JavaScript
/**
* 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;
}
}