JME3 Beginner: How to calculate(use) the forward vector of a VehicleControl for Line of Sight?

Good day:



I am trying to build a car simulation where all cars will be controlled by VehicleControl. So far what I want is for the cars to follow some sort of path (it can be dumb for now). My initial approach was comparing the X values of the vehicle to the targets X values, the car arrives but doing unneeded turns. Reading AIGamas tutorial I would need to calculate the forward vectors. I see VehicleControl already has a method called getForwardVector but it confuses me. It asks for a parameter and then the resulting vector and the parameter both are equaled to the same value.



If you need more information I will be happy to obligue.



[java]

public void update(float tpf) {

Vector3f currentPos = aiVehicle.getPhysicsLocation();

Vector3f baseforwardVector = currentPos.clone();

Vector3f forwardVector;

Vector3f subsVector;



if (currentState == ObjectState.Running) {

aiVehicle.accelerate(-800);

} else if (currentState == ObjectState.Seeking) {



baseforwardVector = baseforwardVector.normalize();

forwardVector = aiVehicle.getForwardVector(baseforwardVector);

subsVector = pointToSeek.subtract(currentPos.clone());

System.out.printf(“baseforwardVector: %f, %f, %fn”, baseforwardVector.x, baseforwardVector.y, baseforwardVector.z);

System.out.printf(“subsVector: %f, %f, %fn”, subsVector.x, subsVector.y, subsVector.z);

System.out.printf(“ForwardVector: %f, %f, %fn”, forwardVector.x, forwardVector.y, forwardVector.z);



if (pointToSeek != null && pointToSeek.x + 3 >= currentPos.x && pointToSeek.x - 3 <= currentPos.x) {

aiVehicle.steer(0.0f);

aiVehicle.accelerate(-40);



} else if (pointToSeek != null && pointToSeek.x > currentPos.x) {

aiVehicle.steer(-0.5f);

aiVehicle.accelerate(-40);

} else if (pointToSeek != null && pointToSeek.x < currentPos.x) {

aiVehicle.steer(0.5f);

aiVehicle.accelerate(-40);

}

} else if (currentState == ObjectState.Stopped) {

aiVehicle.accelerate(0);

aiVehicle.brake(40);



}

}



[/java]

getForwardVector(Vector3f) just allows you a way of passing in the vector to be returned. Passing null creates a new Vector3f.



EDIT: I updated the Javadoc for this method, should make it a bit clearer: http://code.google.com/p/jmonkeyengine/source/detail?r=9285

1 Like

Ok, thank you. So in the line of sight, I would be correct to use the forward vector X to decide on the heading?

From what you described, yes that would be the way to do it.

Ok, I will tell you how it goes.

Like many other people my math is shot. When I realized a vector is two points a tail(starting point) and head it started to make sense. I thought the car was one vector looking straight and the goal a vector going randomly. For the benefit of any other wannabe game dev like myself I will explain what I understood. Correct me if I am wrong.



For this problem I will assume you are far away enough and velocity is not an issue. In other worlds just solving how much we need to turn.



In many books/examples and what not, they will tell you to draw a triangle. How is this triangle formed? One line is the starting point(S1) of the car to where it is heading(H1). In this case AIVehicle.getForwardVector. The other line is from where the car is(S1) to where you want it to go(G1). In other words the starting point and the goal. The third and final line is from where the car is heading(H1) to the goal(g1). This forms a triangle. Then you use SohCahToah(SP) to calculate the angle needed to turn to the goal. When this angle is 0 then you are looking straight at it.



Since I am using a car and not some object than can turn where it stands. Even if the whole calculation says you need to turn 90 degrees or the equivalent in radians. You would have a max turning rate and keep turning until you face what you need to.



Obviously this is not optimized in any way, shape or form. I am not too clear on the different actions performed in the AIGama example. What I am assuming is that since I do not care about the length, the vectors are normalized and substracted to optimize it.

[java]

//Example from AIGama

Vector3f u = preypos.subtract(predpos).normalize();

Vector3f vr = preymove.mult(preyvel).subtract(u.mult(predvel));

Vector3f sr = preypos.subtract(predpos);

float tc = sr.length() / vr.length();

Vector3f st = preypos.add(preymove.mult(preyvel).mult(tc));



u = st.subtract(predpos).normalize();



predator.setLocalTranslation(predpos.add(u.mult(predvel)));[/java]



I really hope this helps another noob like me get his first step into the whole thing. Still need to code what I think is the solution though.

Have you done the vehicle physics tutorial? https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:vehicles

yes I have, I have been using it as a basis for what I have been building. Still the tutorial handles only input from the user. In my case there is no user all the vehicles will run on their own. The noob mistake I made with it was not realizing you could accelerate and brake at the same time. Meaning I needed to stop accelerating and then braking so the car did brake.



Still I am not sure if steering is in radians or degrees.

The Javadoc would lead me to say degrees but @normen could answer this for sure…

Most every rotation in the physics is in radians.

1 Like

Using the code from AIGama I modified it so the prey has no acceleration. It seems to behave much better than my previous tries. Obviously I got long ways to go. There is also a project called PandaAI that may help you. Still some translation from C++ to JMonkeyEngine will be needed.



[java]

Vector3f u = pointToSeek.subtract(currentPos).normalize();

Vector3f preymove = new Vector3f(0f,0.0f,0.0f).normalize();

float predvel = 100.0f, preyvel = 0.000f;

Vector3f vr = preymove.mult(preyvel).subtract(u.mult(predvel));

Vector3f sr = pointToSeek.subtract(currentPos);

float tc = sr.length() / vr.length();

Vector3f st = pointToSeek.add(preymove.mult(preyvel).mult(tc));





System.out.printf("u: %f, %f, %fn", u.x, u.y, u.z);

System.out.printf("preymove: %f, %f, %fn", preymove.x, preymove.y, preymove.z);

System.out.printf("vr: %f, %f, %fn", vr.x, vr.y, vr.z);

System.out.printf("sr: %f, %f, %fn", sr.x, sr.y, sr.z);

System.out.printf("tc: %fn", tc);

System.out.printf("st: %f, %f, %fn", st.x, st.y, st.z);



aiVehicle.steer(-tc);

aiVehicle.accelerate(-100.0f);

[/java]