Simple Particle clipping
by Wesley Hopson · in Torque 3D Professional · 09/27/2014 (4:57 am) · 21 replies
This is part discussion part blog if this works well enough might end up turning it into a resource.
For my game project I have the need to implement some simple clipping for a particle effect. IE not go through objects, well not completely. So after some digging I got a point in collison mesh test working for objects similar in nature to shapebase (Interiors is another can of worms for later). Based around checking which side of the convex hull's planes the point is on, this gives me the advantage of being able to snag the distance to that plane and find the closest plane to the point in the same computation. Prob better tests but it should work for testing.
Now for the bug bear in the room optimizations are not my strong suit in the slightest but I have to keep performance in real time or there is no point. I am thinking I do not actually care if particles enter objects as long as they are ejected and do not generally go all the way through. So I am thinking i could get away with only polling the particles every so many milliseconds. I am thinking of using a poll rate which is how often a particle polls then counting down and resetting that value prob from datablock. Then to keep all the particles from polling at once randomly setting it's initial value at the creation of the particle. So any other ideas for how to cut down on processing needed I am all ears.
Ideally I intend to use this particle effect on the server for some game play mechanics. It somehow seemed a easier approach to creating poison cloud effects that behaved properly for a strategy game.
For my game project I have the need to implement some simple clipping for a particle effect. IE not go through objects, well not completely. So after some digging I got a point in collison mesh test working for objects similar in nature to shapebase (Interiors is another can of worms for later). Based around checking which side of the convex hull's planes the point is on, this gives me the advantage of being able to snag the distance to that plane and find the closest plane to the point in the same computation. Prob better tests but it should work for testing.
Now for the bug bear in the room optimizations are not my strong suit in the slightest but I have to keep performance in real time or there is no point. I am thinking I do not actually care if particles enter objects as long as they are ejected and do not generally go all the way through. So I am thinking i could get away with only polling the particles every so many milliseconds. I am thinking of using a poll rate which is how often a particle polls then counting down and resetting that value prob from datablock. Then to keep all the particles from polling at once randomly setting it's initial value at the creation of the particle. So any other ideas for how to cut down on processing needed I am all ears.
Ideally I intend to use this particle effect on the server for some game play mechanics. It somehow seemed a easier approach to creating poison cloud effects that behaved properly for a strategy game.
#2
I am aware particle effects are not simulated on the server. I am thinking if they were made to be simulated on the server then rendering them is prob a waste of time especially for a dedicated server. Could even use far fewer particles than would be needed to show the effect visually for the client.
so are you suggesting using far simpler bounds around objects like a box around a rock. For example that repels the particle if it is inside. I am not sure that will give very good results but then that is down to tweaking. Interiors sounds like it would be rather complicated. Though there is probably alot of merit in using a much simpler collision mesh for objects that trades on the size vs precision. Somthing for me to think about i guess.
09/27/2014 (6:22 am)
Thanks for the reply. To be more clear as to what i am doing. I am making a top down view tile based final fantasy tactics style strategy game. To deal damage i am going to keep a tally of the number of particles in each square of my grid. This can be done in constant time easy enough as part of the particles update step and again may not necessarily need to be 100% precise anyhow since this is to give me an idea of concentrations. So the big reason I want to use particles is take advantage of emergent behavior. For example a wind spell hitting someone through a poison cloud could spread the particles around ect... Plus there is the benefit of having naturally higher concentrations in smaller rooms. So the primary reason i want the particles to have some simple clipping is so they do not cause problems like going through the walls of rooms.I am aware particle effects are not simulated on the server. I am thinking if they were made to be simulated on the server then rendering them is prob a waste of time especially for a dedicated server. Could even use far fewer particles than would be needed to show the effect visually for the client.
so are you suggesting using far simpler bounds around objects like a box around a rock. For example that repels the particle if it is inside. I am not sure that will give very good results but then that is down to tweaking. Interiors sounds like it would be rather complicated. Though there is probably alot of merit in using a much simpler collision mesh for objects that trades on the size vs precision. Somthing for me to think about i guess.
#3
09/27/2014 (7:48 am)
@Daniel - Could Debris objects be modified for this? Those at least support collision and might be a place to start....
#4
Id be curious to see how you did the particle clipping so that it doesnt go through objects. Would u mind sharing that code?
09/27/2014 (8:45 am)
@Wesley:Id be curious to see how you did the particle clipping so that it doesnt go through objects. Would u mind sharing that code?
#5
for how this is used It is about the same as how castray would work from scenecontainer. I figured out how I would do this from starting there. Of course much higher up I test if it is in the world and object box first before bothering with this test. Also I wrote this with shapebase in mind not gotten far enough to look at other classes. So will prob need a diff sort of test for terrain and interiors ect...
The basic premise for how this will work when i am finished. Is i am acctually not gonna disallow particles from entering collision meshs or actual visible geometry at all far from it acctually. Since we are talking about a gas(or gas like objects) it needs to maintain a very tight border with the object to look right. So we only need to concern ourselves with when the particle acctually enters the collision mesh physically. We can treat this more like a steering behavior in that regard. we have a plane normal to apply a force to push us out again so as long as the object is not super thin it should work fine.
09/27/2014 (9:14 am)
It is far from finished. I am doing alot of theory crafting at the moment with some test code. All i got right now is a function deep in the chain in tsmesh to test if a point is in a convex hull and return the normal of the plane closest to that point as well. I can post that if you want.bool TSMesh::containsParticle(S32 frame, Point3F point, Point3F* norm)
{
if ( planeNormals.empty() )
buildConvexHull(); // if haven't done it yet...
//we are comparing our point to the convex hull of the object rather than each mesh indvidually.
//This should be alot faster and less complicated but possibly less accurate but hey not like that matters for particles. Heck I am fudging there accuracy anyhow on purpose
PlaneF CurPlane;
F32 BestDist = 9999;
F32 Dist;
S32 startPlane = frame * planesPerFrame;
for ( S32 i = startPlane; i < startPlane + planesPerFrame; i++ )
{
CurPlane.set(planeNormals[i].x, planeNormals[i].y, planeNormals[i].z, planeConstants[i] * -1);
Dist = CurPlane.distToPlane(point) * -1;//Because the normals face outwards we want the inside
//Con::printf("Par Norm %f %f %f, d %f, Dist %f", planeNormals[i].x, planeNormals[i].y, planeNormals[i].z, planeConstants[i], Dist);
if (Dist <= -0.005f)
return false;//point in front of the plane we want it behind it or on it instead
//Now to see if our point is closer to this particular plane.
if (Dist < BestDist)
{
BestDist = Dist;
*norm = CurPlane.getNormal();
}
}
return true;
}for how this is used It is about the same as how castray would work from scenecontainer. I figured out how I would do this from starting there. Of course much higher up I test if it is in the world and object box first before bothering with this test. Also I wrote this with shapebase in mind not gotten far enough to look at other classes. So will prob need a diff sort of test for terrain and interiors ect...
The basic premise for how this will work when i am finished. Is i am acctually not gonna disallow particles from entering collision meshs or actual visible geometry at all far from it acctually. Since we are talking about a gas(or gas like objects) it needs to maintain a very tight border with the object to look right. So we only need to concern ourselves with when the particle acctually enters the collision mesh physically. We can treat this more like a steering behavior in that regard. we have a plane normal to apply a force to push us out again so as long as the object is not super thin it should work fine.
#6
09/27/2014 (9:20 am)
Actually Wesley, Id like to see a resource on this so that I can duplicate this. its something that Ive been looking for and Im very curious as to how costly this is.
#7
I am afraid i do not know much about debris never acctually had much cause to look at that particular class at least till now.
09/27/2014 (9:28 am)
I am curious as to how costly this will be too tbh. That is part of why i put this up for discussion and for ways to reduce the processing cost as much as possible. That particular function should be really really cheap far cheaper than a raycast. But we are talking about large numbers of particles so i want to minimize the number of tests i have to do and no i do not mind sharing assuming what I end up with is the least bit applicable to other projects. I am using afx so it is possible i might end up with some of that mixed in at some point.I am afraid i do not know much about debris never acctually had much cause to look at that particular class at least till now.
#8
09/27/2014 (9:41 am)
post what u have as a resource and we can see about dropping it in an engine and testing it out. id be curious to see what the FPS hit is.
#9
09/27/2014 (10:02 am)
I will let you know when i get something worth testing out up and running. Would be helpful to have someone to help test it if nothing else. Like I said nothing more than nuts and bolts and alot of theory crafting right now.
#10
btw I would use a separate render bin and to get a per-pixel collision mask.That will enable partial pixel perfect collisions.
09/28/2014 (7:02 am)
Do it with collision spheres and check for intersection. Simple and fast.btw I would use a separate render bin and to get a per-pixel collision mask.That will enable partial pixel perfect collisions.
#11
09/29/2014 (8:56 am)
Thanks for the reply. I am afraid I am not familar enough with rendering in T3d to know what your talking about could you please elaborate.
#12
If some of you want to test it out and play with it I am gonna get a resource setup pretty soon. Anyone know of good methods to host code files. listing the code changes one by one is rather tedious and the engines and afx are both open source now so should not be a issue right.
Also keep in mind so far this only works with shapebase derived classes or could with some effort be made to work with other classes that use a similar method of collision mesh storage like tsStatic. Need to get to making this work with more classes as a todo on my part.
10/03/2014 (6:28 am)
ok I finally got some time to get this working was actually not too hard at all surprisingly. Not getting any frame issues that i can notice even with the particles cranked way up with a low sampling. While i have not done any fps profiling it does say somthing that my laptop chugs badly on the pacfic demo and can only really handle the afx test map from the TGE age well. Well still hardly a good measuring stick I thinkIf some of you want to test it out and play with it I am gonna get a resource setup pretty soon. Anyone know of good methods to host code files. listing the code changes one by one is rather tedious and the engines and afx are both open source now so should not be a issue right.
Also keep in mind so far this only works with shapebase derived classes or could with some effort be made to work with other classes that use a similar method of collision mesh storage like tsStatic. Need to get to making this work with more classes as a todo on my part.
#13
Id love to see your changes, im still very interested in this.
10/03/2014 (8:26 am)
has AFX gone open source? or does it OFFICIALLY WORK with the MIT branch?Id love to see your changes, im still very interested in this.
#14
http://www.garagegames.com/community/blogs/view/22846
10/03/2014 (9:05 am)
ok resource posted. Does not use much AFX stuff as far as i can tell anyhow all the major changes are in particle and particleEmitter plus the code is fairly short enough so just posted it all in one post. I read on the afx forums that it is open source and works with the mit version. I should prob upgrade my engine version to the mit version one of these days. Huh somehow ended up as a blog post rather than a resource post. Oh well I guess it is somthing I will prob add too over time.http://www.garagegames.com/community/blogs/view/22846
#15
10/03/2014 (4:02 pm)
Well, the standard way to share code these days is to fork the repository on GitHub and make a branch with your changes in it. That way you can really easy show people a diff, and they can just pull it down directly into their own repository rather than having to make the changes manually.
#16
somthing i am noticing is in the demos we have TsStatics with concave collision meshes. In the case of the Teambases in death ball desert I would think those would be interiors. The engine can handle these just fine i am guessing because they are in the demos of all things. However my code as it is is assuming a convex hull of the object acctually means Convex. a point in mesh test is far far quicker with convex meshes than concave plus i can snatch the needed distance to each plane as part of the test itself.
Should I go and make this work with concave collision meshes?
Does anyone know of a super fast point in concave mesh test that would let me also return the nearest plane to the point?
That said I think I have figured out a working method to test for interior bsp trees and get what i need but if the teambases were best as interior instances i get the feeling they would likely be interiors.
10/08/2014 (12:57 am)
@ok thanks I will get on that as soon as I fix my current issues.somthing i am noticing is in the demos we have TsStatics with concave collision meshes. In the case of the Teambases in death ball desert I would think those would be interiors. The engine can handle these just fine i am guessing because they are in the demos of all things. However my code as it is is assuming a convex hull of the object acctually means Convex. a point in mesh test is far far quicker with convex meshes than concave plus i can snatch the needed distance to each plane as part of the test itself.
Should I go and make this work with concave collision meshes?
Does anyone know of a super fast point in concave mesh test that would let me also return the nearest plane to the point?
That said I think I have figured out a working method to test for interior bsp trees and get what i need but if the teambases were best as interior instances i get the feeling they would likely be interiors.
#17
10/08/2014 (1:50 am)
Interiors have been removed from T3D in favour of concave collision meshes. I'm pretty sure the buildPolyList method is what you're looking for. But as for algorithms, I can't help you :(
#18
I have been looking at the buildpolylist function as a guide for how to access the geometry but have thus far avoided using it directly largely because it looks like it has the overhead of moving the information into another format as well as the memory allocations that requires. Just how efficent are the build poly list i know they are used in rendering and collision detection but if i can avoid the overhead i would like too assuming there is much that is.
10/08/2014 (3:40 am)
well i had my supicsions about interiors in that regard for a while but was not sure. I thought they just ousted the .diff format in favor of .dae did not realize the whole class was on it's way out. Thanks for letting me know. I have been looking at the buildpolylist function as a guide for how to access the geometry but have thus far avoided using it directly largely because it looks like it has the overhead of moving the information into another format as well as the memory allocations that requires. Just how efficent are the build poly list i know they are used in rendering and collision detection but if i can avoid the overhead i would like too assuming there is much that is.
#19
So this means if i want to use as many particles as I want I will have to optimize the data i am working with. Not somthing I have wanted to mess with on account it is already optimized for other specfic purposes of which I only understand vaguely as to the reasoning and can seem very arcane.
So what problems am i likely to run into splitting meshes into multiple pieces. is there a max supported individual collision meshes per object also how would this effect the performance of the normal collision detection code having to iterate over a large set of meshes.
Another option i can think of would be to implement a specfic tree structure to help cut down on the number of triangles that need to be processed. This of course would increase the memory foot print but it is more independant of the rest of the engines functions.
10/24/2014 (7:32 am)
Well I think i will have to call defeat on this for making concave meshes workable processing wise not for lack of trying on my part. Sure i have it working in a fairly decent manner but it is just so much more expensive computationally. and from my tinkering around even with convex meshes this can get really expensive with large numbers of particles and large meshes.So this means if i want to use as many particles as I want I will have to optimize the data i am working with. Not somthing I have wanted to mess with on account it is already optimized for other specfic purposes of which I only understand vaguely as to the reasoning and can seem very arcane.
So what problems am i likely to run into splitting meshes into multiple pieces. is there a max supported individual collision meshes per object also how would this effect the performance of the normal collision detection code having to iterate over a large set of meshes.
Another option i can think of would be to implement a specfic tree structure to help cut down on the number of triangles that need to be processed. This of course would increase the memory foot print but it is more independant of the rest of the engines functions.
#20
Than there is also the option of apex, it's a fair bit of work but is a really nice addition to physx and has some pretty cool features.
10/24/2014 (6:32 pm)
This sounds like a classic case for using physics plugin. The physx 3 plugin has particles that support collision. The particles part i gotta admit i have done little testing with as i didn't write that part of the plugin and just haven't needed those features yet. It may serve as a good "base" anyway to come up with something more suited to your projects needs.Than there is also the option of apex, it's a fair bit of work but is a really nice addition to physx and has some pretty cool features.
Torque Owner Daniel Buckmaster
T3D Steering Committee
That said, you may still not want those particles drifting through things. I'd actually go with a less precise approach - treat each dynamic object as a point force that repels particles. That way the particles are unlikely to penetrate, as they are pushed away. Of course this wouldn't work for long thin obstacles like walls, just reasonable spherical ones. You could go into more depth and use bounding boxes, I guess, so you could have repulsion based on distance-to-box...