1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/3d/mesh_base.h"
20 #include "nel/3d/mesh_base_instance.h"
21 #include "nel/3d/lod_character_texture.h"
22 #include "nel/3d/visual_collision_mesh.h"
26 using namespace NLMISC
;
37 // ***************************************************************************
38 CMeshBase::CMeshBase()
40 /* ***********************************************
41 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
42 * It can be loaded/called through CAsyncFileManager for instance
43 * ***********************************************/
45 _UseLightingLocalAttenuation
= false;
47 // To have same functionnality than previous version, init to identity.
48 _DefaultPos
.setDefaultValue(CVector(0,0,0));
49 _DefaultPivot
.setDefaultValue(CVector(0,0,0));
50 _DefaultRotEuler
.setDefaultValue(CVector(0,0,0));
51 _DefaultRotQuat
.setDefaultValue(CQuat::Identity
);
52 _DefaultScale
.setDefaultValue(CVector(1,1,1));
53 _DefaultLMFactor
.setDefaultValue(CRGBA(255,255,255,255));
57 _LodCharacterTexture
= NULL
;
59 _CollisionMeshGeneration
= AutoCameraCol
;
61 _VisualCollisionMesh
= NULL
;
63 _DefaultOpacity
= false;
64 _DefaultTransparency
= false;
68 // ***************************************************************************
69 CMeshBase::~CMeshBase()
71 /* ***********************************************
72 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
73 * It can be loaded/called through CAsyncFileManager for instance
74 * ***********************************************/
77 resetLodCharacterTexture();
78 // delete the Col mesh if created
79 if(_VisualCollisionMesh
)
81 delete _VisualCollisionMesh
;
82 _VisualCollisionMesh
= NULL
;
87 // ***************************************************************************
88 // ***************************************************************************
90 // ***************************************************************************
91 // ***************************************************************************
94 // ***************************************************************************
95 void CMeshBase::setAnimatedMaterial(uint id
, const std::string
&matName
)
97 nlassert(!matName
.empty());
98 if(id
<_Materials
.size())
100 // add / replace animated material.
101 _AnimatedMaterials
[id
].Name
= matName
;
102 // copy Material default.
103 _AnimatedMaterials
[id
].copyFromMaterial(&_Materials
[id
]);
107 // ***************************************************************************
108 CMaterialBase
*CMeshBase::getAnimatedMaterial(uint id
)
110 TAnimatedMaterialMap::iterator it
;
111 it
= _AnimatedMaterials
.find(id
);
112 if(it
!=_AnimatedMaterials
.end())
119 // ***************************************************************************
120 // ***************************************************************************
121 // Serial - buildBase.
122 // ***************************************************************************
123 // ***************************************************************************
126 // ***************************************************************************
127 CMeshBase::CMeshBaseBuild::CMeshBaseBuild()
129 DefaultPos
.set(0,0,0);
130 DefaultPivot
.set(0,0,0);
131 DefaultRotEuler
.set(0,0,0);
132 DefaultScale
.set(1,1,1);
136 UseLightingLocalAttenuation
= false;
137 CollisionMeshGeneration
= CMeshBase::AutoCameraCol
;
140 // ***************************************************************************
142 void CMeshBase::CMeshBaseBuild::serial(NLMISC::IStream
&f
)
146 - Cut in version because of badly coded ITexture* serialisation. throw an exception if
151 sint ver
= f
.serialVersion(1);
154 throw NLMISC::EStream(f
, "MeshBuild in Stream is too old (MeshBaseBuild version < 1)");
156 f
.serial( DefaultPos
);
157 f
.serial( DefaultPivot
);
158 f
.serial( DefaultRotEuler
);
159 f
.serial( DefaultRotQuat
);
160 f
.serial( DefaultScale
);
162 f
.serialCont( Materials
);
166 // ***************************************************************************
167 void CMeshBase::serialMeshBase(NLMISC::IStream
&f
)
169 /* ***********************************************
170 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
171 * It can be loaded/called through CAsyncFileManager for instance
172 * ***********************************************/
176 - _CollisionMeshGeneration
178 - new format for CLightMapInfoList
180 - _LodCharacterTexture
186 - _UseLightingLocalAttenuation
190 - Added Blend Shapes factors
192 - Cut in version because of badly coded ITexture* serialisation. throw an exception if
197 sint ver
= f
.serialVersion(9);
201 f
.serialCont (_AnimatedMorph
);
205 throw NLMISC::EStream(f
, "Mesh in Stream is too old (MeshBase version < 1)");
207 f
.serial (_DefaultPos
);
208 f
.serial (_DefaultPivot
);
209 f
.serial (_DefaultRotEuler
);
210 f
.serial (_DefaultRotQuat
);
211 f
.serial (_DefaultScale
);
213 f
.serialCont(_Materials
);
214 f
.serialCont(_AnimatedMaterials
);
217 f
.serialCont(_LightInfos
);
220 TLightInfoMapV7 temp
;
225 // read/write _IsLightable flag.
226 f
.serial(_IsLightable
);
227 else if( f
.isReading() )
228 // update _IsLightable flag.
229 computeIsLightable();
232 f
.serial(_UseLightingLocalAttenuation
);
233 else if( f
.isReading() )
234 _UseLightingLocalAttenuation
= false;
245 f
.serialPtr(_LodCharacterTexture
);
248 f
.serialEnum(_CollisionMeshGeneration
);
250 _CollisionMeshGeneration
= AutoCameraCol
;
252 // Some runtime not serialized compilation
258 // ***************************************************************************
259 void CMeshBase::buildMeshBase(CMeshBaseBuild
&m
)
261 // Copy light information
262 _LightInfos
= m
.LightInfoMap
;
264 // copy the materials.
265 _Materials
= m
.Materials
;
267 // clear the animated materials.
268 _AnimatedMaterials
.clear();
270 /// Copy default position values
271 _DefaultPos
.setDefaultValue (m
.DefaultPos
);
272 _DefaultPivot
.setDefaultValue (m
.DefaultPivot
);
273 _DefaultRotEuler
.setDefaultValue (m
.DefaultRotEuler
);
274 _DefaultRotQuat
.setDefaultValue (m
.DefaultRotQuat
);
275 _DefaultScale
.setDefaultValue (m
.DefaultScale
);
277 _AnimatedMorph
.resize(m
.DefaultBSFactors
.size());
278 for (uint32 i
= 0; i
< m
.DefaultBSFactors
.size(); ++i
)
280 _AnimatedMorph
[i
].DefaultFactor
.setDefaultValue (m
.DefaultBSFactors
[i
]);
281 _AnimatedMorph
[i
].Name
= m
.BSNames
[i
];
284 // update _IsLightable flag.
285 computeIsLightable();
286 // copy _UseLightingLocalAttenuation
287 _UseLightingLocalAttenuation
= m
.UseLightingLocalAttenuation
;
289 // copy CollisionMeshGeneration
290 _CollisionMeshGeneration
= m
.CollisionMeshGeneration
;
292 // Some runtime not serialized compilation
299 // ***************************************************************************
300 void CMeshBase::instanciateMeshBase(CMeshBaseInstance
*mi
, CScene
*ownerScene
)
305 // setup animated blendShapes
306 //===========================
307 mi
->_AnimatedMorphFactor
.reserve(_AnimatedMorph
.size());
308 for(i
= 0; i
< _AnimatedMorph
.size(); ++i
)
310 CAnimatedMorph
am(&_AnimatedMorph
[i
]);
311 mi
->_AnimatedMorphFactor
.push_back (am
);
316 // Copy material. Textures are referenced only
317 mi
->Materials
= _Materials
;
319 // Instanciate selectable textures (use default set)
320 mi
->selectTextureSet(0);
322 // prepare possible AsyncTextures
323 mi
->AsyncTextures
.resize(_Materials
.size());
325 // setup animated materials.
326 //==========================
327 TAnimatedMaterialMap::iterator it
;
328 mi
->_AnimatedMaterials
.reserve(_AnimatedMaterials
.size());
329 for(it
= _AnimatedMaterials
.begin(); it
!= _AnimatedMaterials
.end(); it
++)
331 CAnimatedMaterial
aniMat(&it
->second
);
333 // set the target instance material.
334 nlassert(it
->first
< mi
->Materials
.size());
335 aniMat
.setMaterial(&mi
->Materials
[it
->first
]);
337 // Must set the Animatable father of the animated material (the mesh_base_instance!).
338 aniMat
.setFather(mi
, CMeshBaseInstance::OwnerBit
);
340 // Append this animated material.
341 mi
->_AnimatedMaterials
.push_back(aniMat
);
345 //==========================
347 // Setup position with the default value
348 mi
->ITransformable::setPos( _DefaultPos
.getDefaultValue() );
349 mi
->ITransformable::setRotQuat( _DefaultRotQuat
.getDefaultValue() );
350 mi
->ITransformable::setScale( _DefaultScale
.getDefaultValue() );
351 mi
->ITransformable::setPivot( _DefaultPivot
.getDefaultValue() );
353 // Setup default opcaity / transparency state
354 mi
->setOpacity( this->getDefaultOpacity() );
355 mi
->setTransparency( this->getDefaultTransparency() );
357 // if the mesh is lightable, then the instance is
358 mi
->setIsLightable(this->isLightable());
360 // a mesh is considered big for lightable if it uses localAttenuation
361 mi
->setIsBigLightable(this->useLightingLocalAttenuation());
363 // The mesh support fast intersect, if the system geometry has been built
364 mi
->enableFastIntersectSupport(!_SystemGeometry
.empty());
368 // ***************************************************************************
369 void CMeshBase::applyMaterialUsageOptim(const std::vector
<bool> &materialUsed
, std::vector
<sint
> &remap
)
371 nlassert(_Materials
.size()==materialUsed
.size());
374 resetLodCharacterTexture();
375 _AnimatedMaterials
.clear();
377 // init all ids to "Not Used"
379 remap
.resize(_Materials
.size(), -1);
381 // remove unused materials and build remap
382 vector
<CMaterial
>::iterator itMat
= _Materials
.begin();
385 for(i
=0;i
<materialUsed
.size();i
++)
387 // if used, still use it, and remap.
394 // remove from the array
397 itMat
= _Materials
.erase(itMat
);
401 // apply the remap to LightMaps infos
402 const uint count
= (uint
)_LightInfos
.size ();
403 for (i
=0; i
<count
; i
++)
405 CLightMapInfoList
&mapInfoList
= _LightInfos
[i
];
406 std::list
<CMeshBase::CLightMapInfoList::CMatStage
>::iterator ite
= mapInfoList
.StageList
.begin ();
407 while (ite
!= mapInfoList
.StageList
.end ())
409 sint newId
= remap
[ite
->MatId
];
413 // apply remap on the material id
419 // remove it from list of light infos
420 ite
= mapInfoList
.StageList
.erase(ite
);
427 // ***************************************************************************
428 void CMeshBase::flushTextures(IDriver
&driver
, uint selectedTexture
)
431 uint matCount
=(uint
)_Materials
.size();
433 // Flush each material textures
434 for (uint mat
=0; mat
<matCount
; mat
++)
436 /// Flush material textures
437 _Materials
[mat
].flushTextures (driver
, selectedTexture
);
442 // ***************************************************************************
443 void CMeshBase::computeIsLightable()
445 // by default the mesh is not lightable
449 uint matCount
=(uint
)_Materials
.size();
452 for (uint mat
=0; mat
<matCount
; mat
++)
454 // if this one is not a lightmap, then OK, the mesh is lightable
455 if( _Materials
[mat
].getShader()!=CMaterial::LightMap
)
464 // ***************************************************************************
465 bool CMeshBase::useLightingLocalAttenuation () const
467 return _UseLightingLocalAttenuation
;
471 // ***************************************************************************
472 void CMeshBase::resetLodCharacterTexture()
474 if(_LodCharacterTexture
)
476 delete _LodCharacterTexture
;
477 _LodCharacterTexture
= NULL
;
481 // ***************************************************************************
482 void CMeshBase::setupLodCharacterTexture(CLodCharacterTexture
&lodText
)
485 resetLodCharacterTexture();
487 _LodCharacterTexture
= new CLodCharacterTexture
;
488 *_LodCharacterTexture
= lodText
;
491 // ***************************************************************************
492 CVisualCollisionMesh
*CMeshBase::getVisualCollisionMesh() const
494 return _VisualCollisionMesh
;
497 // ***************************************************************************
498 void CMeshBase::compileRunTime()
500 _DefaultTransparency
= false;
501 _DefaultOpacity
= false;
502 for( uint i
= 0; i
< _Materials
.size(); ++i
)
503 if( _Materials
[i
].getBlend() )
504 _DefaultTransparency
= true;
506 _DefaultOpacity
= true;