#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;
}
}
}
};