Skip to content

Commit

Permalink
feat: data structures
Browse files Browse the repository at this point in the history
  • Loading branch information
andantet committed Nov 7, 2024
1 parent 04a9aba commit 84573ca
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/main/kotlin/net/mcbrawls/railroad/CameraTrack.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package net.mcbrawls.railroad

import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder

/**
* A camera track which can be played to a player.
*/
data class CameraTrack(
val keyframes: List<TrackKeyframe>,
) {
data class TrackKeyframe(
/**
* The time at which the keyframe is played on the track.
*/
val seconds: Float,

/**
* The keyframe to be played.
*/
val keyframe: Keyframe,
) {
companion object {
/**
* The codec for this class.
*/
val CODEC: Codec<TrackKeyframe> = RecordCodecBuilder.create { instance ->
instance.group(
Codec.FLOAT.fieldOf("seconds").forGetter(TrackKeyframe::seconds),
Keyframe.CODEC.fieldOf("keyframe").forGetter(TrackKeyframe::keyframe),
).apply(instance, ::TrackKeyframe)
}
}
}

companion object {
/**
* The codec for this class.
*/
val CODEC: Codec<CameraTrack> = RecordCodecBuilder.create { instance ->
instance.group(
TrackKeyframe.CODEC.listOf().fieldOf("keyframes").forGetter(CameraTrack::keyframes),
).apply(instance, ::CameraTrack)
}
}
}
21 changes: 21 additions & 0 deletions src/main/kotlin/net/mcbrawls/railroad/Interpolation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.mcbrawls.railroad

import net.mcbrawls.railroad.Vectors.cubicInterpolate

fun interface Interpolation {
fun apply(delta: Float, keyframe: Keyframe, targetKeyframe: Keyframe): Keyframe

companion object {
val LINEAR: Interpolation = Interpolation { delta, keyframe, targetKeyframe ->
val pos = keyframe.pos.lerp(targetKeyframe.pos, delta.toDouble())
val rotation = keyframe.rotation.lerp(targetKeyframe.rotation, delta)
Keyframe(pos, rotation)
}

val CUBIC: Interpolation = Interpolation { delta, keyframe, targetKeyframe ->
val pos = keyframe.pos.cubicInterpolate(targetKeyframe.pos, delta)
val rotation = keyframe.rotation.cubicInterpolate(targetKeyframe.rotation, delta)
Keyframe(pos, rotation)
}
}
}
26 changes: 26 additions & 0 deletions src/main/kotlin/net/mcbrawls/railroad/Keyframe.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package net.mcbrawls.railroad

import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import org.joml.Vector2f
import org.joml.Vector3d

/**
* A position along a camera track.
*/
data class Keyframe(
val pos: Vector3d,
val rotation: Vector2f,
) {
companion object {
/**
* The codec for this class.
*/
val CODEC: Codec<Keyframe> = RecordCodecBuilder.create { instance ->
instance.group(
Vectors.VECTOR_3D.fieldOf("position").forGetter(Keyframe::pos),
Vectors.VECTOR_2F.fieldOf("rotation").forGetter(Keyframe::rotation),
).apply(instance, ::Keyframe)
}
}
}
56 changes: 56 additions & 0 deletions src/main/kotlin/net/mcbrawls/railroad/Vectors.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package net.mcbrawls.railroad

import com.mojang.serialization.Codec
import org.joml.Vector2f
import org.joml.Vector3d

object Vectors {
val VECTOR_3D: Codec<Vector3d> = Codec.DOUBLE.listOf().xmap(
{ list -> Vector3d(list[0], list[1], list[2]) },
{ vect -> listOf(vect.x, vect.y, vect.z) }
)

val VECTOR_2F: Codec<Vector2f> = Codec.FLOAT.listOf().xmap(
{ list -> Vector2f(list[0], list[1]) },
{ vect -> listOf(vect.x, vect.y) }
)

fun Vector3d.cubicInterpolate(end: Vector3d, delta: Float): Vector3d {
val start = this

val t2 = delta * delta
val t3 = t2 * delta

val m0 = (end.sub(start)).mul(0.5)

val h0 = 2 * t3 - 3 * t2 + 1
val h1 = -2 * t3 + 3 * t2
val h2 = t3 - 2 * t2 + delta
val h3 = t3 - t2

return Vector3d(
start.x * h0 + end.x * h1 + m0.x * h2 + m0.x * h3,
start.y * h0 + end.y * h1 + m0.y * h2 + m0.y * h3,
start.z * h0 + end.z * h1 + m0.z * h2 + m0.z * h3
)
}

fun Vector2f.cubicInterpolate(end: Vector2f, delta: Float): Vector2f {
val start = this

val t2 = delta * delta
val t3 = t2 * delta

val m0 = (end.sub(start)).mul(0.5f)

val h0 = 2 * t3 - 3 * t2 + 1
val h1 = -2 * t3 + 3 * t2
val h2 = t3 - 2 * t2 + delta
val h3 = t3 - t2

return Vector2f(
start.x * h0 + end.x * h1 + m0.x * h2 + m0.x * h3,
start.y * h0 + end.y * h1 + m0.y * h2 + m0.y * h3
)
}
}

0 comments on commit 84573ca

Please sign in to comment.