17 Dec 2010

This commit is contained in:
g-cont 2010-12-17 00:00:00 +03:00 committed by Alibek Omarov
parent b02f68c575
commit a45e9a9393
28 changed files with 1177 additions and 153 deletions

View File

@ -260,7 +260,7 @@ usercmd_t CL_CreateCmd( void )
{
usercmd_t cmd;
static double extramsec = 0;
vec3_t color;
color24 color;
int ms;
// send milliseconds of time to apply the move
@ -292,8 +292,8 @@ usercmd_t CL_CreateCmd( void )
clgame.dllFuncs.CL_CreateMove( cl.time - cl.oldtime, &cmd, ( cls.state == ca_active && !cl.refdef.paused ));
R_LightForPoint( cl.frame.local.client.origin, color );
cmd.lightlevel = VectorAvg( color ) * 255;
R_LightForPoint( cl.frame.local.client.origin, &color, false );
cmd.lightlevel = (color.r + color.g + color.b) / 3;
// random seed for predictable random values
cl.random_seed = Com_RandomLong( 0, 0x7fffffff ); // full range

View File

@ -1456,7 +1456,7 @@ void CL_Projectile( const vec3_t origin, const vec3_t velocity, int modelIndex,
pTemp = CL_TempEntAlloc( origin, CM_ClipHandleToModel( modelIndex ));
if( !pTemp ) return;
pfnVecToAngles( velocity, pTemp->entity.angles );
VectorAngles( velocity, pTemp->entity.angles );
VectorCopy( velocity, pTemp->entity.baseline.origin );
pTemp->entity.curstate.body = 0;

View File

@ -153,7 +153,8 @@ typedef struct
matrix4x4 projectionMatrix;
matrix4x4 worldviewProjectionMatrix; // worldviewMatrix * projectionMatrix
int lightstylevalue[MAX_LIGHTSTYLES];
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
float lightstylecolor[MAX_LIGHTSTYLES]; // color 0 - 1.0
mplane_t clipPlane;
} ref_instance_t;
@ -179,6 +180,12 @@ typedef struct
uint num_static_entities;
uint num_solid_entities;
uint num_trans_entities;
uint numColors; // vertex array num colors
uint numVertex; // vertex array num vertex
rgb_t colorsArray[4096]; // MAXSTUDIOVERTS
vec3_t normalArray[4096];
vec3_t vertexArray[4096];
// OpenGL matrix states
qboolean modelviewIdentity;
@ -195,6 +202,8 @@ typedef struct
uint c_studio_polys;
uint c_sprite_polys;
uint c_world_leafs;
uint c_studio_models;
} ref_speeds_t;
extern ref_speeds_t r_stats;
@ -242,7 +251,7 @@ gltexture_t *R_GetTexture( GLenum texnum );
void GL_SetTextureType( GLenum texnum, GLenum type );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags );
int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int outWidth, int outHeight, qboolean isNormalMap );
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
void GL_FreeTexture( GLenum texnum );
void GL_FreeImage( const char *name );
void R_TextureList_f( void );
@ -260,6 +269,8 @@ void R_StoreEfrags( efrag_t **ppefrag );
void R_PushDlights( void );
void R_AnimateLight( void );
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLight );
void R_LightForOrigin( const vec3_t origin, vec3_t dir, color24 *ambient, color24 *diffuse, float radius );
//
// gl_rmain.c
@ -274,8 +285,13 @@ void R_RotateForEntity( cl_entity_t *e );
//
// gl_rmath.c
//
void R_InitMathlib( void );
void R_LatLongToNorm( const byte latlong[2], vec3_t normal );
void R_NormToLatLong( const vec3_t normal, byte latlong[2] );
float V_CalcFov( float *fov_x, float width, float height );
void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x );
byte R_FloatToByte( float x );
//
// gl_rsurf.c
@ -296,6 +312,12 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer );
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw );
void R_DrawSpriteModel( cl_entity_t *e );
//
// gl_studio.c
//
void R_StudioInit( void );
void R_DrawStudioModel( cl_entity_t *e );
//
// gl_warp.c
//
@ -477,6 +499,8 @@ extern convar_t *r_speeds;
extern convar_t *r_fullbright;
extern convar_t *r_norefresh;
extern convar_t *r_lighting_modulate;
extern convar_t *r_lighting_ambient;
extern convar_t *r_lighting_direct;
extern convar_t *r_faceplanecull;
extern convar_t *r_drawentities;
extern convar_t *r_adjust_fov;

View File

@ -5,7 +5,9 @@
#include "common.h"
#include "client.h"
#include "matrix_lib.h"
#include "gl_local.h"
#include "studio.h"
/*
=============================================================================
@ -23,7 +25,7 @@ R_AnimateLight
void R_AnimateLight( void )
{
int i, k, flight, clight;
float l, lerpfrac, backlerp;
float l, c, lerpfrac, backlerp;
lightstyle_t *ls;
// light animations
@ -38,6 +40,7 @@ void R_AnimateLight( void )
if( r_fullbright->integer || !cl.worldmodel->lightdata )
{
RI.lightstylevalue[i] = 256 * 256;
RI.lightstylecolor[i] = 1.0f;
continue;
}
@ -45,17 +48,20 @@ void R_AnimateLight( void )
{
// was 256, changed to 264 for consistency
RI.lightstylevalue[i] = 256 * r_lighting_modulate->value;
RI.lightstylecolor[i] = 1.0f * r_lighting_ambient->value;
continue;
}
else if( ls->length == 1 )
{
// single length style so don't bother interpolating
RI.lightstylevalue[i] = ls->map[0] * 22 * r_lighting_modulate->value;
RI.lightstylecolor[i] = (ls->map[0] / 12.0f ) * r_lighting_ambient->value;
continue;
}
else if( !ls->interp || !cl_lightstyle_lerping->integer )
{
RI.lightstylevalue[i] = ls->map[flight%ls->length] * 22 * r_lighting_modulate->value;
RI.lightstylecolor[i] = (ls->map[flight%ls->length] / 12.0f) * r_lighting_ambient->value;
continue;
}
@ -63,12 +69,15 @@ void R_AnimateLight( void )
// frame just gone
k = ls->map[flight % ls->length];
l = (float)( k * 22 ) * backlerp;
c = (float)( k / 12 ) * backlerp;
// upcoming frame
k = ls->map[clight % ls->length];
l += (float)( k * 22 ) * lerpfrac;
c += (float)( k / 12 ) * lerpfrac;
RI.lightstylevalue[i] = (int)l * r_lighting_modulate->value;
RI.lightstylecolor[i] = c * r_lighting_ambient->value;
}
}
@ -138,7 +147,576 @@ void R_PushDlights( void )
R_MarkLights( l, 1<<i, cl.worldmodel->nodes );
}
}
void R_LightForPoint( const vec3_t point, vec3_t ambientLight )
//===================================================================
/*
=================
R_ReadLightGrid
=================
*/
static void R_ReadLightGrid( const vec3_t origin, vec3_t lightDir )
{
vec3_t vf1, vf2, tdir;
int vi[3], elem[4];
float scale[8];
int i, k, s;
if( !world.lightgrid )
{
// pre-defined light vector
lightDir[0] = RI.refdef.movevars->skyvec_x;
lightDir[1] = RI.refdef.movevars->skyvec_y;
lightDir[2] = RI.refdef.movevars->skyvec_z;
return;
}
for( i = 0; i < 3; i++ )
{
vf1[i] = (origin[i] - world.gridMins[i]) / world.gridSize[i];
vi[i] = (int)vf1[i];
vf1[i] = vf1[i] - floor( vf1[i] );
vf2[i] = 1.0f - vf1[i];
}
elem[0] = vi[2] * world.gridBounds[3] + vi[1] * world.gridBounds[0] + vi[0];
elem[1] = elem[0] + world.gridBounds[0];
elem[2] = elem[0] + world.gridBounds[3];
elem[3] = elem[2] + world.gridBounds[0];
for( i = 0; i < 4; i++ )
{
if( elem[i] < 0 || elem[i] >= world.numgridpoints - 1 )
{
// pre-defined light vector
lightDir[0] = RI.refdef.movevars->skyvec_x;
lightDir[1] = RI.refdef.movevars->skyvec_y;
lightDir[2] = RI.refdef.movevars->skyvec_z;
return;
}
}
scale[0] = vf2[0] * vf2[1] * vf2[2];
scale[1] = vf1[0] * vf2[1] * vf2[2];
scale[2] = vf2[0] * vf1[1] * vf2[2];
scale[3] = vf1[0] * vf1[1] * vf2[2];
scale[4] = vf2[0] * vf2[1] * vf1[2];
scale[5] = vf1[0] * vf2[1] * vf1[2];
scale[6] = vf2[0] * vf1[1] * vf1[2];
scale[7] = vf1[0] * vf1[1] * vf1[2];
VectorClear( lightDir );
for( i = 0; i < 4; i++ )
{
R_LatLongToNorm( world.lightgrid[elem[i]+0].direction, tdir );
VectorScale( tdir, scale[i*2+0], tdir );
for( k = 0; k < LM_STYLES && ( s = world.lightgrid[elem[i]+0].styles[k] ) != 255; k++ )
{
lightDir[0] += RI.lightstylecolor[s] * tdir[0];
lightDir[1] += RI.lightstylecolor[s] * tdir[1];
lightDir[2] += RI.lightstylecolor[s] * tdir[2];
}
R_LatLongToNorm( world.lightgrid[elem[i]+1].direction, tdir );
VectorScale( tdir, scale[i*2+1], tdir );
for( k = 0; k < LM_STYLES && ( s = world.lightgrid[elem[i]+1].styles[k] ) != 255; k++ )
{
lightDir[0] += RI.lightstylecolor[s] * tdir[0];
lightDir[1] += RI.lightstylecolor[s] * tdir[1];
lightDir[2] += RI.lightstylecolor[s] * tdir[2];
}
}
}
/*
=======================================================================
AMBIENT & DIFFUSE LIGHTING
=======================================================================
*/
static uint r_pointColor[3];
static vec3_t r_lightColors[MAXSTUDIOVERTS];
/*
=================
R_RecursiveLightPoint
=================
*/
static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, const vec3_t start, const vec3_t end )
{
float front, back, frac;
int i, map, side, size, s, t;
msurface_t *surf;
mtexinfo_t *tex;
color24 *lm;
vec3_t mid;
// didn't hit anything
if( node->contents < 0 )
return false;
// calculate mid point
front = PlaneDiff( start, node->plane );
back = PlaneDiff( end, node->plane );
side = front < 0;
if(( back < 0 ) == side )
return R_RecursiveLightPoint( model, node->children[side], start, end );
frac = front / ( front - back );
VectorLerp( start, frac, end, mid );
// co down front side
if( R_RecursiveLightPoint( model, node->children[side], start, mid ))
return true; // hit something
if(( back < 0 ) == side )
return false;// didn't hit anything
// check for impact on this node
surf = model->surfaces + node->firstsurface;
for( i = 0; i < node->numsurfaces; i++, surf++ )
{
tex = surf->texinfo;
if( surf->flags & SURF_DRAWTILED )
continue; // no lightmaps
s = DotProduct( mid, tex->vecs[0] ) + tex->vecs[0][3] - surf->texturemins[0];
t = DotProduct( mid, tex->vecs[1] ) + tex->vecs[1][3] - surf->texturemins[1];
if(( s < 0 || s > surf->extents[0] ) || ( t < 0 || t > surf->extents[1] ))
continue;
s >>= 4;
t >>= 4;
if( !surf->samples )
return true;
VectorClear( r_pointColor );
lm = surf->samples + (t * ((surf->extents[0] >> 4) + 1) + s);
size = ((surf->extents[0] >> 4) + 1) * ((surf->extents[1] >> 4) + 1);
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
{
uint scale = RI.lightstylevalue[surf->styles[map]];
r_pointColor[0] += lm->r * scale;
r_pointColor[1] += lm->g * scale;
r_pointColor[2] += lm->b * scale;
lm += size; // skip to next lightmap
}
return true;
}
// go down back side
return R_RecursiveLightPoint( model, node->children[!side], mid, end );
}
/*
=================
R_LightForPoint
=================
*/
void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLight )
{
dlight_t *dl;
vec3_t end, dir;
float dist, add;
int lnum;
// set to full bright if no light data
if( !cl.worldmodel || !cl.worldmodel->lightdata )
{
ambientLight->r = 255;
ambientLight->g = 255;
ambientLight->b = 255;
return;
}
// Get lighting at this point
VectorCopy( point, end );
if( invLight ) end[2] = point[2] + 8192;
else end[2] = point[2] - 8192;
VectorSet( r_pointColor, 255, 255, 255 );
R_RecursiveLightPoint( cl.worldmodel, cl.worldmodel->nodes, point, end );
ambientLight->r = min((r_pointColor[0] >> 7), 255 );
ambientLight->g = min((r_pointColor[1] >> 7), 255 );
ambientLight->b = min((r_pointColor[2] >> 7), 255 );
// add dynamic lights
if( r_dynamic->integer )
{
for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ )
{
if( dl->die < cl.time || !dl->radius )
continue;
VectorSubtract( dl->origin, point, dir );
dist = VectorLength( dir );
if( !dist || dist > dl->radius )
continue;
add = (dl->radius - dist);
ambientLight->r = ambientLight->r + (dl->color.r * add);
ambientLight->g = ambientLight->g + (dl->color.g * add);
ambientLight->b = ambientLight->b + (dl->color.b * add);
}
}
}
/*
=================
R_LightDir
=================
*/
void R_LightDir( const vec3_t origin, vec3_t lightDir, float radius )
{
dlight_t *dl;
vec3_t dir;
float dist;
int lnum;
// get light direction from light grid
R_ReadLightGrid( origin, lightDir );
// add dynamic lights
if( radius > 0.0f && r_dynamic->integer )
{
for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ )
{
if( dl->die < cl.time || !dl->radius )
continue;
VectorSubtract( dl->origin, origin, dir );
dist = VectorLength( dir );
if( !dist || dist > dl->radius + radius )
continue;
VectorAdd( lightDir, dir, lightDir );
}
}
// FIXME: should we normalize final direction ?
// VectorNormalize( lightDir );
}
/*
===============
R_LightForOrigin
extended version of LightForPoint
===============
*/
void R_LightForOrigin( const vec3_t origin, vec3_t dir, color24 *ambient, color24 *diffuse, float radius )
{
int i, j, k, s;
float dot, t[8];
vec3_t vf, vf2, tdir;
int vi[3], elem[4];
vec3_t ambientLocal, diffuseLocal;
float *gridSize, *gridMins;
int *gridBounds;
mgridlight_t *lightgrid;
if( !cl.worldmodel || !world.lightgrid || !world.numgridpoints )
{
// get fullbright
VectorSet( ambientLocal, 255, 255, 255 );
VectorSet( diffuseLocal, 255, 255, 255 );
dir[0] = RI.refdef.movevars->skyvec_x;
dir[1] = RI.refdef.movevars->skyvec_y;
dir[2] = RI.refdef.movevars->skyvec_z;
goto dynamic;
}
else
{
VectorClear( ambientLocal );
VectorClear( diffuseLocal );
}
lightgrid = world.lightgrid;
gridSize = world.gridSize;
gridMins = world.gridMins;
gridBounds = world.gridBounds;
for( i = 0; i < 3; i++ )
{
vf[i] = ( origin[i] - gridMins[i] ) / gridSize[i];
vi[i] = (int)vf[i];
vf[i] = vf[i] - floor( vf[i] );
vf2[i] = 1.0f - vf[i];
}
elem[0] = vi[2] * gridBounds[3] + vi[1] * gridBounds[0] + vi[0];
elem[1] = elem[0] + gridBounds[0];
elem[2] = elem[0] + gridBounds[3];
elem[3] = elem[2] + gridBounds[0];
for( i = 0; i < 4; i++ )
{
if( elem[i] < 0 || elem[i] >= ( world.numgridpoints - 1 ))
{
dir[0] = RI.refdef.movevars->skyvec_x;
dir[1] = RI.refdef.movevars->skyvec_y;
dir[2] = RI.refdef.movevars->skyvec_z;
goto dynamic;
}
}
t[0] = vf2[0] * vf2[1] * vf2[2];
t[1] = vf[0] * vf2[1] * vf2[2];
t[2] = vf2[0] * vf[1] * vf2[2];
t[3] = vf[0] * vf[1] * vf2[2];
t[4] = vf2[0] * vf2[1] * vf[2];
t[5] = vf[0] * vf2[1] * vf[2];
t[6] = vf2[0] * vf[1] * vf[2];
t[7] = vf[0] * vf[1] * vf[2];
VectorClear( dir );
for( i = 0; i < 4; i++ )
{
R_LatLongToNorm( lightgrid[elem[i]].direction, tdir );
VectorScale( tdir, t[i*2+0], tdir );
for( k = 0; k < LM_STYLES && ( s = lightgrid[elem[i]].styles[k] ) != 255; k++ )
{
dir[0] += RI.lightstylecolor[s] * tdir[0];
dir[1] += RI.lightstylecolor[s] * tdir[1];
dir[2] += RI.lightstylecolor[s] * tdir[2];
}
R_LatLongToNorm( lightgrid[elem[i] + 1].direction, tdir );
VectorScale( tdir, t[i*2+1], tdir );
for( k = 0; k < LM_STYLES && ( s = lightgrid[elem[i] + 1].styles[k] ) != 255; k++ )
{
dir[0] += RI.lightstylecolor[s] * tdir[0];
dir[1] += RI.lightstylecolor[s] * tdir[1];
dir[2] += RI.lightstylecolor[s] * tdir[2];
}
}
for( j = 0; j < 3; j++ )
{
if( ambient )
{
for( i = 0; i < 4; i++ )
{
for( k = 0; k < LM_STYLES; k++ )
{
if(( s = lightgrid[elem[i]].styles[k] ) != 255 )
ambientLocal[j] += t[i*2+0] * lightgrid[elem[i]+0].ambient[k][j] * RI.lightstylecolor[s];
if(( s = lightgrid[elem[i] + 1].styles[k] ) != 255 )
ambientLocal[j] += t[i*2+1] * lightgrid[elem[i]+1].ambient[k][j] * RI.lightstylecolor[s];
}
}
}
if( diffuse || radius )
{
for( i = 0; i < 4; i++ )
{
for( k = 0; k < LM_STYLES; k++ )
{
if( ( s = lightgrid[elem[i]].styles[k] ) != 255 )
diffuseLocal[j] += t[i*2+0] * lightgrid[elem[i]+0].diffuse[k][j] * RI.lightstylecolor[s];
if( ( s = lightgrid[elem[i] + 1].styles[k] ) != 255 )
diffuseLocal[j] += t[i*2+1] * lightgrid[elem[i]+1].diffuse[k][j] * RI.lightstylecolor[s];
}
}
}
}
dynamic:
// add dynamic lights
if( radius && r_dynamic->integer )
{
uint lnum;
dlight_t *dl;
float dist, dist2, add;
vec3_t direction;
qboolean anyDlights = false;
for( lnum = 0, dl = cl_dlights; lnum < MAX_DLIGHTS; lnum++, dl++ )
{
if( dl->die < cl.time || !dl->radius )
continue;
VectorSubtract( dl->origin, origin, direction );
dist = VectorLength( direction );
if( !dist || dist > dl->radius + radius )
continue;
if( !anyDlights )
{
VectorNormalizeFast( dir );
anyDlights = true;
}
add = 1.0f - (dist / ( dl->radius + radius ));
dist2 = add * 0.5f / dist;
dot = dl->color.r * add;
diffuseLocal[0] += dot;
ambientLocal[0] += dot * 0.05f;
dir[0] += direction[0] * dist2;
dot = dl->color.g * add;
diffuseLocal[1] += dot;
ambientLocal[1] += dot * 0.05f;
dir[1] += direction[1] * dist2;
dot = dl->color.b * add;
diffuseLocal[2] += dot;
ambientLocal[2] += dot * 0.05f;
dir[2] += direction[2] * dist2;
}
}
VectorNormalizeFast( dir );
if( ambient )
{
dot = bound( 0.0f, r_lighting_ambient->value, 1.0f ) * 255.0f;
ambient->r = (byte)bound( 0, ambientLocal[0] * dot, 255 );
ambient->g = (byte)bound( 0, ambientLocal[1] * dot, 255 );
ambient->b = (byte)bound( 0, ambientLocal[2] * dot, 255 );
}
if( diffuse )
{
dot = bound( 0.0f, r_lighting_direct->value, 1.0f ) * 255.0f;
diffuse->r = (byte)bound( 0, diffuseLocal[0] * dot, 255 );
diffuse->g = (byte)bound( 0, diffuseLocal[1] * dot, 255 );
diffuse->b = (byte)bound( 0, diffuseLocal[2] * dot, 255 );
}
}
/*
=================
R_LightForEntity
=================
*/
void R_LightForEntity( cl_entity_t *e, byte *bArray )
{
dlight_t *dl;
vec3_t end, dir;
float scale = 1.0f;
float add, dot, dist, intensity, radius;
vec3_t ambientLight, directedLight, lightDir;
matrix4x4 matrix, imatrix;
vec3_t pointColor;
float *cArray;
int i, l;
if(( e->curstate.effects & EF_FULLBRIGHT ) || r_fullbright->integer )
return;
// never gets diffuse lighting for world brushes or sprites
if( !e->model || ( e->model->type == mod_brush ) || ( e->model->type == mod_sprite ))
return;
// get lighting at this point
if( e->curstate.effects & EF_INVLIGHT )
VectorSet( end, e->origin[0], e->origin[1], e->origin[2] + 8192 );
else VectorSet( end, e->origin[0], e->origin[1], e->origin[2] - 8192 );
VectorSet( r_pointColor, 1.0f, 1.0f, 1.0f );
R_RecursiveLightPoint( cl.worldmodel, cl.worldmodel->nodes, e->origin, end );
pointColor[0] = (float)min((r_pointColor[0] >> 7), 255 ) * (1.0f / 255.0f);
pointColor[1] = (float)min((r_pointColor[1] >> 7), 255 ) * (1.0f / 255.0f);
pointColor[2] = (float)min((r_pointColor[2] >> 7), 255 ) * (1.0f / 255.0f);
VectorScale( pointColor, r_lighting_ambient->value, ambientLight );
VectorScale( pointColor, r_lighting_direct->value, directedLight );
R_ReadLightGrid( e->origin, lightDir );
// always have some light
if( e->curstate.effects & EF_MINLIGHT )
{
for( i = 0; i < 3; i++ )
{
if( ambientLight[i] > 0.01f )
break;
}
if( i == 3 )
{
VectorSet( ambientLight, 0.01f, 0.01f, 0.01f );
}
}
if( e->model->type != mod_brush && e->curstate.scale > 0.0f )
scale = e->curstate.scale;
// compute lighting at each vertex
Matrix4x4_CreateFromEntity( matrix, 0.0f, 0.0f, 0.0f, e->angles[0], e->angles[1], e->angles[2], scale );
Matrix4x4_Invert_Simple( imatrix, matrix );
// rotate direction
Matrix4x4_VectorRotate( imatrix, lightDir, dir );
VectorNormalizeFast( dir );
for( i = 0; i < tr.numColors; i++ )
{
dot = DotProduct( tr.normalArray[i], dir );
if( dot <= 0.0f ) VectorCopy( ambientLight, r_lightColors[i] );
else VectorMA( ambientLight, dot, directedLight, r_lightColors[i] );
}
// add dynamic lights
if( r_dynamic->integer )
{
radius = e->model->radius;
for( l = 0, dl = cl_dlights; l < MAX_DLIGHTS; l++, dl++ )
{
if( dl->die < cl.time || !dl->radius )
continue;
VectorSubtract( dl->origin, e->origin, dir );
dist = VectorLength( dir );
if( !dist || dist > dl->radius + radius )
continue;
Matrix4x4_VectorRotate( imatrix, dir, lightDir );
intensity = dl->radius * 8;
// compute lighting at each vertex
for( i = 0; i < tr.numColors; i++ )
{
VectorSubtract( lightDir, tr.vertexArray[i], dir );
add = DotProduct( tr.normalArray[i], dir );
if( add <= 0.0f ) continue;
dot = DotProduct( dir, dir );
add *= ( intensity / dot ) * rsqrt( dot );
r_lightColors[i][0] = r_lightColors[i][0] + (dl->color.r * add);
r_lightColors[i][1] = r_lightColors[i][1] + (dl->color.g * add);
r_lightColors[i][2] = r_lightColors[i][2] + (dl->color.b * add);
}
}
}
cArray = r_lightColors[0];
for( i = 0; i < tr.numColors; i++, bArray += 4, cArray += 3 )
{
bArray[0] = R_FloatToByte( cArray[0] );
bArray[1] = R_FloatToByte( cArray[1] );
bArray[2] = R_FloatToByte( cArray[2] );
}
}

View File

@ -43,9 +43,6 @@ typically is a func_wall, func_breakable, func_ladder etc
*/
static qboolean R_StaticEntity( cl_entity_t *ent )
{
if( gl_test->integer )
return false;
if( ent->curstate.rendermode != kRenderNormal )
return false;
@ -698,6 +695,9 @@ void R_DrawEntitiesOnList( void )
case mod_brush:
R_DrawBrushModel( RI.currententity );
break;
case mod_studio:
R_DrawStudioModel( RI.currententity );
break;
case mod_sprite:
R_DrawSpriteModel( RI.currententity );
break;
@ -729,6 +729,9 @@ void R_DrawEntitiesOnList( void )
case mod_brush:
R_DrawBrushModel( RI.currententity );
break;
case mod_studio:
R_DrawStudioModel( RI.currententity );
break;
case mod_sprite:
R_DrawSpriteModel( RI.currententity );
break;

View File

@ -7,6 +7,67 @@
#include "gl_local.h"
#include "mathlib.h"
#define FTABLE_SIZE_POW 10
#define NOISE_SIZE 256
#define FTABLE_SIZE ( 1<<FTABLE_SIZE_POW )
#define NOISE_VAL( a ) r_noiseperm[( a ) & ( NOISE_SIZE - 1 )]
#define FTABLE_CLAMP( x ) (((uint)( ( x )*FTABLE_SIZE ) & ( FTABLE_SIZE-1 )))
#define FTABLE_EVALUATE( table, x ) (( table )[FTABLE_CLAMP( x )] )
#define NOISE_INDEX( x, y, z, t ) NOISE_VAL( x + NOISE_VAL( y + NOISE_VAL( z + NOISE_VAL( t ) ) ) )
#define NOISE_LERP( a, b, w ) ( a * ( 1.0f - w ) + b * w )
static float r_sintableByte[256];
static float r_sintable[FTABLE_SIZE];
static float r_triangletable[FTABLE_SIZE];
static float r_squaretable[FTABLE_SIZE];
static float r_sawtoothtable[FTABLE_SIZE];
static float r_inversesawtoothtable[FTABLE_SIZE];
static float r_noisetable[NOISE_SIZE];
static int r_noiseperm[NOISE_SIZE];
static float r_warpsintable[256] =
{
#include "warpsin.h"
};
/*
==============
R_InitMathlib
==============
*/
void R_InitMathlib( void )
{
int i;
float t;
// build lookup tables
for( i = 0; i < FTABLE_SIZE; i++ )
{
t = (float)i / (float)FTABLE_SIZE;
r_sintable[i] = com.sin( t * M_PI2 );
if( t < 0.25f ) r_triangletable[i] = t * 4.0f;
else if( t < 0.75f ) r_triangletable[i] = 2.0f - 4.0f * t;
else r_triangletable[i] = ( t - 0.75f ) * 4.0f - 1.0f;
if( t < 0.5f ) r_squaretable[i] = 1.0f;
else r_squaretable[i] = -1.0f;
r_sawtoothtable[i] = t;
r_inversesawtoothtable[i] = 1.0f - t;
}
for( i = 0; i < 256; i++ )
r_sintableByte[i] = com.sin((float)i / 255.0f * M_PI2 );
// init the noise table
for( i = 0; i < NOISE_SIZE; i++ )
{
r_noisetable[i] = Com_RandomFloat( -1.0f, 1.0f );
r_noiseperm[i] = Com_RandomLong( 0, 255 );
}
}
/*
====================
V_CalcFov
@ -55,4 +116,68 @@ void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolea
*fov_x = V_CalcFov( &y, height, width );
if( *fov_x < x ) *fov_x = x;
else *fov_y = y;
}
/*
=============
R_NormToLatLong
=============
*/
void R_NormToLatLong( const vec3_t normal, byte latlong[2] )
{
// can't do atan2 (normal[1], normal[0])
if( normal[0] == 0 && normal[1] == 0 )
{
if( normal[2] > 0 )
{
latlong[0] = 0; // acos ( 1 )
latlong[1] = 0;
}
else
{
latlong[0] = 128; // acos ( -1 )
latlong[1] = 0;
}
}
else
{
int angle;
angle = (int)(com.acos( normal[2]) * 255.0 / M_PI2 ) & 255;
latlong[0] = angle;
angle = (int)(com.atan2( normal[1], normal[0] ) * 255.0 / M_PI2 ) & 255;
latlong[1] = angle;
}
}
/*
=============
R_LatLongToNorm
=============
*/
void R_LatLongToNorm( const byte latlong[2], vec3_t normal )
{
float sin_a, sin_b, cos_a, cos_b;
cos_a = r_sintableByte[(latlong[0] + 64) & 255];
sin_a = r_sintableByte[latlong[0]];
cos_b = r_sintableByte[(latlong[1] + 64) & 255];
sin_b = r_sintableByte[latlong[1]];
VectorSet( normal, cos_b * sin_a, sin_b * sin_a, cos_a );
}
byte R_FloatToByte( float x )
{
union {
float f;
uint i;
} f2i;
// shift float to have 8bit fraction at base of number
f2i.f = x + 32768.0f;
f2i.i &= 0x7FFFFF;
// then read as integer and kill float bits...
return ( byte )min( f2i.i, 255 );
}

View File

@ -811,9 +811,16 @@ void R_DrawSpriteModel( cl_entity_t *e )
GL_SetState( state );
color.r = e->curstate.rendercolor.r;
color.g = e->curstate.rendercolor.g;
color.b = e->curstate.rendercolor.b;
if( !gl_test->integer && psprite->texFormat == SPR_ALPHTEST )
{
R_LightForPoint( origin, &color, false );
}
else
{
color.r = e->curstate.rendercolor.r;
color.g = e->curstate.rendercolor.g;
color.b = e->curstate.rendercolor.b;
}
if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha )
frame = oldframe = R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );

View File

@ -12,7 +12,32 @@
#include "pm_local.h"
#include "gl_local.h"
convar_t *r_studio_lerping;
static r_studio_interface_t *pStudioDraw;
static float aliasXscale, aliasYscale;
static matrix3x4 g_rotationmatrix;
/*
====================
R_StudioInit
====================
*/
void R_StudioInit( void )
{
float pixelAspect;
r_studio_lerping = Cvar_Get( "r_studio_lerping", "1", CVAR_ARCHIVE, "enables studio animation lerping" );
// recalc software X and Y alias scale (this stuff is used only by HL software renderer but who knews...)
pixelAspect = ((float)scr_height->integer / (float)scr_width->integer);
if( scr_width->integer < 640 )
pixelAspect *= (320.0f / 240.0f);
else pixelAspect *= (640.0f / 480.0f);
aliasXscale = (float)scr_width->integer / RI.refdef.fov_y;
aliasYscale = aliasXscale * pixelAspect;
}
/*
===============
@ -22,9 +47,7 @@ pfnGetCurrentEntity
*/
static cl_entity_t *pfnGetCurrentEntity( void )
{
// FIXME: implement
// this is will be needs is we called StudioDrawModel or StudioDrawPlayer
return NULL;
return RI.currententity;
}
/*
@ -72,7 +95,7 @@ pfnGetEngineTimes
*/
static void pfnGetEngineTimes( int *framecount, double *current, double *old )
{
if( framecount ) *framecount = host.framecount; // this is will not working properly with mirros etc
if( framecount ) *framecount = tr.framecount;
if( current ) *current = cl.time;
if( old ) *old = cl.oldtime;
}
@ -85,10 +108,10 @@ pfnGetViewInfo
*/
static void pfnGetViewInfo( float *origin, float *upv, float *rightv, float *forwardv )
{
if( origin ) VectorCopy( cl.refdef.vieworg, origin );
if( upv ) VectorCopy( cl.refdef.up, upv );
if( rightv ) VectorCopy( cl.refdef.right, rightv );
if( forwardv ) VectorCopy( cl.refdef.forward, forwardv );
if( origin ) VectorCopy( RI.vieworg, origin );
if( forwardv ) VectorCopy( RI.vforward, forwardv );
if( rightv ) VectorCopy( RI.vright, rightv );
if( upv ) VectorCopy( RI.vup, upv );
}
/*
@ -123,13 +146,12 @@ static void pfnGetModelCounters( int **s, int **a )
===============
pfnGetAliasScale
Software scales not used in Xash3D
===============
*/
static void pfnGetAliasScale( float *x, float *y )
{
if( x ) *x = 0.0f;
if( y ) *y = 0.0f;
if( x ) *x = aliasXscale;
if( y ) *y = aliasYscale;
}
/*
@ -176,8 +198,7 @@ pfnStudioGetRotationMatrix
*/
static float ***pfnStudioGetRotationMatrix( void )
{
// FIXME: implement
return NULL;
return (float ***)g_rotationmatrix;
}
/*
@ -443,6 +464,51 @@ static void pfnStudioDrawShadow( void )
MsgDev( D_INFO, "GL_StudioDrawShadow()\n" ); // just a debug
}
/*
===============
R_StudioDrawModel
===============
*/
static int R_StudioDrawModel( int flags )
{
return 0;
}
/*
===============
R_StudioDrawPlayer
===============
*/
static int R_StudioDrawPlayer( int flags, entity_state_t *pplayer )
{
return 0;
}
/*
=================
R_DrawStudioModel
=================
*/
void R_DrawStudioModel( cl_entity_t *e )
{
int flags, result;
ASSERT( pStudioDraw != NULL );
if( e == &clgame.viewent )
flags = STUDIO_EVENTS;
else flags = STUDIO_RENDER|STUDIO_EVENTS;
// select the properly method
if( e->player )
result = pStudioDraw->StudioDrawPlayer( flags, &cl.frame.playerstate[e->index-1] );
else result = pStudioDraw->StudioDrawModel( flags );
if( result ) r_stats.c_studio_models++;
}
void Mod_UnloadStudioModel( model_t *mod )
{
studiohdr_t *pstudio;
@ -514,7 +580,13 @@ static engine_studio_api_t gStudioAPI =
pfnIsHardware,
pfnStudioDrawShadow,
GL_SetRenderMode,
};
static r_studio_interface_t gStudioDraw =
{
STUDIO_INTERFACE_VERSION,
R_StudioDrawModel,
R_StudioDrawPlayer,
};
/*
@ -526,11 +598,19 @@ Initialize client studio
*/
qboolean CL_InitStudioAPI( void )
{
pStudioDraw = &gStudioDraw;
// Xash will be used internal StudioModelRenderer
if( !clgame.dllFuncs.pfnGetStudioModelInterface )
return true;
pStudioDraw = NULL; // clear previous API
if( clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI ))
return true;
return clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI );
// NOTE: we always return true even if game interface was not correct
// because we need Draw our StudioModels
// just restore pointer to builtin function
pStudioDraw = &gStudioDraw;
return true;
}

View File

@ -45,6 +45,8 @@ convar_t *r_speeds;
convar_t *r_fullbright;
convar_t *r_norefresh;
convar_t *r_lighting_modulate;
convar_t *r_lighting_ambient;
convar_t *r_lighting_direct;
convar_t *r_faceplanecull;
convar_t *r_drawentities;
convar_t *r_adjust_fov;
@ -1363,6 +1365,8 @@ void GL_InitCommands( void )
r_fullbright = Cvar_Get( "r_fullbright", "0", CVAR_CHEAT, "disable lightmaps, get fullbright for entities" );
r_norefresh = Cvar_Get( "r_norefresh", "0", 0, "disable 3D rendering (use with caution)" );
r_lighting_modulate = Cvar_Get( "r_lighting_modulate", "0.6", CVAR_ARCHIVE, "lightstyles modulate scale" );
r_lighting_ambient = Cvar_Get( "r_lighting_ambient", "0.6", 0, "map ambient lighting scale" );
r_lighting_direct = Cvar_Get( "r_lighting_direct", "1", 0, "map directed lighting scale" );
r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", CVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
r_novis = Cvar_Get( "r_novis", "0", 0, "ignore vis information (perfomance test)" );
r_nocull = Cvar_Get( "r_nocull", "0", 0, "ignore frustrum culling (perfomance test)" );
@ -1598,8 +1602,10 @@ qboolean R_Init( void )
GL_InitExtensions();
GL_SetDefaults();
R_InitMathlib();
R_InitImages();
R_SpriteInit();
R_StudioInit();
R_ClearScene();
GL_CheckForErrors();

View File

@ -35,6 +35,14 @@ typedef struct leaflist_s
int topnode; // for overflows where each leaf can't be stored individually
} leaflist_t;
typedef struct
{
byte ambient[LM_STYLES][3];
byte diffuse[LM_STYLES][3];
byte styles[LM_STYLES];
byte direction[2];
} mgridlight_t;
typedef struct
{
int version; // map version
@ -44,6 +52,14 @@ typedef struct
msurface_t **draw_surfaces; // used for sorting translucent surfaces
int max_surfaces; // max surfaces per submodel (for all models)
qboolean loading; // true is worldmodel is loading
// lightgrid stuff
mgridlight_t *lightgrid;
int numgridpoints;
vec3_t gridSize;
vec3_t gridMins;
int gridBounds[4];
} world_static_t;
extern world_static_t world;

View File

@ -83,7 +83,7 @@ void Mod_UnloadStudioModel( struct model_s *mod );
void Mod_UnloadBrushModel( struct model_s *mod );
void GL_SetRenderMode( int mode );
int R_GetSpriteTexture( const struct model_s *m_pSpriteModel, int frame );
void R_LightForPoint( const vec3_t point, vec3_t ambientLight );
void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLight );
qboolean R_DecalShoot( int texture, int ent, int model, vec3_t pos, vec3_t saxis, int flags, rgba_t color );
void R_RemoveEfrags( struct cl_entity_s *ent );
void R_AddEfrags( struct cl_entity_s *ent );

View File

@ -11,7 +11,6 @@
#include <windows.h>
#include "launch_api.h"
#include "engine_api.h"
#include "ref_params.h"
#include "com_export.h"
#include "com_model.h"
@ -33,11 +32,12 @@
// config strings are a general means of communication from
// the server to all connected clients.
// each config string can be at most CS_SIZE characters.
#define CS_SIZE 64 // size of one config string
#define CS_TIME 16 // size of time string
#define CS_SIZE 64 // size of one config string
#define CS_TIME 16 // size of time string
#define MAX_MSGLEN 32768 // max length of network message
// FIXME: replace with NET_MAX_PAYLOAD
#define MAX_DECALS 512 // touching TE_DECAL messages, etc
#define MAX_MSGLEN 32768 // max length of network message
// FIXME: replace with NET_MAX_PAYLOAD
#ifdef _DEBUG
void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage );
@ -208,7 +208,6 @@ void *pfnGetProcAddress( void *hInstance, const char *name );
void pfnFreeLibrary( void *hInstance );
long pfnRandomLong( long lLow, long lHigh );
float pfnRandomFloat( float flLow, float flHigh );
void pfnVecToAngles( const float *rgflVectorIn, float *rgflVectorOut );
int pfnAddCommand( const char *cmd_name, xcommand_t func );
void pfnDelCommand( const char *cmd_name );
void *Cache_Check( byte *mempool, struct cache_user_s *c );

View File

@ -287,44 +287,6 @@ float pfnRandomFloat( float flLow, float flHigh )
return Com_RandomFloat( flLow, flHigh );
}
/*
=================
pfnVecToAngles
=================
*/
void pfnVecToAngles( const float *rgflVectorIn, float *rgflVectorOut )
{
float tmp, yaw, pitch;
if( !rgflVectorIn )
{
if( rgflVectorOut ) VectorClear( rgflVectorOut );
return;
}
if( rgflVectorIn[1] == 0 && rgflVectorIn[0] == 0 )
{
// fast case
yaw = 0;
if( rgflVectorIn[2] > 0 )
pitch = 90;
else pitch = 270;
}
else
{
yaw = ( com.atan2( rgflVectorIn[1], rgflVectorIn[0] ) * 180 / M_PI );
if( yaw < 0 ) yaw += 360;
tmp = com.sqrt( rgflVectorIn[0] * rgflVectorIn[0] + rgflVectorIn[1] * rgflVectorIn[1] );
pitch = ( com.atan2( rgflVectorIn[2], tmp ) * 180 / M_PI );
if( pitch < 0 ) pitch += 360;
}
if( rgflVectorOut ) VectorSet( rgflVectorOut, pitch, yaw, 0 );
else MsgDev( D_ERROR, "SV_VecToAngles: no output vector specified\n" );
}
/*
=============
pfnTime

View File

@ -5,6 +5,7 @@
#include "common.h"
#include "netchan.h"
#include "protocol.h"
#include "cm_local.h"
#include "input.h"

View File

@ -108,6 +108,12 @@ void VectorVectors( vec3_t forward, vec3_t right, vec3_t up )
CrossProduct(right, forward, up);
}
/*
=================
AngleVectors
=================
*/
void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up )
{
float sr, sp, sy, cr, cp, cy;
@ -138,6 +144,42 @@ void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up
}
}
/*
=================
VectorAngles
=================
*/
void VectorAngles( const float *forward, float *angles )
{
float tmp, yaw, pitch;
if( !forward || !angles )
{
if( angles ) VectorClear( angles );
return;
}
if( forward[1] == 0 && forward[0] == 0 )
{
// fast case
yaw = 0;
if( forward[2] > 0 )
pitch = 90.0f;
else pitch = 270.0f;
}
else
{
yaw = ( com.atan2( forward[1], forward[0] ) * 180 / M_PI );
if( yaw < 0 ) yaw += 360;
tmp = com.sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
pitch = ( com.atan2( forward[2], tmp ) * 180 / M_PI );
if( pitch < 0 ) pitch += 360;
}
VectorSet( angles, pitch, yaw, 0 );
}
//
// bounds operations
//

View File

@ -90,6 +90,7 @@ int SignbitsForPlane( const vec3_t normal );
int NearestPOW( int value, qboolean roundDown );
float VectorNormalizeLength2( const vec3_t v, vec3_t out );
void VectorVectors( vec3_t forward, vec3_t right, vec3_t up );
void VectorAngles( const float *forward, float *angles );
void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up );
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
@ -102,6 +103,23 @@ float RadiusFromBounds( const vec3_t mins, const vec3_t maxs );
void AngleQuaternion( const vec3_t angles, vec4_t q );
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt );
extern vec3_t vec3_origin;
//
// matrixlib.c
//
#define Matrix3x4_LoadIdentity( mat ) Matrix3x4_Copy( mat, matrix3x4_identity )
#define Matrix3x4_Copy( out, in ) Mem_Copy( out, in, sizeof( matrix3x4 ))
void Matrix3x4_VectorTransform( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorITransform( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorRotate( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorIRotate( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_ConcatTransforms( matrix3x4 out, const matrix3x4 in1, const matrix3x4 in2 );
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin );
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z );
void Matrix3x4_OriginFromMatrix( const matrix3x4 in, float *out );
extern vec3_t vec3_origin;
extern const matrix3x4 matrix3x4_identity;
#endif//MATHLIB_H

185
engine/common/matrixlib.c Normal file
View File

@ -0,0 +1,185 @@
//=======================================================================
// Copyright XashXT Group 2010 ©
// matrixlib.c - internal matrixlib
//=======================================================================
#include "common.h"
#include "mathlib.h"
const matrix3x4 matrix3x4_identity =
{
{ 1, 0, 0, 0 }, // PITCH [forward], org[0]
{ 0, 1, 0, 0 }, // YAW [right] , org[1]
{ 0, 0, 1, 0 }, // ROLL [up] , org[2]
};
/*
========================================================================
Matrix3x4 operations
========================================================================
*/
void Matrix3x4_VectorTransform( const matrix3x4 in, const float v[3], float out[3] )
{
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3];
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3];
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3];
}
void Matrix3x4_VectorITransform( const matrix3x4 in, const float v[3], float out[3] )
{
float dir[3];
dir[0] = v[0] - in[0][3];
dir[1] = v[1] - in[1][3];
dir[2] = v[2] - in[2][3];
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
}
void Matrix3x4_VectorRotate( const matrix3x4 in, const float v[3], float out[3] )
{
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2];
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2];
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2];
}
void Matrix3x4_VectorIRotate( const matrix3x4 in, const float v[3], float out[3] )
{
out[0] = v[0] * in[0][0] + v[1] * in[1][0] + v[2] * in[2][0];
out[1] = v[0] * in[0][1] + v[1] * in[1][1] + v[2] * in[2][1];
out[2] = v[0] * in[0][2] + v[1] * in[1][2] + v[2] * in[2][2];
}
void Matrix3x4_ConcatTransforms( matrix3x4 out, const matrix3x4 in1, const matrix3x4 in2 )
{
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];
}
void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z )
{
out[0][3] = x;
out[1][3] = y;
out[2][3] = z;
}
void Matrix3x4_OriginFromMatrix( const matrix3x4 in, float *out )
{
out[0] = in[0][3];
out[1] = in[1][3];
out[2] = in[2][3];
}
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin )
{
out[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
out[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
out[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
out[0][1] = 2.0f * quaternion[0] * quaternion[1] - 2.0f * quaternion[3] * quaternion[2];
out[1][1] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[2] * quaternion[2];
out[2][1] = 2.0f * quaternion[1] * quaternion[2] + 2.0f * quaternion[3] * quaternion[0];
out[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
out[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
out[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
out[0][3] = origin[0];
out[1][3] = origin[1];
out[2][3] = origin[2];
}
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale )
{
float angle, sr, sp, sy, cr, cp, cy;
if( angles[ROLL] )
{
angle = angles[YAW] * (M_PI*2 / 360);
com.sincos( angle, &sy, &cy );
angle = angles[PITCH] * (M_PI*2 / 360);
com.sincos( angle, &sp, &cp );
angle = angles[ROLL] * (M_PI*2 / 360);
com.sincos( angle, &sr, &cr );
out[0][0] = (cp*cy) * scale;
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
out[0][2] = (cr*sp*cy+-sr*-sy) * scale;
out[0][3] = origin[0];
out[1][0] = (cp*sy) * scale;
out[1][1] = (sr*sp*sy+cr*cy) * scale;
out[1][2] = (cr*sp*sy+-sr*cy) * scale;
out[1][3] = origin[1];
out[2][0] = (-sp) * scale;
out[2][1] = (sr*cp) * scale;
out[2][2] = (cr*cp) * scale;
out[2][3] = origin[2];
}
else if( angles[PITCH] )
{
angle = angles[YAW] * (M_PI*2 / 360);
com.sincos( angle, &sy, &cy );
angle = angles[PITCH] * (M_PI*2 / 360);
com.sincos( angle, &sp, &cp );
out[0][0] = (cp*cy) * scale;
out[0][1] = (-sy) * scale;
out[0][2] = (sp*cy) * scale;
out[0][3] = origin[0];
out[1][0] = (cp*sy) * scale;
out[1][1] = (cy) * scale;
out[1][2] = (sp*sy) * scale;
out[1][3] = origin[1];
out[2][0] = (-sp) * scale;
out[2][1] = 0;
out[2][2] = (cp) * scale;
out[2][3] = origin[2];
}
else if( angles[YAW] )
{
angle = angles[YAW] * (M_PI*2 / 360);
com.sincos( angle, &sy, &cy );
out[0][0] = (cy) * scale;
out[0][1] = (-sy) * scale;
out[0][2] = 0;
out[0][3] = origin[0];
out[1][0] = (sy) * scale;
out[1][1] = (cy) * scale;
out[1][2] = 0;
out[1][3] = origin[1];
out[2][0] = 0;
out[2][1] = 0;
out[2][2] = scale;
out[2][3] = origin[2];
}
else
{
out[0][0] = scale;
out[0][1] = 0;
out[0][2] = 0;
out[0][3] = origin[0];
out[1][0] = 0;
out[1][1] = scale;
out[1][2] = 0;
out[1][3] = origin[1];
out[2][0] = 0;
out[2][1] = 0;
out[2][2] = scale;
out[2][3] = origin[2];
}
}

View File

@ -4,6 +4,7 @@
//=======================================================================
#include "common.h"
#include "protocol.h"
#include "net_buffer.h"
// precalculated bit masks for WriteUBitLong.

View File

@ -84,10 +84,22 @@
#define MAX_EVENT_BITS 10
#define MAX_EVENTS (1<<MAX_EVENT_BITS) // 10 bits == 1024 events (the original Half-Life limit)
#define MAX_MODEL_BITS 11
#define MAX_MODELS (1<<MAX_MODEL_BITS) // 11 bits == 2048 models
#define MAX_SOUND_BITS 11
#define MAX_SOUNDS (1<<MAX_SOUND_BITS) // 11 bits == 2048 sounds
#define MAX_CUSTOM 1024 // max custom resources per level
#define MAX_USER_MESSAGES 191 // another 63 messages reserved for engine routines
// FIXME: tune this
#define MAX_DLIGHTS 32 // dynamic lights (rendered per one frame)
#define MAX_LIGHTSTYLES 256 // a byte limit, don't modify
#define MAX_EDICTS 4096 // absolute limit, should be enough. (can be up to 32768)
#define MAX_RENDER_DECALS 4096 // max rendering decals per a level
// sound flags
#define SND_VOLUME (1<<0) // a scaled byte
#define SND_ATTENUATION (1<<1) // a byte
@ -99,8 +111,39 @@
#define SND_CHANGE_PITCH (1<<7) // change sound pitch
#define SND_SPAWNING (1<<8) // we're spawning, used in some cases for ambients
// decal flags
#define FDECAL_PERMANENT 0x01 // This decal should not be removed in favor of any new decals
#define FDECAL_CUSTOM 0x02 // This is a custom clan logo and should not be saved/restored
#define FDECAL_DYNAMIC 0x04 // Indicates the decal is dynamic
#define FDECAL_DONTSAVE 0x08 // Decal was loaded from adjacent level, don't save it for this level
#define FDECAL_CLIPTEST 0x10 // Decal needs to be clip-tested
#define FDECAL_NOCLIP 0x20 // Decal is not clipped by containing polygon
#define FDECAL_USESAXIS 0x40 // Uses the s axis field to determine orientation (footprints)
#define FDECAL_ANIMATED 0x80 // this is decal has multiple frames
// Max number of history commands to send ( 2 by default ) in case of dropped packets
#define NUM_BACKUP_COMMAND_BITS 3
#define MAX_BACKUP_COMMANDS (1 << NUM_BACKUP_COMMAND_BITS)
// world size
#define MAX_COORD_INTEGER (16384) // world half-size, modify with precaution
#define MIN_COORD_INTEGER (-MAX_COORD_INTEGER)
#define MAX_COORD_FRACTION ( 1.0 - ( 1.0 / 16.0 ))
#define MIN_COORD_FRACTION (-1.0 + ( 1.0 / 16.0 ))
// network precision
#define COORD_INTEGER_BITS 14
#define COORD_FRACTIONAL_BITS 5
#define COORD_DENOMINATOR ( 1 << ( COORD_FRACTIONAL_BITS ))
#define COORD_RESOLUTION (1.0 / ( COORD_DENOMINATOR ))
#define NORMAL_FRACTIONAL_BITS 11
#define NORMAL_DENOMINATOR (( 1 << ( NORMAL_FRACTIONAL_BITS )) - 1 )
#define NORMAL_RESOLUTION ( 1.0 / ( NORMAL_DENOMINATOR ))
// verify that coordsize.h and worldsize.h are consistently defined
#if( MAX_COORD_INTEGER != ( 1 << COORD_INTEGER_BITS ))
#error MAX_COORD_INTEGER does not match COORD_INTEGER_BITS
#endif
#endif//PROTOCOL_H

View File

@ -274,6 +274,10 @@ SOURCE=.\common\mathlib.c
# End Source File
# Begin Source File
SOURCE=.\common\matrixlib.c
# End Source File
# Begin Source File
SOURCE=.\common\model.c
# End Source File
# Begin Source File

View File

@ -4083,7 +4083,7 @@ static enginefuncs_t gEngfuncs =
pfnGetSpawnParms,
pfnSaveSpawnParms,
pfnVecToYaw,
pfnVecToAngles,
VectorAngles,
pfnMoveToOrigin,
pfnChangeYaw,
pfnChangePitch,

View File

@ -181,7 +181,7 @@ void SV_UpdateMovevars( void )
// check range
if( sv_zmax->value < 256.0f ) Cvar_SetFloat( "sv_zmax", 256.0f );
if( sv_zmax->value > 8192.0f ) Cvar_SetFloat( "sv_zmax", 8192.0f );
if( sv_zmax->value > 32767.0f ) Cvar_SetFloat( "sv_zmax", 32767.0f );
svgame.movevars.gravity = sv_gravity->value;
svgame.movevars.stopspeed = sv_stopspeed->value;

View File

@ -926,7 +926,7 @@ trace_t SV_TraceHitbox( edict_t *ent, const vec3_t start, vec3_t mins, vec3_t ma
void SV_StudioGetAttachment( edict_t *e, int iAttachment, float *org, float *ang )
{
mstudioattachment_t *pAtt;
vec3_t axis[3], bonepos;
vec3_t forward, bonepos;
vec3_t localOrg, localAng;
void *hdr;
@ -953,10 +953,9 @@ void SV_StudioGetAttachment( edict_t *e, int iAttachment, float *org, float *ang
// compute pos and angles
Matrix4x4_VectorTransform( sv_studiobones[pAtt[iAttachment].bone], pAtt[iAttachment].org, localOrg );
Matrix4x4_OriginFromMatrix( sv_studiobones[pAtt[iAttachment].bone], bonepos );
VectorSubtract( localOrg, bonepos, axis[0] ); // make forward
VectorNormalizeFast( axis[0] );
VectorVectors( axis[0], axis[1], axis[2] ); // make right and up
Matrix3x3_ToAngles( axis, localAng, false ); // FIXME: dll's uses FLU ?
VectorSubtract( localOrg, bonepos, forward ); // make forward
VectorNormalizeFast( forward );
VectorAngles( forward, localAng );
if( org ) VectorCopy( localOrg, org );
if( ang ) VectorCopy( localAng, ang );

View File

@ -6,7 +6,6 @@
#include "launch.h"
#include "library.h"
#include "engine_api.h"
#include "mathlib.h"
#define MAX_QUED_EVENTS 256

View File

@ -6,7 +6,6 @@
#include "launch.h"
#include "utils.h"
#include "mdllib.h"
#include "engine_api.h"
#include "mathlib.h"
#include "badimage.h"

View File

@ -1,56 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// engine_api.h - xash engine api
//=======================================================================
#ifndef ENGINE_API_H
#define ENGINE_API_H
#include "const.h"
//
// engine constant limits, touching networking protocol modify with precaution
//
#define MAX_MODEL_BITS 11
#define MAX_MODELS (1<<MAX_MODEL_BITS) // 11 bits == 2048 models
#define MAX_SOUND_BITS 11
#define MAX_SOUNDS (1<<MAX_SOUND_BITS) // 11 bits == 2048 sounds
#define MAX_DLIGHTS 32 // dynamic lights (rendered per one frame)
#define MAX_DECALS 512 // touching TE_DECAL messages, etc
#define MAX_LIGHTSTYLES 256 // a byte limit, don't modify
#define MAX_EDICTS 4096 // absolute limit, should be enough. (can be up to 32768)
#define MAX_RENDER_DECALS 4096 // max rendering decals per a level
// decal flags
#define FDECAL_PERMANENT 0x01 // This decal should not be removed in favor of any new decals
#define FDECAL_CUSTOM 0x02 // This is a custom clan logo and should not be saved/restored
#define FDECAL_DYNAMIC 0x04 // Indicates the decal is dynamic
#define FDECAL_DONTSAVE 0x08 // Decal was loaded from adjacent level, don't save it for this level
#define FDECAL_CLIPTEST 0x10 // Decal needs to be clip-tested
#define FDECAL_NOCLIP 0x20 // Decal is not clipped by containing polygon
#define FDECAL_USESAXIS 0x40 // Uses the s axis field to determine orientation (footprints)
#define FDECAL_ANIMATED 0x80 // this is decal has multiple frames
// world size
#define MAX_COORD_INTEGER (16384) // world half-size, modify with precaution
#define MIN_COORD_INTEGER (-MAX_COORD_INTEGER)
#define MAX_COORD_FRACTION ( 1.0 - ( 1.0 / 16.0 ))
#define MIN_COORD_FRACTION (-1.0 + ( 1.0 / 16.0 ))
// network precision
#define COORD_INTEGER_BITS 14
#define COORD_FRACTIONAL_BITS 5
#define COORD_DENOMINATOR ( 1 << ( COORD_FRACTIONAL_BITS ))
#define COORD_RESOLUTION (1.0 / ( COORD_DENOMINATOR ))
#define NORMAL_FRACTIONAL_BITS 11
#define NORMAL_DENOMINATOR (( 1 << ( NORMAL_FRACTIONAL_BITS )) - 1 )
#define NORMAL_RESOLUTION ( 1.0 / ( NORMAL_DENOMINATOR ))
// verify that coordsize.h and worldsize.h are consistently defined
#if( MAX_COORD_INTEGER != ( 1 << COORD_INTEGER_BITS ))
#error MAX_COORD_INTEGER does not match COORD_INTEGER_BITS
#endif
#endif//ENGINE_API_H

View File

@ -39,6 +39,7 @@ typedef vec_t quat_t[4];
typedef byte rgba_t[4]; // unsigned byte colorpack
typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x3[3][3];
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4];
typedef char string[MAX_STRING];

View File

@ -63,18 +63,6 @@ Package=<4>
###############################################################################
Project: "vid_gl"=".\vid_gl\vid_gl.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>