Skip to content

Commit d904467

Browse files
Merge pull request #58 from ArtifactForms/working2
Working2
2 parents c4d6732 + b9de3f9 commit d904467

File tree

10 files changed

+294
-187
lines changed

10 files changed

+294
-187
lines changed

src/main/java/engine/application/BasicApplication.java

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

33
import engine.Timer;
4+
import engine.components.FlyByCameraControl;
45
import engine.debug.DebugInfoUpdater;
56
import engine.debug.DebugOverlay;
67
import engine.debug.FpsGraph;
@@ -10,13 +11,14 @@
1011
import engine.processing.ProcessingApplication;
1112
import engine.scene.Scene;
1213
import engine.scene.SceneNode;
14+
import engine.scene.camera.PerspectiveCamera;
1315
import workspace.ui.Graphics;
1416

1517
public abstract class BasicApplication implements Application {
1618

1719
private boolean launched;
1820

19-
private boolean displayInfoText = true;
21+
private boolean displayInfo = true;
2022

2123
private boolean isPaused = false;
2224

@@ -74,6 +76,18 @@ public void initialize() {
7476
initializeDebugOverlay();
7577
fpsGraph = new FpsGraph(new FpsHistory());
7678
onInitialize();
79+
setupDefaultCamera();
80+
}
81+
82+
private void setupDefaultCamera() {
83+
if (activeScene == null) return;
84+
if (activeScene.getActiveCamera() != null) return;
85+
86+
PerspectiveCamera defaultCamera = new PerspectiveCamera();
87+
activeScene.setActiveCamera(defaultCamera);
88+
SceneNode cameraNode = new SceneNode("DefaultCamera");
89+
cameraNode.addComponent(new FlyByCameraControl(input, defaultCamera));
90+
activeScene.addNode(cameraNode);
7791
}
7892

7993
private void initializeDebugOverlay() {
@@ -110,7 +124,7 @@ public void update() {
110124
}
111125

112126
@Override
113-
public void render(Graphics g) {
127+
public void render(Graphics g) {
114128
if (activeScene != null) {
115129
activeScene.render(g);
116130
}
@@ -124,7 +138,7 @@ public void render(Graphics g) {
124138
g.strokeWeight(1);
125139
renderUi(g);
126140
renderDebugUi(g);
127-
fpsGraph.render(g);
141+
128142

129143
g.enableDepthTest();
130144
}
@@ -134,8 +148,9 @@ private void renderUi(Graphics g) {
134148
}
135149

136150
private void renderDebugUi(Graphics g) {
137-
if (!displayInfoText) return;
151+
if (!displayInfo) return;
138152
debugOverlay.render(g);
153+
fpsGraph.render(g);
139154
}
140155

141156
@Override
@@ -170,8 +185,8 @@ public Scene getActiveScene() {
170185
public void setActiveScene(Scene activeScene) {
171186
this.activeScene = activeScene;
172187
}
173-
174-
public void setDisplayInfoText(boolean displayInfoText) {
175-
this.displayInfoText = displayInfoText;
188+
189+
public void setDisplayInfo(boolean displayInfo) {
190+
this.displayInfo = displayInfo;
176191
}
177192
}

src/main/java/engine/processing/ProcessingTexture.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public int getHeight() {
2424
@Override
2525
public void bind(int unit) {
2626
// Processing doesn't use texture units in the same way, just bind globally
27-
image.loadPixels();
2827
}
2928

3029
@Override

src/main/java/engine/render/Material.java

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ public class Material {
6868
/** Shininess factor for specular highlights. */
6969
private final float shininess;
7070

71-
private Texture normalTexture;
72-
71+
/** The diffuse texture map (map_Kd) of the material. */
7372
private Texture diffuseTexture;
7473

7574
/**
@@ -88,7 +87,6 @@ private Material(Builder builder) {
8887
this.diffuse = builder.diffuse;
8988
this.specular = builder.specular;
9089
this.shininess = builder.shininess;
91-
this.normalTexture = builder.normalTexture;
9290
this.diffuseTexture = builder.diffuseTexture;
9391
}
9492

@@ -112,8 +110,6 @@ public static class Builder {
112110

113111
private Texture diffuseTexture = null;
114112

115-
private Texture normalTexture = null;
116-
117113
/**
118114
* Sets the base color of the material.
119115
*
@@ -174,17 +170,6 @@ public Builder setUseLighting(boolean useLighting) {
174170
return this;
175171
}
176172

177-
/**
178-
* Sets the normal texture of the material.
179-
*
180-
* @param normalTexture The normal texture, can be null
181-
* @return The builder instance for chaining
182-
*/
183-
public Builder setNormalTexture(Texture normalTexture) {
184-
this.normalTexture = normalTexture;
185-
return this;
186-
}
187-
188173
/**
189174
* Sets the diffuse texture of the material.
190175
*
@@ -217,9 +202,6 @@ public void apply(Graphics g) {
217202
if (diffuseTexture != null) {
218203
g.bindTexture(diffuseTexture, 0); // Bind to texture unit 0
219204
}
220-
if (normalTexture != null) {
221-
g.bindTexture(normalTexture, 1); // Bind to texture unit 1
222-
}
223205
}
224206

225207
/**
@@ -281,11 +263,19 @@ public float getShininess() {
281263
return shininess;
282264
}
283265

266+
/**
267+
* Returns the diffuse texture map (map_Kd) of the material.
268+
*
269+
* <p>The diffuse texture is a 2D image used to define the base color and pattern of the surface,
270+
* simulating the appearance of the material under diffuse lighting. This texture is typically
271+
* applied using UV mapping to wrap the image onto the geometry of a 3D model.
272+
*
273+
* <p>In the context of material definition files (e.g., MTL for OBJ models), this corresponds to
274+
* the `map_Kd` property, which specifies the file path to the texture image.
275+
*
276+
* @return The diffuse texture map as {@link Texture}.
277+
*/
284278
public Texture getDiffuseTexture() {
285279
return diffuseTexture;
286280
}
287-
288-
public Texture getNormalTexture() {
289-
return normalTexture;
290-
}
291281
}

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

Lines changed: 33 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 math.Color;
1112
import workspace.GraphicsPImpl;
1213
import workspace.ui.Graphics;
1314

@@ -37,6 +38,9 @@ public class Scene {
3738
/** Name of the scene. Used for identification or debugging purposes. */
3839
private final String name;
3940

41+
/** The background color of the scene. Defaults to black if not explicitly set. */
42+
private Color background;
43+
4044
/** The currently active camera that determines the scene's view transformation. */
4145
private Camera activeCamera;
4246

@@ -56,6 +60,7 @@ public Scene(String name) {
5660
throw new IllegalArgumentException("Name cannot be null.");
5761
}
5862
this.name = name;
63+
this.background = new Color(0, 0, 0, 1);
5964
}
6065

6166
/**
@@ -116,6 +121,8 @@ public void update(float deltaTime) {
116121
* compatibility with most rendering APIs.
117122
*/
118123
public void render(Graphics g) {
124+
g.clear(background);
125+
119126
if (activeCamera != null) {
120127
g.applyCamera(activeCamera);
121128
}
@@ -295,4 +302,30 @@ public boolean isWireframeMode() {
295302
public void setWireframeMode(boolean wireframeMode) {
296303
this.wireframeMode = wireframeMode;
297304
}
305+
306+
/**
307+
* Retrieves the background color of the scene.
308+
*
309+
* <p>The background color is used to clear the rendering surface before drawing the scene.
310+
*
311+
* @return The current background color of the scene.
312+
*/
313+
public Color getBackground() {
314+
return background;
315+
}
316+
317+
/**
318+
* Sets the background color of the scene.
319+
*
320+
* <p>The background color is used to clear the rendering surface before drawing the scene.
321+
*
322+
* @param background The new background color for the scene. Must not be {@code null}.
323+
* @throws IllegalArgumentException if the provided background color is {@code null}.
324+
*/
325+
public void setBackground(Color background) {
326+
if (background == null) {
327+
throw new IllegalArgumentException("Background color cannot be null.");
328+
}
329+
this.background = background;
330+
}
298331
}

src/main/java/engine/scene/light/DirectionalLight.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,25 @@ public DirectionalLight() {
4545
this(Color.WHITE, new Vector3f(0, 1, 0), 1.0f);
4646
}
4747

48+
/**
49+
* Creates a new DirectionalLight instance with the specified color and direction.
50+
*
51+
* <p>This constructor initializes the light with the given color and direction, and a default
52+
* intensity of 1.0. The provided direction vector is normalized during initialization to ensure
53+
* consistent light behavior.
54+
*
55+
* @param color The color of the light emitted by the directional light source. Represents the RGB
56+
* values of the light's color. This parameter cannot be null.
57+
* @param direction The direction of the light source. This vector determines the direction in
58+
* which the light rays travel. The provided vector is automatically normalized during
59+
* construction, ensuring the direction's magnitude is always 1. This parameter cannot be
60+
* null.
61+
* @throws IllegalArgumentException if the direction or color is null.
62+
*/
63+
public DirectionalLight(Color color, Vector3f direction) {
64+
this(color, direction, 1.0f);
65+
}
66+
4867
/**
4968
* Creates a new DirectionalLight instance.
5069
*

src/main/java/math/Plane.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public float distanceToPoint(Vector3f point) {
7575
* @return the normal vector of the plane.
7676
*/
7777
public Vector3f getNormal() {
78-
return normal;
78+
return new Vector3f(normal);
7979
}
8080

8181
/**

src/main/java/math/Ray3f.java

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,69 @@ public Ray3f(Vector3f origin, Vector3f direction) {
3636
if (direction == null) {
3737
throw new IllegalArgumentException("Direction cannot be null.");
3838
}
39-
this.origin = origin;
40-
this.direction = direction;
39+
this.origin = new Vector3f(origin);
40+
this.direction = new Vector3f(direction);
4141
this.direction.normalizeLocal();
4242
this.directionInv = direction.reciprocal();
4343
}
4444

45+
/**
46+
* Computes the shortest distance from the ray to a point in 3D space.
47+
*
48+
* <p>This method calculates the perpendicular distance from the given point to the ray. If the
49+
* point lies behind the origin of the ray, the distance from the point to the ray's origin is
50+
* returned. If the point lies along the ray's path (in the direction of the ray), the
51+
* perpendicular distance is calculated. The ray is considered to extend infinitely in both
52+
* directions from the origin.
53+
*
54+
* @param point The point in 3D space to compute the distance to (non-null).
55+
* @return The shortest distance from the ray to the point. If the point is behind the ray's
56+
* origin, the distance from the point to the origin is returned.
57+
* @throws IllegalArgumentException if the point is null.
58+
*/
59+
public float distanceToPoint(Vector3f point) {
60+
if (point == null) {
61+
throw new IllegalArgumentException("Point cannot be null.");
62+
}
63+
64+
// Calculate vector from ray origin to the point
65+
Vector3f toPoint = point.subtract(origin);
66+
67+
// Project the vector to the ray's direction (dot product normalized)
68+
float projection = toPoint.dot(direction);
69+
70+
// If the projection is negative, the point is behind the ray's origin
71+
if (projection < 0) {
72+
// Return the distance from the origin to the point
73+
return toPoint.length();
74+
}
75+
76+
// Return the perpendicular distance (calculate as the distance from the point to the closest
77+
// point on the ray)
78+
Vector3f closestPoint = getPointAt(projection);
79+
return closestPoint.subtract(point).length();
80+
}
81+
82+
/**
83+
* Computes the point along the ray at a given parameter {@code t}.
84+
*
85+
* <p>The formula for the point is:
86+
*
87+
* <pre>{@code
88+
* point = origin + t * direction
89+
* }</pre>
90+
*
91+
* where {@code t} is a scalar representing the distance along the ray from the origin. Positive
92+
* values of {@code t} will give points in the direction the ray is pointing, while negative
93+
* values will give points in the opposite direction.
94+
*
95+
* @param t The parameter along the ray (can be negative, zero, or positive).
96+
* @return The point at parameter {@code t}.
97+
*/
98+
public Vector3f getPointAt(float t) {
99+
return origin.add(direction.mult(t));
100+
}
101+
45102
/**
46103
* Returns the origin of the ray.
47104
*
@@ -50,7 +107,7 @@ public Ray3f(Vector3f origin, Vector3f direction) {
50107
* @return The origin of the ray.
51108
*/
52109
public Vector3f getOrigin() {
53-
return origin;
110+
return new Vector3f(origin);
54111
}
55112

56113
/**
@@ -62,7 +119,7 @@ public Vector3f getOrigin() {
62119
* @return The direction vector of the ray.
63120
*/
64121
public Vector3f getDirection() {
65-
return direction;
122+
return new Vector3f(direction);
66123
}
67124

68125
/**
@@ -74,26 +131,6 @@ public Vector3f getDirection() {
74131
* @return The reciprocal of the direction vector of the ray.
75132
*/
76133
public Vector3f getDirectionInv() {
77-
return directionInv;
78-
}
79-
80-
/**
81-
* Computes the point along the ray at a given parameter {@code t}.
82-
*
83-
* <p>The formula for the point is:
84-
*
85-
* <pre>{@code
86-
* point = origin + t * direction
87-
* }</pre>
88-
*
89-
* where {@code t} is a scalar representing the distance along the ray from the origin. Positive
90-
* values of {@code t} will give points in the direction the ray is pointing, while negative
91-
* values will give points in the opposite direction.
92-
*
93-
* @param t The parameter along the ray (can be negative, zero, or positive).
94-
* @return The point at parameter {@code t}.
95-
*/
96-
public Vector3f getPointAt(float t) {
97-
return origin.add(direction.mult(t));
134+
return new Vector3f(directionInv);
98135
}
99136
}

0 commit comments

Comments
 (0)