Skip to content

Commit c4cb569

Browse files
committed
Implement meshlet-gen algorithm
* eb82518 Better parameters (tttsaurus) * 1ab177f le algorithm (tttsaurus) * 63ad4ba Meshlet-gen helper method setup (tttsaurus) * 263f1fe Start over (tttsaurus) * ecac10a Fix some issues with KDTree building/deletion/KNN (#477) (jchung01) * 6f51422 Draw meshlet overlap warning (tttsaurus) * 4745bd1 Better logging (tttsaurus) * 4f1eb48 Meshlet-gen visualized test env setup (tttsaurus) * eb3fd71 Re-added faces to Block (Kuba663) * e6d9984 Merge remote-tracking branch 'origin/proposal/render-system-meshlet' into proposal/render-system-meshlet (Kuba663) * 37d5046 Re-added faces to Block (Kuba663) * 73e2a49 Merge remote-tracking branch 'origin/proposal/render-system-meshlet' into proposal/render-system-meshlet (tttsaurus) * d376a07 Meshlet-gen test setup (tttsaurus) * d00ae9a Move all the block queries to a single place to reduce latency. (Kuba663) * 1ae1876 Fix a ecs-component flattening npe issue (tttsaurus) * b8e808d Merge branch 'proposal/render-system' into proposal/render-system-meshlet (tttsaurus) * c563cfe Fixed the broken algorithm written by a retard (me) (Kuba663) * 4cdf487 Fixed errors in kD-tree (Kuba663) * ca8e4f9 what? (Kuba663) * 8ed71c4 Band-aid solution before the median is fixed (Kuba663) * dee6f19 kD-Tree construction test. (Kuba663) * ad7aa29 Added preconditions to every median related function to make finding errors easier. (Kuba663) * 5e47b49 Added a limited size random probe to the median to reduce lag. (Kuba663) * dbcffcc More extensive median testing (Kuba663) * 36d686e Attempted to fix the median (Kuba663) * 95d1e08 Better looking debug visuals (tttsaurus) * 64c0a01 Update GizmosManager to draw block faces (tttsaurus) * 218014d Separated Meshlets into transparent and opaque (Kuba663) * 6f67be5 Quantile Utils Tests (Kuba663) * 7e88ec8 Mild mistake in unused function (Kuba663) * d298fc1 Merge remote-tracking branch 'origin/proposal/render-system-meshlet' into proposal/render-system-meshlet (Kuba663) * 33821d1 Fixed absurd median mistake (Kuba663) * 99ee070 Meshlet algorithm test env setup (tttsaurus) * 3d37b3b Merge branch 'proposal/render-system' into proposal/render-system-meshlet (tttsaurus) * bbbedf6 Moved the sub-chunk division into the system for threadmaxxing (Kuba663) * e30395d Remove unchanged chunks from the algorithm (Kuba663) * 01280f4 kD-tree deletion test (Kuba663) * 8b26d96 Remove Octree as it's not necessary anymore (Kuba663) * 8ad051f Avoid call EntityManager#flush manually (tttsaurus) * 6b05a18 Remove stray TODO (Kuba663) * 0be8f2e Errors fixed (Kuba663) * 8a4a2f1 Merge branch 'CleanroomMC:proposal/render-system' into proposal/render-system (Eerie) * d4b75aa Forgot I have to flush (Kuba663) * 2b6ddbc Create Entities (Kuba663) * ac2214a Function to set values in MeshletComponent (Kuba663) * 44f8d38 Remove unused imports (Kuba663) * e018a8a Switch set to list (Kuba663) * c302ad8 Normal getter function (Kuba663) * d3e4674 Incomplete chunk meshlet entity creation (misclicked and commited with the same message twice) (Kuba663) * 72a652c Transfer of Blocks from Meshlet to a Set to be used in MeshletComponent (Kuba663) * 3637d4a Removed faces from Block (maybe temporarily) (Kuba663) * 2021987 Meshlet clustering (Kuba663) * d7948a8 Selection of optimal starting points for Meshlet building (Kuba663) * cab3c82 k-nearest neighbour search test (Kuba663) * 18d8835 buildKDTree (Kuba663) * 9892112 Altered the knn function for easier vector lookups (Kuba663) * b07b6f4 Expanding Meshlet bounding box (Kuba663) * 4ae0b1c Replace magic number bitmasks with variables (Kuba663) * 7326639 Move FSM tests to it's own package (Kuba663) * 6384324 kD-tree point deletion (Kuba663) * be32697 kD-tree rewrite (Kuba663) * ec6cd56 Mistake (Kuba663) * 707ff5e Make Meshlet Comparable for utility (Kuba663) * f168d2b Use vectors instead of numbers you retard (Kuba663) * 3374474 Forgot this was a thing (IntelliJ does not commit file content) (Kuba663) * 1ad931b Meshlet class for operations in system + package rename (Kuba663) * 4f79acb getChildren function (Kuba663) * b432340 Forgot something in the KDTree (Kuba663) * 746d815 Adding fields to the MeshletComponent (Kuba663) * 94347c4 Fix (Kuba663) * e35aca5 Fix (Kuba663) * e132650 Building the k-d tree (Kuba663) * a824648 isEmpty on KDTree (Kuba663) * 50fe384 Documentation on compress (Kuba663) * 2ce0320 k-d tree (Kuba663) * cfb70ba Median of medians (Kuba663) * 9a01610 Median of medians (Kuba663) * 658c194 Not sure about bitfields being available for CleanStructs (Kuba663) * ea3fd89 Fix warnings (Kuba663) * e71e62e Octree implementation (Kuba663) * fbfd327 Block CleanStruct (Kuba663)
1 parent 2280a47 commit c4cb569

File tree

28 files changed

+972
-106
lines changed

28 files changed

+972
-106
lines changed

src/main/java/com/cleanroommc/kirino/KirinoCore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public static void updateAndRender(long finishTimeNano) {
172172
//</editor-fold>
173173

174174
KIRINO_ENGINE.renderingCoordinator.update();
175-
// KIRINO_ENGINE.renderingCoordinator.updateWorld(MINECRAFT.world);
175+
KIRINO_ENGINE.renderingCoordinator.updateWorld(MINECRAFT.world);
176176
// KIRINO_ENGINE.renderingCoordinator.runChunkPass();
177177

178178
//<editor-fold desc="vanilla logic">

src/main/java/com/cleanroommc/kirino/ecs/component/ComponentRegistry.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.google.common.collect.BiMap;
1111
import com.google.common.collect.HashBiMap;
1212
import com.google.common.collect.ImmutableMap;
13+
import org.jspecify.annotations.NonNull;
1314
import org.jspecify.annotations.Nullable;
1415

1516
import java.util.*;
@@ -317,7 +318,8 @@ public ICleanComponent newComponent(String name, Object... args) {
317318
// -----Component Deconstruction-----
318319

319320
@SuppressWarnings("DataFlowIssue")
320-
public Object[] flattenComponent(ICleanComponent component) {
321+
public @NonNull Object[] flattenComponent(@NonNull ICleanComponent component) {
322+
Preconditions.checkNotNull(component);
321323
Preconditions.checkArgument(componentExists(component.getClass()),
322324
"Component class %s isn't registered.", component.getClass().getName());
323325

src/main/java/com/cleanroommc/kirino/ecs/component/schema/def/field/FieldRegistry.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package com.cleanroommc.kirino.ecs.component.schema.def.field;
22

3+
import com.cleanroommc.kirino.KirinoCore;
34
import com.cleanroommc.kirino.ecs.component.schema.def.field.scalar.ScalarConstructor;
45
import com.cleanroommc.kirino.ecs.component.schema.def.field.scalar.ScalarDeconstructor;
56
import com.cleanroommc.kirino.ecs.component.schema.def.field.struct.StructRegistry;
7+
import com.cleanroommc.kirino.engine.render.geometry.AABB;
68
import com.cleanroommc.kirino.utils.TypeUtils;
79
import com.google.common.base.Preconditions;
810
import com.google.common.collect.BiMap;
911
import com.google.common.collect.HashBiMap;
12+
import org.jspecify.annotations.NonNull;
1013
import org.jspecify.annotations.Nullable;
1114

1215
import java.util.HashMap;
@@ -109,10 +112,15 @@ public Object newField(String name, Object... args) {
109112
// -----Field Deconstruction-----
110113

111114
@SuppressWarnings("DataFlowIssue")
112-
public Object[] flattenField(Object fieldInstance) {
113-
// force primitive types cuz we use primitive types by default
114-
// see CleanECSRuntime's constructor
115-
Class<?> fieldClass = TypeUtils.toPrimitive(fieldInstance.getClass());
115+
public @NonNull Object[] flattenField(@NonNull Object fieldInstance) {
116+
Preconditions.checkNotNull(fieldInstance);
117+
118+
Class<?> fieldClass = fieldInstance.getClass();
119+
if (TypeUtils.isWrappedPrimitive(fieldClass)) {
120+
// force primitive types cuz we use primitive types by default
121+
// see CleanECSRuntime's constructor
122+
fieldClass = TypeUtils.toPrimitive(fieldInstance.getClass());
123+
}
116124

117125
Preconditions.checkArgument(fieldTypeExists(fieldClass),
118126
"Field class %s isn't registered.", fieldInstance.getClass().getName());

src/main/java/com/cleanroommc/kirino/ecs/component/schema/def/field/scalar/ScalarDeconstructor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ public final class ScalarDeconstructor {
88
private ScalarDeconstructor() {
99
}
1010

11-
public static Object[] flattenScalar(@NonNull ScalarType scalarType, @NonNull Object scalarInstance) {
12-
Preconditions.checkNotNull(scalarInstance, "Scalar instance is null.");
11+
public static @NonNull Object[] flattenScalar(@NonNull ScalarType scalarType, @NonNull Object scalarInstance) {
12+
Preconditions.checkNotNull(scalarType);
13+
Preconditions.checkNotNull(scalarInstance);
1314

1415
switch (scalarType) {
1516
case INT -> {

src/main/java/com/cleanroommc/kirino/ecs/component/schema/def/field/struct/StructRegistry.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.google.common.collect.BiMap;
1313
import com.google.common.collect.HashBiMap;
1414
import com.google.common.collect.ImmutableMap;
15+
import org.jspecify.annotations.NonNull;
1516
import org.jspecify.annotations.Nullable;
1617

1718
import java.util.*;
@@ -325,7 +326,8 @@ public Object newStruct(String name, Object... args) {
325326
// -----Struct Deconstruction-----
326327

327328
@SuppressWarnings("DataFlowIssue")
328-
public Object[] flattenStruct(Object structInstance) {
329+
public @NonNull Object[] flattenStruct(@NonNull Object structInstance) {
330+
Preconditions.checkNotNull(structInstance);
329331
Preconditions.checkArgument(structTypeExists(structInstance.getClass()),
330332
"Struct class %s isn't registered.", structInstance.getClass().getName());
331333

src/main/java/com/cleanroommc/kirino/ecs/entity/EntityManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ public EntityQuery newQuery() {
6767
return result;
6868
}
6969

70+
// test only for now
71+
public synchronized void abort() {
72+
synchronized (commandBuffer) {
73+
commandBuffer.clear();
74+
}
75+
}
76+
7077
/**
7178
* Consume all buffered commands.
7279
* </br></br>

src/main/java/com/cleanroommc/kirino/ecs/job/JobRegistry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ public void registerParallelJob(Class<? extends IParallelJob> clazz) {
6969
for (Field field : clazz.getDeclaredFields()) {
7070
// scan JobDataQuery
7171
if (field.isAnnotationPresent(JobDataQuery.class) && !Modifier.isStatic(field.getModifiers())) {
72-
if (!IPrimitiveArray.class.isAssignableFrom(field.getType())) {
73-
throw new RuntimeException(exceptionText, new IllegalStateException("INativeArray must be assignable from the JobDataQuery-annotated field " + field.getName() + "."));
72+
if (IPrimitiveArray.class != field.getType()) {
73+
throw new RuntimeException(exceptionText, new IllegalStateException("IPrimitiveArray must be the type of the JobDataQuery-annotated field " + field.getName() + "."));
7474
}
7575

7676
JobDataQuery jobDataQuery = field.getAnnotation(JobDataQuery.class);

src/main/java/com/cleanroommc/kirino/ecs/job/JobScheduler.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.cleanroommc.kirino.ecs.storage.ArchetypeDataPool;
77
import com.cleanroommc.kirino.ecs.storage.ArrayRange;
88
import com.cleanroommc.kirino.ecs.storage.IPrimitiveArray;
9+
import com.google.common.base.Preconditions;
910
import org.jspecify.annotations.Nullable;
1011

1112
import java.util.ArrayList;
@@ -29,6 +30,16 @@ public void executeParallel(EntityManager entityManager, Class<? extends IParall
2930
throw new IllegalStateException("Parallel job class " + clazz.getName() + " isn't registered.");
3031
}
3132

33+
if (!parallelJobExternalDataQueries.isEmpty()) {
34+
Preconditions.checkArgument(externalData != null,
35+
"Argument \"externalData\" must not be null since there are %d external data queries.", parallelJobExternalDataQueries.size());
36+
37+
for (String key : parallelJobExternalDataQueries.keySet()) {
38+
Preconditions.checkArgument(externalData.containsKey(key),
39+
"Missing the entry \"%s\" from \"externalData\".", key);
40+
}
41+
}
42+
3243
EntityQuery query = entityManager.newQuery();
3344
((IParallelJob) instantiator.instantiate()).query(query);
3445
List<ArchetypeDataPool> archetypes = entityManager.startQuery(query);

src/main/java/com/cleanroommc/kirino/engine/render/RenderingCoordinator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ public RenderingCoordinator(EventBus eventBus, Logger logger, CleanECSRuntime ec
9898

9999
stateBackup = new GLStateBackup();
100100

101-
scene = new MinecraftScene(ecsRuntime.entityManager, ecsRuntime.jobScheduler);
102-
camera = new MinecraftCamera();
103-
104101
cullingPatch = new MinecraftCulling();
105102
entityRenderingPatch = new MinecraftEntityRendering(cullingPatch);
106103
tesrRenderingPatch = new MinecraftTESRRendering(cullingPatch);
@@ -126,6 +123,9 @@ public RenderingCoordinator(EventBus eventBus, Logger logger, CleanECSRuntime ec
126123

127124
gizmosManager = new GizmosManager(graphicResourceManager);
128125

126+
scene = new MinecraftScene(ecsRuntime.entityManager, ecsRuntime.jobScheduler, gizmosManager);
127+
camera = new MinecraftCamera();
128+
129129
// stagingBufferManager.genPersistentBuffers("default", 256, 256);
130130

131131
ShaderProgram shaderProgram = shaderRegistry.newShaderProgram("forge:shaders/gizmos.vert", "forge:shaders/gizmos.frag");
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.cleanroommc.kirino.engine.render.geometry;
2+
3+
import com.cleanroommc.kirino.ecs.component.scan.CleanStruct;
4+
import org.joml.Vector3i;
5+
6+
@CleanStruct
7+
public class Block {
8+
public Vector3i position;
9+
public int faceMask;
10+
11+
public Block() {
12+
position = new Vector3i();
13+
faceMask = 0b111111;
14+
}
15+
16+
public Block(int x, int y, int z, int faceMask) {
17+
position = new Vector3i(x, y, z);
18+
this.faceMask = faceMask;
19+
}
20+
21+
/**
22+
* <p>Compresses the block rendering record into an integer</p>
23+
* <p>
24+
* The integer is formatted as: <table>
25+
* <tr>
26+
* <th>17</th>
27+
* <th>16</th>
28+
* <th>15</th>
29+
* <th>14</th>
30+
* <th>13</th>
31+
* <th>12</th>
32+
* <th>11</th>
33+
* <th>10</th>
34+
* <th>9</th>
35+
* <th>8</th>
36+
* <th>7</th>
37+
* <th>6</th>
38+
* <th>5</th>
39+
* <th>4</th>
40+
* <th>3</th>
41+
* <th>2</th>
42+
* <th>1</th>
43+
* <th>0</th>
44+
* </tr>
45+
* <tr>
46+
* <th>z</th>
47+
* <th>z</th>
48+
* <th>z</th>
49+
* <th>z</th>
50+
* <th>y</th>
51+
* <th>y</th>
52+
* <th>y</th>
53+
* <th>y</th>
54+
* <th>x</th>
55+
* <th>x</th>
56+
* <th>x</th>
57+
* <th>x</th>
58+
* <th>f</th>
59+
* <th>f</th>
60+
* <th>f</th>
61+
* <th>f</th>
62+
* <th>f</th>
63+
* <th>f</th>
64+
* </tr>
65+
* </table>
66+
* </p>
67+
* <p>
68+
* Where:
69+
* <table>
70+
* <tr>
71+
* <th>x</th>
72+
* <th>the x position of the block in the 16x16x16 cutout of the chunk</th>
73+
* </tr>
74+
* <tr>
75+
* <th>y</th>
76+
* <th>the y position of the block in the 16x16x16 cutout of the chunk</th>
77+
* </tr>
78+
* <tr>
79+
* <th>z</th>
80+
* <th>the z position of the block in the 16x16x16 cutout of the chunk</th>
81+
* </tr>
82+
* <tr>
83+
* <th>f</th>
84+
* <th>A bitfield of the sides to be rendered. From the right in order:
85+
* Down, Up, North, South, West, East</th>
86+
* </tr>
87+
* </table>
88+
* </p>
89+
* @return The integer as described above
90+
*/
91+
int compress() {
92+
return (position.x & 0b1111) << 14
93+
| (position.y & 0b1111) << 10
94+
| (position.z & 0b1111) << 6;
95+
}
96+
}

0 commit comments

Comments
 (0)