diff --git a/CMakeModules/FindOpenVRML.cmake b/CMakeModules/FindOpenVRML.cmake index 835a1ec8f..e40e8f851 100644 --- a/CMakeModules/FindOpenVRML.cmake +++ b/CMakeModules/FindOpenVRML.cmake @@ -10,7 +10,7 @@ # Created by Robert Osfield. # Modified for the debug library by Jean-Sébastien Guay. -FIND_PATH(OPENVRML_INCLUDE_DIR openvrml/openvrml/common.h +FIND_PATH(OPENVRML_INCLUDE_DIR openvrml/openvrml-common.h $ENV{OPENVRML_DIR}/include $ENV{OPENVRML_DIR} ~/Library/Frameworks diff --git a/src/osgPlugins/vrml/IndexedFaceSet.cpp b/src/osgPlugins/vrml/IndexedFaceSet.cpp index 66032b829..fd9ceb8eb 100644 --- a/src/osgPlugins/vrml/IndexedFaceSet.cpp +++ b/src/osgPlugins/vrml/IndexedFaceSet.cpp @@ -4,130 +4,128 @@ #if defined(_MSC_VER) -# pragma warning(disable: 4250) -# pragma warning(disable: 4290) -# pragma warning(disable: 4800) -#endif +# pragma warning(disable: 4250) +# pragma warning(disable: 4290) +# pragma warning(disable: 4800) +#endif #include -#include #include -#include -#include #include - -osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openvrml::vrml97_node::indexed_face_set_node *vrml_ifs) const +osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openvrml::node *vrml_ifs) const { osg::ref_ptr osg_geom = new osg::Geometry(); - + osg_geom->addPrimitiveSet(new osg::DrawArrayLengths(osg::PrimitiveSet::POLYGON)); osg::StateSet *osg_stateset = osg_geom->getOrCreateStateSet(); - + // get array of vertex coordinate_nodes + if(vrml_ifs->type().id() == "IndexedFaceSet") { - const openvrml::field_value& fv = vrml_ifs->field("coord"); - const openvrml::sfnode& sfn = dynamic_cast(fv); - openvrml::vrml97_node::coordinate_node* vrml_coord_node = dynamic_cast(sfn.value.get()); - - const std::vector& vrml_coord = vrml_coord_node->point(); + std::auto_ptr fv = vrml_ifs->field("coord"); + const openvrml::sfnode *sfn = dynamic_cast(fv.get()); + + openvrml::coordinate_node *vrml_coord_node = dynamic_cast((sfn->value()).get()); + const std::vector &vrml_coord = vrml_coord_node->point(); + osg::ref_ptr osg_vertices = new osg::Vec3Array(); - + unsigned i; for (i = 0; i < vrml_coord.size(); i++) { openvrml::vec3f vec = vrml_coord[i]; osg_vertices->push_back(osg::Vec3(vec[0], vec[1], vec[2])); } - + osg_geom->setVertexArray(osg_vertices.get()); - + // get array of vertex indices - const openvrml::field_value &fv2 = vrml_ifs->field("coordIndex"); - const openvrml::mfint32 &vrml_coord_index = dynamic_cast(fv2); - + std::auto_ptr fv2 = vrml_ifs->field("coordIndex"); + const openvrml::mfint32 *vrml_coord_index = dynamic_cast(fv2.get()); + osg::ref_ptr osg_vert_index = new osg::IntArray(); - + int num_vert = 0; - for (i = 0; i < vrml_coord_index.value.size(); i++) + for (i = 0; i < vrml_coord_index->value().size(); i++) { - int index = vrml_coord_index.value[i]; - if (index == -1) + int index = vrml_coord_index->value()[i]; + if (index == -1) { static_cast(osg_geom->getPrimitiveSet(0))->push_back(num_vert); num_vert = 0; - } - else + } + else { osg_vert_index->push_back(index); ++num_vert; } } + if (num_vert) { //GvdB: Last coordIndex wasn't -1 static_cast(osg_geom->getPrimitiveSet(0))->push_back(num_vert); } - + osg_geom->setVertexIndices(osg_vert_index.get()); } - + { // get texture coordinate_nodes - const openvrml::field_value &fv = vrml_ifs->field("texCoord"); - const openvrml::sfnode &sfn = dynamic_cast(fv); - openvrml::vrml97_node::texture_coordinate_node *vrml_tex_coord_node = - dynamic_cast(sfn.value.get()); - + std::auto_ptr fv = vrml_ifs->field("texCoord"); + const openvrml::sfnode *sfn = dynamic_cast(fv.get()); + openvrml::texture_coordinate_node *vrml_tex_coord_node = dynamic_cast(sfn->value().get()); + if (vrml_tex_coord_node != 0) // if no texture, node is NULL pointer { const std::vector &vrml_tex_coord = vrml_tex_coord_node->point(); osg::ref_ptr osg_texcoords = new osg::Vec2Array(); - + unsigned i; for (i = 0; i < vrml_tex_coord.size(); i++) { openvrml::vec2f vec = vrml_tex_coord[i]; osg_texcoords->push_back(osg::Vec2(vec[0], vec[1])); } - + osg_geom->setTexCoordArray(0, osg_texcoords.get()); - + // get array of texture indices - const openvrml::field_value &fv2 = vrml_ifs->field("texCoordIndex"); - const openvrml::mfint32 &vrml_tex_coord_index = dynamic_cast(fv2); - + std::auto_ptr fv2 = vrml_ifs->field("texCoordIndex"); + const openvrml::mfint32 *vrml_tex_coord_index = dynamic_cast(fv2.get()); + osg::ref_ptr osg_tex_coord_index = new osg::IntArray(); - - if(vrml_tex_coord_index.value.size() > 0) + + if(vrml_tex_coord_index->value().size() > 0) { - for (i = 0; i < vrml_tex_coord_index.value.size(); i++) + for (i = 0; i < vrml_tex_coord_index->value().size(); i++) { - int index = vrml_tex_coord_index.value[i]; + int index = vrml_tex_coord_index->value()[i]; if (index != -1) { osg_tex_coord_index->push_back(index); } } osg_geom->setTexCoordIndices(0, osg_tex_coord_index.get()); - } else + } else // no indices defined, use coordIndex osg_geom->setTexCoordIndices(0, osg_geom->getVertexIndices()); } } - + // get array of normals per vertex (if specified) { - const openvrml::field_value& fv = vrml_ifs->field("normal"); - const openvrml::sfnode& sfn = dynamic_cast(fv); - openvrml::vrml97_node::normal_node* vrml_normal_node = dynamic_cast(sfn.value.get()); - + std::auto_ptr fv = vrml_ifs->field("normal"); + const openvrml::sfnode *sfn = dynamic_cast(fv.get()); + openvrml::normal_node *vrml_normal_node = dynamic_cast(sfn->value().get()); + if (vrml_normal_node != 0) // if no normals, node is NULL pointer { const std::vector& vrml_normal_coord = vrml_normal_node->vector(); - + osg::ref_ptr osg_normalcoords = new osg::Vec3Array(); - + unsigned i; for (i = 0; i < vrml_normal_coord.size(); i++) { @@ -135,34 +133,34 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv osg_normalcoords->push_back(osg::Vec3(vec[0], vec[1], vec[2])); } osg_geom->setNormalArray(osg_normalcoords.get()); - + // get array of normal indices - const openvrml::field_value& fv2 = vrml_ifs->field("normalIndex"); - const openvrml::mfint32& vrml_normal_index = dynamic_cast(fv2); - + std::auto_ptr fv2 = vrml_ifs->field("normalIndex"); + const openvrml::mfint32 *vrml_normal_index = dynamic_cast(fv2.get()); + osg::ref_ptr osg_normal_index = new osg::IntArray(); - - if (vrml_normal_index.value.size() > 0) + + if (vrml_normal_index->value().size() > 0) { - for (i = 0; i < vrml_normal_index.value.size(); i++) + for (i = 0; i < vrml_normal_index->value().size(); i++) { - int index = vrml_normal_index.value[i]; + int index = vrml_normal_index->value()[i]; if (index != -1) { osg_normal_index->push_back(index); } } osg_geom->setNormalIndices(osg_normal_index.get()); - } + } else // unspecified, use the coordIndex field osg_geom->setNormalIndices(osg_geom->getVertexIndices()); - + // get normal binding - const openvrml::field_value &fv3 = vrml_ifs->field("normalPerVertex"); - const openvrml::sfbool &vrml_norm_per_vertex = dynamic_cast(fv3); - - if (vrml_norm_per_vertex.value) + std::auto_ptr fv3 = vrml_ifs->field("normalPerVertex"); + const openvrml::sfbool *vrml_norm_per_vertex = dynamic_cast(fv3.get()); + + if (vrml_norm_per_vertex->value()) { osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); } else @@ -171,20 +169,19 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv } } } - + // get array of colours per vertex (if specified) { - const openvrml::field_value &fv = vrml_ifs->field("color"); - const openvrml::sfnode &sfn = dynamic_cast(fv); - openvrml::vrml97_node::color_node *vrml_color_node = - dynamic_cast(sfn.value.get()); - + std::auto_ptr fv = vrml_ifs->field("color"); + const openvrml::sfnode *sfn = dynamic_cast(fv.get()); + openvrml::color_node *vrml_color_node = dynamic_cast(sfn->value().get()); + if (vrml_color_node != 0) // if no colors, node is NULL pointer { const std::vector &vrml_colors = vrml_color_node->color(); - + osg::ref_ptr osg_colors = new osg::Vec3Array(); - + unsigned i; for (i = 0; i < vrml_colors.size(); i++) { @@ -192,32 +189,32 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv osg_colors->push_back(osg::Vec3(color.r(), color.g(), color.b())); } osg_geom->setColorArray(osg_colors.get()); - + // get array of color indices - const openvrml::field_value &fv2 = vrml_ifs->field("colorIndex"); - const openvrml::mfint32 &vrml_color_index = dynamic_cast(fv2); - + std::auto_ptr fv2 = vrml_ifs->field("colorIndex"); + const openvrml::mfint32 *vrml_color_index = dynamic_cast(fv2.get()); + osg::ref_ptr osg_color_index = new osg::IntArray(); - - if(vrml_color_index.value.size() > 0) + + if(vrml_color_index->value().size() > 0) { - for (i = 0; i < vrml_color_index.value.size(); i++) + for (i = 0; i < vrml_color_index->value().size(); i++) { - int index = vrml_color_index.value[i]; + int index = vrml_color_index->value()[i]; if (index != -1) { osg_color_index->push_back(index); } } osg_geom->setColorIndices(osg_color_index.get()); - } else + } else // unspecified, use coordIndices field osg_geom->setColorIndices(osg_geom->getVertexIndices()); - + // get color binding - const openvrml::field_value &fv3 = vrml_ifs->field("colorPerVertex"); - const openvrml::sfbool &vrml_color_per_vertex = dynamic_cast(fv3); - - if (vrml_color_per_vertex.value) + std::auto_ptr fv3 = vrml_ifs->field("colorPerVertex"); + const openvrml::sfbool *vrml_color_per_vertex = dynamic_cast(fv3.get()); + + if (vrml_color_per_vertex->value()) { osg_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); } else @@ -226,12 +223,16 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv } } } - - if (static_cast(vrml_ifs->field("solid")).value) + + + // normal smoothing + std::auto_ptr fv_solid = vrml_ifs->field("solid"); + const openvrml::sfbool *solid = dynamic_cast(fv_solid.get()); + if (solid->value()) { osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK)); } - + if (!osg_geom->getNormalArray()) { #if 0 @@ -239,58 +240,57 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv osgUtil::SmoothingVisitor().smooth(*osg_geom); #else // GvdB: So I ended up computing the smoothing normals myself. Also, I might add support for "creaseAngle" if a big need for it rises. - // However, for now I can perfectly live with the fact that all edges are smoothed despite the use of a crease angle. + // However, for now I can perfectly live with the fact that all edges are smoothed despite the use of a crease angle. osg::Vec3Array& coords = *static_cast(osg_geom->getVertexArray()); assert(coords.size()); - + osg::Vec3Array* normals = new osg::Vec3Array(coords.size()); - + for (osg::Vec3Array::iterator it = normals->begin(); it != normals->end(); ++it) { (*it).set(0.0f, 0.0f, 0.0f); - } - - + } + + osg::IntArray& indices = *static_cast(osg_geom->getVertexIndices()); osg::DrawArrayLengths& lengths = *static_cast(osg_geom->getPrimitiveSet(0)); - int index = 0; - - for (osg::DrawArrayLengths::iterator it = lengths.begin(); it != lengths.end(); ++it) + unsigned index = 0; + + for (osg::DrawArrayLengths::iterator it = lengths.begin(); it != lengths.end(); ++it) { assert(*it >= 3); - const osg::Vec3& v0 = coords[indices[index]]; - const osg::Vec3& v1 = coords[indices[index + 1]]; - const osg::Vec3& v2 = coords[indices[index + 2]]; - + const osg::Vec3& v0 = coords[indices[index]]; + const osg::Vec3& v1 = coords[indices[index + 1]]; + const osg::Vec3& v2 = coords[indices[index + 2]]; + osg::Vec3 normal = (v1 - v0) ^ (v2 - v0); normal.normalize(); - + for (int i = 0; i != *it; ++i) { (*normals)[indices[index + i]] += normal; } - + index += *it; } - + assert(index == indices.size()); - + for(osg::Vec3Array::iterator it = normals->begin(); it != normals->end(); ++it) { (*it).normalize(); } - + osg_geom->setNormalArray(normals); osg_geom->setNormalIndices(osg_geom->getVertexIndices()); - osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - + osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + #endif - } - - + } + osg::DrawArrayLengths& lengths = *static_cast(osg_geom->getPrimitiveSet(0)); - - osg::DrawArrayLengths::iterator it = lengths.begin(); + + osg::DrawArrayLengths::iterator it = lengths.begin(); if (it != lengths.end()) { switch (*it) @@ -298,7 +298,7 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv case 3: while (++it != lengths.end() && *it == 3) ; - + if (it == lengths.end()) { // All polys are triangles @@ -306,13 +306,13 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv mesh->setCount(lengths.size() * 3); osg_geom->removePrimitiveSet(0); osg_geom->addPrimitiveSet(mesh.get()); - } + } break; - + case 4: while (++it != lengths.end() && *it == 4) ; - + if (it == lengths.end()) { // All polys are quads @@ -320,10 +320,11 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv mesh->setCount(lengths.size() * 4); osg_geom->removePrimitiveSet(0); osg_geom->addPrimitiveSet(mesh.get()); - } - + } + break; } - } + } + return osg_geom.get(); } diff --git a/src/osgPlugins/vrml/Primitives.cpp b/src/osgPlugins/vrml/Primitives.cpp index d29160d76..3307bac0b 100644 --- a/src/osgPlugins/vrml/Primitives.cpp +++ b/src/osgPlugins/vrml/Primitives.cpp @@ -5,67 +5,65 @@ #include #if defined(_MSC_VER) -# pragma warning(disable: 4250) -# pragma warning(disable: 4290) -# pragma warning(disable: 4800) -#endif +# pragma warning(disable: 4250) +# pragma warning(disable: 4290) +# pragma warning(disable: 4800) +#endif #include -#include #include -#include -#include #include -osg::ref_ptr ReaderWriterVRML2::convertVRML97Box(openvrml::vrml97_node::box_node* vrml_box) const +osg::ref_ptr ReaderWriterVRML2::convertVRML97Box(openvrml::node* vrml_box) const { - const openvrml::vec3f& size = static_cast(vrml_box->field("size")).value; - - osg::Vec3 halfSize(size[0] * 0.5f, size[1] * 0.5f, size[2] * 0.5f); + std::auto_ptr fv = vrml_box->field("size"); + const openvrml::vec3f &size = static_cast (fv.get())->value(); + + osg::Vec3 halfSize(size[0] * 0.5f, size[1] * 0.5f, size[2] * 0.5f); BoxLibrary::const_iterator it = m_boxLibrary.find(halfSize); if (it != m_boxLibrary.end()) { return (*it).second.get(); - } - + } + osg::ref_ptr osg_geom = new osg::Geometry(); osg::ref_ptr osg_vertices = new osg::Vec3Array(); - osg::ref_ptr osg_texcoords = new osg::Vec2Array(); - osg::ref_ptr osg_normals = new osg::Vec3Array(); - + osg::ref_ptr osg_texcoords = new osg::Vec2Array(); + osg::ref_ptr osg_normals = new osg::Vec3Array(); + osg::ref_ptr box = new osg::DrawArrays(osg::PrimitiveSet::QUADS); - - osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); + + osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2])); - - osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); - osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); - osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], halfSize[1], -halfSize[2])); + + osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], halfSize[2])); + osg_vertices->push_back(osg::Vec3(-halfSize[0], -halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], -halfSize[2])); + osg_vertices->push_back(osg::Vec3(halfSize[0], -halfSize[1], halfSize[2])); for (int i = 0; i != 6; ++i) { @@ -83,9 +81,9 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Box(openvrml::vrml97 osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); box->setCount(osg_vertices->size()); - + osg_geom->addPrimitiveSet(box.get()); - + osg_geom->setVertexArray(osg_vertices.get()); osg_geom->setTexCoordArray(0, osg_texcoords.get()); osg_geom->setNormalArray(osg_normals.get()); @@ -98,10 +96,10 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Box(openvrml::vrml97 return osg_geom.get(); } - -osg::ref_ptr ReaderWriterVRML2::convertVRML97Sphere(openvrml::vrml97_node::sphere_node* vrml_sphere) const +osg::ref_ptr ReaderWriterVRML2::convertVRML97Sphere(openvrml::node* vrml_sphere) const { - float radius = static_cast(vrml_sphere->field("radius")).value; + std::auto_ptr fv = vrml_sphere->field("radius"); + const float radius = static_cast (fv.get())->value(); SphereLibrary::const_iterator it = m_sphereLibrary.find(radius); if (it != m_sphereLibrary.end()) @@ -111,9 +109,9 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Sphere(openvrml::vrm osg::ref_ptr osg_geom = new osg::Geometry(); osg::ref_ptr osg_vertices = new osg::Vec3Array(); - osg::ref_ptr osg_texcoords = new osg::Vec2Array(); + osg::ref_ptr osg_texcoords = new osg::Vec2Array(); osg::ref_ptr osg_normals = new osg::Vec3Array(); - + unsigned int numSegments = 40; unsigned int numRows = 20; @@ -124,9 +122,9 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Sphere(openvrml::vrm float phi = -0.5f * float(osg::PI); float texCoordT = 0.0f; - + osg::ref_ptr sphere = new osg::DrawArrayLengths(osg::PrimitiveSet::QUAD_STRIP); - + for (unsigned int i = 0; i < numRows; ++i, phi += phiDelta, texCoordT += texCoordTDelta) { std::complex latBottom = std::polar(1.0f, phi); @@ -136,35 +134,35 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Sphere(openvrml::vrm float theta = 0.0f; float texCoordS = 0.0f; - + for (unsigned int j = 0; j < numSegments; ++j, theta += thetaDelta, texCoordS += texCoordSDelta) { std::complex n = -std::polar(1.0f, theta); osg_normals->push_back(osg::Vec3(latTop.real() * n.imag(), latTop.imag(), latTop.real() * n.real())); osg_normals->push_back(osg::Vec3(latBottom.real() * n.imag(), latBottom.imag(), latBottom.real() * n.real())); - + osg_texcoords->push_back(osg::Vec2(texCoordS, texCoordT + texCoordTDelta)); osg_texcoords->push_back(osg::Vec2(texCoordS, texCoordT)); - + osg_vertices->push_back(osg::Vec3(eTop.real() * n.imag(), eTop.imag(), eTop.real() * n.real())); osg_vertices->push_back(osg::Vec3(eBottom.real() * n.imag(), eBottom.imag(), eBottom.real() * n.real())); } osg_normals->push_back(osg::Vec3(0.0f, latTop.imag(), -latTop.real())); osg_normals->push_back(osg::Vec3(0.0f, latBottom.imag(), -latBottom.real())); - + osg_texcoords->push_back(osg::Vec2(1.0f, texCoordT + texCoordTDelta)); osg_texcoords->push_back(osg::Vec2(1.0f, texCoordT)); - + osg_vertices->push_back(osg::Vec3(0.0f, eTop.imag(), -eTop.real())); osg_vertices->push_back(osg::Vec3(0.0f, eBottom.imag(), -eBottom.real())); - + sphere->push_back(numSegments * 2 + 2); } - + osg_geom->addPrimitiveSet(sphere.get()); - + osg_geom->setVertexArray(osg_vertices.get()); osg_geom->setTexCoordArray(0, osg_texcoords.get()); osg_geom->setNormalArray(osg_normals.get()); @@ -177,13 +175,12 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Sphere(openvrml::vrm return osg_geom.get(); } - -osg::ref_ptr ReaderWriterVRML2::convertVRML97Cone(openvrml::vrml97_node::cone_node* vrml_cone) const +osg::ref_ptr ReaderWriterVRML2::convertVRML97Cone(openvrml::node* vrml_cone) const { - float height = static_cast(vrml_cone->field("height")).value; - float radius = static_cast(vrml_cone->field("bottomRadius")).value; - bool bottom = static_cast(vrml_cone->field("bottom")).value; - bool side = static_cast(vrml_cone->field("side")).value; + float height = static_cast(vrml_cone->field("height").get())->value(); + float radius = static_cast(vrml_cone->field("bottomRadius").get())->value(); + bool bottom = static_cast(vrml_cone->field("bottom").get())->value(); + bool side = static_cast(vrml_cone->field("side").get())->value(); QuadricKey key(height, radius, bottom, side, false); @@ -192,93 +189,92 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Cone(openvrml::vrml9 { return (*it).second.get(); } - + osg::ref_ptr osg_geom = new osg::Geometry(); osg::ref_ptr osg_vertices = new osg::Vec3Array(); - osg::ref_ptr osg_texcoords = new osg::Vec2Array(); + osg::ref_ptr osg_texcoords = new osg::Vec2Array(); osg::ref_ptr osg_normals = new osg::Vec3Array(); unsigned int numSegments = 40; const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments); - + float topY = height * 0.5f; float bottomY = height * -0.5f; - + if (side) { osg::ref_ptr side = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP); - + const float texCoordDelta = 1.0f / float(numSegments); float theta = 0.0f; float texCoord = 0.0f; - + for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta, texCoord += texCoordDelta) { std::complex n = -std::polar(1.0f, theta); - std::complex e = n * radius; - + std::complex e = n * radius; + osg::Vec3 normal(n.imag() * height, radius, n.real() * height); normal.normalize(); osg_normals->push_back(normal); osg_normals->push_back(normal); - + osg_texcoords->push_back(osg::Vec2(texCoord, 1.0f)); osg_texcoords->push_back(osg::Vec2(texCoord, 0.0f)); - + osg_vertices->push_back(osg::Vec3(0.0f, topY, 0.0f)); osg_vertices->push_back(osg::Vec3(e.imag(), bottomY, e.real())); } - + // do last point by hand to ensure no round off errors. - + osg::Vec3 normal(0.0f, radius, -height); normal.normalize(); - osg_normals->push_back(normal); osg_normals->push_back(normal); - + osg_normals->push_back(normal); + osg_texcoords->push_back(osg::Vec2(1.0f, 1.0f)); osg_texcoords->push_back(osg::Vec2(1.0f, 0.0f)); - + osg_vertices->push_back(osg::Vec3(0.0f, topY, 0.0f)); - osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius)); - + osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius)); + side->setCount(osg_vertices->size()); - osg_geom->addPrimitiveSet(side.get()); + osg_geom->addPrimitiveSet(side.get()); } if (bottom) { osg::ref_ptr bottom = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN); - size_t first = osg_vertices->size(); bottom->setFirst(first); float theta = 0.0f; - + for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta) { std::complex n = -std::polar(1.0f, theta); - std::complex e = n * radius; - + std::complex e = n * radius; + osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); osg_texcoords->push_back(osg::Vec2(0.5f - 0.5f * n.imag(), 0.5f + 0.5f * n.real())); osg_vertices->push_back(osg::Vec3(-e.imag(), bottomY, e.real())); } - + // do last point by hand to ensure no round off errors. - + osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); osg_texcoords->push_back(osg::Vec2(0.5f, 0.0f)); osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius)); - + bottom->setCount(osg_vertices->size() - first); osg_geom->addPrimitiveSet(bottom.get()); } - + osg_geom->setVertexArray(osg_vertices.get()); osg_geom->setTexCoordArray(0, osg_texcoords.get()); osg_geom->setNormalArray(osg_normals.get()); @@ -291,13 +287,13 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Cone(openvrml::vrml9 return osg_geom.get(); } -osg::ref_ptr ReaderWriterVRML2::convertVRML97Cylinder(openvrml::vrml97_node::cylinder_node* vrml_cylinder) const -{ - float height = static_cast(vrml_cylinder->field("height")).value; - float radius = static_cast(vrml_cylinder->field("radius")).value; - bool bottom = static_cast(vrml_cylinder->field("bottom")).value; - bool side = static_cast(vrml_cylinder->field("side")).value; - bool top = static_cast(vrml_cylinder->field("top")).value; +osg::ref_ptr ReaderWriterVRML2::convertVRML97Cylinder(openvrml::node* vrml_cylinder) const +{ + float height = static_cast(vrml_cylinder->field("height").get())->value(); + float radius = static_cast(vrml_cylinder->field("radius").get())->value(); + bool bottom = static_cast(vrml_cylinder->field("bottom").get())->value(); + bool side = static_cast(vrml_cylinder->field("side").get())->value(); + bool top = static_cast(vrml_cylinder->field("top").get())->value(); QuadricKey key(height, radius, bottom, side, top); @@ -307,85 +303,84 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Cylinder(openvrml::v return (*it).second.get(); } - osg::ref_ptr osg_geom = new osg::Geometry(); + osg::ref_ptr osg_geom = new osg::Geometry(); osg::ref_ptr osg_vertices = new osg::Vec3Array(); - osg::ref_ptr osg_texcoords = new osg::Vec2Array(); + osg::ref_ptr osg_texcoords = new osg::Vec2Array(); osg::ref_ptr osg_normals = new osg::Vec3Array(); unsigned int numSegments = 40; const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments); - - + float topY = height * 0.5f; - float bottomY = height * -0.5f; + float bottomY = height * -0.5f; if (side) { osg::ref_ptr side = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP); - + const float texCoordDelta = 1.0f / float(numSegments); float theta = 0.0f; float texCoord = 0.0f; - + for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta, texCoord += texCoordDelta) { std::complex n = -std::polar(1.0f, theta); - std::complex e = n * radius; - + std::complex e = n * radius; + osg::Vec3 normal(n.imag(), 0.0f, n.real()); - + osg_normals->push_back(normal); osg_normals->push_back(normal); - + osg_texcoords->push_back(osg::Vec2(texCoord, 1.0f)); osg_texcoords->push_back(osg::Vec2(texCoord, 0.0f)); - + osg_vertices->push_back(osg::Vec3(e.imag(), topY, e.real())); osg_vertices->push_back(osg::Vec3(e.imag(), bottomY, e.real())); } - + // do last point by hand to ensure no round off errors. osg::Vec3 normal(0.0f, 0.0f, -1.0f); - osg_normals->push_back(normal); osg_normals->push_back(normal); - + osg_normals->push_back(normal); + osg_texcoords->push_back(osg::Vec2(1.0f, 1.0f)); osg_texcoords->push_back(osg::Vec2(1.0f, 0.0f)); - + osg_vertices->push_back(osg::Vec3(0.0f, topY, -radius)); osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius)); side->setCount(osg_vertices->size()); osg_geom->addPrimitiveSet(side.get()); } - + if (bottom) { osg::ref_ptr bottom = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN); - + size_t first = osg_vertices->size(); bottom->setFirst(first); float theta = 0.0f; - + for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta) { std::complex n = -std::polar(1.0f, theta); - std::complex e = n * radius; - + std::complex e = n * radius; + osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); osg_texcoords->push_back(osg::Vec2(0.5f - 0.5f * n.imag(), 0.5f + 0.5f * n.real())); osg_vertices->push_back(osg::Vec3(-e.imag(), bottomY, e.real())); } - + // do last point by hand to ensure no round off errors. - + osg_normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f)); osg_texcoords->push_back(osg::Vec2(0.5f, 0.0f)); osg_vertices->push_back(osg::Vec3(0.0f, bottomY, -radius)); - + bottom->setCount(osg_vertices->size() - first); osg_geom->addPrimitiveSet(bottom.get()); } @@ -393,32 +388,32 @@ osg::ref_ptr ReaderWriterVRML2::convertVRML97Cylinder(openvrml::v if (top) { osg::ref_ptr top = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN); - + size_t first = osg_vertices->size(); top->setFirst(first); float theta = 0.0f; - + for (unsigned int i = 0; i < numSegments; ++i, theta += thetaDelta) { std::complex n = -std::polar(1.0f, theta); - std::complex e = n * radius; - + std::complex e = n * radius; + osg_normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); osg_texcoords->push_back(osg::Vec2(0.5f + 0.5f * n.imag(), 0.5f - 0.5f * n.real())); osg_vertices->push_back(osg::Vec3(e.imag(), topY, e.real())); } - + // do last point by hand to ensure no round off errors. - + osg_normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f)); osg_texcoords->push_back(osg::Vec2(0.5f, 1.0f)); osg_vertices->push_back(osg::Vec3(0.0f, topY, -radius)); - + top->setCount(osg_vertices->size() - first); osg_geom->addPrimitiveSet(top.get()); } - + osg_geom->setVertexArray(osg_vertices.get()); osg_geom->setTexCoordArray(0, osg_texcoords.get()); osg_geom->setNormalArray(osg_normals.get()); diff --git a/src/osgPlugins/vrml/README.txt b/src/osgPlugins/vrml/README.txt index 7e6481695..078b5666c 100644 --- a/src/osgPlugins/vrml/README.txt +++ b/src/osgPlugins/vrml/README.txt @@ -5,8 +5,10 @@ - dependencies: OpenVRML (http://openvrml.org/) + Boost (http://www.boost.org/) OpenSceneGraph (http://www.openscenegraph.org/) CAUTION! -This version of the plugin requires OpenVRML 0.14.3. Version 0.16.2 *WILL NOT* work! +This version of the plugin requires OpenVRML 0.17.12 and Boost 1.38. +Older version *may* work, but were not tested! diff --git a/src/osgPlugins/vrml/ReaderWriterVRML2.cpp b/src/osgPlugins/vrml/ReaderWriterVRML2.cpp index bffd75928..a839fe46e 100644 --- a/src/osgPlugins/vrml/ReaderWriterVRML2.cpp +++ b/src/osgPlugins/vrml/ReaderWriterVRML2.cpp @@ -4,14 +4,15 @@ * * VRML2 file converter for OpenSceneGraph. * - * authors : Jan Ciger (jan.ciger@gmail.com), - * Tolga Abaci (tolga.abaci@gmail.com), + * authors : Jan Ciger (jan.ciger@gmail.com), + * Tolga Abaci (tolga.abaci@gmail.com), * Bruno Herbelin (bruno.herbelin@gmail.com) - * + * * (c) VRlab EPFL, Switzerland, 2004-2006 * - * Gino van den Bergen, DTECTA (gino@dtecta.com) - * + * Gino van den Bergen, DTECTA (gino@dtecta.com) + * Xiangxian Wang (xiangxianwang@yahoo.com.cn) + * */ #include "ReaderWriterVRML2.h" @@ -19,18 +20,18 @@ #include #include +#include +#include + #if defined(_MSC_VER) -# pragma warning(disable: 4250) -# pragma warning(disable: 4290) -# pragma warning(disable: 4800) -#endif +# pragma warning(disable: 4250) +# pragma warning(disable: 4290) +# pragma warning(disable: 4800) +#endif #include -#include #include #include -#include -#include #include #include @@ -55,6 +56,116 @@ #include #include +// ------------------------------------------------------------------------------------- +// OpenVRML helper class +// ------------------------------------------------------------------------------------- +class resource_fetcher: public openvrml::resource_fetcher +{ + private: + virtual std::auto_ptr do_get_resource(const std::string & uri) + { + using std::auto_ptr; + using std::invalid_argument; + using std::string; + using openvrml::resource_istream; + + class file_resource_istream: public resource_istream + { + std::string url_; + std::filebuf buf_; + + public: + explicit file_resource_istream(const std::string & path) : + resource_istream(&this->buf_) + { + // + // Note that the failbit is set in the constructor if no data + // can be read from the stream. This is important. If the + // failbit is not set on such a stream, OpenVRML will attempt + // to read data from a stream that cannot provide it. + // + if (!this->buf_.open(path.c_str(), ios_base::in | ios_base::binary)) + { + this->setstate(ios_base::badbit); + } + } + + void url(const std::string & str) throw (std::bad_alloc) + { + this->url_ = str; + } + + private: + virtual const std::string do_url() const throw () + { + return this->url_; + } + + virtual const std::string do_type() const throw () + { + // + // A real application should use OS facilities for this; + // however, that is beyond the scope of this example (which + // is intended to be portable and stupid). + // + using std::find; + using std::string; + using boost::algorithm::iequals; + using boost::next; + string media_type = "application/octet-stream"; + + const string::const_reverse_iterator dot_pos = find(this->url_.rbegin(), this->url_.rend(), '.'); + if (dot_pos == this->url_.rend() || next(dot_pos.base()) == this->url_.end()) + { + return media_type; + } + + const string::const_iterator hash_pos = find(next(dot_pos.base()), this->url_.end(), '#'); + const string ext(dot_pos.base(), hash_pos); + + if (iequals(ext, "wrl") || iequals(ext, "vrml")) + { + media_type = "model/vrml"; + } + else if (iequals(ext, "png")) + { + media_type = "image/png"; + } + else if (iequals(ext, "jpg") || iequals(ext, "jpeg")) + { + media_type = "image/jpeg"; + } + return media_type; + } + + virtual bool do_data_available() const throw () + { + return !!(*this); + } + }; + + const string scheme = uri.substr(0, uri.find_first_of(':')); + if (scheme != "file") + { + throw invalid_argument('\"' + scheme + "\" URI scheme not " + "supported"); + } + // + // file:// + // ^ + // 01234567 + // + string path = uri.substr(uri.find_first_of('/', 7)); + + auto_ptr in(new file_resource_istream(path)); + static_cast (in.get())->url(uri); + + return in; + } +}; + +// ------------------------------------------------------------------------------------- + // Register with Registry to instantiate the above reader/writer. REGISTER_OSGPLUGIN(vrml, ReaderWriterVRML2) @@ -62,7 +173,8 @@ REGISTER_OSGPLUGIN(vrml, ReaderWriterVRML2) osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string &fname, const Options* opt) const { std::string fileName = osgDB::findDataFile(fname, opt); - if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + if (fileName.empty()) + return ReadResult::FILE_NOT_FOUND; // convert possible Windows backslashes to Unix slashes // OpenVRML doesn't like backslashes, even on Windows @@ -70,72 +182,78 @@ osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string &f #ifdef WIN32 if(unixFileName[1] == ':') // absolute path - fileName = "file:///" + unixFileName; + fileName = "file:///" + unixFileName; #else - if(unixFileName[0] == '/') // absolute path + if (unixFileName[0] == '/') // absolute path fileName = "file://" + unixFileName; #endif - else // relative path + else + // relative path fileName = unixFileName; - - std::fstream null; - openvrml::browser *browser = new openvrml::browser(null, null); + resource_fetcher fetcher; + openvrml::browser *b = new openvrml::browser(fetcher, null, null); - std::vector parameter; - std::vector vuri; - vuri.push_back(fileName); - browser->load_url(vuri, parameter); + std::ifstream vrml_stream(fileName.c_str()); - std::vector< openvrml::node_ptr > mfn; - mfn = browser->root_nodes(); + try + { + const std::vector< boost::intrusive_ptr< openvrml::node > > & mfn = b->create_vrml_from_stream(vrml_stream); - if (mfn.size() == 0) { - return ReadResult::FILE_NOT_HANDLED; + if(mfn.empty()) + return ReadResult::FILE_NOT_HANDLED; + else + { + osg::ref_ptr osg_root = new osg::MatrixTransform(osg::Matrix( 1, 0, 0, 0, + 0, 0, 1, 0, + 0, -1, 0, 0, + 0, 0, 0, 1)); - } else { - osg::ref_ptr osg_root = - new osg::MatrixTransform(osg::Matrix( 1, 0, 0, 0, - 0, 0, 1, 0, - 0, -1, 0, 0, - 0, 0, 0, 1)); - osgDB::getDataFilePathList().push_front(osgDB::getFilePath(unixFileName)); - for (unsigned i = 0; i < mfn.size(); i++) { - openvrml::node *vrml_node = mfn[i].get(); - osg_root->addChild(convertFromVRML(vrml_node).get()); + osgDB::getDataFilePathList().push_front(osgDB::getFilePath(unixFileName)); + for (unsigned i = 0; i < mfn.size(); i++) + { + openvrml::node *vrml_node = mfn[i].get(); + osg_root->addChild(convertFromVRML(vrml_node).get()); + } + osgDB::getDataFilePathList().pop_front(); + return osg_root.get(); } - osgDB::getDataFilePathList().pop_front(); - return osg_root.get(); } + + catch (openvrml::invalid_vrml) { return ReadResult::FILE_NOT_HANDLED; } + catch (std::invalid_argument) { return ReadResult::FILE_NOT_HANDLED; } } osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const { - std::string name = obj->id(); - static int osgLightNum = 0; //light + //static int osgLightNum = 0; //light - // std::cout << obj->type.id << " Node " << " ["<< name <<']' << std::endl; + if (obj->type().id() == "Group") // Group node - if (obj->type.id == "Group") // Group node { - openvrml::vrml97_node::group_node *vrml_group; - vrml_group = dynamic_cast(obj); + openvrml::grouping_node *vrml_group; + vrml_group = dynamic_cast(obj); osg::ref_ptr osg_group = new osg::Group; try { - const openvrml::field_value &fv = obj->field("children"); + std::auto_ptr fv = obj->field("children"); - if ( fv.type() == openvrml::field_value::mfnode_id ) { - const openvrml::mfnode &mfn = dynamic_cast(fv); - for (unsigned i = 0; i < mfn.value.size(); i++) { - openvrml::node *node = mfn.value[i].get(); - osg_group->addChild(convertFromVRML(node).get()); + if ( fv->type() == openvrml::field_value::mfnode_id ) + { + const openvrml::mfnode* mfn = dynamic_cast(fv.get()); + openvrml::mfnode::value_type node_ptr_vector = mfn->value(); + openvrml::mfnode::value_type::iterator it_npv; + + for (it_npv = node_ptr_vector.begin(); it_npv != node_ptr_vector.end(); it_npv++) + { + openvrml::node *node = (*(it_npv)).get(); + osg_group->addChild(convertFromVRML(node)); } } - } + } catch (openvrml::unsupported_interface&) { // no children @@ -143,27 +261,34 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) return osg_group.get(); - } - else if (obj->type.id == "Transform") // Handle transforms + } + + else if (obj->type().id() == "Transform") // Handle transforms + { - openvrml::vrml97_node::transform_node *vrml_transform; - vrml_transform = dynamic_cast(obj); + openvrml::transform_node *vrml_transform; + vrml_transform = dynamic_cast(obj); openvrml::mat4f vrml_m = vrml_transform->transform(); osg::ref_ptr osg_m = new osg::MatrixTransform(osg::Matrix(vrml_m[0][0], vrml_m[0][1], vrml_m[0][2], vrml_m[0][3], vrml_m[1][0], vrml_m[1][1], vrml_m[1][2], vrml_m[1][3], vrml_m[2][0], vrml_m[2][1], vrml_m[2][2], vrml_m[2][3], vrml_m[3][0], vrml_m[3][1], vrml_m[3][2], vrml_m[3][3])); try { - const openvrml::field_value &fv = obj->field("children"); + std::auto_ptr fv = obj->field("children"); - if ( fv.type() == openvrml::field_value::mfnode_id ) { - const openvrml::mfnode &mfn = dynamic_cast(fv); - for (unsigned i = 0; i < mfn.value.size(); i++) { - openvrml::node *node = mfn.value[i].get(); + if ( fv->type() == openvrml::field_value::mfnode_id ) + { + const openvrml::mfnode* mfn = dynamic_cast(fv.get()); + openvrml::mfnode::value_type node_ptr_vector = mfn->value(); + openvrml::mfnode::value_type::iterator it_npv; + + for (it_npv = node_ptr_vector.begin(); it_npv != node_ptr_vector.end(); it_npv++) + { + openvrml::node *node = (*(it_npv)).get(); osg_m->addChild(convertFromVRML(node).get()); } } - } + } catch (openvrml::unsupported_interface&) { // no children @@ -171,44 +296,39 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) return osg_m.get(); - } - else if (obj->type.id == "Shape") // Handle Shape node + } + + else if ((obj->type()).id() == "Shape") // Handle Shape node + { osg::ref_ptr osg_geom; // parse the geometry { - const openvrml::field_value &fv = obj->field("geometry"); + std::auto_ptr fv = obj->field("geometry"); - if (fv.type() == openvrml::field_value::sfnode_id) + if (fv->type() == openvrml::field_value::sfnode_id) { - const openvrml::sfnode &sfn = dynamic_cast(fv); + const openvrml::sfnode * sfn = dynamic_cast(fv.get()); + openvrml::sfnode::value_type node_ptr = sfn->value(); + // is it indexed_face_set_node ? - - openvrml::vrml97_node::abstract_geometry_node* vrml_geom = - static_cast(sfn.value.get()->to_geometry()); - - if (openvrml::vrml97_node::indexed_face_set_node *vrml_ifs = dynamic_cast(vrml_geom)) - { - osg_geom = convertVRML97IndexedFaceSet(vrml_ifs); - } - else if (openvrml::vrml97_node::box_node* vrml_box = dynamic_cast(vrml_geom)) - { - osg_geom = convertVRML97Box(vrml_box); - } - else if (openvrml::vrml97_node::sphere_node* vrml_sphere = dynamic_cast(vrml_geom)) - { - osg_geom = convertVRML97Sphere(vrml_sphere); - } - else if (openvrml::vrml97_node::cone_node* vrml_cone = dynamic_cast(vrml_geom)) - { - osg_geom = convertVRML97Cone(vrml_cone); - } - else if (openvrml::vrml97_node::cylinder_node* vrml_cylinder = dynamic_cast(vrml_geom)) - { - osg_geom = convertVRML97Cylinder(vrml_cylinder); - } - else + if (node_ptr->type().id()=="IndexedFaceSet") + osg_geom = convertVRML97IndexedFaceSet(node_ptr.get()); + + else if (node_ptr->type().id() == "Box") + osg_geom = convertVRML97Box(node_ptr.get()); + + else if (node_ptr->type().id() == "Sphere") + osg_geom = convertVRML97Sphere(node_ptr.get()); + + else if (node_ptr->type().id() == "Cone") + osg_geom = convertVRML97Cone(node_ptr.get()); + + else if (node_ptr->type().id() == "Cylinder") + osg_geom = convertVRML97Cylinder(node_ptr.get()); + + else { // other geometry types not handled yet } @@ -223,60 +343,54 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) osg_stateset->setAttributeAndModes(osg_mat.get()); osg_mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); - // parse the appearance { - const openvrml::field_value &fv = obj->field("appearance"); + std::auto_ptr fv = obj->field("appearance"); - if (fv.type() == openvrml::field_value::sfnode_id) + if (fv->type() == openvrml::field_value::sfnode_id) { - const openvrml::sfnode &sfn = dynamic_cast(fv); - // std::cerr << "FV->sfnode OK" << std::endl << std::flush; + const openvrml::sfnode *sfn = dynamic_cast(fv.get()); + openvrml::appearance_node *vrml_app = dynamic_cast(sfn->value().get()); - openvrml::vrml97_node::appearance_node* vrml_app = static_cast(sfn.value.get()->to_appearance()); + const boost::intrusive_ptr vrml_material_node = vrml_app->material(); + const boost::intrusive_ptr vrml_texture_node = vrml_app->texture(); + const openvrml::material_node *vrml_material = dynamic_cast(vrml_material_node.get()); - const openvrml::node_ptr &vrml_material_node = vrml_app->material(); - const openvrml::node_ptr &vrml_texture_node = vrml_app->texture(); - - const openvrml::vrml97_node::material_node *vrml_material = - dynamic_cast(vrml_material_node.get()); - // std::cerr << "sfnode->Material OK" << std::endl << std::flush; - - if (vrml_material != NULL) + if (vrml_material != NULL) { - osg_mat->setAmbient(osg::Material::FRONT_AND_BACK, - osg::Vec4(vrml_material->ambient_intensity(), - vrml_material->ambient_intensity(), - vrml_material->ambient_intensity(), - 1.0)); - osg_mat->setDiffuse(osg::Material::FRONT_AND_BACK, - osg::Vec4(vrml_material->diffuse_color().r(), - vrml_material->diffuse_color().g(), - vrml_material->diffuse_color().b(), - 1.0)); - osg_mat->setEmission(osg::Material::FRONT_AND_BACK, - osg::Vec4(vrml_material->emissive_color().r(), - vrml_material->emissive_color().g(), - vrml_material->emissive_color().b(), - 1.0)); - osg_mat->setSpecular(osg::Material::FRONT_AND_BACK, - osg::Vec4(vrml_material->specular_color().r(), - vrml_material->specular_color().g(), - vrml_material->specular_color().b(), - 1.0)); + osg_mat->setAmbient(osg::Material::FRONT_AND_BACK, + osg::Vec4(vrml_material->ambient_intensity(), + vrml_material->ambient_intensity(), + vrml_material->ambient_intensity(), + 1.0)); + osg_mat->setDiffuse(osg::Material::FRONT_AND_BACK, + osg::Vec4(vrml_material->diffuse_color().r(), + vrml_material->diffuse_color().g(), + vrml_material->diffuse_color().b(), + 1.0)); + osg_mat->setEmission(osg::Material::FRONT_AND_BACK, + osg::Vec4(vrml_material->emissive_color().r(), + vrml_material->emissive_color().g(), + vrml_material->emissive_color().b(), + 1.0)); + osg_mat->setSpecular(osg::Material::FRONT_AND_BACK, + osg::Vec4(vrml_material->specular_color().r(), + vrml_material->specular_color().g(), + vrml_material->specular_color().b(), + 1.0)); osg_mat->setShininess(osg::Material::FRONT_AND_BACK, vrml_material->shininess() ); if (vrml_material->transparency() > 0.0f) { osg_mat->setTransparency(osg::Material::FRONT_AND_BACK, vrml_material->transparency()); - osg_stateset->setMode(GL_BLEND, osg::StateAttribute::ON); + osg_stateset->setMode(GL_BLEND, osg::StateAttribute::ON); osg_stateset->setAttribute(new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false)); // GvdB: transparent objects do not write depth osg_stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } else { - osg_stateset->setMode(GL_BLEND, osg::StateAttribute::OFF); + osg_stateset->setMode(GL_BLEND, osg::StateAttribute::OFF); osg_stateset->setRenderingHint(osg::StateSet::OPAQUE_BIN); } @@ -284,21 +398,17 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) } - const openvrml::vrml97_node::image_texture_node *vrml_texture = - dynamic_cast(vrml_texture_node.get()); - // std::cerr << "TextureNode -> ImageTexture OK" << std::endl << std::flush; - // if texture is provided - if (vrml_texture != 0) { - const openvrml::field_value &texture_url_fv = vrml_texture->field("url"); - const openvrml::mfstring &mfs = dynamic_cast(texture_url_fv); - // std::cerr << "Texture URL FV -> mfstring OK" << std::endl << std::flush; - - const std::string &url = mfs.value[0]; + if (vrml_texture_node != 0) + { + std::auto_ptr texture_url_fv = vrml_texture_node->field("url"); + const openvrml::mfstring *mfs = dynamic_cast(texture_url_fv.get()); + const std::string &url = mfs->value()[0]; osg::ref_ptr image = osgDB::readRefImageFile(url); - if (image != 0) { + if (image != 0) + { osg::ref_ptr texture = new osg::Texture2D; texture->setImage(image.get()); @@ -308,34 +418,39 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); // get the real texture wrapping parameters (if any) + try + { + std::auto_ptr wrap_fv = vrml_texture_node->field("repeatS"); + const openvrml::sfbool *sfb = dynamic_cast(wrap_fv.get()); - try { - const openvrml::field_value &wrap_fv = vrml_texture->field("repeatS"); - const openvrml::sfbool &sfb = dynamic_cast(wrap_fv); - - if (!sfb.value) { + if (!sfb->value()) texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); - } - } catch (...) { + + } + catch (...) + { // nothing specified } - try { - const openvrml::field_value &wrap_fv = vrml_texture->field("repeatT"); - const openvrml::sfbool &sfb = dynamic_cast(wrap_fv); + try + { + std::auto_ptr wrap_fv = vrml_texture_node->field("repeatT"); + const openvrml::sfbool *sfb = dynamic_cast(wrap_fv.get()); - if (!sfb.value) { + if (!sfb->value()) texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); - } - } catch (...) { + } + catch (...) + { // nothing specified } osg_stateset->setTextureAttributeAndModes(0, texture.get()); //osg_stateset->setMode(GL_BLEND,osg::StateAttribute::ON); //bhbn - } - else { + } + else + { std::cerr << "texture file " << url << " not found !" << std::endl << std::flush; } } @@ -343,135 +458,137 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) } return osg_geode.get(); - } - else + } + else { return 0; } - +#if 0 /* - } else if(obj->type.id == "DirectionalLight") // Handle lights - { - osg::Group* lightGroup = new osg::Group; + } else if(obj->type.id == "DirectionalLight") // Handle lights + { + osg::Group* lightGroup = new osg::Group; - openvrml::vrml97_node::directional_light_node *vrml_light; - vrml_light = dynamic_cast(obj); + openvrml::vrml97_node::directional_light_node *vrml_light; + vrml_light = dynamic_cast(obj); - // create light with global params - osg::Light* myLight = new osg::Light; - myLight->setLightNum(osgLightNum); - myLight->setAmbient(osg::Vec4(vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity())); - float osgR = vrml_light->color().r()*vrml_light->intensity(); - float osgG = vrml_light->color().g()*vrml_light->intensity(); - float osgB = vrml_light->color().b()*vrml_light->intensity(); - myLight->setDiffuse(osg::Vec4(osgR, osgG, osgB, 1.0f)); - myLight->setSpecular(osg::Vec4(osgR, osgG, osgB, 1.0f)); - - // configure light as DIRECTIONAL - openvrml::sfvec3f &dir = vrml_light->direction_; - myLight->setDirection(osg::Vec3(dir.value[0],dir.value[1],dir.value[2])); - myLight->setPosition(osg::Vec4(dir.value[0],dir.value[1],dir.value[2], 0.0f)); - - // add the light in the scenegraph - osg::LightSource* lightS = new osg::LightSource; - lightS->setLight(myLight); - if (vrml_light->on()) { - lightS->setLocalStateSetModes(osg::StateAttribute::ON); - //lightS->setStateSetModes(*rootStateSet,osg::StateAttribute::ON); - } - - lightGroup->addChild(lightS); - osgLightNum++; + // create light with global params + osg::Light* myLight = new osg::Light; + myLight->setLightNum(osgLightNum); + myLight->setAmbient(osg::Vec4(vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity())); + float osgR = vrml_light->color().r()*vrml_light->intensity(); + float osgG = vrml_light->color().g()*vrml_light->intensity(); + float osgB = vrml_light->color().b()*vrml_light->intensity(); + myLight->setDiffuse(osg::Vec4(osgR, osgG, osgB, 1.0f)); + myLight->setSpecular(osg::Vec4(osgR, osgG, osgB, 1.0f)); - return lightGroup; + // configure light as DIRECTIONAL + openvrml::sfvec3f &dir = vrml_light->direction_; + myLight->setDirection(osg::Vec3(dir.value[0],dir.value[1],dir.value[2])); + myLight->setPosition(osg::Vec4(dir.value[0],dir.value[1],dir.value[2], 0.0f)); - } else if(obj->type.id == "PointLight") // Handle lights - { - osg::Group* lightGroup = new osg::Group; + // add the light in the scenegraph + osg::LightSource* lightS = new osg::LightSource; + lightS->setLight(myLight); + if (vrml_light->on()) { + lightS->setLocalStateSetModes(osg::StateAttribute::ON); + //lightS->setStateSetModes(*rootStateSet,osg::StateAttribute::ON); + } - openvrml::vrml97_node::point_light_node *vrml_light; - vrml_light = dynamic_cast(obj); + lightGroup->addChild(lightS); + osgLightNum++; - // create light with global params - osg::Light* myLight = new osg::Light; - myLight->setLightNum(osgLightNum); - //std::cout<<"lightnum = "<location_; - myLight->setPosition(osg::Vec4(pos.value[0], pos.value[1], pos.value[2], 1.0f)); - - myLight->setAmbient(osg::Vec4(vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity())); - float osgR = vrml_light->color().r()*vrml_light->intensity(); - float osgG = vrml_light->color().g()*vrml_light->intensity(); - float osgB = vrml_light->color().b()*vrml_light->intensity(); - myLight->setDiffuse(osg::Vec4(osgR, osgG, osgB, 1.0f)); - myLight->setSpecular(osg::Vec4(osgR, osgG, osgB, 1.0f)); - - // configure light as POINT - myLight->setDirection(osg::Vec3(0.f,0.f,0.f)); - - // add the light in the scenegraph - osg::LightSource* lightS = new osg::LightSource; - lightS->setLight(myLight); - if (vrml_light->on()) { - lightS->setLocalStateSetModes(osg::StateAttribute::ON); - //lightS->setStateSetModes(*rootStateSet,osg::StateAttribute::ON); - } - - lightGroup->addChild(lightS); - osgLightNum++; + return lightGroup; - return lightGroup; + } else if(obj->type.id == "PointLight") // Handle lights + { + osg::Group* lightGroup = new osg::Group; - } else if(obj->type.id == "SpotLight") // Handle lights - { - osg::Group* lightGroup = new osg::Group; + openvrml::vrml97_node::point_light_node *vrml_light; + vrml_light = dynamic_cast(obj); - openvrml::vrml97_node::spot_light_node *vrml_light; - vrml_light = dynamic_cast(obj); + // create light with global params + osg::Light* myLight = new osg::Light; + myLight->setLightNum(osgLightNum); + //std::cout<<"lightnum = "<setLightNum(osgLightNum); - myLight->setPosition(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); - myLight->setAmbient(osg::Vec4(vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity())); - float osgR = vrml_light->color().r()*vrml_light->intensity(); - float osgG = vrml_light->color().g()*vrml_light->intensity(); - float osgB = vrml_light->color().b()*vrml_light->intensity(); - myLight->setDiffuse(osg::Vec4(osgR, osgG, osgB, 1.0f)); - myLight->setSpecular(osg::Vec4(osgR, osgG, osgB, 1.0f)); - - // configure light as SPOT - openvrml::sfvec3f &dir = vrml_light->direction_; - myLight->setDirection(osg::Vec3(dir.value[0],dir.value[1],dir.value[2])); - - // The cutOff value in osg ranges from 0 to 90, we need - // to divide by 2 to avoid openGL error. - // myLight->setSpotCutoff(ls.fallsize/2.0f); - // The bigger the differens is between fallsize and hotsize - // the bigger the exponent should be. - // float diff = ls.fallsize - ls.hotsize; - // myLight->setSpotExponent(diff); - - // add the light in the scenegraph - osg::LightSource* lightS = new osg::LightSource; - lightS->setLight(myLight); - if (vrml_light->on()) { - lightS->setLocalStateSetModes(osg::StateAttribute::ON); - //lightS->setStateSetModes(*rootStateSet,osg::StateAttribute::ON); - } - - lightGroup->addChild(lightS); - osgLightNum++; + openvrml::sfvec3f &pos = vrml_light->location_; + myLight->setPosition(osg::Vec4(pos.value[0], pos.value[1], pos.value[2], 1.0f)); - return lightGroup; + myLight->setAmbient(osg::Vec4(vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity())); + float osgR = vrml_light->color().r()*vrml_light->intensity(); + float osgG = vrml_light->color().g()*vrml_light->intensity(); + float osgB = vrml_light->color().b()*vrml_light->intensity(); + myLight->setDiffuse(osg::Vec4(osgR, osgG, osgB, 1.0f)); + myLight->setSpecular(osg::Vec4(osgR, osgG, osgB, 1.0f)); - } else { + // configure light as POINT + myLight->setDirection(osg::Vec3(0.f,0.f,0.f)); - return NULL; - } - */ + // add the light in the scenegraph + osg::LightSource* lightS = new osg::LightSource; + lightS->setLight(myLight); + if (vrml_light->on()) { + lightS->setLocalStateSetModes(osg::StateAttribute::ON); + //lightS->setStateSetModes(*rootStateSet,osg::StateAttribute::ON); + } + + lightGroup->addChild(lightS); + osgLightNum++; + + return lightGroup; + + } else if(obj->type.id == "SpotLight") // Handle lights + { + osg::Group* lightGroup = new osg::Group; + + openvrml::vrml97_node::spot_light_node *vrml_light; + vrml_light = dynamic_cast(obj); + + // create light with global params + osg::Light* myLight = new osg::Light; + myLight->setLightNum(osgLightNum); + myLight->setPosition(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); + myLight->setAmbient(osg::Vec4(vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity(),vrml_light->ambient_intensity())); + float osgR = vrml_light->color().r()*vrml_light->intensity(); + float osgG = vrml_light->color().g()*vrml_light->intensity(); + float osgB = vrml_light->color().b()*vrml_light->intensity(); + myLight->setDiffuse(osg::Vec4(osgR, osgG, osgB, 1.0f)); + myLight->setSpecular(osg::Vec4(osgR, osgG, osgB, 1.0f)); + + // configure light as SPOT + openvrml::sfvec3f &dir = vrml_light->direction_; + myLight->setDirection(osg::Vec3(dir.value[0],dir.value[1],dir.value[2])); + + // The cutOff value in osg ranges from 0 to 90, we need + // to divide by 2 to avoid openGL error. + // myLight->setSpotCutoff(ls.fallsize/2.0f); + // The bigger the differens is between fallsize and hotsize + // the bigger the exponent should be. + // float diff = ls.fallsize - ls.hotsize; + // myLight->setSpotExponent(diff); + + // add the light in the scenegraph + osg::LightSource* lightS = new osg::LightSource; + lightS->setLight(myLight); + if (vrml_light->on()) { + lightS->setLocalStateSetModes(osg::StateAttribute::ON); + //lightS->setStateSetModes(*rootStateSet,osg::StateAttribute::ON); + } + + lightGroup->addChild(lightS); + osgLightNum++; + + return lightGroup; + + } else { + + return NULL; + } + */ + +#endif + + return 0; } - - diff --git a/src/osgPlugins/vrml/ReaderWriterVRML2.h b/src/osgPlugins/vrml/ReaderWriterVRML2.h index 9f006b5b3..615530ad6 100644 --- a/src/osgPlugins/vrml/ReaderWriterVRML2.h +++ b/src/osgPlugins/vrml/ReaderWriterVRML2.h @@ -4,14 +4,15 @@ * * VRML2 file converter for OpenSceneGraph. * - * authors : Jan Ciger (jan.ciger@gmail.com), - * Tolga Abaci (tolga.abaci@gmail.com), + * authors : Jan Ciger (jan.ciger@gmail.com), + * Tolga Abaci (tolga.abaci@gmail.com), * Bruno Herbelin (bruno.herbelin@gmail.com) - * + * * (c) VRlab EPFL, Switzerland, 2004-2006 * - * Gino van den Bergen, DTECTA (gino@dtecta.com) - * + * Gino van den Bergen, DTECTA (gino@dtecta.com) + * Xiangxian Wang (xiangxianwang@yahoo.com.cn) + * */ #include @@ -25,18 +26,10 @@ #include #include + namespace openvrml { class node; - - namespace vrml97_node - { - class indexed_face_set_node; - class box_node; - class sphere_node; - class cone_node; - class cylinder_node; - } } class QuadricKey @@ -51,7 +44,7 @@ public: bool operator<(const QuadricKey& rhs) const { return m_height < rhs.m_height || - (m_height == rhs.m_height && (m_radius < rhs.m_radius || + (m_height == rhs.m_height && (m_radius < rhs.m_radius || (m_radius == rhs.m_radius && m_flags < rhs.m_flags))); } @@ -67,11 +60,11 @@ private: /** * OpenSceneGraph plugin wrapper/converter. */ -class ReaderWriterVRML2 +class ReaderWriterVRML2 : public osgDB::ReaderWriter { public: - ReaderWriterVRML2() + ReaderWriterVRML2() { supportsExtension("wrl","VRML format"); } @@ -92,12 +85,13 @@ private: osg::ref_ptr convertFromVRML(openvrml::node *obj) const; - osg::ref_ptr convertVRML97IndexedFaceSet(openvrml::vrml97_node::indexed_face_set_node *vrml_ifs) const; - osg::ref_ptr convertVRML97Box(openvrml::vrml97_node::box_node* vrml_box) const; - osg::ref_ptr convertVRML97Sphere(openvrml::vrml97_node::sphere_node* vrml_sphere) const; - osg::ref_ptr convertVRML97Cone(openvrml::vrml97_node::cone_node* vrml_cone) const; - osg::ref_ptr convertVRML97Cylinder(openvrml::vrml97_node::cylinder_node* vrml_cylinder) const; - + + osg::ref_ptr convertVRML97IndexedFaceSet(openvrml::node *vrml_ifs) const; + osg::ref_ptr convertVRML97Box(openvrml::node* vrml_box) const; + osg::ref_ptr convertVRML97Sphere(openvrml::node* vrml_sphere) const; + osg::ref_ptr convertVRML97Cone(openvrml::node* vrml_cone) const; + osg::ref_ptr convertVRML97Cylinder(openvrml::node* vrml_cylinder) const; + mutable BoxLibrary m_boxLibrary; mutable SphereLibrary m_sphereLibrary; mutable ConeLibrary m_coneLibrary;