mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 07:26:48 +01:00
Plans yet to crumble
- Rename Engine#delete -> #invalidate per pepper's TODO. - Plans - Remove thenMap and andMap from Plan API. - Add builder for MapContextPlan for better composition. - Add IfElsePlan and Builder to "fork" on a condition. - VisualizationManagerImpl no longer rolls a special Plan class and instead uses a plan composition chain. - Crumbling - Not implemented yet!! But the skeleton is taking shape. - Remove LevelRendererAccessor, and instead directly pass the map of destructionProgress to the VisualizationManagerImpl when it's time to render crumbling instances. - Give Instances a Handle getter. - Add way to get a block entity visual at a given position. - Add Engine#renderCrumblingInstance stub.
This commit is contained in:
parent
e5cda8944e
commit
055ac161d8
19 changed files with 205 additions and 105 deletions
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.api.backend;
|
|||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.instance.Instance;
|
||||
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
||||
import com.jozufozu.flywheel.api.task.Plan;
|
||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||
|
@ -14,6 +15,8 @@ public interface Engine extends InstancerProvider {
|
|||
|
||||
void renderStage(TaskExecutor executor, RenderContext context, RenderStage stage);
|
||||
|
||||
void renderCrumblingInstance(TaskExecutor taskExecutor, RenderContext context, Instance instance, int progress);
|
||||
|
||||
/**
|
||||
* Maintain the render origin to be within a certain distance from the camera in all directions,
|
||||
* preventing floating point precision issues at high coordinates.
|
||||
|
@ -24,7 +27,5 @@ public interface Engine extends InstancerProvider {
|
|||
|
||||
Vec3i renderOrigin();
|
||||
|
||||
// TODO: "delete" implies that the object cannot be used afterwards, but all current implementations
|
||||
// support the "invalidate" contract as well, meaning they can be reused after this call. Rename?
|
||||
void delete();
|
||||
void invalidate();
|
||||
}
|
||||
|
|
|
@ -2,4 +2,6 @@ package com.jozufozu.flywheel.api.instance;
|
|||
|
||||
public interface Instance {
|
||||
InstanceType<?> type();
|
||||
|
||||
InstanceHandle handle();
|
||||
}
|
||||
|
|
|
@ -33,16 +33,6 @@ public interface Plan<C> {
|
|||
*/
|
||||
Plan<C> then(Plan<C> plan);
|
||||
|
||||
/**
|
||||
* Create a new plan that executes this plan, then transforms the context to execute the given plan.
|
||||
*
|
||||
* @param map A function that transforms the plan context.
|
||||
* @param plan The plan to execute after this plan with the transformed context.
|
||||
* @param <D> The type of the transformed context.
|
||||
* @return The composed plan.
|
||||
*/
|
||||
<D> Plan<C> thenMap(Function<C, D> map, Plan<D> plan);
|
||||
|
||||
/**
|
||||
* Create a new plan that executes this plan and the given plan in parallel.
|
||||
*
|
||||
|
@ -51,16 +41,6 @@ public interface Plan<C> {
|
|||
*/
|
||||
Plan<C> and(Plan<C> plan);
|
||||
|
||||
/**
|
||||
* Create a new plan that executes this plan and the given plan in parallel.
|
||||
*
|
||||
* @param map A function that transforms the plan context.
|
||||
* @param plan The plan to execute in parallel with this plan than accepts the transformed context.
|
||||
* @param <D> The type of the transformed context.
|
||||
* @return The composed plan.
|
||||
*/
|
||||
<D> Plan<C> andMap(Function<C, D> map, Plan<D> plan);
|
||||
|
||||
/**
|
||||
* If possible, create a new plan that accomplishes everything
|
||||
* this plan does but with a simpler execution schedule.
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.backend.engine;
|
|||
import com.jozufozu.flywheel.api.instance.InstanceHandle;
|
||||
|
||||
public class InstanceHandleImpl implements InstanceHandle {
|
||||
private final AbstractInstancer<?> instancer;
|
||||
public final AbstractInstancer<?> instancer;
|
||||
private int index;
|
||||
|
||||
public InstanceHandleImpl(AbstractInstancer<?> instancer, int index) {
|
||||
|
|
|
@ -93,13 +93,18 @@ public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan
|
|||
drawTracker.draw(stage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderCrumblingInstance(TaskExecutor taskExecutor, RenderContext context, Instance instance, int progress) {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRenderOriginChanged() {
|
||||
initializedInstancers.forEach(BatchedInstancer::clear);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
public void invalidate() {
|
||||
instancers.clear();
|
||||
|
||||
meshPools.values()
|
||||
|
|
|
@ -68,6 +68,11 @@ public class IndirectEngine extends AbstractEngine {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderCrumblingInstance(TaskExecutor taskExecutor, RenderContext context, Instance instance, int progress) {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
GlTextureUnit.T2.makeActive();
|
||||
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
|
||||
|
@ -85,7 +90,7 @@ public class IndirectEngine extends AbstractEngine {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
public void invalidate() {
|
||||
drawManager.invalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,11 @@ public class InstancingEngine extends AbstractEngine {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderCrumblingInstance(TaskExecutor taskExecutor, RenderContext context, Instance instance, int progress) {
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
GlTextureUnit.T2.makeActive();
|
||||
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
|
||||
|
@ -97,7 +102,7 @@ public class InstancingEngine extends AbstractEngine {
|
|||
continue;
|
||||
}
|
||||
|
||||
setup(shader);
|
||||
setup(shader, context);
|
||||
|
||||
shader.material().setup();
|
||||
|
||||
|
@ -109,7 +114,7 @@ public class InstancingEngine extends AbstractEngine {
|
|||
}
|
||||
}
|
||||
|
||||
private void setup(ShaderState desc) {
|
||||
private void setup(ShaderState desc, Context context) {
|
||||
var material = desc.material();
|
||||
var vertexType = desc.vertexType();
|
||||
var instanceType = desc.instanceType();
|
||||
|
@ -130,7 +135,7 @@ public class InstancingEngine extends AbstractEngine {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
public void invalidate() {
|
||||
drawManager.invalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import net.minecraft.core.Vec3i;
|
|||
|
||||
public record FrameContext(double cameraX, double cameraY, double cameraZ, FrustumIntersection frustum, float partialTick) {
|
||||
@NotNull
|
||||
public static FrameContext create(RenderContext context, Vec3i renderOrigin, float partialTick) {
|
||||
public static FrameContext create(RenderContext context, Vec3i renderOrigin) {
|
||||
var cameraPos = context.camera()
|
||||
.getPosition();
|
||||
double cameraX = cameraPos.x;
|
||||
|
@ -21,6 +21,6 @@ public record FrameContext(double cameraX, double cameraY, double cameraZ, Frust
|
|||
viewProjection.translate((float) (renderOrigin.getX() - cameraX), (float) (renderOrigin.getY() - cameraY), (float) (renderOrigin.getZ() - cameraZ));
|
||||
FrustumIntersection frustum = new FrustumIntersection(viewProjection);
|
||||
|
||||
return new FrameContext(cameraX, cameraY, cameraZ, frustum, partialTick);
|
||||
return new FrameContext(cameraX, cameraY, cameraZ, frustum, context.partialTick());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package com.jozufozu.flywheel.impl.visualization;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.api.backend.Engine;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.instance.Instance;
|
||||
import com.jozufozu.flywheel.api.task.Plan;
|
||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||
import com.jozufozu.flywheel.api.visual.DynamicVisual;
|
||||
|
@ -20,15 +23,17 @@ import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityVisualManager
|
|||
import com.jozufozu.flywheel.impl.visualization.manager.EffectVisualManager;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.EntityVisualManager;
|
||||
import com.jozufozu.flywheel.lib.task.Flag;
|
||||
import com.jozufozu.flywheel.lib.task.MapContextPlan;
|
||||
import com.jozufozu.flywheel.lib.task.NamedFlag;
|
||||
import com.jozufozu.flywheel.lib.task.NestedPlan;
|
||||
import com.jozufozu.flywheel.lib.task.RaisePlan;
|
||||
import com.jozufozu.flywheel.lib.task.SimplyComposedPlan;
|
||||
import com.jozufozu.flywheel.lib.task.IfElsePlan;
|
||||
import com.jozufozu.flywheel.lib.util.LevelAttached;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.server.level.BlockDestructionProgress;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
@ -50,7 +55,8 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
private final Plan<RenderContext> framePlan;
|
||||
|
||||
private final Flag tickFlag = new NamedFlag("tick");
|
||||
private final Flag frameFlag = new NamedFlag("frame");
|
||||
private final Flag frameVisualsFlag = new NamedFlag("frameVisualUpdates");
|
||||
private final Flag frameFlag = new NamedFlag("frameComplete");
|
||||
|
||||
private VisualizationManagerImpl(LevelAccessor level) {
|
||||
engine = BackendManager.getBackend()
|
||||
|
@ -66,7 +72,21 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
.and(effects.createTickPlan())
|
||||
.then(RaisePlan.raise(tickFlag))
|
||||
.simplify();
|
||||
framePlan = new FramePlan().then(RaisePlan.raise(frameFlag));
|
||||
|
||||
framePlan = IfElsePlan.on((RenderContext ctx) -> engine.updateRenderOrigin(ctx.camera()))
|
||||
.ifTrue(MapContextPlan.map(RenderContext::partialTick)
|
||||
.to(blockEntities.createRecreationPlan()
|
||||
.and(entities.createRecreationPlan())
|
||||
.and(effects.createRecreationPlan())))
|
||||
.ifFalse(MapContextPlan.map((RenderContext ctx) -> FrameContext.create(ctx, engine.renderOrigin()))
|
||||
.to(blockEntities.createFramePlan()
|
||||
.and(entities.createFramePlan())
|
||||
.and(effects.createFramePlan())))
|
||||
.plan()
|
||||
.then(RaisePlan.raise(frameVisualsFlag))
|
||||
.then(engine.createFramePlan())
|
||||
.then(RaisePlan.raise(frameFlag))
|
||||
.simplify();
|
||||
}
|
||||
|
||||
public static boolean supportsVisualization(@Nullable LevelAccessor level) {
|
||||
|
@ -171,6 +191,8 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
// Note we don't lower here because many frames may happen per tick.
|
||||
taskExecutor.syncUntil(tickFlag::isRaised);
|
||||
|
||||
frameVisualsFlag.lower();
|
||||
frameFlag.lower();
|
||||
framePlan.execute(taskExecutor, context);
|
||||
}
|
||||
|
||||
|
@ -181,6 +203,41 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
engine.renderStage(taskExecutor, context, stage);
|
||||
}
|
||||
|
||||
public void renderCrumbling(RenderContext context, Long2ObjectMap<SortedSet<BlockDestructionProgress>> destructionProgress) {
|
||||
taskExecutor.syncUntil(frameVisualsFlag::isRaised);
|
||||
|
||||
for (var entry : destructionProgress.long2ObjectEntrySet()) {
|
||||
var set = entry.getValue();
|
||||
if (set == null || set.isEmpty()) {
|
||||
// Nothing to do if there's no crumbling.
|
||||
continue;
|
||||
}
|
||||
|
||||
var visual = blockEntities.visualAtPos(entry.getLongKey());
|
||||
|
||||
if (visual == null) {
|
||||
// The block doesn't have a visual, this is probably the common case.
|
||||
continue;
|
||||
}
|
||||
|
||||
var instanceList = visual.getCrumblingInstances();
|
||||
|
||||
if (instanceList.isEmpty()) {
|
||||
// The visual doesn't want to render anything crumbling.
|
||||
continue;
|
||||
}
|
||||
|
||||
// now for the fun part
|
||||
|
||||
int progress = set.last()
|
||||
.getProgress();
|
||||
|
||||
for (Instance instance : instanceList) {
|
||||
engine.renderCrumblingInstance(taskExecutor, context, instance, progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all acquired resources and delete this manager.
|
||||
*/
|
||||
|
@ -192,29 +249,6 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
blockEntities.invalidate();
|
||||
entities.invalidate();
|
||||
effects.invalidate();
|
||||
engine.delete();
|
||||
}
|
||||
|
||||
private class FramePlan implements SimplyComposedPlan<RenderContext> {
|
||||
private final Plan<Float> recreationPlan = NestedPlan.of(blockEntities.createRecreationPlan(), entities.createRecreationPlan(), effects.createRecreationPlan());
|
||||
private final Plan<FrameContext> normalPlan = blockEntities.createFramePlan()
|
||||
.and(entities.createFramePlan())
|
||||
.and(effects.createFramePlan());
|
||||
|
||||
private final Plan<RenderContext> enginePlan = engine.createFramePlan();
|
||||
|
||||
@Override
|
||||
public void execute(TaskExecutor taskExecutor, RenderContext context, Runnable onCompletion) {
|
||||
Runnable then = () -> enginePlan.execute(taskExecutor, context, onCompletion);
|
||||
float partialTick = context.partialTick();
|
||||
|
||||
if (engine.updateRenderOrigin(context.camera())) {
|
||||
recreationPlan.execute(taskExecutor, partialTick, then);
|
||||
} else {
|
||||
var frameContext = FrameContext.create(context, engine.renderOrigin(), partialTick);
|
||||
|
||||
normalPlan.execute(taskExecutor, frameContext, then);
|
||||
}
|
||||
}
|
||||
engine.invalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.jozufozu.flywheel.impl.visualization.ratelimit.DistanceUpdateLimiterI
|
|||
import com.jozufozu.flywheel.impl.visualization.ratelimit.NonLimiter;
|
||||
import com.jozufozu.flywheel.impl.visualization.storage.Storage;
|
||||
import com.jozufozu.flywheel.impl.visualization.storage.Transaction;
|
||||
import com.jozufozu.flywheel.lib.task.MapContextPlan;
|
||||
import com.jozufozu.flywheel.lib.task.SimplePlan;
|
||||
|
||||
public abstract class AbstractVisualManager<T> implements VisualManager<T> {
|
||||
|
@ -88,7 +89,8 @@ public abstract class AbstractVisualManager<T> implements VisualManager<T> {
|
|||
tickLimiter.tick();
|
||||
processQueue(0);
|
||||
})
|
||||
.thenMap(this::createVisualTickContext, getStorage().getTickPlan());
|
||||
.then(MapContextPlan.map(this::createVisualTickContext)
|
||||
.to(getStorage().getTickPlan()));
|
||||
}
|
||||
|
||||
public Plan<FrameContext> createFramePlan() {
|
||||
|
@ -96,7 +98,8 @@ public abstract class AbstractVisualManager<T> implements VisualManager<T> {
|
|||
frameLimiter.tick();
|
||||
processQueue(context.partialTick());
|
||||
})
|
||||
.thenMap(this::createVisualContext, getStorage().getFramePlan());
|
||||
.then(MapContextPlan.map(this::createVisualContext)
|
||||
.to(getStorage().getFramePlan()));
|
||||
}
|
||||
|
||||
private VisualFrameContext createVisualContext(FrameContext ctx) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.jozufozu.flywheel.impl.visualization.manager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.Engine;
|
||||
|
@ -30,11 +28,8 @@ public class BlockEntityVisualManager extends AbstractVisualManager<BlockEntity>
|
|||
return storage;
|
||||
}
|
||||
|
||||
public void getCrumblingVisuals(long pos, List<BlockEntityVisual<?>> visuals) {
|
||||
BlockEntityVisual<?> visual = storage.posLookup.get(pos);
|
||||
if (visual != null) {
|
||||
visuals.add(visual);
|
||||
}
|
||||
public BlockEntityVisual<?> visualAtPos(long pos) {
|
||||
return storage.posLookup.get(pos);
|
||||
}
|
||||
|
||||
private static class BlockEntityStorage extends Storage<BlockEntity> {
|
||||
|
|
|
@ -18,6 +18,11 @@ public abstract class AbstractInstance implements Instance {
|
|||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceHandle handle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public final void setChanged() {
|
||||
handle.setChanged();
|
||||
}
|
||||
|
|
65
src/main/java/com/jozufozu/flywheel/lib/task/IfElsePlan.java
Normal file
65
src/main/java/com/jozufozu/flywheel/lib/task/IfElsePlan.java
Normal file
|
@ -0,0 +1,65 @@
|
|||
package com.jozufozu.flywheel.lib.task;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.jozufozu.flywheel.api.task.Plan;
|
||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||
|
||||
/**
|
||||
* Executes one plan or another, depending on a dynamically evaluated condition.
|
||||
* @param condition The condition to branch on.
|
||||
* @param onTrue The plan to execute if the condition is true.
|
||||
* @param onFalse The plan to execute if the condition is false.
|
||||
* @param <C> The type of the context object.
|
||||
*/
|
||||
public record IfElsePlan<C>(Predicate<C> condition, Plan<C> onTrue, Plan<C> onFalse) implements SimplyComposedPlan<C> {
|
||||
public static <C> Builder<C> on(Predicate<C> condition) {
|
||||
return new Builder<>(condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(TaskExecutor taskExecutor, C context, Runnable onCompletion) {
|
||||
if (condition.test(context)) {
|
||||
onTrue.execute(taskExecutor, context, onCompletion);
|
||||
} else {
|
||||
onFalse.execute(taskExecutor, context, onCompletion);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan<C> simplify() {
|
||||
var maybeSimplifiedTrue = onTrue.simplify();
|
||||
var maybeSimplifiedFalse = onFalse.simplify();
|
||||
|
||||
if (maybeSimplifiedTrue instanceof UnitPlan && maybeSimplifiedFalse instanceof UnitPlan) {
|
||||
// The condition may have side effects that still need to be evaluated.
|
||||
return SimplePlan.of(condition::test);
|
||||
}
|
||||
|
||||
return new IfElsePlan<>(condition, maybeSimplifiedTrue, maybeSimplifiedFalse);
|
||||
}
|
||||
|
||||
public static class Builder<C> {
|
||||
private final Predicate<C> condition;
|
||||
private Plan<C> onTrue = UnitPlan.of();
|
||||
private Plan<C> onFalse = UnitPlan.of();
|
||||
|
||||
public Builder(Predicate<C> condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public Builder<C> ifTrue(Plan<C> onTrue) {
|
||||
this.onTrue = onTrue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<C> ifFalse(Plan<C> onFalse) {
|
||||
this.onFalse = onFalse;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IfElsePlan<C> plan() {
|
||||
return new IfElsePlan<>(condition, onTrue, onFalse);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,10 @@ import com.jozufozu.flywheel.api.task.Plan;
|
|||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||
|
||||
public record MapContextPlan<C, D>(Function<C, D> map, Plan<D> plan) implements SimplyComposedPlan<C> {
|
||||
public static <C, D> Builder<C, D> map(Function<C, D> map) {
|
||||
return new Builder<>(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(TaskExecutor taskExecutor, C context, Runnable onCompletion) {
|
||||
D newContext = map.apply(context);
|
||||
|
@ -22,4 +26,20 @@ public record MapContextPlan<C, D>(Function<C, D> map, Plan<D> plan) implements
|
|||
|
||||
return new MapContextPlan<>(map, maybeSimplified);
|
||||
}
|
||||
|
||||
public static class Builder<C, D> {
|
||||
private final Function<C, D> map;
|
||||
|
||||
public Builder(Function<C, D> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public MapContextPlan<C, D> to(Plan<D> plan) {
|
||||
return new MapContextPlan<>(map, plan);
|
||||
}
|
||||
|
||||
public MapContextPlan<C, D> plan() {
|
||||
return new MapContextPlan<>(map, UnitPlan.of());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,21 +10,11 @@ public interface SimplyComposedPlan<C> extends Plan<C> {
|
|||
return new BarrierPlan<>(this, plan);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <D> Plan<C> thenMap(Function<C, D> map, Plan<D> plan) {
|
||||
return then(new MapContextPlan<>(map, plan));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Plan<C> and(Plan<C> plan) {
|
||||
return NestedPlan.of(this, plan);
|
||||
}
|
||||
|
||||
@Override
|
||||
default <D> Plan<C> andMap(Function<C, D> map, Plan<D> plan) {
|
||||
return and(new MapContextPlan<>(map, plan));
|
||||
}
|
||||
|
||||
@Override
|
||||
default Plan<C> simplify() {
|
||||
return this;
|
||||
|
|
|
@ -26,21 +26,11 @@ public class UnitPlan<C> implements Plan<C> {
|
|||
return plan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D> Plan<C> thenMap(Function<C, D> map, Plan<D> plan) {
|
||||
return new MapContextPlan<>(map, plan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan<C> and(Plan<C> plan) {
|
||||
return plan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D> Plan<C> andMap(Function<C, D> map, Plan<D> plan) {
|
||||
return new MapContextPlan<>(map, plan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan<C> simplify() {
|
||||
return this;
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
package com.jozufozu.flywheel.mixin;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.server.level.BlockDestructionProgress;
|
||||
|
||||
@Mixin(LevelRenderer.class)
|
||||
public interface LevelRendererAccessor {
|
||||
@Accessor("destructionProgress")
|
||||
Long2ObjectMap<SortedSet<BlockDestructionProgress>> flywheel$getDestructionProgress();
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.jozufozu.flywheel.mixin;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
@ -16,14 +18,17 @@ import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
|
|||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||
import com.jozufozu.flywheel.api.event.RenderStageEvent;
|
||||
import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
import net.minecraft.server.level.BlockDestructionProgress;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after Sodium
|
||||
|
@ -35,6 +40,10 @@ public class LevelRendererMixin {
|
|||
@Final
|
||||
private RenderBuffers renderBuffers;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private Long2ObjectMap<SortedSet<BlockDestructionProgress>> destructionProgress;
|
||||
|
||||
@Unique
|
||||
private RenderContext flywheel$renderContext;
|
||||
|
||||
|
@ -142,4 +151,12 @@ public class LevelRendererMixin {
|
|||
private void flywheel$onStage$afterWeather(CallbackInfo ci) {
|
||||
flywheel$dispatch(RenderStage.AFTER_WEATHER);
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=destroyProgress"))
|
||||
private void flywheel$crumbling(CallbackInfo ci) {
|
||||
var vm = VisualizationManagerImpl.get(level);
|
||||
if (vm != null) {
|
||||
vm.renderCrumbling(flywheel$renderContext, destructionProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
"EntityTypeMixin",
|
||||
"FogUpdateMixin",
|
||||
"GlStateManagerMixin",
|
||||
"LevelRendererAccessor",
|
||||
"LevelRendererMixin",
|
||||
"LightUpdateMixin",
|
||||
"RenderTypeMixin",
|
||||
|
|
Loading…
Reference in a new issue