From Jan Ciger, "I am attaching the updated VRML plugin, as promised. This version works

with OpenVRML 0.17.12 and Boost 1.38. Other versions may work too, but I
didn't test that."
This commit is contained in:
Robert Osfield 2009-05-26 14:22:56 +00:00
parent e24dad3b71
commit 885a7893b8
6 changed files with 654 additions and 545 deletions

View File

@ -10,7 +10,7 @@
# Created by Robert Osfield. # Created by Robert Osfield.
# Modified for the debug library by Jean-Sébastien Guay. # 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}/include
$ENV{OPENVRML_DIR} $ENV{OPENVRML_DIR}
~/Library/Frameworks ~/Library/Frameworks

View File

@ -10,15 +10,11 @@
#endif #endif
#include <openvrml/vrml97node.h> #include <openvrml/vrml97node.h>
#include <openvrml/common.h>
#include <openvrml/node.h> #include <openvrml/node.h>
#include <openvrml/node_ptr.h>
#include <openvrml/field.h>
#include <osg/CullFace> #include <osg/CullFace>
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openvrml::node *vrml_ifs) const
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openvrml::vrml97_node::indexed_face_set_node *vrml_ifs) const
{ {
osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry(); osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry();
@ -26,12 +22,14 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
osg::StateSet *osg_stateset = osg_geom->getOrCreateStateSet(); osg::StateSet *osg_stateset = osg_geom->getOrCreateStateSet();
// get array of vertex coordinate_nodes // get array of vertex coordinate_nodes
if(vrml_ifs->type().id() == "IndexedFaceSet")
{ {
const openvrml::field_value& fv = vrml_ifs->field("coord"); std::auto_ptr<openvrml::field_value> fv = vrml_ifs->field("coord");
const openvrml::sfnode& sfn = dynamic_cast<const openvrml::sfnode&>(fv); const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
openvrml::vrml97_node::coordinate_node* vrml_coord_node = dynamic_cast<openvrml::vrml97_node::coordinate_node*>(sfn.value.get());
openvrml::coordinate_node *vrml_coord_node = dynamic_cast<openvrml::coordinate_node *>((sfn->value()).get());
const std::vector<openvrml::vec3f> &vrml_coord = vrml_coord_node->point(); const std::vector<openvrml::vec3f> &vrml_coord = vrml_coord_node->point();
osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
unsigned i; unsigned i;
@ -44,15 +42,15 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
osg_geom->setVertexArray(osg_vertices.get()); osg_geom->setVertexArray(osg_vertices.get());
// get array of vertex indices // get array of vertex indices
const openvrml::field_value &fv2 = vrml_ifs->field("coordIndex"); std::auto_ptr<openvrml::field_value> fv2 = vrml_ifs->field("coordIndex");
const openvrml::mfint32 &vrml_coord_index = dynamic_cast<const openvrml::mfint32 &>(fv2); const openvrml::mfint32 *vrml_coord_index = dynamic_cast<const openvrml::mfint32 *>(fv2.get());
osg::ref_ptr<osg::IntArray> osg_vert_index = new osg::IntArray(); osg::ref_ptr<osg::IntArray> osg_vert_index = new osg::IntArray();
int num_vert = 0; 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]; int index = vrml_coord_index->value()[i];
if (index == -1) if (index == -1)
{ {
static_cast<osg::DrawArrayLengths*>(osg_geom->getPrimitiveSet(0))->push_back(num_vert); static_cast<osg::DrawArrayLengths*>(osg_geom->getPrimitiveSet(0))->push_back(num_vert);
@ -64,6 +62,7 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
++num_vert; ++num_vert;
} }
} }
if (num_vert) if (num_vert)
{ {
//GvdB: Last coordIndex wasn't -1 //GvdB: Last coordIndex wasn't -1
@ -75,10 +74,9 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
{ {
// get texture coordinate_nodes // get texture coordinate_nodes
const openvrml::field_value &fv = vrml_ifs->field("texCoord"); std::auto_ptr<openvrml::field_value> fv = vrml_ifs->field("texCoord");
const openvrml::sfnode &sfn = dynamic_cast<const openvrml::sfnode &>(fv); const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
openvrml::vrml97_node::texture_coordinate_node *vrml_tex_coord_node = openvrml::texture_coordinate_node *vrml_tex_coord_node = dynamic_cast<openvrml::texture_coordinate_node *>(sfn->value().get());
dynamic_cast<openvrml::vrml97_node::texture_coordinate_node *>(sfn.value.get());
if (vrml_tex_coord_node != 0) // if no texture, node is NULL pointer if (vrml_tex_coord_node != 0) // if no texture, node is NULL pointer
{ {
@ -95,16 +93,16 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
osg_geom->setTexCoordArray(0, osg_texcoords.get()); osg_geom->setTexCoordArray(0, osg_texcoords.get());
// get array of texture indices // get array of texture indices
const openvrml::field_value &fv2 = vrml_ifs->field("texCoordIndex"); std::auto_ptr<openvrml::field_value> fv2 = vrml_ifs->field("texCoordIndex");
const openvrml::mfint32 &vrml_tex_coord_index = dynamic_cast<const openvrml::mfint32 &>(fv2); const openvrml::mfint32 *vrml_tex_coord_index = dynamic_cast<const openvrml::mfint32 *>(fv2.get());
osg::ref_ptr<osg::IntArray> osg_tex_coord_index = new osg::IntArray(); osg::ref_ptr<osg::IntArray> 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) { if (index != -1) {
osg_tex_coord_index->push_back(index); osg_tex_coord_index->push_back(index);
} }
@ -118,9 +116,9 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
// get array of normals per vertex (if specified) // get array of normals per vertex (if specified)
{ {
const openvrml::field_value& fv = vrml_ifs->field("normal"); std::auto_ptr<openvrml::field_value> fv = vrml_ifs->field("normal");
const openvrml::sfnode& sfn = dynamic_cast<const openvrml::sfnode&>(fv); const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
openvrml::vrml97_node::normal_node* vrml_normal_node = dynamic_cast<openvrml::vrml97_node::normal_node*>(sfn.value.get()); openvrml::normal_node *vrml_normal_node = dynamic_cast<openvrml::normal_node *>(sfn->value().get());
if (vrml_normal_node != 0) // if no normals, node is NULL pointer if (vrml_normal_node != 0) // if no normals, node is NULL pointer
{ {
@ -137,16 +135,16 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
osg_geom->setNormalArray(osg_normalcoords.get()); osg_geom->setNormalArray(osg_normalcoords.get());
// get array of normal indices // get array of normal indices
const openvrml::field_value& fv2 = vrml_ifs->field("normalIndex"); std::auto_ptr<openvrml::field_value> fv2 = vrml_ifs->field("normalIndex");
const openvrml::mfint32& vrml_normal_index = dynamic_cast<const openvrml::mfint32&>(fv2); const openvrml::mfint32 *vrml_normal_index = dynamic_cast<const openvrml::mfint32 *>(fv2.get());
osg::ref_ptr<osg::IntArray> osg_normal_index = new osg::IntArray(); osg::ref_ptr<osg::IntArray> 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) if (index != -1)
{ {
osg_normal_index->push_back(index); osg_normal_index->push_back(index);
@ -159,10 +157,10 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
osg_geom->setNormalIndices(osg_geom->getVertexIndices()); osg_geom->setNormalIndices(osg_geom->getVertexIndices());
// get normal binding // get normal binding
const openvrml::field_value &fv3 = vrml_ifs->field("normalPerVertex"); std::auto_ptr<openvrml::field_value> fv3 = vrml_ifs->field("normalPerVertex");
const openvrml::sfbool &vrml_norm_per_vertex = dynamic_cast<const openvrml::sfbool &>(fv3); const openvrml::sfbool *vrml_norm_per_vertex = dynamic_cast<const openvrml::sfbool *>(fv3.get());
if (vrml_norm_per_vertex.value) if (vrml_norm_per_vertex->value())
{ {
osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
} else } else
@ -174,10 +172,9 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
// get array of colours per vertex (if specified) // get array of colours per vertex (if specified)
{ {
const openvrml::field_value &fv = vrml_ifs->field("color"); std::auto_ptr<openvrml::field_value> fv = vrml_ifs->field("color");
const openvrml::sfnode &sfn = dynamic_cast<const openvrml::sfnode &>(fv); const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
openvrml::vrml97_node::color_node *vrml_color_node = openvrml::color_node *vrml_color_node = dynamic_cast<openvrml::color_node *>(sfn->value().get());
dynamic_cast<openvrml::vrml97_node::color_node *>(sfn.value.get());
if (vrml_color_node != 0) // if no colors, node is NULL pointer if (vrml_color_node != 0) // if no colors, node is NULL pointer
{ {
@ -194,16 +191,16 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
osg_geom->setColorArray(osg_colors.get()); osg_geom->setColorArray(osg_colors.get());
// get array of color indices // get array of color indices
const openvrml::field_value &fv2 = vrml_ifs->field("colorIndex"); std::auto_ptr<openvrml::field_value> fv2 = vrml_ifs->field("colorIndex");
const openvrml::mfint32 &vrml_color_index = dynamic_cast<const openvrml::mfint32 &>(fv2); const openvrml::mfint32 *vrml_color_index = dynamic_cast<const openvrml::mfint32 *>(fv2.get());
osg::ref_ptr<osg::IntArray> osg_color_index = new osg::IntArray(); osg::ref_ptr<osg::IntArray> 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) { if (index != -1) {
osg_color_index->push_back(index); osg_color_index->push_back(index);
} }
@ -214,10 +211,10 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
osg_geom->setColorIndices(osg_geom->getVertexIndices()); osg_geom->setColorIndices(osg_geom->getVertexIndices());
// get color binding // get color binding
const openvrml::field_value &fv3 = vrml_ifs->field("colorPerVertex"); std::auto_ptr<openvrml::field_value> fv3 = vrml_ifs->field("colorPerVertex");
const openvrml::sfbool &vrml_color_per_vertex = dynamic_cast<const openvrml::sfbool &>(fv3); const openvrml::sfbool *vrml_color_per_vertex = dynamic_cast<const openvrml::sfbool *>(fv3.get());
if (vrml_color_per_vertex.value) if (vrml_color_per_vertex->value())
{ {
osg_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); osg_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
} else } else
@ -227,7 +224,11 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
} }
} }
if (static_cast<const openvrml::sfbool&>(vrml_ifs->field("solid")).value)
// normal smoothing
std::auto_ptr<openvrml::field_value> fv_solid = vrml_ifs->field("solid");
const openvrml::sfbool *solid = dynamic_cast<const openvrml::sfbool *>(fv_solid.get());
if (solid->value())
{ {
osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK)); osg_geom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
} }
@ -253,7 +254,7 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
osg::IntArray& indices = *static_cast<osg::IntArray*>(osg_geom->getVertexIndices()); osg::IntArray& indices = *static_cast<osg::IntArray*>(osg_geom->getVertexIndices());
osg::DrawArrayLengths& lengths = *static_cast<osg::DrawArrayLengths*>(osg_geom->getPrimitiveSet(0)); osg::DrawArrayLengths& lengths = *static_cast<osg::DrawArrayLengths*>(osg_geom->getPrimitiveSet(0));
int index = 0; unsigned index = 0;
for (osg::DrawArrayLengths::iterator it = lengths.begin(); it != lengths.end(); ++it) for (osg::DrawArrayLengths::iterator it = lengths.begin(); it != lengths.end(); ++it)
{ {
@ -287,7 +288,6 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
#endif #endif
} }
osg::DrawArrayLengths& lengths = *static_cast<osg::DrawArrayLengths*>(osg_geom->getPrimitiveSet(0)); osg::DrawArrayLengths& lengths = *static_cast<osg::DrawArrayLengths*>(osg_geom->getPrimitiveSet(0));
osg::DrawArrayLengths::iterator it = lengths.begin(); osg::DrawArrayLengths::iterator it = lengths.begin();
@ -325,5 +325,6 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedFaceSet(openv
break; break;
} }
} }
return osg_geom.get(); return osg_geom.get();
} }

View File

@ -11,16 +11,14 @@
#endif #endif
#include <openvrml/vrml97node.h> #include <openvrml/vrml97node.h>
#include <openvrml/common.h>
#include <openvrml/node.h> #include <openvrml/node.h>
#include <openvrml/node_ptr.h>
#include <openvrml/field.h>
#include <osg/CullFace> #include <osg/CullFace>
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Box(openvrml::vrml97_node::box_node* vrml_box) const osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Box(openvrml::node* vrml_box) const
{ {
const openvrml::vec3f& size = static_cast<const openvrml::sfvec3f&>(vrml_box->field("size")).value; std::auto_ptr<openvrml::field_value> fv = vrml_box->field("size");
const openvrml::vec3f &size = static_cast<const openvrml::sfvec3f *> (fv.get())->value();
osg::Vec3 halfSize(size[0] * 0.5f, size[1] * 0.5f, size[2] * 0.5f); osg::Vec3 halfSize(size[0] * 0.5f, size[1] * 0.5f, size[2] * 0.5f);
@ -98,10 +96,10 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Box(openvrml::vrml97
return osg_geom.get(); return osg_geom.get();
} }
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Sphere(openvrml::node* vrml_sphere) const
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Sphere(openvrml::vrml97_node::sphere_node* vrml_sphere) const
{ {
float radius = static_cast<const openvrml::sffloat&>(vrml_sphere->field("radius")).value; std::auto_ptr<openvrml::field_value> fv = vrml_sphere->field("radius");
const float radius = static_cast<const openvrml::sffloat *> (fv.get())->value();
SphereLibrary::const_iterator it = m_sphereLibrary.find(radius); SphereLibrary::const_iterator it = m_sphereLibrary.find(radius);
if (it != m_sphereLibrary.end()) if (it != m_sphereLibrary.end())
@ -177,13 +175,12 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Sphere(openvrml::vrm
return osg_geom.get(); return osg_geom.get();
} }
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cone(openvrml::node* vrml_cone) const
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cone(openvrml::vrml97_node::cone_node* vrml_cone) const
{ {
float height = static_cast<const openvrml::sffloat&>(vrml_cone->field("height")).value; float height = static_cast<const openvrml::sffloat*>(vrml_cone->field("height").get())->value();
float radius = static_cast<const openvrml::sffloat&>(vrml_cone->field("bottomRadius")).value; float radius = static_cast<const openvrml::sffloat*>(vrml_cone->field("bottomRadius").get())->value();
bool bottom = static_cast<const openvrml::sfbool&>(vrml_cone->field("bottom")).value; bool bottom = static_cast<const openvrml::sfbool*>(vrml_cone->field("bottom").get())->value();
bool side = static_cast<const openvrml::sfbool&>(vrml_cone->field("side")).value; bool side = static_cast<const openvrml::sfbool*>(vrml_cone->field("side").get())->value();
QuadricKey key(height, radius, bottom, side, false); QuadricKey key(height, radius, bottom, side, false);
@ -253,7 +250,6 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cone(openvrml::vrml9
{ {
osg::ref_ptr<osg::DrawArrays> bottom = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN); osg::ref_ptr<osg::DrawArrays> bottom = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN);
size_t first = osg_vertices->size(); size_t first = osg_vertices->size();
bottom->setFirst(first); bottom->setFirst(first);
@ -291,13 +287,13 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cone(openvrml::vrml9
return osg_geom.get(); return osg_geom.get();
} }
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cylinder(openvrml::vrml97_node::cylinder_node* vrml_cylinder) const osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cylinder(openvrml::node* vrml_cylinder) const
{ {
float height = static_cast<const openvrml::sffloat&>(vrml_cylinder->field("height")).value; float height = static_cast<const openvrml::sffloat*>(vrml_cylinder->field("height").get())->value();
float radius = static_cast<const openvrml::sffloat&>(vrml_cylinder->field("radius")).value; float radius = static_cast<const openvrml::sffloat*>(vrml_cylinder->field("radius").get())->value();
bool bottom = static_cast<const openvrml::sfbool&>(vrml_cylinder->field("bottom")).value; bool bottom = static_cast<const openvrml::sfbool*>(vrml_cylinder->field("bottom").get())->value();
bool side = static_cast<const openvrml::sfbool&>(vrml_cylinder->field("side")).value; bool side = static_cast<const openvrml::sfbool*>(vrml_cylinder->field("side").get())->value();
bool top = static_cast<const openvrml::sfbool&>(vrml_cylinder->field("top")).value; bool top = static_cast<const openvrml::sfbool*>(vrml_cylinder->field("top").get())->value();
QuadricKey key(height, radius, bottom, side, top); QuadricKey key(height, radius, bottom, side, top);
@ -316,7 +312,6 @@ osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97Cylinder(openvrml::v
const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments); const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments);
float topY = height * 0.5f; float topY = height * 0.5f;
float bottomY = height * -0.5f; float bottomY = height * -0.5f;

View File

@ -5,8 +5,10 @@
- dependencies: - dependencies:
OpenVRML (http://openvrml.org/) OpenVRML (http://openvrml.org/)
Boost (http://www.boost.org/)
OpenSceneGraph (http://www.openscenegraph.org/) OpenSceneGraph (http://www.openscenegraph.org/)
CAUTION! 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!

View File

@ -11,6 +11,7 @@
* (c) VRlab EPFL, Switzerland, 2004-2006 * (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)
* *
*/ */
@ -19,6 +20,9 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/utility.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(disable: 4250) # pragma warning(disable: 4250)
# pragma warning(disable: 4290) # pragma warning(disable: 4290)
@ -26,11 +30,8 @@
#endif #endif
#include <openvrml/vrml97node.h> #include <openvrml/vrml97node.h>
#include <openvrml/common.h>
#include <openvrml/browser.h> #include <openvrml/browser.h>
#include <openvrml/node.h> #include <openvrml/node.h>
#include <openvrml/node_ptr.h>
#include <openvrml/field.h>
#include <osg/TexEnv> #include <osg/TexEnv>
#include <osg/CullFace> #include <osg/CullFace>
@ -55,6 +56,116 @@
#include <assert.h> #include <assert.h>
#include <map> #include <map>
// -------------------------------------------------------------------------------------
// OpenVRML helper class
// -------------------------------------------------------------------------------------
class resource_fetcher: public openvrml::resource_fetcher
{
private:
virtual std::auto_ptr<openvrml::resource_istream> 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<resource_istream> in(new file_resource_istream(path));
static_cast<file_resource_istream *> (in.get())->url(uri);
return in;
}
};
// -------------------------------------------------------------------------------------
// Register with Registry to instantiate the above reader/writer. // Register with Registry to instantiate the above reader/writer.
REGISTER_OSGPLUGIN(vrml, ReaderWriterVRML2) 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 osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string &fname, const Options* opt) const
{ {
std::string fileName = osgDB::findDataFile(fname, opt); 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 // convert possible Windows backslashes to Unix slashes
// OpenVRML doesn't like backslashes, even on Windows // OpenVRML doesn't like backslashes, even on Windows
@ -75,33 +187,32 @@ osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string &f
if (unixFileName[0] == '/') // absolute path if (unixFileName[0] == '/') // absolute path
fileName = "file://" + unixFileName; fileName = "file://" + unixFileName;
#endif #endif
else // relative path else
// relative path
fileName = unixFileName; fileName = unixFileName;
std::fstream null; 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<std::string> parameter; std::ifstream vrml_stream(fileName.c_str());
std::vector<std::string> vuri;
vuri.push_back(fileName);
browser->load_url(vuri, parameter);
std::vector< openvrml::node_ptr > mfn; try
mfn = browser->root_nodes(); {
const std::vector< boost::intrusive_ptr< openvrml::node > > & mfn = b->create_vrml_from_stream(vrml_stream);
if (mfn.size() == 0) { if(mfn.empty())
return ReadResult::FILE_NOT_HANDLED; return ReadResult::FILE_NOT_HANDLED;
else
} else { {
osg::ref_ptr<osg::MatrixTransform> osg_root = osg::ref_ptr<osg::MatrixTransform> osg_root = new osg::MatrixTransform(osg::Matrix( 1, 0, 0, 0,
new osg::MatrixTransform(osg::Matrix( 1, 0, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, -1, 0, 0, 0, -1, 0, 0,
0, 0, 0, 1)); 0, 0, 0, 1));
osgDB::getDataFilePathList().push_front(osgDB::getFilePath(unixFileName)); osgDB::getDataFilePathList().push_front(osgDB::getFilePath(unixFileName));
for (unsigned i = 0; i < mfn.size(); i++) { for (unsigned i = 0; i < mfn.size(); i++)
{
openvrml::node *vrml_node = mfn[i].get(); openvrml::node *vrml_node = mfn[i].get();
osg_root->addChild(convertFromVRML(vrml_node).get()); osg_root->addChild(convertFromVRML(vrml_node).get());
} }
@ -110,29 +221,36 @@ osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string &f
} }
} }
catch (openvrml::invalid_vrml) { return ReadResult::FILE_NOT_HANDLED; }
catch (std::invalid_argument) { return ReadResult::FILE_NOT_HANDLED; }
}
osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const osg::ref_ptr<osg::Node> 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; openvrml::grouping_node *vrml_group;
vrml_group = dynamic_cast<openvrml::vrml97_node::group_node *>(obj); vrml_group = dynamic_cast<openvrml::grouping_node *>(obj);
osg::ref_ptr<osg::Group> osg_group = new osg::Group; osg::ref_ptr<osg::Group> osg_group = new osg::Group;
try try
{ {
const openvrml::field_value &fv = obj->field("children"); std::auto_ptr<openvrml::field_value> fv = obj->field("children");
if ( fv.type() == openvrml::field_value::mfnode_id ) { if ( fv->type() == openvrml::field_value::mfnode_id )
const openvrml::mfnode &mfn = dynamic_cast<const openvrml::mfnode &>(fv); {
for (unsigned i = 0; i < mfn.value.size(); i++) { const openvrml::mfnode* mfn = dynamic_cast<const openvrml::mfnode *>(fv.get());
openvrml::node *node = mfn.value[i].get(); openvrml::mfnode::value_type node_ptr_vector = mfn->value();
osg_group->addChild(convertFromVRML(node).get()); 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));
} }
} }
} }
@ -144,22 +262,29 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
return osg_group.get(); 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; openvrml::transform_node *vrml_transform;
vrml_transform = dynamic_cast<openvrml::vrml97_node::transform_node *>(obj); vrml_transform = dynamic_cast<openvrml::transform_node *>(obj);
openvrml::mat4f vrml_m = vrml_transform->transform(); openvrml::mat4f vrml_m = vrml_transform->transform();
osg::ref_ptr<osg::MatrixTransform> 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])); osg::ref_ptr<osg::MatrixTransform> 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 try
{ {
const openvrml::field_value &fv = obj->field("children"); std::auto_ptr<openvrml::field_value> fv = obj->field("children");
if ( fv.type() == openvrml::field_value::mfnode_id ) { if ( fv->type() == openvrml::field_value::mfnode_id )
const openvrml::mfnode &mfn = dynamic_cast<const openvrml::mfnode &>(fv); {
for (unsigned i = 0; i < mfn.value.size(); i++) { const openvrml::mfnode* mfn = dynamic_cast<const openvrml::mfnode *>(fv.get());
openvrml::node *node = mfn.value[i].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()); osg_m->addChild(convertFromVRML(node).get());
} }
} }
@ -172,42 +297,37 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
return osg_m.get(); 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::Geometry> osg_geom; osg::ref_ptr<osg::Geometry> osg_geom;
// parse the geometry // parse the geometry
{ {
const openvrml::field_value &fv = obj->field("geometry"); std::auto_ptr<openvrml::field_value> 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<const openvrml::sfnode &>(fv); const openvrml::sfnode * sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
openvrml::sfnode::value_type node_ptr = sfn->value();
// is it indexed_face_set_node ? // is it indexed_face_set_node ?
if (node_ptr->type().id()=="IndexedFaceSet")
osg_geom = convertVRML97IndexedFaceSet(node_ptr.get());
openvrml::vrml97_node::abstract_geometry_node* vrml_geom = else if (node_ptr->type().id() == "Box")
static_cast<openvrml::vrml97_node::abstract_geometry_node*>(sfn.value.get()->to_geometry()); 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());
if (openvrml::vrml97_node::indexed_face_set_node *vrml_ifs = dynamic_cast<openvrml::vrml97_node::indexed_face_set_node *>(vrml_geom))
{
osg_geom = convertVRML97IndexedFaceSet(vrml_ifs);
}
else if (openvrml::vrml97_node::box_node* vrml_box = dynamic_cast<openvrml::vrml97_node::box_node*>(vrml_geom))
{
osg_geom = convertVRML97Box(vrml_box);
}
else if (openvrml::vrml97_node::sphere_node* vrml_sphere = dynamic_cast<openvrml::vrml97_node::sphere_node*>(vrml_geom))
{
osg_geom = convertVRML97Sphere(vrml_sphere);
}
else if (openvrml::vrml97_node::cone_node* vrml_cone = dynamic_cast<openvrml::vrml97_node::cone_node*>(vrml_geom))
{
osg_geom = convertVRML97Cone(vrml_cone);
}
else if (openvrml::vrml97_node::cylinder_node* vrml_cylinder = dynamic_cast<openvrml::vrml97_node::cylinder_node*>(vrml_geom))
{
osg_geom = convertVRML97Cylinder(vrml_cylinder);
}
else else
{ {
// other geometry types not handled yet // other geometry types not handled yet
@ -223,24 +343,18 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
osg_stateset->setAttributeAndModes(osg_mat.get()); osg_stateset->setAttributeAndModes(osg_mat.get());
osg_mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); osg_mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
// parse the appearance // parse the appearance
{ {
const openvrml::field_value &fv = obj->field("appearance"); std::auto_ptr<openvrml::field_value> 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<const openvrml::sfnode &>(fv); const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
// std::cerr << "FV->sfnode OK" << std::endl << std::flush; openvrml::appearance_node *vrml_app = dynamic_cast<openvrml::appearance_node *>(sfn->value().get());
openvrml::vrml97_node::appearance_node* vrml_app = static_cast<openvrml::vrml97_node::appearance_node*>(sfn.value.get()->to_appearance()); const boost::intrusive_ptr<openvrml::node> vrml_material_node = vrml_app->material();
const boost::intrusive_ptr<openvrml::node> vrml_texture_node = vrml_app->texture();
const openvrml::node_ptr &vrml_material_node = vrml_app->material(); const openvrml::material_node *vrml_material = dynamic_cast<const openvrml::material_node *>(vrml_material_node.get());
const openvrml::node_ptr &vrml_texture_node = vrml_app->texture();
const openvrml::vrml97_node::material_node *vrml_material =
dynamic_cast<const openvrml::vrml97_node::material_node *>(vrml_material_node.get());
// std::cerr << "sfnode->Material OK" << std::endl << std::flush;
if (vrml_material != NULL) if (vrml_material != NULL)
{ {
@ -284,21 +398,17 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
} }
const openvrml::vrml97_node::image_texture_node *vrml_texture =
dynamic_cast<const openvrml::vrml97_node::image_texture_node *>(vrml_texture_node.get());
// std::cerr << "TextureNode -> ImageTexture OK" << std::endl << std::flush;
// if texture is provided // if texture is provided
if (vrml_texture != 0) { if (vrml_texture_node != 0)
const openvrml::field_value &texture_url_fv = vrml_texture->field("url"); {
const openvrml::mfstring &mfs = dynamic_cast<const openvrml::mfstring &>(texture_url_fv); std::auto_ptr<openvrml::field_value> texture_url_fv = vrml_texture_node->field("url");
// std::cerr << "Texture URL FV -> mfstring OK" << std::endl << std::flush; const openvrml::mfstring *mfs = dynamic_cast<const openvrml::mfstring *>(texture_url_fv.get());
const std::string &url = mfs->value()[0];
const std::string &url = mfs.value[0];
osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile(url); osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile(url);
if (image != 0) { if (image != 0)
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D; osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
texture->setImage(image.get()); texture->setImage(image.get());
@ -308,26 +418,30 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
// get the real texture wrapping parameters (if any) // get the real texture wrapping parameters (if any)
try
{
std::auto_ptr<openvrml::field_value> wrap_fv = vrml_texture_node->field("repeatS");
const openvrml::sfbool *sfb = dynamic_cast<const openvrml::sfbool *>(wrap_fv.get());
try { if (!sfb->value())
const openvrml::field_value &wrap_fv = vrml_texture->field("repeatS");
const openvrml::sfbool &sfb = dynamic_cast<const openvrml::sfbool &>(wrap_fv);
if (!sfb.value) {
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
} }
} catch (...) { catch (...)
{
// nothing specified // nothing specified
} }
try { try
const openvrml::field_value &wrap_fv = vrml_texture->field("repeatT"); {
const openvrml::sfbool &sfb = dynamic_cast<const openvrml::sfbool &>(wrap_fv); std::auto_ptr<openvrml::field_value> wrap_fv = vrml_texture_node->field("repeatT");
const openvrml::sfbool *sfb = dynamic_cast<const openvrml::sfbool *>(wrap_fv.get());
if (!sfb.value) { if (!sfb->value())
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
} }
} catch (...) { catch (...)
{
// nothing specified // nothing specified
} }
@ -335,7 +449,8 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
//osg_stateset->setMode(GL_BLEND,osg::StateAttribute::ON); //bhbn //osg_stateset->setMode(GL_BLEND,osg::StateAttribute::ON); //bhbn
} }
else { else
{
std::cerr << "texture file " << url << " not found !" << std::endl << std::flush; std::cerr << "texture file " << url << " not found !" << std::endl << std::flush;
} }
} }
@ -348,7 +463,7 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
{ {
return 0; return 0;
} }
#if 0
/* /*
} else if(obj->type.id == "DirectionalLight") // Handle lights } else if(obj->type.id == "DirectionalLight") // Handle lights
{ {
@ -471,7 +586,9 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
return NULL; return NULL;
} }
*/ */
#endif
return 0;
} }

View File

@ -11,6 +11,7 @@
* (c) VRlab EPFL, Switzerland, 2004-2006 * (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)
* *
*/ */
@ -25,18 +26,10 @@
#include <osgDB/FileNameUtils> #include <osgDB/FileNameUtils>
#include <osgDB/FileUtils> #include <osgDB/FileUtils>
namespace openvrml namespace openvrml
{ {
class node; class node;
namespace vrml97_node
{
class indexed_face_set_node;
class box_node;
class sphere_node;
class cone_node;
class cylinder_node;
}
} }
class QuadricKey class QuadricKey
@ -92,11 +85,12 @@ private:
osg::ref_ptr<osg::Node> convertFromVRML(openvrml::node *obj) const; osg::ref_ptr<osg::Node> convertFromVRML(openvrml::node *obj) const;
osg::ref_ptr<osg::Geometry> convertVRML97IndexedFaceSet(openvrml::vrml97_node::indexed_face_set_node *vrml_ifs) const;
osg::ref_ptr<osg::Geometry> convertVRML97Box(openvrml::vrml97_node::box_node* vrml_box) const; osg::ref_ptr<osg::Geometry> convertVRML97IndexedFaceSet(openvrml::node *vrml_ifs) const;
osg::ref_ptr<osg::Geometry> convertVRML97Sphere(openvrml::vrml97_node::sphere_node* vrml_sphere) const; osg::ref_ptr<osg::Geometry> convertVRML97Box(openvrml::node* vrml_box) const;
osg::ref_ptr<osg::Geometry> convertVRML97Cone(openvrml::vrml97_node::cone_node* vrml_cone) const; osg::ref_ptr<osg::Geometry> convertVRML97Sphere(openvrml::node* vrml_sphere) const;
osg::ref_ptr<osg::Geometry> convertVRML97Cylinder(openvrml::vrml97_node::cylinder_node* vrml_cylinder) const; osg::ref_ptr<osg::Geometry> convertVRML97Cone(openvrml::node* vrml_cone) const;
osg::ref_ptr<osg::Geometry> convertVRML97Cylinder(openvrml::node* vrml_cylinder) const;
mutable BoxLibrary m_boxLibrary; mutable BoxLibrary m_boxLibrary;
mutable SphereLibrary m_sphereLibrary; mutable SphereLibrary m_sphereLibrary;