diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 87bafa6b19..2070ee850a 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -48,6 +48,7 @@ static std::map makeFactory() newFactory.insert(makeEntry("NiSwitchNode", &construct , RC_NiSwitchNode )); newFactory.insert(makeEntry("NiLODNode", &construct , RC_NiLODNode )); newFactory.insert(makeEntry("AvoidNode", &construct , RC_AvoidNode )); + newFactory.insert(makeEntry("NiCollisionSwitch", &construct , RC_NiCollisionSwitch )); newFactory.insert(makeEntry("NiBSParticleNode", &construct , RC_NiBSParticleNode )); newFactory.insert(makeEntry("NiBSAnimationNode", &construct , RC_NiBSAnimationNode )); newFactory.insert(makeEntry("NiBillboardNode", &construct , RC_NiBillboardNode )); diff --git a/components/nif/node.hpp b/components/nif/node.hpp index de4bfb22eb..4c52cd1581 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -84,7 +84,8 @@ struct NiNode : Node enum Flags { Flag_Hidden = 0x0001, Flag_MeshCollision = 0x0002, - Flag_BBoxCollision = 0x0004 + Flag_BBoxCollision = 0x0004, + Flag_ActiveCollision = 0x0020 }; enum BSAnimFlags { AnimFlag_AutoPlay = 0x0020 diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 67ffbc5748..074dea9cfa 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -40,6 +40,7 @@ enum RecordType RC_NiLODNode, RC_NiBillboardNode, RC_AvoidNode, + RC_NiCollisionSwitch, RC_NiTriShape, RC_NiTriStrips, RC_NiRotatingParticles, diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 91f8494210..dafee1b497 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -254,6 +254,10 @@ bool BulletNifLoader::hasAutoGeneratedCollision(const Nif::Node* rootNode) void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *node, int flags, bool isCollisionNode, bool isAnimated, bool autogenerated, bool avoid) { + // TODO: allow on-the fly collision switching via toggling this flag + if (node->recType == Nif::RC_NiCollisionSwitch && !(node->flags & Nif::NiNode::Flag_ActiveCollision)) + return; + // Accumulate the flags from all the child nodes. This works for all // the flags we currently use, at least. flags |= node->flags; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 602f1fa9aa..76fd4b6560 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -168,6 +168,20 @@ namespace namespace NifOsg { + class CollisionSwitch : public osg::Group + { + public: + CollisionSwitch(bool enabled) : osg::Group() + { + setEnabled(enabled); + } + + void setEnabled(bool enabled) + { + setNodeMask(enabled ? SceneUtil::Mask_Default : SceneUtil::Mask_Effect); + } + }; + bool Loader::sShowMarkers = false; void Loader::setShowMarkers(bool show) @@ -460,6 +474,14 @@ namespace NifOsg case Nif::RC_NiBillboardNode: dataVariance = osg::Object::DYNAMIC; break; + case Nif::RC_NiCollisionSwitch: + { + bool enabled = nifNode->flags & Nif::NiNode::Flag_ActiveCollision; + node = new CollisionSwitch(enabled); + dataVariance = osg::Object::STATIC; + + break; + } default: // 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