mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-20 10:11:33 +00:00
Merge pull request #1986 from akortunov/rootfix
[Regression] Handle RootCollisionNode exactly as in original engine
This commit is contained in:
commit
3c53fe16e9
3 changed files with 19 additions and 31 deletions
|
@ -929,10 +929,8 @@ namespace
|
||||||
mNiStringExtraData.string = "MRK";
|
mNiStringExtraData.string = "MRK";
|
||||||
mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
|
mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
|
||||||
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData);
|
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData);
|
||||||
mNiNode3.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiTriShape)}));
|
||||||
mNiNode3.recType = Nif::RC_RootCollisionNode;
|
mNiNode2.recType = Nif::RC_RootCollisionNode;
|
||||||
mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(nullptr), Nif::NodePtr(&mNiNode3)}));
|
|
||||||
mNiNode2.recType = Nif::RC_NiNode;
|
|
||||||
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiNode2)}));
|
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({Nif::NodePtr(&mNiNode2)}));
|
||||||
mNiNode.recType = Nif::RC_NiNode;
|
mNiNode.recType = Nif::RC_NiNode;
|
||||||
|
|
||||||
|
|
|
@ -96,17 +96,14 @@ osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
bool autogenerated = hasAutoGeneratedCollision(node);
|
||||||
|
|
||||||
// files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource).
|
// files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource).
|
||||||
// assume all nodes in the file will be animated
|
// assume all nodes in the file will be animated
|
||||||
const auto filename = nif.getFilename();
|
const auto filename = nif.getFilename();
|
||||||
const bool isAnimated = pathFileNameStartsWithX(filename);
|
const bool isAnimated = pathFileNameStartsWithX(filename);
|
||||||
|
|
||||||
// If the mesh has RootCollisionNode, attached to actual root node, use it as collision mesh
|
handleNode(filename, node, 0, autogenerated, isAnimated, autogenerated);
|
||||||
const Nif::Node* rootCollisionNode = getCollisionNode(node);
|
|
||||||
if (rootCollisionNode)
|
|
||||||
handleNode(filename, rootCollisionNode, 0, false, isAnimated, false);
|
|
||||||
else
|
|
||||||
handleNode(filename, node, 0, true, isAnimated, true);
|
|
||||||
|
|
||||||
if (mCompoundShape)
|
if (mCompoundShape)
|
||||||
{
|
{
|
||||||
|
@ -163,31 +160,22 @@ bool BulletNifLoader::findBoundingBox(const Nif::Node* node, int flags)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Nif::Node* BulletNifLoader::getCollisionNode(const Nif::Node* rootNode)
|
bool BulletNifLoader::hasAutoGeneratedCollision(const Nif::Node* rootNode)
|
||||||
{
|
{
|
||||||
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(rootNode);
|
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(rootNode);
|
||||||
if(ninode)
|
if(ninode)
|
||||||
{
|
{
|
||||||
// If root NiNode has only other NiNode as child, consider it as a wrapper, not as actual root node
|
|
||||||
const Nif::NodeList &list = ninode->children;
|
const Nif::NodeList &list = ninode->children;
|
||||||
if (list.length() == 1 &&
|
for(size_t i = 0;i < list.length();i++)
|
||||||
rootNode->recType == Nif::RC_NiNode &&
|
|
||||||
list[0].getPtr()->recType == Nif::RC_NiNode)
|
|
||||||
{
|
{
|
||||||
return getCollisionNode(list[0].getPtr());
|
if(!list[i].empty())
|
||||||
}
|
{
|
||||||
|
if(list[i].getPtr()->recType == Nif::RC_RootCollisionNode)
|
||||||
for(size_t i = 0; i < list.length(); i++)
|
return false;
|
||||||
{
|
}
|
||||||
if(list[i].empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const Nif::Node* childNode = list[i].getPtr();
|
|
||||||
if(childNode->recType == Nif::RC_RootCollisionNode)
|
|
||||||
return childNode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *node, int flags,
|
void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *node, int flags,
|
||||||
|
@ -203,13 +191,14 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *n
|
||||||
|
|
||||||
isCollisionNode = isCollisionNode || (node->recType == Nif::RC_RootCollisionNode);
|
isCollisionNode = isCollisionNode || (node->recType == Nif::RC_RootCollisionNode);
|
||||||
|
|
||||||
if (node->recType == Nif::RC_RootCollisionNode && autogenerated)
|
|
||||||
Log(Debug::Info) << "Found RootCollisionNode attached to non-root node in " << fileName << ". Treat it as a common NiTriShape.";
|
|
||||||
|
|
||||||
// Don't collide with AvoidNode shapes
|
// Don't collide with AvoidNode shapes
|
||||||
if(node->recType == Nif::RC_AvoidNode)
|
if(node->recType == Nif::RC_AvoidNode)
|
||||||
flags |= 0x800;
|
flags |= 0x800;
|
||||||
|
|
||||||
|
// We encountered a RootCollisionNode inside autogenerated mesh. It is not right.
|
||||||
|
if (node->recType == Nif::RC_RootCollisionNode && autogenerated)
|
||||||
|
Log(Debug::Info) << "Found RootCollisionNode attached to non-root node in " << fileName << ". Treat it as a common NiTriShape.";
|
||||||
|
|
||||||
// Check for extra data
|
// Check for extra data
|
||||||
Nif::Extra const *e = node;
|
Nif::Extra const *e = node;
|
||||||
while (!e->extra.empty())
|
while (!e->extra.empty())
|
||||||
|
@ -234,6 +223,7 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *n
|
||||||
// Marker can still have collision if the model explicitely specifies it via a RootCollisionNode.
|
// Marker can still have collision if the model explicitely specifies it via a RootCollisionNode.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ private:
|
||||||
|
|
||||||
void handleNode(const std::string& fileName, Nif::Node const *node, int flags, bool isCollisionNode, bool isAnimated=false, bool autogenerated=false);
|
void handleNode(const std::string& fileName, Nif::Node const *node, int flags, bool isCollisionNode, bool isAnimated=false, bool autogenerated=false);
|
||||||
|
|
||||||
const Nif::Node* getCollisionNode(const Nif::Node* rootNode);
|
bool hasAutoGeneratedCollision(const Nif::Node *rootNode);
|
||||||
|
|
||||||
void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf& transform, bool isAnimated);
|
void handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf& transform, bool isAnimated);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue