mesh_base.cpp
Go to the documentation of this file.00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00046
00047
00048
00049 _UseLightingLocalAttenuation= false;
00050
00051
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
00077
00078
00079
00080
00081 resetLodCharacterTexture();
00082
00083 if(_VisualCollisionMesh)
00084 {
00085 delete _VisualCollisionMesh;
00086 _VisualCollisionMesh= NULL;
00087 }
00088 }
00089
00090
00091
00092
00093
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
00105 _AnimatedMaterials[id].Name= matName;
00106
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
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
00150
00151
00152
00153
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
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
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
00230 f.serial(_IsLightable);
00231 else if( f.isReading() )
00232
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
00257 if(f.isReading())
00258 compileRunTime();
00259 }
00260
00261
00262
00263 void CMeshBase::buildMeshBase(CMeshBaseBuild &m)
00264 {
00265
00266 _LightInfos = m.LightInfoMap;
00267
00268
00269 _Materials= m.Materials;
00270
00271
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
00289 computeIsLightable();
00290
00291 _UseLightingLocalAttenuation= m.UseLightingLocalAttenuation;
00292
00293
00294 _CollisionMeshGeneration= m.CollisionMeshGeneration;
00295
00296
00297 compileRunTime();
00298 }
00299
00300
00301
00302
00303
00304 void CMeshBase::instanciateMeshBase(CMeshBaseInstance *mi, CScene *ownerScene)
00305 {
00306 uint32 i;
00307
00308
00309
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
00319
00320
00321 mi->Materials= _Materials;
00322
00323
00324 mi->selectTextureSet(0);
00325
00326
00327 mi->AsyncTextures.resize(_Materials.size());
00328
00329
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
00338 nlassert(it->first < mi->Materials.size());
00339 aniMat.setMaterial(&mi->Materials[it->first]);
00340
00341
00342 aniMat.setFather(mi, CMeshBaseInstance::OwnerBit);
00343
00344
00345 mi->_AnimatedMaterials.push_back(aniMat);
00346 }
00347
00348
00349
00350
00351
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
00358 mi->setOpacity( this->getDefaultOpacity() );
00359 mi->setTransparency( this->getDefaultTransparency() );
00360
00361
00362 mi->setIsLightable(this->isLightable());
00363
00364
00365 mi->setIsBigLightable(this->useLightingLocalAttenuation());
00366
00367
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
00378 resetLodCharacterTexture();
00379 _AnimatedMaterials.clear();
00380
00381
00382 remap.clear();
00383 remap.resize(_Materials.size(), -1);
00384
00385
00386 vector<CMaterial>::iterator itMat= _Materials.begin();
00387 uint dstIdx= 0;
00388 uint i;
00389 for(i=0;i<materialUsed.size();i++)
00390 {
00391
00392 if(materialUsed[i])
00393 {
00394 remap[i]= dstIdx;
00395 itMat++;
00396 dstIdx++;
00397 }
00398
00399 else
00400 {
00401 itMat= _Materials.erase(itMat);
00402 }
00403 }
00404
00405
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
00415 if(newId>=0)
00416 {
00417
00418 ite->MatId= newId;
00419 ite++;
00420 }
00421 else
00422 {
00423
00424 ite= mapInfoList.StageList.erase(ite);
00425 }
00426 }
00427 }
00428 }
00429
00430
00431
00432 void CMeshBase::flushTextures(IDriver &driver, uint selectedTexture)
00433 {
00434
00435 uint matCount=_Materials.size();
00436
00437
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
00450 _IsLightable= false;
00451
00452
00453 uint matCount=_Materials.size();
00454
00455
00456 for (uint mat=0; mat<matCount; mat++)
00457 {
00458
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
00489 resetLodCharacterTexture();
00490
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 }