View Full Version : particle collision problem
skdzines 09-03-2009, 03:38 AM I'm having some problems with particles colliding with other objects.
Let me describe my scene. I have a logo that comes crashing down on to some asphalt. When it hits the asphalt, I turn on the visibility of my damaged asphalt pieces. Basically, I have a floor plane with a hole in it, filling the hole is my damaged asphalt geometry. I took a rectangular cube and performed a solid shatter on it several times. Once shattered, I moved the pieces into the positions I wanted (rotated and transformed) to give it the look that the pavement sunk in around the logo. I selected the debris particles and the plane with the hole and went to Particles > Make Collide. All worked well. Then I did the same thing by selecting the particles and then all of the shards which make up the broken asphalt. When running the simulation, the particles pass right through the broken asphalt chunks.
Can anybody tell me why this is happening?
|
|
Aikiman
09-03-2009, 04:46 AM
can you post the scene?
skdzines
09-05-2009, 01:05 AM
Do you have an email that I can send you the .ma file? This forum won't let me post this large of a fle.
Aikiman
09-05-2009, 07:37 AM
jeremy@jeremyraven.co.nz
Wick3dParticle
09-05-2009, 03:05 PM
Hey Skdzines,
Can you send me the scene too? Or better yat can you host it, so that possibly more people can help?
ilangabai "at" gmail
~Ilan
skdzines
09-05-2009, 08:40 PM
thanks for the reply guys. I've posted the file at http://www.skdzines.com/scenes/clutch_logo_test2.zip
This is just the .ma file, no resource files are included. I've actually got the collision part to work with the individual shards. I didn't realize you couldn't select the particle and all of the shards at once and do a make collide. I had to do each one separately (which was a pain).
Anyway, I could still use some help getting the particles to stop bouncing and jittering once their momentum has stopped. I tried what another member of the forum suggested but I can't seem to get it to work or at least just don't have a good enough understanding of what I'm trying to tell it to do..
I really appreciate everyone's help.
skdzines
09-07-2009, 12:50 AM
if you guys get a chance to look at the file and it's render settings, can you possibly also give me some tips on how to optimize render times? I am using motion blur and am only rendering out a 640x480 image and it takes like 5 min or more to render one frame.
3.0 Ghz Pentium Quad Core
8 Gb Ram
1 Gb Nvidia graphics card
Windows Vista 64 bit
Aikiman
09-07-2009, 02:20 AM
thanks for the reply guys. I've posted the file at http://www.skdzines.com/scenes/clutch_logo_test2.zip
This is just the .ma file, no resource files are included. I've actually got the collision part to work with the individual shards. I didn't realize you couldn't select the particle and all of the shards at once and do a make collide. I had to do each one separately (which was a pain).
Anyway, I could still use some help getting the particles to stop bouncing and jittering once their momentum has stopped. I tried what another member of the forum suggested but I can't seem to get it to work or at least just don't have a good enough understanding of what I'm trying to tell it to do..
I really appreciate everyone's help.
By raising the friction and lowering the resilience on all your geoConnectors will help slowing your particles right down. One way to do this is to select all your geoConnectors at once and use the channel window to change your settings. If you go to your Outliner and turn off "Display DAG Object Only" all of your geoConnectors will appear.
Also I would throw this into your particle expressions runtime...
float $vel = mag(lg_particlesShape.velocity);
if($vel<.1)
lg_particlesShape.userVector2PP=0;
that will stop them rotating when they moving.
skdzines
09-07-2009, 04:23 AM
Thanks again Jeremy. I added the script you provided to the runtime after dynamics expression but I'm not seeing any real difference. Did I add it to the correct one? Also, I lowered the resilience as you suggested to help with the bounciness and raised the friction to get them to stick more. However, I can't really seem to find a happy medium with enough bounce and get them to all stop after a certain period of time. It seems that a lot of them will stop but others keep bouncing up and down constantly. And if I up the resilience a little more to make the bounce look a little more natural, I get even more bouncing from those particles that never seem to stop. The only way I can get them all to stop is to set the resilience to 0 and the friction to 1 which really doesn't look good. Also, I have attached an image which shows the particles sitting well above the floor surface, why is this?
Thanks again for all your help.
Aikiman
09-07-2009, 06:25 AM
Make sure you place the code in the correct particle expression, and I put it in RT before dynamics just after your other code. As for the "gap", this relates to your collision offset which is dulled out for some reason. A good way to get around this is to hide your collision plane and lower below your render plane so it "looks" like you particles are colliding with your render plane. BTW you could probably combine all your meshes to one and just use one coliision, might be easier to handle.
Your high render times can be reduced a little if you cache your particles under solvers > create particle cache. I didnt do a test render sorry, hope that helps though.
skdzines
09-07-2009, 09:51 PM
okay, I've lowered the resilience to around .3 and increased the friction to about .7 which is giving me a better result but no matter what I do, it seems that the debris is constantly bobbing up and down. It isn't spinning or rotating anymore once the pieces have stopped moving though.
I'm also using a different expression that I found to control the spinning of the debris. Here is what I'm using now:
creation:
lg_particlesShape.index = lg_particlesShape.particleId%4;
lg_particlesShape.r_off = <<rand(6.28), rand(6.28), rand(6.28)>>;
lg_particlesShape.r_spd = <<rand(6.28), rand(6.28), rand(6.28)>>*1;
lg_particlesShape.mass = rand(10,30);
runtime before:
lg_particlesShape.rot = lg_particlesShape.r_off + lg_particlesShape.r_spd * lg_particlesShape.age;
float $vel = mag(lg_particlesShape.velocity);
if($vel<.1)
lg_particlesShape.rot=0;
Any other thoughts? Thanks again for your help, I really do appreciate it.
To stop some of the pieces, which should stop, try adding them huge mass.
I haven't opened the scene, so I hope I'm not talking by heart...
Als
Aikiman
09-07-2009, 10:37 PM
I would base your mass on the scale of your instances as in mass = scale that way you could use a uniform field and have the bigger particles move more slower than the lighter ones.
One way to stop your particles from bouncing COULD be to check the collisionIncomingVelocity and if it is lower than a custom threshold then make velocity=0. There are a few custom collision PPs so check them out, I just thought this one might be quite handy as it checks the velocity as it hits the collision and if its going to slow you could just kill the velocity on it.
Wick3dParticle
09-08-2009, 07:51 PM
Hey skdzines,
I took a look at your scene...and I personally would do things a bit differently. There are usually multiple solutions to a problem...so here is mine:
1. make all your fields except gravity in to volumes, and place them a bit above the ground plane. - that way once your particles come to a rest, the fields dont continue to push them around.
2. make empty collision events so that you can use the collision counter to stop velocity.
3. write some "if" expressions based on your collision counter - to zero out velocity, zero out rotation, to pin position, make your gravity field in to a gravityPP - and zero that out as well.
Basically, you want to end up with a situation where you are forcing velocity to 0, position the particle so that it doesnt move, and remove all influences from external forces after it collides a certain amount of times.
I hope that helps.
~Ilan
skdzines
09-08-2009, 09:08 PM
Ilan, thanks for taking a look at the scene. I'm pretty new to all of this so I hope you weren't too horrified when you opened it. Anyway, I'm pretty sure I can figure out how to turn the fields into volumes, however I'm sure I'll have questions about the expressions you mention, primarily:
1. make empty collision events so that you can use the collision counter to stop velocity.
2. make your gravity field in to a gravityPP - and zero that out as well.
Can you give me an example of the above please?
I really appreciate yours and everyone's help and hope I'm not being too much of a pain.
Thanks again!
Wick3dParticle
09-09-2009, 07:19 AM
Hey Skdzines.
So to answer your questions:
1. Create a particle collision event, but dont have it kill or birth any particles.
Then create an "if" statement like for example:
if(event > 5){
particleShape1.velocity = <<0,0,0>>;
}
2. create a per particle attribute and name it after the field and attribute you want to control in the following format:
for example lets say we are creating a gravityPP attribute for the "gravity1" field.
you create a custom PP attribute and call it "gravity1_magnitude".
Then like in step 1, you can control that with your "if" statement.
Hope thats more clear.
Good luck,
~Ilan
skdzines
09-14-2009, 02:52 AM
Thanks again Ilan! I have the particles stopping their rotation and bouncing now for the most part, however, due to the scene having the broken surface and with some pieces slanting inwards, some of the particles that land on these pieces continue to slide. Is there any way to tell the particles to not slide or to hold their current position if the velocity is less than a certain number?
Here is the latest expression I'm using:
creation:
lg_particlesShape.index = rand(0,4);
float $s = rand(1,2);
lg_particlesShape.instScale = $s;
lg_particlesShape.mass = $s*10;
lg_particlesShape.instRotation = <<0,0,0>>;
lg_particlesShape.instRand = rand(-1,1);
runtime before:
float $vel = mag(lg_particlesShape.velocity);
if ($vel > 1){
lg_particlesShape.instRotation += (<<15,12,10>>) * lg_particlesShape.instRand;
}else{
lg_particlesShape.instRotation = <<0,0,0>>;
}
Thanks again for all of your help.
skdzines
09-14-2009, 03:18 PM
here is another issue. When doing the following if statement:
if ($vel > 1){
lg_particlesShape.instRotation += (<<15,12,10>>) * lg_particlesShape.instRand;
}else{
lg_particlesShape.instRotation = <<0,0,0>>;
}
All of the same instanced particles have the exact same rotation of 0,0,0 and therefore all look like the same piece of geometry scattered throughout the scene. Is there any way to pick up what the current rotation value of the object is and apply those numbers to it when it stops?
Wick3dParticle
09-14-2009, 06:37 PM
Is there any way to tell the particles to not slide or to hold their current position if the velocity is less than a certain number?
Did you try setting up the gravityPP, I dont see that in your expressions.
All of the same instanced particles have the exact same rotation of 0,0,0 and therefore all look like the same piece of geometry scattered throughout the scene. Is there any way to pick up what the current rotation value of the object is and apply those numbers to it when it stops?
You are telling them to do that in the following expression:
else{
lg_particlesShape.instRotation = <<0,0,0>>;
}
Instead of assigning them all a rotation of <<0,0,0>>, try the following:
else{
lg_particlesShape.instRotation += <<0,0,0>>;
}
~Ilan
skdzines
09-15-2009, 03:18 AM
Ilan, thanks again for helping out. I'm sorry to be such a pain, but I'm still trying to grasp all of this. I'm not sure on how to do the gravityPP attribute. Please correct me on what I am doing wrong.
What I have done is created a per particle attribute on the lg_particles particle node with the following settings.
Long name: gravity_mag
Type: vector
Per Particle array
Then in my check for velocity in the runtime before dynamics expression I added the following:
float $vel = mag(lg_particlesShape.velocity);
if ($vel > 1){
lg_particlesShape.instRotation += (<<15,12,10>>) * lg_particlesShape.instRand;
}else{
lg_particlesShape.instRotation += <<0,0,0>>;
lg_particlesShape.gravity_mag = 0;
}
I'm not sure if this is correct or not. I'm assuming not simply because I'm still not getting the desired result. I guess my confusion is that I don't understand how this is supposed to tell the gravity field to zero out on each particle. Am I supposed to connect it to one of the Instancer (Geometry Replacement) options much like I did for setting the ObjectIndex and Rotation and if so which one?
I also tried creating an event and then did the following:
if(event > 2){
lg_particlesShape.instRotation += <<0,0,0>>;
}else{
lg_particlesShape.instRotation += (<<15,12,10>>) * lg_particlesShape.instRand;
}
which basically gave me the same result as the other expression when checking the velocity. I thought I could add an attribute to gravityField1 node and then do a similar check of the particle event but was unable to.
I'm pretty confused at this point.
Wick3dParticle
09-15-2009, 02:58 PM
Hey Skdzines,
I understand that this may not be the easiest thing to follow. Read what I wrote again, you must write it out in the specific format I mentioned earlier:
2. create a per particle attribute and name it after the field and attribute you want to control in the following format:
for example lets say we are creating a gravityPP attribute for the "gravity1" field.
you create a custom PP attribute and call it "gravity1_magnitude".
Its going to be a float attribute, not a vector... a gravity's magnitude is not a 3 component value (x,y,z or r,g,b)...right?
I would continue with the event counter to trigger the expressions. And read what I wrote you again, because none of the expressions you showed me really follow what I wrote you.
~Ilan
skdzines
09-16-2009, 12:12 AM
Hey Ilan,
I know at this point I'm probably becoming a nuisance but I still don't get how this is supposed to actually tell the gravity field to no longer affect the particles once they have collided with the surface more than twice. I created a new attribute on the lg_particleShape called gravityField1_magnitude as a Float per particle. Below is the latest expression with what I believe is your suggestion.
Creation:
lg_particlesShape.index = rand(0,4);
float $s = rand(.5,1.5);
lg_particlesShape.instScale = $s;
lg_particlesShape.mass = $s*6;
lg_particlesShape.instRotation = <<0,0,0>>;
lg_particlesShape.instRand = rand(-1,1);
Runtime Before:
if(lg_particlesShape.event < 2){
lg_particlesShape.instRotation += (<<15,12,10>>) * lg_particlesShape.instRand;
}else{
lg_particlesShape.instRotation += <<0,0,0>>;
lg_particlesShape.gravityField1_magnitude = 0;
}
As I mentioned earlier, I just don't understand how this is supposed to tie into the gravityField. It doesn't appear to be the same as say the instScale custom attribute where I am setting the scale based off of a random float number and then assigning that value to the Instancer (Geometry Replacement) Scale. I guess it would make more sense to me if there was a Gravity drop down in the Instancer (Geometry Replacement) where I could select the gravityField1_magnitude attribute as its value. This is where my confusion comes from. I have tried searching endlessly for controlling forces/fields on a per particle basis but have yet to find anything solid.
I'm sorry to keep bugging you, it's just that you're the only one I've found who seems to know how to do what I'm trying to do.
Thanks again!
Aikiman
09-16-2009, 12:19 AM
By creating gravityField1_magnitude you have automatically made a per particle connection to that specific field and that specific field's attribute. So if the particles event count is == or > than 2 then set the magnitude of gravity for that particle to zero which you have already done.
Wick3dParticle
09-16-2009, 12:27 AM
And set the velocity to <<0,0,0>> like I mentioned earlier.
~Ilan
skdzines
09-16-2009, 12:27 AM
thanks aikiman, I was starting to think that maya was maybe smart enough to make the connection automatically just by the naming convention but I wasn't sure, also because I'm still not getting the exact result I'm looking for but it is getting better. I've added a similar attribute for the volumeAxisField as well and telling it to zero out on the particle but I'm still getting some movement out of some particles once they have stopped.
I've also noticed something else weird, even though a particle has stopped moving it seems that the uvs continue to shift or something because I can see movement in the texture. It eventually stops shortly afterward though.
Wick3dParticle
09-16-2009, 12:42 AM
By the way, you arent a nuisance. But if you keep on doing part of what we say, or kind of doing what we write (but kind of not) ... well its not going to work, and you will keep on coming back here and asking.
Im just curious, why did you keep skipping over this part:
1. Create a particle collision event, but dont have it kill or birth any particles.
Then create an "if" statement like for example:
if(event > 5){
particleShape1.velocity = <<0,0,0>>;
}
~Ilan
Aikiman
09-16-2009, 12:46 AM
I never seen UVs move around unless they are being keyframed or your scene is becoming unstable. Make sure you save out another copy of your scene in case this one dies.
skdzines
09-16-2009, 12:48 AM
I actually didn't skip it. I had it in at one point and through all of my trial and error, I somehow must have deleted it. It is looking and working much better now. I was also just really unaware that maya would automatically make the connection to the fields just by the naming convention.
Thanks again for all of you help!
Aikiman
09-16-2009, 12:52 AM
I was also just really unaware that maya would automatically make the connection to the fields just by the naming convention.
Thats a little hidden secret only hardcore maya FX guys know about so now you are part of an elite Maya club, not really but it sounded good :)
Wick3dParticle
09-16-2009, 12:52 AM
I see... cool.
Now for your volume axis... if you just raise it slightly above ground level, you dont need to make it a PP attribute. The particles will come to rest outside the volume, and be un-affected. With gravity it is slightly different because you want gravity to affect it until it reaches the condition you want it to stop in.
Happy things are working for you,
~Ilan
skdzines
09-16-2009, 12:56 AM
Aikiman, I've been saving out versioned copies. Yeah, I don't get. Initially I had all of my shard pieces and debris uvs laid out and the texture applied to them, then if I rotated the object, the uv's from the automatic mapping would get all messed up and distort my texture. Simply by deleting the history on the object I was able to rotate, move and scale without messing up the texture. I thought maybe this issue was still occurring on the instanced particle pieces but I've deleted the history and it still gets this weird affect right after the particles have stopped.
skdzines
09-16-2009, 01:00 AM
Ilan, I raised the volume field above the collision plane more to hopefully stop the extra movement but then I also have to move my particle emitting object higher above the floor so that it is still affected by the volume. If I raise it too much, it won't look like the particles start at the floor and shoot up when the logo comes crashing down. Which is the only reason I tried adding the volume attribute as well.
Thanks again!
skdzines
09-17-2009, 03:28 AM
hey guys, can I bother you again and have you take a look at the scene? I think I am doing everything you have said and it is all starting to look the way I intend. However, I have moved the volume fields well above the floor and the resting particles but some of them still seem to slowly move towards the center of the cracked pavement. I understand that if a particle is resting on a slanted plane or object the gravity should make is slide down that object. But I'm telling the velocity, gravity and volume fields to not effect the particle at all if it has collided more than 3 times.
Once again, here is the expression I am using:
creation:
lg_particlesShape.index = rand(0,4);
float $s = rand(.5,1.5);
lg_particlesShape.instScale = $s;
lg_particlesShape.mass = $s*6;
lg_particlesShape.instRotation = <<0,0,0>>;
lg_particlesShape.instRand = rand(-1,1);
runtime before:
if(lg_particlesShape.event < 3){
lg_particlesShape.instRotation += (<<15,12,10>>) * lg_particlesShape.instRand;
}else{
lg_particlesShape.velocity = <<0,0,0>>;
lg_particlesShape.instRotation += <<0,0,0>>;
lg_particlesShape.gravityField1_magnitude = 0;
lg_particlesShape.volumeAxisField2_magnitude = 0;
}
The file can be downloaded at http://www.skdzines.com/scenes/scene.zip
Thanks again for all of your help. Please feel free to give any other critiques and/or comments on how to improve the exploding debris.
skdzines
09-22-2009, 09:12 PM
hey guys, just wondering if you have had any chance to take a look at the file and see why the particles are still be affected by the gravity fields if they are resting on a shard that is slanted?
Thanks again for all of your help.
skdzines
10-14-2009, 04:59 PM
Hey guys, one more small issue I think. Below is the current expression I'm using on the particles. They all seem to get a pretty nice bounce off of the surface a few times before coming to a rest. However, after they have collided more than 3 times, they come to a sudden stop rather than slowing down a little bit after each collision. I don't remember exactly what my resilience and friction settings are and I'm not at home to check. Anyway, I've tried playing with these numbers and still nothing seems to make much difference.
creation:
lg_particlesShape.index = rand(0,4);
float $s = rand(.5,1.5);
lg_particlesShape.instScale = $s;
lg_particlesShape.mass = $s*6;
lg_particlesShape.instRotation = <<0,0,0>>;
lg_particlesShape.instRand = rand(-1,1);
runtime before:
if(lg_particlesShape.event < 3){
lg_particlesShape.instRotation += (<<15,12,10>>) * lg_particlesShape.instRand;
}else{
lg_particlesShape.velocity = <<0,0,0>>;
lg_particlesShape.instRotation += <<0,0,0>>;
lg_particlesShape.gravityField1_magnitude = 0;
lg_particlesShape.volumeAxisField2_magnitude = 0;
}
Is there something I need to add to tell the velocity to slow down with each collision event so the particles slowly ease in to their rested state? If so, can you give an example of what that might be?
I've tried doing something like this in the before dynamics expression but it didn't work:
if(lg_particlesShape.event < 3){
lg_particlesShape.instRotation += (<<15,12,10>>) * lg_particlesShape.instRand;
lg_particlesShape.velocity = lg_particlesShape.velocity/2;
}else{
......
Thanks again for your help
RayRay
10-14-2009, 05:34 PM
could u do something like this?
$dec = 1
if(lg_particleShaape.event > 1 && < 3){
lg_particlesShape.velocity -= $dec
}
else{
lg_particlesShape.velocity = <<0,0,0>>;
}
then play with the $dec until you get an acceptable velocity decline before it zeros out?
Your thread saved my ass on this project, thanks you three!
CGTalk Moderation
10-14-2009, 05:34 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.