mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
somewhat successful walk/idle anim impl
This commit is contained in:
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
package net.torvald.colourutil
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.jme3.math.FastMath
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2017-01-12.
|
||||
@@ -11,25 +11,27 @@ object CIEXYZUtil {
|
||||
/**
|
||||
* 0..255 -> 0.0..1.0
|
||||
*/
|
||||
private val rgbLineariseLUT = Array<Float>(257, {
|
||||
val step = minOf(it, 255) / 255f
|
||||
private val rgbLinLUT = FloatArray(256) {
|
||||
val step = it / 255f
|
||||
|
||||
if (step > 0.04045f)
|
||||
((step + 0.055f) / 1.055f).powerOf(2.4f)
|
||||
else step / 12.92f
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 0..255 -> 0.0..1.0
|
||||
*/
|
||||
private val rgbUnLineariseLUT = Array<Float>(257, {
|
||||
val step = minOf(it, 255) / 255f
|
||||
private val rgbUnLinLUT = FloatArray(256) {
|
||||
val step = it / 255f
|
||||
|
||||
if (step > 0.0031308f)
|
||||
1.055f * step.powerOf(1f / 2.4f) - 0.055f
|
||||
else
|
||||
step * 12.92f
|
||||
})
|
||||
}
|
||||
|
||||
private val rgbToXyzLut_XR = FloatArray(256) { 0.4124564f * (it / 255f) }
|
||||
|
||||
|
||||
|
||||
@@ -65,8 +67,35 @@ object CIEXYZUtil {
|
||||
|
||||
fun Color.toXYZ(): CIEXYZ = RGB(this).toXYZ()
|
||||
|
||||
/**
|
||||
* "Linearise" the sRGB triads. This use lookup table to speed up calculation.
|
||||
* Integer values (1/255, 2/255, .. , 254/255, 255/255) are accurate but any values in between are
|
||||
* linearly interpolated and thus slightly less accurate. Visually there's little-to-no difference,
|
||||
* but may not optimal for rigorous maths.
|
||||
*/
|
||||
fun RGB.linearise(): RGB {
|
||||
/*val newR = if (r > 0.04045f)
|
||||
val out = floatArrayOf(0f, 0f, 0f)
|
||||
for (i in 0..2) {
|
||||
val value = when (i) {
|
||||
0 -> this.r
|
||||
1 -> this.g
|
||||
2 -> this.b
|
||||
else -> throw InternalError("Fuck you")
|
||||
}
|
||||
val step = value.clampOne() * 255f // 0.0 .. 255.0
|
||||
val intStep = step.toInt() // 0 .. 255
|
||||
val NeXTSTEP = minOf(intStep + 1, 255) // 1 .. 255
|
||||
|
||||
out[i] = interpolateLinear(step - intStep, rgbLinLUT[intStep], rgbLinLUT[NeXTSTEP])
|
||||
}
|
||||
|
||||
|
||||
return RGB(out[0], out[1], out[2], alpha)
|
||||
}
|
||||
|
||||
/** Suitable for rigorous maths but slower */
|
||||
fun RGB.lineariseSuper(): RGB {
|
||||
val newR = if (r > 0.04045f)
|
||||
((r + 0.055f) / 1.055f).powerOf(2.4f)
|
||||
else r / 12.92f
|
||||
val newG = if (g > 0.04045f)
|
||||
@@ -77,28 +106,38 @@ object CIEXYZUtil {
|
||||
else b / 12.92f
|
||||
|
||||
|
||||
return RGB(newR, newG, newB, alpha)*/
|
||||
return RGB(newR, newG, newB, alpha)
|
||||
}
|
||||
|
||||
/**
|
||||
* "Un-linearise" the RGB triads. That is, codes the linear RGB into sRGB. This use lookup table to speed up calculation.
|
||||
* Integer values (1/255, 2/255, .. , 254/255, 255/255) are accurate but any values in between are
|
||||
* linearly interpolated and thus slightly less accurate. Visually there's little-to-no difference,
|
||||
* but may not optimal for rigorous maths.
|
||||
*/
|
||||
fun RGB.unLinearise(): RGB {
|
||||
val out = floatArrayOf(0f, 0f, 0f)
|
||||
for (i in 0..2) {
|
||||
val value = when (i) {
|
||||
0 -> this.r
|
||||
1 -> this.g
|
||||
2 -> this.b
|
||||
else -> throw Exception("Fuck you")
|
||||
else -> throw InternalError("Fuck you")
|
||||
}
|
||||
val step = value.clampOne() * 255f
|
||||
val intStep = step.toInt()
|
||||
val step = value.clampOne() * 255f // 0.0 .. 255.0
|
||||
val intStep = step.toInt() // 0 .. 255
|
||||
val NeXTSTEP = minOf(intStep + 1, 255) // 1 .. 255
|
||||
|
||||
out[i] = interpolateLinear(step - intStep, rgbLineariseLUT[intStep], rgbLineariseLUT[intStep + 1])
|
||||
out[i] = interpolateLinear(step - intStep, rgbUnLinLUT[intStep], rgbUnLinLUT[NeXTSTEP])
|
||||
}
|
||||
|
||||
|
||||
return RGB(out[0], out[1], out[2], alpha)
|
||||
}
|
||||
|
||||
fun RGB.unLinearise(): RGB {
|
||||
/*val newR = if (r > 0.0031308f)
|
||||
/** Suitable for rigorous maths but slower */
|
||||
fun RGB.unLineariseSuper(): RGB {
|
||||
val newR = if (r > 0.0031308f)
|
||||
1.055f * r.powerOf(1f / 2.4f) - 0.055f
|
||||
else
|
||||
r * 12.92f
|
||||
@@ -112,24 +151,7 @@ object CIEXYZUtil {
|
||||
b * 12.92f
|
||||
|
||||
|
||||
return RGB(newR, newG, newB, alpha)*/
|
||||
|
||||
val out = floatArrayOf(0f, 0f, 0f)
|
||||
for (i in 0..2) {
|
||||
val value = when (i) {
|
||||
0 -> this.r
|
||||
1 -> this.g
|
||||
2 -> this.b
|
||||
else -> throw Exception("Fuck you")
|
||||
}
|
||||
val step = value.clampOne() * 255f
|
||||
val intStep = step.toInt()
|
||||
|
||||
out[i] = interpolateLinear(step - intStep, rgbUnLineariseLUT[intStep], rgbUnLineariseLUT[intStep + 1])
|
||||
}
|
||||
|
||||
|
||||
return RGB(out[0], out[1], out[2], alpha)
|
||||
return RGB(newR, newG, newB, alpha)
|
||||
}
|
||||
|
||||
fun RGB.toXYZ(): CIEXYZ {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package net.torvald.colourutil
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.colourutil.CIEXYZUtil.linearise
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2016-07-26.
|
||||
@@ -20,4 +21,17 @@ object ColourUtil {
|
||||
|
||||
return Color(r, g, b, a)
|
||||
}
|
||||
|
||||
/** Get luminosity level using CIEXYZ colour space. Slow but accurate. */
|
||||
fun RGB.getLuminosity(): Float {
|
||||
val new = this.linearise()
|
||||
return 0.2126729f * new.r + 0.7151522f * new.g + 0.0721750f * new.b // from RGB.toXYZ
|
||||
}
|
||||
/** Get luminosity level using CIEXYZ colour space. Slow but accurate. */
|
||||
fun Color.getLuminosity() = RGB(this).getLuminosity()
|
||||
|
||||
/** Get luminosity level using NTSC standard. Fast, less accurate but should be good enough. */
|
||||
fun RGB.getLuminosityQuick() = 0.3f * this.r + 0.59f * this.g + 0.11f * this.b // NTSC standard
|
||||
/** Get luminosity level using NTSC standard. Fast, less accurate but should be good enough. */
|
||||
fun Color.getLuminosityQuick() = 0.3f * this.r + 0.59f * this.g + 0.11f * this.b // NTSC standard
|
||||
}
|
||||
@@ -7,6 +7,7 @@ package net.torvald.spriteanimation
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.Second
|
||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
@@ -16,12 +17,29 @@ class SpriteAnimation(val parentActor: ActorWBMovable) {
|
||||
|
||||
var currentFrame = 0
|
||||
var currentRow = 0
|
||||
|
||||
var nFrames: Int = 1
|
||||
private set
|
||||
var nRows: Int = 1
|
||||
private set
|
||||
var delay = 200f
|
||||
|
||||
private val currentDelay: Second
|
||||
get() = delays[currentRow]
|
||||
|
||||
/**
|
||||
* Sets delays for each rows. Array size must be the same as the rows of the sheet
|
||||
*/
|
||||
var delays: FloatArray = floatArrayOf(0.2f)
|
||||
set(value) {
|
||||
if (value.filter { it <= 0f }.isNotEmpty()) {
|
||||
throw IllegalArgumentException("Delay array contains zero or negative value: $delays")
|
||||
}
|
||||
|
||||
field = value
|
||||
}
|
||||
|
||||
private var delta = 0f
|
||||
|
||||
val looping = true
|
||||
private var animationRunning = true
|
||||
var flipHorizontal = false
|
||||
@@ -61,17 +79,23 @@ class SpriteAnimation(val parentActor: ActorWBMovable) {
|
||||
//skip this if animation is stopped
|
||||
this.delta += delta
|
||||
|
||||
//println("delta accumulation: $delta, currentDelay: $currentDelay")
|
||||
|
||||
//check if it's time to advance the frame
|
||||
if (this.delta >= this.delay) {
|
||||
//if set to not loop, keep the frame at the last frame
|
||||
if (this.currentFrame == this.nFrames && !this.looping) {
|
||||
this.currentFrame = this.nFrames - 1
|
||||
while (this.delta >= currentDelay) {
|
||||
// advance frame
|
||||
if (looping) { // looping, wrap around
|
||||
currentFrame = (currentFrame + 1) % nFrames
|
||||
}
|
||||
else if (currentFrame < nFrames - 1) { // not looping and haven't reached the end
|
||||
currentFrame += 1
|
||||
}
|
||||
|
||||
//advance one frame, then reset delta counter
|
||||
this.currentFrame = this.currentFrame % this.nFrames
|
||||
this.delta = 0f
|
||||
// discount counter
|
||||
this.delta -= currentDelay
|
||||
}
|
||||
|
||||
//println("row, frame: $currentRow, $currentFrame")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +116,7 @@ class SpriteAnimation(val parentActor: ActorWBMovable) {
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
val region = textureRegion.get(currentRow, currentFrame)
|
||||
val region = textureRegion.get(currentFrame, currentRow)
|
||||
batch.color = colorFilter
|
||||
|
||||
if (flipHorizontal && flipVertical) {
|
||||
@@ -139,15 +163,6 @@ class SpriteAnimation(val parentActor: ActorWBMovable) {
|
||||
}
|
||||
}
|
||||
|
||||
fun setSpriteDelay(newDelay: Float) {
|
||||
if (newDelay > 0) {
|
||||
delay = newDelay
|
||||
}
|
||||
else {
|
||||
throw IllegalArgumentException("Delay equal or less than zero")
|
||||
}
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
currentFrame = 1
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ import java.io.StringReader;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Should be made into its own artifact to build.
|
||||
@@ -129,7 +128,7 @@ public class CSVEditor extends JFrame {
|
||||
|
||||
// then work on the file
|
||||
for (CSVRecord record : records) {
|
||||
Vector newRow = new Vector(columns.length);
|
||||
String[] newRow = new String[columns.length];
|
||||
|
||||
// construct newRow
|
||||
for (String column : columns) {
|
||||
@@ -138,7 +137,7 @@ public class CSVEditor extends JFrame {
|
||||
value = csvFormat.getNullString();
|
||||
}
|
||||
|
||||
newRow.add(spreadsheet.getColumnModel().getColumnIndex(column), value);
|
||||
newRow[spreadsheet.getColumnModel().getColumnIndex(column)] = value;
|
||||
}
|
||||
|
||||
((DefaultTableModel) spreadsheet.getModel()).addRow(newRow);
|
||||
@@ -273,6 +272,9 @@ public class CSVEditor extends JFrame {
|
||||
|
||||
|
||||
statBar.setText(lang.getProperty("STAT_INIT"));
|
||||
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -274,7 +274,8 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
/** Load rest of the game with GL context */
|
||||
fun postInit() {
|
||||
setTheRealGamerFirstTime(PlayerBuilderSigrid())
|
||||
//setTheRealGamerFirstTime(PlayerBuilderSigrid())
|
||||
setTheRealGamerFirstTime(PlayerBuilderTestSubject1())
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.AppLoader
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.bipolarClamp
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gameactors.*
|
||||
import net.torvald.terrarum.gameactors.faction.Faction
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
@@ -612,14 +610,15 @@ open class ActorHumanoid(
|
||||
sprite?.update(delta)
|
||||
spriteGlow?.update(delta)
|
||||
|
||||
//println("$this\tsprite current frame: ${sprite!!.currentFrame}")
|
||||
if (walledBottom && controllerMoveDelta?.x != 0.0) {
|
||||
//switch row
|
||||
sprite?.switchRow(SPRITE_ROW_WALK)
|
||||
spriteGlow?.switchRow(SPRITE_ROW_WALK)
|
||||
|
||||
if (walledBottom) {
|
||||
// set anim row
|
||||
if (controllerMoveDelta?.x != 0.0) {
|
||||
sprite?.switchRow(SPRITE_ROW_WALK)
|
||||
spriteGlow?.switchRow(SPRITE_ROW_WALK)
|
||||
}
|
||||
// set anim frame delay
|
||||
// 4f of the divider is a magic number, empirically decided
|
||||
sprite?.delays?.set(SPRITE_ROW_WALK, scale.sqrt().toFloat() / (4f * (controllerMoveDelta?.x ?: 0.0001).abs().toFloat())) // FIXME empirical value
|
||||
spriteGlow?.delays?.set(SPRITE_ROW_WALK, scale.sqrt().toFloat() / (4f * (controllerMoveDelta?.x ?: 0.0001).abs().toFloat())) // FIXME empirical value
|
||||
|
||||
// flipping the sprite
|
||||
if (walkHeading == LEFT) {
|
||||
|
||||
@@ -34,7 +34,6 @@ internal class FixtureTikiTorch : FixtureBase(
|
||||
lightBoxList.add(Hitbox(3.0, 0.0, 4.0, 3.0))
|
||||
|
||||
makeNewSprite(TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/fixtures/tiki_torch.tga"), 10, 27))
|
||||
sprite!!.delay = 0.2f
|
||||
sprite!!.setRowsAndFrames(1, 1)
|
||||
|
||||
actorValue[AVKey.BASEMASS] = 1.0
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.ModMgr
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||
import net.torvald.terrarum.gameactors.ai.NullAI
|
||||
@@ -28,7 +27,6 @@ object PlayerBuilderCynthia {
|
||||
|
||||
|
||||
p.makeNewSprite(TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/test_player_2.tga"), 26, 42))
|
||||
p.sprite!!.delay = 0.2f
|
||||
p.sprite!!.setRowsAndFrames(1, 1)
|
||||
|
||||
p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT) ?: ActorHumanoid.BASE_HEIGHT, 9, 0)
|
||||
|
||||
@@ -20,11 +20,9 @@ object PlayerBuilderSigrid {
|
||||
|
||||
|
||||
p.makeNewSprite(TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/test_player.tga"), 28, 51))
|
||||
p.sprite!!.delay = 0.2f
|
||||
p.sprite!!.setRowsAndFrames(1, 1)
|
||||
|
||||
p.makeNewSpriteGlow(TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/test_player_glow.tga"), 28, 51))
|
||||
p.spriteGlow!!.delay = 0.2f
|
||||
p.spriteGlow!!.setRowsAndFrames(1, 1)
|
||||
|
||||
p.actorValue[AVKey.SCALE] = 1.0
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.ModMgr
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.modulebasegame.Ingame
|
||||
import net.torvald.terrarum.worlddrawer.FeaturesDrawer
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
|
||||
@@ -23,12 +21,12 @@ object PlayerBuilderTestSubject1 {
|
||||
|
||||
|
||||
p.makeNewSprite(TextureRegionPack(ModMgr.getGdxFile("basegame", "sprites/npc_template_anim_prototype.tga"), 48, 52))
|
||||
p.sprite!!.delay = 0.2f
|
||||
p.sprite!!.delays = floatArrayOf(2f, 1f/12f) // second value does nothing -- overridden by ActorHumanoid.updateSprite(float)
|
||||
p.sprite!!.setRowsAndFrames(2, 4)
|
||||
|
||||
p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT) ?: ActorHumanoid.BASE_HEIGHT, 21, 0)
|
||||
|
||||
p.setPosition(4096.0 * FeaturesDrawer.TILE_SIZE, 300.0 * FeaturesDrawer.TILE_SIZE)
|
||||
p.setPosition(3.0 * FeaturesDrawer.TILE_SIZE, 3.0 * FeaturesDrawer.TILE_SIZE)
|
||||
|
||||
|
||||
|
||||
|
||||
65
src/net/torvald/terrarum/tests/RGBtoXYZBenchmark.kt
Normal file
65
src/net/torvald/terrarum/tests/RGBtoXYZBenchmark.kt
Normal file
@@ -0,0 +1,65 @@
|
||||
package net.torvald.terrarum.tests
|
||||
|
||||
import net.torvald.colourutil.CIEXYZUtil.linearise
|
||||
import net.torvald.colourutil.CIEXYZUtil.unLinearise
|
||||
import net.torvald.colourutil.ColourUtil.getLuminosity
|
||||
import net.torvald.colourutil.ColourUtil.getLuminosityQuick
|
||||
import net.torvald.colourutil.RGB
|
||||
import net.torvald.random.HQRNG
|
||||
import kotlin.system.measureNanoTime
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2019-01-03.
|
||||
*/
|
||||
class RGBtoXYZBenchmark {
|
||||
|
||||
private val TEST_SIZE = 100000
|
||||
private val TEST_CHUNK = 1000
|
||||
|
||||
operator fun invoke() {
|
||||
val rng = HQRNG()
|
||||
// prepare test sets
|
||||
val testSets = Array(TEST_SIZE) {
|
||||
RGB(rng.nextFloat(), rng.nextFloat(), rng.nextFloat())
|
||||
}
|
||||
// make sure to initialise Util's LUT
|
||||
testSets[rng.nextInt(0, testSets.size)].linearise()
|
||||
testSets[rng.nextInt(0, testSets.size)].unLinearise()
|
||||
|
||||
|
||||
// conduct the experiment
|
||||
val timer1 = ArrayList<Long>()
|
||||
val timer2 = ArrayList<Long>()
|
||||
|
||||
|
||||
for (i in 0 until TEST_SIZE step TEST_CHUNK) {
|
||||
|
||||
val time1 = measureNanoTime {
|
||||
for (c in i until i + TEST_CHUNK) {
|
||||
testSets[c].getLuminosity()
|
||||
}
|
||||
}
|
||||
|
||||
val time2 = measureNanoTime {
|
||||
for (c in i until i + TEST_CHUNK) {
|
||||
testSets[c].getLuminosityQuick()
|
||||
}
|
||||
}
|
||||
|
||||
timer1.add(time1)
|
||||
timer2.add(time2)
|
||||
}
|
||||
|
||||
|
||||
// print out captured data
|
||||
println("with LUT\tno LUT\tmult")
|
||||
for (i in 0 until timer1.size) {
|
||||
println("${timer1[i]}\t${timer2[i]}\t${timer1[i].toFloat() / timer2[i]}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
RGBtoXYZBenchmark().invoke()
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user