Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.silkmc.silk.core.math.vector

import com.mojang.math.Vector3d
import com.mojang.math.Vector3f
import net.minecraft.core.Vec3i
import net.minecraft.world.phys.Vec3
Expand All @@ -18,16 +19,25 @@ operator fun Vec3.times(vec: Vec3): Vec3 = multiply(vec)
operator fun Vec3.div(vec: Vec3): Vec3 = Vec3(x / vec.x, y / vec.y, z / vec.z)
operator fun Vec3.compareTo(vec: Vec3) = lengthSqr().compareTo(vec.lengthSqr())

fun Vec3.toTriple() = Triple(x, y, z)
fun Vec3(x: Number, y: Number, z: Number) = Vec3(x.toDouble(), y.toDouble(), z.toDouble())

operator fun Vec3.component1() = x
operator fun Vec3.component2() = y
operator fun Vec3.component3() = z


operator fun Vector3f.not(): Vector3f = times(-1f)

operator fun Vector3f.plus(n: Number): Vector3f = copy().apply { n.toFloat().let { nFloat -> add(nFloat, nFloat, nFloat) } }
operator fun Vector3f.minus(n: Number): Vector3f = copy().apply { n.toFloat().let { nFloat -> sub(Vector3f(nFloat, nFloat, nFloat)) } }
operator fun Vector3f.times(n: Number): Vector3f = n.toFloat().let { nFloat -> Vector3f(x() * nFloat, y() * nFloat, z() * nFloat) }
operator fun Vector3f.plus(n: Number): Vector3f =
copy().apply { n.toFloat().let { nFloat -> add(nFloat, nFloat, nFloat) } }

operator fun Vector3f.minus(n: Number): Vector3f =
copy().apply { sub(Vector3f(n, n, n)) }

operator fun Vector3f.times(n: Number): Vector3f =
n.toFloat().let { nFloat -> Vector3f(x() * nFloat, y() * nFloat, z() * nFloat) }

operator fun Vector3f.div(n: Number): Vector3f = times(1.0 / n.toDouble())
operator fun Vector3f.compareTo(n: Number) = Vec3(this).length().compareTo(n.toDouble())

Expand All @@ -37,6 +47,16 @@ operator fun Vector3f.times(vec: Vector3f): Vector3f = Vector3f(x() * vec.x(), y
operator fun Vector3f.div(vec: Vector3f): Vector3f = Vector3f(x() / vec.x(), y() / vec.y(), z() / vec.z())
operator fun Vector3f.compareTo(vec: Vector3f) = Vec3(this).lengthSqr().compareTo(Vec3(vec).lengthSqr())

fun Vector3f.toTriple() = Triple(x, y, z)
fun Vector3f(x: Number, y: Number, z: Number) = Vector3f(x.toFloat(), y.toFloat(), z.toFloat())

val Vector3f.x: Float
get() = x()
val Vector3f.y: Float
get() = y()
val Vector3f.z: Float
get() = z()

operator fun Vector3f.component1() = x()
operator fun Vector3f.component2() = y()
operator fun Vector3f.component3() = z()
Expand All @@ -45,17 +65,56 @@ operator fun Vector3f.component3() = z()
operator fun Vec3i.not(): Vec3i = times(-1)

inline operator fun <reified T : Vec3i> T.plus(n: Number): T = n.toInt().let { nInt -> offset(nInt, nInt, nInt) } as T
inline operator fun <reified T : Vec3i> T.minus(n: Number): T = (-n.toInt()).let { nInt -> offset(nInt, nInt, nInt) } as T
inline operator fun <reified T : Vec3i> T.minus(n: Number): T =
(-n.toInt()).let { nInt -> offset(nInt, nInt, nInt) } as T

operator fun Vec3i.times(n: Number): Vec3i = multiply(n.toInt())
operator fun Vec3i.div(n: Number) = (1.0 / n.toDouble()).let { nDouble -> Vec3i(x * nDouble, y * nDouble, z * nDouble) }
operator fun Vec3i.compareTo(n: Number) = Vec3(x.toDouble(), y.toDouble(), z.toDouble()).length().compareTo(n.toDouble())
operator fun Vec3i.compareTo(n: Number) = Vec3(x, y, z).length().compareTo(n.toDouble())

inline operator fun <reified T : Vec3i> T.plus(vec: Vec3i): T = offset(vec) as T
inline operator fun <reified T : Vec3i> T.minus(vec: Vec3i): T = offset(!vec) as T
operator fun Vec3i.times(vec: Vec3i): Vec3i = Vec3i(x * vec.x, y * vec.y, z * vec.z)
operator fun Vec3i.div(vec: Vec3i): Vec3i = Vec3i(x / vec.x, y / vec.y, z / vec.z)
operator fun Vec3i.compareTo(vec: Vec3i) = Vec3(x.toDouble(), y.toDouble(), z.toDouble()).lengthSqr().compareTo(Vec3(vec.x.toDouble(), vec.y.toDouble(), vec.z.toDouble()).lengthSqr())
operator fun Vec3i.compareTo(vec: Vec3i) =
Vec3(x, y, z).lengthSqr().compareTo(Vec3(vec.x, vec.y, vec.z).lengthSqr())

fun Vec3i.toTriple() = Triple(x, y, z)
fun Vec3i(x: Number, y: Number, z: Number) = Vec3i(x.toDouble(), y.toDouble(), z.toDouble())

operator fun Vec3i.component1() = x
operator fun Vec3i.component2() = y
operator fun Vec3i.component3() = z

operator fun Vector3d.not(): Vector3d = times(-1f)

operator fun Vector3d.plus(n: Number): Vector3d =
copy().apply { n.toDouble().let { set(it + x, it + y, it + z) } }

operator fun Vector3d.minus(n: Number): Vector3d =
copy().apply { n.toDouble().let { set(x - it, y - it, z - it) } }

operator fun Vector3d.times(n: Number): Vector3d = copy().apply { n.toDouble().let { times -> scale(times) } }
operator fun Vector3d.div(n: Number): Vector3d = times(1.0 / n.toDouble())
operator fun Vector3d.compareTo(n: Number) = Vec3(x, y, z).length().compareTo(n.toDouble())

operator fun Vector3d.plus(vec: Vector3d): Vector3d = copy().apply { add(vec) }
operator fun Vector3d.minus(vec: Vector3d): Vector3d = Vector3d(x - vec.x, y - vec.y, z - vec.z)
operator fun Vector3d.times(vec: Vector3d): Vector3d = Vector3d(x * vec.x, y * vec.y, z * vec.z)
operator fun Vector3d.div(vec: Vector3d): Vector3d = Vector3d(x / vec.x, y / vec.y, z / vec.z)
operator fun Vector3d.compareTo(vec: Vector3d) =
Vec3(x, y, z).lengthSqr().compareTo(Vec3(vec.x, vec.y, vec.z).lengthSqr())

fun Vector3d.copy() = Vector3d(x, y, z)
fun Vector3d.toTriple() = Triple(x, y, z)
fun Vector3d(x: Number, y: Number, z: Number) = Vector3d(x.toDouble(), y.toDouble(), z.toDouble())

operator fun Vector3d.component1() = x
operator fun Vector3d.component2() = y
operator fun Vector3d.component3() = z


fun <T : Number> Triple<T, T, T>.toVec3() = Vec3(first, second, third)
fun <T : Number> Triple<T, T, T>.toVec3i() = Vec3i(first, second, third)
fun <T : Number> Triple<T, T, T>.toVector3f() = Vector3f(first, second, third)
fun <T : Number> Triple<T, T, T>.toVector3d() = Vector3d(first, second, third)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.silkmc.silk.core.serialization

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

abstract class SilkDelegateSerializer<T, D>(
private val delegateSerializer: KSerializer<D>,
private val convertTo: T.() -> D,
private val convertFrom: D.() -> T,
) : KSerializer<T> {

override val descriptor: SerialDescriptor
get() = delegateSerializer.descriptor

override fun deserialize(decoder: Decoder): T {
return decoder.decodeSerializableValue(delegateSerializer).convertFrom()
}

override fun serialize(encoder: Encoder, value: T) {
encoder.encodeSerializableValue(delegateSerializer, value.convertTo())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.silkmc.silk.core.serialization

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import net.silkmc.silk.core.serialization.serializers.Vec3iSerializer
import net.silkmc.silk.core.serialization.serializers.Vector3dSerializer
import net.silkmc.silk.core.serialization.serializers.Vector3fSerializer

val silkSerializersModule = SerializersModule {
contextual(Vec3iSerializer)
contextual(Vector3fSerializer)
contextual(Vector3dSerializer)
}

val SilkJson = Json {
serializersModule = silkSerializersModule
}

@OptIn(ExperimentalSerializationApi::class)
val SilkCbor = Cbor {
serializersModule = silkSerializersModule
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package net.silkmc.silk.core.serialization.serializers

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import net.minecraft.core.Vec3i
import net.minecraft.core.BlockPos
import net.silkmc.silk.core.serialization.SilkSerializer

/**
* Use vector serializers for structure. [BlockPos] is a [Vec3i]
*/
@ExperimentalSerializationApi
object BlockPosSerializer : SilkSerializer<BlockPos>() {
override val descriptor = PrimitiveSerialDescriptor(descriptorName, PrimitiveKind.LONG)

override fun deserialize(decoder: Decoder) = BlockPos.of(decoder.decodeLong())!!

override fun serialize(encoder: Encoder, value: BlockPos) = encoder.encodeLong(value.asLong())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.silkmc.silk.core.serialization.serializers

import com.mojang.math.Vector3d
import com.mojang.math.Vector3f
import net.minecraft.core.Vec3i
import net.silkmc.silk.core.serialization.SilkDelegateSerializer
import net.silkmc.silk.core.world.pos.Pos3d
import net.silkmc.silk.core.world.pos.Pos3f
import net.silkmc.silk.core.world.pos.Pos3i

object Vec3iSerializer :
SilkDelegateSerializer<Vec3i, Pos3i>(Pos3i.serializer(), ::Pos3i, Pos3i::toMcVec3i)

object Vector3fSerializer :
SilkDelegateSerializer<Vector3f, Pos3f>(Pos3f.serializer(), ::Pos3f, Pos3f::toMcVector3f)

object Vector3dSerializer :
SilkDelegateSerializer<Vector3d, Pos3d>(Pos3d.serializer(), ::Pos3d, Pos3d::toMcVector3d)
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ data class Pos2d(override val x: Double, override val z: Double) : Pos2Dimension
@Serializable
@SerialName("pos3i")
data class Pos3i(override val x: Int, override val y: Int, override val z: Int) : Pos3DimensionalConvertible<Int, Pos2i, Pos3i> {
constructor(vec3i: Vec3i) : this(vec3i.x, vec3i.y, vec3i.z)

override fun atY(y: Int) = Pos3i(x, y, z)
override fun withoutHeight() = Pos2i(x, z)
}
Expand All @@ -161,6 +163,8 @@ data class Pos3i(override val x: Int, override val y: Int, override val z: Int)
@Serializable
@SerialName("pos3f")
data class Pos3f(override val x: Float, override val y: Float, override val z: Float) : Pos3DimensionalConvertible<Float, Pos2f, Pos3f> {
constructor(vector3f: Vector3f) : this(vector3f.x(), vector3f.y(), vector3f.z())

override fun atY(y: Float) = Pos3f(x, y, z)
override fun withoutHeight() = Pos2f(x, z)
}
Expand All @@ -172,6 +176,8 @@ data class Pos3f(override val x: Float, override val y: Float, override val z: F
@Serializable
@SerialName("pos3d")
data class Pos3d(override val x: Double, override val y: Double, override val z: Double) : Pos3DimensionalConvertible<Double, Pos2d, Pos3d> {
constructor(vector3d: Vector3d) : this(vector3d.x, vector3d.y, vector3d.z)

override fun atY(y: Double) = Pos3d(x, y, z)
override fun withoutHeight() = Pos2d(x, z)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package net.silkmc.silk.core.test.serialization

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import kotlinx.serialization.encodeToString
import net.silkmc.silk.core.math.vector.Vec3i
import net.silkmc.silk.core.serialization.SilkJson

class VectorSerialization : FunSpec({
val json = SilkJson

context("serialize 3d vectors") {
test("blockpos") {
json.encodeToString(Vec3i(1, 2, 3)) shouldBe """{"x":1,"y":2,"z":3}"""
}
}
})