All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.parzivail.p3d.P3dBakedBlockModel Maven / Gradle / Ivy

There is a newer version: 0.0.114+1.20.2
Show newest version
package com.parzivail.p3d;

import F;
import I;
import com.parzivail.util.block.DisplacingBlock;
import com.parzivail.util.block.IPicklingBlock;
import com.parzivail.util.block.VoxelShapeUtil;
import com.parzivail.util.block.rotating.WaterloggableRotating3BlockWithGuiEntity;
import com.parzivail.util.block.rotating.WaterloggableRotating3BlockWithGuiEntity.Side;
import com.parzivail.util.block.rotating.WaterloggableRotatingBlock;
import com.parzivail.util.client.model.DynamicBakedModel;
import com.parzivail.util.math.MathUtil;
import com.parzivail.util.math.QuatUtil;
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_1723;
import net.minecraft.class_1747;
import net.minecraft.class_1799;
import net.minecraft.class_1920;
import net.minecraft.class_2248;
import net.minecraft.class_2338;
import net.minecraft.class_2350.class_2351;
import net.minecraft.class_238;
import net.minecraft.class_243;
import net.minecraft.class_2465;
import net.minecraft.class_265;
import net.minecraft.class_2680;
import net.minecraft.class_2758;
import net.minecraft.class_2960;
import net.minecraft.class_3726;
import net.minecraft.class_4587;
import net.minecraft.class_4587.class_4665;
import net.minecraft.class_4730;
import net.minecraft.class_5819;
import org.jetbrains.annotations.NotNull;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.function.Supplier;

public class P3dBakedBlockModel extends DynamicBakedModel
{
	private final CacheMethod cacheMethod;
	private final class_1058 baseSprite;
	private final HashMap additionalSprites;
	private final class_2960[] modelIds;

	private P3dBakedBlockModel(CacheMethod cacheMethod, class_1058 baseSprite, class_1058 particleSprite, HashMap additionalSprites, class_2960[] modelIds)
	{
		super(particleSprite, ModelHelper.MODEL_TRANSFORM_BLOCK);
		this.cacheMethod = cacheMethod;
		this.baseSprite = baseSprite;
		this.additionalSprites = additionalSprites;
		this.modelIds = modelIds;
	}

	@Override
	protected CacheMethod getDiscriminator()
	{
		return cacheMethod;
	}

	@Override
	protected Mesh createBlockMesh(class_1920 blockView, class_2680 state, class_2338 pos, Supplier randomSupplier, RenderContext context, Matrix4f transformation)
	{
		if (state != null)
		{
			if (state.method_26204() instanceof DisplacingBlock db)
			{
				var shape = db.method_9530(state, blockView, pos, class_3726.method_16194());
				var center = VoxelShapeUtil.getCenter(shape);
				transformation.translate((float)center.field_1352 - 0.5f, 0, (float)center.field_1350 - 0.5f);
			}
			else if (state.method_26204() instanceof WaterloggableRotating3BlockWithGuiEntity)
			{
				var side = state.method_11654(WaterloggableRotating3BlockWithGuiEntity.SIDE);
				if (side != WaterloggableRotating3BlockWithGuiEntity.Side.MIDDLE)
					return createMeshBuilder().build();
			}
		}

		return createMesh(new P3dBlockRenderTarget.Block(blockView, state, pos), randomSupplier, context, transformation);
	}

	@Override
	protected Mesh createItemMesh(class_1799 stack, Supplier randomSupplier, RenderContext context, Matrix4f transformation)
	{
		return createMesh(new P3dBlockRenderTarget.Item(stack), randomSupplier, context, transformation);
	}

	private Mesh createMesh(P3dBlockRenderTarget target, Supplier randomSupplier, RenderContext context, Matrix4f transformation)
	{
		var meshBuilder = createMeshBuilder();
		var quadEmitter = meshBuilder.getEmitter();

		var modelId = modelIds[0];

		if (target instanceof P3dBlockRenderTarget.Block blockRenderTarget)
			modelId = getPickleModel(modelId, blockRenderTarget.getState());

		var model = P3dManager.INSTANCE.get(modelId);

		var ms = new class_4587();
		var e = ms.method_23760();
		e.method_23761().mul(transformation);
		e.method_23762().mul(new Matrix3f(transformation));

		// blocks are centered in P3D models
		ms.method_46416(0.5f, 0, 0.5f);

		// one pixel in P3D models is 1.6 game pixels
		MathUtil.scalePos(ms, 0.625f, 0.625f, 0.625f);

		// P3D models are +Z forward
		ms.method_22907(new Quaternionf().rotationY((float)(Math.PI / -2)));

		class_2248 block = null;
		if (target instanceof P3dBlockRenderTarget.Block blockRenderTarget && blockRenderTarget.getState() != null)
			block = blockRenderTarget.getState().method_26204();
		else if (target instanceof P3dBlockRenderTarget.Item itemRenderTarget && itemRenderTarget.getStack().method_7909() instanceof class_1747 blockItem)
			block = blockItem.method_7711();

		P3dBlockRendererRegistry.get(block).renderBlock(ms, quadEmitter, target, randomSupplier, context, model, baseSprite, additionalSprites);

		return meshBuilder.build();
	}

	private class_2960 getPickleModel(class_2960 defaultModel, class_2680 state)
	{
		if (state != null && state.method_26204() instanceof IPicklingBlock pb)
		{
			var pickleProp = pb.getPickleProperty();
			var pickle = state.method_11654(pickleProp) - 1;
			if (pickle >= 0 && pickle < modelIds.length)
				defaultModel = modelIds[pickle];
		}
		return defaultModel;
	}

	@Override
	protected Matrix4f createTransformation(class_2680 state)
	{
		var modelId = getPickleModel(modelIds[0], state);

		var model = P3dManager.INSTANCE.get(modelId);

		if (state == null)
		{
			// Item transformation, scale largest dimension to 1

			return getItemTransformation(model);
		}

		var mat = new Matrix4f();

		if (state.method_26204() instanceof WaterloggableRotatingBlock)
		{
			mat.translate(0.5f, 0.5f, 0.5f);

			mat.rotate(MathUtil.getRotation(state.method_11654(WaterloggableRotatingBlock.FACING)));

			mat.translate(-0.5f, -0.5f, -0.5f);
		}

		if (state.method_26204() instanceof class_2465)
		{
			var axis = state.method_11654(class_2465.field_11459);

			switch (axis)
			{
				case field_11048:
					mat.rotateZ((float)(Math.PI / -2));
					mat.translate(-1, 0, 0);
					break;
				case field_11051:
					mat.rotateY((float)(Math.PI / -2));
					mat.rotateZ((float)(Math.PI / -2));
					mat.translate(-1, 0, -1);
					break;
				case field_11052:
					break;
			}
		}

		return mat;
	}

	@NotNull
	public static Matrix4f getItemTransformation(P3dModel model)
	{
		var mat = new Matrix4f();

		var bounds = model.bounds();

		var largestDimension = 0.625f * (float)Math.max(bounds.method_17939(), Math.max(bounds.method_17940(), bounds.method_17941()));
		var scale = 1 / largestDimension;

		var minX = (float)bounds.field_1323 * 0.625f;
		var maxX = (float)bounds.field_1320 * 0.625f;
		var minY = (float)bounds.field_1322 * 0.625f;
		var minZ = (float)bounds.field_1321 * 0.625f;
		var maxZ = (float)bounds.field_1324 * 0.625f;

		mat.translate(0.5f, 0, 0.5f);
		mat.scale(scale, scale, scale);
		mat.translate(-0.5f, 0, -0.5f);

		mat.translate((maxX - minX) / 2 - maxX, -minY, (maxZ - minZ) / 2 - maxZ);

		mat.translate(0.5f, 0, 0.5f);
		mat.rotate(QuatUtil.ROT_Y_POS90);
		mat.translate(-0.5f, 0, -0.5f);

		return mat;
	}

	public static P3dBakedBlockModel create(Function spriteMap, CacheMethod cacheMethod, class_2960 baseTexture, class_2960 particleTexture, HashMap additionalTextures, class_2960... models)
	{
		HashMap additionalSprites = new HashMap<>();

		for (var entry : additionalTextures.entrySet())
			additionalSprites.put(entry.getKey(), spriteMap.apply(new class_4730(class_1723.field_21668, entry.getValue())));

		return new P3dBakedBlockModel(
				cacheMethod,
				spriteMap.apply(new class_4730(class_1723.field_21668, baseTexture)),
				spriteMap.apply(new class_4730(class_1723.field_21668, particleTexture)),
				additionalSprites,
				models
		);
	}

	@Override
	public boolean method_4712()
	{
		return true;
	}

	@Override
	public boolean method_24304()
	{
		return true;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy