2020-10-29 19:50:03 +00:00
|
|
|
package wayoftime.bloodmagic.client.render;
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
|
|
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
|
|
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
|
|
|
|
|
|
|
import net.minecraft.client.Minecraft;
|
|
|
|
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
|
|
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
|
|
import net.minecraft.util.Direction;
|
|
|
|
import net.minecraft.util.Direction.Axis;
|
|
|
|
import net.minecraft.util.Direction.AxisDirection;
|
|
|
|
import net.minecraft.util.math.vector.Matrix3f;
|
|
|
|
import net.minecraft.util.math.vector.Matrix4f;
|
|
|
|
import net.minecraft.util.math.vector.Vector3d;
|
|
|
|
import net.minecraft.util.math.vector.Vector3f;
|
|
|
|
import net.minecraft.util.math.vector.Vector3i;
|
|
|
|
import wayoftime.bloodmagic.client.render.BloodMagicRenderer.Model3D;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adapted from BuildCraft
|
|
|
|
*/
|
|
|
|
public class RenderResizableCuboid
|
|
|
|
{
|
|
|
|
public static final RenderResizableCuboid INSTANCE = new RenderResizableCuboid();
|
|
|
|
private static final Vector3f VEC_ZERO = new Vector3f(0, 0, 0);
|
|
|
|
private static final int U_MIN = 0;
|
|
|
|
private static final int U_MAX = 1;
|
|
|
|
private static final int V_MIN = 2;
|
|
|
|
private static final int V_MAX = 3;
|
|
|
|
|
|
|
|
protected EntityRendererManager manager = Minecraft.getInstance().getRenderManager();
|
|
|
|
|
|
|
|
private static Vector3f withValue(Vector3f vector, Axis axis, float value)
|
|
|
|
{
|
|
|
|
if (axis == Axis.X)
|
|
|
|
{
|
|
|
|
return new Vector3f(value, vector.getY(), vector.getZ());
|
|
|
|
} else if (axis == Axis.Y)
|
|
|
|
{
|
|
|
|
return new Vector3f(vector.getX(), value, vector.getZ());
|
|
|
|
} else if (axis == Axis.Z)
|
|
|
|
{
|
|
|
|
return new Vector3f(vector.getX(), vector.getY(), value);
|
|
|
|
}
|
2020-11-11 16:19:21 +00:00
|
|
|
throw new RuntimeException("Was given a null axis! That was probably not intentional, consider this a bug! (Vector = " + vector + ")");
|
2020-10-29 19:50:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static double getValue(Vector3d vector, Axis axis)
|
|
|
|
{
|
|
|
|
if (axis == Axis.X)
|
|
|
|
{
|
|
|
|
return vector.x;
|
|
|
|
} else if (axis == Axis.Y)
|
|
|
|
{
|
|
|
|
return vector.y;
|
|
|
|
} else if (axis == Axis.Z)
|
|
|
|
{
|
|
|
|
return vector.z;
|
|
|
|
}
|
2020-11-11 16:19:21 +00:00
|
|
|
throw new RuntimeException("Was given a null axis! That was probably not intentional, consider this a bug! (Vector = " + vector + ")");
|
2020-10-29 19:50:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void renderCube(Model3D cube, MatrixStack matrix, IVertexBuilder buffer, int argb, int light, int overlay)
|
|
|
|
{
|
|
|
|
float red = BloodMagicRenderer.getRed(argb);
|
|
|
|
float green = BloodMagicRenderer.getGreen(argb);
|
|
|
|
float blue = BloodMagicRenderer.getBlue(argb);
|
|
|
|
float alpha = BloodMagicRenderer.getAlpha(argb);
|
|
|
|
Vector3d size = new Vector3d(cube.sizeX(), cube.sizeY(), cube.sizeZ());
|
|
|
|
matrix.push();
|
|
|
|
matrix.translate(cube.minX, cube.minY, cube.minZ);
|
|
|
|
MatrixStack.Entry lastMatrix = matrix.getLast();
|
|
|
|
Matrix4f matrix4f = lastMatrix.getMatrix();
|
|
|
|
Matrix3f normal = lastMatrix.getNormal();
|
|
|
|
for (Direction face : Direction.values())
|
|
|
|
{
|
|
|
|
if (cube.shouldSideRender(face))
|
|
|
|
{
|
|
|
|
int ordinal = face.ordinal();
|
|
|
|
TextureAtlasSprite sprite = cube.textures[ordinal];
|
|
|
|
if (sprite != null)
|
|
|
|
{
|
|
|
|
Axis u = face.getAxis() == Axis.X ? Axis.Z : Axis.X;
|
|
|
|
Axis v = face.getAxis() == Axis.Y ? Axis.Z : Axis.Y;
|
|
|
|
float other = face.getAxisDirection() == AxisDirection.POSITIVE
|
|
|
|
? (float) getValue(size, face.getAxis())
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
// Swap the face if this is positive: the renderer returns indexes that ALWAYS
|
|
|
|
// are for the negative face, so light it properly this way
|
|
|
|
face = face.getAxisDirection() == AxisDirection.NEGATIVE ? face : face.getOpposite();
|
|
|
|
Direction opposite = face.getOpposite();
|
|
|
|
|
|
|
|
float minU = sprite.getMinU();
|
|
|
|
float maxU = sprite.getMaxU();
|
|
|
|
// Flip the v
|
|
|
|
float minV = sprite.getMaxV();
|
|
|
|
float maxV = sprite.getMinV();
|
|
|
|
double sizeU = getValue(size, u);
|
|
|
|
double sizeV = getValue(size, v);
|
|
|
|
// TODO: Look into this more, as it makes tiling of multiple objects not render
|
|
|
|
// properly if they don't fit the full texture.
|
|
|
|
// Example: Mechanical pipes rendering water or lava, makes it relatively easy
|
|
|
|
// to see the texture artifacts
|
|
|
|
for (int uIndex = 0; uIndex < sizeU; uIndex++)
|
|
|
|
{
|
2020-11-11 16:19:21 +00:00
|
|
|
float[] baseUV = new float[] { minU, maxU, minV, maxV };
|
2020-10-29 19:50:03 +00:00
|
|
|
double addU = 1;
|
|
|
|
// If the size of the texture is greater than the cuboid goes on for then make
|
|
|
|
// sure the texture positions are lowered
|
|
|
|
if (uIndex + addU > sizeU)
|
|
|
|
{
|
|
|
|
addU = sizeU - uIndex;
|
|
|
|
baseUV[U_MAX] = baseUV[U_MIN] + (baseUV[U_MAX] - baseUV[U_MIN]) * (float) addU;
|
|
|
|
}
|
|
|
|
for (int vIndex = 0; vIndex < sizeV; vIndex++)
|
|
|
|
{
|
|
|
|
float[] uv = Arrays.copyOf(baseUV, 4);
|
|
|
|
double addV = 1;
|
|
|
|
if (vIndex + addV > sizeV)
|
|
|
|
{
|
|
|
|
addV = sizeV - vIndex;
|
|
|
|
uv[V_MAX] = uv[V_MIN] + (uv[V_MAX] - uv[V_MIN]) * (float) addV;
|
|
|
|
}
|
2020-11-11 16:19:21 +00:00
|
|
|
float[] xyz = new float[] { uIndex, (float) (uIndex + addU), vIndex,
|
|
|
|
(float) (vIndex + addV) };
|
2020-10-29 19:50:03 +00:00
|
|
|
|
|
|
|
renderPoint(matrix4f, normal, buffer, face, u, v, other, uv, xyz, true, false, red, green, blue, alpha, light, overlay);
|
|
|
|
renderPoint(matrix4f, normal, buffer, face, u, v, other, uv, xyz, true, true, red, green, blue, alpha, light, overlay);
|
|
|
|
renderPoint(matrix4f, normal, buffer, face, u, v, other, uv, xyz, false, true, red, green, blue, alpha, light, overlay);
|
|
|
|
renderPoint(matrix4f, normal, buffer, face, u, v, other, uv, xyz, false, false, red, green, blue, alpha, light, overlay);
|
|
|
|
|
|
|
|
renderPoint(matrix4f, normal, buffer, opposite, u, v, other, uv, xyz, false, false, red, green, blue, alpha, light, overlay);
|
|
|
|
renderPoint(matrix4f, normal, buffer, opposite, u, v, other, uv, xyz, false, true, red, green, blue, alpha, light, overlay);
|
|
|
|
renderPoint(matrix4f, normal, buffer, opposite, u, v, other, uv, xyz, true, true, red, green, blue, alpha, light, overlay);
|
|
|
|
renderPoint(matrix4f, normal, buffer, opposite, u, v, other, uv, xyz, true, false, red, green, blue, alpha, light, overlay);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
matrix.pop();
|
|
|
|
}
|
|
|
|
|
2020-11-11 16:19:21 +00:00
|
|
|
private void renderPoint(Matrix4f matrix4f, Matrix3f normal, IVertexBuilder buffer, Direction face, Axis u, Axis v, float other, float[] uv, float[] xyz, boolean minU, boolean minV, float red, float green, float blue, float alpha, int light, int overlay)
|
2020-10-29 19:50:03 +00:00
|
|
|
{
|
|
|
|
int U_ARRAY = minU ? U_MIN : U_MAX;
|
|
|
|
int V_ARRAY = minV ? V_MIN : V_MAX;
|
|
|
|
Vector3f vertex = withValue(VEC_ZERO, u, xyz[U_ARRAY]);
|
|
|
|
vertex = withValue(vertex, v, xyz[V_ARRAY]);
|
|
|
|
vertex = withValue(vertex, face.getAxis(), other);
|
|
|
|
Vector3i normalForFace = face.getDirectionVec();
|
|
|
|
// TODO: Figure out how and why this works, it gives about the same brightness
|
|
|
|
// as we used to have but I don't understand why/how
|
|
|
|
float adjustment = 2.5F;
|
2020-11-11 16:19:21 +00:00
|
|
|
Vector3f norm = new Vector3f(normalForFace.getX() + adjustment, normalForFace.getY() + adjustment, normalForFace.getZ() + adjustment);
|
2020-10-29 19:50:03 +00:00
|
|
|
norm.normalize();
|
|
|
|
buffer.pos(matrix4f, vertex.getX(), vertex.getY(), vertex.getZ()).color(red, green, blue, alpha).tex(uv[U_ARRAY], uv[V_ARRAY]).overlay(overlay).lightmap(light).normal(normal, norm.getX(), norm.getY(), norm.getZ()).endVertex();
|
|
|
|
}
|
|
|
|
}
|