rendering: fix crashes, remove particle delta ticking

This commit is contained in:
Bixilon 2021-06-10 19:09:39 +02:00 committed by Lukas
parent e12f165648
commit cf0a6a4927
18 changed files with 67 additions and 71 deletions

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.modding.event.CallbackEventInvoker import de.bixilon.minosoft.modding.event.CallbackEventInvoker
import de.bixilon.minosoft.modding.event.events.EntityDestroyEvent import de.bixilon.minosoft.modding.event.events.EntityDestroyEvent
import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent
@ -49,7 +50,7 @@ class EntityHitBoxRenderer(
if (aabb != mesh?.aabb) { if (aabb != mesh?.aabb) {
this.meshes.remove(entity) this.meshes.remove(entity)
if (mesh?.needsUpdate == true) { if (mesh?.state == Mesh.MeshStates.LOADED) {
mesh.unload() mesh.unload()
} }
nextMesh = createMesh(entity, aabb, visible) nextMesh = createMesh(entity, aabb, visible)

View File

@ -89,7 +89,7 @@ class ParticleRenderer(
for (particle in particles.toSynchronizedSet()) { for (particle in particles.toSynchronizedSet()) {
particle.tick() particle.tryTick()
if (particle.dead) { if (particle.dead) {
this.particles -= particle this.particles -= particle
continue continue

View File

@ -18,9 +18,9 @@ import de.bixilon.minosoft.data.physics.PhysicsEntity
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
import de.bixilon.minosoft.gui.rendering.particle.ParticleMesh import de.bixilon.minosoft.gui.rendering.particle.ParticleMesh
import de.bixilon.minosoft.gui.rendering.util.VecUtil
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
import de.bixilon.minosoft.gui.rendering.util.VecUtil.assign import de.bixilon.minosoft.gui.rendering.util.VecUtil.assign
import de.bixilon.minosoft.gui.rendering.util.VecUtil.millis
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plusAssign import de.bixilon.minosoft.gui.rendering.util.VecUtil.plusAssign
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
@ -41,7 +41,7 @@ abstract class Particle(
connection.registries.particleTypeRegistry[resourceLocation]!!.default() connection.registries.particleTypeRegistry[resourceLocation]!!.default()
} }
protected val random = Random protected val random = Random
var lastTickTime = -1L private var lastTickTime = -1L
// ageing // ageing
var dead = false var dead = false
@ -52,6 +52,9 @@ abstract class Particle(
var maxAge: Int = (4.0f / (random.nextFloat() * 0.9f + 0.1f)).toInt() var maxAge: Int = (4.0f / (random.nextFloat() * 0.9f + 0.1f)).toInt()
// moving // moving
val cameraPosition: Vec3d
get() = VecUtil.lerp((System.currentTimeMillis() - lastTickTime) / ProtocolDefinition.TICK_TIMEd, previousPosition, position)
final override val velocity: Vec3d = Vec3d(velocity) final override val velocity: Vec3d = Vec3d(velocity)
var previousPosition = position var previousPosition = position
var movement: Boolean = true var movement: Boolean = true
@ -79,9 +82,6 @@ abstract class Particle(
} }
private var lastRealTickTime = -1L
init { init {
this.velocity += { (random.nextDouble() * 2.0 - 1.0) * MAGIC_VELOCITY_CONSTANT } this.velocity += { (random.nextDouble() * 2.0 - 1.0) * MAGIC_VELOCITY_CONSTANT }
val modifier = (random.nextFloat() + random.nextFloat() + 1.0f) * 0.15000000596046448 val modifier = (random.nextFloat() + random.nextFloat() + 1.0f) * 0.15000000596046448
@ -93,6 +93,16 @@ abstract class Particle(
spacing = Vec3(0.2) spacing = Vec3(0.2)
} }
fun forceMove(delta: Vec3d) {
this.previousPosition = Vec3d(position)
position += delta
}
fun forceMove(move: () -> Double) {
this.previousPosition = Vec3d(position)
position += move
}
open fun move(velocity: Vec3d) { open fun move(velocity: Vec3d) {
if (alreadyCollided) { if (alreadyCollided) {
return return
@ -104,7 +114,7 @@ abstract class Particle(
} }
if (newVelocity != Vec3d.EMPTY) { if (newVelocity != Vec3d.EMPTY) {
position += newVelocity forceMove(newVelocity)
} }
if (abs(newVelocity.y) >= Y_VELOCITY_TO_CHECK && abs(velocity.y) < Y_VELOCITY_TO_CHECK) { if (abs(newVelocity.y) >= Y_VELOCITY_TO_CHECK && abs(velocity.y) < Y_VELOCITY_TO_CHECK) {
@ -112,38 +122,31 @@ abstract class Particle(
} }
} }
private fun move(deltaTime: Int) { private fun move() {
if (!movement) { if (!movement) {
return return
} }
previousPosition = Vec3d(position)
move(velocity.millis * (deltaTime / 1000.0f)) forceMove(velocity)
} }
fun tick() { fun tryTick() {
val currentTime = System.currentTimeMillis() val currentTime = System.currentTimeMillis()
if (lastTickTime == -1L) {
// never ticked before, skip
lastTickTime = currentTime
return
}
val deltaTime = (currentTime - lastTickTime).toInt()
tick(deltaTime)
if (dead) { if (dead) {
return return
} }
if (lastRealTickTime == -1L) { if (lastTickTime == -1L) {
lastRealTickTime = System.currentTimeMillis() lastTickTime = System.currentTimeMillis()
} else if (currentTime - lastRealTickTime >= ProtocolDefinition.TICK_TIME) { return
realTick()
lastRealTickTime = currentTime
} }
if (currentTime - lastTickTime < ProtocolDefinition.TICK_TIME) {
postTick(deltaTime) return
}
tick()
move()
postTick()
lastTickTime = currentTime lastTickTime = currentTime
} }
@ -153,16 +156,9 @@ abstract class Particle(
} }
} }
open fun tick(deltaTime: Int) { open fun postTick() {}
check(!dead) { "Cannot tick dead particle!" }
check(deltaTime >= 0)
}
open fun postTick(deltaTime: Int) { open fun tick() {
move(deltaTime)
}
open fun realTick() {
age() age()
if (dead) { if (dead) {
return return

View File

@ -31,8 +31,8 @@ class ExplosionEmitterParticle(connection: PlayConnection, position: Vec3d, data
movement = false movement = false
} }
override fun realTick() { override fun tick() {
super.realTick() super.tick()
explosionParticleType ?: let { explosionParticleType ?: let {
dead = true dead = true
return return

View File

@ -26,7 +26,7 @@ abstract class TextureParticle(connection: PlayConnection, position: Vec3d, velo
override fun addVertex(particleMesh: ParticleMesh) { override fun addVertex(particleMesh: ParticleMesh) {
texture?.let { texture?.let {
particleMesh.addVertex(position, scale, it, color) particleMesh.addVertex(cameraPosition, scale, it, color)
} }
} }
} }

View File

@ -26,7 +26,7 @@ abstract class AdvancedTextureParticle(connection: PlayConnection, position: Vec
override fun addVertex(particleMesh: ParticleMesh) { override fun addVertex(particleMesh: ParticleMesh) {
texture?.let { texture?.let {
particleMesh.addVertex(position, scale, it, color, minUV, maxUV) particleMesh.addVertex(cameraPosition, scale, it, color, minUV, maxUV)
} }
} }
} }

View File

@ -48,11 +48,11 @@ class PortalParticle(connection: PlayConnection, position: Vec3d, velocity: Vec3
} }
override fun move(velocity: Vec3d) { override fun move(velocity: Vec3d) {
this.position += velocity forceMove(velocity)
} }
override fun realTick() { override fun tick() {
super.realTick() super.tick()
if (dead) { if (dead) {
return return
} }

View File

@ -40,8 +40,8 @@ abstract class SimpleTextureParticle(connection: PlayConnection, position: Vec3d
texture = connection.rendering?.renderWindow?.textures?.allTextures?.get(data.type.textures.random(random)) texture = connection.rendering?.renderWindow?.textures?.allTextures?.get(data.type.textures.random(random))
} }
override fun tick(deltaTime: Int) { override fun tick() {
super.tick(deltaTime) super.tick()
if (dead) { if (dead) {
return return
} }

View File

@ -19,7 +19,6 @@ import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.SimpleTextureParticle import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.SimpleTextureParticle
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
import de.bixilon.minosoft.gui.rendering.util.VecUtil.assign import de.bixilon.minosoft.gui.rendering.util.VecUtil.assign
import de.bixilon.minosoft.gui.rendering.util.VecUtil.millis
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.util.KUtil.asResourceLocation import de.bixilon.minosoft.util.KUtil.asResourceLocation
import glm_.vec3.Vec3 import glm_.vec3.Vec3
@ -47,8 +46,8 @@ class CampfireSmokeParticle(connection: PlayConnection, position: Vec3d, velocit
setRandomSprite() setRandomSprite()
} }
override fun realTick() { override fun tick() {
super.realTick() super.tick()
val horizontal = { (random.nextDouble() / 5000.0f * (if (random.nextBoolean()) 1.0f else -1.0f)) } val horizontal = { (random.nextDouble() / 5000.0f * (if (random.nextBoolean()) 1.0f else -1.0f)) }
velocity.x += horizontal() velocity.x += horizontal()
velocity.y -= gravityStrength velocity.y -= gravityStrength
@ -62,9 +61,9 @@ class CampfireSmokeParticle(connection: PlayConnection, position: Vec3d, velocit
} }
} }
override fun postTick(deltaTime: Int) { override fun postTick() {
super.postTick(deltaTime) super.postTick()
move(velocity.millis * (deltaTime / 1000.0f)) move(velocity)
} }

View File

@ -40,8 +40,8 @@ open class CloudParticle(connection: PlayConnection, position: Vec3d, velocity:
physics = false physics = false
} }
override fun realTick() { override fun tick() {
super.realTick() super.tick()
if (dead) { if (dead) {
return return
} }

View File

@ -38,11 +38,11 @@ abstract class DamageParticle(connection: PlayConnection, position: Vec3d, veloc
super.scale *= 0.75f super.scale *= 0.75f
maxAge = (6.0f / (random.nextFloat() * 0.8f + 0.6f)).toInt().coerceAtLeast(1) maxAge = (6.0f / (random.nextFloat() * 0.8f + 0.6f)).toInt().coerceAtLeast(1)
physics = false physics = false
realTick() tick()
} }
final override fun realTick() { final override fun tick() {
super.realTick() super.tick()
color = color.with(green = this.color.floatGreen * 0.96f, blue = this.color.floatBlue * 0.96f) color = color.with(green = this.color.floatGreen * 0.96f, blue = this.color.floatBlue * 0.96f)
} }
} }

View File

@ -49,9 +49,9 @@ abstract class AbstractDustParticle(connection: PlayConnection, position: Vec3d,
return (random.nextFloat() * 0.2f + 0.8f) * color * brightness return (random.nextFloat() * 0.2f + 0.8f) * color * brightness
} }
override fun realTick() { override fun tick() {
super.realTick() super.tick()
position += velocity forceMove(velocity)
velocity *= 0.99f velocity *= 0.99f
} }

View File

@ -41,11 +41,12 @@ abstract class EnchantedGlyphParticle(connection: PlayConnection, position: Vec3
setRandomSprite() setRandomSprite()
} }
override fun postTick(deltaTime: Int) { override fun postTick() {
super.postTick(deltaTime) super.postTick()
if (dead) { if (dead) {
return return
} }
val ageDivisor = 1.0 - floatAge / maxAge val ageDivisor = 1.0 - floatAge / maxAge
val ageDivisor2 = (1.0 - ageDivisor).pow(3) val ageDivisor2 = (1.0 - ageDivisor).pow(3)
this.position assign (startPosition + velocity * ageDivisor) this.position assign (startPosition + velocity * ageDivisor)

View File

@ -42,8 +42,8 @@ class LavaParticle(connection: PlayConnection, position: Vec3d, data: ParticleDa
maxAge = (16.0f / (random.nextFloat() * 0.8f + 0.2f)).toInt() maxAge = (16.0f / (random.nextFloat() * 0.8f + 0.2f)).toInt()
} }
override fun realTick() { override fun tick() {
super.realTick() super.tick()
if (random.nextFloat() > (floatAge / maxAge)) { if (random.nextFloat() > (floatAge / maxAge)) {
connection.world += SmokeParticle(connection, Vec3d(position), Vec3d(velocity)) connection.world += SmokeParticle(connection, Vec3d(position), Vec3d(velocity))

View File

@ -30,7 +30,7 @@ open class FlameParticle(connection: PlayConnection, position: Vec3d, velocity:
} }
override fun move(velocity: Vec3d) { override fun move(velocity: Vec3d) {
position += velocity forceMove(velocity)
} }
companion object : ParticleFactory<FlameParticle> { companion object : ParticleFactory<FlameParticle> {

View File

@ -16,7 +16,6 @@ package de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.s
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.SimpleTextureParticle import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.SimpleTextureParticle
import de.bixilon.minosoft.gui.rendering.util.VecUtil.assign import de.bixilon.minosoft.gui.rendering.util.VecUtil.assign
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plusAssign
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3d import glm_.vec3.Vec3d
@ -25,7 +24,7 @@ abstract class SlowingParticle(connection: PlayConnection, position: Vec3d, velo
init { init {
friction = 0.96f friction = 0.96f
this.velocity assign (this.velocity * 0.009999999776482582 + velocity) this.velocity assign (this.velocity * 0.009999999776482582 + velocity)
this.position += { (random.nextDouble() - random.nextDouble()) * 0.05 } forceMove { (random.nextDouble() - random.nextDouble()) * 0.05 }
maxAge = (8.0 / (random.nextDouble() * 0.8 + 0.2)).toInt() + 4 maxAge = (8.0 / (random.nextDouble() * 0.8 + 0.2)).toInt() + 4
} }
} }

View File

@ -38,8 +38,8 @@ abstract class SpellParticle(connection: PlayConnection, position: Vec3d, veloci
// ToDo: Toggle if using spyglass // ToDo: Toggle if using spyglass
} }
override fun realTick() { override fun tick() {
super.realTick() super.tick()
color = color.with(alpha = VecUtil.lerp(0.05f, color.floatAlpha, 1.0f)) color = color.with(alpha = VecUtil.lerp(0.05f, color.floatAlpha, 1.0f))
} }

View File

@ -31,12 +31,12 @@ abstract class SuspendParticle(connection: PlayConnection, position: Vec3d, velo
movement = false movement = false
} }
override fun realTick() { override fun tick() {
super.realTick() super.tick()
if (dead) { if (dead) {
return return
} }
position += velocity forceMove(velocity)
velocity *= 0.99f velocity *= 0.99f
} }