From 26d6a7b3e4662f6d3a0475efd44517f1bb4182f3 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 8 Feb 2022 18:18:16 +0100 Subject: [PATCH] Stacks of Cache - Instancing support for bezier girders - Transformation matrices for bezier segments are only calculated once --- .../logistics/trains/BezierConnection.java | 221 +++++++++++++++++- .../logistics/trains/track/TrackInstance.java | 210 ++++++++++------- .../logistics/trains/track/TrackRenderer.java | 189 ++++----------- .../models/block/metal_girder/segment2.json | 4 +- .../textures/block/standard_track_mip.png | Bin 297 -> 404 bytes 5 files changed, 390 insertions(+), 234 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/BezierConnection.java b/src/main/java/com/simibubi/create/content/logistics/trains/BezierConnection.java index a4edaed2a..621c7dd43 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/BezierConnection.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/BezierConnection.java @@ -3,7 +3,11 @@ package com.simibubi.create.content.logistics.trains; import java.util.Iterator; import com.jozufozu.flywheel.repack.joml.Math; +import com.jozufozu.flywheel.util.transform.MatrixTransformStack; +import com.mojang.math.Matrix4f; +import com.simibubi.create.content.logistics.trains.track.TrackRenderer; import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.core.BlockPos; @@ -14,6 +18,8 @@ import net.minecraft.nbt.Tag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; public class BezierConnection implements Iterable { @@ -264,17 +270,19 @@ public class BezierConnection implements Iterable { public Iterator iterator() { resolve(); var offset = Vec3.atLowerCornerOf(tePositions.getFirst()) - .scale(-1) - .add(0, 3 / 16f, 0); + .scale(-1) + .add(0, 3 / 16f, 0); return new Bezierator(this, offset); } public static class Segment { + public int index; public Vec3 position; public Vec3 derivative; public Vec3 faceNormal; public Vec3 normal; + } private static class Bezierator implements Iterator { @@ -293,16 +301,16 @@ public class BezierConnection implements Iterable { this.bc = bc; end1 = bc.starts.getFirst() - .add(offset); + .add(offset); end2 = bc.starts.getSecond() - .add(offset); + .add(offset); finish1 = bc.axes.getFirst() - .scale(bc.handleLength) - .add(end1); + .scale(bc.handleLength) + .add(end1); finish2 = bc.axes.getSecond() - .scale(bc.handleLength) - .add(end2); + .scale(bc.handleLength) + .add(end2); faceNormal1 = bc.normals.getFirst(); faceNormal2 = bc.normals.getSecond(); @@ -321,12 +329,203 @@ public class BezierConnection implements Iterable { float t = this.bc.getSegmentT(segment.index); segment.position = VecHelper.bezier(end1, end2, finish1, finish2, t); segment.derivative = VecHelper.bezierDerivative(end1, end2, finish1, finish2, t) - .normalize(); - segment.faceNormal = faceNormal1.equals(faceNormal2) ? faceNormal1 : VecHelper.slerp(t, faceNormal1, faceNormal2); + .normalize(); + segment.faceNormal = + faceNormal1.equals(faceNormal2) ? faceNormal1 : VecHelper.slerp(t, faceNormal1, faceNormal2); segment.normal = segment.faceNormal.cross(segment.derivative) - .normalize(); + .normalize(); return segment; } } + private SegmentAngles[] bakedSegments; + private GirderAngles[] bakedGirders; + + @OnlyIn(Dist.CLIENT) + public static class SegmentAngles { + + public Matrix4f tieTransform; + public Couple railTransforms; + public BlockPos lightPosition; + + } + + @OnlyIn(Dist.CLIENT) + public static class GirderAngles { + + public Couple beams; + public Couple> beamCaps; + public BlockPos lightPosition; + + } + + @OnlyIn(Dist.CLIENT) + public SegmentAngles[] getBakedSegments() { + if (bakedSegments != null) + return bakedSegments; + + int segmentCount = getSegmentCount(); + bakedSegments = new SegmentAngles[segmentCount + 1]; + Couple previousOffsets = null; + + for (BezierConnection.Segment segment : this) { + int i = segment.index; + boolean end = i == 0 || i == segmentCount; + + SegmentAngles angles = bakedSegments[i] = new SegmentAngles(); + Couple railOffsets = Couple.create(segment.position.add(segment.normal.scale(.965f)), + segment.position.subtract(segment.normal.scale(.965f))); + Vec3 railMiddle = railOffsets.getFirst() + .add(railOffsets.getSecond()) + .scale(.5); + + if (previousOffsets == null) { + previousOffsets = railOffsets; + continue; + } + + // Tie + Vec3 prevMiddle = previousOffsets.getFirst() + .add(previousOffsets.getSecond()) + .scale(.5); + Vec3 tieAngles = TrackRenderer.getModelAngles(segment.normal, railMiddle.subtract(prevMiddle)); + angles.lightPosition = new BlockPos(railMiddle); + + MatrixTransformStack mts = new MatrixTransformStack(); + mts.translate(prevMiddle) + .rotateYRadians(tieAngles.y) + .rotateXRadians(tieAngles.x) + .rotateZRadians(tieAngles.z) + .translate(-1 / 2f, -2 / 16f - 1 / 256f, 0); + angles.tieTransform = mts.unwrap() + .last() + .pose(); + angles.railTransforms = Couple.create(null, null); + + // Rails + float scale = end ? 2.2f : 2.1f; + for (boolean first : Iterate.trueAndFalse) { + Vec3 railI = railOffsets.get(first); + Vec3 prevI = previousOffsets.get(first); + Vec3 diff = railI.subtract(prevI); + Vec3 anglesI = TrackRenderer.getModelAngles(segment.normal, diff); + + mts = new MatrixTransformStack(); + mts.translate(prevI) + .rotateYRadians(anglesI.y) + .rotateXRadians(anglesI.x) + .rotateZRadians(anglesI.z) + .translate(0, -2 / 16f + (i % 2 == 0 ? 1 : -1) / 2048f - 1 / 256f, -1 / 32f) + .scale(1, 1, (float) diff.length() * scale); + angles.railTransforms.set(first, mts.unwrap() + .last() + .pose()); + } + + previousOffsets = railOffsets; + } + + return bakedSegments; + } + + @OnlyIn(Dist.CLIENT) + public GirderAngles[] getBakedGirders() { + if (bakedGirders != null) + return bakedGirders; + + int segmentCount = getSegmentCount(); + bakedGirders = new GirderAngles[segmentCount + 1]; + Couple> previousOffsets = null; + + for (BezierConnection.Segment segment : this) { + int i = segment.index; + boolean end = i == 0 || i == segmentCount; + GirderAngles angles = bakedGirders[i] = new GirderAngles(); + + Vec3 leftGirder = segment.position.add(segment.normal.scale(.965f)); + Vec3 rightGirder = segment.position.subtract(segment.normal.scale(.965f)); + Vec3 upNormal = segment.derivative.normalize() + .cross(segment.normal); + Vec3 firstGirderOffset = upNormal.scale(-8 / 16f); + Vec3 secondGirderOffset = upNormal.scale(-10 / 16f); + Vec3 leftTop = segment.position.add(segment.normal.scale(1)) + .add(firstGirderOffset); + Vec3 rightTop = segment.position.subtract(segment.normal.scale(1)) + .add(firstGirderOffset); + Vec3 leftBottom = leftTop.add(secondGirderOffset); + Vec3 rightBottom = rightTop.add(secondGirderOffset); + + angles.lightPosition = new BlockPos(leftGirder.add(rightGirder) + .scale(.5)); + + Couple> offsets = + Couple.create(Couple.create(leftTop, rightTop), Couple.create(leftBottom, rightBottom)); + + if (previousOffsets == null) { + previousOffsets = offsets; + continue; + } + + angles.beams = Couple.create(null, null); + angles.beamCaps = Couple.create(Couple.create(null, null), Couple.create(null, null)); + float scale = end ? 2.3f : 2.2f; + + for (boolean first : Iterate.trueAndFalse) { + + // Middle + Vec3 currentBeam = offsets.getFirst() + .get(first) + .add(offsets.getSecond() + .get(first)) + .scale(.5); + Vec3 previousBeam = previousOffsets.getFirst() + .get(first) + .add(previousOffsets.getSecond() + .get(first)) + .scale(.5); + Vec3 beamDiff = currentBeam.subtract(previousBeam); + Vec3 beamAngles = TrackRenderer.getModelAngles(segment.normal, beamDiff); + + MatrixTransformStack mts = new MatrixTransformStack(); + mts.translate(previousBeam) + .rotateYRadians(beamAngles.y) + .rotateXRadians(beamAngles.x) + .rotateZRadians(beamAngles.z) + .translate(0, 2 / 16f + (segment.index % 2 == 0 ? 1 : -1) / 2048f - 1 / 1024f, -1 / 32f) + .scale(1, 1, (float) beamDiff.length() * scale); + angles.beams.set(first, mts.unwrap() + .last() + .pose()); + + // Caps + for (boolean top : Iterate.trueAndFalse) { + Vec3 current = offsets.get(top) + .get(first); + Vec3 previous = previousOffsets.get(top) + .get(first); + Vec3 diff = current.subtract(previous); + Vec3 capAngles = TrackRenderer.getModelAngles(segment.normal, diff); + + mts = new MatrixTransformStack(); + mts.translate(previous) + .rotateYRadians(capAngles.y) + .rotateXRadians(capAngles.x) + .rotateZRadians(capAngles.z) + .translate(0, 2 / 16f + (segment.index % 2 == 0 ? 1 : -1) / 2048f - 1 / 1024f, -1 / 32f) + .rotateZ(top ? 0 : 0) + .scale(1, 1, (float) diff.length() * scale); + angles.beamCaps.get(top) + .set(first, mts.unwrap() + .last() + .pose()); + } + } + + previousOffsets = offsets; + + } + + return bakedGirders; + } + } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackInstance.java b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackInstance.java index b2d952618..b07c9bbec 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackInstance.java @@ -19,15 +19,17 @@ import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.logistics.trains.BezierConnection; +import com.simibubi.create.content.logistics.trains.BezierConnection.GirderAngles; +import com.simibubi.create.content.logistics.trains.BezierConnection.SegmentAngles; +import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; -import net.minecraft.world.phys.Vec3; public class TrackInstance extends BlockEntityInstance { - private List instances; + private List instances; public TrackInstance(MaterialManager materialManager, TrackTileEntity track) { super(materialManager, track); @@ -37,47 +39,52 @@ public class TrackInstance extends BlockEntityInstance { @Override public void update() { - if (blockEntity.connections.stream().allMatch(Map::isEmpty)) { + if (blockEntity.connections.stream() + .allMatch(Map::isEmpty)) { return; } instances = blockEntity.connections.stream() - .flatMap(FlwUtil::mapValues) - .map(this::createInstance) - .filter(Objects::nonNull) - .toList(); - LightUpdater.get(world).addListener(this); + .flatMap(FlwUtil::mapValues) + .map(this::createInstance) + .filter(Objects::nonNull) + .toList(); + LightUpdater.get(world) + .addListener(this); } @Override public ImmutableBox getVolume() { List out = new ArrayList<>(); out.addAll(blockEntity.connections.getFirst() - .keySet()); + .keySet()); out.addAll(blockEntity.connections.getSecond() - .keySet()); + .keySet()); return GridAlignedBB.containingAll(out); } @Override public void updateLight() { - if (instances == null) return; - instances.forEach(BezierInstance::updateLight); + if (instances == null) + return; + instances.forEach(BezierTrackInstance::updateLight); } @Nullable - private BezierInstance createInstance(BezierConnection bc) { - if (!bc.isPrimary()) return null; - return new BezierInstance(bc); + private BezierTrackInstance createInstance(BezierConnection bc) { + if (!bc.isPrimary()) + return null; + return new BezierTrackInstance(bc); } @Override public void remove() { - if (instances == null) return; - instances.forEach(BezierInstance::delete); + if (instances == null) + return; + instances.forEach(BezierTrackInstance::delete); } - private class BezierInstance { + private class BezierTrackInstance { private final ModelData[] ties; private final ModelData[] left; @@ -86,17 +93,20 @@ public class TrackInstance extends BlockEntityInstance { private final BlockPos[] leftLightPos; private final BlockPos[] rightLightPos; - private BezierInstance(BezierConnection bc) { + private @Nullable GirderInstance girder; + + private BezierTrackInstance(BezierConnection bc) { BlockPos tePosition = bc.tePositions.getFirst(); + girder = bc.hasGirder ? new GirderInstance(bc) : null; PoseStack pose = new PoseStack(); TransformStack.cast(pose) - .translate(getInstancePosition()) - .nudge((int) bc.tePositions.getFirst() - .asLong()); + .translate(getInstancePosition()) + .nudge((int) bc.tePositions.getFirst() + .asLong()); var mat = materialManager.cutout(RenderType.cutoutMipped()) - .material(Materials.TRANSFORMED); + .material(Materials.TRANSFORMED); int segCount = bc.getSegmentCount(); ties = new ModelData[segCount]; @@ -107,82 +117,120 @@ public class TrackInstance extends BlockEntityInstance { rightLightPos = new BlockPos[segCount]; mat.getModel(AllBlockPartials.TRACK_TIE) - .createInstances(ties); + .createInstances(ties); mat.getModel(AllBlockPartials.TRACK_SEGMENT_LEFT) - .createInstances(left); + .createInstances(left); mat.getModel(AllBlockPartials.TRACK_SEGMENT_RIGHT) - .createInstances(right); + .createInstances(right); - Vec3 leftPrevious = null; - Vec3 rightPrevious = null; + SegmentAngles[] segments = bc.getBakedSegments(); + for (int i = 1; i < segments.length; i++) { + SegmentAngles segment = segments[i]; + var modelIndex = i - 1; - for (BezierConnection.Segment segment : bc) { - Vec3 left = segment.position.add(segment.normal.scale(.965f)); - Vec3 right = segment.position.subtract(segment.normal.scale(.965f)); + ties[modelIndex].setTransform(pose) + .mulPose(segment.tieTransform); + tiesLightPos[modelIndex] = segment.lightPosition.offset(tePosition); - if (leftPrevious != null) { - var modelIndex = segment.index - 1; - { - // Tie - Vec3 railMiddle = left.add(right) - .scale(.5); - Vec3 prevMiddle = leftPrevious.add(rightPrevious) - .scale(.5); - - var tie = ties[modelIndex].setTransform(pose); - Vec3 diff = railMiddle.subtract(prevMiddle); - Vec3 angles = TrackRenderer.getModelAngles(segment.normal, diff); - - tie.translate(prevMiddle) - .rotateYRadians(angles.y) - .rotateXRadians(angles.x) - .rotateZRadians(angles.z) - .translate(-1 / 2f, -2 / 16f - 1 / 256f, 0); - tiesLightPos[modelIndex] = new BlockPos(railMiddle).offset(tePosition); - } - - // Rails - for (boolean first : Iterate.trueAndFalse) { - Vec3 railI = first ? left : right; - Vec3 prevI = first ? leftPrevious : rightPrevious; - - var rail = (first ? this.left : this.right)[modelIndex].setTransform(pose); - Vec3 diff = railI.subtract(prevI); - Vec3 angles = TrackRenderer.getModelAngles(segment.normal, diff); - - rail.translate(prevI) - .rotateYRadians(angles.y) - .rotateXRadians(angles.x) - .rotateZRadians(angles.z) - .translate(0, -2 / 16f + (segment.index % 2 == 0 ? 1 : -1) / 2048f - 1 / 256f, 0) - .scale(1, 1, (float) diff.length() * 2.1f); - (first ? leftLightPos : rightLightPos)[modelIndex] = new BlockPos(prevI).offset(tePosition); - } + for (boolean first : Iterate.trueAndFalse) { + (first ? this.left : this.right)[modelIndex].setTransform(pose) + .mulPose(segment.railTransforms.get(first)); + (first ? leftLightPos : rightLightPos)[modelIndex] = segment.lightPosition.offset(tePosition); } - - leftPrevious = left; - rightPrevious = right; } updateLight(); } void delete() { - for (ModelData d : ties) d.delete(); - for (ModelData d : left) d.delete(); - for (ModelData d : right) d.delete(); + for (ModelData d : ties) + d.delete(); + for (ModelData d : left) + d.delete(); + for (ModelData d : right) + d.delete(); + if (girder != null) + girder.delete(); } void updateLight() { - for (int i = 0; i < ties.length; i++) { + for (int i = 0; i < ties.length; i++) ties[i].updateLight(world, tiesLightPos[i]); - } - for (int i = 0; i < left.length; i++) { + for (int i = 0; i < left.length; i++) left[i].updateLight(world, leftLightPos[i]); - } - for (int i = 0; i < right.length; i++) { + for (int i = 0; i < right.length; i++) right[i].updateLight(world, rightLightPos[i]); - } + if (girder != null) + girder.updateLight(); } + + private class GirderInstance { + + private final Couple beams; + private final Couple> beamCaps; + private final BlockPos[] lightPos; + + private GirderInstance(BezierConnection bc) { + BlockPos tePosition = bc.tePositions.getFirst(); + PoseStack pose = new PoseStack(); + TransformStack.cast(pose) + .translate(getInstancePosition()) + .nudge((int) bc.tePositions.getFirst() + .asLong()); + + var mat = materialManager.cutout(RenderType.cutoutMipped()) + .material(Materials.TRANSFORMED); + + int segCount = bc.getSegmentCount(); + beams = Couple.create(() -> new ModelData[segCount]); + beamCaps = Couple.create(() -> Couple.create(() -> new ModelData[segCount])); + lightPos = new BlockPos[segCount]; + beams.forEach(mat.getModel(AllBlockPartials.GIRDER_SEGMENT_2)::createInstances); + beamCaps.forEach(c -> c.forEach(mat.getModel(AllBlockPartials.GIRDER_SEGMENT)::createInstances)); + + GirderAngles[] bakedGirders = bc.getBakedGirders(); + for (int i = 1; i < bakedGirders.length; i++) { + GirderAngles segment = bakedGirders[i]; + var modelIndex = i - 1; + lightPos[modelIndex] = segment.lightPosition.offset(tePosition); + + for (boolean first : Iterate.trueAndFalse) { + beams.get(first)[modelIndex].setTransform(pose) + .mulPose(segment.beams.get(first)); + for (boolean top : Iterate.trueAndFalse) + beamCaps.get(top) + .get(first)[modelIndex].setTransform(pose) + .mulPose(segment.beamCaps.get(top) + .get(first)); + } + } + + updateLight(); + } + + void delete() { + beams.forEach(arr -> { + for (ModelData d : arr) + d.delete(); + }); + beamCaps.forEach(c -> c.forEach(arr -> { + for (ModelData d : arr) + d.delete(); + })); + } + + void updateLight() { + beams.forEach(arr -> { + for (int i = 0; i < arr.length; i++) + arr[i].updateLight(world, lightPos[i]); + }); + beamCaps.forEach(c -> c.forEach(arr -> { + for (int i = 0; i < arr.length; i++) + arr[i].updateLight(world, lightPos[i]); + })); + } + + } + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackRenderer.java index 5e62f2cb3..ca418c002 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackRenderer.java @@ -1,20 +1,27 @@ package com.simibubi.create.content.logistics.trains.track; +import static com.simibubi.create.AllBlockPartials.GIRDER_SEGMENT; +import static com.simibubi.create.AllBlockPartials.GIRDER_SEGMENT_2; +import static com.simibubi.create.AllBlockPartials.TRACK_SEGMENT_LEFT; +import static com.simibubi.create.AllBlockPartials.TRACK_SEGMENT_RIGHT; +import static com.simibubi.create.AllBlockPartials.TRACK_TIE; + import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.repack.joml.Math; import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.logistics.trains.BezierConnection; +import com.simibubi.create.content.logistics.trains.BezierConnection.GirderAngles; +import com.simibubi.create.content.logistics.trains.BezierConnection.SegmentAngles; import com.simibubi.create.foundation.render.CachedBufferer; -import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; @@ -23,6 +30,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction.Axis; import net.minecraft.util.Mth; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; public class TrackRenderer extends SafeTileEntityRenderer { @@ -46,162 +54,63 @@ public class TrackRenderer extends SafeTileEntityRenderer { ms.pushPose(); BlockPos tePosition = bc.tePositions.getFirst(); + BlockState air = Blocks.AIR.defaultBlockState(); + ClientLevel level = Minecraft.getInstance().level; + SegmentAngles[] segments = bc.getBakedSegments(); TransformStack.cast(ms) .nudge((int) tePosition.asLong()); - if (bc.hasGirder) - renderGirder(bc, ms, vb, tePosition); + renderGirder(bc, ms, vb, tePosition); - Vec3 previous1 = null; - Vec3 previous2 = null; + for (int i = 1; i < segments.length; i++) { + SegmentAngles segment = segments[i]; + int light = LevelRenderer.getLightColor(level, segment.lightPosition.offset(tePosition)); - for (BezierConnection.Segment segment : bc) { - Vec3 rail1 = segment.position.add(segment.normal.scale(.965f)); - Vec3 rail2 = segment.position.subtract(segment.normal.scale(.965f)); + CachedBufferer.partial(TRACK_TIE, air) + .mulPose(segment.tieTransform) + .disableDiffuseMult() + .light(light) + .renderInto(ms, vb); - if (previous1 != null) { - int centralLight = 0; - - { - // Tie - Vec3 railMiddle = rail1.add(rail2) - .scale(.5); - Vec3 prevMiddle = previous1.add(previous2) - .scale(.5); - Vec3 diff = railMiddle.subtract(prevMiddle); - Vec3 angles = getModelAngles(segment.normal, diff); - - centralLight = LevelRenderer.getLightColor(Minecraft.getInstance().level, - new BlockPos(railMiddle).offset(tePosition)); - - SuperByteBuffer sbb = - CachedBufferer.partial(AllBlockPartials.TRACK_TIE, Blocks.AIR.defaultBlockState()); - - sbb.translate(prevMiddle) - .rotateYRadians(angles.y) - .rotateXRadians(angles.x) - .rotateZRadians(angles.z) - .translate(-1 / 2f, -2 / 16f - 1 / 256f, 0); - - sbb.disableDiffuseMult() - .light(centralLight); - sbb.renderInto(ms, vb); - } - - // Rails - for (boolean first : Iterate.trueAndFalse) { - Vec3 railI = first ? rail1 : rail2; - Vec3 prevI = first ? previous1 : previous2; - Vec3 diff = railI.subtract(prevI); - Vec3 angles = getModelAngles(segment.normal, diff); - - SuperByteBuffer sbb = CachedBufferer.partial( - first ? AllBlockPartials.TRACK_SEGMENT_LEFT : AllBlockPartials.TRACK_SEGMENT_RIGHT, - Blocks.AIR.defaultBlockState()); - - sbb.translate(prevI) - .rotateYRadians(angles.y) - .rotateXRadians(angles.x) - .rotateZRadians(angles.z) - .translate(0, -2 / 16f + (segment.index % 2 == 0 ? 1 : -1) / 2048f - 1 / 256f, 0) - .scale(1, 1, (float) diff.length() * 2.1f); - - sbb.disableDiffuseMult() - .light(LevelRenderer.getLightColor(Minecraft.getInstance().level, - new BlockPos(prevI).offset(tePosition))); - sbb.renderInto(ms, vb); - } - } - - previous1 = rail1; - previous2 = rail2; + for (boolean first : Iterate.trueAndFalse) + CachedBufferer.partial(first ? TRACK_SEGMENT_LEFT : TRACK_SEGMENT_RIGHT, air) + .mulPose(segment.railTransforms.get(first)) + .disableDiffuseMult() + .light(light) + .renderInto(ms, vb); } ms.popPose(); } private static void renderGirder(BezierConnection bc, PoseStack ms, VertexConsumer vb, BlockPos tePosition) { - Vec3 previousG11 = null; - Vec3 previousG21 = null; - Vec3 previousG12 = null; - Vec3 previousG22 = null; + if (!bc.hasGirder) + return; - for (BezierConnection.Segment segment : bc) { - Vec3 rail1 = segment.position.add(segment.normal.scale(.965f)); - Vec3 rail2 = segment.position.subtract(segment.normal.scale(.965f)); + BlockState air = Blocks.AIR.defaultBlockState(); + ClientLevel level = Minecraft.getInstance().level; + GirderAngles[] girders = bc.getBakedGirders(); - Vec3 upNormal = segment.derivative.normalize() - .cross(segment.normal); - Vec3 firstGirderOffset = upNormal.scale(-8 / 16f); - Vec3 secondGirderOffset = upNormal.scale(-10 / 16f); - Vec3 g11 = segment.position.add(segment.normal.scale(1)) - .add(firstGirderOffset); - Vec3 g12 = segment.position.subtract(segment.normal.scale(1)) - .add(firstGirderOffset); - Vec3 g21 = g11.add(secondGirderOffset); - Vec3 g22 = g12.add(secondGirderOffset); + for (int i = 1; i < girders.length; i++) { + GirderAngles segment = girders[i]; + int light = LevelRenderer.getLightColor(level, segment.lightPosition.offset(tePosition)); - if (previousG11 != null) { - Vec3 railMiddle = rail1.add(rail2) - .scale(.5); - int centralLight = LevelRenderer.getLightColor(Minecraft.getInstance().level, - new BlockPos(railMiddle).offset(tePosition)); - Vec3 normal = segment.normal; - float l = 2.2f; + for (boolean first : Iterate.trueAndFalse) { + CachedBufferer.partial(GIRDER_SEGMENT_2, air) + .mulPose(segment.beams.get(first)) + .disableDiffuseMult() + .light(light) + .renderInto(ms, vb); - for (boolean first : Iterate.trueAndFalse) { - for (boolean top : Iterate.trueAndFalse) { - Vec3 railI = top ? first ? g11 : g12 : first ? g21 : g22; - Vec3 prevI = top ? first ? previousG11 : previousG12 : first ? previousG21 : previousG22; - Vec3 diff = railI.subtract(prevI); - Vec3 angles = getModelAngles(normal, diff); - - SuperByteBuffer sbb2 = - CachedBufferer.partial(AllBlockPartials.GIRDER_SEGMENT, Blocks.AIR.defaultBlockState()); - - sbb2.translate(prevI) - .rotateYRadians(angles.y) - .rotateXRadians(angles.x) - .rotateZRadians(angles.z) - .translate(0, 2 / 16f + (segment.index % 2 == 0 ? 1 : -1) / 2048f - 1 / 1024f, 0) - .rotateZ(top ? 0 : 0) - .scale(1, 1, (float) diff.length() * l); - - sbb2.disableDiffuseMult() - .light(centralLight); - sbb2.renderInto(ms, vb); - } - - { - Vec3 railI = (first ? g11 : g12).add(first ? g21 : g22) - .scale(.5); - Vec3 prevI = (first ? previousG11 : previousG12).add(first ? previousG21 : previousG22) - .scale(.5); - Vec3 diff = railI.subtract(prevI); - Vec3 angles = getModelAngles(normal, diff); - - SuperByteBuffer sbb2 = - CachedBufferer.partial(AllBlockPartials.GIRDER_SEGMENT_2, Blocks.AIR.defaultBlockState()); - - sbb2.translate(prevI) - .rotateYRadians(angles.y) - .rotateXRadians(angles.x) - .rotateZRadians(angles.z) - .translate(0, 2 / 16f + (segment.index % 2 == 0 ? 1 : -1) / 2048f - 1 / 1024f, 0) - .scale(1, 1, (float) diff.length() * l); - - sbb2.disableDiffuseMult() - .light(centralLight); - sbb2.renderInto(ms, vb); - } - } + for (boolean top : Iterate.trueAndFalse) + CachedBufferer.partial(GIRDER_SEGMENT, air) + .mulPose(segment.beamCaps.get(top) + .get(first)) + .disableDiffuseMult() + .light(light) + .renderInto(ms, vb); } - - previousG11 = g11; - previousG12 = g12; - previousG21 = g21; - previousG22 = g22; } } diff --git a/src/main/resources/assets/create/models/block/metal_girder/segment2.json b/src/main/resources/assets/create/models/block/metal_girder/segment2.json index 10214d8bf..b92afbd5d 100644 --- a/src/main/resources/assets/create/models/block/metal_girder/segment2.json +++ b/src/main/resources/assets/create/models/block/metal_girder/segment2.json @@ -10,9 +10,9 @@ "to": [2, 4, 8], "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, "faces": { - "north": {"uv": [8, 1, 12, 3], "rotation": 270, "texture": "#0"}, + "north": {"uv": [2, 5, 4, 9], "texture": "#0"}, "east": {"uv": [0, 5, 4, 9], "texture": "#0"}, - "south": {"uv": [8, 1, 12, 3], "rotation": 270, "texture": "#0"}, + "south": {"uv": [2, 5, 4, 9], "texture": "#0"}, "west": {"uv": [0, 5, 4, 9], "texture": "#0"} } } diff --git a/src/main/resources/assets/create/textures/block/standard_track_mip.png b/src/main/resources/assets/create/textures/block/standard_track_mip.png index 0b71c5597b458a9853776997c9a03fd4e08ce2eb..b6033cdd8e3298c3b04e60202dbf35a5fc30166a 100644 GIT binary patch delta 360 zcmV-u0hj)%0+a)g83+ad0047(di0SYAb$yPNLh0L01m*yzCk6vo zB^#&+HLvqj_9?ojCnn)a`baK!OGsjSe@t+rjQ1 zpZ|UW{tfkM4eJ7U5AYt~J-`BZ5AYt~J-`B301L1z0QdqnU58`TYX{;00000 delta 252 zcmbQjypm~xBnLAC1B1(wu45Aw73vKFd_r88ESbA?>xwmN7SEY8qqn!OwY4)RuYAgs z$+fkuWo7j#8F>+Iwu#=3F2)8`aX~=M>}O_w2T}qhL4LviQ31mPEak-;s17mAzy<553}&Bgv{wofB)xmPT8a=c5Gfs>IcthN?)7h zSpu(~m~!UmGvVMu1O4q27z)c>_N=)${b~=_ljwvJ6$!p=wk^5rD~{>e2=lD#eB;OX n%f