mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-27 23:47:38 +01:00
Some semblance of immersive portals compat.
- Each world gets its own KineticRenderer now.
This commit is contained in:
parent
52eed2bab3
commit
e1c16d869d
10 changed files with 92 additions and 45 deletions
|
@ -14,10 +14,13 @@ import com.simibubi.create.foundation.item.CustomItemModels;
|
|||
import com.simibubi.create.foundation.item.CustomRenderedItems;
|
||||
import com.simibubi.create.foundation.ponder.content.PonderIndex;
|
||||
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
|
||||
import com.simibubi.create.foundation.render.AllProgramSpecs;
|
||||
import com.simibubi.create.foundation.render.KineticRenderer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBufferCache;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.OptifineHandler;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.utility.WorldAttached;
|
||||
import com.simibubi.create.foundation.utility.ghost.GhostBlocks;
|
||||
import com.simibubi.create.foundation.utility.outliner.Outliner;
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -30,6 +33,7 @@ import net.minecraft.item.Item;
|
|||
import net.minecraft.resources.IReloadableResourceManager;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
|
@ -37,6 +41,7 @@ import net.minecraftforge.client.model.ModelLoader;
|
|||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -48,7 +53,7 @@ public class CreateClient {
|
|||
public static SchematicHandler schematicHandler;
|
||||
public static SchematicAndQuillHandler schematicAndQuillHandler;
|
||||
public static SuperByteBufferCache bufferCache;
|
||||
public static KineticRenderer kineticRenderer;
|
||||
public static WorldAttached<KineticRenderer> kineticRenderer;
|
||||
public static final Outliner outliner = new Outliner();
|
||||
public static GhostBlocks ghostBlocks;
|
||||
|
||||
|
@ -70,7 +75,8 @@ public class CreateClient {
|
|||
}
|
||||
|
||||
public static void clientInit(FMLClientSetupEvent event) {
|
||||
kineticRenderer = new KineticRenderer();
|
||||
AllProgramSpecs.init();
|
||||
kineticRenderer = new WorldAttached<>(KineticRenderer::new);
|
||||
|
||||
schematicSender = new ClientSchematicLoader();
|
||||
schematicHandler = new SchematicHandler();
|
||||
|
@ -192,8 +198,18 @@ public class CreateClient {
|
|||
}
|
||||
|
||||
public static void invalidateRenderers() {
|
||||
CreateClient.bufferCache.invalidate();
|
||||
CreateClient.kineticRenderer.invalidate();
|
||||
invalidateRenderers(null);
|
||||
}
|
||||
|
||||
public static void invalidateRenderers(@Nullable IWorld world) {
|
||||
bufferCache.invalidate();
|
||||
|
||||
if (world != null) {
|
||||
kineticRenderer.get(world).invalidate();
|
||||
} else {
|
||||
kineticRenderer.forEach(InstancedTileRenderer::invalidate);
|
||||
}
|
||||
|
||||
ContraptionRenderDispatcher.invalidateAll();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -534,12 +534,6 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
return block.hasIntegratedCogwheel(world, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnloaded() {
|
||||
if (world != null && world.isRemote)
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.remove(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestModelDataUpdate() {
|
||||
super.requestModelDataUpdate();
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.simibubi.create.foundation.item.TooltipHelper;
|
|||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.networking.LeftClickPacket;
|
||||
import com.simibubi.create.foundation.ponder.PonderTooltipHandler;
|
||||
import com.simibubi.create.foundation.render.KineticRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.backend.RenderWork;
|
||||
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
|
||||
|
@ -125,7 +126,9 @@ public class ClientEvents {
|
|||
if (world.isRemote() && world instanceof ClientWorld) {
|
||||
CreateClient.invalidateRenderers();
|
||||
AnimationTickHolder.reset();
|
||||
((ClientWorld) world).loadedTileEntityList.forEach(CreateClient.kineticRenderer::add);
|
||||
KineticRenderer renderer = CreateClient.kineticRenderer.get(world);
|
||||
renderer.invalidate();
|
||||
((ClientWorld) world).loadedTileEntityList.forEach(renderer::add);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -139,7 +142,7 @@ public class ClientEvents {
|
|||
@SubscribeEvent
|
||||
public static void onUnloadWorld(WorldEvent.Unload event) {
|
||||
if (event.getWorld().isRemote()) {
|
||||
CreateClient.invalidateRenderers();
|
||||
CreateClient.invalidateRenderers(event.getWorld());
|
||||
AnimationTickHolder.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.foundation.mixin;
|
||||
|
||||
import com.simibubi.create.foundation.render.KineticRenderer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -17,12 +18,16 @@ import net.minecraft.world.World;
|
|||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Mixin(World.class)
|
||||
public class AddRemoveTileMixin {
|
||||
|
||||
@Shadow @Final public boolean isRemote;
|
||||
|
||||
@Shadow @Final protected Set<TileEntity> tileEntitiesToBeRemoved;
|
||||
|
||||
/**
|
||||
* JUSTIFICATION: This method is called whenever a tile entity is removed due
|
||||
* to a change in block state, even on the client. By hooking into this method,
|
||||
|
@ -30,11 +35,28 @@ public class AddRemoveTileMixin {
|
|||
*/
|
||||
@Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"), method = "removeTileEntity", locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) {
|
||||
if (isRemote) CreateClient.kineticRenderer.remove(te);
|
||||
if (isRemote) {
|
||||
World thi = (World)(Object) this;
|
||||
CreateClient.kineticRenderer.get(thi).remove(te);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "addTileEntity")
|
||||
private void onAddTile(TileEntity te, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (isRemote) CreateClient.kineticRenderer.queueAdd(te);
|
||||
if (isRemote) {
|
||||
World thi = (World)(Object) this;
|
||||
CreateClient.kineticRenderer.get(thi).queueAdd(te);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities")
|
||||
private void onChunkUnload(CallbackInfo ci) {
|
||||
if (isRemote) {
|
||||
World thi = (World)(Object) this;
|
||||
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(thi);
|
||||
for (TileEntity tile : tileEntitiesToBeRemoved) {
|
||||
kineticRenderer.remove(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.foundation.mixin;
|
|||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.CreateClient;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
@ -33,6 +34,7 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider {
|
|||
@Inject(at = @At("HEAD"), method = "markLightChanged")
|
||||
private void onLightUpdate(LightType type, SectionPos pos, CallbackInfo ci) {
|
||||
ClientChunkProvider thi = ((ClientChunkProvider) (Object) this);
|
||||
ClientWorld world = (ClientWorld) thi.getWorld();
|
||||
|
||||
Chunk chunk = thi.getChunk(pos.getSectionX(), pos.getSectionZ(), false);
|
||||
|
||||
|
@ -43,14 +45,15 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider {
|
|||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> SectionPos.toChunk(entry.getKey().getY()) == sectionY)
|
||||
.map(Map.Entry::getValue).forEach(tile -> {
|
||||
CreateClient.kineticRenderer.onLightUpdate(tile);
|
||||
.map(Map.Entry::getValue)
|
||||
.forEach(tile -> {
|
||||
CreateClient.kineticRenderer.get(world).onLightUpdate(tile);
|
||||
|
||||
if (tile instanceof ILightListener)
|
||||
((ILightListener) tile).onChunkLightUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
ContraptionRenderDispatcher.notifyLightUpdate((ILightReader) thi.getWorld(), type, pos);
|
||||
ContraptionRenderDispatcher.notifyLightUpdate(world, type, pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.foundation.mixin;
|
||||
|
||||
import com.simibubi.create.foundation.render.KineticRenderer;
|
||||
import net.minecraft.client.renderer.*;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
@ -52,17 +53,20 @@ public class RenderHooksMixin {
|
|||
double camY = cameraPos.getY();
|
||||
double camZ = cameraPos.getZ();
|
||||
|
||||
CreateClient.kineticRenderer.beginFrame(camX, camY, camZ);
|
||||
CreateClient.kineticRenderer.get(world).beginFrame(camX, camY, camZ);
|
||||
ContraptionRenderDispatcher.beginFrame(camX, camY, camZ);
|
||||
}
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "loadRenderers")
|
||||
private void refresh(CallbackInfo ci) {
|
||||
CreateClient.kineticRenderer.invalidate();
|
||||
ContraptionRenderDispatcher.invalidateAll();
|
||||
OptifineHandler.refresh();
|
||||
Backend.refresh();
|
||||
|
||||
if (Backend.canUseInstancing() && world != null) world.loadedTileEntityList.forEach(CreateClient.kineticRenderer::add);
|
||||
if (Backend.canUseInstancing() && world != null) {
|
||||
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(world);
|
||||
kineticRenderer.invalidate();
|
||||
world.loadedTileEntityList.forEach(kineticRenderer::add);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,10 @@ import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class AllProgramSpecs {
|
||||
public static void init() {
|
||||
// noop, make sure the static field are loaded.
|
||||
}
|
||||
|
||||
public static final ProgramSpec<BasicProgram> MODEL = register(ProgramSpec.builder("model", BasicProgram::new)
|
||||
.addAttributes(ModelVertexAttributes.class)
|
||||
.addAttributes(InstanceVertexAttributes.class)
|
||||
|
@ -90,10 +94,6 @@ public class AllProgramSpecs {
|
|||
.setFrag(Locations.CONTRAPTION)
|
||||
.createProgramSpec());
|
||||
|
||||
public static class Contraption {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class Locations {
|
||||
public static final ResourceLocation MODEL_FRAG = loc("model.frag");
|
||||
|
|
|
@ -19,6 +19,7 @@ import net.minecraft.client.renderer.RenderType;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
|
||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||
|
@ -40,30 +41,27 @@ public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
public void beginFrame(double cameraX, double cameraY, double cameraZ) {
|
||||
int cX = MathHelper.floor(cameraX);
|
||||
int cY = MathHelper.floor(cameraY);
|
||||
int cZ = MathHelper.floor(cameraZ);
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Entity renderViewEntity = mc.renderViewEntity;
|
||||
|
||||
if (renderViewEntity == null) return;
|
||||
|
||||
BlockPos renderViewPosition = renderViewEntity.getPosition();
|
||||
|
||||
int dX = Math.abs(renderViewPosition.getX() - originCoordinate.getX());
|
||||
int dY = Math.abs(renderViewPosition.getY() - originCoordinate.getY());
|
||||
int dZ = Math.abs(renderViewPosition.getZ() - originCoordinate.getZ());
|
||||
int dX = Math.abs(cX - originCoordinate.getX());
|
||||
int dY = Math.abs(cY - originCoordinate.getY());
|
||||
int dZ = Math.abs(cZ - originCoordinate.getZ());
|
||||
|
||||
if (dX > MAX_ORIGIN_DISTANCE ||
|
||||
dY > MAX_ORIGIN_DISTANCE ||
|
||||
dZ > MAX_ORIGIN_DISTANCE) {
|
||||
dY > MAX_ORIGIN_DISTANCE ||
|
||||
dZ > MAX_ORIGIN_DISTANCE) {
|
||||
|
||||
originCoordinate = renderViewPosition;
|
||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||
|
||||
ArrayList<TileEntity> instancedTiles = new ArrayList<>(instances.keySet());
|
||||
invalidate();
|
||||
instancedTiles.forEach(this::add);
|
||||
}
|
||||
|
||||
super.beginFrame(cameraX, cameraY, cameraZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,13 +2,11 @@ package com.simibubi.create.foundation.render.backend;
|
|||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import com.simibubi.create.foundation.render.KineticRenderer;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.KineticDebugger;
|
||||
import com.simibubi.create.content.schematics.SchematicWorld;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.WorldAttached;
|
||||
|
||||
|
@ -41,14 +39,15 @@ public class FastRenderDispatcher {
|
|||
public static void tick() {
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
|
||||
CreateClient.kineticRenderer.tick();
|
||||
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(world);
|
||||
kineticRenderer.tick();
|
||||
|
||||
ConcurrentHashMap.KeySetView<TileEntity, Boolean> map = queuedUpdates.get(world);
|
||||
map
|
||||
.forEach(te -> {
|
||||
map.remove(te);
|
||||
|
||||
CreateClient.kineticRenderer.update(te);
|
||||
kineticRenderer.update(te);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -71,9 +70,12 @@ public class FastRenderDispatcher {
|
|||
public static void renderLayer(RenderType layer, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||
if (!Backend.canUseInstancing()) return;
|
||||
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(world);
|
||||
|
||||
layer.startDrawing();
|
||||
|
||||
CreateClient.kineticRenderer.render(layer, viewProjection, cameraX, cameraY, cameraZ);
|
||||
kineticRenderer.render(layer, viewProjection, cameraX, cameraY, cameraZ);
|
||||
|
||||
layer.endDrawing();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -39,5 +40,9 @@ public class WorldAttached<T> {
|
|||
public void put(IWorld world, T entry) {
|
||||
attached.put(world, entry);
|
||||
}
|
||||
|
||||
public void forEach(Consumer<T> consumer) {
|
||||
attached.values().forEach(consumer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue