Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGGeometry.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 <stdlib.h>
00044 #include <stdio.h>
00045 
00046 #include "OSGConfig.h"
00047 #include <OSGGL.h>
00048 
00049 #include <OSGAction.h>
00050 #include <OSGDrawAction.h>
00051 #include <OSGRenderAction.h>
00052 #include <OSGIntersectAction.h>
00053 #include <OSGRenderAction.h>
00054 #include <OSGMaterial.h>
00055 #include <OSGChunkMaterial.h>
00056 #include <OSGSimpleMaterial.h>
00057 #include <OSGSimpleTexturedMaterial.h>
00058 #include "OSGDrawable.h"
00059 #include "OSGGeometry.h"
00060 #include "OSGGeoFunctions.h"
00061 #include "OSGGeoPumpFactory.h"
00062 
00063 #include <OSGIntersectActor.h>
00064 
00065 #include "OSGPrimitiveIterator.h"
00066 #include "OSGTriangleIterator.h"
00067 #include "OSGFaceIterator.h"
00068 #include "OSGLineIterator.h"
00069 #include "OSGEdgeIterator.h"
00070 
00071 #include "OSGGeoPropPtrs.h"
00072 OSG_USING_NAMESPACE
00073 
00074 
00075 /***************************************************************************\
00076  *                            Description                                  *
00077 \***************************************************************************/
00078 
00087 /***************************************************************************\
00088  *                           Class variables                               *
00089 \***************************************************************************/
00090 
00091 const UInt16 Geometry::MapPosition       = 1;
00092 const UInt16 Geometry::MapNormal         = Geometry::MapPosition << 1;
00093 const UInt16 Geometry::MapColor          = Geometry::MapNormal << 1;
00094 const UInt16 Geometry::MapSecondaryColor = Geometry::MapColor << 1;
00095 const UInt16 Geometry::MapTexCoords      = Geometry::MapSecondaryColor << 1;
00096 const UInt16 Geometry::MapTexCoords1     = Geometry::MapTexCoords << 1;
00097 const UInt16 Geometry::MapTexCoords2     = Geometry::MapTexCoords1 << 1;
00098 const UInt16 Geometry::MapTexCoords3     = Geometry::MapTexCoords2 << 1;
00099 const UInt16 Geometry::MapEmpty          = Geometry::MapTexCoords3 << 1;
00100 
00101 
00102 /***************************************************************************\
00103  *                           Class methods                                 *
00104 \***************************************************************************/
00105 
00106 /*-------------------------------------------------------------------------*\
00107  -  public                                                                 -
00108 \*-------------------------------------------------------------------------*/
00109 
00112 const char *Geometry::mapType(UInt8 type)
00113 {
00114     switch(type)
00115     {
00116     case GL_POINTS:         return "Points";
00117     case GL_LINES:          return "Lines";
00118     case GL_LINE_LOOP:      return "LineLoop";
00119     case GL_LINE_STRIP:     return "LineStrip";
00120     case GL_TRIANGLES:      return "Triangles";
00121     case GL_TRIANGLE_STRIP: return "TriangleStrip";
00122     case GL_TRIANGLE_FAN:   return "TriangleFan";
00123     case GL_QUADS:          return "Quads";
00124     case GL_QUAD_STRIP:     return "QuadStrip";
00125     case GL_POLYGON:        return "Polygon";
00126     }
00127 
00128     return "Unknown Primitive";
00129 }
00130 
00131 /*-------------------------------------------------------------------------*\
00132  -  private                                                                -
00133 \*-------------------------------------------------------------------------*/
00134 
00135 void Geometry::initMethod(void)
00136 {
00137     DrawAction::registerEnterDefault(getClassType(),
00138         osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE, MaterialDrawablePtr,
00139               CNodePtr, Action *>(&MaterialDrawable::drawActionHandler));
00140 
00141     IntersectAction::registerEnterDefault(getClassType(),
00142         osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE, GeometryPtr,
00143               CNodePtr, Action *>(&Geometry::intersect));
00144 
00145     IntersectActor::regClassEnter(
00146         osgTypedMethodFunctor2BaseCPtr<
00147             NewActionTypes::ResultE,
00148             GeometryPtr,
00149             NodeCorePtr,
00150             ActorBase::FunctorArgumentType &>(&Geometry::intersect),
00151         getClassType());
00152 
00153     RenderAction::registerEnterDefault(getClassType(),
00154         osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE, MaterialDrawablePtr,
00155               CNodePtr, Action *>(&MaterialDrawable::renderActionHandler));
00156 }
00157 
00158 
00159 /***************************************************************************\
00160  *                           Instance methods                              *
00161 \***************************************************************************/
00162 
00163 /*-------------------------------------------------------------------------*\
00164  -  public                                                                 -
00165 \*-------------------------------------------------------------------------*/
00166 
00167 
00168 /*------------- constructors & destructors --------------------------------*/
00169 
00170 Geometry::Geometry(void) :
00171     Inherited()
00172 {
00173 }
00174 
00175 Geometry::Geometry(const Geometry &source) :
00176     Inherited(source)
00177 {
00178 }
00179 
00183 Geometry::~Geometry(void)
00184 {
00185     GeometryPtr thisP = getPtr();
00186 
00187     if(_sfTypes.getValue() != NullFC)
00188     {
00189         beginEditCP(_sfTypes.getValue(), Attachment::ParentsFieldMask);
00190         {
00191             _sfTypes.getValue()->subParent(thisP);
00192         }
00193         endEditCP(_sfTypes.getValue(), Attachment::ParentsFieldMask);
00194 
00195         subRefCP(_sfTypes.getValue());
00196     }
00197 
00198     if(_sfLengths.getValue() != NullFC)
00199     {
00200         beginEditCP(_sfLengths.getValue(), Attachment::ParentsFieldMask);
00201         {
00202             _sfLengths.getValue()->subParent(thisP);
00203         }
00204         endEditCP(_sfLengths.getValue(), Attachment::ParentsFieldMask);
00205 
00206         subRefCP(_sfLengths.getValue());
00207     }
00208 
00209     if(_sfPositions.getValue() != NullFC)
00210     {
00211         beginEditCP(_sfPositions.getValue(), Attachment::ParentsFieldMask);
00212         {
00213             _sfPositions.getValue()->subParent(thisP);
00214         }
00215         endEditCP(_sfPositions.getValue(), Attachment::ParentsFieldMask);
00216 
00217         subRefCP(_sfPositions.getValue());
00218     }
00219 
00220     if(_sfNormals.getValue() != NullFC)
00221     {
00222         beginEditCP(_sfNormals.getValue(), Attachment::ParentsFieldMask);
00223         {
00224             _sfNormals.getValue()->subParent(thisP);
00225         }
00226         endEditCP(_sfNormals.getValue(), Attachment::ParentsFieldMask);
00227 
00228         subRefCP(_sfNormals.getValue());
00229     }
00230 
00231     if(_sfColors.getValue() != NullFC)
00232     {
00233         beginEditCP(_sfColors.getValue(), Attachment::ParentsFieldMask);
00234         {
00235             _sfColors.getValue()->subParent(thisP);
00236         }
00237         endEditCP(_sfColors.getValue(), Attachment::ParentsFieldMask);
00238 
00239         subRefCP(_sfColors.getValue());
00240     }
00241 
00242     if(_sfSecondaryColors.getValue() != NullFC)
00243     {
00244         beginEditCP(_sfSecondaryColors.getValue(),
00245                         Attachment::ParentsFieldMask);
00246         {
00247             _sfSecondaryColors.getValue()->subParent(thisP);
00248         }
00249         endEditCP(_sfSecondaryColors.getValue(),
00250                         Attachment::ParentsFieldMask);
00251 
00252         subRefCP(_sfSecondaryColors.getValue());
00253     }
00254 
00255     if(_sfTexCoords.getValue() != NullFC)
00256     {
00257         beginEditCP(_sfTexCoords.getValue(), Attachment::ParentsFieldMask);
00258         {
00259             _sfTexCoords.getValue()->subParent(thisP);
00260         }
00261         endEditCP(_sfTexCoords.getValue(), Attachment::ParentsFieldMask);
00262 
00263         subRefCP(_sfTexCoords.getValue());
00264     }
00265 
00266     if(_sfTexCoords1.getValue() != NullFC)
00267     {
00268         beginEditCP(_sfTexCoords1.getValue(), Attachment::ParentsFieldMask);
00269         {
00270             _sfTexCoords1.getValue()->subParent(thisP);
00271         }
00272         endEditCP(_sfTexCoords1.getValue(), Attachment::ParentsFieldMask);
00273 
00274         subRefCP(_sfTexCoords1.getValue());
00275     }
00276 
00277     if(_sfTexCoords2.getValue() != NullFC)
00278     {
00279         beginEditCP(_sfTexCoords2.getValue(), Attachment::ParentsFieldMask);
00280         {
00281             _sfTexCoords2.getValue()->subParent(thisP);
00282         }
00283         endEditCP(_sfTexCoords2.getValue(), Attachment::ParentsFieldMask);
00284 
00285         subRefCP(_sfTexCoords2.getValue());
00286     }
00287 
00288     if(_sfTexCoords3.getValue() != NullFC)
00289     {
00290         beginEditCP(_sfTexCoords3.getValue(), Attachment::ParentsFieldMask);
00291         {
00292             _sfTexCoords3.getValue()->subParent(thisP);
00293         }
00294         endEditCP(_sfTexCoords3.getValue(), Attachment::ParentsFieldMask);
00295 
00296         subRefCP(_sfTexCoords3.getValue());
00297     }
00298 
00299     if(_sfIndices.getValue() != NullFC)
00300     {
00301         beginEditCP(_sfIndices.getValue(), Attachment::ParentsFieldMask);
00302         {
00303             _sfIndices.getValue()->subParent(thisP);
00304         }
00305         endEditCP(_sfIndices.getValue(), Attachment::ParentsFieldMask);
00306 
00307         subRefCP(_sfIndices.getValue());
00308     }
00309 
00310     subRefCP(_sfMaterial.getValue());
00311 
00312     if(getGLId() > 0)
00313         Window::destroyGLObject(getGLId(), 1);
00314 }
00315 
00316 void Geometry::onCreate(const Geometry *)
00317 {
00318     // if we're in startup this is the prototype, which shouldn't have an id
00319     if(GlobalSystemState == Startup)
00320         return;
00321 
00322     // !!! this temporary is needed to work around compiler problems(sgi)
00323     // CHECK CHECK
00324     //  TextureChunkPtr tmpPtr = FieldContainer::getPtr<TextureChunkPtr>(*this);
00325     GeometryPtr tmpPtr(*this);
00326 
00327     beginEditCP(tmpPtr, Geometry::GLIdFieldMask);
00328 
00329     setGLId(
00330           Window::registerGLObject(
00331             osgTypedMethodVoidFunctor2ObjCPtrPtr<GeometryPtr,
00332                                                  Window ,
00333                                                  UInt32>(tmpPtr,
00334                                                          &Geometry::handleGL),
00335             1));
00336 
00337     endEditCP(tmpPtr, Geometry::GLIdFieldMask);
00338 }
00339 
00340 /*------------------------------ access -----------------------------------*/
00341 
00342 void Geometry::adjustVolume(Volume & volume)
00343 {
00344     GeoPositionsPtr pos = getPositions();
00345 
00346     volume.setValid();
00347     volume.setEmpty();
00348 
00349     if(pos == NullFC)
00350         return;                  // Node has no points, no volume
00351 
00352     PrimitiveIterator it;
00353 
00354     for(it = this->beginPrimitives(); it != this->endPrimitives(); ++it)
00355     {
00356         for(UInt32 v=0; v < it.getLength(); ++v)
00357         {
00358             volume.extendBy(it.getPosition(v));
00359         }
00360     }
00361 }
00362 
00363 /*---------------------------- pointer ------------------------------------*/
00364 
00365 GeometryPtr Geometry::getPtr(void) const
00366 {
00367     return GeometryPtr(*this);
00368 }
00369 
00370 
00373 void Geometry::handleGL(Window* win, UInt32 idstatus)
00374 {
00375     Window::GLObjectStatusE mode;
00376     UInt32 id;
00377 
00378     Window::unpackIdStatus(idstatus, id, mode);
00379 
00380     if(mode == Window::initialize || mode == Window::needrefresh ||
00381        mode == Window::reinitialize)
00382     {
00383         glNewList(id, GL_COMPILE);
00384 
00385         GeoPumpFactory::Index ind = GeoPumpFactory::the()->getIndex(this);
00386         GeoPumpFactory::GeoPump p =
00387             GeoPumpFactory::the()->getGeoPump(win, ind);
00388 
00389         // call the pump
00390 
00391         if(p)
00392             p(win, this);
00393         else
00394         {
00395             SWARNING << "Geometry::handleGL: no Pump found for geometry "
00396                      << this
00397                      << std::endl;
00398         }
00399 
00400         glEndList();
00401     }
00402     else if(mode == Window::destroy)
00403     {
00404         glDeleteLists(id, 1);
00405     }
00406     else if(mode == Window::finaldestroy)
00407     {
00408         //SWARNING << "Last geometry user destroyed" << std::endl;
00409     }
00410     else
00411     {
00412         SWARNING << "Geometry(" << this << "::handleGL: Illegal mode: "
00413                  << mode << " for id " << id << std::endl;
00414     }
00415 
00416 }
00417 
00418 /*------------------------------- dump ----------------------------------*/
00419 
00420 void Geometry::dump(      UInt32    uiIndent,
00421                     const BitVector bvFlags) const
00422 {
00423     UInt32 i;
00424 
00425     GeometryPtr thisP = getPtr();
00426 
00427     indentLog(uiIndent, PLOG);
00428 
00429     PLOG << "GeoCore"
00430          << "("
00431          << thisP.getFieldContainerId()
00432          << ") : "
00433          << getType().getName()
00434          << " "
00435          << _attachmentMap.getValue().size()
00436          << " attachments | "
00437          << this
00438          << std::endl;
00439 
00440     indentLog(uiIndent, PLOG);
00441     PLOG << "[" << std::endl;
00442 
00443     indentLog(uiIndent + 4, PLOG);
00444     PLOG << "Parents : " << std::endl;
00445 
00446     for(i = 0; i < _parents.size(); i++)
00447     {
00448         indentLog(uiIndent + 4, PLOG);
00449         PLOG << "           " << i << ") " << &(*(_parents[i])) << std::endl;
00450     }
00451 
00452     indentLog(uiIndent, PLOG);
00453     PLOG << "]" << std::endl;
00454 
00455     indentLog(uiIndent, PLOG);
00456     PLOG << "{" << std::endl;
00457 
00458     uiIndent += 4;
00459 
00460     if(getPositions() != NullFC)
00461     {
00462         getPositions()->dump(uiIndent, bvFlags);
00463     }
00464 
00465     if(getIndices() != NullFC)
00466     {
00467         getIndices()->dump(uiIndent, bvFlags);
00468     }
00469 
00470     if(getMaterial() != NullFC)
00471     {
00472         getMaterial()->dump(uiIndent, bvFlags);
00473     }
00474 
00475     if(getTypes() != NullFC)
00476     {
00477         getTypes()->dump(uiIndent, bvFlags);
00478     }
00479 
00480     if(getLengths() != NullFC)
00481     {
00482         getLengths()->dump(uiIndent, bvFlags);
00483     }
00484 
00485     if(getNormals() != NullFC)
00486     {
00487         getNormals()->dump(uiIndent, bvFlags);
00488     }
00489 
00490     if(getColors() != NullFC)
00491     {
00492         getColors()->dump(uiIndent, bvFlags);
00493     }
00494 
00495     if(getTexCoords() != NullFC)
00496     {
00497         getTexCoords()->dump(uiIndent, bvFlags);
00498     }
00499 
00500     if(getTexCoords1() != NullFC)
00501     {
00502         getTexCoords1()->dump(uiIndent, bvFlags);
00503     }
00504 
00505     if(getTexCoords2() != NullFC)
00506     {
00507         getTexCoords2()->dump(uiIndent, bvFlags);
00508     }
00509 
00510     if(getTexCoords3() != NullFC)
00511     {
00512         getTexCoords3()->dump(uiIndent, bvFlags);
00513     }
00514 
00515     uiIndent -= 4;
00516 
00517     AttachmentContainer::dump(uiIndent, bvFlags);
00518 
00519     indentLog(uiIndent, PLOG);
00520     PLOG << "}" << std::endl;
00521 }
00522 
00523 #ifndef OSG_SUPPORT_NO_GEO_INTERFACE
00524 
00528 GeoPropertyArrayInterface *Geometry::getProperty(Int32 mapID)
00529 {
00530     GeoPropertyArrayInterface *pP = 0;
00531 
00532     switch(mapID)
00533     {
00534         case 0:
00535             pP = 0;
00536             break;
00537         case MapPosition:
00538             pP =(getPositions()       == NullFC) ? 0 : &(*getPositions());
00539             break;
00540         case MapNormal:
00541             pP =(getNormals()         == NullFC) ? 0 : &(*getNormals());
00542             break;
00543         case MapColor:
00544             pP =(getColors()          == NullFC) ? 0 : &(*getColors());
00545             break;
00546         case MapSecondaryColor:
00547             pP =(getSecondaryColors() == NullFC) ? 0 : &(*getSecondaryColors());
00548             break;
00549         case MapTexCoords:
00550             pP =(getTexCoords()       == NullFC) ? 0 : &(*getTexCoords());
00551             break;
00552         case MapTexCoords1:
00553             pP =(getTexCoords1()      == NullFC) ? 0 : &(*getTexCoords1());
00554             break;
00555         case MapTexCoords2:
00556             pP =(getTexCoords2()      == NullFC) ? 0 : &(*getTexCoords2());
00557             break;
00558         case MapTexCoords3:
00559             pP =(getTexCoords3()      == NullFC) ? 0 : &(*getTexCoords3());
00560             break;
00561         default:
00562             FFATAL(("Invalid mapID(%d) in Geometry::getProperty()\n",
00563                     mapID));
00564           break;
00565     }
00566 
00567     return pP;
00568 }
00569 
00570 #endif
00571 
00578 Int16  Geometry::calcMappingIndex(UInt16 attrib) const
00579 {
00580     UInt16 nmappings = getIndexMapping().size();
00581     Int16 i;
00582 
00583     for(i = nmappings - 1; i >= 0; i--)
00584     {
00585         if(getIndexMapping()[i] & attrib )
00586             break;
00587     }
00588 
00589     return i;
00590 }
00591 
00592 
00593 
00598 bool Geometry::isMergeable( const GeometryPtr other )
00599 {
00600     if (MergeIndex(other)!=-1 || getPositions()==NullFC) return true;
00601     else return false;
00602 }
00603 
00606 bool Geometry::merge( const GeometryPtr other )
00607 {
00608     if (other == NullFC)
00609     {
00610         FDEBUG(("Geometry::merge: other = NullFC!!!\n"));
00611         return false;
00612     }
00613     //first check whethet the current geometry is empty
00614     //if empty just add everything from the other geometry
00615     if (getPositions()==NullFC)
00616     {
00617         if (other->getPositions()!=NullFC)
00618             setPositions(other->getPositions()->clone());
00619 
00620         if (other->getTypes()!=NullFC)
00621             setTypes(other->getTypes()->clone());
00622 
00623         if (other->getLengths()!=NullFC)
00624             setLengths(other->getLengths()->clone());
00625 
00626         if (other->getNormals()!=NullFC)
00627             setNormals(other->getNormals()->clone());
00628 
00629         if (other->getColors()!=NullFC)
00630             setColors(other->getColors()->clone());
00631 
00632         if (other->getSecondaryColors()!=NullFC)
00633             setSecondaryColors(other->getSecondaryColors()->clone());
00634 
00635         if (other->getTexCoords()!=NullFC)
00636             setTexCoords(other->getTexCoords()->clone());
00637 
00638         if (other->getTexCoords1()!=NullFC)
00639             setTexCoords1(other->getTexCoords1()->clone());
00640 
00641         if (other->getTexCoords2()!=NullFC)
00642             setTexCoords2(other->getTexCoords2()->clone());
00643 
00644         if (other->getTexCoords3()!=NullFC)
00645             setTexCoords3(other->getTexCoords3()->clone());
00646 
00647         if(other->getIndices()!=NullFC)
00648             setIndices(other->getIndices()->clone());
00649 
00650         if(other->getMFIndexMapping()!=NULL)
00651             getMFIndexMapping()->setValues(*(other->getMFIndexMapping()));
00652 
00653         setMaterial(other->getMaterial());
00654         setDlistCache(other->getDlistCache());
00655 
00656         return true;
00657     }
00658 
00659 
00660     //if not empty continue trying a normal merge
00661     Int16 mergetype = MergeIndex( other );
00662     switch ( mergetype )
00663     {
00664     case 0: merge0( other ); break;
00665     case 1: merge1( other ); break;
00666     case 2: merge2( other ); break;
00667     case 3: merge3( other ); break;
00668     case 4: merge4( other ); break;
00669     case 5: merge5( other ); break;
00670     case 6: merge6( other ); break;
00671     default: return false;
00672     }
00673     return true;
00674 }
00675 
00676 /*-------------------------------------------------------------------------*\
00677  -  protected                                                              -
00678 \*-------------------------------------------------------------------------*/
00679 
00680 Action::ResultE Geometry::drawPrimitives(DrawActionBase * action)
00681 {
00682     if(getDlistCache() == true)
00683     {
00684         action->getWindow()->validateGLObject(getGLId());
00685         glCallList(getGLId());
00686     }
00687     else
00688     {
00689         GeoPumpFactory::Index ind = GeoPumpFactory::the()->getIndex(this);
00690         GeoPumpFactory::GeoPump p =
00691             GeoPumpFactory::the()->getGeoPump(action->getWindow(), ind);
00692 
00693         // call the pump
00694 
00695         if(p)
00696             p(action->getWindow(), this);
00697         else
00698         {
00699             SWARNING << "draw: no Pump found for geometry "
00700                      << this
00701                      << std::endl;
00702         }
00703     }
00704 
00705     StatCollector *coll = action->getStatistics();
00706 
00707     if(coll != NULL)
00708     {
00709         StatIntElem *el = coll->getElem(Drawable::statNTriangles,false);
00710         if(el)
00711         {
00712             GeometryPtr geo(this);
00713             UInt32 ntri,nl,np,is;
00714 
00715             calcPrimitiveCount(geo, ntri, nl, np);
00716             el->add(ntri);
00717             coll->getElem(Drawable::statNLines)->add(nl);
00718             coll->getElem(Drawable::statNLines)->add(np);
00719 
00720             if(getIndices() == NullFC)
00721             {
00722                 if(getPositions() != NullFC)
00723                 {
00724                     is = getPositions()->getSize();
00725                 }
00726                 else
00727                 {
00728                     is = 0;
00729                 }
00730             }
00731             else
00732             {
00733                 is = getIndexMapping().size();
00734                 is = getIndices()->getSize() /(is ? is : 1);
00735             }
00736             coll->getElem(Drawable::statNVertices)->add(is);
00737 
00738             UInt32 primitiveCount = 0;
00739             if (getTypes() != NullFC) {
00740                 primitiveCount = getTypes()->getSize();
00741             }
00742             coll->getElem(Drawable::statNPrimitives)->add(primitiveCount);
00743         }
00744     }
00745 
00746     return Action::Continue;
00747 }
00748 
00749 Action::ResultE Geometry::intersect(Action * action)
00750 {
00751     IntersectAction     * ia = dynamic_cast<IntersectAction*>(action);
00752     const DynamicVolume  &dv = ia->getActNode()->getVolume(true);
00753 
00754     if(dv.isValid() && !dv.intersect(ia->getLine()))
00755     {
00756         return Action::Skip; //bv missed -> can not hit children
00757     }
00758 
00759     TriangleIterator it  = this->beginTriangles();
00760     TriangleIterator end = this->endTriangles  ();
00761     Real32 t;
00762     Vec3f norm;
00763 
00764     for(; it != end; ++it)
00765     {
00766         if(ia->getLine().intersect(it.getPosition(0),
00767                                      it.getPosition(1),
00768                                      it.getPosition(2), t, &norm))
00769         {
00770             ia->setHit(t, ia->getActNode(), it.getIndex(), norm);
00771         }
00772     }
00773 
00774     return Action::Continue;
00775 }
00776 
00777 NewActionTypes::ResultE
00778 Geometry::intersect(ActorBase::FunctorArgumentType &funcArg)
00779 {
00780     IntersectActor   *pIA         = dynamic_cast<IntersectActor *>(funcArg.getActor());
00781     Real32            scaleFactor = pIA->getScaleFactor();
00782 
00783     TriangleIterator  itTris      = this->beginTriangles();
00784     TriangleIterator  endTris     = this->endTriangles  ();
00785 
00786     Real32            hitDist;
00787     Vec3f             hitNormal;
00788 
00789     for(; itTris != endTris; ++itTris)
00790     {
00791         if(pIA->getRay().intersect(itTris.getPosition(0),
00792                                    itTris.getPosition(1),
00793                                    itTris.getPosition(2),
00794                                    hitDist,                &hitNormal) == true)
00795         {
00796             pIA->setHit(hitDist * scaleFactor, funcArg.getNode(),
00797                         itTris.getIndex(),     hitNormal        );
00798         }
00799     }
00800 
00801     pIA->setupChildrenPriorities();
00802 
00803     return NewActionTypes::Continue;
00804 }
00805 
00809 void Geometry::changed(BitVector whichField,
00810                        UInt32    origin   )
00811 {
00812     if(whichField & TypesFieldMask)
00813     {
00814         if(origin & ChangedOrigin::Abstract)
00815         {
00816             if(origin & ChangedOrigin::AbstrCheckValid)
00817             {
00818                 GeometryPtr thisP = getPtr();
00819 
00820                 if(_sfTypes.getValue()                    != NullFC &&
00821                    _sfTypes.getValue()->findParent(thisP) ==     -1 )
00822                 {
00823                     GeoPTypesPtr pType = _sfTypes.getValue();
00824 
00825                     _sfTypes.setValue(NullFC);
00826 
00827                     setTypes(pType);
00828                 }
00829             }
00830             else if(origin & ChangedOrigin::AbstrIncRefCount)
00831             {
00832                 addRefCP(_sfTypes.getValue());
00833             }
00834             else
00835             {
00836                 GeoPTypesPtr pType = _sfTypes.getValue();
00837 
00838                 _sfTypes.setValue(NullFC);
00839 
00840                 setTypes(pType);
00841             }
00842         }
00843     }
00844 
00845     if(whichField & LengthsFieldMask)
00846     {
00847         if(origin & ChangedOrigin::Abstract)
00848         {
00849             if(origin & ChangedOrigin::AbstrCheckValid)
00850             {
00851                 GeometryPtr thisP = getPtr();
00852 
00853                 if(_sfLengths.getValue()                    != NullFC &&
00854                    _sfLengths.getValue()->findParent(thisP) ==     -1 )
00855                 {
00856                     GeoPLengthsPtr pLength = _sfLengths.getValue();
00857 
00858                     _sfLengths.setValue(NullFC);
00859 
00860                     setLengths(pLength);
00861                 }
00862             }
00863             else if(origin & ChangedOrigin::AbstrIncRefCount)
00864             {
00865                 addRefCP(_sfLengths.getValue());
00866             }
00867             else
00868             {
00869                 GeoPLengthsPtr pLength = _sfLengths.getValue();
00870 
00871                 _sfLengths.setValue(NullFC);
00872 
00873                 setLengths(pLength);
00874             }
00875         }
00876     }
00877 
00878     if(whichField & PositionsFieldMask)
00879     {
00880         for(UInt32 i = 0; i < _parents.size(); i++)
00881         {
00882             _parents[i]->invalidateVolume();
00883         }
00884 
00885         if(origin & ChangedOrigin::Abstract)
00886         {
00887             if(origin & ChangedOrigin::AbstrCheckValid)
00888             {
00889                 GeometryPtr thisP = getPtr();
00890 
00891                 if(_sfPositions.getValue()                    != NullFC &&
00892                    _sfPositions.getValue()->findParent(thisP) ==     -1 )
00893                 {
00894                     GeoPositionsPtr pPos = _sfPositions.getValue();
00895 
00896                     _sfPositions.setValue(NullFC);
00897 
00898                     setPositions(pPos);
00899                 }
00900             }
00901             else if(origin & ChangedOrigin::AbstrIncRefCount)
00902             {
00903                 addRefCP(_sfPositions.getValue());
00904             }
00905             else
00906             {
00907                 GeoPositionsPtr pPos = _sfPositions.getValue();
00908 
00909                 _sfPositions.setValue(NullFC);
00910 
00911                 setPositions(pPos);
00912             }
00913         }
00914         else
00915         {
00916         }
00917     }
00918 
00919     if(whichField & NormalsFieldMask)
00920     {
00921         if(origin & ChangedOrigin::Abstract)
00922         {
00923             if(origin & ChangedOrigin::AbstrCheckValid)
00924             {
00925                 GeometryPtr thisP = getPtr();
00926 
00927                 if(_sfNormals.getValue()                    != NullFC &&
00928                    _sfNormals.getValue()->findParent(thisP) ==     -1 )
00929                 {
00930                     GeoNormalsPtr pNorm = _sfNormals.getValue();
00931 
00932                     _sfNormals.setValue(NullFC);
00933 
00934                     setNormals(pNorm);
00935                 }
00936             }
00937             else if(origin & ChangedOrigin::AbstrIncRefCount)
00938             {
00939                 addRefCP(_sfNormals.getValue());
00940             }
00941             else
00942             {
00943                 GeoNormalsPtr pNorm = _sfNormals.getValue();
00944 
00945                 _sfNormals.setValue(NullFC);
00946 
00947                 setNormals(pNorm);
00948             }
00949         }
00950     }
00951 
00952     if(whichField & ColorsFieldMask)
00953     {
00954         if(origin & ChangedOrigin::Abstract)
00955         {
00956             if(origin & ChangedOrigin::AbstrCheckValid)
00957             {
00958                 GeometryPtr thisP = getPtr();
00959 
00960                 if(_sfColors.getValue()                    != NullFC &&
00961                    _sfColors.getValue()->findParent(thisP) ==     -1 )
00962                 {
00963                     GeoColorsPtr pColor = _sfColors.getValue();
00964 
00965                     _sfColors.setValue(NullFC);
00966 
00967                     setColors(pColor);
00968                 }
00969             }
00970             else if(origin & ChangedOrigin::AbstrIncRefCount)
00971             {
00972                 addRefCP(_sfColors.getValue());
00973             }
00974             else
00975             {
00976                 GeoColorsPtr pColor = _sfColors.getValue();
00977 
00978                 _sfColors.setValue(NullFC);
00979 
00980                 setColors(pColor);
00981             }
00982         }
00983     }
00984 
00985     if(whichField & SecondaryColorsFieldMask)
00986     {
00987         if(origin & ChangedOrigin::Abstract)
00988         {
00989             if(origin & ChangedOrigin::AbstrCheckValid)
00990             {
00991                 GeometryPtr thisP = getPtr();
00992 
00993                 if(_sfSecondaryColors.getValue()                   != NullFC &&
00994                    _sfSecondaryColors.getValue()->findParent(thisP)==     -1 )
00995                 {
00996                     GeoColorsPtr pColor = _sfSecondaryColors.getValue();
00997 
00998                     _sfSecondaryColors.setValue(NullFC);
00999 
01000                     setSecondaryColors(pColor);
01001                 }
01002             }
01003             else if(origin & ChangedOrigin::AbstrIncRefCount)
01004             {
01005                 addRefCP(_sfSecondaryColors.getValue());
01006             }
01007             else
01008             {
01009                 GeoColorsPtr pColor = _sfSecondaryColors.getValue();
01010 
01011                 _sfSecondaryColors.setValue(NullFC);
01012 
01013                 setSecondaryColors(pColor);
01014             }
01015         }
01016     }
01017 
01018     if(whichField & TexCoordsFieldMask)
01019     {
01020         if(origin & ChangedOrigin::Abstract)
01021         {
01022             if(origin & ChangedOrigin::AbstrCheckValid)
01023             {
01024                 GeometryPtr thisP = getPtr();
01025 
01026                 if(_sfTexCoords.getValue()                    != NullFC &&
01027                    _sfTexCoords.getValue()->findParent(thisP) ==     -1 )
01028                 {
01029                     GeoTexCoordsPtr pTexCoord = _sfTexCoords.getValue();
01030 
01031                     _sfTexCoords.setValue(NullFC);
01032 
01033                     setTexCoords(pTexCoord);
01034                 }
01035             }
01036             else if(origin & ChangedOrigin::AbstrIncRefCount)
01037             {
01038                 addRefCP(_sfTexCoords.getValue());
01039             }
01040             else
01041             {
01042                 GeoTexCoordsPtr pTexCoord = _sfTexCoords.getValue();
01043 
01044                 _sfTexCoords.setValue(NullFC);
01045 
01046                 setTexCoords(pTexCoord);
01047             }
01048         }
01049     }
01050 
01051     if(whichField & TexCoords1FieldMask)
01052     {
01053         if(origin & ChangedOrigin::Abstract)
01054         {
01055             if(origin & ChangedOrigin::AbstrCheckValid)
01056             {
01057