Changeset 400

Show
Ignore:
Timestamp:
10/05/11 11:21:02 (8 months ago)
Author:
Carsten
Message:

Model support:
Separated the pose of a model from the definition of the model, encapsulating the pose in the newly introduced class AnimPoseT.

This is a preparatory step for completing the support of animation channels and animation blending, where a pose will be composed of possibly several animation sequences playing on different channels, and animation sequences that are blended into each other.

This change also improves the existing code and design, as separate concepts are now cleanly separated in code.
It also improves caching, because all cached data is encapsulated in AnimPoseT where it is up to the user code to share or reuse the data across models and/or video frames.

Location:
cafu/trunk
Files:
2 added
14 modified

Legend:

Unmodified
Added
Removed
  • cafu/trunk/CaWE/ModelEditor/ChildFrame.cpp

    r397 r400  
    841841            m_ModelDoc->UpdateAllObservers_SelectionChanged(ANIM, OldSel, m_ModelDoc->GetSelection(ANIM)); 
    842842 
    843             m_ModelDoc->GetAnimState().FrameNr=0.0f; 
     843            m_ModelDoc->GetAnimState().Pose.SetFrameNr(0.0f); 
    844844            m_ModelDoc->UpdateAllObservers_AnimStateChanged(); 
    845845            break; 
     
    852852            m_ModelDoc->UpdateAllObservers_SelectionChanged(ANIM, OldSel, m_ModelDoc->GetSelection(ANIM)); 
    853853 
    854             m_ModelDoc->GetAnimState().FrameNr=0.0f; 
     854            m_ModelDoc->GetAnimState().Pose.SetFrameNr(0.0f); 
    855855            m_ModelDoc->UpdateAllObservers_AnimStateChanged(); 
    856856            break; 
  • cafu/trunk/CaWE/ModelEditor/Commands/Add.cpp

    r394 r400  
    103103 
    104104    // Make sure that the draw cache is refreshed. 
    105     m_ModelDoc->GetModel()->m_Draw_CachedDataAtSequNr=-1234; 
     105    m_ModelDoc->GetAnimState().Pose.SetNeedsRecache(); 
    106106 
    107107    m_ModelDoc->UpdateAllObservers_Created(m_Type, Indices); 
     
    159159 
    160160    // Make sure that the draw cache is refreshed. 
    161     m_ModelDoc->GetModel()->m_Draw_CachedDataAtSequNr=-1234; 
     161    m_ModelDoc->GetAnimState().Pose.SetNeedsRecache(); 
    162162 
    163163    m_ModelDoc->UpdateAllObservers_Deleted(m_Type, Indices); 
  • cafu/trunk/CaWE/ModelEditor/Commands/Delete.cpp

    r396 r400  
    8888                MeshInfoT& MI=m_MeshInfos[m_MeshInfos.Size()-1]; 
    8989 
    90                 MI.Mesh    =m_ModelDoc->GetModel()->GetMeshes()[i]; 
    91                 MI.DrawMesh=m_ModelDoc->GetModel()->m_Draw_Meshes[i]; 
     90                MI.Mesh=m_ModelDoc->GetModel()->GetMeshes()[i]; 
    9291 
    9392                for (unsigned long SkinNr=0; SkinNr<m_ModelDoc->GetModel()->GetSkins().Size(); SkinNr++) 
     
    158157    if (m_Type==MESH) 
    159158    { 
     159        if (m_Indices.Size() >= m_ModelDoc->GetModel()->GetMeshes().Size()) 
     160        { 
     161            m_Message="Cannot delete all meshes -- at least one mesh must be left."; 
     162            return false; 
     163        } 
     164 
    160165        for (unsigned long GFixNr=0; GFixNr<m_ModelDoc->GetModel()->GetGuiFixtures().Size(); GFixNr++) 
    161166            for (unsigned int PointNr=0; PointNr<3; PointNr++) 
     
    183188            case MESH: 
    184189            { 
    185                 m_ModelDoc->GetModel()->m_Meshes     .RemoveAtAndKeepOrder(i); 
    186                 m_ModelDoc->GetModel()->m_Draw_Meshes.RemoveAtAndKeepOrder(i); 
     190                m_ModelDoc->GetModel()->m_Meshes.RemoveAtAndKeepOrder(i); 
    187191 
    188192                for (unsigned long SkinNr=0; SkinNr<m_ModelDoc->GetModel()->GetSkins().Size(); SkinNr++) 
     
    197201 
    198202    // Make sure that the draw cache is refreshed. 
    199     m_ModelDoc->GetModel()->m_Draw_CachedDataAtSequNr=-1234; 
     203    m_ModelDoc->GetAnimState().Pose.SetNeedsRecache(); 
    200204 
    201205    m_ModelDoc->UpdateAllObservers_Deleted(m_Type, m_Indices); 
     
    226230                const MeshInfoT& MI=m_MeshInfos[INr]; 
    227231 
    228                 m_ModelDoc->GetModel()->m_Meshes     .InsertAt(i, MI.Mesh); 
    229                 m_ModelDoc->GetModel()->m_Draw_Meshes.InsertAt(i, MI.DrawMesh); 
     232                m_ModelDoc->GetModel()->m_Meshes.InsertAt(i, MI.Mesh); 
    230233 
    231234                for (unsigned long SkinNr=0; SkinNr<m_ModelDoc->GetModel()->GetSkins().Size(); SkinNr++) 
     
    240243 
    241244    // Make sure that the draw cache is refreshed. 
    242     m_ModelDoc->GetModel()->m_Draw_CachedDataAtSequNr=-1234; 
     245    m_ModelDoc->GetAnimState().Pose.SetNeedsRecache(); 
    243246 
    244247    m_ModelDoc->UpdateAllObservers_Created(m_Type, m_Indices); 
  • cafu/trunk/CaWE/ModelEditor/Commands/Delete.hpp

    r396 r400  
    5454        { 
    5555            CafuModelT::MeshT                Mesh;                  ///< The deleted mesh. 
    56             MatSys::MeshT                    DrawMesh;              ///< The draw mesh related to \c Mesh. 
    5756            ArrayT<MaterialT*>               SkinsMaterials;        ///< The material in each skin for this mesh. 
    5857            ArrayT<MatSys::RenderMaterialT*> SkinsRenderMaterials;  ///< The render material in each skin for this mesh. 
  • cafu/trunk/CaWE/ModelEditor/Commands/TransformJoint.cpp

    r358 r400  
    5252    // Make sure that the BB is updated and the draw cache is refreshed. 
    5353    m_ModelDoc->GetModel()->RecomputeBindPoseBB(); 
    54     m_ModelDoc->GetModel()->m_Draw_CachedDataAtSequNr=-1234; 
     54    m_ModelDoc->GetAnimState().Pose.SetNeedsRecache(); 
    5555 
    5656    m_ModelDoc->UpdateAllObservers_JointChanged(m_JointNr); 
     
    7171    // Make sure that the BB is updated and the draw cache is refreshed. 
    7272    m_ModelDoc->GetModel()->RecomputeBindPoseBB(); 
    73     m_ModelDoc->GetModel()->m_Draw_CachedDataAtSequNr=-1234; 
     73    m_ModelDoc->GetAnimState().Pose.SetNeedsRecache(); 
    7474 
    7575    m_ModelDoc->UpdateAllObservers_JointChanged(m_JointNr); 
  • cafu/trunk/CaWE/ModelEditor/ModelDocument.cpp

    r394 r400  
    4040 
    4141ModelEditor::ModelDocumentT::SubmodelT::SubmodelT(const wxString& fn, CafuModelT* sm, const ArrayT<unsigned int>& jm) 
    42     : m_Filename(fn), m_Submodel(sm), m_JointsMap(jm) 
     42    : m_Filename(fn), 
     43      m_Submodel(sm), 
     44      m_Pose(*sm, -1, 0.0f), 
     45      m_JointsMap(jm) 
    4346{ 
    4447} 
     
    6467    : m_Model(LoadModel(FileName)), 
    6568      m_SequenceBB(m_Model->GetBB(-1, 0.0f)), 
     69      m_AnimState(*m_Model), 
    6670      m_Submodels(), 
    6771      m_Gui(new cf::GuiSys::GuiImplT("Win1=gui:new('WindowT'); gui:SetRootWindow(Win1); gui:activate(true); " 
     
    132136    if (Type==ANIM) 
    133137    { 
     138        m_AnimState.Pose.SetSequNr(m_Selection[ANIM].Size()==0 ? -1 : m_Selection[ANIM][0]); 
     139 
    134140        if (m_Selection[ANIM].Size()==0) 
    135141        { 
     
    224230void ModelEditor::ModelDocumentT::AdvanceTime(float Time) 
    225231{ 
    226     if (m_Selection[ANIM].Size()>0 && Time*m_AnimState.Speed!=0.0f) 
    227     { 
    228         m_AnimState.FrameNr=m_Model->AdvanceFrameNr(m_Selection[ANIM][0], m_AnimState.FrameNr, Time*m_AnimState.Speed, m_AnimState.Loop); 
     232    if (Time*m_AnimState.Speed!=0.0f) 
     233    { 
     234        m_AnimState.Pose.Advance(Time*m_AnimState.Speed, m_AnimState.Loop); 
    229235    } 
    230236} 
  • cafu/trunk/CaWE/ModelEditor/ModelDocument.hpp

    r394 r400  
    2727#include "Math3D/BoundingBox.hpp" 
    2828#include "Math3D/Vector3.hpp" 
     29#include "Models/AnimPose.hpp" 
    2930#include "Templates/Array.hpp" 
    3031#include "wx/wx.h" 
     
    6364            public: 
    6465 
    65             AnimStateT() 
    66                 : FrameNr(0.0f), Speed(1.0f), Loop(true) { } 
     66            AnimStateT(const CafuModelT& Model) 
     67                : Pose(Model), Speed(1.0f), Loop(true) { } 
    6768 
    68             float FrameNr;  ///< The current frame number. 
    69             float Speed;    ///< The speed (relative to clock time) with which the animation is advanced, usually 0 for stop or 1 for playback. 
    70             bool  Loop;     ///< When playing the sequence, loop automatically when its end has been reached? 
     69            AnimPoseT Pose;     ///< The current pose of the model, as defined by sequence and frame number. 
     70            float     Speed;    ///< The speed (relative to clock time) with which the animation is advanced, usually 0 for stop or 1 for playback. 
     71            bool      Loop;     ///< When playing the sequence, loop automatically when its end has been reached? 
    7172        }; 
    7273 
     
    8081            const wxString&             GetFilename() const { return m_Filename; } 
    8182            const CafuModelT*           GetSubmodel() const { return m_Submodel; } 
     83            AnimPoseT&                  GetPose() { return m_Pose; } 
    8284            const ArrayT<unsigned int>& GetJointsMap() const { return m_JointsMap; } 
    8385 
     
    8789            wxString             m_Filename;    ///< The filename of the submodel. 
    8890            CafuModelT*          m_Submodel;    ///< The submodel that is shown with the main model. 
     91            AnimPoseT            m_Pose;        ///< The pose of the submodel. 
    8992            ArrayT<unsigned int> m_JointsMap;   ///< Describes how the joints of the m_Submodel map to the joints of the m_Model super model. 
    9093 
  • cafu/trunk/CaWE/ModelEditor/ScenePropGrid.cpp

    r383 r400  
    135135 
    136136    wxPGProperty* AnimControlCat=Append(new wxPropertyCategory("Animation Control")); 
    137     m_AnimFrameNrProp=AppendIn(AnimControlCat, new wxFloatProperty("Frame No.", wxPG_LABEL, Anim.FrameNr)); 
     137    m_AnimFrameNrProp=AppendIn(AnimControlCat, new wxFloatProperty("Frame No.", wxPG_LABEL, Anim.Pose.GetFrameNr())); 
    138138    m_AnimSpeedProp  =AppendIn(AnimControlCat, new wxFloatProperty("Speed", wxPG_LABEL, Anim.Speed)); 
    139139    m_AnimLoopProp   =AppendIn(AnimControlCat, new wxBoolProperty("Loop", wxPG_LABEL, Anim.Loop)); 
     
    218218    else if (PropName=="Model.Show Mesh")     m_Model_ShowMesh    =Prop->GetValue().GetBool(); 
    219219    else if (PropName=="Model.Show Skeleton") m_Model_ShowSkeleton=Prop->GetValue().GetBool(); 
    220     else if (PropName=="Frame No.") { AnimState.FrameNr=PropValueF; m_IsRecursiveSelfNotify=true; m_Parent->GetModelDoc()->UpdateAllObservers_AnimStateChanged(); m_IsRecursiveSelfNotify=false; } 
    221     else if (PropName=="Speed")     { AnimState.Speed  =PropValueF; m_IsRecursiveSelfNotify=true; m_Parent->GetModelDoc()->UpdateAllObservers_AnimStateChanged(); m_IsRecursiveSelfNotify=false; } 
    222     else if (PropName=="Loop")      { AnimState.Loop   =Prop->GetValue().GetBool(); m_IsRecursiveSelfNotify=true; m_Parent->GetModelDoc()->UpdateAllObservers_AnimStateChanged(); m_IsRecursiveSelfNotify=false; } 
     220    else if (PropName=="Frame No.") { AnimState.Pose.SetFrameNr(PropValueF); m_IsRecursiveSelfNotify=true; m_Parent->GetModelDoc()->UpdateAllObservers_AnimStateChanged(); m_IsRecursiveSelfNotify=false; } 
     221    else if (PropName=="Speed")     { AnimState.Speed=PropValueF; m_IsRecursiveSelfNotify=true; m_Parent->GetModelDoc()->UpdateAllObservers_AnimStateChanged(); m_IsRecursiveSelfNotify=false; } 
     222    else if (PropName=="Loop")      { AnimState.Loop =Prop->GetValue().GetBool(); m_IsRecursiveSelfNotify=true; m_Parent->GetModelDoc()->UpdateAllObservers_AnimStateChanged(); m_IsRecursiveSelfNotify=false; } 
    223223    else if (PropName=="Ambient Light Color") 
    224224    { 
     
    275275    const ModelDocumentT::AnimStateT& AnimState=m_Parent->GetModelDoc()->GetAnimState(); 
    276276 
    277     if (m_AnimFrameNrProp->GetValue().GetDouble()!=AnimState.FrameNr) 
    278         m_AnimFrameNrProp->SetValue(AnimState.FrameNr); 
     277    if (m_AnimFrameNrProp->GetValue().GetDouble()!=AnimState.Pose.GetFrameNr()) 
     278        m_AnimFrameNrProp->SetValue(AnimState.Pose.GetFrameNr()); 
    279279 
    280280    if (m_AnimSpeedProp->GetValue().GetDouble()!=AnimState.Speed) 
  • cafu/trunk/CaWE/ModelEditor/SceneView3D.cpp

    r383 r400  
    101101 
    102102    // Trace the ray against the model, which is a per-triangle accurate test. 
    103     const ModelDocumentT::AnimStateT& Anim   =ModelDoc->GetAnimState(); 
    104     const ArrayT<unsigned int>&       AnimSel=ModelDoc->GetSelection(ANIM); 
    105103    ModelT::TraceResultT Result; 
    106104 
    107     if (ModelDoc->GetModel()->TraceRay(AnimSel.Size()==0 ? -1 : AnimSel[0], Anim.FrameNr, 
    108         ModelDoc->GetSelSkinNr(), RayOrigin, RayDir, Result) && Result.Fraction<BestFraction) 
     105    if (ModelDoc->GetAnimState().Pose.TraceRay(ModelDoc->GetSelSkinNr(), RayOrigin, RayDir, Result) && Result.Fraction<BestFraction) 
    109106    { 
    110107        BestFraction=Result.Fraction; 
     
    164161            ModelDoc->UpdateAllObservers_SelectionChanged(ANIM, OldSel, ModelDoc->GetSelection(ANIM)); 
    165162 
    166             ModelDoc->GetAnimState().FrameNr=0.0f; 
     163            ModelDoc->GetAnimState().Pose.SetFrameNr(0.0f); 
    167164            ModelDoc->UpdateAllObservers_AnimStateChanged(); 
    168165            break; 
     
    176173            ModelDoc->UpdateAllObservers_SelectionChanged(ANIM, OldSel, ModelDoc->GetSelection(ANIM)); 
    177174 
    178             ModelDoc->GetAnimState().FrameNr=0.0f; 
     175            ModelDoc->GetAnimState().Pose.SetFrameNr(0.0f); 
    179176            ModelDoc->UpdateAllObservers_AnimStateChanged(); 
    180177            break; 
     
    237234    const Vector3fT      HitPos=TraceCameraRay(ScreenToClient(CE.GetPosition()), ModelTR); 
    238235    const CafuModelT*    Model=m_Parent->GetModelDoc()->GetModel(); 
     236    const AnimPoseT&     Pose=m_Parent->GetModelDoc()->GetAnimState().Pose; 
    239237    unsigned int         BestVertexNr=0; 
    240238    bool                 HaveModelHit=false; 
     
    242240    if (ModelTR.Fraction>0.0f && ModelTR.MeshNr<Model->GetMeshes().Size() && ModelTR.TriNr<Model->GetMeshes()[ModelTR.MeshNr].Triangles.Size()) 
    243241    { 
    244         float BestDist=0.0f; 
    245  
    246         for (unsigned int i=0; i<3; i++) 
    247         { 
    248             const unsigned int VertexNr=Model->GetMeshes()[ModelTR.MeshNr].Triangles[ModelTR.TriNr].VertexIdx[i]; 
    249             const Vector3fT&   DrawPos =Model->GetMeshes()[ModelTR.MeshNr].Vertices[VertexNr].Draw_Pos; 
    250             const float        Dist    =length(DrawPos-HitPos); 
    251  
    252             if (i==0 || Dist<BestDist) 
    253             { 
    254                 BestDist    =Dist; 
    255                 BestVertexNr=VertexNr; 
    256             } 
    257         } 
    258  
     242        BestVertexNr=Pose.FindClosestVertex(ModelTR.MeshNr, ModelTR.TriNr, HitPos); 
    259243        HaveModelHit=true; 
    260244    } 
     
    383367 
    384368    // Render the model. 
    385     const CafuModelT*                 Model  =ModelDoc->GetModel(); 
    386     const ModelDocumentT::AnimStateT& Anim   =ModelDoc->GetAnimState(); 
    387     const ArrayT<unsigned int>&       AnimSel=ModelDoc->GetSelection(ANIM); 
    388     const int                         SequNr =AnimSel.Size()==0 ? -1 : AnimSel[0]; 
     369    const CafuModelT*                 Model=ModelDoc->GetModel(); 
     370    const ModelDocumentT::AnimStateT& Anim =ModelDoc->GetAnimState(); 
    389371 
    390372    if (ScenePropGrid->m_Model_ShowMesh) 
    391373    { 
    392         Model->Draw(SequNr, Anim.FrameNr, ModelDoc->GetSelSkinNr(), 0.0f /*LodDist*/, (CafuModelT::SuperT*)NULL); 
     374        Anim.Pose.Draw(ModelDoc->GetSelSkinNr(), 0.0f /*LodDist*/); 
    393375 
    394376        for (unsigned long SmNr=0; SmNr<ModelDoc->GetSubmodels().Size(); SmNr++) 
    395377        { 
    396             const ModelDocumentT::SubmodelT* SM=ModelDoc->GetSubmodels()[SmNr]; 
    397             const CafuModelT::SuperT Super( 
    398                 Model->GetDrawJointMatrices(SequNr, Anim.FrameNr), 
     378            ModelDocumentT::SubmodelT* SM=ModelDoc->GetSubmodels()[SmNr]; 
     379            AnimPoseT&                 SmPose=SM->GetPose(); 
     380 
     381            const AnimPoseT::SuperT Super( 
     382                Anim.Pose.GetJointMatrices(), 
    399383                SM->GetJointsMap()); 
    400384 
    401             SM->GetSubmodel()->Draw(0, 0.0f, -1 /*SkinNr*/, 0.0f /*LodDist*/, &Super); 
     385            SmPose.SetSuper(&Super); 
     386            SmPose.Draw(-1 /*SkinNr*/, 0.0f /*LodDist*/); 
     387            SmPose.SetSuper(NULL); 
    402388        } 
    403389    } 
     
    407393    if (ScenePropGrid->m_Model_ShowSkeleton && MatSys::Renderer->GetCurrentRenderAction()==MatSys::RendererI::AMBIENT) 
    408394    { 
    409         RenderSkeleton(Model->GetJoints(), Model->GetDrawJointMatrices(SequNr, Anim.FrameNr), false); 
     395        RenderSkeleton(Model->GetJoints(), Anim.Pose.GetJointMatrices(), false); 
    410396 
    411397        for (unsigned long SmNr=0; SmNr<ModelDoc->GetSubmodels().Size(); SmNr++) 
    412398        { 
    413             const ModelDocumentT::SubmodelT* SM=ModelDoc->GetSubmodels()[SmNr]; 
    414             const CafuModelT::SuperT Super( 
    415                 Model->GetDrawJointMatrices(SequNr, Anim.FrameNr), 
     399            ModelDocumentT::SubmodelT* SM=ModelDoc->GetSubmodels()[SmNr]; 
     400            AnimPoseT&                 SmPose=SM->GetPose(); 
     401 
     402            const AnimPoseT::SuperT Super( 
     403                Anim.Pose.GetJointMatrices(), 
    416404                SM->GetJointsMap()); 
    417405 
    418             RenderSkeleton(SM->GetSubmodel()->GetJoints(), SM->GetSubmodel()->GetDrawJointMatrices(0, 0.0f, &Super), true); 
     406            SmPose.SetSuper(&Super); 
     407            RenderSkeleton(SM->GetSubmodel()->GetJoints(), SmPose.GetJointMatrices(), true); 
     408            SmPose.SetSuper(NULL); 
    419409        } 
    420410    } 
     
    435425                if (!Model->IsVertexNrOK(GF, PointNr)) continue; 
    436426 
    437                 Points[PointNr]=Model->GetMeshes()[GF.Points[PointNr].MeshNr].Vertices[GF.Points[PointNr].VertexNr].Draw_Pos; 
     427                Points[PointNr]=Anim.Pose.GetVertexPos(GF.Points[PointNr].MeshNr, GF.Points[PointNr].VertexNr); 
    438428                PointsOK|=(1 << PointNr); 
    439429            } 
  • cafu/trunk/Libs/Models/Loader_ase.cpp

    r334 r400  
    531531 
    532532                    assert(CafuVertex.NumWeights==1); 
    533                     assert(Mesh.Weights[CafuVertex.FirstWeightIdx].Pos==CafuVertex.Draw_Pos); 
    534  
    535                     if (CafuVertex.Draw_Pos!=AseVertexPos) continue; 
     533                    assert(Mesh.Weights[CafuVertex.FirstWeightIdx].Pos==CafuVertex.gts_Pos); 
     534 
     535                    if (CafuVertex.gts_Pos!=AseVertexPos) continue; 
    536536                    if (CafuVertex.u!=GO.TexCoords[AseTri.IndTexCoords[i]].AsVectorOfFloat().x) continue; 
    537537                    if (CafuVertex.v!=GO.TexCoords[AseTri.IndTexCoords[i]].AsVectorOfFloat().y) continue; 
    538538 
    539                     if (CafuVertex.Draw_Normal!=AseTri.Normals[i].AsVectorOfFloat()) continue; 
    540                     if (CafuVertex.Draw_Tangent!=AseTri.Tangents[i].AsVectorOfFloat()) continue; 
    541                     if (CafuVertex.Draw_BiNormal!=AseTri.BiNormals[i].AsVectorOfFloat()) continue; 
     539                    if (CafuVertex.gts_Normal!=AseTri.Normals[i].AsVectorOfFloat()) continue; 
     540                    if (CafuVertex.gts_Tangent!=AseTri.Tangents[i].AsVectorOfFloat()) continue; 
     541                    if (CafuVertex.gts_BiNormal!=AseTri.BiNormals[i].AsVectorOfFloat()) continue; 
    542542 
    543543                    // This vertex meets all criteria - take it. 
     
    569569                    CafuVertex.FirstWeightIdx=WeightNr; 
    570570                    CafuVertex.NumWeights    =1; 
    571                     CafuVertex.Draw_Pos      =AseVertexPos; 
    572                     CafuVertex.Draw_Normal   =AseTri.Normals[i].AsVectorOfFloat(); 
    573                     CafuVertex.Draw_Tangent  =AseTri.Tangents[i].AsVectorOfFloat(); 
    574                     CafuVertex.Draw_BiNormal =AseTri.BiNormals[i].AsVectorOfFloat(); 
     571                    CafuVertex.gts_Pos       =AseVertexPos; 
     572                    CafuVertex.gts_Normal    =AseTri.Normals[i].AsVectorOfFloat(); 
     573                    CafuVertex.gts_Tangent   =AseTri.Tangents[i].AsVectorOfFloat(); 
     574                    CafuVertex.gts_BiNormal =AseTri.BiNormals[i].AsVectorOfFloat(); 
    575575                } 
    576576 
     
    580580            } 
    581581 
    582             CafuTri.Draw_Normal=AseTri.Normal.AsVectorOfFloat(); 
     582            CafuTri.gts_Normal=AseTri.Normal.AsVectorOfFloat(); 
    583583        } 
    584584 
  • cafu/trunk/Libs/Models/Loader_lwo.cpp

    r322 r400  
    369369                    MeshVertex.NumWeights    =1; 
    370370 
    371                     MeshVertex.Draw_Pos      =Mesh.Weights[PolyVert.index].Pos;     // Normally the base class code computes this, but we also have to pre-provide a proper value here for ComputeTangents(). 
    372                     MeshVertex.Draw_Normal   =Vector3fT(PolyVert.norm); 
    373                  // MeshVertex.Draw_Tangent  =...;      // Set below to polygon average. 
    374                  // MeshVertex.Draw_BiNormal =...;      // Set below to polygon average. 
     371                    MeshVertex.gts_Pos      =Mesh.Weights[PolyVert.index].Pos;     // Normally the base class code computes this, but we also have to pre-provide a proper value here for ComputeTangents(). 
     372                    MeshVertex.gts_Normal   =Vector3fT(PolyVert.norm); 
     373                 // MeshVertex.gts_Tangent  =...;      // Set below to polygon average. 
     374                 // MeshVertex.gts_BiNormal =...;      // Set below to polygon average. 
    375375 
    376376                    WeightVerts[PolyVert.index].PushBack(MeshVertexNr); 
     
    395395                    Triangle.VertexIdx[2]=PolygonMeshVertices[VertexNr+1]; 
    396396 
    397                     Triangle.Draw_Normal=Vector3fT(Poly.norm); 
     397                    Triangle.gts_Normal=Vector3fT(Poly.norm); 
    398398 
    399399 
     
    415415                    // The vertex may be shared across multiple polygons, and we want to build the average over them. 
    416416                    // Therefore we only accumulate the tangents here, and normalize below. 
    417                     Vertex.Draw_Tangent +=myNormalize(Poly_Tangent); 
    418                     Vertex.Draw_BiNormal+=myNormalize(Poly_BiTangent); 
     417                    Vertex.gts_Tangent +=myNormalize(Poly_Tangent); 
     418                    Vertex.gts_BiNormal+=myNormalize(Poly_BiTangent); 
    419419                } 
    420420            } 
     
    426426                CafuModelT::MeshT::VertexT& Vertex=Mesh.Vertices[VertexNr]; 
    427427 
    428                 Vertex.Draw_Tangent =myNormalize(Vertex.Draw_Tangent ); 
    429                 Vertex.Draw_BiNormal=myNormalize(Vertex.Draw_BiNormal); 
     428                Vertex.gts_Tangent =myNormalize(Vertex.gts_Tangent ); 
     429                Vertex.gts_BiNormal=myNormalize(Vertex.gts_BiNormal); 
    430430            } 
    431431        } 
     
    446446    const CafuModelT::MeshT::VertexT&   V_1   =Mesh.Vertices[Tri.VertexIdx[1]]; 
    447447    const CafuModelT::MeshT::VertexT&   V_2   =Mesh.Vertices[Tri.VertexIdx[2]]; 
    448     const Vector3fT                     Edge01=V_1.Draw_Pos-V_0.Draw_Pos; 
    449     const Vector3fT                     Edge02=V_2.Draw_Pos-V_0.Draw_Pos; 
     448    const Vector3fT                     Edge01=V_1.gts_Pos-V_0.gts_Pos; 
     449    const Vector3fT                     Edge02=V_2.gts_Pos-V_0.gts_Pos; 
    450450 
    451451    // Triangles are ordered CW for md5 models and CCW for ase models, so we write 
    452452    // Normal=VectorCross(Edge02, Edge01) for md5 models and Normal=VectorCross(Edge01, Edge02) for ase models. 
    453     // Tri.Draw_Normal=myNormalize(Edge02.cross(Edge01)); 
     453    // Tri.gts_Normal=myNormalize(Edge02.cross(Edge01)); 
    454454 
    455455    // Understanding what's going on here is easy. The key statement is 
  • cafu/trunk/Libs/Models/Model_cmdl.cpp

    r398 r400  
    2121 
    2222#include "Model_cmdl.hpp" 
     23#include "AnimPose.hpp"     // Only for implementing the "old" ModelT interface methods. 
    2324#include "Loader.hpp" 
    2425#include "MaterialSystem/Material.hpp" 
    2526#include "MaterialSystem/Renderer.hpp" 
    2627#include "Math3D/BoundingBox.hpp" 
    27 #include "Math3D/Pluecker.hpp" 
    2828#include "Math3D/Quaternion.hpp" 
    2929#include "String.hpp" 
     
    240240      m_MaterialMan(), 
    241241      m_UseGivenTangentSpace(Loader.UseGivenTS()),  // Should we use the fixed, given tangent space, or recompute it ourselves here? 
    242       m_BindPoseBB(Vector3fT()),                    // Re-initialized in InitMeshes() calling RecomputeBindPoseBB(), but start with a valid box anyways (e.g. for testing models that have a skeleton, but no mesh). 
    243       m_Draw_CachedDataAtSequNr(-1234),             // Just a random number that is unlikely to occur normally. 
    244       m_Draw_CachedDataAtFrameNr(-3.1415926f)       // Just a random number that is unlikely to occur normally. 
     242      m_BindPoseBB(Vector3fT())                     // Re-initialized in InitMeshes() calling RecomputeBindPoseBB(), but start with a valid box anyways (e.g. for testing models that have a skeleton, but no mesh). 
    245243{ 
    246244    // No matter the actual model file format (that is, even if the file format is not "cmdl"), 
     
    305303                Skin.RenderMaterials[MatNr]=MatSys::Renderer->RegisterMaterial(Skin.Materials[MatNr]); 
    306304        } 
    307     } 
    308  
    309     // Allocate the cache space that is needed for drawing. 
    310     m_JointMatrices.PushBackEmpty(m_Joints.Size()); 
    311     m_Draw_Meshes.PushBackEmpty(m_Meshes.Size()); 
    312  
    313     for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    314     { 
    315         m_Draw_Meshes[MeshNr].Type   =MatSys::MeshT::Triangles; 
    316      // m_Draw_Meshes[MeshNr].Winding=MatSys::MeshT::CW;    // CW is the default. 
    317         m_Draw_Meshes[MeshNr].Vertices.PushBackEmpty(m_Meshes[MeshNr].Triangles.Size()*3); 
    318305    } 
    319306} 
     
    931918 
    932919 
    933 static Vector3fT myNormalize(const Vector3fT& A) 
    934 { 
    935     const float Length=length(A); 
    936  
    937     return (Length>0.000001f) ? A.GetScaled(1.0f/Length) : Vector3fT(); 
    938 } 
    939  
    940  
    941 void CafuModelT::UpdateCachedDrawData(int SequenceNr, float FrameNr, const SuperT* Super) const 
    942 { 
    943     // ************************************************************************************************************** 
    944     //  Obtain a joints (bone) hierarchy for the desired frame FrameNr of the desired animation sequence SequenceNr. 
    945     //  The result will be a transformation matrix for each joint (bone). 
    946     // ************************************************************************************************************** 
    947  
    948     if (SequenceNr==-1) 
    949     { 
    950         // Don't animate, just use the bind pose defined in the model file. 
    951         for (unsigned long JointNr=0; JointNr<m_Joints.Size(); JointNr++) 
    952         { 
    953             if (Super && Super->HasMatrix(JointNr)) 
    954             { 
    955                 m_JointMatrices[JointNr]=Super->GetMatrix(JointNr); 
    956                 continue; 
    957             } 
    958  
    959             const JointT& J=m_Joints[JointNr]; 
    960             const MatrixT RelMatrix(J.Pos, cf::math::QuaternionfT::FromXYZ(J.Qtr), J.Scale); 
    961  
    962             m_JointMatrices[JointNr]=(J.Parent==-1) ? RelMatrix : m_JointMatrices[J.Parent]*RelMatrix; 
    963         } 
    964     } 
    965     else 
    966     { 
    967         // SequenceNr is a valid index into m_Anims, so use that. 
    968         const AnimT& Anim=m_Anims[SequenceNr]; 
    969         const int    Frame_0=int(FrameNr);                                          // If FrameNr == 17.83, then Frame_0 == 17 
    970         const float  Frame_f=FrameNr-Frame_0;                                       //                           Frame_f ==  0.83 
    971         const int    Frame_1=(Frame_0+1>=int(Anim.Frames.Size())) ? 0 : Frame_0+1;  //                           Frame_1 == 18 
    972  
    973         for (unsigned long JointNr=0; JointNr<m_Joints.Size(); JointNr++) 
    974         { 
    975             if (Super && Super->HasMatrix(JointNr)) 
    976             { 
    977                 m_JointMatrices[JointNr]=Super->GetMatrix(JointNr); 
    978                 continue; 
    979             } 
    980  
    981             const AnimT::AnimJointT& AJ=Anim.AnimJoints[JointNr]; 
    982             Vector3fT                Data_0[3]={ AJ.DefaultPos, AJ.DefaultQtr, AJ.DefaultScale }; 
    983             Vector3fT                Data_1[3]={ AJ.DefaultPos, AJ.DefaultQtr, AJ.DefaultScale }; 
    984  
    985             // Determine the position, quaternion and scale for Frame_0 and Frame_1. 
    986             unsigned int FlagCount=0; 
    987  
    988             for (int i=0; i<9; i++) 
    989             { 
    990                 if ((AJ.Flags >> i) & 1) 
    991                 { 
    992                     Data_0[i/3][i % 3]=Anim.Frames[Frame_0].AnimData[AJ.FirstDataIdx+FlagCount]; 
    993                     Data_1[i/3][i % 3]=Anim.Frames[Frame_1].AnimData[AJ.FirstDataIdx+FlagCount]; 
    994  
    995                     FlagCount++; 
    996                 } 
    997             } 
    998  
    999             // Interpolate the position and quaternion according to the fraction Frame_f. 
    1000             const Vector3fT              Pos  =Data_0[0]*(1.0f-Frame_f) + Data_1[0]*Frame_f; 
    1001             const cf::math::QuaternionfT Quat =slerp(cf::math::QuaternionfT::FromXYZ(Data_0[1]), cf::math::QuaternionfT::FromXYZ(Data_1[1]), Frame_f); 
    1002             const Vector3fT              Scale=Data_0[2]*(1.0f-Frame_f) + Data_1[2]*Frame_f; 
    1003  
    1004             // Compute the matrix that is relative to the parent bone, and finally obtain the absolute matrix for that bone! 
    1005             const MatrixT RelMatrix(Pos, Quat, Scale); 
    1006             const JointT& J=m_Joints[JointNr]; 
    1007  
    1008             m_JointMatrices[JointNr]=(J.Parent==-1) ? RelMatrix : m_JointMatrices[J.Parent]*RelMatrix; 
    1009         } 
    1010     } 
    1011  
    1012  
    1013     // ******************************************************************************************************************* 
    1014     //  The JointMatrices represent now the pose of the model at the desired frame number of the desired sequence number. 
    1015     //  For all meshes do now compute the vertices according to their weights. 
    1016     // ******************************************************************************************************************* 
    1017  
    1018     for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1019     { 
    1020         MeshT& Mesh=m_Meshes[MeshNr]; 
    1021  
    1022         for (unsigned long VertexNr=0; VertexNr<Mesh.Vertices.Size(); VertexNr++) 
    1023         { 
    1024             MeshT::VertexT& Vertex=Mesh.Vertices[VertexNr]; 
    1025  
    1026             if (Vertex.GeoDups.Size()>0 && Vertex.GeoDups[0]<VertexNr) 
    1027             { 
    1028                 // This vertex has a geometrically identical duplicate that has already been computed. 
    1029                 // Therefore, don't bother to recompute the same position again, just copy it from the duplicate. 
    1030                 Vertex.Draw_Pos=Mesh.Vertices[Vertex.GeoDups[0]].Draw_Pos; 
    1031                 continue; 
    1032             } 
    1033  
    1034             if (Vertex.NumWeights==1) 
    1035             { 
    1036                 const MeshT::WeightT& Weight=Mesh.Weights[Vertex.FirstWeightIdx]; 
    1037  
    1038                 Vertex.Draw_Pos=m_JointMatrices[Weight.JointIdx].Mul_xyz1(Weight.Pos); 
    1039             } 
    1040             else 
    1041             { 
    1042                 Vertex.Draw_Pos=Vector3fT(0.0f, 0.0f, 0.0f); 
    1043  
    1044                 for (unsigned int WeightNr=0; WeightNr<Vertex.NumWeights; WeightNr++) 
    1045                 { 
    1046                     const MeshT::WeightT& Weight=Mesh.Weights[Vertex.FirstWeightIdx+WeightNr]; 
    1047  
    1048                     Vertex.Draw_Pos+=m_JointMatrices[Weight.JointIdx].Mul_xyz1(Weight.Pos) * Weight.Weight; 
    1049                 } 
    1050             } 
    1051         } 
    1052     } 
    1053  
    1054  
    1055     // ******************************************************************************************* 
    1056     //  Compute the tangent-space basis vectors for all triangles and all vertices. 
    1057     //  This is done by first computing the per-triangle axes and then having them enter 
    1058     //  the relevant per-vertex averages as required (taking mirror corrections into account). 
    1059     //  The per-triangle normal vectors are also kept for stencil shadow silhoutte determination. 
    1060     // ******************************************************************************************* 
    1061  
    1062     if (m_UseGivenTangentSpace) 
    1063     { 
    1064         assert(m_Anims.Size()==0);  // It doesn't make sense to have statically given tangent-space axes with *animated* geometry... 
    1065         goto DoneComputingTS; 
    1066     } 
    1067  
    1068     // For all vertices, zero the tangent-space vectors for the subsequent average accumulation. 
    1069     for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1070     { 
    1071         MeshT& Mesh=m_Meshes[MeshNr]; 
    1072  
    1073         for (unsigned long VertexNr=0; VertexNr<Mesh.Vertices.Size(); VertexNr++) 
    1074         { 
    1075             MeshT::VertexT& Vertex=Mesh.Vertices[VertexNr]; 
    1076  
    1077             Vertex.Draw_Normal  =Vector3fT(0, 0, 0); 
    1078             Vertex.Draw_Tangent =Vector3fT(0, 0, 0); 
    1079             Vertex.Draw_BiNormal=Vector3fT(0, 0, 0); 
    1080         } 
    1081     } 
    1082  
    1083     // Compute the per-triangle tangent-space axes and distribute them over the relevant vertices appropriately. 
    1084     for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1085     { 
    1086         MeshT& Mesh=m_Meshes[MeshNr]; 
    1087  
    1088         for (unsigned long TriangleNr=0; TriangleNr<Mesh.Triangles.Size(); TriangleNr++) 
    1089         { 
    1090             MeshT::TriangleT&     Tri   =Mesh.Triangles[TriangleNr]; 
    1091             const MeshT::VertexT& V_0   =Mesh.Vertices[Tri.VertexIdx[0]]; 
    1092             const MeshT::VertexT& V_1   =Mesh.Vertices[Tri.VertexIdx[1]]; 
    1093             const MeshT::VertexT& V_2   =Mesh.Vertices[Tri.VertexIdx[2]]; 
    1094             const Vector3fT       Edge01=V_1.Draw_Pos-V_0.Draw_Pos; 
    1095             const Vector3fT       Edge02=V_2.Draw_Pos-V_0.Draw_Pos; 
    1096  
    1097             // Triangles are ordered CW for md5 models and CCW for ase models, so we write 
    1098             // Normal=VectorCross(Edge02, Edge01) for md5 models and Normal=VectorCross(Edge01, Edge02) for ase models. 
    1099             Tri.Draw_Normal=myNormalize(Edge02.cross(Edge01)); 
    1100  
    1101             // Understanding what's going on here is easy. The key statement is 
    1102             // "The tangent vector is parallel to the direction of increasing S on a parametric surface." 
    1103             // First, there is a short explanation in "The Cg Tutorial", chapter 8. 
    1104             // Second, I have drawn a simple figure that leads to a simple 2x2 system of Gaussian equations, see my TechArchive. 
    1105             const Vector3fT uv01=Vector3fT(V_1.u, V_1.v, 0.0f)-Vector3fT(V_0.u, V_0.v, 0.0f); 
    1106             const Vector3fT uv02=Vector3fT(V_2.u, V_2.v, 0.0f)-Vector3fT(V_0.u, V_0.v, 0.0f); 
    1107             const float     f   =uv01.x*uv02.y-uv01.y*uv02.x>0.0 ? 1.0f : -1.0f; 
    1108  
    1109             const Vector3fT Tri_Draw_Tangent =myNormalize(Edge02.GetScaled(-uv01.y*f) + Edge01.GetScaled(uv02.y*f)); 
    1110             const Vector3fT Tri_Draw_BiNormal=myNormalize(Edge02.GetScaled( uv01.x*f) - Edge01.GetScaled(uv02.x*f)); 
    1111  
    1112  
    1113             // Distribute the per-triangle tangent-space over the affected vertices. 
    1114 #if 1 
    1115             const float Pi=3.14159265358979323846f; 
    1116  
    1117             const float c0=dot(myNormalize(Edge01), myNormalize(Edge02)); 
    1118             const float c1=dot(myNormalize(Edge01), myNormalize(V_1.Draw_Pos-V_2.Draw_Pos)); 
    1119  
    1120             const float w0=(c0>=1.0f) ? 0.0f : ( (c0<=-1.0f) ? Pi : acos(c0) ); 
    1121             const float w1=(c1>=1.0f) ? 0.0f : ( (c1<=-1.0f) ? Pi : acos(c1) ); 
    1122  
    1123             const float TriWeight[3]={ w0, w1, Pi-TriWeight[0]-TriWeight[1] }; 
    1124 #else 
    1125             const float TriWeight[3]={ 1.0f, 1.0f, 1.0f }; 
    1126 #endif 
    1127  
    1128             for (int i=0; i<3; i++) 
    1129             { 
    1130                 MeshT::VertexT& Vertex=Mesh.Vertices[Tri.VertexIdx[i]]; 
    1131  
    1132                 assert(Tri.Polarity==Vertex.Polarity); 
    1133  
    1134                 Vertex.Draw_Normal  +=Tri.Draw_Normal*TriWeight[i]; 
    1135                 Vertex.Draw_Tangent +=Tri_Draw_Tangent*TriWeight[i]; 
    1136                 Vertex.Draw_BiNormal+=Tri_Draw_BiNormal*TriWeight[i]; 
    1137  
    1138                 for (unsigned long DupNr=0; DupNr<Vertex.GeoDups.Size(); DupNr++) 
    1139                 { 
    1140                     MeshT::VertexT& DupVertex=Mesh.Vertices[Vertex.GeoDups[DupNr]]; 
    1141  
    1142                     DupVertex.Draw_Normal  +=Tri.Draw_Normal*TriWeight[i]; 
    1143                     DupVertex.Draw_Tangent +=Tri_Draw_Tangent*(Tri.Polarity==DupVertex.Polarity ? TriWeight[i] : -TriWeight[i]); 
    1144                     DupVertex.Draw_BiNormal+=Tri_Draw_BiNormal*TriWeight[i]; 
    1145                 } 
    1146             } 
    1147         } 
    1148     } 
    1149  
    1150     // Finally normalize the per-vertex tangent-space axes; this is quasi the "division" in the average computations. 
    1151     for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1152     { 
    1153         MeshT& Mesh=m_Meshes[MeshNr]; 
    1154  
    1155         for (unsigned long VertexNr=0; VertexNr<Mesh.Vertices.Size(); VertexNr++) 
    1156         { 
    1157             MeshT::VertexT& Vertex=Mesh.Vertices[VertexNr]; 
    1158  
    1159             // Normalize the tangent-space axes. 
    1160             Vertex.Draw_Normal  =myNormalize(Vertex.Draw_Normal  ); 
    1161             Vertex.Draw_Tangent =myNormalize(Vertex.Draw_Tangent ); 
    1162             Vertex.Draw_BiNormal=myNormalize(Vertex.Draw_BiNormal); 
    1163         } 
    1164     } 
    1165  
    1166     DoneComputingTS: 
    1167  
    1168  
    1169     // *************************************************************************************************************** 
    1170     //  Construct explicit MatSys::MeshT meshes now. 
    1171     //  Note that this is very inefficient - we REALLY should work with index arrays! (and/or vertex buffer objects!) 
    1172     // *************************************************************************************************************** 
    1173  
    1174     for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1175     { 
    1176         const MeshT& Mesh=m_Meshes[MeshNr]; 
    1177  
    1178         for (unsigned long TriNr=0; TriNr<Mesh.Triangles.Size(); TriNr++) 
    1179         { 
    1180             for (unsigned long i=0; i<3; i++) 
    1181             { 
    1182                 unsigned long VertexIdx=Mesh.Triangles[TriNr].VertexIdx[i]; 
    1183  
    1184                 m_Draw_Meshes[MeshNr].Vertices[TriNr*3+i].SetOrigin(Mesh.Vertices[VertexIdx].Draw_Pos.x, Mesh.Vertices[VertexIdx].Draw_Pos.y, Mesh.Vertices[VertexIdx].Draw_Pos.z); 
    1185                 m_Draw_Meshes[MeshNr].Vertices[TriNr*3+i].SetTextureCoord(Mesh.Vertices[VertexIdx].u, Mesh.Vertices[VertexIdx].v); 
    1186                 m_Draw_Meshes[MeshNr].Vertices[TriNr*3+i].SetNormal  (Mesh.Vertices[VertexIdx].Draw_Normal.x,   Mesh.Vertices[VertexIdx].Draw_Normal.y,   Mesh.Vertices[VertexIdx].Draw_Normal.z  ); 
    1187                 m_Draw_Meshes[MeshNr].Vertices[TriNr*3+i].SetTangent (Mesh.Vertices[VertexIdx].Draw_Tangent.x,  Mesh.Vertices[VertexIdx].Draw_Tangent.y,  Mesh.Vertices[VertexIdx].Draw_Tangent.z ); 
    1188                 m_Draw_Meshes[MeshNr].Vertices[TriNr*3+i].SetBiNormal(Mesh.Vertices[VertexIdx].Draw_BiNormal.x, Mesh.Vertices[VertexIdx].Draw_BiNormal.y, Mesh.Vertices[VertexIdx].Draw_BiNormal.z); 
    1189             } 
    1190         } 
    1191     } 
    1192 } 
    1193  
    1194  
    1195 const ArrayT<MatrixT>& CafuModelT::GetDrawJointMatrices(int SequenceNr, float FrameNr, const SuperT* Super) const 
    1196 { 
    1197     // SequenceNr==-1 means "use the bind pose from the model file only (no anim)". 
    1198     if (SequenceNr>=int(m_Anims.Size())) SequenceNr=-1; 
    1199     if (SequenceNr!=-1 && (m_Anims[SequenceNr].FPS<0.0 || m_Anims[SequenceNr].Frames.Size()==0)) SequenceNr=-1; 
    1200     if (SequenceNr==-1) FrameNr=0.0; 
    1201  
    1202     // See Draw() for details. 
    1203     if (m_Draw_CachedDataAtSequNr!=SequenceNr || m_Draw_CachedDataAtFrameNr!=FrameNr || Super!=NULL) 
    1204     { 
    1205         m_Draw_CachedDataAtSequNr =SequenceNr; 
    1206         m_Draw_CachedDataAtFrameNr=FrameNr; 
    1207  
    1208         UpdateCachedDrawData(SequenceNr, FrameNr, Super); 
    1209     } 
    1210  
    1211     return m_JointMatrices; 
    1212 } 
    1213  
    1214  
    1215920const MaterialT* CafuModelT::GetMaterial(unsigned long MeshNr, int SkinNr) const 
    1216921{ 
     
    1247952 
    1248953 
    1249 void CafuModelT::Draw(int SequenceNr, float FrameNr, int SkinNr, float /*LodDist*/, const SuperT* Super) const 
    1250 { 
    1251     // SequenceNr==-1 means "use the bind pose from the model file only (no anim)". 
    1252     if (SequenceNr>=int(m_Anims.Size())) SequenceNr=-1; 
    1253     if (SequenceNr!=-1 && (m_Anims[SequenceNr].FPS<0.0 || m_Anims[SequenceNr].Frames.Size()==0)) SequenceNr=-1; 
    1254     if (SequenceNr==-1) FrameNr=0.0; 
    1255  
    1256  
    1257     // Do an early check whether the light and the sequence BBs intersect. 
    1258     switch (MatSys::Renderer->GetCurrentRenderAction()) 
    1259     { 
    1260         case MatSys::RendererI::AMBIENT: 
    1261             break; 
    1262  
    1263         case MatSys::RendererI::LIGHTING: 
    1264         case MatSys::RendererI::STENCILSHADOW: 
    1265         { 
    1266             const float                LightRadius=MatSys::Renderer->GetCurrentLightSourceRadius(); 
    1267             const Vector3T<float>      LightBox(LightRadius, LightRadius, LightRadius); 
    1268             const Vector3T<float>      LightPosOLD(MatSys::Renderer->GetCurrentLightSourcePosition()); 
    1269             const BoundingBox3T<float> LightBB(LightPosOLD+LightBox, LightPosOLD-LightBox); 
    1270  
    1271             if (!LightBB.Intersects(GetBB(SequenceNr, FrameNr))) return; 
    1272             break; 
    1273         } 
    1274     } 
    1275  
    1276  
    1277     // The caching mechanism is really simple and works as follows: 
    1278     // All data that does not depend on a frame or sequence number is precomputed and prepared once in the constructor. 
    1279     // All data that is specific to a certain frame and sequence number is computed in UpdateCachedDrawData() 
    1280     // and stored in member variables (those whose name begins with m_Draw_ or Draw_). 
    1281     // If we are called again with the same frame and sequence numbers for which we have cached data in the last call, 
    1282     // the data is simply re-used for drawing, skipping the expensive recomputations entirely. 
    1283     // If the numbers are different, the cache data is recomputed and the reference frame and sequence numbers are updated. 
    1284     // 
    1285     // 1. To understand why this works well, consider first a scene with only a single animated model: 
    1286     // First, we assume that the model will be drawn in the ambient pass plus for each light source in the stencil shadow and lighting pass. 
    1287     // That is, assuming there are L light sources, this method is called 1+2*L times per frame with the same frame and sequence numbers. 
    1288     // It's obvious that the first call for the ambient pass will come with different sequence or frame numbers than the 
    1289     // previous call, as our model is animated. In this call the cache is recomputed, and it is obvious that for the 2*L subsequent 
    1290     // calls for the stencil and lighting passes the frame and sequence numbers will be identical so that we can rely on the cached data. 
    1291     // Thus, the computational effort with the cache is only 1/(1+2*L) of the amount without the cache. 
    1292     // 
    1293     // Note that we can ***NOT*** reasonably do any better by a more complex cache management (as is done in the ModelMdlT class). 
    1294     // For example one might think that we might win something if we delay the computations of the tangent space in the ambient 
    1295     // pass until a lighting pass occurs that actually needs the tangent space. 
    1296     // First of all, this makes the cache management terribly complicated, see the ModelMdlT class for a scaring example. 
    1297     // Even better, we may reasonably assume that we will need *all* cache data in each frame eventually (letztendlich) anyway, 
    1298     // so that it is reasonable to compute it fully whenever the frame or sequence number changes. 
    1299     // The only case where the assumption does not hold (and we could have saved computing something) is when no lightsource at all 
    1300     // lights our model, and when also the ambient pass does not need the information (e.g. normal vectors for environment reflection mapping). 
    1301     // As this is hopefully a rare case, we're doing pretty good. 
    1302     // Border cases like outdoor terrains where animated player models are drawn only in the ambient pass should be addressed by dlod models. 
    1303     // 
    1304     // 2. Now consider a scene with multiple animated models that are all rendered by this single instance. 
    1305     // Unfortunately, in this case our caching mechanism fails entirely: everything is recomputed on every call. 
    1306     // In this case, several instances of the model should be created (if speed is important and space is dispensable). 
    1307     // The fact that the Cafu Material System automatically shares rendering resources makes having multiple instances viable. 
    1308     // 
    1309     // 3. Finally, consider a scene with arbitrarily many non-animated models. 
    1310     // As in this case the frame and sequence numbers are always identical for each call, the caching mechanism has maximum efficiency. 
    1311     // All computations occur only once and then never again. This is the optimum cache utilization case. 
    1312     if (m_Draw_CachedDataAtSequNr!=SequenceNr || m_Draw_CachedDataAtFrameNr!=FrameNr || Super!=NULL) 
    1313     { 
    1314         m_Draw_CachedDataAtSequNr =SequenceNr; 
    1315         m_Draw_CachedDataAtFrameNr=FrameNr; 
    1316  
    1317         UpdateCachedDrawData(SequenceNr, FrameNr, Super); 
    1318     } 
    1319  
    1320  
    1321     switch (MatSys::Renderer->GetCurrentRenderAction()) 
    1322     { 
    1323         case MatSys::RendererI::AMBIENT: 
    1324         { 
    1325             for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1326             { 
    1327                 MatSys::Renderer->SetCurrentMaterial(GetRenderMaterial(MeshNr, SkinNr)); 
    1328                 MatSys::Renderer->RenderMesh(m_Draw_Meshes[MeshNr]); 
    1329  
    1330 #if 0 
    1331                 // Render the tangent space axes for each vertex. 
    1332                 static MaterialT SolidColorMaterial; 
    1333                 SolidColorMaterial.UseMeshColors=true; 
    1334  
    1335                 static MatSys::MeshT TangentSpaceAxes(MatSys::MeshT::Lines); 
    1336                 TangentSpaceAxes.Vertices.Overwrite(); 
    1337  
    1338                 for (unsigned long VertexNr=0; VertexNr<m_Draw_Meshes[MeshNr].Vertices.Size(); VertexNr++) 
    1339                 { 
    1340                     const float         scale=1.0f; 
    1341                     const Vector3fT     Orig =Vector3fT(m_Draw_Meshes[MeshNr].Vertices[VertexNr].Origin); 
    1342                     const Vector3fT     S_   =Vector3fT(m_Draw_Meshes[MeshNr].Vertices[VertexNr].Tangent); 
    1343                     const Vector3fT     T_   =Vector3fT(m_Draw_Meshes[MeshNr].Vertices[VertexNr].BiNormal); 
    1344                     const Vector3fT     N_   =Vector3fT(m_Draw_Meshes[MeshNr].Vertices[VertexNr].Normal); 
    1345                     const float         col_ =m_Meshes[MeshNr].Triangles[VertexNr / 3].Polarity ? 0.5f : 0.0f; 
    1346                     const unsigned long Ofs  =TangentSpaceAxes.Vertices.Size(); 
    1347  
    1348                     TangentSpaceAxes.Vertices.PushBackEmpty(6); 
    1349  
    1350                     TangentSpaceAxes.Vertices[Ofs+0].SetOrigin(Orig); 
    1351                     TangentSpaceAxes.Vertices[Ofs+0].SetColor(1, col_, col_); 
    1352                     TangentSpaceAxes.Vertices[Ofs+1].SetOrigin(Orig+S_*scale); 
    1353                     TangentSpaceAxes.Vertices[Ofs+1].SetColor(1, col_, col_); 
    1354  
    1355                     TangentSpaceAxes.Vertices[Ofs+2].SetOrigin(Orig); 
    1356                     TangentSpaceAxes.Vertices[Ofs+2].SetColor(col_, 1, col_); 
    1357                     TangentSpaceAxes.Vertices[Ofs+3].SetOrigin(Orig+T_*scale); 
    1358                     TangentSpaceAxes.Vertices[Ofs+3].SetColor(col_, 1, col_); 
    1359  
    1360                     TangentSpaceAxes.Vertices[Ofs+4].SetOrigin(Orig); 
    1361                     TangentSpaceAxes.Vertices[Ofs+4].SetColor(col_, col_, 1); 
    1362                     TangentSpaceAxes.Vertices[Ofs+5].SetOrigin(Orig+N_*scale); 
    1363                     TangentSpaceAxes.Vertices[Ofs+5].SetColor(col_, col_, 1); 
    1364                 } 
    1365  
    1366                 MatSys::RenderMaterialT* SolidColorRenderMat=MatSys::Renderer->RegisterMaterial(&SolidColorMaterial); 
    1367  
    1368                 MatSys::Renderer->SetCurrentMaterial(SolidColorRenderMat); 
    1369                 MatSys::Renderer->RenderMesh(TangentSpaceAxes); 
    1370  
    1371                 MatSys::Renderer->FreeMaterial(SolidColorRenderMat); 
    1372  
    1373                 // FIXME! Rendering the stencil shadows uses the same material as the ambient pass does! 
    1374                 // (The call to FreeMaterial() above implies that no material is being set, and thus without this line, 
    1375                 //  no stencil shadows get rendered!) 
    1376                 MatSys::Renderer->SetCurrentMaterial(m_Meshes[MeshNr].RenderMaterial); 
    1377 #endif 
    1378             } 
    1379             break; 
    1380         } 
    1381  
    1382         case MatSys::RendererI::LIGHTING: 
    1383         { 
    1384             for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1385             { 
    1386                 MatSys::Renderer->SetCurrentMaterial(GetRenderMaterial(MeshNr, SkinNr)); 
    1387                 MatSys::Renderer->RenderMesh(m_Draw_Meshes[MeshNr]); 
    1388             } 
    1389             break; 
    1390         } 
    1391  
    1392         case MatSys::RendererI::STENCILSHADOW: 
    1393         { 
    1394             const Vector3fT LightPos(MatSys::Renderer->GetCurrentLightSourcePosition()); 
    1395  
    1396             for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1397             { 
    1398                 const MeshT&     Mesh   =m_Meshes[MeshNr]; 
    1399                 const MaterialT* MeshMat=GetMaterial(MeshNr, SkinNr); 
    1400  
    1401                 if (MeshMat==NULL || MeshMat->NoShadows) continue; 
    1402  
    1403                 static ArrayT<bool> TriangleIsFrontFacing; 
    1404                 if (TriangleIsFrontFacing.Size()<Mesh.Triangles.Size()) 
    1405                     TriangleIsFrontFacing.PushBackEmpty(Mesh.Triangles.Size()-TriangleIsFrontFacing.Size()); 
    1406  
    1407                 for (unsigned long TriNr=0; TriNr<Mesh.Triangles.Size(); TriNr++) 
    1408                 { 
    1409                     const MeshT::TriangleT& Tri=Mesh.Triangles[TriNr]; 
    1410                     const float             Dot=(LightPos-Mesh.Vertices[Tri.VertexIdx[0]].Draw_Pos).dot(Tri.Draw_Normal); 
    1411  
    1412                     TriangleIsFrontFacing[TriNr]=Dot>0; 
    1413                 } 
    1414  
    1415  
    1416                 // Note that we have to cull the following polygons wrt. the *VIEWER* (not the light source)! 
    1417                 static MatSys::MeshT MeshSilhouette(MatSys::MeshT::Quads);  // The default winding order is "CW". 
    1418                 MeshSilhouette.Vertices.Overwrite(); 
    1419  
    1420                 for (unsigned long TriNr=0; TriNr<Mesh.Triangles.Size(); TriNr++) 
    1421                 { 
    1422                     if (!TriangleIsFrontFacing[TriNr]) continue; 
    1423  
    1424                     // This triangle is front-facing wrt. the light source. 
    1425                     const MeshT::TriangleT& Tri=Mesh.Triangles[TriNr]; 
    1426  
    1427                     for (unsigned long EdgeNr=0; EdgeNr<3; EdgeNr++) 
    1428                     { 
    1429                         // If an edge has no (-1) or more than one (-2) neighbours, make it a silhouette edge. 
    1430                         const bool IsSilhouetteEdge=(Tri.NeighbIdx[EdgeNr]<0) ? true : !TriangleIsFrontFacing[Tri.NeighbIdx[EdgeNr]]; 
    1431  
    1432                         if (IsSilhouetteEdge) 
    1433                         { 
    1434                             // The neighbour at edge 'EdgeNr' is back-facing (or non-existant), so we have found a possible silhouette edge. 
    1435                             const unsigned long v1=EdgeNr; 
    1436                             const unsigned long v2=(EdgeNr+1) % 3; 
    1437                             const Vector3fT     LA=Mesh.Vertices[Tri.VertexIdx[v1]].Draw_Pos-LightPos; 
    1438                             const Vector3fT     LB=Mesh.Vertices[Tri.VertexIdx[v2]].Draw_Pos-LightPos; 
    1439  
    1440                             MeshSilhouette.Vertices.PushBackEmpty(4); 
    1441  
    1442                             const unsigned long MeshSize=MeshSilhouette.Vertices.Size(); 
    1443  
    1444                             MeshSilhouette.Vertices[MeshSize-4].SetOrigin(Mesh.Vertices[Tri.VertexIdx[v2]].Draw_Pos); 
    1445                             MeshSilhouette.Vertices[MeshSize-3].SetOrigin(Mesh.Vertices[Tri.VertexIdx[v1]].Draw_Pos); 
    1446                             MeshSilhouette.Vertices[MeshSize-2].SetOrigin(LA, 0.0); 
    1447                             MeshSilhouette.Vertices[MeshSize-1].SetOrigin(LB, 0.0); 
    1448                         } 
    1449                     } 
    1450                 } 
    1451  
    1452                 MatSys::Renderer->RenderMesh(MeshSilhouette); 
    1453  
    1454  
    1455                 static MatSys::MeshT MeshCaps(MatSys::MeshT::Triangles);    // The default winding order is "CW". 
    1456                 MeshCaps.Vertices.Overwrite(); 
    1457  
    1458                 for (unsigned long TriNr=0; TriNr<Mesh.Triangles.Size(); TriNr++) 
    1459                 { 
    1460                     if (!TriangleIsFrontFacing[TriNr]) continue; 
    1461  
    1462                     // This triangle is front-facing wrt. the light source. 
    1463                     const MeshT::TriangleT& Tri=Mesh.Triangles[TriNr]; 
    1464  
    1465                     MeshCaps.Vertices.PushBackEmpty(6); 
    1466  
    1467                     const unsigned long MeshSize=MeshCaps.Vertices.Size(); 
    1468  
    1469                     // Render the occluder (front-facing wrt. the light source). 
    1470                     const Vector3fT& A=Mesh.Vertices[Tri.VertexIdx[0]].Draw_Pos; 
    1471                     const Vector3fT& B=Mesh.Vertices[Tri.VertexIdx[1]].Draw_Pos; 
    1472                     const Vector3fT& C=Mesh.Vertices[Tri.VertexIdx[2]].Draw_Pos; 
    1473  
    1474                     MeshCaps.Vertices[MeshSize-6].SetOrigin(A); 
    1475                     MeshCaps.Vertices[MeshSize-5].SetOrigin(B); 
    1476                     MeshCaps.Vertices[MeshSize-4].SetOrigin(C); 
    1477  
    1478                     // Render the occluder (back-facing wrt. the light source). 
    1479                     const Vector3fT LA=A-LightPos; 
    1480                     const Vector3fT LB=B-LightPos; 
    1481                     const Vector3fT LC=C-LightPos; 
    1482  
    1483                     MeshCaps.Vertices[MeshSize-3].SetOrigin(LC, 0.0); 
    1484                     MeshCaps.Vertices[MeshSize-2].SetOrigin(LB, 0.0); 
    1485                     MeshCaps.Vertices[MeshSize-1].SetOrigin(LA, 0.0); 
    1486                 } 
    1487  
    1488                 MatSys::Renderer->RenderMesh(MeshCaps); 
    1489             } 
    1490  
    1491             break; 
    1492         } 
    1493     } 
    1494 } 
    1495  
    1496  
    1497954void CafuModelT::Draw(int SequenceNr, float FrameNr, float LodDist, const ModelT* /*SubModel*/) const 
    1498955{ 
    1499     Draw(SequenceNr, FrameNr, -1 /*default skin*/, LodDist, (SuperT*)NULL); 
     956    AnimPoseT Pose(*this, SequenceNr, FrameNr);     // TODO: This is reconstructed on each call -- no caching at all! 
     957 
     958    Pose.Draw(-1 /*default skin*/, LodDist); 
    1500959} 
    1501960 
     
    15741033bool CafuModelT::TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
    15751034{ 
    1576     float Fraction=0.0f; 
    1577  
    1578     // If we miss the bounding-box, then we miss all the triangles as well. 
    1579     if (!GetBB(SequenceNr, FrameNr).TraceRay(RayOrigin, RayDir, Fraction)) return false; 
    1580  
    1581     // Call this method to update the draw structures according to SequenceNr and FrameNr. 
    1582     GetDrawJointMatrices(SequenceNr, FrameNr); 
    1583  
    1584     for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    1585     { 
    1586         const MeshT&     Mesh   =m_Meshes[MeshNr]; 
    1587         const MaterialT* MeshMat=GetMaterial(MeshNr, SkinNr); 
    1588  
    1589         // If the ClipFlags don't match the ClipMask, this polygon doesn't interfere with the trace. 
    1590         if (!MeshMat) continue; 
    1591         // if ((MeshMat->ClipFlags & ClipMask)==0) continue; 
    1592  
    1593         for (unsigned long TriNr=0; TriNr<Mesh.Triangles.Size(); TriNr++) 
    1594         { 
    1595             // This code is a modification of the code in CollisionModelStaticT::PolygonT::TraceRay(), 
    1596             // see there for details and additional information. 
    1597             using namespace cf::math; 
    1598             const MeshT::TriangleT& Tri=Mesh.Triangles[TriNr]; 
    1599  
    1600             const Vector3fT& A=Mesh.Vertices[Tri.VertexIdx[0]].Draw_Pos; 
    1601             const Vector3fT& B=Mesh.Vertices[Tri.VertexIdx[1]].Draw_Pos; 
    1602             const Vector3fT& C=Mesh.Vertices[Tri.VertexIdx[2]].Draw_Pos; 
    1603  
    1604             const PlueckerfT R=PlueckerfT::CreateFromRay(RayOrigin, RayDir); 
    1605  
    1606             // We use Pluecker coordinates for the orientation tests. 
    1607             // Note that Christer Ericson has shown in his blog at http://realtimecollisiondetection.net/blog/?p=13 
    1608             // that scalar triple products (Spatprodukte) are equivalent and could be used as well.  ;-) 
    1609             if (!MeshMat->TwoSided) 
    1610             { 
    1611                 if (R*PlueckerfT::CreateFromLine(A, B) >= 0) continue; 
    1612                 if (R*PlueckerfT::CreateFromLine(B, C) >= 0) continue; 
    1613                 if (R*PlueckerfT::CreateFromLine(C, A) >= 0) continue; 
    1614             } 
    1615             else 
    1616             { 
    1617                 int Count=0; 
    1618  
    1619                 // Should not change Count if result == 0... 
    1620                 Count+=(R*PlueckerfT::CreateFromLine(A, B) >= 0) ? -1 : 1; 
    1621                 Count+=(R*PlueckerfT::CreateFromLine(B, C) >= 0) ? -1 : 1; 
    1622                 Count+=(R*PlueckerfT::CreateFromLine(C, A) >= 0) ? -1 : 1; 
    1623  
    1624                 if (Count!=-3 && Count!=3) continue; 
    1625             } 
    1626  
    1627             // The "aperture" test passed, now compute the fraction at which RayDir intersects the triangle plane. 
    1628             const float Nenner=dot(Tri.Draw_Normal, RayDir); 
    1629  
    1630             if (Nenner==0) continue;                            // If Nenner==0, then RayDir is parallel to the triangle plane (no intersection). 
    1631             assert(MeshMat->TwoSided || Nenner<0);              // If the material is single sided, then Nenner<0, a consequence of the Pluecker tests above. 
    1632  
    1633             const float Dist=dot(Tri.Draw_Normal, RayOrigin-A); // The distance of RayOrigin to the triangle plane. 
    1634             const float F   =-(Dist-0.03125f)/Nenner; 
    1635  
    1636             // The intersection is only valid in the positive direction of RayDir. 
    1637             if (F<0) continue; 
    1638  
    1639             // Hit the triangle! 
    1640             Result.Fraction=F; 
    1641             Result.Normal  =(Nenner<0) ? Tri.Draw_Normal : -Tri.Draw_Normal;    // Handle two-sided materials properly. 
    1642             Result.Material=MeshMat; 
    1643             Result.MeshNr  =MeshNr; 
    1644             Result.TriNr   =TriNr; 
    1645             return true; 
    1646         } 
    1647     } 
    1648  
    1649     return false; 
     1035    AnimPoseT Pose(*this, SequenceNr, FrameNr);     // TODO: This is reconstructed on each call -- no caching at all! 
     1036 
     1037    return Pose.TraceRay(SkinNr, RayOrigin, RayDir, Result); 
    16501038} 
    16511039 
  • cafu/trunk/Libs/Models/Model_cmdl.hpp

    r398 r400  
    8383            bool         Polarity;      ///< True if this triangle has positive polarity (texture is not mirrored), or false if it has negative polarity (texture is mirrored, SxT points inward). 
    8484 
    85             Vector3fT    Draw_Normal;   ///< The draw normal for this triangle, required for the shadow-silhouette determination. 
     85            Vector3fT    gts_Normal;    ///< The draw normal for this triangle, required for the shadow-silhouette determination. 
    8686        }; 
    8787 
     
    9797            ArrayT<unsigned int> GeoDups;       ///< This array contains the indices of vertices that are geometrical duplicates of this vertex, see AreVerticesGeoDups() for more information. The indices are stored in increasing order, and do *not* include the index of "this" vertex. Note that from the presence of GeoDups in a cmdl/md5 file we can *not* conclude that a break in the smoothing was intended by the modeller. Cylindrically wrapping seams are one counter-example. 
    9898 
    99             Vector3fT            Draw_Pos;      ///< Position of this vertex. 
    100             Vector3fT            Draw_Normal;   ///< Vertex normal. 
    101             Vector3fT            Draw_Tangent;  ///< Vertex tangent. 
    102             Vector3fT            Draw_BiNormal; ///< Vertex binormal. 
     99            Vector3fT            gts_Pos;       ///< Position of this vertex. 
     100            Vector3fT            gts_Normal;    ///< Vertex normal. 
     101            Vector3fT            gts_Tangent;   ///< Vertex tangent. 
     102            Vector3fT            gts_BiNormal; ///< Vertex binormal. 
    103103        }; 
    104104 
     
    239239 
    240240 
    241     /// This struct describes information about a parent or "super" model whose skeleton pose should be used when rendering this model. 
    242     /// For example, a player model can act as the super model for a weapon, so that the skeleton of the weapon is copied from the 
    243     /// player model in order to align the weapon with the hands of the player. 
    244     struct SuperT 
    245     { 
    246         /// The constructor. 
    247         /// @param Matrices_   The draw matrices of the super model. 
    248         /// @param Map_        Describes how our joints map to the joints of the super model. 
    249         ///                    If <tt>Map_[i]</tt> is not a valid index into \c Matrices_, then our joint \c i has no match in the skeleton of the super model. 
    250         SuperT(const ArrayT<MatrixT>& Matrices_, const ArrayT<unsigned int>& Map_) : Matrices(Matrices_), Map(Map_) { } 
    251  
    252         /// Has our joint \c JointNr a correspondence in the super model? 
    253         bool HasMatrix(unsigned long JointNr) const { return Map[JointNr] < Matrices.Size(); } 
    254  
    255         /// For our joint \c JointNr, return the corresponding matrix from the super model. 
    256         /// Only call this if HasMatrix(JointNr) returns \c true. 
    257         const MatrixT& GetMatrix(unsigned long JointNr) const { return Matrices[Map[JointNr]]; } 
    258  
    259         const ArrayT<MatrixT>&      Matrices;   ///< The draw matrices of the super model. 
    260         const ArrayT<unsigned int>& Map;        ///< Describes how our joints map to the joints of the super model. If <tt>Map[i]</tt> is not a valid index into \c Matrices, then our joint \c i has no match in the skeleton of the super model. 
    261     }; 
    262  
    263  
    264241    /// The constructor. Creates a new Cafu model from a file as directed by the given model loader. 
    265242    /// @param Loader   The model loader that actually imports the file and fills in the model data. 
     
    282259    const ArrayT<ChannelT>&     GetChannels() const { return m_Channels; } 
    283260 
    284     /// This method returns the set of drawing matrices (one per joint) at the given sequence and frame number. 
    285     const ArrayT<MatrixT>& GetDrawJointMatrices(int SequenceNr, float FrameNr, const SuperT* Super=NULL) const; 
    286  
    287     /// The new method to draw the model. 
    288     /// @param SequenceNr   The number of the animation sequence to use, -1 for the bind pose. 
    289     /// @param FrameNr      The frame number in the animation sequence to render to model at. 
    290     /// @param SkinNr       The skin to render the model with, -1 for the default skin. 
    291     /// @param LodDist      The distance to the camera for reducing the level-of-detail (currently unused). 
    292     /// @param Super        Information about a parent or "super" model whose skeleton pose should be used when rendering this model. 
    293     void Draw(int SequenceNr, float FrameNr, int SkinNr, float LodDist, const SuperT* Super=NULL) const; 
    294  
    295261    /// Returns the proper material for the given mesh in the given skin. 
    296262    const MaterialT* GetMaterial(unsigned long MeshNr, int SkinNr) const; 
     263 
     264    /// Returns the proper render material for the given mesh in the given skin. 
     265    MatSys::RenderMaterialT* GetRenderMaterial(unsigned long MeshNr, int SkinNr) const; 
    297266 
    298267    /// Determines if <tt>GF.Points[PointNr].MeshNr</tt> is a valid index into this model. 
     
    329298    friend class ModelEditor::CommandUpdateGuiFixtureT; 
    330299 
    331     void RecomputeBindPoseBB();                                                             ///< Recomputes the bounding box for the model in bind pose (stored in m_BindPoseBB). 
    332     void InitMeshes();                                                                      ///< An auxiliary method for the constructors. 
    333     void UpdateCachedDrawData(int SequenceNr, float FrameNr, const SuperT* Super) const;    ///< A private auxiliary method. 
    334     MatSys::RenderMaterialT* GetRenderMaterial(unsigned long MeshNr, int SkinNr) const;     ///< Returns the proper render material for the given mesh in the given skin. 
    335  
     300    void RecomputeBindPoseBB();                     ///< Recomputes the bounding box for the model in bind pose (stored in m_BindPoseBB). 
     301    void InitMeshes();                              ///< An auxiliary method for the constructors. 
    336302 
    337303    const std::string     m_FileName;               ///< File name of this model.   TODO: Remove!?! 
    338304    MaterialManagerImplT  m_MaterialMan;            ///< The material manager for the materials that are used with the meshes of this model. 
    339305    ArrayT<JointT>        m_Joints;                 ///< Array of joints of this model. 
    340     mutable ArrayT<MeshT> m_Meshes;                 ///< Array of (sub)meshes of this model. 
     306    ArrayT<MeshT>        m_Meshes;                 ///< Array of (sub)meshes of this model. 
    341307    ArrayT<SkinT>         m_Skins;                  ///< Array of additional/alternative skins for this model. 
    342308    ArrayT<GuiFixtureT>   m_GuiFixtures;            ///< Array of GUI fixtures in the model. 
     
    347313    const bool            m_UseGivenTangentSpace;   ///< Whether this model should use the fixed, given tangent space that was loaded from the model file, or it the tangent space is dynamically recomputed (useful for animated models). 
    348314 // const bool            m_CastShadows;            ///< Should this model cast shadows? 
    349     BoundingBox3fT        m_BindPoseBB;             ///< The bounding-box for the base pose of the model. 
    350  
    351  
    352     // Members for caching the data that is required for drawing the model at a given animation sequence and frame. 
    353     mutable int                   m_Draw_CachedDataAtSequNr;    ///< The animation sequence number at which we have computed the cache data. 
    354     mutable float                 m_Draw_CachedDataAtFrameNr;   ///< The animation frame    number at which we have computed the cache data. 
    355  
    356     mutable ArrayT<MatrixT>       m_JointMatrices;              ///< The transformation matrices that represent the pose of the skeleton at the given animation sequence and frame number. 
    357     mutable ArrayT<MatSys::MeshT> m_Draw_Meshes;                ///< The draw meshes resulting from m_JointMatrices. 
     315    BoundingBox3fT        m_BindPoseBB;             ///< [REMOVE???] The bounding-box for the base pose of the model. 
    358316}; 
    359317 
  • cafu/trunk/Libs/SConscript

    r367 r400  
    1414                    MapFile.cpp 
    1515                    Models/Loader.cpp Models/Loader_ase.cpp Models/Loader_cmdl.cpp Models/Loader_lwo.cpp Models/Loader_md5.cpp 
    16                     Models/Loader_mdl.cpp 
     16                    Models/Loader_mdl.cpp Models/AnimPose.cpp 
    1717                    Models/Model_cmdl.cpp Models/Model_dlod.cpp Models/Model_dummy.cpp Models/Model_mdl.cpp Models/Model_proxy.cpp 
    1818                    Network/Network.cpp ParticleEngine/ParticleEngineMS.cpp PlatformAux.cpp Terrain/Terrain.cpp