Page 1 of 1

Assert possibly related to cpBodySleep?

Posted: Fri Jan 24, 2014 7:08 pm
by KeithZ
I'm running into the following assert:

Aborting due to Chipmunk error: Internal Error: Dangling contact graph pointers detected. (A)
Failed condition: cpArbiterThreadForBody(arb, body)->next == NULL
Source:..\..\External\Chipmunk\Chipmunk\src\cpSpaceComponent.c:176

It only happens when I put a body to sleep and another body collides with the sleeping body. I'm using cpBodySleep because I want to add all of my objects into the world in a sleeping state. Below is a sample that reproduces the problem for me in Chipmunk 6.2.1.

Code: Select all

void SleepTest()
{
	cpSpace* space = cpSpaceNew();

	const float mass = 10.0f;
	const float radius = 1.0f;

	cpBody* body1 = cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero));
	cpShape* shape1 = cpCircleShapeNew(body1, radius, cpvzero);

	cpBody* body2 = cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero));
	cpShape* shape2 = cpCircleShapeNew(body2, radius, cpvzero);

	cpBodySetPos(body1, cpv(5.0f, 0.0f));
	cpSpaceAddBody(space, body1);
	cpSpaceAddShape(space, shape1);
	cpBodySleep(body1);

	cpBodySetPos(body2, cpv(0.0f, 0.0f));
	cpSpaceAddBody(space, body2);
	cpSpaceAddShape(space, shape2);
	cpBodySleep(body2);

	cpBodySetVel(body1, cpv(-5.0f, 0.0f));

	const float dt = 1.0f / 30.0f;
	float simTime = 0.0f;
	while (simTime < 5.0f)
	{
		cpSpaceStep(space, dt);
		simTime += dt;
	}

	cpSpaceRemoveShape(space, shape1);
	cpSpaceRemoveBody(space, body1);
	cpShapeFree(shape1);
	cpBodyFree(body1);

	cpSpaceRemoveShape(space, shape2);
	cpSpaceRemoveBody(space, body2);
	cpShapeFree(shape2);
	cpBodyFree(body2);

	cpSpaceFree(space);
}
Am I running into a bug or am I doing something incorrect?

Re: Assert possibly related to cpBodySleep?

Posted: Fri Jan 31, 2014 5:08 pm
by slembcke
Ah. I stared at this for like two hours before I figured it out so it's definitely not obvious.

Chipmunk's sleeping features are disabled until you (implicitly) enable them by setting a sleep time threshold. The code that wakes bodies up on contact is disabled (amongst other things) for a small performance boost when sleeping is disabled. That's ultimately what's causing the assertion to trigger.

I'll add an assertion in cpBodySleep() to check that sleeping is enabled in the space too.

Re: Assert possibly related to cpBodySleep?

Posted: Fri Jan 31, 2014 6:53 pm
by KeithZ
Thank you! That removed the assert.

I did see this line in the documentation:
The second is that you must enable sleeping explicitly by choosing a time threshold value for cpSpace.sleepTimeThreshold. If you do not set cpSpace.idleSpeedThreshold explicitly, a value will be chosen automatically based on the current amount of gravity.
But I mixed up sleepTimeThreshold with idleSpeedThreshold and took it to mean that if I didn't set sleepTimeThreshold it would pick a value automatically based on gravity.

Thanks again for the help!