00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "nel/misc/hierarchical_timer.h"
00029 #include "nel/misc/debug.h"
00030 #include "3d/driver.h"
00031 #include "3d/transform_shape.h"
00032 #include "3d/skeleton_model.h"
00033 #include "3d/mesh_base_instance.h"
00034 #include "3d/clip_trav.h"
00035 #include "3d/render_trav.h"
00036 #include "3d/load_balancing_trav.h"
00037
00038 #define NL3D_MEM_INSTANCE NL_ALLOC_CONTEXT( 3dInst )
00039
00040 using namespace NLMISC;
00041
00042
00043 namespace NL3D
00044 {
00045
00046
00047
00048 void CTransformShape::registerBasic()
00049 {
00050 CMOT::registerModel(TransformShapeId, TransformId, CTransformShape::creator);
00051 CMOT::registerObs(ClipTravId, TransformShapeId, CTransformShapeClipObs::creator);
00052 CMOT::registerObs(RenderTravId, TransformShapeId, CTransformShapeRenderObs::creator);
00053 CMOT::registerObs(LoadBalancingTravId, TransformShapeId, CTransformShapeLoadBalancingObs::creator);
00054 }
00055
00056
00057
00058 CTransformShape::CTransformShape()
00059 {
00060 _NumTrianglesAfterLoadBalancing= 100;
00061 _CurrentLightContribution= NULL;
00062 _CurrentUseLocalAttenuation= false;
00063 _DistMax = -1.f;
00064
00065 CTransform::setIsLoadbalancable(true);
00066
00067
00068 CTransform::setIsRenderable(true);
00069 }
00070
00071
00072
00073 float CTransformShape::getNumTriangles (float distance)
00074 {
00075
00076 return Shape->getNumTriangles (distance);
00077 }
00078
00079
00080
00081 void CTransformShape::getAABBox(NLMISC::CAABBox &bbox) const
00082 {
00083 if(Shape)
00084 {
00085 Shape->getAABBox(bbox);
00086 }
00087 else
00088 {
00089 bbox.setCenter(CVector::Null);
00090 bbox.setHalfSize(CVector::Null);
00091 }
00092 }
00093
00094
00095
00096 void CTransformShape::setupCurrentLightContribution(CLightContribution *lightContrib, bool useLocalAtt)
00097 {
00098 _CurrentLightContribution= lightContrib;
00099 _CurrentUseLocalAttenuation= useLocalAtt;
00100 }
00101
00102
00103 void CTransformShape::changeLightSetup(CRenderTrav *rdrTrav)
00104 {
00105
00106 rdrTrav->changeLightSetup(_CurrentLightContribution, _CurrentUseLocalAttenuation);
00107 }
00108
00109
00110
00111 uint CTransformShape::getNumMaterial () const
00112 {
00113 return 0;
00114 }
00115
00116
00117
00118 const CMaterial *CTransformShape::getMaterial (uint materialId) const
00119 {
00120 return NULL;
00121 }
00122
00123
00124
00125 CMaterial *CTransformShape::getMaterial (uint materialId)
00126 {
00127 return NULL;
00128 }
00129
00130
00131
00132 bool CTransformShapeClipObs::clip(IBaseClipObs *caller)
00133 {
00134 CClipTrav *trav= (CClipTrav*)Trav;
00135 CTransformShape *m= (CTransformShape*)Model;
00136
00137
00138 _ClipDueToDistMax= false;
00139
00140 if(m->Shape)
00141 {
00142
00143 float maxDist = m->getDistMax();
00144
00145 if(maxDist!=-1)
00146 {
00147
00148 float sqrDist = (trav->CamPos - m->getMatrix().getPos()).sqrnorm ();
00149 maxDist*=maxDist;
00150
00151
00152 if (sqrDist > maxDist)
00153 {
00154
00155 _ClipDueToDistMax= true;
00156
00157 return false;
00158 }
00159 }
00160
00161
00162 if(trav->ForceNoFrustumClip)
00163 return true;
00164 else
00165 return m->Shape->clip(trav->WorldPyramid, HrcObs->WorldMatrix);
00166 }
00167 else
00168 return false;
00169 }
00170
00171
00172
00173 void CTransformShapeRenderObs::traverse(IObs *caller)
00174 {
00175 NL3D_MEM_INSTANCE
00176 H_AUTO( NL3D_TrShape_Render );
00177
00178 CTransformShape *m= (CTransformShape*)Model;
00179
00180
00181
00182
00183
00184
00185 if(m->isLightable())
00186 {
00187
00188 if(m->Shape)
00189 m->_CurrentUseLocalAttenuation= m->Shape->useLightingLocalAttenuation ();
00190 else
00191 m->_CurrentUseLocalAttenuation= false;
00192
00193
00194 CTransformHrcObs *hrcObs= (CTransformHrcObs*)HrcObs;
00195
00196
00197 if(hrcObs->_AncestorSkeletonModel==NULL)
00198 m->_CurrentLightContribution= &m->getLightContribution();
00199
00200 else
00201 m->_CurrentLightContribution= &hrcObs->_AncestorSkeletonModel->getLightContribution();
00202 }
00203
00204 else
00205 {
00206
00207 m->_CurrentLightContribution= NULL;
00208 m->_CurrentUseLocalAttenuation= false;
00209 }
00210
00211
00212
00213
00214 if(m->Shape)
00215 {
00216 CRenderTrav *rdrTrav= (CRenderTrav*)Trav;
00217 bool currentPassOpaque= rdrTrav->isCurrentPassOpaque();
00218
00219
00220 float polygonCount;
00221 IMeshGeom *meshGeom= NULL;
00222
00223 if( currentPassOpaque )
00224 meshGeom= m->Shape->supportMeshBlockRendering(m, polygonCount);
00225
00226
00227 if(meshGeom)
00228 {
00229 CMeshBaseInstance *inst= safe_cast<CMeshBaseInstance*>(m);
00230 rdrTrav->MeshBlockManager.addInstance(meshGeom, inst, polygonCount);
00231 }
00232
00233 else
00234 {
00235
00236 m->changeLightSetup( rdrTrav );
00237
00238
00239 IDriver *drv= rdrTrav->getDriver();
00240 m->Shape->render( drv, m, currentPassOpaque );
00241 }
00242 }
00243 }
00244
00245
00246
00247 void CTransformShapeLoadBalancingObs::traverse(IObs *caller)
00248 {
00249 CLoadBalancingTrav *loadTrav= (CLoadBalancingTrav*)Trav;
00250 if(loadTrav->getLoadPass()==0)
00251 traversePass0();
00252 else
00253 traversePass1();
00254
00255
00256 }
00257
00258
00259
00260
00261 void CTransformShapeLoadBalancingObs::traversePass0()
00262 {
00263 CLoadBalancingTrav *loadTrav= (CLoadBalancingTrav*)Trav;
00264 CTransformShape *trans= static_cast<CTransformShape*>(Model);
00265 CSkeletonModel *skeleton= trans->getSkeletonModel();
00266
00267
00268 const CVector *modelPos;
00269
00270
00271
00272 if(skeleton)
00273 {
00274
00275
00276 modelPos= &skeleton->Bones[0].getWorldMatrix().getPos();
00277 }
00278 else
00279 {
00280
00281 modelPos= &HrcObs->WorldMatrix.getPos();
00282 }
00283
00284
00285
00286 float modelDist= ( loadTrav->CamPos - *modelPos).norm();
00287
00288
00289
00290 _FaceCount= trans->getNumTriangles(modelDist);
00291 LoadBalancingGroup->addNbFacesPass0(_FaceCount);
00292 }
00293
00294
00295
00296 void CTransformShapeLoadBalancingObs::traversePass1()
00297 {
00298 CTransformShape *trans= static_cast<CTransformShape*>(Model);
00299
00300
00301
00302 trans->_NumTrianglesAfterLoadBalancing= LoadBalancingGroup->computeModelNbFace(_FaceCount);
00303
00304 }
00305
00306
00307 }