
Fixed the ARC so that it could actually accept FluidStacks via capabilities. Also added several entries to the book regarding the Blood Altar and its runes.
162 lines
6.8 KiB
Java
162 lines
6.8 KiB
Java
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);
|
|
}
|
|
throw new RuntimeException("Was given a null axis! That was probably not intentional, consider this a bug! (Vector = " + vector + ")");
|
|
}
|
|
|
|
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;
|
|
}
|
|
throw new RuntimeException("Was given a null axis! That was probably not intentional, consider this a bug! (Vector = " + vector + ")");
|
|
}
|
|
|
|
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++)
|
|
{
|
|
float[] baseUV = new float[] { minU, maxU, minV, maxV };
|
|
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;
|
|
}
|
|
float[] xyz = new float[] { uIndex, (float) (uIndex + addU), vIndex,
|
|
(float) (vIndex + addV) };
|
|
|
|
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();
|
|
}
|
|
|
|
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)
|
|
{
|
|
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;
|
|
Vector3f norm = new Vector3f(normalForFace.getX() + adjustment, normalForFace.getY() + adjustment, normalForFace.getZ() + adjustment);
|
|
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();
|
|
}
|
|
} |