ClipPose.kl¶
Types¶
ClipPose (object)¶
A pose driven by a clip.
The ClipPose, based on the regular Pose, computes the bone transforms by retrieving animation data from a references Clip. The Clip is evaluated, giving a ClipValues data structure, that can then be queried by the pose as it lazily builds the global space transforms.
/*
** Example: clipPose.kl
*/
require Characters;
operator entry(){
//////////////////////////////////
// Generate a skeleton made of a single bone chain.
Bone bones[];
bones.resize(5);
Xfo parentXfo();
UInt32 seed = 9876;
UInt32 offset = 0;
for(Integer i=0; i<bones.size(); i++) {
Bone bone;
bone.name = "Bone"+i;
bone.parentIndex = i-1;
// compute the angles
Scalar random = 0.5 - mathRandomScalar(seed, ++offset);
Scalar xAngle = sin(random * 0.4 + Scalar(i) * 0.03) * 0.5;
Scalar zAngle = cos(0.11 + Scalar(i) * 0.01) * 0.1;
Scalar boneLength = 5.0;
Xfo xfo;
xfo.tr = Vec3(boneLength, 0.0, 0.0);
xfo.ori.setFromEulerAngles(Vec3(xAngle, 0.0f, zAngle));
bone.referencePose = parentXfo * xfo;
bone.length = boneLength;
bone.radius = 1.0;
bone.setFlag(BONEFLAG_DEFORMER);
bones[i] = bone;
parentXfo = bone.referencePose;
}
Skeleton skeleton = Skeleton("", bones);
Character character('Clip');
character.setSkeleton(skeleton);
//////////////////////////////////
// Generate a clip for the skeleton.
Clip clip('MyClip');
seed = 5467;
offset = 0;
for(Integer i=0; i<bones.size(); i++) {
Xfo localXfo = skeleton.getReferenceLocalPose(i);
KeyframeTrackSet trackSet = null;
if(i==0)
trackSet = KeyframeTrackSet(skeleton.getBone(i).name, localXfo, TRACKSETFLAG_TR_TRACKS|TRACKSETFLAG_ORI_TRACKS|TRACKSETFLAG_EULERANGLES_TRACKS);
else
trackSet = KeyframeTrackSet(skeleton.getBone(i).name, localXfo.ori, TRACKSETFLAG_EULERANGLES_TRACKS);
String trackNames[] = trackSet.getTrackNames();
for(Integer j=0; j<trackNames.size(); j++) {
KeyframeTrack track = trackSet.getTrack(trackNames[j]);
track.addKey(Keyframe(0.0, 0.0, Vec2(0.0, 0.0), Vec2(0.333, 0.0)));
track.addKey(Keyframe(2.0, mathRandomScalar(seed, ++offset), Vec2(-0.5, 25.0), Vec2(0.5, 25.0)));
track.addKey(Keyframe(4.0, 0.0, Vec2(-0.333, 0.0), Vec2(0.333, 0.0)));
}
clip.addTrackSet(trackSet);
}
//////////////////////////////////
// /create a pose for the skeleton based on the clip
ClipPose clipPose(skeleton, clip);
character.setPose(clipPose);
for(Integer i=0; i<bones.size(); i++) {
report("Pose:" + skeleton.getBone(i).name + " :" + clipPose.getBoneXfo(i));
}
}
/*
** Output:
Pose:Bone0 :{ori:{v:{x:+2.568705e-2,y:-1.277642e-3,z:+0.04966},w:+0.998435},tr:{x:+5.0,y:+0.0,z:+0.0},sc:{x:+1.0,y:+1.0,z:+1.0}}
Pose:Bone1 :{ori:{v:{x:+2.442186e-2,y:-2.550726e-3,z:+0.099142},w:+0.99477},tr:{x:+9.975325,y:+0.495504,z:+2.551286e-2},sc:{x:+1.0,y:+1.0,z:+1.0}}
Pose:Bone2 :{ori:{v:{x:+0.077133,y:-1.118197e-3,z:+0.148181},w:+0.985947},tr:{x:+14.87697,y:+1.481117,z:+0.075099},sc:{x:+1.0,y:+1.0,z:+1.0}}
Pose:Bone3 :{ori:{v:{x:+0.120761,y:-0.544071e-3,z:+0.196483},w:+0.973041},tr:{x:+19.65738,y:+2.941245,z:+0.20042},sc:{x:+1.0,y:+1.0,z:+1.0}}
Pose:Bone4 :{ori:{v:{x:+0.137246,y:-0.399326e-2,z:+0.244201},w:+0.959954},tr:{x:+24.27132,y:+4.852451,z:+0.442991},sc:{x:+1.0,y:+1.0,z:+1.0}}
*/
Members¶
Skeleton | skeleton | The skeleton that this pose is based on. |
Xfo[] | xfos | The model space transforms for each bone in the skeleton |
Boolean[] | valid | A flag for each item in the array above indicating that the Xfo has been computed. |
UInt64 | version | The intenral version counter |
IClip | clip | |
Integer[][] | keyIndices | |
Scalar | timeCache | |
Boolean | initialized | |
IClipValues | clipValues | |
Float32 | scaleFactor |
Methods¶
ClipPose ( in ClipPose other ) | |
ClipPose ( in Skeleton skeleton, in IClip clip ) | |
ClipPose ( in Skeleton skeleton, in IClip clip, in Float32 scaleFactor ) | |
ClipPose () | |
ClipPose | clone ? () |
evaluate ! ( in Scalar time ) | |
Xfo | getBoneXfo ! ( in Index index ) |
IClip | getClip ? () |
String | getDesc ? ( in String indent, in Boolean includeClip ) |
String | getDesc ? () |
reset ! () | |
setClip ! ( in IClip clip ) |