mesh_base.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright, 2001 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #include "std3d.h"
00025 
00026 #include "nel/3d/mesh_base.h"
00027 #include "nel/3d/mesh_base_instance.h"
00028 #include "nel/3d/lod_character_texture.h"
00029 #include "nel/3d/visual_collision_mesh.h"
00030 
00031 
00032 using namespace std;
00033 using namespace NLMISC;
00034 
00035 
00036 namespace NL3D
00037 {
00038 
00039 
00040 
00041 // ***************************************************************************
00042 CMeshBase::CMeshBase()
00043 {
00044     /* ***********************************************
00045      *  WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
00046      *  It can be loaded/called through CAsyncFileManager for instance
00047      * ***********************************************/
00048 
00049     _UseLightingLocalAttenuation= false;
00050 
00051     // To have same functionnality than previous version, init to identity.
00052     _DefaultPos.setDefaultValue(CVector(0,0,0));
00053     _DefaultPivot.setDefaultValue(CVector(0,0,0));
00054     _DefaultRotEuler.setDefaultValue(CVector(0,0,0));
00055     _DefaultRotQuat.setDefaultValue(CQuat::Identity);
00056     _DefaultScale.setDefaultValue(CVector(1,1,1));
00057     _DefaultLMFactor.setDefaultValue(CRGBA(255,255,255,255));
00058 
00059     _AutoAnim = false;
00060 
00061     _LodCharacterTexture= NULL;
00062 
00063     _CollisionMeshGeneration= AutoCameraCol;
00064 
00065     _VisualCollisionMesh= NULL;
00066 
00067     _DefaultOpacity= false;
00068     _DefaultTransparency= false;
00069 }
00070 
00071 
00072 // ***************************************************************************
00073 CMeshBase::~CMeshBase()
00074 {
00075     /* ***********************************************
00076      *  WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
00077      *  It can be loaded/called through CAsyncFileManager for instance
00078      * ***********************************************/
00079 
00080     // free if exist
00081     resetLodCharacterTexture();
00082     // delete the Col mesh if created
00083     if(_VisualCollisionMesh)
00084     {
00085         delete _VisualCollisionMesh;
00086         _VisualCollisionMesh= NULL;
00087     }
00088 }
00089 
00090 
00091 // ***************************************************************************
00092 // ***************************************************************************
00093 // Animated material.
00094 // ***************************************************************************
00095 // ***************************************************************************
00096 
00097 
00098 // ***************************************************************************
00099 void            CMeshBase::setAnimatedMaterial(uint id, const std::string &matName)
00100 {
00101     nlassert(!matName.empty());
00102     if(id<_Materials.size())
00103     {
00104         // add / replace animated material.
00105         _AnimatedMaterials[id].Name= matName;
00106         // copy Material default.
00107         _AnimatedMaterials[id].copyFromMaterial(&_Materials[id]);
00108     }
00109 }
00110 
00111 // ***************************************************************************
00112 CMaterialBase   *CMeshBase::getAnimatedMaterial(uint id)
00113 {
00114     TAnimatedMaterialMap::iterator  it;
00115     it= _AnimatedMaterials.find(id);
00116     if(it!=_AnimatedMaterials.end())
00117         return &it->second;
00118     else
00119         return NULL;
00120 }
00121 
00122 
00123 // ***************************************************************************
00124 // ***************************************************************************
00125 // Serial - buildBase.
00126 // ***************************************************************************
00127 // ***************************************************************************
00128 
00129 
00130 // ***************************************************************************
00131 CMeshBase::CMeshBaseBuild::CMeshBaseBuild()
00132 {
00133     DefaultPos.set(0,0,0);
00134     DefaultPivot.set(0,0,0);
00135     DefaultRotEuler.set(0,0,0);
00136     DefaultScale.set(1,1,1);
00137 
00138     bCastShadows= false;
00139     bRcvShadows= false;
00140     UseLightingLocalAttenuation= false;
00141     CollisionMeshGeneration= CMeshBase::AutoCameraCol;
00142 }
00143 
00144 // ***************************************************************************
00145 #if 0
00146 void    CMeshBase::CMeshBaseBuild::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00147 {
00148     /*
00149     Version 1:
00150         - Cut in version because of badly coded ITexture* serialisation. throw an exception if
00151             find a version < 1.
00152     Version 0:
00153         - 1st version.
00154     */
00155     sint    ver= f.serialVersion(1);
00156 
00157     if(ver<1)
00158         throw NLMISC::EStream(f, "MeshBuild in Stream is too old (MeshBaseBuild version < 1)");
00159 
00160     f.serial( DefaultPos );
00161     f.serial( DefaultPivot );
00162     f.serial( DefaultRotEuler );
00163     f.serial( DefaultRotQuat );
00164     f.serial( DefaultScale );
00165 
00166     f.serialCont( Materials );
00167 }
00168 #endif
00169 
00170 // ***************************************************************************
00171 void    CMeshBase::serialMeshBase(NLMISC::IStream &f) throw(NLMISC::EStream)
00172 {
00173     /* ***********************************************
00174      *  WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
00175      *  It can be loaded/called through CAsyncFileManager for instance
00176      * ***********************************************/
00177 
00178     /*
00179     Version 9:
00180         - _CollisionMeshGeneration
00181     Version 8:
00182         - new format for CLightMapInfoList
00183     Version 7:
00184         - _LodCharacterTexture
00185     Version 6:
00186         - _DistMax
00187     Version 5:
00188         - _AutoAnim
00189     Version 4:
00190         - _UseLightingLocalAttenuation
00191     Version 3:
00192         - _IsLightable
00193     Version 2:
00194         - Added Blend Shapes factors
00195     Version 1:
00196         - Cut in version because of badly coded ITexture* serialisation. throw an exception if
00197             find a version < 1.
00198     Version 0:
00199         - 1st version.
00200     */
00201     sint ver = f.serialVersion(9);
00202 
00203     if (ver >= 2)
00204     {
00205         f.serialCont (_AnimatedMorph);
00206     }
00207 
00208     if(ver<1)
00209         throw NLMISC::EStream(f, "Mesh in Stream is too old (MeshBase version < 1)");
00210 
00211     f.serial (_DefaultPos);
00212     f.serial (_DefaultPivot);
00213     f.serial (_DefaultRotEuler);
00214     f.serial (_DefaultRotQuat);
00215     f.serial (_DefaultScale);
00216 
00217     f.serialCont(_Materials);
00218     f.serialCont(_AnimatedMaterials);
00219 
00220     if(ver >= 8)
00221         f.serialCont(_LightInfos);
00222     else
00223     {
00224         TLightInfoMapV7 temp;
00225         f.serialCont(temp);
00226     }
00227 
00228     if(ver>=3)
00229         // read/write _IsLightable flag.
00230         f.serial(_IsLightable);
00231     else if( f.isReading() )
00232         // update _IsLightable flag.
00233         computeIsLightable();
00234 
00235     if(ver>=4)
00236         f.serial(_UseLightingLocalAttenuation);
00237     else if( f.isReading() )
00238         _UseLightingLocalAttenuation= false;
00239 
00240     if (ver >= 5)
00241     {
00242         f.serial(_AutoAnim);
00243     }
00244 
00245     if(ver >= 6)
00246         f.serial(_DistMax);
00247 
00248     if(ver >= 7)
00249         f.serialPtr(_LodCharacterTexture);
00250 
00251     if(ver >= 9)
00252         f.serialEnum(_CollisionMeshGeneration);
00253     else
00254         _CollisionMeshGeneration= AutoCameraCol;
00255 
00256     // Some runtime not serialized compilation
00257     if(f.isReading())
00258         compileRunTime();
00259 }
00260 
00261 
00262 // ***************************************************************************
00263 void    CMeshBase::buildMeshBase(CMeshBaseBuild &m)
00264 {
00265     // Copy light information
00266     _LightInfos = m.LightInfoMap;
00267 
00268     // copy the materials.
00269     _Materials= m.Materials;
00270 
00271     // clear the animated materials.
00272     _AnimatedMaterials.clear();
00273 
00275     _DefaultPos.setDefaultValue (m.DefaultPos);
00276     _DefaultPivot.setDefaultValue (m.DefaultPivot);
00277     _DefaultRotEuler.setDefaultValue (m.DefaultRotEuler);
00278     _DefaultRotQuat.setDefaultValue (m.DefaultRotQuat);
00279     _DefaultScale.setDefaultValue (m.DefaultScale);
00280 
00281     _AnimatedMorph  .resize(m.DefaultBSFactors.size());
00282     for (uint32 i = 0; i < m.DefaultBSFactors.size(); ++i)
00283     {
00284         _AnimatedMorph[i].DefaultFactor.setDefaultValue (m.DefaultBSFactors[i]);
00285         _AnimatedMorph[i].Name = m.BSNames[i];
00286     }
00287 
00288     // update _IsLightable flag.
00289     computeIsLightable();
00290     // copy _UseLightingLocalAttenuation
00291     _UseLightingLocalAttenuation= m.UseLightingLocalAttenuation;
00292 
00293     // copy CollisionMeshGeneration
00294     _CollisionMeshGeneration= m.CollisionMeshGeneration;
00295 
00296     // Some runtime not serialized compilation
00297     compileRunTime();
00298 }
00299 
00300 
00301 
00302 
00303 // ***************************************************************************
00304 void    CMeshBase::instanciateMeshBase(CMeshBaseInstance *mi, CScene *ownerScene)
00305 {
00306     uint32 i;
00307 
00308 
00309     // setup animated blendShapes
00310     //===========================
00311     mi->_AnimatedMorphFactor.reserve(_AnimatedMorph.size());
00312     for(i = 0; i < _AnimatedMorph.size(); ++i)
00313     {
00314         CAnimatedMorph am(&_AnimatedMorph[i]);
00315         mi->_AnimatedMorphFactor.push_back (am);
00316     }
00317 
00318     // setup materials.
00319     //=================
00320     // Copy material. Textures are referenced only
00321     mi->Materials= _Materials;
00322 
00323     // Instanciate selectable textures (use default set)
00324     mi->selectTextureSet(0);
00325 
00326     // prepare possible AsyncTextures
00327     mi->AsyncTextures.resize(_Materials.size());
00328 
00329     // setup animated materials.
00330     //==========================
00331     TAnimatedMaterialMap::iterator  it;
00332     mi->_AnimatedMaterials.reserve(_AnimatedMaterials.size());
00333     for(it= _AnimatedMaterials.begin(); it!= _AnimatedMaterials.end(); it++)
00334     {
00335         CAnimatedMaterial   aniMat(&it->second);
00336 
00337         // set the target instance material.
00338         nlassert(it->first < mi->Materials.size());
00339         aniMat.setMaterial(&mi->Materials[it->first]);
00340 
00341         // Must set the Animatable father of the animated material (the mesh_base_instance!).
00342         aniMat.setFather(mi, CMeshBaseInstance::OwnerBit);
00343 
00344         // Append this animated material.
00345         mi->_AnimatedMaterials.push_back(aniMat);
00346     }
00347 
00348     // Misc
00349     //==========================
00350 
00351     // Setup position with the default value
00352     mi->ITransformable::setPos( _DefaultPos.getDefaultValue() );
00353     mi->ITransformable::setRotQuat( _DefaultRotQuat.getDefaultValue() );
00354     mi->ITransformable::setScale( _DefaultScale.getDefaultValue() );
00355     mi->ITransformable::setPivot( _DefaultPivot.getDefaultValue() );
00356 
00357     // Setup default opcaity / transparency state
00358     mi->setOpacity( this->getDefaultOpacity() );
00359     mi->setTransparency( this->getDefaultTransparency() );
00360 
00361     // if the mesh is lightable, then the instance is
00362     mi->setIsLightable(this->isLightable());
00363 
00364     // a mesh is considered big for lightable if it uses localAttenuation
00365     mi->setIsBigLightable(this->useLightingLocalAttenuation());
00366 
00367     // The mesh support fast intersect, if the system geometry has been built
00368     mi->enableFastIntersectSupport(!_SystemGeometry.empty());
00369 }
00370 
00371 
00372 // ***************************************************************************
00373 void    CMeshBase::applyMaterialUsageOptim(const std::vector<bool> &materialUsed, std::vector<sint> &remap)
00374 {
00375     nlassert(_Materials.size()==materialUsed.size());
00376 
00377     // security reset
00378     resetLodCharacterTexture();
00379     _AnimatedMaterials.clear();
00380 
00381     // init all ids to "Not Used"
00382     remap.clear();
00383     remap.resize(_Materials.size(), -1);
00384 
00385     // remove unused materials and build remap
00386     vector<CMaterial>::iterator     itMat= _Materials.begin();
00387     uint                            dstIdx= 0;
00388     uint i;
00389     for(i=0;i<materialUsed.size();i++)
00390     {
00391         // if used, still use it, and remap.
00392         if(materialUsed[i])
00393         {
00394             remap[i]= dstIdx;
00395             itMat++;
00396             dstIdx++;
00397         }
00398         // remove from the array
00399         else
00400         {
00401             itMat= _Materials.erase(itMat);
00402         }
00403     }
00404 
00405     // apply the remap to LightMaps infos
00406     const uint count = _LightInfos.size ();
00407     for (i=0; i<count; i++)
00408     {
00409         CLightMapInfoList &mapInfoList = _LightInfos[i];
00410         std::list<CMeshBase::CLightMapInfoList::CMatStage>::iterator ite = mapInfoList.StageList.begin ();
00411         while (ite != mapInfoList.StageList.end ())
00412         {
00413             sint    newId= remap[ite->MatId];
00414             // If material used
00415             if(newId>=0)
00416             {
00417                 // apply remap on the material id
00418                 ite->MatId= newId;
00419                 ite++;
00420             }
00421             else
00422             {
00423                 // remove it from list of light infos
00424                 ite= mapInfoList.StageList.erase(ite);
00425             }
00426         }
00427     }
00428 }
00429 
00430 
00431 // ***************************************************************************
00432 void    CMeshBase::flushTextures(IDriver &driver, uint selectedTexture)
00433 {
00434     // Mat count
00435     uint matCount=_Materials.size();
00436 
00437     // Flush each material textures
00438     for (uint mat=0; mat<matCount; mat++)
00439     {
00441         _Materials[mat].flushTextures (driver, selectedTexture);
00442     }
00443 }
00444 
00445 
00446 // ***************************************************************************
00447 void    CMeshBase::computeIsLightable()
00448 {
00449     // by default the mesh is not lightable
00450     _IsLightable= false;
00451 
00452     // Mat count
00453     uint matCount=_Materials.size();
00454 
00455     // for each material
00456     for (uint mat=0; mat<matCount; mat++)
00457     {
00458         // if this one is not a lightmap, then OK, the mesh is lightable
00459         if( _Materials[mat].getShader()!=CMaterial::LightMap )
00460         {
00461             _IsLightable= true;
00462             break;
00463         }
00464     }
00465 }
00466 
00467 
00468 // ***************************************************************************
00469 bool    CMeshBase::useLightingLocalAttenuation () const
00470 {
00471     return _UseLightingLocalAttenuation;
00472 }
00473 
00474 
00475 // ***************************************************************************
00476 void    CMeshBase::resetLodCharacterTexture()
00477 {
00478     if(_LodCharacterTexture)
00479     {
00480         delete _LodCharacterTexture;
00481         _LodCharacterTexture= NULL;
00482     }
00483 }
00484 
00485 // ***************************************************************************
00486 void    CMeshBase::setupLodCharacterTexture(CLodCharacterTexture &lodText)
00487 {
00488     // delete old
00489     resetLodCharacterTexture();
00490     // seutp new
00491     _LodCharacterTexture= new CLodCharacterTexture;
00492     *_LodCharacterTexture= lodText;
00493 }
00494 
00495 // ***************************************************************************
00496 CVisualCollisionMesh        *CMeshBase::getVisualCollisionMesh() const
00497 {
00498     return _VisualCollisionMesh;
00499 }
00500 
00501 // ***************************************************************************
00502 void    CMeshBase::compileRunTime()
00503 {
00504     _DefaultTransparency= false;
00505     _DefaultOpacity= false;
00506     for( uint i = 0; i < _Materials.size(); ++i )
00507         if( _Materials[i].getBlend() )
00508             _DefaultTransparency= true;
00509         else
00510             _DefaultOpacity= true;
00511 }
00512 
00513 
00514 } // NL3D

Generated on Thu Jan 7 08:26:27 2010 for NeL by  doxygen 1.6.1