// Path: src/main/java/team/chisel/ctm/api/texture/ISubmap.java
// @ParametersAreNonnullByDefault
// public interface ISubmap {
// 
//     float getYOffset();
// 
//     float getXOffset();
// 
//     float getWidth();
// 
//     float getHeight();
// 
//     float getInterpolatedU(TextureAtlasSprite sprite, float u);
// 
//     float getInterpolatedV(TextureAtlasSprite sprite, float v);
// 
//     float[] toArray();
// 
//     ISubmap normalize();
// 
//     ISubmap relativize();
// }


import com.google.common.base.Preconditions;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.MultimapBuilder;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.blaze3d.vertex.VertexFormatElement;
import com.mojang.math.Vector3f;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.Value;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.Direction;
import net.minecraft.world.phys.Vec2;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import org.apache.commons.lang3.tuple.Pair;
import team.chisel.ctm.api.texture.ISubmap;
import team.chisel.ctm.api.util.NonnullType;
                    Vector3f p = vertPos[v];
                    builder.put(i, p.x(), p.y(), p.z(), 1);
                    break;
                /*case COLOR:
                    builder.put(i, 35, 162, 204); Pretty things
                    break;*/
                case UV:
                    if (ele.getIndex() == 2) {
                        //Stuff for fullbright
                        builder.put(i, ((float) blocklight * 0x20) / 0xFFFF, ((float) skylight * 0x20) / 0xFFFF);
                        break;
                    } else if (ele.getIndex() == 0) {
                        Vec2 uv = vertUv[v];
                        builder.put(i, uv.x, uv.y);
                        break;
                    }
                    // fallthrough
                default:
                    builder.put(i, this.builder.data.get(ele).get(v));
                }
            }
        }

        return builder.build();
    }
    
    public Quad transformUVs(TextureAtlasSprite sprite) {
        return transformUVs(sprite, CTMLogic.FULL_TEXTURE.normalize());
    }
    
// Path: src/main/java/team/chisel/ctm/api/texture/ISubmap.java
// @ParametersAreNonnullByDefault
// public interface ISubmap {
// 
//     float getYOffset();
// 
//     float getXOffset();
// 
//     float getWidth();
// 
//     float getHeight();
// 
//     float getInterpolatedU(TextureAtlasSprite sprite, float u);
// 
//     float getInterpolatedV(TextureAtlasSprite sprite, float v);
// 
//     float[] toArray();
// 
//     ISubmap normalize();
// 
//     ISubmap relativize();
// }


// Path: src/main/java/team/chisel/ctm/client/util/Quad.java
import com.google.common.base.Preconditions;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.MultimapBuilder;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.blaze3d.vertex.VertexFormatElement;
import com.mojang.math.Vector3f;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.Value;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.Direction;
import net.minecraft.world.phys.Vec2;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import org.apache.commons.lang3.tuple.Pair;
import team.chisel.ctm.api.texture.ISubmap;
import team.chisel.ctm.api.util.NonnullType;

                    Vector3f p = vertPos[v];
                    builder.put(i, p.x(), p.y(), p.z(), 1);
                    break;
                /*case COLOR:
                    builder.put(i, 35, 162, 204); Pretty things
                    break;*/
                case UV:
                    if (ele.getIndex() == 2) {
                        //Stuff for fullbright
                        builder.put(i, ((float) blocklight * 0x20) / 0xFFFF, ((float) skylight * 0x20) / 0xFFFF);
                        break;
                    } else if (ele.getIndex() == 0) {
                        Vec2 uv = vertUv[v];
                        builder.put(i, uv.x, uv.y);
                        break;
                    }
                    // fallthrough
                default:
                    builder.put(i, this.builder.data.get(ele).get(v));
                }
            }
        }

        return builder.build();
    }
    
    public Quad transformUVs(TextureAtlasSprite sprite) {
        return transformUVs(sprite, CTMLogic.FULL_TEXTURE.normalize());
    }
    
    public Quad transformUVs(TextureAtlasSprite sprite, ISubmap submap) {