Changeset 382

Show
Ignore:
Timestamp:
09/17/11 11:38:06 (8 months ago)
Author:
Carsten
Message:

Models: Added support for skins (alternative/additional sets of materials for the meshes of a model).

References #86.

Location:
cafu/trunk
Files:
23 modified

Legend:

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

    r381 r382  
    104104    ModelT::TraceResultT Result; 
    105105 
    106     if (m_Parent->GetModelDoc()->GetModel()->TraceRay(AnimSel.Size()==0 ? -1 : AnimSel[0], Anim.FrameNr, RayOrigin, RayDir, Result) && Result.Fraction<BestFraction) 
     106    if (m_Parent->GetModelDoc()->GetModel()->TraceRay(AnimSel.Size()==0 ? -1 : AnimSel[0], Anim.FrameNr, -1 /*SkinNr*/, RayOrigin, RayDir, Result) && Result.Fraction<BestFraction) 
    107107    { 
    108108        BestFraction=Result.Fraction; 
     
    388388    if (ScenePropGrid->m_Model_ShowMesh) 
    389389    { 
    390         Model->Draw(SequNr, Anim.FrameNr, 0.0f /*LodDist*/, (CafuModelT::SuperT*)NULL); 
     390        Model->Draw(SequNr, Anim.FrameNr, -1 /*SkinNr*/, 0.0f /*LodDist*/, (CafuModelT::SuperT*)NULL); 
    391391 
    392392        for (unsigned long SmNr=0; SmNr<ModelDoc->GetSubmodels().Size(); SmNr++) 
     
    397397                SM->GetJointsMap()); 
    398398 
    399             SM->GetSubmodel()->Draw(0, 0.0f, 0.0f /*LodDist*/, &Super); 
     399            SM->GetSubmodel()->Draw(0, 0.0f, -1 /*SkinNr*/, 0.0f /*LodDist*/, &Super); 
    400400        } 
    401401    } 
  • cafu/trunk/Libs/Models/Loader.hpp

    r358 r382  
    5858    /// Actually loads the file data into the appropriate parts of the Cafu model. 
    5959    virtual void Load(ArrayT<CafuModelT::JointT>& Joints, ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<CafuModelT::AnimT>& Anims, MaterialManagerImplT& MaterialMan)=0; 
     60 
     61    /// Loads the skins of the Cafu model. 
     62    virtual void Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan)=0; 
    6063 
    6164    /// Loads the GUI fixtures of the Cafu model. 
  • cafu/trunk/Libs/Models/Loader_ase.hpp

    r334 r382  
    4141    bool UseGivenTS() const { return true; } 
    4242    void Load(ArrayT<CafuModelT::JointT>& Joints, ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<CafuModelT::AnimT>& Anims, MaterialManagerImplT& MaterialMan); 
     43    void Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan) { } 
    4344    void Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs); 
    4445 
  • cafu/trunk/Libs/Models/Loader_assimp.hpp

    r334 r382  
    4545    bool UseGivenTS() const; 
    4646    void Load(ArrayT<CafuModelT::JointT>& Joints, ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<CafuModelT::AnimT>& Anims, MaterialManagerImplT& MaterialMan); 
     47    void Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan) { } 
    4748    void Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs) { } 
    4849 
  • cafu/trunk/Libs/Models/Loader_cmdl.cpp

    r350 r382  
    393393 
    394394 
     395void LoaderCafuT::Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan) 
     396{ 
     397    // Read the skins. 
     398    lua_getglobal(m_LuaState, "Skins"); 
     399    { 
     400        Skins.Overwrite(); 
     401        Skins.PushBackEmptyExact(lua_objlen_ul(m_LuaState, -1)); 
     402 
     403        for (unsigned long SkinNr=0; SkinNr<Skins.Size(); SkinNr++) 
     404        { 
     405            CafuModelT::SkinT& Skin=Skins[SkinNr]; 
     406 
     407            lua_rawgeti(m_LuaState, -1, SkinNr+1); 
     408            { 
     409                lua_getfield(m_LuaState, -1, "name"); 
     410                { 
     411                    const char* Name=lua_tostring(m_LuaState, -1); 
     412                    Skin.Name=Name ? Name : "Skin"; 
     413                } 
     414                lua_pop(m_LuaState, 1); 
     415 
     416                lua_getfield(m_LuaState, -1, "materials"); 
     417                { 
     418                    const unsigned long NumMats=lua_objlen_ul(m_LuaState, -1); 
     419 
     420                    Skin.Materials.PushBackEmptyExact(NumMats); 
     421                    Skin.RenderMaterials.PushBackEmptyExact(NumMats); 
     422 
     423                    for (unsigned int c=0; c<NumMats; c++) 
     424                    { 
     425                        lua_rawgeti(m_LuaState, -1, c+1); 
     426                        { 
     427                            const char*       s=lua_tostring(m_LuaState, -1); 
     428                            const std::string MatName=s ? s : ""; 
     429 
     430                            Skin.Materials[c]      =(s!="") ? MaterialMan.GetMaterial(MatName) : NULL; 
     431                            Skin.RenderMaterials[c]=NULL; 
     432                        } 
     433                        lua_pop(m_LuaState, 1); 
     434                    } 
     435                } 
     436                lua_pop(m_LuaState, 1); 
     437            } 
     438            lua_pop(m_LuaState, 1); 
     439        } 
     440    } 
     441    lua_pop(m_LuaState, 1); 
     442} 
     443 
     444 
    395445void LoaderCafuT::Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs) 
    396446{ 
  • cafu/trunk/Libs/Models/Loader_cmdl.hpp

    r349 r382  
    4444    bool UseGivenTS() const; 
    4545    void Load(ArrayT<CafuModelT::JointT>& Joints, ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<CafuModelT::AnimT>& Anims, MaterialManagerImplT& MaterialMan); 
     46    void Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan); 
    4647    void Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs); 
    4748 
  • cafu/trunk/Libs/Models/Loader_fbx.cpp

    r358 r382  
    831831 
    832832 
     833void LoaderFbxT::Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan) 
     834{ 
     835    // TODO... 
     836} 
     837 
     838 
    833839void LoaderFbxT::Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs) 
    834840{ 
  • cafu/trunk/Libs/Models/Loader_fbx.hpp

    r334 r382  
    4242    bool UseGivenTS() const; 
    4343    void Load(ArrayT<CafuModelT::JointT>& Joints, ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<CafuModelT::AnimT>& Anims, MaterialManagerImplT& MaterialMan); 
     44    void Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan); 
    4445    void Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs); 
    4546 
  • cafu/trunk/Libs/Models/Loader_lwo.hpp

    r334 r382  
    3838    bool UseGivenTS() const { return true; } 
    3939    void Load(ArrayT<CafuModelT::JointT>& Joints, ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<CafuModelT::AnimT>& Anims, MaterialManagerImplT& MaterialMan); 
     40    void Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan) { } 
    4041    void Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs) { } 
    4142 
  • cafu/trunk/Libs/Models/Loader_md5.hpp

    r334 r382  
    4040    bool UseGivenTS() const; 
    4141    void Load(ArrayT<CafuModelT::JointT>& Joints, ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<CafuModelT::AnimT>& Anims, MaterialManagerImplT& MaterialMan); 
     42    void Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan) { } 
    4243    void Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs) { } 
    4344}; 
  • cafu/trunk/Libs/Models/Loader_mdl.cpp

    r352 r382  
    202202    // For clarity and better readibility, break the loading into three separate functions. 
    203203    Load(Joints); 
    204     Load(Meshes); 
     204    Load(Meshes, m_MeshSkinRef); 
    205205    Load(Anims); 
    206206} 
     
    234234 
    235235 
    236 void LoaderHL1mdlT::Load(ArrayT<CafuModelT::MeshT>& Meshes) const 
     236void LoaderHL1mdlT::Load(ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<int>& MeshSkinRef) const 
    237237{ 
    238238    // This is configurable with BodyNr and SkinNr, but at this time we always take the defaults (index 0 each). 
     
    292292                    Weight.Pos     =Vector3fT(StudioVertices[VertexNr]); 
    293293                } 
     294 
     295                MeshSkinRef.PushBack(StudioMesh.SkinRef); 
    294296            } 
    295297 
     
    524526    // TODO: Sequ.LinearMovement ? 
    525527} 
     528 
     529 
     530void LoaderHL1mdlT::Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan) 
     531{ 
     532    const short* SkinRefs0=(short*)((char*)StudioTextureHeader+StudioTextureHeader->SkinIndex); 
     533 
     534    if (StudioTextureHeader->NumSkinFamilies <= 1) return; 
     535    Skins.PushBackEmptyExact(StudioTextureHeader->NumSkinFamilies - 1); 
     536 
     537    // Start with SkinNr=1, because the materials of the first (default) skin are kept directly in the mesh definitions. 
     538    for (int SkinNr=1; SkinNr<StudioTextureHeader->NumSkinFamilies; SkinNr++) 
     539    { 
     540        const short*       SkinRefs=((short*)((char*)StudioTextureHeader+StudioTextureHeader->SkinIndex)) + SkinNr*StudioTextureHeader->NumSkinRef; 
     541        CafuModelT::SkinT& Skin    =Skins[SkinNr-1]; 
     542 
     543        for (unsigned long MeshNr=0; MeshNr<m_MeshSkinRef.Size(); MeshNr++) 
     544        { 
     545            const int msr=m_MeshSkinRef[MeshNr]; 
     546 
     547            Skin.Materials.PushBack(SkinRefs0[msr]==SkinRefs[msr] ? NULL : m_Materials[SkinRefs[msr]]); 
     548            Skin.RenderMaterials.PushBack(NULL); 
     549        } 
     550    } 
     551} 
  • cafu/trunk/Libs/Models/Loader_mdl.hpp

    r334 r382  
    4646    bool UseGivenTS() const; 
    4747    void Load(ArrayT<CafuModelT::JointT>& Joints, ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<CafuModelT::AnimT>& Anims, MaterialManagerImplT& MaterialMan); 
     48    void Load(ArrayT<CafuModelT::SkinT>& Skins, const MaterialManagerImplT& MaterialMan); 
    4849    void Load(ArrayT<CafuModelT::GuiFixtureT>& GuiFixtures, ArrayT<CafuModelT::GuiLocT>& GuiLocs) { } 
    4950 
     
    5253 
    5354    void Load(ArrayT<CafuModelT::JointT>& Joints) const; 
    54     void Load(ArrayT<CafuModelT::MeshT>& Meshes) const; 
     55    void Load(ArrayT<CafuModelT::MeshT>& Meshes, ArrayT<int>& MeshSkinRef) const; 
    5556    void Load(ArrayT<CafuModelT::AnimT>& Anims) const; 
    5657 
     
    5960    ArrayT< ArrayT<char> > AnimationData;   ///< Animation data ("demand loaded sequences"). 
    6061    ArrayT<MaterialT*>     m_Materials;     ///< The MatSys materials used in the model. 
     62    ArrayT<int>            m_MeshSkinRef;   ///< For each mesh, the original StudioMeshT::SkinRef number. 
    6163 
    6264    // Convenient abbreviations into the above data arrays. 
  • cafu/trunk/Libs/Models/Model.hpp

    r343 r382  
    4444        TraceResultT(float Fraction_=0.0f) : Fraction(Fraction_), Material(NULL), MeshNr(-1), TriNr(-1) { } 
    4545 
    46         float        Fraction;  ///< The scalar along RayDir at which the hit occurred (RayOrigin + RayDir*Fraction). 
    47         Vector3fT    Normal;    ///< This is the normal vector of the hit surface. 
    48         MaterialT*  Material;  ///< The material at the point of impact. Can be NULL, e.g. when an edge (i.e. a bevel plane) was hit or the material is not available. 
    49         unsigned int MeshNr;    ///< The number of the hit mesh. Can be -1 (that is, \emph{larger} then the number of meshes in the model) if the hit mesh cannot be determined. 
    50         unsigned int TriNr;     ///< The number of the hit triangle in the hit mesh. Can be -1 (that is, \emph{larger} then the number of triangles in the mesh) if the hit triangle cannot be determined. 
     46        float            Fraction;  ///< The scalar along RayDir at which the hit occurred (RayOrigin + RayDir*Fraction). 
     47        Vector3fT        Normal;    ///< This is the normal vector of the hit surface. 
     48        const MaterialT* Material;  ///< The material at the point of impact. Can be NULL, e.g. when an edge (i.e. a bevel plane) was hit or the material is not available. 
     49        unsigned int     MeshNr;    ///< The number of the hit mesh. Can be -1 (that is, \emph{larger} then the number of meshes in the model) if the hit mesh cannot be determined. 
     50        unsigned int     TriNr;     ///< The number of the hit triangle in the hit mesh. Can be -1 (that is, \emph{larger} then the number of triangles in the mesh) if the hit triangle cannot be determined. 
    5151    }; 
    5252 
     
    9898    /// @param SequenceNr  The animation sequence at which the ray should be traced. 
    9999    /// @param FrameNr     The animation frame at which the ray should be traced. 
     100    /// @param SkinNr      The skin to use for the trace, use -1 for the default skin. 
    100101    /// @param RayOrigin   The point in model space where the ray starts. 
    101102    /// @param RayDir      A unit vector in model space that describes the direction the ray extends to. 
     
    103104    /// 
    104105    /// @returns true if the ray hit the model, false otherwise. When the model was hit, additional details are returned via the Result parameter. 
    105     virtual bool TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const=0; 
     106    virtual bool TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const=0; 
    106107 
    107108    // Returns the number of frames of sequence SequenceNr. Useful for non-repeating (e.g. death) sequences. 
  • cafu/trunk/Libs/Models/Model_cmdl.cpp

    r358 r382  
    232232    // Have the model loader load the model file. 
    233233    Loader.Load(m_Joints, m_Meshes, m_Anims, m_MaterialMan); 
     234    Loader.Load(m_Skins, m_MaterialMan); 
    234235    Loader.Load(m_GuiFixtures, m_GuiLocs); 
    235236    Loader.Postprocess(m_Meshes); 
     
    240241    InitMeshes(); 
    241242 
    242     // Allocate the render materials. 
     243    // Allocate the render materials for the meshes (the default skin). 
    243244    for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    244245    { 
     
    247248        assert(Mesh.RenderMaterial==NULL); 
    248249        Mesh.RenderMaterial=MatSys::Renderer!=NULL ? MatSys::Renderer->RegisterMaterial(Mesh.Material) : NULL; 
     250    } 
     251 
     252    // Allocate the render materials for the skins. 
     253    for (unsigned long SkinNr=0; SkinNr<m_Skins.Size(); SkinNr++) 
     254    { 
     255        SkinT& Skin=m_Skins[SkinNr]; 
     256 
     257        assert(Skin.Materials.Size()==m_Meshes.Size()); 
     258        assert(Skin.Materials.Size()==Skin.RenderMaterials.Size()); 
     259 
     260        for (unsigned long MatNr=0; MatNr<Skin.Materials.Size(); MatNr++) 
     261        { 
     262            assert(Skin.RenderMaterials[MatNr]==NULL); 
     263 
     264            if (Skin.Materials[MatNr]!=NULL && MatSys::Renderer!=NULL) 
     265                Skin.RenderMaterials[MatNr]=MatSys::Renderer->RegisterMaterial(Skin.Materials[MatNr]); 
     266        } 
    249267    } 
    250268 
     
    266284    if (MatSys::Renderer==NULL) return; 
    267285 
     286    // Free all render materials used in skins. 
     287    for (unsigned long SkinNr=0; SkinNr<m_Skins.Size(); SkinNr++) 
     288        for (unsigned long MatNr=0; MatNr<m_Skins[SkinNr].RenderMaterials.Size(); MatNr++) 
     289            MatSys::Renderer->FreeMaterial(m_Skins[SkinNr].RenderMaterials[MatNr]); 
     290 
     291    // Free all render materials used in the meshes (the default skin). 
    268292    for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    269293        MatSys::Renderer->FreeMaterial(m_Meshes[MeshNr].RenderMaterial); 
     
    756780 
    757781 
     782    // *** Write the skins. *** 
     783    OutStream << "\nSkins=\n{\n"; 
     784 
     785    for (unsigned long SkinNr=0; SkinNr<m_Skins.Size(); SkinNr++) 
     786    { 
     787        const SkinT& Skin=m_Skins[SkinNr]; 
     788 
     789        OutStream << "\t{\n" 
     790                  << "\t\tname=\"" << Skin.Name << "\";\n" 
     791                  << "\t\tmaterials={ "; 
     792 
     793        for (unsigned long MatNr=0; MatNr<Skin.Materials.Size(); MatNr++) 
     794        { 
     795            OutStream << "\""; 
     796            if (Skin.Materials[MatNr]!=NULL) OutStream << Skin.Materials[MatNr]->Name; 
     797            OutStream << "\""; 
     798            if (MatNr+1 < Skin.Materials.Size()) OutStream << ", "; 
     799        } 
     800 
     801        OutStream << " };\n" 
     802                  << "\t},\n"; 
     803    } 
     804 
     805    OutStream << "}\n"; 
     806 
     807 
    758808    // *** Write the GUI fixtures. *** 
    759809    OutStream << "\nGuiFixtures=\n{\n"; 
     
    10941144 
    10951145 
    1096 void CafuModelT::Draw(int SequenceNr, float FrameNr, float /*LodDist*/, const SuperT* Super) const 
     1146const MaterialT* CafuModelT::GetMaterial(unsigned long MeshNr, int SkinNr) const 
     1147{ 
     1148    assert(MeshNr<m_Meshes.Size()); 
     1149 
     1150    if (SkinNr<0 || SkinNr>=int(m_Skins.Size())) 
     1151        return m_Meshes[MeshNr].Material; 
     1152 
     1153    if (MeshNr>=m_Skins[SkinNr].Materials.Size()) 
     1154        return m_Meshes[MeshNr].Material; 
     1155 
     1156    if (!m_Skins[SkinNr].Materials[MeshNr]) 
     1157        return m_Meshes[MeshNr].Material; 
     1158 
     1159    return m_Skins[SkinNr].Materials[MeshNr]; 
     1160} 
     1161 
     1162 
     1163MatSys::RenderMaterialT* CafuModelT::GetRenderMaterial(unsigned long MeshNr, int SkinNr) const 
     1164{ 
     1165    assert(MeshNr<m_Meshes.Size()); 
     1166 
     1167    if (SkinNr<0 || SkinNr>=int(m_Skins.Size())) 
     1168        return m_Meshes[MeshNr].RenderMaterial; 
     1169 
     1170    if (MeshNr>=m_Skins[SkinNr].RenderMaterials.Size()) 
     1171        return m_Meshes[MeshNr].RenderMaterial; 
     1172 
     1173    if (!m_Skins[SkinNr].RenderMaterials[MeshNr]) 
     1174        return m_Meshes[MeshNr].RenderMaterial; 
     1175 
     1176    return m_Skins[SkinNr].RenderMaterials[MeshNr]; 
     1177} 
     1178 
     1179 
     1180void CafuModelT::Draw(int SequenceNr, float FrameNr, int SkinNr, float /*LodDist*/, const SuperT* Super) const 
    10971181{ 
    10981182    // SequenceNr==-1 means "use the bind pose from the model file only (no anim)". 
     
    11721256            for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    11731257            { 
    1174                 MatSys::Renderer->SetCurrentMaterial(m_Meshes[MeshNr].RenderMaterial); 
     1258                MatSys::Renderer->SetCurrentMaterial(GetRenderMaterial(MeshNr, SkinNr)); 
    11751259                MatSys::Renderer->RenderMesh(m_Draw_Meshes[MeshNr]); 
    11761260 
     
    12311315            for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    12321316            { 
    1233                 MatSys::Renderer->SetCurrentMaterial(m_Meshes[MeshNr].RenderMaterial); 
     1317                MatSys::Renderer->SetCurrentMaterial(GetRenderMaterial(MeshNr, SkinNr)); 
    12341318                MatSys::Renderer->RenderMesh(m_Draw_Meshes[MeshNr]); 
    12351319            } 
     
    12431327            for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    12441328            { 
    1245                 const MeshT& Mesh=m_Meshes[MeshNr]; 
    1246  
    1247                 if (Mesh.Material==NULL || Mesh.Material->NoShadows) continue; 
     1329                const MeshT&     Mesh   =m_Meshes[MeshNr]; 
     1330                const MaterialT* MeshMat=GetMaterial(MeshNr, SkinNr); 
     1331 
     1332                if (MeshMat==NULL || MeshMat->NoShadows) continue; 
    12481333 
    12491334                static ArrayT<bool> TriangleIsFrontFacing; 
     
    13431428void CafuModelT::Draw(int SequenceNr, float FrameNr, float LodDist, const ModelT* /*SubModel*/) const 
    13441429{ 
    1345     Draw(SequenceNr, FrameNr, LodDist, (SuperT*)NULL); 
     1430    Draw(SequenceNr, FrameNr, -1 /*default skin*/, LodDist, (SuperT*)NULL); 
    13461431} 
    13471432 
     
    14181503 
    14191504 
    1420 bool CafuModelT::TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
     1505bool CafuModelT::TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
    14211506{ 
    14221507    float Fraction=0.0f; 
     
    14301515    for (unsigned long MeshNr=0; MeshNr<m_Meshes.Size(); MeshNr++) 
    14311516    { 
    1432         const MeshT& Mesh=m_Meshes[MeshNr]; 
     1517        const MeshT&     Mesh   =m_Meshes[MeshNr]; 
     1518        const MaterialT* MeshMat=GetMaterial(MeshNr, SkinNr); 
    14331519 
    14341520        // If the ClipFlags don't match the ClipMask, this polygon doesn't interfere with the trace. 
    1435         if (!Mesh.Material) continue; 
    1436         // if ((Mesh.Material->ClipFlags & ClipMask)==0) continue; 
     1521        if (!MeshMat) continue; 
     1522        // if ((MeshMat->ClipFlags & ClipMask)==0) continue; 
    14371523 
    14381524        for (unsigned long TriNr=0; TriNr<Mesh.Triangles.Size(); TriNr++) 
     
    14521538            // Note that Christer Ericson has shown in his blog at http://realtimecollisiondetection.net/blog/?p=13 
    14531539            // that scalar triple products (Spatprodukte) are equivalent and could be used as well.  ;-) 
    1454             if (!Mesh.Material->TwoSided) 
     1540            if (!MeshMat->TwoSided) 
    14551541            { 
    14561542                if (R*PlueckerfT::CreateFromLine(A, B) >= 0) continue; 
     
    14741560 
    14751561            if (Nenner==0) continue;                            // If Nenner==0, then RayDir is parallel to the triangle plane (no intersection). 
    1476             assert(Mesh.Material->TwoSided || Nenner<0);        // If material is single sided, then Nenner<0, a consequence of the Pluecker tests above. 
     1562            assert(MeshMat->TwoSided || Nenner<0);              // If the material is single sided, then Nenner<0, a consequence of the Pluecker tests above. 
    14771563 
    14781564            const float Dist=dot(Tri.Draw_Normal, RayOrigin-A); // The distance of RayOrigin to the triangle plane. 
     
    14851571            Result.Fraction=F; 
    14861572            Result.Normal  =(Nenner<0) ? Tri.Draw_Normal : -Tri.Draw_Normal;    // Handle two-sided materials properly. 
    1487             Result.Material=Mesh.Material; 
     1573            Result.Material=MeshMat; 
    14881574            Result.MeshNr  =MeshNr; 
    14891575            Result.TriNr   =TriNr; 
  • cafu/trunk/Libs/Models/Model_cmdl.hpp

    r358 r382  
    166166 
    167167 
     168    /// This struct describes additional/alternative skins for this model. 
     169    struct SkinT 
     170    { 
     171        std::string                      Name;              ///< The name of this skin. 
     172        ArrayT<MaterialT*>               Materials;         ///< For each mesh \c m, <tt>Materials[m]</tt> is the material for the mesh in this skin. If <tt>Materials[m]</tt> is NULL, the material of the default skin is used. 
     173        ArrayT<MatSys::RenderMaterialT*> RenderMaterials;   ///< Analogous to \c Materials, these are the (possibly NULL) render materials for the meshes in this skin. 
     174    }; 
     175 
     176 
    168177    /// This struct defines how and where a GUI can be fixed to the model. 
    169178    /// The GUI rectangle is defined by three points: the origin, the x-axis endpoint, and the y-axis endpoint, numbered 0, 1 and 2. 
     
    239248    const ArrayT<MeshT>&        GetMeshes() const { return m_Meshes; } 
    240249    const ArrayT<AnimT>&        GetAnims() const { return m_Anims; } 
     250    const ArrayT<SkinT>&        GetSkins() const { return m_Skins; } 
    241251    const ArrayT<GuiFixtureT>&  GetGuiFixtures() const { return m_GuiFixtures; } 
    242252 
     
    247257    /// @param SequenceNr   The number of the animation sequence to use, -1 for the bind pose. 
    248258    /// @param FrameNr      The frame number in the animation sequence to render to model at. 
     259    /// @param SkinNr       The skin to render the model with, -1 for the default skin. 
    249260    /// @param LodDist      The distance to the camera for reducing the level-of-detail (currently unused). 
    250261    /// @param Super        Information about a parent or "super" model whose skeleton pose should be used when rendering this model. 
    251     void Draw(int SequenceNr, float FrameNr, float LodDist, const SuperT* Super=NULL) const; 
     262    void Draw(int SequenceNr, float FrameNr, int SkinNr, float LodDist, const SuperT* Super=NULL) const; 
    252263 
    253264    /// Determines if <tt>GF.Points[PointNr].MeshNr</tt> is a valid index into this model. 
     
    264275    unsigned int       GetNrOfSequences() const; 
    265276    BoundingBox3fT     GetBB(int SequenceNr, float FrameNr) const; 
    266     bool               TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
     277    bool               TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
    267278 // float              GetNrOfFrames(int SequenceNr) const; 
    268279    float              AdvanceFrameNr(int SequenceNr, float FrameNr, float DeltaTime, bool Loop=true) const; 
     
    286297    void InitMeshes();                                                                      ///< An auxiliary method for the constructors. 
    287298    void UpdateCachedDrawData(int SequenceNr, float FrameNr, const SuperT* Super) const;    ///< A private auxiliary method. 
     299    const MaterialT* GetMaterial(unsigned long MeshNr, int SkinNr) const;                   ///< Returns the proper material for the given mesh in the given skin. 
     300    MatSys::RenderMaterialT* GetRenderMaterial(unsigned long MeshNr, int SkinNr) const;     ///< Returns the proper render material for the given mesh in the given skin. 
    288301 
    289302 
     
    293306    mutable ArrayT<MeshT> m_Meshes;                 ///< Array of (sub)meshes of this model. 
    294307    ArrayT<AnimT>         m_Anims;                  ///< Array of animations of this model. 
     308    ArrayT<SkinT>         m_Skins;                  ///< Array of additional/alternative skins for this model. 
    295309 
    296310    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). 
  • cafu/trunk/Libs/Models/Model_dlod.cpp

    r318 r382  
    118118 
    119119 
    120 bool ModelDlodT::TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
     120bool ModelDlodT::TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
    121121{ 
    122122    // for (unsigned long LodModelNr=0; LodModelNr<LodModels.Size(); LodModelNr++) 
    123123    //     if (LodDist>=LodStartRanges[LodModelNr] && LodDist<LodEndRanges[LodModelNr]) 
    124     //         return LodModels[LodModelNr].TraceRay(SequenceNr, FrameNr, RayOrigin, RayDir, Result); 
     124    //         return LodModels[LodModelNr].TraceRay(SequenceNr, FrameNr, SkinNr, RayOrigin, RayDir, Result); 
    125125    // 
    126126    // return false; 
    127     return LodModels[0].TraceRay(SequenceNr, FrameNr, RayOrigin, RayDir, Result); 
     127    return LodModels[0].TraceRay(SequenceNr, FrameNr, SkinNr, RayOrigin, RayDir, Result); 
    128128} 
    129129 
  • cafu/trunk/Libs/Models/Model_dlod.hpp

    r318 r382  
    4747    unsigned int       GetNrOfSequences() const; 
    4848    BoundingBox3fT     GetBB(int SequenceNr, float FrameNr) const; 
    49     bool               TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
     49    bool               TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
    5050 // float              GetNrOfFrames(int SequenceNr) const; 
    5151    float              AdvanceFrameNr(int SequenceNr, float FrameNr, float DeltaTime, bool Loop=true) const; 
  • cafu/trunk/Libs/Models/Model_dummy.cpp

    r343 r382  
    7373 
    7474 
    75 bool ModelDummyT::TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
     75bool ModelDummyT::TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
    7676{ 
    7777    float Fraction=0.0f; 
  • cafu/trunk/Libs/Models/Model_dummy.hpp

    r318 r382  
    4545    unsigned int       GetNrOfSequences() const; 
    4646    BoundingBox3fT     GetBB(int SequenceNr, float FrameNr) const; 
    47     bool               TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
     47    bool               TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
    4848 // float              GetNrOfFrames(int SequenceNr) const; 
    4949    float              AdvanceFrameNr(int SequenceNr, float FrameNr, float DeltaTime, bool Loop=true) const; 
  • cafu/trunk/Libs/Models/Model_mdl.cpp

    r318 r382  
    15751575 
    15761576 
    1577 bool ModelMdlT::TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
     1577bool ModelMdlT::TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
    15781578{ 
    15791579    return false; 
  • cafu/trunk/Libs/Models/Model_mdl.hpp

    r318 r382  
    125125    unsigned int       GetNrOfSequences() const; 
    126126    BoundingBox3fT     GetBB(int SequenceNr, float FrameNr) const; 
    127     bool               TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
     127    bool               TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
    128128 // float              GetNrOfFrames(int SequenceNr) const; 
    129129    float              AdvanceFrameNr(int SequenceNr, float FrameNr, float DeltaTime, bool Loop=true) const; 
  • cafu/trunk/Libs/Models/Model_proxy.cpp

    r318 r382  
    242242 
    243243 
    244 bool ModelProxyT::TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
    245 { 
    246     return ModelPool[PoolIndex]->TraceRay(SequenceNr, FrameNr, RayOrigin, RayDir, Result); 
     244bool ModelProxyT::TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const 
     245{ 
     246    return ModelPool[PoolIndex]->TraceRay(SequenceNr, FrameNr, SkinNr, RayOrigin, RayDir, Result); 
    247247} 
    248248 
  • cafu/trunk/Libs/Models/Model_proxy.hpp

    r318 r382  
    6161    unsigned int       GetNrOfSequences() const; 
    6262    BoundingBox3fT     GetBB(int SequenceNr, float FrameNr) const; 
    63     bool               TraceRay(int SequenceNr, float FrameNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
     63    bool               TraceRay(int SequenceNr, float FrameNr, int SkinNr, const Vector3fT& RayOrigin, const Vector3fT& RayDir, TraceResultT& Result) const; 
    6464 // float              GetNrOfFrames(int SequenceNr) const; 
    6565    float              AdvanceFrameNr(int SequenceNr, float FrameNr, float DeltaTime, bool Loop=true) const;