Page 1 of 1

locking movement to a plane

Posted: Wed Dec 07, 2011 1:39 pm
by pfanne
I know that locking to the movement along the standard axis can be done with setLinearFactor,
But i want to lock the movement along an arbitrary plane.
I thought I could solve this by using the generic6dof constraint, but I can't figure out how to do it.
Read quite a few other threads, but anything I tried resulted in really weird behaviour.
Anybody out there able to help with this?

Thanks in advance.

Re: locking movement to a plane

Posted: Thu Dec 08, 2011 12:35 am
by dphil
I imagine you could perhaps intercept the total force to be applied on a body at each time step, project its vector onto the plane of interest, and then let Bullet continue using that projection as the force to be applied. The code would be quite simple, though offhand I'm not sure where you would inject such code.

Re: locking movement to a plane

Posted: Thu Dec 08, 2011 9:57 am
by Dr.Shepherd
I think if you still want to try Generic Constraint, you have to set up like this:

Code: Select all

		pGen6DOF->setLinearLowerLimit(btVector3(-1000., -1000., 0.));
		pGen6DOF->setLinearUpperLimit(btVector3(1000., 1000., 0.));
The code means your constraints are limited into a large flat bounding box, which can be viewed as a plane.

Also you may need to play around the angular limits to achieve what you exactly want:

Code: Select all

		pGen6DOF->setAngularLowerLimit(btVector3(-SIMD_HALF_PI * 0.5f, -0.75, -SIMD_HALF_PI * 0.8f));
		pGen6DOF->setAngularUpperLimit(btVector3(SIMD_HALF_PI * 0.5f, 0.75, SIMD_HALF_PI * 0.8f));


Re: locking movement to a plane

Posted: Wed Feb 22, 2012 7:28 pm
by pfanne
my main problem is, that i dont really have a second body and i dont know how to configure the frames (i have an idea what they are good for, but i dont know how to use them).
for now i solved the problem by manually resetting the position of the character to the plain, but this results in jittery movement and random jumps.
help with this issue would be greatly appreciated.

Re: locking movement to a plane

Posted: Thu Feb 23, 2012 12:35 pm
by Flix
pfanne wrote:my main problem is, that i dont really have a second body and i dont know how to configure the frames
Well, you can use a static dummy body for this.
The following is a generic code (you will need to modify it to fit your needs):

Code: Select all

static btRigidBody staticBody(0,NULL,NULL);
staticBody.setWorldTransform(btTransform::getIdentity());//No need to add it to the world
btTransform localA,localB;
localA.setIdentity(); localB.setIdentity();
// Now you should set their basis so that your plane normal ends on the X-axis (or on the Z-axis).

// The following should work if your plane normal is the Y axis (and we move it to the X axis): change it accordingly:
btQuaternion q(btVector3(0,0,1),SIMD_HALF_PI);	// If we need a full 360 rotation around Y, Y is limited in [-PI/2,PI/2] AFAIK, so we swap Y with X ( newY = X; newX = -Y )

localA.getBasis().setRotation(q);
localB.getBasis()=localA.getBasis();
			
btGeneric6DofConstraint *joint6DOF =  new btGeneric6DofConstraint (staticBody, *my_body, localA, localB, true);

// Now the limits depend on what you want to do:

// Free translation allowed in this case:
joint6DOF->setLinearLowerLimit(btVector3(1,1,1));	
joint6DOF->setLinearUpperLimit(btVector3(-1,-1,-1));

// This will force the body to be aligned with the Y axis (or your plane normal axis) like setAngularFactor(0,1,0):
joint6DOF->setAngularLowerLimit(btVector3(1,0,0));	// Axis 0 = Y axis now
joint6DOF->setAngularUpperLimit(btVector3(0,0,0));

m_dynamicsWorld->addConstraint(joint6DOF,true);
I don't know how to calculate the quaternion from your normal to the X axis right now... but please note that you only need it if you want to allow the body to rotate seamlessly around your plane normal and lock the other axis (i.e. if you want to replace setAngularFactor(...)). Otherwise you can probably align your normal to any of the three axis, as you like.