Changeset 452 for cafu/trunk
- Timestamp:
- 12/31/11 17:57:20 (5 months ago)
- Location:
- cafu/trunk/Libs
- Files:
-
- 2 added
- 4 modified
-
Models/AnimExpr.cpp (added)
-
Models/AnimExpr.hpp (added)
-
Models/AnimPose.cpp (modified) (11 diffs)
-
Models/AnimPose.hpp (modified) (5 diffs)
-
Models/Classes.dia (modified) (previous)
-
SConscript (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
cafu/trunk/Libs/Models/AnimPose.cpp
r438 r452 21 21 22 22 #include "AnimPose.hpp" 23 #include "AnimExpr.hpp" 23 24 #include "Model_cmdl.hpp" 24 25 … … 31 32 AnimPoseT::AnimPoseT(const CafuModelT& Model, int SequNr, float FrameNr) 32 33 : m_Model(Model), 33 m_SequNr(SequNr), 34 m_FrameNr(FrameNr), 34 m_AnimExpr(NULL), 35 35 m_SuperPose(NULL), 36 36 m_DlodPose(m_Model.GetDlodModel() ? new AnimPoseT(*m_Model.GetDlodModel(), SequNr, FrameNr) : NULL), // Recursively create the chain of dlod poses matching the chain of dlod models. 37 m_ NeedsRecache(true),37 m_RecacheCount(0), 38 38 m_BoundingBox() 39 39 { 40 NormalizeInput();40 m_AnimExpr=new AnimExprStandardT(m_Model, SequNr, FrameNr); 41 41 } 42 42 … … 45 45 { 46 46 delete m_DlodPose; 47 delete m_AnimExpr; 47 48 } 48 49 … … 120 121 typedef CafuModelT::JointT JointT; 121 122 typedef CafuModelT::MeshT MeshT; 122 typedef CafuModelT::AnimT AnimT;123 123 124 124 const ArrayT<JointT>& Joints=m_Model.GetJoints(); 125 125 const ArrayT<MeshT>& Meshes=m_Model.GetMeshes(); 126 const ArrayT<AnimT>& Anims =m_Model.GetAnims();127 126 128 127 … … 132 131 // ************************************************************************************************************** 133 132 134 if (m_SequNr==-1) 135 { 136 // Don't animate, just use the bind pose defined in the model file. 137 for (unsigned long JointNr=0; JointNr<Joints.Size(); JointNr++) 138 { 139 if (m_SuperPose) 140 { 141 const MatrixT* SuperMat=m_SuperPose->GetJointMatrix(Joints[JointNr].Name); 142 143 if (SuperMat) 144 { 145 m_JointMatrices[JointNr]=*SuperMat; 146 continue; 147 } 148 } 149 150 const JointT& J=Joints[JointNr]; 151 const MatrixT RelMatrix(J.Pos, cf::math::QuaternionfT::FromXYZ(J.Qtr), J.Scale); 152 153 m_JointMatrices[JointNr]=(J.Parent==-1) ? RelMatrix : m_JointMatrices[J.Parent]*RelMatrix; 154 } 155 } 156 else 157 { 158 // m_SequNr is a valid index into Anims, so use that. 159 const AnimT& Anim=Anims[m_SequNr]; 160 const int Frame_0=int(m_FrameNr); // If m_FrameNr == 17.83, then Frame_0 == 17 161 const float Frame_f=m_FrameNr-Frame_0; // Frame_f == 0.83 162 const int Frame_1=(Frame_0+1>=int(Anim.Frames.Size())) ? 0 : Frame_0+1; // Frame_1 == 18 163 164 for (unsigned long JointNr=0; JointNr<Joints.Size(); JointNr++) 165 { 166 if (m_SuperPose) 167 { 168 const MatrixT* SuperMat=m_SuperPose->GetJointMatrix(Joints[JointNr].Name); 169 170 if (SuperMat) 171 { 172 m_JointMatrices[JointNr]=*SuperMat; 173 continue; 174 } 175 } 176 177 const AnimT::AnimJointT& AJ=Anim.AnimJoints[JointNr]; 178 179 Vector3fT Data_0[3]={ AJ.DefaultPos, AJ.DefaultQtr, AJ.DefaultScale }; 180 Vector3fT Data_1[3]={ AJ.DefaultPos, AJ.DefaultQtr, AJ.DefaultScale }; 181 182 // Determine the position, quaternion and scale for Frame_0 and Frame_1. 183 unsigned int FlagCount=0; 184 185 for (int i=0; i<9; i++) 186 { 187 if ((AJ.Flags >> i) & 1) 188 { 189 Data_0[i/3][i % 3]=Anim.Frames[Frame_0].AnimData[AJ.FirstDataIdx+FlagCount]; 190 Data_1[i/3][i % 3]=Anim.Frames[Frame_1].AnimData[AJ.FirstDataIdx+FlagCount]; 191 192 FlagCount++; 193 } 194 } 195 196 // Interpolate the position and quaternion according to the fraction Frame_f. 197 const Vector3fT Pos =Data_0[0]*(1.0f-Frame_f) + Data_1[0]*Frame_f; 198 const cf::math::QuaternionfT Quat =slerp(cf::math::QuaternionfT::FromXYZ(Data_0[1]), cf::math::QuaternionfT::FromXYZ(Data_1[1]), Frame_f); 199 const Vector3fT Scale=Data_0[2]*(1.0f-Frame_f) + Data_1[2]*Frame_f; 200 201 // Compute the matrix that is relative to the parent bone, and finally obtain the absolute matrix for that bone! 202 const MatrixT RelMatrix(Pos, Quat, Scale); 203 const JointT& J=Joints[JointNr]; 204 205 m_JointMatrices[JointNr]=(J.Parent==-1) ? RelMatrix : m_JointMatrices[J.Parent]*RelMatrix; 206 } 133 for (unsigned long JointNr=0; JointNr<Joints.Size(); JointNr++) 134 { 135 if (m_SuperPose) 136 { 137 const MatrixT* SuperMat=m_SuperPose->GetJointMatrix(Joints[JointNr].Name); 138 139 if (SuperMat) 140 { 141 m_JointMatrices[JointNr]=*SuperMat; 142 continue; 143 } 144 } 145 146 float Weight; 147 Vector3fT Pos; 148 cf::math::QuaternionfT Quat; 149 Vector3fT Scale; 150 151 m_AnimExpr->GetData(JointNr, Weight, Pos, Quat, Scale); 152 153 // Compute the matrix that is relative to the parent bone, and finally obtain the absolute matrix for that bone! 154 const MatrixT RelMatrix(Pos, Quat, Scale); 155 const JointT& J=Joints[JointNr]; 156 157 // assert(Weight==1.0f); 158 m_JointMatrices[JointNr]=(J.Parent==-1) ? RelMatrix : m_JointMatrices[J.Parent]*RelMatrix; 207 159 } 208 160 … … 261 213 if (m_Model.GetUseGivenTS()) 262 214 { 263 assert( Anims.Size()==0); // It doesn't make sense to have statically given tangent-space axes with *animated* geometry...215 assert(m_Model.GetAnims().Size()==0); // It doesn't make sense to have statically given tangent-space axes with *animated* geometry... 264 216 265 217 // Copy the given tangent space details into the pose. … … 447 399 void AnimPoseT::Recache() const 448 400 { 449 if (!m_ NeedsRecache && !m_SuperPose) return;401 if (!m_SuperPose && m_RecacheCount==m_AnimExpr->GetChangeCount()) return; 450 402 451 403 SyncDimensions(); … … 462 414 // y(); 463 415 464 m_NeedsRecache=false; 465 } 466 467 468 void AnimPoseT::NormalizeInput() 469 { 470 const ArrayT<CafuModelT::AnimT>& Anims=m_Model.GetAnims(); 471 472 // m_SequNr==-1 means "use the bind pose from the model file only (no anim)". 473 if (m_SequNr < -1) m_SequNr = -1; 474 if (m_SequNr >= int(Anims.Size())) m_SequNr = -1; 475 if (m_SequNr != -1 && (Anims[m_SequNr].FPS<0.0 || Anims[m_SequNr].Frames.Size()==0)) m_SequNr = -1; 476 477 m_FrameNr=std::max(m_FrameNr, 0.0f); 478 m_FrameNr=(m_SequNr==-1) ? 0.0f : fmod(m_FrameNr, float(Anims[m_SequNr].Frames.Size())); 479 } 416 m_RecacheCount=m_AnimExpr->GetChangeCount(); 417 } 418 419 420 int AnimPoseT::GetSequNr() const { return dynamic_cast<AnimExprStandardT*>(m_AnimExpr)->GetSequNr(); } 421 float AnimPoseT::GetFrameNr() const { return dynamic_cast<AnimExprStandardT*>(m_AnimExpr)->GetFrameNr(); } 480 422 481 423 482 424 void AnimPoseT::SetSequNr(int SequNr) 483 425 { 484 if (m_SequNr==SequNr) return; 485 486 m_SequNr=SequNr; 487 NormalizeInput(); 488 489 m_NeedsRecache=true; 426 dynamic_cast<AnimExprStandardT*>(m_AnimExpr)->SetSequNr(SequNr); 490 427 491 428 // Recursively update the chain of dlod poses. … … 496 433 void AnimPoseT::SetFrameNr(float FrameNr) 497 434 { 498 if (m_FrameNr==FrameNr) return; 499 500 m_FrameNr=FrameNr; 501 NormalizeInput(); 502 503 m_NeedsRecache=true; 435 dynamic_cast<AnimExprStandardT*>(m_AnimExpr)->SetFrameNr(FrameNr); 504 436 505 437 // Recursively update the chain of dlod poses. … … 513 445 514 446 m_SuperPose=SuperPose; 515 516 m_NeedsRecache=true; 447 m_RecacheCount=0; 517 448 518 449 // Recursively update the chain of dlod poses. … … 523 454 void AnimPoseT::Advance(float Time, bool ForceLoop) 524 455 { 525 // TODO: Beachte korrekte Wrap-Regeln für mit loopen und ohne. 526 // TODO: Loops (next vs. ForceLoop) richtig behandeln 527 const ArrayT<CafuModelT::AnimT>& Anims=m_Model.GetAnims(); 528 529 if (m_SequNr<0 || m_SequNr>=int(Anims.Size())) { SetFrameNr(0.0f); return; } 530 if (Anims[m_SequNr].Frames.Size()<=1) { SetFrameNr(0.0f); return; } 531 532 const float NumFrames=float(Anims[m_SequNr].Frames.Size()); 533 534 float FrameNr=m_FrameNr + Time*Anims[m_SequNr].FPS; 535 536 if (ForceLoop) 537 { 538 // Wrap the sequence (it's a looping (repeating) sequence, like idle, walk, ...). 539 FrameNr=fmod(FrameNr, NumFrames); 540 if (FrameNr<0.0f) FrameNr+=NumFrames; 541 } 542 else 543 { 544 // Clamp the sequence (it's a play-once (non-repeating) sequence, like dying). 545 // On clamping, stop the sequence 1/100th sec before the end of the last frame. 546 if (FrameNr>=NumFrames-1.0f) FrameNr=NumFrames-1.0f-0.01f; 547 if (FrameNr<0.0f) FrameNr=0.0f; 548 } 549 550 SetFrameNr(FrameNr); 456 m_AnimExpr->AdvanceTime(Time, ForceLoop); 551 457 552 458 // Recursively update the chain of dlod poses. -
cafu/trunk/Libs/Models/AnimPose.hpp
r438 r452 29 29 30 30 31 class AnimExpressionT; 31 32 class CafuModelT; 32 33 class MaterialT; … … 93 94 ~AnimPoseT(); 94 95 95 int GetSequNr() const { return m_SequNr; }96 int GetSequNr() const; 96 97 97 98 /// @param SequNr The number of the animation sequence to use, -1 for the bind pose. 98 99 void SetSequNr(int SequNr); 99 100 100 float GetFrameNr() const { return m_FrameNr; }101 float GetFrameNr() const; 101 102 102 103 /// @param FrameNr The frame number in the animation sequence to render the model at. … … 117 118 118 119 /// Call this if something in the related model has changed. 119 void SetNeedsRecache() { m_ NeedsRecache=true; }120 void SetNeedsRecache() { m_RecacheCount=0; } // 0 is different from any value that m_AnimExpr->GetChangedCount() returns. 120 121 121 122 /// This method renders the model in this pose. … … 170 171 void UpdateData() const; 171 172 void Recache() const; 172 void NormalizeInput();173 173 174 174 const CafuModelT& m_Model; ///< The related model that this is a pose for. 175 int m_SequNr; ///< The animation sequence number at which we have computed the cache data. 176 float m_FrameNr; ///< The animation frame number at which we have computed the cache data. 175 AnimExpressionT* m_AnimExpr; ///< The expression that describes the animation state of the joints for which we have computed the cache data. 177 176 const AnimPoseT* m_SuperPose; 178 177 AnimPoseT* m_DlodPose; ///< The next pose in the chain of dlod poses matching the chain of dlod models. … … 180 179 // bool m_DoCache; ///< Cache the computed data? (Set to true by the user if he want to re-use this instance.) 181 180 182 mutable bool m_NeedsRecache; ///< wird auf 'true' gesetzt wann immer SetSequ(), SetFrameNr() oder AdvanceAll() o.ä. aufgerufen wird, übernimmt m_Draw_CachedDataAt*Nr Funktionalität.181 mutable unsigned int m_RecacheCount; ///< Used to detect if the m_AnimExpr has changed, so that our matrices, meshes etc. can be recached. 183 182 mutable ArrayT<MatrixT> m_JointMatrices; ///< The transformation matrices that represent the pose of the skeleton at the given animation sequence and frame number. 184 183 mutable ArrayT<MeshInfoT> m_MeshInfos; ///< Additional data for each mesh in m_Model. -
cafu/trunk/Libs/SConscript
r428 r452 14 14 MapFile.cpp 15 15 Models/Loader.cpp Models/Loader_ase.cpp Models/Loader_cmdl.cpp Models/Loader_dlod.cpp Models/Loader_dummy.cpp Models/Loader_lwo.cpp Models/Loader_md5.cpp 16 Models/Loader_mdl.cpp Models/Anim Pose.cpp16 Models/Loader_mdl.cpp Models/AnimExpr.cpp Models/AnimPose.cpp 17 17 Models/Model_cmdl.cpp Models/ModelManager.cpp 18 18 Network/Network.cpp ParticleEngine/ParticleEngineMS.cpp PlatformAux.cpp Terrain/Terrain.cpp
