mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +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/debug/debuglog.hpp>
|
||||||
|
|
||||||
|
#include <components/misc/convert.hpp>
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
#include <components/nif/node.hpp>
|
#include <components/nif/node.hpp>
|
||||||
@ -24,11 +25,6 @@ osg::Matrixf getWorldTransform(const Nif::Node *node)
|
|||||||
return node->trafo.toMatrix();
|
return node->trafo.toMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
btVector3 getbtVector(const osg::Vec3f &v)
|
|
||||||
{
|
|
||||||
return btVector3(v.x(), v.y(), v.z());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pathFileNameStartsWithX(const std::string& path)
|
bool pathFileNameStartsWithX(const std::string& path)
|
||||||
{
|
{
|
||||||
const std::size_t slashpos = path.find_last_of("/\\");
|
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');
|
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.preallocateVertices(static_cast<int>(data.vertices.size()));
|
||||||
mesh.preallocateIndices(static_cast<int>(data.triangles.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)
|
for (std::size_t i = 0; i < triangles.size(); i += 3)
|
||||||
{
|
{
|
||||||
mesh.addTriangle(
|
mesh.addTriangle(
|
||||||
getbtVector(vertices[triangles[i + 0]] * transform),
|
Misc::Convert::toBullet(vertices[triangles[i + 0]] * transform),
|
||||||
getbtVector(vertices[triangles[i + 1]] * transform),
|
Misc::Convert::toBullet(vertices[triangles[i + 1]] * transform),
|
||||||
getbtVector(vertices[triangles[i + 2]] * 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<osg::Vec3f> &vertices = data.vertices;
|
||||||
const std::vector<std::vector<unsigned short>> &strips = data.strips;
|
const std::vector<std::vector<unsigned short>> &strips = data.strips;
|
||||||
if (vertices.empty() || strips.empty())
|
if (vertices.empty() || strips.empty())
|
||||||
return;
|
return;
|
||||||
mesh.preallocateVertices(static_cast<int>(data.vertices.size()));
|
mesh.preallocateVertices(static_cast<int>(vertices.size()));
|
||||||
int numTriangles = 0;
|
int numTriangles = 0;
|
||||||
for (const std::vector<unsigned short>& strip : strips)
|
for (const std::vector<unsigned short>& strip : strips)
|
||||||
{
|
{
|
||||||
@ -88,17 +84,17 @@ void fillTriangleMeshWithTransform(btTriangleMesh& mesh, const Nif::NiTriStripsD
|
|||||||
if (i%2==0)
|
if (i%2==0)
|
||||||
{
|
{
|
||||||
mesh.addTriangle(
|
mesh.addTriangle(
|
||||||
getbtVector(vertices[a] * transform),
|
Misc::Convert::toBullet(vertices[a] * transform),
|
||||||
getbtVector(vertices[b] * transform),
|
Misc::Convert::toBullet(vertices[b] * transform),
|
||||||
getbtVector(vertices[c] * transform)
|
Misc::Convert::toBullet(vertices[c] * transform)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mesh.addTriangle(
|
mesh.addTriangle(
|
||||||
getbtVector(vertices[a] * transform),
|
Misc::Convert::toBullet(vertices[a] * transform),
|
||||||
getbtVector(vertices[c] * transform),
|
Misc::Convert::toBullet(vertices[c] * transform),
|
||||||
getbtVector(vertices[b] * 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)
|
if (nifNode->recType == Nif::RC_NiTriShape)
|
||||||
fillTriangleMeshWithTransform(mesh, static_cast<const Nif::NiTriShape*>(nifNode)->data.get(), transform);
|
fillTriangleMesh(mesh, static_cast<const Nif::NiTriShape*>(nifNode)->data.get(), transform);
|
||||||
else // if (nifNode->recType == Nif::RC_NiTriStrips)
|
else if (nifNode->recType == Nif::RC_NiTriStrips)
|
||||||
fillTriangleMeshWithTransform(mesh, static_cast<const Nif::NiTriStrips*>(nifNode)->data.get(), transform);
|
fillTriangleMesh(mesh, static_cast<const Nif::NiTriStrips*>(nifNode)->data.get(), transform);
|
||||||
}
|
|
||||||
|
|
||||||
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::Node* node)
|
|
||||||
{
|
|
||||||
fillTriangleMeshWithTransform(mesh, node, osg::Matrixf());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -149,10 +140,12 @@ osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif)
|
|||||||
|
|
||||||
if (findBoundingBox(node))
|
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<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();
|
btTransform transform = btTransform::getIdentity();
|
||||||
transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate));
|
transform.setOrigin(origin);
|
||||||
compound->addChildShape(transform, boxShape.get());
|
compound->addChildShape(transform, boxShape.get());
|
||||||
boxShape.release();
|
boxShape.release();
|
||||||
|
|
||||||
@ -383,7 +376,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
|||||||
if (!mAvoidStaticMesh)
|
if (!mAvoidStaticMesh)
|
||||||
mAvoidStaticMesh.reset(new btTriangleMesh(false));
|
mAvoidStaticMesh.reset(new btTriangleMesh(false));
|
||||||
|
|
||||||
fillTriangleMeshWithTransform(*mAvoidStaticMesh, nifNode, transform);
|
fillTriangleMesh(*mAvoidStaticMesh, nifNode, transform);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -391,7 +384,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
|||||||
mStaticMesh.reset(new btTriangleMesh(false));
|
mStaticMesh.reset(new btTriangleMesh(false));
|
||||||
|
|
||||||
// Static shape, just transform all vertices into position
|
// 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.
|
// 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)
|
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
|
// - finding a random child NiNode in NiBspArrayController
|
||||||
node->setUserValue("recIndex", nifNode->recIndex);
|
node->setUserValue("recIndex", nifNode->recIndex);
|
||||||
|
|
||||||
|
std::vector<Nif::ExtraPtr> extraCollection;
|
||||||
|
|
||||||
for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next)
|
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)
|
if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys)
|
||||||
{
|
{
|
||||||
@ -584,7 +608,7 @@ namespace NifOsg
|
|||||||
|
|
||||||
applyNodeProperties(nifNode, node, composite, imageManager, boundTextures, animflags);
|
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)
|
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)
|
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::Drawable> drawable;
|
||||||
osg::ref_ptr<osg::Geometry> geom (new osg::Geometry);
|
osg::ref_ptr<osg::Geometry> geom (new osg::Geometry);
|
||||||
handleNiGeometry(nifNode, geom, parentNode, composite, boundTextures, animflags);
|
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,
|
void handleSkinnedGeometry(const Nif::Node *nifNode, osg::Group *parentNode, SceneUtil::CompositeStateSetUpdater* composite,
|
||||||
const std::vector<unsigned int>& boundTextures, int animflags)
|
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);
|
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
|
||||||
handleNiGeometry(nifNode, geometry, parentNode, composite, boundTextures, animflags);
|
handleNiGeometry(nifNode, geometry, parentNode, composite, boundTextures, animflags);
|
||||||
osg::ref_ptr<SceneUtil::RigGeometry> rig(new SceneUtil::RigGeometry);
|
osg::ref_ptr<SceneUtil::RigGeometry> rig(new SceneUtil::RigGeometry);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user