forked from teamnwah/openmw-tes3coop
Fix emitter/particlesystem scene graph order problems
This commit is contained in:
parent
e3bfbcb44b
commit
99c9907ff3
1 changed files with 9 additions and 2 deletions
|
@ -468,6 +468,7 @@ namespace NifOsg
|
||||||
nif->fail("First root was not a node, but a " + r->recName);
|
nif->fail("First root was not a node, but a " + r->recName);
|
||||||
|
|
||||||
osg::ref_ptr<osgAnimation::Skeleton> skel = new osgAnimation::Skeleton;
|
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));
|
skel->addChild(handleNode(nifNode, true, std::map<int, int>(), 0, 0, false, textKeys));
|
||||||
|
|
||||||
return skel;
|
return skel;
|
||||||
|
@ -609,8 +610,7 @@ namespace NifOsg
|
||||||
{
|
{
|
||||||
if(!children[i].empty())
|
if(!children[i].empty())
|
||||||
{
|
{
|
||||||
// Insert bones at position 0 to prevent update order problems (see comment in osg Skeleton.cpp)
|
transformNode->addChild(
|
||||||
transformNode->insertChild(0,
|
|
||||||
handleNode(children[i].getPtr(), createSkeleton, boundTextures, animflags, particleflags, skipMeshes, textKeys, rootNode));
|
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);
|
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
|
||||||
triShapeToGeometry(triShape, geometry, geode, boundTextures, animflags);
|
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);
|
osg::ref_ptr<osgAnimation::RigGeometry> rig(new osgAnimation::RigGeometry);
|
||||||
rig->setSourceGeometry(geometry);
|
rig->setSourceGeometry(geometry);
|
||||||
|
|
||||||
// Slightly expand the bounding box to account for movement of the bones
|
// 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,
|
// For more accuracy the skinning should be relative to the parent of the first skinned bone,
|
||||||
// rather than the root 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();
|
osg::BoundingBox box = geometry->getBound();
|
||||||
box.expandBy(box._min-(box._max-box._min)/2);
|
box.expandBy(box._min-(box._max-box._min)/2);
|
||||||
box.expandBy(box._max+(box._max-box._min)/2);
|
box.expandBy(box._max+(box._max-box._min)/2);
|
||||||
|
|
Loading…
Reference in a new issue