diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 15834ffade..5b531121ee 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -8,6 +8,7 @@ #include +#include #include #include @@ -24,11 +25,6 @@ osg::Matrixf getWorldTransform(const Nif::Node *node) return node->trafo.toMatrix(); } -btVector3 getbtVector(const osg::Vec3f &v) -{ - return btVector3(v.x(), v.y(), v.z()); -} - bool pathFileNameStartsWithX(const std::string& path) { const std::size_t slashpos = path.find_last_of("/\\"); @@ -36,7 +32,7 @@ bool pathFileNameStartsWithX(const std::string& path) return letterPos < path.size() && (path[letterPos] == 'x' || path[letterPos] == 'X'); } -void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriShapeData& data, const osg::Matrixf &transform) +void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriShapeData& data, const osg::Matrixf &transform) { mesh.preallocateVertices(static_cast(data.vertices.size())); mesh.preallocateIndices(static_cast(data.triangles.size())); @@ -47,20 +43,20 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriShapeDa for (std::size_t i = 0; i < triangles.size(); i += 3) { mesh.addTriangle( - getbtVector(vertices[triangles[i + 0]] * transform), - getbtVector(vertices[triangles[i + 1]] * transform), - getbtVector(vertices[triangles[i + 2]] * transform) + Misc::Convert::toBullet(vertices[triangles[i + 0]] * transform), + Misc::Convert::toBullet(vertices[triangles[i + 1]] * transform), + Misc::Convert::toBullet(vertices[triangles[i + 2]] * transform) ); } } -void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, const osg::Matrixf &transform) +void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, const osg::Matrixf &transform) { const std::vector &vertices = data.vertices; const std::vector> &strips = data.strips; if (vertices.empty() || strips.empty()) return; - mesh.preallocateVertices(static_cast(data.vertices.size())); + mesh.preallocateVertices(static_cast(vertices.size())); int numTriangles = 0; for (const std::vector& strip : strips) { @@ -88,17 +84,17 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsD if (i%2==0) { mesh.addTriangle( - getbtVector(vertices[a] * transform), - getbtVector(vertices[b] * transform), - getbtVector(vertices[c] * transform) + Misc::Convert::toBullet(vertices[a] * transform), + Misc::Convert::toBullet(vertices[b] * transform), + Misc::Convert::toBullet(vertices[c] * transform) ); } else { mesh.addTriangle( - getbtVector(vertices[a] * transform), - getbtVector(vertices[c] * transform), - getbtVector(vertices[b] * transform) + Misc::Convert::toBullet(vertices[a] * transform), + Misc::Convert::toBullet(vertices[c] * transform), + Misc::Convert::toBullet(vertices[b] * transform) ); } } @@ -106,17 +102,12 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsD } } -void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::Node* nifNode, const osg::Matrixf &transform) +void fillTriangleMesh(btTriangleMesh& mesh, const Nif::Node* nifNode, const osg::Matrixf &transform = osg::Matrixf()) { if (nifNode->recType == Nif::RC_NiTriShape) - fillTriangleMeshWithTransform(mesh, static_cast(nifNode)->data.get(), transform); - else // if (nifNode->recType == Nif::RC_NiTriStrips) - fillTriangleMeshWithTransform(mesh, static_cast(nifNode)->data.get(), transform); -} - -void fillTriangleMesh(btTriangleMesh& mesh, const Nif::Node* node) -{ - fillTriangleMeshWithTransform(mesh, node, osg::Matrixf()); + fillTriangleMesh(mesh, static_cast(nifNode)->data.get(), transform); + else if (nifNode->recType == Nif::RC_NiTriStrips) + fillTriangleMesh(mesh, static_cast(nifNode)->data.get(), transform); } } @@ -149,10 +140,12 @@ osg::ref_ptr BulletNifLoader::load(const Nif::File& nif) if (findBoundingBox(node)) { + const btVector3 halfExtents = Misc::Convert::toBullet(mShape->mCollisionBoxHalfExtents); + const btVector3 origin = Misc::Convert::toBullet(mShape->mCollisionBoxTranslate); std::unique_ptr compound (new btCompoundShape); - std::unique_ptr boxShape(new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents))); + std::unique_ptr boxShape(new btBoxShape(halfExtents)); btTransform transform = btTransform::getIdentity(); - transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate)); + transform.setOrigin(origin); compound->addChildShape(transform, boxShape.get()); boxShape.release(); @@ -383,7 +376,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons if (!mAvoidStaticMesh) mAvoidStaticMesh.reset(new btTriangleMesh(false)); - fillTriangleMeshWithTransform(*mAvoidStaticMesh, nifNode, transform); + fillTriangleMesh(*mAvoidStaticMesh, nifNode, transform); } else { @@ -391,7 +384,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons mStaticMesh.reset(new btTriangleMesh(false)); // Static shape, just transform all vertices into position - fillTriangleMeshWithTransform(*mStaticMesh, nifNode, transform); + fillTriangleMesh(*mStaticMesh, nifNode, transform); } } diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 7a592fb4a0..805283b428 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -60,6 +60,18 @@ namespace } } + bool isTypeGeometry(int type) + { + switch (type) + { + case Nif::RC_NiTriShape: + case Nif::RC_NiTriStrips: + case Nif::RC_NiLines: + return true; + } + return false; + } + // Collect all properties affecting the given drawable that should be handled on drawable basis rather than on the node hierarchy above it. void collectDrawableProperties(const Nif::Node* nifNode, std::vector& out) { @@ -528,7 +540,19 @@ namespace NifOsg // - finding a random child NiNode in NiBspArrayController node->setUserValue("recIndex", nifNode->recIndex); + std::vector extraCollection; + for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next) + extraCollection.emplace_back(e); + + for (size_t i = 0; i < nifNode->extralist.length(); ++i) + { + Nif::ExtraPtr e = nifNode->extralist[i]; + if (!e.empty()) + extraCollection.emplace_back(e); + } + + for (const auto& e : extraCollection) { if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys) { @@ -584,7 +608,7 @@ namespace NifOsg applyNodeProperties(nifNode, node, composite, imageManager, boundTextures, animflags); - const bool isGeometry = nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines; + const bool isGeometry = isTypeGeometry(nifNode->recType); if (isGeometry && !skipMeshes) { @@ -1175,7 +1199,7 @@ namespace NifOsg void handleGeometry(const Nif::Node* nifNode, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) { - assert(nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines); + assert(isTypeGeometry(nifNode->recType)); osg::ref_ptr drawable; osg::ref_ptr geom (new osg::Geometry); handleNiGeometry(nifNode, geom, parentNode, composite, boundTextures, animflags); @@ -1220,7 +1244,7 @@ namespace NifOsg void handleSkinnedGeometry(const Nif::Node *nifNode, osg::Group *parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) { - assert(nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines); + assert(isTypeGeometry(nifNode->recType)); osg::ref_ptr geometry (new osg::Geometry); handleNiGeometry(nifNode, geometry, parentNode, composite, boundTextures, animflags); osg::ref_ptr rig(new SceneUtil::RigGeometry);