All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.bixilon.kotlinglm.Packing.kt Maven / Gradle / Ivy

There is a newer version: 0.9.9.1-12
Show newest version
package de.bixilon.kotlinglm

import de.bixilon.kotlinglm.ext.equal
import de.bixilon.kotlinglm.GLM.clamp
import de.bixilon.kotlinglm.GLM.detail
import de.bixilon.kotlinglm.GLM.floatBitsToInt
import de.bixilon.kotlinglm.GLM.floor
import de.bixilon.kotlinglm.GLM.intBitsToFloat
import de.bixilon.kotlinglm.GLM.isInf
import de.bixilon.kotlinglm.GLM.isNan
import de.bixilon.kotlinglm.GLM.log2
import de.bixilon.kotlinglm.GLM.max
import de.bixilon.kotlinglm.GLM.pow
import de.bixilon.kotlinglm.GLM.round
import de.bixilon.kotlinglm.vec1.Vec1
import de.bixilon.kotlinglm.vec1.Vec1s
import de.bixilon.kotlinglm.vec2.*
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec4.*
import unsigned.*
import kotlin.experimental.or

interface detail_Packing {

    fun float2half(f: Int): Short {
        /*  10 bits    =>                         EE EEEFFFFF
            11 bits    =>                        EEE EEFFFFFF
            Half bits  =>                   SEEEEEFF FFFFFFFF
            Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF

            0x00007c00 => 00000000 00000000 01111100 00000000
            0x000003ff => 00000000 00000000 00000011 11111111
            0x38000000 => 00111000 00000000 00000000 00000000
            0x7f800000 => 01111111 10000000 00000000 00000000
            0x00008000 => 00000000 00000000 10000000 00000000   */
        val sign = (f ushr 16) and 0x8000
        val exponential = (((f and 0x7f800000) - 0x38000000) ushr 13) and 0x7c00
        val mantissa = (f ushr 13) and 0x03ff
        return (sign or exponential or mantissa).s
    }

    fun float2packed11(f: Int): Int {
        /*  10 bits    =>                         EE EEEFFFFF
            11 bits    =>                        EEE EEFFFFFF
            Half bits  =>                   SEEEEEFF FFFFFFFF
            Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF

            0x000007c0 => 00000000 00000000 00000111 11000000
            0x00007c00 => 00000000 00000000 01111100 00000000
            0x000003ff => 00000000 00000000 00000011 11111111
            0x38000000 => 00111000 00000000 00000000 00000000
            0x7f800000 => 01111111 10000000 00000000 00000000
            0x00008000 => 00000000 00000000 10000000 00000000   */
        val exponential = (((f and 0x7f800000) - 0x38000000) ushr 17) and 0x07c0
        val mantissa = (f ushr 17) and 0x003f
        return exponential or mantissa
    }

    fun packed11ToFloat(p: Int): Int {
        /*  10 bits    =>                         EE EEEFFFFF
            11 bits    =>                        EEE EEFFFFFF
            Half bits  =>                   SEEEEEFF FFFFFFFF
            Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF

            0x000007c0 => 00000000 00000000 00000111 11000000
            0x00007c00 => 00000000 00000000 01111100 00000000
            0x000003ff => 00000000 00000000 00000011 11111111
            0x38000000 => 00111000 00000000 00000000 00000000
            0x7f800000 => 01111111 10000000 00000000 00000000
            0x00008000 => 00000000 00000000 10000000 00000000   */
        val exponential = (((p and 0x07c0) shl 17) + 0x38000000) and 0x7f800000
        val mantissa = (p and 0x003f) shl 17
        return exponential or mantissa
    }

    fun float2packed10(f: Int): Int {
        /*  10 bits    =>                         EE EEEFFFFF
            11 bits    =>                        EEE EEFFFFFF
            Half bits  =>                   SEEEEEFF FFFFFFFF
            Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF

            0x0000001F => 00000000 00000000 00000000 00011111
            0x0000003F => 00000000 00000000 00000000 00111111
            0x000003E0 => 00000000 00000000 00000011 11100000
            0x000007C0 => 00000000 00000000 00000111 11000000
            0x00007C00 => 00000000 00000000 01111100 00000000
            0x000003FF => 00000000 00000000 00000011 11111111
            0x38000000 => 00111000 00000000 00000000 00000000
            0x7f800000 => 01111111 10000000 00000000 00000000
            0x00008000 => 00000000 00000000 10000000 00000000   */
        val exponential = (((f and 0x7f800000) - 0x38000000) ushr 18) and 0x03E0
        val mantissa = (f ushr 18) and 0x001f
        return exponential or mantissa
    }

    fun packed10ToFloat(p: Int): Int {
        /*  10 bits    =>                         EE EEEFFFFF
            11 bits    =>                        EEE EEFFFFFF
            Half bits  =>                   SEEEEEFF FFFFFFFF
            Float bits => SEEEEEEE EFFFFFFF FFFFFFFF FFFFFFFF

            0x0000001F => 00000000 00000000 00000000 00011111
            0x0000003F => 00000000 00000000 00000000 00111111
            0x000003E0 => 00000000 00000000 00000011 11100000
            0x000007C0 => 00000000 00000000 00000111 11000000
            0x00007C00 => 00000000 00000000 01111100 00000000
            0x000003FF => 00000000 00000000 00000011 11111111
            0x38000000 => 00111000 00000000 00000000 00000000
            0x7f800000 => 01111111 10000000 00000000 00000000
            0x00008000 => 00000000 00000000 10000000 00000000   */
        val exponential = (((p and 0x03E0) shl 18) + 0x38000000) and 0x7f800000
        val mantissa = (p and 0x001f) shl 18
        return exponential or mantissa
    }

    fun half2float(h: Int) = ((h and 0x8000) shl 16) or (((h and 0x7c00) + 0x1C000) shl 13) or ((h and 0x03FF) shl 13)

    fun floatTo11bit(x: Float): Int {

        if (x == 0f)
            return 0
        else if (isNan(x))
            return 0.inv()
        else if (isInf(x))
            return 0x1F shl 6

        val pack = floatBitsToInt(x)
        return float2packed11(pack)
    }

    fun packed11bitToFloat(x: Int): Float {

        if (x == 0)
            return 0f
        else if (x == ((1 shl 11) - 1))
            return 0.inv().f  //NaN
        else if (x == (0x1f shl 6))
            return 0.inv().f   //Inf

        val result = packed11ToFloat(x)

        return intBitsToFloat(result)
    }

    fun floatTo10bit(x: Float): Int {

        if (x == 0f)
            return 0
        else if (isNan(x))
            return 0.inv()
        else if (isInf(x))
            return 0x1F shl 5

        val pack = floatBitsToInt(x)
        return float2packed10(pack)
    }

    fun packed10bitToFloat(x: Int): Float {

        if (x == 0)
            return 0f
        else if (x == ((1 shl 10) - 1))
            return 0.inv().f    //NaN
        else if (x == (0x1f shl 5))
            return 0.inv().f   //Inf

        val result = packed10ToFloat(x)

        return intBitsToFloat(result)
    }

    fun pack(v: Vec1): Vec1s = Vec1s(detail.toFloat16(v.x))

//    GLM_FUNC_QUALIFIER static vec<1, float, Q> unpack(vec<1, uint16, Q> const& v)
//    {
//        i16vec1 Unpack;
//        memcpy(&Unpack, &v, sizeof(Unpack));
//        return vec<1, float, Q>(detail::toFloat32(v.x));
//    }

    fun packHalf(v: Vec4): Vec4s =
            Vec4s(detail.toFloat16(v.x), detail.toFloat16(v.y), detail.toFloat16(v.z), detail.toFloat16(v.w))

    fun unpackHalf(v: Vec4s): Vec4 =
            Vec4(detail.toFloat32(v.x), detail.toFloat32(v.y), detail.toFloat32(v.z), detail.toFloat32(v.w))
}

interface Packing {

    fun packUnorm1x8(v: Float) = round(clamp(v, 0f, 1f) * 255f).b

    fun unpackUnorm1x8(p: Byte) = p.toUInt().f * 0.0039215686274509803921568627451f // 1 / 255

    fun packUnorm2x8(v: Vec2): Short {
        val x = round(clamp(v.x, 0f, 1f) * 255f)
        val y = round(clamp(v.y, 0f, 1f) * 255f)
        return (x.s shl 8) or y.s
    }

    fun unpackUnorm2x8(p: Short, res: Vec2 = Vec2()): Vec2 {
        res.x = (p ushr 8).toUInt().f
        res.y = (p and 0xff).toUInt().f
        res *= 0.0039215686274509803921568627451f // 1 / 255
        return res
    }

    fun packSnorm1x8(v: Float) = round(clamp(v, -1f, 1f) * 127f).b

    fun unpackSnorm1x8(p: Byte) = clamp(p.f * 0.00787401574803149606299212598425f, // 1f / 127f
            -1f, 1f)

    fun packSnorm2x8(v: Vec2): Short {

        val x = round(clamp(v.x, -1f, 1f) * 127f)
        val y = round(clamp(v.y, -1f, 1f) * 127f)

        val a = x.s shl 8
        val b = y.s and 0xff

        return a or b
    }

    fun unpackSnorm2x8(p: Short, res: Vec2 = Vec2()): Vec2 {

        val a = (p shr 8).f
        val b = p.b.f
        res.x = clamp(a * 0.00787401574803149606299212598425f, // 1.0f / 127.0f
                -1f, 1f)
        res.y = clamp(b * 0.00787401574803149606299212598425f, // 1.0f / 127.0f
                -1f, 1f)
        return res
    }

    fun packUnorm1x16(s: Float) = round(clamp(s, 0f, 1f) * 65535f).s

    fun unpackUnorm1x16(p: Short) = p.toUInt().f * 1.5259021896696421759365224689097e-5f // 1.0 / 65535.0

    fun packUnorm4x16(v: Vec4): Long {
        val x = round(clamp(v.x, 0f, 1f) * 65535f)
        val y = round(clamp(v.y, 0f, 1f) * 65535f)
        val z = round(clamp(v.z, 0f, 1f) * 65535f)
        val w = round(clamp(v.w, 0f, 1f) * 65535f)
        val a = x.L shl 48
        val b = y.L shl 32
        val c = z.L shl 16
        val d = w.L
        return (a and "0xffff000000000000".L) or (b and 0xffff00000000) or (c and 0xffff0000) or (d and 0xffff)
    }

    fun unpackUnorm4x16(p: Long, res: Vec4 = Vec4()): Vec4 {
        res.x = (p ushr 48).s.toUInt().f * 1.5259021896696421759365224689097e-5f // 1.0 / 65535.0
        res.y = ((p ushr 32) and 0xffff).s.toUInt().f * 1.5259021896696421759365224689097e-5f // 1.0 / 65535.0
        res.z = ((p ushr 16) and 0xffff).s.toUInt().f * 1.5259021896696421759365224689097e-5f // 1.0 / 65535.0
        res.w = (p and 0xffff).s.toUInt().f * 1.5259021896696421759365224689097e-5f // 1.0 / 65535.0
        return res
    }

    fun packSnorm1x16(v: Float) = round(clamp(v, -1f, 1f) * 32767f).s

    fun unpackSnorm1x16(p: Short) = clamp(p.f * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
            -1f, 1f)

    fun packSnorm4x16(v: Vec4): Long {
        val x = round(clamp(v.x, -1f, 1f) * 32767f).s
        val y = round(clamp(v.y, -1f, 1f) * 32767f).s
        val z = round(clamp(v.z, -1f, 1f) * 32767f).s
        val w = round(clamp(v.w, -1f, 1f) * 32767f).s
        val a = x.L shl 48
        val b = y.L shl 32
        val c = z.L shl 16
        val d = w.L
        return (a and "0xffff000000000000".L) or (b and 0xffff00000000) or (c and 0xffff0000) or (d and 0xffff)
    }

    fun unpackSnorm4x16(p: Long, res: Vec4 = Vec4()): Vec4 {
        val x = (p shr 48).s
        val y = ((p shr 32) and 0xffff).s
        val z = ((p shr 16) and 0xffff).s
        val w = (p and 0xffff).s
        res.x = clamp(x * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
                -1f, 1f)
        res.y = clamp(y * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
                -1f, 1f)
        res.z = clamp(z * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
                -1f, 1f)
        res.w = clamp(w * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
                -1f, 1f)
        return res
    }

    fun packHalf1x16(v: Float) = detail.toFloat16(v)

    fun unpackHalf1x16(v: Short) = detail.toFloat32(v)

    fun packHalf4x16(v: Vec4): Long {
        val x = detail.toFloat16(v.x)
        val y = detail.toFloat16(v.y)
        val z = detail.toFloat16(v.z)
        val w = detail.toFloat16(v.w)
        return (x.toULong() shl 48) or (y.toULong() shl 32) or (z.toULong() shl 16) or w.toULong()
    }

    fun unpackHalf4x16(v: Long, res: Vec4 = Vec4()): Vec4 {
        val x = (v ushr 48).s
        val y = ((v ushr 32) and 0xffff).s
        val z = ((v ushr 16) and 0xffff).s
        val w = (v and 0xffff).s
        res.x = detail.toFloat32(x)
        res.y = detail.toFloat32(y)
        res.z = detail.toFloat32(z)
        res.w = detail.toFloat32(w)
        return res
    }

    fun packI3x10_1x2(v: Vec4i): Int {
        val x = v.x shl 22
        val y = (v.y and 0b11_1111_1111) shl 12
        val z = (v.z and 0b11_1111_1111) shl 2
        val w = v.w and 0b11
        return x or y or z or w
    }

    fun unpackI3x10_1x2(v: Int, res: Vec4i = Vec4i()): Vec4i {
        res.x = v shr 22
        res.y = (v shr 12) and 0b11_1111_1111
        res.z = (v shr 2) and 0b11_1111_1111
        res.w = v and 0b11
        return res
    }

    fun packU3x10_1x2(v: Vec4ui): Uint {
        val x = v.x shl 22
        val y = (v.y and 0b11_1111_1111) shl 12
        val z = (v.z and 0b11_1111_1111) shl 2
        val w = v.w and 0b11
//        val x = v.x and 0b11_1111_1111
//        val y = (v.y and 0b11_1111_1111) shl 10
//        val z = (v.z and 0b11_1111_1111) shl 20
//        val w = (v.w and 0b11) shl 30
        return x or y or z or w
    }

    fun unpackU3x10_1x2(v: Uint, res: Vec4ui = Vec4ui()): Vec4ui {
        res.x = v shr 22
        res.y = (v shr 12) and 0b11_1111_1111
        res.z = (v shr 2) and 0b11_1111_1111
        res.w = v and 0b11
        return res
    }

    fun packSnorm3x10_1x2(v: Vec4): Int {
        val x = round(clamp(v.x, -1f, 1f) * 511f).i
        val y = round(clamp(v.y, -1f, 1f) * 511f).i
        val z = round(clamp(v.z, -1f, 1f) * 511f).i
        val w = round(clamp(v.w, -1f, 1f)).i
        val a = x shl 22
        val b = (y and 0b11_1111_1111) shl 12
        val c = (z and 0b11_1111_1111) shl 2
        val d = w and 0b11
        return a or b or c or d
    }

    fun unpackSnorm3x10_1x2(v: Int, res: Vec4 = Vec4()): Vec4 {
        res.x = (v shr 22).f
        res.y = ((v shr 12) and 0b11_1111_1111).f
        res.z = ((v shr 2) and 0b11_1111_1111).f
        res.z = (v and 0b11).f
        val tmp = 1f / 511f
        res.x = clamp(res.x * tmp, -1f, 1f)
        res.y = clamp(res.y * tmp, -1f, 1f)
        res.z = clamp(res.z * tmp, -1f, 1f)
        res.w = clamp(res.w * tmp, -1f, 1f)
        return res
    }

    fun packUnorm3x10_1x2(v: Vec4): Int {
        val x = round(clamp(v.x, 0f, 1f) * 1023f).i
        val y = round(clamp(v.y, 0f, 1f) * 1023f).i
        val z = round(clamp(v.z, 0f, 1f) * 1023f).i
        val w = round(clamp(v.w, 0f, 1f) * 3f).i
        val a = x shl 22
        val b = (y and 0b11_1111_1111) shl 12
        val c = (z and 0b11_1111_1111) shl 2
        val d = w and 0b11
        return a or b or c or d
    }

    fun unpackUnorm3x10_1x2(v: Int, res: Vec4 = Vec4()): Vec4 {
        val a = 1f / 1023f
        res.x = (v ushr 22) * a
        res.y = ((v ushr 12) and 0b11_1111_1111) * a
        res.z = ((v ushr 2) and 0b11_1111_1111) * a
        res.w = (v and 0b11) * 1f / 3f
        return res
    }

    fun packF2x11_1x10(v: Vec3) = ((detail.floatTo11bit(v.x) and ((1 shl 11) - 1)) shl 22) or
            ((detail.floatTo11bit(v.y) and ((1 shl 11) - 1)) shl 11) or
            ((detail.floatTo10bit(v.z) and ((1 shl 10) - 1)) shl 0)

    fun unpackF2x11_1x10(v: Int, res: Vec3 = Vec3()): Vec3 {
        res.x = detail.packed11bitToFloat(v ushr 22)
        res.y = detail.packed11bitToFloat(v ushr 11)
        res.z = detail.packed10bitToFloat(v ushr 0)
        return res
    }

    fun packF3x9_E1x5(v: Vec3): Int {
        val sharedExpMax = (pow(2f, 9f - 1f) / pow(2f, 9f)) * pow(2f, 31f - 15f)
        val colorX = clamp(v.x, 0f, sharedExpMax)
        val colorY = clamp(v.y, 0f, sharedExpMax)
        val colorZ = clamp(v.z, 0f, sharedExpMax)
        val maxColor = max(colorX, max(colorY, colorZ))

        val expSharedP = max(-15f - 1f, floor(log2(maxColor))) + 1f + 15f
        val maxShared = floor(maxColor / pow(2f, (expSharedP - 15f - 9f)) + 0.5f)
        val expShared = if (maxShared.equal(pow(2f, 9f))) expSharedP + 1f else expSharedP

        val x = floor(colorX / pow(2f, (expShared - 15f - 9f)) + 0.5f).i
        val y = floor(colorY / pow(2f, (expShared - 15f - 9f)) + 0.5f).i
        val z = floor(colorZ / pow(2f, (expShared - 15f - 9f)) + 0.5f).i

        val a = x shl 23
        val b = (y and 0b1_1111_1111) shl 23
        val c = (z and 0b1_1111_1111) shl 23
        val d = expShared.i
        return a or b or c or d
    }

    fun unpackF3x9_E1x5(v: Int, res: Vec3 = Vec3()): Vec3 {

        val pow = pow(2f, (v and 0b1_1111).f - 15f - 9f)
        res.x = (v ushr 23).f * pow
        res.y = ((v ushr 14) and 0b1_1111_1111).f * pow
        res.z = ((v ushr 5) and 0b1_1111_1111).f * pow

        return res
    }

    /** Based on Brian Karis http://graphicrants.blogspot.fr/2009/04/rgbm-color-encoding.html   */
    fun packRGBM(rgb: Vec3, res: Vec4 = Vec4()): Vec4 {
        val tmp = 1f / 6f
        val colorX = rgb.r * tmp
        val colorY = rgb.g * tmp
        val colorZ = rgb.b * tmp
        var alpha = GLM.clamp(GLM.max(GLM.max(colorX, colorY), GLM.max(colorZ, 1e-6f)), 0f, 1f)
        alpha = GLM.ceil(alpha * 255f) / 255f
        res.r = colorX / alpha
        res.g = colorY / alpha
        res.b = colorZ / alpha
        res.a = alpha
        return res
    }

    fun unpackRGBM(rgbm: Vec4, res: Vec3 = Vec3()): Vec3 {
        res.x = rgbm.x * rgbm.w * 6f
        res.y = rgbm.y * rgbm.w * 6f
        res.z = rgbm.z * rgbm.w * 6f
        return res
    }

    fun packUnorm2x4(v: Vec2): Byte {
        val x = GLM.round(GLM.clamp(v.x, 0f, 1f) * 15f).b
        val y = GLM.round(GLM.clamp(v.y, 0f, 1f) * 15f).b
        val a = x shl 4
        val b = y and 0xf
        return a or b
    }

    fun unpackUnorm2x4(v: Byte, res: Vec2 = Vec2()): Vec2 {
        val scaleFactor = 1f / 15f
        res.x = (v ushr 4).i * scaleFactor
        res.y = (v and 0xf).i * scaleFactor
        return res
    }

    fun packUnorm4x4(v: Vec4): Short {
        val x = GLM.round(GLM.clamp(v.x, 0f, 1f) * 15f).s
        val y = GLM.round(GLM.clamp(v.y, 0f, 1f) * 15f).s
        val z = GLM.round(GLM.clamp(v.z, 0f, 1f) * 15f).s
        val w = GLM.round(GLM.clamp(v.w, 0f, 1f) * 15f).s
        return (x shl 12) or (y shl 8) or (z shl 4) or w
    }

    fun unpackUnorm4x4(v: Short, res: Vec4 = Vec4()): Vec4 {
        val scaleFactor = 1f / 15f
        val x = v ushr 12
        val y = (v ushr 8) and 0xf
        val z = (v ushr 4) and 0xf
        val w = v and 0xf
        res.x = x * scaleFactor
        res.y = y * scaleFactor
        res.z = z * scaleFactor
        res.w = w * scaleFactor
        return res
    }

    fun packUnorm1x5_1x6_1x5(v: Vec3): Short {

        val x = GLM.round(GLM.clamp(v.x, 0f, 1f) * 31f).s
        val y = GLM.round(GLM.clamp(v.y, 0f, 1f) * 63f).s
        val z = GLM.round(GLM.clamp(v.z, 0f, 1f) * 31f).s
        val a = x shl 11
        val b = (y and 0b11_1111) shl 5
        val c = z and 0b1_1111
        return a or b or c
    }

    fun unpackUnorm1x5_1x6_1x5(v: Short, res: Vec3 = Vec3()): Vec3 {

        val scaleFactor = 1f / 31f
        val x = v ushr 11
        val y = (v ushr 5) and 0b11_1111
        val z = v and 0b1_1111
        res.x = x * scaleFactor
        res.y = y * 1 / 63f
        res.z = z * scaleFactor
        return res
    }

    fun packUnorm3x5_1x1(v: Vec4): Short {

        val x = GLM.round(GLM.clamp(v.x, 0f, 1f) * 31f).s
        val y = GLM.round(GLM.clamp(v.y, 0f, 1f) * 31f).s
        val z = GLM.round(GLM.clamp(v.z, 0f, 1f) * 31f).s
        val w = GLM.round(GLM.clamp(v.w, 0f, 1f)).s
        return (x shl 11) or (y shl 6) or (z shl 1) or (w and 0b0001)
    }

    fun unpackUnorm3x5_1x1(v: Short, res: Vec4 = Vec4()): Vec4 {

        val scaleFactor = 1f / 31f
        val x = v ushr 11
        val y = (v ushr 6) and 0b0001_1111
        val z = (v ushr 1) and 0b0001_1111
        val w = v and 0b0001
        res.x = x * scaleFactor
        res.y = y * scaleFactor
        res.z = z * scaleFactor
        res.w = w.f
        return res
    }

    fun packUnorm2x3_1x2(v: Vec3): Byte {

        val x = GLM.round(GLM.clamp(v.x, 0f, 1f) * 7f).b
        val y = GLM.round(GLM.clamp(v.y, 0f, 1f) * 7f).b
        val z = GLM.round(GLM.clamp(v.z, 0f, 1f) * 3f).b
        return (x shl 5) or (y shl 2) or z
    }

    fun unpackUnorm2x3_1x2(v: Byte, res: Vec3 = Vec3()): Vec3 {

        val scaleFactor = 1f / 7f
        val x = v ushr 5
        val y = (v ushr 2) and 0b111
        val z = v and 0b11
        res.x = x * scaleFactor
        res.y = y * scaleFactor
        res.z = z * (1f / 3f)
        return res
    }

    fun packInt2x8(v: Vec2b): Short {
        val x = v.x.s shl 8
        val y = v.y.s and 0xff
        return x or y
    }

    fun unpackInt2x8(p: Short, res: Vec2b = Vec2b()): Vec2b {
        res.x = (p shr 8).b
        res.y = (p and 0xff).b
        return res
    }

    fun packUint2x8(v: Vec2ub): Ushort =
            Ushort((v.x.i shl 8) or v.y.i)

    fun unpackUint2x8(p: Ushort, res: Vec2ub = Vec2ub()): Vec2ub {
        res.array[0] = (p shr 8).b // TODO var Vec2ub.xV backed by the array
        res.array[1] = p.b
        return res
    }

    fun packInt4x8(v: Vec4b): Int =
            (v.x.i shl 24) or (v.y.i shl 16) or (v.z.i shl 8) or v.w.i

    fun unpackInt4x8(p: Int, res: Vec4b = Vec4b()): Vec4b {
        res.x = (p shr 24).b
        res.y = (p shr 16).b
        res.z = (p shr 8).b
        res.w = p.b
        return res
    }

    fun packUint4x8(v: Vec4ub): Uint =
            Uint((v.x.i shl 24) or (v.y.i shl 16) or (v.z.i shl 8) or v.w.i)

    fun unpackUint4x8(p: Uint, res: Vec4ub = Vec4ub()): Vec4ub {
        res.array[0] = (p shr 24).b
        res.array[1] = (p shr 16).b
        res.array[2] = (p shr 8).b
        res.array[3] = p.b
        return res
    }

    fun packInt2x16(v: Vec2s): Int =
            (v.x.i shl 16) or v.y.i

    fun unpackInt2x16(p: Int, res: Vec2s = Vec2s()): Vec2s    {
        res.x = (p shr 16).s
        res.y = p.s
        return res
    }

    fun packInt4x16(v: Vec4s): Long =
            (v.x.L shl 48) or (v.y.L shl 32) or (v.z.L shl 16) or v.w.L

    fun unpackInt4x16(p: Long, res: Vec4s = Vec4s()): Vec4s    {
        res.x = (p shr 48).s
        res.y = (p shr 32).s
        res.z = (p shr 16).s
        res.w = p.s
        return res
    }

    fun packUint2x16(v: Vec2us): Uint =
            Uint((v.x.i shl 16) or v.y.i)

    fun unpackUint2x16(p: Uint, res: Vec2us = Vec2us()): Vec2us {
        res.array[0] = (p shr 16).s
        res.array[1] = p.s
        return res
    }

    fun packUint4x16(v: Vec4us): Ulong =
            Ulong((v.x.L shl 48) or (v.y.L shl 32) or (v.z.L shl 16) or v.w.L)

    fun unpackUint4x16(p: Ulong, res: Vec4us = Vec4us()): Vec4us {
        res.array[0] = (p shr 48).s
        res.array[1] = (p shr 32).s
        res.array[2] = (p shr 16).s
        res.array[3] = p.s
        return res
    }

    fun packInt2x32(v: Vec2i): Long =
            (v.x.L shl 32) or v.y.L

    fun unpackInt2x32(p: Long, res: Vec2i = Vec2i()): Vec2i    {
        res.x = (p shr 32).i
        res.y = p.i
        return res
    }

    fun packUint2x32(v: Vec2ui): Ulong =
            Ulong((v.x.L shl 32) or v.y.L)

    fun unpackUint2x32(p: Ulong, res: Vec2ui = Vec2ui()): Vec2ui {
        res.array[0] = (p shr 32).i
        res.array[1] = p.i
        return res
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy