This is kind of a follow-up on a previous I did:
http://www.jmonkeyengine.com/jmeforum/index.php?topic=7933.0
I was able to solve that issue by using slerp, however; I'm having trouble finding out the angle between where a node is pointed and a location to where it wants to go. There are a couple threads on this already:
http://www.jmonkeyengine.com/jmeforum/index.php?topic=6383.0
…but I must be doing something wrong.
What I'd like is to always have where the ship is facing to be zero degrees, and increase to 360 clockwise around it. This is to support implementing a ship lean function that I have. If the angle is from 0-180, lean right. If it's from 180-360, lean left. This is what I have so far, and for some reason it's not giving me the angles that I'm expecting. the onButton is where I'm doing the angle calculation.
import com.jme.image.Texture;
import com.jme.input.AbsoluteMouse;
import com.jme.input.InputHandler;
import com.jme.input.MouseInputListener;
import com.jme.math.FastMath;
import com.jme.math.Matrix3f;
import com.jme.math.Plane;
import com.jme.math.Quaternion;
import com.jme.math.Ray;
import com.jme.math.Triangle;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.scene.Controller;
import com.jme.scene.Node;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
public class MouseClickMove implements MouseInputListener {
protected static DriftAction drift;
protected Ship ship = proto.getShip();
protected Ship enemy = proto.getEnemy();
protected Node scene = proto.getScene();
protected InputHandler input = proto.getInput();
protected AbsoluteMouse am;
protected shipMoveController shipMove;
protected float modifier;
public void initializeMouseMove() {
setupMouse();
shipMove = new shipMoveController(ship);
shipMove.setSpeed(ship.getVelocity());
ship.addController(shipMove);
}
private void setupMouse() {
// mouse stuff
// Create a new mouse. Restrict its movements to the display screen.
am = new AbsoluteMouse("The Mouse", DisplaySystem.getDisplaySystem()
.getWidth(), DisplaySystem.getDisplaySystem().getHeight());
// Get a picture for my mouse.
final TextureState mCursor = DisplaySystem.getDisplaySystem()
.getRenderer().createTextureState();
final URL cursorLoc = CakeProto.class.getClassLoader().getResource(
"jmetest/data/cursor/cursor1.png");
final Texture t = TextureManager.loadTexture(cursorLoc,
Texture.MM_LINEAR, Texture.FM_LINEAR);
mCursor.setTexture(t);
am.setRenderState(mCursor);
// Make the mouse's background blend with what's already there
final AlphaState as = DisplaySystem.getDisplaySystem().getRenderer()
.createAlphaState();
as.setBlendEnabled(true);
as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
as.setTestEnabled(true);
as.setTestFunction(AlphaState.TF_GREATER);
am.setRenderState(as);
// Get the mouse input device and assign it to the AbsoluteMouse
// Move the mouse to the middle of the screen to start with
am.setLocalTranslation(new Vector3f(DisplaySystem.getDisplaySystem()
.getWidth() / 2,
DisplaySystem.getDisplaySystem().getHeight() / 2, 0));
// Assign the mouse to an input handler
am.registerWithInputHandler(input);
// Attach Children
scene.attachChild(am);
}
@Override
public void onButton(final int button, final boolean pressed, final int x,
final int y) {
final int isPressed = button;
// System.out.println("focus is " + InGameUI2.isFocus());
if ((isPressed == 0) && (InGameUI.isFocus() == false)) {
final Plane p1 = new Plane();
final Vector3f t1a = new Vector3f(0, 0, 0); // point a on Triangle
// 1;
final Vector3f t1b = new Vector3f(1, 0, 0); // point b on Triangle
// 1;
final Vector3f t1c = new Vector3f(0, 0, 1); // point c on Triangle
// 1;
final Triangle t1 = new Triangle(t1a, t1b, t1c);
p1.setPlanePoints(t1);
final Vector2f screenPos = new Vector2f();
// Get the position that the mouse is pointing to
screenPos.set(am.getHotSpotPosition().x, am.getHotSpotPosition().y);
// Get the world location of that X,Y value
final Vector3f worldCoords = DisplaySystem.getDisplaySystem()
.getWorldCoordinates(screenPos, 0);
final Vector3f worldCoords2 = DisplaySystem.getDisplaySystem()
.getWorldCoordinates(screenPos, 1);
final Vector3f direction = worldCoords2.subtractLocal(worldCoords)
.normalizeLocal();
final Vector3f loc1 = new Vector3f();
final Ray mouseRay = new Ray(worldCoords, direction);
final boolean intersection1 = mouseRay.intersectsWherePlane(p1,
loc1);
Vector3f shipDirection = ship.getWorldRotation().getRotationColumn(2);
//direction.normalizeLocal();
Vector3f toDirection = direction.subtract(ship.getWorldTranslation());
toDirection.normalizeLocal();
shipDirection.cross( toDirection, Vector3f.UNIT_Y );
Vector3f.UNIT_Y.normalizeLocal();
float rotationAngle = FastMath.RAD_TO_DEG*(shipDirection.angleBetween(toDirection));
if (rotationAngle > 0 && rotationAngle < 180) {
//lean right
modifier = 1;
} else if (rotationAngle > 180 && rotationAngle < 359) {
//lean left
modifier = -1;
} else {
modifier = 0;
}
System.out.println(rotationAngle);
if (intersection1) {
shipMove.setDesiredLocation(loc1, modifier);
}
drift = new DriftAction(ship);
} else {
return;
}
}
@Override
public void onMove(final int delta, final int delta2, final int newX,
final int newY) {
// TODO Auto-generated method stub
}
@Override
public void onWheel(final int wheelDelta, final int x, final int y) {
// TODO Auto-generated method stub
}
private static class shipMoveController extends Controller {
private static final long serialVersionUID = 1L;
private final Ship ship;
private Vector3f desiredLocation;
private boolean moving;
private float modifier;
private final Vector3f upAxis = new Vector3f(0, 1, 0);
private final Vector3f temp = new Vector3f();
public shipMoveController(final Ship ship) {
this.ship = ship;
}
public void setDesiredLocation(final Vector3f location, float modifier) {
this.desiredLocation = location;
this.modifier = modifier;
this.moving = true;
}
public Vector3f getDesiredLocation() {
return desiredLocation;
}
@Override
public void update(final float time) {
if (!moving) {
return;
}
final Vector3f directional = desiredLocation.subtract(ship
.getLocalTranslation(), temp);
//directional.normalize();
final float length = directional.length();
if (length < 5) { // if it's around x units
ship.deccelerate(time);
moving = false;
return;
}
float shipFlyDistance = ship.getVelocity() * time;
if (shipFlyDistance > length) {
shipFlyDistance = length;
}
directional.multLocal(shipFlyDistance / length);
ship.accelerate(time);
ship.updateWorldVectors();
Quaternion start = new Quaternion(ship.getLocalRotation());
ship.getLocalRotation().lookAt(directional, upAxis);
ship.getLocalRotation().slerp(start, 0.99f);
ship.getLocalTranslation().addLocal(directional);
ship.setRotateOn(modifier);
}
}
}