Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/main/java/cam72cam/mod/render/BakedScaledModel.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package cam72cam.mod.render;

import cam72cam.mod.render.cutter.MeshPlaneCutter;
import cam72cam.mod.render.cutter.Plane;
import cam72cam.mod.render.cutter.adapter.BakedQuadAdapter;
import com.mojang.math.Transformation;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.ItemOverrides;
Expand All @@ -14,6 +17,7 @@
import org.joml.Matrix4f;
import util.Matrix4;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -26,22 +30,80 @@
class BakedScaledModel implements BakedModel {
// I know this is evil and I love it :D

private final boolean isCut;
private final Matrix4 transform;
private final BakedModel source;
private final Map<Direction, List<BakedQuad>> quadCache = new HashMap<>();

public BakedScaledModel(BakedModel source, Matrix4 transform) {
this.source = source;
this.transform = transform;
this.isCut = false;
}

public BakedScaledModel(BakedModel source, float height) {
this.source = source;
transform = new Matrix4().scale(1, height, 1);
isCut = false;
}

public BakedScaledModel(BakedModel source, Matrix4 transform, Plane plane) {

this.source = source;
this.transform = transform;
this.isCut = true;

quadCache.put(null, new ArrayList<>());

for (Direction dir : Direction.values()) {
quadCache.put(dir, new ArrayList<>());
}

RandomSource rand = RandomSource.create();

List<BakedQuad> all = new ArrayList<>();

all.addAll(source.getQuads(null, null, rand));

for (Direction dir : Direction.values()) {
all.addAll(source.getQuads(null, dir, rand));
}

all = MeshPlaneCutter.cut(
all,
plane,
new BakedQuadAdapter()
);

Matrix4f mat = transform.convertToMoj();

IQuadTransformer qt =
QuadTransformers.applying(
new Transformation(mat));

all = qt.process(all);

for (BakedQuad quad : all) {

quadCache.get(null).add(quad);

Direction dir = quad.getDirection();

if (dir != null) {
quadCache.get(dir).add(quad);
}
}
}

@Override
public List<BakedQuad> getQuads(BlockState state, Direction side, RandomSource rand) {
if(isCut) {
return quadCache.getOrDefault(
side,
List.of()
);
}

if (quadCache.get(side) == null) {
Matrix4f mat = transform.convertToMoj();
IQuadTransformer qt = QuadTransformers.applying(new Transformation(mat));
Expand Down
18 changes: 11 additions & 7 deletions src/main/java/cam72cam/mod/render/StandardModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cam72cam.mod.item.Fuzzy;
import cam72cam.mod.item.ItemStack;
import cam72cam.mod.render.cutter.Plane;
import cam72cam.mod.render.opengl.RenderContext;
import cam72cam.mod.render.opengl.RenderState;
import cam72cam.mod.render.opengl.Texture;
Expand All @@ -26,8 +27,9 @@
import util.Matrix4;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.Map;

/** A model that can render both standard MC constructs and custom OpenGL */
public class StandardModel {
Expand All @@ -47,7 +49,7 @@ private static BlockState itemToBlockState(cam72cam.mod.item.ItemStack stack) {
}

/** Add a block with a solid color */
public StandardModel addColorBlock(Color color, Matrix4 transform) {
public StandardModel addColorBlock(Color color, Matrix4 transform, Plane plane) {
BlockState state = Fuzzy.CONCRETE.enumerate()
.stream()
.map(x -> Block.byItem(x.internal().getItem()))
Expand All @@ -56,29 +58,31 @@ public StandardModel addColorBlock(Color color, Matrix4 transform) {
.findFirst().get();

BakedModel model = Minecraft.getInstance().getBlockRenderer().getBlockModelShaper().getBlockModel(state);
Pair<BlockState, BakedModel> pair = Pair.of(state, new BakedScaledModel(model, transform));
Pair<BlockState, BakedModel> pair = Pair.of(state, new BakedScaledModel(model, transform, plane));
// Pair<BlockState, BakedModel> pair = Pair.of(state, new BakedScaledModel(model, transform));
models.add(pair);
inGuiBlock.put(pair, getRenderFunc(new net.minecraft.world.item.ItemStack(state.getBlock().asItem()), transform));
return this;
}

/** Add snow layers */
public StandardModel addSnow(int layers, Matrix4 transform) {
public StandardModel addSnow(int layers, Matrix4 transform, Plane plane) {
layers = Math.max(1, Math.min(8, layers));
BlockState state = Blocks.SNOW.defaultBlockState().setValue(SnowLayerBlock.LAYERS, layers);
BakedModel model = Minecraft.getInstance().getBlockRenderer().getBlockModelShaper().getBlockModel(state);
models.add(Pair.of(state, new BakedScaledModel(model, transform)));
models.add(Pair.of(state, new BakedScaledModel(model, transform, plane)));
// models.add(Pair.of(state, new BakedScaledModel(model, transform)));
return this;
}

/** Add item as a block (best effort) */
public StandardModel addItemBlock(ItemStack bed, Matrix4 transform) {
public StandardModel addItemBlock(ItemStack bed, Matrix4 transform, Plane plane) {
BlockState state = itemToBlockState(bed);
BakedModel model = Minecraft.getInstance().getBlockRenderer().getBlockModelShaper().getBlockModel(state);
if (model instanceof WeightedBakedModel weightedBakedModel) {
//TODO Modify result to make it not dynamic
}
Pair<BlockState, BakedModel> pair = Pair.of(state, new BakedScaledModel(model, transform));
Pair<BlockState, BakedModel> pair = Pair.of(state, new BakedScaledModel(model, transform, plane));
models.add(pair);
inGuiBlock.put(pair, getRenderFunc(bed.internal(), transform));
return this;
Expand Down
68 changes: 68 additions & 0 deletions src/main/java/cam72cam/mod/render/cutter/CapBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package cam72cam.mod.render.cutter;

import cam72cam.mod.math.Vec3d;

import java.util.Comparator;
import java.util.List;

public final class CapBuilder {

private CapBuilder() {}

public static Polygon build(
List<ClipVertex> intersections,
Plane plane) {

List<ClipVertex> vertices =
VertexDeduplicator.deduplicate(
intersections);

if (vertices.size() < 3) {
return null;
}

Vec3d center = computeCenter(vertices);

PlaneBasis basis =
PlaneBasis.fromPlane(plane);

vertices.sort(
Comparator.comparingDouble(v -> {

Vec3d offset = v.pos.subtract(center);

double x = offset.dotProduct(basis.u);
double y = offset.dotProduct(basis.v);

return Math.atan2(y, x);
})
);

Polygon polygon = new Polygon();
polygon.vertices.addAll(vertices);

return polygon;
}

private static Vec3d computeCenter(
List<ClipVertex> vertices) {

double x = 0;
double y = 0;
double z = 0;

for (ClipVertex v : vertices) {
x += v.pos.x;
y += v.pos.y;
z += v.pos.z;
}

double inv = 1.0 / vertices.size();

return new Vec3d(
x * inv,
y * inv,
z * inv
);
}
}
75 changes: 75 additions & 0 deletions src/main/java/cam72cam/mod/render/cutter/CapUVGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package cam72cam.mod.render.cutter;

import cam72cam.mod.math.Vec3d;

import java.util.Collections;

public final class CapUVGenerator {

private CapUVGenerator() {}

public static void generate(Polygon polygon, Plane plane) {

generateUV(
polygon,
PlaneBasis
.fromPlane(plane)
.rotateCCW()
);

reverseWinding(polygon);
}

private static void reverseWinding(
Polygon polygon) {

Collections.reverse(
polygon.vertices
);
}

private static void generateUV(
Polygon polygon,
PlaneBasis basis) {

double minU = Double.POSITIVE_INFINITY;
double maxU = Double.NEGATIVE_INFINITY;

double minV = Double.POSITIVE_INFINITY;
double maxV = Double.NEGATIVE_INFINITY;

for (ClipVertex vertex : polygon.vertices) {

Vec3d p = vertex.pos;

double u = p.dotProduct(basis.u);
double v = p.dotProduct(basis.v);

minU = Math.min(minU, u);
maxU = Math.max(maxU, u);

minV = Math.min(minV, v);
maxV = Math.max(maxV, v);
}

double du = maxU - minU;
double dv = maxV - minV;

if (du < 1E-6) du = 1;
if (dv < 1E-6) dv = 1;

for (ClipVertex vertex : polygon.vertices) {

Vec3d p = vertex.pos;

double lu = p.dotProduct(basis.u);
double lv = p.dotProduct(basis.v);

float u = (float)((lu - minU) / du);
float v = (float)((lv - minV) / dv);

vertex.u = u;
vertex.v = v;
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/cam72cam/mod/render/cutter/ClipResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cam72cam.mod.render.cutter;

import java.util.ArrayList;
import java.util.List;

public class ClipResult {

public final Polygon polygon = new Polygon();

public final List<ClipVertex> intersections = new ArrayList<>();
}
Loading