From Joakim Simmonsson, fix for handling of billboards in FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS

This commit is contained in:
Robert Osfield 2008-11-25 14:31:19 +00:00
parent b6fe330b85
commit 017b4315bc
2 changed files with 56 additions and 34 deletions

View File

@ -310,7 +310,8 @@ class OSGUTIL_EXPORT Optimizer
protected:
void transformDrawables(osg::Geode& geode);
void transformGeode(osg::Geode& geode);
void transformDrawable(osg::Drawable& drawable);
void transformBillboard(osg::Billboard& billboard);
std::vector<osg::Matrix> _matrixStack;

View File

@ -4408,7 +4408,7 @@ void Optimizer::FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor::apply(
// If there is only one parent, just transform all vertices and normals
if(geode.getNumParents() == 1)
{
transformDrawables(geode);
transformGeode(geode);
}
else
{
@ -4428,7 +4428,7 @@ void Optimizer::FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor::apply(
else
osg::notify(osg::NOTICE) << "No parent for this Geode" << std::endl;
transformDrawables(*(new_geode.get()));
transformGeode(*(new_geode.get()));
}
}
}
@ -4469,45 +4469,55 @@ void Optimizer::FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor::apply(
}
void Optimizer::FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor::transformDrawables(osg::Geode& geode)
void Optimizer::FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor::transformGeode(osg::Geode& geode)
{
for(unsigned int i=0; i<geode.getNumDrawables(); i++)
{
osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
if(geometry)
{
// transform all geometry
osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
if(verts)
{
for(unsigned int j=0; j<verts->size(); j++)
(*verts)[j] = (*verts)[j] * _matrixStack.back();
}
else
{
osg::Vec4Array* verts = dynamic_cast<osg::Vec4Array*>(geometry->getVertexArray());
if(verts)
{
for(unsigned int j=0; j<verts->size(); j++)
(*verts)[j] = _matrixStack.back() * (*verts)[j];
}
}
osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
if(normals)
{
for(unsigned int j=0; j<normals->size(); j++)
(*normals)[j] = osg::Matrix::transform3x3((*normals)[j], _matrixStack.back());
}
geometry->dirtyBound();
geometry->dirtyDisplayList();
}
transformDrawable(*geode.getDrawable(i));
}
geode.dirtyBound();
}
void Optimizer::FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor::transformDrawable(osg::Drawable& drawable)
{
osg::Geometry* geometry = drawable.asGeometry();
if(geometry)
{
// transform all geometry
osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
if(verts)
{
for(unsigned int j=0; j<verts->size(); j++)
{
(*verts)[j] = (*verts)[j] * _matrixStack.back();
}
}
else
{
osg::Vec4Array* verts = dynamic_cast<osg::Vec4Array*>(geometry->getVertexArray());
if(verts)
{
for(unsigned int j=0; j<verts->size(); j++)
{
(*verts)[j] = _matrixStack.back() * (*verts)[j];
}
}
}
osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
if(normals)
{
for(unsigned int j=0; j<normals->size(); j++)
(*normals)[j] = osg::Matrix::transform3x3((*normals)[j], _matrixStack.back());
}
geometry->dirtyBound();
geometry->dirtyDisplayList();
}
}
void Optimizer::FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor::transformBillboard(osg::Billboard& billboard)
{
osg::Vec3 axis = osg::Matrix::transform3x3(billboard.getAxis(), _matrixStack.back());
@ -4519,7 +4529,18 @@ void Optimizer::FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor::transf
billboard.setNormal(normal);
for(unsigned int i=0; i<billboard.getNumDrawables(); i++)
billboard.setPosition(i, billboard.getPosition(i) * _matrixStack.back());
{
osg::Vec3 originalBillboardPosition = billboard.getPosition(i);
billboard.setPosition(i, originalBillboardPosition * _matrixStack.back());
osg::Matrix matrixForDrawable = _matrixStack.back();
matrixForDrawable.preMult(osg::Matrix::translate(originalBillboardPosition));
matrixForDrawable.postMult(osg::Matrix::translate(-billboard.getPosition(i)));
_matrixStack.push_back(matrixForDrawable);
transformDrawable(*billboard.getDrawable(i));
_matrixStack.pop_back();
}
billboard.dirtyBound();
}