Rename Named->NiObjectNET and update everything directly related to it

BulletNifLoader: properly check if the node has animation controllers
Flatten extra data linked list
macos_ci_fix
Alexei Kotov 1 year ago
parent 9791fae2db
commit ef896faa90

@ -16,16 +16,16 @@ namespace Nif::Testing
value.mNext = ExtraPtr(nullptr); value.mNext = ExtraPtr(nullptr);
} }
inline void init(Named& value) inline void init(NiObjectNET& value)
{ {
value.extra = ExtraPtr(nullptr); value.mExtra = ExtraPtr(nullptr);
value.extralist = ExtraList(); value.mExtraList = ExtraList();
value.controller = ControllerPtr(nullptr); value.mController = ControllerPtr(nullptr);
} }
inline void init(Node& value) inline void init(Node& value)
{ {
init(static_cast<Named&>(value)); init(static_cast<NiObjectNET&>(value));
value.flags = 0; value.flags = 0;
init(value.trafo); init(value.trafo);
value.hasBounds = false; value.hasBounds = false;
@ -65,7 +65,7 @@ namespace Nif::Testing
value.phase = 0; value.phase = 0;
value.timeStart = 0; value.timeStart = 0;
value.timeStop = 0; value.timeStop = 0;
value.target = NamedPtr(nullptr); value.target = NiObjectNETPtr(nullptr);
} }
} }

@ -837,7 +837,7 @@ namespace
copy(mTransform, mNiTriShape.trafo); copy(mTransform, mNiTriShape.trafo);
mNiTriShape.trafo.scale = 3; mNiTriShape.trafo.scale = 3;
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiTriShape.controller = Nif::ControllerPtr(&mController); mNiTriShape.mController = Nif::ControllerPtr(&mController);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
mNiNode.trafo.scale = 4; mNiNode.trafo.scale = 4;
@ -870,7 +870,7 @@ namespace
copy(mTransform, mNiTriShape2.trafo); copy(mTransform, mNiTriShape2.trafo);
mNiTriShape2.trafo.scale = 3; mNiTriShape2.trafo.scale = 3;
mNiTriShape2.parents.push_back(&mNiNode); mNiTriShape2.parents.push_back(&mNiNode);
mNiTriShape2.controller = Nif::ControllerPtr(&mController); mNiTriShape2.mController = Nif::ControllerPtr(&mController);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({
Nif::NodePtr(&mNiTriShape), Nif::NodePtr(&mNiTriShape),
Nif::NodePtr(&mNiTriShape2), Nif::NodePtr(&mNiTriShape2),
@ -998,7 +998,7 @@ namespace
{ {
mNiStringExtraData.mData = "NCC__"; mNiStringExtraData.mData = "NCC__";
mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData);
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
@ -1027,7 +1027,7 @@ namespace
mNiStringExtraData.mNext = Nif::ExtraPtr(&mNiStringExtraData2); mNiStringExtraData.mNext = Nif::ExtraPtr(&mNiStringExtraData2);
mNiStringExtraData2.mData = "NCC__"; mNiStringExtraData2.mData = "NCC__";
mNiStringExtraData2.recType = Nif::RC_NiStringExtraData; mNiStringExtraData2.recType = Nif::RC_NiStringExtraData;
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData);
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
@ -1054,7 +1054,7 @@ namespace
{ {
mNiStringExtraData.mData = "NC___"; mNiStringExtraData.mData = "NC___";
mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData);
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
@ -1082,7 +1082,7 @@ namespace
mNiStringExtraData.mNext = Nif::ExtraPtr(&mNiStringExtraData2); mNiStringExtraData.mNext = Nif::ExtraPtr(&mNiStringExtraData2);
mNiStringExtraData2.mData = "NC___"; mNiStringExtraData2.mData = "NC___";
mNiStringExtraData2.recType = Nif::RC_NiStringExtraData; mNiStringExtraData2.recType = Nif::RC_NiStringExtraData;
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData);
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
@ -1143,7 +1143,7 @@ namespace
{ {
mNiStringExtraData.mData = "MRK"; mNiStringExtraData.mData = "MRK";
mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData);
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
@ -1162,9 +1162,9 @@ namespace
{ {
mNiIntegerExtraData.mData = 32; // BSX flag "editor marker" mNiIntegerExtraData.mData = 32; // BSX flag "editor marker"
mNiIntegerExtraData.recType = Nif::RC_BSXFlags; mNiIntegerExtraData.recType = Nif::RC_BSXFlags;
mNiTriShape.extralist.push_back(Nif::ExtraPtr(&mNiIntegerExtraData)); mNiTriShape.mExtraList.push_back(Nif::ExtraPtr(&mNiIntegerExtraData));
mNiTriShape.parents.push_back(&mNiNode); mNiTriShape.parents.push_back(&mNiNode);
mNiTriShape.name = "EditorMarker"; mNiTriShape.mName = "EditorMarker";
mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
Nif::NIFFile file("test.nif"); Nif::NIFFile file("test.nif");
@ -1183,7 +1183,7 @@ namespace
{ {
mNiStringExtraData.mData = "MRK"; mNiStringExtraData.mData = "MRK";
mNiStringExtraData.recType = Nif::RC_NiStringExtraData; mNiStringExtraData.recType = Nif::RC_NiStringExtraData;
mNiTriShape.extra = Nif::ExtraPtr(&mNiStringExtraData); mNiTriShape.mExtra = Nif::ExtraPtr(&mNiStringExtraData);
mNiTriShape.parents.push_back(&mNiNode2); mNiTriShape.parents.push_back(&mNiNode2);
mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) })); mNiNode2.children = Nif::NodeList(std::vector<Nif::NodePtr>({ Nif::NodePtr(&mNiTriShape) }));
mNiNode2.recType = Nif::RC_RootCollisionNode; mNiNode2.recType = Nif::RC_RootCollisionNode;

@ -188,7 +188,7 @@ osg::Group {
Nif::BSShaderPPLightingProperty property; Nif::BSShaderPPLightingProperty property;
property.recType = Nif::RC_BSShaderPPLightingProperty; property.recType = Nif::RC_BSShaderPPLightingProperty;
property.textureSet = nullptr; property.textureSet = nullptr;
property.controller = nullptr; property.mController = nullptr;
property.type = GetParam().mShaderType; property.type = GetParam().mShaderType;
node.props.push_back(Nif::RecordPtrT<Nif::Property>(&property)); node.props.push_back(Nif::RecordPtrT<Nif::Property>(&property));
Nif::NIFFile file("test.nif"); Nif::NIFFile file("test.nif");
@ -216,7 +216,7 @@ osg::Group {
Nif::BSLightingShaderProperty property; Nif::BSLightingShaderProperty property;
property.recType = Nif::RC_BSLightingShaderProperty; property.recType = Nif::RC_BSLightingShaderProperty;
property.mTextureSet = nullptr; property.mTextureSet = nullptr;
property.controller = nullptr; property.mController = nullptr;
property.type = GetParam().mShaderType; property.type = GetParam().mShaderType;
node.props.push_back(Nif::RecordPtrT<Nif::Property>(&property)); node.props.push_back(Nif::RecordPtrT<Nif::Property>(&property));
Nif::NIFFile file("test.nif"); Nif::NIFFile file("test.nif");

@ -13,20 +13,28 @@ namespace Nif
} }
} }
void Named::read(NIFStream* nif) void NiObjectNET::read(NIFStream* nif)
{ {
name = nif->getString(); nif->read(mName);
if (nif->getVersion() < NIFStream::generateVersion(10, 0, 1, 0)) if (nif->getVersion() < NIFStream::generateVersion(10, 0, 1, 0))
extra.read(nif); mExtra.read(nif);
else else
readRecordList(nif, extralist); readRecordList(nif, mExtraList);
controller.read(nif); mController.read(nif);
}
void NiObjectNET::post(Reader& nif)
{
mExtra.post(nif);
postRecordList(nif, mExtraList);
mController.post(nif);
} }
void Named::post(Reader& nif) ExtraList NiObjectNET::getExtraList() const
{ {
extra.post(nif); ExtraList list = mExtraList;
postRecordList(nif, extralist); for (ExtraPtr extra = mExtra; !extra.empty(); extra = extra->mNext)
controller.post(nif); list.emplace_back(extra);
return list;
} }
} }

@ -40,7 +40,7 @@ namespace Nif
int flags; int flags;
float frequency, phase; float frequency, phase;
float timeStart, timeStop; float timeStart, timeStop;
NamedPtr target; NiObjectNETPtr target;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(Reader& nif) override; void post(Reader& nif) override;
@ -49,18 +49,20 @@ namespace Nif
ExtrapolationMode extrapolationMode() const { return static_cast<ExtrapolationMode>(flags & Mask); } ExtrapolationMode extrapolationMode() const { return static_cast<ExtrapolationMode>(flags & Mask); }
}; };
/// Has name, extra-data and controller /// Abstract object that has a name, extra data and controllers
struct Named : public Record struct NiObjectNET : public Record
{ {
std::string name; std::string mName;
ExtraPtr extra; ExtraPtr mExtra;
ExtraList extralist; ExtraList mExtraList;
ControllerPtr controller; ControllerPtr mController;
void read(NIFStream* nif) override; void read(NIFStream* nif) override;
void post(Reader& nif) override; void post(Reader& nif) override;
// Collect extra records attached to the object
ExtraList getExtraList() const;
}; };
using NiSequenceStreamHelper = Named;
} // Namespace }
#endif #endif

@ -77,7 +77,7 @@ namespace Nif
void Node::read(NIFStream* nif) void Node::read(NIFStream* nif)
{ {
Named::read(nif); NiObjectNET::read(nif);
flags = nif->getBethVersion() <= 26 ? nif->getUShort() : nif->getUInt(); flags = nif->getBethVersion() <= 26 ? nif->getUShort() : nif->getUInt();
trafo = nif->getTrafo(); trafo = nif->getTrafo();
@ -101,7 +101,7 @@ namespace Nif
void Node::post(Reader& nif) void Node::post(Reader& nif)
{ {
Named::post(nif); NiObjectNET::post(nif);
postRecordList(nif, props); postRecordList(nif, props);
collision.post(nif); collision.post(nif);
} }
@ -128,7 +128,7 @@ namespace Nif
// FIXME: if node 0 is *not* the only root node, this must not happen. // FIXME: if node 0 is *not* the only root node, this must not happen.
// FIXME: doing this here is awful. // FIXME: doing this here is awful.
// We want to do this on world scene graph level rather than local scene graph level. // We want to do this on world scene graph level rather than local scene graph level.
if (0 == recIndex && !Misc::StringUtils::ciEqual(name, "bip01")) if (0 == recIndex && !Misc::StringUtils::ciEqual(mName, "bip01"))
{ {
trafo = Nif::Transformation::getIdentity(); trafo = Nif::Transformation::getIdentity();
} }

@ -62,11 +62,15 @@ namespace Nif
void read(NIFStream* nif); void read(NIFStream* nif);
}; };
struct NiSequenceStreamHelper : NiObjectNET
{
};
/** A Node is an object that's part of the main NIF tree. It has /** A Node is an object that's part of the main NIF tree. It has
parent node (unless it's the root), and transformation (location parent node (unless it's the root), and transformation (location
and rotation) relative to it's parent. and rotation) relative to it's parent.
*/ */
struct Node : public Named struct Node : public NiObjectNET
{ {
enum Flags enum Flags
{ {

@ -29,7 +29,7 @@
namespace Nif namespace Nif
{ {
struct Property : public Named struct Property : public NiObjectNET
{ {
}; };

@ -115,7 +115,7 @@ namespace Nif
struct NiPosData; struct NiPosData;
struct NiVisData; struct NiVisData;
struct Controller; struct Controller;
struct Named; struct NiObjectNET;
struct NiSkinData; struct NiSkinData;
struct NiFloatData; struct NiFloatData;
struct NiMorphData; struct NiMorphData;
@ -156,7 +156,7 @@ namespace Nif
using NiPosDataPtr = RecordPtrT<NiPosData>; using NiPosDataPtr = RecordPtrT<NiPosData>;
using NiVisDataPtr = RecordPtrT<NiVisData>; using NiVisDataPtr = RecordPtrT<NiVisData>;
using ControllerPtr = RecordPtrT<Controller>; using ControllerPtr = RecordPtrT<Controller>;
using NamedPtr = RecordPtrT<Named>; using NiObjectNETPtr = RecordPtrT<NiObjectNET>;
using NiSkinDataPtr = RecordPtrT<NiSkinData>; using NiSkinDataPtr = RecordPtrT<NiSkinData>;
using NiMorphDataPtr = RecordPtrT<NiMorphData>; using NiMorphDataPtr = RecordPtrT<NiMorphData>;
using NiPixelDataPtr = RecordPtrT<NiPixelData>; using NiPixelDataPtr = RecordPtrT<NiPixelData>;

@ -6,7 +6,7 @@
namespace Nif namespace Nif
{ {
struct NiTexture : public Named struct NiTexture : public NiObjectNET
{ {
}; };

@ -277,9 +277,23 @@ namespace NifBullet
if (node.recType == Nif::RC_NiCollisionSwitch && !node.collisionActive()) if (node.recType == Nif::RC_NiCollisionSwitch && !node.collisionActive())
return; return;
if (!node.controller.empty() && node.controller->recType == Nif::RC_NiKeyframeController for (Nif::ControllerPtr ctrl = node.mController; !ctrl.empty(); ctrl = ctrl->next)
&& node.controller->isActive()) {
if (args.mAnimated)
break;
if (!ctrl->isActive())
continue;
switch (ctrl->recType)
{
case Nif::RC_NiKeyframeController:
case Nif::RC_NiPathController:
case Nif::RC_NiRollController:
args.mAnimated = true; args.mAnimated = true;
break;
default:
continue;
}
}
if (node.recType == Nif::RC_RootCollisionNode) if (node.recType == Nif::RC_RootCollisionNode)
{ {
@ -304,13 +318,7 @@ namespace NifBullet
args.mAvoid = true; args.mAvoid = true;
// Check for extra data // Check for extra data
std::vector<Nif::ExtraPtr> extraCollection; for (const auto& e : node.getExtraList())
for (Nif::ExtraPtr e = node.extra; !e.empty(); e = e->mNext)
extraCollection.emplace_back(e);
for (const auto& extraNode : node.extralist)
if (!extraNode.empty())
extraCollection.emplace_back(extraNode);
for (const auto& e : extraCollection)
{ {
if (e->recType == Nif::RC_NiStringExtraData) if (e->recType == Nif::RC_NiStringExtraData)
{ {
@ -378,7 +386,7 @@ namespace NifBullet
{ {
// mHasMarkers is specifically BSXFlags editor marker flag. // mHasMarkers is specifically BSXFlags editor marker flag.
// If this changes, the check must be corrected. // If this changes, the check must be corrected.
if (args.mHasMarkers && Misc::StringUtils::ciStartsWith(niGeometry.name, "EditorMarker")) if (args.mHasMarkers && Misc::StringUtils::ciStartsWith(niGeometry.mName, "EditorMarker"))
return; return;
if (niGeometry.data.empty() || niGeometry.data->mVertices.empty()) if (niGeometry.data.empty() || niGeometry.data->mVertices.empty())

@ -275,21 +275,28 @@ namespace NifOsg
return; return;
} }
Nif::ExtraPtr extra = seq->extra; Nif::ExtraList extraList = seq->getExtraList();
if (extra.empty() || extra->recType != Nif::RC_NiTextKeyExtraData) if (extraList.empty())
{
Log(Debug::Warning) << "NIFFile Warning: NiSequenceStreamHelper has no text keys. File: "
<< nif.getFilename();
return;
}
if (extraList[0]->recType != Nif::RC_NiTextKeyExtraData)
{ {
Log(Debug::Warning) << "NIFFile Warning: First extra data was not a NiTextKeyExtraData, but a " Log(Debug::Warning) << "NIFFile Warning: First extra data was not a NiTextKeyExtraData, but a "
<< (extra.empty() ? std::string_view("nil") : std::string_view(extra->recName)) << std::string_view(extraList[0]->recName) << ". File: " << nif.getFilename();
<< ". File: " << nif.getFilename();
return; return;
} }
extractTextKeys(static_cast<const Nif::NiTextKeyExtraData*>(extra.getPtr()), target.mTextKeys); auto textKeyExtraData = static_cast<const Nif::NiTextKeyExtraData*>(extraList[0].getPtr());
extractTextKeys(textKeyExtraData, target.mTextKeys);
extra = extra->mNext; Nif::ControllerPtr ctrl = seq->mController;
Nif::ControllerPtr ctrl = seq->controller; for (size_t i = 1; i < extraList.size() && !ctrl.empty(); i++, (ctrl = ctrl->next))
for (; !extra.empty() && !ctrl.empty(); (extra = extra->mNext), (ctrl = ctrl->next))
{ {
Nif::ExtraPtr extra = extraList[i];
if (extra->recType != Nif::RC_NiStringExtraData || ctrl->recType != Nif::RC_NiKeyframeController) if (extra->recType != Nif::RC_NiStringExtraData || ctrl->recType != Nif::RC_NiKeyframeController)
{ {
Log(Debug::Warning) << "NIFFile Warning: Unexpected extra data " << extra->recName Log(Debug::Warning) << "NIFFile Warning: Unexpected extra data " << extra->recName
@ -454,7 +461,7 @@ namespace NifOsg
static osg::ref_ptr<osg::LOD> handleLodNode(const Nif::NiLODNode* niLodNode) static osg::ref_ptr<osg::LOD> handleLodNode(const Nif::NiLODNode* niLodNode)
{ {
osg::ref_ptr<osg::LOD> lod(new osg::LOD); osg::ref_ptr<osg::LOD> lod(new osg::LOD);
lod->setName(niLodNode->name); lod->setName(niLodNode->mName);
lod->setCenterMode(osg::LOD::USER_DEFINED_CENTER); lod->setCenterMode(osg::LOD::USER_DEFINED_CENTER);
lod->setCenter(niLodNode->lodCenter); lod->setCenter(niLodNode->lodCenter);
for (unsigned int i = 0; i < niLodNode->lodLevels.size(); ++i) for (unsigned int i = 0; i < niLodNode->lodLevels.size(); ++i)
@ -469,7 +476,7 @@ namespace NifOsg
static osg::ref_ptr<osg::Switch> handleSwitchNode(const Nif::NiSwitchNode* niSwitchNode) static osg::ref_ptr<osg::Switch> handleSwitchNode(const Nif::NiSwitchNode* niSwitchNode)
{ {
osg::ref_ptr<osg::Switch> switchNode(new osg::Switch); osg::ref_ptr<osg::Switch> switchNode(new osg::Switch);
switchNode->setName(niSwitchNode->name); switchNode->setName(niSwitchNode->mName);
switchNode->setNewChildDefaultValue(false); switchNode->setNewChildDefaultValue(false);
switchNode->setSingleChildOn(niSwitchNode->initialIndex); switchNode->setSingleChildOn(niSwitchNode->initialIndex);
return switchNode; return switchNode;
@ -479,7 +486,7 @@ namespace NifOsg
{ {
const Nif::NiFltAnimationNode* niFltAnimationNode = static_cast<const Nif::NiFltAnimationNode*>(nifNode); const Nif::NiFltAnimationNode* niFltAnimationNode = static_cast<const Nif::NiFltAnimationNode*>(nifNode);
osg::ref_ptr<osg::Sequence> sequenceNode(new osg::Sequence); osg::ref_ptr<osg::Sequence> sequenceNode(new osg::Sequence);
sequenceNode->setName(niFltAnimationNode->name); sequenceNode->setName(niFltAnimationNode->mName);
if (!niFltAnimationNode->children.empty()) if (!niFltAnimationNode->children.empty())
{ {
if (niFltAnimationNode->swing()) if (niFltAnimationNode->swing())
@ -604,7 +611,7 @@ namespace NifOsg
// This takes advantage of the fact root nodes can't have additional controllers // This takes advantage of the fact root nodes can't have additional controllers
// loaded from an external .kf file (original engine just throws "can't find node" errors if you // loaded from an external .kf file (original engine just throws "can't find node" errors if you
// try). // try).
if (nifNode->parents.empty() && nifNode->controller.empty() && nifNode->trafo.isIdentity()) if (nifNode->parents.empty() && nifNode->mController.empty() && nifNode->trafo.isIdentity())
node = new osg::Group; node = new osg::Group;
dataVariance = nifNode->isBone ? osg::Object::DYNAMIC : osg::Object::STATIC; dataVariance = nifNode->isBone ? osg::Object::DYNAMIC : osg::Object::STATIC;
@ -622,7 +629,7 @@ namespace NifOsg
osg::ref_ptr<osg::Node> handleNode( osg::ref_ptr<osg::Node> handleNode(
const Nif::Node* nifNode, const Nif::Parent* parent, osg::Group* parentNode, HandleNodeArgs args) const Nif::Node* nifNode, const Nif::Parent* parent, osg::Group* parentNode, HandleNodeArgs args)
{ {
if (args.mRootNode && Misc::StringUtils::ciEqual(nifNode->name, "Bounding Box")) if (args.mRootNode && Misc::StringUtils::ciEqual(nifNode->mName, "Bounding Box"))
return nullptr; return nullptr;
osg::ref_ptr<osg::Group> node = createNode(nifNode); osg::ref_ptr<osg::Group> node = createNode(nifNode);
@ -632,7 +639,7 @@ namespace NifOsg
node->addCullCallback(new BillboardCallback); node->addCullCallback(new BillboardCallback);
} }
node->setName(nifNode->name); node->setName(nifNode->mName);
if (parentNode) if (parentNode)
parentNode->addChild(node); parentNode->addChild(node);
@ -646,16 +653,7 @@ 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 (const auto& e : nifNode->getExtraList())
for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->mNext)
extraCollection.emplace_back(e);
for (const auto& extraNode : nifNode->extralist)
if (!extraNode.empty())
extraCollection.emplace_back(extraNode);
for (const auto& e : extraCollection)
{ {
if (e->recType == Nif::RC_NiTextKeyExtraData && args.mTextKeys) if (e->recType == Nif::RC_NiTextKeyExtraData && args.mTextKeys)
{ {
@ -727,7 +725,7 @@ namespace NifOsg
if (nifNode->isHidden()) if (nifNode->isHidden())
{ {
bool hasVisController = false; bool hasVisController = false;
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) for (Nif::ControllerPtr ctrl = nifNode->mController; !ctrl.empty(); ctrl = ctrl->next)
{ {
hasVisController |= (ctrl->recType == Nif::RC_NiVisController); hasVisController |= (ctrl->recType == Nif::RC_NiVisController);
if (hasVisController) if (hasVisController)
@ -755,12 +753,12 @@ namespace NifOsg
bool skip; bool skip;
if (args.mNifVersion <= Nif::NIFFile::NIFVersion::VER_MW) if (args.mNifVersion <= Nif::NIFFile::NIFVersion::VER_MW)
{ {
skip = (args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->name, "tri editormarker")) skip = (args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->mName, "tri editormarker"))
|| Misc::StringUtils::ciStartsWith(nifNode->name, "shadow") || Misc::StringUtils::ciStartsWith(nifNode->mName, "shadow")
|| Misc::StringUtils::ciStartsWith(nifNode->name, "tri shadow"); || Misc::StringUtils::ciStartsWith(nifNode->mName, "tri shadow");
} }
else else
skip = args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->name, "EditorMarker"); skip = args.mHasMarkers && Misc::StringUtils::ciStartsWith(nifNode->mName, "EditorMarker");
if (!skip) if (!skip)
{ {
Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->skin; Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->skin;
@ -770,7 +768,7 @@ namespace NifOsg
else else
handleSkinnedGeometry(nifNode, parent, node, composite, args.mBoundTextures, args.mAnimFlags); handleSkinnedGeometry(nifNode, parent, node, composite, args.mBoundTextures, args.mAnimFlags);
if (!nifNode->controller.empty()) if (!nifNode->mController.empty())
handleMeshControllers(nifNode, node, composite, args.mBoundTextures, args.mAnimFlags); handleMeshControllers(nifNode, node, composite, args.mBoundTextures, args.mAnimFlags);
} }
} }
@ -807,9 +805,9 @@ namespace NifOsg
const Nif::NiSwitchNode* niSwitchNode = static_cast<const Nif::NiSwitchNode*>(nifNode); const Nif::NiSwitchNode* niSwitchNode = static_cast<const Nif::NiSwitchNode*>(nifNode);
osg::ref_ptr<osg::Switch> switchNode = handleSwitchNode(niSwitchNode); osg::ref_ptr<osg::Switch> switchNode = handleSwitchNode(niSwitchNode);
node->addChild(switchNode); node->addChild(switchNode);
if (niSwitchNode->name == Constants::NightDayLabel) if (niSwitchNode->mName == Constants::NightDayLabel)
mHasNightDayLabel = true; mHasNightDayLabel = true;
else if (niSwitchNode->name == Constants::HerbalismLabel) else if (niSwitchNode->mName == Constants::HerbalismLabel)
mHasHerbalismLabel = true; mHasHerbalismLabel = true;
currentNode = switchNode; currentNode = switchNode;
@ -860,7 +858,7 @@ namespace NifOsg
SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures,
int animflags) int animflags)
{ {
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) for (Nif::ControllerPtr ctrl = nifNode->mController; !ctrl.empty(); ctrl = ctrl->next)
{ {
if (!ctrl->isActive()) if (!ctrl->isActive())
continue; continue;
@ -887,7 +885,7 @@ namespace NifOsg
void handleNodeControllers(const Nif::Node* nifNode, osg::Node* node, int animflags, bool& isAnimated) void handleNodeControllers(const Nif::Node* nifNode, osg::Node* node, int animflags, bool& isAnimated)
{ {
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) for (Nif::ControllerPtr ctrl = nifNode->mController; !ctrl.empty(); ctrl = ctrl->next)
{ {
if (!ctrl->isActive()) if (!ctrl->isActive())
continue; continue;
@ -965,7 +963,7 @@ namespace NifOsg
void handleMaterialControllers(const Nif::Property* materialProperty, void handleMaterialControllers(const Nif::Property* materialProperty,
SceneUtil::CompositeStateSetUpdater* composite, int animflags, const osg::Material* baseMaterial) SceneUtil::CompositeStateSetUpdater* composite, int animflags, const osg::Material* baseMaterial)
{ {
for (Nif::ControllerPtr ctrl = materialProperty->controller; !ctrl.empty(); ctrl = ctrl->next) for (Nif::ControllerPtr ctrl = materialProperty->mController; !ctrl.empty(); ctrl = ctrl->next)
{ {
if (!ctrl->isActive()) if (!ctrl->isActive())
continue; continue;
@ -1016,7 +1014,7 @@ namespace NifOsg
void handleTextureControllers(const Nif::Property* texProperty, SceneUtil::CompositeStateSetUpdater* composite, void handleTextureControllers(const Nif::Property* texProperty, SceneUtil::CompositeStateSetUpdater* composite,
Resource::ImageManager* imageManager, osg::StateSet* stateset, int animflags) Resource::ImageManager* imageManager, osg::StateSet* stateset, int animflags)
{ {
for (Nif::ControllerPtr ctrl = texProperty->controller; !ctrl.empty(); ctrl = ctrl->next) for (Nif::ControllerPtr ctrl = texProperty->mController; !ctrl.empty(); ctrl = ctrl->next)
{ {
if (!ctrl->isActive()) if (!ctrl->isActive())
continue; continue;
@ -1256,7 +1254,7 @@ namespace NifOsg
partsys->setSortMode(osgParticle::ParticleSystem::SORT_BACK_TO_FRONT); partsys->setSortMode(osgParticle::ParticleSystem::SORT_BACK_TO_FRONT);
const Nif::NiParticleSystemController* partctrl = nullptr; const Nif::NiParticleSystemController* partctrl = nullptr;
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) for (Nif::ControllerPtr ctrl = nifNode->mController; !ctrl.empty(); ctrl = ctrl->next)
{ {
if (!ctrl->isActive()) if (!ctrl->isActive())
continue; continue;
@ -1465,7 +1463,7 @@ namespace NifOsg
new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, line.size(), line.data())); new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, line.size(), line.data()));
} }
} }
handleNiGeometryData(geometry, niGeometryData, boundTextures, nifNode->name); handleNiGeometryData(geometry, niGeometryData, boundTextures, nifNode->mName);
// osg::Material properties are handled here for two reasons: // osg::Material properties are handled here for two reasons:
// - if there are no vertex colors, we need to disable colorMode. // - if there are no vertex colors, we need to disable colorMode.
@ -1487,7 +1485,7 @@ namespace NifOsg
if (geom->empty()) if (geom->empty())
return; return;
osg::ref_ptr<osg::Drawable> drawable; osg::ref_ptr<osg::Drawable> drawable;
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next) for (Nif::ControllerPtr ctrl = nifNode->mController; !ctrl.empty(); ctrl = ctrl->next)
{ {
if (!ctrl->isActive()) if (!ctrl->isActive())
continue; continue;
@ -1507,7 +1505,7 @@ namespace NifOsg
} }
if (!drawable.get()) if (!drawable.get())
drawable = geom; drawable = geom;
drawable->setName(nifNode->name); drawable->setName(nifNode->mName);
parentNode->addChild(drawable); parentNode->addChild(drawable);
} }
@ -1543,7 +1541,7 @@ namespace NifOsg
return; return;
osg::ref_ptr<SceneUtil::RigGeometry> rig(new SceneUtil::RigGeometry); osg::ref_ptr<SceneUtil::RigGeometry> rig(new SceneUtil::RigGeometry);
rig->setSourceGeometry(geometry); rig->setSourceGeometry(geometry);
rig->setName(nifNode->name); rig->setName(nifNode->mName);
// Assign bone weights // Assign bone weights
osg::ref_ptr<SceneUtil::RigGeometry::InfluenceMap> map(new SceneUtil::RigGeometry::InfluenceMap); osg::ref_ptr<SceneUtil::RigGeometry::InfluenceMap> map(new SceneUtil::RigGeometry::InfluenceMap);
@ -1553,7 +1551,7 @@ namespace NifOsg
const Nif::NodeList& bones = skin->mBones; const Nif::NodeList& bones = skin->mBones;
for (std::size_t i = 0; i < bones.size(); ++i) for (std::size_t i = 0; i < bones.size(); ++i)
{ {
std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->name); std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->mName);
SceneUtil::RigGeometry::BoneInfluence influence; SceneUtil::RigGeometry::BoneInfluence influence;
influence.mWeights = data->mBones[i].mWeights; influence.mWeights = data->mBones[i].mWeights;
@ -1839,7 +1837,7 @@ namespace NifOsg
for (size_t i = 0; i < texprop->textures.size(); ++i) for (size_t i = 0; i < texprop->textures.size(); ++i)
{ {
if (texprop->textures[i].inUse if (texprop->textures[i].inUse
|| (i == Nif::NiTexturingProperty::BaseTexture && !texprop->controller.empty())) || (i == Nif::NiTexturingProperty::BaseTexture && !texprop->mController.empty()))
{ {
switch (i) switch (i)
{ {
@ -1866,7 +1864,7 @@ namespace NifOsg
if (texprop->textures[i].inUse) if (texprop->textures[i].inUse)
{ {
const Nif::NiTexturingProperty::Texture& tex = texprop->textures[i]; const Nif::NiTexturingProperty::Texture& tex = texprop->textures[i];
if (tex.texture.empty() && texprop->controller.empty()) if (tex.texture.empty() && texprop->mController.empty())
{ {
if (i == 0) if (i == 0)
Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName Log(Debug::Warning) << "Base texture is in use but empty on shape \"" << nodeName
@ -2424,7 +2422,7 @@ namespace NifOsg
mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.specular, 1.f)); mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.specular, 1.f));
mat->setShininess(osg::Material::FRONT_AND_BACK, matprop->data.glossiness); mat->setShininess(osg::Material::FRONT_AND_BACK, matprop->data.glossiness);
if (!matprop->controller.empty()) if (!matprop->mController.empty())
{ {
hasMatCtrl = true; hasMatCtrl = true;
handleMaterialControllers(matprop, composite, animflags, mat); handleMaterialControllers(matprop, composite, animflags, mat);

Loading…
Cancel
Save