Skip to content

Commit 09f2d33

Browse files
Merge pull request #53 from ArtifactForms/working2
Working2
2 parents 6e9d3aa + 3bdd0a1 commit 09f2d33

File tree

5 files changed

+308
-0
lines changed

5 files changed

+308
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package engine.processing;
2+
3+
import engine.resources.ImageLoader;
4+
import processing.core.PApplet;
5+
6+
public class ProcessingImageLoader implements ImageLoader {
7+
PApplet parent;
8+
9+
public ProcessingImageLoader(PApplet parent) {
10+
this.parent = parent;
11+
}
12+
13+
@Override
14+
public Object loadImage(String path) {
15+
return parent.loadImage(
16+
ProcessingImageLoader.class.getClassLoader().getResource("images/" + path).getPath());
17+
}
18+
}

src/main/java/engine/scene/Scene.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import engine.scene.camera.Camera;
1010
import engine.scene.light.Light;
11+
import workspace.GraphicsPImpl;
1112
import workspace.ui.Graphics;
1213

1314
/**
@@ -123,6 +124,8 @@ public void render(Graphics g) {
123124
renderLights(g);
124125

125126
synchronized (rootNodes) {
127+
GraphicsPImpl.faceCount = 0;
128+
GraphicsPImpl.vertexCount = 0;
126129
for (SceneNode node : rootNodes) {
127130
node.render(g);
128131
}

src/main/java/engine/scene/camera/Camera.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package engine.scene.camera;
22

33
import engine.components.Transform;
4+
import math.Matrix4f;
45
import math.Vector3f;
56

67
/**
@@ -141,4 +142,35 @@ public interface Camera {
141142
* height).
142143
*/
143144
void setAspectRatio(float aspectRatio);
145+
146+
/**
147+
* Computes the view matrix for this camera.
148+
*
149+
* <p>The view matrix represents the transformation that converts world-space coordinates into
150+
* camera-space coordinates, based on the camera's position and orientation.
151+
*
152+
* @return The view matrix as a {@link Matrix4f}.
153+
*/
154+
Matrix4f getViewMatrix();
155+
156+
/**
157+
* Computes the projection matrix for this camera.
158+
*
159+
* <p>The projection matrix defines how the 3D scene is projected onto a 2D screen, taking into
160+
* account the field of view, aspect ratio, and near/far clipping planes. The specific
161+
* implementation depends on whether the camera uses perspective or orthographic projection.
162+
*
163+
* @return The projection matrix as a {@link Matrix4f}.
164+
*/
165+
Matrix4f getProjectionMatrix();
166+
167+
/**
168+
* Computes the combined view-projection matrix for this camera.
169+
*
170+
* <p>The view-projection matrix combines the view and projection transformations into a single
171+
* matrix, allowing objects to be transformed directly from world space to clip space.
172+
*
173+
* @return The combined view-projection matrix as a {@link Matrix4f}.
174+
*/
175+
Matrix4f getViewProjectionMatrix();
144176
}

src/main/java/engine/scene/camera/PerspectiveCamera.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import engine.components.Transform;
44
import math.Mathf;
5+
import math.Matrix4;
6+
import math.Matrix4f;
57
import math.Vector3f;
68

79
/**
@@ -147,4 +149,28 @@ public float getAspectRatio() {
147149
public void setAspectRatio(float aspectRatio) {
148150
this.aspectRatio = aspectRatio;
149151
}
152+
153+
@Override
154+
public Matrix4f getViewMatrix() {
155+
Matrix4f view = new Matrix4f();
156+
view.setViewMatrix(transform.getPosition(), transform.getRotation());
157+
// FIXME
158+
return view;
159+
}
160+
161+
@Override
162+
public Matrix4f getProjectionMatrix() {
163+
Matrix4f projection = new Matrix4f();
164+
Matrix4 m = Matrix4.perspective(fov, aspectRatio, nearPlane, farPlane);
165+
;
166+
projection = new Matrix4f(m.getValues());
167+
return projection;
168+
}
169+
170+
@Override
171+
public Matrix4f getViewProjectionMatrix() {
172+
Matrix4f view = getViewMatrix();
173+
Matrix4f projection = getProjectionMatrix();
174+
return projection.multiply(view); // Assuming Matrix4f.multiply() is column-major
175+
}
150176
}

src/main/java/math/Matrix4.java

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
package math;
2+
3+
import java.util.Arrays;
4+
5+
// Potential Optimizations loop unrolling
6+
public class Matrix4 {
7+
8+
// 0 1 2 3
9+
// 4 5 6 7
10+
// 8 9 10 11
11+
// 12 13 14 15
12+
13+
// 00 01 02 03
14+
// 10 11 12 13
15+
// 20 21 22 23
16+
// 30 31 32 33
17+
18+
private static final float[] IDENTITY_VALUES =
19+
new float[] {
20+
1, 0, 0, 0,
21+
0, 1, 0, 0,
22+
0, 0, 1, 0,
23+
0, 0, 0, 1
24+
};
25+
26+
public static final Matrix4 IDENTITY = new Matrix4().setToIdentity();
27+
28+
public static final Matrix4 ZERO = new Matrix4();
29+
30+
private float[] values;
31+
32+
public Matrix4() {
33+
this.values = new float[16];
34+
}
35+
36+
public Matrix4(float... values) {
37+
setValues(values);
38+
}
39+
40+
public Matrix4(Matrix4 other) {
41+
this.values = Arrays.copyOf(other.values, 16);
42+
}
43+
44+
public Matrix4 add(Matrix4 other) {
45+
Matrix4 resultMatrix = new Matrix4();
46+
for (int i = 0; i < 16; i++) {
47+
resultMatrix.values[i] = this.values[i] + other.values[i];
48+
}
49+
return resultMatrix;
50+
}
51+
52+
public Matrix4 addLocal(Matrix4 other) {
53+
for (int i = 0; i < 16; i++) {
54+
this.values[i] += other.values[i];
55+
}
56+
return this;
57+
}
58+
59+
public Matrix4 multiply(Matrix4 other) {
60+
Matrix4 result = new Matrix4();
61+
for (int row = 0; row < 4; row++) {
62+
for (int col = 0; col < 4; col++) {
63+
float sum = 0.0f;
64+
for (int k = 0; k < 4; k++) {
65+
sum += this.values[row * 4 + k] * other.values[k * 4 + col];
66+
}
67+
result.values[row * 4 + col] = sum;
68+
}
69+
}
70+
return result;
71+
}
72+
73+
public Matrix4 multiplyLocal(Matrix4 other) {
74+
setValues(multiply(other).values);
75+
return this;
76+
}
77+
78+
public Vector3f multiply(Vector3f point) {
79+
float x = values[0] * point.x + values[1] * point.y + values[2] * point.z + values[3];
80+
float y = values[4] * point.x + values[5] * point.y + values[6] * point.z + values[7];
81+
float z = values[8] * point.x + values[9] * point.y + values[10] * point.z + values[11];
82+
float w = values[12] * point.x + values[13] * point.y + values[14] * point.z + values[15];
83+
84+
// Homogeneous division if using projective transformations
85+
if (w != 0) {
86+
x /= w;
87+
y /= w;
88+
z /= w;
89+
}
90+
return new Vector3f(x, y, z);
91+
}
92+
93+
public Matrix4 transpose() {
94+
return new Matrix4(
95+
values[0],
96+
values[4],
97+
values[8],
98+
values[12],
99+
values[1],
100+
values[5],
101+
values[9],
102+
values[13],
103+
values[2],
104+
values[6],
105+
values[10],
106+
values[14],
107+
values[3],
108+
values[7],
109+
values[11],
110+
values[15]);
111+
}
112+
113+
public Matrix4 transposeLocal() {
114+
setValues(
115+
values[0],
116+
values[4],
117+
values[8],
118+
values[12],
119+
values[1],
120+
values[5],
121+
values[9],
122+
values[13],
123+
values[2],
124+
values[6],
125+
values[10],
126+
values[14],
127+
values[3],
128+
values[7],
129+
values[11],
130+
values[15]);
131+
return this;
132+
}
133+
134+
public Matrix4 setToIdentity() {
135+
Arrays.fill(values, 0);
136+
values[0] = values[5] = values[10] = values[15] = 1;
137+
return this;
138+
}
139+
140+
public float[] getValues() {
141+
return Arrays.copyOf(values, values.length);
142+
}
143+
144+
public void setValues(float... values) {
145+
if (values.length != 16) {
146+
throw new IllegalArgumentException("Matrix4 must have 16 elements.");
147+
}
148+
this.values = values;
149+
}
150+
151+
public boolean isIdentity() {
152+
return Arrays.equals(values, IDENTITY_VALUES);
153+
}
154+
155+
public static Matrix4 perspective(float fov, float aspect, float zNear, float zFar) {
156+
validateNearFarPlanes(zNear, zFar);
157+
158+
float tanHalfFOV = (float) Math.tan(fov / 2);
159+
Matrix4 matrix = new Matrix4();
160+
161+
matrix.values[0] = 1 / (tanHalfFOV * aspect);
162+
matrix.values[5] = -1 / tanHalfFOV; // Note the negative sign to flip the Y-axis.
163+
matrix.values[10] = -(zFar + zNear) / (zFar - zNear);
164+
matrix.values[11] = -(2 * zFar * zNear) / (zFar - zNear);
165+
matrix.values[14] = -1;
166+
matrix.values[15] = 0;
167+
168+
return matrix;
169+
}
170+
171+
public static Matrix4 lookAt(Vector3f eye, Vector3f center, Vector3f up) {
172+
Vector3f forward = eye.subtract(center).normalize();
173+
Vector3f right = up.cross(forward).normalize();
174+
Vector3f cameraUp = forward.cross(right);
175+
176+
Matrix4 result = new Matrix4();
177+
result.values[0] = right.x;
178+
result.values[1] = right.y;
179+
result.values[2] = right.z;
180+
result.values[3] = -right.dot(eye);
181+
182+
result.values[4] = cameraUp.x;
183+
result.values[5] = cameraUp.y;
184+
result.values[6] = cameraUp.z;
185+
result.values[7] = -cameraUp.dot(eye);
186+
187+
result.values[8] = -forward.x;
188+
result.values[9] = -forward.y;
189+
result.values[10] = -forward.z;
190+
result.values[11] = -forward.dot(eye);
191+
192+
result.values[12] = 0;
193+
result.values[13] = 0;
194+
result.values[14] = 0;
195+
result.values[15] = 1;
196+
197+
return result;
198+
}
199+
200+
private static void validateNearFarPlanes(float zNear, float zFar) {
201+
if (zNear <= 0 || zFar <= 0) {
202+
throw new IllegalArgumentException("Near and far planes must be positive values.");
203+
}
204+
205+
if (zNear > zFar) {
206+
throw new IllegalArgumentException(
207+
String.format("Near plane (%.2f) cannot be greater than far plane (%.2f).", zNear, zFar));
208+
}
209+
210+
if (zNear == zFar) {
211+
throw new IllegalArgumentException(
212+
String.format("Near plane (%.2f) cannot be equal to far plane (%.2f).", zNear, zFar));
213+
}
214+
}
215+
216+
@Override
217+
public String toString() {
218+
StringBuilder sb = new StringBuilder();
219+
for (int i = 0; i < 4; i++) {
220+
sb.append("[");
221+
for (int j = 0; j < 4; j++) {
222+
sb.append(values[i * 4 + j]);
223+
if (j < 3) sb.append(", ");
224+
}
225+
sb.append("]\n");
226+
}
227+
return sb.toString();
228+
}
229+
}

0 commit comments

Comments
 (0)