added rotation and fixed bugs

This commit is contained in:
2024-11-17 12:02:42 +01:00
parent c5d828514b
commit e6c2858bb6
5 changed files with 69 additions and 23 deletions
@@ -60,7 +60,7 @@ class Bde_particles : ModInitializer {
fun init() { fun init() {
addToParticleRegister("DEBUG", ParticleEmitterParams(loopDur = 1, particleTypes = arrayOf(Particle(ParticleParams(lifeTime = 60))))) addToParticleRegister("DEBUG", ParticleEmitterParams())
} }
@@ -149,7 +149,7 @@ fun transformOffsetByQuat(offset: Vector3f, rotation: Vector4f): Vector3f {
fun transformOffsetByScale(offset: Vector3f, scale: Vector3f): Vector3f { fun transformOffsetByScale(offset: Vector3f, scale: Vector3f): Vector3f {
return offset.mul(scale) return Vector3f(offset).mul(scale)
} }
@@ -6,6 +6,8 @@ import com.bytedice.bde_particles.math.*
import net.minecraft.server.world.ServerWorld import net.minecraft.server.world.ServerWorld
import net.minecraft.util.math.Vec3d import net.minecraft.util.math.Vec3d
import org.joml.Vector3f import org.joml.Vector3f
import org.joml.Vector4f
import kotlin.math.abs
import kotlin.math.round import kotlin.math.round
@@ -14,17 +16,13 @@ class Particle(private val particleParams: ParticleParams) {
private var offset = Vector3f(0.0f, 0.0f, 0.0f) private var offset = Vector3f(0.0f, 0.0f, 0.0f)
private var pos = Vec3d(0.0, 0.0, 0.0) private var pos = Vec3d(0.0, 0.0, 0.0)
private val rot = randomBetweenVector3f(particleParams.rotRandom.first, particleParams.rotRandom.second) private var rot = randomBetweenVector3f(particleParams.rotRandom.first, particleParams.rotRandom.second)
private val rotVel = randomBetweenVector3f(particleParams.rotVelRandom.first, particleParams.rotVelRandom.second) private val rotVel = randomBetweenVector3f(particleParams.rotVelRandom.first, particleParams.rotVelRandom.second)
private val scale = randomBetweenVector3f(particleParams.sizeRandom.first, particleParams.sizeRandom.second) private val scale = randomBetweenVector3f(particleParams.sizeRandom.first, particleParams.sizeRandom.second)
private var vel = randomBetweenVector3f(particleParams.velRandom.first, particleParams.velRandom.second) private var vel = randomBetweenVector3f(particleParams.velRandom.first, particleParams.velRandom.second)
private var blockDisplay: DisplayEntity? = null private var blockDisplay: DisplayEntity? = null
private val quatRot = eulerToQuat(rot)
private val scaleOffset = transformOffsetByScale(initOffset, scale)
private val rotOffset = transformOffsetByQuat(scaleOffset, quatRot)
var isDead = false var isDead = false
private var timeAlive = 0 private var timeAlive = 0
@@ -34,10 +32,12 @@ class Particle(private val particleParams: ParticleParams) {
fun init(pos: Vec3d) { fun init(pos: Vec3d) {
this.pos = pos this.pos = pos
val (quatRot, newOffset) = calcTransformOffset(rot, initOffset, scale)
val properties = DisplayEntityProperties( val properties = DisplayEntityProperties(
pos = this.pos, pos = this.pos,
blockType = particleParams.blockCurve[0], blockType = particleParams.blockCurve[0],
translation = rotOffset, translation = newOffset,
leftRotation = quatRot, leftRotation = quatRot,
scale = scale, scale = scale,
tags = arrayOf("BPS_Particle") tags = arrayOf("BPS_Particle")
@@ -58,7 +58,7 @@ class Particle(private val particleParams: ParticleParams) {
fun tick() { fun tick() {
if (!isInit) { error("Particle is not initialized before being ticked. Please use Particle.init() to initialize it.") } if (!isInit) { error("Particle is not initialized before being ticked. Please use Particle.init() to initialize it.") }
val newProperties = calculateNewProperties() val newProperties = calcNewProperties()
blockDisplay?.updateProperties(newProperties) blockDisplay?.updateProperties(newProperties)
@@ -68,8 +68,22 @@ class Particle(private val particleParams: ParticleParams) {
} }
private fun calculateNewProperties() : DisplayEntityProperties { private fun calcTransformOffset(eulerRot: Vector3f, offset: Vector3f, scale: Vector3f): Pair<Vector4f, Vector3f> {
fun calculateBlockCurve() : String { val eulerRotCopy = Vector3f(eulerRot)
val offsetCopy = Vector3f(offset)
val scaleCopy = Vector3f(scale)
val quatRot = eulerToQuat(eulerRotCopy)
val scaleOffset = transformOffsetByScale(offsetCopy, scaleCopy)
val rotOffset = transformOffsetByQuat(scaleOffset, quatRot)
return Pair(quatRot, rotOffset)
}
// TODO: rotVelRandom, rotVelCurve, sizeCurve, forceFields
private fun calcNewProperties() : DisplayEntityProperties {
fun calcBlockCurve() : String {
val newBlockIdx = round( val newBlockIdx = round(
lerp( lerp(
0.0f, 0.0f,
@@ -81,24 +95,45 @@ class Particle(private val particleParams: ParticleParams) {
return particleParams.blockCurve[newBlockIdx] return particleParams.blockCurve[newBlockIdx]
} }
fun calculateOffset() : Vector3f { fun calcRot() : Vector3f {
val newRot = Vector3f(rot)
newRot.add(rotVel)
return newRot
}
fun calcOffset() : Pair<Vector3f, Vector3f> {
var vel = Vector3f(vel)
vel = vel.add(particleParams.gravity) vel = vel.add(particleParams.gravity)
vel = vel.mul(1.0f - particleParams.drag) vel = vel.mul(1.0f - particleParams.drag)
offset = offset.add(vel) if (abs(vel.x) < particleParams.minVel) { vel.x = 0.0f }
return rotOffset.add(offset) if (abs(vel.y) < particleParams.minVel) { vel.y = 0.0f }
if (abs(vel.z) < particleParams.minVel) { vel.z = 0.0f }
var newOffset = Vector3f(offset)
newOffset = newOffset.add(vel)
return Pair(vel, newOffset)
} }
val newBlock = calculateBlockCurve()
val newOffset = calculateOffset() val newBlock = calcBlockCurve()
val (newVel, newOffset) = calcOffset()
val newRot = calcRot()
vel = newVel
offset = newOffset
rot = newRot
val (quatRot, transformOffset) = calcTransformOffset(newRot, initOffset, scale /* newScale */)
val combinedOffset = transformOffset.add(newOffset)
val newProperties = DisplayEntityProperties( val newProperties = DisplayEntityProperties(
pos = pos, pos = pos,
blockType = newBlock, blockType = newBlock,
translation = newOffset, translation = combinedOffset,
leftRotation = quatRot, leftRotation = quatRot,
scale = scale, scale = scale, //fix
tags = arrayOf("BPS_Particle") tags = arrayOf("BPS_Particle")
) )
@@ -1,11 +1,19 @@
package com.bytedice.bde_particles.particle package com.bytedice.bde_particles.particle
// TODO: order these correctly
// loop: false means it will shoot as many particles as spawnsPerTick * loopDur, true means it will loop
// loopDur: 0 or below means no particles will spawn
// loopDelay: if loop is not true then this won't do anything, negative values are treated as 0
// loopCount: if loop is not true then this won't do anything, -1 is treated as infinite
// spawnsPerTick: 0 or below means no particles will spawn
// maxCount: 0 or below means no particles will spawn
// particleTypes: empty means no particles will spawn
data class ParticleEmitterParams ( data class ParticleEmitterParams (
val maxCount: Int = 100, val maxCount: Int = 100,
val spawnsPerTick: Int = 1, val spawnsPerTick: Int = 1,
val particleTypes: Array<Particle> = emptyArray(), val particleTypes: Array<Particle> = emptyArray(),
val loop: Boolean = false, val loop: Boolean = false,
val loopDur: Int = 1, val loopDur: Int = 20,
val loopDelay: Int = 10, val loopDelay: Int = 10,
val loopCount: Int = 2, val loopCount: Int = 2,
) )
@@ -2,18 +2,21 @@ package com.bytedice.bde_particles.particle
import org.joml.Vector3f import org.joml.Vector3f
// sizeRandom: set y and z on both vectors to -1 for uniform scale // not implemented
// 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
data class ParticleParams ( data class ParticleParams (
//val shape: Shape, // add later, start with single point //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:purple_concrete", "minecraft:purple_stained_glass"),
val rotRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(0.0f, 0.0f, 0.0f), Vector3f(360.0f, 360.0f, 360.0f)), 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(1.0f, 1.0f, 1.0f), Vector3f(5.0f, 5.0f, 5.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 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 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 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.1f, 0.1f, -0.1f), Vector3f(0.1f, 0.2f, 0.1f)), val velRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(-0.3f, 0.3f, -0.3f), Vector3f(0.3f, 0.6f, 0.3f)),
val forceFields: ForceField = ForceField(), val forceFields: ForceField = ForceField(),
val gravity: Vector3f = Vector3f(0.0f, -0.025f, 0.0f), val gravity: Vector3f = Vector3f(0.0f, -0.025f, 0.0f),
val drag: Float = 0.2f, val drag: Float = 0.075f,
val minVel: Float = 0.003f, val minVel: Float = 0.0f,
val lifeTime: Int = 20 val lifeTime: Int = 20
) )