Here is my FluidEmitterSceneNode class/
Maybe it will be usefull for someone
I'm not sio2, I can share
Code: Select all
#define MAX_PARTICLES 10000
class CFluidEmitterSceneNode : public scene::ISceneNode
{
private:
MyFluid *m_fluid;
NxFluidEmitter *m_emitter;
SMeshBuffer *Buffer;
NxReal m_particleSize;
public:
CFluidEmitterSceneNode(f32 size, Physx* physx,
ISceneNode* parent, ISceneManager* mgr, s32 id):
ISceneNode(parent, mgr, id), m_particleSize(size)
{
//
//create particles mesh buffer
//
Buffer = new SMeshBuffer();
//
//setup fluid descriptor
//
NxFluidDesc fluidDesc;
fluidDesc.maxParticles = MAX_PARTICLES;
fluidDesc.kernelRadiusMultiplier = 2.0f;
fluidDesc.restParticlesPerMeter = 7.0f;
fluidDesc.motionLimitMultiplier = 3.0f;
fluidDesc.packetSizeMultiplier = 8;
fluidDesc.collisionDistanceMultiplier = 0.1;
fluidDesc.stiffness = 50.0f;
fluidDesc.viscosity = 40.0f;
fluidDesc.restDensity = 1000.0f;
fluidDesc.damping = 0.0f;
fluidDesc.restitutionForStaticShapes = 0.2f;
fluidDesc.dynamicFrictionForStaticShapes= 0.05f;
fluidDesc.simulationMethod = NX_F_SPH;
if (!physx->isHardware())
fluidDesc.flags &= ~NX_FF_HARDWARE;
//Create user fluid.
//- create NxFluid in NxScene
//- setup the buffers to read from data from the SDK
//- set NxFluid::userData field to MyFluid instance
bool trackUserData = false;
bool provideCollisionNormals = false;
m_fluid = new MyFluid
(
physx->getPhysxScene(),
fluidDesc, trackUserData,
provideCollisionNormals,
NxVec3(0.4f,0.5f,0.9f),
m_particleSize
);
assert(m_fluid);
//
//create emitter object
//
PhysXNode * frameActor = physx->addBoxNode(vector3df(), vector3df(40,40,40));
//fill emitter description
NxFluidEmitterDesc emitterDesc;
emitterDesc.maxParticles = 0;
emitterDesc.randomAngle = 0.001f;
emitterDesc.randomPos = NxVec3(0.0f,0.0f,0.0f);
emitterDesc.dimensionX = 0.3f;
emitterDesc.dimensionY = 0.3f;
emitterDesc.type = NX_FE_CONSTANT_FLOW_RATE;
//The rate has no effect with type NX_FE_CONSTANT_PRESSURE
emitterDesc.rate = 300.0f;
emitterDesc.fluidVelocityMagnitude = 100.0f;
emitterDesc.particleLifetime = 5.0f;
emitterDesc.shape = NX_FE_RECTANGULAR;
//attach to actor
emitterDesc.flags |= NX_FEF_ADD_BODY_VELOCITY;
emitterDesc.repulsionCoefficient = 0.02f;
emitterDesc.relPose.M.id();
emitterDesc.relPose.M.rotX(-NxHalfPiF32);
emitterDesc.relPose.t = NxVec3(0,20.1f,0);
emitterDesc.frameShape = frameActor->GetActor()->getShapes()[0];
m_emitter = m_fluid->getNxFluid()->createEmitter(emitterDesc);
setAutomaticCulling(EAC_OFF);
}
unsigned getNbParticles()
{
return m_fluid->getParticlesNum();
}
void reallocateBuffers()
{
IVideoDriver* driver = SceneManager->getVideoDriver();
if (m_fluid->mParticleBufferNum * 4 > Buffer->getVertexCount() ||
m_fluid->mParticleBufferNum * 6 > Buffer->getIndexCount())
{
u32 oldSize = Buffer->getVertexCount();
Buffer->Vertices.set_used(m_fluid->mParticleBufferNum * 4);
u32 i;
//SColor clr = SColor(255,255,255,255); // ARGB
SColor clr = SColor(0,0,0,0);
// fill remaining vertices
for (i=oldSize; i<Buffer->Vertices.size(); i+=4)
{
Buffer->Vertices[0+i].TCoords.set(0.0f, 0.0f);
Buffer->Vertices[0+i].Color = clr;
Buffer->Vertices[1+i].TCoords.set(0.0f, 1.0f);
Buffer->Vertices[0+i].Color = clr;
Buffer->Vertices[2+i].TCoords.set(1.0f, 1.0f);
Buffer->Vertices[0+i].Color = clr;
Buffer->Vertices[3+i].TCoords.set(1.0f, 0.0f);
Buffer->Vertices[0+i].Color = clr;
}
// fill remaining indices
u32 oldIdxSize = Buffer->getIndexCount();
u32 oldvertices = oldSize;
Buffer->Indices.set_used(m_fluid->mParticleBufferNum * 6);
for (i=oldIdxSize; i<Buffer->Indices.size(); i+=6)
{
Buffer->Indices[0+i] = (u16)0+oldvertices;
Buffer->Indices[1+i] = (u16)2+oldvertices;
Buffer->Indices[2+i] = (u16)1+oldvertices;
Buffer->Indices[3+i] = (u16)0+oldvertices;
Buffer->Indices[4+i] = (u16)3+oldvertices;
Buffer->Indices[5+i] = (u16)2+oldvertices;
oldvertices += 4;
}
}
Buffer->Material.Wireframe = false;
Buffer->Material.Lighting = false;
Buffer->Material.setTexture(0, driver->getTexture("billboard_texture_alpha_green.tga"));
Buffer->Material.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;
//Buffer->Material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;
}
virtual void OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
virtual void render()
{
IVideoDriver* driver = SceneManager->getVideoDriver();
ICameraSceneNode* camera = SceneManager->getActiveCamera();
if (!driver || !camera)
return;
const matrix4 &m = camera->getViewFrustum()->getTransform( ETS_VIEW );
const vector3df view ( -m[2], -m[6] , -m[10] );
f32 f;
f = 0.5f * m_particleSize * 0.5;
const vector3df horizontal ( m[0] * f, m[4] * f, m[8] * f );
f = -0.5f * m_particleSize * 0.5;
const vector3df vertical ( m[1] * f, m[5] * f, m[9] * f );
reallocateBuffers();
// create particle vertex data
s32 idx = 0;
for (u32 i=0; i<m_fluid->mParticleBufferNum; ++i)
{
ParticleSDK& particle = m_fluid->mParticleBuffer[i];
Buffer->Vertices[0+idx].Pos = vector3df(particle.position.x, particle.position.y, particle.position.z) + horizontal + vertical;
Buffer->Vertices[0+idx].Normal = view;
Buffer->Vertices[1+idx].Pos = vector3df(particle.position.x, particle.position.y, particle.position.z) + horizontal - vertical;
Buffer->Vertices[1+idx].Normal = view;
Buffer->Vertices[2+idx].Pos = vector3df(particle.position.x, particle.position.y, particle.position.z) - horizontal - vertical;
Buffer->Vertices[2+idx].Normal = view;
Buffer->Vertices[3+idx].Pos = vector3df(particle.position.x, particle.position.y, particle.position.z) - horizontal + vertical;
Buffer->Vertices[3+idx].Normal = view;
idx +=4;
}
matrix4 mat;
driver->setTransform(ETS_WORLD, mat);
driver->setMaterial(Buffer->Material);
driver->drawVertexPrimitiveList(Buffer->getVertices(), m_fluid->mParticleBufferNum*4,
Buffer->getIndices(), m_fluid->mParticleBufferNum*2, EVT_STANDARD, EPT_TRIANGLES);//EIT_32BIT
}
virtual const aabbox3d<f32>& getBoundingBox() const
{
return Buffer->getBoundingBox();
}
virtual u32 getMaterialCount() const
{
return 1;
}
virtual SMaterial& getMaterial(u32 i)
{
return Buffer->getMaterial();
}
};