Reduce Bullet part code duplication

pull/2481/head
capostrophic 5 years ago
parent ed154f0e2c
commit 91efdf18a9

@ -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! // NOTE: a trishape with hasBounds=true, but no BBoxCollision flag should NOT go through handleNiTriShape!
// It must be ignored completely. // It must be ignored completely.
// (occurs in tr_ex_imp_wall_arch_04.nif) // (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<const Nif::NiTriShape*>(node), flags, getWorldTransform(node), isAnimated, avoid); handleNiTriShape(node, flags, getWorldTransform(node), isAnimated, avoid);
}
else if(!node->hasBounds && node->recType == Nif::RC_NiTriStrips)
{
handleNiTriStrips(static_cast<const Nif::NiTriStrips*>(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) bool isAnimated, bool avoid)
{ {
assert(shape != nullptr); assert(nifNode != nullptr);
// If the object was marked "NCO" earlier, it shouldn't collide with // If the object was marked "NCO" earlier, it shouldn't collide with
// anything. So don't do anything. // anything. So don't do anything.
if ((flags & 0x800)) if ((flags & 0x800))
{
return;
}
if (!shape->skin.empty())
isAnimated = false;
if (shape->data.empty())
return;
if (shape->data->triangles.empty())
return; return;
if (isAnimated) if (nifNode->recType == Nif::RC_NiTriShape)
{
if (!mCompoundShape)
mCompoundShape.reset(new btCompoundShape);
std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh);
fillTriangleMesh(*childMesh, shape->data.get());
std::unique_ptr<Resource::TriangleMeshShape> 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 (!mAvoidStaticMesh) const Nif::NiTriShape* shape = static_cast<const Nif::NiTriShape*>(nifNode);
mAvoidStaticMesh.reset(new btTriangleMesh(false)); if (!shape->skin.empty())
isAnimated = false;
fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform); if (shape->data.empty())
return;
if (shape->data->triangles.empty())
return;
} }
else else
{ {
if (!mStaticMesh) const Nif::NiTriStrips* shape = static_cast<const Nif::NiTriStrips*>(nifNode);
mStaticMesh.reset(new btTriangleMesh(false)); if (!shape->skin.empty())
isAnimated = false;
// Static shape, just transform all vertices into position if (shape->data.empty())
fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform); 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 (isAnimated)
{ {
if (!mCompoundShape) if (!mCompoundShape)
@ -406,13 +350,16 @@ void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags
std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh); std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh);
fillTriangleMesh(*childMesh, shape->data.get()); if (nifNode->recType == Nif::RC_NiTriShape)
fillTriangleMesh(*childMesh, static_cast<const Nif::NiTriShape*>(nifNode)->data.get());
else
fillTriangleMesh(*childMesh, static_cast<const Nif::NiTriStrips*>(nifNode)->data.get());
std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true)); std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true));
childMesh.release(); childMesh.release();
float scale = shape->trafo.scale; float scale = nifNode->trafo.scale;
const Nif::Node* parent = shape; const Nif::Node* parent = nifNode;
while (parent->parent) while (parent->parent)
{ {
parent = 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())); 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()); mCompoundShape->addChildShape(trans, childShape.get());
childShape.release(); childShape.release();
@ -434,7 +381,16 @@ void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags
if (!mAvoidStaticMesh) if (!mAvoidStaticMesh)
mAvoidStaticMesh.reset(new btTriangleMesh(false)); mAvoidStaticMesh.reset(new btTriangleMesh(false));
fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform); if (nifNode->recType == Nif::RC_NiTriShape)
{
const Nif::NiTriShape* shape = static_cast<const Nif::NiTriShape*>(nifNode);
fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform);
}
else
{
const Nif::NiTriStrips* shape = static_cast<const Nif::NiTriStrips*>(nifNode);
fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform);
}
} }
else else
{ {
@ -442,7 +398,17 @@ void BulletNifLoader::handleNiTriStrips(const Nif::NiTriStrips *shape, int flags
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, shape->data.get(), transform);
if (nifNode->recType == Nif::RC_NiTriShape)
{
const Nif::NiTriShape* shape = static_cast<const Nif::NiTriShape*>(nifNode);
fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform);
}
else
{
const Nif::NiTriStrips* shape = static_cast<const Nif::NiTriStrips*>(nifNode);
fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform);
}
} }
} }

@ -59,8 +59,7 @@ private:
bool hasAutoGeneratedCollision(const Nif::Node *rootNode); bool hasAutoGeneratedCollision(const Nif::Node *rootNode);
void handleNiTriShape(const Nif::NiTriShape *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);
void handleNiTriStrips(const Nif::NiTriStrips *shape, int flags, const osg::Matrixf& transform, bool isAnimated, bool avoid);
std::unique_ptr<btCompoundShape> mCompoundShape; std::unique_ptr<btCompoundShape> mCompoundShape;

@ -576,12 +576,8 @@ namespace NifOsg
node->setDataVariance(osg::Object::DYNAMIC); node->setDataVariance(osg::Object::DYNAMIC);
} }
if (nifNode->recType == Nif::RC_NiTriShape && isAnimated) // the same thing for animated NiTriShapes // Same thing for animated shapes
{ if ((nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips) && isAnimated)
node->setDataVariance(osg::Object::DYNAMIC);
}
if (nifNode->recType == Nif::RC_NiTriStrips && isAnimated) // the same thing for animated NiTriStrips
{ {
node->setDataVariance(osg::Object::DYNAMIC); node->setDataVariance(osg::Object::DYNAMIC);
} }

Loading…
Cancel
Save