Пример #1
0
void TSShapeInstance::animateNodes(S32 ss)
{
   PROFILE_SCOPE( TSShapeInstance_animateNodes );

   if (!mShape->nodes.size())
      return;

   // @todo: When a node is added, we need to make sure to resize the nodeTransforms array as well
   mNodeTransforms.setSize(mShape->nodes.size());

   // temporary storage for node transforms
   mCurrentRenderState->smNodeCurrentRotations.setSize(mShape->nodes.size());
   mCurrentRenderState->smNodeCurrentTranslations.setSize(mShape->nodes.size());
   mCurrentRenderState->smNodeLocalTransforms.setSize(mShape->nodes.size());
   mCurrentRenderState->smRotationThreads.setSize(mShape->nodes.size());
   mCurrentRenderState->smTranslationThreads.setSize(mShape->nodes.size());

   TSIntegerSet rotBeenSet;
   TSIntegerSet tranBeenSet;
   TSIntegerSet scaleBeenSet;
   rotBeenSet.setAll(mShape->nodes.size());
   tranBeenSet.setAll(mShape->nodes.size());
   scaleBeenSet.setAll(mShape->nodes.size());
   mCurrentRenderState->smNodeLocalTransformDirty.clearAll();

   S32 i,j,nodeIndex,a,b,start,end,firstBlend = mThreadList.size();
   for (i=0; i<mThreadList.size(); i++)
   {
      TSThread * th = mThreadList[i];

      if (th->getSequence()->isBlend())
      {
         // blend sequences need default (if not set by other sequence)
         // break rather than continue because the rest will be blends too
         firstBlend = i;
         break;
      }
      rotBeenSet.takeAway(th->getSequence()->rotationMatters);
      tranBeenSet.takeAway(th->getSequence()->translationMatters);
      scaleBeenSet.takeAway(th->getSequence()->scaleMatters);
   }
   rotBeenSet.takeAway(mCallbackNodes);
   rotBeenSet.takeAway(mHandsOffNodes);
   rotBeenSet.overlap(mMaskRotationNodes);

   TSIntegerSet maskPosNodes=mMaskPosXNodes;
   maskPosNodes.overlap(mMaskPosYNodes);
   maskPosNodes.overlap(mMaskPosZNodes);
   tranBeenSet.overlap(maskPosNodes);

   tranBeenSet.takeAway(mCallbackNodes);
   tranBeenSet.takeAway(mHandsOffNodes);
   // can't add masked nodes since x, y, & z masked separately...
   // we'll set default regardless of mask status

   // all the nodes marked above need to have the default transform
   a = mShape->subShapeFirstNode[ss];
   b = a + mShape->subShapeNumNodes[ss];
   for (i=a; i<b; i++)
   {
      if (rotBeenSet.test(i))
      {
         mShape->defaultRotations[i].getQuatF(&mCurrentRenderState->smNodeCurrentRotations[i]);
         mCurrentRenderState->smRotationThreads[i] = NULL;
      }
      if (tranBeenSet.test(i))
      {
         mCurrentRenderState->smNodeCurrentTranslations[i] = mShape->defaultTranslations[i];
         mCurrentRenderState->smTranslationThreads[i] = NULL;
      }
   }

   // don't want a transform in these cases...
   rotBeenSet.overlap(mHandsOffNodes);
   rotBeenSet.overlap(mCallbackNodes);
   tranBeenSet.takeAway(maskPosNodes);
   tranBeenSet.overlap(mHandsOffNodes);
   tranBeenSet.overlap(mCallbackNodes);

   // default scale
   if (scaleCurrentlyAnimated())
      handleDefaultScale(a,b,scaleBeenSet);

   // handle non-blend sequences
   for (i=0; i<firstBlend; i++)
   {
      TSThread * th = mThreadList[i];

      j=0;
      start = th->getSequence()->rotationMatters.start();
      end   = b;
      for (nodeIndex=start; nodeIndex<end; th->getSequence()->rotationMatters.next(nodeIndex), j++)
      {
         // skip nodes outside of this detail
         if (nodeIndex<a)
            continue;
         if (!rotBeenSet.test(nodeIndex))
         {
            QuatF q1,q2;
            mShape->getRotation(*th->getSequence(),th->keyNum1,j,&q1);
            mShape->getRotation(*th->getSequence(),th->keyNum2,j,&q2);
            TSTransform::interpolate(q1,q2,th->keyPos,&mCurrentRenderState->smNodeCurrentRotations[nodeIndex]);
            rotBeenSet.set(nodeIndex);
            mCurrentRenderState->smRotationThreads[nodeIndex] = th;
         }
      }

      j=0;
      start = th->getSequence()->translationMatters.start();
      end   = b;
      for (nodeIndex=start; nodeIndex<end; th->getSequence()->translationMatters.next(nodeIndex), j++)
      {
         if (nodeIndex<a)
            continue;
         if (!tranBeenSet.test(nodeIndex))
         {
            if (maskPosNodes.test(nodeIndex))
               handleMaskedPositionNode(th,nodeIndex,j);
            else
            {
               const Point3F & p1 = mShape->getTranslation(*th->getSequence(),th->keyNum1,j);
               const Point3F & p2 = mShape->getTranslation(*th->getSequence(),th->keyNum2,j);
               TSTransform::interpolate(p1,p2,th->keyPos,&mCurrentRenderState->smNodeCurrentTranslations[nodeIndex]);
               mCurrentRenderState->smTranslationThreads[nodeIndex] = th;
            }
            tranBeenSet.set(nodeIndex);
         }
      }

      if (scaleCurrentlyAnimated())
         handleAnimatedScale(th,a,b,scaleBeenSet);
   }

   // compute transforms
   for (i=a; i<b; i++)
   {
      if (!mHandsOffNodes.test(i))
         TSTransform::setMatrix(mCurrentRenderState->smNodeCurrentRotations[i],mCurrentRenderState->smNodeCurrentTranslations[i],&mCurrentRenderState->smNodeLocalTransforms[i]);
      else
         mCurrentRenderState->smNodeLocalTransforms[i] = mNodeTransforms[i];     // in case mNodeTransform was changed externally
   }

   // add scale onto transforms
   if (scaleCurrentlyAnimated())
      handleNodeScale(a,b);

   // get callbacks...
   start = getMax(mCallbackNodes.start(),a);
   end = getMin(mCallbackNodes.end(),b);
   for (i=0; i<mNodeCallbacks.size(); i++)
   {
      AssertFatal(mNodeCallbacks[i].callback, "No callback method defined");
      S32 nodeIndex = mNodeCallbacks[i].nodeIndex;
      if (nodeIndex>=start && nodeIndex<end)
      {
         mNodeCallbacks[i].callback->setNodeTransform(this, nodeIndex, mCurrentRenderState->smNodeLocalTransforms[nodeIndex]);
         mCurrentRenderState->smNodeLocalTransformDirty.set(nodeIndex);
      }
   }

   // handle blend sequences
   for (i=firstBlend; i<mThreadList.size(); i++)
   {
      TSThread * th = mThreadList[i];
      if (th->blendDisabled)
         continue;

      handleBlendSequence(th,a,b);
   }

   // transitions...
   if (inTransition())
      handleTransitionNodes(a,b);

   // multiply transforms...
   for (i=a; i<b; i++)
   {
      S32 parentIdx = mShape->nodes[i].parentIndex;
      if (parentIdx < 0)
         mNodeTransforms[i] = mCurrentRenderState->smNodeLocalTransforms[i];
      else
         mNodeTransforms[i].mul(mNodeTransforms[parentIdx],mCurrentRenderState->smNodeLocalTransforms[i]);
   }
}
Пример #2
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;
      }
   }
}