mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-18 13:12:50 +00:00
Misc NIF loader improvements
Bullet NIF loader cleanup Collect all extra records of a node Remove code duplication in geometry type detection in OSG-side NIF loader
This commit is contained in:
parent
7e63afdecf
commit
c79f509652
@ -8,6 +8,7 @@
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
#include <components/misc/convert.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#include <components/nif/node.hpp>
|
||||
@ -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<int>(data.vertices.size()));
|
||||
mesh.preallocateIndices(static_cast<int>(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<osg::Vec3f> &vertices = data.vertices;
|
||||
const std::vector<std::vector<unsigned short>> &strips = data.strips;
|
||||
if (vertices.empty() || strips.empty())
|
||||
return;
|
||||
mesh.preallocateVertices(static_cast<int>(data.vertices.size()));
|
||||
mesh.preallocateVertices(static_cast<int>(vertices.size()));
|
||||
int numTriangles = 0;
|
||||
for (const std::vector<unsigned short>& 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<const Nif::NiTriShape*>(nifNode)->data.get(), transform);
|
||||
else // if (nifNode->recType == Nif::RC_NiTriStrips)
|
||||
fillTriangleMeshWithTransform(mesh, static_cast<const Nif::NiTriStrips*>(nifNode)->data.get(), transform);
|
||||
}
|
||||
|
||||
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::Node* node)
|
||||
{
|
||||
fillTriangleMeshWithTransform(mesh, node, osg::Matrixf());
|
||||
fillTriangleMesh(mesh, static_cast<const Nif::NiTriShape*>(nifNode)->data.get(), transform);
|
||||
else if (nifNode->recType == Nif::RC_NiTriStrips)
|
||||
fillTriangleMesh(mesh, static_cast<const Nif::NiTriStrips*>(nifNode)->data.get(), transform);
|
||||
}
|
||||
|
||||
}
|
||||
@ -149,10 +140,12 @@ osg::ref_ptr<Resource::BulletShape> 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<btCompoundShape> compound (new btCompoundShape);
|
||||
std::unique_ptr<btBoxShape> boxShape(new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents)));
|
||||
std::unique_ptr<btBoxShape> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<const Nif::Property*>& out)
|
||||
{
|
||||
@ -528,7 +540,19 @@ namespace NifOsg
|
||||
// - finding a random child NiNode in NiBspArrayController
|
||||
node->setUserValue("recIndex", nifNode->recIndex);
|
||||
|
||||
std::vector<Nif::ExtraPtr> 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<unsigned int>& 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<osg::Drawable> drawable;
|
||||
osg::ref_ptr<osg::Geometry> 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<unsigned int>& 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<osg::Geometry> geometry (new osg::Geometry);
|
||||
handleNiGeometry(nifNode, geometry, parentNode, composite, boundTextures, animflags);
|
||||
osg::ref_ptr<SceneUtil::RigGeometry> rig(new SceneUtil::RigGeometry);
|
||||
|
Loading…
x
Reference in New Issue
Block a user