Skip to content

Commit

Permalink
SmoothLit joins the battle
Browse files Browse the repository at this point in the history
- Not attached to the name
- Add SmoothLitVisual opt in interface, allowing any visuals to
  contribute light sections to the arena
- Remove lightChunks from VisualEmbedding, it has been usurped
- Pass total collected light sections from BEs, Es, and effects to the
  engine interface. It seemed the most proper way to hand off
  information from the impl to the backend
- Add SmoothLitVisualStorage to maintain the set of collected sections,
  though at the moment it is very naive and simply unions everything
  upon request, which is also naively done every frame
  • Loading branch information
Jozufozu committed Jul 13, 2024
1 parent 39237e1 commit 4b04d74
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import dev.engine_room.flywheel.api.task.Plan;
import dev.engine_room.flywheel.api.task.TaskExecutor;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.client.Camera;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
Expand Down Expand Up @@ -68,6 +69,13 @@ public interface Engine {
*/
void delete();

/**
* Assign the set of sections that visuals have requested GPU light for.
*
* @param sections The set of sections.
*/
void lightSections(LongSet sections);

/**
* A block to be rendered as a crumbling overlay.
* @param progress The progress of the crumbling animation in the range [0, 10).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.function.LongConsumer;

import org.jetbrains.annotations.ApiStatus;

import net.minecraft.core.SectionPos;

/**
Expand Down Expand Up @@ -51,6 +53,7 @@ public interface LitVisual extends Visual {
* A notifier object that can be used to indicate to the impl
* that the sections a visual is contained in have changed.
*/
@ApiStatus.NonExtendable
interface Notifier {
/**
* Invoke this to indicate to the impl that your visual has moved to a different set of sections.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package dev.engine_room.flywheel.api.visual;

import org.jetbrains.annotations.ApiStatus;

import it.unimi.dsi.fastutil.longs.LongSet;

public interface SmoothLitVisual extends Visual {
/**
* Set the section property object.
*
* <p>This method is only called once, upon visual creation,
*
* @param property The property.
*/
void setSectionProperty(SectionProperty property);

@ApiStatus.NonExtendable
interface SectionProperty {
/**
* Invoke this to indicate to the impl that your visual has moved to a different set of sections.
*/
void lightSections(LongSet sections);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import org.joml.Matrix4fc;

import dev.engine_room.flywheel.api.BackendImplemented;
import it.unimi.dsi.fastutil.longs.LongSet;

@BackendImplemented
public interface VisualEmbedding extends VisualizationContext {
Expand All @@ -16,8 +15,6 @@ public interface VisualEmbedding extends VisualizationContext {
*/
void transforms(Matrix4fc pose, Matrix3fc normal);

void lightChunks(LongSet chunks);

/**
* Delete this embedding.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import dev.engine_room.flywheel.lib.task.Flag;
import dev.engine_room.flywheel.lib.task.NamedFlag;
import dev.engine_room.flywheel.lib.task.SyncedPlan;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.client.Camera;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
Expand All @@ -41,7 +42,7 @@ public EngineImpl(LevelAccessor level, DrawManager<? extends AbstractInstancer<?
this.drawManager = drawManager;
sqrMaxOriginDistance = maxOriginDistance * maxOriginDistance;
environmentStorage = new EnvironmentStorage();
lightStorage = new LightStorage(level, environmentStorage);
lightStorage = new LightStorage(level);
}

@Override
Expand Down Expand Up @@ -101,6 +102,11 @@ public void delete() {
lightStorage.delete();
}

@Override
public void lightSections(LongSet sections) {
lightStorage.sections(sections);
}

public <I extends Instance> Instancer<I> instancer(Environment environment, InstanceType<I> type, Model model, RenderStage stage) {
return drawManager.getInstancer(environment, type, model, stage);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package dev.engine_room.flywheel.backend.engine;

import dev.engine_room.flywheel.backend.engine.embed.AbstractEmbeddedEnvironment;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceSet;
import it.unimi.dsi.fastutil.objects.ReferenceSets;
Expand All @@ -18,10 +16,4 @@ public void flush() {
environments.removeIf(AbstractEmbeddedEnvironment::isDeleted);
environments.forEach(AbstractEmbeddedEnvironment::flush);
}

public LongSet allLightSections() {
var out = new LongOpenHashSet();
environments.forEach(e -> e.addLightSections(out));
return out;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import dev.engine_room.flywheel.backend.compile.ContextShader;
import dev.engine_room.flywheel.backend.engine.EngineImpl;
import dev.engine_room.flywheel.backend.gl.shader.GlProgram;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.core.Vec3i;

public abstract class AbstractEmbeddedEnvironment implements Environment, VisualEmbedding {
Expand Down Expand Up @@ -95,10 +94,6 @@ public boolean isDeleted() {
return deleted;
}

public void addLightSections(LongSet out) {

}

/**
* Called by visuals
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import java.util.BitSet;

import org.jetbrains.annotations.Nullable;
import org.lwjgl.system.MemoryUtil;

import dev.engine_room.flywheel.api.event.RenderContext;
import dev.engine_room.flywheel.api.task.Plan;
import dev.engine_room.flywheel.backend.engine.EnvironmentStorage;
import dev.engine_room.flywheel.backend.engine.indirect.StagingBuffer;
import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer;
import dev.engine_room.flywheel.lib.task.SimplePlan;
Expand Down Expand Up @@ -40,7 +40,6 @@ public class LightStorage {
private static final int INVALID_SECTION = -1;

private final LevelAccessor level;
private final EnvironmentStorage environmentStorage;

private final Arena arena;
private final Long2IntMap section2ArenaIndex = new Long2IntOpenHashMap();
Expand All @@ -51,41 +50,49 @@ public class LightStorage {
private final BitSet changed = new BitSet();
private boolean needsLutRebuild = false;

public LightStorage(LevelAccessor level, EnvironmentStorage environmentStorage) {
@Nullable
private LongSet requestedSections;

public LightStorage(LevelAccessor level) {
this.level = level;
this.environmentStorage = environmentStorage;

arena = new Arena(SECTION_SIZE_BYTES, DEFAULT_ARENA_CAPACITY_SECTIONS);
}

public void sections(LongSet sections) {
requestedSections = sections;
}

public Plan<RenderContext> createFramePlan() {
return SimplePlan.of(() -> {
var allLightSections = environmentStorage.allLightSections();
if (requestedSections == null) {
return;
}

removeUnusedSections(allLightSections);
removeUnusedSections(requestedSections);

var knownSections = section2ArenaIndex.keySet();

var updatedSections = LightUpdateHolder.get(level)
.getUpdatedSections();

// Only add the new sections.
allLightSections.removeAll(knownSections);
requestedSections.removeAll(knownSections);

for (long updatedSection : updatedSections) {
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
for (int z = -1; z <= 1; z++) {
long section = SectionPos.offset(updatedSection, x, y, z);
if (knownSections.contains(section)) {
allLightSections.add(section);
requestedSections.add(section);
}
}
}
}
}

for (long section : allLightSections) {
for (long section : requestedSections) {
addSection(section);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import dev.engine_room.flywheel.api.event.RenderStage;
import dev.engine_room.flywheel.backend.engine.EngineImpl;
import it.unimi.dsi.fastutil.longs.LongSet;

public class NestedEmbeddedEnvironment extends AbstractEmbeddedEnvironment {
private final AbstractEmbeddedEnvironment parent;
Expand All @@ -15,11 +14,6 @@ public NestedEmbeddedEnvironment(AbstractEmbeddedEnvironment parent, EngineImpl
this.parent = parent;
}

@Override
public void lightChunks(LongSet chunks) {
// noop
}

@Override
public void composeMatrices(Matrix4f pose, Matrix3f normal) {
parent.composeMatrices(pose, normal);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,12 @@

import dev.engine_room.flywheel.api.event.RenderStage;
import dev.engine_room.flywheel.backend.engine.EngineImpl;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;

public class TopLevelEmbeddedEnvironment extends AbstractEmbeddedEnvironment {
private final LongSet lightSections = new LongArraySet();

public TopLevelEmbeddedEnvironment(EngineImpl engine, RenderStage renderStage) {
super(engine, renderStage);
}

@Override
public void lightChunks(LongSet chunks) {
lightSections.clear();
lightSections.addAll(chunks);
}

@Override
public void addLightSections(LongSet out) {
out.addAll(lightSections);
}

@Override
public void composeMatrices(Matrix4f pose, Matrix3f normal) {
pose.set(this.pose);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import dev.engine_room.flywheel.lib.task.SimplePlan;
import dev.engine_room.flywheel.lib.util.LevelAttached;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.minecraft.client.Minecraft;
import net.minecraft.core.Vec3i;
import net.minecraft.server.level.BlockDestructionProgress;
Expand Down Expand Up @@ -104,6 +105,14 @@ private VisualizationManagerImpl(LevelAccessor level) {
.ifTrue(recreate)
.ifFalse(update)
.plan()
.then(SimplePlan.of(() -> {
// TODO: Lazily re-evaluate the union'd set
var out = new LongOpenHashSet();
out.addAll(blockEntities.lightSections());
out.addAll(entities.lightSections());
out.addAll(effects.lightSections());
engine.lightSections(out);
}))
.then(RaisePlan.raise(frameVisualsFlag))
.then(engine.createFramePlan())
.then(RaisePlan.raise(frameFlag));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import dev.engine_room.flywheel.impl.visualization.storage.Storage;
import dev.engine_room.flywheel.impl.visualization.storage.Transaction;
import dev.engine_room.flywheel.lib.task.SimplePlan;
import it.unimi.dsi.fastutil.longs.LongSet;

public class VisualManagerImpl<T, S extends Storage<T>> implements VisualManager<T> {
private final Queue<Transaction<T>> queue = new ConcurrentLinkedQueue<>();
Expand Down Expand Up @@ -74,4 +75,8 @@ public Plan<TickableVisual.Context> tickPlan() {
return SimplePlan.<TickableVisual.Context>of(context -> processQueue(1))
.then(storage.tickPlan());
}

public LongSet lightSections() {
return getStorage().lightSections();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dev.engine_room.flywheel.impl.visualization.storage;

import java.util.Map;

import dev.engine_room.flywheel.api.visual.SmoothLitVisual;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;

public class SmoothLitVisualStorage {
private final Map<SmoothLitVisual, SectionProperty> visuals = new Reference2ObjectOpenHashMap<>();

public LongSet sections() {
var out = new LongOpenHashSet();
for (SectionProperty value : visuals.values()) {
out.addAll(value.sections);
}
return out;
}

public void remove(SmoothLitVisual smoothLit) {
visuals.remove(smoothLit);
}

public void add(SmoothLitVisual smoothLit) {
var sections = new SectionProperty();
visuals.put(smoothLit, sections);
smoothLit.setSectionProperty(sections);
}

public void clear() {
visuals.clear();
}

private static final class SectionProperty implements SmoothLitVisual.SectionProperty {
private final LongSet sections = new LongArraySet();

@Override
public void lightSections(LongSet sections) {
this.sections.clear();
this.sections.addAll(sections);
}
}
}
Loading

0 comments on commit 4b04d74

Please sign in to comment.