mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-05 03:45:35 +00:00
Merge branch 'particles' into projectiles
This commit is contained in:
commit
e7ad503e30
3 changed files with 159 additions and 34 deletions
|
@ -137,7 +137,8 @@ struct NiNode : Node
|
||||||
AnimFlag_AutoPlay = 0x0020
|
AnimFlag_AutoPlay = 0x0020
|
||||||
};
|
};
|
||||||
enum BSParticleFlags {
|
enum BSParticleFlags {
|
||||||
ParticleFlag_AutoPlay = 0x0020
|
ParticleFlag_AutoPlay = 0x0020,
|
||||||
|
ParticleFlag_LocalSpace = 0x0080
|
||||||
};
|
};
|
||||||
|
|
||||||
void read(NIFStream *nif)
|
void read(NIFStream *nif)
|
||||||
|
|
|
@ -497,7 +497,9 @@ class NIFObjectLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void createParticleEmitterAffectors(Ogre::ParticleSystem *partsys, const Nif::NiParticleSystemController *partctrl)
|
static void createParticleEmitterAffectors(Ogre::ParticleSystem *partsys,
|
||||||
|
const Nif::NiParticleSystemController *partctrl, Ogre::Bone* bone,
|
||||||
|
const std::string& skelBaseName)
|
||||||
{
|
{
|
||||||
Ogre::ParticleEmitter *emitter = partsys->addEmitter("Nif");
|
Ogre::ParticleEmitter *emitter = partsys->addEmitter("Nif");
|
||||||
emitter->setParticleVelocity(partctrl->velocity - partctrl->velocityRandom*0.5f,
|
emitter->setParticleVelocity(partctrl->velocity - partctrl->velocityRandom*0.5f,
|
||||||
|
@ -512,6 +514,8 @@ class NIFObjectLoader
|
||||||
emitter->setParameter("vertical_angle", Ogre::StringConverter::toString(Ogre::Radian(partctrl->verticalAngle).valueDegrees()));
|
emitter->setParameter("vertical_angle", Ogre::StringConverter::toString(Ogre::Radian(partctrl->verticalAngle).valueDegrees()));
|
||||||
emitter->setParameter("horizontal_direction", Ogre::StringConverter::toString(Ogre::Radian(partctrl->horizontalDir).valueDegrees()));
|
emitter->setParameter("horizontal_direction", Ogre::StringConverter::toString(Ogre::Radian(partctrl->horizontalDir).valueDegrees()));
|
||||||
emitter->setParameter("horizontal_angle", Ogre::StringConverter::toString(Ogre::Radian(partctrl->horizontalAngle).valueDegrees()));
|
emitter->setParameter("horizontal_angle", Ogre::StringConverter::toString(Ogre::Radian(partctrl->horizontalAngle).valueDegrees()));
|
||||||
|
emitter->setParameter("skelbase", skelBaseName);
|
||||||
|
emitter->setParameter("bone", bone->getName());
|
||||||
|
|
||||||
Nif::ExtraPtr e = partctrl->extra;
|
Nif::ExtraPtr e = partctrl->extra;
|
||||||
while(!e.empty())
|
while(!e.empty())
|
||||||
|
@ -533,6 +537,8 @@ class NIFObjectLoader
|
||||||
affector->setParameter("force_type", (gr->mType==0) ? "wind" : "point");
|
affector->setParameter("force_type", (gr->mType==0) ? "wind" : "point");
|
||||||
affector->setParameter("direction", Ogre::StringConverter::toString(gr->mDirection));
|
affector->setParameter("direction", Ogre::StringConverter::toString(gr->mDirection));
|
||||||
affector->setParameter("position", Ogre::StringConverter::toString(gr->mPosition));
|
affector->setParameter("position", Ogre::StringConverter::toString(gr->mPosition));
|
||||||
|
affector->setParameter("skelbase", skelBaseName);
|
||||||
|
affector->setParameter("bone", bone->getName());
|
||||||
}
|
}
|
||||||
else if(e->recType == Nif::RC_NiParticleColorModifier)
|
else if(e->recType == Nif::RC_NiParticleColorModifier)
|
||||||
{
|
{
|
||||||
|
@ -565,7 +571,7 @@ class NIFObjectLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
static void createParticleSystem(const std::string &name, const std::string &group,
|
static void createParticleSystem(const std::string &name, const std::string &group,
|
||||||
Ogre::SceneManager *sceneMgr, ObjectList &objectlist,
|
Ogre::SceneNode *sceneNode, ObjectList &objectlist,
|
||||||
const Nif::Node *partnode, int flags, int partflags)
|
const Nif::Node *partnode, int flags, int partflags)
|
||||||
{
|
{
|
||||||
const Nif::NiAutoNormalParticlesData *particledata = NULL;
|
const Nif::NiAutoNormalParticlesData *particledata = NULL;
|
||||||
|
@ -579,7 +585,7 @@ class NIFObjectLoader
|
||||||
fullname += "@type="+partnode->name;
|
fullname += "@type="+partnode->name;
|
||||||
Misc::StringUtils::toLower(fullname);
|
Misc::StringUtils::toLower(fullname);
|
||||||
|
|
||||||
Ogre::ParticleSystem *partsys = sceneMgr->createParticleSystem();
|
Ogre::ParticleSystem *partsys = sceneNode->getCreator()->createParticleSystem();
|
||||||
|
|
||||||
const Nif::NiTexturingProperty *texprop = NULL;
|
const Nif::NiTexturingProperty *texprop = NULL;
|
||||||
const Nif::NiMaterialProperty *matprop = NULL;
|
const Nif::NiMaterialProperty *matprop = NULL;
|
||||||
|
@ -600,9 +606,9 @@ class NIFObjectLoader
|
||||||
particledata->particleRadius*2.0f);
|
particledata->particleRadius*2.0f);
|
||||||
partsys->setCullIndividually(false);
|
partsys->setCullIndividually(false);
|
||||||
partsys->setParticleQuota(particledata->numParticles);
|
partsys->setParticleQuota(particledata->numParticles);
|
||||||
// TODO: There is probably a field or flag to specify this, as some
|
partsys->setKeepParticlesInLocalSpace(partflags & (Nif::NiNode::ParticleFlag_LocalSpace));
|
||||||
// particle effects have it and some don't.
|
|
||||||
partsys->setKeepParticlesInLocalSpace(false);
|
sceneNode->attachObject(partsys);
|
||||||
|
|
||||||
Nif::ControllerPtr ctrl = partnode->controller;
|
Nif::ControllerPtr ctrl = partnode->controller;
|
||||||
while(!ctrl.empty())
|
while(!ctrl.empty())
|
||||||
|
@ -611,12 +617,11 @@ class NIFObjectLoader
|
||||||
{
|
{
|
||||||
const Nif::NiParticleSystemController *partctrl = static_cast<const Nif::NiParticleSystemController*>(ctrl.getPtr());
|
const Nif::NiParticleSystemController *partctrl = static_cast<const Nif::NiParticleSystemController*>(ctrl.getPtr());
|
||||||
|
|
||||||
createParticleEmitterAffectors(partsys, partctrl);
|
if(!partctrl->emitter.empty())
|
||||||
if(!partctrl->emitter.empty() && !partsys->isAttached())
|
|
||||||
{
|
{
|
||||||
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partctrl->emitter->recIndex);
|
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partctrl->emitter->recIndex);
|
||||||
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
|
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
|
||||||
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), partsys);
|
createParticleEmitterAffectors(partsys, partctrl, trgtbone, objectlist.mSkelBase->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::ControllerValueRealPtr srcval((partflags&Nif::NiNode::ParticleFlag_AutoPlay) ?
|
Ogre::ControllerValueRealPtr srcval((partflags&Nif::NiNode::ParticleFlag_AutoPlay) ?
|
||||||
|
@ -634,13 +639,6 @@ class NIFObjectLoader
|
||||||
ctrl = ctrl->next;
|
ctrl = ctrl->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!partsys->isAttached())
|
|
||||||
{
|
|
||||||
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partnode->recIndex);
|
|
||||||
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
|
|
||||||
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), partsys);
|
|
||||||
}
|
|
||||||
|
|
||||||
partsys->setVisible(!(flags&Nif::NiNode::Flag_Hidden));
|
partsys->setVisible(!(flags&Nif::NiNode::Flag_Hidden));
|
||||||
objectlist.mParticles.push_back(partsys);
|
objectlist.mParticles.push_back(partsys);
|
||||||
}
|
}
|
||||||
|
@ -729,7 +727,7 @@ class NIFObjectLoader
|
||||||
|
|
||||||
|
|
||||||
static void createObjects(const std::string &name, const std::string &group,
|
static void createObjects(const std::string &name, const std::string &group,
|
||||||
Ogre::SceneManager *sceneMgr, const Nif::Node *node,
|
Ogre::SceneNode *sceneNode, const Nif::Node *node,
|
||||||
ObjectList &objectlist, int flags, int animflags, int partflags)
|
ObjectList &objectlist, int flags, int animflags, int partflags)
|
||||||
{
|
{
|
||||||
// Do not create objects for the collision shape (includes all children)
|
// Do not create objects for the collision shape (includes all children)
|
||||||
|
@ -784,13 +782,13 @@ class NIFObjectLoader
|
||||||
|
|
||||||
if(node->recType == Nif::RC_NiTriShape && !(flags&0x80000000))
|
if(node->recType == Nif::RC_NiTriShape && !(flags&0x80000000))
|
||||||
{
|
{
|
||||||
createEntity(name, group, sceneMgr, objectlist, node, flags, animflags);
|
createEntity(name, group, sceneNode->getCreator(), objectlist, node, flags, animflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((node->recType == Nif::RC_NiAutoNormalParticles ||
|
if((node->recType == Nif::RC_NiAutoNormalParticles ||
|
||||||
node->recType == Nif::RC_NiRotatingParticles) && !(flags&0x40000000))
|
node->recType == Nif::RC_NiRotatingParticles) && !(flags&0x40000000))
|
||||||
{
|
{
|
||||||
createParticleSystem(name, group, sceneMgr, objectlist, node, flags, partflags);
|
createParticleSystem(name, group, sceneNode, objectlist, node, flags, partflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node);
|
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node);
|
||||||
|
@ -800,7 +798,7 @@ class NIFObjectLoader
|
||||||
for(size_t i = 0;i < children.length();i++)
|
for(size_t i = 0;i < children.length();i++)
|
||||||
{
|
{
|
||||||
if(!children[i].empty())
|
if(!children[i].empty())
|
||||||
createObjects(name, group, sceneMgr, children[i].getPtr(), objectlist, flags, animflags, partflags);
|
createObjects(name, group, sceneNode, children[i].getPtr(), objectlist, flags, animflags, partflags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -821,7 +819,7 @@ class NIFObjectLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void load(Ogre::SceneManager *sceneMgr, ObjectList &objectlist, const std::string &name, const std::string &group, int flags=0)
|
static void load(Ogre::SceneNode *sceneNode, ObjectList &objectlist, const std::string &name, const std::string &group, int flags=0)
|
||||||
{
|
{
|
||||||
Nif::NIFFile::ptr nif = Nif::NIFFile::create(name);
|
Nif::NIFFile::ptr nif = Nif::NIFFile::create(name);
|
||||||
if(nif->numRoots() < 1)
|
if(nif->numRoots() < 1)
|
||||||
|
@ -845,9 +843,9 @@ public:
|
||||||
!NIFSkeletonLoader::createSkeleton(name, group, node).isNull())
|
!NIFSkeletonLoader::createSkeleton(name, group, node).isNull())
|
||||||
{
|
{
|
||||||
// Create a base skeleton entity if this NIF needs one
|
// Create a base skeleton entity if this NIF needs one
|
||||||
createSkelBase(name, group, sceneMgr, node, objectlist);
|
createSkelBase(name, group, sceneNode->getCreator(), node, objectlist);
|
||||||
}
|
}
|
||||||
createObjects(name, group, sceneMgr, node, objectlist, flags, 0, 0);
|
createObjects(name, group, sceneNode, node, objectlist, flags, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadKf(Ogre::Skeleton *skel, const std::string &name,
|
static void loadKf(Ogre::Skeleton *skel, const std::string &name,
|
||||||
|
@ -915,7 +913,7 @@ ObjectList Loader::createObjects(Ogre::SceneNode *parentNode, std::string name,
|
||||||
ObjectList objectlist;
|
ObjectList objectlist;
|
||||||
|
|
||||||
Misc::StringUtils::toLower(name);
|
Misc::StringUtils::toLower(name);
|
||||||
NIFObjectLoader::load(parentNode->getCreator(), objectlist, name, group);
|
NIFObjectLoader::load(parentNode, objectlist, name, group);
|
||||||
|
|
||||||
for(size_t i = 0;i < objectlist.mEntities.size();i++)
|
for(size_t i = 0;i < objectlist.mEntities.size();i++)
|
||||||
{
|
{
|
||||||
|
@ -934,7 +932,7 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena
|
||||||
ObjectList objectlist;
|
ObjectList objectlist;
|
||||||
|
|
||||||
Misc::StringUtils::toLower(name);
|
Misc::StringUtils::toLower(name);
|
||||||
NIFObjectLoader::load(parentNode->getCreator(), objectlist, name, group);
|
NIFObjectLoader::load(parentNode, objectlist, name, group);
|
||||||
|
|
||||||
bool isskinned = false;
|
bool isskinned = false;
|
||||||
for(size_t i = 0;i < objectlist.mEntities.size();i++)
|
for(size_t i = 0;i < objectlist.mEntities.size();i++)
|
||||||
|
@ -984,6 +982,17 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(size_t i = 0;i < objectlist.mParticles.size();i++)
|
||||||
|
{
|
||||||
|
Ogre::ParticleSystem *partsys = objectlist.mParticles[i];
|
||||||
|
if(partsys->isAttached())
|
||||||
|
partsys->detachFromParent();
|
||||||
|
|
||||||
|
Ogre::TagPoint *tag = objectlist.mSkelBase->attachObjectToBone(
|
||||||
|
objectlist.mSkelBase->getSkeleton()->getRootBone()->getName(), partsys);
|
||||||
|
tag->setScale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
return objectlist;
|
return objectlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,7 +1002,7 @@ ObjectList Loader::createObjectBase(Ogre::SceneNode *parentNode, std::string nam
|
||||||
ObjectList objectlist;
|
ObjectList objectlist;
|
||||||
|
|
||||||
Misc::StringUtils::toLower(name);
|
Misc::StringUtils::toLower(name);
|
||||||
NIFObjectLoader::load(parentNode->getCreator(), objectlist, name, group, 0xC0000000);
|
NIFObjectLoader::load(parentNode, objectlist, name, group, 0xC0000000);
|
||||||
|
|
||||||
if(objectlist.mSkelBase)
|
if(objectlist.mSkelBase)
|
||||||
parentNode->attachObject(objectlist.mSkelBase);
|
parentNode->attachObject(objectlist.mSkelBase);
|
||||||
|
|
|
@ -5,11 +5,55 @@
|
||||||
#include <OgreParticleEmitter.h>
|
#include <OgreParticleEmitter.h>
|
||||||
#include <OgreParticleAffector.h>
|
#include <OgreParticleAffector.h>
|
||||||
#include <OgreParticle.h>
|
#include <OgreParticle.h>
|
||||||
|
#include <OgreBone.h>
|
||||||
|
#include <OgreTagPoint.h>
|
||||||
|
#include <OgreEntity.h>
|
||||||
|
#include <OgreSkeletonInstance.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
/* FIXME: "Nif" isn't really an appropriate emitter name. */
|
/* FIXME: "Nif" isn't really an appropriate emitter name. */
|
||||||
class NifEmitter : public Ogre::ParticleEmitter
|
class NifEmitter : public Ogre::ParticleEmitter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
std::string mSkelBaseName;
|
||||||
|
Ogre::Bone* mBone;
|
||||||
|
|
||||||
|
Ogre::ParticleSystem* getPartSys() { return mParent; }
|
||||||
|
|
||||||
|
class CmdSkelBase : public Ogre::ParamCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Ogre::String doGet(const void *target) const
|
||||||
|
{
|
||||||
|
assert(false && "Unimplemented");
|
||||||
|
}
|
||||||
|
void doSet(void *target, const Ogre::String &val)
|
||||||
|
{
|
||||||
|
NifEmitter* emitter = static_cast<NifEmitter*>(target);
|
||||||
|
emitter->mSkelBaseName = val;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CmdBone : public Ogre::ParamCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Ogre::String doGet(const void *target) const
|
||||||
|
{
|
||||||
|
assert(false && "Unimplemented");
|
||||||
|
}
|
||||||
|
void doSet(void *target, const Ogre::String &val)
|
||||||
|
{
|
||||||
|
NifEmitter* emitter = static_cast<NifEmitter*>(target);
|
||||||
|
assert(!emitter->mSkelBaseName.empty() && "Base entity needs to be set first");
|
||||||
|
Ogre::ParticleSystem* partsys = emitter->getPartSys();
|
||||||
|
Ogre::Entity* ent = partsys->getParentSceneNode()->getCreator()->getEntity(emitter->mSkelBaseName);
|
||||||
|
Ogre::Bone* bone = ent->getSkeleton()->getBone(val);
|
||||||
|
assert(bone);
|
||||||
|
emitter->mBone = bone;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** Command object for the emitter width (see Ogre::ParamCommand).*/
|
/** Command object for the emitter width (see Ogre::ParamCommand).*/
|
||||||
class CmdWidth : public Ogre::ParamCommand
|
class CmdWidth : public Ogre::ParamCommand
|
||||||
{
|
{
|
||||||
|
@ -119,6 +163,7 @@ public:
|
||||||
|
|
||||||
NifEmitter(Ogre::ParticleSystem *psys)
|
NifEmitter(Ogre::ParticleSystem *psys)
|
||||||
: Ogre::ParticleEmitter(psys)
|
: Ogre::ParticleEmitter(psys)
|
||||||
|
, mBone(NULL)
|
||||||
{
|
{
|
||||||
initDefaults("Nif");
|
initDefaults("Nif");
|
||||||
}
|
}
|
||||||
|
@ -133,6 +178,7 @@ public:
|
||||||
/** See Ogre::ParticleEmitter. */
|
/** See Ogre::ParticleEmitter. */
|
||||||
void _initParticle(Ogre::Particle *particle)
|
void _initParticle(Ogre::Particle *particle)
|
||||||
{
|
{
|
||||||
|
assert (mBone && "No node set");
|
||||||
Ogre::Vector3 xOff, yOff, zOff;
|
Ogre::Vector3 xOff, yOff, zOff;
|
||||||
|
|
||||||
// Call superclass
|
// Call superclass
|
||||||
|
@ -142,7 +188,7 @@ public:
|
||||||
yOff = Ogre::Math::SymmetricRandom() * mYRange;
|
yOff = Ogre::Math::SymmetricRandom() * mYRange;
|
||||||
zOff = Ogre::Math::SymmetricRandom() * mZRange;
|
zOff = Ogre::Math::SymmetricRandom() * mZRange;
|
||||||
|
|
||||||
particle->position = mPosition + xOff + yOff + zOff;
|
particle->position = mBone->_getDerivedPosition() + xOff + yOff + zOff;
|
||||||
|
|
||||||
// Generate complex data by reference
|
// Generate complex data by reference
|
||||||
genEmissionColour(particle->colour);
|
genEmissionColour(particle->colour);
|
||||||
|
@ -150,7 +196,7 @@ public:
|
||||||
// NOTE: We do not use mDirection/mAngle for the initial direction.
|
// NOTE: We do not use mDirection/mAngle for the initial direction.
|
||||||
Ogre::Radian hdir = mHorizontalDir + mHorizontalAngle*Ogre::Math::SymmetricRandom();
|
Ogre::Radian hdir = mHorizontalDir + mHorizontalAngle*Ogre::Math::SymmetricRandom();
|
||||||
Ogre::Radian vdir = mVerticalDir + mVerticalAngle*Ogre::Math::SymmetricRandom();
|
Ogre::Radian vdir = mVerticalDir + mVerticalAngle*Ogre::Math::SymmetricRandom();
|
||||||
particle->direction = (Ogre::Quaternion(hdir, Ogre::Vector3::UNIT_Z) *
|
particle->direction = (mBone->_getDerivedOrientation() * Ogre::Quaternion(hdir, Ogre::Vector3::UNIT_Z) *
|
||||||
Ogre::Quaternion(vdir, Ogre::Vector3::UNIT_X)) *
|
Ogre::Quaternion(vdir, Ogre::Vector3::UNIT_X)) *
|
||||||
Ogre::Vector3::UNIT_Z;
|
Ogre::Vector3::UNIT_Z;
|
||||||
|
|
||||||
|
@ -313,6 +359,16 @@ protected:
|
||||||
Ogre::PT_REAL),
|
Ogre::PT_REAL),
|
||||||
&msHorizontalAngleCmd);
|
&msHorizontalAngleCmd);
|
||||||
|
|
||||||
|
dict->addParameter(Ogre::ParameterDef("bone",
|
||||||
|
"The bone where the particles should be spawned",
|
||||||
|
Ogre::PT_STRING),
|
||||||
|
&msBoneCmd);
|
||||||
|
|
||||||
|
dict->addParameter(Ogre::ParameterDef("skelbase",
|
||||||
|
"The name of the entity containing the bone (see 'bone' parameter)",
|
||||||
|
Ogre::PT_STRING),
|
||||||
|
&msSkelBaseCmd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -326,6 +382,8 @@ protected:
|
||||||
static CmdVerticalAngle msVerticalAngleCmd;
|
static CmdVerticalAngle msVerticalAngleCmd;
|
||||||
static CmdHorizontalDir msHorizontalDirCmd;
|
static CmdHorizontalDir msHorizontalDirCmd;
|
||||||
static CmdHorizontalAngle msHorizontalAngleCmd;
|
static CmdHorizontalAngle msHorizontalAngleCmd;
|
||||||
|
static CmdBone msBoneCmd;
|
||||||
|
static CmdSkelBase msSkelBaseCmd;
|
||||||
};
|
};
|
||||||
NifEmitter::CmdWidth NifEmitter::msWidthCmd;
|
NifEmitter::CmdWidth NifEmitter::msWidthCmd;
|
||||||
NifEmitter::CmdHeight NifEmitter::msHeightCmd;
|
NifEmitter::CmdHeight NifEmitter::msHeightCmd;
|
||||||
|
@ -334,12 +392,14 @@ NifEmitter::CmdVerticalDir NifEmitter::msVerticalDirCmd;
|
||||||
NifEmitter::CmdVerticalAngle NifEmitter::msVerticalAngleCmd;
|
NifEmitter::CmdVerticalAngle NifEmitter::msVerticalAngleCmd;
|
||||||
NifEmitter::CmdHorizontalDir NifEmitter::msHorizontalDirCmd;
|
NifEmitter::CmdHorizontalDir NifEmitter::msHorizontalDirCmd;
|
||||||
NifEmitter::CmdHorizontalAngle NifEmitter::msHorizontalAngleCmd;
|
NifEmitter::CmdHorizontalAngle NifEmitter::msHorizontalAngleCmd;
|
||||||
|
NifEmitter::CmdBone NifEmitter::msBoneCmd;
|
||||||
|
NifEmitter::CmdSkelBase NifEmitter::msSkelBaseCmd;
|
||||||
|
|
||||||
Ogre::ParticleEmitter* NifEmitterFactory::createEmitter(Ogre::ParticleSystem *psys)
|
Ogre::ParticleEmitter* NifEmitterFactory::createEmitter(Ogre::ParticleSystem *psys)
|
||||||
{
|
{
|
||||||
Ogre::ParticleEmitter *emit = OGRE_NEW NifEmitter(psys);
|
Ogre::ParticleEmitter *emitter = OGRE_NEW NifEmitter(psys);
|
||||||
mEmitters.push_back(emit);
|
mEmitters.push_back(emitter);
|
||||||
return emit;
|
return emitter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -492,6 +552,45 @@ class GravityAffector : public Ogre::ParticleAffector
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
std::string mSkelBaseName;
|
||||||
|
Ogre::Bone* mBone;
|
||||||
|
|
||||||
|
Ogre::ParticleSystem* getPartSys() { return mParent; }
|
||||||
|
|
||||||
|
class CmdSkelBase : public Ogre::ParamCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Ogre::String doGet(const void *target) const
|
||||||
|
{
|
||||||
|
assert(false && "Unimplemented");
|
||||||
|
}
|
||||||
|
void doSet(void *target, const Ogre::String &val)
|
||||||
|
{
|
||||||
|
GravityAffector* affector = static_cast<GravityAffector*>(target);
|
||||||
|
affector->mSkelBaseName = val;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CmdBone : public Ogre::ParamCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Ogre::String doGet(const void *target) const
|
||||||
|
{
|
||||||
|
assert(false && "Unimplemented");
|
||||||
|
}
|
||||||
|
void doSet(void *target, const Ogre::String &val)
|
||||||
|
{
|
||||||
|
GravityAffector* affector = static_cast<GravityAffector*>(target);
|
||||||
|
assert(!affector->mSkelBaseName.empty() && "Base entity needs to be set first");
|
||||||
|
Ogre::ParticleSystem* partsys = affector->getPartSys();
|
||||||
|
Ogre::Entity* ent = partsys->getParentSceneNode()->getCreator()->getEntity(affector->mSkelBaseName);
|
||||||
|
Ogre::Bone* bone = ent->getSkeleton()->getBone(val);
|
||||||
|
assert(bone);
|
||||||
|
affector->mBone = bone;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Command object for force (see Ogre::ParamCommand).*/
|
/** Command object for force (see Ogre::ParamCommand).*/
|
||||||
class CmdForce : public Ogre::ParamCommand
|
class CmdForce : public Ogre::ParamCommand
|
||||||
{
|
{
|
||||||
|
@ -585,6 +684,7 @@ public:
|
||||||
, mForceType(Type_Wind)
|
, mForceType(Type_Wind)
|
||||||
, mPosition(0.0f)
|
, mPosition(0.0f)
|
||||||
, mDirection(0.0f)
|
, mDirection(0.0f)
|
||||||
|
, mBone(NULL)
|
||||||
{
|
{
|
||||||
mType = "Gravity";
|
mType = "Gravity";
|
||||||
|
|
||||||
|
@ -606,6 +706,16 @@ public:
|
||||||
dict->addParameter(Ogre::ParameterDef(force_type_title, force_type_descr, Ogre::PT_STRING), &msForceTypeCmd);
|
dict->addParameter(Ogre::ParameterDef(force_type_title, force_type_descr, Ogre::PT_STRING), &msForceTypeCmd);
|
||||||
dict->addParameter(Ogre::ParameterDef(direction_title, direction_descr, Ogre::PT_VECTOR3), &msDirectionCmd);
|
dict->addParameter(Ogre::ParameterDef(direction_title, direction_descr, Ogre::PT_VECTOR3), &msDirectionCmd);
|
||||||
dict->addParameter(Ogre::ParameterDef(position_title, position_descr, Ogre::PT_VECTOR3), &msPositionCmd);
|
dict->addParameter(Ogre::ParameterDef(position_title, position_descr, Ogre::PT_VECTOR3), &msPositionCmd);
|
||||||
|
|
||||||
|
dict->addParameter(Ogre::ParameterDef("bone",
|
||||||
|
"The bone where the particles should be spawned",
|
||||||
|
Ogre::PT_STRING),
|
||||||
|
&msBoneCmd);
|
||||||
|
|
||||||
|
dict->addParameter(Ogre::ParameterDef("skelbase",
|
||||||
|
"The name of the entity containing the bone (see 'bone' parameter)",
|
||||||
|
Ogre::PT_STRING),
|
||||||
|
&msSkelBaseCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,6 +757,8 @@ public:
|
||||||
static CmdForceType msForceTypeCmd;
|
static CmdForceType msForceTypeCmd;
|
||||||
static CmdDirection msDirectionCmd;
|
static CmdDirection msDirectionCmd;
|
||||||
static CmdPosition msPositionCmd;
|
static CmdPosition msPositionCmd;
|
||||||
|
static CmdBone msBoneCmd;
|
||||||
|
static CmdSkelBase msSkelBaseCmd;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void applyWindForce(Ogre::ParticleSystem *psys, Ogre::Real timeElapsed)
|
void applyWindForce(Ogre::ParticleSystem *psys, Ogre::Real timeElapsed)
|
||||||
|
@ -667,7 +779,8 @@ protected:
|
||||||
while (!pi.end())
|
while (!pi.end())
|
||||||
{
|
{
|
||||||
Ogre::Particle *p = pi.getNext();
|
Ogre::Particle *p = pi.getNext();
|
||||||
const Ogre::Vector3 vec = (p->position - mPosition).normalisedCopy() * force;
|
const Ogre::Vector3 vec = (
|
||||||
|
(mBone->_getDerivedOrientation() * mPosition + mBone->_getDerivedPosition()) - p->position).normalisedCopy() * force;
|
||||||
p->direction += vec;
|
p->direction += vec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -684,6 +797,8 @@ GravityAffector::CmdForce GravityAffector::msForceCmd;
|
||||||
GravityAffector::CmdForceType GravityAffector::msForceTypeCmd;
|
GravityAffector::CmdForceType GravityAffector::msForceTypeCmd;
|
||||||
GravityAffector::CmdDirection GravityAffector::msDirectionCmd;
|
GravityAffector::CmdDirection GravityAffector::msDirectionCmd;
|
||||||
GravityAffector::CmdPosition GravityAffector::msPositionCmd;
|
GravityAffector::CmdPosition GravityAffector::msPositionCmd;
|
||||||
|
GravityAffector::CmdBone GravityAffector::msBoneCmd;
|
||||||
|
GravityAffector::CmdSkelBase GravityAffector::msSkelBaseCmd;
|
||||||
|
|
||||||
Ogre::ParticleAffector *GravityAffectorFactory::createAffector(Ogre::ParticleSystem *psys)
|
Ogre::ParticleAffector *GravityAffectorFactory::createAffector(Ogre::ParticleSystem *psys)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue