Projectile Collision Performance
by Chris Labombard · in Torque Game Engine · 11/29/2005 (5:06 am) · 11 replies
I am experiencing a large slow down when firing a lot of projectiles (they are 2 poly billboards)
By a lot, I mean about 50 - 100.
I profiled the code and found the collision check to be the source of the problem, taking a massive amount of time.
Does anyone know how I might go about fixing the issue ?
NOTE: TGE 1.3
By a lot, I mean about 50 - 100.
I profiled the code and found the collision check to be the source of the problem, taking a massive amount of time.
if (getContainer()->castRay(oldPosition, newPosition, csmDynamicCollisionMask | csmStaticCollisionMask, &rInfo) == true)
Does anyone know how I might go about fixing the issue ?
NOTE: TGE 1.3
About the author
I have been a professional game programmer for over 5 years now. I've worked on virtually every platform, dozens of games and released a few of my own games, including 2 iPhone titles and a title waiting release on Big Fish Games.
#2
I was thikning maybe a different type of collision detection
11/29/2005 (7:31 am)
No. There's objects moving through the environment. I need to know if they hit something. I was thikning maybe a different type of collision detection
#3
You cannot check each particle for collision every frame. Not without slowdown. You can trade speed for accuracy, however, and if you can get this into an acceptable range you might get the results you want.
There are only a few minor changes to the sim/sceneObject.cc castRay function between 1.3 and 1.4, and I haven't noticed a huge increase in efficiency that would solve your problem right away.
That being said; it is certainly possible to write a "batch" cast ray function that takes advantage of the fact that many of your rays are close to eachother. If one ray is thrown out in the early tests, chances are other close rays will be similarly discarded. I've got a few objects that cast several rays at once (and I only need a collision boolean, nothing else) so I might give this a try down the road.
EDIT: it is also possible to use collideBox instead. This checks for collisions against the objects bounding box, and works a bit faster.
EDIT #2: use collideBox first, then castRay only if collideBox hits. slower for particles that hit, a bit faster for particles that dont. (i'm not 100% that castRay's initial tests are necessarily slower than collideBox, however)
11/29/2005 (10:05 am)
Maybe you can give each particle a special property; some particles check for a collision every even tick, and others every odd tick. As long as the particle rememebers its oldPosition value the LAST time a collision was checked, the results would still be somewhat accurate. Maybe a particle can check for a collision every n ticks.You cannot check each particle for collision every frame. Not without slowdown. You can trade speed for accuracy, however, and if you can get this into an acceptable range you might get the results you want.
There are only a few minor changes to the sim/sceneObject.cc castRay function between 1.3 and 1.4, and I haven't noticed a huge increase in efficiency that would solve your problem right away.
That being said; it is certainly possible to write a "batch" cast ray function that takes advantage of the fact that many of your rays are close to eachother. If one ray is thrown out in the early tests, chances are other close rays will be similarly discarded. I've got a few objects that cast several rays at once (and I only need a collision boolean, nothing else) so I might give this a try down the road.
EDIT: it is also possible to use collideBox instead. This checks for collisions against the objects bounding box, and works a bit faster.
EDIT #2: use collideBox first, then castRay only if collideBox hits. slower for particles that hit, a bit faster for particles that dont. (i'm not 100% that castRay's initial tests are necessarily slower than collideBox, however)
#4
Just an issue of something colliding and getting out of the way before the collision check happens. Though with a short time period I dont think it will be an issue.
I think you meant to say projectiles, not particles :)
11/29/2005 (10:15 am)
Manuel - I came up with the same solution. Just an issue of something colliding and getting out of the way before the collision check happens. Though with a short time period I dont think it will be an issue.
I think you meant to say projectiles, not particles :)
#5
07/14/2006 (2:47 am)
Chris did you ever find a good solution for this?
#6
I'd set that up if I were you. Use a variable number of tick deviations. That way if odd and even isnt enough you can use 3 or 4 sets of collision check ticks.
07/14/2006 (7:36 am)
Ron - Other games took priority over this little prototype, so I never implemented the solution Manuel and I discussed. I'd set that up if I were you. Use a variable number of tick deviations. That way if odd and even isnt enough you can use 3 or 4 sets of collision check ticks.
#7
I have seen in some other posts like this that the entire castray system has issues.
www.garagegames.com/mg/forums/result.thread.php?qt=43849
With some of the work by Tom Spilman and some of my own, I have a pretty good projectile collision system that does a great job of reading the collisions now, however it is not apparently performing the projectile processtick function as often as it checks for the actual collision. I get this from the fact that based upon the speed I set for my projectile is directly proportional to amount of distance from the target my player has to be to give the projectile castray time to properly perform its ray casting during processtick.
So what I was trying to find out is how to increase the rate processtick is performed or perhaps someone else would have an new idea since I might be looking at this with blinders on.
07/14/2006 (11:10 am)
OK since my work has been nowhere in this depth so far I have to ask a few questions I suppose.I have seen in some other posts like this that the entire castray system has issues.
www.garagegames.com/mg/forums/result.thread.php?qt=43849
With some of the work by Tom Spilman and some of my own, I have a pretty good projectile collision system that does a great job of reading the collisions now, however it is not apparently performing the projectile processtick function as often as it checks for the actual collision. I get this from the fact that based upon the speed I set for my projectile is directly proportional to amount of distance from the target my player has to be to give the projectile castray time to properly perform its ray casting during processtick.
So what I was trying to find out is how to increase the rate processtick is performed or perhaps someone else would have an new idea since I might be looking at this with blinders on.
#8
07/15/2006 (3:26 pm)
OK here is my code that I added during void Projectile::processTick(const Move* move) right around the old oncollision call. All I am looking for is some sort of way to make the identifcation process not dependant (if possible) on the speed of the projectile so that I am not having this problem with increased projectile speed causing the need to be further back from the object I am firing at for the identification system to work.//***Nelson's Material Mapping (Projectile Section) Update Start***
if( rInfo.object->getTypeMask() & TerrainObjectType )
{
TerrainBlock* tBlock = static_cast<TerrainBlock*>(rInfo.object);
S32 mapIndex = tBlock->mMPMIndex[0];
if (mapIndex != -1)
{
MaterialPropertyMap* pMatMap = static_cast<MaterialPropertyMap*>(Sim::findObject("MaterialPropertyMap"));
const MaterialPropertyMap::MapEntry* pEntry = pMatMap->getMapEntryFromIndex(mapIndex);
if(pEntry)
{
pMatType = pEntry->matType;
}
}
}
else
{
MaterialPropertyMap* pMatMap = static_cast<MaterialPropertyMap*>(Sim::findObject("MaterialPropertyMap"));
const MaterialPropertyMap::MapEntry* pMatEnt = pMatMap->getMapEntryFromIndex(rInfo.material);
if (pMatEnt)
{
pMatType = pMatEnt->matType;
pMatFlag = pMatEnt->matFlags;
}
if(pMatFlag == 1)
{
mPiercePosition = newPosition + mCurrVelocity * (F32(TickMs) / 1000.0f);
mPierceVelocity = mCurrVelocity;
}
}
onCollision(rInfo.point, rInfo.normal, rInfo.object);
explode(rInfo.point, rInfo.normal, objectType, mInitialPosition, mFinalVel );
//***Nelson's Material Mapping (Projectile Section) Update Stop***
#9
07/15/2006 (4:34 pm)
I really think my problem lies within the start variable being based off of the oldPosition value and it being affected by velocity. Also it seems that there is an issue that is related to this that causes it to not even check for collisions until it is a certain distance from the player and that this value is based off of the velocity of the projectile somehow but I do not see where that takes place.
#10
I know there are some out there much better at this stuff than me so I am hoping someone will throw me a bone here because I am not getting much of anywhere and this is getting to be months of testing for me now.
07/15/2006 (8:39 pm)
This is an illustration of what I am dealing with. The collsions still take place but the castRay is not doing its job as it should be. As you can see there is a an area in the ray that is not detecting anything too close to the projectile. The additional issue I am trying to explain here is that the distance of non-detection increases away from the projectile if you increase muzzleVelocity (Projectile Speed). Since my code takes place well after the castRay has even performed, I am convinced it is not the issue but the castray itself or the process tick function.I know there are some out there much better at this stuff than me so I am hoping someone will throw me a bone here because I am not getting much of anywhere and this is getting to be months of testing for me now.
#11
07/17/2006 (2:38 am)
Well it seems my problem is not as I suspected since my armor piercing round code is determined from the exact same castrays as the material to determine explosion type. Therefore my problem is not within castray but within the explosion code for projectiles.
Torque Owner Neil M.
Default Studio Name