This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/engine/common/pm_surface.c

129 lines
3.2 KiB
C
Raw Normal View History

2010-08-12 22:00:00 +02:00
//=======================================================================
// Copyright XashXT Group 2010 <20>
// pm_surface.c - surface tracing
//=======================================================================
#include "common.h"
#include "mathlib.h"
#include "pm_local.h"
/*
==================
2010-10-18 22:00:00 +02:00
PM_RecursiveSurfCheck
2010-08-12 22:00:00 +02:00
==================
*/
2010-11-21 22:00:00 +01:00
msurface_t *PM_RecursiveSurfCheck( model_t *model, mnode_t *node, vec3_t p1, vec3_t p2 )
2010-08-12 22:00:00 +02:00
{
2010-10-18 22:00:00 +02:00
float t1, t2, frac;
int side, ds, dt;
2010-08-12 22:00:00 +02:00
mplane_t *plane;
2010-10-18 22:00:00 +02:00
msurface_t *surf;
vec3_t mid;
2010-08-12 22:00:00 +02:00
int i;
2010-10-18 22:00:00 +02:00
if( node->contents < 0 )
2010-08-12 22:00:00 +02:00
return NULL;
2010-10-18 22:00:00 +02:00
plane = node->plane;
2010-08-19 22:00:00 +02:00
2010-10-18 22:00:00 +02:00
if( plane->type < 3 )
{
t1 = p1[plane->type] - plane->dist;
t2 = p2[plane->type] - plane->dist;
}
else
2010-08-12 22:00:00 +02:00
{
2010-10-18 22:00:00 +02:00
t1 = DotProduct( plane->normal, p1 ) - plane->dist;
t2 = DotProduct( plane->normal, p2 ) - plane->dist;
}
2010-08-12 22:00:00 +02:00
2010-10-18 22:00:00 +02:00
if( t1 >= 0 && t2 >= 0 )
2010-11-21 22:00:00 +01:00
return PM_RecursiveSurfCheck( model, node->children[0], p1, p2 );
2010-10-18 22:00:00 +02:00
if( t1 < 0 && t2 < 0 )
2010-11-21 22:00:00 +01:00
return PM_RecursiveSurfCheck( model, node->children[1], p1, p2 );
2010-08-12 22:00:00 +02:00
2010-10-18 22:00:00 +02:00
frac = t1 / ( t1 - t2 );
2010-08-12 22:00:00 +02:00
2010-10-18 22:00:00 +02:00
if( frac < 0.0f ) frac = 0.0f;
if( frac > 1.0f ) frac = 1.0f;
2010-08-12 22:00:00 +02:00
2010-10-18 22:00:00 +02:00
VectorLerp( p1, frac, p2, mid );
2010-08-12 22:00:00 +02:00
2010-10-18 22:00:00 +02:00
side = (t1 < 0);
2010-08-12 22:00:00 +02:00
2010-10-18 22:00:00 +02:00
// now this is weird.
2010-11-21 22:00:00 +01:00
surf = PM_RecursiveSurfCheck( model, node->children[side], p1, mid );
2010-10-18 22:00:00 +02:00
if( surf != NULL || ( t1 >= 0 && t2 >= 0 ) || ( t1 < 0 && t2 < 0 ))
2010-08-12 22:00:00 +02:00
{
2010-10-18 22:00:00 +02:00
return surf;
}
2010-11-21 22:00:00 +01:00
surf = model->surfaces + node->firstsurface;
2010-08-12 22:00:00 +02:00
2010-11-21 22:00:00 +01:00
for( i = 0; i < node->numsurfaces; i++, surf++ )
2010-10-18 22:00:00 +02:00
{
ds = (int)((float)DotProduct( mid, surf->texinfo->vecs[0] ) + surf->texinfo->vecs[0][3] );
dt = (int)((float)DotProduct( mid, surf->texinfo->vecs[1] ) + surf->texinfo->vecs[1][3] );
2010-08-12 22:00:00 +02:00
2010-10-18 22:00:00 +02:00
if( ds >= surf->texturemins[0] && dt >= surf->texturemins[1] )
2010-08-12 22:00:00 +02:00
{
2011-04-05 22:00:00 +02:00
int s = ds - surf->texturemins[0];
int t = dt - surf->texturemins[1];
2010-10-18 22:00:00 +02:00
if( s <= surf->extents[0] && t <= surf->extents[1] )
return surf;
2010-08-12 22:00:00 +02:00
}
}
2010-11-21 22:00:00 +01:00
return PM_RecursiveSurfCheck( model, node->children[side^1], mid, p2 );
2010-10-18 22:00:00 +02:00
}
/*
==================
PM_TraceTexture
find the face where the traceline hit
assume physentity is valid
==================
*/
const char *PM_TraceTexture( physent_t *pe, vec3_t start, vec3_t end )
{
msurface_t *surf;
matrix4x4 matrix;
model_t *bmodel;
hull_t *hull;
vec3_t start_l, end_l;
2011-03-03 22:00:00 +01:00
vec3_t offset;
2010-10-18 22:00:00 +02:00
bmodel = pe->model;
2010-10-23 22:00:00 +02:00
if( !bmodel || bmodel->type != mod_brush )
2010-10-18 22:00:00 +02:00
return NULL;
2011-04-05 22:00:00 +02:00
hull = &pe->model->hulls[0];
VectorSubtract( hull->clip_mins, vec3_origin, offset );
VectorAdd( offset, pe->origin, offset );
2010-10-18 22:00:00 +02:00
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
// rotate start and end into the models frame of reference
if( !VectorIsNull( pe->angles ))
{
matrix4x4 imatrix;
2010-12-22 22:00:00 +01:00
2011-04-05 22:00:00 +02:00
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
2010-10-18 22:00:00 +02:00
Matrix4x4_Invert_Simple( imatrix, matrix );
Matrix4x4_VectorTransform( imatrix, start, start_l );
Matrix4x4_VectorTransform( imatrix, end, end_l );
}
2010-11-21 22:00:00 +01:00
surf = PM_RecursiveSurfCheck( bmodel, &bmodel->nodes[hull->firstclipnode], start_l, end_l );
2010-10-23 22:00:00 +02:00
if( !surf || !surf->texinfo || !surf->texinfo->texture )
return NULL;
2010-10-18 22:00:00 +02:00
return surf->texinfo->texture->name;
2010-08-12 22:00:00 +02:00
}