Changeset 453

Show
Ignore:
Timestamp:
01/07/12 14:44:14 (5 months ago)
Author:
Carsten
Message:

Model code: This change extends and revises the AnimExpressionT class hierarchy,
so that our support for animation channels and animation blending is now complete!

This change is the "second half" of r452.
Upcoming changes will apply the new functionality to our application code, so that we can actually see the results.

Location:
cafu/trunk/Libs
Files:
1 added
5 modified

Legend:

Unmodified
Added
Removed
  • cafu/trunk/Libs/MaterialSystem/MaterialManagerImpl.hpp

    r439 r453  
    5353 
    5454    /// Returns whether the material with the given name is registered with the material manager, 
    55     /// i.e. if a call to <code>GetMaterial(MaterialName)</code> will return successfully. 
     55    /// i.e.\ if a call to <code>GetMaterial(MaterialName)</code> will return successfully. 
    5656    /// Use this to avoid warning messages to the console if the material is not registered. 
    5757    bool HasMaterial(const std::string& MaterialName) const; 
  • cafu/trunk/Libs/Models/AnimExpr.cpp

    r452 r453  
    2424 
    2525 
     26AnimExpressionT::AnimExpressionT(const CafuModelT& Model) 
     27    : m_Model(Model), 
     28      m_RefCount(0), 
     29      m_ChangeNum(0) 
     30{ 
     31    UpdateChangeNum(); 
     32} 
     33 
     34 
     35void AnimExpressionT::UpdateChangeNum() 
     36{ 
     37    static unsigned int s_ChangeCount=0; 
     38 
     39    m_ChangeNum = ++s_ChangeCount; 
     40} 
     41 
     42 
    2643/*************************/ 
    2744/*** AnimExprStandardT ***/ 
     
    3148    : AnimExpressionT(Model), 
    3249      m_SequNr(SequNr), 
    33       m_FrameNr(FrameNr), 
    34       m_ChangeCount(1)      // The user code inits its own count with 0. 
     50      m_FrameNr(FrameNr) 
    3551{ 
    3652    NormalizeInput(); 
     
    144160    NormalizeInput(); 
    145161 
    146     m_ChangeCount++; 
     162    UpdateChangeNum(); 
    147163} 
    148164 
     
    155171    NormalizeInput(); 
    156172 
    157     m_ChangeCount++; 
    158 } 
     173    UpdateChangeNum(); 
     174} 
     175 
     176 
     177/***********************/ 
     178/*** AnimExprFilterT ***/ 
     179/***********************/ 
     180 
     181namespace 
     182{ 
     183    unsigned int FindChannelByName(const CafuModelT& Model, const std::string& ChannelName) 
     184    { 
     185        unsigned int ChannelNr; 
     186 
     187        for (ChannelNr=0; ChannelNr<Model.GetChannels().Size(); ChannelNr++) 
     188            if (ChannelName == Model.GetChannels()[ChannelNr].Name) 
     189                return ChannelNr; 
     190 
     191        return ChannelNr; 
     192    } 
     193} 
     194 
     195 
     196AnimExprFilterT::AnimExprFilterT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> SubExpr, unsigned int ChannelNr) 
     197    : AnimExpressionT(Model), 
     198      m_SubExpr(SubExpr), 
     199      m_ChannelNr(ChannelNr) 
     200{ 
     201} 
     202 
     203 
     204AnimExprFilterT::AnimExprFilterT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> SubExpr, const std::string& ChannelName) 
     205    : AnimExpressionT(Model), 
     206      m_SubExpr(SubExpr), 
     207      m_ChannelNr(FindChannelByName(Model, ChannelName)) 
     208{ 
     209} 
     210 
     211 
     212void AnimExprFilterT::ReInit(IntrusivePtrT<AnimExpressionT> SubExpr, unsigned int ChannelNr) 
     213{ 
     214    if (m_SubExpr==SubExpr && m_ChannelNr==ChannelNr) return; 
     215 
     216    m_SubExpr  =SubExpr; 
     217    m_ChannelNr=ChannelNr; 
     218 
     219    UpdateChangeNum(); 
     220} 
     221 
     222 
     223unsigned int AnimExprFilterT::GetChangeNum() const 
     224{ 
     225    return std::max(GetChangeNum(), m_SubExpr->GetChangeNum()); 
     226} 
     227 
     228 
     229void AnimExprFilterT::GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const 
     230{ 
     231    Weight=0.0f; 
     232 
     233    if (m_ChannelNr >= GetModel().GetChannels().Size() || GetModel().GetChannels()[m_ChannelNr].IsMember(JointNr)) 
     234    { 
     235        m_SubExpr->GetData(JointNr, Weight, Pos, Quat, Scale); 
     236    } 
     237} 
     238 
     239 
     240/************************/ 
     241/*** AnimExprCombineT ***/ 
     242/************************/ 
     243 
     244AnimExprCombineT::AnimExprCombineT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B) 
     245    : AnimExpressionT(Model), 
     246      m_A(A), 
     247      m_B(B) 
     248{ 
     249} 
     250 
     251 
     252void AnimExprCombineT::ReInit(IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B) 
     253{ 
     254    if (m_A==A && m_B==B) return; 
     255 
     256    m_A=A; 
     257    m_B=B; 
     258 
     259    UpdateChangeNum(); 
     260} 
     261 
     262 
     263unsigned int AnimExprCombineT::GetChangeNum() const 
     264{ 
     265    return std::max(GetChangeNum(), 
     266                    std::max(m_A->GetChangeNum(), m_B->GetChangeNum())); 
     267} 
     268 
     269 
     270void AnimExprCombineT::GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const 
     271{ 
     272    m_A->GetData(JointNr, Weight, Pos, Quat, Scale); 
     273 
     274    float                  WeightB; 
     275    Vector3fT              PosB; 
     276    cf::math::QuaternionfT QuatB; 
     277    Vector3fT              ScaleB; 
     278 
     279    // Pick the expression with the largest weight. 
     280    m_B->GetData(JointNr, WeightB, PosB, QuatB, ScaleB); 
     281 
     282    if (WeightB > Weight) 
     283    { 
     284        Weight = WeightB; 
     285        Pos    = PosB; 
     286        Quat   = QuatB; 
     287        Scale  = ScaleB; 
     288    } 
     289} 
     290 
     291 
     292void AnimExprCombineT::AdvanceTime(float Time, bool ForceLoop) 
     293{ 
     294    m_A->AdvanceTime(Time, ForceLoop); 
     295    m_B->AdvanceTime(Time, ForceLoop); 
     296} 
     297 
     298 
     299/**********************/ 
     300/*** AnimExprBlendT ***/ 
     301/**********************/ 
     302 
     303AnimExprBlendT::AnimExprBlendT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B, float Duration) 
     304    : AnimExpressionT(Model), 
     305      m_A(A), 
     306      m_B(B), 
     307      m_Duration(Duration), 
     308      m_Frac(0.0f) 
     309{ 
     310} 
     311 
     312 
     313void AnimExprBlendT::ReInit(IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B, float Duration) 
     314{ 
     315    m_A=A; 
     316    m_B=B; 
     317    m_Duration=Duration; 
     318    m_Frac=0.0f; 
     319 
     320    UpdateChangeNum(); 
     321} 
     322 
     323 
     324unsigned int AnimExprBlendT::GetChangeNum() const 
     325{ 
     326    return std::max(GetChangeNum(), 
     327                    std::max(m_A->GetChangeNum(), m_B->GetChangeNum())); 
     328} 
     329 
     330 
     331void AnimExprBlendT::GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const 
     332{ 
     333    float                  w[2]; 
     334    Vector3fT              p[2]; 
     335    cf::math::QuaternionfT q[2]; 
     336    Vector3fT              s[2]; 
     337 
     338    if (m_Frac <= 0.0f) 
     339    { 
     340        m_A->GetData(JointNr, Weight, Pos, Quat, Scale); 
     341        return; 
     342    } 
     343 
     344    if (m_Frac >= 1.0f) 
     345    { 
     346        m_B->GetData(JointNr, Weight, Pos, Quat, Scale); 
     347        return; 
     348    } 
     349 
     350    m_A->GetData(JointNr, w[0], p[0], q[0], s[0]); 
     351    m_B->GetData(JointNr, w[1], p[1], q[1], s[1]); 
     352 
     353    const float f0 = 1.0f - m_Frac; 
     354    const float f1 = m_Frac; 
     355 
     356    Weight = w[0]*f0 + w[1]*f1; 
     357    Pos    = p[0]*f0 + p[1]*f1; 
     358    Quat   = slerp(q[0], q[1], f0);   // slerp() is why we cannot have generic "add" and "mul" AnimExpressionT's. 
     359    Scale  = s[0]*f0 + s[1]*f1; 
     360} 
     361 
     362 
     363void AnimExprBlendT::AdvanceTime(float Time, bool ForceLoop) 
     364{ 
     365    // Advance the blend fraction. 
     366    if (m_Duration < 0.001f) 
     367    { 
     368        m_Frac = 1.0f; 
     369    } 
     370    else 
     371    { 
     372        m_Frac += Time/m_Duration; 
     373    } 
     374 
     375    m_Frac = std::min(m_Frac, 1.0f); 
     376 
     377 
     378    // Advance the sub-expressions. 
     379    if (m_Frac < 1.0f) 
     380    { 
     381        m_A->AdvanceTime(Time, ForceLoop); 
     382    } 
     383    else 
     384    { 
     385        m_A=NULL;   // m_A is unused now that m_Frac >= 1.0. 
     386    } 
     387 
     388    m_B->AdvanceTime(Time, ForceLoop); 
     389 
     390 
     391    UpdateChangeNum(); 
     392} 
     393 
     394 
     395/*********************/ 
     396/*** AnimExprPoolT ***/ 
     397/*********************/ 
     398 
     399void AnimExprPoolT::FlattenUnused() 
     400{ 
     401    for (unsigned int AENr=0; AENr<m_Filter.Size(); AENr++) 
     402        if (m_Filter[AENr]->GetRefCount()==1) 
     403            m_Filter[AENr]->ReInit(NULL, 0); 
     404 
     405    for (unsigned int AENr=0; AENr<m_Combine.Size(); AENr++) 
     406        if (m_Combine[AENr]->GetRefCount()==1) 
     407            m_Combine[AENr]->ReInit(NULL, NULL); 
     408 
     409    for (unsigned int AENr=0; AENr<m_Blend.Size(); AENr++) 
     410        if (m_Blend[AENr]->GetRefCount()==1) 
     411            m_Blend[AENr]->ReInit(NULL, NULL, 0.0f); 
     412} 
     413 
     414 
     415IntrusivePtrT<AnimExprStandardT> AnimExprPoolT::GetStandard(int SequNr, float FrameNr) 
     416{ 
     417    FlattenUnused(); 
     418 
     419    for (unsigned int AENr=0; AENr<m_Standard.Size(); AENr++) 
     420    { 
     421        if (m_Standard[AENr]->GetRefCount()==1) 
     422        { 
     423            m_Standard[AENr]->SetSequNr(SequNr); 
     424            m_Standard[AENr]->SetFrameNr(FrameNr); 
     425 
     426            return m_Standard[AENr]; 
     427        } 
     428    } 
     429 
     430    IntrusivePtrT<AnimExprStandardT> NewAE(new AnimExprStandardT(m_Model, SequNr, FrameNr)); 
     431    m_Standard.PushBack(NewAE); 
     432 
     433    return NewAE; 
     434} 
     435 
     436 
     437IntrusivePtrT<AnimExprFilterT> AnimExprPoolT::GetFilter(IntrusivePtrT<AnimExpressionT> SubExpr, unsigned int ChannelNr) 
     438{ 
     439    FlattenUnused(); 
     440 
     441    for (unsigned int AENr=0; AENr<m_Filter.Size(); AENr++) 
     442    { 
     443        if (m_Filter[AENr]->GetRefCount()==1) 
     444        { 
     445            m_Filter[AENr]->ReInit(SubExpr, ChannelNr); 
     446 
     447            return m_Filter[AENr]; 
     448        } 
     449    } 
     450 
     451    IntrusivePtrT<AnimExprFilterT> NewAE(new AnimExprFilterT(m_Model, SubExpr, ChannelNr)); 
     452    m_Filter.PushBack(NewAE); 
     453 
     454    return NewAE; 
     455} 
     456 
     457 
     458IntrusivePtrT<AnimExprFilterT> AnimExprPoolT::GetFilter(IntrusivePtrT<AnimExpressionT> SubExpr, const std::string& ChannelName) 
     459{ 
     460    return GetFilter(SubExpr, FindChannelByName(m_Model, ChannelName)); 
     461} 
     462 
     463 
     464IntrusivePtrT<AnimExprCombineT> AnimExprPoolT::GetCombine(IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B) 
     465{ 
     466    FlattenUnused(); 
     467 
     468    for (unsigned int AENr=0; AENr<m_Combine.Size(); AENr++) 
     469    { 
     470        if (m_Combine[AENr]->GetRefCount()==1) 
     471        { 
     472            m_Combine[AENr]->ReInit(A, B); 
     473 
     474            return m_Combine[AENr]; 
     475        } 
     476    } 
     477 
     478    IntrusivePtrT<AnimExprCombineT> NewAE(new AnimExprCombineT(m_Model, A, B)); 
     479    m_Combine.PushBack(NewAE); 
     480 
     481    return NewAE; 
     482} 
     483 
     484 
     485IntrusivePtrT<AnimExprBlendT> AnimExprPoolT::GetBlend(IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B, float Duration) 
     486{ 
     487    FlattenUnused(); 
     488 
     489    for (unsigned int AENr=0; AENr<m_Blend.Size(); AENr++) 
     490    { 
     491        if (m_Blend[AENr]->GetRefCount()==1) 
     492        { 
     493            m_Blend[AENr]->ReInit(A, B, Duration); 
     494 
     495            return m_Blend[AENr]; 
     496        } 
     497    } 
     498 
     499    IntrusivePtrT<AnimExprBlendT> NewAE(new AnimExprBlendT(m_Model, A, B, Duration)); 
     500    m_Blend.PushBack(NewAE); 
     501 
     502    return NewAE; 
     503} 
  • cafu/trunk/Libs/Models/AnimExpr.hpp

    r452 r453  
    2424 
    2525#include "Math3D/Quaternion.hpp" 
     26#include "Templates/Array.hpp" 
     27#include "Templates/Pointer.hpp" 
    2628 
    2729 
     
    2931 
    3032 
     33/// Animation expressions describe the "skeleton pose" of a model. 
     34/// 
     35/// They are used as an input to AnimPoseT instances, which use the "skeleton pose" expressed by an anim 
     36/// expression in order to derive the "full pose", including meshes and other features such as collision 
     37/// detection. 
     38/// In other words, AnimPoseT's refer to an AnimExpressionT for the "configuration" of its pose. 
     39/// 
     40/// AnimExpressionT's can be hierarchically composed, just like mathematical expressions, 
     41/// which is in fact their strongest and most important feature. 
     42/// They are also very easy and care-free to use and have very good performance, because when obtained 
     43/// from an AnimExprPoolT, the pool minimizes both the number of instances as well as the penalties from 
     44/// memory allocations and deletes. 
    3145class AnimExpressionT 
    3246{ 
    3347    public: 
    3448 
    35     /// The constructor.        TODO: Make protected, so that only derived classes can use it? 
    36     AnimExpressionT(const CafuModelT& Model) : m_Model(Model) { } 
     49    /// The constructor. 
     50    /// (It's ok to have this in "public" instead of "protected": we have pure virtual methods as well.) 
     51    AnimExpressionT(const CafuModelT& Model); 
    3752 
    3853    /// The (virtual) destructor. 
     
    4156    /// Returns the model that this is an anim expression for. 
    4257    const CafuModelT& GetModel() const { return m_Model; } 
     58 
     59    /// Returns the number of IntrusivePtrT<>'s that currently refer to this anim expression. 
     60    /// This is especially useful for the implementation of "pools" of AnimExpressionT's, 
     61    /// so that the pool implementation can learn if this instance is available for being re-used. 
     62    unsigned int GetRefCount() const { return m_RefCount; } 
    4363 
    4464    /// Returns a number that changes whenever this expression changes, 
     
    4666    /// This is the case for example after every call to AdvanceTime() with a nonzero Time, 
    4767    /// or when a sub-expression has been modified (e.g. got a new sequence number assigned). 
    48     /// The caller can use this number in order to control refreshes of its mesh caches. 
    49     virtual unsigned int GetChangeCount() const=0; 
     68    /// The caller can use this number in order to control updates of its mesh caches. 
     69    virtual unsigned int GetChangeNum() const { return m_ChangeNum; } 
    5070 
    5171    /// For the joint with the given JointNr, this function returns 
     
    5878 
    5979 
    60     private: 
     80    protected: 
     81 
     82    void UpdateChangeNum(); 
     83 
     84 
     85    private: 
     86 
     87    template<class T> friend class IntrusivePtrT; 
    6188 
    6289    AnimExpressionT(const AnimExpressionT&);        ///< Use of the Copy    Constructor is not allowed. 
    6390    void operator = (const AnimExpressionT&);       ///< Use of the Assignment Operator is not allowed. 
    6491 
    65     const CafuModelT& m_Model;  ///< The related model that this is an anim expression for. 
     92    const CafuModelT& m_Model;      ///< The related model that this is an anim expression for. 
     93    unsigned int      m_RefCount;   ///< How many IntrusivePtrT<>'s currently refer to this anim expression? 
     94    unsigned int      m_ChangeNum;  ///< Changes whenever the data returned by GetData() changes. 
    6695}; 
    6796 
     
    74103 
    75104    // Implementations and overrides for base class methods. 
    76     virtual unsigned int GetChangeCount() const { return m_ChangeCount; } 
    77105    virtual void GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const; 
    78106    virtual void AdvanceTime(float Time, bool ForceLoop=false); 
     
    97125    void NormalizeInput(); 
    98126 
    99     int          m_SequNr;      ///< The animation sequence number. 
    100     float        m_FrameNr;     ///< The frame number in the sequence. 
    101     unsigned int m_ChangeCount; ///< Changes whenever the data returned by GetData() might have changed. 
     127    int   m_SequNr;     ///< The animation sequence number. 
     128    float m_FrameNr;    ///< The frame number in the sequence. 
     129}; 
     130 
     131 
     132/// Filters the result of another expression by a "channel". 
     133class AnimExprFilterT : public AnimExpressionT 
     134{ 
     135    public: 
     136 
     137    AnimExprFilterT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> SubExpr, unsigned int ChannelNr); 
     138    AnimExprFilterT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> SubExpr, const std::string& ChannelName); 
     139 
     140    /// Re-initializes this anim expression, so that it can be re-used with different parameters (on the same model). 
     141    void ReInit(IntrusivePtrT<AnimExpressionT> SubExpr, unsigned int ChannelNr); 
     142 
     143    // Implementations and overrides for base class methods. 
     144    virtual unsigned int GetChangeNum() const; 
     145    virtual void GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const; 
     146    virtual void AdvanceTime(float Time, bool ForceLoop=false) { m_SubExpr->AdvanceTime(Time, ForceLoop); } 
     147 
     148 
     149    private: 
     150 
     151    IntrusivePtrT<AnimExpressionT> m_SubExpr; 
     152    unsigned int                   m_ChannelNr; 
     153}; 
     154 
     155 
     156class AnimExprCombineT : public AnimExpressionT 
     157{ 
     158    public: 
     159 
     160    AnimExprCombineT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B); 
     161 
     162    /// Re-initializes this anim expression, so that it can be re-used with different parameters (on the same model). 
     163    void ReInit(IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B); 
     164 
     165    // Implementations and overrides for base class methods. 
     166    virtual unsigned int GetChangeNum() const; 
     167    virtual void GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const; 
     168    virtual void AdvanceTime(float Time, bool ForceLoop=false); 
     169 
     170 
     171    private: 
     172 
     173    IntrusivePtrT<AnimExpressionT> m_A; 
     174    IntrusivePtrT<AnimExpressionT> m_B; 
     175}; 
     176 
     177 
     178class AnimExprBlendT : public AnimExpressionT 
     179{ 
     180    public: 
     181 
     182    AnimExprBlendT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B, float Duration); 
     183 
     184    /// Re-initializes this anim expression, so that it can be re-used with different parameters (on the same model). 
     185    /// Note that resetting \c A, \c B or \c Duration individually is not possible, because the implementation 
     186    /// may prune and drop \c A when the blend is complete. 
     187    void ReInit(IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B, float Duration); 
     188 
     189    // Implementations and overrides for base class methods. 
     190    virtual unsigned int GetChangeNum() const; 
     191    virtual void GetData(unsigned int JointNr, float& Weight, Vector3fT& Pos, cf::math::QuaternionfT& Quat, Vector3fT& Scale) const; 
     192    virtual void AdvanceTime(float Time, bool ForceLoop=false); 
     193 
     194 
     195    private: 
     196 
     197    IntrusivePtrT<AnimExpressionT> m_A; 
     198    IntrusivePtrT<AnimExpressionT> m_B; 
     199    float                          m_Duration; 
     200    float                          m_Frac; 
     201}; 
     202 
     203 
     204class AnimExprPoolT 
     205{ 
     206    public: 
     207 
     208    AnimExprPoolT(const CafuModelT& Model) : m_Model(Model) { } 
     209 
     210    // These methods mimic the ctors of the anim expression classes. 
     211    IntrusivePtrT<AnimExprStandardT> GetStandard(int SequNr, float FrameNr); 
     212    IntrusivePtrT<AnimExprFilterT>   GetFilter(IntrusivePtrT<AnimExpressionT> SubExpr, unsigned int ChannelNr); 
     213    IntrusivePtrT<AnimExprFilterT>   GetFilter(IntrusivePtrT<AnimExpressionT> SubExpr, const std::string& ChannelName); 
     214    IntrusivePtrT<AnimExprCombineT>  GetCombine(IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B); 
     215    IntrusivePtrT<AnimExprBlendT>    GetBlend(IntrusivePtrT<AnimExpressionT> A, IntrusivePtrT<AnimExpressionT> B, float Duration); 
     216 
     217 
     218    private: 
     219 
     220    /// This function makes sure that anim expressions that are unused don't keep pointers 
     221    /// to subexpressions, such that the subexpressions are available as unused as well. 
     222    void FlattenUnused(); 
     223 
     224    const CafuModelT&                          m_Model;     ///< The related model that this is an anim expression pool for. 
     225    ArrayT< IntrusivePtrT<AnimExprStandardT> > m_Standard; 
     226    ArrayT< IntrusivePtrT<AnimExprFilterT> >   m_Filter; 
     227    ArrayT< IntrusivePtrT<AnimExprCombineT> >  m_Combine; 
     228    ArrayT< IntrusivePtrT<AnimExprBlendT> >    m_Blend; 
    102229}; 
    103230 
  • cafu/trunk/Libs/Models/AnimPose.cpp

    r452 r453  
    3030 
    3131 
     32AnimPoseT::AnimPoseT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> AnimExpr) 
     33    : m_Model(Model), 
     34      m_AnimExpr(AnimExpr), 
     35      m_SuperPose(NULL), 
     36      m_DlodPose(NULL), 
     37      m_RecacheCount(0), 
     38      m_BoundingBox() 
     39{ 
     40    if (m_Model.GetDlodModel()) 
     41    { 
     42        // Recursively create the chain of dlod poses matching the chain of dlod models. 
     43        // Note that all dlod poses share the *SAME* AnimExpr as the top-most pose! 
     44        m_DlodPose = new AnimPoseT(*m_Model.GetDlodModel(), m_AnimExpr); 
     45    } 
     46} 
     47 
     48 
    3249AnimPoseT::AnimPoseT(const CafuModelT& Model, int SequNr, float FrameNr) 
    3350    : m_Model(Model), 
    34       m_AnimExpr(NULL), 
     51      m_AnimExpr(new AnimExprStandardT(m_Model, SequNr, FrameNr)), 
    3552      m_SuperPose(NULL), 
    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. 
     53      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. 
    3754      m_RecacheCount(0), 
    3855      m_BoundingBox() 
    3956{ 
    40     m_AnimExpr=new AnimExprStandardT(m_Model, SequNr, FrameNr); 
    4157} 
    4258 
     
    4561{ 
    4662    delete m_DlodPose; 
    47     delete m_AnimExpr; 
     63} 
     64 
     65 
     66void AnimPoseT::SetAnimExpr(IntrusivePtrT<AnimExpressionT> AnimExpr) 
     67{ 
     68    for (AnimPoseT* Pose=this; Pose; Pose=Pose->m_DlodPose) 
     69    { 
     70        Pose->m_AnimExpr = AnimExpr; 
     71    } 
    4872} 
    4973 
     
    399423void AnimPoseT::Recache() const 
    400424{ 
    401     if (!m_SuperPose && m_RecacheCount==m_AnimExpr->GetChangeCount()) return; 
     425    if (!m_SuperPose && m_RecacheCount==m_AnimExpr->GetChangeNum()) return; 
    402426 
    403427    SyncDimensions(); 
     
    414438    //     y(); 
    415439 
    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(); } 
     440    m_RecacheCount=m_AnimExpr->GetChangeNum(); 
     441} 
     442 
     443 
     444int   AnimPoseT::GetSequNr() const 
     445{ 
     446    return dynamic_cast<const AnimExprStandardT*>(&*m_AnimExpr)->GetSequNr(); 
     447} 
     448 
     449 
     450float AnimPoseT::GetFrameNr() const 
     451{ 
     452    return dynamic_cast<const AnimExprStandardT*>(&*m_AnimExpr)->GetFrameNr(); 
     453} 
    422454 
    423455 
    424456void AnimPoseT::SetSequNr(int SequNr) 
    425457{ 
    426     dynamic_cast<AnimExprStandardT*>(m_AnimExpr)->SetSequNr(SequNr); 
     458    dynamic_cast<AnimExprStandardT*>(&*m_AnimExpr)->SetSequNr(SequNr); 
    427459 
    428460    // Recursively update the chain of dlod poses. 
     
    433465void AnimPoseT::SetFrameNr(float FrameNr) 
    434466{ 
    435     dynamic_cast<AnimExprStandardT*>(m_AnimExpr)->SetFrameNr(FrameNr); 
     467    dynamic_cast<AnimExprStandardT*>(&*m_AnimExpr)->SetFrameNr(FrameNr); 
    436468 
    437469    // Recursively update the chain of dlod poses. 
  • cafu/trunk/Libs/Models/AnimPose.hpp

    r452 r453  
    2323#define _CAFU_MODEL_ANIM_POSE_HPP_ 
    2424 
    25 #include "Templates/Array.hpp" 
     25#include "AnimExpr.hpp" 
    2626#include "MaterialSystem/Mesh.hpp" 
    2727#include "Math3D/BoundingBox.hpp" 
     
    2929 
    3030 
    31 class AnimExpressionT; 
    3231class CafuModelT; 
    3332class MaterialT; 
     
    3635/// This class describes a specific pose of an associated model. 
    3736/// 
    38 /// A pose is defined by a set of animation sequences at given frame numbers for given channels, 
    39 /// whose combined application to the model yields all data that is relevant for further actions 
     37/// A pose is defined (or "configured") by an AnimExpressionT instance 
     38/// whose application to the model yields all data that is relevant for further actions 
    4039/// on the model in that pose, such as rendering, tracing rays, collision detection, etc. 
    4140/// 
    42 /// The data that is derived from the set of input tuples (sequence, frame number, channel) 
    43 /// is cached within the pose instance. It comprises: 
     41/// The data that is derived from the anim expression is cached within the pose instance. 
     42/// It comprises: 
    4443///   - the transformation matrices for each joint in the skeleton, 
    4544///   - the MatSys render meshes for each mesh, 
     
    4847/// the representation of a model (the \c CafuModelT instance). 
    4948/// As a consequence, AnimPoseT instances should be shared whenever there are multiple users 
    50 /// (such as "static detail model" entity instances) that all show the same model in the same 
    51 /// pose. 
     49/// (such as "static detail model" entity instances) that all show the same model in the same pose. 
    5250class AnimPoseT 
    5351{ 
     
    8987 
    9088    /// The constructor. 
     89    AnimPoseT(const CafuModelT& Model, IntrusivePtrT<AnimExpressionT> AnimExpr); 
     90 
     91    /// The constructor. 
    9192    AnimPoseT(const CafuModelT& Model, int SequNr=-1, float FrameNr=0.0f); 
    9293 
    9394    /// The destructor. 
    9495    ~AnimPoseT(); 
     96 
     97    /// Sets a new anim expression to use for this pose. 
     98    /// 
     99    /// \param AnimExpr   The new anim expression to use for this pose. 
     100    void SetAnimExpr(IntrusivePtrT<AnimExpressionT> AnimExpr); 
    95101 
    96102    int GetSequNr() const; 
     
    172178    void Recache() const; 
    173179 
    174     const CafuModelT&             m_Model;          ///< The related model that this is a pose for. 
    175     AnimExpressionT*              m_AnimExpr;       ///< The expression that describes the animation state of the joints for which we have computed the cache data. 
    176     const AnimPoseT*              m_SuperPose; 
    177     AnimPoseT*                    m_DlodPose;       ///< The next pose in the chain of dlod poses matching the chain of dlod models. 
    178  // ArrayT<...>                   m_Def;            ///< Array of { channel, sequence, framenr, (forceloop), blendweight } tuples. 
    179  // bool                          m_DoCache;        ///< Cache the computed data? (Set to true by the user if he want to re-use this instance.) 
     180    const CafuModelT&              m_Model;         ///< The related model that this is a pose for. 
     181    IntrusivePtrT<AnimExpressionT> m_AnimExpr;      ///< The expression that describes the skeleton pose for which we have computed the cache data. 
     182    const AnimPoseT*               m_SuperPose; 
     183    AnimPoseT*                     m_DlodPose;      ///< The next pose in the chain of dlod poses matching the chain of dlod models. 
    180184 
    181     mutable unsigned int          m_RecacheCount;   ///< Used to detect if the m_AnimExpr has changed, so that our matrices, meshes etc. can be recached. 
    182     mutable ArrayT<MatrixT>       m_JointMatrices; ///< The transformation matrices that represent the pose of the skeleton at the given animation sequence and frame number. 
    183     mutable ArrayT<MeshInfoT>     m_MeshInfos;      ///< Additional data for each mesh in m_Model. 
    184     mutable ArrayT<MatSys::MeshT> m_Draw_Meshes;    ///< The draw meshes resulting from the m_JointMatrices. 
    185     mutable BoundingBox3fT        m_BoundingBox;    ///< The bounding-box for the model in this pose. 
     185    mutable unsigned int           m_RecacheCount;  ///< Used to detect if the m_AnimExpr has changed, so that our matrices, meshes etc. can be recached. 
     186    mutable ArrayT<MatrixT>        m_JointMatrices; ///< The transformation matrices that represent the pose of the skeleton at the given animation sequence and frame number. 
     187    mutable ArrayT<MeshInfoT>      m_MeshInfos;     ///< Additional data for each mesh in m_Model. 
     188    mutable ArrayT<MatSys::MeshT>  m_Draw_Meshes;   ///< The draw meshes resulting from the m_JointMatrices. 
     189    mutable BoundingBox3fT         m_BoundingBox;   ///< The bounding-box for the model in this pose. 
    186190}; 
    187191