Lieutenant Scatterbrain II.

- Swich to tabs. (not everything is tabs yet)
 - Refactor light and color attributes to their own Enum.
 - Quaternion/pivot/position attribute shader.
 - Always update an instance when the WorldRenderer checks if it should rerender a block.
 - Simplify some names.
 - Remove generics in InstanceData classes.
 - Deployer Tiles now use the oriented material.
 - Press heads now correctly orient themselves.
 - ModelData buffers things faster and is simpler.
This commit is contained in:
JozsefA 2021-03-22 20:20:52 -07:00
parent f7f7b67a7d
commit 1310b88828
71 changed files with 1094 additions and 796 deletions

View file

@ -19,7 +19,6 @@ import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.RenderMaterials;
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.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.impl.ModelData; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
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;
@ -277,7 +276,7 @@ public class AllBlockPartials {
.unCentre(); .unCentre();
return stack; return stack;
}; };
return dispatcher.getMaterial(RenderMaterials.MODELS).getModel(this, referenceState, facing, ms); return dispatcher.getMaterial(RenderMaterials.TRANSFORMED).getModel(this, referenceState, facing, ms);
} }
} }

View file

@ -115,8 +115,6 @@ import com.simibubi.create.content.schematics.block.SchematicannonRenderer;
import com.simibubi.create.content.schematics.block.SchematicannonTileEntity; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity;
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
import com.tterrag.registrate.util.entry.TileEntityEntry; import com.tterrag.registrate.util.entry.TileEntityEntry;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class AllTileEntities { public class AllTileEntities {

View file

@ -5,10 +5,8 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec;
public enum KineticVertexAttributes implements IVertexAttrib { public enum KineticAttributes implements IVertexAttrib {
INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3), INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3),
LIGHT("aLight", CommonAttributes.LIGHT),
NETWORK_COLOR("aNetworkTint", CommonAttributes.RGB),
SPEED("aSpeed", CommonAttributes.FLOAT), SPEED("aSpeed", CommonAttributes.FLOAT),
OFFSET("aOffset", CommonAttributes.FLOAT), OFFSET("aOffset", CommonAttributes.FLOAT),
; ;
@ -16,7 +14,7 @@ public enum KineticVertexAttributes implements IVertexAttrib {
private final String name; private final String name;
private final VertexAttribSpec spec; private final VertexAttribSpec spec;
KineticVertexAttributes(String name, VertexAttribSpec spec) { KineticAttributes(String name, VertexAttribSpec spec) {
this.name = name; this.name = name;
this.spec = spec; this.spec = spec;
} }

View file

@ -2,23 +2,17 @@ package com.simibubi.create.content.contraptions.base;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
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.impl.IFlatLight; import com.simibubi.create.foundation.render.backend.instancing.impl.BasicData;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
public class KineticData<D extends KineticData<D>> extends InstanceData implements IFlatLight<D> { public class KineticData extends BasicData {
private float x; private float x;
private float y; private float y;
private float z; private float z;
private byte blockLight;
private byte skyLight;
private byte r;
private byte g;
private byte b;
private float rotationalSpeed; private float rotationalSpeed;
private float rotationOffset; private float rotationOffset;
@ -26,25 +20,25 @@ public class KineticData<D extends KineticData<D>> extends InstanceData implemen
super(owner); super(owner);
} }
public D setTileEntity(KineticTileEntity te) { public KineticData setTileEntity(KineticTileEntity te) {
setPosition(te.getPos()); setPosition(te.getPos());
if (te.hasSource()) { if (te.hasSource()) {
setColor(te.network); setColor(te.network);
}else { }else {
setColor(0xFF, 0xFF, 0x00); setColor(0xFF, 0xFF, 0x00);
} }
return (D) this; return this;
} }
public D setPosition(BlockPos pos) { public KineticData setPosition(BlockPos pos) {
return setPosition(pos.getX(), pos.getY(), pos.getZ()); return setPosition(pos.getX(), pos.getY(), pos.getZ());
} }
public D setPosition(Vector3f pos) { public KineticData setPosition(Vector3f pos) {
return setPosition(pos.getX(), pos.getY(), pos.getZ()); return setPosition(pos.getX(), pos.getY(), pos.getZ());
} }
public D setPosition(int x, int y, int z) { public KineticData setPosition(int x, int y, int z) {
BlockPos origin = owner.renderer.getOriginCoordinate(); BlockPos origin = owner.renderer.getOriginCoordinate();
return setPosition((float) (x - origin.getX()), return setPosition((float) (x - origin.getX()),
@ -52,75 +46,62 @@ public class KineticData<D extends KineticData<D>> extends InstanceData implemen
(float) (z - origin.getZ())); (float) (z - origin.getZ()));
} }
public D setPosition(float x, float y, float z) { public KineticData setPosition(float x, float y, float z) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
return (D) this; return this;
} }
public D nudge(float x, float y, float z) { public KineticData nudge(float x, float y, float z) {
this.x += x; this.x += x;
this.y += y; this.y += y;
this.z += z; this.z += z;
return (D) this; return this;
} }
@Override public KineticData setColor(Long l) {
public D setBlockLight(int blockLight) {
this.blockLight = (byte) ((blockLight & 0xF) << 4);
return (D) this;
}
@Override
public D setSkyLight(int skyLight) {
this.skyLight = (byte) ((skyLight & 0xF) << 4);
return (D) this;
}
public D setColor(Long l) {
if (l != null) if (l != null)
return setColor(l.longValue()); return setColor(l.longValue());
else else {
return setColor(0xFF, 0xFF, 0xFF); setColor(0xFF, 0xFF, 0xFF);
return this;
}
} }
private D setColor(long l) { private KineticData setColor(long l) {
int color = ColorHelper.colorFromLong(l); int color = ColorHelper.colorFromLong(l);
byte r = (byte) ((color >> 16) & 0xFF); byte r = (byte) ((color >> 16) & 0xFF);
byte g = (byte) ((color >> 8) & 0xFF); byte g = (byte) ((color >> 8) & 0xFF);
byte b = (byte) (color & 0xFF); byte b = (byte) (color & 0xFF);
return setColor(r, g, b); setColor(r, g, b);
return this;
} }
public D setColor(int r, int g, int b) { public KineticData setRotationalSpeed(float rotationalSpeed) {
return setColor((byte) r, (byte) g, (byte) b);
}
public D setColor(byte r, byte g, byte b) {
this.r = r;
this.g = g;
this.b = b;
return (D) this;
}
public D setRotationalSpeed(float rotationalSpeed) {
this.rotationalSpeed = rotationalSpeed; this.rotationalSpeed = rotationalSpeed;
return (D) this; return this;
} }
public D setRotationOffset(float rotationOffset) { public KineticData setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset; this.rotationOffset = rotationOffset;
return (D) this; return this;
} }
@Override @Override
public void write(ByteBuffer buf) { public void write(ByteBuffer buf) {
putVec3(buf, x, y, z); super.write(buf);
putVec2(buf, blockLight, skyLight);
putVec3(buf, r, g, b); buf.asFloatBuffer().put(new float[] {
put(buf, rotationalSpeed); x,
put(buf, rotationOffset); y,
z,
rotationalSpeed,
rotationOffset
});
buf.position(buf.position() + 5 * 4);
} }
} }

View file

@ -1,6 +1,6 @@
package com.simibubi.create.content.contraptions.base; package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData; import com.simibubi.create.content.contraptions.components.actors.ActorData;
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.content.logistics.block.FlapData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
@ -10,7 +10,7 @@ public class KineticRenderMaterials {
public static final MaterialType<InstancedModel<RotatingData>> ROTATING = new MaterialType<>(); public static final MaterialType<InstancedModel<RotatingData>> ROTATING = new MaterialType<>();
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<ActorData>> ACTORS = new MaterialType<>();
public static final MaterialType<InstancedModel<FlapData>> FLAPS = new MaterialType<>(); public static final MaterialType<InstancedModel<FlapData>> FLAPS = new MaterialType<>();
} }

View file

@ -25,10 +25,10 @@ public abstract class KineticTileInstance<T extends KineticTileEntity> extends T
} }
protected final void updateRotation(RotatingData key, Direction.Axis axis, float speed) { protected final void updateRotation(RotatingData key, Direction.Axis axis, float speed) {
key.setColor(tile.network) key.setRotationAxis(axis)
.setRotationalSpeed(speed) .setRotationOffset(getRotationOffset(axis))
.setRotationOffset(getRotationOffset(axis)) .setRotationalSpeed(speed)
.setRotationAxis(axis); .setColor(tile.network);
} }
protected final void updateRotation(RotatingData key, Direction.Axis axis) { protected final void updateRotation(RotatingData key, Direction.Axis axis) {
@ -37,12 +37,12 @@ public abstract class KineticTileInstance<T extends KineticTileEntity> extends T
protected final InstanceKey<RotatingData> setup(InstanceKey<RotatingData> key, float speed, Direction.Axis axis) { protected final InstanceKey<RotatingData> setup(InstanceKey<RotatingData> key, float speed, Direction.Axis axis) {
key.getInstance() key.getInstance()
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos)) .setRotationAxis(axis)
.setSkyLight(world.getLightLevel(LightType.SKY, pos)) .setRotationalSpeed(speed)
.setTileEntity(tile) .setRotationOffset(getRotationOffset(axis))
.setRotationalSpeed(speed) .setTileEntity(tile)
.setRotationOffset(getRotationOffset(axis)) .setSkyLight(world.getLightLevel(LightType.SKY, pos))
.setRotationAxis(axis); .setBlockLight(world.getLightLevel(LightType.BLOCK, pos));
return key; return key;
} }

View file

@ -5,14 +5,14 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec;
public enum RotatingVertexAttributes implements IVertexAttrib { public enum RotatingAttributes implements IVertexAttrib {
AXIS("aAxis", CommonAttributes.NORMAL), AXIS("aAxis", CommonAttributes.NORMAL),
; ;
private final String name; private final String name;
private final VertexAttribSpec spec; private final VertexAttribSpec spec;
RotatingVertexAttributes(String name, VertexAttribSpec spec) { RotatingAttributes(String name, VertexAttribSpec spec) {
this.name = name; this.name = name;
this.spec = spec; this.spec = spec;
} }

View file

@ -2,18 +2,12 @@ package com.simibubi.create.content.contraptions.base;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
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.InstancedModel;
import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
public class RotatingData extends KineticData<RotatingData> { public class RotatingData extends KineticData {
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(KineticVertexAttributes.class)
.addAttributes(RotatingVertexAttributes.class)
.build();
private byte rotationAxisX; private byte rotationAxisX;
private byte rotationAxisY; private byte rotationAxisY;
private byte rotationAxisZ; private byte rotationAxisZ;

View file

@ -3,11 +3,18 @@ package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; 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.InstancedModel;
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.impl.BasicAttributes;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
public class RotatingInstancedModel extends InstancedModel<RotatingData> { public class RotatingModel extends InstancedModel<RotatingData> {
public RotatingInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) { public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
.addAttributes(RotatingAttributes.class)
.build();
public RotatingModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf); super(renderer, buf);
} }
@ -18,7 +25,7 @@ public class RotatingInstancedModel extends InstancedModel<RotatingData> {
@Override @Override
protected VertexFormat getInstanceFormat() { protected VertexFormat getInstanceFormat() {
return RotatingData.FORMAT; return FORMAT;
} }
} }

View file

@ -2,13 +2,8 @@ package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
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.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class ShaftlessCogInstance extends SingleRotatingInstance { public class ShaftlessCogInstance extends SingleRotatingInstance {
public ShaftlessCogInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) { public ShaftlessCogInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) {

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.actors;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
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.InstanceData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
@ -10,11 +9,7 @@ import net.minecraft.client.renderer.Quaternion;
import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
public class ContraptionActorData extends InstanceData { public class ActorData extends InstanceData {
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(ActorVertexAttributes.class)
.build();
private float x; private float x;
private float y; private float y;
private float z; private float z;
@ -34,63 +29,63 @@ public class ContraptionActorData extends InstanceData {
private float speed; private float speed;
protected ContraptionActorData(InstancedModel<?> owner) { protected ActorData(InstancedModel<?> owner) {
super(owner); super(owner);
} }
public ContraptionActorData setPosition(BlockPos pos) { public ActorData setPosition(BlockPos pos) {
this.x = pos.getX(); this.x = pos.getX();
this.y = pos.getY(); this.y = pos.getY();
this.z = pos.getZ(); this.z = pos.getZ();
return this; return this;
} }
public ContraptionActorData setBlockLight(int blockLight) { public ActorData setBlockLight(int blockLight) {
this.blockLight = (byte) ((blockLight & 0xF) << 4); this.blockLight = (byte) ((blockLight & 0xF) << 4);
return this; return this;
} }
public ContraptionActorData setSkyLight(int skyLight) { public ActorData setSkyLight(int skyLight) {
this.skyLight = (byte) ((skyLight & 0xF) << 4); this.skyLight = (byte) ((skyLight & 0xF) << 4);
return this; return this;
} }
public ContraptionActorData setRotationOffset(float rotationOffset) { public ActorData setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset; this.rotationOffset = rotationOffset;
return this; return this;
} }
public ContraptionActorData setSpeed(float speed) { public ActorData setSpeed(float speed) {
this.speed = speed; this.speed = speed;
return this; return this;
} }
public ContraptionActorData setRotationAxis(Vector3f axis) { public ActorData setRotationAxis(Vector3f axis) {
setRotationAxis(axis.getX(), axis.getY(), axis.getZ()); setRotationAxis(axis.getX(), axis.getY(), axis.getZ());
return this; return this;
} }
public ContraptionActorData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) { public ActorData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
this.rotationAxisX = (byte) (rotationAxisX * 127); this.rotationAxisX = (byte) (rotationAxisX * 127);
this.rotationAxisY = (byte) (rotationAxisY * 127); this.rotationAxisY = (byte) (rotationAxisY * 127);
this.rotationAxisZ = (byte) (rotationAxisZ * 127); this.rotationAxisZ = (byte) (rotationAxisZ * 127);
return this; return this;
} }
public ContraptionActorData setRotationCenter(Vector3f axis) { public ActorData setRotationCenter(Vector3f axis) {
setRotationCenter(axis.getX(), axis.getY(), axis.getZ()); setRotationCenter(axis.getX(), axis.getY(), axis.getZ());
return this; return this;
} }
public ContraptionActorData setRotationCenter(float rotationCenterX, float rotationCenterY, float rotationCenterZ) { public ActorData setRotationCenter(float rotationCenterX, float rotationCenterY, float rotationCenterZ) {
this.rotationCenterX = (byte) (rotationCenterX * 127); this.rotationCenterX = (byte) (rotationCenterX * 127);
this.rotationCenterY = (byte) (rotationCenterY * 127); this.rotationCenterY = (byte) (rotationCenterY * 127);
this.rotationCenterZ = (byte) (rotationCenterZ * 127); this.rotationCenterZ = (byte) (rotationCenterZ * 127);
return this; return this;
} }
public ContraptionActorData setLocalRotation(Quaternion q) { public ActorData setLocalRotation(Quaternion q) {
this.qX = q.getX(); this.qX = q.getX();
this.qY = q.getY(); this.qY = q.getY();
this.qZ = q.getZ(); this.qZ = q.getZ();

View file

@ -6,18 +6,22 @@ import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRen
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
public class RotatingActorModel extends InstancedModel<ContraptionActorData> { public class ActorModel extends InstancedModel<ActorData> {
public RotatingActorModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) { public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(ActorVertexAttributes.class)
.build();
public ActorModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf); super(renderer, buf);
} }
@Override @Override
protected VertexFormat getInstanceFormat() { protected VertexFormat getInstanceFormat() {
return ContraptionActorData.FORMAT; return FORMAT;
} }
@Override @Override
protected ContraptionActorData newInstance() { protected ActorData newInstance() {
return new ContraptionActorData(this); return new ActorData(this);
} }
} }

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.actors;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
@ -13,15 +12,15 @@ import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.Quaternion; import net.minecraft.client.renderer.Quaternion;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
public class DrillActorInstance extends ActorInstance { public class DrillActorInstance extends com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance {
InstanceKey<ContraptionActorData> drillHead; InstanceKey<ActorData> drillHead;
private Direction facing; private Direction facing;
public DrillActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { public DrillActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context); super(modelManager, context);
RenderMaterial<?, InstancedModel<ContraptionActorData>> renderMaterial = modelManager.getActorMaterial(); RenderMaterial<?, InstancedModel<ActorData>> renderMaterial = modelManager.getActorMaterial();
BlockState state = context.state; BlockState state = context.state;

View file

@ -4,17 +4,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.RenderedContraption;
import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.utility.AngleHelper;
import net.minecraft.block.BlockState;
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;
public class DrillInstance extends SingleRotatingInstance { public class DrillInstance extends SingleRotatingInstance {

View file

@ -36,7 +36,7 @@ public class HarvesterActorInstance extends ActorInstance {
public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context); super(modelManager, context);
RenderMaterial<?, InstancedModel<ModelData>> renderMaterial = modelManager.getBasicMaterial(); RenderMaterial<?, InstancedModel<ModelData>> renderMaterial = modelManager.transformMaterial();
BlockState state = context.state; BlockState state = context.state;

View file

@ -50,7 +50,7 @@ public class HandCrankInstance extends SingleRotatingInstance implements IDynami
.rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis), angle) .rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis), angle)
.unCentre(); .unCentre();
crank.getInstance().setTransformNoCopy(ms); crank.getInstance().setTransform(ms);
} }
@Override @Override

View file

@ -37,7 +37,7 @@ public class DeployerActorInstance extends ActorInstance {
public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context); super(modelManager, context);
RenderMaterial<ContraptionProgram, InstancedModel<ModelData>> mat = modelManager.getBasicMaterial(); RenderMaterial<ContraptionProgram, InstancedModel<ModelData>> mat = modelManager.transformMaterial();
BlockState state = context.state; BlockState state = context.state;
DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class); DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class);
@ -62,9 +62,9 @@ public class DeployerActorInstance extends ActorInstance {
int blockLight = localBlockLight(); int blockLight = localBlockLight();
shaft.getInstance() shaft.getInstance()
.setBlockLight(blockLight) .setRotationAxis(axis)
.setRotationAxis(axis) .setPosition(context.localPos)
.setPosition(context.localPos); .setBlockLight(blockLight);
pole.getInstance().setBlockLight(blockLight); pole.getInstance().setBlockLight(blockLight);
hand.getInstance().setBlockLight(blockLight); hand.getInstance().setBlockLight(blockLight);
@ -91,6 +91,23 @@ public class DeployerActorInstance extends ActorInstance {
msr.translate(context.localPos) msr.translate(context.localPos)
.translate(offset); .translate(offset);
DeployerInstance.transformModel(msr, pole, hand, yRot, zRot, zRotPole); transformModel(msr, pole, hand, yRot, zRot, zRotPole);
}
static void transformModel(MatrixStacker msr, InstanceKey<ModelData> pole, InstanceKey<ModelData> hand, float yRot, float zRot, float zRotPole) {
msr.centre();
msr.rotate(Direction.SOUTH, (float) ((zRot) / 180 * Math.PI));
msr.rotate(Direction.UP, (float) ((yRot) / 180 * Math.PI));
msr.push();
msr.rotate(Direction.SOUTH, (float) ((zRotPole) / 180 * Math.PI));
msr.unCentre();
pole.getInstance().setTransform(msr.unwrap());
msr.pop();
msr.unCentre();
hand.getInstance().setTransform(msr.unwrap());
} }
} }

View file

@ -1,22 +1,24 @@
package com.simibubi.create.content.contraptions.components.deployer; package com.simibubi.create.content.contraptions.components.deployer;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.client.renderer.Quaternion;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i;
import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE; import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE;
import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING; import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING;
public class DeployerInstance extends ShaftInstance implements IDynamicInstance { public class DeployerInstance extends ShaftInstance implements IDynamicInstance, ITickableInstance {
final DeployerTileEntity tile; final DeployerTileEntity tile;
final Direction facing; final Direction facing;
@ -24,12 +26,13 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance
final float zRot; final float zRot;
final float zRotPole; final float zRotPole;
protected final InstanceKey<ModelData> pole; protected final InstanceKey<OrientedData> pole;
protected InstanceKey<ModelData> hand; protected InstanceKey<OrientedData> hand;
AllBlockPartials currentHand; AllBlockPartials currentHand;
float progress = Float.NaN; float progress = Float.NaN;
private boolean newHand = false;
public DeployerInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) { public DeployerInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
super(dispatcher, tile); super(dispatcher, tile);
@ -43,30 +46,41 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance
zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0; zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
zRotPole = rotatePole ? 90 : 0; zRotPole = rotatePole ? 90 : 0;
pole = modelManager.getBasicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance(); pole = RenderMaterials.ORIENTED.get(modelManager).getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance();
updateHandPose(); updateHandPose();
relight(pos, pole.getInstance()); relight(pos, pole.getInstance());
updateRotation(pole, hand, yRot, zRot, zRotPole);
}
@Override
public void tick() {
newHand = updateHandPose();
} }
@Override @Override
public void beginFrame() { public void beginFrame() {
boolean newHand = updateHandPose();
float newProgress = getProgress(AnimationTickHolder.getPartialTicks()); float newProgress = getProgress(AnimationTickHolder.getPartialTicks());
if (!newHand && MathHelper.epsilonEquals(newProgress, progress)) return; if (!newHand && MathHelper.epsilonEquals(newProgress, progress)) return;
progress = newProgress; progress = newProgress;
newHand = false;
MatrixStack ms = new MatrixStack(); float handLength = currentHand == AllBlockPartials.DEPLOYER_HAND_POINTING ? 0
MatrixStacker msr = MatrixStacker.of(ms); : currentHand == AllBlockPartials.DEPLOYER_HAND_HOLDING ? 4 / 16f : 3 / 16f;
float distance = Math.min(MathHelper.clamp(progress, 0, 1) * (tile.reach + handLength), 21 / 16f);
Vec3i facingVec = facing.getDirectionVec();
BlockPos blockPos = getFloatingPos();
msr.translate(getFloatingPos()) float x = blockPos.getX() + ((float) facingVec.getX()) * distance;
.translate(getHandOffset()); float y = blockPos.getY() + ((float) facingVec.getY()) * distance;
float z = blockPos.getZ() + ((float) facingVec.getZ()) * distance;
transformModel(msr, pole, hand, yRot, zRot, zRotPole); pole.getInstance().setPosition(x, y, z);
hand.getInstance().setPosition(x, y, z);
} }
@ -93,21 +107,14 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance
if (hand != null) hand.delete(); if (hand != null) hand.delete();
hand = modelManager.getBasicMaterial().getModel(currentHand, blockState).createInstance(); hand = RenderMaterials.ORIENTED.get(modelManager).getModel(currentHand, blockState).createInstance();
relight(pos, hand.getInstance()); relight(pos, hand.getInstance());
updateRotation(pole, hand, yRot, zRot, zRotPole);
return true; return true;
} }
protected Vec3d getHandOffset() {
float handLength = tile.getHandPose() == AllBlockPartials.DEPLOYER_HAND_POINTING ? 0
: tile.getHandPose() == AllBlockPartials.DEPLOYER_HAND_HOLDING ? 4 / 16f : 3 / 16f;
float distance = Math.min(MathHelper.clamp(progress, 0, 1) * (tile.reach + handLength), 21 / 16f);
Vec3d offset = new Vec3d(facing.getDirectionVec()).scale(distance);
return offset;
}
private float getProgress(float partialTicks) { private float getProgress(float partialTicks) {
if (tile.state == DeployerTileEntity.State.EXPANDING) if (tile.state == DeployerTileEntity.State.EXPANDING)
return 1 - (tile.timer - partialTicks * tile.getTimerSpeed()) / 1000f; return 1 - (tile.timer - partialTicks * tile.getTimerSpeed()) / 1000f;
@ -116,20 +123,15 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance
return 0; return 0;
} }
static void transformModel(MatrixStacker msr, InstanceKey<ModelData> pole, InstanceKey<ModelData> hand, float yRot, float zRot, float zRotPole) { static void updateRotation(InstanceKey<OrientedData> pole, InstanceKey<OrientedData> hand, float yRot, float zRot, float zRotPole) {
msr.centre(); Quaternion q = Direction.SOUTH.getUnitVector().getDegreesQuaternion(zRot);
msr.rotate(Direction.SOUTH, (float) ((zRot) / 180 * Math.PI)); q.multiply(Direction.UP.getUnitVector().getDegreesQuaternion(yRot));
msr.rotate(Direction.UP, (float) ((yRot) / 180 * Math.PI));
msr.push(); hand.getInstance().setRotation(q);
msr.rotate(Direction.SOUTH, (float) ((zRotPole) / 180 * Math.PI));
msr.unCentre();
pole.getInstance().setTransform(msr.unwrap());
msr.pop();
msr.unCentre(); q.multiply(Direction.SOUTH.getUnitVector().getDegreesQuaternion(zRotPole));
hand.getInstance().setTransform(msr.unwrap()); pole.getInstance().setRotation(q);
} }
} }

View file

@ -7,10 +7,8 @@ import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@ -31,8 +29,13 @@ public class FanInstance extends KineticTileInstance<EncasedFanTileEntity> {
shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance();
fan = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); fan = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance();
updateRotation(shaft.getInstance().setTileEntity(tile), axis); RotatingData shaftInstance = shaft.getInstance();
updateRotation(fan.getInstance().setTileEntity(tile), axis, getFanSpeed()); shaftInstance.setTileEntity(tile);
updateRotation(shaftInstance, axis);
RotatingData fanInstance = fan.getInstance();
fanInstance.setTileEntity(tile);
updateRotation(fanInstance, axis, getFanSpeed());
updateLight(); updateLight();
} }

View file

@ -62,7 +62,7 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> im
connectorAngleMult = flipAngle ? -1 : 1; connectorAngleMult = flipAngle ? -1 : 1;
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS); RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED);
upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance(); upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance();
lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance(); lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance();
@ -125,7 +125,7 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> im
.rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, facing.getAxis()), AngleHelper.rad(angle)) .rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, facing.getAxis()), AngleHelper.rad(angle))
.unCentre(); .unCentre();
wheel.getInstance().setTransformNoCopy(ms); wheel.getInstance().setTransform(ms);
lastAngle = angle; lastAngle = angle;
firstFrame = false; firstFrame = false;

View file

@ -30,7 +30,7 @@ public class EngineInstance extends TileEntityInstance<EngineTileEntity> {
Direction facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); Direction facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING);
this.frame = modelManager.getMaterial(RenderMaterials.MODELS).getModel(frame, blockState).createInstance(); this.frame = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(frame, blockState).createInstance();
float angle = AngleHelper.rad(AngleHelper.horizontalAngle(facing)); float angle = AngleHelper.rad(AngleHelper.horizontalAngle(facing));
@ -45,7 +45,7 @@ public class EngineInstance extends TileEntityInstance<EngineTileEntity> {
.translate(0, 0, -1); .translate(0, 0, -1);
this.frame.getInstance() this.frame.getInstance()
.setTransformNoCopy(ms); .setTransform(ms);
updateLight(); updateLight();
} }

View file

@ -5,13 +5,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
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.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class MillStoneCogInstance extends SingleRotatingInstance { public class MillStoneCogInstance extends SingleRotatingInstance {
public MillStoneCogInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) { public MillStoneCogInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) {

View file

@ -26,7 +26,7 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta
mixerHead.getInstance() mixerHead.getInstance()
.setRotationAxis(Direction.Axis.Y); .setRotationAxis(Direction.Axis.Y);
mixerPole = modelManager.getMaterial(RenderMaterials.MODELS) mixerPole = modelManager.getMaterial(RenderMaterials.TRANSFORMED)
.getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, blockState) .getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, blockState)
.createInstance(); .createInstance();
@ -68,7 +68,7 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta
msr.translate(getFloatingPos()); msr.translate(getFloatingPos());
msr.translate(0, -renderedHeadOffset, 0); msr.translate(0, -renderedHeadOffset, 0);
mixerPole.getInstance().setTransformNoCopy(ms); mixerPole.getInstance().setTransform(ms);
} }
private float getRenderedHeadOffset(MechanicalMixerTileEntity mixer) { private float getRenderedHeadOffset(MechanicalMixerTileEntity mixer) {

View file

@ -4,7 +4,6 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
@ -19,9 +18,7 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance {
public PressInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) { public PressInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
super(dispatcher, tile); super(dispatcher, tile);
pressHead = modelManager.getMaterial(RenderMaterials.MODELS) pressHead = AllBlockPartials.MECHANICAL_PRESS_HEAD.renderOnHorizontalModel(dispatcher, blockState).createInstance();
.getModel(AllBlockPartials.MECHANICAL_PRESS_HEAD, blockState)
.createInstance();
updateLight(); updateLight();
transformModels((MechanicalPressTileEntity) tile); transformModels((MechanicalPressTileEntity) tile);
@ -46,7 +43,7 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance {
msr.translate(0, -renderedHeadOffset, 0); msr.translate(0, -renderedHeadOffset, 0);
pressHead.getInstance() pressHead.getInstance()
.setTransformNoCopy(ms); .setTransform(ms);
} }
private float getRenderedHeadOffset(MechanicalPressTileEntity press) { private float getRenderedHeadOffset(MechanicalPressTileEntity press) {

View file

@ -24,7 +24,7 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
public StickerInstance(InstancedTileRenderer<?> modelManager, StickerTileEntity tile) { public StickerInstance(InstancedTileRenderer<?> modelManager, StickerTileEntity tile) {
super(modelManager, tile); super(modelManager, tile);
head = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance(); head = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance();
fakeWorld = tile.getWorld() != Minecraft.getInstance().world; fakeWorld = tile.getWorld() != Minecraft.getInstance().world;
facing = blockState.get(StickerBlock.FACING); facing = blockState.get(StickerBlock.FACING);
@ -54,7 +54,7 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
.translate(0, (offset * offset) * 4 / 16f, 0); .translate(0, (offset * offset) * 4 / 16f, 0);
head.getInstance() head.getInstance()
.setTransformNoCopy(stack); .setTransform(stack);
lastOffset = offset; lastOffset = offset;
} }

View file

@ -7,6 +7,7 @@ import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; 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;
@ -71,7 +72,7 @@ public class StickerTileEntity extends SmartTileEntity implements IInstanceRende
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false)); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false));
piston.chase(target, .4f, Chaser.LINEAR); piston.chase(target, .4f, Chaser.LINEAR);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.get(world).update(this)); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this));
} }
public boolean isAttachedToBlock() { public boolean isAttachedToBlock() {

View file

@ -29,7 +29,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns
public GantryCarriageInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) { public GantryCarriageInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
super(dispatcher, tile); super(dispatcher, tile);
gantryCogs = modelManager.getMaterial(RenderMaterials.MODELS) gantryCogs = modelManager.getMaterial(RenderMaterials.TRANSFORMED)
.getModel(AllBlockPartials.GANTRY_COGS, blockState) .getModel(AllBlockPartials.GANTRY_COGS, blockState)
.createInstance(); .createInstance();
@ -72,7 +72,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns
.translate(0, 9 / 16f, 0) .translate(0, 9 / 16f, 0)
.unCentre(); .unCentre();
gantryCogs.getInstance().setTransformNoCopy(ms); gantryCogs.getInstance().setTransform(ms);
} }
@Override @Override

View file

@ -5,7 +5,7 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec;
public enum ContraptionVertexAttributes implements IVertexAttrib { public enum ContraptionAttributes implements IVertexAttrib {
VERTEX_POSITION("aPos", CommonAttributes.VEC3), VERTEX_POSITION("aPos", CommonAttributes.VEC3),
NORMAL("aNormal", CommonAttributes.NORMAL), NORMAL("aNormal", CommonAttributes.NORMAL),
TEXTURE("aTexCoords", CommonAttributes.UV), TEXTURE("aTexCoords", CommonAttributes.UV),
@ -16,7 +16,7 @@ public enum ContraptionVertexAttributes implements IVertexAttrib {
private final String name; private final String name;
private final VertexAttribSpec spec; private final VertexAttribSpec spec;
ContraptionVertexAttributes(String name, VertexAttribSpec spec) { ContraptionAttributes(String name, VertexAttribSpec spec) {
this.name = name; this.name = name;
this.spec = spec; this.spec = spec;
} }

View file

@ -2,18 +2,19 @@ package com.simibubi.create.content.contraptions.components.structureMovement.re
import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.AllMovementBehaviours;
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.RotatingModel;
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData; import com.simibubi.create.content.contraptions.components.actors.ActorData;
import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel; import com.simibubi.create.content.contraptions.components.actors.ActorModel;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
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.content.logistics.block.FlapModel;
import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel; import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedModel;
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedModel;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.gen.feature.template.Template; import net.minecraft.world.gen.feature.template.Template;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@ -23,7 +24,7 @@ import java.util.ArrayList;
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> { public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
protected ArrayList<ActorInstance> actors = new ArrayList<>(); protected ArrayList<com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance> actors = new ArrayList<>();
public final RenderedContraption contraption; public final RenderedContraption contraption;
@ -33,35 +34,36 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
@Override @Override
public void registerMaterials() { public void registerMaterials() {
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, BasicInstancedModel::new)); materials.put(RenderMaterials.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, TransformedModel::new));
materials.put(RenderMaterials.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.C_ORIENTED, OrientedModel::new));
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.C_BELT, BeltInstancedModel::new)); materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.C_BELT, BeltInstancedModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.C_ROTATING, RotatingInstancedModel::new)); materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.C_ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.C_FLAPS, FlapInstancedModel::new)); materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.C_FLAPS, FlapModel::new));
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, RotatingActorModel::new)); materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, ActorModel::new));
} }
@Override @Override
public void tick() { public void tick() {
actors.forEach(ActorInstance::tick); actors.forEach(com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance::tick);
} }
@Override @Override
public void beginFrame(double cameraX, double cameraY, double cameraZ) { public void beginFrame(double cameraX, double cameraY, double cameraZ) {
super.beginFrame(cameraX, cameraY, cameraZ); super.beginFrame(cameraX, cameraY, cameraZ);
actors.forEach(ActorInstance::beginFrame); actors.forEach(com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance::beginFrame);
} }
@Nullable @Nullable
public ActorInstance createActor(Pair<Template.BlockInfo, MovementContext> actor) { public com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance createActor(Pair<Template.BlockInfo, MovementContext> actor) {
Template.BlockInfo blockInfo = actor.getLeft(); Template.BlockInfo blockInfo = actor.getLeft();
MovementContext context = actor.getRight(); MovementContext context = actor.getRight();
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state); MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
if (movementBehaviour != null && movementBehaviour.hasSpecialInstancedRendering()) { if (movementBehaviour != null && movementBehaviour.hasSpecialInstancedRendering()) {
ActorInstance instance = movementBehaviour.createInstance(this, context); com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance instance = movementBehaviour.createInstance(this, context);
actors.add(instance); actors.add(instance);
@ -71,7 +73,7 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
return null; return null;
} }
public RenderMaterial<?, InstancedModel<ContraptionActorData>> getActorMaterial() { public RenderMaterial<?, InstancedModel<ActorData>> getActorMaterial() {
return getMaterial(KineticRenderMaterials.ACTORS); return getMaterial(KineticRenderMaterials.ACTORS);
} }

View file

@ -14,7 +14,7 @@ import org.lwjgl.opengl.GL20;
public class ContraptionModel extends BufferedModel { public class ContraptionModel extends BufferedModel {
public static final VertexFormat FORMAT = VertexFormat.builder() public static final VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(ContraptionVertexAttributes.class) .addAttributes(ContraptionAttributes.class)
.build(); .build();
protected GlPrimitiveType eboIndexType; protected GlPrimitiveType eboIndexType;

View file

@ -5,22 +5,14 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import org.apache.commons.lang3.tuple.MutablePair;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB; import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld; import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;

View file

@ -5,13 +5,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
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.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class PumpCogInstance extends SingleRotatingInstance { public class PumpCogInstance extends SingleRotatingInstance {
public PumpCogInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) { public PumpCogInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) {

View file

@ -37,7 +37,7 @@ public class FluidValveInstance extends ShaftInstance implements IDynamicInstanc
boolean twist = pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical(); boolean twist = pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical();
pointerRotationOffset = twist ? 90 : 0; pointerRotationOffset = twist ? 90 : 0;
pointer = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance(); pointer = modelManager.transformMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance();
updateLight(); updateLight();
transformPointer((FluidValveTileEntity) tile); transformPointer((FluidValveTileEntity) tile);

View file

@ -5,7 +5,7 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec;
public enum BeltVertexAttributes implements IVertexAttrib { public enum BeltAttributes implements IVertexAttrib {
INSTANCE_ROTATION("aInstanceRot", CommonAttributes.QUATERNION), INSTANCE_ROTATION("aInstanceRot", CommonAttributes.QUATERNION),
SOURCE_TEX("aSourceTexture", CommonAttributes.UV), SOURCE_TEX("aSourceTexture", CommonAttributes.UV),
SCROLL_TEX("aScrollTexture", CommonAttributes.VEC4), SCROLL_TEX("aScrollTexture", CommonAttributes.VEC4),
@ -15,7 +15,7 @@ public enum BeltVertexAttributes implements IVertexAttrib {
private final String name; private final String name;
private final VertexAttribSpec spec; private final VertexAttribSpec spec;
BeltVertexAttributes(String name, VertexAttribSpec spec) { BeltAttributes(String name, VertexAttribSpec spec) {
this.name = name; this.name = name;
this.spec = spec; this.spec = spec;
} }

View file

@ -3,20 +3,13 @@ package com.simibubi.create.content.contraptions.relays.belt;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import com.simibubi.create.content.contraptions.base.KineticData; import com.simibubi.create.content.contraptions.base.KineticData;
import com.simibubi.create.content.contraptions.base.KineticVertexAttributes;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry; import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
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.InstancedModel;
import net.minecraft.client.renderer.Quaternion; import net.minecraft.client.renderer.Quaternion;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
public class BeltData extends KineticData<BeltData> { public class BeltData extends KineticData {
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(KineticVertexAttributes.class)
.addAttributes(BeltVertexAttributes.class)
.build();
private float qX; private float qX;
private float qY; private float qY;
private float qZ; private float qZ;

View file

@ -160,14 +160,14 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
Quaternion q = new Quaternion(rotX, rotY, rotZ, true); Quaternion q = new Quaternion(rotX, rotY, rotZ, true);
key.getInstance() key.getInstance()
.setTileEntity(tile) .setScrollTexture(spriteShift)
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos)) .setScrollMult(diagonal ? 3f / 8f : 0.5f)
.setSkyLight(world.getLightLevel(LightType.SKY, pos)) .setRotation(q)
.setRotation(q) .setRotationalSpeed(getScrollSpeed())
.setRotationalSpeed(getScrollSpeed()) .setRotationOffset(bottom ? 0.5f : 0f)
.setRotationOffset(bottom ? 0.5f : 0f) .setTileEntity(tile)
.setScrollTexture(spriteShift) .setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
.setScrollMult(diagonal ? 3f / 8f : 0.5f); .setSkyLight(world.getLightLevel(LightType.SKY, pos));
return key; return key;
} }

View file

@ -1,24 +1,32 @@
package com.simibubi.create.content.contraptions.relays.belt; package com.simibubi.create.content.contraptions.relays.belt;
import com.simibubi.create.content.contraptions.base.KineticAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; 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.InstancedModel;
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.impl.BasicAttributes;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
public class BeltInstancedModel extends InstancedModel<BeltData> { public class BeltInstancedModel extends InstancedModel<BeltData> {
public BeltInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) { public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
.addAttributes(BeltAttributes.class)
.build();
public BeltInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf); super(renderer, buf);
} }
@Override @Override
protected BeltData newInstance() { protected BeltData newInstance() {
return new BeltData(this); return new BeltData(this);
} }
@Override @Override
protected VertexFormat getInstanceFormat() { protected VertexFormat getInstanceFormat() {
return BeltData.FORMAT; return FORMAT;
} }
} }

View file

@ -53,7 +53,7 @@ public class SplitShaftInstance extends KineticTileInstance<SplitShaftTileEntity
@Override @Override
public void updateLight() { public void updateLight() {
keys.forEach(key -> relight(pos, ((InstanceKey<? extends KineticData<?>>) key).getInstance())); keys.forEach(key -> relight(pos, ((InstanceKey<? extends KineticData>) key).getInstance()));
} }
@Override @Override
@ -66,9 +66,9 @@ public class SplitShaftInstance extends KineticTileInstance<SplitShaftTileEntity
Direction.Axis axis = dir.getAxis(); Direction.Axis axis = dir.getAxis();
key.getInstance() key.getInstance()
.setColor(tile.network) .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setRotationalSpeed(tile.getSpeed() * tile.getRotationSpeedModifier(dir)) .setRotationalSpeed(tile.getSpeed() * tile.getRotationSpeedModifier(dir))
.setRotationOffset(getRotationOffset(axis)) .setRotationOffset(getRotationOffset(axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()); .setColor(tile.network);
} }
} }

View file

@ -30,7 +30,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns
GaugeTileEntity gaugeTile = (GaugeTileEntity) tile; GaugeTileEntity gaugeTile = (GaugeTileEntity) tile;
GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock(); GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock();
InstancedModel<ModelData> dialModel = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_DIAL, blockState); InstancedModel<ModelData> dialModel = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_DIAL, blockState);
InstancedModel<ModelData> headModel = getHeadModel(); InstancedModel<ModelData> headModel = getHeadModel();
ms = new MatrixStack(); ms = new MatrixStack();
@ -151,7 +151,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns
@Override @Override
protected InstancedModel<ModelData> getHeadModel() { protected InstancedModel<ModelData> getHeadModel() {
return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_SPEED, blockState); return modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_HEAD_SPEED, blockState);
} }
} }
@ -162,7 +162,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns
@Override @Override
protected InstancedModel<ModelData> getHeadModel() { protected InstancedModel<ModelData> getHeadModel() {
return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_STRESS, blockState); return modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_HEAD_STRESS, blockState);
} }
} }
} }

View file

@ -42,12 +42,12 @@ public class GearboxInstance extends KineticTileInstance<GearboxTileEntity> {
InstanceKey<RotatingData> key = shaft.createInstance(); InstanceKey<RotatingData> key = shaft.createInstance();
key.getInstance() key.getInstance()
.setBlockLight(blockLight) .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setSkyLight(skyLight) .setRotationalSpeed(getSpeed(direction))
.setRotationalSpeed(getSpeed(direction)) .setRotationOffset(getRotationOffset(axis))
.setRotationOffset(getRotationOffset(axis)) .setTileEntity(tile)
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) .setBlockLight(blockLight)
.setTileEntity(tile); .setSkyLight(skyLight);
keys.put(direction, key); keys.put(direction, key);
} }
@ -82,11 +82,11 @@ public class GearboxInstance extends KineticTileInstance<GearboxTileEntity> {
Direction.Axis axis = direction.getAxis(); Direction.Axis axis = direction.getAxis();
key.getValue() key.getValue()
.getInstance() .getInstance()
.setColor(tile.network) .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setRotationalSpeed(getSpeed(direction)) .setRotationalSpeed(getSpeed(direction))
.setRotationOffset(getRotationOffset(axis)) .setRotationOffset(getRotationOffset(axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()); .setColor(tile.network);
} }
} }

View file

@ -5,7 +5,7 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec;
public enum FlapVertexAttributes implements IVertexAttrib { public enum FlapAttributes implements IVertexAttrib {
INSTANCE_POSITION("aInstancePos",CommonAttributes.VEC3), INSTANCE_POSITION("aInstancePos",CommonAttributes.VEC3),
LIGHT("aLight", CommonAttributes.LIGHT), LIGHT("aLight", CommonAttributes.LIGHT),
SEGMENT_OFFSET("aSegmentOffset", CommonAttributes.VEC3), SEGMENT_OFFSET("aSegmentOffset", CommonAttributes.VEC3),
@ -19,7 +19,7 @@ public enum FlapVertexAttributes implements IVertexAttrib {
private final String name; private final String name;
private final VertexAttribSpec spec; private final VertexAttribSpec spec;
FlapVertexAttributes(String name, VertexAttribSpec spec) { FlapAttributes(String name, VertexAttribSpec spec) {
this.name = name; this.name = name;
this.spec = spec; this.spec = spec;
} }

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.logistics.block; 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.InstanceData;
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.impl.IFlatLight; import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight;
@ -11,115 +10,111 @@ import java.nio.ByteBuffer;
public class FlapData extends InstanceData implements IFlatLight<FlapData> { public class FlapData extends InstanceData implements IFlatLight<FlapData> {
public static VertexFormat FORMAT = VertexFormat.builder() private float x;
.addAttributes(FlapVertexAttributes.class) private float y;
.build(); private float z;
private byte blockLight;
private byte skyLight;
private float x; private float segmentOffsetX;
private float y; private float segmentOffsetY;
private float z; private float segmentOffsetZ;
private byte blockLight;
private byte skyLight;
private float segmentOffsetX; private float pivotX;
private float segmentOffsetY; private float pivotY;
private float segmentOffsetZ; private float pivotZ;
private float pivotX; private float horizontalAngle;
private float pivotY; private float intensity;
private float pivotZ; private float flapScale;
private float horizontalAngle; private float flapness;
private float intensity;
private float flapScale;
private float flapness; public FlapData(InstancedModel<?> owner) {
super(owner);
}
public FlapData(InstancedModel<?> owner) { public FlapData setPosition(BlockPos pos) {
super(owner); return setPosition(pos.getX(), pos.getY(), pos.getZ());
} }
public FlapData setPosition(BlockPos pos) { public FlapData setPosition(Vector3f pos) {
return setPosition(pos.getX(), pos.getY(), pos.getZ()); return setPosition(pos.getX(), pos.getY(), pos.getZ());
} }
public FlapData setPosition(Vector3f pos) { public FlapData setPosition(int x, int y, int z) {
return setPosition(pos.getX(), pos.getY(), pos.getZ()); BlockPos origin = owner.renderer.getOriginCoordinate();
}
public FlapData setPosition(int x, int y, int z) { return setPosition((float) (x - origin.getX()),
BlockPos origin = owner.renderer.getOriginCoordinate(); (float) (y - origin.getY()),
(float) (z - origin.getZ()));
}
return setPosition((float) (x - origin.getX()), public FlapData setPosition(float x, float y, float z) {
(float) (y - origin.getY()), this.x = x;
(float) (z - origin.getZ())); this.y = y;
} this.z = z;
return this;
}
public FlapData setPosition(float x, float y, float z) { @Override
this.x = x; public FlapData setBlockLight(int blockLight) {
this.y = y; this.blockLight = (byte) ((blockLight & 0xF) << 4);
this.z = z; return this;
return this; }
}
@Override @Override
public FlapData setBlockLight(int blockLight) { public FlapData setSkyLight(int skyLight) {
this.blockLight = (byte) ((blockLight & 0xF) << 4); this.skyLight = (byte) ((skyLight & 0xF) << 4);
return this; return this;
} }
@Override public FlapData setSegmentOffset(float x, float y, float z) {
public FlapData setSkyLight(int skyLight) { this.segmentOffsetX = x;
this.skyLight = (byte) ((skyLight & 0xF) << 4); this.segmentOffsetY = y;
return this; this.segmentOffsetZ = z;
} return this;
}
public FlapData setSegmentOffset(float x, float y, float z) { public FlapData setIntensity(float intensity) {
this.segmentOffsetX = x; this.intensity = intensity;
this.segmentOffsetY = y; return this;
this.segmentOffsetZ = z; }
return this;
}
public FlapData setIntensity(float intensity) { public FlapData setHorizontalAngle(float horizontalAngle) {
this.intensity = intensity; this.horizontalAngle = horizontalAngle;
return this; return this;
} }
public FlapData setHorizontalAngle(float horizontalAngle) { public FlapData setFlapScale(float flapScale) {
this.horizontalAngle = horizontalAngle; this.flapScale = flapScale;
return this; return this;
} }
public FlapData setFlapScale(float flapScale) { public FlapData setFlapness(float flapness) {
this.flapScale = flapScale; this.flapness = flapness;
return this; return this;
} }
public FlapData setFlapness(float flapness) { public FlapData setPivotVoxelSpace(float x, float y, float z) {
this.flapness = flapness; pivotX = x / 16f;
return this; pivotY = y / 16f;
} pivotZ = z / 16f;
return this;
}
public FlapData setPivotVoxelSpace(float x, float y, float z) { @Override
pivotX = x / 16f; public void write(ByteBuffer buf) {
pivotY = y / 16f; putVec3(buf, x, y, z);
pivotZ = z / 16f; putVec2(buf, blockLight, skyLight);
return this;
}
@Override putVec3(buf, segmentOffsetX, segmentOffsetY, segmentOffsetZ);
public void write(ByteBuffer buf) { putVec3(buf, pivotX, pivotY, pivotZ);
putVec3(buf, x, y, z);
putVec2(buf, blockLight, skyLight);
putVec3(buf, segmentOffsetX, segmentOffsetY, segmentOffsetZ); put(buf, horizontalAngle);
putVec3(buf, pivotX, pivotY, pivotZ); put(buf, intensity);
put(buf, flapScale);
put(buf, horizontalAngle); put(buf, flapness);
put(buf, intensity); }
put(buf, flapScale);
put(buf, flapness);
}
} }

View file

@ -1,22 +0,0 @@
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;
}
}

View file

@ -0,0 +1,26 @@
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 FlapModel extends InstancedModel<FlapData> {
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(FlapAttributes.class)
.build();
public FlapModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf);
}
@Override
protected FlapData newInstance() {
return new FlapData(this);
}
@Override
protected VertexFormat getInstanceFormat() {
return FORMAT;
}
}

View file

@ -16,7 +16,7 @@ public class AdjustableRepeaterInstance extends TileEntityInstance<AdjustableRep
public AdjustableRepeaterInstance(InstancedTileRenderer<?> modelManager, AdjustableRepeaterTileEntity tile) { public AdjustableRepeaterInstance(InstancedTileRenderer<?> modelManager, AdjustableRepeaterTileEntity tile) {
super(modelManager, tile); super(modelManager, tile);
indicator = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance(); indicator = modelManager.transformMaterial().getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance();
MatrixStack ms = new MatrixStack(); MatrixStack ms = new MatrixStack();
MatrixStacker.of(ms).translate(getFloatingPos()); MatrixStacker.of(ms).translate(getFloatingPos());

View file

@ -24,135 +24,135 @@ import java.util.ArrayList;
public class ArmInstance extends SingleRotatingInstance implements IDynamicInstance { public class ArmInstance extends SingleRotatingInstance implements IDynamicInstance {
final InstanceKey<ModelData> base; final InstanceKey<ModelData> base;
final InstanceKey<ModelData> lowerBody; final InstanceKey<ModelData> lowerBody;
final InstanceKey<ModelData> upperBody; final InstanceKey<ModelData> upperBody;
final InstanceKey<ModelData> head; final InstanceKey<ModelData> head;
final InstanceKey<ModelData> claw; final InstanceKey<ModelData> claw;
private final ArrayList<InstanceKey<ModelData>> clawGrips; private final ArrayList<InstanceKey<ModelData>> clawGrips;
private final ArrayList<InstanceKey<ModelData>> models; private final ArrayList<InstanceKey<ModelData>> models;
private boolean firstTick = true; private boolean firstTick = true;
public ArmInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) { public ArmInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) {
super(modelManager, tile); super(modelManager, tile);
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS); RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED);
base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance(); base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance();
lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance(); lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance();
upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, blockState).createInstance(); upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, blockState).createInstance();
head = mat.getModel(AllBlockPartials.ARM_HEAD, blockState).createInstance(); head = mat.getModel(AllBlockPartials.ARM_HEAD, blockState).createInstance();
claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, blockState).createInstance(); claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, blockState).createInstance();
InstancedModel<ModelData> clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, blockState); InstancedModel<ModelData> clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, blockState);
InstanceKey<ModelData> clawGrip1 = clawHalfModel.createInstance(); InstanceKey<ModelData> clawGrip1 = clawHalfModel.createInstance();
InstanceKey<ModelData> clawGrip2 = clawHalfModel.createInstance(); InstanceKey<ModelData> clawGrip2 = clawHalfModel.createInstance();
clawGrips = Lists.newArrayList(clawGrip1, clawGrip2); clawGrips = Lists.newArrayList(clawGrip1, clawGrip2);
models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2); models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2);
updateLight(); updateLight();
} }
@Override @Override
public void beginFrame() { public void beginFrame() {
ArmTileEntity arm = (ArmTileEntity) tile; ArmTileEntity arm = (ArmTileEntity) tile;
boolean settled = arm.baseAngle.settled() && arm.lowerArmAngle.settled() && arm.upperArmAngle.settled() && arm.headAngle.settled(); boolean settled = arm.baseAngle.settled() && arm.lowerArmAngle.settled() && arm.upperArmAngle.settled() && arm.headAngle.settled();
boolean rave = arm.phase == ArmTileEntity.Phase.DANCING; boolean rave = arm.phase == ArmTileEntity.Phase.DANCING;
if (!settled || rave || firstTick) if (!settled || rave || firstTick)
transformModels(arm, rave); transformModels(arm, rave);
if (settled) if (settled)
firstTick = false; firstTick = false;
} }
private void transformModels(ArmTileEntity arm, boolean rave) { private void transformModels(ArmTileEntity arm, boolean rave) {
float pt = AnimationTickHolder.getPartialTicks(); float pt = AnimationTickHolder.getPartialTicks();
int color = 0xFFFFFF; int color = 0xFFFFFF;
float baseAngle = arm.baseAngle.get(pt); float baseAngle = arm.baseAngle.get(pt);
float lowerArmAngle = arm.lowerArmAngle.get(pt) - 135; float lowerArmAngle = arm.lowerArmAngle.get(pt) - 135;
float upperArmAngle = arm.upperArmAngle.get(pt) - 90; float upperArmAngle = arm.upperArmAngle.get(pt) - 90;
float headAngle = arm.headAngle.get(pt); float headAngle = arm.headAngle.get(pt);
if (rave) { if (rave) {
float renderTick = AnimationTickHolder.getRenderTime(arm.getWorld()) + (tile.hashCode() % 64); float renderTick = AnimationTickHolder.getRenderTime(arm.getWorld()) + (tile.hashCode() % 64);
baseAngle = (renderTick * 10) % 360; baseAngle = (renderTick * 10) % 360;
lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15); lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15);
upperArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 8) + 1) / 4, -45, 95); upperArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 8) + 1) / 4, -45, 95);
headAngle = -lowerArmAngle; headAngle = -lowerArmAngle;
color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100); color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100);
} }
MatrixStack msLocal = new MatrixStack(); MatrixStack msLocal = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(msLocal); MatrixStacker msr = MatrixStacker.of(msLocal);
msr.translate(getFloatingPos()); msr.translate(getFloatingPos());
msr.centre(); msr.centre();
if (blockState.get(ArmBlock.CEILING)) if (blockState.get(ArmBlock.CEILING))
msr.rotateX(180); msr.rotateX(180);
ArmRenderer.transformBase(msr, baseAngle); ArmRenderer.transformBase(msr, baseAngle);
base.getInstance() base.getInstance()
.setTransform(msLocal); .setTransform(msLocal);
ArmRenderer.transformLowerArm(msr, lowerArmAngle); ArmRenderer.transformLowerArm(msr, lowerArmAngle);
lowerBody.getInstance() lowerBody.getInstance()
.setColor(color) .setTransform(msLocal)
.setTransform(msLocal); .setColor(color);
ArmRenderer.transformUpperArm(msr, upperArmAngle); ArmRenderer.transformUpperArm(msr, upperArmAngle);
upperBody.getInstance() upperBody.getInstance()
.setColor(color) .setTransform(msLocal)
.setTransform(msLocal); .setColor(color);
ArmRenderer.transformHead(msr, headAngle); ArmRenderer.transformHead(msr, headAngle);
head.getInstance() head.getInstance()
.setTransform(msLocal); .setTransform(msLocal);
ArmRenderer.transformClaw(msr); ArmRenderer.transformClaw(msr);
claw.getInstance() claw.getInstance()
.setTransform(msLocal); .setTransform(msLocal);
ItemStack item = arm.heldItem; ItemStack item = arm.heldItem;
ItemRenderer itemRenderer = Minecraft.getInstance() ItemRenderer itemRenderer = Minecraft.getInstance()
.getItemRenderer(); .getItemRenderer();
boolean hasItem = !item.isEmpty(); boolean hasItem = !item.isEmpty();
boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem) boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem)
&& itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null) && itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null)
.isGui3d(); .isGui3d();
for (int index : Iterate.zeroAndOne) { for (int index : Iterate.zeroAndOne) {
msLocal.push(); msLocal.push();
int flip = index * 2 - 1; int flip = index * 2 - 1;
ArmRenderer.transformClawHalf(msr, hasItem, isBlockItem, flip); ArmRenderer.transformClawHalf(msr, hasItem, isBlockItem, flip);
clawGrips.get(index) clawGrips.get(index)
.getInstance() .getInstance()
.setTransform(msLocal); .setTransform(msLocal);
msLocal.pop(); msLocal.pop();
} }
} }
@Override @Override
public void updateLight() { public void updateLight() {
super.updateLight(); super.updateLight();
relight(pos, models.stream().map(InstanceKey::getInstance)); relight(pos, models.stream().map(InstanceKey::getInstance));
} }
@Override @Override
protected InstancedModel<RotatingData> getModel() { protected InstancedModel<RotatingData> getModel() {
return AllBlockPartials.ARM_COG.renderOnRotating(modelManager, tile.getBlockState()); return AllBlockPartials.ARM_COG.renderOnRotating(modelManager, tile.getBlockState());
} }
@Override @Override
public void remove() { public void remove() {
super.remove(); super.remove();
models.forEach(InstanceKey::delete); models.forEach(InstanceKey::delete);
} }
} }

View file

@ -23,7 +23,7 @@ public class AnalogLeverInstance extends TileEntityInstance<AnalogLeverTileEntit
public AnalogLeverInstance(InstancedTileRenderer<?> modelManager, AnalogLeverTileEntity tile) { public AnalogLeverInstance(InstancedTileRenderer<?> modelManager, AnalogLeverTileEntity tile) {
super(modelManager, tile); super(modelManager, tile);
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS); RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED);
handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance(); handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance();
indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance(); indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance();
@ -62,7 +62,7 @@ public class AnalogLeverInstance extends TileEntityInstance<AnalogLeverTileEntit
.translate(-1 / 2f, -1 / 16f, -1 / 2f); .translate(-1 / 2f, -1 / 16f, -1 / 2f);
handle.getInstance() handle.getInstance()
.setTransformNoCopy(ms); .setTransform(ms);
} }
@Override @Override

View file

@ -17,7 +17,7 @@ public class SchematicannonInstance extends TileEntityInstance<SchematicannonTil
public SchematicannonInstance(InstancedTileRenderer<?> modelManager, SchematicannonTileEntity tile) { public SchematicannonInstance(InstancedTileRenderer<?> modelManager, SchematicannonTileEntity tile) {
super(modelManager, tile); super(modelManager, tile);
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS); RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED);
connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance(); connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance();
pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance(); pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance();
@ -54,7 +54,7 @@ public class SchematicannonInstance extends TileEntityInstance<SchematicannonTil
msr.translate(-.5f, -15 / 16f, -.5f); msr.translate(-.5f, -15 / 16f, -.5f);
msr.translate(0, -recoil / 100, 0); msr.translate(0, -recoil / 100, 0);
pipe.getInstance().setTransformNoCopy(ms); pipe.getInstance().setTransform(ms);
} }
@Override @Override

View file

@ -1,8 +1,11 @@
package com.simibubi.create.foundation.mixin; package com.simibubi.create.foundation.mixin;
import com.simibubi.create.foundation.render.KineticRenderer; import com.simibubi.create.foundation.render.KineticRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -58,6 +61,11 @@ public class RenderHooksMixin {
ContraptionRenderDispatcher.beginFrame(camX, camY, camZ); ContraptionRenderDispatcher.beginFrame(camX, camY, camZ);
} }
@Inject(at = @At("TAIL"), method = "checkBlockRerender")
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
CreateClient.kineticRenderer.get(world).update(world.getTileEntity(pos));
}
@Inject(at = @At("TAIL"), method = "loadRenderers") @Inject(at = @At("TAIL"), method = "loadRenderers")
private void refresh(CallbackInfo ci) { private void refresh(CallbackInfo ci) {
ContraptionRenderDispatcher.invalidateAll(); ContraptionRenderDispatcher.invalidateAll();

View file

@ -3,112 +3,137 @@ package com.simibubi.create.foundation.render;
import static com.simibubi.create.foundation.render.backend.Backend.register; import static com.simibubi.create.foundation.render.backend.Backend.register;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.base.KineticVertexAttributes; import com.simibubi.create.content.contraptions.base.KineticAttributes;
import com.simibubi.create.content.contraptions.base.RotatingVertexAttributes; import com.simibubi.create.content.contraptions.base.RotatingAttributes;
import com.simibubi.create.content.contraptions.components.actors.ActorVertexAttributes; import com.simibubi.create.content.contraptions.components.actors.ActorVertexAttributes;
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.ContraptionAttributes;
import com.simibubi.create.content.contraptions.relays.belt.BeltVertexAttributes; import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes;
import com.simibubi.create.content.logistics.block.FlapVertexAttributes; import com.simibubi.create.content.logistics.block.FlapAttributes;
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.InstanceVertexAttributes; import com.simibubi.create.foundation.render.backend.instancing.impl.BasicAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.ModelVertexAttributes; import com.simibubi.create.foundation.render.backend.instancing.impl.TransformAttributes;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelAttributes;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedAttributes;
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class AllProgramSpecs { public class AllProgramSpecs {
public static void init() { public static void init() {
// noop, make sure the static field are loaded. // noop, make sure the static field are loaded.
} }
public static final ProgramSpec<BasicProgram> MODEL = register(ProgramSpec.builder("model", BasicProgram::new) public static final ProgramSpec<BasicProgram> MODEL = register(ProgramSpec.builder("model", BasicProgram::new)
.addAttributes(ModelVertexAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(InstanceVertexAttributes.class) .addAttributes(BasicAttributes.class)
.setVert(Locations.MODEL_VERT) .addAttributes(TransformAttributes.class)
.setFrag(Locations.MODEL_FRAG) .setVert(Locations.MODEL_VERT)
.createProgramSpec()); .setFrag(Locations.MODEL_FRAG)
.createProgramSpec());
public static final ProgramSpec<BasicProgram> ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new) public static final ProgramSpec<BasicProgram> ORIENTED = register(ProgramSpec.builder("oriented", BasicProgram::new)
.addAttributes(ModelVertexAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(KineticVertexAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(RotatingVertexAttributes.class) .addAttributes(OrientedAttributes.class)
.setVert(Locations.ROTATING) .setVert(Locations.ORIENTED)
.setFrag(Locations.MODEL_FRAG) .setFrag(Locations.MODEL_FRAG)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> BELT = register(ProgramSpec.builder("belt", BasicProgram::new) public static final ProgramSpec<BasicProgram> ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new)
.addAttributes(ModelVertexAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(KineticVertexAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(BeltVertexAttributes.class) .addAttributes(KineticAttributes.class)
.setVert(Locations.BELT) .addAttributes(RotatingAttributes.class)
.setFrag(Locations.MODEL_FRAG) .setVert(Locations.ROTATING)
.createProgramSpec()); .setFrag(Locations.MODEL_FRAG)
.createProgramSpec());
public static final ProgramSpec<BasicProgram> FLAPS = register(ProgramSpec.builder("flap", BasicProgram::new) public static final ProgramSpec<BasicProgram> BELT = register(ProgramSpec.builder("belt", BasicProgram::new)
.addAttributes(ModelVertexAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(FlapVertexAttributes.class) .addAttributes(BasicAttributes.class)
.setVert(Locations.FLAP) .addAttributes(KineticAttributes.class)
.setFrag(Locations.MODEL_FRAG) .addAttributes(BeltAttributes.class)
.createProgramSpec()); .setVert(Locations.BELT)
public static final ProgramSpec<ContraptionProgram> C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new) .setFrag(Locations.MODEL_FRAG)
.addAttributes(ContraptionVertexAttributes.class) .createProgramSpec());
.setVert(Locations.CONTRAPTION_STRUCTURE)
.setFrag(Locations.CONTRAPTION) public static final ProgramSpec<BasicProgram> FLAPS = register(ProgramSpec.builder("flap", BasicProgram::new)
.createProgramSpec()); .addAttributes(ModelAttributes.class)
public static final ProgramSpec<ContraptionProgram> C_MODEL = register(ProgramSpec.builder("contraption_model", ContraptionProgram::new) .addAttributes(FlapAttributes.class)
.addAttributes(ModelVertexAttributes.class) .setVert(Locations.FLAP)
.addAttributes(InstanceVertexAttributes.class) .setFrag(Locations.MODEL_FRAG)
.setVert(Locations.MODEL_VERT) .createProgramSpec());
.setFrag(Locations.CONTRAPTION) public static final ProgramSpec<ContraptionProgram> C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new)
.setDefines(ShaderConstants.define("CONTRAPTION")) .addAttributes(ContraptionAttributes.class)
.createProgramSpec()); .setVert(Locations.CONTRAPTION_STRUCTURE)
public static final ProgramSpec<ContraptionProgram> C_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new) .setFrag(Locations.CONTRAPTION)
.addAttributes(ModelVertexAttributes.class) .createProgramSpec());
.addAttributes(KineticVertexAttributes.class) public static final ProgramSpec<ContraptionProgram> C_MODEL = register(ProgramSpec.builder("contraption_model", ContraptionProgram::new)
.addAttributes(RotatingVertexAttributes.class) .addAttributes(ModelAttributes.class)
.setVert(Locations.ROTATING) .addAttributes(BasicAttributes.class)
.setFrag(Locations.CONTRAPTION) .addAttributes(TransformAttributes.class)
.setDefines(ShaderConstants.define("CONTRAPTION")) .setVert(Locations.MODEL_VERT)
.createProgramSpec()); .setFrag(Locations.CONTRAPTION)
public static final ProgramSpec<ContraptionProgram> C_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new) .setDefines(ShaderConstants.define("CONTRAPTION"))
.addAttributes(ModelVertexAttributes.class) .createProgramSpec());
.addAttributes(KineticVertexAttributes.class) public static final ProgramSpec<ContraptionProgram> C_ORIENTED = register(ProgramSpec.builder("contraption_oriented", ContraptionProgram::new)
.addAttributes(BeltVertexAttributes.class) .addAttributes(ModelAttributes.class)
.setVert(Locations.BELT) .addAttributes(BasicAttributes.class)
.setFrag(Locations.CONTRAPTION) .addAttributes(OrientedAttributes.class)
.setDefines(ShaderConstants.define("CONTRAPTION")) .setVert(Locations.ORIENTED)
.createProgramSpec()); .setFrag(Locations.CONTRAPTION)
public static final ProgramSpec<ContraptionProgram> C_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new) .setDefines(ShaderConstants.define("CONTRAPTION"))
.addAttributes(ModelVertexAttributes.class) .createProgramSpec());
.addAttributes(FlapVertexAttributes.class) public static final ProgramSpec<ContraptionProgram> C_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new)
.setVert(Locations.FLAP) .addAttributes(ModelAttributes.class)
.setFrag(Locations.CONTRAPTION) .addAttributes(BasicAttributes.class)
.setDefines(ShaderConstants.define("CONTRAPTION")) .addAttributes(KineticAttributes.class)
.createProgramSpec()); .addAttributes(RotatingAttributes.class)
public static final ProgramSpec<ContraptionProgram> C_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new) .setVert(Locations.ROTATING)
.addAttributes(ModelVertexAttributes.class) .setFrag(Locations.CONTRAPTION)
.addAttributes(ActorVertexAttributes.class) .setDefines(ShaderConstants.define("CONTRAPTION"))
.setVert(Locations.CONTRAPTION_ACTOR) .createProgramSpec());
.setFrag(Locations.CONTRAPTION) public static final ProgramSpec<ContraptionProgram> C_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new)
.createProgramSpec()); .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
.addAttributes(BeltAttributes.class)
.setVert(Locations.BELT)
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new)
.addAttributes(ModelAttributes.class)
.addAttributes(FlapAttributes.class)
.setVert(Locations.FLAP)
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new)
.addAttributes(ModelAttributes.class)
.addAttributes(ActorVertexAttributes.class)
.setVert(Locations.CONTRAPTION_ACTOR)
.setFrag(Locations.CONTRAPTION)
.createProgramSpec());
public static class Locations { public static class Locations {
public static final ResourceLocation MODEL_FRAG = loc("model.frag"); public static final ResourceLocation MODEL_FRAG = loc("model.frag");
public static final ResourceLocation MODEL_VERT = loc("model.vert"); public static final ResourceLocation MODEL_VERT = loc("model.vert");
public static final ResourceLocation CONTRAPTION = loc("contraption.frag"); public static final ResourceLocation ORIENTED = loc("oriented.vert");
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 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");
private static ResourceLocation loc(String name) { private static ResourceLocation loc(String name) {
return new ResourceLocation(Create.ID, name); return new ResourceLocation(Create.ID, name);
} }
} }
} }

View file

@ -3,20 +3,20 @@ package com.simibubi.create.foundation.render;
import java.util.ArrayList; 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.RotatingModel;
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.content.logistics.block.FlapModel;
import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.RenderMaterials;
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;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel; import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedModel;
import net.minecraft.client.Minecraft; import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedModel;
import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@ -28,11 +28,12 @@ public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
@Override @Override
public void registerMaterials() { public void registerMaterials() {
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.MODEL, BasicInstancedModel::new)); materials.put(RenderMaterials.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.MODEL, TransformedModel::new));
materials.put(RenderMaterials.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.ORIENTED, OrientedModel::new));
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, RotatingModel::new));
materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.FLAPS, FlapInstancedModel::new)); materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.FLAPS, FlapModel::new));
} }
@Override @Override

View file

@ -3,7 +3,9 @@ package com.simibubi.create.foundation.render.backend;
import com.simibubi.create.foundation.render.backend.instancing.MaterialType; import com.simibubi.create.foundation.render.backend.instancing.MaterialType;
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.impl.ModelData; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
public class RenderMaterials { public class RenderMaterials {
public static final MaterialType<InstancedModel<ModelData>> MODELS = new MaterialType<>(); public static final MaterialType<InstancedModel<ModelData>> TRANSFORMED = new MaterialType<>();
public static final MaterialType<InstancedModel<OrientedData>> ORIENTED = new MaterialType<>();
} }

View file

@ -7,50 +7,45 @@ import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
public class RenderUtil { public class RenderUtil {
public static int nextPowerOf2(int a) { public static int nextPowerOf2(int a) {
int h = Integer.highestOneBit(a); int h = Integer.highestOneBit(a);
return (h == a) ? h : (h << 1); return (h == a) ? h : (h << 1);
} }
public static boolean isPowerOf2(int n) { public static boolean isPowerOf2(int n) {
int b = n & (n - 1); int b = n & (n - 1);
return b == 0 && n != 0; return b == 0 && n != 0;
} }
// GPUs want matrices in column major order. // GPUs want matrices in column major order.
public static void writeMat3(ByteBuffer buf, Matrix3f mat) { public static float[] bufferMatrices(Matrix4f model, Matrix3f normal) {
buf.putFloat(mat.a00); return new float[] {
buf.putFloat(mat.a10); model.a00,
buf.putFloat(mat.a20); model.a10,
buf.putFloat(mat.a01); model.a20,
buf.putFloat(mat.a11); model.a30,
buf.putFloat(mat.a21); model.a01,
buf.putFloat(mat.a02); model.a11,
buf.putFloat(mat.a12); model.a21,
buf.putFloat(mat.a22); model.a31,
} model.a02,
model.a12,
public static void writeMat4(ByteBuffer buf, Matrix4f mat) { model.a22,
buf.putFloat(mat.a00); model.a32,
buf.putFloat(mat.a10); model.a03,
buf.putFloat(mat.a20); model.a13,
buf.putFloat(mat.a30); model.a23,
buf.putFloat(mat.a01); model.a33,
buf.putFloat(mat.a11); normal.a00,
buf.putFloat(mat.a21); normal.a10,
buf.putFloat(mat.a31); normal.a20,
buf.putFloat(mat.a02); normal.a01,
buf.putFloat(mat.a12); normal.a11,
buf.putFloat(mat.a22); normal.a21,
buf.putFloat(mat.a32); normal.a02,
buf.putFloat(mat.a03); normal.a12,
buf.putFloat(mat.a13); normal.a22,
buf.putFloat(mat.a23); };
buf.putFloat(mat.a33); }
}
} }

View file

@ -1,36 +0,0 @@
package com.simibubi.create.foundation.render.backend.gl.attrib;
public enum ModelVertexAttributes implements IVertexAttrib {
VERTEX_POSITION("aPos", CommonAttributes.VEC3),
NORMAL("aNormal", CommonAttributes.NORMAL),
TEXTURE("aTexCoords", CommonAttributes.UV),
;
private final String name;
private final VertexAttribSpec spec;
ModelVertexAttributes(String name, VertexAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public IAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 0;
}
@Override
public int getBufferIndex() {
return 0;
}
}

View file

@ -1,7 +1,5 @@
package com.simibubi.create.foundation.render.backend.instancing; package com.simibubi.create.foundation.render.backend.instancing;
import java.util.function.Consumer;
public class InstanceKey<D extends InstanceData> { public class InstanceKey<D extends InstanceData> {
public static final int INVALID = -1; public static final int INVALID = -1;

View file

@ -3,7 +3,6 @@ package com.simibubi.create.foundation.render.backend.instancing;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.*; import java.util.*;
import java.util.function.Consumer;
import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.RenderUtil; import com.simibubi.create.foundation.render.backend.RenderUtil;
@ -14,13 +13,13 @@ import org.lwjgl.opengl.GL20;
import com.simibubi.create.foundation.render.backend.BufferedModel; import com.simibubi.create.foundation.render.backend.BufferedModel;
import com.simibubi.create.foundation.render.backend.gl.GlBuffer; import com.simibubi.create.foundation.render.backend.gl.GlBuffer;
import com.simibubi.create.foundation.render.backend.gl.GlVertexArray; import com.simibubi.create.foundation.render.backend.gl.GlVertexArray;
import com.simibubi.create.foundation.render.backend.gl.attrib.ModelVertexAttributes; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
public abstract class InstancedModel<D extends InstanceData> extends BufferedModel { public abstract class InstancedModel<D extends InstanceData> extends BufferedModel {
public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelVertexAttributes.class).build(); public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelAttributes.class).build();
public final InstancedTileRenderer<?> renderer; public final InstancedTileRenderer<?> renderer;

View file

@ -9,6 +9,7 @@ import com.simibubi.create.foundation.render.backend.RenderMaterials;
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.impl.ModelData; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -52,7 +53,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
public void beginFrame(double cameraX, double cameraY, double cameraZ) { public void beginFrame(double cameraX, double cameraY, double cameraZ) {
if (queuedAdditions.size() > 0) { if (queuedAdditions.size() > 0) {
queuedAdditions.forEach(this::add); queuedAdditions.forEach(this::addInternal);
queuedAdditions.clear(); queuedAdditions.clear();
} }
if (dynamicInstances.size() > 0) if (dynamicInstances.size() > 0)
@ -75,33 +76,25 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
return (RenderMaterial<P, M>) materials.get(materialType); return (RenderMaterial<P, M>) materials.get(materialType);
} }
public RenderMaterial<P, InstancedModel<ModelData>> getBasicMaterial() { public RenderMaterial<P, InstancedModel<ModelData>> transformMaterial() {
return getMaterial(RenderMaterials.MODELS); return getMaterial(RenderMaterials.TRANSFORMED);
}
public RenderMaterial<P, InstancedModel<OrientedData>> orientedMaterial() {
return getMaterial(RenderMaterials.ORIENTED);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Nullable @Nullable
public <T extends TileEntity> TileEntityInstance<? super T> getInstance(T tile, boolean create) { public <T extends TileEntity> TileEntityInstance<? super T> getInstance(T tile, boolean create) {
if (!Backend.canUseInstancing() || !canCreateInstance(tile)) return null; if (!Backend.canUseInstancing()) return null;
TileEntityInstance<?> instance = instances.get(tile); TileEntityInstance<?> instance = instances.get(tile);
if (instance != null) { if (instance != null) {
return (TileEntityInstance<? super T>) instance; return (TileEntityInstance<? super T>) instance;
} else if (create) { } else if (create && canCreateInstance(tile)) {
TileEntityInstance<? super T> renderer = InstancedTileRenderRegistry.instance.create(this, tile); return createInternal(tile);
if (renderer != null) {
instances.put(tile, renderer);
if (renderer instanceof IDynamicInstance)
dynamicInstances.put(tile, (IDynamicInstance) renderer);
if (renderer instanceof ITickableInstance)
tickableInstances.put(tile, ((ITickableInstance) renderer));
}
return renderer;
} else { } else {
return null; return null;
} }
@ -122,7 +115,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
if (!Backend.canUseInstancing()) return; if (!Backend.canUseInstancing()) return;
if (tile instanceof IInstanceRendered) { if (tile instanceof IInstanceRendered) {
getInstance(tile, true); addInternal(tile);
} }
} }
@ -143,7 +136,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
if (instance.shouldReset()) { if (instance.shouldReset()) {
removeInternal(tile, instance); removeInternal(tile, instance);
getInstance(tile, true); createInternal(tile);
} else { } else {
instance.update(); instance.update();
} }
@ -159,6 +152,10 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
} }
} }
private void addInternal(TileEntity tile) {
getInstance(tile, true);
}
private <T extends TileEntity> void removeInternal(T tile) { private <T extends TileEntity> void removeInternal(T tile) {
TileEntityInstance<? super T> instance = getInstance(tile, false); TileEntityInstance<? super T> instance = getInstance(tile, false);
@ -167,14 +164,30 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
} }
} }
private <T extends TileEntity> void removeInternal(T tile, TileEntityInstance<? super T> instance) { private void removeInternal(TileEntity tile, TileEntityInstance<?> instance) {
instance.remove(); instance.remove();
instances.remove(tile); instances.remove(tile);
dynamicInstances.remove(tile); dynamicInstances.remove(tile);
tickableInstances.remove(tile); tickableInstances.remove(tile);
} }
public void clean() { private <T extends TileEntity> TileEntityInstance<? super T> createInternal(T tile) {
TileEntityInstance<? super T> renderer = InstancedTileRenderRegistry.instance.create(this, tile);
if (renderer != null) {
instances.put(tile, renderer);
if (renderer instanceof IDynamicInstance)
dynamicInstances.put(tile, (IDynamicInstance) renderer);
if (renderer instanceof ITickableInstance)
tickableInstances.put(tile, ((ITickableInstance) renderer));
}
return renderer;
}
private void clean() {
instances.keySet().removeIf(TileEntity::isRemoved); instances.keySet().removeIf(TileEntity::isRemoved);
} }

View file

@ -1,3 +1,10 @@
package com.simibubi.create.foundation.render.backend.instancing; package com.simibubi.create.foundation.render.backend.instancing;
public class MaterialType<M> { } import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
public class MaterialType<M extends InstancedModel<?>> {
public <P extends BasicProgram> RenderMaterial<?, M> get(InstancedTileRenderer<P> renderer) {
return renderer.getMaterial(this);
}
}

View file

@ -0,0 +1,39 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
public enum BasicAttributes implements IVertexAttrib {
LIGHT("aLight", CommonAttributes.LIGHT),
COLOR("aColor", CommonAttributes.RGBA),
;
private final String name;
private final IAttribSpec spec;
BasicAttributes(String name, IAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public IAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 0;
}
@Override
public int getBufferIndex() {
return 0;
}
}

View file

@ -0,0 +1,73 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
import java.nio.ByteBuffer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
public class BasicData extends InstanceData implements IFlatLight<BasicData> {
protected byte blockLight;
protected byte skyLight;
protected byte r = (byte) 0xFF;
protected byte g = (byte) 0xFF;
protected byte b = (byte) 0xFF;
protected byte a = (byte) 0xFF;
public BasicData(InstancedModel<?> owner) {
super(owner);
}
@Override
public BasicData setBlockLight(int blockLight) {
this.blockLight = (byte) (blockLight << 4);
return this;
}
@Override
public BasicData setSkyLight(int skyLight) {
this.skyLight = (byte) (skyLight << 4);
return this;
}
public BasicData setColor(int color) {
return setColor(color, false);
}
public BasicData setColor(int color, boolean alpha) {
byte r = (byte) ((color >> 16) & 0xFF);
byte g = (byte) ((color >> 8) & 0xFF);
byte b = (byte) (color & 0xFF);
if (alpha) {
byte a = (byte) ((color >> 24) & 0xFF);
return setColor(r, g, b, a);
} else {
return setColor(r, g, b);
}
}
public BasicData setColor(int r, int g, int b) {
return setColor((byte) r, (byte) g, (byte) b);
}
public BasicData setColor(byte r, byte g, byte b) {
this.r = r;
this.g = g;
this.b = b;
return this;
}
public BasicData setColor(byte r, byte g, byte b, byte a) {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
return this;
}
@Override
public void write(ByteBuffer buf) {
buf.put(new byte[] { blockLight, skyLight, r, g, b, a });
}
}

View file

@ -0,0 +1,41 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec;
public enum ModelAttributes implements IVertexAttrib {
VERTEX_POSITION("aPos", CommonAttributes.VEC3),
NORMAL("aNormal", CommonAttributes.NORMAL),
TEXTURE("aTexCoords", CommonAttributes.UV),
;
private final String name;
private final VertexAttribSpec spec;
ModelAttributes(String name, VertexAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public IAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 0;
}
@Override
public int getBufferIndex() {
return 0;
}
}

View file

@ -2,101 +2,28 @@ package com.simibubi.create.foundation.render.backend.instancing.impl;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.render.backend.RenderUtil; import com.simibubi.create.foundation.render.backend.RenderUtil;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import net.minecraft.client.renderer.Matrix3f;
import net.minecraft.client.renderer.Matrix4f;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
public class ModelData extends InstanceData implements IFlatLight<ModelData> { public class ModelData extends BasicData {
private static final Matrix4f IDENT4 = new Matrix4f(); private static final float[] empty = new float[25];
private static final Matrix3f IDENT3 = new Matrix3f();
static {
IDENT4.loadIdentity();
IDENT3.loadIdentity();
}
private Matrix4f modelMat = IDENT4; private float[] matrices = empty;
private Matrix3f normalMat = IDENT3;
private byte blockLight;
private byte skyLight;
private byte r = (byte) 0xFF;
private byte g = (byte) 0xFF;
private byte b = (byte) 0xFF;
private byte a = (byte) 0xFF;
public ModelData(InstancedModel<?> owner) { public ModelData(InstancedModel<?> owner) {
super(owner); super(owner);
} }
public ModelData setModelMat(Matrix4f modelMat) {
this.modelMat = modelMat;
return this;
}
public ModelData setNormalMat(Matrix3f normalMat) {
this.normalMat = normalMat;
return this;
}
public ModelData setTransform(MatrixStack stack) { public ModelData setTransform(MatrixStack stack) {
this.modelMat = stack.peek().getModel().copy(); matrices = RenderUtil.bufferMatrices(stack.peek().getModel(), stack.peek().getNormal());
this.normalMat = stack.peek().getNormal().copy();
return this;
}
public ModelData setTransformNoCopy(MatrixStack stack) {
this.modelMat = stack.peek().getModel();
this.normalMat = stack.peek().getNormal();
return this;
}
@Override
public ModelData setBlockLight(int blockLight) {
this.blockLight = (byte) (blockLight << 4);
return this;
}
@Override
public ModelData setSkyLight(int skyLight) {
this.skyLight = (byte) (skyLight << 4);
return this;
}
public ModelData setColor(int color) {
byte a = (byte) ((color >> 24) & 0xFF);
byte r = (byte) ((color >> 16) & 0xFF);
byte g = (byte) ((color >> 8) & 0xFF);
byte b = (byte) (color & 0xFF);
return setColor(r, g, b);
}
public ModelData setColor(int r, int g, int b) {
return setColor((byte) r, (byte) g, (byte) b);
}
public ModelData setColor(byte r, byte g, byte b) {
this.r = r;
this.g = g;
this.b = b;
return this;
}
public ModelData setColor(byte r, byte g, byte b, byte a) {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
return this; return this;
} }
@Override @Override
public void write(ByteBuffer buf) { public void write(ByteBuffer buf) {
RenderUtil.writeMat4(buf, modelMat); super.write(buf);
RenderUtil.writeMat3(buf, normalMat); buf.asFloatBuffer().put(matrices);
buf.put(new byte[] { blockLight, skyLight, r, g, b, a }); buf.position(buf.position() + matrices.length * 4);
} }
} }

View file

@ -0,0 +1,40 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
public enum OrientedAttributes implements IVertexAttrib {
INSTANCE_POS("aInstancePos", CommonAttributes.VEC3),
PIVOT("aPivot", CommonAttributes.VEC3),
ROTATION("aRotation", CommonAttributes.QUATERNION),
;
private final String name;
private final IAttribSpec spec;
OrientedAttributes(String name, IAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public IAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 0;
}
@Override
public int getBufferIndex() {
return 0;
}
}

View file

@ -0,0 +1,107 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
import net.minecraft.client.renderer.Quaternion;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.nio.ByteBuffer;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
public class OrientedData extends BasicData {
private float posX;
private float posY;
private float posZ;
private float pivotX = 0.5f;
private float pivotY = 0.5f;
private float pivotZ = 0.5f;
private float qX;
private float qY;
private float qZ;
private float qW;
public OrientedData(InstancedModel<?> owner) {
super(owner);
}
public OrientedData setPosition(BlockPos pos) {
return setPosition(pos.getX(), pos.getY(), pos.getZ());
}
public OrientedData setPosition(Vector3f pos) {
return setPosition(pos.getX(), pos.getY(), pos.getZ());
}
public OrientedData 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 OrientedData setPosition(float x, float y, float z) {
this.posX = x;
this.posY = y;
this.posZ = z;
return this;
}
public OrientedData nudge(float x, float y, float z) {
this.posX += x;
this.posY += y;
this.posZ += z;
return this;
}
public OrientedData setPivot(Vector3f pos) {
return setPosition(pos.getX(), pos.getY(), pos.getZ());
}
public OrientedData setPivot(Vec3d pos) {
return setPosition((float) pos.getX(), (float) pos.getY(), (float) pos.getZ());
}
public OrientedData setPivot(float x, float y, float z) {
this.pivotX = x;
this.pivotY = y;
this.pivotZ = z;
return this;
}
public OrientedData setRotation(Quaternion q) {
return setRotation(q.getX(), q.getY(), q.getZ(), q.getW());
}
public OrientedData setRotation(float x, float y, float z, float w) {
this.qX = x;
this.qY = y;
this.qZ = z;
this.qW = w;
return this;
}
@Override
public void write(ByteBuffer buf) {
super.write(buf);
buf.asFloatBuffer().put(new float[] {
posX,
posY,
posZ,
pivotX,
pivotY,
pivotZ,
qX,
qY,
qZ,
qW
});
buf.position(buf.position() + 10 * 4);
}
}

View file

@ -0,0 +1,28 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
import net.minecraft.client.renderer.BufferBuilder;
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;
public class OrientedModel extends InstancedModel<OrientedData> {
public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(OrientedAttributes.class)
.build();
public OrientedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf);
}
@Override
protected OrientedData newInstance() {
return new OrientedData(this);
}
@Override
protected VertexFormat getInstanceFormat() {
return INSTANCE_FORMAT;
}
}

View file

@ -1,16 +1,18 @@
package com.simibubi.create.foundation.render.backend.gl.attrib; package com.simibubi.create.foundation.render.backend.instancing.impl;
public enum InstanceVertexAttributes implements IVertexAttrib { import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.backend.gl.attrib.MatrixAttributes;
public enum TransformAttributes implements IVertexAttrib {
TRANSFORM("aTransform", MatrixAttributes.MAT4), TRANSFORM("aTransform", MatrixAttributes.MAT4),
NORMAL_MAT("aNormalMat", MatrixAttributes.MAT3), NORMAL_MAT("aNormalMat", MatrixAttributes.MAT3),
LIGHT("aLight", CommonAttributes.LIGHT),
COLOR("aColor", CommonAttributes.RGBA),
; ;
private final String name; private final String name;
private final IAttribSpec spec; private final IAttribSpec spec;
InstanceVertexAttributes(String name, IAttribSpec spec) { TransformAttributes(String name, IAttribSpec spec) {
this.name = name; this.name = name;
this.spec = spec; this.spec = spec;
} }

View file

@ -1,15 +1,17 @@
package com.simibubi.create.foundation.render.backend.instancing.impl; package com.simibubi.create.foundation.render.backend.instancing.impl;
import com.simibubi.create.foundation.render.backend.gl.attrib.InstanceVertexAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; 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.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
public class BasicInstancedModel extends InstancedModel<ModelData> { public class TransformedModel extends InstancedModel<ModelData> {
public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder().addAttributes(InstanceVertexAttributes.class).build(); public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(TransformAttributes.class)
.build();
public BasicInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) { public TransformedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf); super(renderer, buf);
} }

View file

@ -9,9 +9,9 @@ attribute vec3 aPos;
attribute vec3 aNormal; attribute vec3 aNormal;
attribute vec2 aTexCoords; attribute vec2 aTexCoords;
attribute vec3 aInstancePos;
attribute vec2 aLight; attribute vec2 aLight;
attribute vec3 aNetworkTint; attribute vec4 aColor;
attribute vec3 aInstancePos;
attribute float aSpeed; attribute float aSpeed;
attribute float aOffset; attribute float aOffset;
attribute vec4 aInstanceRot; attribute vec4 aInstanceRot;
@ -77,7 +77,7 @@ void main() {
} }
#else #else
if (uDebug == 1) { if (uDebug == 1) {
Color = vec4(aNetworkTint, 1.); Color = aColor;
} else if (uDebug == 2) { } else if (uDebug == 2) {
Color = vec4(norm, 1.); Color = vec4(norm, 1.);
} else { } else {

View file

@ -7,10 +7,10 @@ attribute vec3 aPos;
attribute vec3 aNormal; attribute vec3 aNormal;
attribute vec2 aTexCoords; attribute vec2 aTexCoords;
attribute mat4 aTransform;
attribute mat3 aNormalMat;
attribute vec2 aLight; attribute vec2 aLight;
attribute vec4 aColor; attribute vec4 aColor;
attribute mat4 aTransform;
attribute mat3 aNormalMat;
varying vec2 TexCoords; varying vec2 TexCoords;
varying vec4 Color; varying vec4 Color;
@ -38,11 +38,11 @@ varying float FragDistance;
void main() { void main() {
vec4 worldPos = aTransform * vec4(aPos, 1.); vec4 worldPos = aTransform * vec4(aPos, 1.);
mat3 normalMat = aNormalMat; vec3 norm = aNormalMat * aNormal;
#ifdef CONTRAPTION #ifdef CONTRAPTION
worldPos = uModel * worldPos; worldPos = uModel * worldPos;
normalMat *= modelToNormal(uModel); norm = modelToNormal(uModel) * norm;
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize; BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
#if defined(USE_FOG) #if defined(USE_FOG)
@ -52,7 +52,7 @@ void main() {
FragDistance = length(worldPos.xyz - uCameraPos); FragDistance = length(worldPos.xyz - uCameraPos);
#endif #endif
vec3 norm = normalize(normalMat * aNormal); norm = normalize(norm);
Diffuse = diffuse(norm); Diffuse = diffuse(norm);
TexCoords = aTexCoords; TexCoords = aTexCoords;

View file

@ -0,0 +1,63 @@
#version 110
#flwinclude <"create:core/matutils.glsl">
#flwinclude <"create:core/quaternion.glsl">
#flwinclude <"create:core/diffuse.glsl">
attribute vec3 aPos;
attribute vec3 aNormal;
attribute vec2 aTexCoords;
attribute vec2 aLight;
attribute vec4 aColor;
attribute vec3 aInstancePos;
attribute vec3 aPivot;
attribute vec4 aRotation;
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;
#if defined(USE_FOG)
varying float FragDistance;
#endif
void main() {
vec4 worldPos = vec4(rotateVertexByQuat(aPos - aPivot, aRotation) + aPivot + aInstancePos, 1.);
vec3 norm = rotateVertexByQuat(aNormal, aRotation);
#ifdef CONTRAPTION
worldPos = uModel * worldPos;
norm = normalize(modelToNormal(uModel) * norm);
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
#if defined(USE_FOG)
FragDistance = length(worldPos.xyz);
#endif
#elif defined(USE_FOG)
FragDistance = length(worldPos.xyz - uCameraPos);
#endif
Diffuse = diffuse(norm);
TexCoords = aTexCoords;
Light = aLight;
gl_Position = uViewProjection * worldPos;
Color = aColor;
}

View file

@ -9,9 +9,9 @@ attribute vec3 aPos;
attribute vec3 aNormal; attribute vec3 aNormal;
attribute vec2 aTexCoords; attribute vec2 aTexCoords;
attribute vec3 aInstancePos;
attribute vec2 aLight; attribute vec2 aLight;
attribute vec3 aNetworkTint; attribute vec4 aColor;
attribute vec3 aInstancePos;
attribute float aSpeed; attribute float aSpeed;
attribute float aOffset; attribute float aOffset;
attribute vec3 aAxis; attribute vec3 aAxis;
@ -54,7 +54,7 @@ void main() {
#ifdef CONTRAPTION #ifdef CONTRAPTION
worldPos = uModel * worldPos; worldPos = uModel * worldPos;
norm = modelToNormal(uModel) * norm; norm = normalize(modelToNormal(uModel) * norm);
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize; BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
#if defined(USE_FOG) #if defined(USE_FOG)
@ -77,7 +77,7 @@ void main() {
} }
#else #else
if (uDebug == 1) { if (uDebug == 1) {
Color = vec4(aNetworkTint, 1.); Color = aColor;
} else if (uDebug == 2) { } else if (uDebug == 2) {
Color = vec4(norm, 1.); Color = vec4(norm, 1.);
} else { } else {