[osg-submissions] Fixes + additions for VRML plugin
Robert Osfield
robert.osfield at gmail.com
Wed Nov 7 07:35:46 PST 2007
HI Gino,
Thanks the for the changes, unfortunately your mail tool has inlined
the .cpp file. Could you repost with the files zipped up to avoid the
mail tool inlining it.
Cheers,
Robert.
On Nov 7, 2007 2:12 PM, Gino van den Bergen <gino at dtecta.com> wrote:
> I've added the following features to the OSG VRML plugin:
> * Support for Box, Sphere, Cone, and Cylinder. These nodes are converted
> to osg::Geometry conform the VRML97 spec.
> * Backface culling is enabled/disabled according to the "solid" flag for
> geometries that are converted from IndexFaceSets.
> * PROTO instances can now be used for "appearance" and "geometry" fields
> in a Shape node.
>
> The file ReaderWriterVRML2.cpp is adapted for the latest stable public
> release:
>
> http://www.openscenegraph.org/svn/osg/OpenSceneGraph/tags/OpenSceneGraph-2.2.0
>
> The changes where needed for being able to read VRML file which are
> output by VMD (http://www.ks.uiuc.edu/Research/vmd/). A sample VRML file
> is enclosed in this submission.
>
> The plugin has been tested against a number of VRML samples that include
> texturing. The texturing is found to be VRML97 compliant for all added
> geometry nodes.
>
> Kind regards,
>
> Gino van den Bergen
> www.dtecta.com
>
>
>
>
> // -*-c++-*-
>
> /*
> *
> * VRML2 file converter for OpenSceneGraph.
> *
> * authors : Jan Ciger (jan.ciger at gmail.com),
> * Tolga Abaci (tolga.abaci at gmail.com),
> * Bruno Herbelin (bruno.herbelin at gmail.com)
> *
> * (c) VRlab EPFL, Switzerland, 2004-2006
> */
>
> #include <iostream>
> #include <fstream>
> #include <string>
> #include <complex>
>
> #include <openvrml/vrml97node.h>
> #include <openvrml/common.h>
> #include <openvrml/browser.h>
> #include <openvrml/node.h>
> #include <openvrml/node_ptr.h>
> #include <openvrml/field.h>
>
> #include <osg/TexEnv>
> #include <osg/CullFace>
>
> #include <osg/Geode>
> #include <osg/Geometry>
> #include <osg/Material>
> #include <osg/Image>
> #include <osg/Texture2D>
> #include <osg/Group>
> #include <osg/MatrixTransform>
> #include <osg/Light>
> #include <osg/LightSource>
>
> #include <osg/Notify>
> #include <osgDB/Registry>
> #include <osgDB/ReadFile>
> #include <osgDB/FileNameUtils>
> #include <osgDB/FileUtils>
>
> #include <assert.h>
> #include <map>
>
>
> /**
> * OpenSceneGraph plugin wrapper/converter.
> */
> class ReaderWriterVRML2 : public osgDB::ReaderWriter
> {
> public:
> ReaderWriterVRML2() { }
>
> virtual const char* className()
> {
> return "VRML2 Reader/Writer";
> }
>
> virtual bool acceptsExtension(const std::string& extension)
> {
> return osgDB::equalCaseInsensitive(extension, "wrl") ? true : false;
> }
>
> virtual ReadResult readNode(const std::string&, const osgDB::ReaderWriter::Options *options = NULL) const;
> private:
> osg::ref_ptr<osg::Node> convertFromVRML(openvrml::node *obj) const;
> };
>
> // Register with Registry to instantiate the above reader/writer.
> 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;
>
> // convert possible Windows backslashes to Unix slashes
> // OpenVRML doesn't like backslashes, even on Windows
> std::string unixFileName = osgDB::convertFileNameToUnixStyle(fileName);
>
> #ifdef WIN32
> if(unixFileName[1] == ':') // absolute path
> #else
> if(unixFileName[0] == '/') // absolute path
> #endif
> fileName = "file://" + unixFileName;
> else // relative path
> fileName = unixFileName;
>
> std::fstream null;
> openvrml::browser *browser = new openvrml::browser(null, null);
>
> std::vector<std::string> parameter;
> std::vector<std::string> vuri;
> vuri.push_back(fileName);
> browser->load_url(vuri, parameter);
>
> std::vector< openvrml::node_ptr > mfn;
> mfn = browser->root_nodes();
>
> if (mfn.size() == 0) {
> return ReadResult::FILE_NOT_HANDLED;
>
> } else {
> osg::ref_ptr<osg::MatrixTransform> osg_root = new osg::MatrixTransform(osg::Matrix(1, 0, 0, 0,
> 0, 0, 1, 0,
> 0, -1, 0, 0,
> 0, 0, 0, 1));
>
> for (unsigned i = 0; i < mfn.size(); i++) {
> openvrml::node *vrml_node = mfn[i].get();
> osg_root->addChild(convertFromVRML(vrml_node).get());
> }
>
> return osg_root.get();
> }
> }
>
> osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) const
> {
> std::string name = obj->id();
> static int osgLightNum = 0; //light
>
> // std::cout << obj->type.id << " Node " << " ["<< name <<']' << std::endl;
>
> if (obj->type.id == "Group") // Group node
> {
> openvrml::vrml97_node::group_node *vrml_group;
> vrml_group = dynamic_cast<openvrml::vrml97_node::group_node *>(obj);
>
> osg::ref_ptr<osg::Group> osg_group = new osg::Group;
>
> try
> {
> const openvrml::field_value &fv = obj->field("children");
>
> 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++) {
> openvrml::node *node = mfn.value[i].get();
> osg_group->addChild(convertFromVRML(node).get());
> }
> }
> } catch (openvrml::unsupported_interface &e)
> {
> // no children
> }
>
> return osg_group.get();
>
> } else if (obj->type.id == "Transform") // Handle transforms
> {
> openvrml::vrml97_node::transform_node *vrml_transform;
> vrml_transform = dynamic_cast<openvrml::vrml97_node::transform_node *>(obj);
>
> 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]));
>
> try
> {
> const openvrml::field_value &fv = obj->field("children");
>
> 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++) {
> openvrml::node *node = mfn.value[i].get();
> osg_m->addChild(convertFromVRML(node).get());
> }
> }
> } catch (openvrml::unsupported_interface &e)
> {
> // no children
> }
>
> return osg_m.get();
>
> } else if (obj->type.id == "Shape") // Handle Shape node
> {
> osg::ref_ptr<osg::Geode> osg_geode = new osg::Geode();
> osg::ref_ptr<osg::Geometry> osg_geom = new osg::Geometry();
> osg_geode->addDrawable(osg_geom.get());
> osg::StateSet *osg_stateset = osg_geom->getOrCreateStateSet();
>
> osg::ref_ptr<osg::Material> osg_mat = new osg::Material();
> osg_stateset->setAttributeAndModes(osg_mat.get());
> osg_mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
>
> // parse the geometry
> {
> const openvrml::field_value &fv = obj->field("geometry");
>
> if (fv.type() == openvrml::field_value::sfnode_id)
> {
> const openvrml::sfnode &sfn = dynamic_cast<const openvrml::sfnode &>(fv);
> // is it indexed_face_set_node ?
>
> openvrml::vrml97_node::abstract_geometry_node* vrml_geom =
> static_cast<openvrml::vrml97_node::abstract_geometry_node*>(sfn.value.get()->to_geometry());
>
> if (openvrml::vrml97_node::indexed_face_set_node *vrml_ifs = dynamic_cast<openvrml::vrml97_node::indexed_face_set_node *>(vrml_geom))
> {
> osg_geom->addPrimitiveSet(new osg::DrawArrayLengths(osg::PrimitiveSet::POLYGON));
>
> // get array of vertex coordinate_nodes
> {
> const openvrml::field_value & fv = vrml_ifs->field("coord");
> const openvrml::sfnode &sfn = dynamic_cast<const openvrml::sfnode &>(fv);
> openvrml::vrml97_node::coordinate_node *vrml_coord_node =
> dynamic_cast<openvrml::vrml97_node::coordinate_node *>(sfn.value.get());
>
> const std::vector<openvrml::vec3f> &vrml_coord = vrml_coord_node->point();
> osg::ref_ptr<osg::Vec3Array> 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<const openvrml::mfint32 &>(fv2);
>
> osg::ref_ptr<osg::IntArray> osg_vert_index = new osg::IntArray();
>
> int num_vert = 0;
> for (i = 0; i < vrml_coord_index.value.size(); i++)
> {
> int index = vrml_coord_index.value[i];
> if (index == -1) {
> ((osg::DrawArrayLengths*) osg_geom->getPrimitiveSet(0))->push_back(num_vert);
> num_vert = 0;
> } else {
> osg_vert_index->push_back(index);
> 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<const openvrml::sfnode &>(fv);
> openvrml::vrml97_node::texture_coordinate_node *vrml_tex_coord_node =
> dynamic_cast<openvrml::vrml97_node::texture_coordinate_node *>(sfn.value.get());
>
> if (vrml_tex_coord_node != 0) // if no texture, node is NULL pointer
> {
> const std::vector<openvrml::vec2f> &vrml_tex_coord = vrml_tex_coord_node->point();
> osg::ref_ptr<osg::Vec2Array> 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<const openvrml::mfint32 &>(fv2);
>
> osg::ref_ptr<osg::IntArray> osg_tex_coord_index = new osg::IntArray();
>
> if(vrml_tex_coord_index.value.size() > 0)
> {
> for (i = 0; i < vrml_tex_coord_index.value.size(); 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
> // 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<const openvrml::sfnode &>(fv);
> openvrml::vrml97_node::normal_node *vrml_normal_node =
> dynamic_cast<openvrml::vrml97_node::normal_node *>(sfn.value.get());
>
> if (vrml_normal_node != 0) // if no normals, node is NULL pointer
> {
> const std::vector<openvrml::vec3f> &vrml_normal_coord = vrml_normal_node->vector();
>
> osg::ref_ptr<osg::Vec3Array> osg_normalcoords = new osg::Vec3Array();
>
> unsigned i;
> for (i = 0; i < vrml_normal_coord.size(); i++)
> {
> const openvrml::vec3f vec = vrml_normal_coord[i];
> 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<const openvrml::mfint32 &>(fv2);
>
> osg::ref_ptr<osg::IntArray> osg_normal_index = new osg::IntArray();
>
> if(vrml_normal_index.value.size() > 0)
> {
> for (i = 0; i < vrml_normal_index.value.size(); 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<const openvrml::sfbool &>(fv3);
>
> if (vrml_norm_per_vertex.value)
> {
> osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
> } else
> {
> osg_geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
> }
> }
> }
>
> // get array of colours per vertex (if specified)
> {
> const openvrml::field_value &fv = vrml_ifs->field("color");
> const openvrml::sfnode &sfn = dynamic_cast<const openvrml::sfnode &>(fv);
> openvrml::vrml97_node::color_node *vrml_color_node =
> dynamic_cast<openvrml::vrml97_node::color_node *>(sfn.value.get());
>
> if (vrml_color_node != 0) // if no colors, node is NULL pointer
> {
> const std::vector<openvrml::color> &vrml_colors = vrml_color_node->color();
>
> osg::ref_ptr<osg::Vec3Array> osg_colors = new osg::Vec3Array();
>
> unsigned i;
> for (i = 0; i < vrml_colors.size(); i++)
> {
> const openvrml::color color = vrml_colors[i];
> 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<const openvrml::mfint32 &>(fv2);
>
> osg::ref_ptr<osg::IntArray> osg_color_index = new osg::IntArray();
>
> if(vrml_color_index.value.size() > 0)
> {
> for (i = 0; i < vrml_color_index.value.size(); 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
> // 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<const openvrml::sfbool &>(fv3);
>
> if (vrml_color_per_vertex.value)
> {
> osg_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
> } else
> {
> osg_geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);
> }
> }
> }
>
> if (static_cast<const openvrml::sfbool&>(vrml_ifs->field("solid")).value)
> {
> osg_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
> }
> }
> else if (openvrml::vrml97_node::box_node* vrml_box = dynamic_cast<openvrml::vrml97_node::box_node*>(vrml_geom))
> {
> const openvrml::vec3f& size = static_cast<const openvrml::sfvec3f&>(vrml_box->field("size")).value;
>
> osg::Vec3 halfSize(size[0] * 0.5f, size[1] * 0.5f, size[2] * 0.5f);
>
> osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
> osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array();
> osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array();
>
> osg::ref_ptr<osg::DrawArrays> 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]));
>
> for (int i = 0; i != 6; ++i)
> {
> osg_texcoords->push_back(osg::Vec2(0.0f, 1.0f));
> osg_texcoords->push_back(osg::Vec2(0.0f, 0.0f));
> osg_texcoords->push_back(osg::Vec2(1.0f, 0.0f));
> osg_texcoords->push_back(osg::Vec2(1.0f, 1.0f));
> }
>
> osg_normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
> osg_normals->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
> osg_normals->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
> osg_normals->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f));
> osg_normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
> 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());
> osg_geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
>
> osg_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
> }
> else if (openvrml::vrml97_node::sphere_node* vrml_sphere = dynamic_cast<openvrml::vrml97_node::sphere_node*>(vrml_geom))
> {
> float radius = static_cast<const openvrml::sffloat&>(vrml_sphere->field("radius")).value;
>
> osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
> osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array();
> osg::ref_ptr<osg::Vec3Array> osg_normals = new osg::Vec3Array();
>
> unsigned int numSegments = 40;
> unsigned int numRows = 20;
>
> const float thetaDelta = 2.0f * float(osg::PI) / float(numSegments);
> const float texCoordSDelta = 1.0f / float(numSegments);
> const float phiDelta = float(osg::PI) / float(numRows);
> const float texCoordTDelta = 1.0f / float(numRows);
>
> float phi = -0.5f * float(osg::PI);
> float texCoordT = 0.0f;
>
> osg::ref_ptr<osg::DrawArrayLengths> sphere = new osg::DrawArrayLengths(osg::PrimitiveSet::QUAD_STRIP);
>
> for (unsigned int i = 0; i < numRows; ++i, phi += phiDelta, texCoordT += texCoordTDelta)
> {
> std::complex<float> latBottom = std::polar(1.0f, phi);
> std::complex<float> latTop = std::polar(1.0f, phi + phiDelta);
> std::complex<float> eBottom = latBottom * radius;
> std::complex<float> eTop = latTop * radius;
>
> float theta = 0.0f;
> float texCoordS = 0.0f;
>
> for (unsigned int j = 0; j < numSegments; ++j, theta += thetaDelta, texCoordS += texCoordSDelta)
> {
> std::complex<float> 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());
> osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
>
> osg_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
>
> }
> else if (openvrml::vrml97_node::cone_node* vrml_cone = dynamic_cast<openvrml::vrml97_node::cone_node*>(vrml_geom))
> {
> float height = static_cast<const openvrml::sffloat&>(vrml_cone->field("height")).value;
> float radius = static_cast<const openvrml::sffloat&>(vrml_cone->field("bottomRadius")).value;
>
> osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
> osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array();
> osg::ref_ptr<osg::Vec3Array> 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 (static_cast<const openvrml::sfbool&>(vrml_cone->field("side")).value)
> {
> osg::ref_ptr<osg::DrawArrays> 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<float> n = -std::polar(1.0f, theta);
> std::complex<float> 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_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));
>
> side->setCount(osg_vertices->size());
> osg_geom->addPrimitiveSet(side.get());
> }
>
> if (static_cast<const openvrml::sfbool&>(vrml_cone->field("bottom")).value)
> {
> osg::ref_ptr<osg::DrawArrays> 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<float> n = -std::polar(1.0f, theta);
> std::complex<float> 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());
> osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
>
> osg_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
> }
> else if (openvrml::vrml97_node::cylinder_node* vrml_cylinder = dynamic_cast<openvrml::vrml97_node::cylinder_node*>(vrml_geom))
> {
> float height = static_cast<const openvrml::sffloat&>(vrml_cylinder->field("height")).value;
> float radius = static_cast<const openvrml::sffloat&>(vrml_cylinder->field("radius")).value;
>
> osg::ref_ptr<osg::Vec3Array> osg_vertices = new osg::Vec3Array();
> osg::ref_ptr<osg::Vec2Array> osg_texcoords = new osg::Vec2Array();
> osg::ref_ptr<osg::Vec3Array> 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 (static_cast<const openvrml::sfbool&>(vrml_cylinder->field("side")).value)
> {
> osg::ref_ptr<osg::DrawArrays> 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<float> n = -std::polar(1.0f, theta);
> std::complex<float> 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_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 (static_cast<const openvrml::sfbool&>(vrml_cylinder->field("bottom")).value)
> {
> osg::ref_ptr<osg::DrawArrays> 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<float> n = -std::polar(1.0f, theta);
> std::complex<float> 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());
> }
>
> if (static_cast<const openvrml::sfbool&>(vrml_cylinder->field("top")).value)
> {
> osg::ref_ptr<osg::DrawArrays> 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<float> n = -std::polar(1.0f, theta);
> std::complex<float> 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());
> osg_geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
>
> osg_stateset->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK));
> }
> else
> {
> // other geometry types not handled yet
> }
> }
> }
>
> // parse the appearance
> {
> const openvrml::field_value &fv = obj->field("appearance");
>
> if (fv.type() == openvrml::field_value::sfnode_id)
> {
> const openvrml::sfnode &sfn = dynamic_cast<const openvrml::sfnode &>(fv);
> // std::cerr << "FV->sfnode OK" << std::endl << std::flush;
>
> openvrml::vrml97_node::appearance_node* vrml_app = static_cast<openvrml::vrml97_node::appearance_node*>(sfn.value.get()->to_appearance());
>
> 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<const openvrml::vrml97_node::material_node *>(vrml_material_node.get());
> // std::cerr << "sfnode->Material OK" << std::endl << std::flush;
>
> 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->setTransparency(osg::Material::FRONT_AND_BACK, vrml_material->transparency() );
> //osg_stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
>
> osg_mat->setShininess(osg::Material::FRONT_AND_BACK, vrml_material->shininess() );
>
> //osg_mat->setColorMode(osg::Material::OFF);
>
> osg_stateset->setAttributeAndModes(osg_mat.get());
> osg_stateset->setMode(GL_BLEND, osg::StateAttribute::ON); //bhbn
>
> }
>
> 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 (vrml_texture != 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::cerr << "Texture URL FV -> mfstring OK" << std::endl << std::flush;
>
> const std::string &url = mfs.value[0];
>
> osg::ref_ptr<osg::Image> image = osgDB::readImageFile(url);
>
> if (image != 0) {
> osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
> texture->setImage(image.get());
>
> // defaults
> texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
> texture->setWrap(osg::Texture::WRAP_R, osg::Texture::REPEAT);
> texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
>
> // get the real texture wrapping parameters (if any)
>
> try {
> 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);
> }
> } catch (...) {
> // nothing specified
> }
>
> try {
> const openvrml::field_value &wrap_fv = vrml_texture->field("repeatT");
> const openvrml::sfbool &sfb = dynamic_cast<const openvrml::sfbool &>(wrap_fv);
>
> if (!sfb.value) {
> texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
> }
> } catch (...) {
> // nothing specified
> }
>
> osg_stateset->setTextureAttributeAndModes(0, texture.get());
> //osg_stateset->setMode(GL_BLEND,osg::StateAttribute::ON); //bhbn
>
> } else {
> std::cerr << "texture file " << url << " not found !" << std::endl << std::flush;
> }
> }
> }
> }
>
> return osg_geode.get();
> } else {
> return 0;
> }
>
> /*
> } 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<openvrml::vrml97_node::directional_light_node *>(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++;
>
> return lightGroup;
>
> } else if(obj->type.id == "PointLight") // Handle lights
> {
> osg::Group* lightGroup = new osg::Group;
>
> openvrml::vrml97_node::point_light_node *vrml_light;
> vrml_light = dynamic_cast<openvrml::vrml97_node::point_light_node *>(obj);
>
> // create light with global params
> osg::Light* myLight = new osg::Light;
> myLight->setLightNum(osgLightNum);
> //std::cout<<"lightnum = "<<osgLightNum;
>
> openvrml::sfvec3f &pos = vrml_light->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;
>
> } 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<openvrml::vrml97_node::spot_light_node *>(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;
> }
> */
> }
>
>
>
>
>
> _______________________________________________
> osg-submissions mailing list
> osg-submissions at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
More information about the osg-submissions
mailing list