diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 98e23868a..aec919cf5 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -199,12 +199,6 @@ class SG_EXPORT NodeVisitor : public virtual Referenced * to the current Node being visited.*/ const NodePath& getNodePath() const { return _nodePath; } - /** Get the Local To World Matrix from the NodePath for specified Transform::Mode, and u.*/ - virtual bool getLocalToWorldMatrix(Matrix& matrix, Node* node); - - /** Get the World To Local Matrix from the NodePath for specified Transform::Mode.*/ - virtual bool getWorldToLocalMatrix(Matrix& matrix, Node* node); - /** Get the eye point in local coordinates. * Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.*/ virtual osg::Vec3 getEyePoint() const { return Vec3(0.0f,0.0f,0.0f); } diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index b79f065b2..fd0b2db05 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -84,6 +84,22 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl * note, should only be called from the draw thread.*/ void compileRenderingObjects(osg::State& state,double& availableTime); + /** Helper class used internally to force the release of texture objects + * and displace lists.*/ + class OSGDB_EXPORT ReleaseTexturesAndDrawablesVisitor : public osg::NodeVisitor + { + public: + ReleaseTexturesAndDrawablesVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) + { + } + + virtual void apply(osg::Node& node); + virtual void apply(osg::Geode& geode); + inline void apply(osg::StateSet* stateset); + inline void apply(osg::Drawable* drawable); + + }; public: diff --git a/include/osgParticle/ParticleProcessor b/include/osgParticle/ParticleProcessor index cf717d82e..0fb06108d 100644 --- a/include/osgParticle/ParticleProcessor +++ b/include/osgParticle/ParticleProcessor @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include @@ -161,7 +161,8 @@ namespace osgParticle { if (need_ltw_matrix_) { ltw_matrix_ = osg::Matrix::identity(); - current_nodevisitor_->getLocalToWorldMatrix(ltw_matrix_, this); + //current_nodevisitor_->getLocalToWorldMatrix(ltw_matrix_, this); + ltw_matrix_ = osg::computeLocalToWorld(current_nodevisitor_->getNodePath()); need_ltw_matrix_ = false; } return ltw_matrix_; @@ -171,7 +172,8 @@ namespace osgParticle { if (need_wtl_matrix_) { wtl_matrix_ = osg::Matrix::identity(); - current_nodevisitor_->getWorldToLocalMatrix(wtl_matrix_, this); + //current_nodevisitor_->getWorldToLocalMatrix(wtl_matrix_, this); + wtl_matrix_ = osg::computeWorldToLocal(current_nodevisitor_->getNodePath()); need_wtl_matrix_ = false; } return wtl_matrix_; diff --git a/src/osg/NodeVisitor.cpp b/src/osg/NodeVisitor.cpp index 1472790a9..0140eea80 100644 --- a/src/osg/NodeVisitor.cpp +++ b/src/osg/NodeVisitor.cpp @@ -44,65 +44,3 @@ NodeVisitor::~NodeVisitor() // if (_traversalVisitor) detach from _traversalVisitor; } -class TransformVisitor : public NodeVisitor -{ - public: - - enum CoordMode - { - WORLD_TO_LOCAL, - LOCAL_TO_WORLD - }; - - - CoordMode _coordMode; - Matrix& _matrix; - NodeVisitor* _nodeVisitor; - - TransformVisitor(Matrix& matrix,CoordMode coordMode,NodeVisitor* nv): - NodeVisitor(), - _coordMode(coordMode), - _matrix(matrix), - _nodeVisitor(nv) - {} - - virtual void apply(Transform& transform) - { - if (_coordMode==LOCAL_TO_WORLD) - { - transform.getLocalToWorldMatrix(_matrix,_nodeVisitor); - } - else // worldToLocal - { - transform.getWorldToLocalMatrix(_matrix,_nodeVisitor); - } - } - -}; - - -bool NodeVisitor::getLocalToWorldMatrix(Matrix& matrix, Node* node) -{ - TransformVisitor tv(matrix,TransformVisitor::LOCAL_TO_WORLD,this); - for(NodePath::iterator itr=_nodePath.begin(); - itr!=_nodePath.end(); - ++itr) - { - if (*itr==node) return true; // don't account for matrix attached to specified node - (*itr)->accept(tv); - } - return true; -} - -bool NodeVisitor::getWorldToLocalMatrix(Matrix& matrix, Node* node) -{ - TransformVisitor tv(matrix,TransformVisitor::WORLD_TO_LOCAL,this); - for(NodePath::iterator itr=_nodePath.begin(); - itr!=_nodePath.end(); - ++itr) - { - if (*itr==node) return true; // don't account for matrix attached to specified node - (*itr)->accept(tv); - } - return true; -} diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 533127f3d..d90fe62b8 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -303,67 +303,57 @@ void DatabasePager::addLoadedDataToSceneGraph(double timeStamp) } -class ReleaseTexturesAndDrawablesVisitor : public osg::NodeVisitor +void DatabasePager::ReleaseTexturesAndDrawablesVisitor::apply(osg::Node& node) { -public: - ReleaseTexturesAndDrawablesVisitor(): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) - { - } - - virtual void apply(osg::Node& node) - { - apply(node.getStateSet()); + apply(node.getStateSet()); - traverse(node); - } + traverse(node); +} - virtual void apply(osg::Geode& geode) - { - apply(geode.getStateSet()); - - for(unsigned int i=0;igetTextureAttributeList(); + for(osg::StateSet::TextureAttributeList::iterator itr=tal.begin(); + itr!=tal.end() && !foundTextureState; + ++itr) { - // search for the existance of any texture object attributes - bool foundTextureState = false; - osg::StateSet::TextureAttributeList& tal = stateset->getTextureAttributeList(); - for(osg::StateSet::TextureAttributeList::iterator itr=tal.begin(); - itr!=tal.end() && !foundTextureState; - ++itr) + osg::StateSet::AttributeList& al = *itr; + osg::StateSet::AttributeList::iterator alitr = al.find(osg::StateAttribute::TEXTURE); + if (alitr!=al.end()) { - osg::StateSet::AttributeList& al = *itr; - osg::StateSet::AttributeList::iterator alitr = al.find(osg::StateAttribute::TEXTURE); - if (alitr!=al.end()) - { - // found texture, so place it in the texture list. - osg::Texture* texture = static_cast(alitr->second.first.get()); - texture->dirtyTextureObject(); - } + // found texture, so place it in the texture list. + osg::Texture* texture = static_cast(alitr->second.first.get()); + texture->dirtyTextureObject(); } } } - - inline void apply(osg::Drawable* drawable) - { - apply(drawable->getStateSet()); +} - if (drawable->getUseDisplayList() || drawable->getUseVertexBufferObjects()) - { - drawable->dirtyDisplayList(); - } +void DatabasePager::ReleaseTexturesAndDrawablesVisitor::apply(osg::Drawable* drawable) +{ + apply(drawable->getStateSet()); + + if (drawable->getUseDisplayList() || drawable->getUseVertexBufferObjects()) + { + drawable->dirtyDisplayList(); } - -}; +} void DatabasePager::removeExpiredSubgraphs(double currentFrameTime) { diff --git a/src/osgPlugins/txp/TrPageParser.cpp b/src/osgPlugins/txp/TrPageParser.cpp index 324a819f0..03208b64c 100644 --- a/src/osgPlugins/txp/TrPageParser.cpp +++ b/src/osgPlugins/txp/TrPageParser.cpp @@ -53,78 +53,78 @@ using std::string; //---------------------------------------------------------------------------- // Check if the node is billboard namespace { - bool is_billboard (Node* node) - { - if (node && (node!=(Node*)1) && (strcmp(node->className(),"GeodeGroup") == 0)) - { - GeodeGroup* group = static_cast(node); - return (group->getNumChildren() && (strcmp(group->getChild(0)->className(),"Billboard") == 0)); - } - return false; - }; + bool is_billboard (Node* node) + { + if (node && (node!=(Node*)1) && (strcmp(node->className(),"GeodeGroup") == 0)) + { + GeodeGroup* group = static_cast(node); + return (group->getNumChildren() && (strcmp(group->getChild(0)->className(),"Billboard") == 0)); + } + return false; + }; - void check_format(trpgTexture::ImageType type, int depth, GLenum& internalFormat, GLenum& pixelFormat, GLenum&) - { - switch(type) - { - case trpgTexture::trpg_RGB8: - internalFormat = GL_RGB; - pixelFormat = GL_RGB; - break; - case trpgTexture::trpg_RGBA8: - internalFormat = GL_RGBA; - pixelFormat = GL_RGBA; - break; - case trpgTexture::trpg_INT8: - internalFormat = GL_LUMINANCE; - pixelFormat = GL_LUMINANCE; - break; - case trpgTexture::trpg_INTA8: - internalFormat = GL_LUMINANCE_ALPHA; - pixelFormat = GL_LUMINANCE_ALPHA; - break; - case trpgTexture::trpg_FXT1: - case trpgTexture::trpg_Filler: - case trpgTexture::trpg_RGBX: // MCM - case trpgTexture::trpg_Unknown: - break; - case trpgTexture::trpg_DDS: - case trpgTexture::trpg_DXT1: - if(depth == 3) - { - internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - pixelFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - } - else - { - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - } - break; - case trpgTexture::trpg_DXT3: - if(depth == 3) - { - // not supported. - } - else - { - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - } - break; - case trpgTexture::trpg_DXT5: - if(depth == 3) - { - // not supported. - } - else - { - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - } - break; - } - } + void check_format(trpgTexture::ImageType type, int depth, GLenum& internalFormat, GLenum& pixelFormat, GLenum&) + { + switch(type) + { + case trpgTexture::trpg_RGB8: + internalFormat = GL_RGB; + pixelFormat = GL_RGB; + break; + case trpgTexture::trpg_RGBA8: + internalFormat = GL_RGBA; + pixelFormat = GL_RGBA; + break; + case trpgTexture::trpg_INT8: + internalFormat = GL_LUMINANCE; + pixelFormat = GL_LUMINANCE; + break; + case trpgTexture::trpg_INTA8: + internalFormat = GL_LUMINANCE_ALPHA; + pixelFormat = GL_LUMINANCE_ALPHA; + break; + case trpgTexture::trpg_FXT1: + case trpgTexture::trpg_Filler: + case trpgTexture::trpg_RGBX: // MCM + case trpgTexture::trpg_Unknown: + break; + case trpgTexture::trpg_DDS: + case trpgTexture::trpg_DXT1: + if(depth == 3) + { + internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + pixelFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + } + else + { + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + } + break; + case trpgTexture::trpg_DXT3: + if(depth == 3) + { + // not supported. + } + else + { + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + } + break; + case trpgTexture::trpg_DXT5: + if(depth == 3) + { + // not supported. + } + else + { + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } + break; + } + } } //---------------------------------------------------------------------------- @@ -144,7 +144,7 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, const trpgTextur GLenum pixelFormat = (GLenum)-1; GLenum dataType = GL_UNSIGNED_BYTE; - check_format(type,depth,internalFormat , pixelFormat , dataType); + check_format(type,depth,internalFormat , pixelFormat , dataType); if(pixelFormat!=(GLenum)-1) { @@ -213,7 +213,7 @@ Texture2D* txp::GetTemplateTexture(trpgrImageHelper& image_helper, trpgLocalMate GLenum pixelFormat = (GLenum)-1; GLenum dataType = GL_UNSIGNED_BYTE; - check_format(type,depth,internalFormat , pixelFormat , dataType); + check_format(type,depth,internalFormat , pixelFormat , dataType); if(pixelFormat!=(GLenum)-1) { @@ -312,11 +312,11 @@ class TransformFunctor : public osg::Drawable::AttributeFunctor } } - inline void SetMatrix(const osg::Matrix& m) - { - _m = m; + inline void SetMatrix(const osg::Matrix& m) + { + _m = m; _im.invert(_m); - } + } }; @@ -343,16 +343,13 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) int numPrims; int numVert; int numNorm; - int matId; geom.GetPrimType(primType); geom.GetNumPrims(numPrims); geom.GetNumVertex(numVert); - bool local; - geom.GetMaterial(0,matId, local); geom.GetNumNormal(numNorm); // Get vertices - Vec3Array* vertices = new Vec3Array(numVert); + Vec3Array* vertices = new Vec3Array(numVert); geom.GetVertices((float *)&(vertices->front())); // Turn the trpgGeometry into something Performer can understand @@ -376,7 +373,7 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) } } - // The normals + // The normals Vec3Array* normals = 0L; if (numNorm == numVert) { @@ -393,12 +390,12 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::TRIANGLES,0,numPrims*3)); } break; - case trpgGeometry::Quads: - { - geometry = new Geometry; + case trpgGeometry::Quads: + { + geometry = new Geometry; geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS,0,numPrims*4)); - } - break; + } + break; case trpgGeometry::TriStrips: { // Need primitive lengths too @@ -467,7 +464,7 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // Add it to the current parent group GeodeGroup *top = parse->GetCurrTop(); - Geode *geode = top->GetGeode(); + Geode *geode = top->GetGeode(); if (geometry) { // added this set use display list off since terrapage will @@ -483,11 +480,34 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) } // Note: Should check number of materials first // Note: Should be combining multiple geosets + bool local; + int matId; + int matNo; + geom.GetNumMaterial(matNo); ref_ptr sset = 0L; - if( local ) - sset = (*parse->GetLocalMaterials())[matId]; - else - sset = (*parse->GetMaterials())[matId]; + for(int n_mat = 0; n_mat < matNo ; ++n_mat) + { + ref_ptr tmp_ss = 0L; + geom.GetMaterial(n_mat,matId,local); + if( local ) + tmp_ss = (*parse->GetLocalMaterials())[matId]; + else + tmp_ss = (*parse->GetMaterials())[matId]; + if(sset.valid()) + { + if(tmp_ss.valid()){ + osg::StateAttribute* texenv0 = tmp_ss->getTextureAttribute(0,StateAttribute::TEXENV); + if(texenv0) + sset->setTextureAttribute(n_mat,texenv0); + osg::StateAttribute* tex0 = tmp_ss->getTextureAttribute(0,StateAttribute::TEXTURE); + if(tex0) + sset->setTextureAttributeAndModes(n_mat,tex0,osg::StateAttribute::ON); + } +// sset->merge(*tmp_ss.get()); + } + else + sset = tmp_ss; + } if (tex_coords) { @@ -495,77 +515,77 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) geometry->setTexCoordArray( texno, tex_coords[texno]); } - if ( is_billboard(top) ) - { - geometry->setStateSet(sset.get()); + if ( is_billboard(top) ) + { + geometry->setStateSet(sset.get()); - Billboard *billboard = static_cast(top->getChild(0)); + Billboard *billboard = static_cast(top->getChild(0)); - switch (parse->getBillboardType()) { - case trpgBillboard::Individual: - { - // compute center of billboard geometry - const BoundingBox& bbox = geometry->getBound(); - Vec3 center ((bbox._min + bbox._max) * 0.5f); + switch (parse->getBillboardType()) { + case trpgBillboard::Individual: + { + // compute center of billboard geometry + const BoundingBox& bbox = geometry->getBound(); + Vec3 center ((bbox._min + bbox._max) * 0.5f); - // make billboard geometry coordinates relative to computed center - Matrix matrix; - matrix.makeTranslate(-center[0], -center[1], -center[2]); + // make billboard geometry coordinates relative to computed center + Matrix matrix; + matrix.makeTranslate(-center[0], -center[1], -center[2]); - TransformFunctor tf(matrix); - geometry->accept(tf); - geometry->dirtyBound(); + TransformFunctor tf(matrix); + geometry->accept(tf); + geometry->dirtyBound(); - billboard->addDrawable(geometry); - billboard->setPos(0, center); - } - break; - case trpgBillboard::Group: - { - Vec3 center(parse->getBillboardCenter()); + billboard->addDrawable(geometry); + billboard->setPos(0, center); + } + break; + case trpgBillboard::Group: + { + Vec3 center(parse->getBillboardCenter()); - // make billboard geometry coordinates relative to specified center - Matrix matrix; - matrix.makeTranslate(-center[0], -center[1], -center[2]); + // make billboard geometry coordinates relative to specified center + Matrix matrix; + matrix.makeTranslate(-center[0], -center[1], -center[2]); - TransformFunctor tf(matrix); - geometry->accept(tf); - geometry->dirtyBound(); + TransformFunctor tf(matrix); + geometry->accept(tf); + geometry->dirtyBound(); - billboard->addDrawable(geometry); - billboard->setPos(0, center); - } - break; - default: - billboard->addDrawable(geometry); - notify(WARN) << "TerraPage loader: fell through case: " << __FILE__ << " " << __LINE__ << ".\n"; - break; - } - } - else - { - // if this is part of the layer we turn the PolygonOffset on - - if ( (parse->GetCurrLayer() == top) && geode->getNumDrawables() ) - { - StateSet* poStateSet = new StateSet; - PolygonOffset* polyoffset = new PolygonOffset; + billboard->addDrawable(geometry); + billboard->setPos(0, center); + } + break; + default: + billboard->addDrawable(geometry); + notify(WARN) << "TerraPage loader: fell through case: " << __FILE__ << " " << __LINE__ << ".\n"; + break; + } + } + else + { + // if this is part of the layer we turn the PolygonOffset on + + if ( (parse->GetCurrLayer() == top) && geode->getNumDrawables() ) + { + StateSet* poStateSet = new StateSet; + PolygonOffset* polyoffset = new PolygonOffset; - poStateSet->merge(*sset.get()); - polyoffset->setFactor(-1.0f*geode->getNumDrawables()); - polyoffset->setUnits(-20.0f*geode->getNumDrawables()); - poStateSet->setAttributeAndModes(polyoffset,osg::StateAttribute::ON); + poStateSet->merge(*sset.get()); + polyoffset->setFactor(-1.0f*geode->getNumDrawables()); + polyoffset->setUnits(-20.0f*geode->getNumDrawables()); + poStateSet->setAttributeAndModes(polyoffset,osg::StateAttribute::ON); - geometry->setStateSet(poStateSet); - - } - else - { - geometry->setStateSet(sset.get()); - } + geometry->setStateSet(poStateSet); + + } + else + { + geometry->setStateSet(sset.get()); + } - geode->addDrawable(geometry); - } + geode->addDrawable(geometry); + } } return (void *) 1; @@ -588,10 +608,10 @@ void* groupRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) if (!group.Read(buf)) return NULL; // Create a new Performer group - GeodeGroup* osg_Group = new GeodeGroup(); + GeodeGroup* osg_Group = new GeodeGroup(); // Dump this group into the hierarchy - parse->AddIntoSceneGraph(osg_Group); - // Register the group for attachements + parse->AddIntoSceneGraph(osg_Group); + // Register the group for attachements int32 id; group.GetID(id); parse->AddToGroupList(id,osg_Group); @@ -615,10 +635,10 @@ void* layerRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) if (!group.Read(buf)) return NULL; // Create a new Performer group - Layer* osg_Group = new Layer(); + Layer* osg_Group = new Layer(); // Dump this group into the hierarchy parse->AddIntoSceneGraph(osg_Group); - // Register for attachements + // Register for attachements int32 id; group.GetID(id); parse->AddToGroupList(id,osg_Group); @@ -642,10 +662,10 @@ void* attachRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) if (!group.Read(buf)) return NULL; // Create a new Performer group - GeodeGroup* osg_Group = new GeodeGroup(); + GeodeGroup* osg_Group = new GeodeGroup(); // Dump this group into the hierarchy - parse->AddIntoSceneGraph(osg_Group); - // Register for attachements + parse->AddIntoSceneGraph(osg_Group); + // Register for attachements int32 id; group.GetID(id); parse->AddToGroupList(id,osg_Group); @@ -674,56 +694,56 @@ void* billboardRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) if (!bill.Read(buf)) return NULL; - // Create a group with a geometry beneath for the billboard + // Create a group with a geometry beneath for the billboard GeodeGroup* osg_Group = new GeodeGroup(); - if (parse->inBillboard()) { - // we don't allow anything under a billboard except geometry - notify(WARN) << "TerraPage loader: can only have geometry nodes beneath a billboard.\n"; - } - else - { - int type, mode; - trpg3dPoint center, axis; + if (parse->inBillboard()) { + // we don't allow anything under a billboard except geometry + notify(WARN) << "TerraPage loader: can only have geometry nodes beneath a billboard.\n"; + } + else + { + int type, mode; + trpg3dPoint center, axis; - if (bill.GetType(type) && bill.GetMode(mode) && bill.GetCenter(center) && bill.GetAxis(axis)) { - Billboard* billboard = new Billboard(); + if (bill.GetType(type) && bill.GetMode(mode) && bill.GetCenter(center) && bill.GetAxis(axis)) { + Billboard* billboard = new Billboard(); - osg_Group->SetGeode(billboard); + osg_Group->SetGeode(billboard); - // save this state for processing of the geometry node(s) - parse->setBillboardType(type); - parse->setBillboardCenter(center); + // save this state for processing of the geometry node(s) + parse->setBillboardType(type); + parse->setBillboardCenter(center); - // set the axis - // NOTE: Needs update, when the billboard implementation for - // arbitrary axis is ready - // billboard->setAxis(Vec3(axis.x, axis.y, axis.z)); - billboard->setAxis(Vec3(0.0f,0.0,1.0f) ); - billboard->setNormal(Vec3(0.0f,-1.0,0.0f)); - - // the mode - switch (mode) { - case trpgBillboard::Axial: - billboard->setMode(Billboard::AXIAL_ROT); - break; - case trpgBillboard::World: - billboard->setMode(Billboard::POINT_ROT_WORLD); - break; - case trpgBillboard::Eye: - billboard->setMode(Billboard::POINT_ROT_EYE); - break; - default: - notify(WARN) << "TerraPage loader: Unknown billboard type.\n"; - notify(WARN) << "TerraPage loader: fell through case: " << __FILE__ << " " << __LINE__ << ".\n"; - break; - } - } - } + // set the axis + // NOTE: Needs update, when the billboard implementation for + // arbitrary axis is ready + // billboard->setAxis(Vec3(axis.x, axis.y, axis.z)); + billboard->setAxis(Vec3(0.0f,0.0,1.0f) ); + billboard->setNormal(Vec3(0.0f,-1.0,0.0f)); + + // the mode + switch (mode) { + case trpgBillboard::Axial: + billboard->setMode(Billboard::AXIAL_ROT); + break; + case trpgBillboard::World: + billboard->setMode(Billboard::POINT_ROT_WORLD); + break; + case trpgBillboard::Eye: + billboard->setMode(Billboard::POINT_ROT_EYE); + break; + default: + notify(WARN) << "TerraPage loader: Unknown billboard type.\n"; + notify(WARN) << "TerraPage loader: fell through case: " << __FILE__ << " " << __LINE__ << ".\n"; + break; + } + } + } // Dump this group into the hierarchy - parse->AddIntoSceneGraph(osg_Group); - // Register + parse->AddIntoSceneGraph(osg_Group); + // Register int32 id; bill.GetID(id); parse->AddToGroupList(id,osg_Group); @@ -756,7 +776,7 @@ void* lodRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) double maxRange = MAX(in,out+width); // Create a new Performer LOD - LOD* osg_Lod = new LOD(); + LOD* osg_Lod = new LOD(); Vec3 osg_Center; osg_Center[0] = center.x; osg_Center[1] = center.y; osg_Center[2] = center.z; osg_Lod->setCenter(osg_Center); @@ -769,7 +789,7 @@ void* lodRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // Dump this group into the hierarchy parse->AddIntoSceneGraph(osg_Lod); - // Register for attachements + // Register for attachements int32 id; lod.GetID(id); // Add the sub-group to the group list, not the LOD @@ -856,9 +876,9 @@ TrPageParser::TrPageParser(TrPageArchive* parent) parent_ = parent; currTop = NULL; top = NULL; - layerDepth = 0; - currLayer = NULL; - in_billboard = false; + layerDepth = 0; + currLayer = NULL; + in_billboard = false; // Register the readers AddCallback(TRPG_GEOMETRY,new geomRead(this)); @@ -867,7 +887,7 @@ TrPageParser::TrPageParser(TrPageArchive* parent) AddCallback(TRPG_BILLBOARD,new billboardRead(this)); AddCallback(TRPG_LOD,new lodRead(this)); AddCallback(TRPG_MODELREF,new modelRefRead(this)); - AddCallback(TRPG_LAYER,new layerRead(this)); + AddCallback(TRPG_LAYER,new layerRead(this)); AddCallback(TRPGTILEHEADER,new tileHeaderRead(this)); } @@ -939,77 +959,77 @@ void TrPageParser::LoadLocalMaterials() int32 size; image_helper.GetImageInfoForLocalMat(&locmat, &mat,&tex,size); - int num_tex; - mat->GetNumTexture(num_tex); - for (int texNo = 0 ; texNo < num_tex; ++texNo) - { - int texId; - trpgTextureEnv texEnv; - mat->GetTexture(texNo,texId,texEnv); + int num_tex; + mat->GetNumTexture(num_tex); + for (int texNo = 0 ; texNo < num_tex; ++texNo) + { + int texId; + trpgTextureEnv texEnv; + mat->GetTexture(texNo,texId,texEnv); - // Set up texture environment - TexEnv *osg_texenv = new TexEnv(); - int32 te_mode; - texEnv.GetEnvMode(te_mode); - switch( te_mode ) - { - case trpgTextureEnv::Alpha : - osg_texenv->setMode(TexEnv::REPLACE); + // Set up texture environment + TexEnv *osg_texenv = new TexEnv(); + int32 te_mode; + texEnv.GetEnvMode(te_mode); + switch( te_mode ) + { + case trpgTextureEnv::Alpha : + osg_texenv->setMode(TexEnv::REPLACE); break; - case trpgTextureEnv::Decal: - osg_texenv->setMode(TexEnv::DECAL); - break; - case trpgTextureEnv::Blend : - osg_texenv->setMode(TexEnv::BLEND); - break; - case trpgTextureEnv::Modulate : - osg_texenv->setMode(TexEnv::MODULATE); - break; - } + case trpgTextureEnv::Decal: + osg_texenv->setMode(TexEnv::DECAL); + break; + case trpgTextureEnv::Blend : + osg_texenv->setMode(TexEnv::BLEND); + break; + case trpgTextureEnv::Modulate : + osg_texenv->setMode(TexEnv::MODULATE); + break; + } - osg_state_set->setTextureAttribute(texNo,osg_texenv); + osg_state_set->setTextureAttribute(texNo,osg_texenv); - image_helper.GetNthImageInfoForLocalMat(&locmat, texNo, &mat,&tex,size); + image_helper.GetNthImageInfoForLocalMat(&locmat, texNo, &mat,&tex,size); - trpgTexture::ImageMode mode; - tex->GetImageMode(mode); - Texture2D* osg_texture = 0L; - if(mode == trpgTexture::Template) - osg_texture = GetTemplateTexture(image_helper,&locmat, tex, texNo); - else if(mode == trpgTexture::Local) - osg_texture = GetLocalTexture(image_helper,tex); - else if(mode == trpgTexture::Global) - osg_texture = parent_->getGlobalTexture(texId); + trpgTexture::ImageMode mode; + tex->GetImageMode(mode); + Texture2D* osg_texture = 0L; + if(mode == trpgTexture::Template) + osg_texture = GetTemplateTexture(image_helper,&locmat, tex, texNo); + else if(mode == trpgTexture::Local) + osg_texture = GetLocalTexture(image_helper,tex); + else if(mode == trpgTexture::Global) + osg_texture = parent_->getGlobalTexture(texId); - if(osg_texture) - { - if(osg_texture->getImage()) - { - GLenum gltype = osg_texture->getImage()->getPixelFormat(); - if( gltype == GL_RGBA || gltype == GL_LUMINANCE_ALPHA ) - { - osg_state_set->setMode(GL_BLEND,StateAttribute::ON); - osg_state_set->setRenderingHint(StateSet::TRANSPARENT_BIN); - } - } - else - { - notify(WARN) << "No image\n"; - } - osg_state_set->setTextureAttributeAndModes(texNo,osg_texture, StateAttribute::ON); + if(osg_texture) + { + if(osg_texture->getImage()) + { + GLenum gltype = osg_texture->getImage()->getPixelFormat(); + if( gltype == GL_RGBA || gltype == GL_LUMINANCE_ALPHA ) + { + osg_state_set->setMode(GL_BLEND,StateAttribute::ON); + osg_state_set->setRenderingHint(StateSet::TRANSPARENT_BIN); + } + } + else + { + notify(WARN) << "No image\n"; + } + osg_state_set->setTextureAttributeAndModes(texNo,osg_texture, StateAttribute::ON); - int wrap_s, wrap_t; - texEnv.GetWrap(wrap_s, wrap_t); - osg_texture->setWrap(Texture2D::WRAP_S, wrap_s == trpgTextureEnv::Repeat ? Texture2D::REPEAT: Texture2D::CLAMP ); - osg_texture->setWrap(Texture2D::WRAP_T, wrap_t == trpgTextureEnv::Repeat ? Texture2D::REPEAT: Texture2D::CLAMP ); - } - else - { - notify(WARN) << "No texture\n"; - } + int wrap_s, wrap_t; + texEnv.GetWrap(wrap_s, wrap_t); + osg_texture->setWrap(Texture2D::WRAP_S, wrap_s == trpgTextureEnv::Repeat ? Texture2D::REPEAT: Texture2D::CLAMP ); + osg_texture->setWrap(Texture2D::WRAP_T, wrap_t == trpgTextureEnv::Repeat ? Texture2D::REPEAT: Texture2D::CLAMP ); + } + else + { + notify(WARN) << "No texture\n"; + } } - Material *osg_material = new Material; + Material *osg_material = new Material; float64 alpha; mat->GetAlpha(alpha); @@ -1086,30 +1106,30 @@ void TrPageParser::LoadLocalMaterials() // We'll want to make the node it's handing us the "top" node bool TrPageParser::StartChildren(void *in_node) { - // Make a node - GeodeGroup *node = (GeodeGroup *)in_node; + // Make a node + GeodeGroup *node = (GeodeGroup *)in_node; - // If we are under layer we need to drop all groups. Then - // the current parent is still the layer node - if (layerDepth==0) - { - // Set it as current parent - currTop = node; - } + // If we are under layer we need to drop all groups. Then + // the current parent is still the layer node + if (layerDepth==0) + { + // Set it as current parent + currTop = node; + } - // - // track whether we are under a billboard in the scene graph - // - if (is_billboard(currTop)) - in_billboard = true; + // + // track whether we are under a billboard in the scene graph + // + if (is_billboard(currTop)) + in_billboard = true; - // Chek if it's layer - if (node && (in_node != (void*)1) && (strcasecmp(node->className(),"Layer") == 0)) - { - if (layerDepth==0) - currLayer = (Layer*)node; - layerDepth++; - } + // Chek if it's layer + if (node && (in_node != (void*)1) && (strcasecmp(node->className(),"Layer") == 0)) + { + if (layerDepth==0) + currLayer = (Layer*)node; + layerDepth++; + } return true; } @@ -1121,48 +1141,48 @@ bool TrPageParser::StartChildren(void *in_node) // If there isn't one, we'll just stick things in our top group. bool TrPageParser::EndChildren(void *in_node) { - // Chek if it's layer - osg::Node* node = (osg::Node*)in_node; - if (node && (in_node != (void*)1) && (strcasecmp(node->className(),"Layer") == 0)) - { - if (layerDepth > 0) - layerDepth--; - else - { - notify(WARN) << "Layer depth < 0 ???\n"; - } - if (layerDepth==0) - { - currLayer = NULL; - for (unsigned int i = 0; i < deadNodes.size(); i++) - { - osg::ref_ptr deadNode = deadNodes[i]; - } - deadNodes.clear(); - } - } + // Chek if it's layer + osg::Node* node = (osg::Node*)in_node; + if (node && (in_node != (void*)1) && (strcasecmp(node->className(),"Layer") == 0)) + { + if (layerDepth > 0) + layerDepth--; + else + { + notify(WARN) << "Layer depth < 0 ???\n"; + } + if (layerDepth==0) + { + currLayer = NULL; + for (unsigned int i = 0; i < deadNodes.size(); i++) + { + osg::ref_ptr deadNode = deadNodes[i]; + } + deadNodes.clear(); + } + } - // - // track whether we are under a billboard in the scene graph - // - if (is_billboard(static_cast(in_node))) - in_billboard = false; + // + // track whether we are under a billboard in the scene graph + // + if (is_billboard(static_cast(in_node))) + in_billboard = false; - // if we are under layer all the groups are dropped out, so no need to do this - if (layerDepth==0) - { - // Get the parent above the current one - int pos = parents.size()-2; - if (pos < 0) - { - // Nothing above the current one. Fall back on our top group - currTop = top; - } - else - { - currTop = (GeodeGroup *)parents[pos]; - } - } + // if we are under layer all the groups are dropped out, so no need to do this + if (layerDepth==0) + { + // Get the parent above the current one + int pos = parents.size()-2; + if (pos < 0) + { + // Nothing above the current one. Fall back on our top group + currTop = top; + } + else + { + currTop = (GeodeGroup *)parents[pos]; + } + } return true; } @@ -1185,12 +1205,12 @@ GeodeGroup *TrPageParser::GetCurrTop() // Add the given pfGroup to the group list at position ID bool TrPageParser::AddToGroupList(int ID,GeodeGroup *group) { - // we dont do this if we are under layer - if (layerDepth==0) - { - // Note: check bounds - groupList[ID] = group; - } + // we dont do this if we are under layer + if (layerDepth==0) + { + // Note: check bounds + groupList[ID] = group; + } return true; } @@ -1211,22 +1231,22 @@ void TrPageParser::SetMaxGroupID(int maxGroupID) // Use this to add nodes into the scenegraph void TrPageParser::AddIntoSceneGraph(osg::Node* node) { - // chek first if we are under some layer - if (layerDepth) - { - deadNodes.push_back(node); - } - else - { - Group *top = GetCurrTop(); - if (top) - top->addChild(node); - } + // chek first if we are under some layer + if (layerDepth) + { + deadNodes.push_back(node); + } + else + { + Group *top = GetCurrTop(); + if (top) + top->addChild(node); + } } //---------------------------------------------------------------------------- // Return the current layer node (also used during parsing) Layer *TrPageParser::GetCurrLayer() { - return currLayer; + return currLayer; } diff --git a/src/osgPlugins/txp/trPagePageManager.cpp b/src/osgPlugins/txp/trPagePageManager.cpp index e8cba7091..d409549e6 100644 --- a/src/osgPlugins/txp/trPagePageManager.cpp +++ b/src/osgPlugins/txp/trPagePageManager.cpp @@ -12,6 +12,7 @@ #include #include +#include #include @@ -335,10 +336,18 @@ bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode) // toUnhook.clear(); } + // visitor to go through unhooked subgraphs to release texture objects + // and display lists. + osgDB::DatabasePager::ReleaseTexturesAndDrawablesVisitor rtadv; + // Do the unhooking first - for (unsigned int ui=0;uiaccept(rtadv); + // better safe than sorry if(!unhookMe ) continue; diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp index ba9a2c32a..bcb11a39c 100644 --- a/src/osgProducer/Viewer.cpp +++ b/src/osgProducer/Viewer.cpp @@ -27,7 +27,6 @@ class PickIntersectVisitor : public osgUtil::IntersectVisitor public: PickIntersectVisitor() { - setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions } virtual ~PickIntersectVisitor() {} @@ -59,11 +58,17 @@ public: PickVisitor() { xp=yp=0; - setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); } ~PickVisitor() {} + // Aug 2003 added to pass the nodemaskOverride to the PickIntersectVisitor + // may be used make the visitor override the nodemask to visit invisible actions + inline void setNodeMaskOverride(osg::Node::NodeMask mask) { + _piv.setNodeMaskOverride(mask); + _nodeMaskOverride = mask; } + + virtual void apply(osg::Projection& pr) { // stack the intersect rays, transform to new projection, traverse // Assumes that the Projection is an absolute projection