Crow_Bar's VFPU-driven matrix math; ADQ Physics Enhancements

This commit is contained in:
moto 2022-05-22 11:21:10 -04:00
parent 4857dab378
commit 3fcf3a0b1f
7 changed files with 509 additions and 241 deletions

View file

@ -50,6 +50,7 @@ COMMON_OBJS = \
source/host_cmd.o \
source/keys.o \
source/mathlib.o \
source/matrixlib.o \
source/menu.o \
source/net_dgrm.o \
source/net_loop.o \

View file

@ -52,6 +52,7 @@ COMMON_OBJS = \
source/host_cmd.o \
source/keys.o \
source/mathlib.o \
source/matrixlib.o \
source/menu.o \
source/net_dgrm.o \
source/net_loop.o \

View file

@ -27,6 +27,7 @@ typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t vec5_t[5];
typedef vec_t matrix4x4[4][4];
typedef byte byte_vec4_t[4];
@ -38,6 +39,9 @@ typedef int fixed16_t;
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif
#define RAD2DEG( x ) ((float)(x) * (float)(180.f / M_PI))
#define DEG2RAD( x ) ((float)(x) * (float)(M_PI / 180.f))
struct mplane_s;
extern vec3_t vec3_origin;
@ -69,6 +73,7 @@ extern int nanmask;
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#define VectorLerp( v1, lerp, v2, c ) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]), (c)[2] = (v1)[2] + (lerp) * ((v2)[2] - (v1)[2]))
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
@ -80,18 +85,7 @@ extern int nanmask;
#define VSM(a,b,c) {c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;}
// MDave -- courtesy of johnfitz, lordhavoc
#define VectorNormalizeFast(_v)\
{\
float _y, _number;\
_number = DotProduct(_v, _v);\
if (_number != 0.0)\
{\
*((long *)&_y) = 0x5f3759df - ((* (long *) &_number) >> 1);\
_y = _y * (1.5f - (_number * 0.5f * _y * _y));\
VectorScale(_v, _y, _v);\
}\
}
#define VectorNormalizeFast( v ){float ilength = (float)rsqrt(DotProduct(v,v));v[0] *= ilength;v[1] *= ilength;v[2] *= ilength; }
typedef float matrix3x4[3][4];
typedef float matrix3x3[3][3];
@ -141,21 +135,6 @@ float anglemod(float a);
(v)[1] - (w)[1] > -_mathlib_temp_float1 && (v)[1] - (w)[1] < _mathlib_temp_float1 && \
(v)[2] - (w)[2] > -_mathlib_temp_float1 && (v)[2] - (w)[2] < _mathlib_temp_float1)
/*
#define VectorNormalizeFast(_v) \
do { \
_mathlib_temp_float1 = DotProduct((_v), (_v)); \
if (_mathlib_temp_float1) { \
_mathlib_temp_float2 = 0.5f * _mathlib_temp_float1; \
_mathlib_temp_int1 = *((int *) &_mathlib_temp_float1); \
_mathlib_temp_int1 = 0x5f375a86 - (_mathlib_temp_int1 >> 1); \
_mathlib_temp_float1 = *((float *) &_mathlib_temp_int1); \
_mathlib_temp_float1 = _mathlib_temp_float1 * (1.5f - _mathlib_temp_float2 * _mathlib_temp_float1 * _mathlib_temp_float1); \
VectorScale((_v), _mathlib_temp_float1, (_v)) \
} \
} while (0);
*/
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
(((p)->type < 3)? \
( \
@ -193,9 +172,51 @@ do { \
(((plane)->type < 3) ? (point)[(plane)->type] - (plane)->dist : DotProduct((point), (plane)->normal) - (plane)->dist) \
)
void SinCos( float radians, float *sine, float *cosine );
float rsqrt( float number );
//
// matrixlib.c
//
#define Matrix3x4_LoadIdentity( mat ) Matrix3x4_Copy( mat, matrix3x4_identity )
#define Matrix3x4_Copy( out, in ) memcpy( 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_TransformPositivePlane( const matrix3x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z );
void Matrix3x4_Invert_Simple( matrix3x4 out, const matrix3x4 in1 );
void Matrix3x4_OriginFromMatrix( const matrix3x4 in, float *out );
#define Matrix4x4_LoadIdentity( mat ) Matrix4x4_Copy( mat, matrix4x4_identity )
#define Matrix4x4_Copy( out, in ) memcpy( out, in, sizeof( matrix4x4 ))
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorRotate( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorIRotate( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_FromOriginQuat( matrix4x4 out, const vec4_t quaternion, const vec3_t origin );
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
void Matrix4x4_TransformStandardPlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin );
void Matrix4x4_SetOrigin( matrix4x4 out, float x, float y, float z );
void Matrix4x4_Invert_Simple( matrix4x4 out, const matrix4x4 in1 );
void Matrix4x4_OriginFromMatrix( const matrix4x4 in, float *out );
extern const matrix3x4 matrix3x4_identity;
extern const matrix4x4 matrix4x4_identity;
void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out);
// Prototypes added by PM.
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out);
extern int _mathlib_temp_int1, _mathlib_temp_int2, _mathlib_temp_int3;
extern float _mathlib_temp_float1, _mathlib_temp_float2, _mathlib_temp_float3;
extern vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;
extern vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;

View file

@ -196,11 +196,7 @@ void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_
void Matrix3x4_TransformPositivePlane( const matrix3x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
{
#ifdef PSP_VFPU
float scale = vfpu_sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
#else
float scale = sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
#endif
float scale = sqrt( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
float iscale = 1.0f / scale;
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
@ -252,13 +248,59 @@ const matrix4x4 matrix4x4_identity =
*/
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] )
{
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %1\n" // C100 = in[0]
"lv.q C110, 16 + %1\n" // C110 = in[1]
"lv.q C120, 32 + %1\n" // C120 = in[2]
"lv.s S130, 0 + %2\n" // S130 = v[0]
"lv.s S131, 4 + %2\n" // S131 = v[1]
"lv.s S132, 8 + %2\n" // S132 = v[2]
"vhdp.q S000, C130, C100\n" // S000 = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3]
"vhdp.q S001, C130, C110\n" // S001 = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3]
"vhdp.q S002, C130, C120\n" // S002 = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3]
"sv.s S000, 0 + %0\n" // out[0] = S000
"sv.s S001, 4 + %0\n" // out[1] = S001
"sv.s S002, 8 + %0\n" // out[2] = S002
".set pop\n" // restore assembler option
: "=m"( *out )
: "m"( *in ), "m"( *v )
);
/*
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 Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] )
{
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %1\n" // C100 = in[0]
"lv.q C110, 16 + %1\n" // C110 = in[1]
"lv.q C120, 32 + %1\n" // C120 = in[2]
"lv.s S130, 0 + %2\n" // S130 = v[0]
"lv.s S131, 4 + %2\n" // S131 = v[1]
"lv.s S132, 8 + %2\n" // S132 = v[2]
"vsub.t C130, C130, R103\n" // C130 = v - in[][3]
#if 1
"vtfm3.t C000, E100, C130\n" // C000 = E100 * C130
#else
"vdot.t S000, C130, R100\n" // S000 = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0]
"vdot.t S001, C130, R101\n" // S001 = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1]
"vdot.t S002, C130, R102\n" // S002 = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2]
#endif
"sv.s S000, 0 + %0\n" // out[0] = S000
"sv.s S001, 4 + %0\n" // out[1] = S001
"sv.s S002, 8 + %0\n" // out[2] = S002
".set pop\n" // restore assembler option
: "=m"( *out )
: "m"( *in ), "m"( *v )
);
/*
vec3_t dir;
dir[0] = v[0] - in[0][3];
@ -268,6 +310,7 @@ void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out
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 Matrix4x4_VectorRotate( const matrix4x4 in, const float v[3], float out[3] )
@ -286,6 +329,26 @@ void Matrix4x4_VectorIRotate( const matrix4x4 in, const float v[3], float out[3]
void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 )
{
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %1\n" // C100 = in1[0]
"lv.q C110, 16 + %1\n" // C110 = in1[1]
"lv.q C120, 32 + %1\n" // C120 = in1[2]
"vzero.q C130\n" // C130 = [0, 0, 0, 0]
"lv.q C200, 0 + %2\n" // C100 = in2[0]
"lv.q C210, 16 + %2\n" // C110 = in2[1]
"lv.q C220, 32 + %2\n" // C120 = in2[2]
"vidt.q C230\n" // C230 = [0, 0, 0, 1]
"vmmul.q E000, E100, E200\n" // E000 = E100 * E200
"sv.q C000, 0 + %0\n" // out[0] = C000
"sv.q C010, 16 + %0\n" // out[1] = C010
"sv.q C020, 32 + %0\n" // out[2] = C020
".set pop\n" // restore assembler option
: "=m"( *out )
: "m"( *in1 ), "m"( *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];
@ -298,6 +361,7 @@ void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matri
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 Matrix4x4_SetOrigin( matrix4x4 out, float x, float y, float z )
@ -433,34 +497,19 @@ void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_
void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin )
{
#ifdef PSP_VFPU
float xyDist = vfpu_sqrtf( in[0][0] * in[0][0] + in[1][0] * in[1][0] );
#else
float xyDist = sqrtf( in[0][0] * in[0][0] + in[1][0] * in[1][0] );
#endif
float xyDist = sqrt( in[0][0] * in[0][0] + in[1][0] * in[1][0] );
// enough here to get angles?
if( xyDist > 0.001f )
{
#ifdef PSP_VFPU
angles[0] = RAD2DEG( vfpu_atan2f( -in[2][0], xyDist ) );
angles[1] = RAD2DEG( vfpu_atan2f( in[1][0], in[0][0] ) );
angles[2] = RAD2DEG( vfpu_atan2f( in[2][1], in[2][2] ) );
#else
angles[0] = RAD2DEG( atan2( -in[2][0], xyDist ) );
angles[1] = RAD2DEG( atan2( in[1][0], in[0][0] ) );
angles[2] = RAD2DEG( atan2( in[2][1], in[2][2] ) );
#endif
}
else // forward is mostly Z, gimbal lock
{
#ifdef PSP_VFPU
angles[0] = RAD2DEG( vfpu_atan2f( -in[2][0], xyDist ) );
angles[1] = RAD2DEG( vfpu_atan2f( -in[0][1], in[1][1] ) );
#else
angles[0] = RAD2DEG( atan2( -in[2][0], xyDist ) );
angles[1] = RAD2DEG( atan2( -in[0][1], in[1][1] ) );
#endif
angles[2] = 0;
}
@ -471,32 +520,80 @@ void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin
void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
{
#ifdef PSP_VFPU
float scale = vfpu_sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
#else
float scale = sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
#endif
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %2\n" // C100 = in[0]
"lv.q C110, 16 + %2\n" // C110 = in[1]
"lv.q C120, 32 + %2\n" // C120 = in[2]
"lv.s S200, 0 + %3\n" // S200 = normal[0]
"lv.s S201, 4 + %3\n" // S201 = normal[1]
"lv.s S202, 8 + %3\n" // S202 = normal[2]
"lv.s S210, %4\n" // S210 = d
"vdot.t S211, C100, C100\n" // S211 = C100 * C100
"vsqrt.s S211, S211\n" // S211 = sqrt( S211 )
"vrcp.s S212, S211\n" // S212 = 1 / S211
"vtfm3.t C000, M100, C200\n" // C000 = M100 * C200
"vscl.t C000, C000, S212\n" // C000 = C000 * S211
"vmul.s S003, S210, S211\n" // S003 = S210 * S211
"vdot.t S010, R103, C000\n" // S010 = R103 * C000
"vadd.s S003, S003, S010\n" // S003 = S003 + S010
"sv.s S000, 0 + %0\n" // out[0] = S000
"sv.s S001, 4 + %0\n" // out[1] = S001
"sv.s S002, 8 + %0\n" // out[2] = S002
"sv.s S003, %1\n" // dist = S003
".set pop\n" // restore assembler option
: "=m"( *out ), "=m"( *dist )
: "m"( *in ), "m"( *normal ), "m"( d )
);
/*
float scale = sqrt( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
float iscale = 1.0f / scale;
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
*dist = d * scale + ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
*/
}
void Matrix4x4_TransformStandardPlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
{
#ifdef PSP_VFPU
float scale = vfpu_sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
#else
float scale = sqrtf( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
#endif
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %2\n" // C100 = in[0]
"lv.q C110, 16 + %2\n" // C110 = in[1]
"lv.q C120, 32 + %2\n" // C120 = in[2]
"lv.s S200, 0 + %3\n" // S200 = normal[0]
"lv.s S201, 4 + %3\n" // S201 = normal[1]
"lv.s S202, 8 + %3\n" // S202 = normal[2]
"lv.s S210, %4\n" // S210 = d
"vdot.t S211, C100, C100\n" // S211 = C100 * C100
"vsqrt.s S211, S211\n" // S211 = sqrt( S211 )
"vrcp.s S212, S211\n" // S212 = 1 / S211
"vtfm3.t C000, M100, C200\n" // C000 = M100 * C200
"vscl.t C000, C000, S212\n" // C000 = C000 * S211
"vmul.s S003, S210, S211\n" // S003 = S210 * S211
"vdot.t S010, R103, C000\n" // S010 = R103 * C000
"vsub.s S003, S003, S010\n" // S003 = S003 - S010
"sv.s S000, 0 + %0\n" // out[0] = S000
"sv.s S001, 4 + %0\n" // out[1] = S001
"sv.s S002, 8 + %0\n" // out[2] = S002
"sv.s S003, %1\n" // dist = S003
".set pop\n" // restore assembler option
: "=m"( *out ), "=m"( *dist )
: "m"( *in ), "m"( *normal ), "m"( d )
);
/*
float scale = sqrt( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
float iscale = 1.0f / scale;
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
*dist = d * scale - ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
*/
}
void Matrix4x4_Invert_Simple( matrix4x4 out, const matrix4x4 in1 )

View file

@ -388,6 +388,23 @@ PUSHMOVE
===============================================================================
*/
/*
============
SV_AllowPushRotate
Allows to change entity yaw?
============
*/
qboolean SV_AllowPushRotate( edict_t *ent )
{
model_t *mod;
mod = sv.models[ (int)ent->v.modelindex ];
if(!mod || mod->type != mod_brush)
return true;
return /*(mod->flags & MODEL_HAS_ORIGIN) ? true :*/ false;
}
/*
============
SV_PushEntity
@ -395,7 +412,7 @@ SV_PushEntity
Does not change the entities velocity at all
============
*/
trace_t SV_PushEntity (edict_t *ent, vec3_t push)
trace_t SV_PushEntity (edict_t *ent, vec3_t push, vec3_t apush)
{
trace_t trace;
vec3_t end;
@ -405,15 +422,26 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push)
if (ent->v.movetype == MOVETYPE_FLYMISSILE)
trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_MISSILE, ent);
else if (ent->v.solid == SOLID_TRIGGER || ent->v.solid == SOLID_NOT)
// only clip against bmodels
trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent);
else if (ent->v.solid == SOLID_CORPSE)
// only clip against bmodels
trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent);
else
trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
VectorCopy (trace.endpos, ent->v.origin);
if( trace.fraction != 0.0f )
{
VectorCopy( trace.endpos, ent->v.origin );
if( apush[YAW] && ( (int)ent->v.flags & FL_CLIENT ))
{
ent->v.avelocity[1] += apush[1];
ent->v.fixangle = 2;
}
// don't rotate pushables!
if( SV_AllowPushRotate( ent ))
ent->v.angles[YAW] += trace.fraction * apush[YAW];
}
SV_LinkEdict (ent, true);
if (trace.ent)
@ -429,23 +457,23 @@ SV_PushMove
============
*/
void SV_PushMove (edict_t *pusher, float movetime)
edict_t *moved_edict[MAX_EDICTS];
vec3_t moved_from[MAX_EDICTS];
edict_t * SV_PushMove (edict_t *pusher, float movetime)
{
int i, e;
int i, e, oldsolid;
edict_t *check, *block;
vec3_t mins, maxs, move;
vec3_t entorig, pushorig;
int num_moved;
edict_t *moved_edict[MAX_EDICTS];
vec3_t moved_from[MAX_EDICTS];
if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
{
pusher->v.ltime += movetime;
return;
return NULL;
}
for (i=0 ; i<3 ; i++)
for (i = 0; i < 3; i++)
{
move[i] = pusher->v.velocity[i] * movetime;
mins[i] = pusher->v.absmin[i] + move[i];
@ -454,49 +482,50 @@ void SV_PushMove (edict_t *pusher, float movetime)
VectorCopy (pusher->v.origin, pushorig);
// move the pusher to it's final position
// move the pusher to it's final position
VectorAdd (pusher->v.origin, move, pusher->v.origin);
pusher->v.ltime += movetime;
SV_LinkEdict (pusher, false);
pusher->v.ltime += movetime;
oldsolid = pusher->v.solid;
// non-solid pushers can't push anything
if( pusher->v.solid == SOLID_NOT )
return NULL;
// see if any solid entities are inside the final position
num_moved = 0;
check = NEXT_EDICT(sv.edicts);
for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
// see if any solid entities are inside the final position
num_moved = 0;
check = NEXT_EDICT (sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check))
{
if (check->free)
continue;
if (check->v.movetype == MOVETYPE_PUSH
|| check->v.movetype == MOVETYPE_NONE
|| check->v.movetype == MOVETYPE_FOLLOW
|| check->v.movetype == MOVETYPE_NOCLIP
|| check->v.movetype == MOVETYPE_LARM
|| check->v.movetype == MOVETYPE_RARM
|| check->v.movetype == MOVETYPE_HEAD)
|| check->v.movetype == MOVETYPE_NONE
|| check->v.movetype == MOVETYPE_NOCLIP)
continue;
// if the entity is standing on the pusher, it will definately be moved
if ( ! ( ((int)check->v.flags & FL_ONGROUND)
&& PROG_TO_EDICT(check->v.groundentity) == pusher) )
// if the entity is standing on the pusher, it will definately be moved
if (!(((int) check->v.flags & FL_ONGROUND)
&& PROG_TO_EDICT (check->v.groundentity) == pusher))
{
if ( check->v.absmin[0] >= maxs[0]
|| check->v.absmin[1] >= maxs[1]
|| check->v.absmin[2] >= maxs[2]
|| check->v.absmax[0] <= mins[0]
|| check->v.absmax[1] <= mins[1]
|| check->v.absmax[2] <= mins[2] )
if (check->v.absmin[0] >= maxs[0]
|| check->v.absmin[1] >= maxs[1]
|| check->v.absmin[2] >= maxs[2]
|| check->v.absmax[0] <= mins[0]
|| check->v.absmax[1] <= mins[1]
|| check->v.absmax[2] <= mins[2])
continue;
// see if the ent's bbox is inside the pusher's final position
// see if the ent's bbox is inside the pusher's final position
if (!SV_TestEntityPosition (check))
continue;
}
// remove the onground flag for non-players
// remove the onground flag for non-players
if (check->v.movetype != MOVETYPE_WALK)
check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
check->v.flags = (int) check->v.flags & ~FL_ONGROUND;
VectorCopy (check->v.origin, entorig);
VectorCopy (check->v.origin, moved_from[num_moved]);
@ -505,17 +534,21 @@ void SV_PushMove (edict_t *pusher, float movetime)
// try moving the contacted entity
pusher->v.solid = SOLID_NOT;
SV_PushEntity (check, move);
pusher->v.solid = SOLID_BSP;
SV_PushEntity (check, move, vec3_origin);
pusher->v.solid = oldsolid;
// if it is still inside the pusher, block
// if it is still inside the pusher, block
block = SV_TestEntityPosition (check);
if (block)
{ // fail the move
{
// fail the move
if (check->v.mins[0] == check->v.maxs[0])
continue;
if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
{ // corpse
{
// corpse
check->v.mins[0] = check->v.mins[1] = 0;
VectorCopy (check->v.mins, check->v.maxs);
continue;
@ -532,22 +565,22 @@ void SV_PushMove (edict_t *pusher, float movetime)
// otherwise, just stay in place until the obstacle is gone
if (pusher->v.blocked)
{
pr_global_struct->self = EDICT_TO_PROG(pusher);
pr_global_struct->other = EDICT_TO_PROG(check);
pr_global_struct->self = EDICT_TO_PROG (pusher);
pr_global_struct->other = EDICT_TO_PROG (check);
PR_ExecuteProgram (pusher->v.blocked);
}
// move back any entities we already moved
for (i=0 ; i<num_moved ; i++)
// move back any entities we already moved
for (i = 0; i < num_moved; i++)
{
VectorCopy (moved_from[i], moved_edict[i]->v.origin);
SV_LinkEdict (moved_edict[i], false);
SV_LinkEdict (moved_edict[i], (moved_edict[i] == check) ? true : false);
}
return;
return check;
}
}
return NULL;
}
@ -557,46 +590,52 @@ SV_PushRotate
============
*/
void SV_PushRotate (edict_t *pusher, float movetime)
edict_t * SV_PushRotate (edict_t *pusher, float movetime)
{
int i, e;
edict_t *check, *block;
vec3_t move, a, amove;
vec3_t entorig, pushorig;
int num_moved;
edict_t *moved_edict[MAX_EDICTS];
vec3_t moved_from[MAX_EDICTS];
vec3_t org, org2;
vec3_t forward, right, up;
int i, e, oldsolid;
matrix4x4 start_l, end_l;;
edict_t *check, *block;
vec3_t move, amove;
vec3_t entorig, pushorig;
int num_moved;
vec3_t org, org2, temp;
if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2])
{
pusher->v.ltime += movetime;
return;
return NULL;
}
for (i=0 ; i<3 ; i++)
for (i = 0; i < 3; i++)
amove[i] = pusher->v.avelocity[i] * movetime;
VectorSubtract (vec3_origin, amove, a);
AngleVectors (a, forward, right, up);
// create pusher initial position
Matrix4x4_CreateFromEntity( start_l, pusher->v.angles, pusher->v.origin, 1.0f );
VectorCopy (pusher->v.angles, pushorig);
// move the pusher to it's final position
// move the pusher to it's final position
VectorAdd (pusher->v.angles, amove, pusher->v.angles);
pusher->v.ltime += movetime;
SV_LinkEdict (pusher, false);
oldsolid = pusher->v.solid;
// non-solid pushers can't push anything
if( pusher->v.solid == SOLID_NOT )
return NULL;
// see if any solid entities are inside the final position
num_moved = 0;
check = NEXT_EDICT(sv.edicts);
for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
// create pusher final position
Matrix4x4_CreateFromEntity( end_l, pusher->v.angles, pusher->v.origin, 1.0f );
// see if any solid entities are inside the final position
num_moved = 0;
check = NEXT_EDICT (sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check))
{
if (check->free)
continue;
if (check->v.movetype == MOVETYPE_PUSH
|| check->v.movetype == MOVETYPE_NONE
|| check->v.movetype == MOVETYPE_FOLLOW
@ -606,52 +645,60 @@ void SV_PushRotate (edict_t *pusher, float movetime)
|| check->v.movetype == MOVETYPE_HEAD)
continue;
// if the entity is standing on the pusher, it will definately be moved
if ( ! ( ((int)check->v.flags & FL_ONGROUND)
&& PROG_TO_EDICT(check->v.groundentity) == pusher) )
// if the entity is standing on the pusher, it will definately be moved
if (!(((int) check->v.flags & FL_ONGROUND) && PROG_TO_EDICT (check->v.groundentity) == pusher))
{
if ( check->v.absmin[0] >= pusher->v.absmax[0]
|| check->v.absmin[1] >= pusher->v.absmax[1]
|| check->v.absmin[2] >= pusher->v.absmax[2]
|| check->v.absmax[0] <= pusher->v.absmin[0]
|| check->v.absmax[1] <= pusher->v.absmin[1]
|| check->v.absmax[2] <= pusher->v.absmin[2] )
if (check->v.absmin[0] >= pusher->v.absmax[0]
|| check->v.absmin[1] >= pusher->v.absmax[1]
|| check->v.absmin[2] >= pusher->v.absmax[2]
|| check->v.absmax[0] <= pusher->v.absmin[0]
|| check->v.absmax[1] <= pusher->v.absmin[1]
|| check->v.absmax[2] <= pusher->v.absmin[2])
continue;
// see if the ent's bbox is inside the pusher's final position
// see if the ent's bbox is inside the pusher's final position
if (!SV_TestEntityPosition (check))
continue;
}
// remove the onground flag for non-players
// remove the onground flag for non-players
if (check->v.movetype != MOVETYPE_WALK)
check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
check->v.flags = (int) check->v.flags & ~FL_ONGROUND;
VectorCopy (check->v.origin, entorig);
VectorCopy (check->v.origin, moved_from[num_moved]);
moved_edict[num_moved] = check;
num_moved++;
// calculate destination position
VectorSubtract (check->v.origin, pusher->v.origin, org);
org2[0] = DotProduct (org, forward);
org2[1] = -DotProduct (org, right);
org2[2] = DotProduct (org, up);
VectorSubtract (org2, org, move);
//if( check->v.movetype == MOVETYPE_PUSHSTEP )
// VectorAverage( check->v.absmin, check->v.absmax, org );
//else
VectorCopy( check->v.origin, org );
Matrix4x4_VectorITransform( start_l, org, temp );
Matrix4x4_VectorTransform( end_l, temp, org2 );
VectorSubtract( org2, org, move );
// try moving the contacted entity
pusher->v.solid = SOLID_NOT;
SV_PushEntity (check, move);
pusher->v.solid = SOLID_BSP;
SV_PushEntity (check, move, amove);
pusher->v.solid = oldsolid;
// if it is still inside the pusher, block
// if it is still inside the pusher, block
block = SV_TestEntityPosition (check);
if (block)
{ // fail the move
{
// fail the move
if (check->v.mins[0] == check->v.maxs[0])
continue;
if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
{ // corpse
{
// corpse
check->v.mins[0] = check->v.mins[1] = 0;
VectorCopy (check->v.mins, check->v.maxs);
continue;
@ -668,27 +715,27 @@ void SV_PushRotate (edict_t *pusher, float movetime)
// otherwise, just stay in place until the obstacle is gone
if (pusher->v.blocked)
{
pr_global_struct->self = EDICT_TO_PROG(pusher);
pr_global_struct->other = EDICT_TO_PROG(check);
pr_global_struct->self = EDICT_TO_PROG (pusher);
pr_global_struct->other = EDICT_TO_PROG (check);
PR_ExecuteProgram (pusher->v.blocked);
}
// move back any entities we already moved
for (i=0 ; i<num_moved ; i++)
// move back any entities we already moved
for (i = 0; i < num_moved; i++)
{
VectorCopy (moved_from[i], moved_edict[i]->v.origin);
VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles);
SV_LinkEdict (moved_edict[i], false);
SV_LinkEdict (moved_edict[i], (moved_edict[i] == check) ? true : false);
}
return;
return check;
}
else
{
VectorAdd (check->v.angles, amove, check->v.angles);
}
}
return NULL;
}
@ -898,7 +945,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
case 7: dir[0] = -2; dir[1] = -2; break;
}
SV_PushEntity (ent, dir);
SV_PushEntity (ent, dir, vec3_origin);
// retry the original move
ent->v.velocity[0] = oldvel[0];
@ -978,7 +1025,7 @@ void SV_WalkMove (edict_t *ent)
downmove[2] = -STEPSIZE + oldvel[2]*host_frametime;
// move up
SV_PushEntity (ent, upmove); // FIXME: don't link?
SV_PushEntity (ent, upmove, vec3_origin); // FIXME: don't link?
// move forward
ent->v.velocity[0] = oldvel[0];
@ -1002,7 +1049,7 @@ void SV_WalkMove (edict_t *ent)
SV_WallFriction (ent, &steptrace);
// move down
downtrace = SV_PushEntity (ent, downmove); // FIXME: don't link?
downtrace = SV_PushEntity (ent, downmove, vec3_origin); // FIXME: don't link?
if (downtrace.plane.normal[2] > 0.7)
{
@ -1075,13 +1122,11 @@ void SV_MonsterWalkMove (edict_t *ent)
vec3_t oldorg, oldvel;
vec3_t nosteporg, nostepvel;
int clip;
int oldonground;
trace_t steptrace, downtrace;
//
// do a regular slide move unless it looks like you ran into a step
//
oldonground = (int)ent->v.flags & FL_ONGROUND;
ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
VectorCopy (ent->v.origin, oldorg);
@ -1525,10 +1570,39 @@ void SV_Physics_Toss (edict_t *ent)
vec3_t move;
float backoff;
#ifdef QUAKE2
edict_t *groundentity;
groundentity = PROG_TO_EDICT(ent->v.groundentity);
if ((int)groundentity->v.flags & FL_CONVEYOR)
VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity);
else
VectorCopy(vec_origin, ent->v.basevelocity);
SV_CheckWater (ent);
#endif
// regular thinking
if (!SV_RunThink (ent))
return;
#ifdef QUAKE2
if (ent->v.velocity[2] > 0)
ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
if ( ((int)ent->v.flags & FL_ONGROUND) )
//@@
if (VectorCompare(ent->v.basevelocity, vec_origin))
return;
SV_CheckVelocity (ent);
// add gravity
if (! ((int)ent->v.flags & FL_ONGROUND)
&& ent->v.movetype != MOVETYPE_FLY
&& ent->v.movetype != MOVETYPE_BOUNCEMISSILE
&& ent->v.movetype != MOVETYPE_FLYMISSILE)
SV_AddGravity (ent);
#else
// if onground, return without moving
if ( ((int)ent->v.flags & FL_ONGROUND) )
return;
@ -1537,16 +1611,22 @@ void SV_Physics_Toss (edict_t *ent)
// add gravity
if (ent->v.movetype != MOVETYPE_FLY
&& ent->v.movetype != MOVETYPE_BOUNCEMISSILE
&& ent->v.movetype != MOVETYPE_FLYMISSILE)
SV_AddGravity (ent);
#endif
// move angles
VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles);
// move origin
#ifdef QUAKE2
VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
#endif
VectorScale (ent->v.velocity, host_frametime, move);
trace = SV_PushEntity (ent, move);
trace = SV_PushEntity (ent, move, vec3_origin);
#ifdef QUAKE2
VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
#endif
if (trace.fraction == 1)
return;
if (ent->free)
@ -1554,8 +1634,10 @@ void SV_Physics_Toss (edict_t *ent)
if (ent->v.movetype == MOVETYPE_BOUNCE)
backoff = 1.5;
#ifdef QUAKE2
else if (ent->v.movetype == MOVETYPE_BOUNCEMISSILE)
backoff = 2.0;
#endif
else
backoff = 1;
@ -1564,7 +1646,11 @@ void SV_Physics_Toss (edict_t *ent)
// stop if on ground
if (trace.plane.normal[2] > 0.7)
{
#ifdef QUAKE2
if (ent->v.velocity[2] < 60 || (ent->v.movetype != MOVETYPE_BOUNCE && ent->v.movetype != MOVETYPE_BOUNCEMISSILE))
#else
if (ent->v.velocity[2] < 60 || ent->v.movetype != MOVETYPE_BOUNCE)
#endif
{
ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
ent->v.groundentity = EDICT_TO_PROG(trace.ent);
@ -1577,6 +1663,7 @@ void SV_Physics_Toss (edict_t *ent)
SV_CheckWaterTransition (ent);
}
/*
===============================================================================

View file

@ -128,7 +128,7 @@ Offset is filled in to contain the adjustment that must be added to the
testing object's origin to get a point to use with the returned hull.
================
*/
hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset, edict_t *move_ent)
{
model_t *model;
vec3_t size;
@ -142,40 +142,43 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
Sys_Error ("SOLID_BSP without MOVETYPE_PUSH");
model = sv.models[ (int)ent->v.modelindex ];
if (!model || model->type != mod_brush)
Sys_Error ("MOVETYPE_PUSH with a non bsp model");
VectorSubtract (maxs, mins, size);
if (model->bspversion == HL_BSPVERSION || model->bspversion == NZP_BSPVERSION)
{
if (size[0] < 3)
if (model->bspversion == HL_BSPVERSION)
{
hull = &model->hulls[0]; // 0x0x0
}
else if (size[0] <= 32)
{
if (size[2] < 54) // pick the nearest of 36 or 72
hull = &model->hulls[3]; // 32x32x36
if (size[0] < 3)
{
hull = &model->hulls[0]; // 0x0x0
}
else if (size[0] <= 32)
{
if (size[2] < 54) // pick the nearest of 36 or 72
hull = &model->hulls[3]; // 32x32x36
else
hull = &model->hulls[1]; // 32x32x72
}
else
hull = &model->hulls[1]; // 32x32x72
{
hull = &model->hulls[2]; // 64x64x64
}
}
else
{
hull = &model->hulls[2]; // 64x64x64
if (size[0] < 3)
hull = &model->hulls[0];
else if (size[0] <= 32)
hull = &model->hulls[1];
else if (size[0] <= 32 && size[2] <= 28) // Crouch
hull = &model->hulls[3];
else
hull = &model->hulls[2];
}
}
else
{
if (size[0] < 3)
hull = &model->hulls[0];
else if (size[0] <= 32)
hull = &model->hulls[1];
else
hull = &model->hulls[2];
}
}
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, ent->v.origin, offset);
@ -720,6 +723,56 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec
return false;
}
/*
==================
SV_WorldTransformAABB
==================
*/
void SV_WorldTransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t maxs, vec3_t outmins, vec3_t outmaxs )
{
vec3_t p1, p2;
matrix4x4 itransform;
int i;
if( !outmins || !outmaxs ) return;
Matrix4x4_Invert_Simple( itransform, transform );
outmins[0] = outmins[1] = outmins[2] = 999999;
outmaxs[0] = outmaxs[1] = outmaxs[2] = -999999;
// compute a full bounding box
for( i = 0; i < 8; i++ )
{
p1[0] = ( i & 1 ) ? mins[0] : maxs[0];
p1[1] = ( i & 2 ) ? mins[1] : maxs[1];
p1[2] = ( i & 4 ) ? mins[2] : maxs[2];
p2[0] = DotProduct( p1, itransform[0] );
p2[1] = DotProduct( p1, itransform[1] );
p2[2] = DotProduct( p1, itransform[2] );
if( p2[0] < outmins[0] ) outmins[0] = p2[0];
if( p2[0] > outmaxs[0] ) outmaxs[0] = p2[0];
if( p2[1] < outmins[1] ) outmins[1] = p2[1];
if( p2[1] > outmaxs[1] ) outmaxs[1] = p2[1];
if( p2[2] < outmins[2] ) outmins[2] = p2[2];
if( p2[2] > outmaxs[2] ) outmaxs[2] = p2[2];
}
// sanity check
for( i = 0; i < 3; i++ )
{
if( outmins[i] > outmaxs[i] )
{
Sys_Error("World_TransformAABB: backwards mins/maxs\n");
outmins[0] = outmins[1] = outmins[2] = 0;
outmaxs[0] = outmaxs[1] = outmaxs[2] = 0;
return;
}
}
}
/*
==================
@ -729,84 +782,89 @@ Handles selection or creation of a clipping hull, and offseting (and
eventually rotation) of the end points
==================
*/
trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *move_ent )
{
trace_t trace;
vec3_t offset;
matrix4x4 matrix;
vec3_t offset, temp;
vec3_t start_l, end_l;
hull_t *hull;
int j;
qboolean transform_bbox = true;
// fill in a default trace
memset (&trace, 0, sizeof(trace_t));
VectorCopy (end, trace.endpos);
trace.fraction = 1;
trace.allsolid = true;
VectorCopy (end, trace.endpos);
// get the clipping hull
hull = SV_HullForEntity (ent, mins, maxs, offset);
hull = SV_HullForEntity (ent, mins, maxs, offset, move_ent);
VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l);
// keep untransformed bbox less than 45 degress or train on subtransit.bsp will stop working
if(( check_angles( ent->v.angles[0] ) || check_angles( ent->v.angles[2] )) && (mins[0] || mins[1] || mins[2]))
transform_bbox = true;
else
transform_bbox = false;
// rotate start and end into the models frame of reference
if (ent->v.solid == SOLID_BSP &&
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) && ent != sv.edicts)//dr_mabuse1981: rotate fix...
if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
{
//vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
vec3_t out_mins, out_maxs;
AngleVectors (ent->v.angles, forward, right, up);
if( transform_bbox )
Matrix4x4_CreateFromEntity( matrix, ent->v.angles, ent->v.origin, 1.0f );
else
Matrix4x4_CreateFromEntity( matrix, ent->v.angles, offset, 1.0f );
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
start_l[1] = -DotProduct (temp, right);
start_l[2] = DotProduct (temp, up);
Matrix4x4_VectorITransform( matrix, start, start_l );
Matrix4x4_VectorITransform( matrix, end, end_l );
VectorCopy (end_l, temp);
end_l[0] = DotProduct (temp, forward);
end_l[1] = -DotProduct (temp, right);
end_l[2] = DotProduct (temp, up);
if( transform_bbox )
{
SV_WorldTransformAABB( matrix, mins, maxs, out_mins, out_maxs );
VectorSubtract( hull->clip_mins, out_mins, offset ); // calc new local offset
for( j = 0; j < 3; j++ )
{
if( start_l[j] >= 0.0f )
start_l[j] -= offset[j];
else start_l[j] += offset[j];
if( end_l[j] >= 0.0f )
end_l[j] -= offset[j];
else end_l[j] += offset[j];
}
}
}
else
{
VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l);
}
// trace a line through the apropriate clipping hull
SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace);
// rotate endpos back to world frame of reference
if (ent->v.solid == SOLID_BSP &&
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) && ent != sv.edicts)
//dr_mabuse1981: rotate fix
if( trace.fraction != 1.0f )
{
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
// compute endpos (generic case)
VectorLerp( start, trace.fraction, end, trace.endpos );
if (trace.fraction != 1)
if(ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
{
VectorSubtract (vec3_origin, ent->v.angles, a);
AngleVectors (a, forward, right, up);
VectorCopy (trace.endpos, temp);
trace.endpos[0] = DotProduct (temp, forward);
trace.endpos[1] = -DotProduct (temp, right);
trace.endpos[2] = DotProduct (temp, up);
VectorCopy (trace.plane.normal, temp);
trace.plane.normal[0] = DotProduct (temp, forward);
trace.plane.normal[1] = -DotProduct (temp, right);
trace.plane.normal[2] = DotProduct (temp, up);
// transform plane
VectorCopy( trace.plane.normal, temp );
Matrix4x4_TransformPositivePlane( matrix, temp, trace.plane.dist, trace.plane.normal, &trace.plane.dist );
}
else
{
trace.plane.dist = DotProduct( trace.endpos, trace.plane.normal );
}
}
// fix trace up by the offset
if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos);
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid )
if( trace.fraction < 1.0f || trace.startsolid )
trace.ent = ent;
return trace;
@ -865,9 +923,10 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
}
if ((int)touch->v.flags & FL_MONSTER)
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, touch);
else
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end);
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, touch);
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
{
@ -937,9 +996,6 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
memset ( &clip, 0, sizeof ( moveclip_t ) );
// clip to world
clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end );
clip.start = start;
clip.end = end;
clip.mins = mins;
@ -947,6 +1003,9 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
clip.type = type;
clip.passedict = passedict;
// clip to world
clip.trace = SV_ClipMoveToEntity( sv.edicts, start, mins, maxs, end, passedict);
if (type == MOVE_MISSILE)
{
for (i=0 ; i<3 ; i++)

View file

@ -62,6 +62,8 @@ int SV_TruePointContents (vec3_t p);
// does not check any entities at all
// the non-true version remaps the water current contents to content_water
#define check_angles( x ) ( (int)x == 90 || (int)x == 180 || (int)x == 270 || (int)x == -90 || (int)x == -180 || (int)x == -270 )
edict_t *SV_TestEntityPosition (edict_t *ent);
qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace);