Billboard scaling fix and culling bug fix

c++11
scrawl 10 years ago
parent a474c72026
commit 12f27123f2

@ -184,7 +184,7 @@ if (${OGRE_VERSION} VERSION_LESS "1.9")
message(FATAL_ERROR "OpenMW requires Ogre 1.9 or later, please install the latest stable version from http://ogre3d.org")
endif()
find_package(OpenSceneGraph 3.2.0 REQUIRED osgDB osgViewer osgGA osgAnimation osgParticle osgQt)
find_package(OpenSceneGraph 3.2.0 REQUIRED osgDB osgViewer osgGA osgAnimation osgParticle osgQt osgUtil)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
find_package(MyGUI REQUIRED)

@ -210,36 +210,49 @@ namespace
}
};
// Custom node used to have a transform always oriented towards the camera. Can have translation and scale
// NodeCallback used to have a transform always oriented towards the camera. Can have translation and scale
// set just like a regular MatrixTransform, but the rotation set will be overridden in order to face the camera.
class BillboardNode : public osg::MatrixTransform
class BillboardCallback : public osg::NodeCallback
{
public:
BillboardNode() : osg::MatrixTransform() {}
BillboardNode(const BillboardNode& copy, const osg::CopyOp& copyop)
: osg::MatrixTransform(copy, copyop) {}
BillboardNode(const osg::Matrix& matrix)
: osg::MatrixTransform(matrix) {}
BillboardCallback()
{
}
BillboardCallback(const BillboardCallback& copy, const osg::CopyOp& copyop)
: osg::NodeCallback(copy, copyop)
{
}
META_Node(NifOsg, BillboardNode)
META_Object(NifOsg, BillboardCallback)
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor*) const
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (_referenceFrame==RELATIVE_RF)
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
osg::MatrixTransform* billboardNode = dynamic_cast<osg::MatrixTransform*>(node);
if (billboardNode && cv)
{
const NifOsg::NodeUserData* userdata = static_cast<const NifOsg::NodeUserData*>(getUserDataContainer()->getUserObject(0));
osg::Matrix modelView = *cv->getModelViewMatrix();
matrix.preMult(_matrix);
matrix.setRotate(osg::Quat());
matrix(0,0) = userdata->mScale;
matrix(1,1) = userdata->mScale;
matrix(2,2) = userdata->mScale;
}
else // absolute
{
matrix = _matrix;
// attempt to preserve scale
float mag[3];
for (int i=0;i<3;++i)
{
mag[i] = std::sqrt(modelView(0,i) * modelView(0,i) + modelView(1,i) * modelView(1,i) + modelView(2,i) * modelView(2,i));
}
modelView.setRotate(osg::Quat());
modelView(0,0) = mag[0];
modelView(1,1) = mag[1];
modelView(2,2) = mag[2];
cv->pushModelViewMatrix(new osg::RefMatrix(modelView), osg::Transform::RELATIVE_RF);
traverse(node, nv);
cv->popModelViewMatrix();
}
return true;
else
traverse(node, nv);
}
};
@ -639,11 +652,7 @@ namespace NifOsg
std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
{
osg::ref_ptr<osg::MatrixTransform> transformNode;
if (nifNode->recType == Nif::RC_NiBillboardNode)
{
transformNode = new BillboardNode(toMatrix(nifNode->trafo));
}
else if (createSkeleton)
if (createSkeleton)
{
osgAnimation::Bone* bone = new osgAnimation::Bone;
transformNode = bone;
@ -655,6 +664,10 @@ namespace NifOsg
{
transformNode = new osg::MatrixTransform(toMatrix(nifNode->trafo));
}
if (nifNode->recType == Nif::RC_NiBillboardNode)
{
transformNode->addCullCallback(new BillboardCallback);
}
if (parentNode)
parentNode->addChild(transformNode);

Loading…
Cancel
Save