mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 11:04:05 +09:00
doppler effect
This commit is contained in:
@@ -25,6 +25,7 @@ import net.torvald.terrarum.blockproperties.WireCodex
|
|||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.gameactors.ActorID
|
import net.torvald.terrarum.gameactors.ActorID
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
|
import net.torvald.terrarum.gameactors.ActorWithBody.Companion.METER
|
||||||
import net.torvald.terrarum.gameactors.faction.FactionCodex
|
import net.torvald.terrarum.gameactors.faction.FactionCodex
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.itemproperties.CraftingCodex
|
import net.torvald.terrarum.itemproperties.CraftingCodex
|
||||||
@@ -91,7 +92,7 @@ object Terrarum : Disposable {
|
|||||||
/**
|
/**
|
||||||
* To be used with physics simulator. This is a magic number.
|
* To be used with physics simulator. This is a magic number.
|
||||||
*/
|
*/
|
||||||
const val PHYS_TIME_FRAME: Double = 26.0 + (2.0 / 3.0)
|
const val PHYS_TIME_FRAME: Double = METER
|
||||||
// 26.0 + (2.0 / 3.0) // lower value == faster gravity response (IT WON'T HOTSWAP!!)
|
// 26.0 + (2.0 / 3.0) // lower value == faster gravity response (IT WON'T HOTSWAP!!)
|
||||||
// protip: using METER, game unit and SI unit will have same number
|
// protip: using METER, game unit and SI unit will have same number
|
||||||
|
|
||||||
@@ -973,11 +974,15 @@ inline fun Disposable.tryDispose() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun distBetweenActors(a: ActorWithBody, b: ActorWithBody): Double {
|
fun distBetweenActors(a: ActorWithBody, b: ActorWithBody): Double {
|
||||||
|
return distBetweenPoints(a.centrePosVector, b.centrePosVector)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun distBetweenPoints(a: Vector2, b: Vector2): Double {
|
||||||
val ww = INGAME.world.width * TILE_SIZED
|
val ww = INGAME.world.width * TILE_SIZED
|
||||||
val apos1 = a.centrePosVector
|
val apos1 = a
|
||||||
val apos2 = Vector2(apos1.x + ww, apos1.y)
|
val apos2 = Vector2(apos1.x + ww, apos1.y)
|
||||||
val apos3 = Vector2(apos1.x - ww, apos1.y)
|
val apos3 = Vector2(apos1.x - ww, apos1.y)
|
||||||
val bpos = b.centrePosVector
|
val bpos = b
|
||||||
val dist = min(min(bpos.distanceSquared(apos1), bpos.distanceSquared(apos2)), bpos.distanceSquared(apos3))
|
val dist = min(min(bpos.distanceSquared(apos1), bpos.distanceSquared(apos2)), bpos.distanceSquared(apos3))
|
||||||
return dist.sqrt()
|
return dist.sqrt()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray)
|
|||||||
|
|
||||||
private val finL = FloatArray(fetchSize + 2 * PADSIZE)
|
private val finL = FloatArray(fetchSize + 2 * PADSIZE)
|
||||||
private val finR = FloatArray(fetchSize + 2 * PADSIZE)
|
private val finR = FloatArray(fetchSize + 2 * PADSIZE)
|
||||||
private val fmidL = FloatArray((fetchSize / q + 1.0).toInt())
|
private val fmidL = FloatArray((fetchSize / q + 1.0).toInt() * 2)
|
||||||
private val fmidR = FloatArray((fetchSize / q + 1.0).toInt())
|
private val fmidR = FloatArray((fetchSize / q + 1.0).toInt() * 2)
|
||||||
private val foutL = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
|
private val foutL = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
|
||||||
private val foutR = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
|
private val foutR = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
|
||||||
private val readBuf = ByteArray(fetchSize * 4)
|
private val readBuf = ByteArray(fetchSize * 4)
|
||||||
|
|||||||
@@ -2,16 +2,16 @@ package net.torvald.terrarum.audio
|
|||||||
|
|
||||||
import com.badlogic.gdx.utils.Queue
|
import com.badlogic.gdx.utils.Queue
|
||||||
import net.torvald.reflection.forceInvoke
|
import net.torvald.reflection.forceInvoke
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.*
|
||||||
|
import net.torvald.terrarum.audio.AudioMixer.Companion.SPEED_OF_SOUND_AIR
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED
|
||||||
import net.torvald.terrarum.audio.dsp.BinoPan
|
import net.torvald.terrarum.audio.dsp.BinoPan
|
||||||
import net.torvald.terrarum.audio.dsp.Lowpass
|
import net.torvald.terrarum.audio.dsp.Lowpass
|
||||||
import net.torvald.terrarum.audio.dsp.NullFilter
|
import net.torvald.terrarum.audio.dsp.NullFilter
|
||||||
import net.torvald.terrarum.distBetweenActors
|
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.relativeXposition
|
import net.torvald.terrarum.gameactors.ActorWithBody.Companion.GAME_TO_SI_VELO
|
||||||
import net.torvald.terrarum.sqr
|
import org.dyn4j.geometry.Vector2
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,7 +136,19 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
|
|||||||
(SAMPLING_RATED*0.5) / (24.0 * (distFromActor / distFalloff).sqr() + 1.0)
|
(SAMPLING_RATED*0.5) / (24.0 * (distFromActor / distFalloff).sqr() + 1.0)
|
||||||
)
|
)
|
||||||
|
|
||||||
// printdbg("dist=$distFromActor\tvol=${fullscaleToDecibels(vol)}\tcutoff=${(track.filters[1] as Lowpass).cutoff}")
|
val sourceVec = (track.trackingTarget as ActorWithBody).let { it.externalV + (it.controllerV ?: Vector2()) }
|
||||||
|
val listenerVec = App.audioMixer.actorNowPlaying!!.let { it.externalV + (it.controllerV ?: Vector2()) }
|
||||||
|
val distFromActorNext = distBetweenPoints(
|
||||||
|
App.audioMixer.actorNowPlaying!!.centrePosVector + listenerVec,
|
||||||
|
(track.trackingTarget as ActorWithBody).centrePosVector + sourceVec
|
||||||
|
)
|
||||||
|
val isApproaching = if (distFromActorNext <= distFromActor) 1.0 else -1.0
|
||||||
|
val relativeSpeed = (sourceVec - listenerVec).magnitude * GAME_TO_SI_VELO * isApproaching
|
||||||
|
val dopplerFactor = (SPEED_OF_SOUND_AIR + relativeSpeed) / SPEED_OF_SOUND_AIR // >1: speedup, <1: speeddown
|
||||||
|
|
||||||
|
track.processor.streamBuf?.playbackSpeed = dopplerFactor.toFloat()
|
||||||
|
|
||||||
|
// printdbg("dist=$distFromActor\tvol=${fullscaleToDecibels(vol)}\tcutoff=${(track.filters[1] as Lowpass).cutoff}\tdopplerFactor=$dopplerFactor")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -2124,15 +2124,20 @@ open class ActorWithBody : Actor {
|
|||||||
*/
|
*/
|
||||||
@Transient const val SI_TO_GAME_ACC = METER / (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME)
|
@Transient const val SI_TO_GAME_ACC = METER / (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME)
|
||||||
/**
|
/**
|
||||||
* [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame]
|
* [m / s] * SI_TO_GAME_VEL0 -> [px / InternalFrame]
|
||||||
*/
|
*/
|
||||||
@Transient const val SI_TO_GAME_VEL = METER / Terrarum.PHYS_TIME_FRAME
|
@Transient const val SI_TO_GAME_VELO = METER / Terrarum.PHYS_TIME_FRAME
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [px / InternalFrame^2] * GAME_TO_SI_ACC -> [m / s^2]
|
* [px / InternalFrame^2] * GAME_TO_SI_ACC -> [m / s^2]
|
||||||
*/
|
*/
|
||||||
@Transient const val GAME_TO_SI_ACC = (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME) / METER
|
@Transient const val GAME_TO_SI_ACC = (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME) / METER
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [px / InternalFrame] * GAME_TO_SI_VELO -> [m / s]
|
||||||
|
*/
|
||||||
|
@Transient const val GAME_TO_SI_VELO = Terrarum.PHYS_TIME_FRAME / METER
|
||||||
|
|
||||||
@Transient const val PHYS_EPSILON_DIST = 1.0 / 4096.0
|
@Transient const val PHYS_EPSILON_DIST = 1.0 / 4096.0
|
||||||
@Transient const val PHYS_EPSILON_VELO = 1.0 / 65536.0
|
@Transient const val PHYS_EPSILON_VELO = 1.0 / 65536.0
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user