[osg-users] Getting texture coordinates of loaded models
jean-sebastien.guay at cm-labs.com
Thu Jul 31 06:15:03 PDT 2008
> osg::Drawable* draw = geode.getDrawable(i);
> //At this level, everything is ok since the Draw pointer contains at
> least one valid Drawable objects. If I use a TriangleFunctor, it will
> return all triangles of that Drawable :)
> // However I would like to get the texture coordinates as well.
> // HERE IS THE ISSUE.
> const osg::Geometry* geometryd = dynamic_cast<const
> osg::Geometry*> (draw);
> // geometryd is dangling !!!
Ok, two issues:
1. ShapeDrawable has special cases for when it gets a PrimitiveFunctor
(which TriangleFunctor is a subclass of). See src/osg/ShapeDrawable.cpp,
in particular PrimitiveShapeVisitor. It will calculate the vertices
according to simple formulas that define the osg::Shape. That's how OSG
does intersection testing with ShapeDrawables. It works because
osg::Drawable defines the accept(PrimitiveFunctor&) method, and then
osg::ShapeDrawable and osg::Geometry override it and implement it in
different ways, using the data they have.
2. Is geometryd dangling but non-zero, or is it zero? If it's zero, then
the draw pointer was not pointing to a Geometry instance (as was
explained in the other thread) but probably to a ShapeDrawable. As
explained, ShapeDrawable* cannot be cast to Geometry* because they are
siblings in the class hierarchy. Seeing that TriangleFunctor gives you
the triangles of the drawable proves nothing because of what I explained
If geometryd is non-zero, then you have another issue. Possibly
somewhere you're keeping a raw C pointer to something, instead of a
ref_ptr, and the object is being deleted from under you when it
But to return to the ShapeDrawable and Geometry issue, they are
fundamentally different. ShapeDrawable has no vertex / normal / color /
texcoord arrays. It just builds a display list once to be able to draw
the shape, that's all. It was designed to do quick debugging objects.
If Robert were here he would say that he again regrets ever having
created ShapeDrawable :-) There have always been questions sent to the
mailing list of why something related to ShapeDrawable doesn't work, and
it's always that the poster assumed ShapeDrawable to work like Geometry.
Unfortunately, it doesn't, and unfortunately, this isn't made clear
enough in the doxygen...
I have plans to change ShapeDrawable to work more like Geometry - either
to be a subclass of Geometry or have an internal Geometry instance. This
would remove a lot of the special cases for ShapeDrawable in the OSG
code, and would remove some confusion as well. But for the mean time,
you have to accept what you have.
You should probably do something like this:
const osg::Geometry* geometryd =
dynamic_cast<const osg::Geometry*> (draw);
const osg::ShapeDrawable* shapedrawable =
dynamic_cast<const osg::ShapeDrawable*> (draw);
// Process it as an osg::Geometry, so get the normals and
// texcoords from the arrays directly.
else if (shapedrawable)
// Process it as a ShapeDrawable. See the DrawShapeVisitor in
// ShapeDrawable.cpp for inspiration on how to calculate the
// normals and texcoords depending on the osg::Shape your
// ShapeDrawable has.
Or else call a method that has two versions, one that takes an
osg::Geometry* as an argument, the other that takes an
osg::ShapeDrawable*. Or define your own PrimitiveFunctor that would not
only calculate the vertices but also the normals and texcoords and store
them so you'd be able to retrieve them. There's a few ways to do what
Hope this clears things up,
Jean-Sebastien Guay jean-sebastien.guay at cm-labs.com
More information about the osg-users