void SimpleDotVisitor::handle(osg::Geode &node, int id) { std::stringstream label; label << "<top> " << node.className(); if (!node.getName().empty()) { label << "| " << node.getName(); } drawNode(id, "record", "solid", label.str(), "brown", "white"); }
void OBJWriterNodeVisitor::apply( osg::Geode &node ) { pushStateSet(node.getStateSet()); _nameStack.push_back(node.getName()); unsigned int count = node.getNumDrawables(); for ( unsigned int i = 0; i < count; i++ ) { node.getDrawable( i )->accept(*this); } popStateSet(node.getStateSet()); _nameStack.pop_back(); }
virtual void apply(osg::Geode& node) { osg::Matrix mat = osg::computeLocalToWorld(getNodePath()); if (m_options && (m_options->getOptionString() == "separateFiles")) { std::string sepFile = m_fout + i2s(counter) + "." + m_fout_ext; m_f = new osgDB::ofstream(sepFile.c_str()); } if (node.getName().empty()) *m_f << "solid " << counter << std::endl; else *m_f << "solid " << node.getName() << std::endl; for (unsigned int i = 0; i < node.getNumDrawables(); ++i) { osg::TriangleFunctor<PushPoints> tf; tf.m_stream = m_f; tf.m_mat = mat; tf.m_dontSaveNormals = m_dontSaveNormals; node.getDrawable(i)->accept(tf); } if (node.getName().empty()) *m_f << "endsolid " << counter << std::endl; else *m_f << "endsolid " << node.getName() << std::endl; if (m_options && (m_options->getOptionString() == "separateFiles")) { m_f->close(); delete m_f; } ++counter; traverse(node); }
void OBJWriterNodeVisitor::apply( osg::Geode &node ) { pushStateSet(node.getStateSet()); _nameStack.push_back(node.getName()); osg::Matrix m = osg::computeLocalToWorld(getNodePath()); unsigned int count = node.getNumDrawables(); for ( unsigned int i = 0; i < count; i++ ) { osg::Geometry *g = node.getDrawable( i )->asGeometry(); if ( g != NULL ) { pushStateSet(g->getStateSet()); processGeometry(g,m); popStateSet(g->getStateSet()); } } popStateSet(node.getStateSet()); _nameStack.pop_back(); }
void FltExportVisitor::writeMesh( const osg::Geode& geode, const osg::Geometry& geom ) { enum DrawMode { SOLID_BACKFACE = 0, SOLID_NO_BACKFACE = 1, WIREFRAME_CLOSED = 2, WIREFRAME_NOT_CLOSED = 3, SURROUND_ALTERNATE_COLOR = 4, OMNIDIRECTIONAL_LIGHT = 8, UNIDIRECTIONAL_LIGHT = 9, BIDIRECTIONAL_LIGHT = 10 }; enum TemplateMode { FIXED_NO_ALPHA_BLENDING = 0, FIXED_ALPHA_BLENDING = 1, AXIAL_ROTATE_WITH_ALPHA_BLENDING = 2, POINT_ROTATE_WITH_ALPHA_BLENDING = 4 }; // const unsigned int TERRAIN_BIT = 0x80000000u >> 0; //const unsigned int NO_COLOR_BIT = 0x80000000u >> 1; //const unsigned int NO_ALT_COLOR_BIT = 0x80000000u >> 2; const unsigned int PACKED_COLOR_BIT = 0x80000000u >> 3; //const unsigned int FOOTPRINT_BIT = 0x80000000u >> 4; // Terrain culture cutout const unsigned int HIDDEN_BIT = 0x80000000u >> 5; //const unsigned int ROOFLINE_BIT = 0x80000000u >> 6; uint32 flags( PACKED_COLOR_BIT ); if (geode.getNodeMask() == 0) flags |= HIDDEN_BIT; enum LightMode { FACE_COLOR = 0, VERTEX_COLOR = 1, FACE_COLOR_LIGHTING = 2, VERTEX_COLOR_LIGHTING = 3 }; int8 lightMode; osg::Vec4 packedColorRaw( 1., 1., 1., 1. ); uint16 transparency( 0 ); if (geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX) { if (isLit( geom )) lightMode = VERTEX_COLOR_LIGHTING; else lightMode = VERTEX_COLOR; } else { const osg::Vec4Array* c = dynamic_cast<const osg::Vec4Array*>( geom.getColorArray() ); if (c && (c->size() > 0)) { packedColorRaw = (*c)[0]; transparency = flt::uint16((1. - packedColorRaw[3]) * (double)0xffff); } if (isLit( geom )) lightMode = FACE_COLOR_LIGHTING; else lightMode = FACE_COLOR; } uint32 packedColor; packedColor = (int)(packedColorRaw[3]*255) << 24 | (int)(packedColorRaw[2]*255) << 16 | (int)(packedColorRaw[1]*255) << 8 | (int)(packedColorRaw[0]*255); int8 drawType; osg::StateSet const* ss = getCurrentStateSet(); { // Default to no facet culling drawType = SOLID_NO_BACKFACE; // If facet-culling isn't *dis*abled, check whether the CullFace mode is BACK if (ss->getMode(GL_CULL_FACE) & osg::StateAttribute::ON) { osg::CullFace const* cullFace = static_cast<osg::CullFace const*>( ss->getAttribute(osg::StateAttribute::CULLFACE) ); if( cullFace->getMode() == osg::CullFace::BACK ) drawType = SOLID_BACKFACE; // Note: OpenFlt can't handle FRONT or FRONT_AND_BACK settings, so ignore these(??) } } // Determine the material properties for the face int16 materialIndex( -1 ); if (isLit( geom )) { osg::Material const* currMaterial = static_cast<osg::Material const*>( ss->getAttribute(osg::StateAttribute::MATERIAL) ); materialIndex = _materialPalette->add(currMaterial); } // Get base texture int16 textureIndex( -1 ); if (isTextured( 0, geom )) { const osg::Texture2D* texture = static_cast<const osg::Texture2D*>( ss->getTextureAttribute( 0, osg::StateAttribute::TEXTURE ) ); if (texture != NULL) textureIndex = _texturePalette->add( 0, texture ); else { std::string warning( "fltexp: Mesh is textured, but Texture2D StateAttribute is NULL." ); osg::notify( osg::WARN ) << warning << std::endl; _fltOpt->getWriteResult().warn( warning ); } } // Set the appropriate template mode based // on blending or Billboarding. TemplateMode templateMode( FIXED_NO_ALPHA_BLENDING ); const osg::Billboard* bb = dynamic_cast< const osg::Billboard* >( &geode ); if (bb != NULL) { if( bb->getMode() == osg::Billboard::AXIAL_ROT ) templateMode = AXIAL_ROTATE_WITH_ALPHA_BLENDING; else templateMode = POINT_ROTATE_WITH_ALPHA_BLENDING; } else if ( ss->getMode( GL_BLEND ) & osg::StateAttribute::ON ) { const osg::BlendFunc* bf = static_cast<const osg::BlendFunc*>( ss->getAttribute(osg::StateAttribute::BLENDFUNC) ); if( (bf->getSource() == osg::BlendFunc::SRC_ALPHA) && (bf->getDestination() == osg::BlendFunc::ONE_MINUS_SRC_ALPHA) ) templateMode = FIXED_ALPHA_BLENDING; } uint16 length( 84 ); IdHelper id( *this, geode.getName() ); _records->writeInt16( (int16) MESH_OP ); _records->writeUInt16( length ); _records->writeID( id ); _records->writeInt32( 0 ); // Reserved _records->writeInt32( 0 ); // IR color code _records->writeInt16( 0 ); // Relative priority _records->writeInt8( drawType ); // Draw type _records->writeInt8( 0 ); // Texture white _records->writeInt16( -1 ); // Color name index _records->writeInt16( -1 ); // Alternate color name index _records->writeInt8( 0 ); // Reserved _records->writeInt8( templateMode ); // Template (billboard) _records->writeInt16( -1 ); // Detail texture pattern index _records->writeInt16( textureIndex ); // Texture pattern index _records->writeInt16( materialIndex ); // Material index _records->writeInt16( 0 ); // Surface material code _records->writeInt16( 0 ); // Feature ID _records->writeInt32( 0 ); // IR material code _records->writeUInt16( transparency ); // Transparency _records->writeInt8( 0 ); // LOD generation control _records->writeInt8( 0 ); // Line style index _records->writeUInt32( flags ); // Flags _records->writeInt8( lightMode ); // Light mode _records->writeFill( 7 ); // Reserved _records->writeUInt32( packedColor ); // Packed color, primary _records->writeUInt32( 0x00ffffff ); // Packed color, alternate _records->writeInt16( -1 ); // Texture mapping index _records->writeInt16( 0 ); // Reserved _records->writeInt32( -1 ); // Primary color index _records->writeInt32( -1 ); // Alternate color index // Next four bytes: // 15.8: two 2-byte "reserved" fields // 15.9: one 4-byte "reserved" field _records->writeInt16( 0 ); // Reserved _records->writeInt16( -1 ); // Shader index }
virtual void apply(osg::Geode &geode) { if (geode.getName().compare(0, 9, "tessellate") == 0) { for (unsigned int i = 0; i < geode.getNumDrawables(); ++i) { osg::Geometry *geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i)); if (geom) { osg::ref_ptr<osgUtil::Tessellator> tscx = new osgUtil::Tessellator(); if (tscx.valid()) { tscx->setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY); if (geode.getName() == "tessellate") { // add a Tessellator so that this geom is retessellated when N is pressed tscx->setBoundaryOnly(true); tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_ABS_GEQ_TWO); // so that first change in wind type makes the commonest tessellation - ODD. geom->setUserData(tscx.get()); } else if (geode.getName() == "tessellate odd") { // OR you can just apply the Tessellator once only, using these different types tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_ODD); // commonest tessellation - ODD. tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate odd bound") { tscx->setBoundaryOnly(true); tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_ODD); // tessellation - ODD, only show boundary. tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate positive") { tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE); // tessellation - pos. tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate positive bound") { tscx->setBoundaryOnly(true); tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE); tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate negative") { tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_NEGATIVE); tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate negative bound") { tscx->setBoundaryOnly(true); tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_NEGATIVE); tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate nonzero") { tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_NONZERO); tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate nonzero bound") { tscx->setBoundaryOnly(true); tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_NONZERO); tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate geq2") { tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_ABS_GEQ_TWO); tscx->retessellatePolygons(*geom); } else if (geode.getName() == "tessellate geq2 bound") { tscx->setBoundaryOnly(true); tscx->setWindingType(osgUtil::Tessellator::TESS_WINDING_ABS_GEQ_TWO); tscx->retessellatePolygons(*geom); } } } } } }
void WriterNodeVisitor::buildFaces(osg::Geode & geo, const osg::Matrix & mat, ListTriangle & listTriangles, bool texcoords) { unsigned int nbTrianglesRemaining = listTriangles.size(); unsigned int nbVerticesRemaining = calcVertices(geo); // May set _succeded to false if (!succeeded()) return; std::string name( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), true, "geo") ); if (!succeeded()) return; Lib3dsMesh *mesh = lib3ds_mesh_new( name.c_str() ); if (!mesh) { OSG_NOTIFY(osg::FATAL) << "Allocation error" << std::endl; _succeeded = false; return; } //copyOsgMatrixToLib3dsMatrix(mesh->matrix, mat); lib3ds_mesh_resize_faces (mesh, osg::minimum(nbTrianglesRemaining, MAX_FACES)); lib3ds_mesh_resize_vertices(mesh, osg::minimum(nbVerticesRemaining, MAX_VERTICES), texcoords ? 0 : 1, 0); // Not mandatory but will allocate once a big block // Test if the mesh will be split and needs sorting if (nbVerticesRemaining >= MAX_VERTICES || nbTrianglesRemaining >= MAX_FACES) { OSG_INFO << "Sorting elements..." << std::endl; WriterCompareTriangle cmp(geo, nbVerticesRemaining); std::sort(listTriangles.begin(), listTriangles.end(), cmp); } MapIndices index_vert; unsigned int numFace = 0; // Current face index for (ListTriangle::iterator it = listTriangles.begin(); it != listTriangles.end(); ++it) //Go through the triangle list to define meshs { // Test if the mesh will be full after adding a face if (index_vert.size()+3 >= MAX_VERTICES || numFace+1 >= MAX_FACES) { // Finnish mesh lib3ds_mesh_resize_faces (mesh, numFace); //lib3ds_mesh_resize_vertices() will be called in buildMesh() buildMesh(geo, mat, index_vert, texcoords, mesh); // May set _succeded to false if (!succeeded()) { lib3ds_mesh_free(mesh); return; } // "Reset" values and start over a new mesh index_vert.clear(); nbTrianglesRemaining -= numFace; numFace = 0; // We can't call a thing like "nbVerticesRemaining -= ...;" because points may be used multiple times. // [Sukender: An optimisation here would take too much time I think.] mesh = lib3ds_mesh_new( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), true, "geo").c_str()); if (!mesh) { OSG_NOTIFY(osg::FATAL) << "Allocation error" << std::endl; _succeeded = false; return; } lib3ds_mesh_resize_faces (mesh, osg::minimum(nbTrianglesRemaining, MAX_FACES)); lib3ds_mesh_resize_vertices(mesh, osg::minimum(nbVerticesRemaining, MAX_VERTICES), texcoords ? 0 : 1, 0); // Not mandatory but will allocate once a big block } Lib3dsFace & face = mesh->faces[numFace++]; face.index[0] = getMeshIndexForGeometryIndex(index_vert, it->first.t1, it->second); face.index[1] = getMeshIndexForGeometryIndex(index_vert, it->first.t2, it->second); face.index[2] = getMeshIndexForGeometryIndex(index_vert, it->first.t3, it->second); face.material = it->first.material; } buildMesh(geo, mat, index_vert, texcoords, mesh); // May set _succeded to false if (!succeeded()) { lib3ds_mesh_free(mesh); return; } }