mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 07:26:48 +01:00
Don't take this out of context
- Make all context records in the API interfaces. - Move records to impl package. - Update *Visual docs. - Inline TickContext.
This commit is contained in:
parent
06359c6ea2
commit
3f8876b073
15 changed files with 152 additions and 51 deletions
|
@ -9,13 +9,20 @@ import net.minecraft.client.multiplayer.ClientLevel;
|
|||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
|
||||
public record RenderContext(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack,
|
||||
Matrix4f projection, Matrix4f viewProjection, Camera camera, float partialTick) {
|
||||
public static RenderContext create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack, Matrix4f projection, Camera camera, float partialTick) {
|
||||
Matrix4f viewProjection = new Matrix4f(projection);
|
||||
viewProjection.mul(stack.last()
|
||||
.pose());
|
||||
public interface RenderContext {
|
||||
LevelRenderer renderer();
|
||||
|
||||
return new RenderContext(renderer, level, buffers, stack, projection, viewProjection, camera, partialTick);
|
||||
}
|
||||
ClientLevel level();
|
||||
|
||||
RenderBuffers buffers();
|
||||
|
||||
PoseStack stack();
|
||||
|
||||
Matrix4f projection();
|
||||
|
||||
Matrix4f viewProjection();
|
||||
|
||||
Camera camera();
|
||||
|
||||
float partialTick();
|
||||
}
|
||||
|
|
|
@ -15,9 +15,12 @@ import com.jozufozu.flywheel.api.instance.Instancer;
|
|||
public interface DynamicVisual extends Visual {
|
||||
/**
|
||||
* Called every frame.
|
||||
* <p>
|
||||
* <b>DISPATCHED IN PARALLEL</b>. Ensure proper synchronization if you need to mutate anything outside this visual.
|
||||
* <p>
|
||||
* <br>
|
||||
* The implementation is free to parallelize calls to this method.
|
||||
* You must ensure proper synchronization if you need to mutate anything outside this visual.
|
||||
* <br>
|
||||
* This method and {@link TickableVisual#tick} will never be called simultaneously.
|
||||
* <br>
|
||||
* {@link Instancer}/{@link Instance} creation/acquisition is safe here.
|
||||
*/
|
||||
void beginFrame(VisualFrameContext ctx);
|
||||
|
|
|
@ -15,6 +15,11 @@ public interface LitVisual extends Visual {
|
|||
* Called when a section this visual is contained in receives a light update.
|
||||
* <br>
|
||||
* Even if multiple sections are updated at the same time, this method will only be called once.
|
||||
* <br>
|
||||
* The implementation is free to parallelize calls to this method, as well as call into
|
||||
* {@link DynamicVisual#beginFrame} simultaneously. It is safe to query/update light here,
|
||||
* but you must ensure proper synchronization if you want to mutate anything outside this
|
||||
* visual or anything that is also mutated by {@link DynamicVisual#beginFrame}.
|
||||
*/
|
||||
void updateLight();
|
||||
|
||||
|
|
|
@ -22,9 +22,12 @@ import com.jozufozu.flywheel.api.instance.Instancer;
|
|||
public interface TickableVisual extends Visual {
|
||||
/**
|
||||
* Called every tick.
|
||||
* <p>
|
||||
* <b>DISPATCHED IN PARALLEL</b>. Ensure proper synchronization if you need to mutate anything outside this visual.
|
||||
* <p>
|
||||
* <br>
|
||||
* The implementation is free to parallelize calls to this method.
|
||||
* You must ensure proper synchronization if you need to mutate anything outside this visual.
|
||||
* <br>
|
||||
* This method and {@link DynamicVisual#beginFrame} will never be called simultaneously.
|
||||
* <br>
|
||||
* {@link Instancer}/{@link Instance} creation/acquisition is safe here.
|
||||
*/
|
||||
void tick(VisualTickContext ctx);
|
||||
|
|
|
@ -5,6 +5,8 @@ package com.jozufozu.flywheel.api.visual;
|
|||
*
|
||||
* @see DynamicVisual
|
||||
* @see TickableVisual
|
||||
* @see PlannedVisual
|
||||
* @see LitVisual
|
||||
*/
|
||||
public interface Visual {
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,16 @@ package com.jozufozu.flywheel.api.visual;
|
|||
|
||||
import org.joml.FrustumIntersection;
|
||||
|
||||
public record VisualFrameContext(double cameraX, double cameraY, double cameraZ, FrustumIntersection frustum,
|
||||
float partialTick, DistanceUpdateLimiter limiter) {
|
||||
public interface VisualFrameContext {
|
||||
double cameraX();
|
||||
|
||||
double cameraY();
|
||||
|
||||
double cameraZ();
|
||||
|
||||
FrustumIntersection frustum();
|
||||
|
||||
float partialTick();
|
||||
|
||||
DistanceUpdateLimiter limiter();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
package com.jozufozu.flywheel.api.visual;
|
||||
|
||||
public record VisualTickContext(double cameraX, double cameraY, double cameraZ, DistanceUpdateLimiter limiter) {
|
||||
public interface VisualTickContext {
|
||||
double cameraX();
|
||||
|
||||
double cameraY();
|
||||
|
||||
double cameraZ();
|
||||
|
||||
DistanceUpdateLimiter limiter();
|
||||
}
|
||||
|
|
|
@ -6,10 +6,17 @@ import net.minecraft.core.Vec3i;
|
|||
|
||||
/**
|
||||
* A context object passed on visual creation.
|
||||
*
|
||||
* @param instancerProvider The {@link InstancerProvider} that the visual can use to get instancers to render models.
|
||||
* @param renderOrigin The origin of the renderer as a world position.
|
||||
* All models render as if this position is (0, 0, 0).
|
||||
*/
|
||||
public record VisualizationContext(InstancerProvider instancerProvider, Vec3i renderOrigin) {
|
||||
public interface VisualizationContext {
|
||||
/**
|
||||
* @return The {@link InstancerProvider} that the visual can use to get instancers to render models.
|
||||
*/
|
||||
InstancerProvider instancerProvider();
|
||||
|
||||
/**
|
||||
* All models render as if this position is (0, 0, 0).
|
||||
*
|
||||
* @return The origin of the renderer as a world position.
|
||||
*/
|
||||
Vec3i renderOrigin();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package com.jozufozu.flywheel.impl.event;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
|
||||
public record RenderContextImpl(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack,
|
||||
Matrix4f projection, Matrix4f viewProjection, Camera camera,
|
||||
float partialTick) implements RenderContext {
|
||||
public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack, Matrix4f projection, Camera camera, float partialTick) {
|
||||
Matrix4f viewProjection = new Matrix4f(projection);
|
||||
viewProjection.mul(stack.last()
|
||||
.pose());
|
||||
|
||||
return new RenderContextImpl(renderer, level, buffers, stack, projection, viewProjection, camera, partialTick);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.jozufozu.flywheel.impl.visual;
|
||||
|
||||
import org.joml.FrustumIntersection;
|
||||
|
||||
import com.jozufozu.flywheel.api.visual.DistanceUpdateLimiter;
|
||||
import com.jozufozu.flywheel.api.visual.VisualFrameContext;
|
||||
|
||||
public record VisualFrameContextImpl(double cameraX, double cameraY, double cameraZ, FrustumIntersection frustum,
|
||||
float partialTick, DistanceUpdateLimiter limiter) implements VisualFrameContext {
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.jozufozu.flywheel.impl.visual;
|
||||
|
||||
import com.jozufozu.flywheel.api.visual.DistanceUpdateLimiter;
|
||||
import com.jozufozu.flywheel.api.visual.VisualTickContext;
|
||||
|
||||
public record VisualTickContextImpl(double cameraX, double cameraY, double cameraZ,
|
||||
DistanceUpdateLimiter limiter) implements VisualTickContext {
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
package com.jozufozu.flywheel.impl.visualization;
|
||||
|
||||
public record TickContext(double cameraX, double cameraY, double cameraZ) {
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.jozufozu.flywheel.impl.visualization;
|
||||
|
||||
import com.jozufozu.flywheel.api.instance.InstancerProvider;
|
||||
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
|
||||
|
||||
import net.minecraft.core.Vec3i;
|
||||
|
||||
/**
|
||||
* A context object passed on visual creation.
|
||||
*
|
||||
* @param instancerProvider The {@link InstancerProvider} that the visual can use to get instancers to render models.
|
||||
* @param renderOrigin The origin of the renderer as a world position.
|
||||
* All models render as if this position is (0, 0, 0).
|
||||
*/
|
||||
public record VisualizationContextImpl(InstancerProvider instancerProvider,
|
||||
Vec3i renderOrigin) implements VisualizationContext {
|
||||
}
|
|
@ -5,6 +5,7 @@ import java.util.List;
|
|||
import java.util.SortedSet;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.FrustumIntersection;
|
||||
import org.joml.Matrix4f;
|
||||
|
@ -28,6 +29,8 @@ import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
|||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.extension.LevelExtension;
|
||||
import com.jozufozu.flywheel.impl.task.FlwTaskExecutor;
|
||||
import com.jozufozu.flywheel.impl.visual.VisualFrameContextImpl;
|
||||
import com.jozufozu.flywheel.impl.visual.VisualTickContextImpl;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityStorage;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.EffectStorage;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.EntityStorage;
|
||||
|
@ -57,7 +60,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
/**
|
||||
* A manager class for a single world where visualization is supported.
|
||||
*/
|
||||
public class VisualizationManagerImpl implements VisualizationManager, Supplier<VisualizationContext> {
|
||||
public class VisualizationManagerImpl implements VisualizationManager {
|
||||
private static final LevelAttached<VisualizationManagerImpl> MANAGERS = new LevelAttached<>(VisualizationManagerImpl::new, VisualizationManagerImpl::delete);
|
||||
|
||||
private final Engine engine;
|
||||
|
@ -67,7 +70,7 @@ public class VisualizationManagerImpl implements VisualizationManager, Supplier<
|
|||
private final VisualManagerImpl<Entity, EntityStorage> entities;
|
||||
private final VisualManagerImpl<Effect, EffectStorage> effects;
|
||||
|
||||
private final Plan<TickContext> tickPlan;
|
||||
private final Plan<VisualTickContext> tickPlan;
|
||||
private final Plan<RenderContext> framePlan;
|
||||
|
||||
private final Flag tickFlag = new NamedFlag("tick");
|
||||
|
@ -85,18 +88,20 @@ public class VisualizationManagerImpl implements VisualizationManager, Supplier<
|
|||
.createEngine(level);
|
||||
taskExecutor = FlwTaskExecutor.get();
|
||||
|
||||
blockEntities = new VisualManagerImpl<>(new BlockEntityStorage(this));
|
||||
entities = new VisualManagerImpl<>(new EntityStorage(this));
|
||||
effects = new VisualManagerImpl<>(new EffectStorage(this));
|
||||
Supplier<VisualizationContext> contextSupplier = () -> new VisualizationContextImpl(engine, engine.renderOrigin());
|
||||
|
||||
var blockEntitiesStorage = blockEntities.getStorage();
|
||||
var entitiesStorage = entities.getStorage();
|
||||
var effectsStorage = effects.getStorage();
|
||||
tickPlan = MapContextPlan.map(this::createVisualTickContext)
|
||||
.to(NestedPlan.of(SimplePlan.<VisualTickContext>of(context -> blockEntities.processQueue(0))
|
||||
var blockEntitiesStorage = new BlockEntityStorage(contextSupplier);
|
||||
var entitiesStorage = new EntityStorage(contextSupplier);
|
||||
var effectsStorage = new EffectStorage(contextSupplier);
|
||||
|
||||
blockEntities = new VisualManagerImpl<>(blockEntitiesStorage);
|
||||
entities = new VisualManagerImpl<>(entitiesStorage);
|
||||
effects = new VisualManagerImpl<>(effectsStorage);
|
||||
|
||||
tickPlan = NestedPlan.of(SimplePlan.<VisualTickContext>of(context -> blockEntities.processQueue(0))
|
||||
.then(blockEntitiesStorage.getTickPlan()), SimplePlan.<VisualTickContext>of(context -> entities.processQueue(0))
|
||||
.then(entitiesStorage.getTickPlan()), SimplePlan.<VisualTickContext>of(context -> effects.processQueue(0))
|
||||
.then(effectsStorage.getTickPlan())))
|
||||
.then(effectsStorage.getTickPlan()))
|
||||
.then(RaisePlan.raise(tickFlag))
|
||||
.simplify();
|
||||
|
||||
|
@ -135,11 +140,7 @@ public class VisualizationManagerImpl implements VisualizationManager, Supplier<
|
|||
viewProjection.translate((float) (renderOrigin.getX() - cameraX), (float) (renderOrigin.getY() - cameraY), (float) (renderOrigin.getZ() - cameraZ));
|
||||
FrustumIntersection frustum = new FrustumIntersection(viewProjection);
|
||||
|
||||
return new VisualFrameContext(cameraX, cameraY, cameraZ, frustum, ctx.partialTick(), frameLimiter);
|
||||
}
|
||||
|
||||
private VisualTickContext createVisualTickContext(TickContext ctx) {
|
||||
return new VisualTickContext(ctx.cameraX(), ctx.cameraY(), ctx.cameraZ(), frameLimiter);
|
||||
return new VisualFrameContextImpl(cameraX, cameraY, cameraZ, frustum, ctx.partialTick(), frameLimiter);
|
||||
}
|
||||
|
||||
protected DistanceUpdateLimiterImpl createUpdateLimiter() {
|
||||
|
@ -151,6 +152,7 @@ public class VisualizationManagerImpl implements VisualizationManager, Supplier<
|
|||
}
|
||||
}
|
||||
|
||||
@Contract("null -> false")
|
||||
public static boolean supportsVisualization(@Nullable LevelAccessor level) {
|
||||
if (!BackendManager.isOn()) {
|
||||
return false;
|
||||
|
@ -198,11 +200,6 @@ public class VisualizationManagerImpl implements VisualizationManager, Supplier<
|
|||
MANAGERS.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisualizationContext get() {
|
||||
return new VisualizationContext(engine, engine.renderOrigin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getRenderOrigin() {
|
||||
return engine.renderOrigin();
|
||||
|
@ -239,7 +236,7 @@ public class VisualizationManagerImpl implements VisualizationManager, Supplier<
|
|||
|
||||
tickLimiter.tick();
|
||||
|
||||
tickPlan.execute(taskExecutor, new TickContext(cameraX, cameraY, cameraZ));
|
||||
tickPlan.execute(taskExecutor, new VisualTickContextImpl(cameraX, cameraY, cameraZ, frameLimiter));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.mixin;
|
|||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
|
@ -15,9 +16,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
|
||||
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
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.event.RenderContextImpl;
|
||||
import com.jozufozu.flywheel.impl.visualization.VisualizationManagerImpl;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
|
@ -45,12 +46,13 @@ abstract class LevelRendererMixin {
|
|||
private Long2ObjectMap<SortedSet<BlockDestructionProgress>> destructionProgress;
|
||||
|
||||
@Unique
|
||||
private RenderContext flywheel$renderContext;
|
||||
@Nullable
|
||||
private RenderContextImpl flywheel$renderContext;
|
||||
|
||||
// @Inject(method = "renderLevel", at = @At("HEAD"))
|
||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"))
|
||||
private void flywheel$beginRender(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
|
||||
flywheel$renderContext = RenderContext.create((LevelRenderer) (Object) this, level, renderBuffers, poseStack, projectionMatrix, camera, partialTick);
|
||||
flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, poseStack, projectionMatrix, camera, partialTick);
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(flywheel$renderContext));
|
||||
}
|
||||
|
@ -67,6 +69,10 @@ abstract class LevelRendererMixin {
|
|||
|
||||
@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$beforeRenderCrumbling(CallbackInfo ci) {
|
||||
if (flywheel$renderContext == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var manager = VisualizationManagerImpl.get(level);
|
||||
if (manager != null) {
|
||||
manager.renderCrumbling(flywheel$renderContext, destructionProgress);
|
||||
|
|
Loading…
Reference in a new issue