Skip to content

Commit 1834770

Browse files
committed
Added line shape, KMathCodecs, ColoredShape, PositionedColoredShape
1 parent 2055ec2 commit 1834770

10 files changed

Lines changed: 253 additions & 16 deletions

File tree

gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ mod_author=latvian.dev
1010

1111
mod_version=2105.1.0
1212

13-
neoforge_version=21.5.34-beta
14-
neoForge.parchment.minecraftVersion=1.21.4
15-
neoForge.parchment.mappingsVersion=2025.03.23
13+
neoforge_version=21.5.75
14+
neoForge.parchment.minecraftVersion=1.21.5
15+
neoForge.parchment.mappingsVersion=2025.06.01

src/main/java/dev/latvian/mods/kmath/KMath.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,20 @@ public String format(Vec3f pos) {
5555
}
5656

5757
List<AABB> CLIP_BOX_LIST = List.of(new AABB(-0.5D, -0.5D, -0.5D, 0.5D, 0.5D, 0.5D));
58-
Vec3 CENTER = new Vec3(0.5D, 0.5D, 0.5D);
58+
Vec3 CENTER_VEC3 = new Vec3(0.5D, 0.5D, 0.5D);
59+
Vec3 ONE_VEC3 = new Vec3(1D, 1D, 1D);
60+
61+
static Vec3 vec3(double x, double y, double z) {
62+
if (x == 0D && y == 0D && z == 0D) {
63+
return Vec3.ZERO;
64+
} else if (x == 1D && y == 1D && z == 1D) {
65+
return ONE_VEC3;
66+
} else if (x == 0.5D && y == 0.5D && z == 0.5D) {
67+
return CENTER_VEC3;
68+
} else {
69+
return new Vec3(x, y, z);
70+
}
71+
}
5972

6073
static String veryShortFormat(float value) {
6174
return NumberFormat.VERY_SHORT.format(value);

src/main/java/dev/latvian/mods/kmath/VoxelShapeBox.java

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
import java.util.ArrayList;
1111
import java.util.List;
1212

13-
public record VoxelShapeBox(List<Line> edges, List<AABB> boxes) {
14-
public static final VoxelShapeBox EMPTY = new VoxelShapeBox(List.of(), List.of());
13+
public record VoxelShapeBox(List<Line> edges, List<AABB> boxes, boolean singleBox) {
14+
public static final VoxelShapeBox EMPTY = new VoxelShapeBox(List.of(), List.of(), false);
1515
public static final VoxelShapeBox FULL = of(AABBs.FULL);
1616
public static final VoxelShapeBox FULL_16 = of(AABBs.FULL_16);
1717
public static final VoxelShapeBox INFINITE = of(AABB.INFINITE);
@@ -39,7 +39,7 @@ public static VoxelShapeBox of(VoxelShape shape) {
3939

4040
var edges = new ArrayList<Line>(12);
4141
shape.forAllEdges((minX, minY, minZ, maxX, maxY, maxZ) -> edges.add(new Line(new Vec3(minX, minY, minZ), new Vec3(maxX, maxY, maxZ))));
42-
return edges.isEmpty() && boxes.isEmpty() ? EMPTY : new VoxelShapeBox(List.copyOf(edges), List.copyOf(boxes));
42+
return edges.isEmpty() && boxes.isEmpty() ? EMPTY : new VoxelShapeBox(List.copyOf(edges), List.copyOf(boxes), boxes.size() == 1);
4343
}
4444

4545
private static void edge(double minX, double minY, double minZ, double maxX, double maxY, double maxZ, List<Line> edges) {
@@ -59,36 +59,36 @@ public static VoxelShapeBox of(AABB box) {
5959
} else if (minY == maxY && minZ == maxZ) {
6060
var edges = new ArrayList<Line>(1);
6161
edge(minX, minY, minZ, maxX, minY, minZ, edges);
62-
return new VoxelShapeBox(List.copyOf(edges), List.of(box));
62+
return new VoxelShapeBox(List.copyOf(edges), List.of(box), true);
6363
} else if (minX == maxX && minZ == maxZ) {
6464
var edges = new ArrayList<Line>(1);
6565
edge(minX, minY, minZ, minX, maxY, minZ, edges);
66-
return new VoxelShapeBox(List.copyOf(edges), List.of(box));
66+
return new VoxelShapeBox(List.copyOf(edges), List.of(box), true);
6767
} else if (minX == maxX && minY == maxY) {
6868
var edges = new ArrayList<Line>(1);
6969
edge(minX, minY, minZ, minX, minY, maxZ, edges);
70-
return new VoxelShapeBox(List.copyOf(edges), List.of(box));
70+
return new VoxelShapeBox(List.copyOf(edges), List.of(box), true);
7171
} else if (minX == maxX) {
7272
var edges = new ArrayList<Line>(4);
7373
edge(minX, minY, minZ, minX, maxY, minZ, edges);
7474
edge(minX, minY, minZ, minX, minY, maxZ, edges);
7575
edge(minX, maxY, minZ, minX, maxY, maxZ, edges);
7676
edge(minX, maxY, maxZ, minX, minY, maxZ, edges);
77-
return new VoxelShapeBox(List.copyOf(edges), List.of(box));
77+
return new VoxelShapeBox(List.copyOf(edges), List.of(box), true);
7878
} else if (minY == maxY) {
7979
var edges = new ArrayList<Line>(4);
8080
edge(minX, minY, minZ, maxX, minY, minZ, edges);
8181
edge(minX, minY, minZ, minX, minY, maxZ, edges);
8282
edge(minX, minY, maxZ, maxX, minY, maxZ, edges);
8383
edge(maxX, minY, maxZ, maxX, minY, minZ, edges);
84-
return new VoxelShapeBox(List.copyOf(edges), List.of(box));
84+
return new VoxelShapeBox(List.copyOf(edges), List.of(box), true);
8585
} else if (minZ == maxZ) {
8686
var edges = new ArrayList<Line>(4);
8787
edge(minX, minY, minZ, maxX, minY, minZ, edges);
8888
edge(minX, minY, minZ, minX, maxY, minZ, edges);
8989
edge(maxX, minY, minZ, maxX, maxY, minZ, edges);
9090
edge(maxX, maxY, minZ, minX, maxY, minZ, edges);
91-
return new VoxelShapeBox(List.copyOf(edges), List.of(box));
91+
return new VoxelShapeBox(List.copyOf(edges), List.of(box), true);
9292
} else {
9393
var edges = new ArrayList<Line>(12);
9494
edge(minX, minY, minZ, maxX, minY, minZ, edges);
@@ -103,7 +103,7 @@ public static VoxelShapeBox of(AABB box) {
103103
edge(minX, maxY, maxZ, maxX, maxY, maxZ, edges);
104104
edge(maxX, minY, maxZ, maxX, maxY, maxZ, edges);
105105
edge(maxX, maxY, minZ, maxX, maxY, maxZ, edges);
106-
return new VoxelShapeBox(List.copyOf(edges), List.of(box));
106+
return new VoxelShapeBox(List.copyOf(edges), List.of(box), true);
107107
}
108108
}
109109

@@ -132,4 +132,68 @@ public void buildLines(Vec3 offset, VertexCallback callback) {
132132
callback.acceptPos(maxX, maxY, maxZ);
133133
}
134134
}
135+
136+
public VoxelShapeBox move(double x, double y, double z) {
137+
if (x == 0D && y == 0D && z == 0D) {
138+
return this;
139+
} else if (singleBox) {
140+
var b = boxes.getFirst();
141+
return of(new AABB(b.minX + x, b.minY + y, b.minZ + z, b.maxX + x, b.maxY + y, b.maxZ + z));
142+
} else {
143+
var movedBoxes = new ArrayList<AABB>(boxes.size());
144+
var movedEdges = new ArrayList<Line>(edges.size());
145+
146+
for (var b : boxes) {
147+
movedBoxes.add(new AABB(
148+
b.minX + x,
149+
b.minY + y,
150+
b.minZ + z,
151+
b.maxX + x,
152+
b.maxY + y,
153+
b.maxZ + z
154+
));
155+
}
156+
157+
for (var e : edges) {
158+
movedEdges.add(new Line(
159+
new Vec3(e.start().x + x, e.start().y + y, e.start().z + z),
160+
new Vec3(e.end().x + x, e.end().y + y, e.end().z + z)
161+
));
162+
}
163+
164+
return new VoxelShapeBox(List.copyOf(movedEdges), List.copyOf(movedBoxes), false);
165+
}
166+
}
167+
168+
public VoxelShapeBox scale(double sx, double sy, double sz) {
169+
if (sx == 1D && sy == 1D && sz == 1D) {
170+
return this;
171+
} else if (singleBox) {
172+
var b = boxes.getFirst();
173+
return of(new AABB(b.minX * sx, b.minY * sy, b.minZ * sz, b.maxX * sx, b.maxY * sy, b.maxZ * sz));
174+
}
175+
176+
var scaledBoxes = new ArrayList<AABB>(boxes.size());
177+
var scaledEdges = new ArrayList<Line>(edges.size());
178+
179+
for (var b : boxes) {
180+
scaledBoxes.add(new AABB(
181+
b.minX * sx,
182+
b.minY * sy,
183+
b.minZ * sz,
184+
b.maxX * sx,
185+
b.maxY * sy,
186+
b.maxZ * sz
187+
));
188+
}
189+
190+
for (var e : edges) {
191+
scaledEdges.add(new Line(
192+
new Vec3(e.start().x * sx, e.start().y * sy, e.start().z * sz),
193+
new Vec3(e.end().x * sx, e.end().y * sy, e.end().z * sz)
194+
));
195+
}
196+
197+
return new VoxelShapeBox(List.copyOf(scaledEdges), List.copyOf(scaledBoxes), false);
198+
}
135199
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package dev.latvian.mods.kmath.codec;
2+
3+
import com.mojang.serialization.Codec;
4+
import dev.latvian.mods.kmath.KMath;
5+
import net.minecraft.world.phys.Vec3;
6+
7+
import java.util.List;
8+
9+
public interface KMathCodecs {
10+
Codec<Vec3> VEC3 = Codec.DOUBLE.listOf(3, 3).xmap(l -> KMath.vec3(l.get(0), l.get(1), l.get(2)), v -> List.of(v.x, v.y, v.z));
11+
}

src/main/java/dev/latvian/mods/kmath/codec/KMathStreamCodecs.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package dev.latvian.mods.kmath.codec;
22

33
import com.google.common.base.Suppliers;
4+
import dev.latvian.mods.kmath.KMath;
45
import io.netty.buffer.ByteBuf;
56
import net.minecraft.network.codec.ByteBufCodecs;
67
import net.minecraft.network.codec.StreamCodec;
8+
import net.minecraft.world.phys.Vec3;
79
import org.jetbrains.annotations.Nullable;
810

911
import java.util.Objects;
@@ -49,4 +51,18 @@ public void encode(B buf, V value) {
4951

5052
StreamCodec<ByteBuf, Double> DOUBLE_OR_ZERO = optional(ByteBufCodecs.DOUBLE, 0D);
5153
StreamCodec<ByteBuf, Double> DOUBLE_OR_ONE = optional(ByteBufCodecs.DOUBLE, 1D);
54+
55+
StreamCodec<ByteBuf, Vec3> VEC3 = new StreamCodec<>() {
56+
@Override
57+
public Vec3 decode(ByteBuf buf) {
58+
return KMath.vec3(buf.readDouble(), buf.readDouble(), buf.readDouble());
59+
}
60+
61+
@Override
62+
public void encode(ByteBuf buf, Vec3 value) {
63+
buf.writeDouble(value.x);
64+
buf.writeDouble(value.y);
65+
buf.writeDouble(value.z);
66+
}
67+
};
5268
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package dev.latvian.mods.kmath.shape;
2+
3+
import com.mojang.serialization.Codec;
4+
import com.mojang.serialization.codecs.RecordCodecBuilder;
5+
import dev.latvian.mods.kmath.color.Color;
6+
import dev.latvian.mods.kmath.color.Gradient;
7+
import io.netty.buffer.ByteBuf;
8+
import net.minecraft.network.codec.StreamCodec;
9+
import net.minecraft.world.phys.Vec3;
10+
import org.joml.Vector3dc;
11+
12+
public record ColoredShape(Shape shape, Gradient quads, Gradient lines) {
13+
public static final Codec<ColoredShape> CODEC = RecordCodecBuilder.create(instance -> instance.group(
14+
Shape.DIRECT_CODEC.fieldOf("shape").forGetter(ColoredShape::shape),
15+
Gradient.CODEC.optionalFieldOf("quads", Color.TRANSPARENT).forGetter(ColoredShape::quads),
16+
Gradient.CODEC.optionalFieldOf("lines", Color.TRANSPARENT).forGetter(ColoredShape::lines)
17+
).apply(instance, ColoredShape::new));
18+
19+
public static final StreamCodec<ByteBuf, ColoredShape> STREAM_CODEC = StreamCodec.composite(
20+
Shape.STREAM_CODEC, ColoredShape::shape,
21+
Gradient.STREAM_CODEC, ColoredShape::quads,
22+
Gradient.STREAM_CODEC, ColoredShape::lines,
23+
ColoredShape::new
24+
);
25+
26+
public static ColoredShape of(Shape shape, Gradient quads, Gradient lines) {
27+
return new ColoredShape(shape, quads, lines);
28+
}
29+
30+
public static ColoredShape quads(Shape shape, Gradient color) {
31+
return new ColoredShape(shape, color, Color.TRANSPARENT);
32+
}
33+
34+
public static ColoredShape lines(Shape shape, Gradient color) {
35+
return new ColoredShape(shape, Color.TRANSPARENT, color);
36+
}
37+
38+
public PositionedColoredShape at(Vec3 pos) {
39+
return new PositionedColoredShape(pos, this);
40+
}
41+
42+
public PositionedColoredShape at(Vector3dc pos) {
43+
return new PositionedColoredShape(new Vec3(pos.x(), pos.y(), pos.z()), this);
44+
}
45+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package dev.latvian.mods.kmath.shape;
2+
3+
import com.mojang.serialization.MapCodec;
4+
import com.mojang.serialization.codecs.RecordCodecBuilder;
5+
import dev.latvian.mods.kmath.Vec3f;
6+
import dev.latvian.mods.kmath.vertex.VertexCallback;
7+
import io.netty.buffer.ByteBuf;
8+
import net.minecraft.network.codec.StreamCodec;
9+
10+
public record LineShape(Vec3f vector) implements Shape {
11+
public static final LineShape DOWN_UNIT = new LineShape(Vec3f.DOWN);
12+
public static final LineShape UP_UNIT = new LineShape(Vec3f.UP);
13+
public static final LineShape NORTH_UNIT = new LineShape(Vec3f.NORTH);
14+
public static final LineShape SOUTH_UNIT = new LineShape(Vec3f.SOUTH);
15+
public static final LineShape WEST_UNIT = new LineShape(Vec3f.WEST);
16+
public static final LineShape EAST_UNIT = new LineShape(Vec3f.EAST);
17+
18+
public static final MapCodec<LineShape> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
19+
Vec3f.CODEC.fieldOf("vector").forGetter(LineShape::vector)
20+
).apply(instance, LineShape::new));
21+
22+
public static final StreamCodec<ByteBuf, LineShape> STREAM_CODEC = StreamCodec.composite(
23+
Vec3f.STREAM_CODEC, LineShape::vector,
24+
LineShape::new
25+
);
26+
27+
public static final ShapeType TYPE = new ShapeType("line", CODEC, STREAM_CODEC);
28+
29+
@Override
30+
public ShapeType type() {
31+
return TYPE;
32+
}
33+
34+
@Override
35+
public Shape optimize() {
36+
if (vector.lengthSq() <= 0F) {
37+
return EmptyShape.INSTANCE;
38+
}
39+
40+
return this;
41+
}
42+
43+
@Override
44+
public void buildLines(float x, float y, float z, VertexCallback callback) {
45+
CuboidBuilder.lines(x, y, z, x + vector.x(), y + vector.y(), z + vector.z(), callback);
46+
}
47+
48+
@Override
49+
public void buildQuads(float x, float y, float z, VertexCallback callback) {
50+
}
51+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package dev.latvian.mods.kmath.shape;
2+
3+
import com.mojang.serialization.Codec;
4+
import com.mojang.serialization.codecs.RecordCodecBuilder;
5+
import dev.latvian.mods.kmath.codec.KMathCodecs;
6+
import dev.latvian.mods.kmath.codec.KMathStreamCodecs;
7+
import io.netty.buffer.ByteBuf;
8+
import net.minecraft.network.codec.StreamCodec;
9+
import net.minecraft.world.phys.Vec3;
10+
11+
public record PositionedColoredShape(Vec3 position, ColoredShape shape) {
12+
public static final Codec<PositionedColoredShape> CODEC = RecordCodecBuilder.create(instance -> instance.group(
13+
KMathCodecs.VEC3.fieldOf("position").forGetter(PositionedColoredShape::position),
14+
ColoredShape.CODEC.fieldOf("shape").forGetter(PositionedColoredShape::shape)
15+
).apply(instance, PositionedColoredShape::new));
16+
17+
public static final StreamCodec<ByteBuf, PositionedColoredShape> STREAM_CODEC = StreamCodec.composite(
18+
KMathStreamCodecs.VEC3, PositionedColoredShape::position,
19+
ColoredShape.STREAM_CODEC, PositionedColoredShape::shape,
20+
PositionedColoredShape::new
21+
);
22+
}

src/main/java/dev/latvian/mods/kmath/shape/ShapeType.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,22 @@
88
import net.minecraft.network.codec.StreamCodec;
99
import net.minecraft.util.StringRepresentable;
1010

11+
import java.util.List;
1112
import java.util.Map;
1213
import java.util.function.Function;
1314
import java.util.stream.Collectors;
14-
import java.util.stream.Stream;
1515

1616
public record ShapeType(String name, MapCodec<? extends Shape> codec, StreamCodec<ByteBuf, ? extends Shape> streamCodec) implements StringRepresentable {
17-
public static final Map<String, ShapeType> MAP = Map.copyOf(Stream.of(EmptyShape.TYPE, CubeShape.TYPE, CuboidShape.TYPE, SphereShape.TYPE, CylinderShape.TYPE).collect(Collectors.toMap(ShapeType::name, Function.identity())));
17+
public static final List<ShapeType> LIST = List.of(
18+
EmptyShape.TYPE,
19+
CubeShape.TYPE,
20+
CuboidShape.TYPE,
21+
SphereShape.TYPE,
22+
CylinderShape.TYPE,
23+
LineShape.TYPE
24+
);
25+
26+
public static final Map<String, ShapeType> MAP = Map.copyOf(LIST.stream().collect(Collectors.toMap(ShapeType::name, Function.identity())));
1827

1928
public static final Codec<ShapeType> CODEC = Codec.STRING.flatXmap(s -> {
2029
var shape = MAP.get(s);

src/main/java/dev/latvian/mods/kmath/shape/UnitShape.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ public static void add(String name, Shape shape) {
2828
add("sphere", SphereShape.UNIT);
2929
add("cylinder", CylinderShape.UNIT);
3030
add("circle", CylinderShape.CIRCLE_UNIT);
31+
add("line_down", LineShape.DOWN_UNIT);
32+
add("line_up", LineShape.UP_UNIT);
33+
add("line_north", LineShape.NORTH_UNIT);
34+
add("line_south", LineShape.SOUTH_UNIT);
35+
add("line_west", LineShape.WEST_UNIT);
36+
add("line_east", LineShape.EAST_UNIT);
3137
}
3238

3339
public static final Codec<UnitShape> CODEC = Codec.STRING.flatXmap(s -> {

0 commit comments

Comments
 (0)