Fix emitter/particlesystem scene graph order problems

pull/638/head
scrawl 10 years ago
parent e3bfbcb44b
commit 99c9907ff3

@ -468,6 +468,7 @@ namespace NifOsg
nif->fail("First root was not a node, but a " + r->recName);
osg::ref_ptr<osgAnimation::Skeleton> skel = new osgAnimation::Skeleton;
skel->setDefaultUpdateCallback(); // validates the skeleton hierarchy
skel->addChild(handleNode(nifNode, true, std::map<int, int>(), 0, 0, false, textKeys));
return skel;
@ -609,8 +610,7 @@ namespace NifOsg
{
if(!children[i].empty())
{
// Insert bones at position 0 to prevent update order problems (see comment in osg Skeleton.cpp)
transformNode->insertChild(0,
transformNode->addChild(
handleNode(children[i].getPtr(), createSkeleton, boundTextures, animflags, particleflags, skipMeshes, textKeys, rootNode));
}
}
@ -1077,11 +1077,18 @@ namespace NifOsg
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
triShapeToGeometry(triShape, geometry, geode, boundTextures, animflags);
// Note the RigGeometry's UpdateCallback uses the skeleton space bone matrix, so the bone UpdateCallback has to be fired first.
// For this to work properly, all bones used for skinning a RigGeometry need to be created before that RigGeometry.
// All NIFs I've checked seem to conform to this restriction, perhaps Gamebryo update method works similarly.
// If a file violates this assumption, the worst that could happen is the bone position being a frame late.
// If this happens, we should get a warning from the Skeleton's validation update callback on the error log.
osg::ref_ptr<osgAnimation::RigGeometry> rig(new osgAnimation::RigGeometry);
rig->setSourceGeometry(geometry);
// Slightly expand the bounding box to account for movement of the bones
// For more accuracy the skinning should be relative to the parent of the first skinned bone,
// rather than the root bone.
// TODO: calculate a correct bounding box based on the bone positions every frame in a ComputeBoundingBoxCallback
osg::BoundingBox box = geometry->getBound();
box.expandBy(box._min-(box._max-box._min)/2);
box.expandBy(box._max+(box._max-box._min)/2);

Loading…
Cancel
Save