mirror of
https://github.com/nzp-team/dquakeplus.git
synced 2025-02-21 10:51:06 +00:00
Crow_Bar's VFPU-driven matrix math; ADQ Physics Enhancements
This commit is contained in:
parent
4857dab378
commit
3fcf3a0b1f
7 changed files with 509 additions and 241 deletions
1
MakePHAT
1
MakePHAT
|
@ -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 \
|
||||
|
|
1
MakeSLIM
1
MakeSLIM
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
299
source/sv_phys.c
299
source/sv_phys.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
|
209
source/world.c
209
source/world.c
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue