Render intersections with some buffer space

This commit is contained in:
Alwinfy 2022-11-07 13:24:37 -05:00 committed by gamma-delta
parent 6b2c3cd5bb
commit f15c975d8a
7 changed files with 94 additions and 47 deletions

View file

@ -45,6 +45,7 @@ import kotlin.math.sin
val NOISE: PerlinNoise = PerlinNoise.create(XoroshiroRandomSource(9001L), listOf(0, 1, 2, 3, 4))
val CAP_THETA: Float = 18f
val READABILITY_OFFSET: Float = 0.2f
/**
* Draw a sequence of linePoints spanning the given points.
@ -199,13 +200,14 @@ fun rotate(vec: Vec2, theta: Float): Vec2 {
fun drawPatternFromPoints(
mat: Matrix4f,
points: List<Vec2>,
dupIndices: Set<Int>?,
drawLast: Boolean,
tail: Int,
head: Int,
flowIrregular: Float,
animTime: Float? = null
) {
val zappyPts = makeZappy(points, 10f, 2.5f, 0.1f, flowIrregular)
val zappyPts = makeZappy(points, dupIndices, 10f, 2.5f, 0.1f, flowIrregular)
val nodes = if (drawLast) {
points
} else {
@ -226,58 +228,99 @@ fun drawPatternFromPoints(
}
}
fun makeZappy(points: List<Vec2>, hops: Float, variance: Float, speed: Float, flowIrregular: Float) =
makeZappy(points, hops.toInt(), variance, speed, flowIrregular)
fun makeZappy(points: List<Vec2>, dupIndices: Set<Int>?, hops: Float, variance: Float, speed: Float, flowIrregular: Float) =
makeZappy(points, dupIndices, hops.toInt(), variance, speed, flowIrregular)
/**
* Split up a sequence of linePoints with a lightning effect
* @param hops: rough number of points to subdivide each segment into
* @param speed: rate at which the lightning effect should move/shake/etc
*/
fun makeZappy(points: List<Vec2>, hops: Int, variance: Float, speed: Float, flowIrregular: Float): List<Vec2> {
fun makeZappy(barePoints: List<Vec2>, dupIndices: Set<Int>?, hops: Int, variance: Float, speed: Float, flowIrregular: Float): List<Vec2> {
// Nothing in, nothing out
if (points.isEmpty()) {
if (barePoints.isEmpty()) {
return emptyList()
}
val scaleVariance = { it: Double -> 1.0.coerceAtMost(8 * (0.5 - abs(0.5 - it))) }
val zSeed = ClientTickCounter.getTotal().toDouble() * speed
// Create our output list of zap points
val zappyPts = mutableListOf(points[0])
// For each segment in the original...
for ((i, pair) in points.zipWithNext().withIndex()) {
val (src, target) = pair
val delta = target.add(src.negated())
// Take hop distance
val hopDist = Mth.sqrt(src.distanceToSqr(target)) / hops
// Compute how big the radius of variance should be
val maxVariance = hopDist * variance
fun zappify(points: List<Vec2>): List<Vec2> {
val scaleVariance = { it: Double -> 1.0.coerceAtMost(8 * (0.5 - abs(0.5 - it))) }
val zSeed = ClientTickCounter.getTotal().toDouble() * speed
// Create our output list of zap points
val zappyPts = mutableListOf(points[0])
// For each segment in the original...
for ((i, pair) in points.zipWithNext().withIndex()) {
val (src, target) = pair
val delta = target.add(src.negated())
// Take hop distance
val hopDist = Mth.sqrt(src.distanceToSqr(target)) / hops
// Compute how big the radius of variance should be
val maxVariance = hopDist * variance
for (j in 1..hops) {
val progress = j.toDouble() / (hops + 1)
// Add the next hop...
val pos = src.add(delta.scale(progress.toFloat()))
// as well as some random variance...
// (We use i, j (segment #, subsegment #) as seeds for the Perlin noise,
// and zSeed (i.e. time elapsed) to perturb the shape gradually over time)
val minorPerturb = NOISE.getValue(i.toDouble(), j.toDouble(), sin(zSeed)) * flowIrregular
val theta = (3 * NOISE.getValue(
i.toDouble() + j.toDouble() / (hops + 1) + minorPerturb - zSeed,
1337.0,
0.0
) * TAU).toFloat()
val r = (NOISE.getValue(
i.toDouble() + j.toDouble() / (hops + 1) - zSeed,
69420.0,
0.0
) * maxVariance * scaleVariance(progress)).toFloat()
val randomHop = Vec2(r * Mth.cos(theta), r * Mth.sin(theta))
// Then record the new location.
zappyPts.add(pos.add(randomHop))
for (j in 1..hops) {
val progress = j.toDouble() / (hops + 1)
// Add the next hop...
val pos = src.add(delta.scale(progress.toFloat()))
// as well as some random variance...
// (We use i, j (segment #, subsegment #) as seeds for the Perlin noise,
// and zSeed (i.e. time elapsed) to perturb the shape gradually over time)
val minorPerturb = NOISE.getValue(i.toDouble(), j.toDouble(), sin(zSeed)) * flowIrregular
val theta = (3 * NOISE.getValue(
i.toDouble() + j.toDouble() / (hops + 1) + minorPerturb - zSeed,
1337.0,
0.0
) * TAU).toFloat()
val r = (NOISE.getValue(
i.toDouble() + j.toDouble() / (hops + 1) - zSeed,
69420.0,
0.0
) * maxVariance * scaleVariance(progress)).toFloat()
val randomHop = Vec2(r * Mth.cos(theta), r * Mth.sin(theta))
// Then record the new location.
zappyPts.add(pos.add(randomHop))
}
// Finally, we hit the destination, add that too
zappyPts.add(target)
}
// Finally, we hit the destination, add that too
zappyPts.add(target)
return zappyPts
}
return zappyPts
val points = mutableListOf<Vec2>()
val daisyChain = mutableListOf<Vec2>()
return if (dupIndices != null) {
for ((i, pair) in barePoints.zipWithNext().withIndex()) {
val (head, tail) = pair
val tangent = tail.add(head.negated()).scale(READABILITY_OFFSET)
if (i != 0 && dupIndices.contains(i)) {
daisyChain.add(head.add(tangent))
} else {
daisyChain.add(head)
}
if (i == barePoints.size - 2) {
daisyChain.add(tail)
points.addAll(zappify(daisyChain))
} else if (dupIndices.contains(i + 1)) {
daisyChain.add(tail.add(tangent.negated()))
points.addAll(zappify(daisyChain))
daisyChain.clear()
}
}
points
} else {
zappify(barePoints)
}
}
fun<T> findDupIndices(pts: Iterable<T>): Set<Int> {
val dedup = HashMap<T, Int>()
val found = HashSet<Int>()
for ((i, pt) in pts.withIndex()) {
val ix = dedup[pt]
if (ix != null) {
found.add(i)
found.add(ix)
} else {
dedup.put(pt, i)
}
}
return found
}
/**

View file

@ -73,7 +73,7 @@ public class BlockEntityAkashicBookshelfRenderer implements BlockEntityRenderer<
lines2.set(j, new Vec2(-v.x, v.y));
}
var zappy = RenderLib.makeZappy(lines2, 10f, 0.5f, 0f, 0f);
var zappy = RenderLib.makeZappy(lines2, RenderLib.findDupIndices(pattern.positions()), 10f, 0.5f, 0f, 0f);
int outer = 0xff_d2c8c8;
int inner = 0xc8_322b33;

View file

@ -84,7 +84,7 @@ public class BlockEntitySlateRenderer implements BlockEntityRenderer<BlockEntity
}
var isLit = bs.getValue(BlockSlate.ENERGIZED);
var zappy = RenderLib.makeZappy(lines2, 10f, isLit ? 2.5f : 0.5f, isLit ? 0.1f : 0f, 0.2f);
var zappy = RenderLib.makeZappy(lines2, RenderLib.findDupIndices(tile.pattern.positions()), 10f, isLit ? 2.5f : 0.5f, isLit ? 0.1f : 0f, 0.2f);
int outer = isLit ? 0xff_64c8ff : 0xff_d2c8c8;
int inner = isLit ? RenderLib.screenCol(outer) : 0xc8_322b33;

View file

@ -298,6 +298,7 @@ class GuiSpellcasting constructor(
super.onClose()
}
override fun render(ps: PoseStack, pMouseX: Int, pMouseY: Int, pPartialTick: Float) {
super.render(ps, pMouseX, pMouseY, pPartialTick)
@ -347,6 +348,7 @@ class GuiSpellcasting constructor(
this.hexSize(),
this.coordToPx(origin)
),
findDupIndices(pat.positions()),
true,
valid.color or (0xC8 shl 24),
valid.fadeColor or (0xC8 shl 24),
@ -357,12 +359,14 @@ class GuiSpellcasting constructor(
// Now draw the currently WIP pattern
if (this.drawState !is PatternDrawState.BetweenPatterns) {
val points = mutableListOf<Vec2>()
var dupIndices: Set<Int>? = null
if (this.drawState is PatternDrawState.JustStarted) {
val ds = this.drawState as PatternDrawState.JustStarted
points.add(this.coordToPx(ds.start))
} else if (this.drawState is PatternDrawState.Drawing) {
val ds = this.drawState as PatternDrawState.Drawing
dupIndices = findDupIndices(ds.wipPattern.positions())
for (pos in ds.wipPattern.positions()) {
val pix = this.coordToPx(pos + ds.start)
points.add(pix)
@ -370,7 +374,7 @@ class GuiSpellcasting constructor(
}
points.add(mousePos)
drawPatternFromPoints(mat, points, false, 0xff_64c8ff_u.toInt(), 0xff_fecbe6_u.toInt(), 0.1f)
drawPatternFromPoints(mat, points, dupIndices, false, 0xff_64c8ff_u.toInt(), 0xff_fecbe6_u.toInt(), 0.1f)
}
RenderSystem.enableDepthTest()

View file

@ -45,7 +45,7 @@ public class PatternTooltipComponent implements ClientTooltipComponent {
var pair = RenderLib.getCenteredPattern(pattern, SIZE, SIZE, 8f);
this.scale = pair.getFirst();
var dots = pair.getSecond();
this.zappyPoints = RenderLib.makeZappy(dots, 10f, 0.8f, 0f, 0f);
this.zappyPoints = RenderLib.makeZappy(dots, RenderLib.findDupIndices(pattern.positions()), 10f, 0.8f, 0f, 0f);
this.pathfinderDots = dots.stream().distinct().collect(Collectors.toList());
}

View file

@ -71,7 +71,7 @@ public class EntityWallScroll extends HangingEntity {
var pair = RenderLib.getCenteredPattern(pattern, 128f / 3 * blockSize, 128f / 3 * blockSize,
16f / 3 * blockSize);
var dots = pair.getSecond();
this.zappyPoints = RenderLib.makeZappy(dots, 10f, 0.8f, 0f, 0f);
this.zappyPoints = RenderLib.makeZappy(dots, RenderLib.findDupIndices(pattern.positions()), 10f, 0.8f, 0f, 0f);
}
this.isAncient = NBTHelper.hasString(scroll, ItemScroll.TAG_OP_ID);

View file

@ -108,7 +108,7 @@ public final class PatternDrawingUtil {
for (var pat : patternEntries) {
var localOrigin = HexUtils.coordToPx(pat.origin(), hexSize, realCom.negated());
var points = pat.pattern().toLines(hexSize, localOrigin);
pat.zappyPoints().addAll(RenderLib.makeZappy(points, 10f, 0.8f, 0f, 0f));
pat.zappyPoints().addAll(RenderLib.makeZappy(points, RenderLib.findDupIndices(pat.pattern().positions()), 10f, 0.8f, 0f, 0f));
}
var pathfinderDots = seenCoords.stream()