How to properly rotate when applytorque is overrotating

I have a similar problem to the other thread, my UFO does tilts but I only want it to tilt a little and now it is overrotating.

[java] public void onAnalog(String name, float value, float tpf) {
int speed = 20000 * 80000;
if (name.equals(“rotateRight”) && rotate) {
ufoNode.rotate(0, 1 * tpf, 0);
}
if (name.equals(“rotateLeft”) && rotate) {
ufoNode.rotate(0, -1 * tpf, 0);
}
if (name.equals(“rotateUp”) && rotate) {
ufoNode.rotate(0, 0, -1 * tpf);
}
if (name.equals(“rotateDown”) && rotate) {
ufoNode.rotate(0, 0, 1 * tpf);
}
Vector3f camDir = cam.getDirection().clone().multLocal(speed * tpf);
Vector3f camUp = cam.getUp().clone().mult(speed * tpf);
camDir.y = 0;
ufoDirection.set(0, 0, 0);
Vector3f xRotation = ufoControl.getPhysicsRotation()
.getRotationColumn(0).normalize();
Vector3f yRotation = ufoControl.getPhysicsRotation()
.getRotationColumn(1).normalize();
Vector3f zRotation = ufoControl.getPhysicsRotation()
.getRotationColumn(2).normalize();
Vector3f rotate = new Vector3f();
if (name.equals(“moveLeft”)) {
ufoDirection.set(cam.getLeft().multLocal(speed * tpf));
if (ufoControl.getAngularVelocity().getZ() < 0.2f) {
// ufoControl.applyTorque(zRotation.mult(speed));
} else // if (ufoControl.getAngularVelocity().getZ() >- 0.2f)
{
// ufoControl.applyTorque(zRotation.mult(2peed).negate());
}
}
if (name.equals(“moveRight”)) {
ufoDirection.set(cam.getLeft()).multLocal(-speed * tpf);
// ufoControl.applyTorque(zRotation.mult(speed).negate());
}
if (name.equals(“moveForward”)) {
ufoDirection.set(camDir);
}
if (name.equals(“moveBackward”)) {
ufoDirection.set(camDir.multLocal(-1f));
}
if (name.equals(“moveUp”)) {
ufoDirection.addLocal(camUp);
}
if (name.equals(“moveDown”)) {
ufoDirection.addLocal(cam.getUp().multLocal(-speed * tpf));
}
ufoControl.applyCentralForce(ufoDirection);
}[/java]

If I use applyTorque, then I don’t have a good way of slowing the rotation when keeping moving left for instance. I tried making a custom control but the prephysicstick method is not called, why not?
[java]
public class UFOBodyControl extends RigidBodyControl implements
PhysicsTickListener {

public UFOBodyControl() {
	super();
	// bulletAppState.getPhysicsSpace().addCollisionListener(this);
}

public UFOBodyControl(CollisionShape shape) {
	super(shape);
}

public UFOBodyControl(CollisionShape shape, float mass) {
	super(shape, mass);
}

public UFOBodyControl(CylinderCollisionShape shape, float f) {
	super(shape, f);
	System.out.println("UFOBodyControl");
}

@Override
public void prePhysicsTick(PhysicsSpace space, float tpf) {
	// apply state changes ...
	System.out.println("prePhysicsTick" + this.getAngularVelocity());
	setAngularVelocity(Vector3f.ZERO);
}

@Override
public void physicsTick(PhysicsSpace arg0, float arg1) {
	// TODO Auto-generated method stub
	System.out.println("physicsTick" + this.getAngularVelocity());

}

}
[/java]

How can I control the spaceship from overrotating?

prePhysicsTick isn’t called until after you invoke physicsSpace.addTickListener().

1 Like
@sgold said: prePhysicsTick isn't called until after you invoke physicsSpace.addTickListener().

Ok, I put it in the onAction method, then it runs:
[java]
public void onAction(String name, boolean keyPressed, float tpf) {
getPhysicsSpace().addTickListener(ufoControl);
[/java]

And the control has a space in the contructor now

[java]
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.collision.shapes.CylinderCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.math.Vector3f;

public class UFOBodyControl extends RigidBodyControl implements
PhysicsCollisionListener, PhysicsTickListener {

private int health = 10;

public void setPhysicsSpace(PhysicsSpace space) {
	super.setPhysicsSpace(space);
	if (space != null) {
		space.addCollisionListener(this);
	}
}

public int getHealth() {
	return health;
}

public void setHealth(int health) {
	this.health = health;
}

public void damage() {
	health = health--;
	System.out.println("health " + health);
}

public UFOBodyControl() {
	super();
	// bulletAppState.getPhysicsSpace().addCollisionListener(this);
}

public UFOBodyControl(CollisionShape shape) {
	super(shape);
}

public UFOBodyControl(CollisionShape shape, float mass) {
	super(shape, mass);
}

public UFOBodyControl(CylinderCollisionShape shape, float f,
		PhysicsSpace space) {
	super(shape, f);
	System.out.println("UFOBodyControl");
	setPhysicsSpace(space);
	getPhysicsSpace().addCollisionListener(this);
}

@Override
public void prePhysicsTick(PhysicsSpace space, float tpf) {
	// apply state changes ...
	// System.out.println("UFO prePhysicsTick" + this.getAngularVelocity());
	setAngularVelocity(Vector3f.ZERO);
}

/*
 * public void prePhysicsTick(PhysicsSpace space, float f) {
 * System.out.println("UFO PhysicsSpace"); }
 */

@Override
public void physicsTick(PhysicsSpace arg0, float arg1) {
	// TODO Auto-generated method stub
	// System.out.println("physicsTick" + this.getAngularVelocity());

}

@Override
public void collision(PhysicsCollisionEvent arg0) {
	// TODO Auto-generated method stub
	System.out.println("collision damage");
	this.damage();
}

}

[/java]
And I’m working on the rotation when the spacecraft moves now getting better results.

[java]public void onAnalog(String name, float value, float tpf) {
int speed = 20000 * 80000;
// FIXME: the rotation depends on the vehicle position
if (name.equals(“rotateRight”) && rotate) {
ufoNode.rotate(0, 1 * tpf, 0);
}
if (name.equals(“rotateLeft”) && rotate) {
ufoNode.rotate(0, -1 * tpf, 0);
}
if (name.equals(“rotateUp”) && rotate) {
ufoNode.rotate(0, 0, -1 * tpf);
}
if (name.equals(“rotateDown”) && rotate) {
ufoNode.rotate(0, 0, 1 * tpf);
}
Vector3f camDir = cam.getDirection().clone().multLocal(speed * tpf);
Vector3f camUp = cam.getUp().clone().mult(speed * tpf);
camDir.y = 0;
ufoDirection.set(0, 0, 0);
Vector3f xRotation = ufoControl.getPhysicsRotation()
.getRotationColumn(0).normalize();
Vector3f yRotation = ufoControl.getPhysicsRotation()
.getRotationColumn(1).normalize();
Vector3f zRotation = ufoControl.getPhysicsRotation()
.getRotationColumn(2).normalize();
Vector3f rotate = new Vector3f();
// System.out.println(“x” +xRotation+“y” +yRotation+“z” +zRotation);
if (name.equals(“moveLeft”)) {
ufoDirection.set(cam.getLeft().multLocal(speed * tpf));
// FIXME: the rolling rolls too much
if (ufoControl.getAngularVelocity().getZ() < 0.2f
&& yRotation.getY() > 0.88f) {
ufoControl.applyTorque(zRotation.mult(speed));
} else // if (ufoControl.getAngularVelocity().getZ() >- 0.2f)
{
// ufoControl.applyTorque(zRotation.mult(2peed).negate());
}
}
if (name.equals(“moveRight”)) {

		// ufoDirection.set(cam.getLeft().multLocal(speed * tpf));
		// FIXME: the rolling rolls too much
		// if (ufoControl.getAngularVelocity().getZ() &lt; 0.2f
		// &amp;&amp; yRotation.getY() &gt; 0.88f) {
		ufoControl.applyTorque(zRotation.mult(speed).negate());

		ufoDirection.set(cam.getLeft()).multLocal(-speed * tpf);
		// ufoControl.applyTorque(zRotation.mult(speed).negate());
	}
	if (name.equals("moveForward")) {
		ufoDirection.set(camDir);
	}
	if (name.equals("moveBackward")) {
		ufoDirection.set(camDir.multLocal(-1f));
	}
	if (name.equals("moveUp")) {
		ufoDirection.addLocal(camUp);
	}
	if (name.equals("moveDown")) {
		ufoDirection.addLocal(cam.getUp().multLocal(-speed * tpf));
	}
	if (name.equals("halt")) {
		System.out.println("22 HALT");
		ufoControl.clearForces();
		ufoControl.setLinearVelocity(Vector3f.ZERO);
		ufoControl.setAngularVelocity(Vector3f.ZERO);
	} else
		ufoControl.applyCentralForce(ufoDirection);
}

[/java]

[video]- YouTube