Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
06ffe8e
Refactoring
ArtifactForms Dec 14, 2024
ef64872
Completed java doc.
ArtifactForms Dec 14, 2024
a223650
Merge branch 'working' of https://github.com/ArtifactForms/MeshLibCor…
ArtifactForms Dec 14, 2024
f1d9d03
feat: Add anchor support to UiElement interface
ArtifactForms Dec 14, 2024
66efa83
Refactoring: Extracted Grid3D class from the Workspace.
ArtifactForms Dec 14, 2024
50ec248
Refactoring: Extracted Axis3D class from Workspace.
ArtifactForms Dec 14, 2024
859222e
Added 3d translation to the graphics context.
ArtifactForms Dec 14, 2024
cc47646
Added scale(x,y,z) to the graphics context.
ArtifactForms Dec 14, 2024
2c2d989
Added default color.
ArtifactForms Dec 14, 2024
8ed2cf4
Refactor Matrix4f class for enhanced functionality and maintainability
ArtifactForms Dec 16, 2024
f5ff143
feat(math): Implement Ray3f class for 3D ray representation
ArtifactForms Dec 16, 2024
fbf811a
feat: Define Camera interface with core properties and utilities
ArtifactForms Dec 16, 2024
b4ced13
dd setPerspective method to Matrix4f class with input validation and
ArtifactForms Dec 16, 2024
aad5b85
Initial commit: Added legacy Timer class implementation.
ArtifactForms Dec 16, 2024
0f7e3a6
Refactor Timer class with improved time tracking, scaling, and
ArtifactForms Dec 16, 2024
5d98d7b
refactor: move light classes from scene.light to engine.scene.light
ArtifactForms Dec 16, 2024
63e10e8
Refactor Graphics Context: Split into Graphics2D, Graphics3D, and
ArtifactForms Dec 16, 2024
4f24521
Add comprehensive Javadoc to Graphics2D interface
ArtifactForms Dec 16, 2024
ff12ecf
feat(Graphics2D): add drawRoundRect and fillRoundRect methods
ArtifactForms Dec 16, 2024
888d8f3
feat: Add Material class with predefined and customizable lighting
ArtifactForms Dec 17, 2024
d37abc1
feat: Implement SceneNode class with scene graph hierarchy, component
ArtifactForms Dec 17, 2024
1eac84c
Implement Scene Management with Thread-Safe Operations and Parallel
ArtifactForms Dec 17, 2024
c19ad7d
feat: Implement Particle class for physics-based effects
ArtifactForms Dec 17, 2024
69f8704
Add MaterialFactory with Builder Pattern and JavaDocs
ArtifactForms Dec 17, 2024
ac48d67
Add Plane class for 3D geometric calculations
ArtifactForms Dec 17, 2024
158ef9c
Add ParticleRenderer interface for modular particle rendering system
ArtifactForms Dec 17, 2024
08f1755
Implement ParticleComponent with emitter and renderer lifecycle
ArtifactForms Dec 17, 2024
4ed2670
Initial commit: Implement ParticleEmitter class
ArtifactForms Dec 17, 2024
9a3c62d
Initial commit: Define Component interface for scene graph architecture
ArtifactForms Dec 17, 2024
0dd1079
Add AbstractComponent as a base class for reusable component logic
ArtifactForms Dec 17, 2024
fc28142
Implement Transform component for 3D transformations with position,
ArtifactForms Dec 17, 2024
506e41d
Added CinematicBlackBarsRenderer for smooth fade-in/out cinematic
ArtifactForms Dec 17, 2024
94ced3c
Added CircularAnimationComponent for smooth circular motion over the XZ
ArtifactForms Dec 17, 2024
8b54a3f
Added ControlWASD component for keyboard-based 3D navigation with WASD
ArtifactForms Dec 17, 2024
4dbd02d
Created RenderComponent interface for modular rendering logic in the
ArtifactForms Dec 17, 2024
6d97f30
Implemented RotationComponent for rotating SceneNodes around a specified
ArtifactForms Dec 17, 2024
77a8aef
feat: Implement Geometry component with mesh and material rendering
ArtifactForms Dec 17, 2024
db20f76
Bugfix: Color add(Color color) used subtract.
ArtifactForms Dec 18, 2024
20f48b2
Format changes. Removed version.
ArtifactForms Dec 18, 2024
41a9370
Add AmbientLight support and update LightRenderer for rendering
ArtifactForms Dec 18, 2024
06ab221
Add getRealtimeSinceStartup() and getRealtimeSinceStartupAsDouble()
ArtifactForms Dec 19, 2024
c7a0a2f
Add. Initialize component when attached.
ArtifactForms Dec 19, 2024
cda016f
Changed interface name from RenderComponent to RenderableComponent
ArtifactForms Dec 21, 2024
548ce45
Refactoring. Removed clutter.
ArtifactForms Dec 21, 2024
cf4f41f
Use Read-Only Access with Collections.unmodifiableList
ArtifactForms Dec 21, 2024
6128d50
Removed clutter.
ArtifactForms Dec 21, 2024
22ac27e
Feat: Added reciprocal()
ArtifactForms Dec 21, 2024
1ac7fd7
Feat: Added float get(int i)
ArtifactForms Dec 21, 2024
63346a4
Add reset method to Timer class to reset all time and frame tracking
ArtifactForms Dec 21, 2024
af6b8ac
Add Bounds class for 3D axis-aligned bounding box (AABB) calculations
ArtifactForms Dec 21, 2024
f430832
feat: add precomputed `directionInv` to `Ray3f` for optimized ray-box
ArtifactForms Dec 21, 2024
9c68ba7
Fix
ArtifactForms Dec 21, 2024
a8d746b
Changes method name.
ArtifactForms Dec 21, 2024
1b24fc9
Add bounding box to Geometry class for culling, spatial partitioning,
ArtifactForms Dec 21, 2024
0a80114
Format and name changes.
ArtifactForms Dec 21, 2024
c11cf48
Method name changes.
ArtifactForms Dec 21, 2024
6e6fcc2
Changed init cleanup to attach detach
ArtifactForms Dec 21, 2024
770227a
Format changes.
ArtifactForms Dec 22, 2024
85efbca
Fixed reasign paramters issue in getColorFromInt(int r, int g, int b)
ArtifactForms Dec 22, 2024
41b2e22
Format changes.
ArtifactForms Dec 22, 2024
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
272 changes: 272 additions & 0 deletions src/main/java/engine/Timer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
package engine;

/**
* The {@code Timer} class provides a utility for tracking elapsed time, frames per second (FPS),
* and time scaling for games or applications. It uses nanosecond precision for timekeeping and
* offers features such as formatted time representation, time-per-frame calculation, and
* slow-motion or speed-up effects via time scaling.
*
* <p>Key features include:
*
* <ul>
* <li>Tracking total elapsed time (scaled and unscaled).
* <li>Calculating frames per second (FPS).
* <li>Formatting time as hours:minutes:seconds.
* <li>Adjustable time scaling for slow-motion or fast-forward effects.
* </ul>
*
* This class is designed to be updated on every frame of an application or game.
*/
public class Timer {

/** Real world time when the timer started. */
private long startTime;

/** The last recorded time in nanoseconds. */
private long lastTime;

/** The time in milliseconds taken for the last frame. */
private float time;

/** Accumulates milliseconds for FPS calculation. */
private long millisecondCounter;

/** The frame count during the last FPS update. */
private int lastFrameCount;

/** The calculated frames per second (FPS). */
private int fps;

/** Total elapsed time in milliseconds. */
private long totalTime;

/** Scaling factor for time (default is 1.0 for real-time). */
private float timeScale;

/** Total number of frames since the Timer started. */
private int frameCount;

/** Constructs a {@code Timer} with a default time scale of 1.0. */
public Timer() {
this.startTime = System.nanoTime();
this.lastTime = System.nanoTime();
this.time = 0;
this.totalTime = 0;
this.timeScale = 1f;
this.frameCount = 0;
}

/**
* Constructs a {@code Timer} with the specified initial time scale.
*
* @param initialTimeScale the initial time scaling factor
*/
public Timer(float initialTimeScale) {
this.timeScale = initialTimeScale;
}

/**
* Returns the current frames per second (FPS).
*
* @return the frames per second
*/
public float getFrameRate() {
return fps;
}

/** Updates the FPS calculation based on the accumulated milliseconds. */
private void updateFPS() {
millisecondCounter += time;

Check failure

Code scanning / CodeQL

Implicit narrowing conversion in compound assignment High

Implicit cast of source type float to narrower destination type
long
.

Copilot Autofix

AI 11 months ago

To fix the problem, we need to ensure that the type of the left-hand side of the compound assignment statement is at least as wide as the type of the right-hand side. In this case, we should change the type of millisecondCounter from long to float to match the type of time. This will prevent the implicit narrowing conversion and preserve the precision of the accumulated time.

Suggested changeset 1
src/main/java/engine/Timer.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/main/java/engine/Timer.java b/src/main/java/engine/Timer.java
--- a/src/main/java/engine/Timer.java
+++ b/src/main/java/engine/Timer.java
@@ -31,3 +31,3 @@
   /** Accumulates milliseconds for FPS calculation. */
-  private long millisecondCounter;
+  private float millisecondCounter;
 
EOF
@@ -31,3 +31,3 @@
/** Accumulates milliseconds for FPS calculation. */
private long millisecondCounter;
private float millisecondCounter;

Copilot is powered by AI and may make mistakes. Always verify output.
if (millisecondCounter >= 1000) {
millisecondCounter = 0;
fps = frameCount - lastFrameCount;
lastFrameCount = frameCount;
}
}

/**
* Updates the Timer. This method must be called once per frame to ensure accurate time tracking.
*/
public void update() {
long currentTime = System.nanoTime();
time = (currentTime - lastTime) / 1_000_000.0f; // Convert to milliseconds
lastTime = currentTime;
totalTime += time;

Check failure

Code scanning / CodeQL

Implicit narrowing conversion in compound assignment High

Implicit cast of source type float to narrower destination type
long
.

Copilot Autofix

AI 11 months ago

To fix the problem, we need to ensure that the type of the left-hand side of the compound assignment statement is at least as wide as the type of the right-hand side. In this case, we should change the type of totalTime from long to float to match the type of time. This will prevent the implicit narrowing conversion and maintain the precision of the time calculations.

  • Change the type of totalTime from long to float in the Timer class.
  • Update the initialization of totalTime in the constructor to match the new type.
Suggested changeset 1
src/main/java/engine/Timer.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/main/java/engine/Timer.java b/src/main/java/engine/Timer.java
--- a/src/main/java/engine/Timer.java
+++ b/src/main/java/engine/Timer.java
@@ -40,3 +40,3 @@
   /** Total elapsed time in milliseconds. */
-  private long totalTime;
+  private float totalTime;
 
@@ -53,3 +53,3 @@
     this.time = 0;
-    this.totalTime = 0;
+    this.totalTime = 0f;
     this.timeScale = 1f;
EOF
@@ -40,3 +40,3 @@
/** Total elapsed time in milliseconds. */
private long totalTime;
private float totalTime;

@@ -53,3 +53,3 @@
this.time = 0;
this.totalTime = 0;
this.totalTime = 0f;
this.timeScale = 1f;
Copilot is powered by AI and may make mistakes. Always verify output.
frameCount++;
updateFPS();
}

/**
* Resets the {@code Timer} to its initial state, clearing all accumulated time and frame count
* values. This includes resetting the following:
*
* <ul>
* <li>The start time to the current system time.
* <li>The last time recorded to the current system time.
* <li>The total elapsed time to zero.
* <li>The frame count to zero.
* <li>The frames per second (FPS) to zero.
* <li>The millisecond counter to zero.
* <li>The last frame count for FPS calculation to zero.
* </ul>
*
* <p>This method can be used when you need to restart the timer, such as for restarting the game
* / application or resetting the simulation state.
*/
public void reset() {
this.startTime = System.nanoTime();
this.lastTime = startTime;
this.time = 0;
this.totalTime = 0;
this.frameCount = 0;
this.fps = 0;
this.millisecondCounter = 0;
this.lastFrameCount = 0;
}

/**
* Returns the total elapsed time in seconds, scaled by the current time scale.
*
* @return the scaled total elapsed time in seconds
*/
public float getTotalTime() {
return totalTime / 1000.0f * timeScale;
}

/**
* Returns the total elapsed time in seconds, independent of the time scale.
*
* @return the unscaled total elapsed time in seconds
*/
public float getUnscaledTotalTime() {
return totalTime / 1000.0f;
}

/**
* Returns a formatted string representing the scaled total time in the format HH:MM:SS.
*
* @return the formatted scaled total time
*/
public String getFormattedTotalTime() {
return formatTime(getTotalTime());
}

/**
* Returns a formatted string representing the unscaled total time in the format HH:MM:SS.
*
* @return the formatted unscaled total time
*/
public String getUnscaledFormattedTotalTime() {
return formatTime(getUnscaledTotalTime());
}

/**
* Returns the time it took to complete the last frame in seconds, scaled by the current time
* scale.
*
* @return the scaled time per frame in seconds
*/
public float getTimePerFrame() {
return time / 1000.0f * timeScale;
}

/**
* Returns the time it took to complete the last frame in seconds, independent of the time scale.
*
* @return the unscaled time per frame in seconds
*/
public float getUnscaledTimePerFrame() {
return time / 1000.0f;
}

/**
* Returns the current time scaling factor.
*
* @return the time scale
*/
public float getTimeScale() {
return timeScale;
}

/**
* Sets the time scaling factor. A value of 1.0 represents real-time, values less than 1.0 slow
* down time, and values greater than 1.0 speed up time.
*
* @param timeScale the new time scaling factor
*/
public void setTimeScale(float timeScale) {
this.timeScale = timeScale;
}

/**
* Returns the real-time elapsed since the game / application started, measured in seconds.
*
* <p>This method uses `System.nanoTime()` to obtain a high-precision timestamp. The returned
* value is a `float` representing the elapsed time in seconds.
*
* @return The real-time elapsed since the game started, in seconds.
*/
public float getRealtimeSinceStartup() {
return (System.nanoTime() - startTime) / 1_000_000_000.0f;
}

/**
* Returns the real-time elapsed since the game / application started, measured in seconds, as a
* `double` value.
*
* <p>This method uses `System.nanoTime()` to obtain a high-precision timestamp. The returned
* value is a `double` representing the elapsed time in seconds, providing higher precision than
* the `float` version.
*
* @return The real-time elapsed since the game started, in seconds, as a `double`.
*/
public double getRealtimeSinceStartupAsDouble() {
return (System.nanoTime() - startTime) / 1_000_000_000.0;
}

/**
* Returns the total number of frames that have passed since the Timer started.
*
* @return the total frame count
*/
public int getFrameCount() {
return frameCount;
}

/**
* Formats a time value in seconds into a string in the format HH:MM:SS.
*
* @param timeInSeconds the time in seconds to format
* @return the formatted time string
*/
private String formatTime(float timeInSeconds) {
int s = (int) timeInSeconds;
return String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, s % 60);
}

/**
* Returns a string representation of this Timer, showing its current state.
*
* @return a string representation of the Timer
*/
@Override
public String toString() {
return "Timer [millisecondCounter="
+ millisecondCounter
+ ", lastFrameCount="
+ lastFrameCount
+ ", fps="
+ fps
+ ", lastTime="
+ lastTime
+ ", time="
+ time
+ ", totalTime="
+ totalTime
+ ", timeScale="
+ timeScale
+ ", frameCount="
+ frameCount
+ "]";
}
}
41 changes: 41 additions & 0 deletions src/main/java/engine/components/AbstractComponent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package engine.components;

import engine.scene.SceneNode;

/**
* Abstract base class for all components in the scene graph.
* <p>
* This class provides a shared implementation of common functionality across
* all components, reducing boilerplate and centralizing shared logic for ease
* of maintenance.
* </p>
*/
public abstract class AbstractComponent implements Component {

/** Reference to the owning SceneNode */
protected SceneNode owner;

/**
* Sets the owner (parent node) of this component.
* <p>
* This is common logic provided by the abstract class to ensure consistency
* among all components.
* </p>
*
* @param owner The SceneNode that owns this component.
*/
@Override
public void setOwner(SceneNode owner) {
this.owner = owner;
}

/**
* Retrieves the owning node for convenience.
*
* @return The owning SceneNode instance.
*/
public SceneNode getOwner() {
return owner;
}

}
Loading
Loading