Refactor extra data and particle modifier handling

Objects no longer inherit from extra data class
"Controlled" harmful abstraction no longer exists
Introduced NiParticleModifier/NiParticleCollider abstractions
Extra data size reading moved into the base read() method
pull/541/head
Capostrophic 5 years ago
parent 6128279dbf
commit 8baddefdbd

@ -211,15 +211,10 @@ namespace
value.extra = Nif::ExtraPtr(nullptr); value.extra = Nif::ExtraPtr(nullptr);
} }
void init(Nif::Controlled& value)
{
init(static_cast<Nif::Extra&>(value));
value.controller = Nif::ControllerPtr(nullptr);
}
void init(Nif::Named& value) void init(Nif::Named& value)
{ {
init(static_cast<Nif::Controlled&>(value)); value.extra = Nif::ExtraPtr(nullptr);
value.controller = Nif::ControllerPtr(nullptr);
} }
void init(Nif::Node& value) void init(Nif::Node& value)
@ -254,7 +249,7 @@ namespace
value.phase = 0; value.phase = 0;
value.timeStart = 0; value.timeStart = 0;
value.timeStop = 0; value.timeStop = 0;
value.target = Nif::ControlledPtr(nullptr); value.target = Nif::NamedPtr(nullptr);
} }
void copy(const btTransform& src, Nif::Transformation& dst) void copy(const btTransform& src, Nif::Transformation& dst)

@ -10,17 +10,19 @@
namespace Nif namespace Nif
{ {
/** A record that can have extra data. The extra data objects // An extra data record. All the extra data connected to an object form a linked list.
themselves descend from the Extra class, and all the extra data
connected to an object form a linked list
*/
class Extra : public Record class Extra : public Record
{ {
public: public:
ExtraPtr extra; ExtraPtr next; // Next extra data record in the list
void read(NIFStream *nif)
{
next.read(nif);
nif->getUInt(); // Size of the record
}
void read(NIFStream *nif) { extra.read(nif); } void post(NIFFile *nif) { next.post(nif); }
void post(NIFFile *nif) { extra.post(nif); }
}; };
class Controller : public Record class Controller : public Record
@ -30,43 +32,33 @@ public:
int flags; int flags;
float frequency, phase; float frequency, phase;
float timeStart, timeStop; float timeStart, timeStop;
ControlledPtr target; NamedPtr target;
void read(NIFStream *nif); void read(NIFStream *nif);
void post(NIFFile *nif); void post(NIFFile *nif);
}; };
/// Anything that has a controller /// Has name, extra-data and controller
class Controlled : public Extra class Named : public Record
{ {
public: public:
std::string name;
ExtraPtr extra;
ControllerPtr controller; ControllerPtr controller;
void read(NIFStream *nif) void read(NIFStream *nif)
{ {
Extra::read(nif); name = nif->getString();
extra.read(nif);
controller.read(nif); controller.read(nif);
} }
void post(NIFFile *nif) void post(NIFFile *nif)
{ {
Extra::post(nif); extra.post(nif);
controller.post(nif); controller.post(nif);
} }
}; };
/// Has name, extra-data and controller
class Named : public Controlled
{
public:
std::string name;
void read(NIFStream *nif)
{
name = nif->getString();
Controlled::read(nif);
}
};
typedef Named NiSequenceStreamHelper; typedef Named NiSequenceStreamHelper;
} // Namespace } // Namespace

@ -31,28 +31,40 @@ namespace Nif
data.post(nif); data.post(nif);
} }
void NiParticleModifier::read(NIFStream *nif)
{
next.read(nif);
controller.read(nif);
}
void NiParticleModifier::post(NIFFile *nif)
{
next.post(nif);
controller.post(nif);
}
void NiParticleGrowFade::read(NIFStream *nif) void NiParticleGrowFade::read(NIFStream *nif)
{ {
Controlled::read(nif); NiParticleModifier::read(nif);
growTime = nif->getFloat(); growTime = nif->getFloat();
fadeTime = nif->getFloat(); fadeTime = nif->getFloat();
} }
void NiParticleColorModifier::read(NIFStream *nif) void NiParticleColorModifier::read(NIFStream *nif)
{ {
Controlled::read(nif); NiParticleModifier::read(nif);
data.read(nif); data.read(nif);
} }
void NiParticleColorModifier::post(NIFFile *nif) void NiParticleColorModifier::post(NIFFile *nif)
{ {
Controlled::post(nif); NiParticleModifier::post(nif);
data.post(nif); data.post(nif);
} }
void NiGravity::read(NIFStream *nif) void NiGravity::read(NIFStream *nif)
{ {
Controlled::read(nif); NiParticleModifier::read(nif);
mDecay = nif->getFloat(); mDecay = nif->getFloat();
mForce = nif->getFloat(); mForce = nif->getFloat();
@ -61,11 +73,17 @@ namespace Nif
mDirection = nif->getVector3(); mDirection = nif->getVector3();
} }
void NiPlanarCollider::read(NIFStream *nif) void NiParticleCollider::read(NIFStream *nif)
{ {
Controlled::read(nif); NiParticleModifier::read(nif);
mBounceFactor = nif->getFloat(); mBounceFactor = nif->getFloat();
}
void NiPlanarCollider::read(NIFStream *nif)
{
NiParticleCollider::read(nif);
/*unknown*/nif->getFloat(); /*unknown*/nif->getFloat();
for (int i=0;i<10;++i) for (int i=0;i<10;++i)
@ -77,7 +95,7 @@ namespace Nif
void NiParticleRotation::read(NIFStream *nif) void NiParticleRotation::read(NIFStream *nif)
{ {
Controlled::read(nif); NiParticleModifier::read(nif);
/* /*
byte (0 or 1) byte (0 or 1)
@ -89,9 +107,8 @@ namespace Nif
void NiSphericalCollider::read(NIFStream* nif) void NiSphericalCollider::read(NIFStream* nif)
{ {
Controlled::read(nif); NiParticleCollider::read(nif);
mBounceFactor = nif->getFloat();
mRadius = nif->getFloat(); mRadius = nif->getFloat();
mCenter = nif->getVector3(); mCenter = nif->getVector3();
} }

@ -66,7 +66,16 @@ public:
void post(NIFFile *nif); void post(NIFFile *nif);
}; };
class NiParticleGrowFade : public Controlled struct NiParticleModifier : public Record
{
NiParticleModifierPtr next;
ControllerPtr controller;
void read(NIFStream *nif);
void post(NIFFile *nif);
};
class NiParticleGrowFade : public NiParticleModifier
{ {
public: public:
float growTime; float growTime;
@ -75,7 +84,7 @@ public:
void read(NIFStream *nif); void read(NIFStream *nif);
}; };
class NiParticleColorModifier : public Controlled class NiParticleColorModifier : public NiParticleModifier
{ {
public: public:
NiColorDataPtr data; NiColorDataPtr data;
@ -84,7 +93,7 @@ public:
void post(NIFFile *nif); void post(NIFFile *nif);
}; };
class NiGravity : public Controlled class NiGravity : public NiParticleModifier
{ {
public: public:
float mForce; float mForce;
@ -99,29 +108,32 @@ public:
void read(NIFStream *nif); void read(NIFStream *nif);
}; };
struct NiParticleCollider : public NiParticleModifier
{
float mBounceFactor;
void read(NIFStream *nif);
};
// NiPinaColada // NiPinaColada
class NiPlanarCollider : public Controlled class NiPlanarCollider : public NiParticleCollider
{ {
public: public:
void read(NIFStream *nif); void read(NIFStream *nif);
float mBounceFactor;
osg::Vec3f mPlaneNormal; osg::Vec3f mPlaneNormal;
float mPlaneDistance; float mPlaneDistance;
}; };
class NiSphericalCollider : public Controlled class NiSphericalCollider : public NiParticleCollider
{ {
public: public:
float mBounceFactor;
float mRadius; float mRadius;
osg::Vec3f mCenter; osg::Vec3f mCenter;
void read(NIFStream *nif); void read(NIFStream *nif);
}; };
class NiParticleRotation : public Controlled class NiParticleRotation : public NiParticleModifier
{ {
public: public:
void read(NIFStream *nif); void read(NIFStream *nif);

@ -72,8 +72,8 @@ public:
int activeCount; int activeCount;
std::vector<Particle> particles; std::vector<Particle> particles;
ExtraPtr affectors; NiParticleModifierPtr affectors;
ExtraPtr colliders; NiParticleModifierPtr colliders;
void read(NIFStream *nif); void read(NIFStream *nif);
void post(NIFFile *nif); void post(NIFFile *nif);

@ -6,8 +6,6 @@ namespace Nif
void NiStringExtraData::read(NIFStream *nif) void NiStringExtraData::read(NIFStream *nif)
{ {
Extra::read(nif); Extra::read(nif);
nif->getInt(); // size of string + 4. Really useful...
string = nif->getString(); string = nif->getString();
} }
@ -15,8 +13,6 @@ void NiTextKeyExtraData::read(NIFStream *nif)
{ {
Extra::read(nif); Extra::read(nif);
nif->getInt(); // 0
int keynum = nif->getInt(); int keynum = nif->getInt();
list.resize(keynum); list.resize(keynum);
for(int i=0; i<keynum; i++) for(int i=0; i<keynum; i++)
@ -30,12 +26,7 @@ void NiVertWeightsExtraData::read(NIFStream *nif)
{ {
Extra::read(nif); Extra::read(nif);
// We should have s*4+2 == i, for some reason. Might simply be the nif->skip(nif->getUShort() * sizeof(float)); // vertex weights I guess
// size of the rest of the record, unhelpful as that may be.
/*int i =*/ nif->getInt();
int s = nif->getUShort();
nif->skip(s * sizeof(float)); // vertex weights I guess
} }

@ -127,7 +127,7 @@ class NiUVData;
class NiPosData; class NiPosData;
class NiVisData; class NiVisData;
class Controller; class Controller;
class Controlled; class Named;
class NiSkinData; class NiSkinData;
class NiFloatData; class NiFloatData;
struct NiMorphData; struct NiMorphData;
@ -141,6 +141,7 @@ class NiSourceTexture;
class NiRotatingParticlesData; class NiRotatingParticlesData;
class NiAutoNormalParticlesData; class NiAutoNormalParticlesData;
class NiPalette; class NiPalette;
struct NiParticleModifier;
typedef RecordPtrT<Node> NodePtr; typedef RecordPtrT<Node> NodePtr;
typedef RecordPtrT<Extra> ExtraPtr; typedef RecordPtrT<Extra> ExtraPtr;
@ -148,7 +149,7 @@ typedef RecordPtrT<NiUVData> NiUVDataPtr;
typedef RecordPtrT<NiPosData> NiPosDataPtr; typedef RecordPtrT<NiPosData> NiPosDataPtr;
typedef RecordPtrT<NiVisData> NiVisDataPtr; typedef RecordPtrT<NiVisData> NiVisDataPtr;
typedef RecordPtrT<Controller> ControllerPtr; typedef RecordPtrT<Controller> ControllerPtr;
typedef RecordPtrT<Controlled> ControlledPtr; typedef RecordPtrT<Named> NamedPtr;
typedef RecordPtrT<NiSkinData> NiSkinDataPtr; typedef RecordPtrT<NiSkinData> NiSkinDataPtr;
typedef RecordPtrT<NiMorphData> NiMorphDataPtr; typedef RecordPtrT<NiMorphData> NiMorphDataPtr;
typedef RecordPtrT<NiPixelData> NiPixelDataPtr; typedef RecordPtrT<NiPixelData> NiPixelDataPtr;
@ -162,6 +163,7 @@ typedef RecordPtrT<NiSourceTexture> NiSourceTexturePtr;
typedef RecordPtrT<NiRotatingParticlesData> NiRotatingParticlesDataPtr; typedef RecordPtrT<NiRotatingParticlesData> NiRotatingParticlesDataPtr;
typedef RecordPtrT<NiAutoNormalParticlesData> NiAutoNormalParticlesDataPtr; typedef RecordPtrT<NiAutoNormalParticlesData> NiAutoNormalParticlesDataPtr;
typedef RecordPtrT<NiPalette> NiPalettePtr; typedef RecordPtrT<NiPalette> NiPalettePtr;
typedef RecordPtrT<NiParticleModifier> NiParticleModifierPtr;
typedef RecordListT<Node> NodeList; typedef RecordListT<Node> NodeList;
typedef RecordListT<Property> PropertyList; typedef RecordListT<Property> PropertyList;

@ -260,18 +260,13 @@ void BulletNifLoader::handleNode(const std::string& fileName, const Nif::Node *n
Log(Debug::Info) << "RootCollisionNode is not attached to the root node in " << fileName << ". Treating it as a common NiTriShape."; Log(Debug::Info) << "RootCollisionNode is not attached to the root node in " << fileName << ". Treating it as a common NiTriShape.";
// Check for extra data // Check for extra data
Nif::Extra const *e = node; for (Nif::ExtraPtr e = node->extra; !e.empty(); e = e->next)
while (!e->extra.empty())
{ {
// Get the next extra data in the list
e = e->extra.getPtr();
assert(e != nullptr);
if (e->recType == Nif::RC_NiStringExtraData) if (e->recType == Nif::RC_NiStringExtraData)
{ {
// String markers may contain important information // String markers may contain important information
// affecting the entire subtree of this node // affecting the entire subtree of this node
Nif::NiStringExtraData *sd = (Nif::NiStringExtraData*)e; Nif::NiStringExtraData *sd = (Nif::NiStringExtraData*)e.getPtr();
if (Misc::StringUtils::ciCompareLen(sd->string, "NC", 2) == 0) if (Misc::StringUtils::ciCompareLen(sd->string, "NC", 2) == 0)
{ {

@ -222,9 +222,9 @@ namespace NifOsg
extractTextKeys(static_cast<const Nif::NiTextKeyExtraData*>(extra.getPtr()), target.mTextKeys); extractTextKeys(static_cast<const Nif::NiTextKeyExtraData*>(extra.getPtr()), target.mTextKeys);
extra = extra->extra; extra = extra->next;
Nif::ControllerPtr ctrl = seq->controller; Nif::ControllerPtr ctrl = seq->controller;
for(;!extra.empty() && !ctrl.empty();(extra=extra->extra),(ctrl=ctrl->next)) for(;!extra.empty() && !ctrl.empty();(extra=extra->next),(ctrl=ctrl->next))
{ {
if(extra->recType != Nif::RC_NiStringExtraData || ctrl->recType != Nif::RC_NiKeyframeController) if(extra->recType != Nif::RC_NiStringExtraData || ctrl->recType != Nif::RC_NiKeyframeController)
{ {
@ -524,7 +524,7 @@ namespace NifOsg
node->getOrCreateUserDataContainer()->addUserObject( node->getOrCreateUserDataContainer()->addUserObject(
new NodeUserData(nifNode->recIndex, nifNode->trafo.scale, nifNode->trafo.rotation)); new NodeUserData(nifNode->recIndex, nifNode->trafo.scale, nifNode->trafo.rotation));
for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->extra) for (Nif::ExtraPtr e = nifNode->extra; !e.empty(); e = e->next)
{ {
if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys) if(e->recType == Nif::RC_NiTextKeyExtraData && textKeys)
{ {
@ -802,13 +802,13 @@ namespace NifOsg
} }
} }
void handleParticlePrograms(Nif::ExtraPtr affectors, Nif::ExtraPtr colliders, osg::Group *attachTo, osgParticle::ParticleSystem* partsys, osgParticle::ParticleProcessor::ReferenceFrame rf) void handleParticlePrograms(Nif::NiParticleModifierPtr affectors, Nif::NiParticleModifierPtr colliders, osg::Group *attachTo, osgParticle::ParticleSystem* partsys, osgParticle::ParticleProcessor::ReferenceFrame rf)
{ {
osgParticle::ModularProgram* program = new osgParticle::ModularProgram; osgParticle::ModularProgram* program = new osgParticle::ModularProgram;
attachTo->addChild(program); attachTo->addChild(program);
program->setParticleSystem(partsys); program->setParticleSystem(partsys);
program->setReferenceFrame(rf); program->setReferenceFrame(rf);
for (; !affectors.empty(); affectors = affectors->extra) for (; !affectors.empty(); affectors = affectors->next)
{ {
if (affectors->recType == Nif::RC_NiParticleGrowFade) if (affectors->recType == Nif::RC_NiParticleGrowFade)
{ {
@ -833,7 +833,7 @@ namespace NifOsg
else else
Log(Debug::Info) << "Unhandled particle modifier " << affectors->recName << " in " << mFilename; Log(Debug::Info) << "Unhandled particle modifier " << affectors->recName << " in " << mFilename;
} }
for (; !colliders.empty(); colliders = colliders->extra) for (; !colliders.empty(); colliders = colliders->next)
{ {
if (colliders->recType == Nif::RC_NiPlanarCollider) if (colliders->recType == Nif::RC_NiPlanarCollider)
{ {

Loading…
Cancel
Save