Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package team.chisel.client.render;
- import java.awt.geom.Rectangle2D;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Set;
- import javax.annotation.Nullable;
- import lombok.Getter;
- import lombok.RequiredArgsConstructor;
- import lombok.Setter;
- import lombok.ToString;
- import lombok.Value;
- import lombok.experimental.NonFinal;
- import net.minecraft.client.Minecraft;
- import net.minecraft.client.renderer.block.model.BakedQuad;
- import net.minecraft.client.renderer.texture.TextureAtlasSprite;
- import net.minecraft.client.renderer.texture.TextureMap;
- import net.minecraft.client.renderer.vertex.VertexFormat;
- import net.minecraft.client.renderer.vertex.VertexFormatElement;
- import net.minecraft.client.renderer.vertex.VertexFormatElement.EnumUsage;
- import net.minecraft.util.EnumFacing;
- import net.minecraftforge.client.model.pipeline.IVertexConsumer;
- import org.lwjgl.util.vector.Vector;
- import org.lwjgl.util.vector.Vector2f;
- import org.lwjgl.util.vector.Vector3f;
- import com.google.common.collect.ListMultimap;
- import com.google.common.collect.Lists;
- import com.google.common.collect.MultimapBuilder;
- import com.google.common.collect.Sets;
- @ToString(of = { "verts", "uvs" })
- public class Quad {
- @Value
- public static class Vertex {
- Vector3f pos;
- Vector2f uvs;
- }
- public static class UVs {
- private static final TextureAtlasSprite BASE = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(TextureMap.LOCATION_MISSING_TEXTURE.toString());
- private static final float BASE_WIDTH = BASE.getMaxU() - BASE.getMinU(), BASE_HEIGHT = BASE.getMaxV() - BASE.getMinV();
- @Getter
- private TextureAtlasSprite base = BASE;
- @Getter
- private float width = BASE_WIDTH, height = BASE_HEIGHT;
- private final Vector2f[] data;
- @NonFinal
- @Getter
- float minU, minV, maxU, maxV;
- private UVs(Vector2f[] data) {
- this.data = data;
- minU = Float.MAX_VALUE;
- minV = Float.MAX_VALUE;
- for (Vector2f v : data) {
- minU = Math.min(minU, v.x);
- minV = Math.min(minV, v.y);
- maxU = Math.max(maxU, v.x);
- maxV = Math.max(maxV, v.y);
- }
- }
- public void transform(TextureAtlasSprite other) {
- float scaleU = BASE_WIDTH / (other.getMaxU() - other.getMinU());
- float scaleV = BASE_HEIGHT / (other.getMaxV() - other.getMinV());
- float startU = (minU - BASE.getMinU()) * scaleU;
- float startV = (minV - BASE.getMinV()) * scaleV;
- float endU = (BASE.getMaxU() - maxU) * scaleU;
- float endV = (BASE.getMaxV() - maxV) * scaleV;
- minU = startU + other.getMinU();
- minV = startV + other.getMinV();
- maxU = other.getMaxU() - endU;
- maxV = other.getMaxV() - endV;
- base = other;
- }
- public Rectangle2D.Float rect() {
- return new Rectangle2D.Float(minU, minV, width, height);
- }
- }
- private Vector3f[] verts;
- @Getter
- private UVs uvs;
- private Quad(Vector3f[] verts, Vector2f[] uvs) {
- this.verts = verts;
- this.uvs = new UVs(uvs);
- }
- public void compute() {
- }
- public Quad[] subdivide(int count) {
- List<Rectangle2D.Float> rects = Lists.newArrayList();
- Rectangle2D.Float uvRect = uvs.rect();
- normalizeUVs(uvRect);
- rects.add(uvRect);
- Rectangle2D.Float rect2 = divide(uvRect, false);
- rects.add(rect2);
- if (rect2 != null) {
- rects.add(divide(rect2, true));
- }
- rects.add(divide(uvRect, true));
- for (Rectangle2D.Float rect : rects) {
- }
- return null;
- }
- private void normalizeUVs(Rectangle2D.Float rect) {
- TextureAtlasSprite sprite = uvs.getBase();
- float width = sprite.getMaxU() - sprite.getMinU();
- float height = sprite.getMaxV() - sprite.getMinV();
- rect.x = normalize(sprite.getMinU(), sprite.getMaxU(), rect.x);
- rect.y = normalize(sprite.getMinV(), sprite.getMaxV(), rect.y);
- rect.width /= width;
- rect.height /= height;
- }
- @Nullable
- private Rectangle2D.Float divide(Rectangle2D.Float rect, boolean vertical) {
- float min, max;
- if (vertical) {
- min = rect.y;
- max = rect.y + rect.height;
- } else {
- min = rect.x;
- max = rect.x + rect.width;
- }
- if (min < 0.5 && max > 0.5) {
- Rectangle2D.Float split = new Rectangle2D.Float(rect.x, rect.y, vertical ? rect.width : 0.5f - rect.x, vertical ? 0.5f - rect.y : rect.height);
- if (vertical) {
- rect.height -= 0.5f - rect.y;
- rect.y = 0.5f;
- } else {
- rect.width -= 0.5f - rect.x;
- rect.x = 0.5f;
- }
- return split;
- } else {
- return null;
- }
- }
- private float normalize(float min, float max, float x) {
- return (x - min) / (max - min);
- }
- public static Quad from(BakedQuad baked, VertexFormat fmt) {
- Builder b = new Builder(fmt);
- baked.pipe(b);
- return b.build();
- }
- @RequiredArgsConstructor
- public static class Builder implements IVertexConsumer {
- @Getter
- private final VertexFormat vertexFormat;
- @Setter
- private int quadTint;
- @Setter
- private EnumFacing quadOrientation;
- @Override
- public void setQuadColored() {}
- private ListMultimap<VertexFormatElement.EnumUsage, float[]> data = MultimapBuilder.enumKeys(EnumUsage.class).arrayListValues().build();
- @Override
- public void put(int element, float... data) {
- if (element == 2) {
- System.out.println(Arrays.toString(data));
- }
- float[] copy = new float[data.length];
- System.arraycopy(data, 0, copy, 0, data.length);
- this.data.put(vertexFormat.getElement(element).getUsage(), copy);
- }
- public Quad build() {
- Vector3f[] verts = fromData(data.get(EnumUsage.POSITION), 3);
- Vector2f[] uvs = fromData(data.get(EnumUsage.UV), 2);
- return new Quad(verts, uvs);
- }
- @SuppressWarnings("unchecked")
- private <T extends Vector> T[] fromData(List<float[]> data, int size) {
- Vector[] ret = size == 2 ? new Vector2f[data.size()] : new Vector3f[data.size()];
- for (int i = 0; i < data.size(); i++) {
- ret[i] = size == 2 ? new Vector2f(data.get(i)[0], data.get(i)[1]) : new Vector3f(data.get(i)[0], data.get(i)[1], data.get(i)[2]);
- }
- return (T[]) ret;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement