Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions src/main/java/engine/application/BasicApplication.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package engine.application;

import engine.Timer;
import engine.components.FlyByCameraControl;
import engine.debug.DebugInfoUpdater;
import engine.debug.DebugOverlay;
import engine.debug.FpsGraph;
Expand All @@ -10,13 +11,14 @@
import engine.processing.ProcessingApplication;
import engine.scene.Scene;
import engine.scene.SceneNode;
import engine.scene.camera.PerspectiveCamera;
import workspace.ui.Graphics;

public abstract class BasicApplication implements Application {

private boolean launched;

private boolean displayInfoText = true;
private boolean displayInfo = true;

private boolean isPaused = false;

Expand Down Expand Up @@ -74,6 +76,18 @@ public void initialize() {
initializeDebugOverlay();
fpsGraph = new FpsGraph(new FpsHistory());
onInitialize();
setupDefaultCamera();
}

private void setupDefaultCamera() {
if (activeScene == null) return;
if (activeScene.getActiveCamera() != null) return;

PerspectiveCamera defaultCamera = new PerspectiveCamera();
activeScene.setActiveCamera(defaultCamera);
SceneNode cameraNode = new SceneNode("DefaultCamera");
cameraNode.addComponent(new FlyByCameraControl(input, defaultCamera));
activeScene.addNode(cameraNode);
}

private void initializeDebugOverlay() {
Expand Down Expand Up @@ -110,7 +124,7 @@ public void update() {
}

@Override
public void render(Graphics g) {
public void render(Graphics g) {
if (activeScene != null) {
activeScene.render(g);
}
Expand All @@ -124,7 +138,7 @@ public void render(Graphics g) {
g.strokeWeight(1);
renderUi(g);
renderDebugUi(g);
fpsGraph.render(g);


g.enableDepthTest();
}
Expand All @@ -134,8 +148,9 @@ private void renderUi(Graphics g) {
}

private void renderDebugUi(Graphics g) {
if (!displayInfoText) return;
if (!displayInfo) return;
debugOverlay.render(g);
fpsGraph.render(g);
}

@Override
Expand Down Expand Up @@ -170,8 +185,8 @@ public Scene getActiveScene() {
public void setActiveScene(Scene activeScene) {
this.activeScene = activeScene;
}
public void setDisplayInfoText(boolean displayInfoText) {
this.displayInfoText = displayInfoText;

public void setDisplayInfo(boolean displayInfo) {
this.displayInfo = displayInfo;
}
}
1 change: 0 additions & 1 deletion src/main/java/engine/processing/ProcessingTexture.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public int getHeight() {
@Override
public void bind(int unit) {
// Processing doesn't use texture units in the same way, just bind globally
image.loadPixels();
}

@Override
Expand Down
36 changes: 13 additions & 23 deletions src/main/java/engine/render/Material.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ public class Material {
/** Shininess factor for specular highlights. */
private final float shininess;

private Texture normalTexture;

/** The diffuse texture map (map_Kd) of the material. */
private Texture diffuseTexture;

/**
Expand All @@ -88,7 +87,6 @@ private Material(Builder builder) {
this.diffuse = builder.diffuse;
this.specular = builder.specular;
this.shininess = builder.shininess;
this.normalTexture = builder.normalTexture;
this.diffuseTexture = builder.diffuseTexture;
}

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

private Texture diffuseTexture = null;

private Texture normalTexture = null;

/**
* Sets the base color of the material.
*
Expand Down Expand Up @@ -174,17 +170,6 @@ public Builder setUseLighting(boolean useLighting) {
return this;
}

/**
* Sets the normal texture of the material.
*
* @param normalTexture The normal texture, can be null
* @return The builder instance for chaining
*/
public Builder setNormalTexture(Texture normalTexture) {
this.normalTexture = normalTexture;
return this;
}

/**
* Sets the diffuse texture of the material.
*
Expand Down Expand Up @@ -217,9 +202,6 @@ public void apply(Graphics g) {
if (diffuseTexture != null) {
g.bindTexture(diffuseTexture, 0); // Bind to texture unit 0
}
if (normalTexture != null) {
g.bindTexture(normalTexture, 1); // Bind to texture unit 1
}
}

/**
Expand Down Expand Up @@ -281,11 +263,19 @@ public float getShininess() {
return shininess;
}

/**
* Returns the diffuse texture map (map_Kd) of the material.
*
* <p>The diffuse texture is a 2D image used to define the base color and pattern of the surface,
* simulating the appearance of the material under diffuse lighting. This texture is typically
* applied using UV mapping to wrap the image onto the geometry of a 3D model.
*
* <p>In the context of material definition files (e.g., MTL for OBJ models), this corresponds to
* the `map_Kd` property, which specifies the file path to the texture image.
*
* @return The diffuse texture map as {@link Texture}.
*/
public Texture getDiffuseTexture() {
return diffuseTexture;
}

public Texture getNormalTexture() {
return normalTexture;
}
}
33 changes: 33 additions & 0 deletions src/main/java/engine/scene/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import engine.scene.camera.Camera;
import engine.scene.light.Light;
import math.Color;
import workspace.GraphicsPImpl;
import workspace.ui.Graphics;

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

/** The background color of the scene. Defaults to black if not explicitly set. */
private Color background;

/** The currently active camera that determines the scene's view transformation. */
private Camera activeCamera;

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

/**
Expand Down Expand Up @@ -116,6 +121,8 @@ public void update(float deltaTime) {
* compatibility with most rendering APIs.
*/
public void render(Graphics g) {
g.clear(background);

if (activeCamera != null) {
g.applyCamera(activeCamera);
}
Expand Down Expand Up @@ -295,4 +302,30 @@ public boolean isWireframeMode() {
public void setWireframeMode(boolean wireframeMode) {
this.wireframeMode = wireframeMode;
}

/**
* Retrieves the background color of the scene.
*
* <p>The background color is used to clear the rendering surface before drawing the scene.
*
* @return The current background color of the scene.
*/
public Color getBackground() {
return background;
}

/**
* Sets the background color of the scene.
*
* <p>The background color is used to clear the rendering surface before drawing the scene.
*
* @param background The new background color for the scene. Must not be {@code null}.
* @throws IllegalArgumentException if the provided background color is {@code null}.
*/
public void setBackground(Color background) {
if (background == null) {
throw new IllegalArgumentException("Background color cannot be null.");
}
this.background = background;
}
}
19 changes: 19 additions & 0 deletions src/main/java/engine/scene/light/DirectionalLight.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,25 @@ public DirectionalLight() {
this(Color.WHITE, new Vector3f(0, 1, 0), 1.0f);
}

/**
* Creates a new DirectionalLight instance with the specified color and direction.
*
* <p>This constructor initializes the light with the given color and direction, and a default
* intensity of 1.0. The provided direction vector is normalized during initialization to ensure
* consistent light behavior.
*
* @param color The color of the light emitted by the directional light source. Represents the RGB
* values of the light's color. This parameter cannot be null.
* @param direction The direction of the light source. This vector determines the direction in
* which the light rays travel. The provided vector is automatically normalized during
* construction, ensuring the direction's magnitude is always 1. This parameter cannot be
* null.
* @throws IllegalArgumentException if the direction or color is null.
*/
public DirectionalLight(Color color, Vector3f direction) {
this(color, direction, 1.0f);
}

/**
* Creates a new DirectionalLight instance.
*
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/math/Plane.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public float distanceToPoint(Vector3f point) {
* @return the normal vector of the plane.
*/
public Vector3f getNormal() {
return normal;
return new Vector3f(normal);
}

/**
Expand Down
87 changes: 62 additions & 25 deletions src/main/java/math/Ray3f.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,69 @@ public Ray3f(Vector3f origin, Vector3f direction) {
if (direction == null) {
throw new IllegalArgumentException("Direction cannot be null.");
}
this.origin = origin;
this.direction = direction;
this.origin = new Vector3f(origin);
this.direction = new Vector3f(direction);
this.direction.normalizeLocal();
this.directionInv = direction.reciprocal();
}

/**
* Computes the shortest distance from the ray to a point in 3D space.
*
* <p>This method calculates the perpendicular distance from the given point to the ray. If the
* point lies behind the origin of the ray, the distance from the point to the ray's origin is
* returned. If the point lies along the ray's path (in the direction of the ray), the
* perpendicular distance is calculated. The ray is considered to extend infinitely in both
* directions from the origin.
*
* @param point The point in 3D space to compute the distance to (non-null).
* @return The shortest distance from the ray to the point. If the point is behind the ray's
* origin, the distance from the point to the origin is returned.
* @throws IllegalArgumentException if the point is null.
*/
public float distanceToPoint(Vector3f point) {
if (point == null) {
throw new IllegalArgumentException("Point cannot be null.");
}

// Calculate vector from ray origin to the point
Vector3f toPoint = point.subtract(origin);

// Project the vector to the ray's direction (dot product normalized)
float projection = toPoint.dot(direction);

// If the projection is negative, the point is behind the ray's origin
if (projection < 0) {
// Return the distance from the origin to the point
return toPoint.length();
}

// Return the perpendicular distance (calculate as the distance from the point to the closest
// point on the ray)
Vector3f closestPoint = getPointAt(projection);
return closestPoint.subtract(point).length();
}

/**
* Computes the point along the ray at a given parameter {@code t}.
*
* <p>The formula for the point is:
*
* <pre>{@code
* point = origin + t * direction
* }</pre>
*
* where {@code t} is a scalar representing the distance along the ray from the origin. Positive
* values of {@code t} will give points in the direction the ray is pointing, while negative
* values will give points in the opposite direction.
*
* @param t The parameter along the ray (can be negative, zero, or positive).
* @return The point at parameter {@code t}.
*/
public Vector3f getPointAt(float t) {
return origin.add(direction.mult(t));
}

/**
* Returns the origin of the ray.
*
Expand All @@ -50,7 +107,7 @@ public Ray3f(Vector3f origin, Vector3f direction) {
* @return The origin of the ray.
*/
public Vector3f getOrigin() {
return origin;
return new Vector3f(origin);
}

/**
Expand All @@ -62,7 +119,7 @@ public Vector3f getOrigin() {
* @return The direction vector of the ray.
*/
public Vector3f getDirection() {
return direction;
return new Vector3f(direction);
}

/**
Expand All @@ -74,26 +131,6 @@ public Vector3f getDirection() {
* @return The reciprocal of the direction vector of the ray.
*/
public Vector3f getDirectionInv() {
return directionInv;
}

/**
* Computes the point along the ray at a given parameter {@code t}.
*
* <p>The formula for the point is:
*
* <pre>{@code
* point = origin + t * direction
* }</pre>
*
* where {@code t} is a scalar representing the distance along the ray from the origin. Positive
* values of {@code t} will give points in the direction the ray is pointing, while negative
* values will give points in the opposite direction.
*
* @param t The parameter along the ray (can be negative, zero, or positive).
* @return The point at parameter {@code t}.
*/
public Vector3f getPointAt(float t) {
return origin.add(direction.mult(t));
return new Vector3f(directionInv);
}
}
Loading
Loading