entity: drawing, rename realTick to tick, abstract skeletal animations

This commit is contained in:
Bixilon 2022-06-08 20:02:45 +02:00
parent 8aba492316
commit 27f4ed0882
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
13 changed files with 81 additions and 44 deletions

View File

@ -120,7 +120,6 @@ abstract class Entity(
open val eyeHeight: Float
get() = dimensions.y * 0.85f
private var lastFakeTickTime = -1L
protected open var previousPosition: Vec3d = Vec3d(position)
override var position: Vec3d = position
set(value) {
@ -297,29 +296,23 @@ abstract class Entity(
@Synchronized
fun tick() {
fun tryTick() {
val currentTime = TimeUtil.millis
if (lastFakeTickTime == -1L) {
lastFakeTickTime = currentTime
return
}
val deltaTime = currentTime - lastFakeTickTime
if (deltaTime <= 0) {
return
}
if (currentTime - lastTickTime >= ProtocolDefinition.TICK_TIME) {
realTick()
tick()
postTick()
lastTickTime = currentTime
}
cameraPosition = interpolateLinear((currentTime - lastTickTime) / ProtocolDefinition.TICK_TIMEf, Vec3(previousPosition), Vec3(position))
}
open fun draw(time: Long) {
cameraPosition = interpolateLinear((time - lastTickTime) / ProtocolDefinition.TICK_TIMEf, Vec3(previousPosition), Vec3(position))
}
open val pushableByFluids: Boolean = false
open fun realTick() {
open fun tick() {
previousPosition = position
if (spawnSprintingParticles) {
spawnSprintingParticles()

View File

@ -122,8 +122,8 @@ abstract class LivingEntity(connection: PlayConnection, entityType: EntityType,
}
}
override fun realTick() {
super.realTick()
override fun tick() {
super.tick()
tickStatusEffects()
if (isSleeping) {

View File

@ -39,11 +39,11 @@ class FallingBlockEntity(connection: PlayConnection, entityType: EntityType, dat
override fun onAttack(attacker: Entity): Boolean = false
override fun setObjectData(data: Int) {
blockState = connection.registries.blockStateRegistry[data]
blockState = connection.registries.blockStateRegistry.getOrNull(data)
}
override fun realTick() {
super.realTick()
override fun tick() {
super.tick()
applyGravity()
move(velocity)

View File

@ -33,8 +33,8 @@ class ItemEntity(connection: PlayConnection, entityType: EntityType, data: Entit
get() = data.get(ITEM_DATA, null)
override fun realTick() {
super.realTick()
override fun tick() {
super.tick()
when {
// ToDo: Apply water and lava "bouncing"

View File

@ -101,12 +101,12 @@ abstract class PlayerEntity(
override val spawnSprintingParticles: Boolean
get() = super.spawnSprintingParticles && gamemode != Gamemodes.SPECTATOR
override fun realTick() {
override fun tick() {
if (gamemode == Gamemodes.SPECTATOR) {
onGround = false
}
// ToDo: Update water submersion state
super.realTick()
super.tick()
val clampedPosition = position.clamp(-World.MAX_SIZEd, World.MAX_SIZEd)
if (clampedPosition != position) {

View File

@ -23,8 +23,8 @@ abstract class ThrowableProjectile(connection: PlayConnection, entityType: Entit
open val gravity: Float = 0.03f
override fun realTick() {
super.realTick()
override fun tick() {
super.tick()
val velocity = this.velocity

View File

@ -583,12 +583,12 @@ class LocalPlayerEntity(
override val pushableByFluids: Boolean
get() = !baseAbilities.isFlying
override fun realTick() {
override fun tick() {
if (connection.world[positionInfo.blockPosition.chunkPosition] == null) {
// chunk not loaded, so we don't tick?
return
}
super.realTick()
super.tick()
tickMovement()
sendMovementPackets()
@ -596,6 +596,12 @@ class LocalPlayerEntity(
fovMultiplier.value = 1.0 + (walkingSpeed * 1.9).clamp(-2.0, 2.0)
}
override fun draw(time: Long) = Unit
fun _draw(time: Long) {
super.draw(time)
}
override val health: Double
get() = healthCondition.hp.toDouble()

View File

@ -187,7 +187,7 @@ class WorldEntities : Iterable<Entity> {
lock.acquire()
val latch = CountUpAndDownLatch(entities.size)
for (entity in entities) {
DefaultThreadPool += ThreadPoolRunnable(priority = ThreadPool.Priorities.HIGH) { entity.tick(); latch.dec() }
DefaultThreadPool += ThreadPoolRunnable(priority = ThreadPool.Priorities.HIGH) { entity.tryTick(); latch.dec() }
}
lock.release()
latch.await()

View File

@ -13,9 +13,11 @@
package de.bixilon.minosoft.gui.rendering.camera
import de.bixilon.kutil.time.TimeUtil
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.player.LocalPlayerEntity
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.camera.target.TargetHandler
import de.bixilon.minosoft.gui.rendering.world.view.WorldVisibilityGraph
@ -58,7 +60,11 @@ class Camera(
}
fun draw() {
matrixHandler.entity.tick()
val entity = matrixHandler.entity
entity.tryTick()
if (entity is LocalPlayerEntity) {
entity._draw(TimeUtil.millis)
}
matrixHandler.draw()
visibilityGraph.draw()
targetHandler.raycast()

View File

@ -17,6 +17,7 @@ import de.bixilon.kutil.collections.CollectionUtil.synchronizedListOf
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.latch.CountUpAndDownLatch
import de.bixilon.kutil.time.TimeUtil
import de.bixilon.minosoft.config.key.KeyActions
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
@ -90,6 +91,7 @@ class EntityRenderer(
override fun prepareDraw() {
runAsync {
it.entity.draw(TimeUtil.millis)
it.update = it.checkUpdate()
it.prepareAsync()
}

View File

@ -27,6 +27,8 @@ open class PlayerModel(renderer: EntityRenderer, player: PlayerEntity) : Skeleta
override val instance = createModel()
open val skinParts: Set<SettingsC2SP.SkinParts> = player.getSkinParts()
private var playing = false
private fun createModel(): SkeletalInstance {
val unbaked = renderWindow.modelLoader.entities.loadUnbakedModel(BB_MODEL)

View File

@ -13,32 +13,25 @@
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import de.bixilon.kotlinglm.func.rad
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel.Companion.fromBlockCoordinates
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.SkeletalAnimator
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.KeyframeChannels
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY_INSTANCE
import java.util.*
data class SkeletalAnimation(
val uuid: UUID,
val name: String,
val loop: AnimationLoops = AnimationLoops.LOOP,
val override: Boolean = false,
val length: Float,
val animators: Map<UUID, SkeletalAnimator>,
) {
@JsonDeserialize(`as` = StaticSkeletalAnimation::class)
interface SkeletalAnimation {
val name: String
val loop: AnimationLoops
val length: Float
fun get(channel: KeyframeChannels, animatorUUID: UUID, time: Float): Vec3? {
val animator = animators[animatorUUID] ?: return null
fun get(channel: KeyframeChannels, animatorUUID: UUID, time: Float): Vec3?
return animator.get(channel, tweakTime(time))
}
private fun tweakTime(time: Float): Float {
fun tweakTime(time: Float): Float {
when (loop) {
AnimationLoops.LOOP -> return time % length
AnimationLoops.ONCE -> {

View File

@ -0,0 +1,35 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.skeletal.model.animations
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.SkeletalAnimator
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.KeyframeChannels
import java.util.*
data class StaticSkeletalAnimation(
val uuid: UUID,
override val name: String,
override val loop: AnimationLoops = AnimationLoops.LOOP,
val override: Boolean = false,
override val length: Float,
val animators: Map<UUID, SkeletalAnimator>,
) : SkeletalAnimation {
override fun get(channel: KeyframeChannels, animatorUUID: UUID, time: Float): Vec3? {
val animator = animators[animatorUUID] ?: return null
return animator.get(channel, tweakTime(time))
}
}