mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
some decent particle performance improvements, lazy hit boxes
This commit is contained in:
parent
2d308d40bc
commit
a1035542db
@ -20,4 +20,5 @@ data class EntityHitBoxConfig(
|
||||
@Json(name = "own_hit_box") val ownHitBox: Boolean = false,
|
||||
@Json(name = "disable_z_buffer") val disableZBuffer: Boolean = false,
|
||||
@Json(name = "invisible_entities") val invisibleEntities: Boolean = false,
|
||||
@Json(name = "lazy_hit_boxes") val lazyHitBoxes: Boolean = false,
|
||||
)
|
||||
|
@ -12,10 +12,21 @@
|
||||
*/
|
||||
package de.bixilon.minosoft.data.entities
|
||||
|
||||
import glm_.func.cos
|
||||
import glm_.func.rad
|
||||
import glm_.func.sin
|
||||
import glm_.vec3.Vec3d
|
||||
|
||||
data class EntityRotation(
|
||||
val yaw: Double,
|
||||
val pitch: Double,
|
||||
) {
|
||||
val front: Vec3d
|
||||
get() = Vec3d(
|
||||
(yaw + 90).rad.cos * (-pitch).rad.cos,
|
||||
(-pitch).rad.sin,
|
||||
(yaw + 90).rad.sin * (-pitch).rad.cos
|
||||
).normalize()
|
||||
|
||||
constructor(bodyYaw: Float, pitch: Float) : this(bodyYaw.toDouble(), pitch.toDouble())
|
||||
|
||||
|
@ -25,9 +25,6 @@ import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
|
||||
import glm_.func.cos
|
||||
import glm_.func.rad
|
||||
import glm_.func.sin
|
||||
import glm_.vec3.Vec3
|
||||
import glm_.vec3.Vec3d
|
||||
|
||||
@ -72,7 +69,11 @@ class EntityHitBox(
|
||||
}
|
||||
if (visible) {
|
||||
val mesh = LineMesh(renderWindow)
|
||||
mesh.drawAABB(aabb = aabb, color = hitBoxColor)
|
||||
if (Minosoft.config.config.game.entities.hitBox.lazyHitBoxes) {
|
||||
mesh.drawLazyAABB(aabb, color = hitBoxColor)
|
||||
} else {
|
||||
mesh.drawAABB(aabb = aabb, color = hitBoxColor, margin = 0.1f)
|
||||
}
|
||||
val center = Vec3(aabb.center)
|
||||
|
||||
if (!velocity.empty) {
|
||||
@ -85,15 +86,9 @@ class EntityHitBox(
|
||||
mesh.drawAABB(eyeAABB, RenderConstants.DEFAULT_LINE_WIDTH, ChatColors.DARK_RED)
|
||||
|
||||
|
||||
val front = Vec3d(
|
||||
(rotation.yaw + 90).rad.cos * (-rotation.pitch).rad.cos,
|
||||
(-rotation.pitch).rad.sin,
|
||||
(rotation.yaw + 90).rad.sin * (-rotation.pitch).rad.cos
|
||||
).normalize()
|
||||
|
||||
val eyeStart = Vec3(center.x, eyeHeight, center.z)
|
||||
|
||||
mesh.drawLine(eyeStart, eyeStart + Vec3(front) * 5, color = ChatColors.BLUE)
|
||||
mesh.drawLine(eyeStart, eyeStart + Vec3(rotation.front) * 5, color = ChatColors.BLUE)
|
||||
mesh.load()
|
||||
this.mesh = mesh
|
||||
}
|
||||
|
@ -46,9 +46,7 @@ import de.bixilon.minosoft.util.KUtil
|
||||
import de.bixilon.minosoft.util.KUtil.decide
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import de.bixilon.minosoft.util.Previous
|
||||
import glm_.func.cos
|
||||
import glm_.func.rad
|
||||
import glm_.func.sin
|
||||
import glm_.glm
|
||||
import glm_.mat4x4.Mat4
|
||||
import glm_.mat4x4.Mat4d
|
||||
@ -123,8 +121,9 @@ class Camera(
|
||||
}
|
||||
yaw %= 180
|
||||
val pitch = glm.clamp(delta.y + connection.player.rotation.pitch, -89.9, 89.9)
|
||||
connection.player.rotation = EntityRotation(yaw, pitch)
|
||||
setRotation(yaw, pitch)
|
||||
val rotation = EntityRotation(yaw, pitch)
|
||||
connection.player.rotation = rotation
|
||||
setRotation(rotation)
|
||||
}
|
||||
|
||||
private fun calculateFogDistance() {
|
||||
@ -273,7 +272,7 @@ class Camera(
|
||||
}
|
||||
|
||||
private fun onPositionChange() {
|
||||
setRotation(connection.player.rotation.yaw, connection.player.rotation.pitch)
|
||||
setRotation(connection.player.rotation)
|
||||
recalculateViewProjectionMatrix()
|
||||
frustum.recalculate()
|
||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
||||
@ -310,12 +309,8 @@ class Camera(
|
||||
return glm.lookAt(eyePosition, eyePosition + cameraFront, CAMERA_UP_VEC3)
|
||||
}
|
||||
|
||||
private fun setRotation(yaw: Double, pitch: Double) {
|
||||
cameraFront = Vec3d(
|
||||
(yaw + 90).rad.cos * (-pitch).rad.cos,
|
||||
(-pitch).rad.sin,
|
||||
(yaw + 90).rad.sin * (-pitch).rad.cos
|
||||
).normalize()
|
||||
private fun setRotation(rotation: EntityRotation) {
|
||||
cameraFront = rotation.front
|
||||
|
||||
cameraRight = (cameraFront cross CAMERA_UP_VEC3).normalize()
|
||||
cameraUp = (cameraRight cross cameraFront).normalize()
|
||||
|
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering.particle
|
||||
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
@ -27,22 +26,30 @@ import glm_.vec3.Vec3d
|
||||
|
||||
class ParticleMesh(renderWindow: RenderWindow, data: DirectArrayFloatList) : Mesh(renderWindow, ParticleMeshStruct, PrimitiveTypes.POINT, -1, clearOnLoad = false, data = data) {
|
||||
|
||||
fun addVertex(position: Vec3d, scale: Float, texture: AbstractTexture, tintColor: RGBColor, uvMin: Vec2 = Vec2(0.0f, 0.0f), uvMax: Vec2 = Vec2(1.0f, 1.0f)) {
|
||||
val minTransformedUV = texture.renderData?.transformUV(uvMin) ?: uvMin
|
||||
val maxTransformedUV = texture.renderData?.transformUV(uvMax) ?: uvMax
|
||||
fun addVertex(position: Vec3d, scale: Float, texture: AbstractTexture, tintColor: RGBColor, uvMin: FloatArray? = null, uvMax: FloatArray? = null) {
|
||||
val minTransformedUV = if (uvMin == null) {
|
||||
EMPTY_UV_ARRAY
|
||||
} else {
|
||||
texture.renderData.transformUV(uvMin)
|
||||
}
|
||||
val maxTransformedUV = texture.renderData.transformUV(uvMax)
|
||||
data.add(position.x.toFloat())
|
||||
data.add(position.y.toFloat())
|
||||
data.add(position.z.toFloat())
|
||||
data.add(minTransformedUV.x)
|
||||
data.add(minTransformedUV.y)
|
||||
data.add(maxTransformedUV.x)
|
||||
data.add(maxTransformedUV.y)
|
||||
data.add(Float.fromBits(texture.renderData?.shaderTextureId ?: RenderConstants.DEBUG_TEXTURE_ID))
|
||||
data.add(minTransformedUV[0])
|
||||
data.add(minTransformedUV[1])
|
||||
data.add(maxTransformedUV[0])
|
||||
data.add(maxTransformedUV[1])
|
||||
data.add(Float.fromBits(texture.renderData.shaderTextureId))
|
||||
data.add(scale)
|
||||
data.add(Float.fromBits(tintColor.rgba))
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private val EMPTY_UV_ARRAY = floatArrayOf(0.0f, 0.0f)
|
||||
}
|
||||
|
||||
data class ParticleMeshStruct(
|
||||
val position: Vec3,
|
||||
val minUVCoordinates: Vec2,
|
||||
|
@ -15,10 +15,7 @@ package de.bixilon.minosoft.gui.rendering.particle
|
||||
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.Renderer
|
||||
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
||||
import de.bixilon.minosoft.gui.rendering.*
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.Particle
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||
@ -55,9 +52,9 @@ class ParticleRenderer(
|
||||
private var translucentMesh = ParticleMesh(renderWindow, DirectArrayFloatList(RenderConstants.MAXIMUM_PARTICLE_AMOUNT * ParticleMesh.ParticleMeshStruct.FLOATS_PER_VERTEX))
|
||||
|
||||
private val particlesLock = ReadWriteLock()
|
||||
private var particles: MutableSet<Particle> = mutableSetOf()
|
||||
private var particles: MutableList<Particle> = mutableListOf()
|
||||
private var particleQueueLock = ReadWriteLock()
|
||||
private var particleQueue: MutableSet<Particle> = mutableSetOf()
|
||||
private var particleQueue: MutableList<Particle> = mutableListOf()
|
||||
|
||||
|
||||
private lateinit var particleTask: TimeWorkerTask
|
||||
@ -107,19 +104,38 @@ class ParticleRenderer(
|
||||
connection.world.particleRenderer = this
|
||||
|
||||
particleTask = TimeWorker.addTask(TimeWorkerTask(ProtocolDefinition.TICK_TIME, maxDelayTime = ProtocolDefinition.TICK_TIME / 2) {
|
||||
if (renderWindow.renderingState == RenderingStates.PAUSED || renderWindow.renderingState == RenderingStates.STOPPED) {
|
||||
return@TimeWorkerTask
|
||||
}
|
||||
|
||||
val cameraLength = connection.player.position.length()
|
||||
val toRemove: MutableSet<Particle> = mutableSetOf()
|
||||
|
||||
particlesLock.acquire()
|
||||
try {
|
||||
val time = KUtil.time
|
||||
for (particle in particles) {
|
||||
if (particle.position.length() - cameraLength >= Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X) {
|
||||
particle.dead = true
|
||||
toRemove += particle
|
||||
} else if (particle.dead) {
|
||||
toRemove += particle
|
||||
}
|
||||
particle.tryTick(time)
|
||||
}
|
||||
} finally {
|
||||
particlesLock.release()
|
||||
}
|
||||
|
||||
particlesLock.lock()
|
||||
particles -= toRemove
|
||||
|
||||
particleQueueLock.lock()
|
||||
particles += particleQueue
|
||||
particleQueue.clear()
|
||||
particleQueueLock.unlock()
|
||||
|
||||
particlesLock.unlock()
|
||||
})
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<PlayConnectionStateChangeEvent> {
|
||||
@ -131,6 +147,9 @@ class ParticleRenderer(
|
||||
}
|
||||
|
||||
fun add(particle: Particle) {
|
||||
if (renderWindow.renderingState == RenderingStates.PAUSED || renderWindow.renderingState == RenderingStates.STOPPED) {
|
||||
return
|
||||
}
|
||||
val particleCount = particles.size
|
||||
if (particleCount >= RenderConstants.MAXIMUM_PARTICLE_AMOUNT) {
|
||||
Log.log(LogMessageType.RENDERING_GENERAL, LogLevels.WARN) { "Can not add particle: Limit reached (${particleCount} > ${RenderConstants.MAXIMUM_PARTICLE_AMOUNT}" }
|
||||
@ -154,26 +173,17 @@ class ParticleRenderer(
|
||||
transparentMesh.unload()
|
||||
translucentMesh.unload()
|
||||
|
||||
val toRemove: MutableSet<Particle> = mutableSetOf()
|
||||
|
||||
transparentMesh.data.clear()
|
||||
translucentMesh.data.clear()
|
||||
transparentMesh = ParticleMesh(renderWindow, transparentMesh.data)
|
||||
translucentMesh = ParticleMesh(renderWindow, translucentMesh.data)
|
||||
|
||||
|
||||
particlesLock.lock()
|
||||
particleQueueLock.acquire()
|
||||
particles += particleQueue
|
||||
particleQueueLock.release()
|
||||
particlesLock.unlock()
|
||||
|
||||
particlesLock.acquire()
|
||||
|
||||
val time = KUtil.time
|
||||
for (particle in particles) {
|
||||
if (particle.dead) {
|
||||
toRemove += particle
|
||||
continue
|
||||
}
|
||||
particle.addVertex(transparentMesh, translucentMesh, time)
|
||||
@ -181,12 +191,6 @@ class ParticleRenderer(
|
||||
|
||||
particlesLock.release()
|
||||
|
||||
if (toRemove.isNotEmpty()) {
|
||||
particlesLock.lock()
|
||||
particles -= toRemove
|
||||
particlesLock.unlock()
|
||||
}
|
||||
|
||||
transparentMesh.load()
|
||||
translucentMesh.load()
|
||||
}
|
||||
|
@ -25,11 +25,11 @@ abstract class AdvancedTextureParticle(connection: PlayConnection, position: Vec
|
||||
var minUV: Vec2 = Vec2(0.0f, 0.0f)
|
||||
var maxUV: Vec2 = Vec2(1.0f, 1.0f)
|
||||
|
||||
override fun addVertex(transparentMesh: ParticleMesh, translucentMesh: ParticleMesh, time:Long) {
|
||||
override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh, time: Long) {
|
||||
val texture = texture ?: return
|
||||
when {
|
||||
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh
|
||||
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh
|
||||
else -> transparentMesh
|
||||
}.addVertex(getCameraPosition(time), scale, texture, color, minUV, maxUV)
|
||||
}.addVertex(getCameraPosition(time), scale, texture, color, minUV.array, maxUV.array)
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ interface AbstractTexture {
|
||||
val transparency: TextureTransparencies
|
||||
var properties: ImageProperties
|
||||
|
||||
var renderData: TextureRenderData?
|
||||
var renderData: TextureRenderData
|
||||
|
||||
var data: ByteBuffer?
|
||||
|
||||
|
@ -33,7 +33,7 @@ class MemoryTexture(
|
||||
) : AbstractTexture {
|
||||
override lateinit var textureArrayUV: Vec2
|
||||
override lateinit var singlePixelSize: Vec2
|
||||
override var renderData: TextureRenderData? = null
|
||||
override lateinit var renderData: TextureRenderData
|
||||
override var transparency: TextureTransparencies = TextureTransparencies.OPAQUE
|
||||
private set
|
||||
override var data: ByteBuffer? = null
|
||||
|
@ -26,7 +26,7 @@ import java.nio.ByteBuffer
|
||||
|
||||
|
||||
class PNGTexture(override val resourceLocation: ResourceLocation) : AbstractTexture {
|
||||
override var renderData: TextureRenderData? = null
|
||||
override lateinit var renderData: TextureRenderData
|
||||
|
||||
override lateinit var textureArrayUV: Vec2
|
||||
override lateinit var singlePixelSize: Vec2
|
||||
|
@ -28,7 +28,7 @@ class SpriteTexture(private val original: AbstractTexture) : AbstractTexture {
|
||||
override var textureArrayUV: Vec2 by original::textureArrayUV
|
||||
override var singlePixelSize: Vec2 by original::singlePixelSize
|
||||
override var properties: ImageProperties by original::properties
|
||||
override var renderData: TextureRenderData? by original::renderData
|
||||
override var renderData: TextureRenderData by original::renderData
|
||||
override val transparency: TextureTransparencies by original::transparency
|
||||
|
||||
override var state: TextureStates = TextureStates.DECLARED
|
||||
|
@ -19,5 +19,6 @@ interface TextureRenderData {
|
||||
val shaderTextureId: Int
|
||||
val animationData: Int
|
||||
|
||||
fun transformUV(end: Vec2): Vec2
|
||||
fun transformUV(end: Vec2?): Vec2
|
||||
fun transformUV(end: FloatArray?): FloatArray
|
||||
}
|
||||
|
@ -22,12 +22,31 @@ class OpenGLTextureData(
|
||||
val uvEnd: Vec2?,
|
||||
override val animationData: Int = -1,
|
||||
) : TextureRenderData {
|
||||
private val uvEndArray = uvEnd?.array
|
||||
override val shaderTextureId: Int = (array shl 28) or (index shl 12) or (animationData + 1)
|
||||
|
||||
override fun transformUV(end: Vec2): Vec2 {
|
||||
if (uvEnd == null) {
|
||||
override fun transformUV(end: Vec2?): Vec2 {
|
||||
if (end == null) {
|
||||
return uvEnd ?: VEC2_ONE
|
||||
}
|
||||
if (uvEndArray == null) {
|
||||
return end
|
||||
}
|
||||
return end * uvEnd
|
||||
return Vec2(end.x * uvEndArray[0], end.y * uvEndArray[1])
|
||||
}
|
||||
|
||||
override fun transformUV(end: FloatArray?): FloatArray {
|
||||
if (end == null) {
|
||||
return uvEndArray ?: ONE_ARRAY
|
||||
}
|
||||
if (uvEndArray == null) {
|
||||
return end
|
||||
}
|
||||
return floatArrayOf(end[0] * uvEndArray[0], end[1] * uvEndArray[1])
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val VEC2_ONE = Vec2(1.0f, 1.0f)
|
||||
private val ONE_ARRAY = VEC2_ONE.array
|
||||
}
|
||||
}
|
||||
|
@ -22,14 +22,10 @@ import glm_.vec3.Vec3
|
||||
open class GenericColorMesh(renderWindow: RenderWindow, primitiveType: PrimitiveTypes = renderWindow.renderSystem.preferredPrimitiveType) : Mesh(renderWindow, GenericColorMeshStruct, primitiveType) {
|
||||
|
||||
fun addVertex(position: Vec3, color: RGBColor?) {
|
||||
data.addAll(
|
||||
floatArrayOf(
|
||||
position.x,
|
||||
position.y,
|
||||
position.z,
|
||||
Float.fromBits((color ?: ChatColors.WHITE).rgba)
|
||||
)
|
||||
)
|
||||
data.add(position.x)
|
||||
data.add(position.y)
|
||||
data.add(position.z)
|
||||
data.add(Float.fromBits((color ?: ChatColors.WHITE).rgba))
|
||||
}
|
||||
|
||||
data class GenericColorMeshStruct(
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.util.mesh
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.AABB
|
||||
import de.bixilon.minosoft.data.registries.VoxelShape
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
@ -59,6 +60,15 @@ open class LineMesh(renderWindow: RenderWindow) : GenericColorMesh(renderWindow)
|
||||
drawAABB(aabb + position, lineWidth, color, margin)
|
||||
}
|
||||
|
||||
fun drawLazyAABB(aabb: AABB, color: RGBColor) {
|
||||
for (direction in Directions.VALUES) {
|
||||
val positions = direction.getPositions(Vec3(aabb.min), Vec3(aabb.max))
|
||||
for ((positionIndex, _) in order) {
|
||||
addVertex(positions[positionIndex], color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun drawAABB(aabb: AABB, lineWidth: Float = RenderConstants.DEFAULT_LINE_WIDTH, color: RGBColor, margin: Float = 0.0f) {
|
||||
val min = aabb.min - margin
|
||||
val max = aabb.max + margin
|
||||
|
@ -47,6 +47,7 @@ class DirectArrayFloatList(
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun ensureSize(needed: Int) {
|
||||
checkFinalized()
|
||||
if (limit - size >= needed) {
|
||||
|
@ -14,8 +14,7 @@
|
||||
#version 330
|
||||
|
||||
layout (points) in;
|
||||
layout (triangle_strip) out;
|
||||
layout (max_vertices = 4) out;
|
||||
layout (triangle_strip, max_vertices = 4) out;
|
||||
|
||||
uniform mat4 uViewProjectionMatrix;
|
||||
uniform vec3 uCameraRight;
|
||||
|
Loading…
x
Reference in New Issue
Block a user