// ------------------------------------------------------------------------------
// transform.cxx : Last Revision 22.04.07 : http://www.dilatech.com
// ------------------------------------------------------------------------------

#include "../projekt.hxx"

// ******************************************************************************
float2x2 CXForm::MakeRotation( const float x )
// ******************************************************************************
{
    float2x2 r;
    float *p = r.v[X].v;

    /*
        p[0] = cosf(x);
        p[1] = sinf(x);
        p[2] = -sinf(x);
        p[3] = cosf(x);
    */
    __asm
    {
        fld dword ptr [x]
        fsincos
        fst dword ptr [p+0]
        fld st(1)
        fstp dword ptr [p+4]
        fld st(1)
        fchs
        fstp dword ptr [p+8]
        fstp dword ptr [p+12]
        ffree st(0)
    }

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationX( const float x )
// ******************************************************************************
{
    float4x4 r;
    DALIGN16 float p[16];

    /*
        p[0] = 1.0f;
        p[1] = 0.0f;
        p[2] = 0.0f;
        p[3] = 0.0f;
        p[4] = 0.0f;
        p[5] = cosf(x);
        p[6] = sinf(x);
        p[7] = 0.0f;
        p[8] = 0.0f;
        p[9] = -sinf(x);
        p[10] = cosf(x);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [x]
        fsincos
        fst dword ptr [p+20]
        fld st(1)
        fstp dword ptr [p+24]
        fld st(1)
        fchs
        fstp dword ptr [p+36]
        fstp dword ptr [p+40]
        ffree st(0)
        xor edx, edx
        mov dword ptr [p+4], edx
        mov dword ptr [p+8], edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+16], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+32], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+0], edx
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationY( const float y )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(y);
        p[1] = 0.0f;
        p[2] = -sinf(y);
        p[3] = 0.0f;
        p[4] = 0.0f;
        p[5] = 1.0f;
        p[6] = 0.0f;
        p[7] = 0.0f;
        p[8] = sinf(y);
        p[9] = 0.0f;
        p[10] = cosf(y);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [y]
        fsincos
        fst dword ptr [p+0]
        fld st(1)
        fchs
        fstp dword ptr [p+8]
        fld st(1)
        fstp dword ptr [p+32]
        fstp dword ptr [p+40]
        ffree st(0)
        xor edx, edx
        mov dword ptr [p+4], edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+16], edx
        mov dword ptr [p+24], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+36], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+20], edx
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationZ( const float z )
// ******************************************************************************
{
    float4x4 r;
    __declspec(align(16)) float p[16];

    /*
        p[0] = cosf(z);
        p[1] = sinf(z);
        p[2] = 0.0f;
        p[3] = 0.0f;
        p[4] = -sinf(z);
        p[5] = cosf(z);
        p[6] = 0.0f;
        p[7] = 0.0f;
        p[8] = 0.0f;
        p[9] = 0.0f;
        p[10] = 1.0f;
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [z]
        fsincos
        fst dword ptr [p+0]
        fld st(1)
        fstp dword ptr [p+4]
        fld st(1)
        fchs
        fstp dword ptr [p+16]
        fstp dword ptr [p+20]
        ffree st(0)
        xor edx, edx
        mov dword ptr [p+8], edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+24], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+32], edx
        mov dword ptr [p+36], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+40], edx
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationXY( const float x, const float y )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(y);
        p[1] = 0.0f;
        p[2] = -sinf(y);
        p[3] = 0.0f;
        p[4] = sinf(x)*sinf(y);
        p[5] = cosf(x);
        p[6] = sinf(x)*cosf(y);
        p[7] = 0.0f;
        p[8] = cosf(x)*sinf(y);
        p[9] = -sinf(x);
        p[10] = cosf(x)*cosf(y);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [y]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fstp dword ptr [p+0]
        fld st(3)
        fchs
        fstp dword ptr [p+8]
        fld st(1)
        fmul st(0), st(4)
        fstp dword ptr [p+16]
        fst dword ptr [p+20]
        fld st(1)
        fmul st(0), st(3)
        fstp dword ptr [p+24]
        fld st(0)
        fmul st(0), st(4)
        fstp dword ptr [p+32]
        fld st(1)
        fchs
        fstp dword ptr [p+36]
        fmul st(0), st(2)
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        xor edx, edx
        mov dword ptr [p+4], edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationXZ( const float x, const float z )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(z);
        p[1] = sinf(z);
        p[2] = 0.0f;
        p[3] = 0.0f;
        p[4] = -cosf(x)*sinf(z);
        p[5] = cosf(x)*cosf(z);
        p[6] = sinf(x);
        p[7] = 0.0f;
        p[8] = sinf(x)*sinf(z);
        p[9] = -sinf(x)*cosf(z);
        p[10] = cosf(x);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [z]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fstp dword ptr [p+0]
        fld st(3)
        fstp dword ptr [p+4]
        fld st(0)
        fmul st(0), st(4)
        fchs
        fstp dword ptr [p+16]
        fld st(0)
        fmul st(0), st(3)
        fstp dword ptr [p+20]
        fld st(1)
        fstp dword ptr [p+24]
        fld st(1)
        fmul st(0), st(4)
        fstp dword ptr [p+32]
        fld st(1)
        fmul st(0), st(3)
        fchs
        fstp dword ptr [p+36]
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        xor edx, edx
        mov dword ptr [p+8], edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationYX( const float y, const float x )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(y);
        p[1] = sinf(y)*sinf(x);
        p[2] = -sinf(y)*cosf(x);
        p[3] = 0.0f;
        p[4] = 0.0f;
        p[5] = cosf(x);
        p[6] = sinf(x);
        p[7] = 0.0f;
        p[8] = sinf(y);
        p[9] = -cosf(y)*sinf(x);
        p[10] = cosf(y)*cosf(x);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [y]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fstp dword ptr [p+0]
        fld st(1)
        fmul st(0), st(4)
        fstp dword ptr [p+4]
        fld st(0)
        fmul st(0), st(4)
        fchs
        fstp dword ptr [p+8]
        fst dword ptr [p+20]
        fld st(1)
        fstp dword ptr [p+24]
        fld st(3)
        fstp dword ptr [p+32]
        fld st(1)
        fmul st(0), st(3)
        fchs
        fstp dword ptr [p+36]
        fmul st(0), st(2)
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+16], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationYZ( const float y, const float z )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(y)*cosf(z);
        p[1] = cosf(y)*sinf(z);
        p[2] = -sinf(y);
        p[3] = 0.0f;
        p[4] = -sinf(z);
        p[5] = cosf(z);
        p[6] = 0.0f;
        p[7] = 0.0f;
        p[8] = sinf(y)*cosf(z);
        p[9] = sinf(y)*sinf(z);
        p[10] = cosf(y);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [y]
        fsincos
        fld dword ptr [z]
        fsincos
        fld st(0)
        fmul st(0), st(3)
        fstp dword ptr [p+0]
        fld st(1)
        fmul st(0), st(3)
        fstp dword ptr [p+4]
        fld st(3)
        fchs
        fstp dword ptr [p+8]
        fld st(1)
        fchs
        fstp dword ptr [p+16]
        fst dword ptr [p+20]
        fmul st(0), st(3)
        fstp dword ptr [p+32]
        fmul st(0), st(2)
        fstp dword ptr [p+36]
        fstp dword ptr [p+40]
        ffree st(0)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+24], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationZX( const float z, const float x )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(z);
        p[1] = sinf(z)*cosf(x);
        p[2] = sinf(z)*sinf(x);
        p[3] = 0.0f;
        p[4] = -sinf(z);
        p[5] = cosf(z)*cosf(x);
        p[6] = cosf(z)*sinf(x);
        p[7] = 0.0f;
        p[8] = 0.0f;
        p[9] = -sinf(x);
        p[10] = cosf(x);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [z]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fstp dword ptr [p+0]
        fld st(0)
        fmul st(0), st(4)
        fstp dword ptr [p+4]
        fld st(1)
        fmul st(0), st(4)
        fstp dword ptr [p+8]
        fld st(3)
        fchs
        fstp dword ptr [p+16]
        fld st(0)
        fmul st(0), st(3)
        fstp dword ptr [p+20]
        fld st(1)
        fmul st(0), st(3)
        fstp dword ptr [p+24]
        fld st(1)
        fchs
        fstp dword ptr [p+36]
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+32], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationZY( const float z, const float y )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(z)*cosf(y);
        p[1] = sinf(z);
        p[2] = -cosf(z)*sinf(y);
        p[3] = 0.0f;
        p[4] = -sinf(z)*cosf(y);
        p[5] = cosf(z);
        p[6] = sinf(z)*sinf(y);
        p[7] = 0.0f;
        p[8] = sinf(y);
        p[9] = 0.0f;
        p[10] = cosf(y);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [z]
        fsincos
        fld dword ptr [y]
        fsincos
        fld st(0)
        fmul st(0), st(3)
        fstp dword ptr [p+0]
        fld st(3)
        fstp dword ptr [p+4]
        fld st(1)
        fmul st(0), st(3)
        fchs
        fstp dword ptr [p+8]
        fld st(0)
        fmul st(0), st(4)
        fchs
        fstp dword ptr [p+16]
        fld st(2)
        fstp dword ptr [p+20]
        fld st(1)
        fmul st(0), st(4)
        fstp dword ptr [p+24]
        fld st(1)
        fstp dword ptr [p+32]
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+36], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationXYZ( const float x, const float y, const float z )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(y)*cosf(z);
        p[1] = cosf(y)*sinf(z);
        p[2] = -sinf(y);
        p[3] = 0.0f;
        p[4] = sinf(x)*sinf(y)*cosf(z) - cosf(x)*sinf(z);
        p[5] = sinf(x)*sinf(y)*sinf(z) + cosf(x)*cosf(z);
        p[6] = sinf(x)*cosf(y);
        p[7] = 0.0f;
        p[8] = cosf(x)*sinf(y)*cosf(z) + sinf(x)*sinf(z);
        p[9] = cosf(x)*sinf(y)*sinf(z) - sinf(x)*cosf(z);
        p[10] = cosf(x)*cosf(y);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [y]
        fsincos
        fld dword ptr [z]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fmul st(0), st(5)
        fstp dword ptr [p+0]
        fld st(3)
        fmul st(0), st(5)
        fstp dword ptr [p+4]
        fld st(5)
        fchs
        fstp dword ptr [p+8]
        fld st(1)
        fmul st(0), st(6)
        fmul st(0), st(3)
        fld st(1)
        fmul st(0), st(5)
        fsubp st(1), st(0)
        fstp dword ptr [p+16]
        fld st(1)
        fmul st(0), st(6)
        fmul st(0), st(4)
        fld st(1)
        fmul st(0), st(4)
        faddp st(1), st(0)
        fstp dword ptr [p+20]
        fld st(1)
        fmul st(0), st(5)
        fstp dword ptr [p+24]
        fld st(0)
        fmul st(0), st(6)
        fmul st(0), st(3)
        fld st(2)
        fmul st(0), st(5)
        faddp st(1), st(0)
        fstp dword ptr [p+32]
        fld st(0)
        fmul st(0), st(6)
        fmul st(0), st(4)
        fld st(2)
        fmul st(0), st(4)
        fsubp st(1), st(0)
        fstp dword ptr [p+36]
        fmul st(0), st(4)
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        ffree st(3)
        ffree st(4)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationXZY( const float x, const float z, const float y )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(z)*cosf(y);
        p[1] = sinf(z);
        p[2] = -cosf(z)*sinf(y);
        p[3] = 0.0f;
        p[4] = sinf(x)*sinf(y) - cosf(x)*sinf(z)*cosf(y);
        p[5] = cosf(x)*cosf(z);
        p[6] = cosf(x)*sinf(z)*sinf(y) + sinf(x)*cosf(y);
        p[7] = 0.0f;
        p[8] = sinf(x)*sinf(z)*cosf(y) + cosf(x)*sinf(y);
        p[9] = -sinf(x)*cosf(z);
        p[10] = cosf(x)*cosf(y) - sinf(x)*sinf(z)*sinf(y);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [z]
        fsincos
        fld dword ptr [y]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fmul st(0), st(5)
        fstp dword ptr [p+0]
        fld st(5)
        fstp dword ptr [p+4]
        fld st(3)
        fmul st(0), st(5)
        fchs
        fstp dword ptr [p+8]
        fld st(1)
        fmul st(0), st(4)
        fld st(1)
        fmul st(0), st(7)
        fmul st(0), st(4)
        fsubp st(1), st(0)
        fstp dword ptr [p+16]
        fld st(0)
        fmul st(0), st(5)
        fstp dword ptr [p+20]
        fld st(0)
        fmul st(0), st(6)
        fmul st(0), st(4)
        fld st(2)
        fmul st(0), st(4)
        faddp st(1), st(0)
        fstp dword ptr [p+24]
        fld st(1)
        fmul st(0), st(6)
        fmul st(0), st(3)
        fld st(1)
        fmul st(0), st(5)
        faddp st(1), st(0)
        fstp dword ptr [p+32]
        fld st(1)
        fmul st(0), st(5)
        fchs
        fstp dword ptr [p+36]
        fmul st(0), st(2)
        fld st(1)
        fmul st(0), st(6)
        fmul st(0), st(4)
        fsub st(1), st(0)
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        ffree st(3)
        ffree st(4)
        ffree st(5)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationYXZ( const float y, const float x, const float z )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(y)*cosf(z) - sinf(y)*sinf(x)*sinf(z);
        p[1] = cosf(y)*sinf(z) + sinf(y)*sinf(x)*cosf(z);
        p[2] = -sinf(y)*cosf(x);
        p[3] = 0.0f;
        p[4] = -cosf(x)*sinf(z);
        p[5] = cosf(x)*cosf(z);
        p[6] = sinf(x);
        p[7] = 0.0f;
        p[8] = sinf(y)*cosf(z) + cosf(y)*sinf(x)*sinf(z);
        p[9] = sinf(y)*sinf(z) - cosf(y)*sinf(x)*cosf(z);
        p[10] = cosf(y)*cosf(x);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [y]
        fsincos
        fld dword ptr [z]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fmul st(0), st(5)
        fld st(2)
        fmul st(0), st(7)
        fmul st(0), st(5)
        fsubp st(1), st(0)
        fstp dword ptr [p+0]
        fld st(3)
        fmul st(0), st(5)
        fld st(2)
        fmul st(0), st(7)
        fmul st(0), st(4)
        faddp st(1), st(0)
        fstp dword ptr [p+4]
        fld st(0)
        fmul st(0), st(6)
        fchs
        fstp dword ptr [p+8]
        fld st(0)
        fmul st(0), st(4)
        fchs
        fstp dword ptr [p+16]
        fld st(0)
        fmul st(0), st(3)
        fstp dword ptr [p+20]
        fld st(1)
        fstp dword ptr [p+24]
        fld st(2)
        fmul st(0), st(6)
        fld st(2)
        fmul st(0), st(6)
        fmul st(0), st(5)
        faddp st(1), st(0)
        fstp dword ptr [p+32]
        fld st(3)
        fmul st(0), st(6)
        fld st(2)
        fmul st(0), st(6)
        fmul st(0), st(4)
        fsubp st(1), st(0)
        fstp dword ptr [p+36]
        fmul st(0), st(4)
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        ffree st(3)
        ffree st(4)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationYZX( const float y, const float z, const float x )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(y)*cosf(z);
        p[1] = cosf(y)*sinf(z)*cosf(x) + sinf(y)*sinf(x);
        p[2] = cosf(y)*sinf(z)*sinf(x) - sinf(y)*cosf(x);
        p[3] = 0.0f;
        p[4] = -sinf(z);
        p[5] = cosf(z)*cosf(x);
        p[6] = cosf(z)*sinf(x);
        p[7] = 0.0f;
        p[8] = sinf(y)*cosf(z);
        p[9] = sinf(y)*sinf(z)*cosf(x) - cosf(y)*sinf(x);
        p[10] = sinf(y)*sinf(z)*sinf(x) + cosf(y)*cosf(x);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [y]
        fsincos
        fld dword ptr [z]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fmul st(0), st(5)
        fstp dword ptr [p+0]
        fld st(3)
        fmul st(0), st(5)
        fmul st(0), st(1)
        fld st(2)
        fmul st(0), st(7)
        faddp st(1), st(0)
        fstp dword ptr [p+4]
        fld st(3)
        fmul st(0), st(5)
        fmul st(0), st(2)
        fld st(1)
        fmul st(0), st(7)
        fsubp st(1), st(0)
        fstp dword ptr [p+8]
        fld st(3)
        fchs
        fstp dword ptr [p+16]
        fld st(0)
        fmul st(0), st(3)
        fstp dword ptr [p+20]
        fld st(1)
        fmul st(0), st(3)
        fstp dword ptr [p+24]
        fld st(2)
        fmul st(0), st(6)
        fstp dword ptr [p+32]
        fld st(3)
        fmul st(0), st(6)
        fmul st(0), st(1)
        fld st(2)
        fmul st(0), st(6)
        fsubp st(1), st(0)
        fstp dword ptr [p+36]
        fld st(3)
        fmul st(0), st(6)
        fmul st(0), st(2)
        fld st(1)
        fmul st(0), st(6)
        faddp st(1), st(0)
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        ffree st(3)
        ffree st(4)
        ffree st(5)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationZXY( const float z, const float x, const float y )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(z)*cosf(y) + sinf(z)*sinf(x)*sinf(y);
        p[1] = sinf(z)*cosf(x);
        p[2] = sinf(z)*sinf(x)*cosf(y) - cosf(z)*sinf(y);
        p[3] = 0.0f;
        p[4] = cosf(z)*sinf(x)*sinf(y) - sinf(z)*cosf(y);
        p[5] = cosf(z)*cosf(x);
        p[6] = sinf(z)*sinf(y) + cosf(z)*sinf(x)*cosf(y);
        p[7] = 0.0f;
        p[8] = cosf(x)*sinf(y);
        p[9] = -sinf(x);
        p[10] = cosf(x)*cosf(y);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [z]
        fsincos
        fld dword ptr [y]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fmul st(0), st(5)
        fld st(2)
        fmul st(0), st(7)
        fmul st(0), st(5)
        faddp st(1), st(0)
        fstp dword ptr [p+0]
        fld st(0)
        fmul st(0), st(6)
        fstp dword ptr [p+4]
        fld st(1)
        fmul st(0), st(6)
        fmul st(0), st(3)
        fld st(4)
        fmul st(0), st(6)
        fsubp st(1), st(0)
        fstp dword ptr [p+8]
        fld st(1)
        fmul st(0), st(5)
        fmul st(0), st(4)
        fld st(3)
        fmul st(0), st(7)
        fsubp st(1), st(0)
        fstp dword ptr [p+16]
        fld st(0)
        fmul st(0), st(5)
        fstp dword ptr [p+20]
        fld st(3)
        fmul st(0), st(6)
        fld st(2)
        fmul st(0), st(6)
        fmul st(0), st(4)
        faddp st(1), st(0)
        fstp dword ptr [p+24]
        fld st(0)
        fmul st(0), st(4)
        fstp dword ptr [p+32]
        fld st(1)
        fchs
        fstp dword ptr [p+36]
        fmul st(0), st(2)
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        ffree st(3)
        ffree st(4)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}

// ******************************************************************************
float4x4 CXForm::MakeRotationZYX( const float z, const float y, const float x )
// ******************************************************************************
{
    DALIGN64 float p[16];
    float4x4 r;

    /*
        p[0] = cosf(z)*cosf(y);
        p[1] = sinf(z)*cosf(x) + cosf(z)*sinf(y)*sinf(x);
        p[2] = sinf(z)*sinf(x) - cosf(z)*sinf(y)*cosf(x);
        p[3] = 0.0f;
        p[4] = -sinf(z)*cosf(y);
        p[5] = cosf(z)*cosf(x) - sinf(z)*sinf(y)*sinf(x);
        p[6] = cosf(z)*sinf(x) + sinf(z)*sinf(y)*cosf(x);
        p[7] = 0.0f;
        p[8] = sinf(y);
        p[9] = -cosf(y)*sinf(x);
        p[10] = cosf(y)*cosf(x);
        p[11] = 0.0f;
        p[12] = 0.0f;
        p[13] = 0.0f;
        p[14] = 0.0f;
        p[15] = 1.0f;
    */
    __asm
    {
        fld dword ptr [z]
        fsincos
        fld dword ptr [y]
        fsincos
        fld dword ptr [x]
        fsincos
        fld st(2)
        fmul st(0), st(5)
        fstp dword ptr [p+0]
        fld st(0)
        fmul st(0), st(6)
        fld st(4)
        fmul st(0), st(6)
        fmul st(0), st(3)
        faddp st(1), st(0)
        fstp dword ptr [p+4]
        fld st(1)
        fmul st(0), st(6)
        fld st(4)
        fmul st(0), st(6)
        fmul st(0), st(2)
        fsubp st(1), st(0)
        fstp dword ptr [p+8]
        fld st(2)
        fmul st(0), st(6)
        fchs
        fstp dword ptr [p+16]
        fld st(0)
        fmul st(0), st(5)
        fld st(4)
        fmul st(0), st(7)
        fmul st(0), st(3)
        fsubp st(1), st(0)
        fstp dword ptr [p+20]
        fld st(1)
        fmul st(0), st(5)
        fld st(4)
        fmul st(0), st(7)
        fmul st(0), st(2)
        faddp st(1), st(0)
        fstp dword ptr [p+24]
        fld st(3)
        fstp dword ptr [p+32]
        fld st(1)
        fmul st(0), st(3)
        fchs
        fstp dword ptr [p+36]
        fmul st(0), st(2)
        fstp dword ptr [p+40]
        ffree st(0)
        ffree st(1)
        ffree st(2)
        ffree st(3)
        ffree st(4)
        xor edx, edx
        mov dword ptr [p+12], edx
        mov dword ptr [p+28], edx
        mov dword ptr [p+44], edx
        mov dword ptr [p+48], edx
        mov dword ptr [p+52], edx
        mov dword ptr [p+56], edx
        mov edx, 3f800000h
        mov dword ptr [p+60], edx
    }

    r[X] = _mm_load_ps( p );
    r[Y] = _mm_load_ps( p + 4 );
    r[Z] = _mm_load_ps( p + 8 );
    r[W] = _mm_load_ps( p + 12 );

    return r;
}
