diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 75634356c..d7f54d247 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -362,7 +362,8 @@ namespace MWMechanics } // If set in the settings file, player followers and escorters will become aggressive toward enemies in combat with them or the player - if (!aggressive && isPlayerFollowerOrEscorter && Settings::Manager::getBool("followers attack on sight", "Game")) + static const bool followersAttackOnSight = Settings::Manager::getBool("followers attack on sight", "Game"); + if (!aggressive && isPlayerFollowerOrEscorter && followersAttackOnSight) { if (actor2.getClass().getCreatureStats(actor2).getAiSequence().isInCombat(actor1)) aggressive = true; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 40a3070d8..84039bd31 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -1338,6 +1338,7 @@ namespace MWPhysics bool cmode = found->second->getCollisionMode(); cmode = !cmode; found->second->enableCollisionMode(cmode); + found->second->enableCollisionBody(cmode); return cmode; } diff --git a/components/nif/data.cpp b/components/nif/data.cpp index 0813ab36b..a6721fde1 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -23,13 +23,11 @@ void NiSkinInstance::post(NIFFile *nif) if(bnum != data->bones.size()) nif->fail("Mismatch in NiSkinData bone count"); - root->makeRootBone(&data->trafo); - for(size_t i=0; ifail("Oops: Missing bone! Don't know how to handle this."); - bones[i]->makeBone(i, data->bones[i]); + bones[i]->setBone(); } } diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 17b58bd46..c32969d1b 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -55,8 +55,7 @@ public: parent = NULL; - boneTrafo = NULL; - boneIndex = -1; + isBone = false; } void post(NIFFile *nif) @@ -69,27 +68,11 @@ public: // NiNodes (or types derived from NiNodes) can be parents. NiNode *parent; - // Bone transformation. If set, node is a part of a skeleton. - const Transformation *boneTrafo; + bool isBone; - // Bone weight info, from NiSkinData - const NiSkinData::BoneInfo *boneInfo; - - // Bone index. If -1, this node is either not a bone, or if - // boneTrafo is set it is the root bone in the skeleton. - short boneIndex; - - void makeRootBone(const Transformation *tr) - { - boneTrafo = tr; - boneIndex = -1; - } - - void makeBone(short ind, const NiSkinData::BoneInfo &bi) + void setBone() { - boneInfo = &bi; - boneTrafo = &bi.trafo; - boneIndex = ind; + isBone = true; } }; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index bdd104b3d..afe38b9bc 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -512,10 +512,10 @@ namespace NifOsg } // 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) + osg::ref_ptr createNode(const Nif::Node* nifNode) { - if (nifNode->boneTrafo || nifNode->boneIndex != -1) - return osg::Object::DYNAMIC; + osg::ref_ptr node; + osg::Object::DataVariance dataVariance = osg::Object::UNSPECIFIED; switch (nifNode->recType) { @@ -524,10 +524,35 @@ 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). - return osg::Object::STATIC; + if (nifNode->trafo.isIdentity()) + node = new osg::Group; + dataVariance = osg::Object::STATIC; + break; default: - return osg::Object::DYNAMIC; + // The Root node can be created as a Group if no transformation is required. + // This takes advantage of the fact root nodes can't have additional controllers + // loaded from an external .kf file (original engine just throws "can't find node" errors if you try). + if (!nifNode->parent && nifNode->controller.empty()) + { + node = new osg::Group; + dataVariance = osg::Object::STATIC; + } + else + { + dataVariance = (nifNode->controller.empty() ? osg::Object::STATIC : osg::Object::DYNAMIC); + } + + if (nifNode->isBone) + dataVariance = osg::Object::DYNAMIC; + + break; } + if (!node) + node = new osg::MatrixTransform(nifNode->trafo.toMatrix()); + + node->setDataVariance(dataVariance); + + return node; } osg::ref_ptr handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::ImageManager* imageManager, @@ -536,30 +561,12 @@ namespace NifOsg if (rootNode != NULL && Misc::StringUtils::ciEqual(nifNode->name, "Bounding Box")) return NULL; - osg::Object::DataVariance dataVariance = getDataVariance(nifNode); - - osg::ref_ptr 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); + osg::ref_ptr node = createNode(nifNode); if (nifNode->recType == Nif::RC_NiBillboardNode) { node->addCullCallback(new BillboardCallback); } - else if (!rootNode && nifNode->controller.empty() && nifNode->trafo.isIdentity()) - { - // The Root node can be created as a Group if no transformation is required. - // This takes advantage of the fact root nodes can't have additional controllers - // loaded from an external .kf file (original engine just throws "can't find node" errors if you try). - node = new osg::Group; - node->setDataVariance(osg::Object::STATIC); - } if (!nifNode->controller.empty() && nifNode->controller->recType == Nif::RC_NiKeyframeController) isAnimated = true; diff --git a/components/sceneutil/clone.cpp b/components/sceneutil/clone.cpp index 2c0ce98ba..738c7a30d 100644 --- a/components/sceneutil/clone.cpp +++ b/components/sceneutil/clone.cpp @@ -94,7 +94,7 @@ namespace SceneUtil osgParticle::ParticleProcessor* CopyOp::operator() (const osgParticle::ParticleProcessor* processor) const { - osgParticle::ParticleProcessor* cloned = osg::clone(processor, osg::CopyOp::SHALLOW_COPY); + osgParticle::ParticleProcessor* cloned = osg::clone(processor, osg::CopyOp::DEEP_COPY_CALLBACKS); mMap[cloned] = processor->getParticleSystem(); return cloned; }