예제 #1
0
UNNAMESPACE_BEGIN

/*==============================================================================
   Procedural API/functions.
==============================================================================*/

//------------------------------------------------------------------------------
//!
int animationVM( VMState* vm )
{
   ProceduralAnimation* userData = (ProceduralAnimation*)VM::userData( vm );
   SkeletalAnimation* anim       = userData->animation();

   // Only accept a table as argument.
   if( !VM::isTable( vm, 1 ) )
   {
      StdErr << "Missing arguments to animation()." << nl;
      return 0;
   }

   // Read parameters.
   float rate;
   if( VM::get( vm, 1, "rate", rate ) ) anim->rate( rate );

   Vec3f vel;
   if( VM::get( vm, 1, "velocity", vel ) ) anim->velocity( vel );

   Vec3f offset;
   if( VM::get( vm, 1, "offset", offset ) ) anim->offset( offset );

   bool cyclic;
   if( VM::get( vm, 1, "cyclic", cyclic ) ) anim->cyclic( cyclic );

   uint type;
   if( VM::get( vm, 1, "type", type ) ) anim->type( type );

   if( VM::get( vm, 1, "poses" ) )
   {
      anim->reservePoses( VM::getTableSize( vm, -1 ) );

      // Read all poses.
      for( int p = 1; VM::geti( vm, -1, p ); ++p )
      {
         Reff ref = Reff::identity();
         if( !VM::get( vm, -1, "p", ref.position() ) )
         {
            ref.position( Vec3f::zero() );
         }
         if( !VM::get( vm, -1, "q", ref.orientation() ) )
         {
            ref.orientation( Quatf::identity() );
         }

         RCP<SkeletalPose> pose = anim->addPose( ref );
         pose->reserveBones( VM::getTableSize( vm, -1 ) );
         // Read all bones positions in pose.
         for( int i = 1; VM::geti( vm, -1, i ); ++i )
         {
            pose->addBone( VM::toQuatf( vm, -1 ) );
            VM::pop( vm, 1 );
         }
         VM::pop( vm, 1 );
      }
      VM::pop( vm, 1 );
   }
   anim->prepare();  // Fix some corner cases.
   anim->makeRelative();
   return 0;
}