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/3d_zone_cpp-source.html | 1184 ++++++++++++++++++++++++++++++ 1 file changed, 1184 insertions(+) create mode 100644 docs/doxygen/nel/3d_zone_cpp-source.html (limited to 'docs/doxygen/nel/3d_zone_cpp-source.html') diff --git a/docs/doxygen/nel/3d_zone_cpp-source.html b/docs/doxygen/nel/3d_zone_cpp-source.html new file mode 100644 index 00000000..b1afd882 --- /dev/null +++ b/docs/doxygen/nel/3d_zone_cpp-source.html @@ -0,0 +1,1184 @@ + + + + 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  
+

zone.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 "nel/3d/zone.h"
+00027 #include "nel/3d/landscape.h"
+00028 #include "nel/misc/common.h"
+00029 
+00030 
+00031 using namespace NLMISC;
+00032 using namespace std;
+00033 
+00034 
+00035 // define it only for debug bind.
+00036 //#define       NL3D_DEBUG_DONT_BIND_PATCH
+00037 
+00038 
+00039 namespace NL3D {
+00040 
+00041 
+00042 const sint      ClipIn= 0;
+00043 const sint      ClipOut= 1;
+00044 const sint      ClipSide= 2;
+00045 
+00046 
+00047 // ***************************************************************************
+00048 CZone::CZone()
+00049 {
+00050         ComputeTileErrorMetric= false;
+00051         ZoneId= 0;
+00052         Compiled= false;
+00053         Landscape= NULL;
+00054 }
+00055 // ***************************************************************************
+00056 CZone::~CZone()
+00057 {
+00058         // release() must have been called.
+00059         nlassert(!Compiled);
+00060 }
+00061 
+00062 
+00063 // ***************************************************************************
+00064 void                    CZone::computeBBScaleBias(const CAABBox &bb)
+00065 {
+00066         ZoneBB= bb;
+00067         // Take a security for noise. (usefull for zone clipping).
+00068         ZoneBB.setHalfSize(ZoneBB.getHalfSize()+CVector(NL3D_NOISE_MAX, NL3D_NOISE_MAX, NL3D_NOISE_MAX));
+00069         CVector hs= ZoneBB.getHalfSize();
+00070         float   rmax= maxof(hs.x, hs.y, hs.z);
+00071         PatchScale= rmax / 32760;               // Prevent from float imprecision by taking 32760 and not 32767.
+00072         PatchBias= ZoneBB.getCenter();
+00073 }
+00074 
+00075 
+00076 // ***************************************************************************
+00077 void                    CZone::build(uint16 zoneId, const std::vector<CPatchInfo> &patchs, const std::vector<CBorderVertex> &borderVertices)
+00078 {
+00079         sint    i,j;
+00080         nlassert(!Compiled);
+00081 
+00082         ZoneId= zoneId;
+00083         BorderVertices= borderVertices;
+00084 
+00085         // Compute the bbox and the bias/scale.
+00086         //=====================================
+00087         CAABBox         bb;
+00088         if(patchs.size())
+00089                 bb.setCenter(patchs[0].Patch.Vertices[0]);
+00090         bb.setHalfSize(CVector::Null);
+00091         for(j=0;j<(sint)patchs.size();j++)
+00092         {
+00093                 const CBezierPatch      &p= patchs[j].Patch;
+00094                 for(i=0;i<4;i++)
+00095                         bb.extend(p.Vertices[i]);
+00096                 for(i=0;i<8;i++)
+00097                         bb.extend(p.Tangents[i]);
+00098                 for(i=0;i<4;i++)
+00099                         bb.extend(p.Interiors[i]);
+00100         }
+00101         // Compute BBox, and Patch Scale Bias, according to Noise.
+00102         computeBBScaleBias(bb);
+00103 
+00104 
+00105         // Compute/compress Patchs.
+00106         //=========================
+00107         Patchs.resize(patchs.size());
+00108         PatchConnects.resize(patchs.size());
+00109         sint    maxVertex=-1;
+00110         for(j=0;j<(sint)patchs.size();j++)
+00111         {
+00112                 const CPatchInfo        &pi= patchs[j];
+00113                 const CBezierPatch      &p= pi.Patch;
+00114                 CPatch                          &pa= Patchs[j];
+00115                 CPatchConnect           &pc= PatchConnects[j];
+00116 
+00117                 // Smoothing flags
+00118                 pa.Flags&=~NL_PATCH_SMOOTH_FLAG_MASK;
+00119                 pa.Flags|=NL_PATCH_SMOOTH_FLAG_MASK&(pi.Flags<<NL_PATCH_SMOOTH_FLAG_SHIFT);
+00120 
+00121                 // Build the patch.
+00122                 for(i=0;i<4;i++)
+00123                         pa.Vertices[i].pack(p.Vertices[i], PatchBias, PatchScale);
+00124                 for(i=0;i<8;i++)
+00125                         pa.Tangents[i].pack(p.Tangents[i], PatchBias, PatchScale);
+00126                 for(i=0;i<4;i++)
+00127                         pa.Interiors[i].pack(p.Interiors[i], PatchBias, PatchScale);
+00128                 pa.Tiles= pi.Tiles;
+00129                 pa.TileColors= pi.TileColors;
+00130 
+00131                 // Copy order of the patch
+00132                 pa.OrderS= pi.OrderS;
+00133                 pa.OrderT= pi.OrderT;
+00134 
+00135                 // Number of lumels in this patch
+00136                 uint lumelCount=(pi.OrderS*NL_LUMEL_BY_TILE+1)*(pi.OrderT*NL_LUMEL_BY_TILE+1);
+00137 
+00138                 // Lumel empty ?
+00139                 if (pi.Lumels.size ()==lumelCount)
+00140                 {
+00141                         // Pack the lumel map
+00142                         pa.packShadowMap (&pi.Lumels[0]);
+00143                 }
+00144                 else
+00145                 {
+00146                         // Reset lightmap
+00147                         pa.resetCompressedLumels ();
+00148                 }
+00149 
+00150                 nlassert(pa.Tiles.size()== (uint)pi.OrderS*pi.OrderT);
+00151                 nlassert(pa.TileColors.size()== (uint)(pi.OrderS+1)*(pi.OrderT+1));
+00152 
+00153                 // Build the patchConnect.
+00154                 pc.ErrorSize= pi.ErrorSize;
+00155                 for(i=0;i<4;i++)
+00156                 {
+00157                         pc.BaseVertices[i]= pi.BaseVertices[i];
+00158                         maxVertex= max((sint)pc.BaseVertices[i], maxVertex);
+00159                 }
+00160                 for(i=0;i<4;i++)
+00161                         pc.BindEdges[i]= pi.BindEdges[i];
+00162         }
+00163 
+00164         NumVertices= maxVertex+1;
+00165 }
+00166 
+00167 
+00168 // ***************************************************************************
+00169 void                    CZone::retrieve(std::vector<CPatchInfo> &patchs, std::vector<CBorderVertex> &borderVertices)
+00170 {
+00171         sint i,j;
+00172 
+00173         // uncompress Patchs.
+00174         //=========================
+00175         patchs.resize(Patchs.size());
+00176         for(j=0;j<(sint)patchs.size();j++)
+00177         {
+00178                 CPatchInfo                      &pi= patchs[j];
+00179                 CBezierPatch            &p= pi.Patch;
+00180                 CPatch                          &pa= Patchs[j];
+00181                 CPatchConnect           &pc= PatchConnects[j];
+00182 
+00183                 // re-Build the uncompressed bezier patch.
+00184                 for(i=0;i<4;i++)
+00185                         pa.Vertices[i].unpack(p.Vertices[i], PatchBias, PatchScale);
+00186                 for(i=0;i<8;i++)
+00187                         pa.Tangents[i].unpack(p.Tangents[i], PatchBias, PatchScale);
+00188                 for(i=0;i<4;i++)
+00189                         pa.Interiors[i].unpack(p.Interiors[i], PatchBias, PatchScale);
+00190                 pi.Tiles= pa.Tiles;
+00191                 pi.TileColors= pa.TileColors;
+00192                 pi.Lumels.resize ((pa.OrderS*4+1)*(pa.OrderT*4+1));
+00193 
+00194                 // Unpack the lumel map
+00195                 pa.unpackShadowMap (&pi.Lumels[0]);
+00196 
+00197                 // from the patchConnect.
+00198                 pi.OrderS= pa.OrderS;
+00199                 pi.OrderT= pa.OrderT;
+00200                 pi.ErrorSize= pc.ErrorSize;
+00201                 for(i=0;i<4;i++)
+00202                 {
+00203                         pi.BaseVertices[i]= pc.BaseVertices[i];
+00204                 }
+00205                 for(i=0;i<4;i++)
+00206                         pi.BindEdges[i]= pc.BindEdges[i];
+00207         }
+00208 
+00209         // retrieve bordervertices.
+00210         //=========================
+00211         borderVertices= BorderVertices;
+00212 }
+00213 
+00214 
+00215 // ***************************************************************************
+00216 void                    CZone::build(const CZone &zone)
+00217 {
+00218         nlassert(!Compiled);
+00219 
+00220         ZoneId= zone.ZoneId;
+00221         BorderVertices= zone.BorderVertices;
+00222 
+00223         // Compute the bbox and the bias/scale.
+00224         //=====================================
+00225         ZoneBB= zone.ZoneBB;
+00226         PatchScale= zone.PatchScale;
+00227         PatchBias= zone.PatchBias;
+00228 
+00229 
+00230         // Compute/compress Patchs.
+00231         //=========================
+00232         Patchs= zone.Patchs;
+00233         PatchConnects= zone.PatchConnects;
+00234 
+00235 
+00236         NumVertices= zone.NumVertices;
+00237 }
+00238 
+00239 
+00240 
+00241 // ***************************************************************************
+00242 void                    CBorderVertex::serial(NLMISC::IStream &f)
+00243 {
+00244         uint    ver= f.serialVersion(0);
+00245         f.serial(CurrentVertex, NeighborZoneId, NeighborVertex);
+00246 }
+00247 void                    CZone::CPatchConnect::serial(NLMISC::IStream &f)
+00248 {
+00249         uint    ver= f.serialVersion(1);
+00250 
+00251         if (ver<1)
+00252                 f.serial(OldOrderS, OldOrderT, ErrorSize);
+00253         else
+00254                 f.serial(ErrorSize);
+00255         f.serial(BaseVertices[0], BaseVertices[1], BaseVertices[2], BaseVertices[3]);
+00256         f.serial(BindEdges[0], BindEdges[1], BindEdges[2], BindEdges[3]);
+00257 }
+00258 void                    CPatchInfo::CBindInfo::serial(NLMISC::IStream &f)
+00259 {
+00260         int             i;
+00261         uint    ver= f.serialVersion(0);
+00262         f.serial(NPatchs);
+00263         f.serial(ZoneId);
+00264         for(i=0;i<4;i++)
+00265                 f.serial(Next[i]);
+00266         for(i=0;i<4;i++)
+00267                 f.serial(Edge[i]);
+00268 }
+00269 
+00270 // ***************************************************************************
+00271 void                    CZone::serial(NLMISC::IStream &f)
+00272 {
+00273         /*
+00274         Version 2:
+00275                 - Lumels.
+00276         Version 1:
+00277                 - Tile color.
+00278         Version 0:
+00279                 - base verison.
+00280         */
+00281         uint    ver= f.serialVersion(2);
+00282 
+00283         f.serialCheck((uint32)'ENOZ');
+00284         f.serial(ZoneId, ZoneBB, PatchBias, PatchScale, NumVertices);
+00285         f.serialCont(BorderVertices);
+00286         f.serialCont(Patchs);
+00287         f.serialCont(PatchConnects);
+00288 
+00289         // If read and version 0, must init default TileColors of patchs.
+00290         //===============================================================
+00291         if(f.isReading() && ver<2)
+00292         {
+00293                 for(sint j=0;j<(sint)Patchs.size();j++)
+00294                 {
+00295                         CPatch                          &pa= Patchs[j];
+00296                         CPatchConnect           &pc= PatchConnects[j];
+00297 
+00298                         // Force Order of the patch
+00299                         pa.OrderS=pc.OldOrderS;
+00300                         pa.OrderT=pc.OldOrderT;
+00301 
+00302                         // Tile colors exist ?
+00303                         if (ver<1)
+00304                         {
+00305                                 // Leave it as default behavior: Must init the color as pure white...
+00306                                 // We must fo it with help of patchconnects OrderS and OrderT.
+00307                                 pa.TileColors.resize( (pc.OldOrderS+1)*(pc.OldOrderT+1) );
+00308                                 for(sint i=0;i<(sint)pa.TileColors.size();i++)
+00309                                 {
+00310                                         pa.TileColors[i].Color565= 0xFFFF;
+00311                                         pa.TileColors[i].Shade= 0xFF;
+00312                                         pa.TileColors[i].LightX= 0xFF;
+00313                                         pa.TileColors[i].LightY= 0x00;
+00314                                         pa.TileColors[i].LightZ= 0x00;
+00315                                 }
+00316                         }
+00317 
+00318                         // Lumels exist ?
+00319                         if (ver<2)
+00320                         {
+00321                                 // Reset shadows
+00322                                 pa.resetCompressedLumels ();
+00323                         }
+00324                 }
+00325         }
+00326 }
+00327 
+00328 
+00329 // ***************************************************************************
+00330 void                    CZone::compile(CLandscape *landscape, TZoneMap &loadedZones)
+00331 {
+00332         sint    i,j;
+00333         TZoneMap                neighborZones;
+00334 
+00335         // Can't compile if compiled.
+00336         nlassert(!Compiled);
+00337         Landscape= landscape;
+00338 
+00339         // Attach this to loadedZones.
+00340         //============================
+00341         nlassert(loadedZones.find(ZoneId)==loadedZones.end());
+00342         loadedZones[ZoneId]= this;
+00343         
+00344         // Create/link the base vertices according to present neigbor zones.
+00345         //============================
+00346         BaseVertices.clear();
+00347         BaseVertices.resize(NumVertices);
+00348         // First try to link vertices to other.
+00349         for(i=0;i<(sint)BorderVertices.size();i++)
+00350         {
+00351                 sint    cur= BorderVertices[i].CurrentVertex;
+00352                 sint    vertto= BorderVertices[i].NeighborVertex;
+00353                 sint    zoneto= BorderVertices[i].NeighborZoneId;
+00354                 nlassert(cur<NumVertices);
+00355 
+00356                 if(loadedZones.find(zoneto)!=loadedZones.end())
+00357                 {
+00358                         CZone   *zone;
+00359                         zone= (*loadedZones.find(zoneto)).second;
+00360                         nlassert(zone!=this);
+00361                         // insert the zone in the neigborood (if not done...).
+00362                         neighborZones[zoneto]= zone;
+00363                         // Doesn't matter if BaseVertices is already linked to an other zone... 
+00364                         // This should be the same pointer in this case...
+00365                         BaseVertices[cur]=  zone->getBaseVertex(vertto);
+00366                 }
+00367         }
+00368         // Else, create unbounded vertices.
+00369         for(i=0;i<(sint)BaseVertices.size();i++)
+00370         {
+00371                 if(BaseVertices[i]==NULL)
+00372                 {
+00373                         BaseVertices[i]=  new CTessBaseVertex;
+00374                 }
+00375         }
+00376 
+00377 
+00378         // compile() the patchs.
+00379         //======================
+00380         for(j=0;j<(sint)Patchs.size();j++)
+00381         {
+00382                 CPatch                          &pa= Patchs[j];
+00383                 CPatchConnect           &pc= PatchConnects[j];
+00384                 CTessVertex                     *baseVertices[4];
+00385 
+00386                 baseVertices[0]= &(BaseVertices[pc.BaseVertices[0]]->Vert);
+00387                 baseVertices[1]= &(BaseVertices[pc.BaseVertices[1]]->Vert);
+00388                 baseVertices[2]= &(BaseVertices[pc.BaseVertices[2]]->Vert);
+00389                 baseVertices[3]= &(BaseVertices[pc.BaseVertices[3]]->Vert);
+00390                 pa.compile(this, pa.OrderS, pa.OrderT, baseVertices, pc.ErrorSize);
+00391         };
+00392 
+00393         // bind() the patchs. (after all compiled).
+00394         //===================
+00395         for(j=0;j<(sint)Patchs.size();j++)
+00396         {
+00397                 CPatch                          &pa= Patchs[j];
+00398                 CPatchConnect           &pc= PatchConnects[j];
+00399 
+00400                 bindPatch(loadedZones, pa, pc);
+00401         }
+00402         
+00403         
+00404         // rebindBorder() on neighbor zones.
+00405         //==================================
+00406         ItZoneMap               zoneIt;
+00407         // Traverse the neighborood.
+00408         for(zoneIt= neighborZones.begin(); zoneIt!=neighborZones.end(); zoneIt++)
+00409         {
+00410                 (*zoneIt).second->rebindBorder(loadedZones);
+00411         }
+00412 
+00413         // End!!
+00414         Compiled= true;
+00415 }
+00416 
+00417 // ***************************************************************************
+00418 void                    CZone::release(TZoneMap &loadedZones)
+00419 {
+00420         sint    i,j;
+00421 
+00422         if(!Compiled)
+00423                 return;
+00424 
+00425         // detach this zone to loadedZones.
+00426         //=================================
+00427         nlassert(loadedZones.find(ZoneId)!=loadedZones.end());
+00428         loadedZones.erase(ZoneId);
+00429         // It doesn't server to unbindPatch(), since patch is not binded to neigbors.
+00430 
+00431 
+00432         // unbind() the patchs.
+00433         //=====================
+00434         for(j=0;j<(sint)Patchs.size();j++)
+00435         {
+00436                 CPatch                          &pa= Patchs[j];
+00437                 CPatchConnect           &pc= PatchConnects[j];
+00438                 unbindPatch(loadedZones, pa, pc);
+00439                 /* 
+00440                         This patch may be unbinded with exceptions (multiple patch case), but there is no problem, since in this case,
+00441                         his neighbor will (or have precedently) unbind.
+00442                         Since only Bind 1/1 are permitted on zone neighborood, there should be no problem:
+00443                         patch are unbinded with no exceptions.
+00444                 */
+00445         }
+00446 
+00447 
+00448         // rebindBorder() on neighbor zones.
+00449         //==================================
+00450         // Build the nieghborood.
+00451         TZoneMap                neighborZones;
+00452         for(i=0;i<(sint)BorderVertices.size();i++)
+00453         {
+00454                 sint    cur= BorderVertices[i].CurrentVertex;
+00455                 sint    zoneto= BorderVertices[i].NeighborZoneId;
+00456                 nlassert(cur<NumVertices);
+00457 
+00458                 if(loadedZones.find(zoneto)!=loadedZones.end())
+00459                 {
+00460                         CZone   *zone;
+00461                         zone= (*loadedZones.find(zoneto)).second;
+00462                         nlassert(zone!=this);
+00463                         // insert the zone in the neigborood (if not done...).
+00464                         neighborZones[zoneto]= zone;
+00465                 }
+00466         }
+00467         // rebind borders.
+00468         ItZoneMap               zoneIt;
+00469         // Traverse the neighborood.
+00470         for(zoneIt= neighborZones.begin(); zoneIt!=neighborZones.end(); zoneIt++)
+00471         {
+00472                 // Since 
+00473                 (*zoneIt).second->rebindBorder(loadedZones);
+00474         }
+00475 
+00476 
+00477         // release() the patchs.
+00478         //======================
+00479         // unbind() need compiled neigbor patchs, so do the release after all unbind (so after rebindBorder() too...).
+00480         for(j=0;j<(sint)Patchs.size();j++)
+00481         {
+00482                 CPatch                          &pa= Patchs[j];
+00483                 pa.release();
+00484         }
+00485 
+00486 
+00487         // destroy/unlink the base vertices (internal..), according to present neigbor zones.
+00488         //=================================
+00489         // Just release the smartptrs (easy!!). Do it after patchs released...
+00490         BaseVertices.clear();
+00491         
+00492 
+00493         // End!!
+00494         Compiled= false;
+00495         Landscape= NULL;
+00496 }
+00497 
+00498 
+00499 // ***************************************************************************
+00500 // ***************************************************************************
+00501 // Private part.
+00502 // ***************************************************************************
+00503 // ***************************************************************************
+00504 
+00505 
+00506 // ***************************************************************************
+00507 void                    CZone::rebindBorder(TZoneMap &loadedZones)
+00508 {
+00509         sint    j;
+00510 
+00511         // rebind patchs which are on border.
+00512         for(j=0;j<(sint)Patchs.size();j++)
+00513         {
+00514                 CPatch                          &pa= Patchs[j];
+00515                 CPatchConnect           &pc= PatchConnects[j];
+00516 
+00517                 if(patchOnBorder(pc))
+00518                         bindPatch(loadedZones, pa, pc);
+00519         }
+00520 }
+00521 
+00522 // ***************************************************************************
+00523 CPatch          *CZone::getZonePatch(TZoneMap &loadedZones, sint zoneId, sint patch)
+00524 {
+00525 #ifdef NL3D_DEBUG_DONT_BIND_PATCH
+00526         return NULL;
+00527 #endif
+00528         if(loadedZones.find(zoneId)==loadedZones.end())
+00529                 return NULL;
+00530         else
+00531                 return (loadedZones[zoneId])->getPatch(patch);
+00532 }
+00533 
+00534 
+00535 // ***************************************************************************
+00536 void            CZone::unbindAndMakeBindInfo(TZoneMap &loadedZones, CPatch &pa, CPatchConnect &pc, CPatch::CBindInfo    edges[4])
+00537 {
+00538         CPatch  *exceptions[4]= {NULL, NULL, NULL, NULL};
+00539 
+00540         /*
+00541                 Remind: the old version with CPatch::unbindFrom*() doesn't work because of CZone::release(). This function
+00542                 first erase the zone from loadedZones...
+00543                 Not matter here. We use CPatch::unbind() which should do all the good job correctly (unbind pa from ohters
+00544                 , and unbind others from pa at same time).
+00545         */
+00546 
+00547         // Fill all edges.
+00548         for(sint i=0;i<4;i++)
+00549         {
+00550                 CPatchInfo::CBindInfo   &pcBind= pc.BindEdges[i];
+00551                 CPatch::CBindInfo               &paBind= edges[i];
+00552 
+00553                 nlassert(pcBind.NPatchs==0 || pcBind.NPatchs==1 || pcBind.NPatchs==2 || pcBind.NPatchs==4 || pcBind.NPatchs==5);
+00554                 paBind.NPatchs= pcBind.NPatchs;
+00555 
+00556                 // Special case of a small patch connected to a bigger.
+00557                 if(paBind.NPatchs==5)
+00558                 {
+00559                         // In this case, neither the unbind must not be done, nor the bind.
+00560                         exceptions[i]= CZone::getZonePatch(loadedZones, pcBind.ZoneId, pcBind.Next[0]);
+00561                         // This code prevent the bind in CPatch::bind() to be done!!
+00562                         // The bind must not be done, since exceptions[] prevent the unbind!
+00563                         paBind.NPatchs=0;
+00564                         continue;
+00565                 }
+00566 
+00567 
+00568                 if(paBind.NPatchs>=1)
+00569                 {
+00570                         paBind.Edge[0]= pcBind.Edge[0];
+00571                         paBind.Next[0]= CZone::getZonePatch(loadedZones, pcBind.ZoneId, pcBind.Next[0]);
+00572                         // If not loaded, don't bind to this edge.
+00573                         if(!paBind.Next[0])
+00574                                 paBind.NPatchs=0;
+00575                 }
+00576                 if(paBind.NPatchs>=2)
+00577                 {
+00578                         paBind.Edge[1]= pcBind.Edge[1];
+00579                         paBind.Next[1]= CZone::getZonePatch(loadedZones, pcBind.ZoneId, pcBind.Next[1]);
+00580                         // If not loaded, don't bind to this edge.
+00581                         if(!paBind.Next[1])
+00582                                 paBind.NPatchs=0;
+00583                 }
+00584                 if(paBind.NPatchs>=4)
+00585                 {
+00586                         paBind.Edge[2]= pcBind.Edge[2];
+00587                         paBind.Edge[3]= pcBind.Edge[3];
+00588                         paBind.Next[2]= CZone::getZonePatch(loadedZones, pcBind.ZoneId, pcBind.Next[2]);
+00589                         paBind.Next[3]= CZone::getZonePatch(loadedZones, pcBind.ZoneId, pcBind.Next[3]);
+00590                         // If not loaded, don't bind to this edge.
+00591                         if(!paBind.Next[2] || !paBind.Next[3])
+00592                                 paBind.NPatchs=0;
+00593                 }
+00594         }
+00595 
+00596         pa.unbind(exceptions);
+00597 }
+00598 
+00599 // ***************************************************************************
+00600 void            CZone::bindPatch(TZoneMap &loadedZones, CPatch &pa, CPatchConnect &pc)
+00601 {
+00602         CPatch::CBindInfo       edges[4];
+00603 
+00604         unbindAndMakeBindInfo(loadedZones, pa, pc, edges);
+00605 
+00606         pa.bind(edges);
+00607 }
+00608 
+00609 
+00610 // ***************************************************************************
+00611 void            CZone::unbindPatch(TZoneMap &loadedZones, CPatch &pa, CPatchConnect &pc)
+00612 {
+00613         CPatch::CBindInfo       edges[4];
+00614 
+00615         unbindAndMakeBindInfo(loadedZones,  pa, pc, edges);
+00616 
+00617         // Don't rebind.
+00618 }
+00619 
+00620 
+00621 // ***************************************************************************
+00622 bool                    CZone::patchOnBorder(const CPatchConnect &pc) const
+00623 {
+00624         // If only one of neighbor patch is not of this zone, we are on a border.
+00625 
+00626         // Test all edges.
+00627         for(sint i=0;i<4;i++)
+00628         {
+00629                 const CPatchInfo::CBindInfo     &pcBind= pc.BindEdges[i];
+00630 
+00631                 nlassert(pcBind.NPatchs==0 || pcBind.NPatchs==1 || pcBind.NPatchs==2 || pcBind.NPatchs==4 || pcBind.NPatchs==5);
+00632                 if(pcBind.NPatchs>=1)
+00633                 {
+00634                         if(pcBind.ZoneId != ZoneId)
+00635                                 return true;
+00636                 }
+00637         }
+00638 
+00639         return false;
+00640 }
+00641 
+00642 
+00643 // ***************************************************************************
+00644 // ***************************************************************************
+00645 // Render part.
+00646 // ***************************************************************************
+00647 // ***************************************************************************
+00648 
+00649 
+00650 // ***************************************************************************
+00651 void                    CZone::clip(const std::vector<CPlane>   &pyramid)
+00652 {
+00653         nlassert(Compiled);
+00654 
+00655         // Store current pyramid.
+00656         CurrentPyramid= pyramid;
+00657 
+00658         // Fill ClipResult.
+00659         ClipResult= ClipIn;
+00660         for(sint i=0;i<(sint)pyramid.size();i++)
+00661         {
+00662                 // If entirely out.
+00663                 if(!ZoneBB.clipBack(pyramid[i]))
+00664                 {
+00665                         ClipResult= ClipOut;
+00666                         // If out of only one plane, out of all.
+00667                         break;
+00668                 }
+00669                 // If partially IN (ie not entirely out, and not entirely IN)
+00670                 else if(ZoneBB.clipFront(pyramid[i]))
+00671                 {
+00672                         // Force ClipResult to be ClipSide, and not ClipIn.
+00673                         ClipResult=ClipSide;
+00674                 }
+00675         }
+00676 
+00677         // Fill computeTileErrorMetric.
+00678         CBSphere                zonesphere(ZoneBB.getCenter(), ZoneBB.getRadius());
+00679         if(zonesphere.intersect(CTessFace::TileFarSphere))
+00680                 ComputeTileErrorMetric= true;
+00681         else
+00682                 ComputeTileErrorMetric= false;
+00683 
+00684         // Easy Clip  :)
+00685         if(Patchs.size()==0)
+00686         {
+00687                 ClipResult= ClipOut;
+00688         }
+00689 
+00690 
+00691         // Clip By Patch Pass.
+00692         //--------------------
+00693         if(ClipResult==ClipOut)
+00694         {
+00695                 CPatch          *pPatch= &(*Patchs.begin());
+00696                 for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00697                 {
+00698                         pPatch->forceClip();
+00699                 }
+00700         }
+00701         else if(ClipResult==ClipIn)
+00702         {
+00703                 CPatch          *pPatch= &(*Patchs.begin());
+00704                 for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00705                 {
+00706                         pPatch->forceNoClip();
+00707                 }
+00708         }
+00709         else
+00710         {
+00711                 CPatch          *pPatch= &(*Patchs.begin());
+00712                 for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00713                 {
+00714                         pPatch->clip(CurrentPyramid);
+00715                 }
+00716         }
+00717 
+00718 }
+00719 
+00720 
+00721 // ***************************************************************************
+00722 // DebugYoyo.
+00723 // Code for Debug test Only.. Do not erase it, may be used later :)
+00724 /*
+00725 static  void    cleanTess(CTessFace *face)
+00726 {
+00727         if(!face->isLeaf())
+00728         {
+00729                 cleanTess(face->SonLeft);
+00730                 cleanTess(face->SonRight);
+00731         }
+00732         // If has father, clean it.
+00733         if(face->Father)
+00734         {
+00735                 CTessFace       *face1=face->Father;
+00736                 CTessFace       *face2=face->Father->FBase;
+00737                 face1->FLeft= face1->SonLeft->FBase;
+00738                 face1->FRight= face1->SonRight->FBase;
+00739                 if(face2!=NULL)
+00740                 {
+00741                         face2->FLeft= face2->SonLeft->FBase;
+00742                         face2->FRight= face2->SonRight->FBase;
+00743                 }
+00744         }
+00745 }
+00746 static  void    testTess(CTessFace *face)
+00747 {
+00748         if(!face->isLeaf())
+00749         {
+00750                 testTess(face->SonLeft);
+00751                 testTess(face->SonRight);
+00752         }
+00753         // Test validity.
+00754         nlassert(!face->FBase || face->FBase->Patch!=(CPatch*)0xdddddddd);
+00755         nlassert(!face->FLeft || face->FLeft->Patch!=(CPatch*)0xdddddddd);
+00756         nlassert(!face->FRight || face->FRight->Patch!=(CPatch*)0xdddddddd);
+00757 }
+00758 static  void    checkTess()
+00759 {
+00760         // This test should be inserted at begin of CZone::refine().
+00761         // And it needs hacking public/private.
+00762         CPatch          *pPatch;
+00763         sint            n;
+00764         pPatch= &(*Patchs.begin());
+00765         for(n=(sint)Patchs.size();n>0;n--, pPatch++)
+00766         {
+00767                 cleanTess(pPatch->Son0);
+00768                 cleanTess(pPatch->Son1);
+00769         }
+00770         pPatch= &(*Patchs.begin());
+00771         for(n=(sint)Patchs.size();n>0;n--, pPatch++)
+00772         {
+00773                 testTess(pPatch->Son0);
+00774                 testTess(pPatch->Son1);
+00775         }
+00776 }
+00777 */
+00778 
+00779 
+00780 // ***************************************************************************
+00781 // DebugYoyo.
+00782 //volatile sint pipo1;
+00783 //volatile sint pipo2;
+00784 void                    CZone::refine()
+00785 {
+00786         nlassert(Compiled);
+00787         // Must be 2^X-1.
+00788         static const    sint    hideRefineFreq= 15;
+00789 
+00790         // DebugYoyo.
+00791         // For the monkey bind test.
+00792         /*extern sint numFrames;
+00793         pipo1=(rand()>>12)&1;
+00794         pipo2=(rand()>>12)&1;
+00795         //if(pipo1 && numFrames>1360)
+00796         if(true)
+00797         {
+00798                 TZoneMap        pipoMap;
+00799                 pipoMap[ZoneId]= this;
+00800                 bindPatch(pipoMap, Patchs[0], PatchConnects[0]);
+00801         }*/
+00802 
+00803         
+00804         // Force refine of invisible zones only every 8 times.
+00805         if(ClipResult==ClipOut && (CTessFace::CurrentDate & hideRefineFreq)!=(ZoneId & hideRefineFreq))
+00806                 return;
+00807         // Fuck stlport....
+00808         if(Patchs.size()==0)
+00809                 return;
+00810 
+00811         CPatch          *pPatch= &(*Patchs.begin());
+00812         if(ClipResult==ClipSide)
+00813         {
+00814                 // Force refine of invisible patchs only every 16 times.
+00815                 // NB: do this only if zone is clipSide
+00816                 for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00817                 {
+00818                         // "ZoneId+n", because there is only 70 approx patchs per zone. doing this may stabilize framerate.
+00819                         if(pPatch->isClipped() && (CTessFace::CurrentDate & hideRefineFreq)!=((ZoneId+n) & hideRefineFreq))
+00820                                 continue;
+00821                         pPatch->refine();
+00822                 }
+00823         }
+00824         else
+00825         {
+00826                 // Else refine ALL patchs (even those which may be invisible).
+00827                 for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00828                 {
+00829                         pPatch->refine();
+00830                 }
+00831         }
+00832 
+00833 }
+00834 // ***************************************************************************
+00835 void                    CZone::refineAll()
+00836 {
+00837         nlassert(Compiled);
+00838 
+00839         // Fuck stlport....
+00840         if(Patchs.size()==0)
+00841                 return;
+00842 
+00843         // Do a dummy clip.
+00844         ComputeTileErrorMetric= true;
+00845         ClipResult= ClipIn;
+00846         CPatch          *pPatch= &(*Patchs.begin());
+00847         sint n;
+00848         for(n=(sint)Patchs.size();n>0;n--, pPatch++)
+00849         {
+00850                 pPatch->forceNoClip();
+00851         }
+00852 
+00853 
+00854         // refine ALL patchs (even those which may be invisible).
+00855         pPatch= &(*Patchs.begin());
+00856         for(n=(sint)Patchs.size();n>0;n--, pPatch++)
+00857         {
+00858                 pPatch->refine();
+00859         }
+00860 
+00861 }
+00862 
+00863 // ***************************************************************************
+00864 void                    CZone::preRender(const std::vector<CPlane>      &pyramid)
+00865 {
+00866         nlassert(Compiled);
+00867         if(ClipResult==ClipOut)
+00868                 return;
+00869 
+00870         // PreRender Pass.
+00871         CPatch          *pPatch= &(*Patchs.begin());
+00872         for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00873         {
+00874                 pPatch->preRender(pyramid);
+00875         }
+00876 }
+00877 // ***************************************************************************
+00878 void                    CZone::renderFar0()
+00879 {
+00880         nlassert(Compiled);
+00881         if(ClipResult==ClipOut)
+00882                 return;
+00883 
+00884         // RenderFar0.
+00885         CPatch          *pPatch= &(*Patchs.begin());
+00886         for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00887         {
+00888                 pPatch->renderFar0();
+00889         }
+00890 }
+00891 // ***************************************************************************
+00892 void                    CZone::renderFar1()
+00893 {
+00894         nlassert(Compiled);
+00895         if(ClipResult==ClipOut)
+00896                 return;
+00897 
+00898         // RenderFar1.
+00899         CPatch          *pPatch= &(*Patchs.begin());
+00900         for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00901         {
+00902                 pPatch->renderFar1();
+00903         }
+00904 }
+00905 // ***************************************************************************
+00906 void                    CZone::renderTile(sint pass)
+00907 {
+00908         nlassert(Compiled);
+00909         if(ClipResult==ClipOut)
+00910                 return;
+00911 
+00912         // RenderTile.
+00913         CPatch          *pPatch= &(*Patchs.begin());
+00914         for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00915         {
+00916                 pPatch->renderTile(pass);
+00917         }
+00918 }
+00919 
+00920 
+00921 // ***************************************************************************
+00922 void                    CZone::resetRenderFar()
+00923 {
+00924         CPatch          *pPatch= &(*Patchs.begin());
+00925         for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00926         {
+00927                 pPatch->resetRenderFar();
+00928         }
+00929 }
+00930 
+00931 
+00932 // ***************************************************************************
+00933 void                    CZone::forceMergeAtTileLevel()
+00934 {
+00935         CPatch          *pPatch= &(*Patchs.begin());
+00936         for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
+00937         {
+00938                 pPatch->forceMergeAtTileLevel();
+00939         }
+00940 }
+00941 
+00942 
+00943 // ***************************************************************************
+00944 // ***************************************************************************
+00945 // Misc part.
+00946 // ***************************************************************************
+00947 // ***************************************************************************
+00948 
+00949 
+00950 // ***************************************************************************
+00951 void                    CZone::changePatchTextureAndColor (sint numPatch, const std::vector<CTileElement> *tiles, const std::vector<CTileColor> *colors)
+00952 {
+00953         nlassert(numPatch>=0);
+00954         nlassert(numPatch<getNumPatchs());
+00955         
+00956 
+00957         // Update the patch texture.
+00958         if (tiles)
+00959         {
+00960                 nlassert( Patchs[numPatch].Tiles.size() == tiles->size() );
+00961                 Patchs[numPatch].Tiles = *tiles;
+00962         }
+00963 
+00964         // Update the patch colors.
+00965         if (colors)
+00966         {
+00967                 nlassert( Patchs[numPatch].TileColors.size() == colors->size() );
+00968                 Patchs[numPatch].TileColors = *colors;
+00969         }
+00970 
+00971         if (Compiled&&(tiles||colors))
+00972         {
+00973                 Patchs[numPatch].deleteTileUvs();
+00974                 Patchs[numPatch].recreateTileUvs();
+00975         }
+00976 }
+00977 
+00978 
+00979 // ***************************************************************************
+00980 const std::vector<CTileElement> &CZone::getPatchTexture(sint numPatch) const
+00981 {
+00982         nlassert(numPatch>=0);
+00983         nlassert(numPatch<getNumPatchs());
+00984 
+00985         // Update the patch texture.
+00986         return Patchs[numPatch].Tiles;
+00987 }
+00988 
+00989 
+00990 // ***************************************************************************
+00991 const std::vector<CTileColor> &CZone::getPatchColor(sint numPatch) const
+00992 {
+00993         nlassert(numPatch>=0);
+00994         nlassert(numPatch<getNumPatchs());
+00995 
+00996         // Update the patch texture.
+00997         return Patchs[numPatch].TileColors;
+00998 }
+00999 
+01000 
+01001 // ***************************************************************************
+01002 void                    CZone::debugBinds(FILE *f)
+01003 {
+01004         fprintf(f, "*****************************\n");
+01005         fprintf(f, "ZoneId: %d. NPatchs:%d\n", ZoneId, PatchConnects.size());
+01006         sint i;
+01007         for(i=0;i<(sint)PatchConnects.size();i++)
+01008         {
+01009                 CPatchConnect   &pc= PatchConnects[i];
+01010                 fprintf(f, "patch%d:\n", i);
+01011                 for(sint j=0;j<4;j++)
+01012                 {
+01013                         CPatchInfo::CBindInfo   &bd= pc.BindEdges[j];
+01014                         fprintf(f, "    edge%d: Zone:%d. NPatchs:%d. ", j, bd.ZoneId, bd.NPatchs);
+01015                         for(sint k=0;k<bd.NPatchs;k++)
+01016                         {
+01017                                 fprintf(f, "p%de%d - ", bd.Next[k], bd.Edge[k]);
+01018                         }
+01019                         fprintf(f, "\n");
+01020                 }
+01021         }
+01022 
+01023         fprintf(f,"Vertices :\n");
+01024         for(i=0;i<(sint)BorderVertices.size();i++)
+01025         {
+01026                 fprintf(f,"current : %d -> (zone %d) vertex %d\n",BorderVertices[i].CurrentVertex,
+01027                                                                                         BorderVertices[i].NeighborZoneId,
+01028                                                                                         BorderVertices[i].NeighborVertex);
+01029         }
+01030 }
+01031 
+01032 
+01033 // ***************************************************************************
+01034 void                    CZone::applyHeightField(const CLandscape &landScape)
+01035 {
+01036         sint    i,j;
+01037         vector<CBezierPatch>    patchs;
+01038 
+01039         // no patch, do nothing.
+01040         if(Patchs.size()==0)
+01041                 return;
+01042 
+01043         // 0. Unpack patchs to Bezier Patchs.
+01044         //===================================
+01045         patchs.resize(Patchs.size());
+01046         for(j=0;j<(sint)patchs.size();j++)
+01047         {
+01048                 CBezierPatch            &p= patchs[j];
+01049                 CPatch                          &pa= Patchs[j];
+01050 
+01051                 // re-Build the uncompressed bezier patch.
+01052                 for(i=0;i<4;i++)
+01053                         pa.Vertices[i].unpack(p.Vertices[i], PatchBias, PatchScale);
+01054                 for(i=0;i<8;i++)
+01055                         pa.Tangents[i].unpack(p.Tangents[i], PatchBias, PatchScale);
+01056                 for(i=0;i<4;i++)
+01057                         pa.Interiors[i].unpack(p.Interiors[i], PatchBias, PatchScale);
+01058         }
+01059 
+01060         // 1. apply heightfield on bezier patchs.
+01061         //===================================
+01062         for(j=0;j<(sint)patchs.size();j++)
+01063         {
+01064                 CBezierPatch            &p= patchs[j];
+01065 
+01066                 // apply delta.
+01067                 for(i=0;i<4;i++)
+01068                         p.Vertices[i]+= landScape.getHeightFieldDeltaZ(p.Vertices[i].x, p.Vertices[i].y);
+01069                 for(i=0;i<8;i++)
+01070                         p.Tangents[i]+= landScape.getHeightFieldDeltaZ(p.Tangents[i].x, p.Tangents[i].y);
+01071                 for(i=0;i<4;i++)
+01072                         p.Interiors[i]+= landScape.getHeightFieldDeltaZ(p.Interiors[i].x, p.Interiors[i].y);
+01073         }
+01074 
+01075 
+01076         // 2. Re-compute Patch Scale/Bias, and Zone BBox.
+01077         //===================================
+01078         CAABBox         bb;
+01079         bb.setCenter(patchs[0].Vertices[0]);
+01080         bb.setHalfSize(CVector::Null);
+01081         for(j=0;j<(sint)patchs.size();j++)
+01082         {
+01083                 // extend bbox.
+01084                 const CBezierPatch      &p= patchs[j];
+01085                 for(i=0;i<4;i++)
+01086                         bb.extend(p.Vertices[i]);
+01087                 for(i=0;i<8;i++)
+01088                         bb.extend(p.Tangents[i]);
+01089                 for(i=0;i<4;i++)
+01090                         bb.extend(p.Interiors[i]);
+01091         }
+01092         // Compute BBox, and Patch Scale Bias, according to Noise.
+01093         computeBBScaleBias(bb);
+01094 
+01095 
+01096         // 3. Re-pack patchs.
+01097         //===================================
+01098         for(j=0;j<(sint)patchs.size();j++)
+01099         {
+01100                 CBezierPatch            &p= patchs[j];
+01101                 CPatch                          &pa= Patchs[j];
+01102 
+01103                 // Build the packed patch.
+01104                 for(i=0;i<4;i++)
+01105                         pa.Vertices[i].pack(p.Vertices[i], PatchBias, PatchScale);
+01106                 for(i=0;i<8;i++)
+01107                         pa.Tangents[i].pack(p.Tangents[i], PatchBias, PatchScale);
+01108                 for(i=0;i<4;i++)
+01109                         pa.Interiors[i].pack(p.Interiors[i], PatchBias, PatchScale);
+01110         }
+01111 }
+01112 
+01113 
+01114 
+01115 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1