forked from mirror/openmw-tes3mp
Add world space particle systems, will need more changes when emitters are added
This commit is contained in:
parent
510375aa63
commit
f843e12538
2 changed files with 43 additions and 5 deletions
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <osgGA/TrackballManipulator>
|
#include <osgGA/TrackballManipulator>
|
||||||
|
|
||||||
#include <osgDB/Registry>
|
|
||||||
#include <osgDB/WriteFile>
|
#include <osgDB/WriteFile>
|
||||||
|
|
||||||
#include <osg/PolygonMode>
|
#include <osg/PolygonMode>
|
||||||
|
|
|
@ -192,11 +192,37 @@ namespace
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Node callback used to set the inverse of the parent's world matrix on the MatrixTransform
|
||||||
|
// that the callback is attached to. Used for certain particle systems,
|
||||||
|
// so that the particles do not move with the node they are attached to.
|
||||||
|
class InverseWorldMatrix : public osg::NodeCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InverseWorldMatrix()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
|
||||||
|
{
|
||||||
|
osg::NodePath path = nv->getNodePath();
|
||||||
|
path.pop_back();
|
||||||
|
|
||||||
|
osg::MatrixTransform* trans = dynamic_cast<osg::MatrixTransform*>(node);
|
||||||
|
|
||||||
|
osg::Matrix worldMat = osg::computeLocalToWorld( path );
|
||||||
|
trans->setMatrix(osg::Matrix::inverse(worldMat));
|
||||||
|
}
|
||||||
|
traverse(node,nv);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geometry> handleMorphGeometry(const Nif::NiGeomMorpherController* morpher)
|
osg::ref_ptr<osg::Geometry> handleMorphGeometry(const Nif::NiGeomMorpherController* morpher)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osgAnimation::MorphGeometry> morphGeom = new osgAnimation::MorphGeometry;
|
osg::ref_ptr<osgAnimation::MorphGeometry> morphGeom = new osgAnimation::MorphGeometry;
|
||||||
morphGeom->setMethod(osgAnimation::MorphGeometry::RELATIVE);
|
morphGeom->setMethod(osgAnimation::MorphGeometry::RELATIVE);
|
||||||
// NIF format doesn't specify morphed normals
|
// No normals available in the MorphData
|
||||||
morphGeom->setMorphNormals(false);
|
morphGeom->setMorphNormals(false);
|
||||||
|
|
||||||
const std::vector<Nif::NiMorphData::MorphData>& morphs = morpher->data.getPtr()->mMorphs;
|
const std::vector<Nif::NiMorphData::MorphData>& morphs = morpher->data.getPtr()->mMorphs;
|
||||||
|
@ -499,6 +525,10 @@ namespace NifOsg
|
||||||
if (!partctrl)
|
if (!partctrl)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
osg::Matrix particletransform;
|
||||||
|
if (!(particleflags & Nif::NiNode::ParticleFlag_LocalSpace))
|
||||||
|
particletransform = getWorldTransform(nifNode);
|
||||||
|
|
||||||
int i=0;
|
int i=0;
|
||||||
for (std::vector<Nif::NiParticleSystemController::Particle>::const_iterator it = partctrl->particles.begin();
|
for (std::vector<Nif::NiParticleSystemController::Particle>::const_iterator it = partctrl->particles.begin();
|
||||||
i<particledata->activeCount && it != partctrl->particles.end(); ++it, ++i)
|
i<particledata->activeCount && it != partctrl->particles.end(); ++it, ++i)
|
||||||
|
@ -509,8 +539,8 @@ namespace NifOsg
|
||||||
|
|
||||||
osgParticle::Particle* created = partsys->createParticle(&particletemplate);
|
osgParticle::Particle* created = partsys->createParticle(&particletemplate);
|
||||||
created->setLifeTime(500);//std::max(0.f, particle.lifespan));
|
created->setLifeTime(500);//std::max(0.f, particle.lifespan));
|
||||||
created->setVelocity(particle.velocity);
|
created->setVelocity(particle.velocity * particletransform);
|
||||||
created->setPosition(particledata->vertices.at(particle.vertex));
|
created->setPosition(particledata->vertices.at(particle.vertex) * particletransform);
|
||||||
|
|
||||||
osg::Vec4f partcolor (1.f,1.f,1.f,1.f);
|
osg::Vec4f partcolor (1.f,1.f,1.f,1.f);
|
||||||
if (particle.vertex < int(particledata->colors.size()))
|
if (particle.vertex < int(particledata->colors.size()))
|
||||||
|
@ -534,7 +564,16 @@ namespace NifOsg
|
||||||
partsys->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
partsys->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||||
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
||||||
geode->addDrawable(partsys);
|
geode->addDrawable(partsys);
|
||||||
|
|
||||||
|
if (particleflags & Nif::NiNode::ParticleFlag_LocalSpace)
|
||||||
parentNode->addChild(geode);
|
parentNode->addChild(geode);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
osg::MatrixTransform* trans = new osg::MatrixTransform;
|
||||||
|
trans->setUpdateCallback(new InverseWorldMatrix);
|
||||||
|
trans->addChild(geode);
|
||||||
|
parentNode->addChild(trans);
|
||||||
|
}
|
||||||
|
|
||||||
osgParticle::ParticleSystemUpdater* updater = new osgParticle::ParticleSystemUpdater;
|
osgParticle::ParticleSystemUpdater* updater = new osgParticle::ParticleSystemUpdater;
|
||||||
updater->addParticleSystem(partsys);
|
updater->addParticleSystem(partsys);
|
||||||
|
|
Loading…
Reference in a new issue