## 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