00001
00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 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
00036
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
00059 nlassert(!Compiled);
00060 }
00061
00062
00063
00064 void CZone::computeBBScaleBias(const CAABBox &bb)
00065 {
00066 ZoneBB= bb;
00067
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;
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
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
00102 computeBBScaleBias(bb);
00103
00104
00105
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
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
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
00132 pa.OrderS= pi.OrderS;
00133 pa.OrderT= pi.OrderT;
00134
00135
00136 uint lumelCount=(pi.OrderS*NL_LUMEL_BY_TILE+1)*(pi.OrderT*NL_LUMEL_BY_TILE+1);
00137
00138
00139 if (pi.Lumels.size ()==lumelCount)
00140 {
00141
00142 pa.packShadowMap (&pi.Lumels[0]);
00143 }
00144 else
00145 {
00146
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
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
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
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
00195 pa.unpackShadowMap (&pi.Lumels[0]);
00196
00197
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
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
00224
00225 ZoneBB= zone.ZoneBB;
00226 PatchScale= zone.PatchScale;
00227 PatchBias= zone.PatchBias;
00228
00229
00230
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 00275 00276 00277 00278 00279 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
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
00299 pa.OrderS=pc.OldOrderS;
00300 pa.OrderT=pc.OldOrderT;
00301
00302
00303 if (ver<1)
00304 {
00305
00306
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
00319 if (ver<2)
00320 {
00321
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
00336 nlassert(!Compiled);
00337 Landscape= landscape;
00338
00339
00340
00341 nlassert(loadedZones.find(ZoneId)==loadedZones.end());
00342 loadedZones[ZoneId]= this;
00343
00344
00345
00346 BaseVertices.clear();
00347 BaseVertices.resize(NumVertices);
00348
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
00362 neighborZones[zoneto]= zone;
00363
00364
00365 BaseVertices[cur]= zone->getBaseVertex(vertto);
00366 }
00367 }
00368
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
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
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
00405
00406 ItZoneMap zoneIt;
00407
00408 for(zoneIt= neighborZones.begin(); zoneIt!=neighborZones.end(); zoneIt++)
00409 {
00410 (*zoneIt).second->rebindBorder(loadedZones);
00411 }
00412
00413
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
00426
00427 nlassert(loadedZones.find(ZoneId)!=loadedZones.end());
00428 loadedZones.erase(ZoneId);
00429
00430
00431
00432
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 00441 00442 00443 00444
00445 }
00446
00447
00448
00449
00450
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
00464 neighborZones[zoneto]= zone;
00465 }
00466 }
00467
00468 ItZoneMap zoneIt;
00469
00470 for(zoneIt= neighborZones.begin(); zoneIt!=neighborZones.end(); zoneIt++)
00471 {
00472
00473 (*zoneIt).second->rebindBorder(loadedZones);
00474 }
00475
00476
00477
00478
00479
00480 for(j=0;j<(sint)Patchs.size();j++)
00481 {
00482 CPatch &pa= Patchs[j];
00483 pa.release();
00484 }
00485
00486
00487
00488
00489
00490 BaseVertices.clear();
00491
00492
00493
00494 Compiled= false;
00495 Landscape= NULL;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 void CZone::rebindBorder(TZoneMap &loadedZones)
00508 {
00509 sint j;
00510
00511
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 00542 00543 00544 00545
00546
00547
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
00557 if(paBind.NPatchs==5)
00558 {
00559
00560 exceptions[i]= CZone::getZonePatch(loadedZones, pcBind.ZoneId, pcBind.Next[0]);
00561
00562
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
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
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
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
00618 }
00619
00620
00621
00622 bool CZone::patchOnBorder(const CPatchConnect &pc) const
00623 {
00624
00625
00626
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
00646
00647
00648
00649
00650
00651 void CZone::clip(const std::vector<CPlane> &pyramid)
00652 {
00653 nlassert(Compiled);
00654
00655
00656 CurrentPyramid= pyramid;
00657
00658
00659 ClipResult= ClipIn;
00660 for(sint i=0;i<(sint)pyramid.size();i++)
00661 {
00662
00663 if(!ZoneBB.clipBack(pyramid[i]))
00664 {
00665 ClipResult= ClipOut;
00666
00667 break;
00668 }
00669
00670 else if(ZoneBB.clipFront(pyramid[i]))
00671 {
00672
00673 ClipResult=ClipSide;
00674 }
00675 }
00676
00677
00678 CBSphere zonesphere(ZoneBB.getCenter(), ZoneBB.getRadius());
00679 if(zonesphere.intersect(CTessFace::TileFarSphere))
00680 ComputeTileErrorMetric= true;
00681 else
00682 ComputeTileErrorMetric= false;
00683
00684
00685 if(Patchs.size()==0)
00686 {
00687 ClipResult= ClipOut;
00688 }
00689
00690
00691
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
00723
00724 00725 00726 00727 00728 00729 00730 00731 00732 00733 00734 00735 00736 00737 00738 00739 00740 00741 00742 00743 00744 00745 00746 00747 00748 00749 00750 00751 00752 00753 00754 00755 00756 00757 00758 00759 00760 00761 00762 00763 00764 00765 00766 00767 00768 00769 00770 00771 00772 00773 00774 00775 00776 00777
00778
00779
00780
00781
00782
00783
00784 void CZone::refine()
00785 {
00786 nlassert(Compiled);
00787
00788 static const sint hideRefineFreq= 15;
00789
00790
00791
00792 00793 00794 00795 00796 00797 00798 00799 00800 00801
00802
00803
00804
00805 if(ClipResult==ClipOut && (CTessFace::CurrentDate & hideRefineFreq)!=(ZoneId & hideRefineFreq))
00806 return;
00807
00808 if(Patchs.size()==0)
00809 return;
00810
00811 CPatch *pPatch= &(*Patchs.begin());
00812 if(ClipResult==ClipSide)
00813 {
00814
00815
00816 for(sint n=(sint)Patchs.size();n>0;n--, pPatch++)
00817 {
00818
00819 if(pPatch->isClipped() && (CTessFace::CurrentDate & hideRefineFreq)!=((ZoneId+n) & hideRefineFreq))
00820 continue;
00821 pPatch->refine();
00822 }
00823 }
00824 else
00825 {
00826
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
00840 if(Patchs.size()==0)
00841 return;
00842
00843
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
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
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
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
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
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
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
00958 if (tiles)
00959 {
00960 nlassert( Patchs[numPatch].Tiles.size() == tiles->size() );
00961 Patchs[numPatch].Tiles = *tiles;
00962 }
00963
00964
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
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
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
01040 if(Patchs.size()==0)
01041 return;
01042
01043
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
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
01061
01062 for(j=0;j<(sint)patchs.size();j++)
01063 {
01064 CBezierPatch &p= patchs[j];
01065
01066
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
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
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
01093 computeBBScaleBias(bb);
01094
01095
01096
01097
01098 for(j=0;j<(sint)patchs.size();j++)
01099 {
01100 CBezierPatch &p= patchs[j];
01101 CPatch &pa= Patchs[j];
01102
01103
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 }