mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-20 20:41:33 +00:00
Reduce Bullet part code duplication
This commit is contained in:
parent
ed154f0e2c
commit
91efdf18a9
3 changed files with 53 additions and 92 deletions
|
@ -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,25 +311,37 @@ 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;
|
return;
|
||||||
|
|
||||||
|
if (nifNode->recType == Nif::RC_NiTriShape)
|
||||||
|
{
|
||||||
|
const Nif::NiTriShape* shape = static_cast<const Nif::NiTriShape*>(nifNode);
|
||||||
|
if (!shape->skin.empty())
|
||||||
|
isAnimated = false;
|
||||||
|
if (shape->data.empty())
|
||||||
|
return;
|
||||||
|
if (shape->data->triangles.empty())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const Nif::NiTriStrips* shape = static_cast<const Nif::NiTriStrips*>(nifNode);
|
||||||
|
if (!shape->skin.empty())
|
||||||
|
isAnimated = false;
|
||||||
|
if (shape->data.empty())
|
||||||
|
return;
|
||||||
|
if (shape->data->strips.empty())
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shape->skin.empty())
|
|
||||||
isAnimated = false;
|
|
||||||
|
|
||||||
if (shape->data.empty())
|
|
||||||
return;
|
|
||||||
if (shape->data->triangles.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (isAnimated)
|
if (isAnimated)
|
||||||
{
|
{
|
||||||
|
@ -342,13 +350,16 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *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;
|
||||||
|
@ -360,7 +371,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *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.insert(std::make_pair(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();
|
||||||
|
@ -370,71 +381,16 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *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)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!mStaticMesh)
|
|
||||||
mStaticMesh.reset(new btTriangleMesh(false));
|
|
||||||
|
|
||||||
// Static shape, just transform all vertices into position
|
|
||||||
fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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 (!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;
|
const Nif::NiTriShape* shape = static_cast<const Nif::NiTriShape*>(nifNode);
|
||||||
scale *= parent->trafo.scale;
|
fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const Nif::NiTriStrips* shape = static_cast<const Nif::NiTriStrips*>(nifNode);
|
||||||
|
fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform);
|
||||||
}
|
}
|
||||||
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.emplace(shape->recIndex, mCompoundShape->getNumChildShapes());
|
|
||||||
|
|
||||||
mCompoundShape->addChildShape(trans, childShape.get());
|
|
||||||
childShape.release();
|
|
||||||
}
|
|
||||||
else if (avoid)
|
|
||||||
{
|
|
||||||
if (!mAvoidStaticMesh)
|
|
||||||
mAvoidStaticMesh.reset(new btTriangleMesh(false));
|
|
||||||
|
|
||||||
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…
Reference in a new issue