got a bunch of ticking things to work
This commit is contained in:
@@ -60,9 +60,7 @@ class Bde_particles : ModInitializer {
|
||||
|
||||
|
||||
fun init() {
|
||||
addToParticleRegister("DEBUG", ParticleEmitterParams(loopDur = 20))
|
||||
|
||||
|
||||
addToParticleRegister("DEBUG", ParticleEmitterParams(loopDur = 1, particleTypes = arrayOf(Particle(ParticleParams(lifeTime = 60)))))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,23 +8,22 @@ import net.minecraft.nbt.NbtList
|
||||
import net.minecraft.nbt.NbtString
|
||||
import net.minecraft.server.world.ServerWorld
|
||||
|
||||
class DisplayEntity(var properties: DisplayEntityProperties?) {
|
||||
class DisplayEntity(private var properties: DisplayEntityProperties?) {
|
||||
private var hasSpawned = false
|
||||
private var entity: BlockDisplayEntity? = null
|
||||
|
||||
fun spawn(world: ServerWorld) : BlockDisplayEntity? {
|
||||
if (hasSpawned || properties == null) { return null }
|
||||
fun spawn(world: ServerWorld) {
|
||||
if (hasSpawned || properties == null) { return }
|
||||
|
||||
val e = updateProperties(world, properties!!)
|
||||
world.spawnEntity(e)
|
||||
entity = BlockDisplayEntity(EntityType.BLOCK_DISPLAY, world)
|
||||
updateProperties(properties!!)
|
||||
|
||||
world.spawnEntity(entity)
|
||||
|
||||
this.hasSpawned = true
|
||||
return e
|
||||
}
|
||||
|
||||
fun updateProperties(world: ServerWorld, properties: DisplayEntityProperties) : BlockDisplayEntity {
|
||||
val e = BlockDisplayEntity(EntityType.BLOCK_DISPLAY, world)
|
||||
|
||||
fun updateProperties(properties: DisplayEntityProperties) {
|
||||
val nbt = NbtCompound().apply {
|
||||
val tagList = NbtList()
|
||||
|
||||
@@ -60,24 +59,21 @@ class DisplayEntity(var properties: DisplayEntityProperties?) {
|
||||
add(NbtFloat.of(properties.rightRotation.w))
|
||||
}
|
||||
|
||||
put("translation", offsetList)
|
||||
put("left_rotation", rotList)
|
||||
put("scale", scaleList)
|
||||
put("translation", offsetList)
|
||||
put("left_rotation", rotList)
|
||||
put("scale", scaleList)
|
||||
put("right_rotation", rightRotList)
|
||||
})
|
||||
}
|
||||
|
||||
e.readNbt(nbt)
|
||||
entity?.readNbt(nbt)
|
||||
entity?.refreshPositionAndAngles(properties.pos.x, properties.pos.y, properties.pos.z, properties.rot.x, properties.rot.y)
|
||||
|
||||
e.refreshPositionAndAngles(properties.pos.x, properties.pos.y, properties.pos.z, properties.rot.x, properties.rot.y)
|
||||
|
||||
entity = e
|
||||
this.properties = properties
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
fun kill() {
|
||||
if (entity == null) { println("BPS - Particle entity is null!"); return }
|
||||
entity?.kill()
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,15 @@ fun randomFloatBetween(min: Float, max: Float) : Float {
|
||||
}
|
||||
|
||||
|
||||
fun randomBetweenVector3f(min: Vector3f, max: Vector3f) : Vector3f {
|
||||
return Vector3f(
|
||||
randomFloatBetween(min.x, max.x),
|
||||
randomFloatBetween(min.y, max.y),
|
||||
randomFloatBetween(min.z, max.z)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun eulerToQuat(euler: Vector3f): Vector4f {
|
||||
val roll = euler.x
|
||||
val pitch = euler.y
|
||||
|
||||
@@ -10,37 +10,32 @@ import kotlin.math.round
|
||||
|
||||
|
||||
class Particle(private val particleParams: ParticleParams) {
|
||||
private val rot = Vector3f(
|
||||
randomFloatBetween(particleParams.rotRandom.first.x, particleParams.rotRandom.second.x),
|
||||
randomFloatBetween(particleParams.rotRandom.first.y, particleParams.rotRandom.second.x),
|
||||
randomFloatBetween(particleParams.rotRandom.first.z, particleParams.rotRandom.second.z)
|
||||
)
|
||||
private val rotVel = Vector3f(
|
||||
randomFloatBetween(particleParams.rotVelRandom.first.x, particleParams.rotVelRandom.second.x),
|
||||
randomFloatBetween(particleParams.rotVelRandom.first.y, particleParams.rotVelRandom.second.x),
|
||||
randomFloatBetween(particleParams.rotVelRandom.first.z, particleParams.rotVelRandom.second.z)
|
||||
)
|
||||
private val scale = Vector3f(
|
||||
randomFloatBetween(particleParams.sizeRandom.first.x, particleParams.sizeRandom.second.x),
|
||||
randomFloatBetween(particleParams.sizeRandom.first.y, particleParams.sizeRandom.second.x),
|
||||
randomFloatBetween(particleParams.sizeRandom.first.z, particleParams.sizeRandom.second.z)
|
||||
)
|
||||
private val initOffset = Vector3f(-0.5f, -0.5f, -0.5f)
|
||||
private var offset = Vector3f(0.0f, 0.0f, 0.0f)
|
||||
private var pos = Vec3d(0.0, 0.0, 0.0)
|
||||
|
||||
private val 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 blockDisplay: DisplayEntity? = null
|
||||
|
||||
private val quatRot = eulerToQuat(rot)
|
||||
private val scaleOffset = transformOffsetByScale(initOffset, scale)
|
||||
private val rotOffset = transformOffsetByQuat(scaleOffset, quatRot)
|
||||
|
||||
var isDead = false
|
||||
private var timeAlive = 0
|
||||
|
||||
private var isInit = false
|
||||
|
||||
fun init(pos: Vec3d) {
|
||||
val offset = Vector3f(-0.5f, -0.5f, -0.5f)
|
||||
val quatRot = eulerToQuat(rot)
|
||||
|
||||
val scaleOffset = transformOffsetByScale(offset, scale)
|
||||
val rotOffset = transformOffsetByQuat(scaleOffset, quatRot)
|
||||
fun init(pos: Vec3d) {
|
||||
this.pos = pos
|
||||
|
||||
val properties = DisplayEntityProperties(
|
||||
pos = pos,
|
||||
pos = this.pos,
|
||||
blockType = particleParams.blockCurve[0],
|
||||
translation = rotOffset,
|
||||
leftRotation = quatRot,
|
||||
@@ -60,14 +55,12 @@ class Particle(private val particleParams: ParticleParams) {
|
||||
}
|
||||
|
||||
|
||||
fun tick(world: ServerWorld) {
|
||||
fun tick() {
|
||||
if (!isInit) { error("Particle is not initialized before being ticked. Please use Particle.init() to initialize it.") }
|
||||
|
||||
val properties = blockDisplay?.properties ?: return
|
||||
|
||||
val newProperties = calculateNewProperties()
|
||||
|
||||
blockDisplay?.updateProperties(world, newProperties)
|
||||
blockDisplay?.updateProperties(newProperties)
|
||||
|
||||
if (timeAlive > particleParams.lifeTime) { isDead = true; blockDisplay?.kill() }
|
||||
|
||||
@@ -76,17 +69,37 @@ class Particle(private val particleParams: ParticleParams) {
|
||||
|
||||
|
||||
private fun calculateNewProperties() : DisplayEntityProperties {
|
||||
val newBlockIdx = round(lerp(
|
||||
0.0f,
|
||||
particleParams.blockCurve.lastIndex.toFloat(),
|
||||
(timeAlive.toFloat() / particleParams.lifeTime.toFloat()).coerceIn(0.0f, 1.0f)
|
||||
)).toInt()
|
||||
fun calculateBlockCurve() : String {
|
||||
val newBlockIdx = round(
|
||||
lerp(
|
||||
0.0f,
|
||||
particleParams.blockCurve.lastIndex.toFloat(),
|
||||
(timeAlive.toFloat() / particleParams.lifeTime.toFloat()).coerceIn(0.0f, 1.0f)
|
||||
)
|
||||
).toInt()
|
||||
|
||||
val newBlock = particleParams.blockCurve[newBlockIdx]
|
||||
return particleParams.blockCurve[newBlockIdx]
|
||||
}
|
||||
|
||||
fun calculateOffset() : Vector3f {
|
||||
vel = vel.add(particleParams.gravity)
|
||||
vel = vel.mul(1.0f - particleParams.drag)
|
||||
|
||||
offset = offset.add(vel)
|
||||
return rotOffset.add(offset)
|
||||
}
|
||||
|
||||
|
||||
val newBlock = calculateBlockCurve()
|
||||
val newOffset = calculateOffset()
|
||||
|
||||
val newProperties = DisplayEntityProperties(
|
||||
blockType = newBlock
|
||||
pos = pos,
|
||||
blockType = newBlock,
|
||||
translation = newOffset,
|
||||
leftRotation = quatRot,
|
||||
scale = scale,
|
||||
tags = arrayOf("BPS_Particle")
|
||||
)
|
||||
|
||||
return newProperties
|
||||
|
||||
@@ -16,11 +16,14 @@ class ParticleEmitter(emitterPos: Vec3d, emitterWorld: ServerWorld, emitterParam
|
||||
private var loopDur = 0
|
||||
private var loopDelayActive = false
|
||||
|
||||
private var isCounting = true
|
||||
|
||||
var isDead = false
|
||||
|
||||
|
||||
fun tick() {
|
||||
count()
|
||||
if (isCounting) { count() }
|
||||
if (!isCounting && allParticles.isEmpty()) { isDead = true }
|
||||
|
||||
if (!loopDelayActive) {
|
||||
repeat(this.params.spawnsPerTick) {
|
||||
@@ -33,7 +36,7 @@ class ParticleEmitter(emitterPos: Vec3d, emitterWorld: ServerWorld, emitterParam
|
||||
|
||||
for (particle in allParticles) {
|
||||
if (particle.isDead) { allParticles = allParticles.toMutableList().apply { remove(particle) }.toTypedArray() }
|
||||
else { particle.tick(world) }
|
||||
else { particle.tick() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +46,7 @@ class ParticleEmitter(emitterPos: Vec3d, emitterWorld: ServerWorld, emitterParam
|
||||
loopCount += 1
|
||||
loopDur = 0
|
||||
loopDelayActive = true
|
||||
if (!params.loop) { isDead = true }
|
||||
if (!params.loop) { isCounting = false }
|
||||
}
|
||||
else if (loopDelay >= params.loopDelay) {
|
||||
loopDelay = 0
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.bytedice.bde_particles.particle
|
||||
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import org.joml.Vector3f
|
||||
|
||||
data class ParticleParams (
|
||||
@@ -11,9 +10,9 @@ data class ParticleParams (
|
||||
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(1.0f, 1.0f, 1.0f), Vector3f(5.0f, 5.0f, 5.0f)),
|
||||
val velRandom: Pair<Vector3f, Vector3f> = Pair(Vector3f(-0.1f, 0.1f, -0.1f), Vector3f(0.1f, 0.2f, 0.1f)),
|
||||
val forceFields: ForceField = ForceField(),
|
||||
val gravity: Vec3d = Vec3d(0.0, -9.0, 0.0),
|
||||
val gravity: Vector3f = Vector3f(0.0f, -0.025f, 0.0f),
|
||||
val drag: Float = 0.2f,
|
||||
val minVel: Float = 0.003f,
|
||||
val lifeTime: Int = 20
|
||||
|
||||
Reference in New Issue
Block a user