diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 7cfdbf40f..40a9134f3 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -292,13 +292,9 @@ 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) + if(!node->hasBounds && (node->recType == Nif::RC_NiTriShape || node->recType == Nif::RC_NiTriStrips)) { - handleNiTriShape(static_cast(node), flags, getWorldTransform(node), isAnimated, avoid); - } - else if(!node->hasBounds && node->recType == Nif::RC_NiTriStrips) - { - handleNiTriStrips(static_cast(node), flags, getWorldTransform(node), isAnimated, avoid); + handleNiTriShape(node, flags, getWorldTransform(node), isAnimated, avoid); } } @@ -315,90 +311,38 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *n } } -void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf &transform, +void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, const osg::Matrixf &transform, bool isAnimated, bool avoid) { - assert(shape != nullptr); + 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; - } - - if (!shape->skin.empty()) - isAnimated = false; - - if (shape->data.empty()) - return; - if (shape->data->triangles.empty()) return; - if (isAnimated) - { - if (!mCompoundShape) - mCompoundShape.reset(new btCompoundShape); - - std::unique_ptr childMesh(new btTriangleMesh); - - fillTriangleMesh(*childMesh, shape->data.get()); - - std::unique_ptr childShape(new Resource::TriangleMeshShape(childMesh.get(), true)); - childMesh.release(); - - float scale = shape->trafo.scale; - const Nif::Node* parent = shape; - while (parent->parent) - { - 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.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes())); - - mCompoundShape->addChildShape(trans, childShape.get()); - childShape.release(); - } - else if (avoid) + if (nifNode->recType == Nif::RC_NiTriShape) { - if (!mAvoidStaticMesh) - mAvoidStaticMesh.reset(new btTriangleMesh(false)); - - fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform); + const Nif::NiTriShape* shape = static_cast(nifNode); + if (!shape->skin.empty()) + isAnimated = false; + if (shape->data.empty()) + return; + if (shape->data->triangles.empty()) + return; } else { - if (!mStaticMesh) - mStaticMesh.reset(new btTriangleMesh(false)); - - // Static shape, just transform all vertices into position - fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform); + const Nif::NiTriStrips* shape = static_cast(nifNode); + if (!shape->skin.empty()) + isAnimated = false; + if (shape->data.empty()) + return; + if (shape->data->strips.empty()) + return; } -} -void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags, const osg::Matrixf &transform, - bool isAnimated, bool avoid) -{ - assert(shape != nullptr); - - // If the object was marked "NCO" earlier, it shouldn't collide with - // anything. So don't do anything. - if ((flags & 0x800)) - return; - if (!shape->skin.empty()) - isAnimated = false; - if (shape->data.empty()) - return; - if (shape->data->strips.empty()) - return; - if (isAnimated) { if (!mCompoundShape) @@ -406,13 +350,16 @@ void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags std::unique_ptr childMesh(new btTriangleMesh); - fillTriangleMesh(*childMesh, shape->data.get()); + if (nifNode->recType == Nif::RC_NiTriShape) + fillTriangleMesh(*childMesh, static_cast(nifNode)->data.get()); + else + fillTriangleMesh(*childMesh, static_cast(nifNode)->data.get()); std::unique_ptr childShape(new Resource::TriangleMeshShape(childMesh.get(), true)); childMesh.release(); - float scale = shape->trafo.scale; - const Nif::Node* parent = shape; + float scale = nifNode->trafo.scale; + const Nif::Node* parent = nifNode; while (parent->parent) { parent = parent->parent; @@ -424,7 +371,7 @@ void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags btTransform trans(btQuaternion(q.x(), q.y(), q.z(), q.w()), btVector3(v.x(), v.y(), v.z())); - mShape->mAnimatedShapes.emplace(shape->recIndex, mCompoundShape->getNumChildShapes()); + mShape->mAnimatedShapes.emplace(nifNode->recIndex, mCompoundShape->getNumChildShapes()); mCompoundShape->addChildShape(trans, childShape.get()); childShape.release(); @@ -434,7 +381,16 @@ void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags if (!mAvoidStaticMesh) mAvoidStaticMesh.reset(new btTriangleMesh(false)); - fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform); + if (nifNode->recType == Nif::RC_NiTriShape) + { + const Nif::NiTriShape* shape = static_cast(nifNode); + fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform); + } + else + { + const Nif::NiTriStrips* shape = static_cast(nifNode); + fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform); + } } else { @@ -442,7 +398,17 @@ void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags mStaticMesh.reset(new btTriangleMesh(false)); // Static shape, just transform all vertices into position - fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform); + + if (nifNode->recType == Nif::RC_NiTriShape) + { + const Nif::NiTriShape* shape = static_cast(nifNode); + fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform); + } + else + { + const Nif::NiTriStrips* shape = static_cast(nifNode); + fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform); + } } } diff --git a/components/nifbullet/bulletnifloader.hpp b/components/nifbullet/bulletnifloader.hpp index afc8772cd..e423e5149 100644 --- a/components/nifbullet/bulletnifloader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -59,8 +59,7 @@ private: bool hasAutoGeneratedCollision(const Nif::Node *rootNode); - void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf& transform, bool isAnimated, bool avoid); - void handleNiTriStrips(const Nif::NiTriStrips *shape, 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; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index d4ecee0e8..f5f36a36d 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -576,12 +576,8 @@ namespace NifOsg node->setDataVariance(osg::Object::DYNAMIC); } - if (nifNode->recType == Nif::RC_NiTriShape && isAnimated) // the same thing for animated NiTriShapes - { - node->setDataVariance(osg::Object::DYNAMIC); - } - - if (nifNode->recType == Nif::RC_NiTriStrips && isAnimated) // the same thing for animated NiTriStrips + // Same thing for animated shapes + if ((nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips) && isAnimated) { node->setDataVariance(osg::Object::DYNAMIC); }