FxPhysics2D::resolveOverlapPair Issue
by Ray Gebhardt · in Torque Game Builder · 03/14/2005 (3:20 pm) · 19 replies
For some reason fxPhysics2D::resolveOverlapPair is being applied, even if you set an object to setCollisionPhysics(false, false); In fact it runs on an object even if setCollisionActive is set to receive only. I tried figure out a way to fix the issue, but so far I have only been able to implement a partially fix.
Basically what happens, is if I try to disable collision physics on an object, it still does the caclulations to keep the objects from intersecting each other. I am trying to create an object in the scene that just receives collision, but doesn't take part in the physics system (my character has a sword, and I want to manually handle how the sword reacts with objects in a specialized way).
Basically what happens, is if I try to disable collision physics on an object, it still does the caclulations to keep the objects from intersecting each other. I am trying to create an object in the scene that just receives collision, but doesn't take part in the physics system (my character has a sword, and I want to manually handle how the sword reacts with objects in a specialized way).
#2
I have just configured 100 objects that have "setCollisionPhysics(false, false);" set but their collisions active in both directions. I create them all overlapping and they don't solve the overlap. If I apply impulses to them, they stay overlapped. I'm not seeing this at all although I'm not doubting you're seeing a problem there.
What is your setup?
Here's what I tried...
- Melv.
03/15/2005 (1:45 am)
Ray,I have just configured 100 objects that have "setCollisionPhysics(false, false);" set but their collisions active in both directions. I create them all overlapping and they don't solve the overlap. If I apply impulses to them, they stay overlapped. I'm not seeing this at all although I'm not doubting you're seeing a problem there.
What is your setup?
Here's what I tried...
for ( %n = 0; %n < 15; %n++ )
{
%ball = new fxStaticSprite2D() { scenegraph = t2dSceneGraph; };
%ball.setPosition( (-20 + (%n*2)) SPC 0 );
%ball.setSize( 5 );
%ball.setImageMap( ggLogoImageMap );
%ball.setCollisionActive( true, true );
%ball.setCollisionPhysics( false, false );
%ball.setCollisionMasks( BIT(0), BIT(0) );
%ball.setCollisionPolyPrimitive( 12 );
%ball.setImpulseForcePolar( 0, 20 );
%ball.setDebugOn( BIT(5) );
}- Melv.
#3
I have a quick question, that seems like it might be interrelated to this issue. Should an fxTileLayer2D be set to only send collisions, rather than only receive collisions? Right now it has the following code in the constructor:
BTW, I love the physics code!
(Damn it, your name is spelled Melvyn, not Melvin...I have to change the name of my game j/king).
03/15/2005 (6:47 am)
I am only having this issue if I have physics enabled for one object, but disabled for another. So lets say I have object one object configured like this:%ball.setCollisionActive(true, true); %ball.setCollisionPhysics(true, true); %ball.setCollisionMasks(BIT(0), BIT(0));And then i have another object configured like this:
%bat.setCollisionActive(true, true); %bat.setCollisionPhysics(false, false); %bat.setCollisionMasks(BIT(0), BIT(0));The second object will still send and receive physics collisions, even though they are disabled. I was looking into the issue last night, and I think I may almost have a fix.
I have a quick question, that seems like it might be interrelated to this issue. Should an fxTileLayer2D be set to only send collisions, rather than only receive collisions? Right now it has the following code in the constructor:
Parent::mCollisionSendAllowed = false;But it seems that logically it should be replaced with:
Parent::mCollisionReceiveAllowed = false;I will try setting up fxTileLayer2D to only send collisions tonight as a test. If it works as I think it will, it might even fix a few other slight glitches I ran into.
BTW, I love the physics code!
(Damn it, your name is spelled Melvyn, not Melvin...I have to change the name of my game j/king).
#4
- Melv.
03/15/2005 (10:15 am)
I'll have a look at this later. Need to eat, bath baby, talk to wife first. :)- Melv.
#5
fxSceneObject2D.cc - Line 3328
with this block of code:
After replacing that code, the setCollisionPhysics/setCollisionActive functions should work as advertised.
03/15/2005 (4:52 pm)
I have fixed the bug I outlined above. The formatting is a little messed up because I had to prevent the forums from word wrapping the lines. The code should still function correctly though. You just have to replace following code block:fxSceneObject2D.cc - Line 3328
// We only need to solve the contacts if we've got physics send enabled on // the source or physics receive on the destination. pCollisionStatus->mSrcSolve = getCollisionPhysicsSend() && !processIsMountedRigid(); pCollisionStatus->mDstSolve = pDstObject->getCollisionPhysicsReceive() && !pDstObject->processIsMountedRigid(); // Solve? if ( pCollisionStatus->mSrcSolve || pCollisionStatus->mDstSolve ) // Yes, so solve collision. fxPhysics2D::solveCollision( pCollisionStatus );
with this block of code:
// We only need to solve the contacts if we've got physics send enabled on // the source or physics receive on the destination. pCollisionStatus->mSrcSolve = getCollisionPhysicsReceive() && pDstObject->getCollisionPhysicsSend() && !processIsMountedRigid(); pCollisionStatus->mDstSolve = pDstObject->getCollisionPhysicsReceive() && getCollisionPhysicsSend() && !pDstObject->processIsMountedRigid(); // Solve? if ( pCollisionStatus->mSrcSolve || pCollisionStatus->mDstSolve ) // Yes, so solve collision. fxPhysics2D::solveCollision( pCollisionStatus );
After replacing that code, the setCollisionPhysics/setCollisionActive functions should work as advertised.
#6
Sorry I didn't get a chance to look at this last night and I'm currently at work so I'll need to look at it in more detail when I get home.
Taking a look at the code as well as your submission, I'm not sure if there actually is a problem with it or if the nature of what I intended the "setCollisionPhysics()" to achieve isn't being communicated well or perhaps even needs altering.
The intention for the "setCollisionPhysics()" call was to specify whether the object would react when a collision was sent/received from/to the object in question. As you know, the code here is dealing with a forward (send) collision (there isn't any receive code) from %src to %dst.
With that in mind, we only want to process the %src object if it has its send-physics active (and it's not mounted-rigid) and we only want to process the %dst object if it has its receive-physics enabled (or it's not mounted-rigid).
In other words, in the routine, the only reactions to the %src should be related to sending (because it's the source sending here only) and the %dst should be related to receiving (because it's the destination receiving here only).
I'm pretty open minded here on what's going wrong. I'm also aware that I'm pretty exhausted as well. ;)
EDIT: Just thought I'd add that I really do appreciate your efforts in helping with the code! :)
- Melv.
03/16/2005 (7:10 am)
Ray,Sorry I didn't get a chance to look at this last night and I'm currently at work so I'll need to look at it in more detail when I get home.
Taking a look at the code as well as your submission, I'm not sure if there actually is a problem with it or if the nature of what I intended the "setCollisionPhysics()" to achieve isn't being communicated well or perhaps even needs altering.
The intention for the "setCollisionPhysics()" call was to specify whether the object would react when a collision was sent/received from/to the object in question. As you know, the code here is dealing with a forward (send) collision (there isn't any receive code) from %src to %dst.
With that in mind, we only want to process the %src object if it has its send-physics active (and it's not mounted-rigid) and we only want to process the %dst object if it has its receive-physics enabled (or it's not mounted-rigid).
In other words, in the routine, the only reactions to the %src should be related to sending (because it's the source sending here only) and the %dst should be related to receiving (because it's the destination receiving here only).
I'm pretty open minded here on what's going wrong. I'm also aware that I'm pretty exhausted as well. ;)
EDIT: Just thought I'd add that I really do appreciate your efforts in helping with the code! :)
- Melv.
#7
So if the %src object was set to send collisions, it would also receive collisions. On top of that, the collision response code is being called twice for each pair of objects, if they are overlapping. This made it so that no matter what, you couldn't disable the sending or receiving of physics on an object.
Now there are probably a few other ways to fix this bug. I just chose this method because it was easy, and offers pretty much the same performance/functionality as the old code.
BTW, thanks a lot for always responding to my posts. I know my posts aren't usually as clear as they should, but I never used forums before I got T2D :).
03/16/2005 (3:59 pm)
Well I agree with everything you said in your previous post. That is part of what made it kind of hard to figure out why things weren't working as I expected. After messing around with the code for a while, I noticed that fxPhysics2D::solveCollision was actually applying the collision response to %src if mSrcSolve was true, and %dst if mDstSolve was true. The two sections of code you will want to look at, to confirm this functionality are "fxPhysics2D.cc" line 1602, and "fxPhysics2D.cc" line 1770. So if the %src object was set to send collisions, it would also receive collisions. On top of that, the collision response code is being called twice for each pair of objects, if they are overlapping. This made it so that no matter what, you couldn't disable the sending or receiving of physics on an object.
Now there are probably a few other ways to fix this bug. I just chose this method because it was easy, and offers pretty much the same performance/functionality as the old code.
BTW, thanks a lot for always responding to my posts. I know my posts aren't usually as clear as they should, but I never used forums before I got T2D :).
#8
03/16/2005 (4:37 pm)
If you try to fix this bug by disabling the solving for the %src object, it doesn't work for the case of tilemaps. The player will sink into the tilemap if you apply a positive constant force to him on the Y axis.
#9
I'll have a browse through this in my break at lunchtime today.
Many thanks. :)
- Melv.
03/17/2005 (12:08 am)
Ray,I'll have a browse through this in my break at lunchtime today.
Many thanks. :)
- Melv.
#10
03/17/2005 (6:44 am)
I looked at my posted code, and I did notice one thing that was kind of confusing. I didn't change the comment above the block of code I modified. It would probably make more sense if I change it so it said:// We only need to solve the contacts if we have physics // receive enabled on the source, and physics send enabled // for the destination; or if we have physics receive enabled // on the destination, and physics send enabled for the source. // When we solve the collisions for the source/destiation pair // both the source and destination will be processed if necessary. pCollisionStatus->mSrcSolve = getCollisionPhysicsReceive() && pDstObject->getCollisionPhysicsSend() && !processIsMountedRigid(); pCollisionStatus->mDstSolve = pDstObject->getCollisionPhysicsReceive() && getCollisionPhysicsSend() && !pDstObject->processIsMountedRigid(); // Solve? if ( pCollisionStatus->mSrcSolve || pCollisionStatus->mDstSolve ) // Yes, so solve collision. fxPhysics2D::solveCollision( pCollisionStatus );
#11
Well it seemed to work pretty good after couple tweaks, but with one major issue. The tiles in a tile layer don't send collisions, they only receive collisions. So I am going to look through the code and see how I can get that to work the other way around.
03/17/2005 (7:43 pm)
After looking at the code even more, realized that the collision response code should only be processing the send. Well I thought that before, but the actual collision response code wasn't taking that into account :). So I tried just disabling the code that would send a collision response to the source object. I did this in order to have to code only send to the destination object.Well it seemed to work pretty good after couple tweaks, but with one major issue. The tiles in a tile layer don't send collisions, they only receive collisions. So I am going to look through the code and see how I can get that to work the other way around.
#12
I believe the physics response code in "fxPhysics2D::solveCollision" is being processed incorrectly. Going by Chris Hecker's description of collision response, only the destination object's velocity and position should be modified in a send only calculation. What happens in the current code, is the velocity and position are adjusted for both the source and destination. This would be correct processing, if the function was meant to apply the collision response for the source and destination (in other words, both objects send and receive). So the first changes I made in the code involved disabling the sending of the collision response to the source in "fxPhysics2D::resolveOverlapPair" and "fxPhysics2D::resolveCollisionBasis".
After I made the change above, I ran into an issue. Tile layers only received collisions, and never sent them. The system would break down, because the tile layer would never send a collision to the object colliding with it. So say for example, you had a Super Mario style character standing on a tile within a tile layer, you would see the character slowly start to sink into the ground.
To resolve this issue, I had to make two changes. The first was to change tile layers so that they only send collisions, instead of only receive them. The next change that had to be made, was a slight change to how collisions were queried in the scene.
The current physics code iterates through each fxSceneObject2D in the scene graph. In each iteration, the scene object will assign itself as the %src, and perform a scene query ("fxSceneObject2D::getCollisionAreaPhysicsModels") to see which objects it is colliding with. The code will then iterate through each object returned in the scene query, assign it as the %dst and pass %src and %dst to "fxSceneObject2D::processCollisionStatus".
The above logic works in every case, other than in the case of a tile that is sending collisions. The tiles in a tile map are not scene objects, so they can never be a sender in the current code through. The tiles are only returned by scene queries. What I did to get around this problem, was I swapped the %src and %dst that are passed to "fxSceneObject2D::processCollisionStatus". So the %dst would be the scene object that is currently being processed, and the %src would be the object that was returned from the scene query.
Now doing these changes does make the physics system react slightly different, but it seems to be a lot closer to the desired logic. You don't get any redundant calls to fxSceneObject2D::processCollisionStatus, so in theory the physics should be slightly faster / more stable then they are in the current code base.
I will post the code when I get home from work tonight. Tell me what you think.
03/18/2005 (8:39 am)
I was looking through the code, and checking out Chris Hecker's physics tutorials (which are very interesting BTW). I think I figured out what needs to be done to fix the physics issues I outlined above (and possibly make the physics system a little more stable).I believe the physics response code in "fxPhysics2D::solveCollision" is being processed incorrectly. Going by Chris Hecker's description of collision response, only the destination object's velocity and position should be modified in a send only calculation. What happens in the current code, is the velocity and position are adjusted for both the source and destination. This would be correct processing, if the function was meant to apply the collision response for the source and destination (in other words, both objects send and receive). So the first changes I made in the code involved disabling the sending of the collision response to the source in "fxPhysics2D::resolveOverlapPair" and "fxPhysics2D::resolveCollisionBasis".
After I made the change above, I ran into an issue. Tile layers only received collisions, and never sent them. The system would break down, because the tile layer would never send a collision to the object colliding with it. So say for example, you had a Super Mario style character standing on a tile within a tile layer, you would see the character slowly start to sink into the ground.
To resolve this issue, I had to make two changes. The first was to change tile layers so that they only send collisions, instead of only receive them. The next change that had to be made, was a slight change to how collisions were queried in the scene.
The current physics code iterates through each fxSceneObject2D in the scene graph. In each iteration, the scene object will assign itself as the %src, and perform a scene query ("fxSceneObject2D::getCollisionAreaPhysicsModels") to see which objects it is colliding with. The code will then iterate through each object returned in the scene query, assign it as the %dst and pass %src and %dst to "fxSceneObject2D::processCollisionStatus".
The above logic works in every case, other than in the case of a tile that is sending collisions. The tiles in a tile map are not scene objects, so they can never be a sender in the current code through. The tiles are only returned by scene queries. What I did to get around this problem, was I swapped the %src and %dst that are passed to "fxSceneObject2D::processCollisionStatus". So the %dst would be the scene object that is currently being processed, and the %src would be the object that was returned from the scene query.
Now doing these changes does make the physics system react slightly different, but it seems to be a lot closer to the desired logic. You don't get any redundant calls to fxSceneObject2D::processCollisionStatus, so in theory the physics should be slightly faster / more stable then they are in the current code base.
I will post the code when I get home from work tonight. Tell me what you think.
#13
03/18/2005 (2:47 pm)
Well there are enough changes to the code to make it impossible to post here. Can you tell me what you think of my solution? If you like it i can email you the files i change, a diff from the EA or something like that.
#14
I'll go through this at the weekend. Sorry that I've not been on this thread in the last 24 hours but please be assured that I've got a link to it on my desktop and I will go through this in detail with you very soon.
I really do appreciate your work with this! :)
- Melv.
03/18/2005 (3:36 pm)
Ray,I'll go through this at the weekend. Sorry that I've not been on this thread in the last 24 hours but please be assured that I've got a link to it on my desktop and I will go through this in detail with you very soon.
I really do appreciate your work with this! :)
- Melv.
#15
* Mounts with a 0 force lag behind slightly.
* A Super Mario style platformer character bobbing up a
little when he hits tile seams (if you are using a constant
force to hold him to the ground).
* The "texture bleeding" rendering artifacts.
* A more robust animation system.
If you want any of them fixed, you can just assign them to me, and I will find a solution to them. If you have a particular way you want them to be done, I can do it your way too ;). They are only real issues at the moment that I need to resolve to get my game working perfectly.
EDIT: I know T2D is your baby, I just thought I would offer the help.
03/18/2005 (4:57 pm)
Its no problem. It took me a little while to hash out a solution that would work anyways. If you think the solution is the right thing to do, I will send you the source files. If you think there is a better way, well I can implement that instead. There are a few other issues that I was thinking about working on too.* Mounts with a 0 force lag behind slightly.
* A Super Mario style platformer character bobbing up a
little when he hits tile seams (if you are using a constant
force to hold him to the ground).
* The "texture bleeding" rendering artifacts.
* A more robust animation system.
If you want any of them fixed, you can just assign them to me, and I will find a solution to them. If you have a particular way you want them to be done, I can do it your way too ;). They are only real issues at the moment that I need to resolve to get my game working perfectly.
EDIT: I know T2D is your baby, I just thought I would offer the help.
#16
There's lots of stuff to change here, particularly the physics, so what we've got here was the most stable version we could come up with for the EA release. There are lots of things that need fixing (and have now been) but there are things that need completing. Physics is definately one that will change, particularly the integration side of things, maybe even using verlet calculations, not sure really.
I'm definately not too proud to accept help in finding/resolving issues and I'll gladly accept any help you can provide. I've been almost killing myself trying to address all the issues and I've just not had time to focus on the physics side which is in dire need of work, especially getting it completely ready for networking etc.
Some of the things in the list are already on the list to do such as changing the way imageMaps work so that the user is completely abstracted away from the hardware issues such as POT usage or texture bleeding. The animation system is pretty basic and that was intentional, at least in terms of the amount of time we wanted to spend on it for the EA release. Also, the mount problem is easy for me to address.
There are certain things that, if you do have the time, you could help me with that I've just not had time to address. The most important one is the tile-map "hitch" issue. I think this is a precision/normal issue but I just haven't had time to confirm that.
When I have finally resolved all the other more minor problems then I'll be all overthe physics code again. It's not an excuse but the motherload of that code was written over a pretty intensive weekend and then further refined over a two week period (part-time). There are other issues with the code that need resolving as well as the ones you mention. Your work with tracing through the physics has been extremely helpful and has really just confirmed what we already knew; we need to do more work on it. We want to get sleep processing in and other more robust iterative methods for processing collisions such as those used in "JigLib" but are aware that we don't want T2D to be primarily a rigid-body simulation system but a 2D games dev system. I was trying to avoid forcing people to use rigid-body dynamics in they don't want it.
Thanks for spending your time helping out Ray, that's pretty "Nool" of you. :) *sorry, couldn't resist*
It may be easier for us to communicate via email? If so, please feel free to do so.
- Melv.
03/19/2005 (4:19 am)
@Ray,There's lots of stuff to change here, particularly the physics, so what we've got here was the most stable version we could come up with for the EA release. There are lots of things that need fixing (and have now been) but there are things that need completing. Physics is definately one that will change, particularly the integration side of things, maybe even using verlet calculations, not sure really.
I'm definately not too proud to accept help in finding/resolving issues and I'll gladly accept any help you can provide. I've been almost killing myself trying to address all the issues and I've just not had time to focus on the physics side which is in dire need of work, especially getting it completely ready for networking etc.
Some of the things in the list are already on the list to do such as changing the way imageMaps work so that the user is completely abstracted away from the hardware issues such as POT usage or texture bleeding. The animation system is pretty basic and that was intentional, at least in terms of the amount of time we wanted to spend on it for the EA release. Also, the mount problem is easy for me to address.
There are certain things that, if you do have the time, you could help me with that I've just not had time to address. The most important one is the tile-map "hitch" issue. I think this is a precision/normal issue but I just haven't had time to confirm that.
When I have finally resolved all the other more minor problems then I'll be all overthe physics code again. It's not an excuse but the motherload of that code was written over a pretty intensive weekend and then further refined over a two week period (part-time). There are other issues with the code that need resolving as well as the ones you mention. Your work with tracing through the physics has been extremely helpful and has really just confirmed what we already knew; we need to do more work on it. We want to get sleep processing in and other more robust iterative methods for processing collisions such as those used in "JigLib" but are aware that we don't want T2D to be primarily a rigid-body simulation system but a 2D games dev system. I was trying to avoid forcing people to use rigid-body dynamics in they don't want it.
Thanks for spending your time helping out Ray, that's pretty "Nool" of you. :) *sorry, couldn't resist*
It may be easier for us to communicate via email? If so, please feel free to do so.
- Melv.
#17
Just thought I'd add that I've now found the issue for the collision "hitch" problem.
TileMap Hitch Problem
- Melv.
03/21/2005 (8:36 am)
Ray,Just thought I'd add that I've now found the issue for the collision "hitch" problem.
TileMap Hitch Problem
- Melv.
#18
03/21/2005 (4:11 pm)
Sweet! I can get back to being lazy again. ;) I will try it out tonight.
#19
03/22/2005 (5:57 pm)
Lol Nool... as long as your on the chat room being lazy its all good ;)
Associate Melv May
Thank you for raising the problem.
- Melv.