import { IAsset, AssetBase } from '@awayjs/core';
import { JointPose } from './JointPose';
/**
* A collection of pose objects, determining the pose for an entire skeleton.
* The jointPoses vector object corresponds to a skeleton's joints vector object, however, there is no
* reference to a skeleton's instance, since several skeletons can be influenced by the same pose (eg: animation
* clips are added to any animator with a valid skeleton)
*
* @see away.animators.Skeleton
* @see away.animators.JointPose
*/
export class SkeletonPose extends AssetBase implements IAsset {
public static assetType: string = '[asset SkeletonPose]';
/**
* A flat list of pose objects that comprise the skeleton pose. The pose indices correspond to the target skeleton's joint indices.
*
* @see away.animators.Skeleton#joints
*/
public jointPoses: Array;
/**
* The total number of joint poses in the skeleton pose.
*/
public get numJointPoses(): number {
return this.jointPoses.length;
}
/**
* Creates a new SkeletonPose object.
*/
constructor() {
super();
this.jointPoses = new Array();
}
/**
* @inheritDoc
*/
public get assetType(): string {
return SkeletonPose.assetType;
}
/**
* Returns the joint pose object with the given joint name, otherwise returns a null object.
*
* @param jointName The name of the joint object whose pose is to be found.
* @return The pose object with the given joint name.
*/
public jointPoseFromName(jointName: string): JointPose {
const jointPoseIndex: number = this.jointPoseIndexFromName(jointName);
if (jointPoseIndex != -1)
return this.jointPoses[jointPoseIndex]; else
return null;
}
/**
* Returns the pose index, given the joint name. -1 is returned if the joint name is not found in the pose.
*
* @param The name of the joint object whose pose is to be found.
* @return The index of the pose object in the jointPoses Array
*
* @see #jointPoses
*/
public jointPoseIndexFromName(jointName: string): number {
// this is implemented as a linear search, rather than a possibly
// more optimal method (Dictionary lookup, for example) because:
// a) it is assumed that it will be called once for each joint
// b) it is assumed that it will be called only during load, and not during main loop
// c) maintaining a dictionary (for safety) would dictate an interface to access JointPoses,
// rather than direct array access. this would be sub-optimal.
let jointPoseIndex: number;
let jointPose: JointPose;
for (var i: number; i < this.jointPoses.length; i++) {
jointPose = this.jointPoses[i];
if (jointPose.name == jointName)
return jointPoseIndex;
jointPoseIndex++;
}
return -1;
}
/**
* Creates a copy of the SkeletonPose object, with a dulpicate of its component joint poses.
*
* @return SkeletonPose
*/
public clone(): SkeletonPose {
const clone: SkeletonPose = new SkeletonPose();
const numJointPoses: number = this.jointPoses.length;
for (let i: number = 0; i < numJointPoses; i++) {
const cloneJointPose: JointPose = new JointPose();
const thisJointPose: JointPose = this.jointPoses[i];
cloneJointPose.name = thisJointPose.name;
cloneJointPose.copyFrom(thisJointPose);
clone.jointPoses[i] = cloneJointPose;
}
return clone;
}
/**
* @inheritDoc
*/
public dispose(): void {
this.jointPoses.length = 0;
}
}