Enabling Collisions Between Joined Bodies

Is it possible to enable two bodies connected by a joint to still collide with one another? By default, it appears that collisions between bodies connected by a joint are disabled.

Here’s my use case. Suppose I have two non-overlapping bodies connected by a pivot joint between them. (See note below about overlapping/non-overlapping bodies.) Without the joint, these objects will collide. With the joint, they won’t. I’ve put some very basic sample code at the bottom of this post illustrating the point.

Box2D has a boolean property for joints called collideConnected (see second paragraph of section 8.2 at http://www.box2d.org/manual.html) which allows bodies connected by a joint to still collide with each other. Does Corona expose this property? It would address my use case, but I haven’t been able to find it.

If not, what workarounds are there? I can think of three:

  • Collision filters: Unfortunately, as far as I can tell, this doesn’t work. Once the joint is created, it disables collisions between the bodies, regardless of their collision filters. Since a body’s collision filter can’t be changed after the body is created, there’s no way to reinstate the collision filter settings between them after the joint is created.
  • Rotation limits: I could just set the rotation limits of the pivot joint so that the objects can’t rotate into one another. Essentially, the rotation limit prevents the collision between the bodies instead of the usual collision detection. This would work well enough for simple bodies like squares, but for more complex, polygon bodies, calculating the right rotation limits is more complicated and therefore not ideal. Also, collision detection events wouldn’t fire.
  • "Shadow" bodies: Each body could actually consist of two identical, overlapping bodies welded together. One piece would be visible, and it would joined to the other object’s visible piece. Because of the joint, these pieces won’t collide with each other. However, each body would also have a second, invisible “shadow”. The shadow would be welded to the visible piece, but since it wouldn’t be joined to any other object, the shadow will collide with the other object’s shadow, and the visible pieces will appear to collide as well because the shadow is welded to them. This solution works (see sample code below), but it’s a bit cumbersome.

Any other simpler solutions?

[lua]-- This file is used for testing aspects of the Corona SDK

require(“physics”)

physics.start()

local shadowEnabled = false

– Create a ground
ground = display.newRect(0,400,320,410)
physics.addBody(ground, “static”, {density = 3, friction=5, bounce=0.3} )

– Create a 20x20 pixel square with upper-left corner at (100,100)
obj1 = display.newRect(100,100,20,20)

– Create another 20x20 pixel square with upper-left corner at (122,122), i.e. just below and to the right of the first square
obj2 = display.newRect(122,122,20,20)

– Add both bodies to physics and join them by a freely rotating pivot joint directly in between the cornerns
physics.addBody(obj1, “dynamic”, {density = 3, friction=5, bounce=0.3} )
physics.addBody(obj2, “dynamic”, {density = 3, friction=5, bounce=0.3} )
physics.newJoint(“pivot”, obj1, obj2, 121, 121)

if shadowEnabled == true then
obj1.shadow = display.newRect(100,100,20,20)
obj2.shadow = display.newRect(122,122,20,20)
physics.addBody(obj1.shadow, “dynamic”, {density = 3, friction=5, bounce=0.3} )
physics.newJoint(“weld”, obj1, obj1.shadow, obj1.x, obj1.y)
physics.addBody(obj2.shadow, “dynamic”, {density = 3, friction=5, bounce=0.3} )
physics.newJoint(“weld”, obj2, obj2.shadow, obj2.x, obj2.y)
end[/lua]

Note: Although pivot joints are most commonly used to represent an axle-style pivot at a point of overlap between two bodies, and the Physics Joints reference at http://developer.anscamobile.com/content/game-edition-physics-joints suggests that pivot joints should be placed where the bodies overlap, this isn’t actually a requirement. Pivot joints work just fine if the pivot point happens to be outside one or both bodies. This is consistent with the behavior and documentation of Box2D [import]uid: 109711 topic_id: 19468 reply_id: 319468[/import]

I’ve been using the “shadow joint” approach to be able to switch friction coefficients so the object slides easily when the user is touch-jointing it, but settles and stays put like a ramp or ladder when released. I’m curious to see what others’ advice for your problem is, and wish I knew more to help you. [import]uid: 63787 topic_id: 19468 reply_id: 131181[/import]

Thanks mightyenigma. I actually did end up using what I called the “shadow” body approach, and it worked out fine. I also use a technique like what you describe to effectively lower the friction of an object when it is being touched.

  • Andrew [import]uid: 109711 topic_id: 19468 reply_id: 131183[/import]

I’ve been using the “shadow joint” approach to be able to switch friction coefficients so the object slides easily when the user is touch-jointing it, but settles and stays put like a ramp or ladder when released. I’m curious to see what others’ advice for your problem is, and wish I knew more to help you. [import]uid: 63787 topic_id: 19468 reply_id: 131181[/import]

Thanks mightyenigma. I actually did end up using what I called the “shadow” body approach, and it worked out fine. I also use a technique like what you describe to effectively lower the friction of an object when it is being touched.

  • Andrew [import]uid: 109711 topic_id: 19468 reply_id: 131183[/import]