2010-02-15 23:26:55 +00:00
/*
Copyright ( C ) 1996 - 2001 Id Software , Inc .
Copyright ( C ) 2002 - 2009 John Fitzgibbons and others
Copyright ( C ) 2007 - 2008 Kristian Duske
2014-09-22 08:55:46 +00:00
Copyright ( C ) 2010 - 2014 QuakeSpasm developers
2010-02-15 23:26:55 +00:00
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
// mathlib.c -- math primitives
# include "quakedef.h"
vec3_t vec3_origin = { 0 , 0 , 0 } ;
/*-----------------------------------------------------------------*/
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 ] ;
}
/*
* * assumes " src " is normalized
*/
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 ) ;
}
//johnfitz -- removed RotatePointAroundVector() becuase it's no longer used and my compiler fucked it up anyway
2019-11-02 20:22:54 +00:00
//spike -- readded, because it is useful, and my version of gcc has never had a problem with it.
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 ] ;
}
}
2010-02-15 23:26:55 +00:00
/*-----------------------------------------------------------------*/
float anglemod ( float a )
{
#if 0
if ( a > = 0 )
a - = 360 * ( int ) ( a / 360 ) ;
else
a + = 360 * ( 1 + ( int ) ( - a / 360 ) ) ;
# endif
a = ( 360.0 / 65536 ) * ( ( int ) ( a * ( 65536 / 360.0 ) ) & 65535 ) ;
return a ;
}
/*
= = = = = = = = = = = = = = = = = =
BoxOnPlaneSide
Returns 1 , 2 , or 1 + 2
= = = = = = = = = = = = = = = = = =
*/
int BoxOnPlaneSide ( vec3_t emins , vec3_t emaxs , mplane_t * p )
{
float dist1 , dist2 ;
int sides ;
#if 0 // this is done by the BOX_ON_PLANE_SIDE macro before calling this
// function
// fast axial cases
if ( p - > type < 3 )
{
if ( p - > dist < = emins [ p - > type ] )
return 1 ;
if ( p - > dist > = emaxs [ p - > type ] )
return 2 ;
return 3 ;
}
# endif
// general case
switch ( p - > signbits )
{
case 0 :
2014-09-22 08:55:46 +00:00
dist1 = p - > normal [ 0 ] * emaxs [ 0 ] + p - > normal [ 1 ] * emaxs [ 1 ] + p - > normal [ 2 ] * emaxs [ 2 ] ;
dist2 = p - > normal [ 0 ] * emins [ 0 ] + p - > normal [ 1 ] * emins [ 1 ] + p - > normal [ 2 ] * emins [ 2 ] ;
2010-02-15 23:26:55 +00:00
break ;
case 1 :
2014-09-22 08:55:46 +00:00
dist1 = p - > normal [ 0 ] * emins [ 0 ] + p - > normal [ 1 ] * emaxs [ 1 ] + p - > normal [ 2 ] * emaxs [ 2 ] ;
dist2 = p - > normal [ 0 ] * emaxs [ 0 ] + p - > normal [ 1 ] * emins [ 1 ] + p - > normal [ 2 ] * emins [ 2 ] ;
2010-02-15 23:26:55 +00:00
break ;
case 2 :
2014-09-22 08:55:46 +00:00
dist1 = p - > normal [ 0 ] * emaxs [ 0 ] + p - > normal [ 1 ] * emins [ 1 ] + p - > normal [ 2 ] * emaxs [ 2 ] ;
dist2 = p - > normal [ 0 ] * emins [ 0 ] + p - > normal [ 1 ] * emaxs [ 1 ] + p - > normal [ 2 ] * emins [ 2 ] ;
2010-02-15 23:26:55 +00:00
break ;
case 3 :
2014-09-22 08:55:46 +00:00
dist1 = p - > normal [ 0 ] * emins [ 0 ] + p - > normal [ 1 ] * emins [ 1 ] + p - > normal [ 2 ] * emaxs [ 2 ] ;
dist2 = p - > normal [ 0 ] * emaxs [ 0 ] + p - > normal [ 1 ] * emaxs [ 1 ] + p - > normal [ 2 ] * emins [ 2 ] ;
2010-02-15 23:26:55 +00:00
break ;
case 4 :
2014-09-22 08:55:46 +00:00
dist1 = p - > normal [ 0 ] * emaxs [ 0 ] + p - > normal [ 1 ] * emaxs [ 1 ] + p - > normal [ 2 ] * emins [ 2 ] ;
dist2 = p - > normal [ 0 ] * emins [ 0 ] + p - > normal [ 1 ] * emins [ 1 ] + p - > normal [ 2 ] * emaxs [ 2 ] ;
2010-02-15 23:26:55 +00:00
break ;
case 5 :
2014-09-22 08:55:46 +00:00
dist1 = p - > normal [ 0 ] * emins [ 0 ] + p - > normal [ 1 ] * emaxs [ 1 ] + p - > normal [ 2 ] * emins [ 2 ] ;
dist2 = p - > normal [ 0 ] * emaxs [ 0 ] + p - > normal [ 1 ] * emins [ 1 ] + p - > normal [ 2 ] * emaxs [ 2 ] ;
2010-02-15 23:26:55 +00:00
break ;
case 6 :
2014-09-22 08:55:46 +00:00
dist1 = p - > normal [ 0 ] * emaxs [ 0 ] + p - > normal [ 1 ] * emins [ 1 ] + p - > normal [ 2 ] * emins [ 2 ] ;
dist2 = p - > normal [ 0 ] * emins [ 0 ] + p - > normal [ 1 ] * emaxs [ 1 ] + p - > normal [ 2 ] * emaxs [ 2 ] ;
2010-02-15 23:26:55 +00:00
break ;
case 7 :
2014-09-22 08:55:46 +00:00
dist1 = p - > normal [ 0 ] * emins [ 0 ] + p - > normal [ 1 ] * emins [ 1 ] + p - > normal [ 2 ] * emins [ 2 ] ;
dist2 = p - > normal [ 0 ] * emaxs [ 0 ] + p - > normal [ 1 ] * emaxs [ 1 ] + p - > normal [ 2 ] * emaxs [ 2 ] ;
2010-02-15 23:26:55 +00:00
break ;
default :
dist1 = dist2 = 0 ; // shut up compiler
2017-07-28 12:50:10 +00:00
Sys_Error ( " BoxOnPlaneSide: Bad signbits " ) ;
2010-02-15 23:26:55 +00:00
break ;
}
#if 0
int i ;
vec3_t corners [ 2 ] ;
for ( i = 0 ; i < 3 ; i + + )
{
if ( plane - > normal [ i ] < 0 )
{
corners [ 0 ] [ i ] = emins [ i ] ;
corners [ 1 ] [ i ] = emaxs [ i ] ;
}
else
{
corners [ 1 ] [ i ] = emins [ i ] ;
corners [ 0 ] [ i ] = emaxs [ i ] ;
}
}
dist = DotProduct ( plane - > normal , corners [ 0 ] ) - plane - > dist ;
dist2 = DotProduct ( plane - > normal , corners [ 1 ] ) - plane - > dist ;
sides = 0 ;
if ( dist1 > = 0 )
sides = 1 ;
if ( dist2 < 0 )
sides | = 2 ;
# endif
sides = 0 ;
if ( dist1 > = p - > dist )
sides = 1 ;
if ( dist2 < p - > dist )
sides | = 2 ;
# ifdef PARANOID
2014-09-22 08:55:46 +00:00
if ( sides = = 0 )
Sys_Error ( " BoxOnPlaneSide: sides==0 " ) ;
2010-02-15 23:26:55 +00:00
# endif
return sides ;
}
//johnfitz -- the opposite of AngleVectors. this takes forward and generates pitch yaw roll
2017-09-17 02:12:53 +00:00
//Spike: take right and up vectors to properly set yaw and roll
void VectorAngles ( const vec3_t forward , float * up , vec3_t angles )
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
if ( forward [ 0 ] = = 0 & & forward [ 1 ] = = 0 )
{ //either vertically up or down
if ( forward [ 2 ] > 0 )
{
angles [ PITCH ] = - 90 ;
angles [ YAW ] = up ? atan2 ( - up [ 1 ] , - up [ 0 ] ) / M_PI_DIV_180 : 0 ;
}
else
{
angles [ PITCH ] = 90 ;
angles [ YAW ] = up ? atan2 ( up [ 1 ] , up [ 0 ] ) / M_PI_DIV_180 : 0 ;
}
angles [ ROLL ] = 0 ;
}
else
{
angles [ PITCH ] = - atan2 ( forward [ 2 ] , sqrt ( DotProduct2 ( forward , forward ) ) ) ;
angles [ YAW ] = atan2 ( forward [ 1 ] , forward [ 0 ] ) ;
if ( up )
{
vec_t cp = cos ( angles [ PITCH ] ) , sp = sin ( angles [ PITCH ] ) ;
vec_t cy = cos ( angles [ YAW ] ) , sy = sin ( angles [ YAW ] ) ;
vec3_t tleft , tup ;
tleft [ 0 ] = - sy ;
tleft [ 1 ] = cy ;
tleft [ 2 ] = 0 ;
tup [ 0 ] = sp * cy ;
tup [ 1 ] = sp * sy ;
tup [ 2 ] = cp ;
angles [ ROLL ] = - atan2 ( DotProduct ( up , tleft ) , DotProduct ( up , tup ) ) / M_PI_DIV_180 ;
}
else angles [ ROLL ] = 0 ;
angles [ PITCH ] / = M_PI_DIV_180 ;
angles [ YAW ] / = M_PI_DIV_180 ;
}
2010-02-15 23:26:55 +00:00
}
void AngleVectors ( vec3_t angles , vec3_t forward , vec3_t right , vec3_t up )
{
float angle ;
float sr , sp , sy , cr , cp , cy ;
angle = angles [ YAW ] * ( M_PI * 2 / 360 ) ;
sy = sin ( angle ) ;
cy = cos ( angle ) ;
angle = angles [ PITCH ] * ( M_PI * 2 / 360 ) ;
sp = sin ( angle ) ;
cp = cos ( angle ) ;
angle = angles [ ROLL ] * ( M_PI * 2 / 360 ) ;
sr = sin ( angle ) ;
cr = cos ( angle ) ;
forward [ 0 ] = cp * cy ;
forward [ 1 ] = cp * sy ;
forward [ 2 ] = - sp ;
right [ 0 ] = ( - 1 * sr * sp * cy + - 1 * cr * - sy ) ;
right [ 1 ] = ( - 1 * sr * sp * sy + - 1 * cr * cy ) ;
right [ 2 ] = - 1 * sr * cp ;
up [ 0 ] = ( cr * sp * cy + - sr * - sy ) ;
up [ 1 ] = ( cr * sp * sy + - sr * cy ) ;
up [ 2 ] = cr * cp ;
}
2017-09-17 02:12:53 +00:00
int VectorCompare ( const vec3_t v1 , const vec3_t v2 )
2010-02-15 23:26:55 +00:00
{
int i ;
for ( i = 0 ; i < 3 ; i + + )
if ( v1 [ i ] ! = v2 [ i ] )
return 0 ;
return 1 ;
}
2017-09-17 02:12:53 +00:00
vec_t _DotProduct ( const vec3_t v1 , const vec3_t v2 )
2010-02-15 23:26:55 +00:00
{
return v1 [ 0 ] * v2 [ 0 ] + v1 [ 1 ] * v2 [ 1 ] + v1 [ 2 ] * v2 [ 2 ] ;
}
2017-09-17 02:12:53 +00:00
void _VectorSubtract ( const vec3_t veca , const vec3_t vecb , vec3_t out )
2010-02-15 23:26:55 +00:00
{
out [ 0 ] = veca [ 0 ] - vecb [ 0 ] ;
out [ 1 ] = veca [ 1 ] - vecb [ 1 ] ;
out [ 2 ] = veca [ 2 ] - vecb [ 2 ] ;
}
2017-09-17 02:12:53 +00:00
void _VectorAdd ( const vec3_t veca , const vec3_t vecb , vec3_t out )
2010-02-15 23:26:55 +00:00
{
out [ 0 ] = veca [ 0 ] + vecb [ 0 ] ;
out [ 1 ] = veca [ 1 ] + vecb [ 1 ] ;
out [ 2 ] = veca [ 2 ] + vecb [ 2 ] ;
}
2017-09-17 02:12:53 +00:00
void _VectorCopy ( const vec3_t in , vec3_t out )
2010-02-15 23:26:55 +00:00
{
out [ 0 ] = in [ 0 ] ;
out [ 1 ] = in [ 1 ] ;
out [ 2 ] = in [ 2 ] ;
}
2017-09-17 02:12:53 +00:00
void CrossProduct ( const vec3_t v1 , const vec3_t v2 , vec3_t cross )
2010-02-15 23:26:55 +00:00
{
cross [ 0 ] = v1 [ 1 ] * v2 [ 2 ] - v1 [ 2 ] * v2 [ 1 ] ;
cross [ 1 ] = v1 [ 2 ] * v2 [ 0 ] - v1 [ 0 ] * v2 [ 2 ] ;
cross [ 2 ] = v1 [ 0 ] * v2 [ 1 ] - v1 [ 1 ] * v2 [ 0 ] ;
}
2017-09-17 02:12:53 +00:00
vec_t VectorLength ( const vec3_t v )
2010-02-15 23:26:55 +00:00
{
2010-08-01 19:22:46 +00:00
return sqrt ( DotProduct ( v , v ) ) ;
2010-02-15 23:26:55 +00:00
}
float VectorNormalize ( vec3_t v )
{
float length , ilength ;
2010-08-01 19:22:46 +00:00
length = sqrt ( DotProduct ( v , v ) ) ;
2010-02-15 23:26:55 +00:00
if ( length )
{
ilength = 1 / length ;
v [ 0 ] * = ilength ;
v [ 1 ] * = ilength ;
v [ 2 ] * = ilength ;
}
return length ;
}
void VectorInverse ( vec3_t v )
{
v [ 0 ] = - v [ 0 ] ;
v [ 1 ] = - v [ 1 ] ;
v [ 2 ] = - v [ 2 ] ;
}
2017-09-17 02:12:53 +00:00
void VectorScale ( const vec3_t in , vec_t scale , vec3_t out )
2010-02-15 23:26:55 +00:00
{
out [ 0 ] = in [ 0 ] * scale ;
out [ 1 ] = in [ 1 ] * scale ;
out [ 2 ] = in [ 2 ] * scale ;
}
int Q_log2 ( int val )
{
int answer = 0 ;
while ( val > > = 1 )
answer + + ;
return answer ;
}
/*
= = = = = = = = = = = = = = = =
R_ConcatRotations
= = = = = = = = = = = = = = = =
*/
void R_ConcatRotations ( float in1 [ 3 ] [ 3 ] , float in2 [ 3 ] [ 3 ] , float out [ 3 ] [ 3 ] )
{
out [ 0 ] [ 0 ] = in1 [ 0 ] [ 0 ] * in2 [ 0 ] [ 0 ] + in1 [ 0 ] [ 1 ] * in2 [ 1 ] [ 0 ] +
in1 [ 0 ] [ 2 ] * in2 [ 2 ] [ 0 ] ;
out [ 0 ] [ 1 ] = in1 [ 0 ] [ 0 ] * in2 [ 0 ] [ 1 ] + in1 [ 0 ] [ 1 ] * in2 [ 1 ] [ 1 ] +
in1 [ 0 ] [ 2 ] * in2 [ 2 ] [ 1 ] ;
out [ 0 ] [ 2 ] = in1 [ 0 ] [ 0 ] * in2 [ 0 ] [ 2 ] + in1 [ 0 ] [ 1 ] * in2 [ 1 ] [ 2 ] +
in1 [ 0 ] [ 2 ] * in2 [ 2 ] [ 2 ] ;
out [ 1 ] [ 0 ] = in1 [ 1 ] [ 0 ] * in2 [ 0 ] [ 0 ] + in1 [ 1 ] [ 1 ] * in2 [ 1 ] [ 0 ] +
in1 [ 1 ] [ 2 ] * in2 [ 2 ] [ 0 ] ;
out [ 1 ] [ 1 ] = in1 [ 1 ] [ 0 ] * in2 [ 0 ] [ 1 ] + in1 [ 1 ] [ 1 ] * in2 [ 1 ] [ 1 ] +
in1 [ 1 ] [ 2 ] * in2 [ 2 ] [ 1 ] ;
out [ 1 ] [ 2 ] = in1 [ 1 ] [ 0 ] * in2 [ 0 ] [ 2 ] + in1 [ 1 ] [ 1 ] * in2 [ 1 ] [ 2 ] +
in1 [ 1 ] [ 2 ] * in2 [ 2 ] [ 2 ] ;
out [ 2 ] [ 0 ] = in1 [ 2 ] [ 0 ] * in2 [ 0 ] [ 0 ] + in1 [ 2 ] [ 1 ] * in2 [ 1 ] [ 0 ] +
in1 [ 2 ] [ 2 ] * in2 [ 2 ] [ 0 ] ;
out [ 2 ] [ 1 ] = in1 [ 2 ] [ 0 ] * in2 [ 0 ] [ 1 ] + in1 [ 2 ] [ 1 ] * in2 [ 1 ] [ 1 ] +
in1 [ 2 ] [ 2 ] * in2 [ 2 ] [ 1 ] ;
out [ 2 ] [ 2 ] = in1 [ 2 ] [ 0 ] * in2 [ 0 ] [ 2 ] + in1 [ 2 ] [ 1 ] * in2 [ 1 ] [ 2 ] +
in1 [ 2 ] [ 2 ] * in2 [ 2 ] [ 2 ] ;
}
/*
= = = = = = = = = = = = = = = =
R_ConcatTransforms
= = = = = = = = = = = = = = = =
*/
void R_ConcatTransforms ( float in1 [ 3 ] [ 4 ] , float in2 [ 3 ] [ 4 ] , float out [ 3 ] [ 4 ] )
{
out [ 0 ] [ 0 ] = in1 [ 0 ] [ 0 ] * in2 [ 0 ] [ 0 ] + in1 [ 0 ] [ 1 ] * in2 [ 1 ] [ 0 ] +
in1 [ 0 ] [ 2 ] * in2 [ 2 ] [ 0 ] ;
out [ 0 ] [ 1 ] = in1 [ 0 ] [ 0 ] * in2 [ 0 ] [ 1 ] + in1 [ 0 ] [ 1 ] * in2 [ 1 ] [ 1 ] +
in1 [ 0 ] [ 2 ] * in2 [ 2 ] [ 1 ] ;
out [ 0 ] [ 2 ] = in1 [ 0 ] [ 0 ] * in2 [ 0 ] [ 2 ] + in1 [ 0 ] [ 1 ] * in2 [ 1 ] [ 2 ] +
in1 [ 0 ] [ 2 ] * in2 [ 2 ] [ 2 ] ;
out [ 0 ] [ 3 ] = in1 [ 0 ] [ 0 ] * in2 [ 0 ] [ 3 ] + in1 [ 0 ] [ 1 ] * in2 [ 1 ] [ 3 ] +
in1 [ 0 ] [ 2 ] * in2 [ 2 ] [ 3 ] + in1 [ 0 ] [ 3 ] ;
out [ 1 ] [ 0 ] = in1 [ 1 ] [ 0 ] * in2 [ 0 ] [ 0 ] + in1 [ 1 ] [ 1 ] * in2 [ 1 ] [ 0 ] +
in1 [ 1 ] [ 2 ] * in2 [ 2 ] [ 0 ] ;
out [ 1 ] [ 1 ] = in1 [ 1 ] [ 0 ] * in2 [ 0 ] [ 1 ] + in1 [ 1 ] [ 1 ] * in2 [ 1 ] [ 1 ] +
in1 [ 1 ] [ 2 ] * in2 [ 2 ] [ 1 ] ;
out [ 1 ] [ 2 ] = in1 [ 1 ] [ 0 ] * in2 [ 0 ] [ 2 ] + in1 [ 1 ] [ 1 ] * in2 [ 1 ] [ 2 ] +
in1 [ 1 ] [ 2 ] * in2 [ 2 ] [ 2 ] ;
out [ 1 ] [ 3 ] = in1 [ 1 ] [ 0 ] * in2 [ 0 ] [ 3 ] + in1 [ 1 ] [ 1 ] * in2 [ 1 ] [ 3 ] +
in1 [ 1 ] [ 2 ] * in2 [ 2 ] [ 3 ] + in1 [ 1 ] [ 3 ] ;
out [ 2 ] [ 0 ] = in1 [ 2 ] [ 0 ] * in2 [ 0 ] [ 0 ] + in1 [ 2 ] [ 1 ] * in2 [ 1 ] [ 0 ] +
in1 [ 2 ] [ 2 ] * in2 [ 2 ] [ 0 ] ;
out [ 2 ] [ 1 ] = in1 [ 2 ] [ 0 ] * in2 [ 0 ] [ 1 ] + in1 [ 2 ] [ 1 ] * in2 [ 1 ] [ 1 ] +
in1 [ 2 ] [ 2 ] * in2 [ 2 ] [ 1 ] ;
out [ 2 ] [ 2 ] = in1 [ 2 ] [ 0 ] * in2 [ 0 ] [ 2 ] + in1 [ 2 ] [ 1 ] * in2 [ 1 ] [ 2 ] +
in1 [ 2 ] [ 2 ] * in2 [ 2 ] [ 2 ] ;
out [ 2 ] [ 3 ] = in1 [ 2 ] [ 0 ] * in2 [ 0 ] [ 3 ] + in1 [ 2 ] [ 1 ] * in2 [ 1 ] [ 3 ] +
in1 [ 2 ] [ 2 ] * in2 [ 2 ] [ 3 ] + in1 [ 2 ] [ 3 ] ;
}
/*
= = = = = = = = = = = = = = = = = = =
FloorDivMod
Returns mathematically correct ( floor - based ) quotient and remainder for
numer and denom , both of which should contain no fractional part . The
quotient must fit in 32 bits .
= = = = = = = = = = = = = = = = = = = =
*/
void FloorDivMod ( double numer , double denom , int * quotient ,
int * rem )
{
int q , r ;
double x ;
# ifndef PARANOID
if ( denom < = 0.0 )
Constified Con_DebugLog, Con_Print, Con_Printf, Con_Warning, Con_DPrintf,
Con_DPrintf2, Con_SafePrintf, Con_CenterPrintf, Con_LogCenterPrint,
Con_NotifyBox, PL_ErrorDialog, PR_RunError, Host_EndGame, Host_Error,
SV_ClientPrintf, SV_BroadcastPrintf, Host_ClientCommands, Sys_DebugLog,
Sys_Error, Sys_Printf, BOPS_Error and va. Added noreturn attribute to
Sys_Error, Sys_Quit, BOPS_Error, PR_RunError, Host_EndGame and Host_Error.
Added format printf attribute to Con_DebugLog, Con_Printf, Con_Warning,
Con_DPrintf, Con_DPrintf2, Con_SafePrintf, Con_CenterPrintf, PL_ErrorDialog,
PR_RunError, Host_EndGame, Host_Error, SV_ClientPrintf, SV_BroadcastPrintf,
Host_ClientCommands, Sys_DebugLog, Sys_Error, Sys_Printf and va. Adjusted
Host_Status_f and NET_Ban_f for the new attributes. Fixed broken format
strings in Con_Dump_f, Mod_LoadTexinfo, PR_AllocStringSlots and FloorDivMod.
Defined __attribute__ macros in quakedef.h so that we don't break non-gcc
compilers.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@154 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-04-26 16:30:40 +00:00
Sys_Error ( " FloorDivMod: bad denominator %f \n " , denom ) ;
2010-02-15 23:26:55 +00:00
// if ((floor(numer) != numer) || (floor(denom) != denom))
// Sys_Error ("FloorDivMod: non-integer numer or denom %f %f\n",
// numer, denom);
# endif
if ( numer > = 0.0 )
{
x = floor ( numer / denom ) ;
q = ( int ) x ;
r = ( int ) floor ( numer - ( x * denom ) ) ;
}
else
{
//
// perform operations with positive values, and fix mod to make floor-based
//
x = floor ( - numer / denom ) ;
q = - ( int ) x ;
r = ( int ) floor ( - numer - ( x * denom ) ) ;
if ( r ! = 0 )
{
q - - ;
r = ( int ) denom - r ;
}
}
* quotient = q ;
* rem = r ;
}
/*
= = = = = = = = = = = = = = = = = = =
GreatestCommonDivisor
= = = = = = = = = = = = = = = = = = = =
*/
int GreatestCommonDivisor ( int i1 , int i2 )
{
if ( i1 > i2 )
{
if ( i2 = = 0 )
return ( i1 ) ;
return GreatestCommonDivisor ( i2 , i1 % i2 ) ;
}
else
{
if ( i1 = = 0 )
return ( i2 ) ;
return GreatestCommonDivisor ( i1 , i2 % i1 ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = =
Invert24To16
Inverts an 8.24 value to a 16.16 value
= = = = = = = = = = = = = = = = = = = =
*/
fixed16_t Invert24To16 ( fixed16_t val )
{
if ( val < 256 )
return ( 0xFFFFFFFF ) ;
return ( fixed16_t )
( ( ( double ) 0x10000 * ( double ) 0x1000000 / ( double ) val ) + 0.5 ) ;
}
2021-03-18 09:06:29 +00:00
/*
= = = = = = = = = = = = = = = = = = =
Various 4 * 4 matrix functions .
= = = = = = = = = = = = = = = = = = =
*/
void Matrix4_Transform4 ( const mat4_t matrix , const vec4_t vector , vec4_t product )
{
product [ 0 ] = matrix [ 0 ] * vector [ 0 ] + matrix [ 4 ] * vector [ 1 ] + matrix [ 8 ] * vector [ 2 ] + matrix [ 12 ] * vector [ 3 ] ;
product [ 1 ] = matrix [ 1 ] * vector [ 0 ] + matrix [ 5 ] * vector [ 1 ] + matrix [ 9 ] * vector [ 2 ] + matrix [ 13 ] * vector [ 3 ] ;
product [ 2 ] = matrix [ 2 ] * vector [ 0 ] + matrix [ 6 ] * vector [ 1 ] + matrix [ 10 ] * vector [ 2 ] + matrix [ 14 ] * vector [ 3 ] ;
product [ 3 ] = matrix [ 3 ] * vector [ 0 ] + matrix [ 7 ] * vector [ 1 ] + matrix [ 11 ] * vector [ 2 ] + matrix [ 15 ] * vector [ 3 ] ;
}
void Matrix4_Multiply ( const mat4_t a , const mat4_t b , mat4_t out )
{
out [ 0 ] = a [ 0 ] * b [ 0 ] + a [ 4 ] * b [ 1 ] + a [ 8 ] * b [ 2 ] + a [ 12 ] * b [ 3 ] ;
out [ 1 ] = a [ 1 ] * b [ 0 ] + a [ 5 ] * b [ 1 ] + a [ 9 ] * b [ 2 ] + a [ 13 ] * b [ 3 ] ;
out [ 2 ] = a [ 2 ] * b [ 0 ] + a [ 6 ] * b [ 1 ] + a [ 10 ] * b [ 2 ] + a [ 14 ] * b [ 3 ] ;
out [ 3 ] = a [ 3 ] * b [ 0 ] + a [ 7 ] * b [ 1 ] + a [ 11 ] * b [ 2 ] + a [ 15 ] * b [ 3 ] ;
out [ 4 ] = a [ 0 ] * b [ 4 ] + a [ 4 ] * b [ 5 ] + a [ 8 ] * b [ 6 ] + a [ 12 ] * b [ 7 ] ;
out [ 5 ] = a [ 1 ] * b [ 4 ] + a [ 5 ] * b [ 5 ] + a [ 9 ] * b [ 6 ] + a [ 13 ] * b [ 7 ] ;
out [ 6 ] = a [ 2 ] * b [ 4 ] + a [ 6 ] * b [ 5 ] + a [ 10 ] * b [ 6 ] + a [ 14 ] * b [ 7 ] ;
out [ 7 ] = a [ 3 ] * b [ 4 ] + a [ 7 ] * b [ 5 ] + a [ 11 ] * b [ 6 ] + a [ 15 ] * b [ 7 ] ;
out [ 8 ] = a [ 0 ] * b [ 8 ] + a [ 4 ] * b [ 9 ] + a [ 8 ] * b [ 10 ] + a [ 12 ] * b [ 11 ] ;
out [ 9 ] = a [ 1 ] * b [ 8 ] + a [ 5 ] * b [ 9 ] + a [ 9 ] * b [ 10 ] + a [ 13 ] * b [ 11 ] ;
out [ 10 ] = a [ 2 ] * b [ 8 ] + a [ 6 ] * b [ 9 ] + a [ 10 ] * b [ 10 ] + a [ 14 ] * b [ 11 ] ;
out [ 11 ] = a [ 3 ] * b [ 8 ] + a [ 7 ] * b [ 9 ] + a [ 11 ] * b [ 10 ] + a [ 15 ] * b [ 11 ] ;
out [ 12 ] = a [ 0 ] * b [ 12 ] + a [ 4 ] * b [ 13 ] + a [ 8 ] * b [ 14 ] + a [ 12 ] * b [ 15 ] ;
out [ 13 ] = a [ 1 ] * b [ 12 ] + a [ 5 ] * b [ 13 ] + a [ 9 ] * b [ 14 ] + a [ 13 ] * b [ 15 ] ;
out [ 14 ] = a [ 2 ] * b [ 12 ] + a [ 6 ] * b [ 13 ] + a [ 10 ] * b [ 14 ] + a [ 14 ] * b [ 15 ] ;
out [ 15 ] = a [ 3 ] * b [ 12 ] + a [ 7 ] * b [ 13 ] + a [ 11 ] * b [ 14 ] + a [ 15 ] * b [ 15 ] ;
}
/*
* Compute inverse of 4 x4 transformation matrix .
* Code contributed by Jacques Leroy jle @ star . be
* Return true for success , false for failure ( singular matrix )
* Spike : This comes from mesa ' s GLU .
*/
qboolean Matrix4_Invert ( const float * m , float * out )
{
/* NB. OpenGL Matrices are COLUMN major. */
# define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; }
# define MAT(m,r,c) (m)[(c)*4+(r)]
float wtmp [ 4 ] [ 8 ] ;
float m0 , m1 , m2 , m3 , s ;
float * r0 , * r1 , * r2 , * r3 ;
r0 = wtmp [ 0 ] , r1 = wtmp [ 1 ] , r2 = wtmp [ 2 ] , r3 = wtmp [ 3 ] ;
r0 [ 0 ] = MAT ( m , 0 , 0 ) , r0 [ 1 ] = MAT ( m , 0 , 1 ) ,
r0 [ 2 ] = MAT ( m , 0 , 2 ) , r0 [ 3 ] = MAT ( m , 0 , 3 ) ,
r0 [ 4 ] = 1.0 , r0 [ 5 ] = r0 [ 6 ] = r0 [ 7 ] = 0.0 ,
r1 [ 0 ] = MAT ( m , 1 , 0 ) , r1 [ 1 ] = MAT ( m , 1 , 1 ) ,
r1 [ 2 ] = MAT ( m , 1 , 2 ) , r1 [ 3 ] = MAT ( m , 1 , 3 ) ,
r1 [ 5 ] = 1.0 , r1 [ 4 ] = r1 [ 6 ] = r1 [ 7 ] = 0.0 ,
r2 [ 0 ] = MAT ( m , 2 , 0 ) , r2 [ 1 ] = MAT ( m , 2 , 1 ) ,
r2 [ 2 ] = MAT ( m , 2 , 2 ) , r2 [ 3 ] = MAT ( m , 2 , 3 ) ,
r2 [ 6 ] = 1.0 , r2 [ 4 ] = r2 [ 5 ] = r2 [ 7 ] = 0.0 ,
r3 [ 0 ] = MAT ( m , 3 , 0 ) , r3 [ 1 ] = MAT ( m , 3 , 1 ) ,
r3 [ 2 ] = MAT ( m , 3 , 2 ) , r3 [ 3 ] = MAT ( m , 3 , 3 ) ,
r3 [ 7 ] = 1.0 , r3 [ 4 ] = r3 [ 5 ] = r3 [ 6 ] = 0.0 ;
/* choose pivot - or die */
if ( fabs ( r3 [ 0 ] ) > fabs ( r2 [ 0 ] ) )
SWAP_ROWS ( r3 , r2 )
if ( fabs ( r2 [ 0 ] ) > fabs ( r1 [ 0 ] ) )
SWAP_ROWS ( r2 , r1 )
if ( fabs ( r1 [ 0 ] ) > fabs ( r0 [ 0 ] ) )
SWAP_ROWS ( r1 , r0 )
if ( 0.0 = = r0 [ 0 ] )
return false ;
/* eliminate first variable */
m1 = r1 [ 0 ] / r0 [ 0 ] ;
m2 = r2 [ 0 ] / r0 [ 0 ] ;
m3 = r3 [ 0 ] / r0 [ 0 ] ;
s = r0 [ 1 ] ;
r1 [ 1 ] - = m1 * s ;
r2 [ 1 ] - = m2 * s ;
r3 [ 1 ] - = m3 * s ;
s = r0 [ 2 ] ;
r1 [ 2 ] - = m1 * s ;
r2 [ 2 ] - = m2 * s ;
r3 [ 2 ] - = m3 * s ;
s = r0 [ 3 ] ;
r1 [ 3 ] - = m1 * s ;
r2 [ 3 ] - = m2 * s ;
r3 [ 3 ] - = m3 * s ;
s = r0 [ 4 ] ;
if ( s ! = 0.0 ) {
r1 [ 4 ] - = m1 * s ;
r2 [ 4 ] - = m2 * s ;
r3 [ 4 ] - = m3 * s ;
}
s = r0 [ 5 ] ;
if ( s ! = 0.0 ) {
r1 [ 5 ] - = m1 * s ;
r2 [ 5 ] - = m2 * s ;
r3 [ 5 ] - = m3 * s ;
}
s = r0 [ 6 ] ;
if ( s ! = 0.0 ) {
r1 [ 6 ] - = m1 * s ;
r2 [ 6 ] - = m2 * s ;
r3 [ 6 ] - = m3 * s ;
}
s = r0 [ 7 ] ;
if ( s ! = 0.0 ) {
r1 [ 7 ] - = m1 * s ;
r2 [ 7 ] - = m2 * s ;
r3 [ 7 ] - = m3 * s ;
}
/* choose pivot - or die */
if ( fabs ( r3 [ 1 ] ) > fabs ( r2 [ 1 ] ) )
SWAP_ROWS ( r3 , r2 )
if ( fabs ( r2 [ 1 ] ) > fabs ( r1 [ 1 ] ) )
SWAP_ROWS ( r2 , r1 )
if ( 0.0 = = r1 [ 1 ] )
return false ;
/* eliminate second variable */
m2 = r2 [ 1 ] / r1 [ 1 ] ;
m3 = r3 [ 1 ] / r1 [ 1 ] ;
r2 [ 2 ] - = m2 * r1 [ 2 ] ;
r3 [ 2 ] - = m3 * r1 [ 2 ] ;
r2 [ 3 ] - = m2 * r1 [ 3 ] ;
r3 [ 3 ] - = m3 * r1 [ 3 ] ;
s = r1 [ 4 ] ;
if ( 0.0 ! = s ) {
r2 [ 4 ] - = m2 * s ;
r3 [ 4 ] - = m3 * s ;
}
s = r1 [ 5 ] ;
if ( 0.0 ! = s ) {
r2 [ 5 ] - = m2 * s ;
r3 [ 5 ] - = m3 * s ;
}
s = r1 [ 6 ] ;
if ( 0.0 ! = s ) {
r2 [ 6 ] - = m2 * s ;
r3 [ 6 ] - = m3 * s ;
}
s = r1 [ 7 ] ;
if ( 0.0 ! = s ) {
r2 [ 7 ] - = m2 * s ;
r3 [ 7 ] - = m3 * s ;
}
/* choose pivot - or die */
if ( fabs ( r3 [ 2 ] ) > fabs ( r2 [ 2 ] ) )
SWAP_ROWS ( r3 , r2 )
if ( 0.0 = = r2 [ 2 ] )
return false ;
/* eliminate third variable */
m3 = r3 [ 2 ] / r2 [ 2 ] ;
r3 [ 3 ] - = m3 * r2 [ 3 ] , r3 [ 4 ] - = m3 * r2 [ 4 ] ,
r3 [ 5 ] - = m3 * r2 [ 5 ] , r3 [ 6 ] - = m3 * r2 [ 6 ] , r3 [ 7 ] - = m3 * r2 [ 7 ] ;
/* last check */
if ( 0.0 = = r3 [ 3 ] )
return false ;
s = 1.0 / r3 [ 3 ] ; /* now back substitute row 3 */
r3 [ 4 ] * = s ;
r3 [ 5 ] * = s ;
r3 [ 6 ] * = s ;
r3 [ 7 ] * = s ;
m2 = r2 [ 3 ] ; /* now back substitute row 2 */
s = 1.0 / r2 [ 2 ] ;
r2 [ 4 ] = s * ( r2 [ 4 ] - r3 [ 4 ] * m2 ) , r2 [ 5 ] = s * ( r2 [ 5 ] - r3 [ 5 ] * m2 ) ,
r2 [ 6 ] = s * ( r2 [ 6 ] - r3 [ 6 ] * m2 ) , r2 [ 7 ] = s * ( r2 [ 7 ] - r3 [ 7 ] * m2 ) ;
m1 = r1 [ 3 ] ;
r1 [ 4 ] - = r3 [ 4 ] * m1 , r1 [ 5 ] - = r3 [ 5 ] * m1 ,
r1 [ 6 ] - = r3 [ 6 ] * m1 , r1 [ 7 ] - = r3 [ 7 ] * m1 ;
m0 = r0 [ 3 ] ;
r0 [ 4 ] - = r3 [ 4 ] * m0 , r0 [ 5 ] - = r3 [ 5 ] * m0 ,
r0 [ 6 ] - = r3 [ 6 ] * m0 , r0 [ 7 ] - = r3 [ 7 ] * m0 ;
m1 = r1 [ 2 ] ; /* now back substitute row 1 */
s = 1.0 / r1 [ 1 ] ;
r1 [ 4 ] = s * ( r1 [ 4 ] - r2 [ 4 ] * m1 ) , r1 [ 5 ] = s * ( r1 [ 5 ] - r2 [ 5 ] * m1 ) ,
r1 [ 6 ] = s * ( r1 [ 6 ] - r2 [ 6 ] * m1 ) , r1 [ 7 ] = s * ( r1 [ 7 ] - r2 [ 7 ] * m1 ) ;
m0 = r0 [ 2 ] ;
r0 [ 4 ] - = r2 [ 4 ] * m0 , r0 [ 5 ] - = r2 [ 5 ] * m0 ,
r0 [ 6 ] - = r2 [ 6 ] * m0 , r0 [ 7 ] - = r2 [ 7 ] * m0 ;
m0 = r0 [ 1 ] ; /* now back substitute row 0 */
s = 1.0 / r0 [ 0 ] ;
r0 [ 4 ] = s * ( r0 [ 4 ] - r1 [ 4 ] * m0 ) , r0 [ 5 ] = s * ( r0 [ 5 ] - r1 [ 5 ] * m0 ) ,
r0 [ 6 ] = s * ( r0 [ 6 ] - r1 [ 6 ] * m0 ) , r0 [ 7 ] = s * ( r0 [ 7 ] - r1 [ 7 ] * m0 ) ;
MAT ( out , 0 , 0 ) = r0 [ 4 ] ;
MAT ( out , 0 , 1 ) = r0 [ 5 ] , MAT ( out , 0 , 2 ) = r0 [ 6 ] ;
MAT ( out , 0 , 3 ) = r0 [ 7 ] , MAT ( out , 1 , 0 ) = r1 [ 4 ] ;
MAT ( out , 1 , 1 ) = r1 [ 5 ] , MAT ( out , 1 , 2 ) = r1 [ 6 ] ;
MAT ( out , 1 , 3 ) = r1 [ 7 ] , MAT ( out , 2 , 0 ) = r2 [ 4 ] ;
MAT ( out , 2 , 1 ) = r2 [ 5 ] , MAT ( out , 2 , 2 ) = r2 [ 6 ] ;
MAT ( out , 2 , 3 ) = r2 [ 7 ] , MAT ( out , 3 , 0 ) = r3 [ 4 ] ;
MAT ( out , 3 , 1 ) = r3 [ 5 ] , MAT ( out , 3 , 2 ) = r3 [ 6 ] ;
MAT ( out , 3 , 3 ) = r3 [ 7 ] ;
return true ;
# undef MAT
# undef SWAP_ROWS
}
void Matrix4_ViewMatrix ( const vec3_t viewangles , const vec3_t vieworg , mat4_t out )
2021-03-21 14:09:24 +00:00
{ //directly compute a view matrix. this is not the same as a model matrix (in part because the values are all negated).
2021-03-18 09:06:29 +00:00
float cp = cos ( - viewangles [ 0 ] * M_PI / 180.0 ) ;
float sp = sin ( - viewangles [ 0 ] * M_PI / 180.0 ) ;
float cy = cos ( - viewangles [ 1 ] * M_PI / 180.0 ) ;
float sy = sin ( - viewangles [ 1 ] * M_PI / 180.0 ) ;
float cr = cos ( - viewangles [ 2 ] * M_PI / 180.0 ) ;
float sr = sin ( - viewangles [ 2 ] * M_PI / 180.0 ) ;
2021-03-21 14:09:24 +00:00
out [ 0 ] = - sr * sp * cy - cr * sy ;
2021-03-18 09:06:29 +00:00
out [ 1 ] = - cr * sp * cy + sr * sy ;
out [ 2 ] = - cp * cy ;
out [ 3 ] = 0 ;
2021-03-21 14:09:24 +00:00
out [ 4 ] = sr * sp * sy - cr * cy ;
out [ 5 ] = cr * sp * sy + sr * cy ;
2021-03-18 09:06:29 +00:00
out [ 6 ] = cp * sy ;
out [ 7 ] = 0 ;
2021-03-21 14:09:24 +00:00
out [ 8 ] = sr * cp ;
2021-03-18 09:06:29 +00:00
out [ 9 ] = cr * cp ;
out [ 10 ] = - sp ;
out [ 11 ] = 0 ;
out [ 12 ] = - out [ 0 ] * vieworg [ 0 ] - out [ 4 ] * vieworg [ 1 ] - out [ 8 ] * vieworg [ 2 ] ;
out [ 13 ] = - out [ 1 ] * vieworg [ 0 ] - out [ 5 ] * vieworg [ 1 ] - out [ 9 ] * vieworg [ 2 ] ;
out [ 14 ] = - out [ 2 ] * vieworg [ 0 ] - out [ 6 ] * vieworg [ 1 ] - out [ 10 ] * vieworg [ 2 ] ;
out [ 15 ] = 1 - out [ 3 ] * vieworg [ 0 ] - out [ 7 ] * vieworg [ 1 ] - out [ 11 ] * vieworg [ 2 ] ;
}
//computes an orthographic projection matrix (mostly equivelent to glFrustum)
void Matrix4_ProjectionMatrix ( float fovx , float fovy , float neard , float fard , qboolean d3d , float xskew , float yskew , mat4_t out )
{
double xmin , xmax , ymin , ymax ;
double dn = ( d3d ? 0 : - 1 ) , df = 1 ;
xmax = neard * tan ( fovx * M_PI / 360.0 ) ;
xmin = - xmax ;
ymax = neard * tan ( fovy * M_PI / 360.0 ) ;
ymin = - ymax ;
xmax + = xskew ; //this stuff for r_stereo
xmin + = xskew ;
ymax + = yskew ;
ymin + = yskew ;
out [ 0 ] = ( 2 * neard ) / ( xmax - xmin ) ;
out [ 4 ] = 0 ;
out [ 8 ] = ( xmax + xmin ) / ( xmax - xmin ) ;
out [ 12 ] = 0 ;
out [ 1 ] = 0 ;
out [ 5 ] = ( 2 * neard ) / ( ymax - ymin ) ;
out [ 9 ] = ( ymax + ymin ) / ( ymax - ymin ) ;
out [ 13 ] = 0 ;
out [ 2 ] = 0 ;
out [ 6 ] = 0 ;
if ( fard < neard )
{ //fiddle with the far clip plane to make it rather large
2021-03-18 12:33:44 +00:00
//depth precision is non-linear, decaying with distance relative to the near clip plane, a closer near plane degrades precision faster, so an 'infinite' far clip plane doesn't actually hurt typical precision all that much, at least with a 24bit depth buffer.
2021-03-18 09:06:29 +00:00
const double epsilon = 1.0 / ( 1 < < 22 ) ;
out [ 10 ] = epsilon - 1 ;
out [ 14 ] = ( epsilon - ( df - dn ) ) * neard ;
}
else
{
out [ 10 ] = ( fard * df - neard * dn ) / ( neard - fard ) ;
out [ 14 ] = ( ( df - dn ) * fard * neard ) / ( neard - fard ) ;
}
out [ 3 ] = 0 ;
out [ 7 ] = 0 ;
out [ 11 ] = - 1 ;
out [ 15 ] = 0 ;
}