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); }
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); }
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]); } } }
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; } } }