wall scrolls don't look like they were drawn with tank treads anymore
This commit is contained in:
parent
9a276c70de
commit
a43ead40d6
2 changed files with 111 additions and 56 deletions
|
@ -46,7 +46,7 @@ fun getNoise(x: Double, y: Double, z: Double): Double =
|
|||
NOISE.getValue(x * 0.6, y * 0.6, z * 0.6) / 2.0
|
||||
|
||||
// how many degrees are between each triangle on the smooth caps of the lines
|
||||
const val CAP_THETA = 180f / 5f
|
||||
const val CAP_THETA = 180f / 10f
|
||||
const val DEFAULT_READABILITY_OFFSET = 0.2f
|
||||
const val DEFAULT_LAST_SEGMENT_LEN_PROP = 0.8f
|
||||
|
||||
|
@ -121,24 +121,24 @@ fun drawLineSeq(
|
|||
// Draw the line segment as a hexagon, sort of
|
||||
// I can't imagine what the hell alwinfy is up to but this is implementing what TRIANGLE_FAN does
|
||||
// using normal triangles so we can send the entire segment to the buffer at once
|
||||
val p1Up = p1.add(tangent.scale(Math.max(0f, jlow))).add(normal)
|
||||
val p1Down = p1.add(tangent.scale(Math.max(0f, -jlow))).add(normal.negated())
|
||||
val p1Down = p1.add(tangent.scale(Math.max(0f, jlow))).add(normal)
|
||||
val p1Up = p1.add(tangent.scale(Math.max(0f, -jlow))).add(normal.negated())
|
||||
val p2Down = p2.add(tangent.scale(Math.max(0f, jhigh)).negated()).add(normal)
|
||||
val p2Up = p2.add(tangent.scale(Math.max(0f, -jhigh)).negated()).add(normal.negated())
|
||||
|
||||
vertex(color1, p1Up)
|
||||
vertex(color1, p1Down)
|
||||
vertex(color1, p1)
|
||||
vertex(color1, p1Down)
|
||||
|
||||
vertex(color1, p1Up)
|
||||
|
||||
vertex(color1, p1Down)
|
||||
vertex(color1, p1Up)
|
||||
vertex(color2, p2Up)
|
||||
|
||||
vertex(color1, p1Up)
|
||||
vertex(color1, p1Down)
|
||||
vertex(color2, p2Up)
|
||||
vertex(color2, p2)
|
||||
|
||||
vertex(color1, p1Up)
|
||||
vertex(color1, p1Down)
|
||||
vertex(color2, p2)
|
||||
vertex(color2, p2Down)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.client.entity;
|
||||
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.common.entities.EntityWallScroll;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
@ -166,66 +167,120 @@ public class WallScrollRenderer extends EntityRenderer<EntityWallScroll> {
|
|||
.endVertex();
|
||||
}
|
||||
|
||||
private static void vertexCol(Matrix4f mat, Matrix3f normal, int light, VertexConsumer verts, int col, float x,
|
||||
float y) {
|
||||
verts.vertex(mat, -x, y, 0)
|
||||
private static void vertexCol(Matrix4f mat, Matrix3f normal, int light, VertexConsumer verts, int col, Vec2 pos) {
|
||||
verts.vertex(mat, -pos.x, pos.y, 0)
|
||||
.color(col)
|
||||
.uv(0, 0).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(light)
|
||||
.normal(normal, 0, 0, 1)
|
||||
.endVertex();
|
||||
}
|
||||
|
||||
private static void theCoolerDrawLineSeq(Matrix4f mat, Matrix3f normal, int light, VertexConsumer verts,
|
||||
private static void theCoolerDrawLineSeq(Matrix4f mat, Matrix3f normalMat, int light, VertexConsumer verts,
|
||||
List<Vec2> points, float width, int color
|
||||
) {
|
||||
if (points.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
float prevXHi, prevYHi, prevXLo, prevYLo;
|
||||
{
|
||||
var p1 = points.get(0);
|
||||
var p2 = points.get(1);
|
||||
|
||||
var dx = p2.x - p1.x;
|
||||
var dy = p2.y - p1.y;
|
||||
var nx = -dy;
|
||||
var ny = dx;
|
||||
var tlen = Mth.sqrt(nx * nx + ny * ny) / (width * 0.5f);
|
||||
var tx = nx / tlen;
|
||||
var ty = ny / tlen;
|
||||
|
||||
prevXHi = p1.x - tx;
|
||||
prevYHi = p1.y - ty;
|
||||
prevXLo = p1.x + tx;
|
||||
prevYLo = p1.y + ty;
|
||||
// TODO: abstract some of this out with RenderLib to stop WET code
|
||||
var joinAngles = new float[points.size()];
|
||||
var joinOffsets = new float[points.size()];
|
||||
for (int i = 2; i < points.size(); i++) {
|
||||
var p0 = points.get(i - 2);
|
||||
var p1 = points.get(i - 1);
|
||||
var p2 = points.get(i);
|
||||
var prev = p1.add(p0.negated());
|
||||
var next = p2.add(p1.negated());
|
||||
var angle = (float) Mth.atan2(
|
||||
prev.x * next.y - prev.y * next.x,
|
||||
prev.x * next.x + prev.y * next.y);
|
||||
joinAngles[i - 1] = angle;
|
||||
var clamp = Math.min(prev.length(), next.length()) / (width * 0.5f);
|
||||
joinOffsets[i - 1] = Mth.clamp(Mth.sin(angle) / (1 + Mth.cos(angle)), -clamp, clamp);
|
||||
}
|
||||
|
||||
for (var i = 0; i < points.size() - 1; i++) {
|
||||
var p1 = points.get(i);
|
||||
var p2 = points.get(i + 1);
|
||||
|
||||
var dx = p2.x - p1.x;
|
||||
var dy = p2.y - p1.y;
|
||||
var nx = -dy;
|
||||
var ny = dx;
|
||||
var tlen = Mth.sqrt(nx * nx + ny * ny) / (width * 0.5f);
|
||||
var tx = nx / tlen;
|
||||
var ty = ny / tlen;
|
||||
var tangent = p2.add(p1.negated()).normalized().scale(width * 0.5f);
|
||||
var normal = new Vec2(-tangent.y, tangent.x);
|
||||
|
||||
var xHi = p2.x - tx;
|
||||
var yHi = p2.y - ty;
|
||||
var xLo = p2.x + tx;
|
||||
var yLo = p2.y + ty;
|
||||
vertexCol(mat, normal, light, verts, color, prevXHi, prevYHi);
|
||||
vertexCol(mat, normal, light, verts, color, prevXLo, prevYLo);
|
||||
vertexCol(mat, normal, light, verts, color, xLo, yLo);
|
||||
vertexCol(mat, normal, light, verts, color, xHi, yHi);
|
||||
var jlow = joinOffsets[i];
|
||||
var jhigh = joinOffsets[i + 1];
|
||||
|
||||
prevXHi = xHi;
|
||||
prevYHi = yHi;
|
||||
prevXLo = xLo;
|
||||
prevYLo = yLo;
|
||||
var p1Down = p1.add(tangent.scale(Math.max(0f, jlow))).add(normal);
|
||||
var p1Up = p1.add(tangent.scale(Math.max(0f, -jlow))).add(normal.negated());
|
||||
var p2Down = p2.add(tangent.scale(Math.max(0f, jhigh)).negated()).add(normal);
|
||||
var p2Up = p2.add(tangent.scale(Math.max(0f, -jhigh)).negated()).add(normal.negated());
|
||||
|
||||
// Draw the chamfer hexagon as two trapezoids
|
||||
// the points are in different orders to keep clockwise
|
||||
vertexCol(mat, normalMat, light, verts, color, p1);
|
||||
vertexCol(mat, normalMat, light, verts, color, p2);
|
||||
vertexCol(mat, normalMat, light, verts, color, p2Up);
|
||||
vertexCol(mat, normalMat, light, verts, color, p1Up);
|
||||
|
||||
vertexCol(mat, normalMat, light, verts, color, p1);
|
||||
vertexCol(mat, normalMat, light, verts, color, p1Down);
|
||||
vertexCol(mat, normalMat, light, verts, color, p2Down);
|
||||
vertexCol(mat, normalMat, light, verts, color, p2);
|
||||
|
||||
if (i > 0) {
|
||||
var sangle = joinAngles[i];
|
||||
var angle = Math.abs(sangle);
|
||||
var rnormal = normal.negated();
|
||||
var joinSteps = Mth.ceil(angle * 180 / (RenderLib.CAP_THETA * Mth.PI));
|
||||
if (joinSteps < 1) continue;
|
||||
|
||||
if (sangle < 0) {
|
||||
var prevVert = new Vec2(p1.x - rnormal.x, p1.y - rnormal.y);
|
||||
for (var j = 1; j <= joinSteps; j++) {
|
||||
var fan = RenderLib.rotate(rnormal, -sangle * ((float) j / joinSteps));
|
||||
var fanShift = new Vec2(p1.x - fan.x, p1.y - fan.y);
|
||||
|
||||
vertexCol(mat, normalMat, light, verts, color, p1);
|
||||
vertexCol(mat, normalMat, light, verts, color, p1);
|
||||
vertexCol(mat, normalMat, light, verts, color, fanShift);
|
||||
vertexCol(mat, normalMat, light, verts, color, prevVert);
|
||||
prevVert = fanShift;
|
||||
}
|
||||
} else {
|
||||
var startFan = RenderLib.rotate(normal, -sangle);
|
||||
var prevVert = new Vec2(p1.x - startFan.x, p1.y - startFan.y);
|
||||
for (var j = joinSteps - 1; j >= 0; j--) {
|
||||
var fan = RenderLib.rotate(normal, -sangle * ((float) j / joinSteps));
|
||||
var fanShift = new Vec2(p1.x - fan.x, p1.y - fan.y);
|
||||
|
||||
vertexCol(mat, normalMat, light, verts, color, p1);
|
||||
vertexCol(mat, normalMat, light, verts, color, p1);
|
||||
vertexCol(mat, normalMat, light, verts, color, fanShift);
|
||||
vertexCol(mat, normalMat, light, verts, color, prevVert);
|
||||
prevVert = fanShift;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var pair : new Vec2[][]{
|
||||
{points.get(0), points.get(1)},
|
||||
{points.get(points.size() - 1), points.get(points.size() - 2)}
|
||||
}) {
|
||||
var point = pair[0];
|
||||
var prev = pair[1];
|
||||
|
||||
var tangent = point.add(prev.negated()).normalized().scale(0.5f * width);
|
||||
var normal = new Vec2(-tangent.y, tangent.x);
|
||||
var joinSteps = Mth.ceil(180f / RenderLib.CAP_THETA);
|
||||
for (int j = joinSteps; j > 0; j--) {
|
||||
var fan0 = RenderLib.rotate(normal, -Mth.PI * ((float) j / joinSteps));
|
||||
var fan1 = RenderLib.rotate(normal, -Mth.PI * ((float) (j - 1) / joinSteps));
|
||||
|
||||
vertexCol(mat, normalMat, light, verts, color, point);
|
||||
vertexCol(mat, normalMat, light, verts, color, point);
|
||||
vertexCol(mat, normalMat, light, verts, color, point.add(fan1));
|
||||
vertexCol(mat, normalMat, light, verts, color, point.add(fan0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,13 +290,13 @@ public class WallScrollRenderer extends EntityRenderer<EntityWallScroll> {
|
|||
for (int i = 0; i < fracOfCircle; i++) {
|
||||
// We do need rects, irritatingly
|
||||
// so we do fake triangles
|
||||
vertexCol(mat, normal, light, verts, color, point.x, point.y);
|
||||
vertexCol(mat, normal, light, verts, color, point.x, point.y);
|
||||
vertexCol(mat, normal, light, verts, color, point);
|
||||
vertexCol(mat, normal, light, verts, color, point);
|
||||
for (int j = 0; j <= 1; j++) {
|
||||
var theta = (i - j) / (float) fracOfCircle * Mth.TWO_PI;
|
||||
var rx = Mth.cos(theta) * radius + point.x;
|
||||
var ry = Mth.sin(theta) * radius + point.y;
|
||||
vertexCol(mat, normal, light, verts, color, rx, ry);
|
||||
vertexCol(mat, normal, light, verts, color, new Vec2(rx, ry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue