summaryrefslogtreecommitdiffstats
path: root/src/animation/AnimBlendNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/animation/AnimBlendNode.cpp')
-rw-r--r--src/animation/AnimBlendNode.cpp172
1 files changed, 163 insertions, 9 deletions
diff --git a/src/animation/AnimBlendNode.cpp b/src/animation/AnimBlendNode.cpp
index df6cd1d5..6352c11b 100644
--- a/src/animation/AnimBlendNode.cpp
+++ b/src/animation/AnimBlendNode.cpp
@@ -46,6 +46,44 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight)
}
bool
+CAnimBlendNode::UpdateCompressed(CVector &trans, CQuaternion &rot, float weight)
+{
+ bool looped = false;
+
+ trans = CVector(0.0f, 0.0f, 0.0f);
+ rot = CQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
+
+ if(association->IsRunning()){
+ remainingTime -= association->timeStep;
+ if(remainingTime <= 0.0f)
+ looped = NextKeyFrameCompressed();
+ }
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB);
+ float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime();
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector transA, transB;
+ kfA->GetTranslation(&transA);
+ kfB->GetTranslation(&transB);
+ trans = transB + t*(transA - transB);
+ trans *= blend;
+ }
+ if(sequence->type & CAnimBlendSequence::KF_ROT){
+ CQuaternion rotA, rotB;
+ kfA->GetRotation(&rotA);
+ kfB->GetRotation(&rotB);
+ rot.Slerp(rotB, rotA, theta, invSin, t);
+ rot *= blend;
+ }
+ }
+
+ return looped;
+}
+
+bool
CAnimBlendNode::NextKeyFrame(void)
{
bool looped;
@@ -82,6 +120,43 @@ CAnimBlendNode::NextKeyFrame(void)
return looped;
}
+bool
+CAnimBlendNode::NextKeyFrameCompressed(void)
+{
+ bool looped;
+
+ if(sequence->numFrames <= 1)
+ return false;
+
+ looped = false;
+ frameB = frameA;
+
+ // Advance as long as we have to
+ while(remainingTime <= 0.0f){
+ frameA++;
+
+ if(frameA >= sequence->numFrames){
+ // reached end of animation
+ if(!association->IsRepeating()){
+ frameA--;
+ remainingTime = 0.0f;
+ return false;
+ }
+ looped = true;
+ frameA = 0;
+ }
+
+ remainingTime += sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime();
+ }
+
+ frameB = frameA - 1;
+ if(frameB < 0)
+ frameB += sequence->numFrames;
+
+ CalcDeltasCompressed();
+ return looped;
+}
+
// Set animation to time t
bool
CAnimBlendNode::FindKeyFrame(float t)
@@ -92,20 +167,22 @@ CAnimBlendNode::FindKeyFrame(float t)
frameA = 0;
frameB = frameA;
- if(sequence->numFrames >= 2){
- frameA++;
-
+ if(sequence->numFrames == 1){
+ remainingTime = 0.0f;
+ }else{
// advance until t is between frameB and frameA
- while(t > sequence->GetKeyFrame(frameA)->deltaTime){
+ while (t > sequence->GetKeyFrame(++frameA)->deltaTime) {
t -= sequence->GetKeyFrame(frameA)->deltaTime;
- frameB = frameA++;
- if(frameA >= sequence->numFrames){
+ if (frameA + 1 >= sequence->numFrames) {
// reached end of animation
- if(!association->IsRepeating())
+ if (!association->IsRepeating()) {
+ CalcDeltas();
+ remainingTime = 0.0f;
return false;
+ }
frameA = 0;
- frameB = 0;
}
+ frameB = frameA;
}
remainingTime = sequence->GetKeyFrame(frameA)->deltaTime - t;
@@ -115,6 +192,25 @@ CAnimBlendNode::FindKeyFrame(float t)
return true;
}
+bool
+CAnimBlendNode::SetupKeyFrameCompressed(void)
+{
+ if(sequence->numFrames < 1)
+ return false;
+
+ frameA = 1;
+ frameB = 0;
+
+ if(sequence->numFrames == 1){
+ frameA = 0;
+ remainingTime = 0.0f;
+ }else
+ remainingTime = sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime();
+
+ CalcDeltasCompressed();
+ return true;
+}
+
void
CAnimBlendNode::CalcDeltas(void)
{
@@ -130,6 +226,28 @@ CAnimBlendNode::CalcDeltas(void)
}
void
+CAnimBlendNode::CalcDeltasCompressed(void)
+{
+ if((sequence->type & CAnimBlendSequence::KF_ROT) == 0)
+ return;
+ KeyFrameCompressed *kfA = sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameCompressed *kfB = sequence->GetKeyFrameCompressed(frameB);
+ CQuaternion rotA, rotB;
+ kfA->GetRotation(&rotA);
+ kfB->GetRotation(&rotB);
+ float cos = DotProduct(rotA, rotB);
+ if(cos < 0.0f){
+ rotB *= -1.0f;
+ kfB->SetRotation(rotB);
+ }
+ cos = DotProduct(rotA, rotB);
+ if(cos > 1.0f)
+ cos = 1.0f;
+ theta = Acos(cos);
+ invSin = theta == 0.0f ? 0.0f : 1.0f/Sin(theta);
+}
+
+void
CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
{
trans = CVector(0.0f, 0.0f, 0.0f);
@@ -138,7 +256,7 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
if(blend > 0.0f){
KeyFrameTrans *kfA = (KeyFrameTrans*)sequence->GetKeyFrame(frameA);
KeyFrameTrans *kfB = (KeyFrameTrans*)sequence->GetKeyFrame(frameB);
- float t = (kfA->deltaTime - remainingTime)/kfA->deltaTime;
+ float t = kfA->deltaTime == 0.0f ? 0.0f : (kfA->deltaTime - remainingTime)/kfA->deltaTime;
if(sequence->type & CAnimBlendSequence::KF_TRANS){
trans = kfB->translation + t*(kfA->translation - kfB->translation);
trans *= blend;
@@ -147,6 +265,26 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
}
void
+CAnimBlendNode::GetCurrentTranslationCompressed(CVector &trans, float weight)
+{
+ trans = CVector(0.0f, 0.0f, 0.0f);
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB);
+ float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime();
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector transA, transB;
+ kfA->GetTranslation(&transA);
+ kfB->GetTranslation(&transB);
+ trans = transB + t*(transA - transB);
+ trans *= blend;
+ }
+ }
+}
+
+void
CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
{
trans = CVector(0.0f, 0.0f, 0.0f);
@@ -158,3 +296,19 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
trans = kf->translation * blend;
}
}
+
+void
+CAnimBlendNode::GetEndTranslationCompressed(CVector &trans, float weight)
+{
+ trans = CVector(0.0f, 0.0f, 0.0f);
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(sequence->numFrames-1);
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector pos;
+ kf->GetTranslation(&pos);
+ trans = pos * blend;
+ }
+ }
+}