added curves

This commit is contained in:
2024-11-17 12:56:00 +01:00
parent e6c2858bb6
commit f9212345f7
3 changed files with 57 additions and 23 deletions
@@ -156,3 +156,23 @@ fun transformOffsetByScale(offset: Vector3f, scale: Vector3f): Vector3f {
fun lerp(x: Float, y: Float, t: Float) : Float {
return x + (y - x) * t
}
fun interpolateCurve(curve: Array<Vector3f>, t: Float): Vector3f {
if (curve.size < 2) { return curve[0] }
val clampedT = t.coerceIn(0.0f, 1.0f)
val scaledT = clampedT * (curve.size - 1)
val segmentIndex = scaledT.toInt()
val segmentT = scaledT - segmentIndex
val start = curve[segmentIndex]
val end = curve[(segmentIndex + 1).coerceAtMost(curve.size - 1)] // Ensure bounds
return Vector3f(
start.x + (end.x - start.x) * segmentT,
start.y + (end.y - start.y) * segmentT,
start.z + (end.z - start.z) * segmentT
)
}
@@ -18,8 +18,8 @@ class Particle(private val particleParams: ParticleParams) {
private var rot = randomBetweenVector3f(particleParams.rotRandom.first, particleParams.rotRandom.second)
private val rotVel = randomBetweenVector3f(particleParams.rotVelRandom.first, particleParams.rotVelRandom.second)
private val scale = randomBetweenVector3f(particleParams.sizeRandom.first, particleParams.sizeRandom.second)
private var vel = randomBetweenVector3f(particleParams.velRandom.first, particleParams.velRandom.second)
private var scale = randomBetweenVector3f(particleParams.sizeRandom.first, particleParams.sizeRandom.second)
private var blockDisplay: DisplayEntity? = null
@@ -32,6 +32,13 @@ class Particle(private val particleParams: ParticleParams) {
fun init(pos: Vec3d) {
this.pos = pos
if ( particleParams.uniformSize ) {
val randomUniform = randomFloatBetween(particleParams.sizeRandom.first.x, particleParams.sizeRandom.second.x)
scale.x = randomUniform
scale.y = randomUniform
scale.z = randomUniform
}
val (quatRot, newOffset) = calcTransformOffset(rot, initOffset, scale)
val properties = DisplayEntityProperties(
@@ -81,23 +88,20 @@ class Particle(private val particleParams: ParticleParams) {
}
// TODO: rotVelRandom, rotVelCurve, sizeCurve, forceFields
// TODO: forceFields, shape
private fun calcNewProperties() : DisplayEntityProperties {
fun calcBlockCurve() : String {
val newBlockIdx = round(
lerp(
0.0f,
particleParams.blockCurve.lastIndex.toFloat(),
(timeAlive.toFloat() / particleParams.lifeTime.toFloat()).coerceIn(0.0f, 1.0f)
)
).toInt()
fun calcBlockCurve(timeAliveClamped: Float) : String {
val newBlockIdx = round(lerp(0.0f, particleParams.blockCurve.lastIndex.toFloat(), timeAliveClamped)).toInt()
return particleParams.blockCurve[newBlockIdx]
}
fun calcRot() : Vector3f {
fun calcRot(timeAliveClamped: Float) : Vector3f {
val newRot = Vector3f(rot)
newRot.add(rotVel)
val newVel = Vector3f(rotVel)
newVel.mul(interpolateCurve(particleParams.sizeCurve, timeAliveClamped))
newRot.add(newVel)
return newRot
}
@@ -115,17 +119,24 @@ class Particle(private val particleParams: ParticleParams) {
return Pair(vel, newOffset)
}
fun calcSize(timeAliveClamped: Float) : Vector3f {
val scale = Vector3f(scale)
scale.mul(interpolateCurve(particleParams.sizeCurve, timeAliveClamped))
return scale
}
val timeAliveClamped = (timeAlive.toFloat() / particleParams.lifeTime.toFloat()).coerceIn(0.0f, 1.0f)
val newBlock = calcBlockCurve()
val newBlock = calcBlockCurve(timeAliveClamped)
val (newVel, newOffset) = calcOffset()
val newRot = calcRot()
val newRot = calcRot(timeAliveClamped)
val newScale = calcSize(timeAliveClamped)
vel = newVel
offset = newOffset
rot = newRot
val (quatRot, transformOffset) = calcTransformOffset(newRot, initOffset, scale /* newScale */)
val (quatRot, transformOffset) = calcTransformOffset(newRot, initOffset, newScale)
val combinedOffset = transformOffset.add(newOffset)
val newProperties = DisplayEntityProperties(
@@ -133,7 +144,7 @@ class Particle(private val particleParams: ParticleParams) {
blockType = newBlock,
translation = combinedOffset,
leftRotation = quatRot,
scale = scale, //fix
scale = newScale,
tags = arrayOf("BPS_Particle")
)
@@ -2,21 +2,24 @@ package com.bytedice.bde_particles.particle
import org.joml.Vector3f
// sizeRandom: set y and z on both vectors to -1 for uniform scale // not implemented
// TODO: order these correctly, explain all
// sizeRandom: if uniformSize is true then sizeRandom will be uniform (cubic) and the values are taken from X
// lifeTime: any value below 1 will result in a particle not spawning
// minVel values 0 or less mean the particle can travel however slow it wants
// minVel: values 0 or less mean the particle can travel however slow it wants
// gravity: Y being -0.025 is close to regular gravity
data class ParticleParams (
//val shape: Shape, // add later, start with single point
val blockCurve: Array<String> = arrayOf("minecraft:purple_concrete", "minecraft:purple_stained_glass"),
val blockCurve: Array<String> = arrayOf("minecraft:shroomlight", "minecraft:orange_concrete", "minecraft:orange_stained_glass", "minecraft:gray_stained_glass", "minecraft:light_gray_stained_glass"),
val rotRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(0.0f, 0.0f, 0.0f), Vector3f(360.0f, 360.0f, 360.0f)),
val rotVelRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(-0.2f, -0.2f, -0.2f), Vector3f(0.2f, 0.2f, 0.2f)),
val rotVelCurve: Array<Vector3f> = arrayOf(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(0.0f, 0.0f, 0.0f)),
val sizeRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(0.5f, 0.5f, 0.5f), Vector3f(1.0f, 1.0f, 1.0f)),
val sizeCurve: Array<Vector3f> = arrayOf(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(0.0f, 0.0f, 0.0f)),
val velRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(-0.3f, 0.3f, -0.3f), Vector3f(0.3f, 0.6f, 0.3f)),
val uniformSize: Boolean = true,
val sizeCurve: Array<Vector3f> = arrayOf(Vector3f(1.0f, 1.0f, 1.0f), Vector3f(0.5f, 0.5f, 0.5f)),
val velRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(-0.1f, 0.4f, -0.1f), Vector3f(0.1f, 0.8f, 0.1f)),
val forceFields: ForceField = ForceField(),
val gravity: Vector3f = Vector3f(0.0f, -0.025f, 0.0f),
val gravity: Vector3f = Vector3f(0.0f, -0.01f, 0.0f),
val drag: Float = 0.075f,
val minVel: Float = 0.0f,
val lifeTime: Int = 20
val lifeTime: Int = 30
)