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") message(FATAL_ERROR "OpenMW requires Ogre 1.9 or later, please install the latest stable version from http://ogre3d.org")
endif() 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}) include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
find_package(MyGUI REQUIRED) 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. // 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: public:
BillboardNode() : osg::MatrixTransform() {} BillboardCallback()
BillboardNode(const BillboardNode& copy, const osg::CopyOp& copyop) {
: osg::MatrixTransform(copy, copyop) {} }
BillboardNode(const osg::Matrix& matrix) BillboardCallback(const BillboardCallback& copy, const osg::CopyOp& copyop)
: osg::MatrixTransform(matrix) {} : 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); // attempt to preserve scale
matrix.setRotate(osg::Quat()); float mag[3];
matrix(0,0) = userdata->mScale; for (int i=0;i<3;++i)
matrix(1,1) = userdata->mScale; {
matrix(2,2) = userdata->mScale; mag[i] = std::sqrt(modelView(0,i) * modelView(0,i) + modelView(1,i) * modelView(1,i) + modelView(2,i) * modelView(2,i));
} }
else // absolute
{ modelView.setRotate(osg::Quat());
matrix = _matrix; 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) std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
{ {
osg::ref_ptr<osg::MatrixTransform> transformNode; osg::ref_ptr<osg::MatrixTransform> transformNode;
if (nifNode->recType == Nif::RC_NiBillboardNode) if (createSkeleton)
{
transformNode = new BillboardNode(toMatrix(nifNode->trafo));
}
else if (createSkeleton)
{ {
osgAnimation::Bone* bone = new osgAnimation::Bone; osgAnimation::Bone* bone = new osgAnimation::Bone;
transformNode = bone; transformNode = bone;
@ -655,6 +664,10 @@ namespace NifOsg
{ {
transformNode = new osg::MatrixTransform(toMatrix(nifNode->trafo)); transformNode = new osg::MatrixTransform(toMatrix(nifNode->trafo));
} }
if (nifNode->recType == Nif::RC_NiBillboardNode)
{
transformNode->addCullCallback(new BillboardCallback);
}
if (parentNode) if (parentNode)
parentNode->addChild(transformNode); parentNode->addChild(transformNode);

Loading…
Cancel
Save