07 Sep 2009
This commit is contained in:
parent
87d79be8d2
commit
9e0c409367
|
@ -11,6 +11,12 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#pragma warning( disable : 4244 ) // int or float down-conversion
|
||||
#define NUMVERTEXNORMALS 162
|
||||
|
||||
static float bytedirs[NUMVERTEXNORMALS][3] =
|
||||
{
|
||||
#include "anorms.h"
|
||||
};
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (float)3.14159265358979323846
|
||||
|
@ -171,36 +177,36 @@ public:
|
|||
}
|
||||
int DirToBits( void )
|
||||
{
|
||||
int max, bits, numBits = 8; // pack as unsigned char ( state->skin supports this )
|
||||
float bias;
|
||||
int i, best = 0;
|
||||
float d, bestd = 0;
|
||||
BOOL normalized = FALSE;
|
||||
|
||||
numBits /= 3;
|
||||
max = ( 1 << ( numBits - 1 )) - 1;
|
||||
bias = 0.5f / max;
|
||||
if( x == 0 && y == 0 && z == 0 )
|
||||
return NUMVERTEXNORMALS;
|
||||
|
||||
bits = ((*(const unsigned long *)&( x )) >> 31) << ( numBits * 3 - 1 );
|
||||
bits |= ((int)(( fabs( x ) + bias ) * max ) ) << ( numBits * 2 );
|
||||
bits |= ((*(const unsigned long *)&( y )) >> 31) << ( numBits * 2 - 1 );
|
||||
bits |= ((int)(( fabs( y ) + bias ) * max ) ) << ( numBits * 1 );
|
||||
bits |= ((*(const unsigned long *)&( z )) >> 31) << ( numBits * 1 - 1 );
|
||||
bits |= ((int)(( fabs( z ) + bias ) * max ) ) << ( numBits * 0 );
|
||||
if((x*x+y*y+z*z) == 1 )
|
||||
normalized = TRUE;
|
||||
|
||||
return bits;
|
||||
for( i = 0; i < NUMVERTEXNORMALS; i++ )
|
||||
{
|
||||
d = (x*bytedirs[i][0]+y*bytedirs[i][1]+z*bytedirs[i][2]);
|
||||
if(( d == 1 ) && normalized )
|
||||
return i;
|
||||
if( d > bestd )
|
||||
{
|
||||
bestd = d;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
Vector BitsToDir( int bits )
|
||||
{
|
||||
static float sign[2] = { 1.0f, -1.0f };
|
||||
int max, numBits = 8; // pack as unsigned char
|
||||
float invMax;
|
||||
|
||||
numBits /= 3;
|
||||
max = ( 1 << ( numBits - 1 )) - 1;
|
||||
invMax = 1.0f / max;
|
||||
|
||||
x = sign[(bits >> (numBits * 3 - 1 )) & 1] * ((bits >> (numBits * 2 )) & max) * invMax;
|
||||
y = sign[(bits >> (numBits * 2 - 1 )) & 1] * ((bits >> (numBits * 1 )) & max) * invMax;
|
||||
z = sign[(bits >> (numBits * 1 - 1 )) & 1] * ((bits >> (numBits * 0 )) & max) * invMax;
|
||||
Normalize();
|
||||
if( bits < 0 || bits >= NUMVERTEXNORMALS )
|
||||
return Vector( 0, 0, 0 );
|
||||
x = bytedirs[bits][0];
|
||||
y = bytedirs[bits][1];
|
||||
z = bytedirs[bits][2];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ void CL_AddDLights( void )
|
|||
dl = cl_dlights;
|
||||
for( i = 0; i < MAX_DLIGHTS; i++, dl++ )
|
||||
{
|
||||
if( dl->radius ) re->AddDynLight( dl->origin, dl->color, dl->radius, -1 );
|
||||
if( dl->radius ) re->AddDynLight( dl->origin, dl->color, dl->radius, dl->cone, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -991,30 +991,53 @@ if cl_testlights is set, create 32 lights models
|
|||
*/
|
||||
void CL_TestLights( void )
|
||||
{
|
||||
int i, j;
|
||||
float f, r;
|
||||
cdlight_t dl;
|
||||
int i, j;
|
||||
float f, r;
|
||||
cdlight_t dl;
|
||||
|
||||
if( !cl_testlights->integer )
|
||||
return;
|
||||
|
||||
Mem_Set( &dl, 0, sizeof( cdlight_t ));
|
||||
|
||||
for( i = 0; i < bound( 1, cl_testlights->integer, MAX_DLIGHTS ); i++ )
|
||||
if( cl_testflashlight->integer )
|
||||
{
|
||||
r = 64 * ( (i%4) - 1.5 );
|
||||
f = 64 * (i/4) + 128;
|
||||
vec3_t end;
|
||||
edict_t *ed = CL_GetLocalPlayer();
|
||||
int cnt = CL_ContentsMask( ed );
|
||||
static shader_t flashlight_shader = 0;
|
||||
trace_t trace;
|
||||
|
||||
for( j = 0; j < 3; j++ )
|
||||
dl.origin[j] = cl.refdef.vieworg[j] + cl.refdef.forward[j] * f + cl.refdef.right[j] * r;
|
||||
Mem_Set( &dl, 0, sizeof( cdlight_t ));
|
||||
|
||||
dl.color[0] = ((i%6)+1) & 1;
|
||||
dl.color[1] = (((i%6)+1) & 2)>>1;
|
||||
dl.color[2] = (((i%6)+1) & 4)>>2;
|
||||
dl.radius = 200;
|
||||
// if( !flashlight_shader )
|
||||
// flashlight_shader = re->RegisterShader( "flashlight", SHADER_GENERIC );
|
||||
|
||||
if( !re->AddDynLight( dl.origin, dl.color, dl.radius, -1 ))
|
||||
break;
|
||||
VectorScale( cl.refdef.forward, 256, end );
|
||||
VectorAdd( end, cl.refdef.vieworg, end );
|
||||
|
||||
trace = CL_Trace( cl.refdef.vieworg, vec3_origin, vec3_origin, end, MOVE_HITMODEL, ed, cnt );
|
||||
VectorSet( dl.color, 1.0f, 1.0f, 1.0f );
|
||||
dl.radius = 96;
|
||||
VectorCopy( trace.endpos, dl.origin );
|
||||
|
||||
re->AddDynLight( dl.origin, dl.color, dl.radius, dl.cone, -1 );
|
||||
}
|
||||
if( cl_testlights->integer )
|
||||
{
|
||||
Mem_Set( &dl, 0, sizeof( cdlight_t ));
|
||||
|
||||
for( i = 0; i < bound( 1, cl_testlights->integer, MAX_DLIGHTS ); i++ )
|
||||
{
|
||||
r = 64 * ( (i%4) - 1.5 );
|
||||
f = 64 * (i/4) + 128;
|
||||
|
||||
for( j = 0; j < 3; j++ )
|
||||
dl.origin[j] = cl.refdef.vieworg[j] + cl.refdef.forward[j] * f + cl.refdef.right[j] * r;
|
||||
|
||||
dl.color[0] = ((i%6)+1) & 1;
|
||||
dl.color[1] = (((i%6)+1) & 2)>>1;
|
||||
dl.color[2] = (((i%6)+1) & 4)>>2;
|
||||
dl.radius = 200;
|
||||
|
||||
if( !re->AddDynLight( dl.origin, dl.color, dl.radius, NULL, -1 ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ cvar_t *scr_width;
|
|||
cvar_t *scr_height;
|
||||
cvar_t *cl_testentities;
|
||||
cvar_t *cl_testlights;
|
||||
cvar_t *cl_testflashlight;
|
||||
cvar_t *cl_levelshot_name;
|
||||
cvar_t *cl_envshot_size;
|
||||
cvar_t *cl_font;
|
||||
|
@ -448,6 +449,7 @@ void SCR_Init( void )
|
|||
scr_download = Cvar_Get("scr_download", "0", 0, "downloading bar progress" );
|
||||
cl_testentities = Cvar_Get ("cl_testentities", "0", 0, "test client entities" );
|
||||
cl_testlights = Cvar_Get ("cl_testlights", "0", 0, "test dynamic lights" );
|
||||
cl_testflashlight = Cvar_Get ("cl_testflashlight", "0", 0, "test generic flashlight" );
|
||||
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", CVAR_ARCHIVE, "envshot size of cube side" );
|
||||
cl_font = Cvar_Get( "cl_font", "default", CVAR_ARCHIVE, "in-game messages font" );
|
||||
|
||||
|
|
|
@ -331,6 +331,7 @@ extern cvar_t *m_side;
|
|||
extern cvar_t *cl_mouselook;
|
||||
extern cvar_t *cl_testentities;
|
||||
extern cvar_t *cl_testlights;
|
||||
extern cvar_t *cl_testflashlight;
|
||||
extern cvar_t *cl_lightlevel; // FIXME HACK
|
||||
extern cvar_t *cl_paused;
|
||||
extern cvar_t *cl_levelshot_name;
|
||||
|
|
|
@ -39,7 +39,7 @@ static net_field_t ent_fields[] =
|
|||
{ ES_FIELD(framerate), NET_FLOAT, false }, // custom framerate
|
||||
{ ES_FIELD(sequence), NET_WORD, false }, // 1024 sequences
|
||||
{ ES_FIELD(gaitsequence), NET_WORD, false }, // 1024 gaitsequences
|
||||
{ ES_FIELD(skin), NET_WORD, false }, // 255 skins
|
||||
{ ES_FIELD(skin), NET_BYTE, false }, // 255 skins
|
||||
{ ES_FIELD(body), NET_BYTE, false }, // 255 bodies
|
||||
{ ES_FIELD(weaponmodel), NET_WORD, false }, // p_model index, not name
|
||||
{ ES_FIELD(weaponanim), NET_WORD, false }, // 1024 sequences
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: engine - Win32 Debug--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP3D64.tmp" with contents
|
||||
[
|
||||
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "common" /I "server" /I "client" /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\engine\!debug/" /Fo"..\temp\engine\!debug/" /Fd"..\temp\engine\!debug/" /FD /c
|
||||
"D:\Xash3D\src_main\engine\client\cl_effects.c"
|
||||
]
|
||||
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP3D64.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP3D65.tmp" with contents
|
||||
[
|
||||
user32.lib msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\engine\!debug/engine.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\engine\!debug/engine.dll" /implib:"..\temp\engine\!debug/engine.lib" /pdbtype:sept
|
||||
"\Xash3D\src_main\temp\engine\!debug\cinematic.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_cmds.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_demo.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_effects.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_frame.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_game.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_input.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_main.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_parse.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_phys.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_scrn.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_view.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\com_library.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\con_keys.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\con_main.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\con_utils.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\engfuncs.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\engine.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\host.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\infostring.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\input.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\menu.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\net_chan.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\net_huff.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\net_msg.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_client.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_cmds.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_frame.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_game.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_init.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_main.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_move.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_phys.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_save.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_world.obj"
|
||||
]
|
||||
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP3D65.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP3D66.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
copy \Xash3D\src_main\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll"
|
||||
]
|
||||
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP3D66.bat"
|
||||
Compiling...
|
||||
cl_effects.c
|
||||
Linking...
|
||||
Creating library ..\temp\engine\!debug/engine.lib and object ..\temp\engine\!debug/engine.exp
|
||||
<h3>Output Window</h3>
|
||||
Performing Custom Build Step on \Xash3D\src_main\temp\engine\!debug\engine.dll
|
||||
‘ª®¯¨à®¢ ® ä ©«®¢: 1.
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
engine.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
115
launch/cpuinfo.c
115
launch/cpuinfo.c
|
@ -291,68 +291,73 @@ void Sys_InitMathlib( cpuinfo_t *cpu )
|
|||
int numchecks = 16; // iterations
|
||||
float a;
|
||||
|
||||
// testing sqrt
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 1; i < 800000; i++ ) a = sqrtf( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "crt_sqrt %i ms\n", result[0] );
|
||||
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 1; i < 800000; i++ ) a = com_sqrt( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a+1] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "com_sqrt %i ms\n", result[1] );
|
||||
|
||||
if( cpu->m_b3DNow )
|
||||
// IMPORTANT! compilers with optimized sqrt, sin cos and another funcs
|
||||
// may does wrong results !!!
|
||||
if( Sys.app_name == HOST_NORMAL || Sys.app_name == HOST_DEDICATED )
|
||||
{
|
||||
// testing sqrt
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < 800000; i++ ) a = amd_sqrt( i );
|
||||
for( i = 1; i < 800000; i++ ) a = sqrtf( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a+2] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "amd_sqrt %i ms\n", result[2] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[2] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "amd_sqrt not supported\n" );
|
||||
}
|
||||
result[(int)a] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "crt_sqrt %i ms\n", result[0] );
|
||||
|
||||
if( cpu->m_bSSE )
|
||||
{
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < 800000; i++ ) a = sse_sqrt( i );
|
||||
for( i = 1; i < 800000; i++ ) a = com_sqrt( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a+3] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "sse_sqrt %i ms\n", result[3] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[3] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "sse_sqrt not supported\n" );
|
||||
}
|
||||
result[(int)a+1] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "com_sqrt %i ms\n", result[1] );
|
||||
|
||||
min = min( result[0], min( result[1], min( result[2], result[3] )));
|
||||
if( min == result[0] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using crt_sqrt\n");
|
||||
com.sqrt = sqrtf;
|
||||
}
|
||||
else if( min == result[1] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using com_sqrt\n");
|
||||
com.sqrt = com_sqrt;
|
||||
}
|
||||
else if( min == result[2] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using amd_sqrt\n");
|
||||
com.sqrt = amd_sqrt;
|
||||
}
|
||||
else if( min == result[3] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using sse_sqrt\n");
|
||||
com.sqrt = sse_sqrt;
|
||||
}
|
||||
if( cpu->m_b3DNow )
|
||||
{
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < 800000; i++ ) a = amd_sqrt( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a+2] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "amd_sqrt %i ms\n", result[2] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[2] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "amd_sqrt not supported\n" );
|
||||
}
|
||||
|
||||
if( cpu->m_bSSE )
|
||||
{
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < 800000; i++ ) a = sse_sqrt( i );
|
||||
a *= 0.00000001;
|
||||
result[(int)a+3] = Sys_Milliseconds() - start;
|
||||
MsgDev( D_NOTE, "sse_sqrt %i ms\n", result[3] );
|
||||
}
|
||||
else
|
||||
{
|
||||
result[3] = 0x7fffffff;
|
||||
MsgDev( D_NOTE, "sse_sqrt not supported\n" );
|
||||
}
|
||||
|
||||
min = min( result[0], min( result[1], min( result[2], result[3] )));
|
||||
if( min == result[0] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using crt_sqrt\n");
|
||||
com.sqrt = sqrtf;
|
||||
}
|
||||
else if( min == result[1] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using com_sqrt\n");
|
||||
com.sqrt = com_sqrt;
|
||||
}
|
||||
else if( min == result[2] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using amd_sqrt\n");
|
||||
com.sqrt = amd_sqrt;
|
||||
}
|
||||
else if( min == result[3] )
|
||||
{
|
||||
MsgDev( D_NOTE, "Sys_InitMathlib: using sse_sqrt\n");
|
||||
com.sqrt = sse_sqrt;
|
||||
}
|
||||
}
|
||||
|
||||
start = Sys_Milliseconds();
|
||||
for( i = 0; i < numchecks; i++ ) _crt_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
|
||||
|
|
|
@ -1331,7 +1331,7 @@ void FS_ApplyBaseDir( void )
|
|||
com.strncpy( gs_basedir, tok.string, sizeof( gs_basedir ));
|
||||
break;
|
||||
}
|
||||
else MsgDev( D_ERROR, "missing associated directory with %s.exe", gs_basedir );
|
||||
else MsgDev( D_ERROR, "missing associated directory with %s.exe\n", gs_basedir );
|
||||
}
|
||||
}
|
||||
PS_FreeScript( script );
|
||||
|
|
|
@ -1639,6 +1639,8 @@ bool CM_StudioModel( byte *buffer, uint filesize )
|
|||
VectorCopy( loadmodel->mins, loadmodel->yawmins );
|
||||
VectorCopy( loadmodel->maxs, loadmodel->yawmaxs );
|
||||
|
||||
loadmodel->TraceBox = CM_TraceStudio;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
200
public/quatlib.h
200
public/quatlib.h
|
@ -1,200 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2009 ©
|
||||
// quatlib.h - base math functions
|
||||
//=======================================================================
|
||||
#ifndef QUATLIB_H
|
||||
#define QUATLIB_H
|
||||
|
||||
// The expression a * rsqrt(b) is intended as a higher performance alternative to a / sqrt(b).
|
||||
// The two expressions are comparably accurate, but do not compute exactly the same value in every case.
|
||||
// For example, a * rsqrt(a*a + b*b) can be just slightly greater than 1, in rare cases.
|
||||
#define SQRTFAST( x ) (( x ) * rsqrt( x ))
|
||||
#define VectorLengthFast(v) (SQRTFAST(DotProduct((v),(v))))
|
||||
#define DistanceFast(v1,v2) (SQRTFAST(VectorDistance2(v1,v2)))
|
||||
|
||||
_inline void Quat_Identity( quat_t q )
|
||||
{
|
||||
q[0] = 0;
|
||||
q[1] = 0;
|
||||
q[2] = 0;
|
||||
q[3] = 1;
|
||||
}
|
||||
|
||||
_inline void Quat_Copy( const quat_t q1, quat_t q2 )
|
||||
{
|
||||
q2[0] = q1[0];
|
||||
q2[1] = q1[1];
|
||||
q2[2] = q1[2];
|
||||
q2[3] = q1[3];
|
||||
}
|
||||
|
||||
_inline bool Quat_Compare( const quat_t q1, const quat_t q2 )
|
||||
{
|
||||
if( q1[0] != q2[0] || q1[1] != q2[1] || q1[2] != q2[2] || q1[3] != q2[3] )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
_inline void Quat_Conjugate( const quat_t q1, quat_t q2 )
|
||||
{
|
||||
q2[0] = -q1[0];
|
||||
q2[1] = -q1[1];
|
||||
q2[2] = -q1[2];
|
||||
q2[3] = q1[3];
|
||||
}
|
||||
|
||||
_inline float Quat_Normalize( quat_t q )
|
||||
{
|
||||
float length;
|
||||
|
||||
length = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
|
||||
if( length != 0 )
|
||||
{
|
||||
float ilength = 1.0 / sqrt( length );
|
||||
|
||||
q[0] *= ilength;
|
||||
q[1] *= ilength;
|
||||
q[2] *= ilength;
|
||||
q[3] *= ilength;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
_inline float Quat_Inverse( const quat_t q1, quat_t q2 )
|
||||
{
|
||||
Quat_Conjugate( q1, q2 );
|
||||
return Quat_Normalize( q2 );
|
||||
}
|
||||
|
||||
_inline void Quat_FromAxis( vec3_t m[3], quat_t q )
|
||||
{
|
||||
float tr, s;
|
||||
|
||||
tr = m[0][0] + m[1][1] + m[2][2];
|
||||
if( tr > 0.00001 )
|
||||
{
|
||||
s = sqrt( tr + 1.0 );
|
||||
q[3] = s * 0.5; s = 0.5 / s;
|
||||
q[0] = (m[2][1] - m[1][2]) * s;
|
||||
q[1] = (m[0][2] - m[2][0]) * s;
|
||||
q[2] = (m[1][0] - m[0][1]) * s;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
i = 0;
|
||||
if( m[1][1] > m[0][0] ) i = 1;
|
||||
if( m[2][2] > m[i][i] ) i = 2;
|
||||
j = (i + 1) % 3;
|
||||
k = (i + 2) % 3;
|
||||
|
||||
s = sqrt( m[i][i] - (m[j][j] + m[k][k]) + 1.0 );
|
||||
|
||||
q[i] = s * 0.5; if( s != 0.0 ) s = 0.5 / s;
|
||||
q[j] = (m[j][i] + m[i][j]) * s;
|
||||
q[k] = (m[k][i] + m[i][k]) * s;
|
||||
q[3] = (m[k][j] - m[j][k]) * s;
|
||||
}
|
||||
Quat_Normalize( q );
|
||||
}
|
||||
|
||||
_inline void Quat_Multiply( const quat_t q1, const quat_t q2, quat_t out )
|
||||
{
|
||||
out[0] = q1[3] * q2[0] + q1[0] * q2[3] + q1[1] * q2[2] - q1[2] * q2[1];
|
||||
out[1] = q1[3] * q2[1] + q1[1] * q2[3] + q1[2] * q2[0] - q1[0] * q2[2];
|
||||
out[2] = q1[3] * q2[2] + q1[2] * q2[3] + q1[0] * q2[1] - q1[1] * q2[0];
|
||||
out[3] = q1[3] * q2[3] - q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2];
|
||||
}
|
||||
|
||||
_inline void Quat_Lerp( const quat_t q1, const quat_t q2, float t, quat_t out )
|
||||
{
|
||||
quat_t p1;
|
||||
vec_t omega, cosom, sinom, scale0, scale1, sinsqr;
|
||||
|
||||
if( Quat_Compare( q1, q2 ))
|
||||
{
|
||||
Quat_Copy( q1, out );
|
||||
return;
|
||||
}
|
||||
|
||||
cosom = q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3];
|
||||
if( cosom < 0.0 )
|
||||
{
|
||||
cosom = -cosom;
|
||||
p1[0] = -q1[0]; p1[1] = -q1[1];
|
||||
p1[2] = -q1[2]; p1[3] = -q1[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
p1[0] = q1[0]; p1[1] = q1[1];
|
||||
p1[2] = q1[2]; p1[3] = q1[3];
|
||||
}
|
||||
|
||||
if( cosom < 1.0 - 0.0001 )
|
||||
{
|
||||
sinsqr = 1.0 - cosom * cosom;
|
||||
sinom = rsqrt( sinsqr );
|
||||
omega = atan2( sinsqr * sinom, cosom );
|
||||
scale0 = sin( (1.0 - t) * omega ) * sinom;
|
||||
scale1 = sin( t * omega ) * sinom;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale0 = 1.0 - t;
|
||||
scale1 = t;
|
||||
}
|
||||
|
||||
out[0] = scale0 * p1[0] + scale1 * q2[0];
|
||||
out[1] = scale0 * p1[1] + scale1 * q2[1];
|
||||
out[2] = scale0 * p1[2] + scale1 * q2[2];
|
||||
out[3] = scale0 * p1[3] + scale1 * q2[3];
|
||||
}
|
||||
|
||||
_inline void Quat_Vectors( const quat_t q, vec3_t f, vec3_t r, vec3_t u )
|
||||
{
|
||||
float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
|
||||
|
||||
x2 = q[0] + q[0]; y2 = q[1] + q[1]; z2 = q[2] + q[2];
|
||||
|
||||
xx = q[0] * x2; yy = q[1] * y2; zz = q[2] * z2;
|
||||
f[0] = 1.0f - yy - zz; r[1] = 1.0f - xx - zz; u[2] = 1.0f - xx - yy;
|
||||
|
||||
yz = q[1] * z2; wx = q[3] * x2;
|
||||
r[2] = yz - wx; u[1] = yz + wx;
|
||||
|
||||
xy = q[0] * y2; wz = q[3] * z2;
|
||||
f[1] = xy - wz; r[0] = xy + wz;
|
||||
|
||||
xz = q[0] * z2; wy = q[3] * y2;
|
||||
f[2] = xz + wy; u[0] = xz - wy;
|
||||
}
|
||||
|
||||
_inline void Quat_Matrix( const quat_t q, vec3_t m[3] )
|
||||
{
|
||||
Quat_Vectors( q, m[0], m[1], m[2] );
|
||||
}
|
||||
|
||||
_inline void Quat_TransformVector( const quat_t q, const vec3_t v, vec3_t out )
|
||||
{
|
||||
float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
|
||||
|
||||
x2 = q[0] + q[0]; y2 = q[1] + q[1]; z2 = q[2] + q[2];
|
||||
xx = q[0] * x2; xy = q[0] * y2; xz = q[0] * z2;
|
||||
yy = q[1] * y2; yz = q[1] * z2; zz = q[2] * z2;
|
||||
wx = q[3] * x2; wy = q[3] * y2; wz = q[3] * z2;
|
||||
|
||||
out[0] = (1.0f - yy - zz) * v[0] + (xy - wz) * v[1] + (xz + wy) * v[2];
|
||||
out[1] = (xy + wz) * v[0] + (1.0f - xx - zz) * v[1] + (yz - wx) * v[2];
|
||||
out[2] = (xz - wy) * v[0] + (yz + wx) * v[1] + (1.0f - xx - yy) * v[2];
|
||||
}
|
||||
|
||||
_inline void Quat_ConcatTransforms( const quat_t q1,const vec3_t v1,const quat_t q2,const vec3_t v2,quat_t q, vec3_t v )
|
||||
{
|
||||
Quat_Multiply( q1, q2, q );
|
||||
Quat_TransformVector( q1, v2, v );
|
||||
v[0] += v1[0];
|
||||
v[1] += v1[1];
|
||||
v[2] += v1[2];
|
||||
}
|
||||
#endif//QUATLIB_H
|
|
@ -70,7 +70,7 @@ typedef struct render_exp_s
|
|||
|
||||
// prepare frame to rendering
|
||||
bool (*AddRefEntity)( edict_t *pRefEntity, int ed_type, float lerp );
|
||||
bool (*AddDynLight)( vec3_t org, vec3_t color, float intensity, shader_t shader );
|
||||
bool (*AddDynLight)( vec3_t org, vec3_t color, float rad, vec2_t cone, shader_t shader );
|
||||
bool (*AddPolygon)( const poly_t *poly );
|
||||
bool (*AddLightStyle)( int stylenum, vec3_t color );
|
||||
void (*ClearScene)( void );
|
||||
|
|
|
@ -71,5 +71,5 @@ if exist xtools\xtools.plg del /f /q xtools\xtools.plg
|
|||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
xash.exe -dev 3 -log +map test_bigbox
|
||||
xash.exe -dev 3 -log +map qctest
|
||||
:done
|
814
render/r_alias.c
814
render/r_alias.c
|
@ -1,814 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2002-2007 Victor Luchits
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
// r_alias.c: Quake 2 .md2 and Quake III Arena .md3 model formats support
|
||||
|
||||
#include "r_local.h"
|
||||
#include "mathlib.h"
|
||||
#include "quatlib.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
static mesh_t alias_mesh;
|
||||
|
||||
static vec3_t alias_mins;
|
||||
static vec3_t alias_maxs;
|
||||
static float alias_radius;
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_AliasBuildMeshesForFrame0
|
||||
=================
|
||||
*/
|
||||
static void Mod_AliasBuildMeshesForFrame0( ref_model_t *mod )
|
||||
{
|
||||
int i, j, k;
|
||||
size_t size;
|
||||
maliasframe_t *frame;
|
||||
maliasmodel_t *aliasmodel = ( maliasmodel_t * )mod->extradata;
|
||||
|
||||
frame = &aliasmodel->frames[0];
|
||||
for( k = 0; k < aliasmodel->nummeshes; k++ )
|
||||
{
|
||||
maliasmesh_t *mesh = &aliasmodel->meshes[k];
|
||||
|
||||
size = sizeof( vec4_t ) + sizeof( vec4_t ); // xyz and normals
|
||||
if( GL_Support( R_SHADER_GLSL100_EXT ))
|
||||
size += sizeof( vec4_t ); // s-vectors
|
||||
size *= mesh->numverts;
|
||||
|
||||
mesh->xyzArray = ( vec4_t * )Mod_Malloc( mod, size );
|
||||
mesh->normalsArray = ( vec4_t * )( ( byte * )mesh->xyzArray + mesh->numverts * sizeof( vec4_t ) );
|
||||
if( GL_Support( R_SHADER_GLSL100_EXT ))
|
||||
mesh->sVectorsArray = ( vec4_t * )( ( byte * )mesh->normalsArray + mesh->numverts * sizeof( vec4_t ) );
|
||||
|
||||
for( i = 0; i < mesh->numverts; i++ )
|
||||
{
|
||||
for( j = 0; j < 3; j++ )
|
||||
mesh->xyzArray[i][j] = frame->translate[j] + frame->scale[j] * mesh->vertexes[i].point[j];
|
||||
mesh->xyzArray[i][3] = 1;
|
||||
R_LatLongToNorm( mesh->vertexes[i].latlong, mesh->normalsArray[i] );
|
||||
mesh->normalsArray[i][3] = 0;
|
||||
}
|
||||
|
||||
if( GL_Support( R_SHADER_GLSL100_EXT ))
|
||||
R_BuildTangentVectors( mesh->numverts, mesh->xyzArray, mesh->normalsArray, mesh->stArray, mesh->numtris, mesh->elems, mesh->sVectorsArray );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
MD3 MODELS
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_AliasLoadModel
|
||||
=================
|
||||
*/
|
||||
void Mod_AliasLoadModel( ref_model_t *mod, const void *buffer )
|
||||
{
|
||||
int version, i, j, l;
|
||||
int bufsize, numverts;
|
||||
byte *buf;
|
||||
dmd3header_t *pinmodel;
|
||||
dmd3frame_t *pinframe;
|
||||
dmd3tag_t *pintag;
|
||||
dmd3mesh_t *pinmesh;
|
||||
dmd3skin_t *pinskin;
|
||||
dmd3coord_t *pincoord;
|
||||
dmd3vertex_t *pinvert;
|
||||
elem_t *pinelem, *poutelem;
|
||||
maliasvertex_t *poutvert;
|
||||
vec2_t *poutcoord;
|
||||
maliasskin_t *poutskin;
|
||||
maliasmesh_t *poutmesh;
|
||||
maliastag_t *pouttag;
|
||||
maliasframe_t *poutframe;
|
||||
maliasmodel_t *poutmodel;
|
||||
vec3_t ebbox = { 0, 0, 0 };
|
||||
|
||||
pinmodel = ( dmd3header_t * )buffer;
|
||||
version = LittleLong( pinmodel->version );
|
||||
|
||||
if( version != MD3_ALIAS_VERSION )
|
||||
Host_Error( "%s has wrong version number (%i should be %i)\n",
|
||||
mod->name, version, MD3_ALIAS_VERSION );
|
||||
|
||||
mod->type = mod_alias;
|
||||
mod->extradata = poutmodel = Mod_Malloc( mod, sizeof( maliasmodel_t ) );
|
||||
mod->radius = 0;
|
||||
ClearBounds( mod->mins, mod->maxs );
|
||||
|
||||
// byte swap the header fields and sanity check
|
||||
poutmodel->numframes = LittleLong( pinmodel->num_frames );
|
||||
poutmodel->numtags = LittleLong( pinmodel->num_tags );
|
||||
poutmodel->nummeshes = LittleLong( pinmodel->num_meshes );
|
||||
poutmodel->numskins = 0;
|
||||
|
||||
if( poutmodel->numframes <= 0 )
|
||||
Host_Error( "model %s has no frames\n", mod->name );
|
||||
// else if( poutmodel->numframes > MD3_MAX_FRAMES )
|
||||
// Host_Error( "model %s has too many frames\n", mod->name );
|
||||
|
||||
if( poutmodel->numtags > MD3_MAX_TAGS )
|
||||
Host_Error( "model %s has too many tags\n", mod->name );
|
||||
else if( poutmodel->numtags < 0 )
|
||||
Host_Error( "model %s has invalid number of tags\n", mod->name );
|
||||
|
||||
if( poutmodel->nummeshes < 0 )
|
||||
Host_Error( "model %s has invalid number of meshes\n", mod->name );
|
||||
else if( !poutmodel->nummeshes && !poutmodel->numtags )
|
||||
Host_Error( "model %s has no meshes and no tags\n", mod->name );
|
||||
// else if( poutmodel->nummeshes > MD3_MAX_MESHES )
|
||||
// Host_Error( "model %s has too many meshes\n", mod->name );
|
||||
|
||||
bufsize = poutmodel->numframes * ( sizeof( maliasframe_t ) + sizeof( maliastag_t ) * poutmodel->numtags ) +
|
||||
poutmodel->nummeshes * sizeof( maliasmesh_t );
|
||||
buf = Mod_Malloc( mod, bufsize );
|
||||
|
||||
//
|
||||
// load the frames
|
||||
//
|
||||
pinframe = ( dmd3frame_t * )( ( byte * )pinmodel + LittleLong( pinmodel->ofs_frames ) );
|
||||
poutframe = poutmodel->frames = ( maliasframe_t * )buf; buf += sizeof( maliasframe_t ) * poutmodel->numframes;
|
||||
for( i = 0; i < poutmodel->numframes; i++, pinframe++, poutframe++ )
|
||||
{
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
poutframe->scale[j] = MD3_XYZ_SCALE;
|
||||
poutframe->translate[j] = LittleFloat( pinframe->translate[j] );
|
||||
}
|
||||
|
||||
// never trust the modeler utility and recalculate bbox and radius
|
||||
ClearBounds( poutframe->mins, poutframe->maxs );
|
||||
}
|
||||
|
||||
//
|
||||
// load the tags
|
||||
//
|
||||
pintag = ( dmd3tag_t * )( ( byte * )pinmodel + LittleLong( pinmodel->ofs_tags ) );
|
||||
pouttag = poutmodel->tags = ( maliastag_t * )buf; buf += sizeof( maliastag_t ) * poutmodel->numframes * poutmodel->numtags;
|
||||
for( i = 0; i < poutmodel->numframes; i++ )
|
||||
{
|
||||
for( l = 0; l < poutmodel->numtags; l++, pintag++, pouttag++ )
|
||||
{
|
||||
vec3_t axis[3];
|
||||
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
axis[0][j] = LittleFloat( pintag->axis[0][j] );
|
||||
axis[1][j] = LittleFloat( pintag->axis[1][j] );
|
||||
axis[2][j] = LittleFloat( pintag->axis[2][j] );
|
||||
pouttag->origin[j] = LittleFloat( pintag->origin[j] );
|
||||
}
|
||||
|
||||
Quat_FromAxis( axis, pouttag->quat );
|
||||
Quat_Normalize( pouttag->quat );
|
||||
|
||||
com.strncpy( pouttag->name, pintag->name, MD3_MAX_PATH );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// load the meshes
|
||||
//
|
||||
pinmesh = ( dmd3mesh_t * )( ( byte * )pinmodel + LittleLong( pinmodel->ofs_meshes ) );
|
||||
poutmesh = poutmodel->meshes = ( maliasmesh_t * )buf;
|
||||
for( i = 0; i < poutmodel->nummeshes; i++, poutmesh++ )
|
||||
{
|
||||
if( pinmesh->id != ALIASMODHEADER )
|
||||
Host_Error( "mesh %s in model %s has wrong id (%s should be %s)\n",
|
||||
pinmesh->name, mod->name, pinmesh->id, ALIASMODHEADER );
|
||||
|
||||
com.strncpy( poutmesh->name, pinmesh->name, MD3_MAX_PATH );
|
||||
|
||||
Mod_StripLODSuffix( poutmesh->name );
|
||||
|
||||
poutmesh->numtris = LittleLong( pinmesh->num_tris );
|
||||
poutmesh->numskins = LittleLong( pinmesh->num_skins );
|
||||
poutmesh->numverts = numverts = LittleLong( pinmesh->num_verts );
|
||||
|
||||
/* if( poutmesh->numskins <= 0 )
|
||||
Host_Error( ERR_DROP, "mesh %i in model %s has no skins", i, mod->name );
|
||||
else*/ if( poutmesh->numskins > MD3_MAX_SHADERS )
|
||||
Host_Error( "mesh %i in model %s has too many skins\n", i, mod->name );
|
||||
if( poutmesh->numtris <= 0 )
|
||||
Host_Error( "mesh %i in model %s has no elements\n", i, mod->name );
|
||||
else if( poutmesh->numtris > MD3_MAX_TRIANGLES )
|
||||
Host_Error( "mesh %i in model %s has too many triangles\n", i, mod->name );
|
||||
if( poutmesh->numverts <= 0 )
|
||||
Host_Error( "mesh %i in model %s has no vertices\n", i, mod->name );
|
||||
else if( poutmesh->numverts > MD3_MAX_VERTS )
|
||||
Host_Error( "mesh %i in model %s has too many vertices\n", i, mod->name );
|
||||
|
||||
bufsize = sizeof( maliasskin_t ) * poutmesh->numskins + poutmesh->numtris * sizeof( elem_t ) * 3 +
|
||||
numverts * ( sizeof( vec2_t ) + sizeof( maliasvertex_t ) * poutmodel->numframes );
|
||||
buf = Mod_Malloc( mod, bufsize );
|
||||
|
||||
//
|
||||
// load the skins
|
||||
//
|
||||
pinskin = ( dmd3skin_t * )( ( byte * )pinmesh + LittleLong( pinmesh->ofs_skins ) );
|
||||
poutskin = poutmesh->skins = ( maliasskin_t * )buf; buf += sizeof( maliasskin_t ) * poutmesh->numskins;
|
||||
for( j = 0; j < poutmesh->numskins; j++, pinskin++, poutskin++ )
|
||||
{
|
||||
FS_StripExtension( pinskin->name );
|
||||
poutskin->shader = R_LoadShader( pinskin->name, SHADER_ALIAS_MD3, false, 0, SHADER_INVALID );
|
||||
R_DeformvBBoxForShader( poutskin->shader, ebbox );
|
||||
}
|
||||
|
||||
//
|
||||
// load the elems
|
||||
//
|
||||
pinelem = ( elem_t * )( ( byte * )pinmesh + LittleLong( pinmesh->ofs_elems ) );
|
||||
poutelem = poutmesh->elems = ( elem_t * )buf; buf += poutmesh->numtris * sizeof( elem_t ) * 3;
|
||||
for( j = 0; j < poutmesh->numtris; j++, pinelem += 3, poutelem += 3 )
|
||||
{
|
||||
poutelem[0] = (elem_t)LittleLong( pinelem[0] );
|
||||
poutelem[1] = (elem_t)LittleLong( pinelem[1] );
|
||||
poutelem[2] = (elem_t)LittleLong( pinelem[2] );
|
||||
}
|
||||
|
||||
//
|
||||
// load the texture coordinates
|
||||
//
|
||||
pincoord = ( dmd3coord_t * )( ( byte * )pinmesh + LittleLong( pinmesh->ofs_tcs ) );
|
||||
poutcoord = poutmesh->stArray = ( vec2_t * )buf; buf += poutmesh->numverts * sizeof( vec2_t );
|
||||
for( j = 0; j < poutmesh->numverts; j++, pincoord++ )
|
||||
{
|
||||
poutcoord[j][0] = LittleFloat( pincoord->st[0] );
|
||||
poutcoord[j][1] = LittleFloat( pincoord->st[1] );
|
||||
}
|
||||
|
||||
//
|
||||
// load the vertexes and normals
|
||||
//
|
||||
pinvert = ( dmd3vertex_t * )( ( byte * )pinmesh + LittleLong( pinmesh->ofs_verts ) );
|
||||
poutvert = poutmesh->vertexes = ( maliasvertex_t * )buf;
|
||||
for( l = 0, poutframe = poutmodel->frames; l < poutmodel->numframes; l++, poutframe++, pinvert += poutmesh->numverts, poutvert += poutmesh->numverts )
|
||||
{
|
||||
vec3_t v;
|
||||
|
||||
for( j = 0; j < poutmesh->numverts; j++ )
|
||||
{
|
||||
poutvert[j].point[0] = LittleShort( pinvert[j].point[0] );
|
||||
poutvert[j].point[1] = LittleShort( pinvert[j].point[1] );
|
||||
poutvert[j].point[2] = LittleShort( pinvert[j].point[2] );
|
||||
|
||||
poutvert[j].latlong[0] = pinvert[j].norm[0];
|
||||
poutvert[j].latlong[1] = pinvert[j].norm[1];
|
||||
|
||||
VectorCopy( poutvert[j].point, v );
|
||||
AddPointToBounds( v, poutframe->mins, poutframe->maxs );
|
||||
}
|
||||
}
|
||||
|
||||
pinmesh = ( dmd3mesh_t * )( ( byte * )pinmesh + LittleLong( pinmesh->meshsize ) );
|
||||
}
|
||||
|
||||
//
|
||||
// build S and T vectors for frame 0
|
||||
//
|
||||
Mod_AliasBuildMeshesForFrame0( mod );
|
||||
|
||||
//
|
||||
// calculate model bounds
|
||||
//
|
||||
poutframe = poutmodel->frames;
|
||||
for( i = 0; i < poutmodel->numframes; i++, poutframe++ )
|
||||
{
|
||||
VectorMA( poutframe->translate, MD3_XYZ_SCALE, poutframe->mins, poutframe->mins );
|
||||
VectorMA( poutframe->translate, MD3_XYZ_SCALE, poutframe->maxs, poutframe->maxs );
|
||||
VectorSubtract( poutframe->mins, ebbox, poutframe->mins );
|
||||
VectorAdd( poutframe->maxs, ebbox, poutframe->maxs );
|
||||
poutframe->radius = RadiusFromBounds( poutframe->mins, poutframe->maxs );
|
||||
|
||||
AddPointToBounds( poutframe->mins, mod->mins, mod->maxs );
|
||||
AddPointToBounds( poutframe->maxs, mod->mins, mod->maxs );
|
||||
mod->radius = max( mod->radius, poutframe->radius );
|
||||
}
|
||||
mod->touchFrame = tr.registration_sequence; // register model
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_AliasModelLOD
|
||||
=============
|
||||
*/
|
||||
static ref_model_t *R_AliasModelLOD( ref_entity_t *e )
|
||||
{
|
||||
int lod;
|
||||
float dist;
|
||||
|
||||
if( !e->model->numlods ) return e->model;
|
||||
|
||||
dist = DistanceFast( e->origin, RI.viewOrigin );
|
||||
dist *= RI.lod_dist_scale_for_fov;
|
||||
|
||||
lod = (int)( dist / e->model->radius );
|
||||
if( r_lodscale->integer )
|
||||
lod /= r_lodscale->integer;
|
||||
lod += r_lodbias->integer;
|
||||
|
||||
if( lod < 1 ) return e->model;
|
||||
return e->model->lods[min( lod, e->model->numlods )-1];
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_AliasModelLerpBBox
|
||||
=============
|
||||
*/
|
||||
static void R_AliasModelLerpBBox( ref_entity_t *e, ref_model_t *mod )
|
||||
{
|
||||
int i;
|
||||
maliasmodel_t *aliasmodel = ( maliasmodel_t * )mod->extradata;
|
||||
maliasframe_t *pframe, *poldframe;
|
||||
float *thismins, *oldmins, *thismaxs, *oldmaxs;
|
||||
|
||||
if( !aliasmodel->nummeshes )
|
||||
{
|
||||
alias_radius = 0;
|
||||
ClearBounds( alias_mins, alias_maxs );
|
||||
return;
|
||||
}
|
||||
|
||||
if( ( e->frame >= aliasmodel->numframes ) || ( e->frame < 0 ) )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_DrawAliasModel %s: no such frame %g\n", mod->name, e->frame );
|
||||
e->frame = 0;
|
||||
}
|
||||
if( ( e->prev.frame >= aliasmodel->numframes ) || ( e->prev.frame < 0 ) )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_DrawAliasModel %s: no such oldframe %g\n", mod->name, e->prev.frame );
|
||||
e->prev.frame = 0;
|
||||
}
|
||||
|
||||
pframe = aliasmodel->frames + (int)e->frame;
|
||||
poldframe = aliasmodel->frames + (int)e->prev.frame;
|
||||
|
||||
// compute axially aligned mins and maxs
|
||||
if( pframe == poldframe )
|
||||
{
|
||||
VectorCopy( pframe->mins, alias_mins );
|
||||
VectorCopy( pframe->maxs, alias_maxs );
|
||||
alias_radius = pframe->radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
thismins = pframe->mins;
|
||||
thismaxs = pframe->maxs;
|
||||
|
||||
oldmins = poldframe->mins;
|
||||
oldmaxs = poldframe->maxs;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
alias_mins[i] = min( thismins[i], oldmins[i] );
|
||||
alias_maxs[i] = max( thismaxs[i], oldmaxs[i] );
|
||||
}
|
||||
alias_radius = RadiusFromBounds( thismins, thismaxs );
|
||||
}
|
||||
|
||||
if( e->scale != 1.0f )
|
||||
{
|
||||
VectorScale( alias_mins, e->scale, alias_mins );
|
||||
VectorScale( alias_maxs, e->scale, alias_maxs );
|
||||
alias_radius *= e->scale;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_AliasModelLerpTag
|
||||
=============
|
||||
*/
|
||||
bool R_AliasModelLerpTag( orientation_t *orient, maliasmodel_t *aliasmodel, int oldframenum, int framenum, float lerpfrac, const char *name )
|
||||
{
|
||||
int i;
|
||||
quat_t quat;
|
||||
maliastag_t *tag, *oldtag;
|
||||
|
||||
// find the appropriate tag
|
||||
for( i = 0; i < aliasmodel->numtags; i++ )
|
||||
{
|
||||
if( !com.stricmp( aliasmodel->tags[i].name, name ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == aliasmodel->numtags )
|
||||
{
|
||||
// MsgDev ("R_AliasModelLerpTag: no such tag %s\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// ignore invalid frames
|
||||
if( ( framenum >= aliasmodel->numframes ) || ( framenum < 0 ) )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_AliasModelLerpTag %s: no such oldframe %i\n", name, framenum );
|
||||
framenum = 0;
|
||||
}
|
||||
if( ( oldframenum >= aliasmodel->numframes ) || ( oldframenum < 0 ) )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_AliasModelLerpTag %s: no such oldframe %i\n", name, oldframenum );
|
||||
oldframenum = 0;
|
||||
}
|
||||
|
||||
tag = aliasmodel->tags + framenum * aliasmodel->numtags + i;
|
||||
oldtag = aliasmodel->tags + oldframenum * aliasmodel->numtags + i;
|
||||
|
||||
// interpolate axis and origin
|
||||
Quat_Lerp( oldtag->quat, tag->quat, lerpfrac, quat );
|
||||
Quat_Matrix( quat, orient->axis );
|
||||
|
||||
orient->origin[0] = oldtag->origin[0] + ( tag->origin[0] - oldtag->origin[0] ) * lerpfrac;
|
||||
orient->origin[1] = oldtag->origin[1] + ( tag->origin[1] - oldtag->origin[1] ) * lerpfrac;
|
||||
orient->origin[2] = oldtag->origin[2] + ( tag->origin[2] - oldtag->origin[2] ) * lerpfrac;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_DrawAliasFrameLerp
|
||||
|
||||
Interpolates between two frames and origins
|
||||
=============
|
||||
*/
|
||||
static void R_DrawAliasFrameLerp( const meshbuffer_t *mb, float backlerp )
|
||||
{
|
||||
int i, meshnum;
|
||||
int features;
|
||||
float backv[3], frontv[3];
|
||||
vec3_t normal, oldnormal;
|
||||
bool unlockVerts, calcVerts, calcNormals, calcSTVectors;
|
||||
vec3_t move;
|
||||
maliasframe_t *frame, *oldframe;
|
||||
maliasmesh_t *mesh;
|
||||
maliasvertex_t *v, *ov;
|
||||
ref_entity_t *e = RI.currententity;
|
||||
ref_model_t *mod = Mod_ForHandle( mb->modhandle );
|
||||
maliasmodel_t *model = ( maliasmodel_t * )mod->extradata;
|
||||
ref_shader_t *shader;
|
||||
static maliasmesh_t *alias_prevmesh;
|
||||
static ref_shader_t *alias_prevshader;
|
||||
static int alias_framecount, alias_riparams;
|
||||
|
||||
if( alias_riparams != RI.params || RI.params & RP_SHADOWMAPVIEW )
|
||||
{
|
||||
alias_riparams = RI.params; // do not try to lock arrays between RI updates
|
||||
alias_framecount = !r_framecount;
|
||||
}
|
||||
|
||||
meshnum = -mb->infokey - 1;
|
||||
if( meshnum < 0 || meshnum >= model->nummeshes )
|
||||
return;
|
||||
mesh = model->meshes + meshnum;
|
||||
|
||||
frame = model->frames + (int)e->frame;
|
||||
oldframe = model->frames + (int)e->prev.frame;
|
||||
for( i = 0; i < 3; i++ )
|
||||
move[i] = frame->translate[i] + ( oldframe->translate[i] - frame->translate[i] ) * backlerp;
|
||||
|
||||
MB_NUM2SHADER( mb->shaderkey, shader );
|
||||
|
||||
features = MF_NONBATCHED | shader->features;
|
||||
if( RI.params & RP_SHADOWMAPVIEW )
|
||||
{
|
||||
features &= ~( MF_COLORS|MF_SVECTORS|MF_ENABLENORMALS );
|
||||
if( !( shader->features & MF_DEFORMVS ) )
|
||||
features &= ~MF_NORMALS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( features & MF_SVECTORS ) || r_shownormals->integer )
|
||||
features |= MF_NORMALS;
|
||||
if( e->outlineHeight )
|
||||
features |= MF_NORMALS|(GL_Support( R_SHADER_GLSL100_EXT ) ? MF_ENABLENORMALS : 0);
|
||||
}
|
||||
|
||||
calcNormals = calcSTVectors = false;
|
||||
calcNormals = (( features & MF_NORMALS ) != 0 ) && (( e->frame != 0 ) || ( e->prev.frame != 0 ));
|
||||
|
||||
if( alias_framecount == r_framecount && RI.previousentity && RI.previousentity->model == e->model && alias_prevmesh == mesh && alias_prevshader == shader )
|
||||
{
|
||||
ref_entity_t *pe = RI.previousentity;
|
||||
if( pe->frame == e->frame && pe->prev.frame == e->prev.frame && ( pe->backlerp == e->backlerp || e->frame == e->prev.frame ))
|
||||
{
|
||||
unlockVerts = ((( features & MF_DEFORMVS )));
|
||||
calcNormals = ( calcNormals && ( shader->features & SHADER_DEFORM_NORMAL ));
|
||||
}
|
||||
}
|
||||
|
||||
unlockVerts = true;
|
||||
calcSTVectors = ( ( features & MF_SVECTORS ) != 0 ) && calcNormals;
|
||||
|
||||
alias_prevmesh = mesh;
|
||||
alias_prevshader = shader;
|
||||
alias_framecount = r_framecount;
|
||||
|
||||
if( unlockVerts )
|
||||
{
|
||||
if( !e->frame && !e->prev.frame )
|
||||
{
|
||||
calcVerts = false;
|
||||
|
||||
if( calcNormals )
|
||||
{
|
||||
v = mesh->vertexes;
|
||||
for( i = 0; i < mesh->numverts; i++, v++ )
|
||||
R_LatLongToNorm( v->latlong, inNormalsArray[i] );
|
||||
}
|
||||
}
|
||||
else if( e->frame == e->prev.frame )
|
||||
{
|
||||
calcVerts = true;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
frontv[i] = frame->scale[i];
|
||||
|
||||
v = mesh->vertexes + (int)e->frame * mesh->numverts;
|
||||
for( i = 0; i < mesh->numverts; i++, v++ )
|
||||
{
|
||||
Vector4Set( inVertsArray[i],
|
||||
move[0] + v->point[0]*frontv[0],
|
||||
move[1] + v->point[1]*frontv[1],
|
||||
move[2] + v->point[2]*frontv[2], 1 );
|
||||
|
||||
if( calcNormals )
|
||||
R_LatLongToNorm( v->latlong, inNormalsArray[i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
calcVerts = true;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
backv[i] = backlerp * oldframe->scale[i];
|
||||
frontv[i] = ( 1.0f - backlerp ) * frame->scale[i];
|
||||
}
|
||||
|
||||
v = mesh->vertexes + (int)e->frame * mesh->numverts;
|
||||
ov = mesh->vertexes + (int)e->prev.frame * mesh->numverts;
|
||||
for( i = 0; i < mesh->numverts; i++, v++, ov++ )
|
||||
{
|
||||
Vector4Set( inVertsArray[i],
|
||||
move[0] + v->point[0]*frontv[0] + ov->point[0]*backv[0],
|
||||
move[1] + v->point[1]*frontv[1] + ov->point[1]*backv[1],
|
||||
move[2] + v->point[2]*frontv[2] + ov->point[2]*backv[2], 1 );
|
||||
|
||||
if( calcNormals )
|
||||
{
|
||||
R_LatLongToNorm( v->latlong, normal );
|
||||
R_LatLongToNorm( ov->latlong, oldnormal );
|
||||
|
||||
VectorSet( inNormalsArray[i],
|
||||
normal[0] + ( oldnormal[0] - normal[0] ) * backlerp,
|
||||
normal[1] + ( oldnormal[1] - normal[1] ) * backlerp,
|
||||
normal[2] + ( oldnormal[2] - normal[2] ) * backlerp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( calcSTVectors )
|
||||
R_BuildTangentVectors( mesh->numverts, inVertsArray, inNormalsArray, mesh->stArray, mesh->numtris, mesh->elems, inSVectorsArray );
|
||||
|
||||
alias_mesh.xyzArray = calcVerts ? inVertsArray : mesh->xyzArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
features |= MF_KEEPLOCK;
|
||||
}
|
||||
|
||||
alias_mesh.elems = mesh->elems;
|
||||
alias_mesh.numElems = mesh->numtris * 3;
|
||||
alias_mesh.numVertexes = mesh->numverts;
|
||||
|
||||
alias_mesh.stArray = mesh->stArray;
|
||||
if( features & MF_NORMALS )
|
||||
alias_mesh.normalsArray = calcNormals ? inNormalsArray : mesh->normalsArray;
|
||||
if( features & MF_SVECTORS )
|
||||
alias_mesh.sVectorsArray = calcSTVectors ? inSVectorsArray : mesh->sVectorsArray;
|
||||
|
||||
R_RotateForEntity( e );
|
||||
|
||||
R_PushMesh( &alias_mesh, features );
|
||||
R_RenderMeshBuffer( mb );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawAliasModel
|
||||
=================
|
||||
*/
|
||||
void R_DrawAliasModel( const meshbuffer_t *mb )
|
||||
{
|
||||
ref_entity_t *e = RI.currententity;
|
||||
|
||||
if( OCCLUSION_QUERIES_ENABLED( RI ) && OCCLUSION_TEST_ENTITY( e ) )
|
||||
{
|
||||
ref_shader_t *shader;
|
||||
|
||||
MB_NUM2SHADER( mb->shaderkey, shader );
|
||||
if( !R_GetOcclusionQueryResultBool( shader->type == SHADER_PLANAR_SHADOW ? OQ_PLANARSHADOW : OQ_ENTITY,
|
||||
e - r_entities, true ) )
|
||||
return;
|
||||
}
|
||||
|
||||
// hack the depth range to prevent view model from poking into walls
|
||||
if( e->ent_type == ED_VIEWMODEL )
|
||||
{
|
||||
pglDepthRange( gldepthmin, gldepthmin + 0.3 * ( gldepthmax - gldepthmin ) );
|
||||
|
||||
// backface culling for left-handed weapons
|
||||
if( r_lefthand->integer == 1 )
|
||||
GL_FrontFace( !glState.frontFace );
|
||||
}
|
||||
|
||||
if( !r_lerpmodels->integer )
|
||||
e->backlerp = 0;
|
||||
|
||||
R_DrawAliasFrameLerp( mb, e->backlerp );
|
||||
|
||||
if( e->ent_type == ED_VIEWMODEL )
|
||||
{
|
||||
pglDepthRange( gldepthmin, gldepthmax );
|
||||
|
||||
// backface culling for left-handed weapons
|
||||
if( r_lefthand->integer == 1 )
|
||||
GL_FrontFace( !glState.frontFace );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_AliasModelBBox
|
||||
=================
|
||||
*/
|
||||
float R_AliasModelBBox( ref_entity_t *e, vec3_t mins, vec3_t maxs )
|
||||
{
|
||||
ref_model_t *mod;
|
||||
|
||||
mod = R_AliasModelLOD( e );
|
||||
if( !mod )
|
||||
return 0;
|
||||
|
||||
R_AliasModelLerpBBox( e, mod );
|
||||
|
||||
VectorCopy( alias_mins, mins );
|
||||
VectorCopy( alias_maxs, maxs );
|
||||
return alias_radius;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CullAliasModel
|
||||
=================
|
||||
*/
|
||||
bool R_CullAliasModel( ref_entity_t *e )
|
||||
{
|
||||
int i, j, clipped;
|
||||
bool frustum, query;
|
||||
unsigned int modhandle, numtris;
|
||||
ref_model_t *mod;
|
||||
ref_shader_t *shader;
|
||||
meshbuffer_t *mb;
|
||||
maliasmodel_t *aliasmodel;
|
||||
maliasmesh_t *mesh;
|
||||
|
||||
mod = R_AliasModelLOD( e );
|
||||
if( !( aliasmodel = ( ( maliasmodel_t * )mod->extradata ) ) || !aliasmodel->nummeshes )
|
||||
return true;
|
||||
|
||||
R_AliasModelLerpBBox( e, mod );
|
||||
modhandle = Mod_Handle( mod );
|
||||
|
||||
clipped = R_CullModel( e, alias_mins, alias_maxs, alias_radius );
|
||||
frustum = clipped & 1;
|
||||
if( clipped & 2 )
|
||||
return true;
|
||||
|
||||
query = OCCLUSION_QUERIES_ENABLED( RI ) && OCCLUSION_TEST_ENTITY( e ) ? true : false;
|
||||
if( !frustum && query )
|
||||
R_IssueOcclusionQuery( R_GetOcclusionQueryNum( OQ_ENTITY, e - r_entities ), e, alias_mins, alias_maxs );
|
||||
|
||||
if( ( RI.refdef.rdflags & RDF_NOWORLDMODEL )
|
||||
|| ( r_shadows->integer != SHADOW_PLANAR && !( r_shadows->integer == SHADOW_MAPPING && ( e->flags & EF_PLANARSHADOW )))
|
||||
|| R_CullPlanarShadow( e, alias_mins, alias_maxs, query ) )
|
||||
return frustum; // entity is not in PVS or shadow is culled away by frustum culling
|
||||
|
||||
numtris = 0;
|
||||
for( i = 0, mesh = aliasmodel->meshes; i < aliasmodel->nummeshes; i++, mesh++ )
|
||||
{
|
||||
shader = NULL;
|
||||
|
||||
if( e->skinfile )
|
||||
shader = R_FindShaderForSkinFile( e->skinfile, mesh->name );
|
||||
else if( mesh->numskins )
|
||||
{
|
||||
for( j = 0; j < mesh->numskins; j++ )
|
||||
{
|
||||
shader = mesh->skins[j].shader;
|
||||
if( shader && shader->sort <= SORT_ALPHATEST )
|
||||
break;
|
||||
shader = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if( shader && ( shader->sort <= SORT_ALPHATEST ))
|
||||
{
|
||||
mb = R_AddMeshToList( MB_MODEL, NULL, R_PlanarShadowShader(), -( i+1 ));
|
||||
if( mb ) mb->modhandle = modhandle;
|
||||
}
|
||||
}
|
||||
|
||||
return frustum;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_AddAliasModelToList
|
||||
=================
|
||||
*/
|
||||
void R_AddAliasModelToList( ref_entity_t *e )
|
||||
{
|
||||
int i, j;
|
||||
unsigned int modhandle, entnum = e - r_entities;
|
||||
mfog_t *fog = NULL;
|
||||
ref_model_t *mod;
|
||||
ref_shader_t *shader;
|
||||
maliasmodel_t *aliasmodel;
|
||||
maliasmesh_t *mesh;
|
||||
|
||||
mod = R_AliasModelLOD( e );
|
||||
aliasmodel = ( maliasmodel_t * )mod->extradata;
|
||||
modhandle = Mod_Handle( mod );
|
||||
|
||||
if( RI.params & RP_SHADOWMAPVIEW )
|
||||
{
|
||||
if( r_entShadowBits[entnum] & RI.shadowGroup->bit )
|
||||
{
|
||||
if( !r_shadows_self_shadow->integer )
|
||||
r_entShadowBits[entnum] &= ~RI.shadowGroup->bit;
|
||||
if( e->ent_type == ED_VIEWMODEL )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
R_AliasModelLerpBBox( e, mod );
|
||||
if( !R_CullModel( e, alias_mins, alias_maxs, alias_radius ) )
|
||||
r_entShadowBits[entnum] |= RI.shadowGroup->bit;
|
||||
return; // mark as shadowed, proceed with caster otherwise
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fog = R_FogForSphere( e->origin, alias_radius );
|
||||
#if 0
|
||||
if( !( e->ent_type == ED_VIEWMODEL ) && fog )
|
||||
{
|
||||
R_AliasModelLerpBBox( e, mod );
|
||||
if( R_CompletelyFogged( fog, e->origin, alias_radius ))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for( i = 0, mesh = aliasmodel->meshes; i < aliasmodel->nummeshes; i++, mesh++ )
|
||||
{
|
||||
shader = NULL;
|
||||
|
||||
if( e->skinfile ) shader = R_FindShaderForSkinFile( e->skinfile, mesh->name );
|
||||
else if( mesh->numskins )
|
||||
{
|
||||
for( j = 0; j < mesh->numskins; j++ )
|
||||
{
|
||||
shader = mesh->skins[j].shader;
|
||||
if( shader ) R_AddModelMeshToList( modhandle, fog, shader, i );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( shader ) R_AddModelMeshToList( modhandle, fog, shader, i );
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "r_local.h"
|
||||
#include "mathlib.h"
|
||||
#include "quatlib.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
static mesh_t alias_mesh;
|
||||
|
@ -406,12 +405,10 @@ void Mod_QAliasLoadModel( ref_model_t *mod, const void *buffer )
|
|||
pheader->size = LittleFloat( pinmodel->size ) * (1.0f / 11.0f);
|
||||
pheader->synctype = LittleLong( pinmodel->synctype );
|
||||
|
||||
poutmodel->numtags = 0;
|
||||
poutmodel->tags = NULL;
|
||||
poutmodel->nummeshes = 1;
|
||||
|
||||
poutmesh = poutmodel->meshes = Mod_Malloc( mod, sizeof( maliasmesh_t ));
|
||||
com.strncpy( poutmesh->name, "default", MD3_MAX_PATH );
|
||||
com.strncpy( poutmesh->name, "default", MAX_SHADERPATH );
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
|
|
|
@ -1539,10 +1539,13 @@ void R_ModifyColor( const ref_stage_t *pass )
|
|||
temp = R_TableEvaluate( *rgbgenfunc, temp ) * rgbgenfunc->args[1] + rgbgenfunc->args[0];
|
||||
}
|
||||
|
||||
temp = temp * rgbgenfunc->args[1] + rgbgenfunc->args[0];
|
||||
a = pass->rgbGen.args[0] * temp; rgba[0] = a <= 0 ? 0 : R_FloatToByte( a );
|
||||
a = pass->rgbGen.args[1] * temp; rgba[1] = a <= 0 ? 0 : R_FloatToByte( a );
|
||||
a = pass->rgbGen.args[2] * temp; rgba[2] = a <= 0 ? 0 : R_FloatToByte( a );
|
||||
temp = bound( 0.0f, temp, 1.0f );
|
||||
a = bound( 0.0f, pass->rgbGen.args[0] * temp, 1.0f );
|
||||
rgba[0] = R_FloatToByte( a );
|
||||
a = bound( 0.0f, pass->rgbGen.args[1] * temp, 1.0f );
|
||||
rgba[1] = R_FloatToByte( a );
|
||||
a = bound( 0.0f, pass->rgbGen.args[2] * temp, 1.0f );
|
||||
rgba[2] = R_FloatToByte( a );
|
||||
|
||||
for( i = 0, c = *(int *)rgba; i < r_backacc.numColors; i++, bArray += 4 )
|
||||
*(int *)bArray = c;
|
||||
|
|
|
@ -103,6 +103,8 @@ typedef struct
|
|||
texture_t *blackTexture;
|
||||
texture_t *blankbumpTexture;
|
||||
texture_t *dlightTexture;
|
||||
texture_t *dspotlightTexture;
|
||||
texture_t *normalizeTexture; // cubemap
|
||||
texture_t *fogTexture;
|
||||
texture_t *skyTexture;
|
||||
texture_t *coronaTexture;
|
||||
|
|
140
render/r_image.c
140
render/r_image.c
|
@ -3277,8 +3277,8 @@ R_InitDynamicLightTexture
|
|||
static rgbdata_t *R_InitDynamicLightTexture( int *flags, int *samples )
|
||||
{
|
||||
vec3_t v = { 0, 0, 0 };
|
||||
int x, y, z, size, size2, halfsize;
|
||||
float intensity;
|
||||
int x, y, z, d, size;
|
||||
|
||||
// dynamic light texture
|
||||
if( GL_Support( R_TEXTURE_3D_EXT ))
|
||||
|
@ -3287,7 +3287,7 @@ static rgbdata_t *R_InitDynamicLightTexture( int *flags, int *samples )
|
|||
}
|
||||
else
|
||||
{
|
||||
size = 64;
|
||||
size = 128;
|
||||
r_image.depth = 1;
|
||||
}
|
||||
|
||||
|
@ -3298,30 +3298,136 @@ static rgbdata_t *R_InitDynamicLightTexture( int *flags, int *samples )
|
|||
r_image.type = PF_RGBA_GN;
|
||||
r_image.size = r_image.width * r_image.height * r_image.depth * 4;
|
||||
|
||||
halfsize = size / 2;
|
||||
intensity = halfsize * halfsize;
|
||||
size2 = size * size;
|
||||
|
||||
*flags = TF_NOPICMIP|TF_NOMIPMAP|TF_CLAMP|TF_UNCOMPRESSED;
|
||||
*samples = 3;
|
||||
|
||||
for( x = 0; x < r_image.width; x++ )
|
||||
{
|
||||
for( y = 0; y < r_image.height; y++ )
|
||||
if( GL_Support( R_TEXTURE_3D_EXT ))
|
||||
{
|
||||
for( x = 0; x < r_image.width; x++ )
|
||||
{
|
||||
for( z = 0; z < r_image.depth; z++ )
|
||||
for( y = 0; y < r_image.height; y++ )
|
||||
{
|
||||
v[0] = (( x + 0.5f ) * ( 2.0f / (float)size ) - 1.0f );
|
||||
v[1] = (( y + 0.5f ) * ( 2.0f / (float)size ) - 1.0f );
|
||||
if( r_image.depth > 1 ) v[2] = (( z + 0.5f ) * ( 2.0f / (float)size ) - 1.0f );
|
||||
for( z = 0; z < r_image.depth; z++ )
|
||||
{
|
||||
float dist, att;
|
||||
|
||||
intensity = 1.0f - com.sqrt( DotProduct( v, v ) );
|
||||
if( intensity > 0 ) intensity = intensity * intensity * 215.5f;
|
||||
d = bound( 0, intensity, 255 );
|
||||
v[0] = (float)x - halfsize;
|
||||
v[1] = (float)y - halfsize;
|
||||
v[2] = (float)z - halfsize;
|
||||
|
||||
data2D[((z * size + y) * size + x) * 4 + 0] = d;
|
||||
data2D[((z * size + y) * size + x) * 4 + 1] = d;
|
||||
data2D[((z * size + y) * size + x) * 4 + 2] = d;
|
||||
dist = VectorLength( v );
|
||||
if( dist > halfsize ) dist = halfsize;
|
||||
|
||||
if( x == 0 || y == 0 || z == 0 || x == size - 1 || y == size - 1 || z == size - 1 )
|
||||
att = 0;
|
||||
else att = (((dist * dist) / intensity) -1 ) * -255;
|
||||
|
||||
data2D[(x * size2 + y * size + z) * 4 + 0] = (byte)(att);
|
||||
data2D[(x * size2 + y * size + z) * 4 + 1] = (byte)(att);
|
||||
data2D[(x * size2 + y * size + z) * 4 + 2] = (byte)(att);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( x = 0; x < size; x++ )
|
||||
{
|
||||
for( y = 0; y < size; y++ )
|
||||
{
|
||||
float result;
|
||||
|
||||
if( x == size - 1 || x == 0 || y == size - 1 || y == 0 )
|
||||
result = 255;
|
||||
else
|
||||
{
|
||||
float xf = ((float)x - 64 ) / 64.0f;
|
||||
float yf = ((float)y - 64 ) / 64.0f;
|
||||
result = ((xf * xf) + (yf * yf)) * 255;
|
||||
if( result > 255 ) result = 255;
|
||||
}
|
||||
data2D[(x*size+y)*4+0] = (byte)255 - result;
|
||||
data2D[(x*size+y)*4+1] = (byte)255 - result;
|
||||
data2D[(x*size+y)*4+2] = (byte)255 - result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return &r_image;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitSpotLightTexture
|
||||
==================
|
||||
*/
|
||||
static rgbdata_t *R_InitSpotLightTexture( int *flags, int *samples )
|
||||
{
|
||||
*flags = TF_NOPICMIP|TF_NOMIPMAP|TF_CLAMP|TF_UNCOMPRESSED;
|
||||
*samples = 0;
|
||||
|
||||
return FS_LoadImage( "textures/effects/flashlight.tga", NULL, 0 ); // UNDONE: test only
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitNormalizeCubemap
|
||||
==================
|
||||
*/
|
||||
static rgbdata_t *R_InitNormalizeCubemap( int *flags, int *samples )
|
||||
{
|
||||
int i, x, y, size = 32;
|
||||
byte *dataCM = data2D;
|
||||
float s, t;
|
||||
vec3_t normal;
|
||||
|
||||
if( !GL_Support( R_TEXTURECUBEMAP_EXT ))
|
||||
return NULL;
|
||||
|
||||
// normal cube map texture
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
for( y = 0; y < size; y++ )
|
||||
{
|
||||
for( x = 0; x < size; x++ )
|
||||
{
|
||||
s = (((float)x + 0.5f) * (2.0f / size )) - 1.0f;
|
||||
t = (((float)y + 0.5f) * (2.0f / size )) - 1.0f;
|
||||
|
||||
switch( i )
|
||||
{
|
||||
case 0: VectorSet( normal, 1.0f, -t, -s ); break;
|
||||
case 1: VectorSet( normal, -1.0f, -t, s ); break;
|
||||
case 2: VectorSet( normal, s, 1.0f, t ); break;
|
||||
case 3: VectorSet( normal, s, -1.0f, -t ); break;
|
||||
case 4: VectorSet( normal, s, -t, 1.0f ); break;
|
||||
case 5: VectorSet( normal, -s, -t, -1.0f); break;
|
||||
}
|
||||
|
||||
VectorNormalize( normal );
|
||||
|
||||
dataCM[4*(y*size+x)+0] = (byte)(128 + 127 * normal[0]);
|
||||
dataCM[4*(y*size+x)+1] = (byte)(128 + 127 * normal[1]);
|
||||
dataCM[4*(y*size+x)+2] = (byte)(128 + 127 * normal[2]);
|
||||
dataCM[4*(y*size+x)+3] = 255;
|
||||
}
|
||||
}
|
||||
dataCM += (size*size*4); // move pointer
|
||||
}
|
||||
|
||||
*flags = (TF_STATIC|TF_NOPICMIP|TF_NOMIPMAP|TF_UNCOMPRESSED|TF_CUBEMAP|TF_CLAMP);
|
||||
*samples = 3;
|
||||
|
||||
r_image.width = r_image.height = size;
|
||||
r_image.numMips = r_image.depth = 1;
|
||||
r_image.size = r_image.width * r_image.height * 4 * 6;
|
||||
r_image.flags |= (IMAGE_CUBEMAP|IMAGE_HAS_COLOR); // yes it's cubemap
|
||||
r_image.buffer = data2D;
|
||||
r_image.type = PF_RGBA_GN;
|
||||
|
||||
return &r_image;
|
||||
}
|
||||
|
||||
|
@ -3550,7 +3656,7 @@ static void R_InitScreenTexture( texture_t **ptr, const char *name, int id, int
|
|||
|
||||
r_screen.width = width;
|
||||
r_screen.height = height;
|
||||
r_screen.type = PF_LUMINANCE;
|
||||
r_screen.type = (samples == 1) ? PF_LUMINANCE : PF_RGB_24;
|
||||
r_screen.buffer = data;
|
||||
r_screen.depth = r_screen.numMips = 1;
|
||||
r_screen.size = width * height * samples;
|
||||
|
@ -3636,6 +3742,8 @@ static void R_InitBuiltinTextures( void )
|
|||
{ "*black", &tr.blackTexture, R_InitBlackTexture },
|
||||
{ "*blankbump", &tr.blankbumpTexture, R_InitBlankBumpTexture },
|
||||
{ "*dlight", &tr.dlightTexture, R_InitDynamicLightTexture },
|
||||
{ "*dspotlight", &tr.dspotlightTexture, R_InitSpotLightTexture },
|
||||
{ "*normalize", &tr.normalizeTexture, R_InitNormalizeCubemap },
|
||||
{ "*particle", &tr.particleTexture, R_InitParticleTexture },
|
||||
{ "*corona", &tr.coronaTexture, R_InitCoronaTexture },
|
||||
{ "*cintexture", &tr.cinTexture, R_InitCinematicTexture },
|
||||
|
|
|
@ -68,11 +68,11 @@ void R_LightBounds( const vec3_t origin, float intensity, vec3_t mins, vec3_t ma
|
|||
R_AddSurfDlighbits
|
||||
=============
|
||||
*/
|
||||
uint R_AddSurfDlighbits( msurface_t *surf, unsigned int dlightbits )
|
||||
uint R_AddSurfDlighbits( msurface_t *surf, uint dlightbits )
|
||||
{
|
||||
unsigned int k, bit;
|
||||
dlight_t *lt;
|
||||
float dist;
|
||||
uint k, bit;
|
||||
dlight_t *lt;
|
||||
float dist;
|
||||
|
||||
for( k = 0, bit = 1, lt = r_dlights; k < r_numDlights; k++, bit <<= 1, lt++ )
|
||||
{
|
||||
|
@ -86,7 +86,7 @@ uint R_AddSurfDlighbits( msurface_t *surf, unsigned int dlightbits )
|
|||
}
|
||||
else if( surf->facetype == MST_PATCH || surf->facetype == MST_TRISURF )
|
||||
{
|
||||
if( !BoundsIntersect( surf->mins, surf->maxs, lt->mins, lt->maxs ) )
|
||||
if( !BoundsIntersect( surf->mins, surf->maxs, lt->mins, lt->maxs ))
|
||||
dlightbits &= ~bit;
|
||||
}
|
||||
}
|
||||
|
@ -496,10 +496,10 @@ void R_LightForEntity( ref_entity_t *e, byte *bArray )
|
|||
if( e->flags & EF_MINLIGHT )
|
||||
{
|
||||
for( i = 0; i < 3; i++ )
|
||||
if( ambient[i] > 0.1 )
|
||||
if( ambient[i] > 0.01 )
|
||||
break;
|
||||
if( i == 3 )
|
||||
VectorSet( ambient, 0.1f, 0.1f, 0.1f );
|
||||
VectorSet( ambient, 0.01f, 0.01f, 0.01f );
|
||||
}
|
||||
|
||||
// rotate direction
|
||||
|
|
|
@ -178,6 +178,7 @@ typedef struct
|
|||
vec3_t origin;
|
||||
vec3_t color;
|
||||
vec3_t mins, maxs;
|
||||
vec2_t cone; // spotlight cone
|
||||
float intensity;
|
||||
const ref_shader_t *shader;
|
||||
} dlight_t;
|
||||
|
|
|
@ -2340,7 +2340,8 @@ bool R_AddEntityToScene( edict_t *pRefEntity, int ed_type, float lerpfrac )
|
|||
r_numEntities++;
|
||||
|
||||
// never adding child entity without parent
|
||||
if( result && pRefEntity->v.weaponmodel && (refent->renderfx != kRenderFxDeadPlayer))
|
||||
// only studio models can have attached childrens
|
||||
if( result && refent->model->type == mod_studio && pRefEntity->v.weaponmodel && (refent->renderfx != kRenderFxDeadPlayer))
|
||||
{
|
||||
edict_t FollowEntity = *pRefEntity;
|
||||
|
||||
|
@ -2357,7 +2358,7 @@ bool R_AddEntityToScene( edict_t *pRefEntity, int ed_type, float lerpfrac )
|
|||
return result;
|
||||
}
|
||||
|
||||
bool R_AddDynamicLight( vec3_t org, vec3_t color, float intensity, shader_t handle )
|
||||
bool R_AddDynamicLight( vec3_t org, vec3_t color, float intensity, vec2_t cone, shader_t handle )
|
||||
{
|
||||
dlight_t *dl;
|
||||
ref_shader_t *shader;
|
||||
|
@ -2370,6 +2371,7 @@ bool R_AddDynamicLight( vec3_t org, vec3_t color, float intensity, shader_t hand
|
|||
|
||||
VectorCopy( org, dl->origin );
|
||||
VectorCopy( color, dl->color );
|
||||
if( cone ) Vector2Copy( cone, dl->cone );
|
||||
dl->intensity = intensity * DLIGHT_SCALE;
|
||||
dl->shader = shader;
|
||||
|
||||
|
|
|
@ -279,9 +279,6 @@ typedef struct
|
|||
int numframes;
|
||||
maliasframe_t *frames;
|
||||
|
||||
int numtags;
|
||||
maliastag_t *tags;
|
||||
|
||||
int nummeshes;
|
||||
maliasmesh_t *meshes;
|
||||
|
||||
|
|
|
@ -1779,8 +1779,7 @@ static bool Shaderpass_Distortion( ref_shader_t *shader, ref_stage_t *pass, scri
|
|||
if( bumpScale )
|
||||
pass->textures[1] = Shader_FindImage( shader, va( "heightMap( \"%s\", %g );", tok.string, bumpScale ), flags );
|
||||
else pass->textures[1] = Shader_FindImage( shader, tok.string, flags );
|
||||
if( pass->textures[1] == tr.defaultTexture )
|
||||
MsgDev( D_WARN, "missing normalmap image '%s' in shader '%s'\n", tok.string, shader->name );
|
||||
if( pass->textures[1] == tr.defaultTexture ) pass->textures[1] = NULL;
|
||||
pass->num_textures++;
|
||||
}
|
||||
}
|
||||
|
@ -2983,7 +2982,7 @@ static void Shader_SetFeatures( ref_shader_t *s )
|
|||
|
||||
for( i = 0, pass = s->stages; i < s->num_stages; i++, pass++ )
|
||||
{
|
||||
if( pass->program && ( pass->program_type == PROGRAM_TYPE_MATERIAL || pass->program_type == PROGRAM_TYPE_DISTORTION ) )
|
||||
if( pass->program && ( pass->program_type == PROGRAM_TYPE_MATERIAL || pass->program_type == PROGRAM_TYPE_DISTORTION ))
|
||||
s->features |= MF_NORMALS|MF_SVECTORS|MF_LMCOORDS|MF_ENABLENORMALS;
|
||||
|
||||
if( pass->flags & SHADERSTAGE_RENDERMODE )
|
||||
|
|
|
@ -244,11 +244,11 @@ void R_AddBrushModelToList( ref_entity_t *e )
|
|||
}
|
||||
|
||||
dlightbits = 0;
|
||||
if( ( r_dynamiclight->integer == 1 ) && !r_fullbright->integer && !( RI.params & RP_SHADOWMAPVIEW ) )
|
||||
if(( r_dynamiclight->integer == 1 ) && !r_fullbright->integer && !( RI.params & RP_SHADOWMAPVIEW ))
|
||||
{
|
||||
for( i = 0; i < r_numDlights; i++ )
|
||||
{
|
||||
if( BoundsIntersect( modelmins, modelmaxs, r_dlights[i].mins, r_dlights[i].maxs ) )
|
||||
if( BoundsIntersect( modelmins, modelmaxs, r_dlights[i].mins, r_dlights[i].maxs ))
|
||||
dlightbits |= ( 1<<i );
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ WORLD MODEL
|
|||
R_MarkLeafSurfaces
|
||||
================
|
||||
*/
|
||||
static void R_MarkLeafSurfaces( msurface_t **mark, unsigned int clipflags, unsigned int dlightbits )
|
||||
static void R_MarkLeafSurfaces( msurface_t **mark, uint clipflags, uint dlightbits )
|
||||
{
|
||||
unsigned int newDlightbits;
|
||||
msurface_t *surf;
|
||||
|
@ -335,7 +335,7 @@ static void R_MarkLeafSurfaces( msurface_t **mark, unsigned int clipflags, unsig
|
|||
R_RecursiveWorldNode
|
||||
================
|
||||
*/
|
||||
static void R_RecursiveWorldNode( mnode_t *node, unsigned int clipflags, unsigned int dlightbits )
|
||||
static void R_RecursiveWorldNode( mnode_t *node, uint clipflags, uint dlightbits )
|
||||
{
|
||||
uint i, newDlightbits;
|
||||
const cplane_t *clipplane;
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: render - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP43E0.tmp" with contents
|
||||
[
|
||||
/nologo /ML /W3 /GX /O2 /Ob2 /I "../public" /I "../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fo"..\temp\render\!release/" /Fd"..\temp\render\!release/" /FD /c
|
||||
"D:\Xash3D\src_main\render\r_model.c"
|
||||
]
|
||||
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP43E0.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP43E1.tmp" with contents
|
||||
[
|
||||
msvcrt.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /out:"..\temp\render\!release/render.dll" /implib:"..\temp\render\!release/render.lib" /libpath:"../public/libs/"
|
||||
"\Xash3D\src_main\temp\render\!release\cin.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_aliasq.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_backend.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_bloom.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_cin.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_cull.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_draw.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_image.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_light.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_main.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_math.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_mesh.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_model.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_opengl.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_poly.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_program.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_register.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_shader.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_shadow.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_sky.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_sprite.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_studio.obj"
|
||||
"\Xash3D\src_main\temp\render\!release\r_surf.obj"
|
||||
]
|
||||
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP43E1.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP43E2.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
copy \Xash3D\src_main\temp\render\!release\render.dll "D:\Xash3D\bin\render.dll"
|
||||
]
|
||||
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP43E2.bat"
|
||||
Compiling...
|
||||
r_model.c
|
||||
Linking...
|
||||
Creating library ..\temp\render\!release/render.lib and object ..\temp\render\!release/render.exp
|
||||
<h3>Output Window</h3>
|
||||
Performing Custom Build Step on \Xash3D\src_main\temp\render\!release\render.dll
|
||||
‘ª®¯¨à®¢ ® ä ©«®¢: 1.
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
render.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
2
todo.log
2
todo.log
|
@ -137,4 +137,4 @@ Beta 13.12.09
|
|||
113. fixup debug tools OK
|
||||
114. fixup shadowmaps OK
|
||||
115. fixup CullStudioModel OK
|
||||
116. create flashlight for player
|
||||
116. create flashlight for player OK
|
||||
|
|
|
@ -280,16 +280,13 @@ void CreateEntityLights( void )
|
|||
/* set default flags */
|
||||
flags = LIGHT_WOLF_DEFAULT;
|
||||
|
||||
/* inverse distance squared attenuation? */
|
||||
if( spawnflags & 1 )
|
||||
{
|
||||
flags &= ~LIGHT_ATTEN_LINEAR;
|
||||
flags |= LIGHT_ATTEN_ANGLE;
|
||||
}
|
||||
|
||||
// spawnflag 1 is reserved for START_OFF
|
||||
/* angle attenuate? */
|
||||
if( spawnflags & 2 )
|
||||
{
|
||||
flags |= LIGHT_ATTEN_ANGLE;
|
||||
flags &= ~LIGHT_ATTEN_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
/* other flags (borrowed from wolf) */
|
||||
|
|
Reference in New Issue