|
|
|
@ -34,11 +34,10 @@ bool pathFileNameStartsWithX(const std::string& path)
|
|
|
|
|
|
|
|
|
|
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()));
|
|
|
|
|
|
|
|
|
|
const std::vector<osg::Vec3f> &vertices = data.vertices;
|
|
|
|
|
const std::vector<unsigned short> &triangles = data.triangles;
|
|
|
|
|
mesh.preallocateVertices(static_cast<int>(vertices.size()));
|
|
|
|
|
mesh.preallocateIndices(static_cast<int>(triangles.size()));
|
|
|
|
|
|
|
|
|
|
for (std::size_t i = 0; i < triangles.size(); i += 3)
|
|
|
|
|
{
|
|
|
|
@ -54,8 +53,6 @@ void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, co
|
|
|
|
|
{
|
|
|
|
|
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>(vertices.size()));
|
|
|
|
|
int numTriangles = 0;
|
|
|
|
|
for (const std::vector<unsigned short>& strip : strips)
|
|
|
|
@ -102,12 +99,12 @@ void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiTriStripsData& data, co
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::Node* nifNode, const osg::Matrixf &transform = osg::Matrixf())
|
|
|
|
|
void fillTriangleMesh(btTriangleMesh& mesh, const Nif::NiGeometry* geometry, const osg::Matrixf &transform = osg::Matrixf())
|
|
|
|
|
{
|
|
|
|
|
if (nifNode->recType == Nif::RC_NiTriShape)
|
|
|
|
|
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);
|
|
|
|
|
if (geometry->recType == Nif::RC_NiTriShape)
|
|
|
|
|
fillTriangleMesh(mesh, static_cast<const Nif::NiTriShapeData&>(geometry->data.get()), transform);
|
|
|
|
|
else if (geometry->recType == Nif::RC_NiTriStrips)
|
|
|
|
|
fillTriangleMesh(mesh, static_cast<const Nif::NiTriStripsData&>(geometry->data.get()), transform);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
@ -341,23 +338,31 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
|
|
|
|
if ((flags & 0x800))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (nifNode->recType == Nif::RC_NiTriShape)
|
|
|
|
|
auto niGeometry = static_cast<const Nif::NiGeometry*>(nifNode);
|
|
|
|
|
if (niGeometry->data.empty() || niGeometry->data->vertices.empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (niGeometry->recType == Nif::RC_NiTriShape)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTriShape* shape = static_cast<const Nif::NiTriShape*>(nifNode);
|
|
|
|
|
if (!shape->skin.empty())
|
|
|
|
|
isAnimated = false;
|
|
|
|
|
if (shape->data.empty() || shape->data->triangles.empty())
|
|
|
|
|
if (niGeometry->data->recType != Nif::RC_NiTriShapeData)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
auto data = static_cast<const Nif::NiTriShapeData*>(niGeometry->data.getPtr());
|
|
|
|
|
if (data->triangles.empty())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else if (niGeometry->recType == Nif::RC_NiTriStrips)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTriStrips* shape = static_cast<const Nif::NiTriStrips*>(nifNode);
|
|
|
|
|
if (!shape->skin.empty())
|
|
|
|
|
isAnimated = false;
|
|
|
|
|
if (shape->data.empty() || shape->data->strips.empty())
|
|
|
|
|
if (niGeometry->data->recType != Nif::RC_NiTriStripsData)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
auto data = static_cast<const Nif::NiTriStripsData*>(niGeometry->data.getPtr());
|
|
|
|
|
if (data->strips.empty())
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!niGeometry->skin.empty())
|
|
|
|
|
isAnimated = false;
|
|
|
|
|
|
|
|
|
|
if (isAnimated)
|
|
|
|
|
{
|
|
|
|
@ -366,7 +371,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh);
|
|
|
|
|
|
|
|
|
|
fillTriangleMesh(*childMesh, nifNode);
|
|
|
|
|
fillTriangleMesh(*childMesh, niGeometry);
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true));
|
|
|
|
|
childMesh.release();
|
|
|
|
@ -394,7 +399,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
|
|
|
|
if (!mAvoidStaticMesh)
|
|
|
|
|
mAvoidStaticMesh.reset(new btTriangleMesh(false));
|
|
|
|
|
|
|
|
|
|
fillTriangleMesh(*mAvoidStaticMesh, nifNode, transform);
|
|
|
|
|
fillTriangleMesh(*mAvoidStaticMesh, niGeometry, transform);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -402,7 +407,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::Node *nifNode, int flags, cons
|
|
|
|
|
mStaticMesh.reset(new btTriangleMesh(false));
|
|
|
|
|
|
|
|
|
|
// Static shape, just transform all vertices into position
|
|
|
|
|
fillTriangleMesh(*mStaticMesh, nifNode, transform);
|
|
|
|
|
fillTriangleMesh(*mStaticMesh, niGeometry, transform);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|