com.parzivail.util.client.model.ConnectedTextureModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pswg Show documentation
Show all versions of pswg Show documentation
Explore the galaxy with Galaxies: Parzi's Star Wars Mod!
package com.parzivail.util.client.model;
import F;
import I;
import com.mojang.datafixers.util.Pair;
import com.parzivail.util.client.ConnectedTextureHelper;
import com.parzivail.util.client.ConnectedTextureHelper.Sides;
import com.parzivail.util.client.SubSprite;
import com.parzivail.util.math.MathUtil;
import com.parzivail.util.math.SpriteSheetPoint;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.class_1058;
import net.minecraft.class_1087;
import net.minecraft.class_1100;
import net.minecraft.class_1799;
import net.minecraft.class_1920;
import net.minecraft.class_2338;
import net.minecraft.class_2350;
import net.minecraft.class_2429;
import net.minecraft.class_2680;
import net.minecraft.class_2746;
import net.minecraft.class_2960;
import net.minecraft.class_3665;
import net.minecraft.class_4730;
import net.minecraft.class_5819;
import net.minecraft.class_7775;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
@Environment(EnvType.CLIENT)
public class ConnectedTextureModel extends DynamicBakedModel
{
private static final Vector3f[] ORIGINS = new Vector3f[6];
private static final Vector3f[] DELTAU = new Vector3f[6];
private static final Vector3f[] DELTAV = new Vector3f[6];
static
{
ORIGINS[class_2350.field_11036.method_10146()] = new Vector3f(0, 1, 0);
ORIGINS[class_2350.field_11033.method_10146()] = new Vector3f(1, 0, 0);
ORIGINS[class_2350.field_11039.method_10146()] = new Vector3f(0, 1, 0);
ORIGINS[class_2350.field_11034.method_10146()] = new Vector3f(1, 1, 1);
ORIGINS[class_2350.field_11043.method_10146()] = new Vector3f(1, 1, 0);
ORIGINS[class_2350.field_11035.method_10146()] = new Vector3f(0, 1, 1);
DELTAU[class_2350.field_11036.method_10146()] = MathUtil.V3F_POS_X;
DELTAV[class_2350.field_11036.method_10146()] = MathUtil.V3F_POS_Z;
DELTAU[class_2350.field_11033.method_10146()] = MathUtil.V3F_NEG_X;
DELTAV[class_2350.field_11033.method_10146()] = MathUtil.V3F_POS_Z;
DELTAU[class_2350.field_11035.method_10146()] = MathUtil.V3F_POS_X;
DELTAV[class_2350.field_11035.method_10146()] = MathUtil.V3F_NEG_Y;
DELTAU[class_2350.field_11043.method_10146()] = MathUtil.V3F_NEG_X;
DELTAV[class_2350.field_11043.method_10146()] = MathUtil.V3F_NEG_Y;
DELTAU[class_2350.field_11039.method_10146()] = MathUtil.V3F_POS_Z;
DELTAV[class_2350.field_11039.method_10146()] = MathUtil.V3F_NEG_Y;
DELTAU[class_2350.field_11034.method_10146()] = MathUtil.V3F_NEG_Z;
DELTAV[class_2350.field_11034.method_10146()] = MathUtil.V3F_NEG_Y;
}
private final boolean hConnect;
private final boolean vConnect;
private final boolean lConnect;
private final EnumSet capDirections;
private final class_1058 borderSprite;
private final class_1058 capSprite;
public ConnectedTextureModel(boolean hConnect, boolean vConnect, boolean lConnect, EnumSet capDirections, class_1058 blankSprite, class_1058 borderSprite, class_1058 capSprite)
{
super(blankSprite, ModelHelper.MODEL_TRANSFORM_BLOCK);
this.hConnect = hConnect;
this.vConnect = vConnect;
this.lConnect = lConnect;
this.capDirections = capDirections;
this.borderSprite = borderSprite;
this.capSprite = capSprite;
}
@Override
protected CacheMethod getDiscriminator()
{
return CacheMethod.NO_CACHING;
}
@Override
protected Mesh createBlockMesh(class_1920 blockView, class_2680 state, class_2338 pos, Supplier randomSupplier, RenderContext context, Matrix4f transformation)
{
// var minecraft = MinecraftClient.getInstance();
var meshBuilder = createMeshBuilder();//RENDERER.meshBuilder();
var quadEmitter = meshBuilder.getEmitter();
// var blockModels = minecraft.getBlockRenderManager().getModels();
// TODO: fix item lighting
// if (state == null) // Assume it's an item
// {
// model = Client.minecraft.getItemRenderer().getHeldItemModel(new ItemStack(SwgBlocks.Panel.LabWall), null, null);
// }
for (var i = 0; i < ModelHelper.NULL_FACE_ID; i++)
{
if (state != null && !(state.method_26204() instanceof class_2429))
continue;
final var faceDirection = ModelHelper.faceFromIndex(i);
if (faceDirection != null)
{
final var facingProp = class_2429.field_11329.get(faceDirection);
if (state != null && state.method_11654(facingProp))
{
quadEmitter.emit();
continue;
}
}
var sprite = modelSprite;
if (capSprite != null && capDirections.contains(faceDirection))
sprite = capSprite;
Vector3f min = ORIGINS[faceDirection.method_10146()];
Vector3f dU = DELTAU[faceDirection.method_10146()];
Vector3f dV = DELTAV[faceDirection.method_10146()];
emitTopQuad(quadEmitter, sprite, borderSprite, blockView, state, pos, faceDirection, min, dU, dV);
}
return meshBuilder.build();
}
private static Vector3f uv(Vector3f min, Vector3f dU, Vector3f dV, float u, float v)
{
return new Vector3f(
min.x + dU.x * u + dV.x * v,
min.y + dU.y * u + dV.y * v,
min.z + dU.z * u + dV.z * v
);
}
private void emitTopQuad(QuadEmitter quadEmitter, class_1058 blankSprite, class_1058 borderSprite, class_1920 blockView, class_2680 state, class_2338 pos, class_2350 direction, Vector3f min, Vector3f dU, Vector3f dV)
{
var subSpriteEntry = ConnectedTextureHelper.getConnectedBlockTexture(blockView, state, pos, direction, hConnect, vConnect, lConnect);
var normal = direction.method_23955();
if (subSpriteEntry == null)
{
// No corners or edges
quadEmitter
.colorIndex(1)
.spriteColor(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)
.pos(0, min)
.normal(0, normal)
.sprite(0, 0, blankSprite.method_4594(), blankSprite.method_4593())
.pos(1, uv(min, dU, dV, 0, 1))
.normal(1, normal)
.sprite(1, 0, blankSprite.method_4594(), blankSprite.method_4575())
.pos(2, uv(min, dU, dV, 1, 1))
.normal(2, normal)
.sprite(2, 0, blankSprite.method_4577(), blankSprite.method_4575())
.pos(3, uv(min, dU, dV, 1, 0))
.normal(3, normal)
.sprite(3, 0, blankSprite.method_4577(), blankSprite.method_4593())
.emit();
return;
}
// top left
var subSprite = getSubSprite(subSpriteEntry.TopLeft(), blankSprite, borderSprite, 4, 4);
quadEmitter
.colorIndex(1)
.spriteColor(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)
.pos(0, min)
.normal(0, normal)
.sprite(0, 0, subSprite.minU(), subSprite.minV())
.pos(1, uv(min, dU, dV, 0, 0.5f))
.normal(1, normal)
.sprite(1, 0, subSprite.minU(), subSprite.maxV())
.pos(2, uv(min, dU, dV, 0.5f, 0.5f))
.normal(2, normal)
.sprite(2, 0, subSprite.maxU(), subSprite.maxV())
.pos(3, uv(min, dU, dV, 0.5f, 0))
.normal(3, normal)
.sprite(3, 0, subSprite.maxU(), subSprite.minV())
.emit();
// top right
subSprite = getSubSprite(subSpriteEntry.TopRight(), blankSprite, borderSprite, 4, 4);
quadEmitter
.colorIndex(1)
.spriteColor(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)
.pos(0, uv(min, dU, dV, 0.5f, 0))
.normal(0, normal)
.sprite(0, 0, subSprite.minU(), subSprite.minV())
.pos(1, uv(min, dU, dV, 0.5f, 0.5f))
.normal(1, normal)
.sprite(1, 0, subSprite.minU(), subSprite.maxV())
.pos(2, uv(min, dU, dV, 1, 0.5f))
.normal(2, normal)
.sprite(2, 0, subSprite.maxU(), subSprite.maxV())
.pos(3, uv(min, dU, dV, 1, 0))
.normal(3, normal)
.sprite(3, 0, subSprite.maxU(), subSprite.minV())
.emit();
// bottom left
subSprite = getSubSprite(subSpriteEntry.BottomLeft(), blankSprite, borderSprite, 4, 4);
quadEmitter
.colorIndex(1)
.spriteColor(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)
.pos(0, uv(min, dU, dV, 0, 0.5f))
.normal(0, normal)
.sprite(0, 0, subSprite.minU(), subSprite.minV())
.pos(1, uv(min, dU, dV, 0, 1))
.normal(1, normal)
.sprite(1, 0, subSprite.minU(), subSprite.maxV())
.pos(2, uv(min, dU, dV, 0.5f, 1))
.normal(2, normal)
.sprite(2, 0, subSprite.maxU(), subSprite.maxV())
.pos(3, uv(min, dU, dV, 0.5f, 0.5f))
.normal(3, normal)
.sprite(3, 0, subSprite.maxU(), subSprite.minV())
.emit();
// bottom right
subSprite = getSubSprite(subSpriteEntry.BottomRight(), blankSprite, borderSprite, 4, 4);
quadEmitter
.colorIndex(1)
.spriteColor(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)
.pos(0, uv(min, dU, dV, 0.5f, 0.5f))
.normal(0, normal)
.sprite(0, 0, subSprite.minU(), subSprite.minV())
.pos(1, uv(min, dU, dV, 0.5f, 1))
.normal(1, normal)
.sprite(1, 0, subSprite.minU(), subSprite.maxV())
.pos(2, uv(min, dU, dV, 1, 1))
.normal(2, normal)
.sprite(2, 0, subSprite.maxU(), subSprite.maxV())
.pos(3, uv(min, dU, dV, 1, 0.5f))
.normal(3, normal)
.sprite(3, 0, subSprite.maxU(), subSprite.minV())
.emit();
}
private static SubSprite getSubSprite(SpriteSheetPoint point, class_1058 blankSprite, class_1058 borderSprite, int columns, int rows)
{
var sprite = borderSprite;
if (point.sheet() == 1) // "blank" cornerless texture
{
sprite = blankSprite;
rows = 2;
columns = 2;
}
var spriteWidth = sprite.method_4577() - sprite.method_4594();
var spriteHeight = sprite.method_4575() - sprite.method_4593();
var columnSpan = spriteWidth / columns;
var rowSpan = spriteHeight / rows;
return new SubSprite(sprite.method_4594() + point.x() * columnSpan, sprite.method_4593() + point.y() * rowSpan, sprite.method_4594() + (point.x() + 1) * columnSpan, sprite.method_4593() + (point.y() + 1) * rowSpan);
}
@Override
protected Mesh createItemMesh(class_1799 stack, Supplier randomSupplier, RenderContext context, Matrix4f transformation)
{
return createBlockMesh(null, null, null, null, null, transformation);
}
@Override
protected Matrix4f createTransformation(class_2680 state)
{
return new Matrix4f();
}
@Override
public boolean method_4712()
{
return false;
}
@Override
public boolean method_24304()
{
return false;
}
public static class Unbaked extends ClonableUnbakedModel
{
private final Function, ConnectedTextureModel> baker;
private ConnectedTextureModel cachedBakedModel;
private final boolean hConnect;
private final boolean vConnect;
private final boolean lConnect;
private final EnumSet capDirections;
private final class_4730 sprite;
private final class_4730 borderSprite;
private final class_4730 capSprite;
public Unbaked(boolean hConnect, boolean vConnect, boolean lConnect, EnumSet capDirections, class_4730 sprite, class_4730 borderSprite, class_4730 capSprite)
{
this.hConnect = hConnect;
this.vConnect = vConnect;
this.lConnect = lConnect;
this.capDirections = capDirections;
this.sprite = sprite;
this.borderSprite = borderSprite;
this.capSprite = capSprite;
this.baker = spriteLoader -> new ConnectedTextureModel(hConnect, vConnect, lConnect, capDirections, spriteLoader.apply(sprite), spriteLoader.apply(borderSprite), capSprite == null ? null : spriteLoader.apply(capSprite));
}
@Override
public Collection method_4755()
{
return Collections.emptyList();
}
@Override
public void method_45785(Function modelLoader)
{
// TODO: parents?
}
@Nullable
@Override
public class_1087 method_4753(class_7775 baker, Function textureGetter, class_3665 rotationContainer, class_2960 modelId)
{
if (cachedBakedModel != null)
return cachedBakedModel;
var result = this.baker.apply(textureGetter);
cachedBakedModel = result;
return result;
}
// TODO: no longer required?
// @Override
public Collection getTextureDependencies(Function unbakedModelGetter, Set> unresolvedTextureReferences)
{
var ids = new ArrayList();
ids.add(sprite);
ids.add(borderSprite);
if (capSprite != null)
ids.add(capSprite);
return ids;
}
@Override
public ClonableUnbakedModel copy()
{
return new Unbaked(hConnect, vConnect, lConnect, capDirections.clone(), sprite, borderSprite, capSprite);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy