Maarten Baert's website

Game Maker / C++ projects

Home Model Creator ExtremePhysics Game Maker DLLs SimpleScreenRecorder AlterPCB Quadcopters   Recent comments Search

Last modified: Tue, 1 Mar 2011
Refresh

Contact


ep_contact_destroy

ep_contact_destroy(world_id, contact_id)

Destroys the contact with the given id.

This function can be used to disable some collisions (e.g. to create one-way platforms). This function should be used after calling ep_world_update_contacts but before calling ep_world_simulate_step (in all other cases destroying contacts doesn't have any effect). ep_world_update_contacts will recreate the contact every step, so you will have to destroy it again every step to disable the collision.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_exists

ep_contact_exists(world_id, contact_id)

Returns whether the contact with the given id exists.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_body1

ep_contact_get_body1(world_id, contact_id)

Returns the id of the first body this contact is connected with.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_body2

ep_contact_get_body2(world_id, contact_id)

Returns the id of the second body this contact is connected with.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_shape1

ep_contact_get_shape1(world_id, contact_id)

Returns the id of the shape of the first body this contact is connected with.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_shape2

ep_contact_get_shape2(world_id, contact_id)

Returns the id of the shape of the second body this contact is connected with.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_normal_x

ep_contact_get_normal_x(world_id, contact_id)

Returns the x component of the contact normal.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_normal_y

ep_contact_get_normal_y(world_id, contact_id)

Returns the y component of the contact normal.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point1_active

ep_contact_get_point1_active(world_id, contact_id)

Returns whether the first contact point is active.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point2_active

ep_contact_get_point2_active(world_id, contact_id)

Returns whether the second contact point is active.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point1_x

ep_contact_get_point1_x(world_id, contact_id)

Returns the x component of the position of the first contact point (in world coordinates).

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point1_y

ep_contact_get_point1_y(world_id, contact_id)

Returns the y component of the position of the first contact point (in world coordinates).

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point2_x

ep_contact_get_point2_x(world_id, contact_id)

Returns the x component of the position of the second contact point (in world coordinates).

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point2_y

ep_contact_get_point2_y(world_id, contact_id)

Returns the y component of the position of the second contact point (in world coordinates).

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point1_normalforce

ep_contact_get_point1_normalforce(world_id, contact_id)

Returns the normal force of the first contact point.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point1_tangentforce

ep_contact_get_point1_tangentforce(world_id, contact_id)

Returns the tangent force of the first contact point.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point2_normalforce

ep_contact_get_point2_normalforce(world_id, contact_id)

Returns the normal force of the second contact point.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point2_tangentforce

ep_contact_get_point2_tangentforce(world_id, contact_id)

Returns the tangent force of the second contact point.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point1_normalveldelta

ep_contact_get_point1_normalveldelta(world_id, contact_id)

Returns the velocity difference of the first contact point at the start of the step in the direction of the normal vector.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point1_tangentveldelta

ep_contact_get_point1_tangentveldelta(world_id, contact_id)

Returns the velocity difference of the first contact point at the start of the step in the direction perpendicular to the normal vector.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point2_normalveldelta

ep_contact_get_point2_normalveldelta(world_id, contact_id)

Returns the velocity difference of the second contact point at the start of the step in the direction of the normal vector.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_get_point2_tangentveldelta

ep_contact_get_point2_tangentveldelta(world_id, contact_id)

Returns the velocity difference of the second contact point at the start of the step in the direction perpendicular to the normal vector.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_previous

ep_contact_previous(world_id, contact_id)

Returns the id of the previous contact, or 0 if there is no previous contact.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


ep_contact_next

ep_contact_next(world_id, contact_id)

Returns the id of the next contact, or 0 if there is no next contact.

  • world_id: The id of the world.

  • contact_id: The id of the contact.


Comments

Lfcesar

Comment #1: Mon, 8 Oct 2012, 3:48 (GMT+1, DST)

Quote


I'm new using extremephysics, which
I want to know is how I can do to know
the force with which an object collided with
another, or multiple objects with an object.
or how hard is colliding
Can you help me porfabor

Maarten Baert

Administrator

Comment #2: Thu, 11 Oct 2012, 10:57 (GMT+1, DST)

Quote


Quote: Lfcesar

I'm new using extremephysics, which
I want to know is how I can do to know
the force with which an object collided with
another, or multiple objects with an object.
or how hard is colliding
Can you help me porfabor

Use ep_contact_get_point1_normalforce and ep_contact_get_point2_normalforce. You can check which contact points are active with ep_contact_get_point1_active and ep_contact_get_point2_active.

Lfcesar

Comment #3: Thu, 11 Oct 2012, 20:03 (GMT+1, DST)

Quote


ohh thanks, but I can make an example please do not use still functions well and I get

Last modified: Thu, 11 Oct 2012, 20:03 (GMT+1, DST)

Maarten Baert

Administrator

Comment #4: Wed, 17 Oct 2012, 13:19 (GMT+1, DST)

Quote


Quote: Lfcesar

ohh thanks, but I can make an example please do not use still functions well and I get

... what? I really don't understand what you're saying. :)

Platoonsgt1

Comment #5: Wed, 1 May 2013, 5:34 (GMT+1, DST)

Quote


ep_contact_destroy does not seem to exist in ExtremePhysics 2.1

Do you know of a way to create one-way platforms without using it?

Also, will my 2.1 files be compatible with 2.2, if I choose to update?

Just to check, is this code likely to work at creating a one-way platform?

var s, c;
if instance_exists(self)
for(s = ep_body_first_shape(global.world, body); s!=0; s = ep_shape_next(global.world, body, s))
{
    for(c = ep_shape_get_first_contact(global.world, body, s); c!=0; c = ep_shape_get_next_contact(global.world, body, s, c))
    {
        if not (ep_contact_get_point1_x(global.world,c) = x+16 and ep_contact_get_point2_x(global.world,c) = x+16)
        {ep_contact_destroy(global.world,c)}
    }
}

This is in the step event on an object which should only collide on its right surface, and is 32 wide.

Maarten Baert

Administrator

Comment #6: Fri, 3 May 2013, 13:42 (GMT+1, DST)

Quote


Quote: Platoonsgt1

ep_contact_destroy does not seem to exist in ExtremePhysics 2.1

Do you know of a way to create one-way platforms without using it?

Also, will my 2.1 files be compatible with 2.2, if I choose to update?

Just to check, is this code likely to work at creating a one-way platform?

var s, c;
if instance_exists(self)
for(s = ep_body_first_shape(global.world, body); s!=0; s = ep_shape_next(global.world, body, s))
{
    for(c = ep_shape_get_first_contact(global.world, body, s); c!=0; c = ep_shape_get_next_contact(global.world, body, s, c))
    {
        if not (ep_contact_get_point1_x(global.world,c) = x+16 and ep_contact_get_point2_x(global.world,c) = x+16)
        {ep_contact_destroy(global.world,c)}
    }
}

This is in the step event on an object which should only collide on its right surface, and is 32 wide.

You should upgrade to the latest version. There's a file called version.txt that lists all the changes. You may have to add ep_world_update_contacts before ep_world_simulate_step if it wasn't there already. Other than that I don't think there were any major changes, maybe some new/removed function arguments but that's easy to fix.

The testbed has an example for one-way platforms based on the normal vectors of the contacts. This is usually more reliable, so try to use that if you can. The code you have now will almost certainly not work because the x coordinate will almost never be exactly x+16. There are usually small deviations.

Last modified: Fri, 3 May 2013, 13:44 (GMT+1, DST)

Earacher

Comment #7: Tue, 14 May 2013, 13:40 (GMT+1, DST)

Quote


Hi Maarten.
When I (jump or move) and collide the wall or something
there is no force in most situations
why?
[img]http://i.imgur.com/1zitXMK.jpg[/img]

Maarten Baert

Administrator

Comment #8: Tue, 14 May 2013, 15:07 (GMT+1, DST)

Quote


Quote: Earacher

Hi Maarten.
When I (jump or move) and collide the wall or something
there is no force in most situations
why?
[img]http://i.imgur.com/1zitXMK.jpg[/img]

Are you using substeps? In that case, the force will only be there for one substep, so you have to run your force-checking code after every substep to make sure it detects this.

Last modified: Tue, 14 May 2013, 15:09 (GMT+1, DST)

Earacher

Comment #9: Tue, 14 May 2013, 16:19 (GMT+1, DST)

Quote


Quote: Maarten Baert
Quote: Earacher

Hi Maarten.
When I (jump or move) and collide the wall or something
there is no force in most situations
why?
[img]http://i.imgur.com/1zitXMK.jpg[/img]

Are you using substeps? In that case, the force will only be there for one substep, so you have to run your force-checking code after every substep to make sure it detects this.

Can I change substep to 1?Is that unstable?

Maarten Baert

Administrator

Comment #10: Tue, 14 May 2013, 16:54 (GMT+1, DST)

Quote


Quote: Earacher

Can I change substep to 1?Is that unstable?

Sure, that will work, it's just slightly less accurate.

Earacher

Comment #11: Wed, 5 Jun 2013, 16:57 (GMT+1, DST)

Quote


Hello Maarten.
What does active actually mean?Is that "dynamic"?

Maarten Baert

Administrator

Comment #12: Wed, 5 Jun 2013, 17:34 (GMT+1, DST)

Quote


Quote: Earacher

Hello Maarten.
What does active actually mean?Is that "dynamic"?

No. There are two contact types: point contacts (e.g. a ball resting on the ground) and line contacts (e.g. a box resting on the ground). Point contacts have only one active contact point, line contacts have two active contact points (and separate forces/velocities for each point).

David37

Comment #13: Sat, 7 Sep 2013, 3:57 (GMT+1, DST)

Quote


Hi Maarten.

Thank you for your creation of Extreme Physics - it is absolutely brilliant, and faster than I would have believed possible with Gamemaker. I wish I had known of this earlier.

I am using your 3rd method of collision detection (all collisions at once). http://www.maartenbaert.be/extremephysics/tutorials/collision-detection/
I am trying to refrain from using a separate object for each body, as I have found this to be slower, so all my "instances" are identified by their body number and a common ds_grid array for any details. When using your code (slightly modified as bodies don't have separate objects) to check all collisions at once, I am finding that sometimes I am getting multiple explosions for the one collision (i.e. a collision between two bodies will sometimes give more than one explosion). I believe this is caused by having more than one contact point for a collision between two multipolygons.

Is there an efficient (and fast) way to disregard further contacts between two bodies once the first is found? I have wondered about storing the body ids in the loop, and disregarding the next contact if the body ids are the same, but as I'm not sure about the order Extreme Physics creates contacts, I can't say if this will work 100%. If you are able to provide advice about this problem or information on the order of generation of contacts, I would be very grateful.

Maarten Baert

Administrator

Comment #14: Sat, 7 Sep 2013, 22:56 (GMT+1, DST)

Quote


Quote: David37

I believe this is caused by having more than one contact point for a collision between two multipolygons.

Not just multiple contact points, but multiple contacts: each pair of shapes gets its own contact.

Quote: David37

Is there an efficient (and fast) way to disregard further contacts between two bodies once the first is found? I have wondered about storing the body ids in the loop, and disregarding the next contact if the body ids are the same, but as I'm not sure about the order Extreme Physics creates contacts, I can't say if this will work 100%. If you are able to provide advice about this problem or information on the order of generation of contacts, I would be very grateful.

Tricky. ExtremePhysics creates contacts in the order they occur. If they occur at the same time (step), it depends on the broad-phase, which is essentially random: they are ordered by the x coordinate of the left side of the axis-aligned bounding box of each shape :). The collision system only deals with shapes, not bodies, so you can't rely on this.

You could keep a list of all pairs of bodies that you have processed. You could put these in a ds_map using only the key (essentially a 'set' data structure). The key could be something like:

key = min(b1, b2) + max(b1, b2) * 1000000;

This should be unique as long as you don't have a million bodies :).

A different way to check contacts would be something like this:

for each body {
    for each shape in body {
        for each contact in shape {
            if other body id > this body id {
                // handle collision
                // continue with next body (break out of last two for loops)
            }
        }
    }
}

It is less efficient because there is more overhead, and every contact is checked twice, but you won't have to keep lists about what collisions you've already processed.

David37

Comment #15: Sun, 8 Sep 2013, 8:32 (GMT+1, DST)

Quote


Quote: Maarten Baert
Quote: David37

I believe this is caused by having more than one contact point for a collision between two multipolygons.

Not just multiple contact points, but multiple contacts: each pair of shapes gets its own contact.

Quote: David37

Is there an efficient (and fast) way to disregard further contacts between two bodies once the first is found? I have wondered about storing the body ids in the loop, and disregarding the next contact if the body ids are the same, but as I'm not sure about the order Extreme Physics creates contacts, I can't say if this will work 100%. If you are able to provide advice about this problem or information on the order of generation of contacts, I would be very grateful.

Tricky. ExtremePhysics creates contacts in the order they occur. If they occur at the same time (step), it depends on the broad-phase, which is essentially random: they are ordered by the x coordinate of the left side of the axis-aligned bounding box of each shape :). The collision system only deals with shapes, not bodies, so you can't rely on this.

You could keep a list of all pairs of bodies that you have processed. You could put these in a ds_map using only the key (essentially a 'set' data structure). The key could be something like:

key = min(b1, b2) + max(b1, b2) * 1000000;

This should be unique as long as you don't have a million bodies :).

A different way to check contacts would be something like this:

for each body {
    for each shape in body {
        for each contact in shape {
            if other body id > this body id {
                // handle collision
                // continue with next body (break out of last two for loops)
            }
        }
    }
}

It is less efficient because there is more overhead, and every contact is checked twice, but you won't have to keep lists about what collisions you've already processed.

Thanks very much for this Maarten. I used your key/ds_map solution, and it works nicely. Thanks also for your very prompt response.

Write a comment