# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

transform_shape.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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         // By default all transformShape are LoadBalancable
00065         CTransform::setIsLoadbalancable(true);
00066 
00067         // The model is renderable
00068         CTransform::setIsRenderable(true);
00069 }
00070 
00071 
00072 // ***************************************************************************
00073 float           CTransformShape::getNumTriangles (float distance)
00074 {
00075         // Call shape method
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         // setup the instance lighting.
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         // reset
00138         _ClipDueToDistMax= false;
00139 
00140         if(m->Shape)
00141         {
00142                 // first test DistMax (faster).
00143                 float maxDist = m->getDistMax();
00144                 // if DistMax test enabled
00145                 if(maxDist!=-1)
00146                 {
00147                         // Calc the distance
00148                         float sqrDist = (trav->CamPos - m->getMatrix().getPos()).sqrnorm ();
00149                         maxDist*=maxDist;
00150                         
00151                         // if dist > maxDist, skip
00152                         if (sqrDist > maxDist)
00153                         {
00154                                 // flag this state
00155                                 _ClipDueToDistMax= true;
00156                                 // Ok, not shown
00157                                 return false;
00158                         }
00159                 }
00160 
00161                 // Else finer clip with pyramid, only if needed
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         // Compute the current lighting setup for this instance
00182         //===================
00183 
00184         // if the transform is lightable (ie not a fully lightmaped model), setup lighting
00185         if(m->isLightable())
00186         {
00187                 // useLocalAttenuation for this shape ??
00188                 if(m->Shape)
00189                         m->_CurrentUseLocalAttenuation= m->Shape->useLightingLocalAttenuation ();
00190                 else
00191                         m->_CurrentUseLocalAttenuation= false;
00192 
00193                 // Get HrcObs.
00194                 CTransformHrcObs        *hrcObs= (CTransformHrcObs*)HrcObs;
00195 
00196                 // the std case is to take my model lightContribution
00197                 if(hrcObs->_AncestorSkeletonModel==NULL)
00198                         m->_CurrentLightContribution= &m->getLightContribution();
00199                 // but if skinned/sticked (directly or not) to a skeleton, take its.
00200                 else
00201                         m->_CurrentLightContribution= &hrcObs->_AncestorSkeletonModel->getLightContribution();
00202         }
00203         // else must disable the lightSetup
00204         else
00205         {
00206                 // setting NULL will disable all lights
00207                 m->_CurrentLightContribution= NULL;
00208                 m->_CurrentUseLocalAttenuation= false;
00209         }
00210 
00211 
00212         // render the shape.
00213         //=================
00214         if(m->Shape)
00215         {
00216                 CRenderTrav                     *rdrTrav= (CRenderTrav*)Trav;
00217                 bool                            currentPassOpaque= rdrTrav->isCurrentPassOpaque();
00218 
00219                 // shape must be rendered in a CMeshBlockManager ??
00220                 float polygonCount;
00221                 IMeshGeom       *meshGeom= NULL;
00222                 // true only if in pass opaque
00223                 if( currentPassOpaque )
00224                         meshGeom= m->Shape->supportMeshBlockRendering(m, polygonCount);
00225 
00226                 // if ok, add the meshgeom to the block manager.
00227                 if(meshGeom)
00228                 {
00229                         CMeshBaseInstance       *inst= safe_cast<CMeshBaseInstance*>(m);
00230                         rdrTrav->MeshBlockManager.addInstance(meshGeom, inst, polygonCount);
00231                 }
00232                 // else render it.
00233                 else
00234                 {
00235                         // setup the lighting
00236                         m->changeLightSetup( rdrTrav );
00237 
00238                         // render the shape.
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         // There is no reason to do a hierarchy for LoadBalancing. => no traverseSons()
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         // World Model position
00268         const CVector           *modelPos;
00269 
00270         // If this isntance is binded or skinned to a skeleton, take the world matrix of this one as
00271         // center for LoadBalancing Resolution.
00272         if(skeleton)
00273         {
00274                 // Take the root bone of the skeleton as reference (bone 0)
00275                 // And so get our position.
00276                 modelPos= &skeleton->Bones[0].getWorldMatrix().getPos();
00277         }
00278         else
00279         {
00280                 // get our position from 
00281                 modelPos= &HrcObs->WorldMatrix.getPos();
00282         }
00283 
00284 
00285         // Then compute distance from camera.
00286         float   modelDist= ( loadTrav->CamPos - *modelPos).norm();
00287 
00288 
00289         // Get the number of triangles this model use now.
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         // Set the result into the isntance.
00302         trans->_NumTrianglesAfterLoadBalancing= LoadBalancingGroup->computeModelNbFace(_FaceCount);
00303 
00304 }
00305 
00306 
00307 } // NL3D