# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

mesh_base.cpp

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