Упаковал 3D-вектор с плавающей точкой в ​​unsigned int и распаковал его - PullRequest
0 голосов
/ 13 мая 2018

GetPacked упакует трехмерную точку в беззнаковое целое. Я хочу распаковать его обратно в точку, но не работать. Помогите пожалуйста

uint32_t GetPacked(float x, float y, float z)
{   
    return ( 0xff000000 
        | ( ( uint32_t ) ( ( x * 127.5f ) + 127.5f ) << 16 )
        | ( ( uint32_t ) ( ( y * 127.5f ) + 127.5f ) << 8 ) 
        | ( ( uint32_t ) ( ( z * 127.5f ) + 127.5f ) ) );
}

// багги распакованы

void UnPacked(uint32_t p, float* _x, float* _y, float* _z)
{
    *_z = ( ( p & 0xff ) - 127.5f) / 127.5f;
    p >>= 8;
    *_y = ( ( ( p ) & 0xff ) - 127.5f) / 127.5f;
    p >>= 8;
    *_x = ( ( ( p ) & 0xff ) - 127.5f) / 127.5f;
}

спасибо

PS: я создал онлайн-тест в ideone

1 Ответ

0 голосов
/ 13 мая 2018

Вы потеряете точность.

// a, b, b in the range of -127.5 +127.5

uint32_t Code(float a, float b, float c)
{
    union
    {
        uint32_t u32;
        uint8_t u8[4];
    } u;

    u.u8[3] = 0xff;
    u.u8[0] = a + 127.5f;
    u.u8[1] = b + 127.5f;
    u.u8[2] = c + 127.5f;

    return u.u32;
}

void DeCode(uint32_t u32, float *a, float *b, float *c)
{
    union
    {
        uint32_t u32;
        uint8_t u8[4];
    } u;

    u.u32 = u32;
    *a = (float)u.u8[0] - 127.5f;
    *b = (float)u.u8[1] - 127.5f;
    *c = (float)u.u8[2] - 127.5f;
}


int main(void)
{
    float a = 102.3f, b = -56.4f, c = -126f, d,e,f;

    uint32_t coded = Code(a, b, c);
    DeCode(coded, &d, &e, &f);

    printf("Original values: %f,%f,%f. Coded -%x. Decoded %f,%f,%f\n", a, b, c, coded, d, e, f);
}

Для большей точности вы можете масштабировать ее до 10 бит.

#define B10MAX      ((float)((1u << 10) - 1))
float Scale(float x)
{
    return B10MAX * (x + 127.5f) / 255.0f;
}

float DeScale(unsigned x)
{
    return 255.0f *(x) / B10MAX - 127.5f;
}

uint32_t Code10(float a, float b, float c)
{
    union
    {
        uint32_t u32;
        struct
        {
            uint32_t value1 : 10;
            uint32_t value2 : 10;
            uint32_t value3 : 10;
        };
    } u;

    u.value1 = Scale(a);
    u.value2 = Scale(b);
    u.value3 = Scale(c);

    return u.u32;
}

void DeCode10(uint32_t v, float *a, float *b, float *c)
{
    union
    {
        uint32_t u32;
        struct
        {
            uint32_t value1 : 10;
            uint32_t value2 : 10;
            uint32_t value3 : 10;
        };
    } u = {.u32 = v,};

    *a = DeScale(u.value1);
    *b = DeScale(u.value2);
    *c = DeScale(u.value3);
}

и в основном

coded = Code10(a, b, c);
DeCode10(coded, &d, &e, &f);

printf("Original values: %f,%f,%f. Coded = %x. Decoded %f,%f,%f\n", a, b, c, coded, d, e, f);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...