Improved particle system v2.0.0 is live! Now with particle physics!
by Lukas Joergensen · in Torque 3D Professional · 05/27/2012 (4:15 pm) · 21 replies
Patch video of patch 2.0.0
(Switch to 3 minutes in to just see the new features in 2.0.0)
Highlights:
Attractive particles Particle repulsion Particle collision
Download it here!
(Switch to 3 minutes in to just see the new features in 2.0.0)
Highlights:
Download it here!
About the author
IPS Bundle available at: https://www.winterleafentertainment.com/Products/IPS.aspx
#2
But have to ask, what protection does it have? Cuz' I don't believe I am allowed to release these source code files unless only T3D users have access to it :)
05/27/2012 (4:50 pm)
Ooh it's that site I lost all info on.But have to ask, what protection does it have? Cuz' I don't believe I am allowed to release these source code files unless only T3D users have access to it :)
#3
05/27/2012 (4:55 pm)
Yes, in fact everything is protected by SSL connections, and access is granted only to users with a valid license. Just ask, and i will verify from your profile if you have the license or not, then i will create an account for you.
#4
05/27/2012 (4:58 pm)
Will create an account then and see if I get it used :P
#5
05/27/2012 (5:01 pm)
Give me please your email to send the info
#6
05/27/2012 (5:03 pm)
--My first name--PJ@clan-net.dk
#7
Here is an example of one:
Donate Link
Alfio, I just sent you a donation. It is not much, but it should help some.
Also, could you add me to the repo? Thanks.
05/27/2012 (11:38 pm)
This is just beautiful. Where is the donate link? With Paypal you can create a donate link that goes in an email. I don't see any reason why you could not put that at the bottom of your resource.Here is an example of one:
Donate Link
Alfio, I just sent you a donation. It is not much, but it should help some.
Also, could you add me to the repo? Thanks.
#8
05/28/2012 (12:55 am)
Hmm, I think I will add a donations button if you are even asking for it :) Just hoping it wont be against any of GarageGames politics.
#9
05/29/2012 (4:22 am)
Put it on a separate webpage then. I saw the other thread so maybe we should wait to see that we don't put GG in a bad position by posting donate links here.
#10
05/29/2012 (5:55 am)
Forgot i had this post! Fixed in a second!
#11
05/29/2012 (8:11 am)
And why hasn't GarageGames hired you yet? :P Awesome work, Lukas! So many possibilities!
#12
Actually the changes here are really simple, especially the particle physics. And they aren't really hurting the framerate that much. I just don't know why it wasn't there to begin with! :D
05/30/2012 (1:13 pm)
@Jordan I don't know! Ask them! :DActually the changes here are really simple, especially the particle physics. And they aren't really hurting the framerate that much. I just don't know why it wasn't there to begin with! :D
#13
06/03/2012 (10:56 am)
Is it possible for particles to add force to objects? In the future I'll need to be able to make water spray from boats affect other boats.Scott
#14
Look in: void GraphEmitter::update( U32 ms ) in GraphEmitter.cpp
Find this code:
I have considered adding a callback in that function but I don't have the time to work on the resource atm.
Edit i believe you can write something like:
06/03/2012 (10:59 am)
@Scott, certainly!Look in: void GraphEmitter::update( U32 ms ) in GraphEmitter.cpp
Find this code:
// added part ----------------
RayInfo rInfo;
if(gClientContainer.castRay(part->pos, part->pos + part->vel * t, TerrainObjectType | InteriorObjectType | VehicleObjectType | PlayerObjectType | StaticShapeObjectType, &rInfo))
{rInfo contains the object which the particles collided with! Just kind of add a rInfo.object->applyForce or something.I have considered adding a callback in that function but I don't have the time to work on the resource atm.
Edit i believe you can write something like:
rInfo.object->applyImpulse(part->pos,part->pos + part->vel * t);Maybe tweak the values a bit.
#15
Are no one experiencing these errors or are you simply not telling me about them? :P
To fix paste this in between the emitParticles functions:
In the particleEmitter.h file:
06/03/2012 (4:25 pm)
Hey guys! Seems like I have made another mistake and accidentally overridden the emitParticles function which the projectile class uses!Are no one experiencing these errors or are you simply not telling me about them? :P
To fix paste this in between the emitParticles functions:
In the particleEmitter.h file:
void emitParticles(const Point3F& start,
const Point3F& end,
const Point3F& axis,
const Point3F& velocity,
const U32 numMilliseconds);In the particleEmitter.cpp file:
#16
06/03/2012 (4:26 pm)
//-----------------------------------------------------------------------------
// emitParticles
//-----------------------------------------------------------------------------
void ParticleEmitter::emitParticles(const Point3F& start,
const Point3F& end,
const Point3F& axis,
const Point3F& velocity,
const U32 numMilliseconds)
{
if( mDead ) return;
if( mDataBlock->particleDataBlocks.empty() )
return;
// lifetime over - no more particles
if( mLifetimeMS > 0 && mElapsedTimeMS > mLifetimeMS )
{
return;
}
U32 currTime = 0;
bool particlesAdded = false;
Point3F axisx;
if( mFabs(axis.z) < 0.9f )
mCross(axis, Point3F(0, 0, 1), &axisx);
else
mCross(axis, Point3F(0, 1, 0), &axisx);
axisx.normalize();
if( mNextParticleTime != 0 )
{
// Need to handle next particle
//
if( mNextParticleTime > numMilliseconds )
{
// Defer to next update
// (Note that this introduces a potential spatial irregularity if the owning
// object is accelerating, and updating at a low frequency)
//
mNextParticleTime -= numMilliseconds;
mInternalClock += numMilliseconds;
mLastPosition = end;
mHasLastPosition = true;
return;
}
else
{
currTime += mNextParticleTime;
mInternalClock += mNextParticleTime;
// Emit particle at curr time
// Create particle at the correct position
Point3F pos;
pos.interpolate(start, end, F32(currTime) / F32(numMilliseconds));
addParticle(pos, axis, velocity, axisx);
particlesAdded = true;
mNextParticleTime = 0;
}
}
while( currTime < numMilliseconds )
{
S32 nextTime = mDataBlock->ejectionPeriodMS;
if( mDataBlock->periodVarianceMS != 0 )
{
nextTime += S32(gRandGen.randI() % (2 * mDataBlock->periodVarianceMS + 1)) -
S32(mDataBlock->periodVarianceMS);
}
AssertFatal(nextTime > 0, "Error, next particle ejection time must always be greater than 0");
if( currTime + nextTime > numMilliseconds )
{
mNextParticleTime = (currTime + nextTime) - numMilliseconds;
mInternalClock += numMilliseconds - currTime;
AssertFatal(mNextParticleTime > 0, "Error, should not have deferred this particle!");
break;
}
currTime += nextTime;
mInternalClock += nextTime;
// Create particle at the correct position
Point3F pos;
pos.interpolate(start, end, F32(currTime) / F32(numMilliseconds));
addParticle(pos, axis, velocity, axisx);
particlesAdded = true;
// This override-advance code is restored in order to correctly adjust
// animated parameters of particles allocated within the same frame
// update. Note that ordering is important and this code correctly
// adds particles in the same newest-to-oldest ordering of the link-list.
//
// NOTE: We are assuming that the just added particle is at the head of our
// list. If that changes, so must this...
U32 advanceMS = numMilliseconds - currTime;
if (mDataBlock->overrideAdvance == false && advanceMS != 0)
{
Particle* last_part = part_list_head.next;
if (advanceMS > last_part->totalLifetime)
{
part_list_head.next = last_part->next;
n_parts--;
last_part->next = part_freelist;
part_freelist = last_part;
}
else
{
if (advanceMS != 0)
{
F32 t = F32(advanceMS) / 1000.0;
Point3F a = last_part->acc;
a -= last_part->vel * last_part->dataBlock->dragCoefficient;
a -= mWindVelocity * last_part->dataBlock->windCoefficient;
a += Point3F(0.0f, 0.0f, -9.81f) * last_part->dataBlock->gravityCoefficient;
last_part->vel += a * t;
last_part->pos += last_part->vel * t;
updateKeyData( last_part );
}
}
}
}
// DMMFIX: Lame and slow...
if( particlesAdded == true )
updateBBox();
if( n_parts > 0 && getSceneManager() == NULL )
{
gClientSceneGraph->addObjectToScene(this);
ClientProcessList::get()->addObject(this);
}
mLastPosition = end;
mHasLastPosition = true;
}
#17
Edit:
I figured out that I needed to consult the PHYSICSMGR for this functionality. However it still seems to have no effect on the physicsShape, it does get into the if statement now though.
Scott
06/03/2012 (11:58 pm)
Hey Lukas, I tried what you said for applying the impulse, but it seems to have no effect on physicsShapes. In fact the castRay doesn't seem to work at all. It doesn't find physicsShapes, at least I can't figure out a way to do it, I tried just about every combination of ObjectType flags. Is it not possible?Edit:
I figured out that I needed to consult the PHYSICSMGR for this functionality. However it still seems to have no effect on the physicsShape, it does get into the if statement now though.
if(PHYSICSMGR->getWorld(isServerObject() ? "server" : "client" )->castRay(part->pos, part->pos + part->vel * t, &rInfo, Point3F(0,0,0)))
{
rInfo.object->applyImpulse(part->pos,part->pos + part->vel * t);
}Scott
#18
Oh so you are using physX?
Try have a look at this comment then:
http://www.garagegames.com/community/forums/viewthread/105537/1#comment-728083
Seems like physicsShape isn't using the same raycast function
So instead you would do something like this:
06/04/2012 (1:44 am)
@ScottOh so you are using physX?
Try have a look at this comment then:
http://www.garagegames.com/community/forums/viewthread/105537/1#comment-728083
Seems like physicsShape isn't using the same raycast function
So instead you would do something like this:
PhysicsWorld *world = gPhysicsPlugin->getWorld( "Client" /*( or "Server" )*/);
// see if we are in a physics world
if ( world )
{
// get the physx hit obj
hitP = world->castRay( startPnt, endPnt, &rInfo, Point3F(0,0,0) );
if ( hitP )I don't know what the last point is for.
#19
I'm trying to use bullet, but it doesn't seem to have any effect. I tried it with the first way with the BouncingBoulder Rigid shape, and I couldn't get the particles to push it either.
06/04/2012 (2:02 am)
Heh, just edited my post as you said that apparantly.I'm trying to use bullet, but it doesn't seem to have any effect. I tried it with the first way with the BouncingBoulder Rigid shape, and I couldn't get the particles to push it either.
#20
Also try and check if there is any special function for applying an impulse to a physX object, never worked with the physX so I don't know what to take into account.
06/04/2012 (2:10 am)
Hmm you say it goes into the if sentence, can you check that it is colliding with the right object? So it isn't applying the impulse to the particles or something.Also try and check if there is any special function for applying an impulse to a physX object, never worked with the physX so I don't know what to take into account.
Torque Owner Alfio Saitta
Collateral Studios
How about making your changes directly to a svn shared repository? So maybe you can follow the bug reporting and more.