This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/render/r_utils.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;
}