mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-10 12:34:11 +01:00
Treeify bells and minecarts
- Use InstanceTrees in BellVisual and MinecartVisual - Use JOML Matrix4fStack instead of PoseStack - Directly transform Matrix4f instead of using PoseStack to compute initial pose
This commit is contained in:
parent
ed727e7a1b
commit
904933e22e
@ -73,6 +73,12 @@ public class PosedInstance extends ColoredLitInstance implements Transform<Posed
|
||||
return this;
|
||||
}
|
||||
|
||||
public PosedInstance setTransform(Matrix4fc pose, Matrix3fc normal) {
|
||||
this.pose.set(pose);
|
||||
this.normal.set(normal);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PosedInstance setTransform(PoseStack.Pose pose) {
|
||||
this.pose.set(pose.pose());
|
||||
normal.set(pose.normal());
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dev.engine_room.flywheel.lib.instance;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Quaternionfc;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
@ -40,6 +41,11 @@ public class TransformedInstance extends ColoredLitInstance implements Affine<Tr
|
||||
return this;
|
||||
}
|
||||
|
||||
public TransformedInstance setTransform(Matrix4fc pose) {
|
||||
this.pose.set(pose);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TransformedInstance setTransform(PoseStack.Pose pose) {
|
||||
this.pose.set(pose.pose());
|
||||
return this;
|
||||
|
@ -193,7 +193,7 @@ public final class InstanceTree {
|
||||
affine.rotate(tempQuaternion.rotationZYX(zRot, yRot, xRot));
|
||||
}
|
||||
|
||||
if (xScale != 1.0F || yScale != 1.0F || zScale != 1.0F) {
|
||||
if (xScale != ModelPart.DEFAULT_SCALE || yScale != ModelPart.DEFAULT_SCALE || zScale != ModelPart.DEFAULT_SCALE) {
|
||||
affine.scale(xScale, yScale, zScale);
|
||||
}
|
||||
}
|
||||
@ -300,13 +300,6 @@ public final class InstanceTree {
|
||||
return zScale;
|
||||
}
|
||||
|
||||
public void pos(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public void xPos(float x) {
|
||||
this.x = x;
|
||||
setChanged();
|
||||
@ -322,10 +315,10 @@ public final class InstanceTree {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public void rotation(float xRot, float yRot, float zRot) {
|
||||
this.xRot = xRot;
|
||||
this.yRot = yRot;
|
||||
this.zRot = zRot;
|
||||
public void pos(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@ -344,10 +337,10 @@ public final class InstanceTree {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public void scale(float xScale, float yScale, float zScale) {
|
||||
this.xScale = xScale;
|
||||
this.yScale = yScale;
|
||||
this.zScale = zScale;
|
||||
public void rotation(float xRot, float yRot, float zRot) {
|
||||
this.xRot = xRot;
|
||||
this.yRot = yRot;
|
||||
this.zRot = zRot;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@ -366,6 +359,13 @@ public final class InstanceTree {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public void scale(float xScale, float yScale, float zScale) {
|
||||
this.xScale = xScale;
|
||||
this.yScale = yScale;
|
||||
this.zScale = zScale;
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public void offsetPos(float xOffset, float yOffset, float zOffset) {
|
||||
x += xOffset;
|
||||
y += yOffset;
|
||||
@ -388,6 +388,10 @@ public final class InstanceTree {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public void offsetPos(Vector3fc offset) {
|
||||
offsetPos(offset.x(), offset.y(), offset.z());
|
||||
}
|
||||
|
||||
public void offsetRotation(float xOffset, float yOffset, float zOffset) {
|
||||
xRot += xOffset;
|
||||
yRot += yOffset;
|
||||
@ -410,6 +414,10 @@ public final class InstanceTree {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public void offsetRotation(Vector3fc offset) {
|
||||
offsetRotation(offset.x(), offset.y(), offset.z());
|
||||
}
|
||||
|
||||
public void offsetScale(float xOffset, float yOffset, float zOffset) {
|
||||
xScale += xOffset;
|
||||
yScale += yOffset;
|
||||
@ -432,14 +440,6 @@ public final class InstanceTree {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
public void offsetPos(Vector3fc offset) {
|
||||
offsetPos(offset.x(), offset.y(), offset.z());
|
||||
}
|
||||
|
||||
public void offsetRotation(Vector3fc offset) {
|
||||
offsetRotation(offset.x(), offset.y(), offset.z());
|
||||
}
|
||||
|
||||
public void offsetScale(Vector3fc offset) {
|
||||
offsetScale(offset.x(), offset.y(), offset.z());
|
||||
}
|
||||
@ -491,6 +491,10 @@ public final class InstanceTree {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
private void setChanged() {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
if (instance != null) {
|
||||
instance.delete();
|
||||
@ -500,10 +504,6 @@ public final class InstanceTree {
|
||||
}
|
||||
}
|
||||
|
||||
private void setChanged() {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@FunctionalInterface
|
||||
public interface ObjIntIntConsumer<T> {
|
||||
|
@ -99,6 +99,10 @@ public abstract class AbstractBlockEntityVisual<T extends BlockEntity> extends A
|
||||
.shouldUpdate(pos.distToCenterSqr(context.camera().getPosition()));
|
||||
}
|
||||
|
||||
protected int computePackedLight() {
|
||||
return LevelRenderer.getLightColor(level, pos);
|
||||
}
|
||||
|
||||
protected void relight(BlockPos pos, @Nullable FlatLit... instances) {
|
||||
FlatLit.relight(LevelRenderer.getLightColor(level, pos), instances);
|
||||
}
|
||||
|
@ -92,11 +92,14 @@ public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVis
|
||||
return entity.noCulling || visibilityTester.check(frustum);
|
||||
}
|
||||
|
||||
protected void relight(float partialTick, @Nullable FlatLit... instances) {
|
||||
protected int computePackedLight(float partialTick) {
|
||||
BlockPos pos = BlockPos.containing(entity.getLightProbePosition(partialTick));
|
||||
int blockLight = entity.isOnFire() ? 15 : level.getBrightness(LightLayer.BLOCK, pos);
|
||||
int skyLight = level.getBrightness(LightLayer.SKY, pos);
|
||||
int light = LightTexture.pack(blockLight, skyLight);
|
||||
FlatLit.relight(light, instances);
|
||||
return LightTexture.pack(blockLight, skyLight);
|
||||
}
|
||||
|
||||
protected void relight(float partialTick, @Nullable FlatLit... instances) {
|
||||
FlatLit.relight(computePackedLight(partialTick), instances);
|
||||
}
|
||||
}
|
||||
|
@ -2,23 +2,22 @@ package dev.engine_room.flywheel.vanilla;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.joml.AxisAngle4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.Instance;
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
|
||||
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
|
||||
import dev.engine_room.flywheel.lib.material.SimpleMaterial;
|
||||
import dev.engine_room.flywheel.lib.model.ModelHolder;
|
||||
import dev.engine_room.flywheel.lib.model.SingleMeshModel;
|
||||
import dev.engine_room.flywheel.lib.model.part.ModelPartConverter;
|
||||
import dev.engine_room.flywheel.lib.model.RetexturedMesh;
|
||||
import dev.engine_room.flywheel.lib.model.part.InstanceTree;
|
||||
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
|
||||
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
|
||||
import net.minecraft.client.model.geom.ModelLayers;
|
||||
import net.minecraft.client.renderer.blockentity.BellRenderer;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.entity.BellBlockEntity;
|
||||
|
||||
@ -27,29 +26,28 @@ public class BellVisual extends AbstractBlockEntityVisual<BellBlockEntity> imple
|
||||
.mipmap(false)
|
||||
.build();
|
||||
|
||||
private static final ModelHolder BELL_MODEL = new ModelHolder(() -> {
|
||||
return new SingleMeshModel(ModelPartConverter.convert(ModelLayers.BELL, BellRenderer.BELL_RESOURCE_LOCATION.sprite(), "bell_body"), MATERIAL);
|
||||
});
|
||||
private final InstanceTree instances;
|
||||
private final InstanceTree bellBody;
|
||||
|
||||
private final OrientedInstance bell;
|
||||
private final Matrix4fc initialPose;
|
||||
|
||||
private boolean wasShaking = false;
|
||||
|
||||
public BellVisual(VisualizationContext ctx, BellBlockEntity blockEntity, float partialTick) {
|
||||
super(ctx, blockEntity, partialTick);
|
||||
|
||||
bell = createBellInstance().pivot(0.5f, 0.75f, 0.5f)
|
||||
.position(getVisualPosition());
|
||||
bell.setChanged();
|
||||
TextureAtlasSprite sprite = BellRenderer.BELL_RESOURCE_LOCATION.sprite();
|
||||
instances = InstanceTree.create(instancerProvider(), ModelLayers.BELL, (path, mesh) -> {
|
||||
return new Model.ConfiguredMesh(MATERIAL, new RetexturedMesh(mesh, sprite));
|
||||
});
|
||||
bellBody = instances.childOrThrow("bell_body");
|
||||
|
||||
BlockPos visualPos = getVisualPosition();
|
||||
initialPose = new Matrix4f().translate(visualPos.getX(), visualPos.getY(), visualPos.getZ());
|
||||
|
||||
updateRotation(partialTick);
|
||||
}
|
||||
|
||||
private OrientedInstance createBellInstance() {
|
||||
return instancerProvider().instancer(InstanceTypes.ORIENTED, BELL_MODEL.get())
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(Context context) {
|
||||
if (doDistanceLimitThisFrame(context) || !isVisible(context.frustum())) {
|
||||
@ -60,37 +58,46 @@ public class BellVisual extends AbstractBlockEntityVisual<BellBlockEntity> imple
|
||||
}
|
||||
|
||||
private void updateRotation(float partialTick) {
|
||||
float xRot = 0;
|
||||
float zRot = 0;
|
||||
|
||||
if (blockEntity.shaking) {
|
||||
float ringTime = (float) blockEntity.ticks + partialTick;
|
||||
float angle = Mth.sin(ringTime / (float) Math.PI) / (4.0F + ringTime / 3.0F);
|
||||
|
||||
Vector3f ringAxis = blockEntity.clickDirection.getCounterClockWise()
|
||||
.step();
|
||||
|
||||
bell.rotation(new Quaternionf(new AxisAngle4f(angle, ringAxis)))
|
||||
.setChanged();
|
||||
switch (blockEntity.clickDirection) {
|
||||
case NORTH -> xRot = -angle;
|
||||
case SOUTH -> xRot = angle;
|
||||
case EAST -> zRot = -angle;
|
||||
case WEST -> zRot = angle;
|
||||
}
|
||||
|
||||
wasShaking = true;
|
||||
} else if (wasShaking) {
|
||||
bell.rotation(new Quaternionf())
|
||||
.setChanged();
|
||||
|
||||
wasShaking = false;
|
||||
}
|
||||
|
||||
bellBody.xRot(xRot);
|
||||
bellBody.zRot(zRot);
|
||||
instances.updateInstancesStatic(initialPose);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight(float partialTick) {
|
||||
relight(bell);
|
||||
int packedLight = computePackedLight();
|
||||
instances.traverse(instance -> {
|
||||
instance.light(packedLight)
|
||||
.setChanged();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectCrumblingInstances(Consumer<Instance> consumer) {
|
||||
consumer.accept(bell);
|
||||
instances.traverse(consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _delete() {
|
||||
bell.delete();
|
||||
instances.delete();
|
||||
}
|
||||
}
|
||||
|
@ -6,19 +6,17 @@ import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
|
||||
import dev.engine_room.flywheel.api.instance.Instance;
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.model.Model;
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import dev.engine_room.flywheel.lib.material.CutoutShaders;
|
||||
import dev.engine_room.flywheel.lib.material.SimpleMaterial;
|
||||
import dev.engine_room.flywheel.lib.model.RetexturedMesh;
|
||||
import dev.engine_room.flywheel.lib.model.part.InstanceTree;
|
||||
import dev.engine_room.flywheel.lib.transform.TransformStack;
|
||||
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
|
||||
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
|
||||
import it.unimi.dsi.fastutil.floats.Float2FloatFunction;
|
||||
@ -29,7 +27,9 @@ import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.Sheets;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.AbstractChestBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
@ -40,7 +40,7 @@ import net.minecraft.world.level.block.entity.LidBlockEntity;
|
||||
import net.minecraft.world.level.block.state.properties.ChestType;
|
||||
|
||||
public class ChestVisual<T extends BlockEntity & LidBlockEntity> extends AbstractBlockEntityVisual<T> implements SimpleDynamicVisual {
|
||||
private static final dev.engine_room.flywheel.api.material.Material MATERIAL = SimpleMaterial.builder()
|
||||
private static final Material MATERIAL = SimpleMaterial.builder()
|
||||
.cutout(CutoutShaders.ONE_TENTH)
|
||||
.texture(Sheets.CHEST_SHEET)
|
||||
.mipmap(false)
|
||||
@ -84,14 +84,7 @@ public class ChestVisual<T extends BlockEntity & LidBlockEntity> extends Abstrac
|
||||
lid = instances.childOrThrow("lid");
|
||||
lock = instances.childOrThrow("lock");
|
||||
|
||||
PoseStack poseStack = new PoseStack();
|
||||
TransformStack.of(poseStack).translate(getVisualPosition());
|
||||
float horizontalAngle = blockState.getValue(ChestBlock.FACING).toYRot();
|
||||
poseStack.translate(0.5F, 0.5F, 0.5F);
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(-horizontalAngle));
|
||||
poseStack.translate(-0.5F, -0.5F, -0.5F);
|
||||
initialPose = poseStack.last().pose();
|
||||
|
||||
initialPose = createInitialPose();
|
||||
neighborCombineResult = chestBlock.combine(blockState, level, pos, true);
|
||||
lidProgress = neighborCombineResult.apply(ChestBlock.opennessCombiner(blockEntity));
|
||||
|
||||
@ -112,6 +105,15 @@ public class ChestVisual<T extends BlockEntity & LidBlockEntity> extends Abstrac
|
||||
return calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DATE) >= 24 && calendar.get(Calendar.DATE) <= 26;
|
||||
}
|
||||
|
||||
private Matrix4f createInitialPose() {
|
||||
BlockPos visualPos = getVisualPosition();
|
||||
float horizontalAngle = blockState.getValue(ChestBlock.FACING).toYRot();
|
||||
return new Matrix4f().translate(visualPos.getX(), visualPos.getY(), visualPos.getZ())
|
||||
.translate(0.5F, 0.5F, 0.5F)
|
||||
.rotateY(-horizontalAngle * Mth.DEG_TO_RAD)
|
||||
.translate(-0.5F, -0.5F, -0.5F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSectionCollector(SectionCollector sectionCollector) {
|
||||
this.lightSections = sectionCollector;
|
||||
|
@ -1,22 +1,19 @@
|
||||
package dev.engine_room.flywheel.vanilla;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fStack;
|
||||
|
||||
import dev.engine_room.flywheel.api.material.Material;
|
||||
import dev.engine_room.flywheel.api.visual.DynamicVisual;
|
||||
import dev.engine_room.flywheel.api.visual.TickableVisual;
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import dev.engine_room.flywheel.lib.instance.FlatLit;
|
||||
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
|
||||
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
|
||||
import dev.engine_room.flywheel.lib.material.SimpleMaterial;
|
||||
import dev.engine_room.flywheel.lib.model.ModelHolder;
|
||||
import dev.engine_room.flywheel.lib.model.Models;
|
||||
import dev.engine_room.flywheel.lib.model.SingleMeshModel;
|
||||
import dev.engine_room.flywheel.lib.model.part.ModelPartConverter;
|
||||
import dev.engine_room.flywheel.lib.util.RecyclingPoseStack;
|
||||
import dev.engine_room.flywheel.lib.model.part.InstanceTree;
|
||||
import dev.engine_room.flywheel.lib.visual.ComponentEntityVisual;
|
||||
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
|
||||
import dev.engine_room.flywheel.lib.visual.SimpleTickableVisual;
|
||||
@ -24,7 +21,6 @@ import dev.engine_room.flywheel.lib.visual.component.FireComponent;
|
||||
import dev.engine_room.flywheel.lib.visual.component.HitboxComponent;
|
||||
import dev.engine_room.flywheel.lib.visual.component.ShadowComponent;
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
import net.minecraft.client.model.geom.ModelLayers;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
@ -39,31 +35,19 @@ public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityV
|
||||
.mipmap(false)
|
||||
.build();
|
||||
|
||||
public static final ModelHolder CHEST_BODY_MODEL = createBodyModelHolder(ModelLayers.CHEST_MINECART);
|
||||
public static final ModelHolder COMMAND_BLOCK_BODY_MODEL = createBodyModelHolder(ModelLayers.COMMAND_BLOCK_MINECART);
|
||||
public static final ModelHolder FURNACE_BODY_MODEL = createBodyModelHolder(ModelLayers.FURNACE_MINECART);
|
||||
public static final ModelHolder HOPPER_BODY_MODEL = createBodyModelHolder(ModelLayers.HOPPER_MINECART);
|
||||
public static final ModelHolder STANDARD_BODY_MODEL = createBodyModelHolder(ModelLayers.MINECART);
|
||||
public static final ModelHolder SPAWNER_BODY_MODEL = createBodyModelHolder(ModelLayers.SPAWNER_MINECART);
|
||||
public static final ModelHolder TNT_BODY_MODEL = createBodyModelHolder(ModelLayers.TNT_MINECART);
|
||||
|
||||
private final TransformedInstance body;
|
||||
private final InstanceTree instances;
|
||||
@Nullable
|
||||
private TransformedInstance contents;
|
||||
|
||||
private final ModelHolder bodyModel;
|
||||
|
||||
private final RecyclingPoseStack stack = new RecyclingPoseStack();
|
||||
private final Matrix4fStack stack = new Matrix4fStack(2);
|
||||
|
||||
private BlockState blockState;
|
||||
private boolean active;
|
||||
|
||||
public MinecartVisual(VisualizationContext ctx, T entity, float partialTick, ModelHolder bodyModel) {
|
||||
public MinecartVisual(VisualizationContext ctx, T entity, float partialTick, ModelLayerLocation layerLocation) {
|
||||
super(ctx, entity, partialTick);
|
||||
|
||||
this.bodyModel = bodyModel;
|
||||
|
||||
body = createBodyInstance();
|
||||
instances = InstanceTree.create(instancerProvider(), layerLocation, MATERIAL);
|
||||
blockState = entity.getDisplayBlockState();
|
||||
contents = createContentsInstance();
|
||||
|
||||
@ -75,23 +59,12 @@ public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityV
|
||||
updateLight(partialTick);
|
||||
}
|
||||
|
||||
private static ModelHolder createBodyModelHolder(ModelLayerLocation layer) {
|
||||
return new ModelHolder(() -> {
|
||||
return new SingleMeshModel(ModelPartConverter.convert(layer), MATERIAL);
|
||||
});
|
||||
}
|
||||
|
||||
private TransformedInstance createBodyInstance() {
|
||||
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, bodyModel.get())
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TransformedInstance createContentsInstance() {
|
||||
RenderShape shape = blockState.getRenderShape();
|
||||
|
||||
if (shape == RenderShape.ENTITYBLOCK_ANIMATED) {
|
||||
body.setZeroTransform();
|
||||
instances.traverse(instance -> instance.setZeroTransform().setChanged());
|
||||
active = false;
|
||||
return null;
|
||||
}
|
||||
@ -135,14 +108,14 @@ public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityV
|
||||
}
|
||||
|
||||
private void updateInstances(float partialTick) {
|
||||
stack.setIdentity();
|
||||
stack.identity();
|
||||
|
||||
double posX = Mth.lerp(partialTick, entity.xOld, entity.getX());
|
||||
double posY = Mth.lerp(partialTick, entity.yOld, entity.getY());
|
||||
double posZ = Mth.lerp(partialTick, entity.zOld, entity.getZ());
|
||||
|
||||
var renderOrigin = renderOrigin();
|
||||
stack.translate(posX - renderOrigin.getX(), posY - renderOrigin.getY(), posZ - renderOrigin.getZ());
|
||||
stack.translate((float) (posX - renderOrigin.getX()), (float) (posY - renderOrigin.getY()), (float) (posZ - renderOrigin.getZ()));
|
||||
float yaw = Mth.lerp(partialTick, entity.yRotO, entity.getYRot());
|
||||
|
||||
long randomBits = entity.getId() * 493286711L;
|
||||
@ -166,7 +139,7 @@ public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityV
|
||||
offset2 = pos;
|
||||
}
|
||||
|
||||
stack.translate(pos.x - posX, (offset1.y + offset2.y) / 2.0D - posY, pos.z - posZ);
|
||||
stack.translate((float) (pos.x - posX), (float) ((offset1.y + offset2.y) / 2.0D - posY), (float) (pos.z - posZ));
|
||||
Vec3 vec = offset2.add(-offset1.x, -offset1.y, -offset1.z);
|
||||
if (vec.length() != 0.0D) {
|
||||
vec = vec.normalize();
|
||||
@ -175,9 +148,9 @@ public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityV
|
||||
}
|
||||
}
|
||||
|
||||
stack.translate(0.0D, 0.375D, 0.0D);
|
||||
stack.mulPose(Axis.YP.rotationDegrees(180 - yaw));
|
||||
stack.mulPose(Axis.ZP.rotationDegrees(-pitch));
|
||||
stack.translate(0.0F, 0.375F, 0.0F);
|
||||
stack.rotateY((180 - yaw) * Mth.DEG_TO_RAD);
|
||||
stack.rotateZ(-pitch * Mth.DEG_TO_RAD);
|
||||
|
||||
float hurtTime = entity.getHurtTime() - partialTick;
|
||||
float damage = entity.getDamage() - partialTick;
|
||||
@ -187,40 +160,44 @@ public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityV
|
||||
}
|
||||
|
||||
if (hurtTime > 0) {
|
||||
stack.mulPose(Axis.XP.rotationDegrees(Mth.sin(hurtTime) * hurtTime * damage / 10.0F * (float) entity.getHurtDir()));
|
||||
stack.rotateX((Mth.sin(hurtTime) * hurtTime * damage / 10.0F * (float) entity.getHurtDir()) * Mth.DEG_TO_RAD);
|
||||
}
|
||||
|
||||
int displayOffset = entity.getDisplayOffset();
|
||||
if (contents != null) {
|
||||
stack.pushPose();
|
||||
int displayOffset = entity.getDisplayOffset();
|
||||
stack.pushMatrix();
|
||||
stack.scale(0.75F, 0.75F, 0.75F);
|
||||
stack.translate(-0.5F, (float) (displayOffset - 8) / 16, 0.5F);
|
||||
stack.mulPose(Axis.YP.rotationDegrees(90));
|
||||
stack.rotateY(90 * Mth.DEG_TO_RAD);
|
||||
updateContents(contents, stack, partialTick);
|
||||
stack.popPose();
|
||||
stack.popMatrix();
|
||||
}
|
||||
|
||||
stack.scale(-1.0F, -1.0F, 1.0F);
|
||||
body.setTransform(stack)
|
||||
.setChanged();
|
||||
instances.updateInstances(stack);
|
||||
|
||||
// TODO: Use LightUpdatedVisual/ShaderLightVisual if possible.
|
||||
updateLight(partialTick);
|
||||
}
|
||||
|
||||
protected void updateContents(TransformedInstance contents, PoseStack stack, float partialTick) {
|
||||
contents.setTransform(stack)
|
||||
protected void updateContents(TransformedInstance contents, Matrix4f pose, float partialTick) {
|
||||
contents.setTransform(pose)
|
||||
.setChanged();
|
||||
}
|
||||
|
||||
public void updateLight(float partialTick) {
|
||||
relight(partialTick, body, contents);
|
||||
int packedLight = computePackedLight(partialTick);
|
||||
instances.traverse(instance -> {
|
||||
instance.light(packedLight)
|
||||
.setChanged();
|
||||
});
|
||||
FlatLit.relight(packedLight, contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _delete() {
|
||||
super._delete();
|
||||
body.delete();
|
||||
instances.delete();
|
||||
if (contents != null) {
|
||||
contents.delete();
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package dev.engine_room.flywheel.vanilla;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
|
||||
import net.minecraft.client.model.geom.ModelLayers;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.vehicle.MinecartTNT;
|
||||
@ -12,11 +13,11 @@ public class TntMinecartVisual<T extends MinecartTNT> extends MinecartVisual<T>
|
||||
private static final int WHITE_OVERLAY = OverlayTexture.pack(OverlayTexture.u(1.0F), 10);
|
||||
|
||||
public TntMinecartVisual(VisualizationContext ctx, T entity, float partialTick) {
|
||||
super(ctx, entity, partialTick, TNT_BODY_MODEL);
|
||||
super(ctx, entity, partialTick, ModelLayers.TNT_MINECART);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateContents(TransformedInstance contents, PoseStack stack, float partialTick) {
|
||||
protected void updateContents(TransformedInstance contents, Matrix4f pose, float partialTick) {
|
||||
int fuseTime = entity.getFuse();
|
||||
if (fuseTime > -1 && (float) fuseTime - partialTick + 1.0F < 10.0F) {
|
||||
float f = 1.0F - ((float) fuseTime - partialTick + 1.0F) / 10.0F;
|
||||
@ -24,7 +25,7 @@ public class TntMinecartVisual<T extends MinecartTNT> extends MinecartVisual<T>
|
||||
f *= f;
|
||||
f *= f;
|
||||
float scale = 1.0F + f * 0.3F;
|
||||
stack.scale(scale, scale, scale);
|
||||
pose.scale(scale);
|
||||
}
|
||||
|
||||
int overlay;
|
||||
@ -34,7 +35,7 @@ public class TntMinecartVisual<T extends MinecartTNT> extends MinecartVisual<T>
|
||||
overlay = OverlayTexture.NO_OVERLAY;
|
||||
}
|
||||
|
||||
contents.setTransform(stack)
|
||||
contents.setTransform(pose)
|
||||
.overlay(overlay)
|
||||
.setChanged();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package dev.engine_room.flywheel.vanilla;
|
||||
import static dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer.builder;
|
||||
import static dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer.builder;
|
||||
|
||||
import net.minecraft.client.model.geom.ModelLayers;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
@ -47,27 +48,27 @@ public class VanillaVisuals {
|
||||
.apply();
|
||||
|
||||
builder(EntityType.CHEST_MINECART)
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.CHEST_BODY_MODEL))
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.CHEST_MINECART))
|
||||
.skipVanillaRender(MinecartVisual::shouldSkipRender)
|
||||
.apply();
|
||||
builder(EntityType.COMMAND_BLOCK_MINECART)
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.COMMAND_BLOCK_BODY_MODEL))
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.COMMAND_BLOCK_MINECART))
|
||||
.skipVanillaRender(MinecartVisual::shouldSkipRender)
|
||||
.apply();
|
||||
builder(EntityType.FURNACE_MINECART)
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.FURNACE_BODY_MODEL))
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.FURNACE_MINECART))
|
||||
.skipVanillaRender(MinecartVisual::shouldSkipRender)
|
||||
.apply();
|
||||
builder(EntityType.HOPPER_MINECART)
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.HOPPER_BODY_MODEL))
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.HOPPER_MINECART))
|
||||
.skipVanillaRender(MinecartVisual::shouldSkipRender)
|
||||
.apply();
|
||||
builder(EntityType.MINECART)
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.STANDARD_BODY_MODEL))
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.MINECART))
|
||||
.skipVanillaRender(MinecartVisual::shouldSkipRender)
|
||||
.apply();
|
||||
builder(EntityType.SPAWNER_MINECART)
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.SPAWNER_BODY_MODEL))
|
||||
.factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.SPAWNER_MINECART))
|
||||
.skipVanillaRender(MinecartVisual::shouldSkipRender)
|
||||
.apply();
|
||||
builder(EntityType.TNT_MINECART)
|
||||
|
Loading…
Reference in New Issue
Block a user