mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-29 08:27:03 +01:00
The flappening.
Tunnel and funnel flaps are now rendered with the new engine.
This commit is contained in:
parent
1e28bc998a
commit
5499fdbad0
20 changed files with 592 additions and 35 deletions
|
@ -104,6 +104,7 @@ import com.simibubi.create.content.contraptions.relays.gearbox.GearboxInstance;
|
||||||
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxRenderer;
|
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxRenderer;
|
||||||
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxTileEntity;
|
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.relays.gearbox.GearshiftTileEntity;
|
import com.simibubi.create.content.contraptions.relays.gearbox.GearshiftTileEntity;
|
||||||
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelTileEntity;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelTileEntity;
|
||||||
|
@ -116,6 +117,7 @@ import com.simibubi.create.content.logistics.block.depot.DepotTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity;
|
import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterRenderer;
|
import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterRenderer;
|
||||||
import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterTileEntity;
|
import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterTileEntity;
|
||||||
|
import com.simibubi.create.content.logistics.block.funnel.FunnelInstance;
|
||||||
import com.simibubi.create.content.logistics.block.funnel.FunnelRenderer;
|
import com.simibubi.create.content.logistics.block.funnel.FunnelRenderer;
|
||||||
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
|
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateTileEntity;
|
import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateTileEntity;
|
||||||
|
@ -339,12 +341,14 @@ public class AllTileEntities {
|
||||||
.tileEntity("andesite_tunnel", BeltTunnelTileEntity::new)
|
.tileEntity("andesite_tunnel", BeltTunnelTileEntity::new)
|
||||||
.validBlocks(AllBlocks.ANDESITE_TUNNEL)
|
.validBlocks(AllBlocks.ANDESITE_TUNNEL)
|
||||||
.renderer(() -> BeltTunnelRenderer::new)
|
.renderer(() -> BeltTunnelRenderer::new)
|
||||||
|
.onRegister(BeltTunnelInstance::register)
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
public static final TileEntityEntry<BrassTunnelTileEntity> BRASS_TUNNEL = Create.registrate()
|
public static final TileEntityEntry<BrassTunnelTileEntity> BRASS_TUNNEL = Create.registrate()
|
||||||
.tileEntity("brass_tunnel", BrassTunnelTileEntity::new)
|
.tileEntity("brass_tunnel", BrassTunnelTileEntity::new)
|
||||||
.validBlocks(AllBlocks.BRASS_TUNNEL)
|
.validBlocks(AllBlocks.BRASS_TUNNEL)
|
||||||
.renderer(() -> BeltTunnelRenderer::new)
|
.renderer(() -> BeltTunnelRenderer::new)
|
||||||
|
.onRegister(BeltTunnelInstance::register)
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
public static final TileEntityEntry<ArmTileEntity> MECHANICAL_ARM = Create.registrate()
|
public static final TileEntityEntry<ArmTileEntity> MECHANICAL_ARM = Create.registrate()
|
||||||
|
@ -591,6 +595,7 @@ public class AllTileEntities {
|
||||||
.validBlocks(AllBlocks.BRASS_FUNNEL, AllBlocks.BRASS_BELT_FUNNEL, AllBlocks.ANDESITE_FUNNEL,
|
.validBlocks(AllBlocks.BRASS_FUNNEL, AllBlocks.BRASS_BELT_FUNNEL, AllBlocks.ANDESITE_FUNNEL,
|
||||||
AllBlocks.ANDESITE_BELT_FUNNEL)
|
AllBlocks.ANDESITE_BELT_FUNNEL)
|
||||||
.renderer(() -> FunnelRenderer::new)
|
.renderer(() -> FunnelRenderer::new)
|
||||||
|
.onRegister(FunnelInstance::register)
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
public static final TileEntityEntry<ContentObserverTileEntity> CONTENT_OBSERVER = Create.registrate()
|
public static final TileEntityEntry<ContentObserverTileEntity> CONTENT_OBSERVER = Create.registrate()
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.base;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
|
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltData;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltData;
|
||||||
|
import com.simibubi.create.content.logistics.block.FlapData;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.MaterialType;
|
import com.simibubi.create.foundation.render.backend.instancing.MaterialType;
|
||||||
|
|
||||||
|
@ -10,4 +11,6 @@ public class KineticRenderMaterials {
|
||||||
public static final MaterialType<InstancedModel<BeltData>> BELTS = new MaterialType<>();
|
public static final MaterialType<InstancedModel<BeltData>> BELTS = new MaterialType<>();
|
||||||
|
|
||||||
public static final MaterialType<InstancedModel<ContraptionActorData>> ACTORS = new MaterialType<>();
|
public static final MaterialType<InstancedModel<ContraptionActorData>> ACTORS = new MaterialType<>();
|
||||||
|
|
||||||
|
public static final MaterialType<InstancedModel<FlapData>> FLAPS = new MaterialType<>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
||||||
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
|
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
|
||||||
import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel;
|
import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
|
||||||
|
import com.simibubi.create.content.logistics.block.FlapInstancedModel;
|
||||||
import com.simibubi.create.foundation.render.AllProgramSpecs;
|
import com.simibubi.create.foundation.render.AllProgramSpecs;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
||||||
|
@ -16,6 +17,7 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
|
||||||
public void registerMaterials() {
|
public void registerMaterials() {
|
||||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_BELT, BeltInstancedModel::new));
|
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_BELT, BeltInstancedModel::new));
|
||||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ROTATING, RotatingInstancedModel::new));
|
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ROTATING, RotatingInstancedModel::new));
|
||||||
|
materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_FLAPS, FlapInstancedModel::new));
|
||||||
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ACTOR, RotatingActorModel::new));
|
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ACTOR, RotatingActorModel::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,20 +104,17 @@ public class ContraptionRenderDispatcher {
|
||||||
return contraption;
|
return contraption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void beginFrame(double camX, double camY, double camZ) {
|
||||||
|
for (RenderedContraption renderer : renderers.values()) {
|
||||||
|
renderer.beginFrame(camX, camY, camZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void renderLayer(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
public static void renderLayer(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
removeDeadContraptions();
|
removeDeadContraptions();
|
||||||
|
|
||||||
if (renderers.isEmpty()) return;
|
if (renderers.isEmpty()) return;
|
||||||
|
|
||||||
if (firstLayer) {
|
|
||||||
|
|
||||||
for (RenderedContraption renderer : renderers.values()) {
|
|
||||||
renderer.beginFrame(camX, camY, camZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
firstLayer = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer.startDrawing();
|
layer.startDrawing();
|
||||||
GL11.glEnable(GL13.GL_TEXTURE_3D);
|
GL11.glEnable(GL13.GL_TEXTURE_3D);
|
||||||
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
|
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
|
||||||
|
|
|
@ -521,7 +521,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRenderAsTE() {
|
public boolean shouldRenderAsTE() {
|
||||||
return isController();
|
return BeltBlock.canTransportObjects(getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLight() {
|
private void updateLight() {
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
package com.simibubi.create.content.logistics.block;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class FlapData extends InstanceData {
|
||||||
|
|
||||||
|
public static VertexFormat FORMAT = VertexFormat.builder()
|
||||||
|
.addAttributes(FlapVertexAttributes.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private float x;
|
||||||
|
private float y;
|
||||||
|
private float z;
|
||||||
|
private byte blockLight;
|
||||||
|
private byte skyLight;
|
||||||
|
|
||||||
|
private float segmentOffsetX;
|
||||||
|
private float segmentOffsetY;
|
||||||
|
private float segmentOffsetZ;
|
||||||
|
|
||||||
|
private float pivotX;
|
||||||
|
private float pivotY;
|
||||||
|
private float pivotZ;
|
||||||
|
|
||||||
|
private float horizontalAngle;
|
||||||
|
private float intensity;
|
||||||
|
private float flapScale;
|
||||||
|
|
||||||
|
private float flapness;
|
||||||
|
|
||||||
|
public FlapData(InstancedModel<?> owner) {
|
||||||
|
super(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setPosition(BlockPos pos) {
|
||||||
|
return setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setPosition(Vector3f pos) {
|
||||||
|
return setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setPosition(int x, int y, int z) {
|
||||||
|
BlockPos origin = owner.renderer.getOriginCoordinate();
|
||||||
|
|
||||||
|
return setPosition((float) (x - origin.getX()),
|
||||||
|
(float) (y - origin.getY()),
|
||||||
|
(float) (z - origin.getZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setPosition(float x, float y, float z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setBlockLight(int blockLight) {
|
||||||
|
this.blockLight = (byte) ((blockLight & 0xF) << 4);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setSkyLight(int skyLight) {
|
||||||
|
this.skyLight = (byte) ((skyLight & 0xF) << 4);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setSegmentOffset(float x, float y, float z) {
|
||||||
|
this.segmentOffsetX = x;
|
||||||
|
this.segmentOffsetY = y;
|
||||||
|
this.segmentOffsetZ = z;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setIntensity(float intensity) {
|
||||||
|
this.intensity = intensity;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setHorizontalAngle(float horizontalAngle) {
|
||||||
|
this.horizontalAngle = horizontalAngle;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setFlapScale(float flapScale) {
|
||||||
|
this.flapScale = flapScale;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setFlapness(float flapness) {
|
||||||
|
this.flapness = flapness;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlapData setPivotVoxelSpace(float x, float y, float z) {
|
||||||
|
pivotX = x / 16f;
|
||||||
|
pivotY = y / 16f;
|
||||||
|
pivotZ = z / 16f;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuffer buf) {
|
||||||
|
putVec3(buf, x, y, z);
|
||||||
|
putVec2(buf, blockLight, skyLight);
|
||||||
|
|
||||||
|
putVec3(buf, segmentOffsetX, segmentOffsetY, segmentOffsetZ);
|
||||||
|
putVec3(buf, pivotX, pivotY, pivotZ);
|
||||||
|
|
||||||
|
put(buf, horizontalAngle);
|
||||||
|
put(buf, intensity);
|
||||||
|
put(buf, flapScale);
|
||||||
|
|
||||||
|
put(buf, flapness);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.simibubi.create.content.logistics.block;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
|
||||||
|
public class FlapInstancedModel extends InstancedModel<FlapData> {
|
||||||
|
public FlapInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||||
|
super(renderer, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FlapData newInstance() {
|
||||||
|
return new FlapData(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected VertexFormat getInstanceFormat() {
|
||||||
|
return FlapData.FORMAT;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.simibubi.create.content.logistics.block;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes;
|
||||||
|
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
|
||||||
|
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec;
|
||||||
|
|
||||||
|
public enum FlapVertexAttributes implements IVertexAttrib {
|
||||||
|
INSTANCE_POSITION("aInstancePos",CommonAttributes.VEC3),
|
||||||
|
LIGHT("aLight", CommonAttributes.LIGHT),
|
||||||
|
SEGMENT_OFFSET("aSegmentOffset", CommonAttributes.VEC3),
|
||||||
|
PIVOT("aPivot", CommonAttributes.VEC3),
|
||||||
|
HORIZONTAL_ANGLE("aHorizontalAngle", CommonAttributes.FLOAT),
|
||||||
|
INTENSITY("aIntensity", CommonAttributes.FLOAT),
|
||||||
|
FLAP_SCALE("aFlapScale", CommonAttributes.FLOAT),
|
||||||
|
FLAPNESS("aFlapness", CommonAttributes.FLOAT),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final VertexAttribSpec spec;
|
||||||
|
|
||||||
|
FlapVertexAttributes(String name, VertexAttribSpec spec) {
|
||||||
|
this.name = name;
|
||||||
|
this.spec = spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String attribName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VertexAttribSpec attribSpec() {
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDivisor() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBufferIndex() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.simibubi.create.content.logistics.block.belts.tunnel;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlockPartials;
|
||||||
|
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
||||||
|
import com.simibubi.create.content.logistics.block.FlapData;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||||
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.world.LightType;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BeltTunnelInstance extends TileEntityInstance<BeltTunnelTileEntity> {
|
||||||
|
public static void register(TileEntityType<? extends BeltTunnelTileEntity> type) {
|
||||||
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||||
|
InstancedTileRenderRegistry.instance.register(type, BeltTunnelInstance::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Direction, ArrayList<InstanceKey<FlapData>>> tunnelFlaps;
|
||||||
|
|
||||||
|
public BeltTunnelInstance(InstancedTileRenderer<?> modelManager, BeltTunnelTileEntity tile) {
|
||||||
|
super(modelManager, tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
tunnelFlaps = new EnumMap<>(Direction.class);
|
||||||
|
|
||||||
|
InstancedModel<FlapData> model = modelManager.getMaterial(KineticRenderMaterials.FLAPS)
|
||||||
|
.getModel(AllBlockPartials.BELT_TUNNEL_FLAP, lastState);
|
||||||
|
|
||||||
|
int blockLight = world.getLightLevel(LightType.BLOCK, pos);
|
||||||
|
int skyLight = world.getLightLevel(LightType.SKY, pos);
|
||||||
|
|
||||||
|
tile.flaps.forEach((direction, flapValue) -> {
|
||||||
|
|
||||||
|
float flapness = flapValue.get(AnimationTickHolder.getPartialTicks());
|
||||||
|
|
||||||
|
float horizontalAngle = direction.getOpposite().getHorizontalAngle();
|
||||||
|
|
||||||
|
float flapScale = direction.getAxis() == Direction.Axis.X ? 1 : -1;
|
||||||
|
|
||||||
|
ArrayList<InstanceKey<FlapData>> flaps = new ArrayList<>(4);
|
||||||
|
|
||||||
|
for (int segment = 0; segment <= 3; segment++) {
|
||||||
|
float intensity = segment == 3 ? 1.5f : segment + 1;
|
||||||
|
float segmentOffset = -3 / 16f * segment;
|
||||||
|
|
||||||
|
flaps.add(model.setupInstance(flapData -> {
|
||||||
|
flapData.setPosition(pos)
|
||||||
|
.setSegmentOffset(segmentOffset, 0, 0)
|
||||||
|
.setBlockLight(blockLight)
|
||||||
|
.setSkyLight(skyLight)
|
||||||
|
.setHorizontalAngle(horizontalAngle)
|
||||||
|
.setFlapness(flapness)
|
||||||
|
.setFlapScale(flapScale)
|
||||||
|
.setPivotVoxelSpace(0, 10, 1)
|
||||||
|
.setIntensity(intensity);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
tunnelFlaps.put(direction, flaps);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
tunnelFlaps.forEach((direction, keys) -> {
|
||||||
|
|
||||||
|
float flapness = tile.flaps.get(direction).get(AnimationTickHolder.getPartialTicks());
|
||||||
|
for (InstanceKey<FlapData> key : keys) {
|
||||||
|
key.modifyInstance(data -> data.setFlapness(flapness));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onUpdate() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLight() {
|
||||||
|
int blockLight = world.getLightLevel(LightType.BLOCK, pos);
|
||||||
|
int skyLight = world.getLightLevel(LightType.SKY, pos);
|
||||||
|
|
||||||
|
for (ArrayList<InstanceKey<FlapData>> instanceKeys : tunnelFlaps.values()) {
|
||||||
|
for (InstanceKey<FlapData> it : instanceKeys) {
|
||||||
|
it.modifyInstance(data -> data.setBlockLight(blockLight)
|
||||||
|
.setSkyLight(skyLight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
tunnelFlaps.values()
|
||||||
|
.stream()
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.forEach(InstanceKey::delete);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,8 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||||
|
import com.simibubi.create.foundation.render.backend.Backend;
|
||||||
|
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||||
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
|
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
@ -28,6 +30,9 @@ public class BeltTunnelRenderer extends SmartTileEntityRenderer<BeltTunnelTileEn
|
||||||
protected void renderSafe(BeltTunnelTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
protected void renderSafe(BeltTunnelTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||||
|
|
||||||
|
if (FastRenderDispatcher.available(te.getWorld())) return;
|
||||||
|
|
||||||
SuperByteBuffer flapBuffer = AllBlockPartials.BELT_TUNNEL_FLAP.renderOn(te.getBlockState());
|
SuperByteBuffer flapBuffer = AllBlockPartials.BELT_TUNNEL_FLAP.renderOn(te.getBlockState());
|
||||||
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
|
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
|
||||||
Vec3d pivot = VecHelper.voxelSpace(0, 10, 1f);
|
Vec3d pivot = VecHelper.voxelSpace(0, 10, 1f);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.simibubi.create.content.logistics.block.belts.tunnel;
|
package com.simibubi.create.content.logistics.block.belts.tunnel;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
import com.simibubi.create.CreateClient;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
@ -33,9 +33,9 @@ import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
public class BeltTunnelTileEntity extends SmartTileEntity {
|
public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRendered {
|
||||||
|
|
||||||
public HashMap<Direction, InterpolatedChasingValue> flaps;
|
public Map<Direction, InterpolatedChasingValue> flaps;
|
||||||
public Set<Direction> sides;
|
public Set<Direction> sides;
|
||||||
|
|
||||||
protected LazyOptional<IItemHandler> cap = LazyOptional.empty();
|
protected LazyOptional<IItemHandler> cap = LazyOptional.empty();
|
||||||
|
@ -43,7 +43,7 @@ public class BeltTunnelTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
public BeltTunnelTileEntity(TileEntityType<? extends BeltTunnelTileEntity> type) {
|
public BeltTunnelTileEntity(TileEntityType<? extends BeltTunnelTileEntity> type) {
|
||||||
super(type);
|
super(type);
|
||||||
flaps = new HashMap<>();
|
flaps = new EnumMap<>(Direction.class);
|
||||||
sides = new HashSet<>();
|
sides = new HashSet<>();
|
||||||
flapsToSend = new LinkedList<>();
|
flapsToSend = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,9 @@ public class BeltTunnelTileEntity extends SmartTileEntity {
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
super.initialize();
|
super.initialize();
|
||||||
// updateTunnelConnections();
|
updateTunnelConnections();
|
||||||
|
if (world != null && world.isRemote)
|
||||||
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.add(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -212,4 +214,8 @@ public class BeltTunnelTileEntity extends SmartTileEntity {
|
||||||
return this.cap.cast();
|
return this.cap.cast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChunkLightUpdate() {
|
||||||
|
CreateClient.kineticRenderer.onLightUpdate(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
package com.simibubi.create.content.logistics.block.funnel;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlockPartials;
|
||||||
|
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
||||||
|
import com.simibubi.create.content.logistics.block.FlapData;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||||
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.world.LightType;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class FunnelInstance extends TileEntityInstance<FunnelTileEntity> {
|
||||||
|
public static void register(TileEntityType<? extends FunnelTileEntity> type) {
|
||||||
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||||
|
InstancedTileRenderRegistry.instance.register(type, FunnelInstance::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<InstanceKey<FlapData>> flaps;
|
||||||
|
|
||||||
|
public FunnelInstance(InstancedTileRenderer<?> modelManager, FunnelTileEntity tile) {
|
||||||
|
super(modelManager, tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
flaps = new ArrayList<>(4);
|
||||||
|
|
||||||
|
if (!tile.hasFlap()) return;
|
||||||
|
|
||||||
|
AllBlockPartials flapPartial = (lastState.getBlock() instanceof FunnelBlock ? AllBlockPartials.FUNNEL_FLAP
|
||||||
|
: AllBlockPartials.BELT_FUNNEL_FLAP);
|
||||||
|
InstancedModel<FlapData> model = modelManager.getMaterial(KineticRenderMaterials.FLAPS)
|
||||||
|
.getModel(flapPartial, lastState);
|
||||||
|
|
||||||
|
int blockLight = world.getLightLevel(LightType.BLOCK, pos);
|
||||||
|
int skyLight = world.getLightLevel(LightType.SKY, pos);
|
||||||
|
|
||||||
|
Direction direction = FunnelBlock.getFunnelFacing(lastState);
|
||||||
|
|
||||||
|
float flapness = tile.flap.get(AnimationTickHolder.getPartialTicks());
|
||||||
|
float horizontalAngle = direction.getOpposite().getHorizontalAngle();
|
||||||
|
|
||||||
|
for (int segment = 0; segment <= 3; segment++) {
|
||||||
|
float intensity = segment == 3 ? 1.5f : segment + 1;
|
||||||
|
float segmentOffset = -3 / 16f * segment;
|
||||||
|
|
||||||
|
flaps.add(model.setupInstance(flapData -> flapData.setPosition(pos)
|
||||||
|
.setSegmentOffset(segmentOffset, 0, -tile.getFlapOffset())
|
||||||
|
.setBlockLight(blockLight)
|
||||||
|
.setSkyLight(skyLight)
|
||||||
|
.setHorizontalAngle(horizontalAngle)
|
||||||
|
.setFlapness(flapness)
|
||||||
|
.setFlapScale(-1)
|
||||||
|
.setPivotVoxelSpace(0, 10, 9.5f)
|
||||||
|
.setIntensity(intensity)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (flaps == null) return;
|
||||||
|
|
||||||
|
float flapness = tile.flap.get(AnimationTickHolder.getPartialTicks());
|
||||||
|
|
||||||
|
for (InstanceKey<FlapData> key : flaps) {
|
||||||
|
key.modifyInstance(data -> data.setFlapness(flapness));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLight() {
|
||||||
|
if (flaps == null) return;
|
||||||
|
|
||||||
|
int blockLight = world.getLightLevel(LightType.BLOCK, pos);
|
||||||
|
int skyLight = world.getLightLevel(LightType.SKY, pos);
|
||||||
|
|
||||||
|
for (InstanceKey<FlapData> it : flaps) {
|
||||||
|
it.modifyInstance(data -> data.setBlockLight(blockLight)
|
||||||
|
.setSkyLight(skyLight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if (flaps == null) return;
|
||||||
|
|
||||||
|
flaps.forEach(InstanceKey::delete);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||||
|
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||||
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
|
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
|
@ -27,7 +28,7 @@ public class FunnelRenderer extends SmartTileEntityRenderer<FunnelTileEntity> {
|
||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||||
|
|
||||||
if (!te.hasFlap())
|
if (!te.hasFlap() || FastRenderDispatcher.available(te.getWorld()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BlockState blockState = te.getBlockState();
|
BlockState blockState = te.getBlockState();
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.content.contraptions.components.saw.SawTileEntity;
|
import com.simibubi.create.content.contraptions.components.saw.SawTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation;
|
import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
||||||
|
@ -14,6 +15,7 @@ import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
|
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
|
||||||
import com.simibubi.create.foundation.item.TooltipHelper;
|
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||||
|
@ -33,11 +35,13 @@ import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringInformation {
|
public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringInformation, IInstanceRendered {
|
||||||
|
|
||||||
private FilteringBehaviour filtering;
|
private FilteringBehaviour filtering;
|
||||||
private InvManipulationBehaviour invManipulation;
|
private InvManipulationBehaviour invManipulation;
|
||||||
|
@ -381,4 +385,15 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
super.initialize();
|
||||||
|
if (world != null && world.isRemote)
|
||||||
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.add(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChunkLightUpdate() {
|
||||||
|
CreateClient.kineticRenderer.onLightUpdate(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
package com.simibubi.create.foundation.mixin;
|
package com.simibubi.create.foundation.mixin;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.render.backend.light.ILightListener;
|
import net.minecraft.client.renderer.*;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
|
||||||
import net.minecraft.util.math.SectionPos;
|
|
||||||
import net.minecraft.world.ILightReader;
|
|
||||||
import net.minecraft.world.chunk.Chunk;
|
|
||||||
import org.lwjgl.opengl.GL20;
|
import org.lwjgl.opengl.GL20;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
@ -20,15 +16,10 @@ import com.simibubi.create.foundation.render.backend.Backend;
|
||||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||||
import com.simibubi.create.foundation.render.backend.OptifineHandler;
|
import com.simibubi.create.foundation.render.backend.OptifineHandler;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.Matrix4f;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
@Mixin(WorldRenderer.class)
|
@Mixin(WorldRenderer.class)
|
||||||
public class RenderHooksMixin {
|
public class RenderHooksMixin {
|
||||||
|
@ -40,7 +31,7 @@ public class RenderHooksMixin {
|
||||||
* layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects.
|
* layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects.
|
||||||
* This should probably be a forge event.
|
* This should probably be a forge event.
|
||||||
*/
|
*/
|
||||||
@Inject(at = @At(value = "TAIL"), method = "renderLayer")
|
@Inject(at = @At("TAIL"), method = "renderLayer")
|
||||||
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ, CallbackInfo ci) {
|
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ, CallbackInfo ci) {
|
||||||
if (!Backend.available()) return;
|
if (!Backend.available()) return;
|
||||||
|
|
||||||
|
@ -54,7 +45,18 @@ public class RenderHooksMixin {
|
||||||
GL20.glUseProgram(0);
|
GL20.glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At(value = "TAIL"), method = "loadRenderers")
|
@Inject(at = @At(value = "INVOKE", target = "updateChunks(J)V"), method = "render")
|
||||||
|
private void setupFrame(MatrixStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo info, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) {
|
||||||
|
Vec3d cameraPos = info.getProjectedView();
|
||||||
|
double camX = cameraPos.getX();
|
||||||
|
double camY = cameraPos.getY();
|
||||||
|
double camZ = cameraPos.getZ();
|
||||||
|
|
||||||
|
CreateClient.kineticRenderer.beginFrame(camX, camY, camZ);
|
||||||
|
ContraptionRenderDispatcher.beginFrame(camX, camY, camZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(at = @At("TAIL"), method = "loadRenderers")
|
||||||
private void refresh(CallbackInfo ci) {
|
private void refresh(CallbackInfo ci) {
|
||||||
CreateClient.kineticRenderer.invalidate();
|
CreateClient.kineticRenderer.invalidate();
|
||||||
ContraptionRenderDispatcher.invalidateAll();
|
ContraptionRenderDispatcher.invalidateAll();
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.content.contraptions.components.actors.ActorVertexAtt
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionProgram;
|
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionProgram;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionVertexAttributes;
|
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionVertexAttributes;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltVertexAttributes;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltVertexAttributes;
|
||||||
|
import com.simibubi.create.content.logistics.block.FlapVertexAttributes;
|
||||||
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
||||||
import com.simibubi.create.foundation.render.backend.gl.attrib.ModelVertexAttributes;
|
import com.simibubi.create.foundation.render.backend.gl.attrib.ModelVertexAttributes;
|
||||||
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
|
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
|
||||||
|
@ -33,6 +34,13 @@ public class AllProgramSpecs {
|
||||||
.setFrag(Locations.INSTANCED)
|
.setFrag(Locations.INSTANCED)
|
||||||
.createProgramSpec());
|
.createProgramSpec());
|
||||||
|
|
||||||
|
public static final ProgramSpec<BasicProgram> FLAPS = register(ProgramSpec.builder("flap", BasicProgram::new)
|
||||||
|
.addAttributes(ModelVertexAttributes.class)
|
||||||
|
.addAttributes(FlapVertexAttributes.class)
|
||||||
|
.setVert(Locations.FLAP)
|
||||||
|
.setFrag(Locations.INSTANCED)
|
||||||
|
.createProgramSpec());
|
||||||
|
|
||||||
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new)
|
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new)
|
||||||
.addAttributes(ContraptionVertexAttributes.class)
|
.addAttributes(ContraptionVertexAttributes.class)
|
||||||
.setVert(Locations.CONTRAPTION_STRUCTURE)
|
.setVert(Locations.CONTRAPTION_STRUCTURE)
|
||||||
|
@ -57,6 +65,14 @@ public class AllProgramSpecs {
|
||||||
.setDefines(ShaderConstants.define("CONTRAPTION"))
|
.setDefines(ShaderConstants.define("CONTRAPTION"))
|
||||||
.createProgramSpec());
|
.createProgramSpec());
|
||||||
|
|
||||||
|
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new)
|
||||||
|
.addAttributes(ModelVertexAttributes.class)
|
||||||
|
.addAttributes(FlapVertexAttributes.class)
|
||||||
|
.setVert(Locations.FLAP)
|
||||||
|
.setFrag(Locations.CONTRAPTION)
|
||||||
|
.setDefines(ShaderConstants.define("CONTRAPTION"))
|
||||||
|
.createProgramSpec());
|
||||||
|
|
||||||
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new)
|
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new)
|
||||||
.addAttributes(ModelVertexAttributes.class)
|
.addAttributes(ModelVertexAttributes.class)
|
||||||
.addAttributes(ActorVertexAttributes.class)
|
.addAttributes(ActorVertexAttributes.class)
|
||||||
|
@ -64,12 +80,14 @@ public class AllProgramSpecs {
|
||||||
.setFrag(Locations.CONTRAPTION)
|
.setFrag(Locations.CONTRAPTION)
|
||||||
.createProgramSpec());
|
.createProgramSpec());
|
||||||
|
|
||||||
|
|
||||||
public static class Locations {
|
public static class Locations {
|
||||||
public static final ResourceLocation INSTANCED = loc("instanced.frag");
|
public static final ResourceLocation INSTANCED = loc("instanced.frag");
|
||||||
public static final ResourceLocation CONTRAPTION = loc("contraption.frag");
|
public static final ResourceLocation CONTRAPTION = loc("contraption.frag");
|
||||||
|
|
||||||
public static final ResourceLocation ROTATING = loc("rotating.vert");
|
public static final ResourceLocation ROTATING = loc("rotating.vert");
|
||||||
public static final ResourceLocation BELT = loc("belt.vert");
|
public static final ResourceLocation BELT = loc("belt.vert");
|
||||||
|
public static final ResourceLocation FLAP = loc("flap.vert");
|
||||||
public static final ResourceLocation CONTRAPTION_STRUCTURE = loc("contraption_structure.vert");
|
public static final ResourceLocation CONTRAPTION_STRUCTURE = loc("contraption_structure.vert");
|
||||||
public static final ResourceLocation CONTRAPTION_ACTOR = loc("contraption_actor.vert");
|
public static final ResourceLocation CONTRAPTION_ACTOR = loc("contraption_actor.vert");
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.ArrayList;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
|
||||||
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
|
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
|
||||||
|
import com.simibubi.create.content.logistics.block.FlapInstancedModel;
|
||||||
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
|
||||||
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
|
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||||
|
@ -26,6 +27,7 @@ public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
|
||||||
public void registerMaterials() {
|
public void registerMaterials() {
|
||||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::new));
|
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::new));
|
||||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingInstancedModel::new));
|
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingInstancedModel::new));
|
||||||
|
materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.FLAPS, FlapInstancedModel::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -40,6 +40,10 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void beginFrame(double cameraX, double cameraY, double cameraZ) {
|
||||||
|
instances.values().forEach(TileEntityInstance::tick);
|
||||||
|
}
|
||||||
|
|
||||||
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
render(layer, viewProjection, camX, camY, camZ, null);
|
render(layer, viewProjection, camX, camY, camZ, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ public abstract class TileEntityInstance<T extends TileEntity> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called every frame, this can be used to make more dynamic animations.
|
||||||
|
*/
|
||||||
|
public void tick() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acquire all {@link InstanceKey}s and initialize any data you may need to calculate the instance properties.
|
* Acquire all {@link InstanceKey}s and initialize any data you may need to calculate the instance properties.
|
||||||
*/
|
*/
|
||||||
|
@ -42,7 +47,7 @@ public abstract class TileEntityInstance<T extends TileEntity> {
|
||||||
* Update changed instance data using the {@link InstanceKey}s you got in {@link #init()}.
|
* Update changed instance data using the {@link InstanceKey}s you got in {@link #init()}.
|
||||||
* You don't have to update light data. That should be done in {@link #updateLight()}
|
* You don't have to update light data. That should be done in {@link #updateLight()}
|
||||||
*/
|
*/
|
||||||
protected abstract void onUpdate();
|
protected void onUpdate() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a light update occurs in the world. If your model needs it, update light here.
|
* Called when a light update occurs in the world. If your model needs it, update light here.
|
||||||
|
|
104
src/main/resources/assets/create/shader/flap.vert
Normal file
104
src/main/resources/assets/create/shader/flap.vert
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#version 110
|
||||||
|
#define PI 3.1415926538
|
||||||
|
|
||||||
|
attribute vec3 aPos;
|
||||||
|
attribute vec3 aNormal;
|
||||||
|
attribute vec2 aTexCoords;
|
||||||
|
|
||||||
|
attribute vec3 aInstancePos;
|
||||||
|
attribute vec2 aLight;
|
||||||
|
|
||||||
|
attribute vec3 aSegmentOffset;
|
||||||
|
attribute vec3 aPivot;
|
||||||
|
attribute float aHorizontalAngle;
|
||||||
|
attribute float aIntensity;
|
||||||
|
attribute float aFlapScale;
|
||||||
|
|
||||||
|
attribute float aFlapness;
|
||||||
|
|
||||||
|
// outputs
|
||||||
|
varying vec2 TexCoords;
|
||||||
|
varying vec4 Color;
|
||||||
|
varying float Diffuse;
|
||||||
|
varying vec2 Light;
|
||||||
|
|
||||||
|
#if defined(CONTRAPTION)
|
||||||
|
varying vec3 BoxCoord;
|
||||||
|
|
||||||
|
uniform vec3 uLightBoxSize;
|
||||||
|
uniform vec3 uLightBoxMin;
|
||||||
|
uniform mat4 uModel;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform float uTime;
|
||||||
|
uniform mat4 uViewProjection;
|
||||||
|
uniform int uDebug;
|
||||||
|
|
||||||
|
uniform vec3 uCameraPos;
|
||||||
|
varying float FragDistance;
|
||||||
|
|
||||||
|
float diffuse(vec3 normal) {
|
||||||
|
float x = normal.x;
|
||||||
|
float y = normal.y;
|
||||||
|
float z = normal.z;
|
||||||
|
return min(x * x * .6 + y * y * ((3. + y) / 4.) + z * z * .8, 1.);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 rotate(vec3 axis, float angle) {
|
||||||
|
float s = sin(angle);
|
||||||
|
float c = cos(angle);
|
||||||
|
float oc = 1. - c;
|
||||||
|
|
||||||
|
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.,
|
||||||
|
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.,
|
||||||
|
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.,
|
||||||
|
0., 0., 0., 1.);
|
||||||
|
}
|
||||||
|
|
||||||
|
float toRad(float degrees) {
|
||||||
|
return fract(degrees / 360.) * PI * 2.;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getFlapAngle() {
|
||||||
|
float absFlap = abs(aFlapness);
|
||||||
|
|
||||||
|
float angle = sin((1. - absFlap) * PI * aIntensity) * 30. * aFlapness * aFlapScale;
|
||||||
|
|
||||||
|
float halfAngle = angle * 0.5;
|
||||||
|
|
||||||
|
float which = step(0., aFlapness);
|
||||||
|
float degrees = which * halfAngle + (1. - which) * angle; // branchless conditional multiply
|
||||||
|
|
||||||
|
return -toRad(degrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float flapAngle = getFlapAngle();
|
||||||
|
|
||||||
|
mat4 orientation = rotate(vec3(0., 1., 0.), toRad(aHorizontalAngle));
|
||||||
|
mat4 flapRotation = rotate(vec3(1., 0., 0.), flapAngle);
|
||||||
|
|
||||||
|
vec4 worldPos = flapRotation * vec4(aPos - aPivot, 1.) + vec4(aPivot + aSegmentOffset, 0.);
|
||||||
|
worldPos = orientation * vec4(worldPos.xyz - .5, 1.) + vec4(aInstancePos + .5, 0.);
|
||||||
|
|
||||||
|
#ifdef CONTRAPTION
|
||||||
|
worldPos = uModel * worldPos;
|
||||||
|
mat4 normalMat = uModel * orientation * flapRotation;
|
||||||
|
|
||||||
|
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
|
||||||
|
FragDistance = length(worldPos.xyz);
|
||||||
|
#else
|
||||||
|
mat4 normalMat = orientation * flapRotation;
|
||||||
|
|
||||||
|
FragDistance = length(worldPos.xyz - uCameraPos);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
|
||||||
|
|
||||||
|
Diffuse = diffuse(norm);
|
||||||
|
TexCoords = aTexCoords;
|
||||||
|
Light = aLight;
|
||||||
|
gl_Position = uViewProjection * worldPos;
|
||||||
|
|
||||||
|
Color = vec4(1.);
|
||||||
|
}
|
Loading…
Reference in a new issue