|
|
|
@ -356,7 +356,7 @@ namespace NifOsg
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<TextKeyMapHolder> textkeys (new TextKeyMapHolder);
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> created = handleNode(nifNode, NULL, imageManager, std::vector<int>(), 0, false, &textkeys->mTextKeys);
|
|
|
|
|
osg::ref_ptr<osg::Node> created = handleNode(nifNode, NULL, imageManager, std::vector<int>(), 0, false, false, &textkeys->mTextKeys);
|
|
|
|
|
|
|
|
|
|
if (nif->getUseSkinning())
|
|
|
|
|
{
|
|
|
|
@ -511,15 +511,12 @@ namespace NifOsg
|
|
|
|
|
stateset->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::ImageManager* imageManager,
|
|
|
|
|
std::vector<int> boundTextures, int animflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
|
|
|
|
// Get a default dataVariance for this node to be used as a hint by optimization (post)routines
|
|
|
|
|
osg::Object::DataVariance getDataVariance(const Nif::Node* nifNode)
|
|
|
|
|
{
|
|
|
|
|
if (rootNode != NULL && Misc::StringUtils::ciEqual(nifNode->name, "Bounding Box"))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Group> node = new osg::MatrixTransform(nifNode->trafo.toMatrix());
|
|
|
|
|
if (nifNode->boneTrafo || nifNode->boneIndex != -1)
|
|
|
|
|
return osg::Object::DYNAMIC;
|
|
|
|
|
|
|
|
|
|
// Set a default DataVariance (used as hint by optimization routines).
|
|
|
|
|
switch (nifNode->recType)
|
|
|
|
|
{
|
|
|
|
|
case Nif::RC_NiTriShape:
|
|
|
|
@ -527,16 +524,30 @@ namespace NifOsg
|
|
|
|
|
case Nif::RC_NiRotatingParticles:
|
|
|
|
|
// Leaf nodes in the NIF hierarchy, so won't be able to dynamically attach children.
|
|
|
|
|
// No support for keyframe controllers (just crashes in the original engine).
|
|
|
|
|
if (nifNode->trafo.isIdentity())
|
|
|
|
|
node = new osg::Group;
|
|
|
|
|
node->setDataVariance(osg::Object::STATIC);
|
|
|
|
|
break;
|
|
|
|
|
return osg::Object::STATIC;
|
|
|
|
|
default:
|
|
|
|
|
// could have new children attached at any time, or added external keyframe controllers from .kf files
|
|
|
|
|
node->setDataVariance(osg::Object::DYNAMIC);
|
|
|
|
|
break;
|
|
|
|
|
return osg::Object::DYNAMIC;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::ImageManager* imageManager,
|
|
|
|
|
std::vector<int> boundTextures, int animflags, bool skipMeshes, bool isAnimated, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
|
|
|
|
{
|
|
|
|
|
if (rootNode != NULL && Misc::StringUtils::ciEqual(nifNode->name, "Bounding Box"))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
osg::Object::DataVariance dataVariance = getDataVariance(nifNode);
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Group> node;
|
|
|
|
|
if (dataVariance == osg::Object::STATIC && nifNode->trafo.isIdentity())
|
|
|
|
|
node = new osg::Group;
|
|
|
|
|
else
|
|
|
|
|
node = new osg::MatrixTransform(nifNode->trafo.toMatrix());
|
|
|
|
|
node->setDataVariance(dataVariance);
|
|
|
|
|
|
|
|
|
|
if (nifNode->controller.empty())
|
|
|
|
|
node->setDataVariance(osg::Object::STATIC);
|
|
|
|
|
|
|
|
|
|
if (nifNode->recType == Nif::RC_NiBillboardNode)
|
|
|
|
|
{
|
|
|
|
|
node->addCullCallback(new BillboardCallback);
|
|
|
|
@ -550,6 +561,9 @@ namespace NifOsg
|
|
|
|
|
node->setDataVariance(osg::Object::STATIC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!nifNode->controller.empty() && nifNode->controller->recType == Nif::RC_NiKeyframeController)
|
|
|
|
|
isAnimated = true;
|
|
|
|
|
|
|
|
|
|
node->setName(nifNode->name);
|
|
|
|
|
|
|
|
|
|
if (parentNode)
|
|
|
|
@ -599,6 +613,11 @@ namespace NifOsg
|
|
|
|
|
node->setNodeMask(0x1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (skipMeshes && isAnimated) // make sure the empty node is not optimized away so the physicssystem can find it.
|
|
|
|
|
{
|
|
|
|
|
node->setDataVariance(osg::Object::DYNAMIC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We can skip creating meshes for hidden nodes if they don't have a VisController that
|
|
|
|
|
// might make them visible later
|
|
|
|
|
if (nifNode->flags & Nif::NiNode::Flag_Hidden)
|
|
|
|
@ -665,7 +684,7 @@ namespace NifOsg
|
|
|
|
|
for(size_t i = 0;i < children.length();++i)
|
|
|
|
|
{
|
|
|
|
|
if(!children[i].empty())
|
|
|
|
|
handleNode(children[i].getPtr(), node, imageManager, boundTextures, animflags, skipMeshes, textKeys, rootNode);
|
|
|
|
|
handleNode(children[i].getPtr(), node, imageManager, boundTextures, animflags, skipMeshes, isAnimated, textKeys, rootNode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|