Pose (object)

An object storing the pose of a Character

The Pose object stores the pose of a character, based on a given skeleton.

Custom Pose objects can be created that provide other methods for computing the pose of a character. For example, a pose object could pull the pose data directly from a cache file, or compute it using a simulation algorithm.

/*
** Example: pose.kl
*/

require Characters;

operator entry(){



  //////////////////////////////////
  // Generate a chain of bones with a random shape.
  Bone bones[];
  bones.resize(5);
  Xfo parentXfo();
  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(12, i);
    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);

  Pose pose(skeleton);
  character.setPose(pose);
  for(Integer i=0; i<bones.size(); i++) {
    report("Pose:" + skeleton.getBone(i).name + " :" + pose.getBoneXfo(i));
  }
}

/*
** Output:

Pose:Bone0 :{ori:{v:{x:-2.880228e-2,y:+1.432589e-3,z:+0.049656},w:+0.998349},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:-0.040728,y:+2.859098e-3,z:+0.099126},w:+0.994236},tr:{x:+9.975321,y:+0.495335,z:-2.860452e-2},sc:{x:+1.0,y:+1.0,z:+1.0}}
Pose:Bone2 :{ori:{v:{x:-1.088853e-2,y:+0.634854e-2,z:+0.148186},w:+0.988879},tr:{x:+14.87698,y:+1.479723,z:-0.097403},sc:{x:+1.0,y:+1.0,z:+1.0}}
Pose:Bone3 :{ori:{v:{x:+1.734111e-2,y:+0.965453e-2,z:+0.196705},w:+0.980261},tr:{x:+19.65698,y:+2.944419,z:-0.176318},sc:{x:+1.0,y:+1.0,z:+1.0}}
Pose:Bone4 :{ori:{v:{x:+0.055097,y:+1.436532e-2,z:+0.244337},w:+0.968017},tr:{x:+24.26912,y:+4.874321,z:-0.236847},sc:{x:+1.0,y:+1.0,z:+1.0}}

*/

/*
** Example: customPoseObject.kl
*/

require Characters;

// Custom poses enable character systems to be built that compute thier poses
// is thier own way. A ragdoll simulation might pull the pose transforms directly 
// from Bullet, or a cache reader might load a pose from disk. The IPose interface
// enables this integration of custom systems into the Fabric Engine scene.
object CustomPose : Pose {
};

function CustomPose(Skeleton skeleton){
  this.skeleton = skeleton;
  this.version = mathRandomInteger(67842, UInt32(this.skeleton.getVersion()));
  this.reset();
}


/// Updates the internal cache for a given bone. 
/// \internal
function CustomPose.updateXfo!(Index index){
  
  Scalar random = 0.5 - mathRandomScalar(12, index);
  Scalar xAngle = sin(random * 0.4 + Scalar(index) * 0.03) * 0.5;
  Scalar zAngle = cos(0.11 + Scalar(index) * 0.01) * 0.1;

  Xfo xfo;
  xfo.tr = Vec3(mathRandomScalar(13, index) * 5.0, mathRandomScalar(14, index) * 5.0, 0.0);
  xfo.ori.setFromEulerAngles(Vec3(xAngle, 0.0f, zAngle));

  this.xfos[index] = xfo;
  this.valid[index] = true;
}

/// Get the pose of a bone in the skeleton using its index.
/// \note Lazily computes the pose if the cache is not valid.  
function Xfo CustomPose.getBoneXfo!(Index index){
  if(!this.valid[index])
    this.updateXfo(index);
  return this.xfos[index];
}


operator entry(){

  Character character('Procedural Pose');


  //////////////////////////////////
  // Generate a chain of bones with a random shape.
  Bone bones[];
  bones.resize(5);
  Xfo parentXfo();
  for(Integer i=0;i<5;i++) {

    Bone bone();
    bone.name = "Bone"+i;
    bone.parentIndex = i-1;

    Xfo xfo;
    xfo.tr = Vec3(5.0, 0.0, 0.0);
    bone.referencePose = parentXfo * xfo;
    bone.length = 5.0;
    bone.radius = 1.0;
    bone.setFlag(BONEFLAG_DEFORMER);
    bones[i] = bone;
    parentXfo = bone.referencePose;
  }

  Skeleton skeleton = Skeleton("", bones);
  character.setSkeleton(skeleton);
  character.setPose(CustomPose(skeleton));

  Mat44 skinningMatricies[] = character.getSkinningMatrices();
  report(skinningMatricies);
}

/*
** Output:

[{row0:{x:+0.995064,y:-0.099232,z:+0.0,t:-2.3679},row1:{x:+0.099066,y:+0.993409,z:+0.057651,t:+0.774196},row2:{x:-0.57209e-2,y:-0.057367,z:+0.998336,t:+2.860451e-2},row3:{x:+0.0,y:+0.0,z:+0.0,t:+1.0}},{row0:{x:+0.995075,y:-0.099117,z:-1.164153e-10,t:-7.850447},row1:{x:+0.099089,y:+0.994787,z:+2.407886e-2,t:-0.267534},row2:{x:-2.386645e-3,y:-2.396029e-2,z:+0.99971,t:+2.386645e-2},row3:{x:+0.0,y:+0.0,z:+0.0,t:+1.0}},{row0:{x:+0.995088,y:-0.098993,z:+0.0,t:-13.48693},row1:{x:+0.098819,y:+0.993333,z:-0.059358,t:-0.365168},row2:{x:+0.587611e-2,y:+0.059066,z:+0.998236,t:-0.088141},row3:{x:+0.0,y:+0.0,z:+0.0,t:+1.0}},{row0:{x:+0.995101,y:-0.098859,z:+0.0,t:-16.4809},row1:{x:+0.098704,y:+0.993536,z:-0.056054,t:+2.648208},row2:{x:+0.55415e-2,y:+0.055779,z:+0.998427,t:-0.11083},row3:{x:+0.0,y:+0.0,z:+0.0,t:+1.0}},{row0:{x:+0.995115,y:-0.098716,z:-2.328306e-10,t:-22.70404},row1:{x:+0.098434,y:+0.992281,z:-0.075418,t:-0.218665},row2:{x:+0.744506e-2,y:+0.07505,z:+0.997151,t:-0.186126},row3:{x:+0.0,y:+0.0,z:+0.0,t:+1.0}}]

*/

Pose Pose Pose IPose IPose Pose->IPose ClipPose ClipPose ClipPose->Pose

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

Methods

  Pose ( in Pose other )
  Pose ( in Skeleton skeleton )
  Pose ()
Pose clone ? ()
Xfo getBoneXfo ! ( in Index index )
String getDesc ? ( in String indent, in Boolean includeXfos )
String getDesc ? ()
UInt64 getVersion ? ()
  incrementVersion ! ()
  reset ! ()
  setBoneXfo ! ( in Index index, in Xfo xfo )

Methods in detail

Pose ( in Pose other )

copy constructor


Pose ( in Skeleton skeleton )

Standard constructor taking a skeleton

skeleton The skeleton that the pose will be based on


Pose ()

default constructor


Pose Pose.clone? ()

clone method


Xfo Pose.getBoneXfo! ( in Index index )

Get the pose of a bone in the skeleton using its index.

注釈

Lazily computes the pose if the cache is not valid.


String Pose.getDesc? ( in String indent, in Boolean includeXfos )

Generates a Description string of this pose.

indent The indentation to use when generating the string.


String Pose.getDesc? ()

Generates a Description string of this Pose.


UInt64 Pose.getVersion? ()

Returns the internal version counter.


Pose.incrementVersion! ()

Increments the internal version counter.


Pose.reset! ()

Reset the pose back to the reference pose stored in the skeleton.


Pose.setBoneXfo! ( in Index index, in Xfo xfo )

Set the pose of a bone in the skeleton using its index.

注釈

This marks the joint as valid.