Instanced arms.
This commit is contained in:
parent
d252a204ef
commit
95eabe9cf9
13 changed files with 375 additions and 129 deletions
|
@ -4,12 +4,11 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
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.TransformData;
|
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.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.world.LightType;
|
import net.minecraft.world.LightType;
|
||||||
|
@ -24,7 +23,7 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
|
||||||
|
|
||||||
float lastOffset = Float.NaN;
|
float lastOffset = Float.NaN;
|
||||||
|
|
||||||
private InstanceKey<TransformData> head;
|
private InstanceKey<ModelData> head;
|
||||||
|
|
||||||
public StickerInstance(InstancedTileRenderer<?> modelManager, StickerTileEntity tile) {
|
public StickerInstance(InstancedTileRenderer<?> modelManager, StickerTileEntity tile) {
|
||||||
super(modelManager, tile);
|
super(modelManager, tile);
|
||||||
|
@ -61,7 +60,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()
|
||||||
.setTransform(stack);
|
.setTransformNoCopy(stack);
|
||||||
|
|
||||||
lastOffset = offset;
|
lastOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import com.simibubi.create.foundation.render.backend.instancing.ITickableInstanc
|
||||||
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.InstancedTileRenderRegistry;
|
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 com.simibubi.create.foundation.render.backend.instancing.impl.TransformData;
|
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;
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
|
@ -28,7 +28,7 @@ public class GantryCarriageInstance extends ShaftInstance implements ITickableIn
|
||||||
InstancedTileRenderRegistry.instance.register(type, GantryCarriageInstance::new));
|
InstancedTileRenderRegistry.instance.register(type, GantryCarriageInstance::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstanceKey<TransformData> gantryCogs;
|
private InstanceKey<ModelData> gantryCogs;
|
||||||
|
|
||||||
public GantryCarriageInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
|
public GantryCarriageInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
|
||||||
super(dispatcher, tile);
|
super(dispatcher, tile);
|
||||||
|
@ -47,7 +47,7 @@ public class GantryCarriageInstance extends ShaftInstance implements ITickableIn
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
lastState = world.getBlockState(pos);
|
lastState = tile.getBlockState();
|
||||||
Direction facing = lastState.get(GantryCarriageBlock.FACING);
|
Direction facing = lastState.get(GantryCarriageBlock.FACING);
|
||||||
Boolean alongFirst = lastState.get(GantryCarriageBlock.AXIS_ALONG_FIRST_COORDINATE);
|
Boolean alongFirst = lastState.get(GantryCarriageBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||||
Direction.Axis rotationAxis = KineticTileEntityRenderer.getRotationAxisOf(tile);
|
Direction.Axis rotationAxis = KineticTileEntityRenderer.getRotationAxisOf(tile);
|
||||||
|
@ -80,7 +80,7 @@ public class GantryCarriageInstance extends ShaftInstance implements ITickableIn
|
||||||
.translate(0, 9 / 16f, 0)
|
.translate(0, 9 / 16f, 0)
|
||||||
.unCentre();
|
.unCentre();
|
||||||
|
|
||||||
gantryCogs.getInstance().setTransform(ms);
|
gantryCogs.getInstance().setTransformNoCopy(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,14 +10,14 @@ import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||||
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.TransformedInstancedModel;
|
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
|
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerMaterials() {
|
public void registerMaterials() {
|
||||||
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, TransformedInstancedModel::new));
|
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, BasicInstancedModel::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, RotatingInstancedModel::new));
|
||||||
|
|
|
@ -1,29 +1,178 @@
|
||||||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
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.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.gui.widgets.InterpolatedValue;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
|
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||||
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.ItemRenderer;
|
||||||
|
import net.minecraft.item.BlockItem;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.LightType;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
|
||||||
public class ArmInstance extends SingleRotatingInstance {
|
import java.util.ArrayList;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class ArmInstance extends SingleRotatingInstance implements ITickableInstance {
|
||||||
public static void register(TileEntityType<? extends KineticTileEntity> type) {
|
public static void register(TileEntityType<? extends KineticTileEntity> type) {
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||||
InstancedTileRenderRegistry.instance.register(type, ArmInstance::new));
|
InstancedTileRenderRegistry.instance.register(type, ArmInstance::new));
|
||||||
}
|
}
|
||||||
|
private InstanceKey<ModelData> base;
|
||||||
|
private InstanceKey<ModelData> lowerBody;
|
||||||
|
private InstanceKey<ModelData> upperBody;
|
||||||
|
private InstanceKey<ModelData> head;
|
||||||
|
private InstanceKey<ModelData> claw;
|
||||||
|
private ArrayList<InstanceKey<ModelData>> clawGrips;
|
||||||
|
|
||||||
|
private ArrayList<InstanceKey<ModelData>> models;
|
||||||
|
|
||||||
|
private boolean firstTick = true;
|
||||||
|
|
||||||
public ArmInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) {
|
public ArmInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) {
|
||||||
super(modelManager, tile);
|
super(modelManager, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS);
|
||||||
|
|
||||||
|
base = mat.getModel(AllBlockPartials.ARM_BASE, lastState).createInstance();
|
||||||
|
lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, lastState).createInstance();
|
||||||
|
upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, lastState).createInstance();
|
||||||
|
head = mat.getModel(AllBlockPartials.ARM_HEAD, lastState).createInstance();
|
||||||
|
claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, lastState).createInstance();
|
||||||
|
|
||||||
|
InstancedModel<ModelData> clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, lastState);
|
||||||
|
InstanceKey<ModelData> clawGrip1 = clawHalfModel.createInstance();
|
||||||
|
InstanceKey<ModelData> clawGrip2 = clawHalfModel.createInstance();
|
||||||
|
|
||||||
|
clawGrips = Lists.newArrayList(clawGrip1, clawGrip2);
|
||||||
|
models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2);
|
||||||
|
|
||||||
|
tick();
|
||||||
|
updateLight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
ArmTileEntity arm = (ArmTileEntity) tile;
|
||||||
|
|
||||||
|
boolean settled = Stream.of(arm.baseAngle, arm.lowerArmAngle, arm.upperArmAngle, arm.headAngle).allMatch(InterpolatedValue::settled);
|
||||||
|
boolean rave = arm.phase == ArmTileEntity.Phase.DANCING;
|
||||||
|
|
||||||
|
if (!settled || rave || firstTick)
|
||||||
|
transformModels(arm, rave);
|
||||||
|
|
||||||
|
if (settled)
|
||||||
|
firstTick = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void transformModels(ArmTileEntity arm, boolean rave) {
|
||||||
|
float pt = AnimationTickHolder.getPartialTicks();
|
||||||
|
int color = 0xFFFFFF;
|
||||||
|
|
||||||
|
float baseAngle = arm.baseAngle.get(pt);
|
||||||
|
float lowerArmAngle = arm.lowerArmAngle.get(pt) - 135;
|
||||||
|
float upperArmAngle = arm.upperArmAngle.get(pt) - 90;
|
||||||
|
float headAngle = arm.headAngle.get(pt);
|
||||||
|
|
||||||
|
if (rave) {
|
||||||
|
float renderTick = AnimationTickHolder.getRenderTime() + (tile.hashCode() % 64);
|
||||||
|
baseAngle = (renderTick * 10) % 360;
|
||||||
|
lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15);
|
||||||
|
upperArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 8) + 1) / 4, -45, 95);
|
||||||
|
headAngle = -lowerArmAngle;
|
||||||
|
color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MatrixStack msLocal = new MatrixStack();
|
||||||
|
MatrixStacker msr = MatrixStacker.of(msLocal);
|
||||||
|
msr.translate(getFloatingPos());
|
||||||
|
msr.centre();
|
||||||
|
|
||||||
|
if (lastState.get(ArmBlock.CEILING))
|
||||||
|
msr.rotateX(180);
|
||||||
|
|
||||||
|
ArmRenderer.transformBase(msr, baseAngle);
|
||||||
|
base.getInstance()
|
||||||
|
.setTransform(msLocal);
|
||||||
|
|
||||||
|
ArmRenderer.transformLowerArm(msr, lowerArmAngle);
|
||||||
|
lowerBody.getInstance()
|
||||||
|
.setColor(color)
|
||||||
|
.setTransform(msLocal);
|
||||||
|
|
||||||
|
ArmRenderer.transformUpperArm(msr, upperArmAngle);
|
||||||
|
upperBody.getInstance()
|
||||||
|
.setColor(color)
|
||||||
|
.setTransform(msLocal);
|
||||||
|
|
||||||
|
ArmRenderer.transformHead(msr, headAngle);
|
||||||
|
head.getInstance()
|
||||||
|
.setTransform(msLocal);
|
||||||
|
|
||||||
|
ArmRenderer.transformClaw(msr);
|
||||||
|
claw.getInstance()
|
||||||
|
.setTransform(msLocal);
|
||||||
|
|
||||||
|
ItemStack item = arm.heldItem;
|
||||||
|
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||||
|
.getItemRenderer();
|
||||||
|
boolean hasItem = !item.isEmpty();
|
||||||
|
boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem)
|
||||||
|
&& itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null)
|
||||||
|
.isGui3d();
|
||||||
|
|
||||||
|
for (int index : Iterate.zeroAndOne) {
|
||||||
|
msLocal.push();
|
||||||
|
int flip = index * 2 - 1;
|
||||||
|
ArmRenderer.transformClawHalf(msr, hasItem, isBlockItem, flip);
|
||||||
|
clawGrips.get(index)
|
||||||
|
.getInstance()
|
||||||
|
.setTransform(msLocal);
|
||||||
|
msLocal.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLight() {
|
||||||
|
super.updateLight();
|
||||||
|
byte block = (byte) (world.getLightLevel(LightType.BLOCK, pos) << 4);
|
||||||
|
byte sky = (byte) (world.getLightLevel(LightType.SKY, pos) << 4);
|
||||||
|
|
||||||
|
|
||||||
|
models.stream()
|
||||||
|
.map(InstanceKey::getInstance)
|
||||||
|
.forEach(data -> data.setSkyLight(sky).setBlockLight(block));
|
||||||
|
}
|
||||||
|
|
||||||
@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
|
||||||
|
public void remove() {
|
||||||
|
super.remove();
|
||||||
|
models.forEach(InstanceKey::delete);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
||||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||||
|
import com.simibubi.create.foundation.render.backend.Backend;
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
@ -39,6 +40,21 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
||||||
int overlay) {
|
int overlay) {
|
||||||
super.renderSafe(te, pt, ms, buffer, light, overlay);
|
super.renderSafe(te, pt, ms, buffer, light, overlay);
|
||||||
ArmTileEntity arm = (ArmTileEntity) te;
|
ArmTileEntity arm = (ArmTileEntity) te;
|
||||||
|
|
||||||
|
boolean usingFlywheel = Backend.canUseInstancing();
|
||||||
|
|
||||||
|
ItemStack item = arm.heldItem;
|
||||||
|
boolean hasItem = !item.isEmpty();
|
||||||
|
|
||||||
|
if (usingFlywheel && !hasItem) return;
|
||||||
|
|
||||||
|
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||||
|
.getItemRenderer();
|
||||||
|
|
||||||
|
boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem)
|
||||||
|
&& itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null)
|
||||||
|
.isGui3d();
|
||||||
|
|
||||||
IVertexBuilder builder = buffer.getBuffer(RenderType.getSolid());
|
IVertexBuilder builder = buffer.getBuffer(RenderType.getSolid());
|
||||||
BlockState blockState = te.getBlockState();
|
BlockState blockState = te.getBlockState();
|
||||||
|
|
||||||
|
@ -61,59 +77,15 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
||||||
color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100);
|
color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
SuperByteBuffer base = AllBlockPartials.ARM_BASE.renderOn(blockState).light(light);
|
|
||||||
SuperByteBuffer lowerBody = AllBlockPartials.ARM_LOWER_BODY.renderOn(blockState).light(light);
|
|
||||||
SuperByteBuffer upperBody = AllBlockPartials.ARM_UPPER_BODY.renderOn(blockState).light(light);
|
|
||||||
SuperByteBuffer head = AllBlockPartials.ARM_HEAD.renderOn(blockState).light(light);
|
|
||||||
SuperByteBuffer claw = AllBlockPartials.ARM_CLAW_BASE.renderOn(blockState).light(light);
|
|
||||||
SuperByteBuffer clawGrip = AllBlockPartials.ARM_CLAW_GRIP.renderOn(blockState);
|
|
||||||
|
|
||||||
msr.centre();
|
msr.centre();
|
||||||
|
|
||||||
if (blockState.get(ArmBlock.CEILING))
|
if (blockState.get(ArmBlock.CEILING))
|
||||||
msr.rotateX(180);
|
msr.rotateX(180);
|
||||||
|
|
||||||
msLocal.translate(0, 4 / 16d, 0);
|
if (usingFlywheel)
|
||||||
msr.rotateY(baseAngle);
|
doItemTransforms(msr, baseAngle, lowerArmAngle, upperArmAngle, headAngle);
|
||||||
base.transform(msLocal)
|
else
|
||||||
.renderInto(ms, builder);
|
renderArm(builder, ms, msLocal, msr, blockState, color, baseAngle, lowerArmAngle, upperArmAngle, headAngle, hasItem, isBlockItem, light);
|
||||||
|
|
||||||
msLocal.translate(0, 1 / 16d, -2 / 16d);
|
|
||||||
msr.rotateX(lowerArmAngle);
|
|
||||||
msLocal.translate(0, -1 / 16d, 0);
|
|
||||||
lowerBody.color(color)
|
|
||||||
.transform(msLocal)
|
|
||||||
.renderInto(ms, builder);
|
|
||||||
|
|
||||||
msLocal.translate(0, 12 / 16d, 12 / 16d);
|
|
||||||
msr.rotateX(upperArmAngle);
|
|
||||||
upperBody.color(color)
|
|
||||||
.transform(msLocal)
|
|
||||||
.renderInto(ms, builder);
|
|
||||||
|
|
||||||
msLocal.translate(0, 11 / 16d, -11 / 16d);
|
|
||||||
msr.rotateX(headAngle);
|
|
||||||
head.transform(msLocal)
|
|
||||||
.renderInto(ms, builder);
|
|
||||||
|
|
||||||
msLocal.translate(0, 0, -4 / 16d);
|
|
||||||
claw.transform(msLocal)
|
|
||||||
.renderInto(ms, builder);
|
|
||||||
ItemStack item = arm.heldItem;
|
|
||||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
|
||||||
.getItemRenderer();
|
|
||||||
boolean hasItem = !item.isEmpty();
|
|
||||||
boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem)
|
|
||||||
&& itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null)
|
|
||||||
.isGui3d();
|
|
||||||
|
|
||||||
for (int flip : Iterate.positiveAndNegative) {
|
|
||||||
msLocal.push();
|
|
||||||
msLocal.translate(0, flip * 3 / 16d, -1 / 16d);
|
|
||||||
msr.rotateX(flip * (hasItem ? isBlockItem ? 0 : -35 : 0));
|
|
||||||
clawGrip.light(light).transform(msLocal).renderInto(ms, builder);
|
|
||||||
msLocal.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasItem) {
|
if (hasItem) {
|
||||||
ms.push();
|
ms.push();
|
||||||
|
@ -131,6 +103,83 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderArm(IVertexBuilder builder, MatrixStack ms, MatrixStack msLocal, MatrixStacker msr, BlockState blockState, int color, float baseAngle, float lowerArmAngle, float upperArmAngle, float headAngle, boolean hasItem, boolean isBlockItem, int light) {
|
||||||
|
SuperByteBuffer base = AllBlockPartials.ARM_BASE.renderOn(blockState).light(light);
|
||||||
|
SuperByteBuffer lowerBody = AllBlockPartials.ARM_LOWER_BODY.renderOn(blockState).light(light);
|
||||||
|
SuperByteBuffer upperBody = AllBlockPartials.ARM_UPPER_BODY.renderOn(blockState).light(light);
|
||||||
|
SuperByteBuffer head = AllBlockPartials.ARM_HEAD.renderOn(blockState).light(light);
|
||||||
|
SuperByteBuffer claw = AllBlockPartials.ARM_CLAW_BASE.renderOn(blockState).light(light);
|
||||||
|
SuperByteBuffer clawGrip = AllBlockPartials.ARM_CLAW_GRIP.renderOn(blockState);
|
||||||
|
|
||||||
|
transformBase(msr, baseAngle);
|
||||||
|
base.transform(msLocal)
|
||||||
|
.renderInto(ms, builder);
|
||||||
|
|
||||||
|
transformLowerArm(msr, lowerArmAngle);
|
||||||
|
lowerBody.color(color)
|
||||||
|
.transform(msLocal)
|
||||||
|
.renderInto(ms, builder);
|
||||||
|
|
||||||
|
transformUpperArm(msr, upperArmAngle);
|
||||||
|
upperBody.color(color)
|
||||||
|
.transform(msLocal)
|
||||||
|
.renderInto(ms, builder);
|
||||||
|
|
||||||
|
transformHead(msr, headAngle);
|
||||||
|
head.transform(msLocal)
|
||||||
|
.renderInto(ms, builder);
|
||||||
|
|
||||||
|
transformClaw(msr);
|
||||||
|
claw.transform(msLocal)
|
||||||
|
.renderInto(ms, builder);
|
||||||
|
|
||||||
|
for (int flip : Iterate.positiveAndNegative) {
|
||||||
|
msLocal.push();
|
||||||
|
transformClawHalf(msr, hasItem, isBlockItem, flip);
|
||||||
|
clawGrip.light(light).transform(msLocal).renderInto(ms, builder);
|
||||||
|
msLocal.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doItemTransforms(MatrixStacker msr, float baseAngle, float lowerArmAngle, float upperArmAngle, float headAngle) {
|
||||||
|
|
||||||
|
transformBase(msr, baseAngle);
|
||||||
|
transformLowerArm(msr, lowerArmAngle);
|
||||||
|
transformUpperArm(msr, upperArmAngle);
|
||||||
|
transformHead(msr, headAngle);
|
||||||
|
transformClaw(msr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transformClawHalf(MatrixStacker msr, boolean hasItem, boolean isBlockItem, int flip) {
|
||||||
|
msr.translate(0, flip * 3 / 16d, -1 / 16d);
|
||||||
|
msr.rotateX(flip * (hasItem ? isBlockItem ? 0 : -35 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transformClaw(MatrixStacker msr) {
|
||||||
|
msr.translate(0, 0, -4 / 16d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transformHead(MatrixStacker msr, float headAngle) {
|
||||||
|
msr.translate(0, 11 / 16d, -11 / 16d);
|
||||||
|
msr.rotateX(headAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transformUpperArm(MatrixStacker msr, float upperArmAngle) {
|
||||||
|
msr.translate(0, 12 / 16d, 12 / 16d);
|
||||||
|
msr.rotateX(upperArmAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transformLowerArm(MatrixStacker msr, float lowerArmAngle) {
|
||||||
|
msr.translate(0, 1 / 16d, -2 / 16d);
|
||||||
|
msr.rotateX(lowerArmAngle);
|
||||||
|
msr.translate(0, -1 / 16d, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transformBase(MatrixStacker msr, float baseAngle) {
|
||||||
|
msr.translate(0, 4 / 16d, 0);
|
||||||
|
msr.rotateY(baseAngle);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
|
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return AllBlockPartials.ARM_COG.renderOn(te.getBlockState());
|
return AllBlockPartials.ARM_COG.renderOn(te.getBlockState());
|
||||||
|
|
|
@ -17,4 +17,8 @@ public class InterpolatedValue {
|
||||||
return MathHelper.lerp(partialTicks, lastValue, value);
|
return MathHelper.lerp(partialTicks, lastValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean settled() {
|
||||||
|
return Math.abs(value - lastValue) < 1e-3;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ 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.TransformedInstancedModel;
|
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.Matrix4f;
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
@ -27,7 +27,7 @@ public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerMaterials() {
|
public void registerMaterials() {
|
||||||
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.MODEL, TransformedInstancedModel::new));
|
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.MODEL, BasicInstancedModel::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, RotatingInstancedModel::new));
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package com.simibubi.create.foundation.render.backend;
|
package com.simibubi.create.foundation.render.backend;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
|
|
||||||
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.TransformData;
|
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||||
|
|
||||||
public class RenderMaterials {
|
public class RenderMaterials {
|
||||||
public static final MaterialType<InstancedModel<TransformData>> MODELS = new MaterialType<>();
|
public static final MaterialType<InstancedModel<ModelData>> MODELS = new MaterialType<>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ public enum InstanceVertexAttributes implements IVertexAttrib {
|
||||||
TRANSFORM("aTransform", MatrixAttributes.MAT4),
|
TRANSFORM("aTransform", MatrixAttributes.MAT4),
|
||||||
NORMAL_MAT("aNormalMat", MatrixAttributes.MAT3),
|
NORMAL_MAT("aNormalMat", MatrixAttributes.MAT3),
|
||||||
LIGHT("aLight", CommonAttributes.LIGHT),
|
LIGHT("aLight", CommonAttributes.LIGHT),
|
||||||
|
COLOR("aColor", CommonAttributes.RGBA),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
|
@ -6,16 +6,16 @@ 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 TransformedInstancedModel extends InstancedModel<TransformData> {
|
public class BasicInstancedModel extends InstancedModel<ModelData> {
|
||||||
public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder().addAttributes(InstanceVertexAttributes.class).build();
|
public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder().addAttributes(InstanceVertexAttributes.class).build();
|
||||||
|
|
||||||
public TransformedInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
public BasicInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||||
super(renderer, buf);
|
super(renderer, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TransformData newInstance() {
|
protected ModelData newInstance() {
|
||||||
return new TransformData(this);
|
return new ModelData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -0,0 +1,100 @@
|
||||||
|
package com.simibubi.create.foundation.render.backend.instancing.impl;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
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 net.minecraft.client.renderer.Matrix3f;
|
||||||
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class ModelData extends InstanceData {
|
||||||
|
private static final Matrix4f IDENT4 = new Matrix4f();
|
||||||
|
private static final Matrix3f IDENT3 = new Matrix3f();
|
||||||
|
static {
|
||||||
|
IDENT4.loadIdentity();
|
||||||
|
IDENT3.loadIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Matrix4f modelMat = IDENT4;
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
this.modelMat = stack.peek().getModel().copy();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelData setBlockLight(byte blockLight) {
|
||||||
|
this.blockLight = blockLight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelData setSkyLight(byte skyLight) {
|
||||||
|
this.skyLight = skyLight;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuffer buf) {
|
||||||
|
RenderUtil.writeMat4(buf, modelMat);
|
||||||
|
RenderUtil.writeMat3(buf, normalMat);
|
||||||
|
buf.put(new byte[] { blockLight, skyLight, r, g, b, a });
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,56 +0,0 @@
|
||||||
package com.simibubi.create.foundation.render.backend.instancing.impl;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
|
||||||
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 net.minecraft.client.renderer.Matrix3f;
|
|
||||||
import net.minecraft.client.renderer.Matrix4f;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public class TransformData extends InstanceData {
|
|
||||||
|
|
||||||
private Matrix4f modelMat;
|
|
||||||
private Matrix3f normalMat;
|
|
||||||
|
|
||||||
private byte blockLight;
|
|
||||||
private byte skyLight;
|
|
||||||
|
|
||||||
public TransformData(InstancedModel<?> owner) {
|
|
||||||
super(owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransformData setModelMat(Matrix4f modelMat) {
|
|
||||||
this.modelMat = modelMat;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransformData setNormalMat(Matrix3f normalMat) {
|
|
||||||
this.normalMat = normalMat;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransformData setTransform(MatrixStack stack) {
|
|
||||||
this.modelMat = stack.peek().getModel();
|
|
||||||
this.normalMat = stack.peek().getNormal();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransformData setBlockLight(byte blockLight) {
|
|
||||||
this.blockLight = blockLight;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransformData setSkyLight(byte skyLight) {
|
|
||||||
this.skyLight = skyLight;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(ByteBuffer buf) {
|
|
||||||
RenderUtil.writeMat4(buf, modelMat);
|
|
||||||
RenderUtil.writeMat3(buf, normalMat);
|
|
||||||
buf.put(new byte[] { blockLight, skyLight });
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,6 +7,7 @@ attribute vec2 aTexCoords;
|
||||||
attribute mat4 aTransform;
|
attribute mat4 aTransform;
|
||||||
attribute mat3 aNormalMat;
|
attribute mat3 aNormalMat;
|
||||||
attribute vec2 aLight;
|
attribute vec2 aLight;
|
||||||
|
attribute vec4 aColor;
|
||||||
|
|
||||||
varying vec2 TexCoords;
|
varying vec2 TexCoords;
|
||||||
varying vec4 Color;
|
varying vec4 Color;
|
||||||
|
@ -72,5 +73,5 @@ void main() {
|
||||||
Light = aLight;
|
Light = aLight;
|
||||||
gl_Position = uViewProjection * worldPos;
|
gl_Position = uViewProjection * worldPos;
|
||||||
|
|
||||||
Color = vec4(1.);
|
Color = aColor;
|
||||||
}
|
}
|
Loading…
Reference in a new issue