OSGTiledQuadTreeTerrain.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *               Copyright (C) 2000-2002 by the OpenSG Forum                 *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 //---------------------------------------------------------------------------
00040 //  Includes
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 // Documentation for this class is emited in the
00057 // OSGTiledQuadTreeTerrainBase.cpp file.
00058 // To modify it, please change the .fcd file (OSGTiledQuadTreeTerrain.fcd) and
00059 // regenerate the base file.
00060
00061 /***************************************************************************\
00062  *                           Class variables                               *
00063 \***************************************************************************/
00064
00065 /***************************************************************************\
00066  *                           Class methods                                 *
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  *                           Instance methods                              *
00083 \***************************************************************************/
00084
00085 /*-------------------------------------------------------------------------*\
00086  -  private                                                                 -
00087 \*-------------------------------------------------------------------------*/
00088
00089 // file local typedef
00090 typedef std::vector<NodeUnrecPtr> NodeStore;
00091
00092
00093 /*----------------------- constructors & destructors ----------------------*/
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 /*----------------------------- class specific ----------------------------*/
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     // GeoMorphing is copied into each terrain node here
00142     // EyePointValid is set true here
00143     // EyePoint is calculated in ::renderEnter and copied into each terrain 
00144     // node PerPixelLighting is copied into each terrain node here
00145     // UpdateTerrain is copied into each terrain node in ::renderEnter
00146     // Detail is copied into each terrain node here
00147     // BorderDetail is set to 1 here
00148
00149     // changed HeightData
00150     // * update HeightError and HeightQuad
00151     if((whichField & HeightTilesFieldMask) && getMFHeightTiles()->size() > 0)
00152     {
00153         if(getParents().size() > 0 && getParents()[0] != NULL)
00154         { // parent must be set!
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             // mention: order of loops!
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                     // activate the roi*roi tiles for current point
00189                     // (getCurrentX()=getSizeROI(),getCurrentY()=getSizeROI())
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         { // parent must be set!
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                     { // use material of MFHeightTextures
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                     { // use material of this MaterialGroup
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         { // parent must be set!
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         { // parent must be set!
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    //Int32 num2 = num*num;
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    { // dynamic tesselation
00499        const FrustumVolume& frustum = da->getFrustum();
00500
00501        Matrix camera  = da->getCameraToWorld();
00502        Matrix toworld = da->top_matrix();
00503        //action->getActNode()->getToWorld(toworld);
00504        toworld.invert();
00505        camera.multLeft(toworld);
00506
00507       // choose tile
00508       Real32 step   = (getHeightTiles(0)->getWidth()-1)*getVertexSpacing();
00509       Real32 tstepx = 1.0f/getSizeX();
00510       Real32 tstepy = 1.0f/getSizeY();
00511       // tiling cs is [0, getSizeX()*getWidth()]*[0, getSizeY()*getWidth()]
00512
00513       Pnt3f eyePoint(camera[3][0], camera[3][1], camera[3][2]);
00514       // set eye point for all terrain child nodes
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       // find tile (x, y) for current eye point
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       // change tiling to tile (x, y)
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 //   RenderAction* da = dynamic_cast<RenderAction*>(action);
01255
01256    if(getUpdate() && getSizeX() > 0 && getSizeY() > 0)
01257    { // dynamic tesselation
01258 //       const FrustumVolume& frustum = da->getFrustum();
01259
01260 //       Matrix camera  = da->getCameraToWorld();
01261 //       Matrix toworld = da->top_matrix();
01262        //action->getActNode()->getToWorld(toworld);
01263        toworld.invert();
01264        camera.multLeft(toworld);
01265
01266       // choose tile
01267       Real32 step   = (getHeightTiles(0)->getWidth()-1)*getVertexSpacing();
01268       Real32 tstepx = 1.0f/getSizeX();
01269       Real32 tstepy = 1.0f/getSizeY();
01270       // tiling cs is [0, getSizeX()*getWidth()]*[0, getSizeY()*getWidth()]
01271
01272       Pnt3f eyePoint(camera[3][0], camera[3][1], camera[3][2]);
01273       // set eye point for all terrain child nodes
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       // find tile (x, y) for current eye point
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       // change tiling to tile (x, y)
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