Point to Point Chaining Question

stelly
Posts: 3
Joined: Thu Jan 31, 2013 9:17 am

Point to Point Chaining Question

Post by stelly »

Hello everybody,

I have a question about point to point constraints. I am trying to create a series of stick bodies connected with ball joints, such that when I run the simulation they will droop (due to gravity) but retain their rigid shape (this is unlike a soft body situation where the bodies can elongate). In the example below I am making a series of five sticks 4x1x1 units each and spaced by 1 unit in between. The first one is fixed by zero mass. Then I create p2p joints at the middle of their intervals. The manual and demos show that the constraint point needs to be in local coordinates within each body so, if my sticks are 4 units centered about 0,0,0 then +/-2.5 should be 0.5 units off. The behavior I get is quite bizarre see this video http://youtu.be/pGHIKNExqdg. So the question is: what am I doing so wrong here? Thanks in advance and sorry for the bad C# code below

Code: Select all

world.Gravity = new Vec3D( 0, 0, -10 );

int count = 5;
for( int index = 0; index < count; index++ )
{
  AddBox( 2 + index * 5, 0, 0, 4, 1, 1, index ); 
}
        
for( int index = 1; index < count; index++ )
{
  world.AddConstraint(
    new Point2PointConstraint(  
       bodies[index - 1],  
       bodies[index - 0], 
       new Vec3D(  2.5f, 0, 0 ), 
       new Vec3D( -2.5f, 0, 0 ) ) );
}

where: AddBox is simiar to localCreateRigidBody in the demos (the first three params are translations tx, ty, tz, the following three are the dimensions dx, dy, dz and the last is the mass)
stelly
Posts: 3
Joined: Thu Jan 31, 2013 9:17 am

Re: Point to Point Chaining Question

Post by stelly »

This has been driving me nuts. I don't understand how constraints are supposed to be set up. It seems simple in principle: connect two boxes by their sides

Code: Select all

        var b1 = AddBox( 0, 0, 0, 4, 1, 1, 1 );
        var j1 = new Point2PointConstraint( b1, new Vec3D( 0, 0, 0 ) );
        world.AddConstraint( j1 );

        var b2 = AddBox( 8, 0, 0, 4, 1, 1, 1 );
        var j2 = new Point2PointConstraint( b1, b2, new Vec3D( 2, 0, 0 ), new Vec3D( -2, 0, 0 ) );
        world.AddConstraint( j2 );
Image

Any ideas how to set a side to side distance constraint or better an axial constraint as in the diagram?
anthrax11
Posts: 72
Joined: Wed Feb 24, 2010 9:49 pm

Re: Point to Point Chaining Question

Post by anthrax11 »

Point2PointConstraint maintains the distance between two anchor points, but the bodies are still free to pivot around those points.

A hinge constraint with angles limited to 0 would work, which looks something like this:

Code: Select all

        var j2 = new HingeConstraint( b1, b2, Matrix.Translation( 2, 0, 0 ), Matrix.Translation( -2, 0, 0 ) );
        j2.SetLimit(0, 0);
Also, if you set the mass of the first body to 0, then it can't pivot or move at all. Instead, you can give the body some mass and anchor it to the world with a p2p constraint.

Code: Select all

        var j3 = new Point2PointConstraint( b1, new Vec3D( 0, 0, 0 ) );
stelly
Posts: 3
Joined: Thu Jan 31, 2013 9:17 am

Re: Point to Point Chaining Question [SOLVED]

Post by stelly »

Thank you anthrax. I managed to make it work (in C++), need to test if it is a bullet# issue. But here is how for people that may have similar issues (paste the code below into the basic demo initPhysics).

In my original code was using setOrigin(translation) onto the body matrices m1, and m2 (after setIdentity) to set the objects in the desired world positions. It seems that this doesn't work for some reason. Any ideas why? When I used body->translate( ) it worked as expected!!!


Code: Select all

	btTransform m1;
	m1.setIdentity( );

		btBoxShape* s1 = new btBoxShape( btVector3( 4, 1, 1 ) );
		m_collisionShapes.push_back( s1 );

		btVector3 i1(0,0,0);
     	s1->calculateLocalInertia( 1, i1 );

		btDefaultMotionState* t1 = new btDefaultMotionState( m1 );
		btRigidBody::btRigidBodyConstructionInfo r1( 1, t1, s1, i1 );
		btRigidBody* b1 = new btRigidBody( r1 );
					
		b1->setDamping(0.5f,0.5f);

		btVector3 o1( 0, 20,-30);
		b1->translate(o1);

		m_dynamicsWorld->addRigidBody( b1 );	




		btTransform m2;
		m2.setIdentity( );
	   
		btBoxShape* s2 = new btBoxShape( btVector3( 4, 1, 1 ) );
		m_collisionShapes.push_back( s2 );

		btVector3 i2(0,0,0);
     	s2->calculateLocalInertia( 1, i2 );

		btDefaultMotionState* t2 = new btDefaultMotionState( m2 );
		btRigidBody::btRigidBodyConstructionInfo r2( 1, t2, s2, i2 );
		btRigidBody* b2 = new btRigidBody( r2 );
				
		b2->setDamping(0.5f,0.5f);

		btVector3 o2(-10, 20,-30);
		b2->translate(o2);

		m_dynamicsWorld->addRigidBody( b2 );	



		btVector3 p1( 0, 0, 0);
		btPoint2PointConstraint* c1 = new btPoint2PointConstraint( *b1, p1 );
		m_dynamicsWorld->addConstraint(c1,false);

	    btVector3 x1(  5, 0, 0 );
	    btVector3 x2( -5, 0, 0 );
		btPoint2PointConstraint* c2 = new btPoint2PointConstraint( *b1, *b2, x1, x2 );
		m_dynamicsWorld->addConstraint(c2,true);