253 lines
4.7 KiB
C
253 lines
4.7 KiB
C
//=======================================================================
|
|
// Copyright XashXT Group 2007 ©
|
|
// r_utils.c - render utils
|
|
//=======================================================================
|
|
|
|
#include "gl_local.h"
|
|
|
|
/*
|
|
====================
|
|
RotatePointAroundVector
|
|
|
|
====================
|
|
*/
|
|
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
|
|
{
|
|
float m[3][3];
|
|
float im[3][3];
|
|
float zrot[3][3];
|
|
float tmpmat[3][3];
|
|
float rot[3][3];
|
|
int i;
|
|
vec3_t vr, vup, vf;
|
|
|
|
vf[0] = dir[0];
|
|
vf[1] = dir[1];
|
|
vf[2] = dir[2];
|
|
|
|
PerpendicularVector( vr, dir );
|
|
CrossProduct( vr, vf, vup );
|
|
|
|
m[0][0] = vr[0];
|
|
m[1][0] = vr[1];
|
|
m[2][0] = vr[2];
|
|
|
|
m[0][1] = vup[0];
|
|
m[1][1] = vup[1];
|
|
m[2][1] = vup[2];
|
|
|
|
m[0][2] = vf[0];
|
|
m[1][2] = vf[1];
|
|
m[2][2] = vf[2];
|
|
|
|
memcpy( im, m, sizeof( im ) );
|
|
|
|
im[0][1] = m[1][0];
|
|
im[0][2] = m[2][0];
|
|
im[1][0] = m[0][1];
|
|
im[1][2] = m[2][1];
|
|
im[2][0] = m[0][2];
|
|
im[2][1] = m[1][2];
|
|
|
|
memset( zrot, 0, sizeof( zrot ) );
|
|
zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;
|
|
|
|
zrot[0][0] = cos( DEG2RAD( degrees ) );
|
|
zrot[0][1] = sin( DEG2RAD( degrees ) );
|
|
zrot[1][0] = -sin( DEG2RAD( degrees ) );
|
|
zrot[1][1] = cos( DEG2RAD( degrees ) );
|
|
|
|
R_ConcatRotations( m, zrot, tmpmat );
|
|
R_ConcatRotations( tmpmat, im, rot );
|
|
|
|
for ( i = 0; i < 3; i++ )
|
|
{
|
|
dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2];
|
|
}
|
|
}
|
|
|
|
/*
|
|
====================
|
|
ProjectPointOnPlane
|
|
|
|
====================
|
|
*/
|
|
void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
|
|
{
|
|
float d;
|
|
vec3_t n;
|
|
float inv_denom;
|
|
|
|
inv_denom = 1.0F / DotProduct( normal, normal );
|
|
|
|
d = DotProduct( normal, p ) * inv_denom;
|
|
|
|
n[0] = normal[0] * inv_denom;
|
|
n[1] = normal[1] * inv_denom;
|
|
n[2] = normal[2] * inv_denom;
|
|
|
|
dst[0] = p[0] - d * n[0];
|
|
dst[1] = p[1] - d * n[1];
|
|
dst[2] = p[2] - d * n[2];
|
|
}
|
|
|
|
/*
|
|
====================
|
|
PerpendicularVector
|
|
|
|
====================
|
|
*/
|
|
void PerpendicularVector( vec3_t dst, const vec3_t src )
|
|
{
|
|
int pos;
|
|
int i;
|
|
float minelem = 1.0F;
|
|
vec3_t tempvec;
|
|
|
|
/*
|
|
** find the smallest magnitude axially aligned vector
|
|
*/
|
|
for ( pos = 0, i = 0; i < 3; i++ )
|
|
{
|
|
if ( fabs( src[i] ) < minelem )
|
|
{
|
|
pos = i;
|
|
minelem = fabs( src[i] );
|
|
}
|
|
}
|
|
tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
|
|
tempvec[pos] = 1.0F;
|
|
|
|
/*
|
|
** project the point onto the plane defined by src
|
|
*/
|
|
ProjectPointOnPlane( dst, tempvec, src );
|
|
|
|
/*
|
|
** normalize the result
|
|
*/
|
|
VectorNormalize( dst );
|
|
}
|
|
|
|
|
|
/*
|
|
====================
|
|
Image Decompress
|
|
|
|
ShortToFloat
|
|
====================
|
|
*/
|
|
uint ShortToFloat( word y )
|
|
{
|
|
int s = (y >> 15) & 0x00000001;
|
|
int e = (y >> 10) & 0x0000001f;
|
|
int m = y & 0x000003ff;
|
|
|
|
//float: 1 sign bit, 8 exponent bits, 23 mantissa bits
|
|
//half: 1 sign bit, 5 exponent bits, 10 mantissa bits
|
|
|
|
if (e == 0)
|
|
{
|
|
if (m == 0) return s << 31; // Plus or minus zero
|
|
else // Denormalized number -- renormalize it
|
|
{
|
|
while (!(m & 0x00000400))
|
|
{
|
|
m <<= 1;
|
|
e -= 1;
|
|
}
|
|
e += 1;
|
|
m &= ~0x00000400;
|
|
}
|
|
}
|
|
else if (e == 31)
|
|
{
|
|
if (m == 0) return (s << 31) | 0x7f800000; // Positive or negative infinity
|
|
else return (s << 31) | 0x7f800000 | (m << 13); // Nan -- preserve sign and significand bits
|
|
}
|
|
|
|
// Normalized number
|
|
e = e + (127 - 15);
|
|
m = m << 13;
|
|
return (s << 31) | (e << 23) | m; // Assemble s, e and m.
|
|
}
|
|
|
|
/*
|
|
====================
|
|
Image Decompress
|
|
|
|
read colors from dxt image
|
|
====================
|
|
*/
|
|
void R_DXTReadColors(const byte* data, color32* out)
|
|
{
|
|
byte r0, g0, b0, r1, g1, b1;
|
|
|
|
b0 = data[0] & 0x1F;
|
|
g0 = ((data[0] & 0xE0) >> 5) | ((data[1] & 0x7) << 3);
|
|
r0 = (data[1] & 0xF8) >> 3;
|
|
|
|
b1 = data[2] & 0x1F;
|
|
g1 = ((data[2] & 0xE0) >> 5) | ((data[3] & 0x7) << 3);
|
|
r1 = (data[3] & 0xF8) >> 3;
|
|
|
|
out[0].r = r0 << 3;
|
|
out[0].g = g0 << 2;
|
|
out[0].b = b0 << 3;
|
|
|
|
out[1].r = r1 << 3;
|
|
out[1].g = g1 << 2;
|
|
out[1].b = b1 << 3;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
Image Decompress
|
|
|
|
read one color from dxt image
|
|
====================
|
|
*/
|
|
void R_DXTReadColor(word data, color32* out)
|
|
{
|
|
byte r, g, b;
|
|
|
|
b = data & 0x1f;
|
|
g = (data & 0x7E0) >>5;
|
|
r = (data & 0xF800)>>11;
|
|
|
|
out->r = r << 3;
|
|
out->g = g << 2;
|
|
out->b = b << 3;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
R_GetBitsFromMask
|
|
|
|
====================
|
|
*/
|
|
void R_GetBitsFromMask(uint Mask, uint *ShiftLeft, uint *ShiftRight)
|
|
{
|
|
uint Temp, i;
|
|
|
|
if (Mask == 0)
|
|
{
|
|
*ShiftLeft = *ShiftRight = 0;
|
|
return;
|
|
}
|
|
|
|
Temp = Mask;
|
|
for (i = 0; i < 32; i++, Temp >>= 1)
|
|
{
|
|
if (Temp & 1) break;
|
|
}
|
|
*ShiftRight = i;
|
|
|
|
// Temp is preserved, so use it again:
|
|
for (i = 0; i < 8; i++, Temp >>= 1)
|
|
{
|
|
if (!(Temp & 1)) break;
|
|
}
|
|
*ShiftLeft = 8 - i;
|
|
return;
|
|
} |