From Mathias Froehlich, "I added some features to the vrml plugin.
The plugin can now handle embeded PixelTexture fields in addition to the already implemented ImageTexture fields. Fixed a bug with texture repeat being applied to the wrong texture dimension. Added handling for IndexedLineSet geometries."
This commit is contained in:
@@ -14,6 +14,122 @@
|
||||
|
||||
#include <osg/CullFace>
|
||||
|
||||
osg::ref_ptr<osg::Geometry> ReaderWriterVRML2::convertVRML97IndexedLineSet(openvrml::node *vrml_ifs) const
|
||||
{
|
||||
osg::ref_ptr<osg::Geometry> 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<openvrml::field_value> fv = vrml_ifs->field("coord");
|
||||
const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.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();
|
||||
|
||||
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
|
||||
std::auto_ptr<openvrml::field_value> fv2 = vrml_ifs->field("coordIndex");
|
||||
const openvrml::mfint32 *vrml_coord_index = dynamic_cast<const openvrml::mfint32 *>(fv2.get());
|
||||
|
||||
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)
|
||||
{
|
||||
static_cast<osg::DrawArrayLengths*>(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::DrawArrayLengths*>(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<openvrml::field_value> fv = vrml_ifs->field("color");
|
||||
const openvrml::sfnode *sfn = dynamic_cast<const openvrml::sfnode *>(fv.get());
|
||||
openvrml::color_node *vrml_color_node = dynamic_cast<openvrml::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
|
||||
std::auto_ptr<openvrml::field_value> fv2 = vrml_ifs->field("colorIndex");
|
||||
const openvrml::mfint32 *vrml_color_index = dynamic_cast<const openvrml::mfint32 *>(fv2.get());
|
||||
|
||||
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
|
||||
std::auto_ptr<openvrml::field_value> fv3 = vrml_ifs->field("colorPerVertex");
|
||||
const openvrml::sfbool *vrml_color_per_vertex = dynamic_cast<const openvrml::sfbool *>(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<osg::Geometry> ReaderWriterVRML2::convertVRML97Box(openvrml::node* vrml_box) const
|
||||
{
|
||||
std::auto_ptr<openvrml::field_value> fv = vrml_box->field("size");
|
||||
|
||||
@@ -315,6 +315,9 @@ osg::ref_ptr<osg::Node> 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<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
|
||||
openvrml::appearance_node *vrml_app = dynamic_cast<openvrml::appearance_node *>(sfn->value().get());
|
||||
|
||||
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 boost::intrusive_ptr<openvrml::texture_node> vrml_texture_node = openvrml::node_cast<openvrml::texture_node*>(vrml_app->texture().get());
|
||||
const openvrml::material_node *vrml_material = dynamic_cast<const openvrml::material_node *>(vrml_material_node.get());
|
||||
|
||||
if (vrml_material != NULL)
|
||||
@@ -400,57 +403,83 @@ osg::ref_ptr<osg::Node> ReaderWriterVRML2::convertFromVRML(openvrml::node *obj)
|
||||
// if texture is provided
|
||||
if (vrml_texture_node != 0)
|
||||
{
|
||||
std::auto_ptr<openvrml::field_value> texture_url_fv = vrml_texture_node->field("url");
|
||||
const openvrml::mfstring *mfs = dynamic_cast<const openvrml::mfstring *>(texture_url_fv.get());
|
||||
const std::string &url = mfs->value()[0];
|
||||
osg::ref_ptr<osg::Image> image;
|
||||
|
||||
osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile(url);
|
||||
if (vrml_texture_node->type().id() == "ImageTexture")
|
||||
{
|
||||
try
|
||||
{
|
||||
std::auto_ptr<openvrml::field_value> texture_url_fv = vrml_texture_node->field("url");
|
||||
const openvrml::mfstring *mfs = dynamic_cast<const openvrml::mfstring *>(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<osg::Texture2D> 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<openvrml::field_value> wrap_fv = vrml_texture_node->field("repeatS");
|
||||
const openvrml::sfbool *sfb = dynamic_cast<const openvrml::sfbool *>(wrap_fv.get());
|
||||
|
||||
if (!sfb->value())
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// nothing specified
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
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())
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ private:
|
||||
|
||||
|
||||
osg::ref_ptr<osg::Geometry> convertVRML97IndexedFaceSet(openvrml::node *vrml_ifs) const;
|
||||
osg::ref_ptr<osg::Geometry> convertVRML97IndexedLineSet(openvrml::node *vrml_ifs) const;
|
||||
osg::ref_ptr<osg::Geometry> convertVRML97Box(openvrml::node* vrml_box) const;
|
||||
osg::ref_ptr<osg::Geometry> convertVRML97Sphere(openvrml::node* vrml_sphere) const;
|
||||
osg::ref_ptr<osg::Geometry> convertVRML97Cone(openvrml::node* vrml_cone) const;
|
||||
|
||||
Reference in New Issue
Block a user