more accurate floating point comparison with epsilon

This commit is contained in:
minjaesong
2022-09-14 10:54:26 +09:00
parent f696672d0f
commit 17f85aa155
4 changed files with 15 additions and 10 deletions

View File

@@ -854,4 +854,4 @@ fun checkForSavegameDamage(skimmer: DiskSkimmer): Boolean {
e.printStackTrace()
return true
}
}
}

View File

@@ -609,7 +609,9 @@ open class ActorWithBody : Actor {
// make sure tooltip to disable even when the actor's update is paused at unfortunate time
if (!mouseUp && INGAME.getTooltipMessage() == this.tooltipText) INGAME.setTooltipMessage(null)
isStationary = (hitbox - oldHitbox).magnitudeSquared < PHYS_EPSILON_VELO
// isStationary = (hitbox - oldHitbox).magnitudeSquared < PHYS_EPSILON_VELO
isStationary = isCloseEnough(hitbox.startX, oldHitbox.startX) && // this is supposed to be more accurate, idk
isCloseEnough(hitbox.startY, oldHitbox.startY)
}
fun getDrag(externalForce: Vector2): Vector2 {
@@ -774,7 +776,7 @@ open class ActorWithBody : Actor {
}*/
// trying to use same function as the others, in an effort to eliminate the "contradiction" mentioned below
if (isColliding(stepBox, vectorSum.y > PHYS_EPSILON_VELO)) {
if (isColliding(stepBox, vectorSum.y > PHYS_EPSILON_DIST)) {
collidingStep = step
}
@@ -1927,7 +1929,7 @@ open class ActorWithBody : Actor {
@Transient const val GAME_TO_SI_ACC = (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME) / METER
@Transient const val PHYS_EPSILON_DIST = 0.00001
@Transient const val PHYS_EPSILON_VELO = 0.0001
// @Transient const val PHYS_EPSILON_VELO = 0.0001
/**
@@ -1967,6 +1969,8 @@ open class ActorWithBody : Actor {
@Transient private val HITBOX_COLOURS0 = Color(0xFF00FF88.toInt())
@Transient private val HITBOX_COLOURS1 = Color(0xFFFF0088.toInt())
fun isCloseEnough(a: Double, b: Double) = ((a / b).let { if (it.isNaN()) 0.0 else it } - 1).absoluteValue < PHYS_EPSILON_DIST
}

View File

@@ -751,7 +751,7 @@ open class ActorHumanoid : ActorWithBody, Controllable, Pocketed, Factionable, L
if (this is HasAssembledSprite) {
try {
val baseDelay = animDesc!!.getAnimByFrameName("ANIM_RUN").delay
val moveSpeedMult = (controllerV?.x ?: 0.0).abs().coerceAtLeast(PHYS_EPSILON_VELO).toFloat() / 1.414f // FIXME empirical value
val moveSpeedMult = (controllerV?.x ?: 0.0).abs().coerceAtLeast(0.001).toFloat() / 1.414f // FIXME empirical value
val stride = scale.toFloat()
val maxMoveSpeed = scale.sqrt().toFloat() // ActorWithBody uses scale.sqrt() for determining walk acceleration
val scaleCompensation = stride / maxMoveSpeed

View File

@@ -12,9 +12,7 @@ import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gameitems.mouseInInteractableRange
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import org.dyn4j.geometry.Vector2
import java.util.*
import kotlin.math.absoluteValue
/**
* @param width of hitbox, in tiles, when the door is opened. Default to 2. Closed door always have width of 1. (this limits how big and thick the door can be)
@@ -261,13 +259,16 @@ open class FixtureSwingingDoorBase : FixtureBase {
}
private fun ActorWithBody.movingTowardsRight(): Boolean {
return ((this.controllerV ?: Vector2()) + this.externalV).x >= PHYS_EPSILON_VELO
// return ((this.controllerV ?: Vector2()) + this.externalV).x >= PHYS_EPSILON_VELO
return (((this.controllerV?.x ?: 0.0) / this.externalV.x).let { if (it.isNaN()) 0.0 else it } - 1) >= PHYS_EPSILON_DIST
}
private fun ActorWithBody.movingTowardsLeft(): Boolean {
return ((this.controllerV ?: Vector2()) + this.externalV).x <= -PHYS_EPSILON_VELO
// return ((this.controllerV ?: Vector2()) + this.externalV).x <= -PHYS_EPSILON_VELO
return (((this.controllerV?.x ?: 0.0) / this.externalV.x).let { if (it.isNaN()) 0.0 else it } - 1) <= PHYS_EPSILON_DIST
}
private fun ActorWithBody.notMoving(): Boolean {
return ((this.controllerV ?: Vector2()) + this.externalV).x.absoluteValue < PHYS_EPSILON_VELO
// return ((this.controllerV ?: Vector2()) + this.externalV).x.absoluteValue < PHYS_EPSILON_VELO
return ActorWithBody.isCloseEnough(this.controllerV?.x ?: 0.0, this.externalV.x)
}
private var doorCloseQueueTimer = 0f