Page 1 of 1

body:getContacts() returns contacts for bodies that do not touch?

Posted: Wed Aug 16, 2023 6:32 pm
by knorke
I seem to have a problem with contacts in box2d physics.
body:getContacts() returns contacts for bodies that are close but not touching.
A contact is returned when the distance between them is still roughly half their size.
I tried circleShapes and polygonShapes.
world:getContactList() seems to work correctly.

I created a minimal example to explain my question:

In the attached .love file press left/right arrowkeys to spawn balls that will move towards center of the screen.
Contacts are drawn as red squares:

Code: Select all

	--draw contacts
	lg.setColor(255,0,0,255)
	local contacts = world:getContactList()
	for i=1,#contacts do
		local x1,y1,x2,y2 = contacts[i]:getPositions()
		if (x1) then
			lg.circle ("fill",x1,y1,6,4)
		end
		if (x2) then
			lg.circle ("fill",x2,y2,6,4)
		end
	end
Also, on each ball a number is printed. It shows the number of contacts of this body:

Code: Select all

local contacts = body:getContacts()
local x,y=body:getPosition()
lg.setColor (0,0,0,0.5)
lg.rectangle ("fill",x,y,10,10) --background for visibility
lg.setColor (1,1,1,1)
lg.print (#contacts, body:getPosition() )
Between the green&blue balls there is a contact and it is drawn correctly as red square.
Other balls show a number of contacts higher than zero but they are not touching.
contacts.png
contacts.png (6.35 KiB) Viewed 811 times

Re: body:getContacts() returns contacts for bodies that do not touch?

Posted: Wed Aug 16, 2023 7:10 pm
by knorke
Hello there
In the box2D docu I found:
http://www.iforce2d.net/b2dtut/collision-anatomy
A very important point to note if you do this, is that the existence of a contact in these lists does not mean that the two fixtures of the contact are actually touching - it only means their AABBs are touching.
If you want to know if the fixtures themselves are really touching you can use IsTouching() to check.
That is unexpected but okay. I added the extra check like this:

Code: Select all

if bodyA:isTouching(bodyB) then
According to the Box2D wiki these lists should both return contacts in the same AABB-style:
world->GetContactList()
body->GetContactList()
But in Love2D they return different things?
world:getContactList() = actual, really touching contacts.
body:getContacts() = AABB-style.