diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 544ec6b0b4..ed5eba819f 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -18,11 +18,11 @@ namespace { -osg::Matrixf getWorldTransform(const Nif::Node *node) +osg::Matrixf getWorldTransform(const Nif::Node& node) { - if(node->parent != nullptr) - return node->trafo.toMatrix() * getWorldTransform(node->parent); - return node->trafo.toMatrix(); + if(node.parent != nullptr) + return node.trafo.toMatrix() * getWorldTransform(*node.parent); + return node.trafo.toMatrix(); } bool pathFileNameStartsWithX(const std::string& path) @@ -99,12 +99,12 @@ void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, co } } -void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiGeometry* geometry, const osg::Matrixf &transform = osg::Matrixf()) +void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiGeometry& geometry, const osg::Matrixf &transform = osg::Matrixf()) { - if (geometry->recType == Nif::RC_NiTriShape || geometry->recType == Nif::RC_BSLODTriShape) - fillTriangleMesh(mesh, static_cast(geometry->data.get()), transform); - else if (geometry->recType == Nif::RC_NiTriStrips) - fillTriangleMesh(mesh, static_cast(geometry->data.get()), transform); + if (geometry.recType == Nif::RC_NiTriShape || geometry.recType == Nif::RC_BSLODTriShape) + fillTriangleMesh(mesh, static_cast(geometry.data.get()), transform); + else if (geometry.recType == Nif::RC_NiTriStrips) + fillTriangleMesh(mesh, static_cast(geometry.data.get()), transform); } } @@ -141,7 +141,7 @@ osg::ref_ptr BulletNifLoader::load(const Nif::File& nif) // Try to find a valid bounding box first. If one's found for any root node, use that. for (const Nif::Node* node : roots) { - if (findBoundingBox(node, filename)) + if (findBoundingBox(*node, filename)) { const btVector3 extents = Misc::Convert::toBullet(mShape->mCollisionBox.mExtents); const btVector3 center = Misc::Convert::toBullet(mShape->mCollisionBox.mCenter); @@ -164,8 +164,8 @@ osg::ref_ptr BulletNifLoader::load(const Nif::File& nif) // from the collision data present in every root node. for (const Nif::Node* node : roots) { - bool autogenerated = hasAutoGeneratedCollision(node); - handleNode(filename, node, 0, autogenerated, isAnimated, autogenerated); + bool autogenerated = hasAutoGeneratedCollision(*node); + handleNode(filename, *node, 0, autogenerated, isAnimated, autogenerated); } if (mCompoundShape) @@ -198,41 +198,40 @@ osg::ref_ptr BulletNifLoader::load(const Nif::File& nif) // Find a boundingBox in the node hierarchy. // Return: use bounding box for collision? -bool BulletNifLoader::findBoundingBox(const Nif::Node* node, const std::string& filename) +bool BulletNifLoader::findBoundingBox(const Nif::Node& node, const std::string& filename) { - if (node->hasBounds) + if (node.hasBounds) { - unsigned int type = node->bounds.type; + unsigned int type = node.bounds.type; switch (type) { case Nif::NiBoundingVolume::Type::BOX_BV: - mShape->mCollisionBox.mExtents = node->bounds.box.extents; - mShape->mCollisionBox.mCenter = node->bounds.box.center; + mShape->mCollisionBox.mExtents = node.bounds.box.extents; + mShape->mCollisionBox.mCenter = node.bounds.box.center; break; default: { std::stringstream warning; - warning << "Unsupported NiBoundingVolume type " << type << " in node " << node->recIndex; + warning << "Unsupported NiBoundingVolume type " << type << " in node " << node.recIndex; warning << " in file " << filename; warn(warning.str()); } } - if (node->flags & Nif::NiNode::Flag_BBoxCollision) + if (node.flags & Nif::NiNode::Flag_BBoxCollision) { return true; } } - const Nif::NiNode *ninode = dynamic_cast(node); - if(ninode) + if (const Nif::NiNode *ninode = dynamic_cast(&node)) { const Nif::NodeList &list = ninode->children; for(size_t i = 0;i < list.length();i++) { if(!list[i].empty()) { - if (findBoundingBox(list[i].getPtr(), filename)) + if (findBoundingBox(list[i].get(), filename)) return true; } } @@ -240,10 +239,9 @@ bool BulletNifLoader::findBoundingBox(const Nif::Node* node, const std::string& return false; } -bool BulletNifLoader::hasAutoGeneratedCollision(const Nif::Node* rootNode) +bool BulletNifLoader::hasAutoGeneratedCollision(const Nif::Node& rootNode) { - const Nif::NiNode *ninode = dynamic_cast(rootNode); - if(ninode) + if (const Nif::NiNode* ninode = dynamic_cast(&rootNode)) { const Nif::NodeList &list = ninode->children; for(size_t i = 0;i < list.length();i++) @@ -258,32 +256,32 @@ bool BulletNifLoader::hasAutoGeneratedCollision(const Nif::Node* rootNode) return true; } -void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *node, int flags, +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)) + 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; + flags |= node.flags; - if (!node->controller.empty() && node->controller->recType == Nif::RC_NiKeyframeController - && (node->controller->flags & Nif::NiNode::ControllerFlag_Active)) + if (!node.controller.empty() && node.controller->recType == Nif::RC_NiKeyframeController + && (node.controller->flags & Nif::NiNode::ControllerFlag_Active)) isAnimated = true; - isCollisionNode = isCollisionNode || (node->recType == Nif::RC_RootCollisionNode); + isCollisionNode = isCollisionNode || (node.recType == Nif::RC_RootCollisionNode); // Don't collide with AvoidNode shapes - avoid = avoid || (node->recType == Nif::RC_AvoidNode); + avoid = avoid || (node.recType == Nif::RC_AvoidNode); // We encountered a RootCollisionNode inside autogenerated mesh. It is not right. - if (node->recType == Nif::RC_RootCollisionNode && autogenerated) + if (node.recType == Nif::RC_RootCollisionNode && autogenerated) Log(Debug::Info) << "RootCollisionNode is not attached to the root node in " << fileName << ". Treating it as a common NiTriShape."; // Check for extra data - for (Nif::ExtraPtr e = node->extra; !e.empty(); e = e->next) + for (Nif::ExtraPtr e = node.extra; !e.empty(); e = e->next) { if (e->recType == Nif::RC_NiStringExtraData) { @@ -310,61 +308,58 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *n // NOTE: a trishape with hasBounds=true, but no BBoxCollision flag should NOT go through handleNiTriShape! // It must be ignored completely. // (occurs in tr_ex_imp_wall_arch_04.nif) - if(!node->hasBounds && (node->recType == Nif::RC_NiTriShape - || node->recType == Nif::RC_NiTriStrips - || node->recType == Nif::RC_BSLODTriShape)) + if(!node.hasBounds && (node.recType == Nif::RC_NiTriShape + || node.recType == Nif::RC_NiTriStrips + || node.recType == Nif::RC_BSLODTriShape)) { handleNiTriShape(node, flags, getWorldTransform(node), isAnimated, avoid); } } // For NiNodes, loop through children - const Nif::NiNode *ninode = dynamic_cast(node); - if(ninode) + if (const Nif::NiNode *ninode = dynamic_cast(&node)) { const Nif::NodeList &list = ninode->children; for(size_t i = 0;i < list.length();i++) { if(!list[i].empty()) - handleNode(fileName, list[i].getPtr(), flags, isCollisionNode, isAnimated, autogenerated, avoid); + handleNode(fileName, list[i].get(), flags, isCollisionNode, isAnimated, autogenerated, avoid); } } } -void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, const osg::Matrixf &transform, +void BulletNifLoader::handleNiTriShape(const Nif::Node& nifNode, int flags, const osg::Matrixf &transform, bool isAnimated, bool avoid) { - assert(nifNode != nullptr); - // If the object was marked "NCO" earlier, it shouldn't collide with // anything. So don't do anything. if ((flags & 0x800)) return; - auto niGeometry = static_cast(nifNode); - if (niGeometry->data.empty() || niGeometry->data->vertices.empty()) + const Nif::NiGeometry& niGeometry = static_cast(nifNode); + if (niGeometry.data.empty() || niGeometry.data->vertices.empty()) return; - if (niGeometry->recType == Nif::RC_NiTriShape || niGeometry->recType == Nif::RC_BSLODTriShape) + if (niGeometry.recType == Nif::RC_NiTriShape || niGeometry.recType == Nif::RC_BSLODTriShape) { - if (niGeometry->data->recType != Nif::RC_NiTriShapeData) + if (niGeometry.data->recType != Nif::RC_NiTriShapeData) return; - auto data = static_cast(niGeometry->data.getPtr()); + auto data = static_cast(niGeometry.data.getPtr()); if (data->triangles.empty()) return; } - else if (niGeometry->recType == Nif::RC_NiTriStrips) + else if (niGeometry.recType == Nif::RC_NiTriStrips) { - if (niGeometry->data->recType != Nif::RC_NiTriStripsData) + if (niGeometry.data->recType != Nif::RC_NiTriStripsData) return; - auto data = static_cast(niGeometry->data.getPtr()); + auto data = static_cast(niGeometry.data.getPtr()); if (data->strips.empty()) return; } - if (!niGeometry->skin.empty()) + if (!niGeometry.skin.empty()) isAnimated = false; if (isAnimated) @@ -382,20 +377,16 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons std::unique_ptr childShape(new Resource::TriangleMeshShape(childMesh.get(), true)); childMesh.release(); - float scale = nifNode->trafo.scale; - const Nif::Node* parent = nifNode; - while (parent->parent) - { - parent = parent->parent; + float scale = nifNode.trafo.scale; + for (const Nif::Node* parent = nifNode.parent; parent != nullptr; parent = parent->parent) scale *= parent->trafo.scale; - } osg::Quat q = transform.getRotate(); osg::Vec3f v = transform.getTrans(); childShape->setLocalScaling(btVector3(scale, scale, scale)); btTransform trans(btQuaternion(q.x(), q.y(), q.z(), q.w()), btVector3(v.x(), v.y(), v.z())); - mShape->mAnimatedShapes.emplace(nifNode->recIndex, mCompoundShape->getNumChildShapes()); + mShape->mAnimatedShapes.emplace(nifNode.recIndex, mCompoundShape->getNumChildShapes()); mCompoundShape->addChildShape(trans, childShape.get()); childShape.release(); diff --git a/components/nifbullet/bulletnifloader.hpp b/components/nifbullet/bulletnifloader.hpp index 3d6a95e09f..5a17a4240c 100644 --- a/components/nifbullet/bulletnifloader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -52,14 +52,14 @@ public: osg::ref_ptr load(const Nif::File& file); private: - bool findBoundingBox(const Nif::Node* node, const std::string& filename); + bool findBoundingBox(const Nif::Node& node, const std::string& filename); - void handleNode(const std::string& fileName, Nif::Node const *node, int flags, bool isCollisionNode, + void handleNode(const std::string& fileName, const Nif::Node& node, int flags, bool isCollisionNode, bool isAnimated=false, bool autogenerated=false, bool avoid=false); - bool hasAutoGeneratedCollision(const Nif::Node *rootNode); + bool hasAutoGeneratedCollision(const Nif::Node& rootNode); - void handleNiTriShape(const Nif::Node *nifNode, int flags, const osg::Matrixf& transform, bool isAnimated, bool avoid); + void handleNiTriShape(const Nif::Node& nifNode, int flags, const osg::Matrixf& transform, bool isAnimated, bool avoid); std::unique_ptr mCompoundShape;