1
0
mirror of https://github.com/GeyserMC/Rainbow.git synced 2025-12-19 14:59:16 +00:00

Bedrock geometry mapper

This commit is contained in:
Eclipse
2025-07-04 14:07:57 +00:00
parent be7afcd935
commit 419511bfff
2 changed files with 74 additions and 4 deletions

View File

@@ -0,0 +1,64 @@
package org.geysermc.packgenerator.mapping.geometry;
import net.minecraft.client.renderer.block.model.BlockElement;
import net.minecraft.client.renderer.block.model.BlockElementFace;
import net.minecraft.client.renderer.block.model.BlockElementRotation;
import net.minecraft.client.renderer.block.model.SimpleUnbakedGeometry;
import net.minecraft.core.Direction;
import org.geysermc.packgenerator.pack.geometry.BedrockGeometry;
import org.joml.Vector2f;
import org.joml.Vector3f;
import java.util.Map;
public class GeometryMapper {
public static BedrockGeometry mapGeometry(String identifier, SimpleUnbakedGeometry geometry) {
BedrockGeometry.Builder builder = BedrockGeometry.builder(identifier);
BedrockGeometry.Bone.Builder bone = BedrockGeometry.bone(identifier);
for (BlockElement element : geometry.elements()) {
bone.withCube(mapBlockElement(element));
}
// TODO texture size, etc.
return builder.withBone(bone).build();
}
private static BedrockGeometry.Cube.Builder mapBlockElement(BlockElement element) {
BedrockGeometry.Cube.Builder builder = BedrockGeometry.cube(new Vector3f(element.from()), element.to().sub(element.from(), new Vector3f()));
for (Map.Entry<Direction, BlockElementFace> faceEntry : element.faces().entrySet()) {
// TODO texture key
Direction direction = faceEntry.getKey();
BlockElementFace face = faceEntry.getValue();
Vector2f uvOrigin;
Vector2f uvSize;
BlockElementFace.UVs uvs = face.uvs();
if (uvs != null) {
uvOrigin = new Vector2f(uvs.minU(), uvs.minV());
uvSize = new Vector2f(uvs.maxU() - uvs.minU(), uvs.maxV() - uvs.minV());
} else {
uvOrigin = new Vector2f();
uvSize = new Vector2f();
}
builder.withFace(direction, uvOrigin, uvSize, face.rotation());
}
BlockElementRotation rotation = element.rotation();
if (rotation != null) {
builder.withPivot(rotation.origin());
Vector3f bedrockRotation = switch (rotation.axis()) {
case X -> new Vector3f(rotation.angle(), 0.0F, 0.0F);
case Y -> new Vector3f(0.0F, rotation.angle(), 0.0F);
case Z -> new Vector3f(0.0F, 0.0F, rotation.angle());
};
builder.withRotation(bedrockRotation);
}
return builder;
}
}

View File

@@ -1,5 +1,6 @@
package org.geysermc.packgenerator.pack.geometry;
import com.mojang.math.Quadrant;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.Direction;
@@ -247,25 +248,30 @@ public record BedrockGeometry(BedrockVersion formatVersion, List<GeometryDefinit
return this;
}
public Builder withFace(Direction direction, Vector2f uvOrigin, Vector2f uvSize) {
public Builder withFace(Direction direction, Vector2f uvOrigin, Vector2f uvSize, Quadrant uvRotation) {
if (faces.containsKey(direction)) {
throw new IllegalArgumentException("Already added a face for direction " + direction);
}
faces.put(direction, new Face(uvOrigin, uvSize));
faces.put(direction, new Face(uvOrigin, uvSize, uvRotation));
return this;
}
public Builder withFace(Direction direction, Vector2f uvOrigin, Vector2f uvSize) {
return withFace(direction, uvOrigin, uvSize, Quadrant.R0);
}
public Cube build() {
return new Cube(origin, size, rotation, pivot, inflate, mirror, Map.copyOf(faces));
}
}
}
public record Face(Vector2f uvOrigin, Vector2f uvSize) {
public record Face(Vector2f uvOrigin, Vector2f uvSize, Quadrant uvRotation) {
public static final Codec<Face> CODEC = RecordCodecBuilder.create(instance ->
instance.group(
ExtraCodecs.VECTOR2F.fieldOf("uv").forGetter(Face::uvOrigin),
ExtraCodecs.VECTOR2F.fieldOf("uv_size").forGetter(Face::uvSize)
ExtraCodecs.VECTOR2F.fieldOf("uv_size").forGetter(Face::uvSize),
Quadrant.CODEC.optionalFieldOf("uv_rotation", Quadrant.R0).forGetter(Face::uvRotation)
).apply(instance, Face::new)
);
}