added new parameters

This commit is contained in:
2024-12-23 16:03:13 +01:00
parent 22027610ea
commit fdea77092b
5 changed files with 176 additions and 41 deletions
@@ -52,6 +52,9 @@ import kotlin.reflect.full.declaredMemberProperties
// Copying particle params in-game. // Copying particle params in-game.
// Custom curve equation command args (parse from strings). // Custom curve equation command args (parse from strings).
// Force field "config" option. // Force field "config" option.
// TODO: (now)
// add lerpValInt to commands
// Better particle debug tools. // Better particle debug tools.
// Use more BDEs instead of particles, and show more values than origin and velocity. // Use more BDEs instead of particles, and show more values than origin and velocity.
@@ -103,12 +103,15 @@ fun parseArgTypeToFunc(type: KType, configArg: LiteralArgumentBuilder<ServerComm
ParamClasses.StringCurve::class -> { access, config, reg -> ParamClasses.StringCurve::class -> { access, config, reg ->
stringCurveArg(access as KProperty1<EmitterParams, ParamClasses.StringCurve>, config, reg) stringCurveArg(access as KProperty1<EmitterParams, ParamClasses.StringCurve>, config, reg)
} }
ParamClasses.LerpVal::class -> { access, config, _ -> ParamClasses.LerpValVec3f::class -> { access, config, _ ->
lerpValArg(access as KProperty1<EmitterParams, ParamClasses.LerpVal>, config) lerpValVec3fArg(access as KProperty1<EmitterParams, ParamClasses.LerpValVec3f>, config)
} }
ParamClasses.ForceFieldArray::class -> { access, config, _ -> ParamClasses.ForceFieldArray::class -> { access, config, _ ->
forceFieldArg(access as KProperty1<EmitterParams, ParamClasses.ForceFieldArray>, config) forceFieldArg(access as KProperty1<EmitterParams, ParamClasses.ForceFieldArray>, config)
} }
ParamClasses.LerpValInt::class -> { access, config, _ ->
lerpValIntArg(access as KProperty1<EmitterParams, ParamClasses.LerpValInt>, config)
}
else -> null else -> null
} }
} }
@@ -550,8 +553,8 @@ fun stringCurveRemoveArg(context: CommandContext<ServerCommandSource>,
successText(access, "--$item", id, context) successText(access, "--$item", id, context)
} }
fun lerpValArg(access: KProperty1<EmitterParams,ParamClasses.LerpVal>, fun lerpValVec3fArg(access: KProperty1<EmitterParams,ParamClasses.LerpValVec3f>,
configArg: LiteralArgumentBuilder<ServerCommandSource> configArg: LiteralArgumentBuilder<ServerCommandSource>
) : LiteralArgumentBuilder<ServerCommandSource> ) : LiteralArgumentBuilder<ServerCommandSource>
{ {
return configArg return configArg
@@ -575,7 +578,7 @@ fun lerpValArg(access: KProperty1<EmitterParams,ParamClasses.LerpVal>,
val curve = stringToCurve(curveName) val curve = stringToCurve(curveName)
updateParam(id, access, ParamClasses.LerpVal.LerpVec3f(minX, minY, minZ, maxX, maxY, maxZ, curve!!)) updateParam(id, access, ParamClasses.LerpValVec3f.LerpVec3f(minX, minY, minZ, maxX, maxY, maxZ, curve!!))
successText(access, "LerpVec3f", id, context) successText(access, "LerpVec3f", id, context)
Command.SINGLE_SUCCESS Command.SINGLE_SUCCESS
@@ -614,7 +617,7 @@ fun lerpValArg(access: KProperty1<EmitterParams,ParamClasses.LerpVal>,
val curveY = stringToCurve(curveNameY) val curveY = stringToCurve(curveNameY)
val curveZ = stringToCurve(curveNameZ) val curveZ = stringToCurve(curveNameZ)
updateParam(id, access, ParamClasses.LerpVal.MultiLerpVec3f(minX, minY, minZ, maxX, maxY, maxZ, curveX!!, curveY!!, curveZ!!)) updateParam(id, access, ParamClasses.LerpValVec3f.MultiLerpVec3f(minX, minY, minZ, maxX, maxY, maxZ, curveX!!, curveY!!, curveZ!!))
successText(access, "MultiLerpVec3f", id, context) successText(access, "MultiLerpVec3f", id, context)
Command.SINGLE_SUCCESS Command.SINGLE_SUCCESS
@@ -629,11 +632,51 @@ fun lerpValArg(access: KProperty1<EmitterParams,ParamClasses.LerpVal>,
) )
) )
) )
.then(CommandManager.literal("LerpUniform")
.then(CommandManager.argument("Min", FloatArgumentType.floatArg())
.then(CommandManager.argument("Max", FloatArgumentType.floatArg())
.then(curveListArg("Curve")
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
val min = FloatArgumentType.getFloat(context, "Min")
val max = FloatArgumentType.getFloat(context, "Max")
val curveName = StringArgumentType.getString(context, "Curve")
val curve = stringToCurve(curveName)
updateParam(id, access, ParamClasses.LerpValVec3f.LerpUniform(min, max, curve!!))
successText(access, "LerpUniform", id, context)
Command.SINGLE_SUCCESS
}
)
)
)
)
.then(CommandManager.literal("Constant")
.then(CommandManager.argument("X", FloatArgumentType.floatArg())
.then(CommandManager.argument("Y", FloatArgumentType.floatArg())
.then(CommandManager.argument("Z", FloatArgumentType.floatArg())
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
val x = FloatArgumentType.getFloat(context, "X")
val y = FloatArgumentType.getFloat(context, "Y")
val z = FloatArgumentType.getFloat(context, "Z")
updateParam(id, access, ParamClasses.LerpValVec3f.Constant(Vector3f(x, y, z)))
successText(access, "Constant", id, context)
Command.SINGLE_SUCCESS
}
)
)
)
)
.then(CommandManager.literal("Null") .then(CommandManager.literal("Null")
.executes { context -> .executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID") val id = StringArgumentType.getString(context, "Emitter ID")
updateParam(id, access, ParamClasses.LerpVal.Null) updateParam(id, access, ParamClasses.LerpValVec3f.Null)
successText(access, "Null", id, context) successText(access, "Null", id, context)
Command.SINGLE_SUCCESS Command.SINGLE_SUCCESS
@@ -777,4 +820,55 @@ fun forceFieldRemoveArg(context: CommandContext<ServerCommandSource>,
val calcIndex = if (index == -1) { forceFields.array.size } else { index.coerceIn(0, forceFields.array.size) } val calcIndex = if (index == -1) { forceFields.array.size } else { index.coerceIn(0, forceFields.array.size) }
successText(access, "--ForceField at $calcIndex", id, context) successText(access, "--ForceField at $calcIndex", id, context)
}
fun lerpValIntArg(access: KProperty1<EmitterParams, ParamClasses.LerpValInt>,
configArg: LiteralArgumentBuilder<ServerCommandSource>
) : LiteralArgumentBuilder<ServerCommandSource>
{
return configArg
.then(CommandManager.literal("LerpInt")
.then(CommandManager.argument("Min", IntegerArgumentType.integer())
.then(CommandManager.argument("Max", IntegerArgumentType.integer())
.then(curveListArg("Curve")
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
val min = IntegerArgumentType.getInteger(context, "Min")
val max = IntegerArgumentType.getInteger(context, "Max")
val curveName = StringArgumentType.getString(context, "Curve")
val curve = stringToCurve(curveName)
updateParam(id, access, ParamClasses.LerpValInt.LerpInt(min, max, curve!!))
successText(access, "LerpInt", id, context)
Command.SINGLE_SUCCESS
}
)
)
)
)
.then(CommandManager.literal("Constant")
.then(CommandManager.argument("Value", IntegerArgumentType.integer())
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
val value = IntegerArgumentType.getInteger(context, "Value")
updateParam(id, access, ParamClasses.LerpValInt.Constant(value))
successText(access, "Constant", id, context)
Command.SINGLE_SUCCESS
}
)
)
.then(CommandManager.literal("Null")
.executes { context ->
val id = StringArgumentType.getString(context, "Emitter ID")
updateParam(id, access, ParamClasses.LerpValInt.Null)
successText(access, "Null", id, context)
Command.SINGLE_SUCCESS
}
)
} }
@@ -27,10 +27,11 @@ data class EmitterParams (
var drag: Float, var drag: Float,
var minVel: Float, var minVel: Float,
// curves // curves
var offsetCurve: ParamClasses.LerpVal, var offsetCurve: ParamClasses.LerpValVec3f,
var rotVelCurve: ParamClasses.LerpVal, var rotVelCurve: ParamClasses.LerpValVec3f,
var scaleCurve: ParamClasses.LerpVal, var scaleCurve: ParamClasses.LerpValVec3f,
var modelCurve: ParamClasses.StringCurve, var modelCurve: ParamClasses.StringCurve,
var brightnessCurve: ParamClasses.LerpValInt,
) )
{ {
companion object Presets { companion object Presets {
@@ -53,9 +54,9 @@ data class EmitterParams (
constVel = Vector3f(0.0f, 0.0f, 0.0f), constVel = Vector3f(0.0f, 0.0f, 0.0f),
drag = 0.075f, drag = 0.075f,
minVel = 0.0f, minVel = 0.0f,
offsetCurve = ParamClasses.LerpVal.Null, offsetCurve = ParamClasses.LerpValVec3f.Null,
rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Sqrt), rotVelCurve = ParamClasses.LerpValVec3f.LerpUniform(1.0f, 0.0f, LerpCurves.Sqrt),
scaleCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 2.5f, LerpCurves.Linear), scaleCurve = ParamClasses.LerpValVec3f.LerpUniform(1.0f, 2.5f, LerpCurves.Linear),
modelCurve = ParamClasses.StringCurve( modelCurve = ParamClasses.StringCurve(
arrayOf( arrayOf(
"shroomlight", "shroomlight",
@@ -66,7 +67,8 @@ data class EmitterParams (
"light_gray_stained_glass" "light_gray_stained_glass"
), ),
LerpCurves.Sqrt LerpCurves.Sqrt
) ),
brightnessCurve = ParamClasses.LerpValInt.LerpInt(15, 0, LerpCurves.Sqrt)
) )
val DEBUG = EmitterParams( val DEBUG = EmitterParams(
maxCount = 50, maxCount = 50,
@@ -87,9 +89,9 @@ data class EmitterParams (
constVel = Vector3f(0.0f, -0.05f, 0.0f), constVel = Vector3f(0.0f, -0.05f, 0.0f),
drag = 0.075f, drag = 0.075f,
minVel = 0.0f, minVel = 0.0f,
offsetCurve = ParamClasses.LerpVal.Null, offsetCurve = ParamClasses.LerpValVec3f.Null,
rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Linear), rotVelCurve = ParamClasses.LerpValVec3f.LerpUniform(1.0f, 0.0f, LerpCurves.Linear),
scaleCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 1.0f, LerpCurves.Linear), scaleCurve = ParamClasses.LerpValVec3f.LerpUniform(1.0f, 1.0f, LerpCurves.Linear),
modelCurve = ParamClasses.StringCurve( modelCurve = ParamClasses.StringCurve(
arrayOf( arrayOf(
"shroomlight", "shroomlight",
@@ -100,7 +102,8 @@ data class EmitterParams (
"light_gray_stained_glass" "light_gray_stained_glass"
), ),
LerpCurves.Linear LerpCurves.Linear
) ),
brightnessCurve = ParamClasses.LerpValInt.Null
) )
val STRESS_TEST = EmitterParams( val STRESS_TEST = EmitterParams(
maxCount = 10000, maxCount = 10000,
@@ -126,9 +129,9 @@ data class EmitterParams (
constVel = Vector3f(0.0f, 0.001f, 0.0f), constVel = Vector3f(0.0f, 0.001f, 0.0f),
drag = 0.075f, drag = 0.075f,
minVel = 0.0f, minVel = 0.0f,
offsetCurve = ParamClasses.LerpVal.Null, offsetCurve = ParamClasses.LerpValVec3f.Null,
rotVelCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 0.0f, LerpCurves.Linear), rotVelCurve = ParamClasses.LerpValVec3f.LerpUniform(1.0f, 0.0f, LerpCurves.Linear),
scaleCurve = ParamClasses.LerpVal.LerpUniform(1.0f, 1.5f, LerpCurves.Linear), scaleCurve = ParamClasses.LerpValVec3f.LerpUniform(1.0f, 1.5f, LerpCurves.Linear),
modelCurve = ParamClasses.StringCurve( modelCurve = ParamClasses.StringCurve(
arrayOf( arrayOf(
"shroomlight", "shroomlight",
@@ -139,7 +142,8 @@ data class EmitterParams (
"light_gray_stained_glass" "light_gray_stained_glass"
), ),
LerpCurves.Linear LerpCurves.Linear
) ),
brightnessCurve = ParamClasses.LerpValInt.Null
) )
} }
} }
@@ -38,19 +38,22 @@ class ParamClasses {
} }
data object Null : PairVec3f() data object Null : PairVec3f()
} }
class PairInt ( class PairInt (
private val min: Int, private val min: Int,
private val max: Int, private val max: Int,
) { ) {
fun randomize() : Int { return randomIntBetween(min, max) } fun randomize() : Int { return randomIntBetween(min, max) }
} }
class PairFloat( class PairFloat(
private val min: Float, private val min: Float,
private val max: Float, private val max: Float,
) { ) {
fun randomize() : Float { return randomFloatBetween(min, max) } fun randomize() : Float { return randomFloatBetween(min, max) }
} }
sealed class LerpVal {
sealed class LerpValVec3f {
class LerpVec3f( class LerpVec3f(
private val fromX: Float, private val fromX: Float,
private val fromY: Float, private val fromY: Float,
@@ -59,7 +62,7 @@ class ParamClasses {
private val toY: Float, private val toY: Float,
private val toZ: Float, private val toZ: Float,
private val curve: LerpCurves, private val curve: LerpCurves,
) : LerpVal() { ) : LerpValVec3f() {
fun lerp(t: Float): Vector3f { fun lerp(t: Float): Vector3f {
val x = com.bytedice.bde_particles.lerp(fromX, toX, curve.function(t)) val x = com.bytedice.bde_particles.lerp(fromX, toX, curve.function(t))
val y = com.bytedice.bde_particles.lerp(fromY, toY, curve.function(t)) val y = com.bytedice.bde_particles.lerp(fromY, toY, curve.function(t))
@@ -77,7 +80,7 @@ class ParamClasses {
private val curveX: LerpCurves, private val curveX: LerpCurves,
private val curveY: LerpCurves, private val curveY: LerpCurves,
private val curveZ: LerpCurves private val curveZ: LerpCurves
) : LerpVal() { ) : LerpValVec3f() {
fun lerp(t: Float): Vector3f { fun lerp(t: Float): Vector3f {
val x = com.bytedice.bde_particles.lerp(fromX, toX, curveX.function(t)) val x = com.bytedice.bde_particles.lerp(fromX, toX, curveX.function(t))
val y = com.bytedice.bde_particles.lerp(fromY, toY, curveY.function(t)) val y = com.bytedice.bde_particles.lerp(fromY, toY, curveY.function(t))
@@ -89,12 +92,13 @@ class ParamClasses {
private val from: Float, private val from: Float,
private val to: Float, private val to: Float,
private val curve: LerpCurves, private val curve: LerpCurves,
) : LerpVal() { ) : LerpValVec3f() {
fun lerp(t: Float) : Float { fun lerp(t: Float) : Float {
return com.bytedice.bde_particles.lerp(from, to, curve.function(t)) return com.bytedice.bde_particles.lerp(from, to, curve.function(t))
} }
} }
data object Null : LerpVal() data class Constant(val value: Vector3f) : LerpValVec3f()
data object Null : LerpValVec3f()
fun lerpToVector3f(t: Float) : Vector3f { fun lerpToVector3f(t: Float) : Vector3f {
when (this) { when (this) {
@@ -104,10 +108,34 @@ class ParamClasses {
val x = this.lerp(t) val x = this.lerp(t)
return Vector3f(x, x, x) return Vector3f(x, x, x)
} }
is Constant -> return this.value
is Null -> return Vector3f(1.0f, 1.0f, 1.0f) is Null -> return Vector3f(1.0f, 1.0f, 1.0f)
} }
} }
} }
sealed class LerpValInt {
class LerpInt(
private val from: Int,
private val to: Int,
private val curve: LerpCurves,
) : LerpValInt() {
fun lerp(t: Float): Int {
return Math.round(com.bytedice.bde_particles.lerp(from.toFloat(), to.toFloat(), curve.function(t)))
}
}
data class Constant(val value: Int) : LerpValInt()
data object Null: LerpValInt()
fun lerpToInt(t: Float) : Int? {
return when (this) {
is LerpInt -> this.lerp(t)
is Constant -> this.value
is Null -> null
}
}
}
sealed class Duration { sealed class Duration {
data class SingleBurst( data class SingleBurst(
val loopDur: Int val loopDur: Int
@@ -122,6 +150,7 @@ class ParamClasses {
val loopDelay: Int val loopDelay: Int
) : Duration() ) : Duration()
} }
sealed class TransformWithVel { sealed class TransformWithVel {
data object RotOnly : TransformWithVel() { data object RotOnly : TransformWithVel() {
fun velToRot(velocity: Vector3f): Vector3f { fun velToRot(velocity: Vector3f): Vector3f {
@@ -156,12 +185,14 @@ class ParamClasses {
} }
data object None : TransformWithVel() data object None : TransformWithVel()
} }
class StringCurve ( class StringCurve (
var array: Array<String>, var array: Array<String>,
var curve: LerpCurves var curve: LerpCurves
) { ) {
fun lerp(t: Float) : String { return lerpArray(array as Array<Any>, t, curve) as String } fun lerp(t: Float) : String { return lerpArray(array as Array<Any>, t, curve) as String }
} }
data class ForceFieldArray ( data class ForceFieldArray (
var array: Array<ForceField> var array: Array<ForceField>
) )
@@ -73,13 +73,14 @@ class Particle(
val (quatRot, newPos) = calcTransformOffset(this.rot, originOffset, scale) val (quatRot, newPos) = calcTransformOffset(this.rot, originOffset, scale)
val properties = DisplayEntityProperties( val properties = DisplayEntityProperties(
pos = entityPos, pos = entityPos,
rot = entityRot, rot = entityRot,
model = if (emitterParams.modelCurve.array.isNotEmpty()) { emitterParams.modelCurve.lerp(0.0f) } else "none", model = if (emitterParams.modelCurve.array.isNotEmpty()) { emitterParams.modelCurve.lerp(0.0f) } else "none",
translation = newPos.add(pos), translation = newPos.add(pos),
leftRotation = quatRot, leftRotation = quatRot,
scale = Vector3f(scale).mul(emitterParams.scaleCurve.lerpToVector3f(0.0f)), scale = Vector3f(scale).mul(emitterParams.scaleCurve.lerpToVector3f(0.0f)),
tags = arrayOf("BPS_Particle", "BPS_UUID", SESSION_UUID.toString()) tags = arrayOf("BPS_Particle", "BPS_UUID", SESSION_UUID.toString()),
brightnessOverride = emitterParams.brightnessCurve.lerpToInt(0.0f)
) )
particleEntity = DisplayEntity(properties) particleEntity = DisplayEntity(properties)
@@ -133,6 +134,7 @@ class Particle(
val newModel = if (emitterParams.modelCurve.array.isNotEmpty()) { emitterParams.modelCurve.lerp(timeAliveClamped) } else "none" val newModel = if (emitterParams.modelCurve.array.isNotEmpty()) { emitterParams.modelCurve.lerp(timeAliveClamped) } else "none"
val (newVel, newPos) = calcPos() val (newVel, newPos) = calcPos()
val newOriginOffset = Vector3f(originOffset.mul(emitterParams.offsetCurve.lerpToVector3f(timeAliveClamped))) val newOriginOffset = Vector3f(originOffset.mul(emitterParams.offsetCurve.lerpToVector3f(timeAliveClamped)))
val newBrightness = emitterParams.brightnessCurve.lerpToInt(timeAliveClamped)
val newScale: Vector3f val newScale: Vector3f
val newRot: Vector3f val newRot: Vector3f
@@ -166,12 +168,13 @@ class Particle(
val combinedOffset = transformOffset.add(newPos) val combinedOffset = transformOffset.add(newPos)
val newProperties = DisplayEntityProperties( val newProperties = DisplayEntityProperties(
pos = entityPos, pos = entityPos,
model = newModel, model = newModel,
translation = combinedOffset.add(newOriginOffset), translation = combinedOffset.add(newOriginOffset),
leftRotation = quatRot, leftRotation = quatRot,
scale = newScale, scale = newScale,
tags = arrayOf("BPS_Particle", "BPS_UUID", SESSION_UUID.toString()) tags = arrayOf("BPS_Particle", "BPS_UUID", SESSION_UUID.toString()),
brightnessOverride = newBrightness
) )
return newProperties return newProperties