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);
}
void init(Nif::Controlled& value)
{
init(static_cast<Nif::Extra&>(value));
value.controller = Nif::ControllerPtr(nullptr);
}
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)
@ -254,7 +249,7 @@ namespace
value.phase = 0;
value.timeStart = 0;
value.timeStop = 0;
value.target = Nif::ControlledPtr(nullptr);
value.target = Nif::NamedPtr(nullptr);
}
void copy(const btTransform& src, Nif::Transformation& dst)

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

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

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

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

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

@ -127,7 +127,7 @@ class NiUVData;
class NiPosData;
class NiVisData;
class Controller;
class Controlled;
class Named;
class NiSkinData;
class NiFloatData;
struct NiMorphData;
@ -141,6 +141,7 @@ class NiSourceTexture;
class NiRotatingParticlesData;
class NiAutoNormalParticlesData;
class NiPalette;
struct NiParticleModifier;
typedef RecordPtrT<Node> NodePtr;
typedef RecordPtrT<Extra> ExtraPtr;
@ -148,7 +149,7 @@ typedef RecordPtrT<NiUVData> NiUVDataPtr;
typedef RecordPtrT<NiPosData> NiPosDataPtr;
typedef RecordPtrT<NiVisData> NiVisDataPtr;
typedef RecordPtrT<Controller> ControllerPtr;
typedef RecordPtrT<Controlled> ControlledPtr;
typedef RecordPtrT<Named> NamedPtr;
typedef RecordPtrT<NiSkinData> NiSkinDataPtr;
typedef RecordPtrT<NiMorphData> NiMorphDataPtr;
typedef RecordPtrT<NiPixelData> NiPixelDataPtr;
@ -162,6 +163,7 @@ typedef RecordPtrT<NiSourceTexture> NiSourceTexturePtr;
typedef RecordPtrT<NiRotatingParticlesData> NiRotatingParticlesDataPtr;
typedef RecordPtrT<NiAutoNormalParticlesData> NiAutoNormalParticlesDataPtr;
typedef RecordPtrT<NiPalette> NiPalettePtr;
typedef RecordPtrT<NiParticleModifier> NiParticleModifierPtr;
typedef RecordListT<Node> NodeList;
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.";
// Check for extra data
Nif::Extra const *e = node;
while (!e->extra.empty())
for (Nif::ExtraPtr e = node->extra; !e.empty(); e = e->next)
{
// Get the next extra data in the list
e = e->extra.getPtr();
assert(e != nullptr);
if (e->recType == Nif::RC_NiStringExtraData)
{
// String markers may contain important information
// 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)
{

@ -222,9 +222,9 @@ namespace NifOsg
extractTextKeys(static_cast<const Nif::NiTextKeyExtraData*>(extra.getPtr()), target.mTextKeys);
extra = extra->extra;
extra = extra->next;
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)
{
@ -524,7 +524,7 @@ namespace NifOsg
node->getOrCreateUserDataContainer()->addUserObject(
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)
{
@ -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;
attachTo->addChild(program);
program->setParticleSystem(partsys);
program->setReferenceFrame(rf);
for (; !affectors.empty(); affectors = affectors->extra)
for (; !affectors.empty(); affectors = affectors->next)
{
if (affectors->recType == Nif::RC_NiParticleGrowFade)
{
@ -833,7 +833,7 @@ namespace NifOsg
else
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)
{

Loading…
Cancel
Save