Hot questions for Using Lightweight Java Game Library in math

Question:

I am currently making a 3D first person shooter with java LWJGL. I want to turn and move a bullet towards a specified point in the world. I managed to make the bullet turn on the Y-axis but not the X and Z. How can i make the bullet turn on the Z and X-axis and then move towards the point?

Here is my Bullet Class:

package entities;

import org.lwjgl.util.vector.Vector3f;

import models.TexturedModel;
import renderEngine.DisplayManager;
import toolbox.MousePicker;

public class Bullet extends Entity{

private static Vector3f currentRay = new Vector3f();
private static final float RAY_RANGE = 600;
public static boolean reset = true;
public Bullet(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, float scale) {
    super(model, position, rotX, rotY, rotZ, scale);

}
public void move(Bullet b){
    float distance =  2 * DisplayManager.getFrameTimeSeconds();
    currentRay = MousePicker.calculateMouseRay();
    Vector3f endPoint = MousePicker.getPointOnRay(currentRay, 10000);
    //I want my Bullet to move towards the Vector3f endPoint

    float zDistance = endPoint.z - this.getPosition().z;
    float xDistance = endPoint.x - this.getPosition().x;
    double angleToTurn = Math.toDegrees(Math.atan2(xDistance,     zDistance));
    this.setRotY((float)angleToTurn);
    float dx = (float) (distance * Math.sin(Math.toRadians(super.getRotY())));
    float dz = (float) (distance * Math.cos(Math.toRadians(super.getRotY())));

    super.increasePosition(dx, 0, dz);


}
    }

Answer:

What you want to do is to get the speed required to make your bullet closer to your target (here the mouse) endPoint.

So first, you get the vector between the two endPoint.sub(position);

Then you normalize() it to get the direction.

You scale() it with your desired speed to get the instant speed.

and you super.increasePosition(speed.x, speed.y, speed.z); to make it move toward the target

Question:

I'm currently trying to program with openGL using java and the LWJGL 3 library. I tried to implement the perspective projection matrix, but with the current state, the models won't show up.

public static Matrix4f pespectiveProjectionMatrix(float screenWidth, float screenHeight, float FOV, float near, float far) {
    Matrix4f result = identity();

    float aspectRatio = screenWidth / screenHeight;

    result.elements[0 + 0 * 4] = (float) ((1 / tan(toRadians(FOV / 2))) / aspectRatio);
    result.elements[1 + 1 * 4] = (float) (1 / tan(FOV / 2));
    result.elements[2 + 2 * 4] = -(far + near) / (far - near);
    result.elements[2 + 3 * 4] = -1;
    result.elements[3 + 2 * 4] = -(2 * far * near) / (far - near);
    result.elements[3 + 3 * 4] = 0;

    return result;
}

The Matrix4f class provides an "elements" array, that contains a 4 * 4 matrix.The identity() method returns a simple identity matrix.

This is what the current matrix looks like:

0.75     |0.0      |0.0       |0.0      |
0.0      |0.6173696|0.0       |0.0      |
0.0      |0.0      |-1.0001999|-1.0     |
0.0      |0.0      |-0.20002  |0.0      |

vertex shader:

#version 400 core

in vec3 position;
in vec2 textureCoords;

out vec2 pass_textureCoords;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;

void main(void) {

    gl_Position = projectionMatrix * transformationMatrix * vec4(position, 1.0);
    pass_textureCoords = textureCoords;

}

rendering:

Matrix4f projectionMatrix = Matrix4f.pespectiveProjectionMatrix(800.0f, 600.0f, 90.0f, 0.1f, 1000.0f); //Creates the projection matrix (screenWidth, screenHeight, FOV, near cutting plane, far cutting plane)

shader.loadTransformationMatrix(transformationMatrix); //loads the transformationMatrix
shader.loadProjectionMatrix(projectionMatrix); //Load the projection matrix in a uniform variable

Answer:

My problem was, that I forgot to convert FOV to radians on the second line:

result.elements[1 + 1 * 4] = (float) (1 / tan(FOV / 2));

Should be

result.elements[1 + 1 * 4] = (float) (1 / tan(toRadians(FOV / 2)));

Question:

I have a code for my C++ Transform class that is supposed to give the user of the class a Model View Matrix

code-listing 1:

glm::mat4 Transform::GetModel(glm::vec3 pos, glm::vec3 rot, glm::vec3 scale, glm::mat4 parentTransformationMatrix){
    glm::mat4 posMat    = glm::translate(pos);
    glm::mat4 scaleMat  = glm::scale(scale);
    glm::mat4 rotX      = glm::rotate(rot.x, glm::vec3(1.0, 0.0, 0.0));
    glm::mat4 rotY      = glm::rotate(rot.y, glm::vec3(0.0, 1.0, 0.0));
    glm::mat4 rotZ      = glm::rotate(rot.z, glm::vec3(0.0, 0.0, 1.0));
    glm::mat4 rotMat    = rotX * rotY * rotZ;

    return parentTransformationMatrix * posMat * rotMat * scaleMat;
}

I made part of the code using JOML (for LWJGL3) already but I'm stuck with other parts (commented)

code-listing 2:

public Matrix4f GetModel(Vector3f pos, Vector3f rot, Vector3f scale, Matrix4f parentTransformationMatrix){
    Matrix4f posMat   ;// = translate(pos);
    Matrix4f scaleMat ;// = scale(scale);
    Matrix4f rotX     ;// = rotate(rot.x, Vector3f(1.0, 0.0, 0.0));
    Matrix4f rotY     ;// = rotate(rot.y, Vector3f(0.0, 1.0, 0.0));
    Matrix4f rotZ     ;// = rotate(rot.z, Vector3f(0.0, 0.0, 1.0));
    Matrix4f rotMat    = rotX.mul(rotY).mul(rotZ);

    return parentTransformationMatrix.mul(posMat).mul(rotMat).mul(scaleMat);
}

Answer:

The exact equivalent of your GLM code would be this Java code using JOML:

public Matrix4f GetModel(Vector3f pos, Vector3f rot, Vector3f scale, Matrix4f parent) {
  return new Matrix4f(parent).translate(pos).scale(scale).rotateXYZ(rot);
}

Unlike C/C++, Java does not (yet) have stack allocation built into the language itself (unless optimized by HotSpot when JIT'ting the bytecode). So prefer having a "dest"/destination/out parameter over creating a new Matrix4f instance (or modifying the parentTransformationMatrix matrix like you did above, because calling mul will modify it and not create a new Matrix4f).

So we end up with:

public Matrix4f GetModel(Vector3f pos, Vector3f rot, Vector3f scale, Matrix4f parent, Matrix4f dest) {
  return parent.translate(pos, dest).scale(scale).rotateXYZ(rot);
}

Question:

I'm working on a game where you are a spaceship. This spaceship has to be able to rotate. The rectangle has two arrays x[], y[] containing all the corners positions of the rectangle. But when I apply the rotation formula, I get a rather wierd rotation. To try to explain it, it looks like it's rotating the bottom left of the screen.

To make these corner arrays i take in an x position, y position, width and height.

Making of the corner-arrays

public Vertex2f(float x, float y, float w, float h){
    this.x[0] = x; 
    this.y[0] = y;

    this.x[1] = x+w;
    this.y[1] = y;

    this.x[2] = x+w;
    this.y[2] = y+h;

    this.x[3] = x;
    this.y[3] = y+h;
}

My rotation function

public void rotate(float angle){
    this.rotation = angle;

    double cos = Math.cos(rotation);
    double sin = Math.sin(rotation);

    for(int i = 0; i < x.length; i++){
        x[i] = (float)(cos * x[i] - sin * y[i]);
        y[i] = (float)(sin * x[i] + cos * y[i]);

    }

}

If it helps I am using LWJGL/OpenGL in java for all the graphics and Slick2d to load and init the sprites I am using.


Answer:

Try this one:

public void rotate(float angle){
    this.rotation = angle;

    double cos = Math.cos(rotation);
    double sin = Math.sin(rotation);

    double xOffset = (x[0]+x[2])/2;
    double yOffset = (y[0]+y[2])/2;

    for(int i = 0; i < 3; i++){
        x[i] = (float)(cos * (x[i]-xOffset) - sin * (y[i]-yOffset)) + xOffset;
        y[i] = (float)(sin * (x[i]-xOffset) + cos * (y[i]-yOffset)) + yOffset;

    }

}

you have to rotate around center of your rectangle. Otherwise center is in x=0 and y=0

edited:

public void rotate(float angle){
    this.rotation = angle;

    double cos = Math.cos(rotation);
    double sin = Math.sin(rotation);

    double xOffset = (x[0]+x[2])/2;
    double yOffset = (y[0]+y[2])/2;

    for(int i = 0; i < 3; i++){
        double newX = (float)(cos * (x[i]-xOffset) - sin * (y[i]-yOffset)) + xOffset;
        double newY = (float)(sin * (x[i]-xOffset) + cos * (y[i]-yOffset)) + yOffset;

        x[i] = newX;
        y[i] = newY;
    }
}

see other thread