Exemplo n.º 1
0
void TSShapeInstance::handleNodeScale(S32 a, S32 b)
{
   if (animatesUniformScale())
   {
      for (S32 i=a; i<b; i++)
         if (!mHandsOffNodes.test(i))
            TSTransform::applyScale(mCurrentRenderState->smNodeCurrentUniformScales[i],&mCurrentRenderState->smNodeLocalTransforms[i]);
   }
   else if (animatesAlignedScale())
   {
      for (S32 i=a; i<b; i++)
         if (!mHandsOffNodes.test(i))
            TSTransform::applyScale(mCurrentRenderState->smNodeCurrentAlignedScales[i],&mCurrentRenderState->smNodeLocalTransforms[i]);
   }
   else
   {
      for (S32 i=a; i<b; i++)
         if (!mHandsOffNodes.test(i))
            TSTransform::applyScale(mCurrentRenderState->smNodeCurrentArbitraryScales[i],&mCurrentRenderState->smNodeLocalTransforms[i]);
   }

   TSIntegerSet scaledNodes;
   scaledNodes.difference(mHandsOffNodes);
   mCurrentRenderState->smNodeLocalTransformDirty.overlap(scaledNodes);
}
Exemplo n.º 2
0
void TSShapeInstance::handleDefaultScale(S32 a, S32 b, TSIntegerSet & scaleBeenSet)
{
   // set default scale values (i.e., identity) and do any initialization
   // relating to animated scale (since scale normally not animated)

   mCurrentRenderState->smScaleThreads.setSize(mShape->nodes.size());
   scaleBeenSet.takeAway(mCallbackNodes);
   scaleBeenSet.takeAway(mHandsOffNodes);
   if (animatesUniformScale())
   {
      mCurrentRenderState->smNodeCurrentUniformScales.setSize(mShape->nodes.size());
      for (S32 i=a; i<b; i++)
         if (scaleBeenSet.test(i))
         {
            mCurrentRenderState->smNodeCurrentUniformScales[i] = 1.0f;
            mCurrentRenderState->smScaleThreads[i] = NULL;
         }
   }
   else if (animatesAlignedScale())
   {
      mCurrentRenderState->smNodeCurrentAlignedScales.setSize(mShape->nodes.size());
      for (S32 i=a; i<b; i++)
         if (scaleBeenSet.test(i))
         {
            mCurrentRenderState->smNodeCurrentAlignedScales[i].set(1.0f,1.0f,1.0f);
            mCurrentRenderState->smScaleThreads[i] = NULL;
         }
   }
   else
   {
      mCurrentRenderState->smNodeCurrentArbitraryScales.setSize(mShape->nodes.size());
      for (S32 i=a; i<b; i++)
         if (scaleBeenSet.test(i))
         {
            mCurrentRenderState->smNodeCurrentArbitraryScales[i].identity();
            mCurrentRenderState->smScaleThreads[i] = NULL;
         }
   }

   scaleBeenSet.overlap(mHandsOffNodes);
   scaleBeenSet.overlap(mCallbackNodes);
}
Exemplo n.º 3
0
void TSShapeInstance::handleBlendSequence(TSThread * thread, S32 a, S32 b)
{
   S32 jrot=0;
   S32 jtrans=0;
   S32 jscale=0;
   TSIntegerSet nodeMatters = thread->getSequence()->translationMatters;
   nodeMatters.overlap(thread->getSequence()->rotationMatters);
   nodeMatters.overlap(thread->getSequence()->scaleMatters);
   nodeMatters.takeAway(mHandsOffNodes);
   S32 start = nodeMatters.start();
   S32 end   = b;
   for (S32 nodeIndex=start; nodeIndex<end; nodeMatters.next(nodeIndex))
   {
      // skip nodes outside of this detail
      if (start<a || mDisableBlendNodes.test(nodeIndex))
      {
         if (thread->getSequence()->rotationMatters.test(nodeIndex))
            jrot++;
         if (thread->getSequence()->translationMatters.test(nodeIndex))
            jtrans++;
         if (thread->getSequence()->scaleMatters.test(nodeIndex))
            jscale++;
         continue;
      }

      MatrixF mat(true);
      if (thread->getSequence()->rotationMatters.test(nodeIndex))
      {
         QuatF q1,q2;
         mShape->getRotation(*thread->getSequence(),thread->keyNum1,jrot,&q1);
         mShape->getRotation(*thread->getSequence(),thread->keyNum2,jrot,&q2);
         QuatF quat;
         TSTransform::interpolate(q1,q2,thread->keyPos,&quat);
         TSTransform::setMatrix(quat,&mat);
         jrot++;
      }

      if (thread->getSequence()->translationMatters.test(nodeIndex))
      {
         const Point3F & p1 = mShape->getTranslation(*thread->getSequence(),thread->keyNum1,jtrans);
         const Point3F & p2 = mShape->getTranslation(*thread->getSequence(),thread->keyNum2,jtrans);
         Point3F p;
         TSTransform::interpolate(p1,p2,thread->keyPos,&p);
         mat.setColumn(3,p);
         jtrans++;
      }

      if (thread->getSequence()->scaleMatters.test(nodeIndex))
      {
         if (thread->getSequence()->animatesUniformScale())
         {
            F32 s1 = mShape->getUniformScale(*thread->getSequence(),thread->keyNum1,jscale);
            F32 s2 = mShape->getUniformScale(*thread->getSequence(),thread->keyNum2,jscale);
            F32 scale = TSTransform::interpolate(s1,s2,thread->keyPos);
            TSTransform::applyScale(scale,&mat);
         }
         else if (animatesAlignedScale())
         {
            Point3F s1 = mShape->getAlignedScale(*thread->getSequence(),thread->keyNum1,jscale);
            Point3F s2 = mShape->getAlignedScale(*thread->getSequence(),thread->keyNum2,jscale);
            Point3F scale;
            TSTransform::interpolate(s1,s2,thread->keyPos,&scale);
            TSTransform::applyScale(scale,&mat);
         }
         else
         {
            TSScale s1,s2;
            mShape->getArbitraryScale(*thread->getSequence(),thread->keyNum1,jscale,&s1);
            mShape->getArbitraryScale(*thread->getSequence(),thread->keyNum2,jscale,&s2);
            TSScale scale;
            TSTransform::interpolate(s1,s2,thread->keyPos,&scale);
            TSTransform::applyScale(scale,&mat);
         }
         jscale++;
      }

      // apply blend transform
      mCurrentRenderState->smNodeLocalTransforms[nodeIndex].mul(mat);
      mCurrentRenderState->smNodeLocalTransformDirty.set(nodeIndex);
   }
}
Exemplo n.º 4
0
void TSShapeInstance::handleAnimatedScale(TSThread * thread, S32 a, S32 b, TSIntegerSet & scaleBeenSet)
{
   S32 j=0;
   S32 start = thread->getSequence()->scaleMatters.start();
   S32 end   = b;

   // code the scale conversion (might need to "upgrade" from uniform to arbitrary, e.g.)
   // code uniform, aligned, and arbitrary as 0,1, and 2, respectively,
   // with sequence coding in first two bits, shape coding in next two bits
   S32 code = 0;
   if (thread->getSequence()->animatesAlignedScale())
      code += 1;
   else if (thread->getSequence()->animatesArbitraryScale())
      code += 2;
   if (animatesAlignedScale())
      code += 4;
   if (animatesArbitraryScale())
      code += 8;

   F32 uniformScale = 1.0f;
   Point3F alignedScale(0.0f, 0.0f, 0.0f);
   TSScale arbitraryScale;
   for (S32 nodeIndex=start; nodeIndex<end; thread->getSequence()->scaleMatters.next(nodeIndex), j++)
   {
      if (nodeIndex<a)
         continue;

      if (!scaleBeenSet.test(nodeIndex))
      {
         // compute scale in sequence format
         switch (code)
         {           // Sequence   Shape
            case 0:  // uniform -> uniform
            case 4:  // uniform -> aligned
            case 8:  // uniform -> arbitrary
            {
               F32 s1 = mShape->getUniformScale(*thread->getSequence(),thread->keyNum1,j);
               F32 s2 = mShape->getUniformScale(*thread->getSequence(),thread->keyNum2,j);
               uniformScale = TSTransform::interpolate(s1,s2,thread->keyPos);
               alignedScale.set(uniformScale,uniformScale,uniformScale);
               break;
            }
            case 5:  // aligned -> aligned
            case 9:  // aligned -> arbitrary
            {
               const Point3F & s1 = mShape->getAlignedScale(*thread->getSequence(),thread->keyNum1,j);
               const Point3F & s2 = mShape->getAlignedScale(*thread->getSequence(),thread->keyNum2,j);
               TSTransform::interpolate(s1,s2,thread->keyPos,&alignedScale);
               break;
            }
            case 10: // arbitrary -> arbitary
            {
               TSScale s1,s2;
               mShape->getArbitraryScale(*thread->getSequence(),thread->keyNum1,j,&s1);
               mShape->getArbitraryScale(*thread->getSequence(),thread->keyNum2,j,&s2);
               TSTransform::interpolate(s1,s2,thread->keyPos,&arbitraryScale);
               break;
            }
            default: AssertFatal(0,"TSShapeInstance::handleAnimatedScale"); break;
         }

         switch (code)
         {
            case 0:  // uniform -> uniform
            {
               mCurrentRenderState->smNodeCurrentUniformScales[nodeIndex] = uniformScale;
               break;
            }
            case 4:  // uniform -> aligned
            case 5:  // aligned -> aligned
               mCurrentRenderState->smNodeCurrentAlignedScales[nodeIndex] = alignedScale;
               break;
            case 8:  // uniform -> arbitrary
            case 9:  // aligned -> arbitrary
            {
               mCurrentRenderState->smNodeCurrentArbitraryScales[nodeIndex].identity();
               mCurrentRenderState->smNodeCurrentArbitraryScales[nodeIndex].mScale = alignedScale;
               break;
            }
            case 10: // arbitrary -> arbitary
            {
               mCurrentRenderState->smNodeCurrentArbitraryScales[nodeIndex] = arbitraryScale;
               break;
            }
            default: AssertFatal(0,"TSShapeInstance::handleAnimatedScale"); break;
         }
         mCurrentRenderState->smScaleThreads[nodeIndex] = thread;
         scaleBeenSet.set(nodeIndex);
      }
   }
}
Exemplo n.º 5
0
void TSShapeInstance::handleTransitionNodes(S32 a, S32 b)
{
   TSIntegerSet transitionNodes;
   updateTransitionNodeTransforms(transitionNodes);

   S32 nodeIndex;
   S32 start = mTransitionRotationNodes.start();
   S32 end   = b;
   for (nodeIndex=start; nodeIndex<end; mTransitionRotationNodes.next(nodeIndex))
   {
      if (nodeIndex<a)
         continue;
      TSThread * thread = mCurrentRenderState->smRotationThreads[nodeIndex];
      thread = thread && thread->transitionData.inTransition ? thread : NULL;
      if (!thread)
      {
         // if not controlled by a sequence in transition then there must be
         // some other thread out there that used to control us that is in
         // transition now...use that thread to control interpolation
         for (S32 i=0; i<mTransitionThreads.size(); i++)
         {
            if (mTransitionThreads[i]->transitionData.oldRotationNodes.test(nodeIndex) || mTransitionThreads[i]->getSequence()->rotationMatters.test(nodeIndex))
            {
               thread = mTransitionThreads[i];
               break;
            }
         }
         AssertFatal(thread!=NULL,"TSShapeInstance::handleRotTransitionNodes (rotation)");
      }
      QuatF tmpQ;
      TSTransform::interpolate(mNodeReferenceRotations[nodeIndex].getQuatF(&tmpQ),mCurrentRenderState->smNodeCurrentRotations[nodeIndex],thread->transitionData.pos,&mCurrentRenderState->smNodeCurrentRotations[nodeIndex]);
   }

   // then translation
   start = mTransitionTranslationNodes.start();
   end   = b;
   for (nodeIndex=start; nodeIndex<end; mTransitionTranslationNodes.next(nodeIndex))
   {
      TSThread * thread = mCurrentRenderState->smTranslationThreads[nodeIndex];
      thread = thread && thread->transitionData.inTransition ? thread : NULL;
      if (!thread)
      {
         // if not controlled by a sequence in transition then there must be
         // some other thread out there that used to control us that is in
         // transition now...use that thread to control interpolation
         for (S32 i=0; i<mTransitionThreads.size(); i++)
         {
            if (mTransitionThreads[i]->transitionData.oldTranslationNodes.test(nodeIndex) || mTransitionThreads[i]->getSequence()->translationMatters.test(nodeIndex))
            {
               thread = mTransitionThreads[i];
               break;
            }
         }
         AssertFatal(thread!=NULL,"TSShapeInstance::handleTransitionNodes (translation).");
      }
      Point3F & p = mCurrentRenderState->smNodeCurrentTranslations[nodeIndex];
      Point3F & p1 = mNodeReferenceTranslations[nodeIndex];
      Point3F & p2 = p;
      F32 k = thread->transitionData.pos;
      p.x = p1.x + k * (p2.x-p1.x);
      p.y = p1.y + k * (p2.y-p1.y);
      p.z = p1.z + k * (p2.z-p1.z);
   }

   // then scale...
   if (scaleCurrentlyAnimated())
   {
      start = mTransitionScaleNodes.start();
      end   = b;
      for (nodeIndex=start; nodeIndex<end; mTransitionScaleNodes.next(nodeIndex))
      {
         TSThread * thread = mCurrentRenderState->smScaleThreads[nodeIndex];
         thread = thread && thread->transitionData.inTransition ? thread : NULL;
         if (!thread)
         {
            // if not controlled by a sequence in transition then there must be
            // some other thread out there that used to control us that is in
            // transition now...use that thread to control interpolation
            for (S32 i=0; i<mTransitionThreads.size(); i++)
            {
               if (mTransitionThreads[i]->transitionData.oldScaleNodes.test(nodeIndex) || mTransitionThreads[i]->getSequence()->scaleMatters.test(nodeIndex))
               {
                  thread = mTransitionThreads[i];
                  break;
               }
            }
            AssertFatal(thread!=NULL,"TSShapeInstance::handleTransitionNodes (scale).");
         }
         if (animatesUniformScale())
            mCurrentRenderState->smNodeCurrentUniformScales[nodeIndex] += thread->transitionData.pos * (mNodeReferenceUniformScales[nodeIndex]-mCurrentRenderState->smNodeCurrentUniformScales[nodeIndex]);
         else if (animatesAlignedScale())
            TSTransform::interpolate(mNodeReferenceScaleFactors[nodeIndex],mCurrentRenderState->smNodeCurrentAlignedScales[nodeIndex],thread->transitionData.pos,&mCurrentRenderState->smNodeCurrentAlignedScales[nodeIndex]);
         else
         {
            QuatF q;
            TSTransform::interpolate(mNodeReferenceScaleFactors[nodeIndex],mCurrentRenderState->smNodeCurrentArbitraryScales[nodeIndex].mScale,thread->transitionData.pos,&mCurrentRenderState->smNodeCurrentArbitraryScales[nodeIndex].mScale);
            TSTransform::interpolate(mNodeReferenceArbitraryScaleRots[nodeIndex].getQuatF(&q),mCurrentRenderState->smNodeCurrentArbitraryScales[nodeIndex].mRotate,thread->transitionData.pos,&mCurrentRenderState->smNodeCurrentArbitraryScales[nodeIndex].mRotate);
         }
      }
   }

   // update transforms for transition nodes
   start = transitionNodes.start();
   end   = b;
   for (nodeIndex=start; nodeIndex<end; transitionNodes.next(nodeIndex))
   {
      TSTransform::setMatrix(mCurrentRenderState->smNodeCurrentRotations[nodeIndex], mCurrentRenderState->smNodeCurrentTranslations[nodeIndex], &mCurrentRenderState->smNodeLocalTransforms[nodeIndex]);
      if (scaleCurrentlyAnimated())
      {
         if (animatesUniformScale())
            TSTransform::applyScale(mCurrentRenderState->smNodeCurrentUniformScales[nodeIndex],&mCurrentRenderState->smNodeLocalTransforms[nodeIndex]);
         else if (animatesAlignedScale())
               TSTransform::applyScale(mCurrentRenderState->smNodeCurrentAlignedScales[nodeIndex],&mCurrentRenderState->smNodeLocalTransforms[nodeIndex]);
         else
            TSTransform::applyScale(mCurrentRenderState->smNodeCurrentArbitraryScales[nodeIndex],&mCurrentRenderState->smNodeLocalTransforms[nodeIndex]);
      }
   }
}
Exemplo n.º 6
0
void TSShapeInstance::updateTransitions()
{
   if (mTransitionThreads.empty())
      return;

   TSIntegerSet transitionNodes;
   updateTransitionNodeTransforms(transitionNodes);

   S32 i;
   mNodeReferenceRotations.setSize(mShape->nodes.size());
   mNodeReferenceTranslations.setSize(mShape->nodes.size());
   for (i=0; i<mShape->nodes.size(); i++)
   {
      if (mTransitionRotationNodes.test(i))
         mNodeReferenceRotations[i].set(smNodeCurrentRotations[i]);
      if (mTransitionTranslationNodes.test(i))
         mNodeReferenceTranslations[i] = smNodeCurrentTranslations[i];
   }

   if (animatesScale())
   {
      // Make sure smNodeXXXScale arrays have been resized
      TSIntegerSet dummySet;
      handleDefaultScale(0, 0, dummySet);

      if (animatesUniformScale())
      {
         mNodeReferenceUniformScales.setSize(mShape->nodes.size());
         for (i=0; i<mShape->nodes.size(); i++)
         {
            if (mTransitionScaleNodes.test(i))
               mNodeReferenceUniformScales[i] = smNodeCurrentUniformScales[i];
         }
      }
      else if (animatesAlignedScale())
      {
         mNodeReferenceScaleFactors.setSize(mShape->nodes.size());
         for (i=0; i<mShape->nodes.size(); i++)
         {
            if (mTransitionScaleNodes.test(i))
               mNodeReferenceScaleFactors[i] = smNodeCurrentAlignedScales[i];
         }
      }
      else
      {
         mNodeReferenceScaleFactors.setSize(mShape->nodes.size());
         mNodeReferenceArbitraryScaleRots.setSize(mShape->nodes.size());
         for (i=0; i<mShape->nodes.size(); i++)
         {
            if (mTransitionScaleNodes.test(i))
            {
               mNodeReferenceScaleFactors[i] = smNodeCurrentArbitraryScales[i].mScale;
               mNodeReferenceArbitraryScaleRots[i].set(smNodeCurrentArbitraryScales[i].mRotate);
            }
         }
      }
   }

   // reset transition durations to account for new reference transforms
   for (i=0; i<mTransitionThreads.size(); i++)
   {
      TSThread * th = mTransitionThreads[i];
      if (th->transitionData.inTransition)
      {
         th->transitionData.duration *= 1.0f - th->transitionData.pos;
         th->transitionData.pos = 0.0f;
      }
   }
}