locking movement to a plane

Post Reply
pfanne
Posts: 7
Joined: Fri Dec 02, 2011 10:21 am

locking movement to a plane

Post 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.
User avatar
dphil
Posts: 237
Joined: Tue Jun 29, 2010 10:27 pm
Contact:

Re: locking movement to a plane

Post 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.
User avatar
Dr.Shepherd
Posts: 168
Joined: Tue Jan 04, 2011 11:47 pm
Contact:

Re: locking movement to a plane

Post 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));

pfanne
Posts: 7
Joined: Fri Dec 02, 2011 10:21 am

Re: locking movement to a plane

Post 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.
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: locking movement to a plane

Post 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.
Post Reply