Changeset 459

Show
Ignore:
Timestamp:
01/11/12 11:36:20 (4 months ago)
Author:
Carsten
Message:

Model code:
AnimPoseT now compares AnimExpressionT instances by value in order to determine if it must refresh its mesh caches.

That is, if Pose is an AnimPoseT instance and Model is the related model instance, then in the call sequence

    Pose.SetAnimExpr(new AnimExprStandardT(Model, -1, 0.0f));
    Pose.Draw(0, 0.0f);

    Pose.SetAnimExpr(new AnimExprStandardT(Model, -1, 0.0f));
    Pose.Draw(0, 0.0f);

the second call to SetAnimExpr() will now no longer trigger cache refreshes in Pose (even though the second anim expression is an entirely different instance than the first).

This feature is very important for the worldly use of AnimPoseTs and AnimExpressionTs, where poses may be shared across different users and the above call sequence occurs frequently.

Location:
cafu/trunk/Libs/Models
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • cafu/trunk/Libs/Models/AnimExpr.cpp

    r455 r459  
    153153 
    154154 
     155IntrusivePtrT<AnimExpressionT> AnimExprStandardT::Clone() const 
     156{ 
     157    return GetModel().GetAnimExprPool().GetStandard(m_SequNr, m_FrameNr); 
     158} 
     159 
     160 
     161bool AnimExprStandardT::IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const 
     162{ 
     163    AnimExprStandardT* Other=dynamic_cast<AnimExprStandardT*>(AE.get()); 
     164 
     165    if (!Other) return false; 
     166    return m_SequNr==Other->m_SequNr && m_FrameNr==Other->m_FrameNr; 
     167} 
     168 
     169 
    155170void AnimExprStandardT::SetSequNr(int SequNr) 
    156171{ 
     
    238253 
    239254 
     255IntrusivePtrT<AnimExpressionT> AnimExprFilterT::Clone() const 
     256{ 
     257    return GetModel().GetAnimExprPool().GetFilter(m_SubExpr->Clone(), m_ChannelNr); 
     258} 
     259 
     260 
     261bool AnimExprFilterT::IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const 
     262{ 
     263    AnimExprFilterT* Other=dynamic_cast<AnimExprFilterT*>(AE.get()); 
     264 
     265    if (!Other) return false; 
     266    return m_ChannelNr==Other->m_ChannelNr && m_SubExpr->IsEqual(Other->m_SubExpr); 
     267} 
     268 
     269 
    240270/************************/ 
    241271/*** AnimExprCombineT ***/ 
     
    294324    m_A->AdvanceTime(Time, ForceLoop); 
    295325    m_B->AdvanceTime(Time, ForceLoop); 
     326} 
     327 
     328 
     329IntrusivePtrT<AnimExpressionT> AnimExprCombineT::Clone() const 
     330{ 
     331    return GetModel().GetAnimExprPool().GetCombine(m_A->Clone(), m_B->Clone()); 
     332} 
     333 
     334 
     335bool AnimExprCombineT::IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const 
     336{ 
     337    AnimExprCombineT* Other=dynamic_cast<AnimExprCombineT*>(AE.get()); 
     338 
     339    if (!Other) return false; 
     340    return m_A->IsEqual(Other->m_A) && m_B->IsEqual(Other->m_B); 
    296341} 
    297342 
     
    398443 
    399444 
     445IntrusivePtrT<AnimExpressionT> AnimExprBlendT::Clone() const 
     446{ 
     447    IntrusivePtrT<AnimExprBlendT> Blend=GetModel().GetAnimExprPool().GetBlend(m_A->Clone(), m_B->Clone(), m_Duration); 
     448 
     449    Blend->m_Frac=m_Frac; 
     450    return Blend; 
     451} 
     452 
     453 
     454bool AnimExprBlendT::IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const 
     455{ 
     456    AnimExprBlendT* Other=dynamic_cast<AnimExprBlendT*>(AE.get()); 
     457 
     458    if (!Other) return false; 
     459    return m_Frac==Other->m_Frac && m_Duration==Other->m_Duration && m_A->IsEqual(Other->m_A) && m_B->IsEqual(Other->m_B); 
     460} 
     461 
     462 
    400463/*********************/ 
    401464/*** AnimExprPoolT ***/ 
  • cafu/trunk/Libs/Models/AnimExpr.hpp

    r457 r459  
    2828 
    2929 
     30class AnimExpressionT; 
    3031class CafuModelT; 
     32 
     33typedef IntrusivePtrT<AnimExpressionT> AnimExpressionPtrT; 
    3134 
    3235 
     
    7780    virtual void AdvanceTime(float Time, bool ForceLoop=false) { } 
    7881 
     82    /// The virtual copy constructor. 
     83    /// Creates a new anim expression that is an exact copy of this, even when called 
     84    /// via the base class pointer (the caller doesn't need to know the exact derived class). 
     85    virtual IntrusivePtrT<AnimExpressionT> Clone() const=0; 
     86 
     87    /// Returns whether this anim expression is equal to \c A. 
     88    /// Two anim expressions are equal if their GetData() methods return the same data. 
     89    virtual bool IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const=0; 
     90 
    7991 
    8092    protected: 
     
    105117    virtual void GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const; 
    106118    virtual void AdvanceTime(float Time, bool ForceLoop=false); 
     119    virtual IntrusivePtrT<AnimExpressionT> Clone() const;   // Unfortunately, the proper covariant return type cannot be used with smart pointers. 
     120    virtual bool IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const; 
    107121 
    108122    /// Returns the sequence number that is currently set in this expression. 
     
    145159    virtual void GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const; 
    146160    virtual void AdvanceTime(float Time, bool ForceLoop=false) { m_SubExpr->AdvanceTime(Time, ForceLoop); } 
     161    virtual IntrusivePtrT<AnimExpressionT> Clone() const;   // Unfortunately, the proper covariant return type cannot be used with smart pointers. 
     162    virtual bool IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const; 
    147163 
    148164 
     
    167183    virtual void GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const; 
    168184    virtual void AdvanceTime(float Time, bool ForceLoop=false); 
     185    virtual IntrusivePtrT<AnimExpressionT> Clone() const;   // Unfortunately, the proper covariant return type cannot be used with smart pointers. 
     186    virtual bool IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const; 
    169187 
    170188 
     
    200218    virtual void GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const; 
    201219    virtual void AdvanceTime(float Time, bool ForceLoop=false); 
     220    virtual IntrusivePtrT<AnimExpressionT> Clone() const;   // Unfortunately, the proper covariant return type cannot be used with smart pointers. 
     221    virtual bool IsEqual(const IntrusivePtrT<AnimExpressionT>& AE) const; 
    202222 
    203223 
  • cafu/trunk/Libs/Models/AnimPose.cpp

    r455 r459  
    3535      m_SuperPose(NULL), 
    3636      m_DlodPose(NULL), 
    37       m_RecacheCount(0), 
     37      m_CachedAE(NULL), 
    3838      m_BoundingBox() 
    3939{ 
     
    5252      m_SuperPose(NULL), 
    5353      m_DlodPose(m_Model.GetDlodModel() ? new AnimPoseT(*m_Model.GetDlodModel(), m_AnimExpr) : NULL),  // Recursively create the chain of dlod poses matching the chain of dlod models. 
    54       m_RecacheCount(0), 
     54      m_CachedAE(NULL), 
    5555      m_BoundingBox() 
    5656{ 
     
    423423void AnimPoseT::Recache() const 
    424424{ 
    425     if (!m_SuperPose && m_RecacheCount==m_AnimExpr->GetChangeNum()) return; 
     425    if (!m_SuperPose && m_AnimExpr->IsEqual(m_CachedAE)) return; 
    426426 
    427427    SyncDimensions(); 
     
    438438    //     y(); 
    439439 
    440     m_RecacheCount=m_AnimExpr->GetChangeNum(); 
     440    if (m_SuperPose) 
     441    { 
     442        assert(m_CachedAE==NULL); 
     443    } 
     444    else 
     445    { 
     446        m_CachedAE=m_AnimExpr->Clone(); 
     447    } 
    441448} 
    442449 
     
    477484 
    478485    m_SuperPose=SuperPose; 
    479     m_RecacheCount=0; 
     486    m_CachedAE=NULL; 
    480487 
    481488    // Recursively update the chain of dlod poses. 
  • cafu/trunk/Libs/Models/AnimPose.hpp

    r457 r459  
    127127 
    128128    /// Call this if something in the related model has changed. 
    129     void SetNeedsRecache() { m_RecacheCount=0; }    // 0 is different from any value that m_AnimExpr->GetChangedCount() returns. 
     129    void SetNeedsRecache() { m_CachedAE=NULL; } 
    130130 
    131131    /// This method renders the model in this pose. 
     
    181181    void Recache() const; 
    182182 
    183     const CafuModelT&              m_Model;         ///< The related model that this is a pose for. 
    184     IntrusivePtrT<AnimExpressionT> m_AnimExpr;      ///< The expression that describes the skeleton pose for which we have computed the cache data. 
    185     const AnimPoseT*               m_SuperPose; 
    186     AnimPoseT*                     m_DlodPose;      ///< The next pose in the chain of dlod poses matching the chain of dlod models. 
     183    const CafuModelT&             m_Model;          ///< The related model that this is a pose for. 
     184    AnimExpressionPtrT            m_AnimExpr;       ///< The expression that describes the skeleton pose for which we have computed the cache data. 
     185    const AnimPoseT*              m_SuperPose; 
     186    AnimPoseT*                    m_DlodPose;       ///< The next pose in the chain of dlod poses matching the chain of dlod models. 
    187187 
    188     mutable unsigned int           m_RecacheCount;  ///< Used to detect if the m_AnimExpr has changed, so that our matrices, meshes etc. can be recached. 
    189     mutable ArrayT<MatrixT>        m_JointMatrices; ///< The transformation matrices that represent the pose of the skeleton at the given animation sequence and frame number. 
    190     mutable ArrayT<MeshInfoT>      m_MeshInfos;     ///< Additional data for each mesh in m_Model. 
    191     mutable ArrayT<MatSys::MeshT>  m_Draw_Meshes;   ///< The draw meshes resulting from the m_JointMatrices. 
    192     mutable BoundingBox3fT         m_BoundingBox;   ///< The bounding-box for the model in this pose. 
     188    mutable AnimExpressionPtrT    m_CachedAE;       ///< Used to detect if the m_AnimExpr has changed, so that our matrices, meshes etc. can be recached. 
     189    mutable ArrayT<MatrixT>       m_JointMatrices; ///< The transformation matrices that represent the pose of the skeleton at the given animation sequence and frame number. 
     190    mutable ArrayT<MeshInfoT>     m_MeshInfos;      ///< Additional data for each mesh in m_Model. 
     191    mutable ArrayT<MatSys::MeshT> m_Draw_Meshes;    ///< The draw meshes resulting from the m_JointMatrices. 
     192    mutable BoundingBox3fT        m_BoundingBox;    ///< The bounding-box for the model in this pose. 
    193193}; 
    194194 
  • cafu/trunk/Libs/Models/Model_cmdl.cpp

    r455 r459  
    3030#include <iostream> 
    3131 
     32#if defined(_WIN32) && defined(_MSC_VER) 
     33    // Turn off warning C4355: 'this' : used in base member initializer list. 
     34    #pragma warning(disable:4355) 
     35#endif 
     36 
    3237 
    3338/*static*/ const unsigned int CafuModelT::CMDL_FILE_VERSION=1; 
     
    249254      m_UseGivenTangentSpace(Loader.UseGivenTS()),  // Should we use the fixed, given tangent space, or recompute it ourselves here? 
    250255      m_DlodModel(NULL), 
    251       m_DlodDist(0.0f) 
    252       , m_TEMP_Pose(NULL) 
     256      m_DlodDist(0.0f), 
     257      m_AnimExprPool(*this), 
     258      m_TEMP_Pose(NULL) 
    253259{ 
    254260    // No matter the actual model file format (that is, even if the file format is not "cmdl"), 
  • cafu/trunk/Libs/Models/Model_cmdl.hpp

    r457 r459  
    228228    /// so that multiple animations can play on different parts of the model at the same time. 
    229229    /// For example, you can play a walking animation on the legs, an animation for swinging 
    230     /// the arms on the upper body, and an animation for moving the eyes on the head.  
     230    /// the arms on the upper body, and an animation for moving the eyes on the head. 
    231231    /// 
    232232    /// Technically, a channel defines a group of joints. It is used to limit or "filter" 
     
    281281    bool IsVertexNrOK(const GuiFixtureT& GF, unsigned int PointNr) const; 
    282282 
     283    /// This method returns the pool of anim expressions for this model. 
     284    AnimExprPoolT& GetAnimExprPool() const { return m_AnimExprPool; } 
     285 
    283286    /// This method is strictly for backwards-compatibility only, do not use in new code! 
    284287    AnimPoseT* GetSharedPose(int SequNr, float FrameNr) const; 
     
    314317    void InitMeshes();                              ///< An auxiliary method for the constructors. 
    315318 
    316     const std::string    m_FileName;                ///< File name of this model.   TODO: Remove!?! 
    317     MaterialManagerImplT m_MaterialMan;             ///< The material manager for the materials that are used with the meshes of this model. 
    318     ArrayT<JointT>       m_Joints;                  ///< Array of joints of this model. 
    319     ArrayT<MeshT>        m_Meshes;                  ///< Array of (sub)meshes of this model. 
    320     ArrayT<SkinT>        m_Skins;                   ///< Array of additional/alternative skins for this model. 
    321     ArrayT<GuiFixtureT>  m_GuiFixtures;             ///< Array of GUI fixtures in the model. 
    322     ArrayT<GuiLocT>      m_GuiLocs;                 ///< Array of locations where GUIs can be attached to this model. 
    323     ArrayT<AnimT>        m_Anims;                   ///< Array of animations of this model. 
    324     ArrayT<ChannelT>     m_Channels;                ///< Array of channels in this model. 
    325  
    326     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). 
    327  // const bool           m_CastShadows;             ///< Should this model cast shadows? 
    328  
    329     CafuModelT*          m_DlodModel;               ///< Use the m_DlodModel instead of this when the camera is more than m_DlodDist away. 
    330     float                m_DlodDist;                ///< The distance beyond which the m_DlodModel is used instead of this. 
    331  
    332     mutable AnimPoseT*   m_TEMP_Pose;               ///< TEMPORARY! 
     319    const std::string     m_FileName;               ///< File name of this model.   TODO: Remove!?! 
     320    MaterialManagerImplT  m_MaterialMan;            ///< The material manager for the materials that are used with the meshes of this model. 
     321    ArrayT<JointT>        m_Joints;                 ///< Array of joints of this model. 
     322    ArrayT<MeshT>         m_Meshes;                 ///< Array of (sub)meshes of this model. 
     323    ArrayT<SkinT>         m_Skins;                  ///< Array of additional/alternative skins for this model. 
     324    ArrayT<GuiFixtureT>   m_GuiFixtures;            ///< Array of GUI fixtures in the model. 
     325    ArrayT<GuiLocT>       m_GuiLocs;                ///< Array of locations where GUIs can be attached to this model. 
     326    ArrayT<AnimT>         m_Anims;                  ///< Array of animations of this model. 
     327    ArrayT<ChannelT>      m_Channels;               ///< Array of channels in this model. 
     328 
     329    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). 
     330 // const bool            m_CastShadows;            ///< Should this model cast shadows? 
     331 
     332    CafuModelT*           m_DlodModel;              ///< Use the m_DlodModel instead of this when the camera is more than m_DlodDist away. 
     333    float                 m_DlodDist;               ///< The distance beyond which the m_DlodModel is used instead of this. 
     334 
     335    mutable AnimExprPoolT m_AnimExprPool;           ///< The pool of anim expressions for this model. 
     336    mutable AnimPoseT*    m_TEMP_Pose;              ///< TEMPORARY! 
    333337}; 
    334338