i searched for topics about applying force to smoothly eliminate sideways movement, but unsuccesful. i came with this solution
[java]
// Compensate drifting
if(movementControl) {
// Apply linear force (smoothly cancel sideways movement)
if(getLinearVelocity().length() > 0.5f) {
Vector3f nVel = getLinearVelocity().normalize();
Vector3f nDir = getPhysicsRotation().mult(Vector3f.UNIT_Z).normalize();
if(nVel.angleBetween(nDir) > 0.03f && nVel.negate().angleBetween(nDir) > 0.03f) {
applyCentralForce(nDir.subtract(nVel).mult(mass * movementPower * tpf * 0.7f));
}
}
}
[/java]
it does almost what i want, it half-succesfully cancels sideways movement up down left right, more accurately it transforms it into forward movement slightly and it have some problems with reversing. is here any code snippet for this? 
i used angular damping for cancelling rotation but i cant use linear damping because i want forward and backward vector untouched
thanks ascaria
First, any time you find yourself doing angleBetween() it’s almost always wrong. Here is a prime example where a dot product would have worked just as well. For example, nVel.dot(dir) will be 1.0 when they are parallel and 0 when they are 90 degrees.
…but it sounds like what you really want is to cancel non-forward velocity. In that case, it might be better to figure out what the non-forward velocity is and then apply a counter impulse. In other words, I think if you find out how much forward velocity you actually have (nVel.dot(nDir)) then you should be able to subtract that from nVel and what you are left with is the non-forward velocity. You should be left with a vector only in the xy plane of the object because all “z” has been removed.
Then apply a force or impulse in the opposite direction.
I’ve never done it with bullet but that’s the math off the top of my head.
Edit: by “subtract that from nVel” I mean:
float fwdSpeed = nVel.dot(nDir);
Vector3f nonFwdVel = nVel.subtract(nDir.mult(fwdSpeed));
2 Likes
works like charm
thanks very much 
[java]
// Compensate drifting
if(movementControl) {
// Apply linear force (smoothly cancel sideways movement)
if(getLinearVelocity().length() > 0.5f) {
Vector3f nVel = getLinearVelocity().normalize();
Vector3f nDir = getPhysicsRotation().mult(Vector3f.UNIT_Z).normalize();
/*
if(nVel.angleBetween(nDir) > 0.03f && nVel.negate().angleBetween(nDir) > 0.03f) {
applyCentralForce(nDir.subtract(nVel).mult(mass * movementPower * tpf * 0.7f));
}
*/
Vector3f nonFwdVel = nVel.subtract(nDir.mult(nVel.dot(nDir))).negateLocal();
applyCentralForce(nonFwdVel.mult(mass * movementPower * tpf * 0.7f));
}
}
[/java]
hello,
some addition to my topic…
i found this answer very useful http://answers.unity3d.com/questions/32551/how-do-i-obtain-the-local-velocity-of-a-rigid-body.html
i constructed this preview
Vector3f localVelocity = rigidBody.getPhysicsRotation().inverse().mult(rigidBody.getLinearVelocity());
localVelocity.z = 0;
Vector3f worldNonFwdVelocity = rigidBody.getPhysicsRotation().mult(localVelocity).negate();
its greatly simplifying my needs
- i realized rigid body linear velocity is simply 3 values in 3 directions in world space (so it is already decomposed into 3 directions)
- i transformed it into local space, so every axis is now how much speed exist in every direction
- resetting z is only thing i need
- transforming back to worldNonFwdVelocity is common thing
5a) i can simple obtain non-fwd counter-momentum momentum.set(worldNonFwdVelocity).multLocal(rigidBody.getMass() / tpf);
(it is already negated)
5b) and also non-fwd counter-force linear.set(worldNonFwdVelocity).normalizeLocal().multLocal(enginesControl.getLinearAcceleration());
- then i can simply compensate drifting
// If the linear compensation is lower than the total momentum, but big enough to do some work
if(linear.lengthSquared() > 1f && linear.lengthSquared() < momentum.lengthSquared()) {
// Apply drifting resistance
linearCompensation.set(linear);
//System.out.println("compensating linear");
} else if(momentum.lengthSquared() > 0.00001f) {
// Apply counter momentum resistance, because linear compensation is too big or too small
linearCompensation.set(momentum);
//System.out.println("compensating momentum mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm");
}
return linearCompensation;
ps: applying counter-momentum is for preventing overshoot