Esempio n. 1
0
void Camera::update_following(double dt) {
    ActorPtr following_actor = following_actor_.lock();
    if(following_actor) {
        kmQuaternion actor_rotation = following_actor->absolute_rotation();
        kmVec3 actor_position = following_actor->absolute_position();

        kmVec3 actor_forward;
        kmQuaternionGetForwardVec3RH(&actor_forward, &actor_rotation);

        kmQuaternion initial_rotation;
        kmQuaternionAssign(&initial_rotation, &rotation_);

        float t = ((following_lag_ == 0) ? 1.0 : dt * (1.0 / following_lag_));
        kmQuaternionSlerp(&rotation_, &initial_rotation, &actor_rotation, t);

        kmVec3 rotated_offset;
        kmQuaternionMultiplyVec3(&rotated_offset, &rotation_, &following_offset_);

        //kmMat4RotationQuaternion(&new_rotation_matrix, &rotation_);
        //kmVec3MultiplyMat4(&rotated_offset, &following_offset_, &new_rotation_matrix);
        kmVec3Add(&position_, &rotated_offset, &actor_position);

        update_from_parent();
    } else {
        //The actor was destroyed, so reset
        following_actor_ = ActorRef();
    }
}
Esempio n. 2
0
void dlAdvanceAnimTick( dlAnimTick *animTick, float pTime )
{
   dlAnim               *anim;
   dlNodeAnim           *node;
   dlAnimTickOldNode    *oldNode;
   unsigned int   frame, nextFrame;
   dlVectorKey    *vkey, *nextvKey;
   dlQuatKey      *qkey, *nextqKey;
   kmVec3         presentTranslation, presentScaling;
   kmQuaternion   presentRotation;
   float          diffTime, factor;
   float          ticksPerSecond;

   CALL("%p, %f", animTick, pTime);

   /* get dlAnim */
   anim = animTick->anim;

   ticksPerSecond = anim->ticksPerSecond != 0.0 ? anim->ticksPerSecond : 25.0f;
   pTime *= ticksPerSecond;

   /* map into anim's duration */
   float time = 0.0f;
   if( anim->duration > 0.0)
      time = fmod( pTime, anim->duration);

   /* calculate the transformations for each animation channel */
   node     = anim->node;
   oldNode  = animTick->oldNode;
   while(node && oldNode)
   {
      /* ******** Position **** */
      presentTranslation.x = 0;
      presentTranslation.y = 0;
      presentTranslation.z = 0;

      if(node->translation)
      {
         frame = (time >= animTick->oldTime) ? oldNode->translationTime : 0;
         while( frame < node->num_translation - 1)
         {
            if( time < oldNode->translation[frame+1]->time)
               break;
            ++frame;
         }

         /* interpolate between this frame's value and next frame's value */
         nextFrame   = (frame + 1) % node->num_translation;
         vkey        = oldNode->translation[frame];
         nextvKey    = oldNode->translation[nextFrame];
         diffTime    = nextvKey->time - vkey->time;
#if 1
         if( diffTime < 0.0)
            diffTime += anim->duration;
         if( diffTime > 0)
         {
            factor            = (time - vkey->time) / diffTime;
            presentTranslation.x = vkey->value.x + (nextvKey->value.x - vkey->value.x) * factor;
            presentTranslation.y = vkey->value.y + (nextvKey->value.y - vkey->value.y) * factor;
            presentTranslation.z = vkey->value.z + (nextvKey->value.z - vkey->value.z) * factor;
         } else
         {
            presentTranslation = vkey->value;
         }
#else
         presentTranslation = vkey->value;
#endif

         oldNode->translationTime = frame;
      }

      /* ******** Rotation ******** */
      presentRotation.w = 0;
      presentRotation.x = 0;
      presentRotation.y = 0;
      presentRotation.z = 0;

      if(node->rotation)
      {
         frame = (time >= animTick->oldTime) ? oldNode->rotationTime : 0;
         while( frame < node->num_rotation - 1)
         {
            if( time < oldNode->rotation[frame+1]->time)
               break;
            ++frame;
         }

         /* interpolate between this frame's value and next frame's value */
         nextFrame   = (frame + 1) % node->num_rotation;
         qkey        = oldNode->rotation[frame];
         nextqKey    = oldNode->rotation[nextFrame];
         diffTime    = nextqKey->time - qkey->time;

#if 1
         if( diffTime < 0.0f)
            diffTime += anim->duration;
         if( diffTime > 0.0f)
         {
            factor   = (time - qkey->time) / diffTime;
            kmQuaternionSlerp( &presentRotation,
                  &qkey->value,
                  &nextqKey->value,
                  factor);
         } else
         {
            presentRotation = qkey->value;
         }
#else
         presentRotation = qkey->value;
#endif

         oldNode->rotationTime = frame;
      }

      /* ******** Scaling ********** */
      presentScaling.x = 1;
      presentScaling.y = 1;
      presentScaling.z = 1;

      if(node->scaling)
      {
         frame = (time >= animTick->oldTime) ? oldNode->scalingTime : 0;
         while( frame < node->num_scaling - 1)
         {
            if( time < oldNode->scaling[frame+1]->time)
               break;
            ++frame;
         }

         /* TODO: (thom) interpolation maybe? This time maybe even logarithmic, not linear */
         presentScaling        = oldNode->scaling[frame]->value;
         oldNode->scalingTime  = frame;
      }

      // build a transformation matrix from it
      kmMat4 *mat = &node->bone->relativeMatrix;
      kmMat4RotationQuaternion( mat, &presentRotation );

      mat->mat[0] *= presentScaling.x; mat->mat[4] *= presentScaling.x; mat->mat[8] *= presentScaling.x;
      mat->mat[1] *= presentScaling.y; mat->mat[5] *= presentScaling.y; mat->mat[9] *= presentScaling.y;
      mat->mat[2] *= presentScaling.z; mat->mat[6] *= presentScaling.z; mat->mat[10] *= presentScaling.z;
      mat->mat[3] = presentTranslation.x; mat->mat[7] = presentTranslation.y; mat->mat[11] = presentTranslation.z;

      node      = node->next;
      oldNode   = oldNode->next;
   }

   /* old time */
   animTick->oldTime = time;
}