From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/mesh__multi__lod_8cpp-source.html | 747 +++++++++++++++++++++ 1 file changed, 747 insertions(+) create mode 100644 docs/doxygen/nel/mesh__multi__lod_8cpp-source.html (limited to 'docs/doxygen/nel/mesh__multi__lod_8cpp-source.html') diff --git a/docs/doxygen/nel/mesh__multi__lod_8cpp-source.html b/docs/doxygen/nel/mesh__multi__lod_8cpp-source.html new file mode 100644 index 00000000..6f4da03f --- /dev/null +++ b/docs/doxygen/nel/mesh__multi__lod_8cpp-source.html @@ -0,0 +1,747 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# 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  
+

mesh_multi_lod.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 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 "3d/mesh_multi_lod.h"
+00029 #include "3d/mesh_multi_lod_instance.h"
+00030 #include "3d/mesh_instance.h"
+00031 #include "3d/mesh_mrm.h"
+00032 #include "3d/scene.h"
+00033 #include "3d/coarse_mesh_manager.h"
+00034 #include "3d/skeleton_model.h"
+00035 #include "3d/fast_floor.h"
+00036 #include "3d/mesh_blender.h"
+00037 
+00038 #include "nel/misc/debug.h"
+00039 
+00040 using namespace NLMISC;
+00041 
+00042 namespace NL3D 
+00043 {
+00044 
+00045 
+00046 
+00047 
+00048 // ***************************************************************************
+00049 
+00050 void CMeshMultiLod::build(CMeshMultiLodBuild &mbuild)
+00051 {
+00052         // Clear the mesh
+00053         clear ();
+00054 
+00055         // Build the base mesh
+00056         CMeshBase::buildMeshBase (mbuild.BaseMesh);
+00057 
+00058         // Static flag
+00059         _StaticLod=mbuild.StaticLod;
+00060 
+00061         // Resize the array
+00062         _MeshVector.resize (mbuild.LodMeshes.size());
+00063 
+00064         // Number of coarse meshes
+00065         uint coarse=0;
+00066 
+00067         // For each slots
+00068         for (uint slot=0; slot<mbuild.LodMeshes.size(); slot++)
+00069         {
+00070                 // Dist max
+00071                 _MeshVector[slot].DistMax=mbuild.LodMeshes[slot].DistMax;
+00072 
+00073                 // BlendLength
+00074                 _MeshVector[slot].BlendLength=mbuild.LodMeshes[slot].BlendLength;
+00075 
+00076                 // Flags
+00077                 _MeshVector[slot].Flags=0;
+00078 
+00079                 // Blend in ?
+00080                 if (mbuild.LodMeshes[slot].Flags & CMeshMultiLodBuild::CBuildSlot::BlendIn)
+00081                         _MeshVector[slot].Flags|=CMeshSlot::BlendIn;
+00082 
+00083                 // Blend out ?
+00084                 if (mbuild.LodMeshes[slot].Flags & CMeshMultiLodBuild::CBuildSlot::BlendOut)
+00085                         _MeshVector[slot].Flags|=CMeshSlot::BlendOut;
+00086 
+00087                 // Coarse mesh ?
+00088                 if (mbuild.LodMeshes[slot].Flags & CMeshMultiLodBuild::CBuildSlot::CoarseMesh)
+00089                 {
+00090                         // Warning: no more than 2 coarse meshes in a lod mesh!
+00091                         nlassert (coarse<=1);
+00092 
+00093                         // Flag
+00094                         _MeshVector[slot].Flags|=CMeshSlot::CoarseMesh;
+00095 
+00096                         // Flag coarse ID
+00097                         if (coarse==1)
+00098                                 _MeshVector[slot].Flags|=CMeshSlot::CoarseMeshId;
+00099 
+00100                         // One more
+00101                         coarse++;
+00102                 }
+00103 
+00104                 // Is opaque
+00105                 if (mbuild.LodMeshes[slot].Flags & CMeshMultiLodBuild::CBuildSlot::IsOpaque)
+00106                         _MeshVector[slot].Flags|=CMeshSlot::IsOpaque;
+00107 
+00108                 // Is transparent
+00109                 if (mbuild.LodMeshes[slot].Flags & CMeshMultiLodBuild::CBuildSlot::IsTransparent)
+00110                         _MeshVector[slot].Flags|=CMeshSlot::IsTransparent;
+00111 
+00112                 // MeshGeom
+00113                 nlassert (mbuild.LodMeshes[slot].MeshGeom);
+00114 
+00115                 // Valid pointer ?
+00116                 if (_MeshVector[slot].Flags&CMeshSlot::CoarseMesh)
+00117                 {
+00118                         // If it is a coarse mesh, it must be a CMeshGeom.
+00119                         if (dynamic_cast<CMeshGeom*>(mbuild.LodMeshes[slot].MeshGeom)==NULL)
+00120                         {
+00121                                 // If it is a coarse mesh, it must be a CMeshGeom.
+00122                                 _MeshVector[slot].MeshGeom = NULL;
+00123                                 delete mbuild.LodMeshes[slot].MeshGeom;
+00124                         }
+00125                         else
+00126                                 // Ok, no prb
+00127                                 _MeshVector[slot].MeshGeom = mbuild.LodMeshes[slot].MeshGeom;
+00128                 }
+00129                 else
+00130                         // Ok, no prb
+00131                         _MeshVector[slot].MeshGeom = mbuild.LodMeshes[slot].MeshGeom;   
+00132         }
+00133 
+00134         // Sort the slot by the distance...
+00135         for (int i=mbuild.LodMeshes.size()-1; i>0; i--)
+00136         for (int j=0; j<i; j++)
+00137         {
+00138                 // Bad sort ?
+00139                 if (_MeshVector[j].DistMax>_MeshVector[j+1].DistMax)
+00140                 {
+00141                         // Exchange slots
+00142                         CMeshSlot tmp=_MeshVector[j];
+00143                         _MeshVector[j]=_MeshVector[j+1];
+00144                         _MeshVector[j+1]=tmp;
+00145                         tmp.MeshGeom=NULL;
+00146                 }
+00147         }
+00148 
+00149         // Calc start and end polygon count
+00150         for (uint k=0; k<mbuild.LodMeshes.size(); k++)
+00151         {
+00152                 // Get start distance
+00153                 float startDist;
+00154                 if (k==0)
+00155                         startDist=0;
+00156                 else 
+00157                         startDist=_MeshVector[k-1].DistMax;
+00158 
+00159                 // Get start poly count
+00160                 float startPolyCount;
+00161                 startPolyCount=_MeshVector[k].MeshGeom->getNumTriangles (startDist);
+00162 
+00163                 // Get end distance
+00164                 float endDist=_MeshVector[k].DistMax;
+00165 
+00166                 // Get end poly count
+00167                 if (k==mbuild.LodMeshes.size()-1)
+00168                 {
+00169                         _MeshVector[k].EndPolygonCount=_MeshVector[k].MeshGeom->getNumTriangles (endDist);
+00170                         if (startPolyCount==_MeshVector[k].EndPolygonCount)
+00171                                 _MeshVector[k].EndPolygonCount=startPolyCount/2;
+00172                 }
+00173                 else 
+00174                         _MeshVector[k].EndPolygonCount=_MeshVector[k+1].MeshGeom->getNumTriangles (endDist);
+00175 
+00176                 // Calc A
+00177                 if (endDist==startDist)
+00178                         _MeshVector[k].A=0;
+00179                 else
+00180                         _MeshVector[k].A=(_MeshVector[k].EndPolygonCount-startPolyCount)/(endDist-startDist);
+00181 
+00182                 // Calc A
+00183                 _MeshVector[k].B=_MeshVector[k].EndPolygonCount-_MeshVector[k].A*endDist;
+00184         }
+00185 
+00186         // End: compile the max distance of display
+00187         compileDistMax();
+00188 }
+00189 
+00190 // ***************************************************************************
+00191 
+00192 CTransformShape *CMeshMultiLod::createInstance(CScene &scene)
+00193 {
+00194         // Create a CMeshInstance, an instance of a multi lod mesh.
+00195         CMeshMultiLodInstance *mi=(CMeshMultiLodInstance*)scene.createModel(NL3D::MeshMultiLodInstanceId);
+00196         mi->Shape= this;
+00197         mi->_LastLodMatrixDate[0]=0;
+00198         mi->_LastLodMatrixDate[1]=0;
+00199 
+00200         // instanciate the material part of the Mesh, ie the CMeshBase.
+00201         CMeshBase::instanciateMeshBase(mi, &scene);
+00202 
+00203 
+00204         // For all lods, do some instance init for MeshGeom
+00205         for(uint i=0; i<_MeshVector.size(); i++)
+00206         {
+00207                 if(_MeshVector[i].MeshGeom)
+00208                         _MeshVector[i].MeshGeom->initInstance(mi);
+00209         }
+00210 
+00211 
+00212         return mi;
+00213 }
+00214 
+00215 // ***************************************************************************
+00216 
+00217 bool CMeshMultiLod::clip(const std::vector<CPlane>      &pyramid, const CMatrix &worldMatrix)
+00218 {
+00219         // Look for the biggest mesh
+00220         uint meshCount=_MeshVector.size();
+00221         for (uint i=0; i<meshCount; i++)
+00222         {
+00223                 // Ref on slot
+00224                 CMeshSlot &slot=_MeshVector[i];
+00225 
+00226                 // Is mesh present ?
+00227                 if (slot.MeshGeom)
+00228                 {
+00229                         // Clip this mesh
+00230                         return slot.MeshGeom->clip (pyramid, worldMatrix);
+00231                 }
+00232         }
+00233         return true;
+00234 }
+00235 
+00236 // ***************************************************************************
+00237 
+00238 void CMeshMultiLod::render(IDriver *drv, CTransformShape *trans, bool passOpaque)
+00239 {
+00240         // Render good meshes
+00241         CMeshMultiLodInstance *instance=safe_cast<CMeshMultiLodInstance*>(trans);
+00242 
+00243         // Static or dynamic coarse mesh ?
+00244         CCoarseMeshManager *manager;
+00245         if (_StaticLod)
+00246         {
+00247                 // Get the static coarse mesh manager
+00248                 manager=instance->getScene()->getStaticCoarseMeshManager();
+00249         }
+00250         else
+00251         {
+00252                 // Get the dynamic coarse mesh manager
+00253                 manager=instance->getScene()->getDynamicCoarseMeshManager();
+00254         }
+00255 
+00256         // *** Render Lods
+00257 
+00258         // Second lod ?
+00259         if ( (instance->Lod1!=0xffffffff) && (passOpaque==false) )
+00260         {
+00261                 // build rdrFlags to rdr both transparent and opaque materials, 
+00262                 // use globalAlphaBlend, and disable ZWrite for Lod1
+00263                 uint32  rdrFlags= IMeshGeom::RenderOpaqueMaterial | IMeshGeom::RenderTransparentMaterial |
+00264                         IMeshGeom::RenderGlobalAlpha | IMeshGeom::RenderGADisableZWrite;
+00265                 // NB: very important to render Lod1 first, because Lod0 is still rendered with ZWrite enabled.
+00266                 renderMeshGeom (instance->Lod1, drv, instance, instance->PolygonCountLod1, rdrFlags, 1.f-instance->BlendFactor, manager);
+00267         }
+00268 
+00269 
+00270         // Have an opaque pass ?
+00271         if ( (instance->Flags&CMeshMultiLodInstance::Lod0Blend) == 0)
+00272         {
+00273                 // Is this slot a CoarseMesh?
+00274                 if ( _MeshVector[instance->Lod0].Flags&CMeshSlot::CoarseMesh )
+00275                 {
+00276                         // render as a CoarseMesh the lod 0, only in opaque pass
+00277                         if(passOpaque)
+00278                                 renderCoarseMesh (instance->Lod0, drv, instance, manager);
+00279                 }
+00280                 else
+00281                 {
+00282                         // build rdrFlags the normal way (as CMesh::render() for example)
+00283                         uint32  mask= (0-(uint32)passOpaque);
+00284                         uint32  rdrFlags;
+00285                         // select rdrFlags, without ifs.
+00286                         rdrFlags=       mask & (IMeshGeom::RenderOpaqueMaterial | IMeshGeom::RenderPassOpaque);
+00287                         rdrFlags|=      ~mask & (IMeshGeom::RenderTransparentMaterial);
+00288                         // Only render the normal way the first lod
+00289                         renderMeshGeom (instance->Lod0, drv, instance, instance->PolygonCountLod0, rdrFlags, 1, manager);
+00290                 }
+00291         }
+00292         else
+00293         {
+00294                 // Should not be in opaque
+00295                 nlassert (passOpaque==false);
+00296 
+00297                 // build rdrFlags to rdr both transparent and opaque materials, 
+00298                 // use globalAlphaBlend, BUT Don't disable ZWrite for Lod0
+00299                 uint32  rdrFlags= IMeshGeom::RenderOpaqueMaterial | IMeshGeom::RenderTransparentMaterial |
+00300                         IMeshGeom::RenderGlobalAlpha;
+00301 
+00302                 // Render first lod in blend mode. Don't disable ZWrite for Lod0
+00303                 renderMeshGeom (instance->Lod0, drv, instance, instance->PolygonCountLod0, rdrFlags, instance->BlendFactor, manager);
+00304         }
+00305 
+00306         // *** Remove unused coarse meshes.
+00307         // Manager must exist beacuse a mesh has been loaded...
+00308         if (manager)
+00309         {
+00310                 uint meshCount=_MeshVector.size();
+00311                 for (uint j=0; j<meshCount; j++)
+00312                 {
+00313                         // Is this slot a CoarseMesh?
+00314                         if ( _MeshVector[j].Flags&CMeshSlot::CoarseMesh )
+00315                         {
+00316                                 // Are we in Alpha Blend Transition?
+00317                                 bool    alphaTrans= instance->Flags&CMeshMultiLodInstance::Lod0Blend;
+00318                                 // we must remove coarse if the slot is not used, or if we are in Alpha Transition.
+00319                                 // NB: only Lod0 can use CoarseMesh (see code before)
+00320                                 if ( alphaTrans || (j!=instance->Lod0) )
+00321                                 {
+00322                                         // Get coarse id
+00323                                         uint coarseId=(_MeshVector[j].Flags&CMeshSlot::CoarseMeshId)?1:0;
+00324                                         uint flag=CMeshMultiLodInstance::Coarse0Loaded<<coarseId;
+00325                                         
+00326                                         // Coarse mesh loaded ?
+00327                                         if ( instance->Flags&flag )
+00328                                         {
+00329                                                 // Yes, remove it..
+00330 
+00331                                                 // Remove the lod
+00332                                                 manager->removeMesh (instance->CoarseMeshId[coarseId]);
+00333 
+00334                                                 // Clear the flag
+00335                                                 instance->Flags&=~flag;
+00336                                         }
+00337                                 }
+00338                         }
+00339                 }
+00340         }
+00341 }
+00342 
+00343 // ***************************************************************************
+00344 
+00345 void CMeshMultiLod::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
+00346 {
+00347         // Serial a version number
+00348         (void)f.serialVersion (0);
+00349 
+00350         // serial Materials infos contained in CMeshBase.
+00351         CMeshBase::serialMeshBase(f);
+00352 
+00353         // Static lod flag
+00354         f.serial (_StaticLod);
+00355 
+00356         // Serial the values
+00357         f.serialCont (_MeshVector);
+00358 
+00359 
+00360         // if reading, compile the new max distance of display
+00361         if (f.isReading())
+00362         {
+00363                 compileDistMax();
+00364         }
+00365 }
+00366 
+00367 // ***************************************************************************
+00368 
+00369 float CMeshMultiLod::getNumTriangles (float distance)
+00370 {
+00371         // Look in the table for good distances..
+00372         uint meshCount=_MeshVector.size();
+00373 
+00374         // At least on mesh
+00375         if (meshCount>0)
+00376         {
+00377                 uint i=0;
+00378 
+00379                 // Look for good i
+00380                 while ( _MeshVector[i].DistMax<distance )
+00381                 {
+00382                         if (i==meshCount-1)
+00383                                 // Abort if last one
+00384                                 break;
+00385                         i++;
+00386                 }
+00387 
+00388                 // Ref on slot
+00389                 CMeshSlot &slot=_MeshVector[i];
+00390 
+00391                 // Is mesh present ?
+00392                 if (slot.MeshGeom)
+00393                 {
+00394                         // Get the polygon count with the distance
+00395                         float polyCount=slot.A * distance + slot.B;
+00396 
+00397                         /*// Get the perfect polygon count in this slot for the asked distance
+00398                         float goodPolyCount=slot.MeshGeom->getNumTriangles (distance);
+00399 
+00400                         // Get the next slot perfect polygon count
+00401                         float realEndPolyCount;
+00402 
+00403                         // Last slot ?
+00404                         if ( (i<meshCount-1) && _MeshVector[i+1].MeshGeom )
+00405                                 // Take end number polygon count in the next slot
+00406                                 realEndPolyCount=_MeshVector[i+1].MeshGeom->getNumTriangles (slot.DistMax);
+00407                         else
+00408                                 // Take end number polygon count in the this slot
+00409                                 realEndPolyCount=slot.EndPolygonCount;
+00410 
+00411                         // Return blended polygon count to have a continous decreasing function
+00412                         return (goodPolyCount-slot.BeginPolygonCount) * (realEndPolyCount-slot.BeginPolygonCount) / 
+00413                                 (slot.EndPolygonCount-slot.BeginPolygonCount) + slot.BeginPolygonCount;*/
+00414                         return polyCount;
+00415                 }
+00416         }
+00417 
+00418         return 0;
+00419 }
+00420 
+00421 // ***************************************************************************
+00422 
+00423 void CMeshMultiLod::getAABBox(NLMISC::CAABBox &bbox) const
+00424 {
+00425         // Get count
+00426         uint count=_MeshVector.size();
+00427         for (uint slot=0; slot<count; slot++)
+00428         {
+00429                 // Shape ?
+00430                 if (_MeshVector[slot].MeshGeom)
+00431                 {
+00432                         // Get the bounding box
+00433                         bbox=_MeshVector[slot].MeshGeom->getBoundingBox().getAABBox();
+00434 
+00435                         // ok
+00436                         break;
+00437                 }
+00438         }
+00439 }
+00440 
+00441 // ***************************************************************************
+00442 
+00443 void CMeshMultiLod::clear ()
+00444 {
+00445         _MeshVector.clear ();
+00446 }
+00447 
+00448 // ***************************************************************************
+00449 
+00450 void CMeshMultiLod::CMeshSlot::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
+00451 {
+00452         // Check version
+00453         (void)f.serialVersion (0);
+00454 
+00455         f.serialPolyPtr (MeshGeom);
+00456         f.serial (A);
+00457         f.serial (B);
+00458         f.serial (DistMax);
+00459         f.serial (EndPolygonCount);
+00460         f.serial (BlendLength);
+00461         f.serial (Flags);
+00462 
+00463         if (f.isReading())
+00464         {
+00465         }
+00466 }
+00467 
+00468 // ***************************************************************************
+00469 
+00470 CMeshMultiLod::CMeshSlot::CMeshSlot ()
+00471 {
+00472         MeshGeom=NULL;
+00473 }
+00474 
+00475 // ***************************************************************************
+00476 
+00477 CMeshMultiLod::CMeshSlot::~CMeshSlot ()
+00478 {
+00479         if (MeshGeom)
+00480                 delete MeshGeom;
+00481 }
+00482 
+00483 // ***************************************************************************
+00484 
+00485 void CMeshMultiLod::renderMeshGeom (uint slot, IDriver *drv, CMeshMultiLodInstance *trans, float numPoylgons, uint32 rdrFlags, float alpha, CCoarseMeshManager *manager)
+00486 {
+00487         // Ref
+00488         CMeshSlot &slotRef=_MeshVector[slot];
+00489 
+00490         // MeshGeom exist?
+00491         if (slotRef.MeshGeom)
+00492         {
+00493                 // NB Here, the meshGeom may still be a coarseMesh, but rendered through CMeshGeom
+00494                 if(slotRef.Flags&CMeshSlot::CoarseMesh)
+00495                 {
+00496                         // Render only for opaque material
+00497                         if(manager && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) )
+00498                         {
+00499                                 bool    gaDisableZWrite= (rdrFlags & IMeshGeom::RenderGADisableZWrite)?true:false;
+00500 
+00501                                 // Render the CoarseMesh with the manager material
+00502                                 CMaterial       &material= manager->getMaterial();
+00503 
+00504                                 // modulate material for alphaBlend transition
+00505                                 // ----------
+00506                                 // get average sun color for this coarseMesh
+00507                                 CRGBA   newCol= trans->getCoarseMeshLighting();
+00508 
+00509                                 // Use a CMeshBlender to modify material and driver.
+00510                                 CMeshBlender    blender;
+00511                                 blender.prepareRenderForGlobalAlphaCoarseMesh(material, drv, newCol, alpha, gaDisableZWrite);
+00512                                 
+00513 
+00514                                 // render simple the coarseMesh
+00515                                 CMeshGeom *meshGeom= safe_cast<CMeshGeom*>(slotRef.MeshGeom);
+00516                                 meshGeom->renderSimpleWithMaterial(drv, trans->getWorldMatrix(), material);
+00517 
+00518 
+00519                                 // resetup standard CoarseMeshMaterial material values
+00520                                 // ----------
+00521                                 // blender restore
+00522                                 blender.restoreRenderCoarseMesh(material, drv, gaDisableZWrite);
+00523                         }
+00524                 }
+00525                 else
+00526                 {
+00527                         // Render the geom mesh
+00528                         // Disable ZWrite only if in transition and for rendering Lod1
+00529                         slotRef.MeshGeom->render (drv, trans, numPoylgons, rdrFlags, alpha);
+00530                 }
+00531         }
+00532 }
+00533 // ***************************************************************************
+00534 
+00535 void CMeshMultiLod::renderCoarseMesh (uint slot, IDriver *drv, CMeshMultiLodInstance *trans, CCoarseMeshManager *manager)
+00536 {
+00537         // if the manager is NULL, quit.
+00538         if(manager==NULL)
+00539                 return;
+00540 
+00541         // Ref
+00542         CMeshSlot &slotRef=_MeshVector[slot];
+00543 
+00544         // the slot must be a Coarse mesh
+00545         nlassert(slotRef.Flags&CMeshSlot::CoarseMesh);
+00546 
+00547         // Mask
+00548         uint coarseId=(slotRef.Flags&CMeshSlot::CoarseMeshId)?1:0;
+00549         uint maskFlag = CMeshMultiLodInstance::Coarse0Loaded<<coarseId;
+00550 
+00551         // Get a pointer on the geom mesh
+00552         CMeshGeom *meshGeom= safe_cast<CMeshGeom*>(slotRef.MeshGeom);
+00553 
+00554         // Added in the manager ?
+00555         if ( (trans->Flags&maskFlag) == 0)
+00556         {
+00557                 // Add to the manager
+00558                 trans->CoarseMeshId[coarseId]=manager->addMesh (*meshGeom);
+00559                         
+00560                 // Added ?
+00561                 if (trans->CoarseMeshId[coarseId]!=CCoarseMeshManager::CantAddCoarseMesh)
+00562                         // Flag it
+00563                         trans->Flags|=maskFlag;
+00564 
+00565                 // Dirt the matrix
+00566                 trans->_LastLodMatrixDate[coarseId]=0;
+00567                 // Dirt the lighting. NB: period maximum is 255. Hence the -256, to ensure lighting compute now
+00568                 trans->_LastLodLightingDate[coarseId]= -0x100;
+00569         }
+00570 
+00571         // Finally loaded ?
+00572         if (trans->Flags&maskFlag)
+00573         {
+00574                 // Matrix has changed ?
+00575                 if ( trans->ITransformable::compareMatrixDate (trans->_LastLodMatrixDate[coarseId]) )
+00576                 {
+00577                         // Get date
+00578                         trans->_LastLodMatrixDate[coarseId] = trans->ITransformable::getMatrixDate();
+00579 
+00580                         // Set matrix
+00581                         manager->setMatrixMesh ( trans->CoarseMeshId[coarseId], *meshGeom, trans->getMatrix() );
+00582                 }
+00583 
+00584                 // Lighting: test if must update lighting, according to date of HrcTrav (num of CScene::render() call).
+00585                 CScene  *scene= trans->getScene();
+00586                 if(scene)
+00587                 {
+00588                         sint64  currentDate= scene->getHrcTrav()->CurrentDate;
+00589                         if( trans->_LastLodLightingDate[coarseId] < currentDate - scene->getCoarseMeshLightingUpdate() )
+00590                         {
+00591                                 // reset the date.
+00592                                 trans->_LastLodLightingDate[coarseId]= currentDate;
+00593 
+00594                                 // get average sun color
+00595                                 CRGBA   sunContrib= trans->getCoarseMeshLighting();
+00596 
+00597                                 // Set color
+00598                                 manager->setColorMesh ( trans->CoarseMeshId[coarseId], *meshGeom, sunContrib );
+00599                         }
+00600                 }
+00601         }
+00602 }
+00603 
+00604 // ***************************************************************************
+00605 void    CMeshMultiLod::compileDistMax()
+00606 {
+00607         // Last element
+00608         std::vector<CMeshSlot>::const_iterator ite=_MeshVector.end();
+00609         ite--;
+00610         if (ite!=_MeshVector.end())
+00611                 IShape::_DistMax= ite->DistMax;
+00612         else
+00613                 IShape::_DistMax= -1;
+00614 }
+00615 
+00616 // ***************************************************************************
+00617 const IMeshGeom& CMeshMultiLod::getMeshGeom (uint slot) const
+00618 {
+00619         // Checks
+00620         nlassert (slot<getNumSlotMesh ());
+00621 
+00622         return *_MeshVector[slot].MeshGeom;
+00623 }
+00624 
+00625 
+00626 // ***************************************************************************
+00627 void                    CMeshMultiLod::changeMRMDistanceSetup(float distanceFinest, float distanceMiddle, float distanceCoarsest)
+00628 {
+00629         // no-op if empty.
+00630         if(getNumSlotMesh ()==0)
+00631                 return;
+00632 
+00633         // If not NULL
+00634         if(_MeshVector[0].MeshGeom==NULL)
+00635                 return;
+00636 
+00637         // verify it is a CMeshMRMGeom. else no-op.
+00638         CMeshMRMGeom    *mgeom= dynamic_cast<CMeshMRMGeom*>(_MeshVector[0].MeshGeom);
+00639         if(mgeom==NULL)
+00640                 return;
+00641         
+00642         // ok, setup.
+00643         mgeom->changeMRMDistanceSetup(distanceFinest, distanceMiddle, distanceCoarsest);
+00644 }
+00645 
+00646 
+00647 // ***************************************************************************
+00648 IMeshGeom               *CMeshMultiLod::supportMeshBlockRendering (CTransformShape *trans, float &polygonCount ) const
+00649 {
+00650         IMeshGeom       *ret= NULL;
+00651 
+00652         // get the instance
+00653         CMeshMultiLodInstance *instance=safe_cast<CMeshMultiLodInstance*>(trans);
+00654 
+00655         // Must not be in blend transition.
+00656         if ( (instance->Flags&CMeshMultiLodInstance::Lod0Blend) == 0)
+00657         {
+00658                 uint    slot= instance->Lod0;
+00659                 // The slot must not be a CoarseMesh
+00660                 if ( (_MeshVector[slot].Flags&CMeshSlot::CoarseMesh)==0 )
+00661                 {
+00662                         // MeshGeom exist?
+00663                         ret= _MeshVector[slot].MeshGeom;
+00664                 }
+00665         }
+00666 
+00667         // Ok if meshGeom is ok.
+00668         if( ret && ret->supportMeshBlockRendering() )
+00669         {
+00670                 polygonCount= instance->PolygonCountLod0;
+00671                 return ret;
+00672         }
+00673         else
+00674                 return NULL;
+00675 }
+00676 
+00677 
+00678 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1