Instanced bearings
This commit is contained in:
parent
b743e00978
commit
b9f6a3b94e
7 changed files with 189 additions and 31 deletions
|
@ -50,10 +50,7 @@ import com.simibubi.create.content.contraptions.components.press.PressInstance;
|
|||
import com.simibubi.create.content.contraptions.components.saw.SawInstance;
|
||||
import com.simibubi.create.content.contraptions.components.saw.SawRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.saw.SawTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkBearingTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.WindmillBearingTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.*;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.chassis.ChassisTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerInstance;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerRenderer;
|
||||
|
@ -380,21 +377,21 @@ public class AllTileEntities {
|
|||
|
||||
public static final TileEntityEntry<WindmillBearingTileEntity> WINDMILL_BEARING = Create.registrate()
|
||||
.tileEntity("windmill_bearing", WindmillBearingTileEntity::new)
|
||||
.instance(() -> BackHalfShaftInstance::new)
|
||||
.instance(() -> BearingInstance::new)
|
||||
.validBlocks(AllBlocks.WINDMILL_BEARING)
|
||||
.renderer(() -> BearingRenderer::new)
|
||||
.register();
|
||||
|
||||
public static final TileEntityEntry<MechanicalBearingTileEntity> MECHANICAL_BEARING = Create.registrate()
|
||||
.tileEntity("mechanical_bearing", MechanicalBearingTileEntity::new)
|
||||
.instance(() -> BackHalfShaftInstance::new)
|
||||
.instance(() -> BearingInstance::new)
|
||||
.validBlocks(AllBlocks.MECHANICAL_BEARING)
|
||||
.renderer(() -> BearingRenderer::new)
|
||||
.register();
|
||||
|
||||
public static final TileEntityEntry<ClockworkBearingTileEntity> CLOCKWORK_BEARING = Create.registrate()
|
||||
.tileEntity("clockwork_bearing", ClockworkBearingTileEntity::new)
|
||||
.instance(() -> BackHalfShaftInstance::new)
|
||||
.instance(() -> BearingInstance::new)
|
||||
.validBlocks(AllBlocks.CLOCKWORK_BEARING)
|
||||
.renderer(() -> BearingRenderer::new)
|
||||
.register();
|
||||
|
|
|
@ -8,15 +8,6 @@ public class NonStationaryLighter<C extends Contraption> extends ContraptionLigh
|
|||
super(contraption);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GridAlignedBB contraptionBoundsToVolume(GridAlignedBB bounds) {
|
||||
bounds.grow(2); // so we have at least enough data on the edges to avoid artifacts and have smooth lighting
|
||||
bounds.minY = Math.max(bounds.minY, 0);
|
||||
bounds.maxY = Math.min(bounds.maxY, 255);
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(RenderedContraption owner) {
|
||||
super.tick(owner);
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
||||
|
||||
import net.minecraft.client.renderer.Quaternion;
|
||||
import net.minecraft.client.renderer.Vector3f;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.contraptions.base.BackHalfShaftInstance;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.foundation.render.backend.core.OrientedData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
|
||||
public class BearingInstance<B extends KineticTileEntity & IBearingTileEntity> extends BackHalfShaftInstance implements IDynamicInstance {
|
||||
final B bearing;
|
||||
|
||||
final OrientedData topInstance;
|
||||
|
||||
final Vector3f rotationAxis;
|
||||
final Quaternion blockOrientation;
|
||||
|
||||
public BearingInstance(InstancedTileRenderer<?> modelManager, B tile) {
|
||||
super(modelManager, tile);
|
||||
this.bearing = tile;
|
||||
|
||||
Direction facing = blockState.get(BlockStateProperties.FACING);
|
||||
rotationAxis = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector();
|
||||
|
||||
blockOrientation = getBlockStateOrientation(facing);
|
||||
|
||||
AllBlockPartials top =
|
||||
bearing.isWoodenTop() ? AllBlockPartials.BEARING_TOP_WOODEN : AllBlockPartials.BEARING_TOP;
|
||||
|
||||
topInstance = getOrientedMaterial().getModel(top, blockState).createInstance();
|
||||
|
||||
topInstance.setPosition(getInstancePosition()).setRotation(blockOrientation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame() {
|
||||
|
||||
float interpolatedAngle = bearing.getInterpolatedAngle(AnimationTickHolder.getPartialTicks() - 1);
|
||||
Quaternion rot = rotationAxis.getDegreesQuaternion(interpolatedAngle);
|
||||
|
||||
rot.multiply(blockOrientation);
|
||||
|
||||
topInstance.setRotation(rot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
super.updateLight();
|
||||
relight(pos, topInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
topInstance.delete();
|
||||
}
|
||||
|
||||
static Quaternion getBlockStateOrientation(Direction facing) {
|
||||
Quaternion orientation;
|
||||
|
||||
if (facing.getAxis().isHorizontal()) {
|
||||
orientation = Vector3f.POSITIVE_Y.getDegreesQuaternion(AngleHelper.horizontalAngle(facing.getOpposite()));
|
||||
} else {
|
||||
orientation = Quaternion.IDENTITY.copy();
|
||||
}
|
||||
|
||||
orientation.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(-90 - AngleHelper.verticalAngle(facing)));
|
||||
return orientation;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import com.simibubi.create.AllBlockPartials;
|
|||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
|
@ -22,6 +23,9 @@ public class BearingRenderer extends KineticTileEntityRenderer {
|
|||
@Override
|
||||
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int light, int overlay) {
|
||||
|
||||
if (FastRenderDispatcher.available(te.getWorld())) return;
|
||||
|
||||
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||
|
||||
IBearingTileEntity bearingTe = (IBearingTileEntity) te;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.Quaternion;
|
||||
import net.minecraft.client.renderer.Vector3f;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
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.foundation.render.backend.core.OrientedData;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
|
||||
public class StabilizedBearingInstance extends ActorInstance {
|
||||
|
||||
final OrientedData topInstance;
|
||||
|
||||
final Direction facing;
|
||||
final Vector3f rotationAxis;
|
||||
final Quaternion blockOrientation;
|
||||
|
||||
public StabilizedBearingInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
|
||||
super(modelManager, context);
|
||||
|
||||
BlockState blockState = context.state;
|
||||
|
||||
facing = blockState.get(BlockStateProperties.FACING);
|
||||
rotationAxis = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, facing.getAxis()).getUnitVector();
|
||||
|
||||
blockOrientation = BearingInstance.getBlockStateOrientation(facing);
|
||||
|
||||
topInstance = modelManager.getOrientedMaterial().getModel(AllBlockPartials.BEARING_TOP, blockState).createInstance();
|
||||
|
||||
topInstance.setPosition(context.localPos)
|
||||
.setRotation(blockOrientation)
|
||||
.setBlockLight(localBlockLight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame() {
|
||||
float counterRotationAngle = StabilizedBearingMovementBehaviour.getCounterRotationAngle(context, facing, AnimationTickHolder.getPartialTicks());
|
||||
|
||||
Quaternion rotation = rotationAxis.getDegreesQuaternion(counterRotationAngle);
|
||||
|
||||
rotation.multiply(blockOrientation);
|
||||
|
||||
topInstance.setRotation(rotation);
|
||||
}
|
||||
}
|
|
@ -7,12 +7,16 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con
|
|||
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.OrientedContraptionEntity;
|
||||
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.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.Quaternion;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
|
@ -20,28 +24,57 @@ import net.minecraft.util.Direction.Axis;
|
|||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class StabilizedBearingMovementBehaviour extends MovementBehaviour {
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal,
|
||||
IRenderTypeBuffer buffer) {
|
||||
if (FastRenderDispatcher.available()) return;
|
||||
|
||||
Direction facing = context.state.get(BlockStateProperties.FACING);
|
||||
AllBlockPartials top = AllBlockPartials.BEARING_TOP;
|
||||
SuperByteBuffer superBuffer = top.renderOn(context.state);
|
||||
float renderPartialTicks = AnimationTickHolder.getPartialTicks();
|
||||
|
||||
// rotate to match blockstate
|
||||
Axis axis = facing.getAxis();
|
||||
if (axis.isHorizontal())
|
||||
superBuffer.rotateCentered(Direction.UP,
|
||||
AngleHelper.rad(AngleHelper.horizontalAngle(facing.getOpposite())));
|
||||
superBuffer.rotateCentered(Direction.EAST, AngleHelper.rad(-90 - AngleHelper.verticalAngle(facing)));
|
||||
Quaternion orientation = BearingInstance.getBlockStateOrientation(facing);
|
||||
|
||||
// rotate against parent
|
||||
float angle = getCounterRotationAngle(context, facing, renderPartialTicks) * facing.getAxisDirection().getOffset();
|
||||
|
||||
Quaternion rotation = facing.getUnitVector().getDegreesQuaternion(angle);
|
||||
|
||||
rotation.multiply(orientation);
|
||||
|
||||
orientation = rotation;
|
||||
|
||||
superBuffer.rotateCentered(orientation);
|
||||
|
||||
// render
|
||||
superBuffer.light(msLocal.peek()
|
||||
.getModel(), ContraptionRenderDispatcher.getLightOnContraption(context));
|
||||
superBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSpecialInstancedRendering() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ActorInstance createInstance(ContraptionKineticRenderer kr, MovementContext context) {
|
||||
return new StabilizedBearingInstance(kr, context);
|
||||
}
|
||||
|
||||
static float getCounterRotationAngle(MovementContext context, Direction facing, float renderPartialTicks) {
|
||||
float offset = 0;
|
||||
int offsetMultiplier = facing.getAxisDirection().getOffset();
|
||||
|
||||
|
||||
Axis axis = facing.getAxis();
|
||||
|
||||
AbstractContraptionEntity entity = context.contraption.entity;
|
||||
if (entity instanceof ControlledContraptionEntity) {
|
||||
ControlledContraptionEntity controlledCE = (ControlledContraptionEntity) entity;
|
||||
|
@ -54,17 +87,12 @@ public class StabilizedBearingMovementBehaviour extends MovementBehaviour {
|
|||
offset = -orientedCE.getYaw(renderPartialTicks);
|
||||
else {
|
||||
if (orientedCE.isInitialOrientationPresent() && orientedCE.getInitialOrientation()
|
||||
.getAxis() == axis)
|
||||
.getAxis() == axis)
|
||||
offset = -orientedCE.getPitch(renderPartialTicks);
|
||||
}
|
||||
}
|
||||
if (offset != 0)
|
||||
superBuffer.rotateCentered(Direction.UP, AngleHelper.rad(offset * offsetMultiplier));
|
||||
|
||||
// render
|
||||
superBuffer.light(msLocal.peek()
|
||||
.getModel(), ContraptionRenderDispatcher.getLightOnContraption(context));
|
||||
superBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -196,11 +196,21 @@ public class SuperByteBuffer extends TemplateBuffer {
|
|||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer rotate(Quaternion q) {
|
||||
transforms.multiply(q);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer rotateCentered(Direction axis, float radians) {
|
||||
return translate(.5f, .5f, .5f).rotate(axis, radians)
|
||||
.translate(-.5f, -.5f, -.5f);
|
||||
}
|
||||
|
||||
public SuperByteBuffer rotateCentered(Quaternion q) {
|
||||
return translate(.5f, .5f, .5f).rotate(q)
|
||||
.translate(-.5f, -.5f, -.5f);
|
||||
}
|
||||
|
||||
public SuperByteBuffer shiftUV(SpriteShiftEntry entry) {
|
||||
this.spriteShiftFunc = (builder, u, v) -> {
|
||||
float targetU = entry.getTarget().getInterpolatedU((getUnInterpolatedU(entry.getOriginal(), u)));
|
||||
|
|
Loading…
Reference in a new issue