mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-01 00:39:43 +00:00
Refactor NiParticleSystemController and update definitions
This commit is contained in:
parent
d55ba0cfa2
commit
8856dff3db
5 changed files with 148 additions and 145 deletions
|
@ -162,67 +162,71 @@ namespace Nif
|
|||
mInterpolator.post(nif);
|
||||
}
|
||||
|
||||
void NiParticleInfo::read(NIFStream* nif)
|
||||
{
|
||||
nif->read(mVelocity);
|
||||
if (nif->getVersion() <= NIFStream::generateVersion(10, 4, 0, 1))
|
||||
nif->read(mRotationAxis);
|
||||
nif->read(mAge);
|
||||
nif->read(mLifespan);
|
||||
nif->read(mLastUpdate);
|
||||
nif->read(mSpawnGeneration);
|
||||
nif->read(mCode);
|
||||
}
|
||||
|
||||
void NiParticleSystemController::read(NIFStream* nif)
|
||||
{
|
||||
NiTimeController::read(nif);
|
||||
|
||||
velocity = nif->getFloat();
|
||||
velocityRandom = nif->getFloat();
|
||||
verticalDir = nif->getFloat();
|
||||
verticalAngle = nif->getFloat();
|
||||
horizontalDir = nif->getFloat();
|
||||
horizontalAngle = nif->getFloat();
|
||||
/*normal?*/ nif->getVector3();
|
||||
color = nif->getVector4();
|
||||
size = nif->getFloat();
|
||||
startTime = nif->getFloat();
|
||||
stopTime = nif->getFloat();
|
||||
nif->getChar();
|
||||
emitRate = nif->getFloat();
|
||||
lifetime = nif->getFloat();
|
||||
lifetimeRandom = nif->getFloat();
|
||||
|
||||
emitFlags = nif->getUShort();
|
||||
offsetRandom = nif->getVector3();
|
||||
|
||||
emitter.read(nif);
|
||||
|
||||
/* Unknown Short, 0?
|
||||
* Unknown Float, 1.0?
|
||||
* Unknown Int, 1?
|
||||
* Unknown Int, 0?
|
||||
* Unknown Short, 0?
|
||||
*/
|
||||
nif->skip(16);
|
||||
|
||||
numParticles = nif->getUShort();
|
||||
activeCount = nif->getUShort();
|
||||
|
||||
particles.resize(numParticles);
|
||||
for (size_t i = 0; i < particles.size(); i++)
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13))
|
||||
nif->read(mSpeed);
|
||||
nif->read(mSpeedVariation);
|
||||
nif->read(mDeclination);
|
||||
nif->read(mDeclinationVariation);
|
||||
nif->read(mPlanarAngle);
|
||||
nif->read(mPlanarAngleVariation);
|
||||
nif->read(mInitialNormal);
|
||||
nif->read(mInitialColor);
|
||||
nif->read(mInitialSize);
|
||||
nif->read(mEmitStartTime);
|
||||
nif->read(mEmitStopTime);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13))
|
||||
{
|
||||
particles[i].velocity = nif->getVector3();
|
||||
nif->getVector3(); /* unknown */
|
||||
particles[i].lifetime = nif->getFloat();
|
||||
particles[i].lifespan = nif->getFloat();
|
||||
particles[i].timestamp = nif->getFloat();
|
||||
nif->getUShort(); /* unknown */
|
||||
particles[i].vertex = nif->getUShort();
|
||||
mResetParticleSystem = nif->get<uint8_t>() != 0;
|
||||
nif->read(mBirthRate);
|
||||
}
|
||||
|
||||
nif->getUInt(); /* -1? */
|
||||
affectors.read(nif);
|
||||
colliders.read(nif);
|
||||
nif->getChar();
|
||||
nif->read(mLifetime);
|
||||
nif->read(mLifetimeVariation);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13))
|
||||
nif->read(mEmitFlags);
|
||||
nif->read(mEmitterDimensions);
|
||||
mEmitter.read(nif);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 13))
|
||||
{
|
||||
nif->read(mNumSpawnGenerations);
|
||||
nif->read(mPercentageSpawned);
|
||||
nif->read(mSpawnMultiplier);
|
||||
nif->read(mSpawnSpeedChaos);
|
||||
nif->read(mSpawnDirChaos);
|
||||
mParticles.resize(nif->get<uint16_t>());
|
||||
nif->read(mNumValid);
|
||||
for (NiParticleInfo& particle : mParticles)
|
||||
particle.read(nif);
|
||||
nif->skip(4); // NiEmitterModifier link
|
||||
}
|
||||
mModifier.read(nif);
|
||||
mCollider.read(nif);
|
||||
if (nif->getVersion() >= NIFStream::generateVersion(3, 3, 0, 15))
|
||||
nif->read(mStaticTargetBound);
|
||||
}
|
||||
|
||||
void NiParticleSystemController::post(Reader& nif)
|
||||
{
|
||||
NiTimeController::post(nif);
|
||||
|
||||
emitter.post(nif);
|
||||
affectors.post(nif);
|
||||
colliders.post(nif);
|
||||
mEmitter.post(nif);
|
||||
mModifier.post(nif);
|
||||
mCollider.post(nif);
|
||||
}
|
||||
|
||||
void NiMaterialColorController::read(NIFStream* nif)
|
||||
|
|
|
@ -94,6 +94,19 @@ namespace Nif
|
|||
{
|
||||
};
|
||||
|
||||
struct NiParticleInfo
|
||||
{
|
||||
osg::Vec3f mVelocity;
|
||||
osg::Vec3f mRotationAxis;
|
||||
float mAge;
|
||||
float mLifespan;
|
||||
float mLastUpdate;
|
||||
uint16_t mSpawnGeneration;
|
||||
uint16_t mCode;
|
||||
|
||||
void read(NIFStream* nif);
|
||||
};
|
||||
|
||||
struct NiParticleSystemController : public NiTimeController
|
||||
{
|
||||
enum BSPArrayController
|
||||
|
@ -102,55 +115,47 @@ namespace Nif
|
|||
BSPArrayController_AtVertex = 0x10
|
||||
};
|
||||
|
||||
struct Particle
|
||||
{
|
||||
osg::Vec3f velocity;
|
||||
float lifetime;
|
||||
float lifespan;
|
||||
float timestamp;
|
||||
unsigned short vertex;
|
||||
};
|
||||
|
||||
float velocity;
|
||||
float velocityRandom;
|
||||
|
||||
float verticalDir; // 0=up, pi/2=horizontal, pi=down
|
||||
float verticalAngle;
|
||||
float horizontalDir;
|
||||
float horizontalAngle;
|
||||
|
||||
osg::Vec4f color;
|
||||
float size;
|
||||
float startTime;
|
||||
float stopTime;
|
||||
|
||||
float emitRate;
|
||||
float lifetime;
|
||||
float lifetimeRandom;
|
||||
|
||||
enum EmitFlags
|
||||
{
|
||||
EmitFlag_NoAutoAdjust = 0x1 // If this flag is set, we use the emitRate value. Otherwise,
|
||||
// we calculate an emit rate so that the maximum number of particles
|
||||
// in the system (numParticles) is never exceeded.
|
||||
};
|
||||
int emitFlags;
|
||||
|
||||
osg::Vec3f offsetRandom;
|
||||
|
||||
NiAVObjectPtr emitter;
|
||||
|
||||
int numParticles;
|
||||
int activeCount;
|
||||
std::vector<Particle> particles;
|
||||
|
||||
NiParticleModifierPtr affectors;
|
||||
NiParticleModifierPtr colliders;
|
||||
float mSpeed;
|
||||
float mSpeedVariation;
|
||||
float mDeclination;
|
||||
float mDeclinationVariation;
|
||||
float mPlanarAngle;
|
||||
float mPlanarAngleVariation;
|
||||
osg::Vec3f mInitialNormal;
|
||||
osg::Vec4f mInitialColor;
|
||||
float mInitialSize;
|
||||
float mEmitStartTime;
|
||||
float mEmitStopTime;
|
||||
bool mResetParticleSystem{ false };
|
||||
float mBirthRate;
|
||||
float mLifetime;
|
||||
float mLifetimeVariation;
|
||||
uint16_t mEmitFlags{ 0 };
|
||||
osg::Vec3f mEmitterDimensions;
|
||||
NiAVObjectPtr mEmitter;
|
||||
uint16_t mNumSpawnGenerations;
|
||||
float mPercentageSpawned;
|
||||
uint16_t mSpawnMultiplier;
|
||||
float mSpawnSpeedChaos;
|
||||
float mSpawnDirChaos;
|
||||
uint16_t mNumParticles;
|
||||
uint16_t mNumValid;
|
||||
std::vector<NiParticleInfo> mParticles;
|
||||
NiParticleModifierPtr mModifier;
|
||||
NiParticleModifierPtr mCollider;
|
||||
uint8_t mStaticTargetBound;
|
||||
|
||||
void read(NIFStream* nif) override;
|
||||
void post(Reader& nif) override;
|
||||
|
||||
bool noAutoAdjust() const { return emitFlags & EmitFlag_NoAutoAdjust; }
|
||||
bool noAutoAdjust() const { return mEmitFlags & EmitFlag_NoAutoAdjust; }
|
||||
bool emitAtVertex() const { return mFlags & BSPArrayController_AtVertex; }
|
||||
};
|
||||
using NiBSPArrayController = NiParticleSystemController;
|
||||
|
|
|
@ -556,14 +556,8 @@ namespace NifOsg
|
|||
}
|
||||
|
||||
ParticleSystemController::ParticleSystemController(const Nif::NiParticleSystemController* ctrl)
|
||||
: mEmitStart(ctrl->startTime)
|
||||
, mEmitStop(ctrl->stopTime)
|
||||
{
|
||||
}
|
||||
|
||||
ParticleSystemController::ParticleSystemController()
|
||||
: mEmitStart(0.f)
|
||||
, mEmitStop(0.f)
|
||||
: mEmitStart(ctrl->mEmitStartTime)
|
||||
, mEmitStop(ctrl->mEmitStopTime)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -379,7 +379,7 @@ namespace NifOsg
|
|||
{
|
||||
public:
|
||||
ParticleSystemController(const Nif::NiParticleSystemController* ctrl);
|
||||
ParticleSystemController();
|
||||
ParticleSystemController() = default;
|
||||
ParticleSystemController(const ParticleSystemController& copy, const osg::CopyOp& copyop);
|
||||
|
||||
META_Object(NifOsg, ParticleSystemController)
|
||||
|
@ -387,8 +387,8 @@ namespace NifOsg
|
|||
void operator()(osgParticle::ParticleProcessor* node, osg::NodeVisitor* nv);
|
||||
|
||||
private:
|
||||
float mEmitStart;
|
||||
float mEmitStop;
|
||||
float mEmitStart{ 0.f };
|
||||
float mEmitStop{ 0.f };
|
||||
};
|
||||
|
||||
class PathController : public SceneUtil::NodeCallback<PathController, NifOsg::MatrixTransform*>,
|
||||
|
|
|
@ -1061,7 +1061,7 @@ namespace NifOsg
|
|||
}
|
||||
}
|
||||
|
||||
void handleParticlePrograms(Nif::NiParticleModifierPtr affectors, Nif::NiParticleModifierPtr colliders,
|
||||
void handleParticlePrograms(Nif::NiParticleModifierPtr modifier, Nif::NiParticleModifierPtr collider,
|
||||
osg::Group* attachTo, osgParticle::ParticleSystem* partsys,
|
||||
osgParticle::ParticleProcessor::ReferenceFrame rf)
|
||||
{
|
||||
|
@ -1069,50 +1069,50 @@ namespace NifOsg
|
|||
attachTo->addChild(program);
|
||||
program->setParticleSystem(partsys);
|
||||
program->setReferenceFrame(rf);
|
||||
for (; !affectors.empty(); affectors = affectors->mNext)
|
||||
for (; !modifier.empty(); modifier = modifier->mNext)
|
||||
{
|
||||
if (affectors->recType == Nif::RC_NiParticleGrowFade)
|
||||
if (modifier->recType == Nif::RC_NiParticleGrowFade)
|
||||
{
|
||||
const Nif::NiParticleGrowFade* gf = static_cast<const Nif::NiParticleGrowFade*>(affectors.getPtr());
|
||||
const Nif::NiParticleGrowFade* gf = static_cast<const Nif::NiParticleGrowFade*>(modifier.getPtr());
|
||||
program->addOperator(new GrowFadeAffector(gf->mGrowTime, gf->mFadeTime));
|
||||
}
|
||||
else if (affectors->recType == Nif::RC_NiGravity)
|
||||
else if (modifier->recType == Nif::RC_NiGravity)
|
||||
{
|
||||
const Nif::NiGravity* gr = static_cast<const Nif::NiGravity*>(affectors.getPtr());
|
||||
const Nif::NiGravity* gr = static_cast<const Nif::NiGravity*>(modifier.getPtr());
|
||||
program->addOperator(new GravityAffector(gr));
|
||||
}
|
||||
else if (affectors->recType == Nif::RC_NiParticleColorModifier)
|
||||
else if (modifier->recType == Nif::RC_NiParticleColorModifier)
|
||||
{
|
||||
const Nif::NiParticleColorModifier* cl
|
||||
= static_cast<const Nif::NiParticleColorModifier*>(affectors.getPtr());
|
||||
= static_cast<const Nif::NiParticleColorModifier*>(modifier.getPtr());
|
||||
if (cl->mData.empty())
|
||||
continue;
|
||||
const Nif::NiColorData* clrdata = cl->mData.getPtr();
|
||||
program->addOperator(new ParticleColorAffector(clrdata));
|
||||
}
|
||||
else if (affectors->recType == Nif::RC_NiParticleRotation)
|
||||
else if (modifier->recType == Nif::RC_NiParticleRotation)
|
||||
{
|
||||
// unused
|
||||
}
|
||||
else
|
||||
Log(Debug::Info) << "Unhandled particle modifier " << affectors->recName << " in " << mFilename;
|
||||
Log(Debug::Info) << "Unhandled particle modifier " << modifier->recName << " in " << mFilename;
|
||||
}
|
||||
for (; !colliders.empty(); colliders = colliders->mNext)
|
||||
for (; !collider.empty(); collider = collider->mNext)
|
||||
{
|
||||
if (colliders->recType == Nif::RC_NiPlanarCollider)
|
||||
if (collider->recType == Nif::RC_NiPlanarCollider)
|
||||
{
|
||||
const Nif::NiPlanarCollider* planarcollider
|
||||
= static_cast<const Nif::NiPlanarCollider*>(colliders.getPtr());
|
||||
= static_cast<const Nif::NiPlanarCollider*>(collider.getPtr());
|
||||
program->addOperator(new PlanarCollider(planarcollider));
|
||||
}
|
||||
else if (colliders->recType == Nif::RC_NiSphericalCollider)
|
||||
else if (collider->recType == Nif::RC_NiSphericalCollider)
|
||||
{
|
||||
const Nif::NiSphericalCollider* sphericalcollider
|
||||
= static_cast<const Nif::NiSphericalCollider*>(colliders.getPtr());
|
||||
= static_cast<const Nif::NiSphericalCollider*>(collider.getPtr());
|
||||
program->addOperator(new SphericalCollider(sphericalcollider));
|
||||
}
|
||||
else
|
||||
Log(Debug::Info) << "Unhandled particle collider " << colliders->recName << " in " << mFilename;
|
||||
Log(Debug::Info) << "Unhandled particle collider " << collider->recName << " in " << mFilename;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1124,7 +1124,7 @@ namespace NifOsg
|
|||
auto particleNode = static_cast<const Nif::NiParticles*>(nifNode);
|
||||
if (particleNode->data.empty() || particleNode->data->recType != Nif::RC_NiParticlesData)
|
||||
{
|
||||
partsys->setQuota(partctrl->numParticles);
|
||||
partsys->setQuota(partctrl->mParticles.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1134,35 +1134,35 @@ namespace NifOsg
|
|||
osg::BoundingBox box;
|
||||
|
||||
int i = 0;
|
||||
for (const auto& particle : partctrl->particles)
|
||||
for (const auto& particle : partctrl->mParticles)
|
||||
{
|
||||
if (i++ >= particledata->mActiveCount)
|
||||
break;
|
||||
|
||||
if (particle.lifespan <= 0)
|
||||
if (particle.mLifespan <= 0)
|
||||
continue;
|
||||
|
||||
if (particle.vertex >= particledata->mVertices.size())
|
||||
if (particle.mCode >= particledata->mVertices.size())
|
||||
continue;
|
||||
|
||||
ParticleAgeSetter particletemplate(std::max(0.f, particle.lifetime));
|
||||
ParticleAgeSetter particletemplate(std::max(0.f, particle.mAge));
|
||||
|
||||
osgParticle::Particle* created = partsys->createParticle(&particletemplate);
|
||||
created->setLifeTime(particle.lifespan);
|
||||
created->setLifeTime(particle.mLifespan);
|
||||
|
||||
// Note this position and velocity is not correct for a particle system with absolute reference frame,
|
||||
// which can not be done in this loader since we are not attached to the scene yet. Will be fixed up
|
||||
// post-load in the SceneManager.
|
||||
created->setVelocity(particle.velocity);
|
||||
const osg::Vec3f& position = particledata->mVertices[particle.vertex];
|
||||
created->setVelocity(particle.mVelocity);
|
||||
const osg::Vec3f& position = particledata->mVertices[particle.mCode];
|
||||
created->setPosition(position);
|
||||
|
||||
created->setColorRange(osgParticle::rangev4(partctrl->color, partctrl->color));
|
||||
created->setColorRange(osgParticle::rangev4(partctrl->mInitialColor, partctrl->mInitialColor));
|
||||
created->setAlphaRange(osgParticle::rangef(1.f, 1.f));
|
||||
|
||||
float size = partctrl->size;
|
||||
if (particle.vertex < particledata->mSizes.size())
|
||||
size *= particledata->mSizes[particle.vertex];
|
||||
float size = partctrl->mInitialSize;
|
||||
if (particle.mCode < particledata->mSizes.size())
|
||||
size *= particledata->mSizes[particle.mCode];
|
||||
|
||||
created->setSizeRange(osgParticle::rangef(size, size));
|
||||
box.expandBy(osg::BoundingSphere(position, size));
|
||||
|
@ -1179,39 +1179,39 @@ namespace NifOsg
|
|||
std::vector<int> targets;
|
||||
if (partctrl->recType == Nif::RC_NiBSPArrayController && !partctrl->emitAtVertex())
|
||||
{
|
||||
getAllNiNodes(partctrl->emitter.getPtr(), targets);
|
||||
getAllNiNodes(partctrl->mEmitter.getPtr(), targets);
|
||||
}
|
||||
|
||||
osg::ref_ptr<Emitter> emitter = new Emitter(targets);
|
||||
|
||||
osgParticle::ConstantRateCounter* counter = new osgParticle::ConstantRateCounter;
|
||||
if (partctrl->noAutoAdjust())
|
||||
counter->setNumberOfParticlesPerSecondToCreate(partctrl->emitRate);
|
||||
else if (partctrl->lifetime == 0 && partctrl->lifetimeRandom == 0)
|
||||
counter->setNumberOfParticlesPerSecondToCreate(partctrl->mBirthRate);
|
||||
else if (partctrl->mLifetime == 0 && partctrl->mLifetimeVariation == 0)
|
||||
counter->setNumberOfParticlesPerSecondToCreate(0);
|
||||
else
|
||||
counter->setNumberOfParticlesPerSecondToCreate(
|
||||
partctrl->numParticles / (partctrl->lifetime + partctrl->lifetimeRandom / 2));
|
||||
partctrl->mParticles.size() / (partctrl->mLifetime + partctrl->mLifetimeVariation / 2));
|
||||
|
||||
emitter->setCounter(counter);
|
||||
|
||||
ParticleShooter* shooter = new ParticleShooter(partctrl->velocity - partctrl->velocityRandom * 0.5f,
|
||||
partctrl->velocity + partctrl->velocityRandom * 0.5f, partctrl->horizontalDir,
|
||||
partctrl->horizontalAngle, partctrl->verticalDir, partctrl->verticalAngle, partctrl->lifetime,
|
||||
partctrl->lifetimeRandom);
|
||||
ParticleShooter* shooter = new ParticleShooter(partctrl->mSpeed - partctrl->mSpeedVariation * 0.5f,
|
||||
partctrl->mSpeed + partctrl->mSpeedVariation * 0.5f, partctrl->mPlanarAngle,
|
||||
partctrl->mPlanarAngleVariation, partctrl->mDeclination, partctrl->mDeclinationVariation,
|
||||
partctrl->mLifetime, partctrl->mLifetimeVariation);
|
||||
emitter->setShooter(shooter);
|
||||
emitter->setFlags(partctrl->mFlags);
|
||||
|
||||
if (partctrl->recType == Nif::RC_NiBSPArrayController && partctrl->emitAtVertex())
|
||||
{
|
||||
emitter->setGeometryEmitterTarget(partctrl->emitter->recIndex);
|
||||
emitter->setGeometryEmitterTarget(partctrl->mEmitter->recIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
osgParticle::BoxPlacer* placer = new osgParticle::BoxPlacer;
|
||||
placer->setXRange(-partctrl->offsetRandom.x() / 2.f, partctrl->offsetRandom.x() / 2.f);
|
||||
placer->setYRange(-partctrl->offsetRandom.y() / 2.f, partctrl->offsetRandom.y() / 2.f);
|
||||
placer->setZRange(-partctrl->offsetRandom.z() / 2.f, partctrl->offsetRandom.z() / 2.f);
|
||||
placer->setXRange(-partctrl->mEmitterDimensions.x() / 2.f, partctrl->mEmitterDimensions.x() / 2.f);
|
||||
placer->setYRange(-partctrl->mEmitterDimensions.y() / 2.f, partctrl->mEmitterDimensions.y() / 2.f);
|
||||
placer->setZRange(-partctrl->mEmitterDimensions.z() / 2.f, partctrl->mEmitterDimensions.z() / 2.f);
|
||||
emitter->setPlacer(placer);
|
||||
}
|
||||
|
||||
|
@ -1280,11 +1280,11 @@ namespace NifOsg
|
|||
|
||||
handleParticleInitialState(nifNode, partsys, partctrl);
|
||||
|
||||
partsys->getDefaultParticleTemplate().setSizeRange(osgParticle::rangef(partctrl->size, partctrl->size));
|
||||
partsys->getDefaultParticleTemplate().setColorRange(osgParticle::rangev4(partctrl->color, partctrl->color));
|
||||
partsys->getDefaultParticleTemplate().setSizeRange(osgParticle::rangef(partctrl->mInitialSize, partctrl->mInitialSize));
|
||||
partsys->getDefaultParticleTemplate().setColorRange(osgParticle::rangev4(partctrl->mInitialColor, partctrl->mInitialColor));
|
||||
partsys->getDefaultParticleTemplate().setAlphaRange(osgParticle::rangef(1.f, 1.f));
|
||||
|
||||
if (!partctrl->emitter.empty())
|
||||
if (!partctrl->mEmitter.empty())
|
||||
{
|
||||
osg::ref_ptr<Emitter> emitter = handleParticleEmitter(partctrl);
|
||||
emitter->setParticleSystem(partsys);
|
||||
|
@ -1293,7 +1293,7 @@ namespace NifOsg
|
|||
// The emitter node may not actually be handled yet, so let's delay attaching the emitter to a later
|
||||
// moment. If the emitter node is placed later than the particle node, it'll have a single frame delay
|
||||
// in particle processing. But that shouldn't be a game-breaking issue.
|
||||
mEmitterQueue.emplace_back(partctrl->emitter->recIndex, emitter);
|
||||
mEmitterQueue.emplace_back(partctrl->mEmitter->recIndex, emitter);
|
||||
|
||||
osg::ref_ptr<ParticleSystemController> callback(new ParticleSystemController(partctrl));
|
||||
setupController(partctrl, callback, animflags);
|
||||
|
@ -1310,16 +1310,16 @@ namespace NifOsg
|
|||
partsys->update(0.0, nv);
|
||||
}
|
||||
|
||||
// affectors should be attached *after* the emitter in the scene graph for correct update order
|
||||
// modifiers should be attached *after* the emitter in the scene graph for correct update order
|
||||
// attach to same node as the ParticleSystem, we need osgParticle Operators to get the correct
|
||||
// localToWorldMatrix for transforming to particle space
|
||||
handleParticlePrograms(partctrl->affectors, partctrl->colliders, parentNode, partsys.get(), rf);
|
||||
handleParticlePrograms(partctrl->mModifier, partctrl->mCollider, parentNode, partsys.get(), rf);
|
||||
|
||||
std::vector<const Nif::Property*> drawableProps;
|
||||
collectDrawableProperties(nifNode, parent, drawableProps);
|
||||
applyDrawableProperties(parentNode, drawableProps, composite, true, animflags);
|
||||
|
||||
// particle system updater (after the emitters and affectors in the scene graph)
|
||||
// particle system updater (after the emitters and modifiers in the scene graph)
|
||||
// I think for correct culling needs to be *before* the ParticleSystem, though osg examples do it the other
|
||||
// way
|
||||
osg::ref_ptr<osgParticle::ParticleSystemUpdater> updater = new osgParticle::ParticleSystemUpdater;
|
||||
|
|
Loading…
Reference in a new issue