transform_shape.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright, 2000 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #include "std3d.h"
00025 
00026 #include "nel/misc/hierarchical_timer.h"
00027 #include "nel/misc/debug.h"
00028 #include "nel/3d/driver.h"
00029 #include "nel/3d/transform_shape.h"
00030 #include "nel/3d/skeleton_model.h"
00031 #include "nel/3d/mesh_base_instance.h"
00032 #include "nel/3d/clip_trav.h"
00033 #include "nel/3d/render_trav.h"
00034 #include "nel/3d/load_balancing_trav.h"
00035 #include "nel/3d/quad_grid_clip_cluster.h"
00036 #include "nel/3d/scene.h"
00037 
00038 
00039 using namespace NLMISC;
00040 
00041 
00042 namespace NL3D
00043 {
00044 
00045 
00046 // ***************************************************************************
00047 void        CTransformShape::registerBasic()
00048 {
00049     CScene::registerModel(TransformShapeId, TransformId, CTransformShape::creator);
00050 }
00051 
00052 
00053 // ***************************************************************************
00054 CTransformShape::CTransformShape()
00055 {
00056     _NumTrianglesAfterLoadBalancing= 100;
00057     _CurrentLightContribution= NULL;
00058     _CurrentUseLocalAttenuation= false;
00059     _DistMax = -1.f;
00060     // By default all transformShape are LoadBalancable
00061     CTransform::setIsLoadbalancable(true);
00062 
00063     // The model is renderable
00064     CTransform::setIsRenderable(true);
00065 
00066     // I am a CTransformShape
00067     CTransform::setIsTransformShape(true);
00068 }
00069 
00070 
00071 // ***************************************************************************
00072 float       CTransformShape::getNumTriangles (float distance)
00073 {
00074     // Call shape method
00075     return Shape->getNumTriangles (distance);
00076 }
00077 
00078 
00079 // ***************************************************************************
00080 void        CTransformShape::getAABBox(NLMISC::CAABBox &bbox) const
00081 {
00082     if(Shape)
00083     {
00084         Shape->getAABBox(bbox);
00085     }
00086     else
00087     {
00088         bbox.setCenter(CVector::Null);
00089         bbox.setHalfSize(CVector::Null);
00090     }
00091 }
00092 
00093 
00094 // ***************************************************************************
00095 void        CTransformShape::setupCurrentLightContribution(CLightContribution *lightContrib, bool useLocalAtt)
00096 {
00097     _CurrentLightContribution= lightContrib;
00098     _CurrentUseLocalAttenuation= useLocalAtt;
00099 }
00100 
00101 // ***************************************************************************
00102 void        CTransformShape::changeLightSetup(CRenderTrav *rdrTrav)
00103 {
00104     // setup the instance lighting.
00105     rdrTrav->changeLightSetup(_CurrentLightContribution, _CurrentUseLocalAttenuation);
00106 }
00107 
00108 
00109 // ***************************************************************************
00110 uint        CTransformShape::getNumMaterial () const
00111 {
00112     return 0;
00113 }
00114 
00115 
00116 // ***************************************************************************
00117 const CMaterial *CTransformShape::getMaterial (uint /* materialId */) const
00118 {
00119     return NULL;
00120 }
00121 
00122 
00123 // ***************************************************************************
00124 CMaterial *CTransformShape::getMaterial (uint /* materialId */)
00125 {
00126     return NULL;
00127 }
00128 
00129 // ***************************************************************************
00130 void    CTransformShape::unlinkFromQuadCluster()
00131 {
00132     // if linked to a quadGridClipCluster, unlink it
00133     _QuadClusterListNode.unlink();
00134 }
00135 
00136 
00137 // ***************************************************************************
00138 bool    CTransformShape::clip()
00139 {
00140     H_AUTO( NL3D_TrShape_Clip );
00141 
00142     CClipTrav           &clipTrav= getOwnerScene()->getClipTrav();
00143 
00144     if(Shape)
00145     {
00146         // first test DistMax (faster).
00147         float maxDist = getDistMax();
00148         // if DistMax test enabled
00149         if(maxDist!=-1)
00150         {
00151             // Calc the distance
00152             float sqrDist = (clipTrav.CamPos - getWorldMatrix().getPos()).sqrnorm ();
00153             maxDist*=maxDist;
00154 
00155             // if dist > maxDist, skip
00156             if (sqrDist > maxDist)
00157             {
00158                 // Ok, not shown
00159                 return false;
00160             }
00161         }
00162 
00163         // Else finer clip with pyramid, only if needed
00164         if(clipTrav.ForceNoFrustumClip)
00165             return true;
00166         else
00167             return Shape->clip(clipTrav.WorldPyramid, getWorldMatrix());
00168     }
00169     else
00170         return false;
00171 }
00172 
00173 
00174 // ***************************************************************************
00175 void    CTransformShape::traverseRender()
00176 {
00177     H_AUTO( NL3D_TrShape_Render );
00178 
00179 
00180     // Compute the current lighting setup for this instance
00181     //===================
00182 
00183 
00184     // if the transform is lightable (ie not a fully lightmaped model), setup lighting
00185     if(isLightable())
00186     {
00187         // useLocalAttenuation for this shape ??
00188         if(Shape)
00189             _CurrentUseLocalAttenuation= Shape->useLightingLocalAttenuation ();
00190         else
00191             _CurrentUseLocalAttenuation= false;
00192 
00193         // the std case is to take my model lightContribution
00194         if(_AncestorSkeletonModel==NULL)
00195             _CurrentLightContribution= &getLightContribution();
00196         // but if skinned/sticked (directly or not) to a skeleton, take its.
00197         else
00198             _CurrentLightContribution= &((CTransformShape*)_AncestorSkeletonModel)->getLightContribution();
00199     }
00200     // else must disable the lightSetup
00201     else
00202     {
00203         // setting NULL will disable all lights
00204         _CurrentLightContribution= NULL;
00205         _CurrentUseLocalAttenuation= false;
00206     }
00207 
00208 
00209     // render the shape.
00210     //=================
00211     if(Shape)
00212     {
00213         CRenderTrav         &rdrTrav= getOwnerScene()->getRenderTrav();
00214         bool                currentPassOpaque= rdrTrav.isCurrentPassOpaque();
00215 
00216         // shape must be rendered in a CMeshBlockManager ??
00217         float polygonCount = 0.f;
00218         IMeshGeom   *meshGeom= NULL;
00219         // true only if in pass opaque
00220         if( currentPassOpaque )
00221             meshGeom= Shape->supportMeshBlockRendering(this, polygonCount);
00222 
00223         // if ok, add the meshgeom to the block manager.
00224         if(meshGeom)
00225         {
00226             CMeshBaseInstance   *inst= safe_cast<CMeshBaseInstance*>(this);
00227             rdrTrav.MeshBlockManager.addInstance(meshGeom, inst, polygonCount);
00228         }
00229         // else render it.
00230         else
00231         {
00232             // setup the lighting
00233             changeLightSetup( &rdrTrav );
00234 
00235             // render the shape.
00236             IDriver             *drv= rdrTrav.getDriver();
00237             Shape->render( drv, this, currentPassOpaque );
00238         }
00239     }
00240 }
00241 
00242 
00243 // ***************************************************************************
00244 void    CTransformShape::profileRender()
00245 {
00246     // profile the shape.
00247     if(Shape)
00248     {
00249         CRenderTrav         &rdrTrav= getOwnerScene()->getRenderTrav();
00250         bool                currentPassOpaque= rdrTrav.isCurrentPassOpaque();
00251 
00252         Shape->profileSceneRender( &rdrTrav, this, currentPassOpaque );
00253     }
00254 }
00255 
00256 
00257 // ***************************************************************************
00258 void    CTransformShape::traverseLoadBalancing()
00259 {
00260     CLoadBalancingTrav      &loadTrav= getOwnerScene()->getLoadBalancingTrav();
00261     if(loadTrav.getLoadPass()==0)
00262         traverseLoadBalancingPass0();
00263     else
00264         traverseLoadBalancingPass1();
00265 }
00266 
00267 
00268 
00269 // ***************************************************************************
00270 void    CTransformShape::traverseLoadBalancingPass0()
00271 {
00272     CLoadBalancingTrav      &loadTrav= getOwnerScene()->getLoadBalancingTrav();
00273     CSkeletonModel          *skeleton= getSkeletonModel();
00274 
00275     // World Model position
00276     const CVector       *modelPos;
00277 
00278     // If this isntance is binded or skinned to a skeleton, take the world matrix of this one as
00279     // center for LoadBalancing Resolution.
00280     if(skeleton)
00281     {
00282         // Take the root bone of the skeleton as reference (bone 0)
00283         // And so get our position.
00284         modelPos= &skeleton->Bones[0].getWorldMatrix().getPos();
00285     }
00286     else
00287     {
00288         // get our position from
00289         modelPos= &getWorldMatrix().getPos();
00290     }
00291 
00292 
00293     // Then compute distance from camera.
00294     float   modelDist= ( loadTrav.CamPos - *modelPos).norm();
00295 
00296 
00297     // Get the number of triangles this model use now.
00298     _FaceCount= getNumTriangles(modelDist);
00299     _LoadBalancingGroup->addNbFacesPass0(_FaceCount);
00300 }
00301 
00302 
00303 // ***************************************************************************
00304 void    CTransformShape::traverseLoadBalancingPass1()
00305 {
00306     // Set the result into the isntance.
00307     _NumTrianglesAfterLoadBalancing= _LoadBalancingGroup->computeModelNbFace(_FaceCount);
00308 
00309 }
00310 
00311 // ***************************************************************************
00312 void    CTransformShape::getLightHotSpotInWorld(CVector &modelPos, float &modelRadius) const
00313 {
00314     /*
00315     // get the untransformed bbox from the model.
00316     CAABBox     bbox;
00317     getAABBox(bbox);
00318     // get transformed center pos of bbox
00319     modelPos= getWorldMatrix() * bbox.getCenter();
00320     // If the model is a big lightable, must take radius from aabbox, else suppose 0 radius.
00321     if(isBigLightable())
00322     {
00323         // get size of the bbox (bounding sphere)
00324         modelRadius= bbox.getRadius();
00325     }
00326     else
00327     {
00328         // Assume 0 radius => faster computeLinearAttenuation()
00329         modelRadius= 0;
00330     }
00331     */
00332 
00333     // This method works well for Big Trees.
00334     // TODO: generalize, saving a LightHotSpot per shape.
00335 
00336     // get pos of object. Ie the hotSpot is the pivot.
00337     modelPos= getWorldMatrix().getPos();
00338     // If the model is a big lightable, must take radius from aabbox, else suppose 0 radius.
00339     if(isBigLightable())
00340     {
00341         // get the untransformed bbox from the model.
00342         CAABBox     bbox;
00343         getAABBox(bbox);
00344         // get size of the bbox (bounding sphere)
00345         modelRadius= bbox.getRadius();
00346     }
00347     else
00348     {
00349         // Assume 0 radius => faster computeLinearAttenuation()
00350         modelRadius= 0;
00351     }
00352 
00353 }
00354 
00355 
00356 } // NL3D

Generated on Thu Jan 7 08:26:31 2010 for NeL by  doxygen 1.6.1