Render intersections with some buffer space
This commit is contained in:
parent
6b2c3cd5bb
commit
f15c975d8a
7 changed files with 94 additions and 47 deletions
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue