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_skinned_instance.h"
20 #include "nel/3d/mesh_mrm_skinned.h"
21 #include "nel/3d/skeleton_model.h"
22 #include "nel/3d/raw_skinned.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 CMeshMRMSkinnedInstance::~CMeshMRMSkinnedInstance()
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 CMeshMRMSkinnedInstance::registerBasic()
58 CScene::registerModel(MeshMRMSkinnedInstanceId
, MeshBaseInstanceId
, CMeshMRMSkinnedInstance::creator
);
62 // ***************************************************************************
63 void CMeshMRMSkinnedInstance::clearRawSkinCache()
69 // ***************************************************************************
70 void CMeshMRMSkinnedInstance::clearShiftedTriangleCache()
72 delete _ShiftedTriangleCache
;
73 _ShiftedTriangleCache
= NULL
;
76 // ***************************************************************************
77 void CMeshMRMSkinnedInstance::setApplySkin(bool state
)
79 // Call parents method
80 CMeshBaseInstance::setApplySkin (state
);
82 // Get a pointer on the shape
83 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((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 CMeshMRMSkinnedInstance::changeMRMDistanceSetup(float distanceFinest
, float distanceMiddle
, float distanceCoarsest
)
108 // Get a pointer on the shape.
109 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
110 // Affect the mesh directly.
111 pMesh
->changeMRMDistanceSetup(distanceFinest
, distanceMiddle
, distanceCoarsest
);
116 // ***************************************************************************
117 const std::vector
<sint32
> *CMeshMRMSkinnedInstance::getSkinBoneUsage() const
119 // Get a pointer on the shape
120 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
122 // Recompute the id, if needed
123 pMesh
->computeBonesId (_FatherSkeletonModel
);
126 return &pMesh
->getMeshGeom().getSkinBoneUsage();
130 // ***************************************************************************
131 const std::vector
<NLMISC::CBSphere
> *CMeshMRMSkinnedInstance::getSkinBoneSphere() const
133 // Get a pointer on the shape
134 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
136 // Recompute the id, and skin spheres, if needed
137 pMesh
->computeBonesId (_FatherSkeletonModel
);
140 return &pMesh
->getMeshGeom().getSkinBoneSphere();
144 // ***************************************************************************
145 bool CMeshMRMSkinnedInstance::getSkinBoneBBox(NLMISC::CAABBox
&bbox
, uint boneId
)
147 // Get a pointer on the shape
148 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((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 CMeshMRMSkinnedInstance::isSkinnable() const
161 // true if the mesh is skinned
166 // ***************************************************************************
167 void CMeshMRMSkinnedInstance::renderSkin(float alphaMRM
)
169 // Don't setup lighting or matrix in Skin. Done by the skeleton
171 if(Shape
&& getVisibility() != CHrcTrav::Hide
)
173 // Get a pointer on the shape
174 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
176 // render the meshGeom
177 CMeshMRMSkinnedGeom
&meshGeom
= const_cast<CMeshMRMSkinnedGeom
&>(pMesh
->getMeshGeom ());
178 meshGeom
.renderSkin( this, alphaMRM
);
183 // ***************************************************************************
184 const CMRMLevelDetail
*CMeshMRMSkinnedInstance::getMRMLevelDetail() const
188 CMeshMRMSkinned
*meshMrm
= safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
189 return &meshMrm
->getMeshGeom().getLevelDetail();
195 // ***************************************************************************
196 bool CMeshMRMSkinnedInstance::supportSkinGrouping() const
200 CMeshMRMSkinned
*meshMrm
= safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
201 return meshMrm
->getMeshGeom().supportSkinGrouping();
206 // ***************************************************************************
207 sint
CMeshMRMSkinnedInstance::renderSkinGroupGeom(float alphaMRM
, uint remainingVertices
, uint8
*dest
)
209 // Get a pointer on the shape
210 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
211 // render the meshGeom
212 CMeshMRMSkinnedGeom
&meshGeom
= const_cast<CMeshMRMSkinnedGeom
&>(pMesh
->getMeshGeom ());
213 return meshGeom
.renderSkinGroupGeom(this, alphaMRM
, remainingVertices
, dest
);
215 // ***************************************************************************
216 void CMeshMRMSkinnedInstance::renderSkinGroupPrimitives(uint baseVertex
, std::vector
<CSkinSpecularRdrPass
> &specularRdrPasses
, uint skinIndex
)
218 // Get a pointer on the shape
219 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
220 // render the meshGeom
221 CMeshMRMSkinnedGeom
&meshGeom
= const_cast<CMeshMRMSkinnedGeom
&>(pMesh
->getMeshGeom ());
222 meshGeom
.renderSkinGroupPrimitives(this, baseVertex
, specularRdrPasses
, skinIndex
);
224 // ***************************************************************************
225 void CMeshMRMSkinnedInstance::renderSkinGroupSpecularRdrPass(uint rdrPassId
)
227 // Get a pointer on the shape
228 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
229 // render the meshGeom
230 CMeshMRMSkinnedGeom
&meshGeom
= const_cast<CMeshMRMSkinnedGeom
&>(pMesh
->getMeshGeom ());
231 meshGeom
.renderSkinGroupSpecularRdrPass(this, rdrPassId
);
234 // ***************************************************************************
235 void CMeshMRMSkinnedInstance::initRenderFilterType()
239 // If the Shape has a VP or not...
240 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
242 if( pMesh
->getMeshGeom().hasMeshVertexProgram() )
243 _RenderFilterType
= UScene::FilterMeshMRMVP
;
245 _RenderFilterType
= UScene::FilterMeshMRMNoVP
;
250 // ***************************************************************************
251 bool CMeshMRMSkinnedInstance::supportShadowSkinGrouping() const
255 CMeshMRMSkinned
*meshMrm
= safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
256 return meshMrm
->getMeshGeom().supportShadowSkinGrouping();
262 // ***************************************************************************
263 sint
CMeshMRMSkinnedInstance::renderShadowSkinGeom(uint remainingVertices
, uint8
*vbDest
)
265 // Get a pointer on the shape
266 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
267 // render the meshGeom
268 CMeshMRMSkinnedGeom
&meshGeom
= const_cast<CMeshMRMSkinnedGeom
&>(pMesh
->getMeshGeom ());
269 return meshGeom
.renderShadowSkinGeom(this, remainingVertices
, vbDest
);
272 // ***************************************************************************
273 void CMeshMRMSkinnedInstance::renderShadowSkinPrimitives(CMaterial
&castMat
, IDriver
*drv
, uint baseVertex
)
275 // Get a pointer on the shape
276 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
277 // render the meshGeom
278 CMeshMRMSkinnedGeom
&meshGeom
= const_cast<CMeshMRMSkinnedGeom
&>(pMesh
->getMeshGeom ());
279 meshGeom
.renderShadowSkinPrimitives(this, castMat
, drv
, baseVertex
);
282 // ***************************************************************************
283 bool CMeshMRMSkinnedInstance::supportIntersectSkin() const
285 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
286 CMeshMRMSkinnedGeom
&meshGeom
= const_cast<CMeshMRMSkinnedGeom
&>(pMesh
->getMeshGeom ());
287 return meshGeom
.supportIntersectSkin();
290 // ***************************************************************************
291 bool CMeshMRMSkinnedInstance::intersectSkin(const CMatrix
&toRaySpace
, float &dist2D
, float &distZ
, bool computeDist2D
)
293 // Get a pointer on the shape
294 CMeshMRMSkinned
*pMesh
= NLMISC::safe_cast
<CMeshMRMSkinned
*>((IShape
*)Shape
);
295 // render the meshGeom
296 CMeshMRMSkinnedGeom
&meshGeom
= const_cast<CMeshMRMSkinnedGeom
&>(pMesh
->getMeshGeom ());
297 return meshGeom
.intersectSkin(this, toRaySpace
, dist2D
, distZ
, computeDist2D
);