mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 02:15:34 -04:00
wip refactor entity rendering
This commit is contained in:
parent
8fd9456a64
commit
1bc96ceb09
@ -228,7 +228,8 @@ testing {
|
|||||||
options {
|
options {
|
||||||
val options = this as TestNGOptions
|
val options = this as TestNGOptions
|
||||||
options.preserveOrder = true
|
options.preserveOrder = true
|
||||||
// options.excludeGroups("models", "mesher", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "rendering")
|
// options.excludeGroups("models", "mesher", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "rendering", "texture", "atlas", "gui")
|
||||||
|
options.excludeGroups("models", "mesher", "chunk", "input", "font", "command", "registry", "biome", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "chunk_renderer", "texture", "atlas", "gui")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,4 +40,27 @@ Entities are always designed without any rotation (i.e. `yaw`=`0`)
|
|||||||
- shoulder entities (parrots)
|
- shoulder entities (parrots)
|
||||||
- held item
|
- held item
|
||||||
- light (shade and lightmap)
|
- light (shade and lightmap)
|
||||||
-
|
|
||||||
|
## General
|
||||||
|
|
||||||
|
- render layers (opaque -> transparent -> translucent -> ...) (but face culling enabled)
|
||||||
|
- sort in layers after distance (or -distance)
|
||||||
|
- there are also invisible renderers (like AreaEffectCloud is just emitting particles)
|
||||||
|
- update all models async (with their visibility, etc)
|
||||||
|
- queue for unloading and loading meshes before draw (better while async preparing to save time. Maybe port that system to block entities)
|
||||||
|
- Loop over all visible entity renderers and work on the entity layer as needed
|
||||||
|
- update visible and not visible
|
||||||
|
- entity name is also visible through walls, rest not
|
||||||
|
- also with frustum (no need to update renderers that are out of the frustum)
|
||||||
|
- option to turn on/off "features"
|
||||||
|
- how to register entity models?
|
||||||
|
- loop over all entity (and block entity) types and register?
|
||||||
|
|
||||||
|
## Hitboxes
|
||||||
|
|
||||||
|
- Create line mesh with default aabb
|
||||||
|
- interpolate aabb if size changes (e.g. changing pose for players)
|
||||||
|
- how about rendering velocity or view?
|
||||||
|
- Store offset and rotation as uniform
|
||||||
|
- Make hitbox a default feature of entity renderer
|
||||||
|
- draw as opaque
|
||||||
|
@ -32,9 +32,9 @@ import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
|
|||||||
import de.bixilon.minosoft.data.text.ChatComponent
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
|
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
|
||||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
|
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.models.DummyModel
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.DummyEntityRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.models.EntityModel
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||||
import de.bixilon.minosoft.physics.entities.EntityPhysics
|
import de.bixilon.minosoft.physics.entities.EntityPhysics
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
@ -85,7 +85,7 @@ abstract class Entity(
|
|||||||
|
|
||||||
var lastTickTime = -1L
|
var lastTickTime = -1L
|
||||||
|
|
||||||
open var model: EntityModel<*>? = null
|
open var renderer: EntityRenderer<*>? = null
|
||||||
|
|
||||||
open val physics: EntityPhysics<*> = unsafeNull()
|
open val physics: EntityPhysics<*> = unsafeNull()
|
||||||
|
|
||||||
@ -229,13 +229,8 @@ abstract class Entity(
|
|||||||
|
|
||||||
open fun onAttack(attacker: Entity) = true
|
open fun onAttack(attacker: Entity) = true
|
||||||
|
|
||||||
open fun createModel(renderer: EntityRenderer): EntityModel<*>? {
|
open fun createRenderer(renderer: EntitiesRenderer): EntityRenderer<*>? = DummyEntityRenderer(renderer, this)
|
||||||
return DummyModel(renderer, this).apply { this@Entity.model = this }
|
open fun createPhysics(): EntityPhysics<*> = EntityPhysics(this)
|
||||||
}
|
|
||||||
|
|
||||||
open fun createPhysics(): EntityPhysics<*> {
|
|
||||||
return EntityPhysics(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun physics(): EntityPhysics<*> = physics.unsafeCast()
|
open fun physics(): EntityPhysics<*> = physics.unsafeCast()
|
||||||
|
|
||||||
|
@ -98,9 +98,7 @@ abstract class LivingEntity(connection: PlayConnection, entityType: EntityType,
|
|||||||
else -> super.hitboxColor
|
else -> super.hitboxColor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createPhysics(): LivingEntityPhysics<*> {
|
override fun createPhysics(): LivingEntityPhysics<*> = LivingEntityPhysics(this)
|
||||||
return LivingEntityPhysics(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
super.tick()
|
super.tick()
|
||||||
|
@ -135,9 +135,7 @@ abstract class PlayerEntity(
|
|||||||
return ChatColors.RED
|
return ChatColors.RED
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createPhysics(): PlayerPhysics<*> {
|
override fun createPhysics(): PlayerPhysics<*> = PlayerPhysics(this)
|
||||||
return PlayerPhysics(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun swingHand(hand: Hands) {
|
fun swingHand(hand: Hands) {
|
||||||
|
@ -13,15 +13,12 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.data.entities.event.events.damage
|
package de.bixilon.minosoft.data.entities.event.events.damage
|
||||||
|
|
||||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
|
||||||
import de.bixilon.minosoft.data.entities.entities.LivingEntity
|
import de.bixilon.minosoft.data.entities.entities.LivingEntity
|
||||||
import de.bixilon.minosoft.data.entities.event.EntityEvent
|
import de.bixilon.minosoft.data.entities.event.EntityEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.models.DamageableModel
|
|
||||||
|
|
||||||
interface DamageEvent : EntityEvent<LivingEntity> {
|
interface DamageEvent : EntityEvent<LivingEntity> {
|
||||||
|
|
||||||
override fun handle(entity: LivingEntity) {
|
override fun handle(entity: LivingEntity) {
|
||||||
entity.model?.nullCast<DamageableModel>()?.onDamage()
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,9 @@ class RenderLoop(
|
|||||||
context.input.draw(deltaFrameTime)
|
context.input.draw(deltaFrameTime)
|
||||||
context.camera.draw()
|
context.camera.draw()
|
||||||
|
|
||||||
|
val state = context.connection.registries.block["chest"]!!.states.default
|
||||||
|
context.connection.world[4, -60, 1] = state
|
||||||
|
|
||||||
// handle opengl context tasks, but limit it per frame
|
// handle opengl context tasks, but limit it per frame
|
||||||
context.queue.timeWork(RenderConstants.MAXIMUM_QUEUE_TIME_PER_FRAME)
|
context.queue.timeWork(RenderConstants.MAXIMUM_QUEUE_TIME_PER_FRAME)
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ import de.bixilon.kutil.concurrent.queue.Queue
|
|||||||
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||||
import de.bixilon.kutil.observer.DataObserver.Companion.observed
|
import de.bixilon.kutil.observer.DataObserver.Companion.observed
|
||||||
import de.bixilon.minosoft.gui.rendering.camera.Camera
|
import de.bixilon.minosoft.gui.rendering.camera.Camera
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.RenderLight
|
|
||||||
import de.bixilon.minosoft.gui.rendering.font.manager.FontManager
|
import de.bixilon.minosoft.gui.rendering.font.manager.FontManager
|
||||||
import de.bixilon.minosoft.gui.rendering.framebuffer.FramebufferManager
|
import de.bixilon.minosoft.gui.rendering.framebuffer.FramebufferManager
|
||||||
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
import de.bixilon.minosoft.gui.rendering.input.key.manager.InputManager
|
||||||
|
import de.bixilon.minosoft.gui.rendering.light.RenderLight
|
||||||
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
|
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
|
||||||
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererManager
|
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererManager
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.ShaderManager
|
import de.bixilon.minosoft.gui.rendering.shader.ShaderManager
|
||||||
|
@ -20,7 +20,7 @@ import de.bixilon.minosoft.data.entities.entities.player.local.LocalPlayerEntity
|
|||||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderUtil.runAsync
|
import de.bixilon.minosoft.gui.rendering.RenderUtil.runAsync
|
||||||
import de.bixilon.minosoft.gui.rendering.camera.view.ViewManager
|
import de.bixilon.minosoft.gui.rendering.camera.view.ViewManager
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.view.WorldVisibilityGraph
|
import de.bixilon.minosoft.gui.rendering.camera.visibility.WorldVisibilityGraph
|
||||||
|
|
||||||
class Camera(
|
class Camera(
|
||||||
val context: RenderContext,
|
val context: RenderContext,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -11,6 +11,6 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.view
|
package de.bixilon.minosoft.gui.rendering.camera.visibility
|
||||||
|
|
||||||
typealias VisibilityGraph = Array<Array<BooleanArray?>?>
|
typealias VisibilityGraph = Array<Array<BooleanArray?>?>
|
@ -11,7 +11,7 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.view
|
package de.bixilon.minosoft.gui.rendering.camera.visibility
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.func.common.clamp
|
import de.bixilon.kotlinglm.func.common.clamp
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
import de.bixilon.kotlinglm.vec2.Vec2i
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.chunk.shader
|
|||||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.minosoft.gui.rendering.camera.FogManager
|
import de.bixilon.minosoft.gui.rendering.camera.FogManager
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.types.*
|
import de.bixilon.minosoft.gui.rendering.shader.types.*
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
|
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.chunk.shader
|
|||||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.minosoft.gui.rendering.camera.FogManager
|
import de.bixilon.minosoft.gui.rendering.camera.FogManager
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.types.FogShader
|
import de.bixilon.minosoft.gui.rendering.shader.types.FogShader
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.types.LightShader
|
import de.bixilon.minosoft.gui.rendering.shader.types.LightShader
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.entities
|
||||||
|
|
||||||
|
import de.bixilon.kutil.concurrent.queue.Queue
|
||||||
|
import de.bixilon.kutil.latch.AbstractLatch
|
||||||
|
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||||
|
import de.bixilon.kutil.time.TimeUtil.millis
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.hitbox.HitboxManager
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.visibility.VisibilityManager
|
||||||
|
import de.bixilon.minosoft.gui.rendering.renderer.renderer.AsyncRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererBuilder
|
||||||
|
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.LayerSettings
|
||||||
|
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.WorldRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||||
|
import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.system.base.layer.TranslucentLayer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.system.base.settings.RenderSettings
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
|
class EntitiesRenderer(
|
||||||
|
val connection: PlayConnection,
|
||||||
|
override val context: RenderContext,
|
||||||
|
) : WorldRenderer, AsyncRenderer {
|
||||||
|
override val layers = LayerSettings()
|
||||||
|
override val renderSystem: RenderSystem = context.system
|
||||||
|
val profile = connection.profiles.entity
|
||||||
|
val visibilityGraph = context.camera.visibilityGraph
|
||||||
|
val hitbox = HitboxManager(this)
|
||||||
|
val renderers = EntityRendererManager(this)
|
||||||
|
val visibility = VisibilityManager(this)
|
||||||
|
val queue = Queue()
|
||||||
|
|
||||||
|
|
||||||
|
private var reset = false
|
||||||
|
|
||||||
|
override fun registerLayers() {
|
||||||
|
layers.register(EntityLayer, null, this::draw) { visibility.size <= 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun prePrepareDraw() {
|
||||||
|
queue.work()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun prepareDrawAsync() {
|
||||||
|
val millis = millis()
|
||||||
|
this.visibility.reset()
|
||||||
|
renderers.iterate {
|
||||||
|
if (reset) it.reset()
|
||||||
|
visibility.update(it)
|
||||||
|
it.update(millis)
|
||||||
|
}
|
||||||
|
this.reset = false
|
||||||
|
this.visibility.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postPrepareDraw() {
|
||||||
|
queue.work()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun init(latch: AbstractLatch) {
|
||||||
|
context.camera.offset::offset.observe(this) { reset = true }
|
||||||
|
hitbox.init()
|
||||||
|
renderers.init()
|
||||||
|
visibility.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun draw() {
|
||||||
|
for (feature in visibility) {
|
||||||
|
feature.draw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object EntityLayer : RenderLayer {
|
||||||
|
override val settings = RenderSettings(faceCulling = false)
|
||||||
|
override val priority: Int get() = TranslucentLayer.priority - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
companion object : RendererBuilder<EntitiesRenderer> {
|
||||||
|
|
||||||
|
override fun build(connection: PlayConnection, context: RenderContext): EntitiesRenderer {
|
||||||
|
return EntitiesRenderer(connection, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.entities
|
||||||
|
|
||||||
|
import de.bixilon.kutil.collections.iterator.async.ConcurrentIterator
|
||||||
|
import de.bixilon.kutil.collections.map.LockMap
|
||||||
|
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
|
||||||
|
import de.bixilon.kutil.concurrent.pool.ThreadPool
|
||||||
|
import de.bixilon.kutil.observer.set.SetObserver.Companion.observeSet
|
||||||
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||||
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
|
import de.bixilon.minosoft.util.logging.LogLevels
|
||||||
|
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||||
|
|
||||||
|
class EntityRendererManager(val renderer: EntitiesRenderer) : Iterable<EntityRenderer<*>> {
|
||||||
|
val lock = SimpleLock()
|
||||||
|
private val renderers: LockMap<Entity, EntityRenderer<*>> = LockMap(HashMap(), lock)
|
||||||
|
|
||||||
|
|
||||||
|
val size: Int get() = renderers.size
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
renderer.connection.world.entities::entities.observeSet(this) {
|
||||||
|
for (entity in it.adds) {
|
||||||
|
this += entity
|
||||||
|
}
|
||||||
|
for (entity in it.removes) {
|
||||||
|
this -= entity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun plusAssign(entity: Entity) = add(entity)
|
||||||
|
fun add(entity: Entity) {
|
||||||
|
try {
|
||||||
|
renderers.lock.lock()
|
||||||
|
val renderer = entity.createRenderer(this.renderer) ?: return
|
||||||
|
entity.renderer?.let { onReplace(it) }
|
||||||
|
this.renderers.unsafe.put(entity, renderer)?.let { onReplace(it) }
|
||||||
|
} finally {
|
||||||
|
renderers.lock.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("That should never ever happen!")
|
||||||
|
private fun onReplace(renderer: EntityRenderer<*>) {
|
||||||
|
Log.log(LogMessageType.RENDERING, LogLevels.WARN) { "Entity renderer of ${renderer.entity} just got replaced???" }
|
||||||
|
unload(renderer)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun minusAssign(entity: Entity) = remove(entity)
|
||||||
|
fun remove(entity: Entity) {
|
||||||
|
renderers.lock.lock()
|
||||||
|
val previous = renderers.unsafe.remove(entity)
|
||||||
|
entity.renderer = null
|
||||||
|
renderers.lock.unlock()
|
||||||
|
previous?.let { unload(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun unload(renderer: EntityRenderer<*>) {
|
||||||
|
this.renderer.queue += { renderer.unload() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<EntityRenderer<*>> {
|
||||||
|
return renderers.unsafe.values.iterator()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun iterate(executor: ((EntityRenderer<*>) -> Unit)) {
|
||||||
|
lock.acquire()
|
||||||
|
ConcurrentIterator(renderers.unsafe.values.spliterator(), priority = ThreadPool.HIGHER).iterate(executor)
|
||||||
|
lock.release()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.entities.feature
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||||
|
|
||||||
|
abstract class EntityRenderFeature(val renderer: EntityRenderer<*>) {
|
||||||
|
var enabled = true
|
||||||
|
open val priority: Int get() = 0
|
||||||
|
|
||||||
|
open fun updateVisibility(occluded: Boolean, visible: Boolean): Boolean {
|
||||||
|
val enabled = !occluded && visible
|
||||||
|
if (this.enabled == enabled) return false
|
||||||
|
this.enabled = enabled
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun update(millis: Long) = Unit
|
||||||
|
open fun unload() = Unit
|
||||||
|
|
||||||
|
abstract fun draw()
|
||||||
|
}
|
@ -11,16 +11,27 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.skeletal
|
package de.bixilon.minosoft.gui.rendering.entities.feature
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.models.block.element.FaceVertexData
|
|
||||||
import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalConsumer
|
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
|
|
||||||
|
|
||||||
class DummySkeletalConsumer : SkeletalConsumer {
|
class FeatureManager(val renderer: EntityRenderer<*>) {
|
||||||
|
|
||||||
override fun addQuad(positions: FaceVertexData, uv: FaceVertexData, transform: Int, normal: Vec3, texture: ShaderTexture) {
|
|
||||||
TODO("Not yet implemented")
|
operator fun plusAssign(feature: EntityRenderFeature) = register(feature)
|
||||||
|
fun register(feature: EntityRenderFeature) {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update(millis: Long) {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unload() {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.entities.feature
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
|
||||||
|
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
|
||||||
|
|
||||||
|
class SkeletalFeature(
|
||||||
|
renderer: EntityRenderer<*>,
|
||||||
|
val instance: SkeletalInstance,
|
||||||
|
) : EntityRenderFeature(renderer) {
|
||||||
|
private val manager = renderer.renderer.context.skeletal
|
||||||
|
|
||||||
|
constructor(renderer: EntityRenderer<*>, model: BakedSkeletalModel) : this(renderer, model.createInstance(renderer.renderer.context))
|
||||||
|
|
||||||
|
override fun update(millis: Long) {
|
||||||
|
instance.transform.reset()
|
||||||
|
instance.animation.draw(millis)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun draw() {
|
||||||
|
manager.upload(instance)
|
||||||
|
instance.model.mesh.draw()
|
||||||
|
}
|
||||||
|
}
|
@ -11,30 +11,16 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.entity.hitbox
|
package de.bixilon.minosoft.gui.rendering.entities.hitbox
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
|
||||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||||
|
|
||||||
data class HitboxData(
|
data class HitboxData(
|
||||||
|
val aabb: AABB,
|
||||||
val color: RGBColor,
|
val color: RGBColor,
|
||||||
val velocity: Vec3d?,
|
val velocity: Vec3?,
|
||||||
val rotation: EntityRotation,
|
val rotation: EntityRotation,
|
||||||
) {
|
)
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
fun of(entity: Entity): HitboxData? {
|
|
||||||
val color = entity.hitboxColor ?: return null
|
|
||||||
var velocity: Vec3d? = entity.physics.velocity
|
|
||||||
if (velocity!!.length2() < 0.003) {
|
|
||||||
velocity = null
|
|
||||||
}
|
|
||||||
val rotation = entity.renderInfo.rotation
|
|
||||||
|
|
||||||
return HitboxData(color, velocity, rotation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -11,18 +11,14 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.entity
|
package de.bixilon.minosoft.gui.rendering.entities.hitbox
|
||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable
|
import de.bixilon.minosoft.gui.rendering.entities.feature.EntityRenderFeature
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||||
|
|
||||||
interface ModelUpdater : Drawable {
|
class HitboxFeature(renderer: EntityRenderer<*>) : EntityRenderFeature(renderer) {
|
||||||
|
|
||||||
fun checkUpdate(): Boolean = false
|
override fun draw() {
|
||||||
|
TODO("Not yet implemented")
|
||||||
fun prepareAsync() = Unit
|
}
|
||||||
fun prepare() = Unit
|
|
||||||
|
|
||||||
fun unload() = Unit
|
|
||||||
|
|
||||||
fun reset() = Unit
|
|
||||||
}
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.entities.hitbox
|
||||||
|
|
||||||
|
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||||
|
import de.bixilon.minosoft.config.key.KeyActions
|
||||||
|
import de.bixilon.minosoft.config.key.KeyBinding
|
||||||
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
|
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
|
||||||
|
import de.bixilon.minosoft.util.KUtil.format
|
||||||
|
|
||||||
|
class HitboxManager(private val renderer: EntitiesRenderer) {
|
||||||
|
private val profile = renderer.profile.hitbox
|
||||||
|
var enabled = profile.enabled
|
||||||
|
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
profile::enabled.observe(this) { this.enabled = it }
|
||||||
|
registerKeybinding()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerKeybinding() {
|
||||||
|
renderer.context.input.bindings.register(TOGGLE, KeyBinding(
|
||||||
|
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
||||||
|
KeyActions.STICKY to setOf(KeyCodes.KEY_B),
|
||||||
|
), pressed = enabled
|
||||||
|
) {
|
||||||
|
profile.enabled = it
|
||||||
|
renderer.connection.util.sendDebugMessage("Entity hit boxes: ${it.format()}")
|
||||||
|
enabled = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TOGGLE = minosoft("toggle_hitboxes")
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -11,10 +11,9 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.entity.models
|
package de.bixilon.minosoft.gui.rendering.entities.renderer
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
|
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
|
||||||
|
|
||||||
@Deprecated("TODO")
|
class DummyEntityRenderer(renderer: EntitiesRenderer, entity: Entity) : EntityRenderer<Entity>(renderer, entity)
|
||||||
class DummyModel(renderer: EntityRenderer, entity: Entity) : EntityModel<Entity>(renderer, entity)
|
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.entities.renderer
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.feature.EntityRenderFeature
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.feature.FeatureManager
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.hitbox.HitboxFeature
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.visibility.EntityVisibility
|
||||||
|
|
||||||
|
abstract class EntityRenderer<E : Entity>(
|
||||||
|
val renderer: EntitiesRenderer,
|
||||||
|
val entity: Entity,
|
||||||
|
) {
|
||||||
|
val features = FeatureManager(this)
|
||||||
|
val visibility = EntityVisibility(this)
|
||||||
|
|
||||||
|
val hitbox = HitboxFeature(this).register()
|
||||||
|
|
||||||
|
fun <T : EntityRenderFeature> T.register(): T {
|
||||||
|
features += this
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun update(millis: Long) {
|
||||||
|
entity.draw(millis)
|
||||||
|
features.update(millis)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun unload() {
|
||||||
|
features.unload()
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun reset() {
|
||||||
|
features.reset()
|
||||||
|
}
|
||||||
|
}
|
@ -11,9 +11,14 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.entity.models
|
package de.bixilon.minosoft.gui.rendering.entities.visibility
|
||||||
|
|
||||||
interface DamageableModel {
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||||
|
|
||||||
fun onDamage()
|
class EntityVisibility(val renderer: EntityRenderer<*>) {
|
||||||
|
val visible: Boolean = true
|
||||||
|
|
||||||
|
fun update(force: Boolean) {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.entities.visibility
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.feature.EntityRenderFeature
|
||||||
|
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.events.VisibilityGraphChangeEvent
|
||||||
|
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
|
class VisibilityManager(val renderer: EntitiesRenderer) : Iterable<EntityRenderFeature> {
|
||||||
|
private var update = false
|
||||||
|
var size: Int = 0
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val count = AtomicInteger()
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
renderer.connection.events.listen<VisibilityGraphChangeEvent> { update = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
count.set(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update(renderer: EntityRenderer<*>) {
|
||||||
|
renderer.visibility.update(this.update)
|
||||||
|
if (renderer.visibility.visible) {
|
||||||
|
count.incrementAndGet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun finish() {
|
||||||
|
this.update = false
|
||||||
|
size = count.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<EntityRenderFeature> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
* Minosoft
|
|
||||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.entity
|
|
||||||
|
|
||||||
import de.bixilon.kutil.collections.CollectionUtil.lockMapOf
|
|
||||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedListOf
|
|
||||||
import de.bixilon.kutil.collections.iterator.async.ConcurrentIterator
|
|
||||||
import de.bixilon.kutil.collections.map.LockMap
|
|
||||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
|
||||||
import de.bixilon.kutil.concurrent.pool.ThreadPool
|
|
||||||
import de.bixilon.kutil.latch.AbstractLatch
|
|
||||||
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
|
||||||
import de.bixilon.kutil.time.TimeUtil.millis
|
|
||||||
import de.bixilon.minosoft.config.key.KeyActions
|
|
||||||
import de.bixilon.minosoft.config.key.KeyBinding
|
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
|
||||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
|
||||||
import de.bixilon.minosoft.data.entities.entities.player.local.LocalPlayerEntity
|
|
||||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.models.EntityModel
|
|
||||||
import de.bixilon.minosoft.gui.rendering.events.VisibilityGraphChangeEvent
|
|
||||||
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererBuilder
|
|
||||||
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.LayerSettings
|
|
||||||
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.WorldRenderer
|
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer
|
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.settings.RenderSettings
|
|
||||||
import de.bixilon.minosoft.modding.event.events.EntityDestroyEvent
|
|
||||||
import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent
|
|
||||||
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
|
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
|
||||||
import de.bixilon.minosoft.util.KUtil.format
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
|
||||||
|
|
||||||
class EntityRenderer(
|
|
||||||
val connection: PlayConnection,
|
|
||||||
override val context: RenderContext,
|
|
||||||
) : WorldRenderer {
|
|
||||||
override val layers = LayerSettings()
|
|
||||||
override val renderSystem: RenderSystem = context.system
|
|
||||||
val profile = connection.profiles.entity
|
|
||||||
val visibilityGraph = context.camera.visibilityGraph
|
|
||||||
private val models: LockMap<Entity, EntityModel<*>> = lockMapOf()
|
|
||||||
private var toUnload: MutableList<EntityModel<*>> = synchronizedListOf()
|
|
||||||
|
|
||||||
var hitboxes = profile.hitbox.enabled
|
|
||||||
|
|
||||||
val modelCount: Int get() = models.size
|
|
||||||
var visibleCount: Int = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
private var reset = false
|
|
||||||
|
|
||||||
override fun registerLayers() {
|
|
||||||
layers.register(EntityLayer, null, this::draw) { visibleCount <= 0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun init(latch: AbstractLatch) {
|
|
||||||
connection.events.listen<EntitySpawnEvent> { event ->
|
|
||||||
if (event.entity is LocalPlayerEntity) return@listen
|
|
||||||
DefaultThreadPool += { event.entity.createModel(this)?.let { models[event.entity] = it } }
|
|
||||||
}
|
|
||||||
connection.events.listen<EntityDestroyEvent> {
|
|
||||||
if (it.entity is LocalPlayerEntity) return@listen
|
|
||||||
DefaultThreadPool += add@{ toUnload += models.remove(it.entity) ?: return@add }
|
|
||||||
}
|
|
||||||
connection.events.listen<VisibilityGraphChangeEvent> {
|
|
||||||
runAsync { it.updateVisibility(visibilityGraph) }
|
|
||||||
}
|
|
||||||
|
|
||||||
profile.hitbox::enabled.observe(this) { this.hitboxes = it }
|
|
||||||
context.camera.offset::offset.observe(this) { reset = true }
|
|
||||||
|
|
||||||
context.input.bindings.register(
|
|
||||||
HITBOX_TOGGLE_KEY_COMBINATION,
|
|
||||||
KeyBinding(
|
|
||||||
KeyActions.MODIFIER to setOf(KeyCodes.KEY_F3),
|
|
||||||
KeyActions.STICKY to setOf(KeyCodes.KEY_B),
|
|
||||||
), pressed = profile.hitbox.enabled
|
|
||||||
) {
|
|
||||||
profile.hitbox.enabled = it
|
|
||||||
connection.util.sendDebugMessage("Entity hit boxes: ${it.format()}")
|
|
||||||
hitboxes = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun postAsyncInit(latch: AbstractLatch) {
|
|
||||||
// localModel = context.connection.player.createModel(this)
|
|
||||||
|
|
||||||
// models[connection.player] = localModel
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun unloadUnused() {
|
|
||||||
while (toUnload.isNotEmpty()) { // ToDo: Thread safety
|
|
||||||
val model = toUnload.removeAt(0)
|
|
||||||
model.unload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun prePrepareDraw() {
|
|
||||||
val count = AtomicInteger()
|
|
||||||
val reset = reset
|
|
||||||
val millis = millis()
|
|
||||||
runAsync {
|
|
||||||
it.entity.draw(millis)
|
|
||||||
if (reset) {
|
|
||||||
it.reset()
|
|
||||||
}
|
|
||||||
it.update = it.checkUpdate()
|
|
||||||
it.prepareAsync()
|
|
||||||
if (it.visible) {
|
|
||||||
count.incrementAndGet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.visibleCount = count.get()
|
|
||||||
if (reset) {
|
|
||||||
this.reset = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun postPrepareDraw() {
|
|
||||||
unloadUnused()
|
|
||||||
models.lock.acquire()
|
|
||||||
for (model in models.unsafe.values) {
|
|
||||||
model.prepare()
|
|
||||||
}
|
|
||||||
models.lock.release()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun draw() {
|
|
||||||
// ToDo: Probably more transparent
|
|
||||||
models.lock.acquire()
|
|
||||||
for (model in models.unsafe.values) {
|
|
||||||
if (model.skipDraw) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
model.draw()
|
|
||||||
}
|
|
||||||
models.lock.release()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun runAsync(executor: ((EntityModel<*>) -> Unit)) {
|
|
||||||
models.lock.acquire()
|
|
||||||
ConcurrentIterator(models.unsafe.values.spliterator(), priority = ThreadPool.HIGHER).iterate(executor)
|
|
||||||
models.lock.release()
|
|
||||||
}
|
|
||||||
|
|
||||||
private object EntityLayer : RenderLayer {
|
|
||||||
override val settings = RenderSettings(faceCulling = false)
|
|
||||||
override val priority: Int get() = 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object : RendererBuilder<EntityRenderer> {
|
|
||||||
private val HITBOX_TOGGLE_KEY_COMBINATION = minosoft("toggle_hitboxes")
|
|
||||||
|
|
||||||
|
|
||||||
override fun build(connection: PlayConnection, context: RenderContext): EntityRenderer {
|
|
||||||
return EntityRenderer(connection, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* Minosoft
|
|
||||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.entity.hitbox
|
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
|
||||||
import de.bixilon.minosoft.data.entities.entities.LivingEntity
|
|
||||||
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
|
|
||||||
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
|
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.ModelUpdater
|
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.models.EntityModel
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
|
||||||
|
|
||||||
class EntityHitbox(
|
|
||||||
val model: EntityModel<*>,
|
|
||||||
) : ModelUpdater {
|
|
||||||
private var _mesh: LineMesh? = null
|
|
||||||
private var mesh: LineMesh? = null
|
|
||||||
private var aabb: AABB = model.aabb
|
|
||||||
private var data: HitboxData? = null
|
|
||||||
|
|
||||||
|
|
||||||
var enabled: Boolean = true
|
|
||||||
get() = field && model.renderer.hitboxes
|
|
||||||
private var lastEnabled = enabled
|
|
||||||
|
|
||||||
|
|
||||||
override fun checkUpdate(): Boolean {
|
|
||||||
val enabled = enabled
|
|
||||||
val lastEnabled = lastEnabled
|
|
||||||
this.lastEnabled = enabled
|
|
||||||
if (!enabled) {
|
|
||||||
return !lastEnabled
|
|
||||||
}
|
|
||||||
val aabb = model.aabb
|
|
||||||
val data = HitboxData.of(model.entity)
|
|
||||||
if (lastEnabled && this.aabb == aabb && this.data == data) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
this.data = data
|
|
||||||
this.aabb = aabb
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun prepareAsync() {
|
|
||||||
if (mesh != null) {
|
|
||||||
this._mesh = mesh
|
|
||||||
mesh = null
|
|
||||||
}
|
|
||||||
if (!enabled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val data = this.data ?: return
|
|
||||||
|
|
||||||
val visible = ((model.entity.isInvisible && model.renderer.profile.hitbox.showInvisible) || !model.entity.isInvisible) && model.visible && if (model.entity is LivingEntity) model.entity.health > 0.0 else true
|
|
||||||
|
|
||||||
if (!visible) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val lazy = model.renderer.profile.hitbox.lazy
|
|
||||||
val shrunk = aabb.shrink(0.01f)
|
|
||||||
val mesh = LineMesh(model.context, if (lazy) 1488 else 2496)
|
|
||||||
if (lazy) {
|
|
||||||
mesh.drawLazyAABB(shrunk, color = data.color)
|
|
||||||
} else {
|
|
||||||
mesh.drawAABB(aabb = shrunk, color = data.color, margin = 0.1f)
|
|
||||||
}
|
|
||||||
val offset = model.context.camera.offset.offset
|
|
||||||
val center = Vec3(shrunk.center - offset)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data.velocity?.let { mesh.drawLine(center, center + Vec3(it) * 3, color = ChatColors.YELLOW) }
|
|
||||||
|
|
||||||
val eyeHeight = shrunk.min.y + model.entity.eyeHeight
|
|
||||||
val eyeAABB = AABB(Vec3d(shrunk.min.x, eyeHeight, shrunk.min.z), Vec3d(shrunk.max.x, eyeHeight, shrunk.max.z)).hShrink(-RenderConstants.DEFAULT_LINE_WIDTH)
|
|
||||||
mesh.drawAABB(eyeAABB, RenderConstants.DEFAULT_LINE_WIDTH, ChatColors.DARK_RED)
|
|
||||||
|
|
||||||
|
|
||||||
val eyeStart = Vec3(center.x, eyeHeight - offset.y, center.z)
|
|
||||||
|
|
||||||
mesh.drawLine(eyeStart, eyeStart + data.rotation.front * 5.0f, color = ChatColors.BLUE)
|
|
||||||
this.mesh = mesh
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun prepare() {
|
|
||||||
_mesh?.unload()
|
|
||||||
_mesh = null
|
|
||||||
val mesh = mesh ?: return
|
|
||||||
if (mesh.state == Mesh.MeshStates.PREPARING) {
|
|
||||||
mesh.load()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun draw() {
|
|
||||||
if (!enabled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mesh?.draw()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun unload() {
|
|
||||||
val mesh = mesh
|
|
||||||
this.mesh = null
|
|
||||||
if (mesh != null && mesh.state == Mesh.MeshStates.LOADED) {
|
|
||||||
mesh.unload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Minosoft
|
|
||||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.entity.models
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
|
||||||
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
|
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.view.WorldVisibilityGraph
|
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
|
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.ModelUpdater
|
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.hitbox.EntityHitbox
|
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
|
|
||||||
|
|
||||||
abstract class EntityModel<E : Entity>(
|
|
||||||
val renderer: EntityRenderer,
|
|
||||||
val entity: E,
|
|
||||||
) : ModelUpdater {
|
|
||||||
val context = renderer.context
|
|
||||||
open var update = true
|
|
||||||
var aabb = AABB.EMPTY
|
|
||||||
open var hitbox: EntityHitbox = EntityHitbox(this)
|
|
||||||
var visible = false
|
|
||||||
|
|
||||||
override val skipDraw: Boolean
|
|
||||||
get() = !visible
|
|
||||||
|
|
||||||
override fun checkUpdate(): Boolean {
|
|
||||||
val aabb = entity.renderInfo.cameraAABB
|
|
||||||
var update = false
|
|
||||||
if (this.aabb != aabb) {
|
|
||||||
this.aabb = aabb
|
|
||||||
visible = renderer.visibilityGraph.isAABBVisible(aabb)
|
|
||||||
update = true
|
|
||||||
}
|
|
||||||
update = hitbox.checkUpdate() || update
|
|
||||||
|
|
||||||
return update
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reset() {
|
|
||||||
update = true
|
|
||||||
hitbox.reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun prepareAsync() {
|
|
||||||
if (!update) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hitbox.prepareAsync()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun prepare() {
|
|
||||||
if (!update) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
hitbox.prepare()
|
|
||||||
update = false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun draw() {
|
|
||||||
drawHitbox()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun unload() {
|
|
||||||
hitbox.unload()
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun updateVisibility(graph: WorldVisibilityGraph) {
|
|
||||||
visible = graph.isAABBVisible(aabb)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun drawHitbox() {
|
|
||||||
if (!hitbox.enabled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (renderer.profile.hitbox.showThroughWalls) {
|
|
||||||
context.system.reset(faceCulling = false, depth = DepthFunctions.ALWAYS)
|
|
||||||
} else {
|
|
||||||
context.system.reset(faceCulling = false)
|
|
||||||
}
|
|
||||||
|
|
||||||
context.shaders.genericColorShader.use()
|
|
||||||
|
|
||||||
hitbox.draw()
|
|
||||||
}
|
|
||||||
}
|
|
@ -34,7 +34,7 @@ import de.bixilon.minosoft.data.text.formatting.color.ChatColors
|
|||||||
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
||||||
import de.bixilon.minosoft.data.world.chunk.light.SectionLight
|
import de.bixilon.minosoft.data.world.chunk.light.SectionLight
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.ChunkRenderer
|
import de.bixilon.minosoft.gui.rendering.chunk.ChunkRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
|
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.events.ResizeWindowEvent
|
import de.bixilon.minosoft.gui.rendering.events.ResizeWindowEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
|
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||||
@ -99,8 +99,8 @@ class DebugHUDElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Layouted
|
|||||||
layout += AutoTextElement(guiRenderer, 1) { "C v=${visible.sizeString}, l=${loaded.size.format()}, cQ=${culledQueue.size.format()}, q=${meshingQueue.size.format()}, pT=${meshingQueue.tasks.size.format()}/${meshingQueue.tasks.max.format()}, lQ=${loadingQueue.size.format()}/${meshingQueue.maxMeshesToLoad.format()}, w=${connection.world.chunks.chunks.size.format()}" }
|
layout += AutoTextElement(guiRenderer, 1) { "C v=${visible.sizeString}, l=${loaded.size.format()}, cQ=${culledQueue.size.format()}, q=${meshingQueue.size.format()}, pT=${meshingQueue.tasks.size.format()}/${meshingQueue.tasks.max.format()}, lQ=${loadingQueue.size.format()}/${meshingQueue.maxMeshesToLoad.format()}, w=${connection.world.chunks.chunks.size.format()}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
layout += context.renderer[EntityRenderer]?.let {
|
layout += context.renderer[EntitiesRenderer]?.let {
|
||||||
AutoTextElement(guiRenderer, 1) { BaseComponent("E v=", it.visibleCount, ", m=", it.modelCount, ", w=", connection.world.entities.size) }
|
AutoTextElement(guiRenderer, 1) { BaseComponent("E v=", it.visibility.size, ", t=", it.renderers.size, ", w=", connection.world.entities.size) }
|
||||||
} ?: AutoTextElement(guiRenderer, 1) { "E w=${connection.world.entities.size.format()}" }
|
} ?: AutoTextElement(guiRenderer, 1) { "E w=${connection.world.entities.size.format()}" }
|
||||||
|
|
||||||
context.renderer[ParticleRenderer]?.apply {
|
context.renderer[ParticleRenderer]?.apply {
|
||||||
|
@ -11,14 +11,14 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.light
|
package de.bixilon.minosoft.gui.rendering.light
|
||||||
|
|
||||||
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||||
import de.bixilon.minosoft.config.DebugOptions
|
import de.bixilon.minosoft.config.DebugOptions
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.updater.DebugLightUpdater
|
import de.bixilon.minosoft.gui.rendering.light.updater.DebugLightUpdater
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.updater.FullbrightLightUpdater
|
import de.bixilon.minosoft.gui.rendering.light.updater.FullbrightLightUpdater
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.updater.LightmapUpdater
|
import de.bixilon.minosoft.gui.rendering.light.updater.LightmapUpdater
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.updater.normal.NormalLightmapUpdater
|
import de.bixilon.minosoft.gui.rendering.light.updater.normal.NormalLightmapUpdater
|
||||||
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
|
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -11,7 +11,7 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.light
|
package de.bixilon.minosoft.gui.rendering.light
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
@ -11,7 +11,7 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.light
|
package de.bixilon.minosoft.gui.rendering.light
|
||||||
|
|
||||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||||
import de.bixilon.minosoft.config.DebugOptions
|
import de.bixilon.minosoft.config.DebugOptions
|
||||||
@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
|||||||
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil
|
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderingStates
|
import de.bixilon.minosoft.gui.rendering.RenderingStates
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.debug.LightmapDebugWindow
|
import de.bixilon.minosoft.gui.rendering.light.debug.LightmapDebugWindow
|
||||||
import de.bixilon.minosoft.util.KUtil.format
|
import de.bixilon.minosoft.util.KUtil.format
|
||||||
import de.bixilon.minosoft.util.delegate.JavaFXDelegate.observeFX
|
import de.bixilon.minosoft.util.delegate.JavaFXDelegate.observeFX
|
||||||
|
|
@ -11,13 +11,13 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.light.debug
|
package de.bixilon.minosoft.gui.rendering.light.debug
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
||||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||||
import de.bixilon.minosoft.gui.eros.controller.JavaFXWindowController
|
import de.bixilon.minosoft.gui.eros.controller.JavaFXWindowController
|
||||||
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil
|
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.Lightmap
|
import de.bixilon.minosoft.gui.rendering.light.Lightmap
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import javafx.fxml.FXML
|
import javafx.fxml.FXML
|
||||||
import javafx.scene.canvas.Canvas
|
import javafx.scene.canvas.Canvas
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -11,10 +11,10 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.light.updater
|
package de.bixilon.minosoft.gui.rendering.light.updater
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -11,10 +11,10 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.light.updater
|
package de.bixilon.minosoft.gui.rendering.light.updater
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -11,9 +11,9 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.light.updater
|
package de.bixilon.minosoft.gui.rendering.light.updater
|
||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
|
|
||||||
interface LightmapUpdater {
|
interface LightmapUpdater {
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -11,7 +11,7 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.light.updater.normal
|
package de.bixilon.minosoft.gui.rendering.light.updater.normal
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.kutil.math.MathConstants.PIf
|
import de.bixilon.kutil.math.MathConstants.PIf
|
||||||
@ -22,8 +22,8 @@ import de.bixilon.minosoft.data.registries.effects.vision.VisionEffect
|
|||||||
import de.bixilon.minosoft.data.world.time.DayPhases
|
import de.bixilon.minosoft.data.world.time.DayPhases
|
||||||
import de.bixilon.minosoft.data.world.time.WorldTime
|
import de.bixilon.minosoft.data.world.time.WorldTime
|
||||||
import de.bixilon.minosoft.data.world.weather.WorldWeather
|
import de.bixilon.minosoft.data.world.weather.WorldWeather
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.updater.LightmapUpdater
|
import de.bixilon.minosoft.gui.rendering.light.updater.LightmapUpdater
|
||||||
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.clamp
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.clamp
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.modify
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.modify
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -15,7 +15,7 @@ package de.bixilon.minosoft.gui.rendering.particle
|
|||||||
|
|
||||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.types.*
|
import de.bixilon.minosoft.gui.rendering.shader.types.*
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
|
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -17,7 +17,7 @@ import de.bixilon.minosoft.gui.rendering.chunk.ChunkRenderer
|
|||||||
import de.bixilon.minosoft.gui.rendering.chunk.border.WorldBorderRenderer
|
import de.bixilon.minosoft.gui.rendering.chunk.border.WorldBorderRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.chunk.ChunkBorderRenderer
|
import de.bixilon.minosoft.gui.rendering.chunk.chunk.ChunkBorderRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.outline.BlockOutlineRenderer
|
import de.bixilon.minosoft.gui.rendering.chunk.outline.BlockOutlineRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
|
import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
||||||
@ -31,7 +31,7 @@ object DefaultRenderer {
|
|||||||
BlockOutlineRenderer,
|
BlockOutlineRenderer,
|
||||||
ParticleRenderer,
|
ParticleRenderer,
|
||||||
|
|
||||||
EntityRenderer,
|
EntitiesRenderer,
|
||||||
CloudRenderer,
|
CloudRenderer,
|
||||||
ChunkBorderRenderer,
|
ChunkBorderRenderer,
|
||||||
WorldBorderRenderer,
|
WorldBorderRenderer,
|
||||||
|
@ -27,6 +27,7 @@ class WorldRendererPipeline(val renderer: RendererManager) : Drawable {
|
|||||||
for (renderer in renderer) {
|
for (renderer in renderer) {
|
||||||
if (renderer !is WorldRenderer) continue
|
if (renderer !is WorldRenderer) continue
|
||||||
list += renderer.layers.elements
|
list += renderer.layers.elements
|
||||||
|
renderer.layers.elements.clear() // TODO: replace WorldRenderer::layers with unsafeNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
return list.sorted().toTypedArray()
|
return list.sorted().toTypedArray()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.shader.types
|
package de.bixilon.minosoft.gui.rendering.shader.types
|
||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.AbstractShader
|
import de.bixilon.minosoft.gui.rendering.shader.AbstractShader
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.uniform.ShaderUniform
|
import de.bixilon.minosoft.gui.rendering.shader.uniform.ShaderUniform
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.skeletal
|
|||||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
import de.bixilon.minosoft.gui.rendering.camera.FogManager
|
import de.bixilon.minosoft.gui.rendering.camera.FogManager
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.light.LightmapBuffer
|
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.types.*
|
import de.bixilon.minosoft.gui.rendering.shader.types.*
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniformBuffer
|
import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniformBuffer
|
||||||
|
@ -46,8 +46,7 @@ class AnimationManager(val instance: SkeletalInstance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun draw() {
|
fun draw(millis: Long = millis()) {
|
||||||
val millis = millis()
|
|
||||||
val delta = if (lastDraw < 0) 0L else millis - lastDraw
|
val delta = if (lastDraw < 0) 0L else millis - lastDraw
|
||||||
this.lastDraw = millis
|
this.lastDraw = millis
|
||||||
draw(delta / 1000.0f)
|
draw(delta / 1000.0f)
|
||||||
|
@ -37,9 +37,9 @@ data class SkeletalFace(
|
|||||||
|
|
||||||
val texture = context.textures[texture ?: context.texture ?: throw IllegalStateException("Element has no texture set!")] ?: throw IllegalStateException("Texture not found!")
|
val texture = context.textures[texture ?: context.texture ?: throw IllegalStateException("Element has no texture set!")] ?: throw IllegalStateException("Texture not found!")
|
||||||
|
|
||||||
// TODO: why flip on x?
|
|
||||||
val uv = this.uv ?: CuboidUtil.cubeUV(element.uv!!, element.from, element.to, direction)
|
val uv = this.uv ?: CuboidUtil.cubeUV(element.uv!!, element.from, element.to, direction)
|
||||||
|
|
||||||
|
// TODO: why flip on x?
|
||||||
val uvData = FaceUV(
|
val uvData = FaceUV(
|
||||||
texture.texture.transformUV(Vec2(uv.end.x, uv.start.y) / texture.properties.resolution),
|
texture.texture.transformUV(Vec2(uv.end.x, uv.start.y) / texture.properties.resolution),
|
||||||
texture.texture.transformUV(Vec2(uv.start.x, uv.end.y) / texture.properties.resolution),
|
texture.texture.transformUV(Vec2(uv.start.x, uv.end.y) / texture.properties.resolution),
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.protocol.packets.s2c.play.entity
|
package de.bixilon.minosoft.protocol.packets.s2c.play.entity
|
||||||
|
|
||||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.models.DamageableModel
|
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
||||||
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
||||||
@ -29,8 +27,6 @@ class DamageTiltS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
|
|||||||
|
|
||||||
override fun handle(connection: PlayConnection) {
|
override fun handle(connection: PlayConnection) {
|
||||||
val entity = connection.world.entities[entityId] ?: return
|
val entity = connection.world.entities[entityId] ?: return
|
||||||
|
|
||||||
entity.model?.nullCast<DamageableModel>()?.onDamage()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun log(reducedLog: Boolean) {
|
override fun log(reducedLog: Boolean) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user