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_mrm_instance.h"
20 #include "nel/3d/mesh_mrm.h"
21 #include "nel/3d/skeleton_model.h"
22 #include "nel/3d/raw_skin.h"
23 #include "nel/3d/shifted_triangle_cache.h"
24 #include "nel/3d/u_scene.h"
25 #include "nel/3d/scene.h"
28 using namespace NLMISC
;
38 // ***************************************************************************
39 CMeshMRMInstance::~CMeshMRMInstance()
41 // Auto detach me from skeleton. Must do it here, not in ~CTransform().
42 if(_FatherSkeletonModel
)
44 // detach me from the skeleton.
45 // hrc and clip hierarchy is modified.
46 _FatherSkeletonModel
->detachSkeletonSon(this);
47 nlassert(_FatherSkeletonModel
==NULL
);
48 // If skinned, setApplySkin(false) should have been called through detachSkeletonSon()
49 nlassert(_RawSkinCache
== NULL
);
50 nlassert(_ShiftedTriangleCache
== NULL
);
55 // ***************************************************************************
56 void CMeshMRMInstance::registerBasic()
58 CScene::registerModel(MeshMRMInstanceId
, MeshBaseInstanceId
, CMeshMRMInstance::creator
);
62 // ***************************************************************************
63 void CMeshMRMInstance::clearRawSkinCache()
69 // ***************************************************************************
70 void CMeshMRMInstance::clearShiftedTriangleCache()
72 delete _ShiftedTriangleCache
;
73 _ShiftedTriangleCache
= NULL
;
76 // ***************************************************************************
77 void CMeshMRMInstance::setApplySkin(bool state
)
79 // Call parents method
80 CMeshBaseInstance::setApplySkin (state
);
82 // Get a pointer on the shape
83 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
88 pMesh
->computeBonesId (_FatherSkeletonModel
);
91 // update the skeleton usage according to the mesh.
92 pMesh
->updateSkeletonUsage(_FatherSkeletonModel
, state
);
94 // If unbinded, clean all the cache.
98 clearShiftedTriangleCache();
103 // ***************************************************************************
104 void CMeshMRMInstance::changeMRMDistanceSetup(float distanceFinest
, float distanceMiddle
, float distanceCoarsest
)
108 // Get a pointer on the shape.
109 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
110 // Affect the mesh directly.
111 pMesh
->changeMRMDistanceSetup(distanceFinest
, distanceMiddle
, distanceCoarsest
);
116 // ***************************************************************************
117 const std::vector
<sint32
> *CMeshMRMInstance::getSkinBoneUsage() const
119 // Get a pointer on the shape
120 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
122 // Recompute the id, if needed
123 pMesh
->computeBonesId (_FatherSkeletonModel
);
126 return &pMesh
->getMeshGeom().getSkinBoneUsage();
130 // ***************************************************************************
131 const std::vector
<NLMISC::CBSphere
> *CMeshMRMInstance::getSkinBoneSphere() const
133 // Get a pointer on the shape
134 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
136 // Recompute the id, and skin spheres, if needed
137 pMesh
->computeBonesId (_FatherSkeletonModel
);
140 return &pMesh
->getMeshGeom().getSkinBoneSphere();
144 // ***************************************************************************
145 bool CMeshMRMInstance::getSkinBoneBBox(NLMISC::CAABBox
&bbox
, uint boneId
)
147 // Get a pointer on the shape
148 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
150 // Recompute the id, and skin spheres, if needed
151 pMesh
->computeBonesId (_FatherSkeletonModel
);
154 return pMesh
->getMeshGeom().getSkinBoneBBox(_FatherSkeletonModel
, bbox
, boneId
);
158 // ***************************************************************************
159 bool CMeshMRMInstance::isSkinnable() const
164 // Get a pointer on the shape
165 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
167 // true if the mesh is skinned
168 return pMesh
->getMeshGeom().isSkinned();
172 // ***************************************************************************
173 void CMeshMRMInstance::renderSkin(float alphaMRM
)
175 // Don't setup lighting or matrix in Skin. Done by the skeleton
177 if(Shape
&& getVisibility() != CHrcTrav::Hide
)
179 // Get a pointer on the shape
180 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
182 // render the meshGeom
183 CMeshMRMGeom
&meshGeom
= const_cast<CMeshMRMGeom
&>(pMesh
->getMeshGeom ());
184 meshGeom
.renderSkin( this, alphaMRM
);
189 // ***************************************************************************
190 const CMRMLevelDetail
*CMeshMRMInstance::getMRMLevelDetail() const
194 CMeshMRM
*meshMrm
= safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
195 return &meshMrm
->getMeshGeom().getLevelDetail();
201 // ***************************************************************************
202 bool CMeshMRMInstance::supportSkinGrouping() const
206 CMeshMRM
*meshMrm
= safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
207 return meshMrm
->getMeshGeom().supportSkinGrouping();
212 // ***************************************************************************
213 sint
CMeshMRMInstance::renderSkinGroupGeom(float alphaMRM
, uint remainingVertices
, uint8
*dest
)
215 // Get a pointer on the shape
216 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
217 // render the meshGeom
218 CMeshMRMGeom
&meshGeom
= const_cast<CMeshMRMGeom
&>(pMesh
->getMeshGeom ());
219 return meshGeom
.renderSkinGroupGeom(this, alphaMRM
, remainingVertices
, dest
);
221 // ***************************************************************************
222 void CMeshMRMInstance::renderSkinGroupPrimitives(uint baseVertex
, std::vector
<CSkinSpecularRdrPass
> &specularRdrPasses
, uint skinIndex
)
224 // Get a pointer on the shape
225 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
226 // render the meshGeom
227 CMeshMRMGeom
&meshGeom
= const_cast<CMeshMRMGeom
&>(pMesh
->getMeshGeom ());
228 meshGeom
.renderSkinGroupPrimitives(this, baseVertex
, specularRdrPasses
, skinIndex
);
230 // ***************************************************************************
231 void CMeshMRMInstance::renderSkinGroupSpecularRdrPass(uint rdrPassId
)
233 // Get a pointer on the shape
234 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
235 // render the meshGeom
236 CMeshMRMGeom
&meshGeom
= const_cast<CMeshMRMGeom
&>(pMesh
->getMeshGeom ());
237 meshGeom
.renderSkinGroupSpecularRdrPass(this, rdrPassId
);
240 // ***************************************************************************
241 void CMeshMRMInstance::initRenderFilterType()
245 // If the Shape has a VP or not...
246 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
248 if( pMesh
->getMeshGeom().hasMeshVertexProgram() )
249 _RenderFilterType
= UScene::FilterMeshMRMVP
;
251 _RenderFilterType
= UScene::FilterMeshMRMNoVP
;
256 // ***************************************************************************
257 bool CMeshMRMInstance::supportShadowSkinGrouping() const
261 CMeshMRM
*meshMrm
= safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
262 return meshMrm
->getMeshGeom().supportShadowSkinGrouping();
268 // ***************************************************************************
269 sint
CMeshMRMInstance::renderShadowSkinGeom(uint remainingVertices
, uint8
*vbDest
)
271 // Get a pointer on the shape
272 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
273 // render the meshGeom
274 CMeshMRMGeom
&meshGeom
= const_cast<CMeshMRMGeom
&>(pMesh
->getMeshGeom ());
275 return meshGeom
.renderShadowSkinGeom(this, remainingVertices
, vbDest
);
278 // ***************************************************************************
279 void CMeshMRMInstance::renderShadowSkinPrimitives(CMaterial
&castMat
, IDriver
*drv
, uint baseVertex
)
281 // Get a pointer on the shape
282 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
283 // render the meshGeom
284 CMeshMRMGeom
&meshGeom
= const_cast<CMeshMRMGeom
&>(pMesh
->getMeshGeom ());
285 meshGeom
.renderShadowSkinPrimitives(this, castMat
, drv
, baseVertex
);
288 // ***************************************************************************
289 bool CMeshMRMInstance::supportIntersectSkin() const
291 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
292 CMeshMRMGeom
&meshGeom
= const_cast<CMeshMRMGeom
&>(pMesh
->getMeshGeom ());
293 return meshGeom
.supportIntersectSkin();
296 // ***************************************************************************
297 bool CMeshMRMInstance::intersectSkin(const CMatrix
&toRaySpace
, float &dist2D
, float &distZ
, bool computeDist2D
)
299 // Get a pointer on the shape
300 CMeshMRM
*pMesh
= NLMISC::safe_cast
<CMeshMRM
*>((IShape
*)Shape
);
301 // render the meshGeom
302 CMeshMRMGeom
&meshGeom
= const_cast<CMeshMRMGeom
&>(pMesh
->getMeshGeom ());
303 return meshGeom
.intersectSkin(this, toRaySpace
, dist2D
, distZ
, computeDist2D
);