#pragma once

#include “mesh3d.h”

float __forceinline __fastcall rsq(float number)

{

long i;

float x2, y;

const float threehalfs = 1.5f;

x2 = number * 0.5f;

y = number;

i = * (long *) &y; // evil floating point bit level hacking

i = 0x5f3759df - (i >> 1); // what the ****?

y = * (float *) &i;

y = y * (threehalfs - (x2 * y * y)); // 1st iteration

return y;

}

#include <xmmintrin.h>

struct VECTOR

{

union

{

struct { float x,y,z,w; };

__m128 SSE;

};

VECTOR( ) { }

VECTOR( float X, float Y, float Z ) : x( X ), y( Y ), z( Z ), w( 0 ) { }

void NORMALIZE( )

{

float one_div_length = rsq( x * x + y * y + z * z );

x *= one_div_length;

y *= one_div_length;

z *= one_div_length;

}

operator float* ( )

{

return &x;

}

};

struct VECTOR4 : VECTOR

{

float w;

VECTOR4( float X, float Y, float Z, float W = 1 )

{

x = X;

y = Y;

z = Z;

w = W;

}

};

VECTOR CROSS( const VECTOR& v0, const VECTOR& v1 )

{

return VECTOR( v0.y * v1.z - v0.z * v1.y, v0.z * v1.x - v0.x * v1.z, v0.x * v1.y - v0.y * v1.x );

}

float DP3( const VECTOR& v0, const VECTOR& v1 )

{

return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;

}

float DP4( const VECTOR4& v0, const VECTOR4& v1 )

{

return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w;

}

float ABS( float a )

{

/* __asm {

mov eax, a

add eax, 0x7FFFFFFF

mov a, eax

}

return a;*/

return a > 0 ? a : -a;

}

struct VERTEX

{

VECTOR pos;

VECTOR nrml;

VECTOR tex0;

VECTOR S;

VECTOR T;

VECTOR SxT;

VERTEX( ) { }

};

struct MESH

{

VERTEX* vdata;

unsigned int vcount;

unsigned int* fdata;

unsigned int fcount; //facecount = indexcount * 3, it IS facecount!

void COPYFROM_mesh3d( mesh3d* m3d )

{

vcount = m3d->vcount;

vdata = new VERTEX[ m3d->vcount ];

fcount = m3d->fcount;

fdata = new unsigned int[ 3 * m3d->fcount ];

```
memcpy( fdata, m3d->fdata, m3d->fcount * 3 * sizeof( unsigned int ) );
for( unsigned int i = 0; i < vcount; i ++ )
{
vdata[ i ].pos.x = m3d->vdata[ i ].pos.x;
vdata[ i ].pos.y = m3d->vdata[ i ].pos.y;
vdata[ i ].pos.z = m3d->vdata[ i ].pos.z;
vdata[ i ].tex0.x = m3d->vdata[ i ].tex0.x;
vdata[ i ].tex0.y = m3d->vdata[ i ].tex0.y;
vdata[ i ].tex0.z = 0;
vdata[ i ].nrml.x = 0;
vdata[ i ].nrml.y = 0;
vdata[ i ].nrml.z = 0;
vdata[ i ].S.x = 0;
vdata[ i ].S.y = 0;
vdata[ i ].S.z = 0;
vdata[ i ].T.x = 0;
vdata[ i ].T.y = 0;
vdata[ i ].T.z = 0;
vdata[ i ].SxT.x = 0;
vdata[ i ].SxT.y = 0;
vdata[ i ].SxT.z = 0;
}
```

}

void CALC_T_SPACE( )

{

for( unsigned int f = 0; f < fcount; f ++ )

{

VERTEX& v0 = vdata[ fdata[ f * 3 + 0 ] ];

VERTEX& v1 = vdata[ fdata[ f * 3 + 1 ] ];

VERTEX& v2 = vdata[ fdata[ f * 3 + 2 ] ];

```
VECTOR e1, e2;
VECTOR cp;
e1 = VECTOR( v1.pos.x - v0.pos.x, v1.pos.y - v0.pos.y, v1.pos.z - v0.pos.z );
e2 = VECTOR( v2.pos.x - v0.pos.x, v2.pos.y - v0.pos.y, v2.pos.z - v0.pos.z );
cp = CROSS( e1, e2 );
{
v0.nrml.x += cp.x;
v0.nrml.y += cp.y;
v0.nrml.z += cp.z;
v1.nrml.x += cp.x;
v1.nrml.y += cp.y;
v1.nrml.z += cp.z;
v2.nrml.x += cp.x;
v2.nrml.y += cp.y;
v2.nrml.z += cp.z;
}
e1 = VECTOR( v1.pos.x - v0.pos.x, v1.tex0.x - v0.tex0.x, v1.tex0.y - v0.tex0.y );
e2 = VECTOR( v2.pos.x - v0.pos.x, v2.tex0.x - v0.tex0.x, v2.tex0.y - v0.tex0.y );
cp = CROSS( e1, e2 );
if( cp.x )
{
v0.S.x += -cp.y / cp.x;
v0.T.x += -cp.z / cp.x;
v1.S.x += -cp.y / cp.x;
v1.T.x += -cp.z / cp.x;
v2.S.x += -cp.y / cp.x;
v2.T.x += -cp.z / cp.x;
}
e1 = VECTOR( v1.pos.y - v0.pos.y, v1.tex0.x - v0.tex0.x, v1.tex0.y - v0.tex0.y );
e2 = VECTOR( v2.pos.y - v0.pos.y, v2.tex0.x - v0.tex0.x, v2.tex0.y - v0.tex0.y );
cp = CROSS( e1, e2 );
if( cp.x )
{
v0.S.y += -cp.y / cp.x;
v0.T.y += -cp.z / cp.x;
v1.S.y += -cp.y / cp.x;
v1.T.y += -cp.z / cp.x;
v2.S.y += -cp.y / cp.x;
v2.T.y += -cp.z / cp.x;
}
e1 = VECTOR( v1.pos.z - v0.pos.z, v1.tex0.x - v0.tex0.x, v1.tex0.y - v0.tex0.y );
e2 = VECTOR( v2.pos.z - v0.pos.z, v2.tex0.x - v0.tex0.x, v2.tex0.y - v0.tex0.y );
cp = CROSS( e1, e2 );
if( cp.x )
{
v0.S.z += -cp.y / cp.x;
v0.T.z += -cp.z / cp.x;
v1.S.z += -cp.y / cp.x;
v1.T.z += -cp.z / cp.x;
v2.S.z += -cp.y / cp.x;
v2.T.z += -cp.z / cp.x;
}
}
for( unsigned int v = 0; v < vcount; v ++ )
{
VERTEX& v0 = vdata[ v ];
v0.nrml.NORMALIZE( );
v0.S.NORMALIZE( );
v0.T.NORMALIZE( );
v0.SxT = CROSS( v0.S, v0.T );
v0.SxT.NORMALIZE( );
if( DP3( v0.SxT, v0.nrml ) < 0 )
{
v0.SxT.x = -v0.SxT.x;
v0.SxT.y = -v0.SxT.y;
v0.SxT.z = -v0.SxT.z;
}
}
```

}

};