00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047
00048 #include "OSGTiledQuadTreeTerrain.h"
00049 #include "OSGQuadTreeTerrain.h"
00050 #include "OSGRenderAction.h"
00051 #include "OSGImage.h"
00052 #include "OSGChunkMaterial.h"
00053
00054 OSG_USING_NAMESPACE
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 void TiledQuadTreeTerrain::initMethod(InitPhase ePhase)
00070 {
00071 Inherited::initMethod(ePhase);
00072
00073 if(ePhase == TypeObject::SystemPost)
00074 {
00075 RenderAction::registerEnterDefault(
00076 TiledQuadTreeTerrain::getClassType(),
00077 reinterpret_cast<Action::Callback>(&TiledQuadTreeTerrain::renderEnter));
00078 }
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 typedef std::vector<NodeUnrecPtr> NodeStore;
00091
00092
00093
00094
00095 TiledQuadTreeTerrain::TiledQuadTreeTerrain(void) :
00096 Inherited()
00097 {
00098 }
00099
00100 TiledQuadTreeTerrain::TiledQuadTreeTerrain(
00101 const TiledQuadTreeTerrain &source) :
00102
00103 Inherited(source)
00104 {
00105 }
00106
00107 TiledQuadTreeTerrain::~TiledQuadTreeTerrain(void)
00108 {
00109 }
00110
00111
00112
00113 inline MaterialTransitPtr cloneMaterial(Material * const mat)
00114 {
00115 #if 0
00116
00117 for(MFStateChunkPtr::const_iterator it = m->getChunks().begin();
00118 it != m->getChunks().end();
00119 ++it)
00120 {
00121 clone->addChunk(*it);
00122 }
00123 #endif
00124
00125 ChunkMaterial *m = dynamic_cast<ChunkMaterial *>(mat);
00126 ChunkMaterialTransitPtr clone(NULL);
00127
00128 if(m != NULL)
00129 {
00130 clone = dynamic_pointer_cast<ChunkMaterial>(m->shallowCopy());
00131 }
00132
00133 return MaterialTransitPtr(clone);
00134 }
00135
00136
00137 void TiledQuadTreeTerrain::changed(ConstFieldMaskArg whichField,
00138 UInt32 origin,
00139 BitVector details)
00140 {
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 if((whichField & HeightTilesFieldMask) && getMFHeightTiles()->size() > 0)
00152 {
00153 if(getParents().size() > 0 && getParents()[0] != NULL)
00154 {
00155 Node *pParent = dynamic_cast<Node *>(getParents()[0]);
00156
00157 while(pParent->getNChildren() > 0)
00158 {
00159 pParent->subChild(0u);
00160 }
00161
00162 Real32 step =
00163 (getHeightTiles(0)->getWidth()-1)*getVertexSpacing();
00164
00165 UInt32 i, j;
00166
00167 const UInt32 roi = getSizeROI()+getSizeROI()+1;
00168
00169
00170 for(j=0; j<roi; ++j)
00171 {
00172 for(i=0; i<roi; ++i)
00173 {
00174 QuadTreeTerrainUnrecPtr terrain = QuadTreeTerrain::create();
00175
00176 terrain->setVertexSpacing(getVertexSpacing());
00177 terrain->setHeightScale (getHeightScale());
00178 terrain->setGeoMorphing (getGeoMorphing());
00179 terrain->setDetail (getDetail());
00180 terrain->setBorderDetail (1);
00181 terrain->setEyePointValid(true);
00182 terrain->setUpdateTerrain(getUpdateTerrain());
00183 terrain->setPerPixelLighting(getPerPixelLighting());
00184
00185 NodeUnrecPtr node = Node::create();
00186
00187 node->setCore(terrain);
00188
00189
00190
00191 if (i < getSizeX() && j < getSizeY())
00192 {
00193 terrain->setHeightData(getHeightTiles(j*getSizeX()+i));
00194 terrain->setOriginX(i*step);
00195 terrain->setOriginY(j*step);
00196 node->setTravMask(TypeTraits<UInt32>::BitsSet);
00197 }
00198 else
00199 {
00200 node->setTravMask(0);
00201 }
00202
00203 pParent->addChild(node);
00204 }
00205 }
00206 }
00207 setCurrentX(getSizeROI());
00208 setCurrentY(getSizeROI());
00209 }
00210
00211 if(((whichField & MaterialFieldMask) ||
00212 (whichField & PerPixelLightingFieldMask)))
00213 {
00214 if(getParents().size() > 0 && getParents()[0] != NULL)
00215 {
00216 Real32 tstepx = 1.0f/getSizeX();
00217 Real32 tstepy = 1.0f/getSizeY();
00218 UInt32 i, j;
00219 const UInt32 roi = getSizeROI()+getSizeROI()+1;
00220 for(j=0; j<roi; ++j)
00221 {
00222 for(i=0; i<roi; ++i)
00223 {
00224 Node *pParent = dynamic_cast<Node *>(getParents()[0]);
00225
00226 Node *node = pParent->getChild(j*roi+i);
00227
00228 QuadTreeTerrain *terrain =
00229 dynamic_cast<QuadTreeTerrain *>(node->getCore());
00230
00231 if (terrain == NULL)
00232 {
00233 continue;
00234 }
00235
00236 if(getMaterial() == NULL)
00237 {
00238 if(getMFHeightTextures()->size() > j*getSizeX()+i &&
00239 i < getSizeX() && j < getSizeY())
00240 {
00241 terrain->setMaterial(
00242 getHeightTextures(j*getSizeX()+i));
00243 }
00244 }
00245 else
00246 {
00247 MaterialUnrecPtr mat = cloneMaterial(getMaterial());
00248 terrain->setMaterial(mat);
00249 terrain->setOriginTexX(i*tstepx);
00250 terrain->setOriginTexY(j*tstepy);
00251 terrain->setTexSpacing (tstepx);
00252 terrain->setTexYSpacing(tstepy);
00253 }
00254
00255 terrain->setPerPixelLighting(getPerPixelLighting());
00256 }
00257 }
00258 }
00259 }
00260
00261 if((whichField & GeoMorphingFieldMask))
00262 {
00263 if(getParents().size() > 0 && getParents()[0] != NULL)
00264 {
00265 const UInt32 roi = getSizeROI()+getSizeROI()+1;
00266 const UInt32 roi2 = roi*roi;
00267
00268 for(UInt32 i=0; i<roi2; ++i)
00269 {
00270 Node *pParent = dynamic_cast<Node *>(getParents()[0]);
00271
00272 Node *node = pParent->getChild(i);
00273
00274 QuadTreeTerrain *terrain =
00275 dynamic_cast<QuadTreeTerrain *>(node->getCore());
00276
00277 if(terrain == NULL)
00278 {
00279 continue;
00280 }
00281
00282 terrain->setGeoMorphing(getGeoMorphing());
00283 }
00284 }
00285 }
00286
00287 if((whichField & DetailFieldMask))
00288 {
00289 if(getParents().size() > 0 && getParents()[0] != NULL)
00290 {
00291 const UInt32 roi = getSizeROI()+getSizeROI()+1;
00292 const UInt32 roi2 = roi*roi;
00293
00294 for (UInt32 i=0; i<roi2; ++i)
00295 {
00296 Node *pParent = dynamic_cast<Node *>(getParents()[0]);
00297
00298 Node *node = pParent->getChild(i);
00299
00300 QuadTreeTerrain *terrain =
00301 dynamic_cast<QuadTreeTerrain *>(node->getCore());
00302
00303 if(terrain == NULL)
00304 {
00305 continue;
00306 }
00307
00308 terrain->setDetail(getDetail());
00309 }
00310 }
00311 }
00312 Inherited::changed(whichField, origin, details);
00313 }
00314
00315 inline void reorderChilds (Node * const parent, const NodeStore &order, Int32 num)
00316 {
00317 UInt32 num2 = num*num;
00318
00319 OSG_ASSERT(num2 <= order.size());
00320
00321 for(UInt32 i=0; i<num2; ++i)
00322 {
00323 parent->addChild(order[i]);
00324 }
00325 }
00326 inline void subAllChilds (Node * const parent, const NodeStore &order, Int32 num)
00327 {
00328
00329 while (parent->getNChildren() > 0)
00330 {
00331 parent->subChild(0u);
00332 }
00333 }
00334
00335 inline void caseChilds_n1n1(Node * const parent, NodeStore &order, Int32 num)
00336 {
00337 Int32 num2 = num*num-num;
00338 Int32 i, j, k;
00339
00340 for (i=0, k=0; i<num; ++i, ++k)
00341 {
00342 order[k] = parent->getChild(num2+i);
00343 }
00344 for(i=0; i<num-1; ++i)
00345 {
00346 order[k] = parent->getChild(i*num+num-1);
00347
00348 for(j=0, ++k; j<num-1; ++j, ++k)
00349 {
00350 order[k] = parent->getChild(i*num+j);
00351 }
00352 }
00353 subAllChilds(parent, order, num);
00354 }
00355
00356 inline void caseChilds_n10 (Node * const parent, NodeStore &order, Int32 num)
00357 {
00358 Int32 i, j, k;
00359
00360 for(i=0, k=0; i<num; ++i)
00361 {
00362 order[k] = parent->getChild(i*num+num-1);
00363
00364 for(j=0, ++k; j<num-1; ++j, ++k)
00365 {
00366 order[k] = parent->getChild(i*num+j);
00367 }
00368 }
00369 subAllChilds(parent, order, num);
00370 }
00371
00372 inline void caseChilds_n1p1 (Node * const parent, NodeStore &order, Int32 num)
00373 {
00374 Int32 i, j, k;
00375
00376 for(i=1, k=0; i<num; ++i)
00377 {
00378 order[k] = parent->getChild(i*num+num-1);
00379
00380 for(j=0, ++k; j<num-1; ++j, ++k)
00381 {
00382 order[k] = parent->getChild(i*num+j);
00383 }
00384 }
00385
00386 for(i=0; i<num; ++i, ++k)
00387 {
00388 order[k] = parent->getChild(i);
00389 }
00390 subAllChilds(parent, order, num);
00391 }
00392
00393 inline void caseChilds_0n1 (Node * const parent, NodeStore &order, Int32 num)
00394 {
00395 Int32 num2 = num*num-num;
00396 Int32 i, j, k;
00397
00398 for(i=0, k=0; i<num; ++i, ++k)
00399 {
00400 order[k] = parent->getChild(num2+i);
00401 }
00402
00403 for(i=0; i<num-1; ++i)
00404 {
00405 for(j=0; j<num; ++j, ++k)
00406 {
00407 order[k] = parent->getChild(i*num+j);
00408 }
00409 }
00410 subAllChilds(parent, order, num);
00411 }
00412
00413 inline void caseChilds_0p1 (Node * const parent, NodeStore &order, Int32 num)
00414 {
00415 Int32 i, j, k;
00416
00417 for(i=1, k=0; i<num; ++i)
00418 {
00419 for(j=0; j<num; ++j, ++k)
00420 {
00421 order[k] = parent->getChild(i*num+j);
00422 }
00423 }
00424
00425 for(i=0; i<num; ++i, ++k)
00426 {
00427 order[k] = parent->getChild(i);
00428 }
00429
00430 subAllChilds(parent, order, num);
00431 }
00432
00433 inline void caseChilds_p1n1 (Node * const parent, NodeStore &order, Int32 num)
00434 {
00435 Int32 num2 = num*num-num;
00436 Int32 i, j, k;
00437
00438 for(i=0, k=0; i<num; ++i, ++k)
00439 {
00440 order[k] = parent->getChild(num2+i);
00441 }
00442
00443 for(i=0; i<num-1; ++i, ++k)
00444 {
00445 for(j=1; j<num; ++j, ++k)
00446 {
00447 order[k] = parent->getChild(i*num+j);
00448 }
00449 order[k] = parent->getChild(i*num);
00450 }
00451 subAllChilds(parent, order, num);
00452 }
00453
00454 inline void caseChilds_p10 (Node * const parent, NodeStore &order, Int32 num)
00455 {
00456 Int32 i, j, k;
00457
00458 for(i=0, k=0; i<num; ++i, ++k)
00459 {
00460 for(j=1; j<num; ++j, ++k)
00461 {
00462 order[k] = parent->getChild(i*num+j);
00463 }
00464 order[k] = parent->getChild(i*num);
00465 }
00466 subAllChilds(parent, order, num);
00467 }
00468
00469 inline void caseChilds_p1p1 (Node * const parent, NodeStore &order, Int32 num)
00470 {
00471 Int32 i, j, k;
00472
00473 for(i=1, k=0; i<num; ++i, ++k)
00474 {
00475 for(j=1; j<num; ++j, ++k)
00476 {
00477 order[k] = parent->getChild(i*num+j);
00478 }
00479 order[k] = parent->getChild(i*num);
00480 }
00481
00482 for(i=0; i<num; ++i, ++k)
00483 {
00484 order[k] = parent->getChild(i);
00485 }
00486 subAllChilds(parent, order, num);
00487 }
00488
00489 #ifdef OSG_OLD_RENDER_ACTION
00490 Action::ResultE TiledQuadTreeTerrain::renderEnter (Action* action)
00491 {
00492 NodePtr node;
00493 QuadTreeTerrainPtr core;
00494
00495 RenderAction* da = dynamic_cast<RenderAction*>(action);
00496
00497 if(da != NULL && getUpdate() && getSizeX() > 0 && getSizeY() > 0)
00498 {
00499 const FrustumVolume& frustum = da->getFrustum();
00500
00501 Matrix camera = da->getCameraToWorld();
00502 Matrix toworld = da->top_matrix();
00503
00504 toworld.invert();
00505 camera.multLeft(toworld);
00506
00507
00508 Real32 step = (getHeightTiles(0)->getWidth()-1)*getVertexSpacing();
00509 Real32 tstepx = 1.0f/getSizeX();
00510 Real32 tstepy = 1.0f/getSizeY();
00511
00512
00513 Pnt3f eyePoint(camera[3][0], camera[3][1], camera[3][2]);
00514
00515
00516 const Int32 roi = getSizeROI()+getSizeROI()+1;
00517 const Int32 roi2 = roi*roi;
00518
00519 for(UInt32 i=0; i<roi2; ++i)
00520 {
00521 NodePtr pParent = dynamic_cast<NodePtr>(getParents()[0]);
00522 node = pParent->getChild(i);
00523
00524 core = dynamic_cast<QuadTreeTerrainPtr>(node->getCore());
00525
00526 core->setEyePoint(eyePoint);
00527 core->setUpdateTerrain(getUpdateTerrain());
00528 }
00529
00530
00531 Int32 x = Int32((eyePoint[0])/step);
00532 Int32 y = Int32((eyePoint[2])/step);
00533
00534 x = osgMax(x, 0);
00535 x = osgMin(x, Int32(getSizeX()-1));
00536 y = osgMax(y, 0);
00537 y = osgMin(y, Int32(getSizeY()-1));
00538
00539
00540 if(x != getCurrentX() || y != getCurrentY())
00541 {
00542 if(x < getCurrentX()-1)
00543 {
00544 x = getCurrentX()-1;
00545 }
00546 else if(x > getCurrentX()+1)
00547 {
00548 x = getCurrentX()+1;
00549 }
00550
00551 if(y < getCurrentY()-1)
00552 {
00553 y = getCurrentY()-1;
00554 }
00555 else if (y > getCurrentY()+1)
00556 {
00557 y = getCurrentY()+1;
00558 }
00559 SNOTICE << "current ("
00560 << getCurrentX() << ","
00561 << getCurrentY() << ")->("
00562 << x << ","
00563 << y << ")"
00564 << std::endl;
00565
00566 Int32 i, j;
00567
00568 NodeStore order;
00569 order.resize(roi * roi, NULL);
00570
00571 switch (x - getCurrentX())
00572 {
00573 case -1:
00574 switch (y - getCurrentY())
00575 {
00576 case -1:
00577 {
00578 NodePtr pParent =
00579 dynamic_cast<NodePtr>(getParents()[0]);
00580
00581 caseChilds_n1n1(pParent, order, roi);
00582
00583 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
00584 {
00585 node = order[i+getSizeROI()];
00586 if(y-getSizeROI() >= 0 &&
00587 x+i >= 0 &&
00588 x+i < getSizeX())
00589 {
00590 node->setTravMask(
00591 TypeTraits<UInt32>::BitsSet);
00592 core =
00593 dynamic_cast<QuadTreeTerrainPtr>(
00594 node->getCore());
00595
00596 core->setHeightData(
00597 getHeightTiles((y-getSizeROI())*
00598 getSizeX() + x+i));
00599
00600 if(getMaterial() == NULL)
00601 {
00602 core->setMaterial(
00603 getHeightTextures((y-getSizeROI())*
00604 getSizeX() + x+i));
00605 }
00606 else
00607 {
00608 core->setOriginTexX((x+i)*tstepx);
00609 core->setOriginTexY((y-getSizeROI())*
00610 tstepy);
00611 }
00612
00613 core->setOriginX((x+i)*step);
00614 core->setOriginY((y-getSizeROI())*step);
00615 }
00616 else
00617 {
00618 node->setTravMask(0);
00619 }
00620 }
00621
00622 for(i=-getSizeROI()+1; i<=getSizeROI(); ++i)
00623 {
00624 node = order[(i+getSizeROI())*roi];
00625
00626 if(x-getSizeROI() >= 0 &&
00627 y+i >= 0 &&
00628 y+i < getSizeY())
00629 {
00630 node->setTravMask(
00631 TypeTraits<UInt32>::BitsSet);
00632 core =
00633 dynamic_cast<QuadTreeTerrainPtr>(
00634 node->getCore());
00635
00636 core->setHeightData(
00637 getHeightTiles((y+i)*
00638 getSizeX() +
00639 (x-getSizeROI())));
00640
00641 if(getMaterial() == NULL)
00642 {
00643 core->setMaterial(
00644 getHeightTextures((y+i)*
00645 getSizeX() +
00646 x-getSizeROI()));
00647 }
00648 else
00649 {
00650 core->setOriginTexX((x-getSizeROI())*
00651 tstepx);
00652
00653 core->setOriginTexY((y+i)*tstepy);
00654 }
00655
00656 core->setOriginX((x-getSizeROI())*step);
00657 core->setOriginY((y+i)*step);
00658 }
00659 else
00660 {
00661 node->setTravMask(0);
00662 }
00663 }
00664 reorderChilds(pParent, order, roi);
00665 break;
00666 }
00667 case 0:
00668 {
00669 NodePtr pParent =
00670 dynamic_cast<NodePtr>(getParents()[0]);
00671
00672 caseChilds_n10(pParent, order, roi);
00673
00674 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
00675 {
00676 node = order[(i+getSizeROI())*roi];
00677
00678 if(x-getSizeROI() >= 0 &&
00679 y+i >= 0 &&
00680 y+i < getSizeY())
00681 {
00682 node->setTravMask(
00683 TypeTraits<UInt32>::BitsSet);
00684 core =
00685 dynamic_cast<QuadTreeTerrainPtr>(
00686 node->getCore());
00687
00688 core->setHeightData(
00689 getHeightTiles((y+i)*
00690 getSizeX() +
00691 x-getSizeROI()));
00692
00693 if(getMaterial() == NULL)
00694 {
00695 core->setMaterial(
00696 getHeightTextures((y+i)*
00697 getSizeX() +
00698 x-getSizeROI()));
00699 }
00700 else
00701 {
00702 core->setOriginTexX((x-getSizeROI())*
00703 tstepx);
00704 core->setOriginTexY((y+i)*tstepy);
00705 }
00706
00707 core->setOriginX((x-getSizeROI())*step);
00708 core->setOriginY((y+i)*step);
00709 }
00710 else
00711 {
00712 node->setTravMask(0);
00713 }
00714 }
00715 reorderChilds(pParent, order, roi);
00716 break;
00717 }
00718
00719 case 1:
00720 {
00721 NodePtr pParent =
00722 dynamic_cast<NodePtr>(getParents()[0]);
00723
00724 caseChilds_n1p1(pParent, order, roi);
00725
00726 for(i=-getSizeROI(); i<getSizeROI(); ++i)
00727 {
00728 node = order[(i+getSizeROI())*roi];
00729
00730 if(x-getSizeROI() >= 0 &&
00731 y+i >= 0 &&
00732 y+i < getSizeY())
00733 {
00734 node->setTravMask(
00735 TypeTraits<UInt32>::BitsSet);
00736 core =
00737 dynamic_cast<QuadTreeTerrainPtr>(
00738 node->getCore());
00739
00740 core->setHeightData(
00741 getHeightTiles((y+i)*
00742 getSizeX() +
00743 x-getSizeROI()));
00744
00745 if(getMaterial() == NULL)
00746 {
00747 core->setMaterial(
00748 getHeightTextures((y+i)*
00749 getSizeX() +
00750 x-getSizeROI()));
00751 }
00752 else
00753 {
00754 core->setOriginTexX((x-getSizeROI())*
00755 tstepx);
00756 core->setOriginTexY((y+i)*tstepy);
00757 }
00758
00759 core->setOriginX((x-getSizeROI())*step);
00760 core->setOriginY((y+i)*step);
00761 }
00762 else
00763 {
00764 node->setTravMask(0);
00765 }
00766 }
00767
00768 for(j=-getSizeROI(); j<=getSizeROI(); ++j)
00769 {
00770 node = order[roi2-roi+j+getSizeROI()];
00771
00772 if(x+j >= 0 &&
00773 x+j < getSizeX() &&
00774 y+getSizeROI() < getSizeY())
00775 {
00776 node->setTravMask(
00777 TypeTraits<UInt32>::BitsSet);
00778 core =
00779 dynamic_cast<QuadTreeTerrainPtr>(
00780 node->getCore());
00781
00782 core->setHeightData(
00783 getHeightTiles((y+getSizeROI())*
00784 getSizeX() +
00785 x+j));
00786
00787 if(getMaterial() == NULL)
00788 {
00789 core->setMaterial(
00790 getHeightTextures((y+
00791 getSizeROI())*
00792 getSizeX() + x+j));
00793 }
00794 else
00795 {
00796 core->setOriginTexX((x+j)*tstepx);
00797 core->setOriginTexY((y+getSizeROI())*
00798 tstepy);
00799 }
00800
00801 core->setOriginX((x+j)*step);
00802 core->setOriginY((y+getSizeROI())*step);
00803 }
00804 else
00805 {
00806 node->setTravMask(0);
00807 }
00808 }
00809 reorderChilds(pParent, order, roi);
00810 break;
00811 }
00812 }
00813 break;
00814
00815 case 0:
00816 switch (y - getCurrentY())
00817 {
00818 case -1:
00819 {
00820 NodePtr pParent =
00821 dynamic_cast<NodePtr>(getParents()[0]);
00822
00823 caseChilds_0n1(pParent, order, roi);
00824
00825 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
00826 {
00827 node = order[i+getSizeROI()];
00828
00829 if (x+i >= 0 &&
00830 x+i < getSizeX() &&
00831 y-getSizeROI() >= 0)
00832 {
00833 node->setTravMask(
00834 TypeTraits<UInt32>::BitsSet);
00835 core =
00836 dynamic_cast<QuadTreeTerrainPtr>(
00837 node->getCore());
00838
00839 core->setHeightData(
00840 getHeightTiles((y-getSizeROI())*
00841 getSizeX() + x+i));
00842
00843 if(getMaterial() == NULL)
00844 {
00845 core->setMaterial(
00846 getHeightTextures((y-getSizeROI())*
00847 getSizeX() + x+i));
00848 }
00849 else
00850 {
00851 core->setOriginTexX((x+i)*tstepx);
00852 core->setOriginTexY((y-getSizeROI())*
00853 tstepy);
00854 }
00855
00856 core->setOriginX((x+i)*step);
00857 core->setOriginY((y-getSizeROI())*step);
00858 }
00859 else
00860 {
00861 node->setTravMask(0);
00862 }
00863 }
00864 reorderChilds(pParent, order, roi);
00865 break;
00866 }
00867 case 1:
00868 {
00869 NodePtr pParent =
00870 dynamic_cast<NodePtr>(getParents()[0]);
00871
00872 caseChilds_0p1(pParent, order, roi);
00873
00874 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
00875 {
00876 node = order[roi2-roi+(i+getSizeROI())];
00877 if(x+i >= 0 &&
00878 x+i < getSizeX() &&
00879 y+getSizeROI() < getSizeY())
00880 {
00881 node->setTravMask(
00882 TypeTraits<UInt32>::BitsSet);
00883 core =
00884 dynamic_cast<QuadTreeTerrainPtr>(
00885 node->getCore());
00886
00887 core->setHeightData(
00888 getHeightTiles((y+getSizeROI())*
00889 getSizeX() + x+i));
00890
00891 if(getMaterial() == NULL)
00892 {
00893 core->setMaterial(
00894 getHeightTextures((y+getSizeROI())*
00895 getSizeX() + x+i));
00896 }
00897 else
00898 {
00899 core->setOriginTexX((x+i)*tstepx);
00900 core->setOriginTexY((y+getSizeROI())*
00901 tstepy);
00902 }
00903 core->setOriginX((x+i)*step);
00904 core->setOriginY((y+getSizeROI())*step);
00905 }
00906 else
00907 {
00908 node->setTravMask(0);
00909 }
00910 }
00911 reorderChilds(pParent, order, roi);
00912 break;
00913 }
00914 }
00915 break;
00916 case +1:
00917 switch (y - getCurrentY())
00918 {
00919 case -1:
00920 {
00921 NodePtr pParent =
00922 dynamic_cast<NodePtr>(getParents()[0]);
00923
00924 caseChilds_p1n1(pParent, order, roi);
00925
00926 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
00927 {
00928 node = order[i+getSizeROI()];
00929
00930 if(x+i >= 0 &&
00931 x+i < getSizeX() &&
00932 y-getSizeROI() >= 0)
00933 {
00934 node->setTravMask(
00935 TypeTraits<UInt32>::BitsSet);
00936 core =
00937 dynamic_cast<QuadTreeTerrainPtr>(
00938 node->getCore());
00939
00940 core->setHeightData(
00941 getHeightTiles((y-getSizeROI())*
00942 getSizeX() + x+i));
00943
00944 if(getMaterial() == NULL)
00945 {
00946 core->setMaterial(
00947 getHeightTextures((y-getSizeROI())*
00948 getSizeX() + x+i));
00949 }
00950 else
00951 {
00952 core->setOriginTexX((x+i)*tstepx);
00953 core->setOriginTexY((y-getSizeROI())*
00954 tstepy);
00955 }
00956
00957 core->setOriginX((x+i)*step);
00958 core->setOriginY((y-getSizeROI())*step);
00959 }
00960 else
00961 {
00962 node->setTravMask(0);
00963 }
00964 }
00965
00966 for(i=-getSizeROI()+1; i<=getSizeROI(); ++i)
00967 {
00968 node = order[(i+getSizeROI())*roi+(roi-1)];
00969
00970 if(x+getSizeROI() < getSizeX() &&
00971 y+i >= 0 &&
00972 y+i < getSizeY())
00973 {
00974 node->setTravMask(
00975 TypeTraits<UInt32>::BitsSet);
00976 core =
00977 dynamic_cast<QuadTreeTerrainPtr>(
00978 node->getCore());
00979
00980 core->setHeightData(
00981 getHeightTiles((y+i)*getSizeX() +
00982 (x+getSizeROI())));
00983
00984 if(getMaterial() == NULL)
00985 {
00986 core->setMaterial(
00987 getHeightTextures((y+i)*
00988 getSizeX() +
00989 x+getSizeROI()));
00990 }
00991 else
00992 {
00993 core->setOriginTexX((x+getSizeROI())*
00994 tstepx);
00995 core->setOriginTexY((y+i)*tstepy);
00996 }
00997
00998 core->setOriginX((x+getSizeROI())*step);
00999 core->setOriginY((y+i)*step);
01000 }
01001 else
01002 {
01003 node->setTravMask(0);
01004 }
01005 }
01006 reorderChilds(pParent, order, roi);
01007 break;
01008 }
01009 case 0:
01010 {
01011 NodePtr pParent =
01012 dynamic_cast<NodePtr>(getParents()[0]);
01013
01014 caseChilds_p10(pParent, order, roi);
01015
01016 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
01017 {
01018 node = order[(i+getSizeROI())*roi+roi-1];
01019
01020 if(x+getSizeROI() < getSizeX() &&
01021 y+i >= 0 &&
01022 y+i < getSizeY())
01023 {
01024 node->setTravMask(
01025 TypeTraits<UInt32>::BitsSet);
01026 core =
01027 dynamic_cast<QuadTreeTerrainPtr>(
01028 node->getCore());
01029
01030 core->setHeightData(
01031 getHeightTiles((y+i)*
01032 getSizeX() +
01033 x+getSizeROI()));
01034
01035 if(getMaterial() == NULL)
01036 {
01037 core->setMaterial(
01038 getHeightTextures((y+i)*
01039 getSizeX() +
01040 x+getSizeROI()));
01041 }
01042 else
01043 {
01044 core->setOriginTexX((x+getSizeROI())*
01045 tstepx);
01046 core->setOriginTexY((y+i)*tstepy);
01047 }
01048
01049 core->setOriginX((x+getSizeROI())*step);
01050 core->setOriginY((y+i)*step);
01051 }
01052 else
01053 {
01054 node->setTravMask(0);
01055 }
01056 }
01057 reorderChilds(pParent, order, roi);
01058 break;
01059 }
01060 case 1:
01061 {
01062 NodePtr pParent =
01063 dynamic_cast<NodePtr>(getParents()[0]);
01064
01065 caseChilds_p1p1(pParent, order, roi);
01066
01067 for(i=-getSizeROI(); i<getSizeROI(); ++i)
01068 {
01069 node = order[(i+getSizeROI())*roi+roi-1];
01070
01071 if(x-getSizeROI() >= 0 &&
01072 y+i >= 0 &&
01073 y+i < getSizeY())
01074 {
01075 node->setTravMask(
01076 TypeTraits<UInt32>::BitsSet);
01077 core =
01078 dynamic_cast<QuadTreeTerrainPtr>(
01079 node->getCore());
01080
01081 core->setHeightData(
01082 getHeightTiles((y+i)*getSizeX() +
01083 x-getSizeROI()));
01084
01085 if(getMaterial() == NULL)
01086 {
01087 core->setMaterial(
01088 getHeightTextures((y+i)*
01089 getSizeX() +
01090 x-getSizeROI()));
01091 }
01092 else
01093 {
01094 core->setOriginTexX((x-getSizeROI())*
01095 tstepx);
01096 core->setOriginTexY((y+i)*tstepy);
01097 }
01098
01099 core->setOriginX((x-getSizeROI())*step);
01100 core->setOriginY((y+i)*step);
01101
01102 }
01103 else
01104 {
01105 node->setTravMask(0);
01106 }
01107 }
01108
01109 for(j=-getSizeROI(); j<=getSizeROI(); ++j)
01110 {
01111 node = order[roi2-roi+(j+getSizeROI())];
01112
01113 if(y+getSizeROI() < getSizeY() &&
01114 x+j >= 0 &&
01115 x+j < getSizeX())
01116 {
01117 node->setTravMask(
01118 TypeTraits<UInt32>::BitsSet);
01119 core =
01120 dynamic_cast<QuadTreeTerrainPtr>(
01121 node->getCore());
01122
01123 core->setHeightData(
01124 getHeightTiles((y+getSizeROI())*
01125 getSizeX() + x+j));
01126
01127 if(getMaterial() == NULL)
01128 {
01129 core->setMaterial(
01130 getHeightTextures((y+getSizeROI())*
01131 getSizeX() + x+j));
01132 }
01133 else
01134 {
01135 core->setOriginTexX((x+j)*tstepx);
01136 core->setOriginTexY((y+getSizeROI())*
01137 tstepy);
01138 }
01139
01140 core->setOriginX((x+j)*step);
01141 core->setOriginY((y+getSizeROI())*step);
01142 }
01143 else
01144 {
01145 node->setTravMask(0);
01146 }
01147 }
01148 reorderChilds(pParent, order, roi);
01149
01150 break;
01151 }
01152 }
01153 break;
01154 }
01155
01156
01157 setCurrentX(x);
01158 setCurrentY(y);
01159
01160 #ifdef OSG_DEBUG
01161 UInt32 dup;
01162 for (UInt32 i=0; i<roi2; ++i)
01163 {
01164 NodePtr pParent = dynamic_cast<NodePtr>(getParents()[0]);
01165 node = pParent->getChild(i);
01166
01167 core = dynamic_cast<QuadTreeTerrainPtr>(node->getCore());
01168
01169 if(node->getTravMask())
01170 {
01171 std::cout << "tile " << i << "("
01172 << core->getOriginX() << ","
01173 << core->getOriginY() << "):";
01174 dup = 0;
01175
01176 for(UInt32 j=0; j<roi2; ++j)
01177 {
01178 NodePtr pParent2 =
01179 dynamic_cast<NodePtr>(getParents()[0]);
01180 NodePtr node2 = pParent2->getChild(j);
01181 QuadTreeTerrainPtr core2 =
01182 dynamic_cast<QuadTreeTerrainPtr>(node2->getCore());
01183
01184 if (node2->getTravMask() &&
01185 core->getOriginX() == core2->getOriginX() &&
01186 core->getOriginY() == core2->getOriginY())
01187 {
01188 std::cout << " " << j;
01189 ++dup;
01190 }
01191 }
01192
01193 std::cout << std::endl;
01194
01195 if(dup > 1)
01196 {
01197 SFATAL << "tile has " << dup-1
01198 << " duplicates!" << std::endl;
01199 }
01200 }
01201 }
01202 #endif
01203 }
01204 }
01205
01206 UInt32 numIndis = 0;
01207 UInt32 numFans = 0;
01208 NodePtr pParent = dynamic_cast<NodePtr>(getParents()[0]);
01209
01210 for(UInt32 i=0; i<pParent->getNChildren(); ++i)
01211 {
01212 node = pParent->getChild(i);
01213
01214 if (node != NULL)
01215 {
01216 core = dynamic_cast<QuadTreeTerrainPtr>(node->getCore());
01217
01218 if(core != NULL && core->getIndices() != NULL)
01219 {
01220 numIndis += core->getIndices()->size();
01221 numFans += core->getTypes()->size();
01222 }
01223 }
01224 }
01225 SNOTICE << numIndis/3 << " triangles in "
01226 << numFans << " fans" << std::endl;
01227
01228 return Action::Continue;
01229 }
01230 #endif
01231
01232 Action::ResultE TiledQuadTreeTerrain::renderEnter (Action* action)
01233 {
01234 RenderAction* da =
01235 dynamic_cast<RenderAction*>(action);
01236
01237 Action::ResultE returnValue =
01238 this->doRenderEnter(da->getFrustum(),
01239 da->getActivePartition()->getCameraToWorld(),
01240 da->getActivePartition()->topMatrix());
01241
01242
01243 return returnValue;
01244 }
01245
01246 Action::ResultE TiledQuadTreeTerrain::doRenderEnter(
01247 const FrustumVolume &frustum,
01248 Matrix camera,
01249 Matrix toworld)
01250 {
01251 Node *node;
01252 QuadTreeTerrain *core;
01253
01254
01255
01256 if(getUpdate() && getSizeX() > 0 && getSizeY() > 0)
01257 {
01258
01259
01260
01261
01262
01263 toworld.invert();
01264 camera.multLeft(toworld);
01265
01266
01267 Real32 step = (getHeightTiles(0)->getWidth()-1)*getVertexSpacing();
01268 Real32 tstepx = 1.0f/getSizeX();
01269 Real32 tstepy = 1.0f/getSizeY();
01270
01271
01272 Pnt3f eyePoint(camera[3][0], camera[3][1], camera[3][2]);
01273
01274
01275 const UInt32 roi = getSizeROI()+getSizeROI()+1;
01276 const UInt32 roi2 = roi*roi;
01277
01278 for(UInt32 i=0; i<roi2; ++i)
01279 {
01280 Node *pParent = dynamic_cast<Node *>(getParents()[0]);
01281
01282 node = pParent->getChild(i);
01283
01284 core = dynamic_cast<QuadTreeTerrain *>(node->getCore());
01285
01286 core->setEyePoint(eyePoint);
01287 core->setUpdateTerrain(getUpdateTerrain());
01288 }
01289
01290
01291 Int32 x = Int32((eyePoint[0])/step);
01292 Int32 y = Int32((eyePoint[2])/step);
01293
01294 x = osgMax(x, 0);
01295 x = osgMin(x, Int32(getSizeX()-1));
01296 y = osgMax(y, 0);
01297 y = osgMin(y, Int32(getSizeY()-1));
01298
01299
01300 if(x != getCurrentX() || y != getCurrentY())
01301 {
01302 if(x < getCurrentX()-1)
01303 {
01304 x = getCurrentX()-1;
01305 }
01306 else if(x > getCurrentX()+1)
01307 {
01308 x = getCurrentX()+1;
01309 }
01310
01311 if(y < getCurrentY()-1)
01312 {
01313 y = getCurrentY()-1;
01314 }
01315 else if (y > getCurrentY()+1)
01316 {
01317 y = getCurrentY()+1;
01318 }
01319 SNOTICE << "current ("
01320 << getCurrentX() << ","
01321 << getCurrentY() << ")->("
01322 << x << ","
01323 << y << ")"
01324 << std::endl;
01325
01326 Int32 i, j;
01327
01328 NodeStore order;
01329 order.resize(roi * roi, NULL);
01330
01331 switch (x - getCurrentX())
01332 {
01333 case -1:
01334 switch (y - getCurrentY())
01335 {
01336 case -1:
01337 {
01338 Node *pParent =
01339 dynamic_cast<Node *>(getParents()[0]);
01340
01341 caseChilds_n1n1(pParent, order, roi);
01342
01343 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
01344 {
01345 node = order[i+getSizeROI()];
01346 if(y-getSizeROI() >= 0 &&
01347 x+i >= 0 &&
01348 x+i < Int32(getSizeX()))
01349 {
01350 node->setTravMask(
01351 TypeTraits<UInt32>::BitsSet);
01352 core =
01353 dynamic_cast<QuadTreeTerrain *>(
01354 node->getCore());
01355
01356 core->setHeightData(
01357 getHeightTiles((y-getSizeROI())*
01358 getSizeX() + x+i));
01359
01360 if(getMaterial() == NULL)
01361 {
01362 core->setMaterial(
01363 getHeightTextures((y-getSizeROI())*
01364 getSizeX() + x+i));
01365 }
01366 else
01367 {
01368 core->setOriginTexX((x+i)*tstepx);
01369 core->setOriginTexY((y-getSizeROI())*
01370 tstepy);
01371 }
01372
01373 core->setOriginX((x+i)*step);
01374 core->setOriginY((y-getSizeROI())*step);
01375 }
01376 else
01377 {
01378 node->setTravMask(0);
01379 }
01380 }
01381
01382 for(i=-getSizeROI()+1; i<=getSizeROI(); ++i)
01383 {
01384 node = order[(i+getSizeROI())*roi];
01385
01386 if(x-getSizeROI() >= 0 &&
01387 y+i >= 0 &&
01388 y+i < Int32(getSizeY()))
01389 {
01390 node->setTravMask(
01391 TypeTraits<UInt32>::BitsSet);
01392 core =
01393 dynamic_cast<QuadTreeTerrain *>(
01394 node->getCore());
01395
01396 core->setHeightData(
01397 getHeightTiles((y+i)*
01398 getSizeX() +
01399 (x-getSizeROI())));
01400
01401 if(getMaterial() == NULL)
01402 {
01403 core->setMaterial(
01404 getHeightTextures((y+i)*
01405 getSizeX() +
01406 x-getSizeROI()));
01407 }
01408 else
01409 {
01410 core->setOriginTexX((x-getSizeROI())*
01411 tstepx);
01412
01413 core->setOriginTexY((y+i)*tstepy);
01414 }
01415
01416 core->setOriginX((x-getSizeROI())*step);
01417 core->setOriginY((y+i)*step);
01418 }
01419 else
01420 {
01421 node->setTravMask(0);
01422 }
01423 }
01424 reorderChilds(pParent, order, roi);
01425 break;
01426 }
01427 case 0:
01428 {
01429 Node *pParent =
01430 dynamic_cast<Node *>(getParents()[0]);
01431
01432 caseChilds_n10(pParent, order, roi);
01433
01434 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
01435 {
01436 node = order[(i+getSizeROI())*roi];
01437
01438 if(x-getSizeROI() >= 0 &&
01439 y+i >= 0 &&
01440 y+i < Int32(getSizeY()))
01441 {
01442 node->setTravMask(
01443 TypeTraits<UInt32>::BitsSet);
01444 core =
01445 dynamic_cast<QuadTreeTerrain *>(
01446 node->getCore());
01447
01448 core->setHeightData(
01449 getHeightTiles((y+i)*
01450 getSizeX() +
01451 x-getSizeROI()));
01452
01453 if(getMaterial() == NULL)
01454 {
01455 core->setMaterial(
01456 getHeightTextures((y+i)*
01457 getSizeX() +
01458 x-getSizeROI()));
01459 }
01460 else
01461 {
01462 core->setOriginTexX((x-getSizeROI())*
01463 tstepx);
01464 core->setOriginTexY((y+i)*tstepy);
01465 }
01466
01467 core->setOriginX((x-getSizeROI())*step);
01468 core->setOriginY((y+i)*step);
01469 }
01470 else
01471 {
01472 node->setTravMask(0);
01473 }
01474 }
01475 reorderChilds(pParent, order, roi);
01476 break;
01477 }
01478
01479 case 1:
01480 {
01481 Node *pParent =
01482 dynamic_cast<Node *>(getParents()[0]);
01483
01484 caseChilds_n1p1(pParent, order, roi);
01485
01486 for(i=-getSizeROI(); i<getSizeROI(); ++i)
01487 {
01488 node = order[(i+getSizeROI())*roi];
01489
01490 if(x-getSizeROI() >= 0 &&
01491 y+i >= 0 &&
01492 y+i < Int32(getSizeY()))
01493 {
01494 node->setTravMask(
01495 TypeTraits<UInt32>::BitsSet);
01496 core =
01497 dynamic_cast<QuadTreeTerrain *>(
01498 node->getCore());
01499
01500 core->setHeightData(
01501 getHeightTiles((y+i)*
01502 getSizeX() +
01503 x-getSizeROI()));
01504
01505 if(getMaterial() == NULL)
01506 {
01507 core->setMaterial(
01508 getHeightTextures((y+i)*
01509 getSizeX() +
01510 x-getSizeROI()));
01511 }
01512 else
01513 {
01514 core->setOriginTexX((x-getSizeROI())*
01515 tstepx);
01516 core->setOriginTexY((y+i)*tstepy);
01517 }
01518
01519 core->setOriginX((x-getSizeROI())*step);
01520 core->setOriginY((y+i)*step);
01521 }
01522 else
01523 {
01524 node->setTravMask(0);
01525 }
01526 }
01527
01528 for(j=-getSizeROI(); j<=getSizeROI(); ++j)
01529 {
01530 node = order[roi2-roi+j+getSizeROI()];
01531
01532 if(x+j >= 0 &&
01533 x+j < Int32(getSizeX()) &&
01534 y+getSizeROI() < Int32(getSizeY()))
01535 {
01536 node->setTravMask(
01537 TypeTraits<UInt32>::BitsSet);
01538 core =
01539 dynamic_cast<QuadTreeTerrain *>(
01540 node->getCore());
01541
01542 core->setHeightData(
01543 getHeightTiles((y+getSizeROI())*
01544 getSizeX() +
01545 x+j));
01546
01547 if(getMaterial() == NULL)
01548 {
01549 core->setMaterial(
01550 getHeightTextures((y+
01551 getSizeROI())*
01552 getSizeX() + x+j));
01553 }
01554 else
01555 {
01556 core->setOriginTexX((x+j)*tstepx);
01557 core->setOriginTexY((y+getSizeROI())*
01558 tstepy);
01559 }
01560
01561 core->setOriginX((x+j)*step);
01562 core->setOriginY((y+getSizeROI())*step);
01563 }
01564 else
01565 {
01566 node->setTravMask(0);
01567 }
01568 }
01569 reorderChilds(pParent, order, roi);
01570 break;
01571 }
01572 }
01573 break;
01574
01575 case 0:
01576 switch (y - getCurrentY())
01577 {
01578 case -1:
01579 {
01580 Node *pParent =
01581 dynamic_cast<Node *>(getParents()[0]);
01582
01583 caseChilds_0n1(pParent, order, roi);
01584
01585 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
01586 {
01587 node = order[i+getSizeROI()];
01588
01589 if (x+i >= 0 &&
01590 x+i < Int32(getSizeX()) &&
01591 y-getSizeROI() >= 0)
01592 {
01593 node->setTravMask(
01594 TypeTraits<UInt32>::BitsSet);
01595 core =
01596 dynamic_cast<QuadTreeTerrain *>(
01597 node->getCore());
01598
01599 core->setHeightData(
01600 getHeightTiles((y-getSizeROI())*
01601 getSizeX() + x+i));
01602
01603 if(getMaterial() == NULL)
01604 {
01605 core->setMaterial(
01606 getHeightTextures((y-getSizeROI())*
01607 getSizeX() + x+i));
01608 }
01609 else
01610 {
01611 core->setOriginTexX((x+i)*tstepx);
01612 core->setOriginTexY((y-getSizeROI())*
01613 tstepy);
01614 }
01615
01616 core->setOriginX((x+i)*step);
01617 core->setOriginY((y-getSizeROI())*step);
01618 }
01619 else
01620 {
01621 node->setTravMask(0);
01622 }
01623 }
01624 reorderChilds(pParent, order, roi);
01625 break;
01626 }
01627 case 1:
01628 {
01629 Node *pParent =
01630 dynamic_cast<Node *>(getParents()[0]);
01631
01632 caseChilds_0p1(pParent, order, roi);
01633
01634 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
01635 {
01636 node = order[roi2-roi+(i+getSizeROI())];
01637 if(x+i >= 0 &&
01638 x+i < Int32(getSizeX()) &&
01639 y+getSizeROI() < Int32(getSizeY()))
01640 {
01641 node->setTravMask(
01642 TypeTraits<UInt32>::BitsSet);
01643 core =
01644 dynamic_cast<QuadTreeTerrain *>(
01645 node->getCore());
01646
01647 core->setHeightData(
01648 getHeightTiles((y+getSizeROI())*
01649 getSizeX() + x+i));
01650
01651 if(getMaterial() == NULL)
01652 {
01653 core->setMaterial(
01654 getHeightTextures((y+getSizeROI())*
01655 getSizeX() + x+i));
01656 }
01657 else
01658 {
01659 core->setOriginTexX((x+i)*tstepx);
01660 core->setOriginTexY((y+getSizeROI())*
01661 tstepy);
01662 }
01663 core->setOriginX((x+i)*step);
01664 core->setOriginY((y+getSizeROI())*step);
01665 }
01666 else
01667 {
01668 node->setTravMask(0);
01669 }
01670 }
01671 reorderChilds(pParent, order, roi);
01672 break;
01673 }
01674 }
01675 break;
01676 case +1:
01677 switch (y - getCurrentY())
01678 {
01679 case -1:
01680 {
01681 Node *pParent =
01682 dynamic_cast<Node *>(getParents()[0]);
01683
01684 caseChilds_p1n1(pParent, order, roi);
01685
01686 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
01687 {
01688 node = order[i+getSizeROI()];
01689
01690 if(x+i >= 0 &&
01691 x+i < Int32(getSizeX()) &&
01692 y-getSizeROI() >= 0)
01693 {
01694 node->setTravMask(
01695 TypeTraits<UInt32>::BitsSet);
01696 core =
01697 dynamic_cast<QuadTreeTerrain *>(
01698 node->getCore());
01699
01700 core->setHeightData(
01701 getHeightTiles((y-getSizeROI())*
01702 getSizeX() + x+i));
01703
01704 if(getMaterial() == NULL)
01705 {
01706 core->setMaterial(
01707 getHeightTextures((y-getSizeROI())*
01708 getSizeX() + x+i));
01709 }
01710 else
01711 {
01712 core->setOriginTexX((x+i)*tstepx);
01713 core->setOriginTexY((y-getSizeROI())*
01714 tstepy);
01715 }
01716
01717 core->setOriginX((x+i)*step);
01718 core->setOriginY((y-getSizeROI())*step);
01719 }
01720 else
01721 {
01722 node->setTravMask(0);
01723 }
01724 }
01725
01726 for(i=-getSizeROI()+1; i<=getSizeROI(); ++i)
01727 {
01728 node = order[(i+getSizeROI())*roi+(roi-1)];
01729
01730 if(x+getSizeROI() < Int32(getSizeX()) &&
01731 y+i >= 0 &&
01732 y+i < Int32(getSizeY()))
01733 {
01734 node->setTravMask(
01735 TypeTraits<UInt32>::BitsSet);
01736 core =
01737 dynamic_cast<QuadTreeTerrain *>(
01738 node->getCore());
01739
01740 core->setHeightData(
01741 getHeightTiles((y+i)*getSizeX() +
01742 (x+getSizeROI())));
01743
01744 if(getMaterial() == NULL)
01745 {
01746 core->setMaterial(
01747 getHeightTextures((y+i)*
01748 getSizeX() +
01749 x+getSizeROI()));
01750 }
01751 else
01752 {
01753 core->setOriginTexX((x+getSizeROI())*
01754 tstepx);
01755 core->setOriginTexY((y+i)*tstepy);
01756 }
01757
01758 core->setOriginX((x+getSizeROI())*step);
01759 core->setOriginY((y+i)*step);
01760 }
01761 else
01762 {
01763 node->setTravMask(0);
01764 }
01765 }
01766 reorderChilds(pParent, order, roi);
01767 break;
01768 }
01769 case 0:
01770 {
01771 Node *pParent =
01772 dynamic_cast<Node *>(getParents()[0]);
01773
01774 caseChilds_p10(pParent, order, roi);
01775
01776 for(i=-getSizeROI(); i<=getSizeROI(); ++i)
01777 {
01778 node = order[(i+getSizeROI())*roi+roi-1];
01779
01780 if(x+getSizeROI() < Int32(getSizeX()) &&
01781 y+i >= 0 &&
01782 y+i < Int32(getSizeY()))
01783 {
01784 node->setTravMask(
01785 TypeTraits<UInt32>::BitsSet);
01786 core =
01787 dynamic_cast<QuadTreeTerrain *>(
01788 node->getCore());
01789
01790 core->setHeightData(
01791 getHeightTiles((y+i)*
01792 getSizeX() +
01793 x+getSizeROI()));
01794
01795 if(getMaterial() == NULL)
01796 {
01797 core->setMaterial(
01798 getHeightTextures((y+i)*
01799 getSizeX() +
01800 x+getSizeROI()));
01801 }
01802 else
01803 {
01804 core->setOriginTexX((x+getSizeROI())*
01805 tstepx);
01806 core->setOriginTexY((y+i)*tstepy);
01807 }
01808
01809 core->setOriginX((x+getSizeROI())*step);
01810 core->setOriginY((y+i)*step);
01811 }
01812 else
01813 {
01814 node->setTravMask(0);
01815 }
01816 }
01817 reorderChilds(pParent, order, roi);
01818 break;
01819 }
01820 case 1:
01821 {
01822 Node *pParent =
01823 dynamic_cast<Node *>(getParents()[0]);
01824
01825 caseChilds_p1p1(pParent, order, roi);
01826
01827 for(i=-getSizeROI(); i<getSizeROI(); ++i)
01828 {
01829 node = order[(i+getSizeROI())*roi+roi-1];
01830
01831 if(x-getSizeROI() >= 0 &&
01832 y+i >= 0 &&
01833 y+i < Int32(getSizeY()))
01834 {
01835 node->setTravMask(
01836 TypeTraits<UInt32>::BitsSet);
01837 core =
01838 dynamic_cast<QuadTreeTerrain *>(
01839 node->getCore());
01840
01841 core->setHeightData(
01842 getHeightTiles((y+i)*getSizeX() +
01843 x-getSizeROI()));
01844
01845 if(getMaterial() == NULL)
01846 {
01847 core->setMaterial(
01848 getHeightTextures((y+i)*
01849 getSizeX() +
01850 x-getSizeROI()));
01851 }
01852 else
01853 {
01854 core->setOriginTexX((x-getSizeROI())*
01855 tstepx);
01856 core->setOriginTexY((y+i)*tstepy);
01857 }
01858
01859 core->setOriginX((x-getSizeROI())*step);
01860 core->setOriginY((y+i)*step);
01861
01862 }
01863 else
01864 {
01865 node->setTravMask(0);
01866 }
01867 }
01868
01869 for(j=-getSizeROI(); j<=getSizeROI(); ++j)
01870 {
01871 node = order[roi2-roi+(j+getSizeROI())];
01872
01873 if(y+getSizeROI() < Int32(getSizeY()) &&
01874 x+j >= 0 &&
01875 x+j < Int32(getSizeX()))
01876 {
01877 node->setTravMask(
01878 TypeTraits<UInt32>::BitsSet);
01879 core =
01880 dynamic_cast<QuadTreeTerrain *>(
01881 node->getCore());
01882
01883 core->setHeightData(
01884 getHeightTiles((y+getSizeROI())*
01885 getSizeX() + x+j));
01886
01887 if(getMaterial() == NULL)
01888 {
01889 core->setMaterial(
01890 getHeightTextures((y+getSizeROI())*
01891 getSizeX() + x+j));
01892 }
01893 else
01894 {
01895 core->setOriginTexX((x+j)*tstepx);
01896 core->setOriginTexY((y+getSizeROI())*
01897 tstepy);
01898 }
01899
01900 core->setOriginX((x+j)*step);
01901 core->setOriginY((y+getSizeROI())*step);
01902 }
01903 else
01904 {
01905 node->setTravMask(0);
01906 }
01907 }
01908 reorderChilds(pParent, order, roi);
01909
01910 break;
01911 }
01912 }
01913 break;
01914 }
01915
01916
01917 setCurrentX(x);
01918 setCurrentY(y);
01919
01920 #ifdef OSG_DEBUG
01921 UInt32 dup;
01922 for (UInt32 i=0; i<roi2; ++i)
01923 {
01924 Node *pParent = dynamic_cast<Node *>(getParents()[0]);
01925 node = pParent->getChild(i);
01926
01927 core = dynamic_cast<QuadTreeTerrain *>(node->getCore());
01928
01929 if(node->getTravMask())
01930 {
01931 std::cout << "tile " << i << "("
01932 << core->getOriginX() << ","
01933 << core->getOriginY() << "):";
01934 dup = 0;
01935
01936 for(UInt32 j=0; j<roi2; ++j)
01937 {
01938 Node *pParent2 =
01939 dynamic_cast<Node *>(getParents()[0]);
01940 Node *node2 = pParent2->getChild(j);
01941 QuadTreeTerrain *core2 =
01942 dynamic_cast<QuadTreeTerrain *>(node2->getCore());
01943
01944 if (node2->getTravMask() &&
01945 core->getOriginX() == core2->getOriginX() &&
01946 core->getOriginY() == core2->getOriginY())
01947 {
01948 std::cout << " " << j;
01949 ++dup;
01950 }
01951 }
01952
01953 std::cout << std::endl;
01954
01955 if(dup > 1)
01956 {
01957 SFATAL << "tile has " << dup-1
01958 << " duplicates!" << std::endl;
01959 }
01960 }
01961 }
01962 #endif
01963 }
01964 }
01965
01966 UInt32 numIndis = 0;
01967 UInt32 numFans = 0;
01968 Node *pParent = dynamic_cast<Node *>(getParents()[0]);
01969
01970 for(UInt32 i=0; i<pParent->getNChildren(); ++i)
01971 {
01972 node = pParent->getChild(i);
01973
01974 if (node != NULL)
01975 {
01976 core = dynamic_cast<QuadTreeTerrain *>(node->getCore());
01977
01978 if(core != NULL && core->getIndices() != NULL)
01979 {
01980 numIndis += core->getIndices()->size();
01981 numFans += core->getTypes()->size();
01982 }
01983 }
01984 }
01985 SNOTICE << numIndis/3 << " triangles in "
01986 << numFans << " fans" << std::endl;
01987
01988 return Action::Continue;
01989 }
01990
01991 void TiledQuadTreeTerrain::dump( UInt32 ,
01992 const BitVector ) const
01993 {
01994 SLOG << "Dump TiledTerrain NI" << std::endl;
01995 }
01996