Hi there folks
Cream's back, long time no see
So i returned to my AI project starting off with Mojos Vehicle Unit to use it as a base of what i am calling a Unit
More about that later.
This Unit will be a unit steered by AI and as there must be steering forces for something which should be steered i build up a class where i can steer a vehicle.
First the Code:
package com.basics.ai.controller;
import com.jme.math.*;
import com.jme.input.action.*;
import jmetest.flagrushtut.lesson6.Vehicle;
import jmetest.flagrushtut.lesson6.actions.DriftAction;
import com.basics.ai.exception.*;
public class AIController {
//the node to manipulate
private Vehicle node;
//temporary vector for the rotation
private static final Vector3f tempVa = new Vector3f();
/**
* The vehicle to accelerate is supplied during construction.
* @param vehicle the vehicle to speed up.
*/
public AIController(Vehicle node) {
this.node = node;
}
/**
* the action calls the vehicle's accelerate command which adjusts its velocity. It
* then translates the vehicle based on this new velocity value.
*/
public void performAccelerateAction(InputActionEvent evt) {
node.accelerate(evt.getTime());
Vector3f loc = node.getLocalTranslation();
loc.addLocal(node.getLocalRotation().getRotationColumn(2, tempVa)
.multLocal(node.getVelocity() * evt.getTime()));
node.setLocalTranslation(loc);
}
/**
* the action calls the vehicle's brake command which adjusts its velocity. It
* then translates the vehicle based on this new velocity value.
*/
public void performBrakeAction(InputActionEvent evt) {
node.brake(evt.getTime());
Vector3f loc = node.getLocalTranslation();
loc.addLocal(node.getLocalRotation().getRotationColumn(2, tempVa)
.multLocal(node.getVelocity() * evt.getTime()));
node.setLocalTranslation(loc);
}
/**
* the action calls the vehicle's drift command which adjusts its velocity. It
* then translates the vehicle based on this new velocity value.
*/
public void performDriftAction(InputActionEvent evt) {
node.drift(evt.getTime());
Vector3f loc = node.getLocalTranslation();
loc.addLocal(node.getLocalRotation().getRotationColumn(2, tempVa)
.multLocal(node.getVelocity() * evt.getTime()));
node.setLocalTranslation(loc);
}
//temporary variables to handle rotation
private static final Matrix3f incr = new Matrix3f();
private static final Matrix3f tempMa = new Matrix3f();
private static final Matrix3f tempMb = new Matrix3f();
//we are using +Y as our up
private Vector3f upAxis = new Vector3f(0, 1, 0);
private Vector3f rightAxis = new Vector3f(1, 0, 0);
private Vector3f depthAxis = new Vector3f(0, 0, 1);
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performRotateLeftAction(InputActionEvent evt) {
upAxis = node.getLocalRotation().getRotationColumn(1);
//we want to turn differently depending on which direction we are traveling in.
if (node.getVelocity() < 0) {
incr.fromAxisAngle(upAxis, -(node.getTurnSpeed() / 2) * evt.getTime());
} else {
incr.fromAxisAngle(upAxis, (node.getTurnSpeed() / 2) * evt.getTime());
}
node.getLocalRotation().fromRotationMatrix(
incr.mult(node.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
node.getLocalRotation().normalize();
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performRotateRightAction(InputActionEvent evt) {
upAxis = node.getLocalRotation().getRotationColumn(1);
if (node.getVelocity() < 0) {
incr.fromAxisAngle(upAxis, node.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(upAxis, -node.getTurnSpeed() * evt.getTime());
}
node.getLocalRotation().fromRotationMatrix(
incr.mult(node.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
node.getLocalRotation().normalize();
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performRollLeftAction(InputActionEvent evt) {
depthAxis = node.getLocalRotation().getRotationColumn(2);
//we want to turn differently depending on which direction we are traveling in.
if(node.getVelocity() < 0) {
incr.fromAxisAngle(depthAxis, -node.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(depthAxis, node.getTurnSpeed() * evt.getTime());
}
node.getLocalRotation().fromRotationMatrix(
incr.mult(node.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
node.getLocalRotation().normalize();
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performRollRightAction(InputActionEvent evt) {
depthAxis = node.getLocalRotation().getRotationColumn(2);
if (node.getVelocity() < 0) {
incr.fromAxisAngle(depthAxis, node.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(depthAxis, -node.getTurnSpeed() * evt.getTime());
}
node.getLocalRotation().fromRotationMatrix(
incr.mult(node.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
node.getLocalRotation().normalize();
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performRotateDownAction(InputActionEvent evt) {
rightAxis = node.getLocalRotation().getRotationColumn(0);
//we want to turn differently depending on which direction we are traveling in.
if(node.getVelocity() < 0) {
incr.fromAxisAngle(rightAxis, -node.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(rightAxis, node.getTurnSpeed() * evt.getTime());
}
node.getLocalRotation().fromRotationMatrix(
incr.mult(node.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
node.getLocalRotation().normalize();
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performRotateUpAction(InputActionEvent evt) {
rightAxis = node.getLocalRotation().getRotationColumn(0);
if (node.getVelocity() < 0) {
incr.fromAxisAngle(rightAxis, node.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(rightAxis, -node.getTurnSpeed() * evt.getTime());
}
node.getLocalRotation().fromRotationMatrix(
incr.mult(node.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
node.getLocalRotation().normalize();
}
}
As u can see theres not that much new in it.
The last methods came up when i moved on from the car sample to an aircraft sample where i also wanted to steer up and down or make a roll to the left or the right.
While testing this out i found out that if you leave the 2D Area of a Car Sample you have to readjust the Axis of Movement (upAxis, depthAxis, rightAxis).
I also made up 4 Controller to make my Vehicle capable of the same movement.
package com.jme.input.action;
import jmetest.flagrushtut.lesson6.Vehicle;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
import com.jme.math.Matrix3f;
import com.jme.math.Vector3f;
/**
* VehicleRotateLeftAction turns the vehicle to the left (while
* traveling forward).
* @author Mark Powell
*
*/
public class VehicleRollLeftAction extends KeyInputAction {
//temporary variables to handle rotation
private static final Matrix3f incr = new Matrix3f();
private static final Matrix3f tempMa = new Matrix3f();
private static final Matrix3f tempMb = new Matrix3f();
//we are using +Z as our up
private Vector3f upAxis = new Vector3f(0,0,1);
//the node to manipulate
private Vehicle vehicle;
/**
* create a new action with the vehicle to turn.
* @param vehicle the vehicle to turn
*/
public VehicleRollLeftAction(Vehicle vehicle) {
this.vehicle = vehicle;
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performAction(InputActionEvent evt) {
upAxis = vehicle.getLocalRotation().getRotationColumn(2);
//we want to turn differently depending on which direction we are traveling in.
if(vehicle.getVelocity() < 0) {
incr.fromAxisAngle(upAxis, -vehicle.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(upAxis, vehicle.getTurnSpeed() * evt.getTime());
}
vehicle.getLocalRotation().fromRotationMatrix(
incr.mult(vehicle.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
vehicle.getLocalRotation().normalize();
}
}
package com.jme.input.action;
import jmetest.flagrushtut.lesson6.Vehicle;
import com.jme.math.Matrix3f;
import com.jme.math.Vector3f;
public class VehicleRollRightAction extends KeyInputAction {
// temporary variables to handle rotation
private static final Matrix3f incr = new Matrix3f();
private static final Matrix3f tempMa = new Matrix3f();
private static final Matrix3f tempMb = new Matrix3f();
// the node to manipulate
private Vehicle vehicle;
private Vector3f upAxis = new Vector3f(0, 0, 1);
/**
* create a new action with the vehicle to turn.
*
* @param vehicle
* the vehicle to turn
*/
public VehicleRollRightAction(Vehicle vehicle) {
this.vehicle = vehicle;
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performAction(InputActionEvent evt) {
upAxis = vehicle.getLocalRotation().getRotationColumn(2);
if (vehicle.getVelocity() < 0) {
incr.fromAxisAngle(upAxis, vehicle.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(upAxis, -vehicle.getTurnSpeed() * evt.getTime());
}
vehicle.getLocalRotation().fromRotationMatrix(
incr.mult(vehicle.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
vehicle.getLocalRotation().normalize();
}
}
package com.jme.input.action;
import jmetest.flagrushtut.lesson6.Vehicle;
import com.jme.math.Matrix3f;
import com.jme.math.Vector3f;
public class VehicleRotateRightAction extends KeyInputAction {
// temporary variables to handle rotation
private static final Matrix3f incr = new Matrix3f();
private static final Matrix3f tempMa = new Matrix3f();
private static final Matrix3f tempMb = new Matrix3f();
// the node to manipulate
private Vehicle vehicle;
private Vector3f upAxis = new Vector3f(0, 1, 0);
/**
* create a new action with the vehicle to turn.
*
* @param vehicle
* the vehicle to turn
*/
public VehicleRotateRightAction(Vehicle vehicle) {
this.vehicle = vehicle;
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performAction(InputActionEvent evt) {
upAxis = vehicle.getLocalRotation().getRotationColumn(1);
if (vehicle.getVelocity() < 0) {
incr.fromAxisAngle(upAxis, vehicle.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(upAxis, -vehicle.getTurnSpeed() * evt.getTime());
}
vehicle.getLocalRotation().fromRotationMatrix(
incr.mult(vehicle.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
vehicle.getLocalRotation().normalize();
}
}
package com.jme.input.action;
import jmetest.flagrushtut.lesson6.Vehicle;
import com.jme.math.Matrix3f;
import com.jme.math.Vector3f;
public class VehicleRotateUpAction extends KeyInputAction {
// temporary variables to handle rotation
private static final Matrix3f incr = new Matrix3f();
private static final Matrix3f tempMa = new Matrix3f();
private static final Matrix3f tempMb = new Matrix3f();
// the node to manipulate
private Vehicle vehicle;
private Vector3f upAxis = new Vector3f(1, 0, 0);
/**
* create a new action with the vehicle to turn.
*
* @param vehicle
* the vehicle to turn
*/
public VehicleRotateUpAction(Vehicle vehicle) {
this.vehicle = vehicle;
}
/**
* turn the vehicle by its turning speed. If the vehicle is traveling
* backwards, swap direction.
*/
public void performAction(InputActionEvent evt) {
upAxis = vehicle.getLocalRotation().getRotationColumn(0);
if (vehicle.getVelocity() < 0) {
incr.fromAxisAngle(upAxis, vehicle.getTurnSpeed() * evt.getTime());
} else {
incr.fromAxisAngle(upAxis, -vehicle.getTurnSpeed() * evt.getTime());
}
vehicle.getLocalRotation().fromRotationMatrix(
incr.mult(vehicle.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
vehicle.getLocalRotation().normalize();
}
}
Similar the other two missing .
I am trying to get a paper where i can read something about steering techniques cause i am no pilot and i would like to get some feeling on where i want to steer in a dogfight related on the opponents location and heading.