diff --git a/src/osgPlugins/vrml/Primitives.cpp b/src/osgPlugins/vrml/Primitives.cpp index e83f66a3e..21fd35e6b 100644 --- a/src/osgPlugins/vrml/Primitives.cpp +++ b/src/osgPlugins/vrml/Primitives.cpp @@ -14,6 +14,122 @@ #include +osg::ref_ptr ReaderWriterVRML2::convertVRML97IndexedLineSet(openvrml::node *vrml_ifs) const +{ + osg::ref_ptr osg_geom = new osg::Geometry(); + + osg_geom->addPrimitiveSet(new osg::DrawArrayLengths(osg::PrimitiveSet::LINE_STRIP)); + + // get array of vertex coordinate_nodes + if(vrml_ifs->type().id() == "IndexedLineSet") + { + 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 + 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++) + { + int index = vrml_coord_index->value()[i]; + if (index == -1) + { + static_cast(osg_geom->getPrimitiveSet(0))->push_back(num_vert); + num_vert = 0; + } + 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 array of colours per vertex (if specified) + { + 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++) + { + 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 + 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) + { + 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 + 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 + { + osg_geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE); + } + } + } + + osg_geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + + return osg_geom; +} + osg::ref_ptr ReaderWriterVRML2::convertVRML97Box(openvrml::node* vrml_box) const { std::auto_ptr fv = vrml_box->field("size"); diff --git a/src/osgPlugins/vrml/ReaderWriterVRML2.cpp b/src/osgPlugins/vrml/ReaderWriterVRML2.cpp index c86585ace..8ac38793b 100644 --- a/src/osgPlugins/vrml/ReaderWriterVRML2.cpp +++ b/src/osgPlugins/vrml/ReaderWriterVRML2.cpp @@ -315,6 +315,9 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) if (node_ptr->type().id()=="IndexedFaceSet") osg_geom = convertVRML97IndexedFaceSet(node_ptr.get()); + else if (node_ptr->type().id()=="IndexedLineSet") + osg_geom = convertVRML97IndexedLineSet(node_ptr.get()); + else if (node_ptr->type().id() == "Box") osg_geom = convertVRML97Box(node_ptr.get()); @@ -352,7 +355,7 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) openvrml::appearance_node *vrml_app = dynamic_cast(sfn->value().get()); const boost::intrusive_ptr vrml_material_node = vrml_app->material(); - const boost::intrusive_ptr vrml_texture_node = vrml_app->texture(); + const boost::intrusive_ptr vrml_texture_node = openvrml::node_cast(vrml_app->texture().get()); const openvrml::material_node *vrml_material = dynamic_cast(vrml_material_node.get()); if (vrml_material != NULL) @@ -400,57 +403,83 @@ osg::ref_ptr ReaderWriterVRML2::convertFromVRML(openvrml::node *obj) // if texture is provided 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; - osg::ref_ptr image = osgDB::readRefImageFile(url); + if (vrml_texture_node->type().id() == "ImageTexture") + { + try + { + 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]; + + image = osgDB::readRefImageFile(url); + + if (!image.valid()) + { + std::cerr << "texture file " << url << " not found !" << std::endl << std::flush; + } + } + catch (openvrml::unsupported_interface&) + { + // no url field in the texture + } + } - if (image != 0) + if (!image.valid()) + { + // If we cannot read the image try the openvrml builtin mechanisms to read the image. + // This includes PixelTexture fields. + const openvrml::image& vrml_image = vrml_texture_node->image(); + + // Convert to an osg image + image = new osg::Image; + image->allocateImage(vrml_image.x(), vrml_image.y(), 1, GL_RGBA, GL_UNSIGNED_BYTE); + for (std::size_t y = 0; y < vrml_image.y(); ++y) + { + for (std::size_t x = 0; x < vrml_image.x(); ++x) + { + openvrml::int32 p = vrml_image.pixel(x, y); + unsigned char* data = image->data(x, y); + data[0] = 0xff & (p >> 24); + data[1] = 0xff & (p >> 16); + data[2] = 0xff & (p >> 8); + data[3] = 0xff & (p >> 0); + } + } + } + + if (image.valid()) { osg::ref_ptr texture = new osg::Texture2D; texture->setImage(image.get()); - // defaults - texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); + // get the real texture wrapping parameters + if (vrml_texture_node->repeat_s()) + { + texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); + } + else + { + texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); + } + + if (vrml_texture_node->repeat_t()) + { + texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); + } + else + { + texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP); + } 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 - { - std::auto_ptr wrap_fv = vrml_texture_node->field("repeatS"); - const openvrml::sfbool *sfb = dynamic_cast(wrap_fv.get()); - - if (!sfb->value()) - texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); - - } - catch (...) - { - // nothing specified - } - - try - { - std::auto_ptr wrap_fv = vrml_texture_node->field("repeatT"); - const openvrml::sfbool *sfb = dynamic_cast(wrap_fv.get()); - - 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; + if (image->isImageTranslucent()) { + osg_stateset->setMode(GL_BLEND, osg::StateAttribute::ON); + osg_stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + } } } } diff --git a/src/osgPlugins/vrml/ReaderWriterVRML2.h b/src/osgPlugins/vrml/ReaderWriterVRML2.h index 2c22d622b..7049479e1 100644 --- a/src/osgPlugins/vrml/ReaderWriterVRML2.h +++ b/src/osgPlugins/vrml/ReaderWriterVRML2.h @@ -85,6 +85,7 @@ private: osg::ref_ptr convertVRML97IndexedFaceSet(openvrml::node *vrml_ifs) const; + osg::ref_ptr convertVRML97IndexedLineSet(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;