mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
rendering: more animations
* Known bugs: Not all textures are animated
This commit is contained in:
parent
fa6990b0b2
commit
d348f8b7c5
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 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.textures
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.textures.properties.AnimationFrame
|
||||
|
||||
class TextureAnimation(
|
||||
val texture: Texture,
|
||||
) {
|
||||
var currentFrameIndex = 0
|
||||
var currentTime = 0L
|
||||
|
||||
val animationProperties = texture.properties.animation!!
|
||||
|
||||
fun getCurrentFrame(): AnimationFrame {
|
||||
return animationProperties.frames[currentFrameIndex]
|
||||
}
|
||||
|
||||
fun getAndSetNextFrame(): AnimationFrame {
|
||||
currentFrameIndex = getNextIndex()
|
||||
currentTime = 0L
|
||||
|
||||
return animationProperties.frames[currentFrameIndex]
|
||||
}
|
||||
|
||||
fun getNextFrame(): AnimationFrame {
|
||||
return animationProperties.frames[getNextIndex()]
|
||||
}
|
||||
|
||||
private fun getNextIndex(): Int {
|
||||
var nextFrameIndex = currentFrameIndex + 1
|
||||
|
||||
if (nextFrameIndex == animationProperties.frames.size) {
|
||||
nextFrameIndex = 0
|
||||
}
|
||||
|
||||
return nextFrameIndex
|
||||
}
|
||||
}
|
@ -17,7 +17,6 @@ import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.data.assets.MinecraftAssetsManager
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.matthiasmann.twl.utils.PNGDecoder
|
||||
import glm_.vec2.Vec2
|
||||
@ -74,7 +73,7 @@ class TextureArray(val allTextures: MutableList<Texture>) {
|
||||
it.add(texture)
|
||||
texture.properties.animation?.let { properties ->
|
||||
properties.animationId = animator.animatedTextures.size
|
||||
animator.animatedTextures.add(texture)
|
||||
animator.animatedTextures.add(TextureAnimation(texture))
|
||||
|
||||
val bytesPerTexture = size.x * size.y * PNGDecoder.Format.RGBA.numComponents
|
||||
val fullBuffer = texture.buffer!!
|
||||
@ -147,24 +146,22 @@ class TextureArray(val allTextures: MutableList<Texture>) {
|
||||
const val TEXTURE_MAX_RESOLUTION = 1024
|
||||
|
||||
val DEBUG_TEXTURE = Texture.getResourceTextureIdentifier(textureName = "block/debug")
|
||||
|
||||
private const val INTS_PER_ANIMATED_TEXTURE = 4
|
||||
}
|
||||
|
||||
inner class Animator {
|
||||
val animatedTextures: MutableList<Texture> = mutableListOf()
|
||||
val animatedTextures: MutableList<TextureAnimation> = mutableListOf()
|
||||
private var animatedBufferDataId = -1
|
||||
|
||||
|
||||
private var currentTick = 0
|
||||
private var lastTickIncrementTime = 0L
|
||||
|
||||
|
||||
lateinit var animatedData: IntArray
|
||||
var lastRun = 0L
|
||||
private lateinit var animatedData: IntArray
|
||||
|
||||
var initialized = false
|
||||
private set
|
||||
|
||||
fun initBuffer() {
|
||||
animatedData = IntArray(32 * 4) // 4 data ints per entry
|
||||
animatedData = IntArray(32 * INTS_PER_ANIMATED_TEXTURE) // 4 data ints per entry
|
||||
|
||||
|
||||
animatedBufferDataId = glGenBuffers()
|
||||
@ -184,21 +181,36 @@ class TextureArray(val allTextures: MutableList<Texture>) {
|
||||
if (!Minosoft.getConfig().config.game.animations.textures) {
|
||||
return
|
||||
}
|
||||
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - lastTickIncrementTime >= ProtocolDefinition.TICK_TIME) {
|
||||
currentTick++
|
||||
lastTickIncrementTime = currentTime
|
||||
val deltaLastDraw = currentTime - lastRun
|
||||
lastRun = currentTime
|
||||
|
||||
for (textureAnimation in animatedTextures) {
|
||||
var currentFrame = textureAnimation.getCurrentFrame()
|
||||
textureAnimation.currentTime += deltaLastDraw
|
||||
|
||||
if (textureAnimation.currentTime >= currentFrame.animationTime) {
|
||||
currentFrame = textureAnimation.getAndSetNextFrame()
|
||||
textureAnimation.currentTime = 0L
|
||||
}
|
||||
|
||||
val nextFrame = textureAnimation.getNextFrame()
|
||||
|
||||
val interpolation = if (textureAnimation.animationProperties.interpolate) {
|
||||
(textureAnimation.currentTime * 100) / currentFrame.animationTime
|
||||
} else {
|
||||
0L
|
||||
}
|
||||
|
||||
|
||||
for (texture in animatedTextures) {
|
||||
val animationProperties = texture.properties.animation!!
|
||||
val baseAnimatedData = (textureAnimation.texture.arrayId shl 24) or textureAnimation.texture.arrayLayer
|
||||
|
||||
val arrayOffset = animationProperties.animationId * 4
|
||||
val arrayOffset = textureAnimation.animationProperties.animationId * INTS_PER_ANIMATED_TEXTURE
|
||||
|
||||
animatedData[arrayOffset] = (texture.arrayId shl 24) or (texture.arrayLayer + (currentTick % animationProperties.frameCount))
|
||||
animatedData[arrayOffset + 1] = (texture.arrayId shl 24) or (texture.arrayLayer + 1) + (currentTick % animationProperties.frameCount)
|
||||
animatedData[arrayOffset + 2] = 0
|
||||
animatedData[arrayOffset] = baseAnimatedData or currentFrame.index
|
||||
animatedData[arrayOffset + 1] = baseAnimatedData or nextFrame.index
|
||||
animatedData[arrayOffset + 2] = interpolation.toInt()
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 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.textures.properties
|
||||
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
|
||||
data class AnimationFrame(
|
||||
val index: Int,
|
||||
val time: Int,
|
||||
) {
|
||||
val animationTime = time * ProtocolDefinition.TICK_TIME
|
||||
}
|
@ -20,12 +20,17 @@ data class AnimationProperties(
|
||||
val interpolate: Boolean = false,
|
||||
var width: Int = -1,
|
||||
var height: Int = -1,
|
||||
@Json(name = "frametime") val frameTime: Int = 1,
|
||||
val frames: Any = Any(),// ToDo,
|
||||
@Json(name = "frametime") private val frameTime: Int = 1,
|
||||
@Json(name = "frames") private val _frames: List<Any> = listOf(),
|
||||
) {
|
||||
@Transient
|
||||
lateinit var frames: Array<AnimationFrame>
|
||||
private set
|
||||
|
||||
var animationId = -1
|
||||
|
||||
var frameCount = -1
|
||||
private set
|
||||
|
||||
fun postInit(texture: Texture) {
|
||||
if (width == -1) {
|
||||
@ -36,5 +41,26 @@ data class AnimationProperties(
|
||||
}
|
||||
|
||||
frameCount = texture.size.y / height
|
||||
|
||||
val frames: MutableList<AnimationFrame> = mutableListOf()
|
||||
|
||||
if (_frames.isEmpty()) {
|
||||
for (i in 0 until frameCount) {
|
||||
frames.add(AnimationFrame(i, frameTime))
|
||||
}
|
||||
} else {
|
||||
for (frame in _frames) {
|
||||
if (frame is Number) {
|
||||
frames.add(AnimationFrame(frame.toInt(), frameTime))
|
||||
continue
|
||||
}
|
||||
check(frame is Map<*, *>) { "Invalid frame: $frame" }
|
||||
|
||||
frames.add(AnimationFrame((frame["index"] as Number).toInt(), (frame["time"] as Number?)?.toInt() ?: frameTime))
|
||||
}
|
||||
}
|
||||
|
||||
this.frames = frames.toTypedArray()
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -16,4 +16,5 @@ package de.bixilon.minosoft.gui.rendering.textures.properties
|
||||
data class TextureProperties(
|
||||
val blur: Boolean = false,
|
||||
val clamp: Boolean = false,
|
||||
// ToDo: mipmaps
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user