Game Development Community

CLAMP response bug

by Michael Woerister · in Torque Game Builder · 01/16/2006 (7:58 am) · 22 replies

EDIT: this is T2D 1.1 ALPHA 2

It seems there is a bug in the CLAMP collision response. If I set a constant force for the scenegraph and let one object sit on a immoveable other one, the first object slowly sinks into the other one:

www.unet.univie.ac.at/~a0402917/pixel/ClampBug.png
Here is the code I use:

...
        // ************************************************************************
	//
	// Add your custom code here...
	//
	// ************************************************************************
	
	t2dScene.setConstantForce("0 50",true);
	t2dScene.setDebugOn(255);
	
	
	$floor = new t2dStaticSprite() {scenegraph = t2dScene;};
	
	$floor.setImageMap(imageMap1234);
	$floor.setImmovable( true );
	$floor.setPosition("0 25");
	$floor.setSize("80 10");
	$floor.setGroup(1);
	$floor.setCollisionPolyPrimitive(4);
	$floor.setCollisionActive(true,true);
	$floor.setCollisionPhysics(true,true);
	$floor.setCollisionResponse( CLAMP );

	
	$obj = new t2dStaticSprite() {scenegraph = t2dScene;};	
	$obj.setImageMap(imageMap1234);
	$obj.setFrame(1);
	$obj.setPosition("0 0");
	$obj.setSize("10 10");
	$obj.setCollisionMasks(BIT(1));
	$obj.setCollisionPolyPrimitive(4);
	$obj.setCollisionActive(true,true);
	$obj.setCollisionPhysics(true,true);
	$obj.setCollisionResponse( CLAMP );

	$actionmap = new ActionMap();
	$actionmap.bindCmd(keyboard,"a","$obj.setLinearVelocityX(-50);","$obj.setLinearVelocityX(0);");
	$actionmap.bindCmd(keyboard,"d","$obj.setLinearVelocityX(50);","$obj.setLinearVelocityX(0);");
	$actionmap.bindCmd(keyboard,"w","$obj.setImpulseForce(\"0 -100\");","");
	$actionmap.push();

This does not happen if both objects are set to RIGID.

- Michael
Page «Previous 1 2
#1
01/17/2006 (11:24 pm)
Michael,

Thanks, this is issue#1176.

- Melv.
#2
01/26/2006 (9:02 am)
Michael,

I've just finished looking at this and it seems that there's a bug in the "setCollisionMasks()" call when you're using the second default argument.

Try changing this routine to the following:-

ConsoleMethod(t2dSceneObject, setCollisionMasks, void, 3, 4, "(groupMask, [layerMask]) - Sets the collision masks.")
{
    // Calculate Group-Mask.
    const U32 groupMask = dAtoi(argv[2]);
    // Calculate Layer-Mask.
    const U32 layerMask = (argc > 3) ? dAtoi(argv[3]) : T2D_MASK_ALL;

    // Set Collision Masks.
    object->setCollisionMasks( groupMask, layerMask );
}

Using "$obj.setCollisionGroups( 1 );" instead of the mask-version solves the issue. I'm still going to look into this futher but if you look closely at the collision config, you'll see that the collisions are full-on in both directions, even for the immovable one, even its physics is on.

- Melv.
#3
01/26/2006 (12:33 pm)
To explain this a little further; the example as you post it has the player being clamped to the surface via collisions. Not whilst this is patronisingly obvious :) what isn't so obvious is that the "player" is reacting to collisions randomly between the "player" hitting/overlapping the "surface" and the "surface" overlapping the "player". The reason for this is that although the platform is immovable, it has full collisions on, including physics (which won't get actioned but will causes some processing anyway).

What needs to happen here is for only one collision to happen and that should really be the player hitting/overlapping the platform. You can do this by altering the collisions on the platform, namely disabling send collisions but leaving receive collisions so that the player can actually collide with the platform. Also, both send/receive collisions should be disabled as the platform is immovable. It won't every move but the configuration conflicts and does calculations right up to the point where it decides the platform can't move. Best to disable it.

With regards to the bug above, it's best to specify both masks when using "setCollisionMasks()" or use the seperable "setCollisionGroups()" and "setCollisionMasks" or the alternate "setCollisionAgainst()" which is much simpler.

When you do this, everything should react as expected.

- Melv.
#4
01/26/2006 (12:41 pm)
Thanks Melv,

I think I need to read through a good collision setup tutorial some time.
#5
01/26/2006 (3:10 pm)
Michael,

I think I need to write one for you and everyone. ;)

- Melv.
#6
01/30/2006 (9:59 am)
Hi Melv.

I'm suffering the same problem, I tested your suggestion and it didn't work:
%vehicle.setGroup ($gn_vehicleGroup);
	%vehicle.setLayer ($gn_vehicleLayer);
	%vehicle.setCollisionActive (false, false); // disabled collision
	%vehicle.setCollisionPhysics (false, true); // only receiving
	%vehicle.setCollisionMaterial (immovableMaterial);
	%vehicle.setCollisionMasks ($go_playerGroups | $go_platformGroups,
						$go_playerLayers | $go_platformLayers);
	%vehicle.idCollision = $JT_COLL_VEHICLE;
	%vehicle.setCollisionCallback (true);
	%vehicle.setCollisionResponse (CLAMP);
	%vehicle.setCollisionMaxIterations (2);
The above code fails because the player just go through the vehicle. Can't land above the vehicle.

In my case this code almost works:
%vehicle.setGroup ($gn_vehicleGroup);
	%vehicle.setLayer ($gn_vehicleLayer);
	%vehicle.setCollisionActive (true, false);
	%vehicle.setCollisionPhysics (true, false);
	%vehicle.setCollisionMaterial (immovableMaterial);
	%vehicle.setCollisionMasks ($go_playerGroups | $go_platformGroups,
						$go_playerLayers | $go_platformLayers);
	%vehicle.idCollision = $JT_COLL_VEHICLE;
	%vehicle.setCollisionCallback (true);
	%vehicle.setCollisionResponse (RIGID);
	%vehicle.setCollisionMaxIterations (2);
The code above almost work, BUT when my player is over the vehicle
it slowly sinks into my vehicle. So this is the same problem for me.
It's weird because the collision poly is over the truck but the image
is inside my truck.

img223.imageshack.us/img223/5160/truck6uu.png
#7
01/31/2006 (2:12 pm)
Without this fixed I guess I'm not going to use elevators and vehicles in my game.
Somebody have experienced this? I'd like to know is a bug in my code. :)
#8
02/01/2006 (12:37 am)
@Adam: There's obviously more going on here that just the code snippet above. Can you reproduce the problem in a simple way? I'm going to create another mock-up again. I presume you're applying a constance-force for gravity? Are you applying this to the object or the scene?

Quote:It's weird because the collision poly is over the truck but the image is inside my truck.
The image above is quite cluttered (the grid doesn't help) so I'm not sure of what I'm seeing. The brownish/red "blob"feature seems to have penetrated the larger green rectangle but there's a bounding-box that's not penetrated. Are you saying that the smaller one is the collision-box whereas the object is being rendered below/away from it. That's insane!!!!

That would most certainly be a problem and I'm not even sure how it could happen but it would most certainly cause serious problems. I know I've asked this before but is there any code or mock-up you could send me that shows this so I can help quicker?

I would like to solve this one ASAP. I have reopened this issue (#1176).

- Melv.
#9
02/01/2006 (7:51 am)
Hi Melv!
yes I'm aplying a constant force to the player and yes the object is being rendered away from its collision box
Right now I'm in the hurry to upgrade to alpha4, so as soon I have time I'm going to send you
a project that reproduces this.
#10
02/01/2006 (8:56 am)
Adam,

I really appreciate you taking the time to send me some code; it'll help both of us resolve this much quicker.

Look forward to hearing from you.

- Melv.
#11
02/01/2006 (5:29 pm)
Hi Melv demo sent to you.
Regards.
#12
02/02/2006 (12:43 am)
Adam,

I'm looking after my daughter all day today because my wife has gone to a funeral. Literally as soon as she gets back, I'll have a look at what you sent. Mucho thanks. :)

- Melv.
#13
02/02/2006 (8:00 am)
Ok Melv.
Kids are first :)
#14
02/02/2006 (8:39 am)
Adam,

Could you give me some hints on where the player and the "alt+T" object is configured to save me searching?

I'm basically looking for the collision-configuration for both objects.

- Melv.
#15
02/02/2006 (9:50 am)
@Adam: It's hard to see exactly what's going on but as far as I can see, the only reason the "player" being stopped at all is because of overlap processing, not a collision response. Looking further into your code, the "player" isn't set to collide with the "vehicle" at all whereas the "vehicle" is set to collide with the "player" but it has physics turned on but is immovable! All sorts of odd problems here.

It might help reduce the complexity a little if you have a look at the new "setCollisionGroups()" and "setCollisionLayers()" calls that remove the need to maintain masks associated with literal groups/layers.

I think the problem you're seeing is all the mixed collision-response that's setup. T2D is doing its best to honor the requests but some of them are getting in your way. The "vehicle" object is immovable so you should ensure that its physics are set to false for both send/receive. Also, because it's not moving, there's no real need to have send collisions active for this object. If you do and this object processes the collision first, you may not get what you desire from the target object. Your vehicle should only have receive collisions on because that allows others to collide with it.

Your vehicle code becomes...

%vehicle.setCollisionActive (false, true);
%vehicle.setCollisionPhysics (false, false);

... and also simplified the config of the vehicle because setting a collision-material, collision response and collision-masks on this object is redundant. I simply use...

%vehicle.setImmovable( true );

... and I added two "vehicle" collision masks to your code although this stuff can be simplified with the functions described above ...

$go_vehicleGroups = BIT($gn_vehicleGroup);
$go_vehicleLayers = BIT($gn_vehicleLayer);

... and added these to the players collision mask ...

%gpxActor.setCollisionMasks ($go_enemyGroups | $go_platformGroups | $go_vehicleGroups,
$go_enemyLayers | $go_platformLayers | $go_vehicleLayers);

... and the player collides normally and doesn't sink.

The trouble is now that your player won't move left or right but will jump. This is going to be some logic in your movement code I guess as T2D isn't controlling this and if it can jump, it can move left/right. I haven't look in detail at that though.

There may still be something going wrong here because the fact that something isn't being updated because of the discontinuity between the bounding-box and the rendered sprite. This isn't causing the "sinking" problem though but I think it may well be related to the point you mention in your "how to test.txt" document; when the "player" moves off the "vehicle", it doesn't fall from rest.

I'm going to continue to look at that.

- Melv.
#16
02/02/2006 (10:09 am)
Just a side note: "setFlip()" will action immediately (when called from script) as of the next release. Previously you'd need to delay a frame and I noticed you were doing this.

Hope this helps,

- Melv.
#17
02/02/2006 (11:29 am)
Sorry Melv I was discconnected this morning and I just saw your question right now,
sorry for the extra time Melv. As always your support is incredible :).

Well I wasn't sure about my methods, I get them after a lot of trials an errors
and this was what "worked" somehow, my player was "immovable" because
if I used some standard material, player and vehicle started to tremble until
they were expelled.
Of course I wanted my vehicle were be mobile, and with your suggestions seems
is working now.

Yes the player can't move due to a fail in my code, I changed the statemachine and this is
working now.

And with your configuration the player falls now from rest. So everything seems OK

Yeah, that problem with setFlip I'd forgotten totally, glad you didn't :)

Thankyou very much Melv. I can sign your support is awesome!!
#18
02/02/2006 (11:40 am)
Wow, it sounds like you got it all working then, that's good news.

You are most welcome for the support, it benefits both of us. :)

Are you still experiencing the problem that when you step off your "vehicle", you're not falling from rest?

- Melv.
#19
02/02/2006 (11:59 am)
NO the player is falling now normally from rest AFI tested.

You can test this replacing in chaIma:
function chaIma::onCollision (%this, %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
	switch (%dstObj.idCollision)
	{
		case $JT_COLL_TILE_PASSABLE:
			%this.onHitGround (%srcObj, %normal);
		case $JT_COLL_TILE:
			%this.onHitGround (%srcObj, %normal);
		case $JT_COLL_VEHICLE:
			%this.onHitGround (%srcObj, %normal); // << change
	}
}
Thanxs again. Regards
#20
02/02/2006 (12:25 pm)
Thanks, I'll check that out.

BTW: When are we going to see a proper demo of this project? I keep getting teased with bits of it. :)

Good Luck,

- Melv.
Page «Previous 1 2