mirror of
https://github.com/nzp-team/quakespasm.git
synced 2024-11-21 19:31:21 +00:00
Fixed some zombie collision errors -- still incomplete but functional
This commit is contained in:
parent
bcbd9ac17f
commit
b1d3e94186
11 changed files with 6267 additions and 50 deletions
|
@ -106,6 +106,7 @@ SOURCEFILES :=\
|
||||||
source/cfgfile.c \
|
source/cfgfile.c \
|
||||||
source/host.c \
|
source/host.c \
|
||||||
source/host_cmd.c \
|
source/host_cmd.c \
|
||||||
|
source/matrixlib.o \
|
||||||
source/mathlib.c \
|
source/mathlib.c \
|
||||||
source/pr_cmds.c \
|
source/pr_cmds.c \
|
||||||
source/pr_edict.c \
|
source/pr_edict.c \
|
||||||
|
|
|
@ -240,6 +240,7 @@ OBJS :=\
|
||||||
source/cfgfile.o \
|
source/cfgfile.o \
|
||||||
source/host.o \
|
source/host.o \
|
||||||
source/host_cmd.o \
|
source/host_cmd.o \
|
||||||
|
source/matrixlib.o \
|
||||||
source/mathlib.o \
|
source/mathlib.o \
|
||||||
source/pr_cmds.o \
|
source/pr_cmds.o \
|
||||||
source/pr_edict.o \
|
source/pr_edict.o \
|
||||||
|
|
|
@ -32,6 +32,12 @@ float _mathlib_temp_float1, _mathlib_temp_float2, _mathlib_temp_float3;
|
||||||
//#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
|
//#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
|
||||||
#define DEG2RAD( a ) ( (a) * M_PI_DIV_180 ) //johnfitz
|
#define DEG2RAD( a ) ( (a) * M_PI_DIV_180 ) //johnfitz
|
||||||
|
|
||||||
|
void SinCos( float radians, float *sine, float *cosine )
|
||||||
|
{
|
||||||
|
*sine = sin(radians);
|
||||||
|
*cosine = cos(radians);
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
|
void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
|
||||||
{
|
{
|
||||||
float d;
|
float d;
|
||||||
|
|
|
@ -37,6 +37,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
struct mplane_s;
|
struct mplane_s;
|
||||||
|
|
||||||
extern vec3_t vec3_origin;
|
extern vec3_t vec3_origin;
|
||||||
|
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 float matrix3x4[3][4];
|
||||||
|
typedef float matrix3x3[3][3];
|
||||||
|
|
||||||
#define nanmask (255 << 23) /* 7F800000 */
|
#define nanmask (255 << 23) /* 7F800000 */
|
||||||
#if 0 /* macro is violating strict aliasing rules */
|
#if 0 /* macro is violating strict aliasing rules */
|
||||||
|
@ -58,6 +66,7 @@ static inline int IS_NAN (float x) {
|
||||||
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
|
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
|
||||||
#define VectorClear(a) ((a)[0] = (a)[1] = (a)[2] = 0)
|
#define VectorClear(a) ((a)[0] = (a)[1] = (a)[2] = 0)
|
||||||
#define VectorNegate(a, b) ((b)[0] = -(a)[0], (b)[1] = -(a)[1], (b)[2] = -(a)[2])
|
#define VectorNegate(a, b) ((b)[0] = -(a)[0], (b)[1] = -(a)[1], (b)[2] = -(a)[2])
|
||||||
|
#define RAD2DEG( x ) ((float)(x) * (float)(180.f / M_PI))
|
||||||
#define DEG2RAD( a ) ( a * M_PI ) / 180.0F //sB porting seperate viewmodel fov
|
#define DEG2RAD( a ) ( a * M_PI ) / 180.0F //sB porting seperate viewmodel fov
|
||||||
|
|
||||||
//johnfitz -- courtesy of lordhavoc
|
//johnfitz -- courtesy of lordhavoc
|
||||||
|
@ -115,6 +124,46 @@ int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
|
||||||
float anglemod(float a);
|
float anglemod(float a);
|
||||||
void vectoangles (vec3_t vec, vec3_t ang);
|
void vectoangles (vec3_t vec, vec3_t ang);
|
||||||
|
|
||||||
|
void SinCos( float radians, float *sine, float *cosine );
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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_identity2 )
|
||||||
|
#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_identity2;
|
||||||
|
|
||||||
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
|
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
|
||||||
(((p)->type < 3)? \
|
(((p)->type < 3)? \
|
||||||
( \
|
( \
|
||||||
|
|
847
source/matrixlib.c
Normal file
847
source/matrixlib.c
Normal file
|
@ -0,0 +1,847 @@
|
||||||
|
/*
|
||||||
|
matrixlib.c - internal matrixlib
|
||||||
|
Copyright (C) 2010 Uncle Mike
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quakedef.h"
|
||||||
|
|
||||||
|
const matrix3x4 matrix3x4_identity =
|
||||||
|
{
|
||||||
|
{ 1, 0, 0, 0 }, // PITCH [forward], org[0]
|
||||||
|
{ 0, 1, 0, 0 }, // YAW [right] , org[1]
|
||||||
|
{ 0, 0, 1, 0 }, // ROLL [up] , org[2]
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
Matrix3x4 operations
|
||||||
|
|
||||||
|
========================================================================
|
||||||
|
*/
|
||||||
|
void Matrix3x4_VectorTransform( const matrix3x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3];
|
||||||
|
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3];
|
||||||
|
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_VectorITransform( const matrix3x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
vec3_t dir;
|
||||||
|
|
||||||
|
dir[0] = v[0] - in[0][3];
|
||||||
|
dir[1] = v[1] - in[1][3];
|
||||||
|
dir[2] = v[2] - in[2][3];
|
||||||
|
|
||||||
|
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
|
||||||
|
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
|
||||||
|
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_VectorRotate( const matrix3x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2];
|
||||||
|
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2];
|
||||||
|
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_VectorIRotate( const matrix3x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[1][0] + v[2] * in[2][0];
|
||||||
|
out[1] = v[0] * in[0][1] + v[1] * in[1][1] + v[2] * in[2][1];
|
||||||
|
out[2] = v[0] * in[0][2] + v[1] * in[1][2] + v[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_ConcatTransforms( matrix3x4 out, const matrix3x4 in1, const matrix3x4 in2 )
|
||||||
|
{
|
||||||
|
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
|
||||||
|
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
|
||||||
|
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
|
||||||
|
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3];
|
||||||
|
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
|
||||||
|
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
|
||||||
|
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
|
||||||
|
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3];
|
||||||
|
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
|
||||||
|
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
|
||||||
|
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
|
||||||
|
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z )
|
||||||
|
{
|
||||||
|
out[0][3] = x;
|
||||||
|
out[1][3] = y;
|
||||||
|
out[2][3] = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_OriginFromMatrix( const matrix3x4 in, float *out )
|
||||||
|
{
|
||||||
|
out[0] = in[0][3];
|
||||||
|
out[1] = in[1][3];
|
||||||
|
out[2] = in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_AnglesFromMatrix( const matrix3x4 in, vec3_t out )
|
||||||
|
{
|
||||||
|
float xyDist = sqrt( in[0][0] * in[0][0] + in[1][0] * in[1][0] );
|
||||||
|
|
||||||
|
if( xyDist > 0.001f )
|
||||||
|
{
|
||||||
|
// enough here to get angles?
|
||||||
|
out[0] = RAD2DEG( atan2( -in[2][0], xyDist ));
|
||||||
|
out[1] = RAD2DEG( atan2( in[1][0], in[0][0] ));
|
||||||
|
out[2] = RAD2DEG( atan2( in[2][1], in[2][2] ));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// forward is mostly Z, gimbal lock
|
||||||
|
out[0] = RAD2DEG( atan2( -in[2][0], xyDist ));
|
||||||
|
out[1] = RAD2DEG( atan2( -in[0][1], in[1][1] ));
|
||||||
|
out[2] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin )
|
||||||
|
{
|
||||||
|
out[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
|
||||||
|
out[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
|
||||||
|
out[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
|
||||||
|
|
||||||
|
out[0][1] = 2.0f * quaternion[0] * quaternion[1] - 2.0f * quaternion[3] * quaternion[2];
|
||||||
|
out[1][1] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[2] * quaternion[2];
|
||||||
|
out[2][1] = 2.0f * quaternion[1] * quaternion[2] + 2.0f * quaternion[3] * quaternion[0];
|
||||||
|
|
||||||
|
out[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
|
||||||
|
out[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
|
||||||
|
out[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
|
||||||
|
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale )
|
||||||
|
{
|
||||||
|
float angle, sr, sp, sy, cr, cp, cy;
|
||||||
|
|
||||||
|
if( angles[ROLL] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
angle = angles[PITCH] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sp, &cp );
|
||||||
|
angle = angles[ROLL] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sr, &cr );
|
||||||
|
|
||||||
|
out[0][0] = (cp*cy) * scale;
|
||||||
|
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
|
||||||
|
out[0][2] = (cr*sp*cy+-sr*-sy) * scale;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (cp*sy) * scale;
|
||||||
|
out[1][1] = (sr*sp*sy+cr*cy) * scale;
|
||||||
|
out[1][2] = (cr*sp*sy+-sr*cy) * scale;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = (-sp) * scale;
|
||||||
|
out[2][1] = (sr*cp) * scale;
|
||||||
|
out[2][2] = (cr*cp) * scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
else if( angles[PITCH] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
angle = angles[PITCH] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sp, &cp );
|
||||||
|
|
||||||
|
out[0][0] = (cp*cy) * scale;
|
||||||
|
out[0][1] = (-sy) * scale;
|
||||||
|
out[0][2] = (sp*cy) * scale;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (cp*sy) * scale;
|
||||||
|
out[1][1] = (cy) * scale;
|
||||||
|
out[1][2] = (sp*sy) * scale;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = (-sp) * scale;
|
||||||
|
out[2][1] = 0.0f;
|
||||||
|
out[2][2] = (cp) * scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
else if( angles[YAW] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
|
||||||
|
out[0][0] = (cy) * scale;
|
||||||
|
out[0][1] = (-sy) * scale;
|
||||||
|
out[0][2] = 0.0f;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (sy) * scale;
|
||||||
|
out[1][1] = (cy) * scale;
|
||||||
|
out[1][2] = 0.0f;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = 0.0f;
|
||||||
|
out[2][1] = 0.0f;
|
||||||
|
out[2][2] = scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out[0][0] = scale;
|
||||||
|
out[0][1] = 0.0f;
|
||||||
|
out[0][2] = 0.0f;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = 0.0f;
|
||||||
|
out[1][1] = scale;
|
||||||
|
out[1][2] = 0.0f;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = 0.0f;
|
||||||
|
out[2][1] = 0.0f;
|
||||||
|
out[2][2] = scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_TransformPositivePlane( const matrix3x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
|
||||||
|
{
|
||||||
|
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 Matrix3x4_Invert_Simple( matrix3x4 out, const matrix3x4 in1 )
|
||||||
|
{
|
||||||
|
// we only support uniform scaling, so assume the first row is enough
|
||||||
|
// (note the lack of sqrt here, because we're trying to undo the scaling,
|
||||||
|
// this means multiplying by the inverse scale twice - squaring it, which
|
||||||
|
// makes the sqrt a waste of time)
|
||||||
|
float scale = 1.0f / (in1[0][0] * in1[0][0] + in1[0][1] * in1[0][1] + in1[0][2] * in1[0][2]);
|
||||||
|
|
||||||
|
// invert the rotation by transposing and multiplying by the squared
|
||||||
|
// recipricol of the input matrix scale as described above
|
||||||
|
out[0][0] = in1[0][0] * scale;
|
||||||
|
out[0][1] = in1[1][0] * scale;
|
||||||
|
out[0][2] = in1[2][0] * scale;
|
||||||
|
out[1][0] = in1[0][1] * scale;
|
||||||
|
out[1][1] = in1[1][1] * scale;
|
||||||
|
out[1][2] = in1[2][1] * scale;
|
||||||
|
out[2][0] = in1[0][2] * scale;
|
||||||
|
out[2][1] = in1[1][2] * scale;
|
||||||
|
out[2][2] = in1[2][2] * scale;
|
||||||
|
|
||||||
|
// invert the translate
|
||||||
|
out[0][3] = -(in1[0][3] * out[0][0] + in1[1][3] * out[0][1] + in1[2][3] * out[0][2]);
|
||||||
|
out[1][3] = -(in1[0][3] * out[1][0] + in1[1][3] * out[1][1] + in1[2][3] * out[1][2]);
|
||||||
|
out[2][3] = -(in1[0][3] * out[2][0] + in1[1][3] * out[2][1] + in1[2][3] * out[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix3x4_Transpose( matrix3x4 out, const matrix3x4 in1 )
|
||||||
|
{
|
||||||
|
// transpose only rotational component
|
||||||
|
out[0][0] = in1[0][0];
|
||||||
|
out[0][1] = in1[1][0];
|
||||||
|
out[0][2] = in1[2][0];
|
||||||
|
out[1][0] = in1[0][1];
|
||||||
|
out[1][1] = in1[1][1];
|
||||||
|
out[1][2] = in1[2][1];
|
||||||
|
out[2][0] = in1[0][2];
|
||||||
|
out[2][1] = in1[1][2];
|
||||||
|
out[2][2] = in1[2][2];
|
||||||
|
|
||||||
|
// copy origin
|
||||||
|
out[0][3] = in1[0][3];
|
||||||
|
out[1][3] = in1[1][3];
|
||||||
|
out[2][3] = in1[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Matrix3x4_TransformAABB
|
||||||
|
==================
|
||||||
|
|
||||||
|
void Matrix3x4_TransformAABB( const matrix3x4 world, const vec3_t mins, const vec3_t maxs, vec3_t absmin, vec3_t absmax )
|
||||||
|
{
|
||||||
|
vec3_t localCenter, localExtents;
|
||||||
|
vec3_t worldCenter, worldExtents;
|
||||||
|
|
||||||
|
VectorAverage( mins, maxs, localCenter );
|
||||||
|
VectorSubtract( maxs, localCenter, localExtents );
|
||||||
|
|
||||||
|
Matrix3x4_VectorTransform( world, localCenter, worldCenter );
|
||||||
|
worldExtents[0] = DotProductAbs( localExtents, world[0] ); // auto-transposed!
|
||||||
|
worldExtents[1] = DotProductAbs( localExtents, world[1] );
|
||||||
|
worldExtents[2] = DotProductAbs( localExtents, world[2] );
|
||||||
|
|
||||||
|
VectorSubtract( worldCenter, worldExtents, absmin );
|
||||||
|
VectorAdd( worldCenter, worldExtents, absmax );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
const matrix4x4 matrix4x4_identity2 =
|
||||||
|
{
|
||||||
|
{ 1, 0, 0, 0 }, // PITCH
|
||||||
|
{ 0, 1, 0, 0 }, // YAW
|
||||||
|
{ 0, 0, 1, 0 }, // ROLL
|
||||||
|
{ 0, 0, 0, 1 }, // ORIGIN
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
Matrix4x4 operations
|
||||||
|
|
||||||
|
========================================================================
|
||||||
|
*/
|
||||||
|
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3];
|
||||||
|
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3];
|
||||||
|
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
vec3_t dir;
|
||||||
|
|
||||||
|
dir[0] = v[0] - in[0][3];
|
||||||
|
dir[1] = v[1] - in[1][3];
|
||||||
|
dir[2] = v[2] - in[2][3];
|
||||||
|
|
||||||
|
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
|
||||||
|
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
|
||||||
|
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_VectorRotate( const matrix4x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2];
|
||||||
|
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2];
|
||||||
|
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_VectorIRotate( const matrix4x4 in, const float v[3], float out[3] )
|
||||||
|
{
|
||||||
|
out[0] = v[0] * in[0][0] + v[1] * in[1][0] + v[2] * in[2][0];
|
||||||
|
out[1] = v[0] * in[0][1] + v[1] * in[1][1] + v[2] * in[2][1];
|
||||||
|
out[2] = v[0] * in[0][2] + v[1] * in[1][2] + v[2] * in[2][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 )
|
||||||
|
{
|
||||||
|
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
|
||||||
|
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
|
||||||
|
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
|
||||||
|
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3];
|
||||||
|
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
|
||||||
|
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
|
||||||
|
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
|
||||||
|
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3];
|
||||||
|
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
|
||||||
|
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
|
||||||
|
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
|
||||||
|
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_SetOrigin( matrix4x4 out, float x, float y, float z )
|
||||||
|
{
|
||||||
|
out[0][3] = x;
|
||||||
|
out[1][3] = y;
|
||||||
|
out[2][3] = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_OriginFromMatrix( const matrix4x4 in, float *out )
|
||||||
|
{
|
||||||
|
out[0] = in[0][3];
|
||||||
|
out[1] = in[1][3];
|
||||||
|
out[2] = in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_FromOriginQuat( matrix4x4 out, const vec4_t quaternion, const vec3_t origin )
|
||||||
|
{
|
||||||
|
out[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
|
||||||
|
out[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
|
||||||
|
out[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[0][1] = 2.0f * quaternion[0] * quaternion[1] - 2.0f * quaternion[3] * quaternion[2];
|
||||||
|
out[1][1] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[2] * quaternion[2];
|
||||||
|
out[2][1] = 2.0f * quaternion[1] * quaternion[2] + 2.0f * quaternion[3] * quaternion[0];
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
|
||||||
|
out[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
|
||||||
|
out[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0.0f;
|
||||||
|
out[3][1] = 0.0f;
|
||||||
|
out[3][2] = 0.0f;
|
||||||
|
out[3][3] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale )
|
||||||
|
{
|
||||||
|
float angle, sr, sp, sy, cr, cp, cy;
|
||||||
|
|
||||||
|
if( angles[ROLL] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
angle = angles[PITCH] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sp, &cp );
|
||||||
|
angle = angles[ROLL] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sr, &cr );
|
||||||
|
|
||||||
|
out[0][0] = (cp*cy) * scale;
|
||||||
|
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
|
||||||
|
out[0][2] = (cr*sp*cy+-sr*-sy) * scale;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (cp*sy) * scale;
|
||||||
|
out[1][1] = (sr*sp*sy+cr*cy) * scale;
|
||||||
|
out[1][2] = (cr*sp*sy+-sr*cy) * scale;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = (-sp) * scale;
|
||||||
|
out[2][1] = (sr*cp) * scale;
|
||||||
|
out[2][2] = (cr*cp) * scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0.0f;
|
||||||
|
out[3][1] = 0.0f;
|
||||||
|
out[3][2] = 0.0f;
|
||||||
|
out[3][3] = 1.0f;
|
||||||
|
}
|
||||||
|
else if( angles[PITCH] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
angle = angles[PITCH] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sp, &cp );
|
||||||
|
|
||||||
|
out[0][0] = (cp*cy) * scale;
|
||||||
|
out[0][1] = (-sy) * scale;
|
||||||
|
out[0][2] = (sp*cy) * scale;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (cp*sy) * scale;
|
||||||
|
out[1][1] = (cy) * scale;
|
||||||
|
out[1][2] = (sp*sy) * scale;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = (-sp) * scale;
|
||||||
|
out[2][1] = 0.0f;
|
||||||
|
out[2][2] = (cp) * scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0.0f;
|
||||||
|
out[3][1] = 0.0f;
|
||||||
|
out[3][2] = 0.0f;
|
||||||
|
out[3][3] = 1.0f;
|
||||||
|
}
|
||||||
|
else if( angles[YAW] )
|
||||||
|
{
|
||||||
|
angle = angles[YAW] * (M_PI_2 / 360.0f);
|
||||||
|
SinCos( angle, &sy, &cy );
|
||||||
|
|
||||||
|
out[0][0] = (cy) * scale;
|
||||||
|
out[0][1] = (-sy) * scale;
|
||||||
|
out[0][2] = 0.0f;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = (sy) * scale;
|
||||||
|
out[1][1] = (cy) * scale;
|
||||||
|
out[1][2] = 0.0f;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = 0.0f;
|
||||||
|
out[2][1] = 0.0f;
|
||||||
|
out[2][2] = scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0.0f;
|
||||||
|
out[3][1] = 0.0f;
|
||||||
|
out[3][2] = 0.0f;
|
||||||
|
out[3][3] = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out[0][0] = scale;
|
||||||
|
out[0][1] = 0.0f;
|
||||||
|
out[0][2] = 0.0f;
|
||||||
|
out[0][3] = origin[0];
|
||||||
|
out[1][0] = 0.0f;
|
||||||
|
out[1][1] = scale;
|
||||||
|
out[1][2] = 0.0f;
|
||||||
|
out[1][3] = origin[1];
|
||||||
|
out[2][0] = 0.0f;
|
||||||
|
out[2][1] = 0.0f;
|
||||||
|
out[2][2] = scale;
|
||||||
|
out[2][3] = origin[2];
|
||||||
|
out[3][0] = 0.0f;
|
||||||
|
out[3][1] = 0.0f;
|
||||||
|
out[3][2] = 0.0f;
|
||||||
|
out[3][3] = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin )
|
||||||
|
{
|
||||||
|
float xyDist = sqrt( in[0][0] * in[0][0] + in[1][0] * in[1][0] );
|
||||||
|
|
||||||
|
// enough here to get angles?
|
||||||
|
if( xyDist > 0.001f )
|
||||||
|
{
|
||||||
|
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] ));
|
||||||
|
}
|
||||||
|
else // forward is mostly Z, gimbal lock
|
||||||
|
{
|
||||||
|
angles[0] = RAD2DEG( atan2( -in[2][0], xyDist ));
|
||||||
|
angles[1] = RAD2DEG( atan2( -in[0][1], in[1][1] ));
|
||||||
|
angles[2] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
origin[0] = in[0][3];
|
||||||
|
origin[1] = in[1][3];
|
||||||
|
origin[2] = in[2][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
|
||||||
|
{
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
// we only support uniform scaling, so assume the first row is enough
|
||||||
|
// (note the lack of sqrt here, because we're trying to undo the scaling,
|
||||||
|
// this means multiplying by the inverse scale twice - squaring it, which
|
||||||
|
// makes the sqrt a waste of time)
|
||||||
|
float scale = 1.0f / (in1[0][0] * in1[0][0] + in1[0][1] * in1[0][1] + in1[0][2] * in1[0][2]);
|
||||||
|
|
||||||
|
// invert the rotation by transposing and multiplying by the squared
|
||||||
|
// recipricol of the input matrix scale as described above
|
||||||
|
out[0][0] = in1[0][0] * scale;
|
||||||
|
out[0][1] = in1[1][0] * scale;
|
||||||
|
out[0][2] = in1[2][0] * scale;
|
||||||
|
out[1][0] = in1[0][1] * scale;
|
||||||
|
out[1][1] = in1[1][1] * scale;
|
||||||
|
out[1][2] = in1[2][1] * scale;
|
||||||
|
out[2][0] = in1[0][2] * scale;
|
||||||
|
out[2][1] = in1[1][2] * scale;
|
||||||
|
out[2][2] = in1[2][2] * scale;
|
||||||
|
|
||||||
|
// invert the translate
|
||||||
|
out[0][3] = -(in1[0][3] * out[0][0] + in1[1][3] * out[0][1] + in1[2][3] * out[0][2]);
|
||||||
|
out[1][3] = -(in1[0][3] * out[1][0] + in1[1][3] * out[1][1] + in1[2][3] * out[1][2]);
|
||||||
|
out[2][3] = -(in1[0][3] * out[2][0] + in1[1][3] * out[2][1] + in1[2][3] * out[2][2]);
|
||||||
|
|
||||||
|
// don't know if there's anything worth doing here
|
||||||
|
out[3][0] = 0.0f;
|
||||||
|
out[3][1] = 0.0f;
|
||||||
|
out[3][2] = 0.0f;
|
||||||
|
out[3][3] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Matrix4x4_Transpose( matrix4x4 out, const matrix4x4 in1 )
|
||||||
|
{
|
||||||
|
out[0][0] = in1[0][0];
|
||||||
|
out[0][1] = in1[1][0];
|
||||||
|
out[0][2] = in1[2][0];
|
||||||
|
out[0][3] = in1[3][0];
|
||||||
|
out[1][0] = in1[0][1];
|
||||||
|
out[1][1] = in1[1][1];
|
||||||
|
out[1][2] = in1[2][1];
|
||||||
|
out[1][3] = in1[3][1];
|
||||||
|
out[2][0] = in1[0][2];
|
||||||
|
out[2][1] = in1[1][2];
|
||||||
|
out[2][2] = in1[2][2];
|
||||||
|
out[2][3] = in1[3][2];
|
||||||
|
out[3][0] = in1[0][3];
|
||||||
|
out[3][1] = in1[1][3];
|
||||||
|
out[3][2] = in1[2][3];
|
||||||
|
out[3][3] = in1[3][3];
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean Matrix4x4_Invert_Full( matrix4x4 out, const matrix4x4 in1 )
|
||||||
|
{
|
||||||
|
float *temp;
|
||||||
|
float *r[4];
|
||||||
|
float rtemp[4][8];
|
||||||
|
float m[4];
|
||||||
|
float s;
|
||||||
|
|
||||||
|
r[0] = rtemp[0];
|
||||||
|
r[1] = rtemp[1];
|
||||||
|
r[2] = rtemp[2];
|
||||||
|
r[3] = rtemp[3];
|
||||||
|
|
||||||
|
r[0][0] = in1[0][0];
|
||||||
|
r[0][1] = in1[0][1];
|
||||||
|
r[0][2] = in1[0][2];
|
||||||
|
r[0][3] = in1[0][3];
|
||||||
|
r[0][4] = 1.0f;
|
||||||
|
r[0][5] = 0.0f;
|
||||||
|
r[0][6] = 0.0f;
|
||||||
|
r[0][7] = 0.0f;
|
||||||
|
|
||||||
|
r[1][0] = in1[1][0];
|
||||||
|
r[1][1] = in1[1][1];
|
||||||
|
r[1][2] = in1[1][2];
|
||||||
|
r[1][3] = in1[1][3];
|
||||||
|
r[1][5] = 1.0f;
|
||||||
|
r[1][4] = 0.0f;
|
||||||
|
r[1][6] = 0.0f;
|
||||||
|
r[1][7] = 0.0f;
|
||||||
|
|
||||||
|
r[2][0] = in1[2][0];
|
||||||
|
r[2][1] = in1[2][1];
|
||||||
|
r[2][2] = in1[2][2];
|
||||||
|
r[2][3] = in1[2][3];
|
||||||
|
r[2][6] = 1.0f;
|
||||||
|
r[2][4] = 0.0f;
|
||||||
|
r[2][5] = 0.0f;
|
||||||
|
r[2][7] = 0.0f;
|
||||||
|
|
||||||
|
r[3][0] = in1[3][0];
|
||||||
|
r[3][1] = in1[3][1];
|
||||||
|
r[3][2] = in1[3][2];
|
||||||
|
r[3][3] = in1[3][3];
|
||||||
|
r[3][4] = 0.0f;
|
||||||
|
r[3][5] = 0.0f;
|
||||||
|
r[3][6] = 0.0f;
|
||||||
|
r[3][7] = 1.0f;
|
||||||
|
|
||||||
|
if( fabs( r[3][0] ) > fabs( r[2][0] ))
|
||||||
|
{
|
||||||
|
temp = r[3];
|
||||||
|
r[3] = r[2];
|
||||||
|
r[2] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fabs( r[2][0] ) > fabs( r[1][0] ))
|
||||||
|
{
|
||||||
|
temp = r[2];
|
||||||
|
r[2] = r[1];
|
||||||
|
r[1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fabs( r[1][0] ) > fabs( r[0][0] ))
|
||||||
|
{
|
||||||
|
temp = r[1];
|
||||||
|
r[1] = r[0];
|
||||||
|
r[0] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( r[0][0] )
|
||||||
|
{
|
||||||
|
m[1] = r[1][0] / r[0][0];
|
||||||
|
m[2] = r[2][0] / r[0][0];
|
||||||
|
m[3] = r[3][0] / r[0][0];
|
||||||
|
|
||||||
|
s = r[0][1];
|
||||||
|
r[1][1] -= m[1] * s;
|
||||||
|
r[2][1] -= m[2] * s;
|
||||||
|
r[3][1] -= m[3] * s;
|
||||||
|
|
||||||
|
s = r[0][2];
|
||||||
|
r[1][2] -= m[1] * s;
|
||||||
|
r[2][2] -= m[2] * s;
|
||||||
|
r[3][2] -= m[3] * s;
|
||||||
|
|
||||||
|
s = r[0][3];
|
||||||
|
r[1][3] -= m[1] * s;
|
||||||
|
r[2][3] -= m[2] * s;
|
||||||
|
r[3][3] -= m[3] * s;
|
||||||
|
|
||||||
|
s = r[0][4];
|
||||||
|
if( s )
|
||||||
|
{
|
||||||
|
r[1][4] -= m[1] * s;
|
||||||
|
r[2][4] -= m[2] * s;
|
||||||
|
r[3][4] -= m[3] * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = r[0][5];
|
||||||
|
if( s )
|
||||||
|
{
|
||||||
|
r[1][5] -= m[1] * s;
|
||||||
|
r[2][5] -= m[2] * s;
|
||||||
|
r[3][5] -= m[3] * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = r[0][6];
|
||||||
|
if( s )
|
||||||
|
{
|
||||||
|
r[1][6] -= m[1] * s;
|
||||||
|
r[2][6] -= m[2] * s;
|
||||||
|
r[3][6] -= m[3] * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = r[0][7];
|
||||||
|
if( s )
|
||||||
|
{
|
||||||
|
r[1][7] -= m[1] * s;
|
||||||
|
r[2][7] -= m[2] * s;
|
||||||
|
r[3][7] -= m[3] * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fabs( r[3][1] ) > fabs( r[2][1] ))
|
||||||
|
{
|
||||||
|
temp = r[3];
|
||||||
|
r[3] = r[2];
|
||||||
|
r[2] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fabs( r[2][1] ) > fabs( r[1][1] ))
|
||||||
|
{
|
||||||
|
temp = r[2];
|
||||||
|
r[2] = r[1];
|
||||||
|
r[1] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( r[1][1] )
|
||||||
|
{
|
||||||
|
m[2] = r[2][1] / r[1][1];
|
||||||
|
m[3] = r[3][1] / r[1][1];
|
||||||
|
r[2][2] -= m[2] * r[1][2];
|
||||||
|
r[3][2] -= m[3] * r[1][2];
|
||||||
|
r[2][3] -= m[2] * r[1][3];
|
||||||
|
r[3][3] -= m[3] * r[1][3];
|
||||||
|
|
||||||
|
s = r[1][4];
|
||||||
|
if( s )
|
||||||
|
{
|
||||||
|
r[2][4] -= m[2] * s;
|
||||||
|
r[3][4] -= m[3] * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = r[1][5];
|
||||||
|
if( s )
|
||||||
|
{
|
||||||
|
r[2][5] -= m[2] * s;
|
||||||
|
r[3][5] -= m[3] * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = r[1][6];
|
||||||
|
if( s )
|
||||||
|
{
|
||||||
|
r[2][6] -= m[2] * s;
|
||||||
|
r[3][6] -= m[3] * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = r[1][7];
|
||||||
|
if( s )
|
||||||
|
{
|
||||||
|
r[2][7] -= m[2] * s;
|
||||||
|
r[3][7] -= m[3] * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fabs( r[3][2] ) > fabs( r[2][2] ))
|
||||||
|
{
|
||||||
|
temp = r[3];
|
||||||
|
r[3] = r[2];
|
||||||
|
r[2] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( r[2][2] )
|
||||||
|
{
|
||||||
|
m[3] = r[3][2] / r[2][2];
|
||||||
|
r[3][3] -= m[3] * r[2][3];
|
||||||
|
r[3][4] -= m[3] * r[2][4];
|
||||||
|
r[3][5] -= m[3] * r[2][5];
|
||||||
|
r[3][6] -= m[3] * r[2][6];
|
||||||
|
r[3][7] -= m[3] * r[2][7];
|
||||||
|
|
||||||
|
if( r[3][3] )
|
||||||
|
{
|
||||||
|
s = 1.0f / r[3][3];
|
||||||
|
r[3][4] *= s;
|
||||||
|
r[3][5] *= s;
|
||||||
|
r[3][6] *= s;
|
||||||
|
r[3][7] *= s;
|
||||||
|
|
||||||
|
m[2] = r[2][3];
|
||||||
|
s = 1.0f / r[2][2];
|
||||||
|
r[2][4] = s * (r[2][4] - r[3][4] * m[2]);
|
||||||
|
r[2][5] = s * (r[2][5] - r[3][5] * m[2]);
|
||||||
|
r[2][6] = s * (r[2][6] - r[3][6] * m[2]);
|
||||||
|
r[2][7] = s * (r[2][7] - r[3][7] * m[2]);
|
||||||
|
|
||||||
|
m[1] = r[1][3];
|
||||||
|
r[1][4] -= r[3][4] * m[1];
|
||||||
|
r[1][5] -= r[3][5] * m[1];
|
||||||
|
r[1][6] -= r[3][6] * m[1];
|
||||||
|
r[1][7] -= r[3][7] * m[1];
|
||||||
|
|
||||||
|
m[0] = r[0][3];
|
||||||
|
r[0][4] -= r[3][4] * m[0];
|
||||||
|
r[0][5] -= r[3][5] * m[0];
|
||||||
|
r[0][6] -= r[3][6] * m[0];
|
||||||
|
r[0][7] -= r[3][7] * m[0];
|
||||||
|
|
||||||
|
m[1] = r[1][2];
|
||||||
|
s = 1.0f / r[1][1];
|
||||||
|
r[1][4] = s * (r[1][4] - r[2][4] * m[1]);
|
||||||
|
r[1][5] = s * (r[1][5] - r[2][5] * m[1]);
|
||||||
|
r[1][6] = s * (r[1][6] - r[2][6] * m[1]);
|
||||||
|
r[1][7] = s * (r[1][7] - r[2][7] * m[1]);
|
||||||
|
|
||||||
|
m[0] = r[0][2];
|
||||||
|
r[0][4] -= r[2][4] * m[0];
|
||||||
|
r[0][5] -= r[2][5] * m[0];
|
||||||
|
r[0][6] -= r[2][6] * m[0];
|
||||||
|
r[0][7] -= r[2][7] * m[0];
|
||||||
|
|
||||||
|
m[0] = r[0][1];
|
||||||
|
s = 1.0f / r[0][0];
|
||||||
|
r[0][4] = s * (r[0][4] - r[1][4] * m[0]);
|
||||||
|
r[0][5] = s * (r[0][5] - r[1][5] * m[0]);
|
||||||
|
r[0][6] = s * (r[0][6] - r[1][6] * m[0]);
|
||||||
|
r[0][7] = s * (r[0][7] - r[1][7] * m[0]);
|
||||||
|
|
||||||
|
out[0][0] = r[0][4];
|
||||||
|
out[0][1] = r[0][5];
|
||||||
|
out[0][2] = r[0][6];
|
||||||
|
out[0][3] = r[0][7];
|
||||||
|
out[1][0] = r[1][4];
|
||||||
|
out[1][1] = r[1][5];
|
||||||
|
out[1][2] = r[1][6];
|
||||||
|
out[1][3] = r[1][7];
|
||||||
|
out[2][0] = r[2][4];
|
||||||
|
out[2][1] = r[2][5];
|
||||||
|
out[2][2] = r[2][6];
|
||||||
|
out[2][3] = r[2][7];
|
||||||
|
out[3][0] = r[3][4];
|
||||||
|
out[3][1] = r[3][5];
|
||||||
|
out[3][2] = r[3][6];
|
||||||
|
out[3][3] = r[3][7];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -893,6 +893,35 @@ void PF_tracemove(void)//progs side
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PF_tracebox (void)
|
||||||
|
{
|
||||||
|
float *v1, *v2, *mins, *maxs;
|
||||||
|
trace_t trace;
|
||||||
|
int nomonsters;
|
||||||
|
edict_t *ent;
|
||||||
|
|
||||||
|
v1 = G_VECTOR(OFS_PARM0);
|
||||||
|
mins = G_VECTOR(OFS_PARM1);
|
||||||
|
maxs = G_VECTOR(OFS_PARM2);
|
||||||
|
v2 = G_VECTOR(OFS_PARM3);
|
||||||
|
nomonsters = G_FLOAT(OFS_PARM4);
|
||||||
|
ent = G_EDICT(OFS_PARM5);
|
||||||
|
|
||||||
|
trace = SV_Move (v1, mins, maxs, v2, nomonsters, ent);
|
||||||
|
|
||||||
|
pr_global_struct->trace_allsolid = trace.allsolid;
|
||||||
|
pr_global_struct->trace_startsolid = trace.startsolid;
|
||||||
|
pr_global_struct->trace_fraction = trace.fraction;
|
||||||
|
pr_global_struct->trace_inwater = trace.inwater;
|
||||||
|
pr_global_struct->trace_inopen = trace.inopen;
|
||||||
|
VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
|
||||||
|
VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
|
||||||
|
pr_global_struct->trace_plane_dist = trace.plane.dist;
|
||||||
|
if (trace.ent)
|
||||||
|
pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
|
||||||
|
else
|
||||||
|
pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
PF_checkpos
|
PF_checkpos
|
||||||
|
@ -3181,7 +3210,7 @@ static builtin_t pr_builtin[] =
|
||||||
PF_useprint, // #87
|
PF_useprint, // #87
|
||||||
Get_First_Waypoint, // #88
|
Get_First_Waypoint, // #88
|
||||||
NULL, // #89
|
NULL, // #89
|
||||||
NULL, // #90
|
PF_tracebox, // #90
|
||||||
NULL, // #91
|
NULL, // #91
|
||||||
NULL, // #92
|
NULL, // #92
|
||||||
NULL, // #93
|
NULL, // #93
|
||||||
|
|
3233
source/pr_cmds.c.bak
Normal file
3233
source/pr_cmds.c.bak
Normal file
File diff suppressed because it is too large
Load diff
|
@ -129,6 +129,7 @@ typedef struct client_s
|
||||||
#define MOVETYPE_NOCLIP 8
|
#define MOVETYPE_NOCLIP 8
|
||||||
#define MOVETYPE_FLYMISSILE 9 // extra size to monsters
|
#define MOVETYPE_FLYMISSILE 9 // extra size to monsters
|
||||||
#define MOVETYPE_BOUNCE 10
|
#define MOVETYPE_BOUNCE 10
|
||||||
|
#define MOVETYPE_FOLLOW 12
|
||||||
#define MOVETYPE_HEAD 13 // track movement of head
|
#define MOVETYPE_HEAD 13 // track movement of head
|
||||||
#define MOVETYPE_LARM 14 // track movement of larm
|
#define MOVETYPE_LARM 14 // track movement of larm
|
||||||
#define MOVETYPE_RARM 15 // track movement of rarm
|
#define MOVETYPE_RARM 15 // track movement of rarm
|
||||||
|
|
154
source/sv_move.c
154
source/sv_move.c
|
@ -320,7 +320,96 @@ void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
|
||||||
}
|
}
|
||||||
|
|
||||||
// try other directions
|
// try other directions
|
||||||
if ( ((rand()&3) & 1) || abs((int)deltay)>abs((int)deltax)) // ericw -- explicit int cast to suppress clang suggestion to use fabsf
|
if ( ((rand()&3) & 1) || abs(deltay)>abs(deltax))
|
||||||
|
{
|
||||||
|
tdir=d[1];
|
||||||
|
d[1]=d[2];
|
||||||
|
d[2]=tdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d[1]!=DI_NODIR && d[1]!=turnaround
|
||||||
|
&& SV_StepDirection(actor, d[1], dist))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (d[2]!=DI_NODIR && d[2]!=turnaround
|
||||||
|
&& SV_StepDirection(actor, d[2], dist))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* there is no direct path to the player, so pick another direction */
|
||||||
|
|
||||||
|
if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (rand()&1) /*randomly determine direction of search*/
|
||||||
|
{
|
||||||
|
for (tdir=0 ; tdir<=315 ; tdir += 45)
|
||||||
|
if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (tdir=315 ; tdir >=0 ; tdir -= 45)
|
||||||
|
if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
actor->v.ideal_yaw = olddir; // can't move
|
||||||
|
|
||||||
|
// if a bridge was pulled out from underneath a monster, it may not have
|
||||||
|
// a valid standing position at all
|
||||||
|
|
||||||
|
if (!SV_CheckBottom (actor))
|
||||||
|
SV_FixCheckBottom (actor);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
SV_NewChaseDirO
|
||||||
|
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void SV_NewChaseDirO (edict_t *actor, vec3_t goal, float dist)
|
||||||
|
{
|
||||||
|
float deltax,deltay;
|
||||||
|
float d[3];
|
||||||
|
float tdir, olddir, turnaround;
|
||||||
|
|
||||||
|
olddir = anglemod( (int)(actor->v.ideal_yaw/45)*45 );
|
||||||
|
turnaround = anglemod(olddir - 180);
|
||||||
|
|
||||||
|
deltax = goal[0] - actor->v.origin[0];
|
||||||
|
deltay = goal[1] - actor->v.origin[1];
|
||||||
|
if (deltax>10)
|
||||||
|
d[1]= 0;
|
||||||
|
else if (deltax<-10)
|
||||||
|
d[1]= 180;
|
||||||
|
else
|
||||||
|
d[1]= DI_NODIR;
|
||||||
|
if (deltay<-10)
|
||||||
|
d[2]= 270;
|
||||||
|
else if (deltay>10)
|
||||||
|
d[2]= 90;
|
||||||
|
else
|
||||||
|
d[2]= DI_NODIR;
|
||||||
|
|
||||||
|
// try direct route
|
||||||
|
if (d[1] != DI_NODIR && d[2] != DI_NODIR)
|
||||||
|
{
|
||||||
|
if (d[1] == 0)
|
||||||
|
tdir = d[2] == 90 ? 45 : 315;
|
||||||
|
else
|
||||||
|
tdir = d[2] == 90 ? 135 : 215;
|
||||||
|
|
||||||
|
if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try other directions
|
||||||
|
if ( ((rand()&3) & 1) || abs(deltay)>abs(deltax))
|
||||||
{
|
{
|
||||||
tdir=d[1];
|
tdir=d[1];
|
||||||
d[1]=d[2];
|
d[1]=d[2];
|
||||||
|
@ -386,6 +475,26 @@ qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
======================
|
||||||
|
SV_CloseEnough
|
||||||
|
|
||||||
|
======================
|
||||||
|
*/
|
||||||
|
qboolean SV_CloseEnoughO (edict_t *ent, vec3_t goal, float dist)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0 ; i<3 ; i++)
|
||||||
|
{
|
||||||
|
if (goal[i] > ent->v.absmax[i] + dist)
|
||||||
|
return false;
|
||||||
|
if (goal[i] < ent->v.absmin[i] - dist)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
======================
|
======================
|
||||||
SV_MoveToGoal
|
SV_MoveToGoal
|
||||||
|
@ -393,6 +502,39 @@ SV_MoveToGoal
|
||||||
======================
|
======================
|
||||||
*/
|
*/
|
||||||
void SV_MoveToGoal (void)
|
void SV_MoveToGoal (void)
|
||||||
|
{
|
||||||
|
edict_t *ent;
|
||||||
|
float dist;
|
||||||
|
float *goal;
|
||||||
|
|
||||||
|
ent = PROG_TO_EDICT(pr_global_struct->self);
|
||||||
|
|
||||||
|
dist = G_FLOAT(OFS_PARM0);
|
||||||
|
goal = G_VECTOR(OFS_PARM1);
|
||||||
|
|
||||||
|
if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
|
||||||
|
{
|
||||||
|
G_FLOAT(OFS_RETURN) = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the next step hits the enemy, return immediately
|
||||||
|
if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnoughO (ent, goal, dist) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// bump around...
|
||||||
|
if ((rand()&3)==1 || !SV_StepDirection (ent, ent->v.ideal_yaw, dist))
|
||||||
|
SV_NewChaseDirO (ent, goal, dist);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
======================
|
||||||
|
SV_MoveToOrigin
|
||||||
|
|
||||||
|
======================
|
||||||
|
*/
|
||||||
|
void SV_MoveToOrigin (void)
|
||||||
{
|
{
|
||||||
edict_t *ent, *goal;
|
edict_t *ent, *goal;
|
||||||
float dist;
|
float dist;
|
||||||
|
@ -408,14 +550,12 @@ void SV_MoveToGoal (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the next step hits the enemy, return immediately
|
// if the next step hits the enemy, return immediately
|
||||||
if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnough (ent, goal, dist) )
|
if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts && SV_CloseEnough (ent, goal, dist) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// bump around...
|
// bump around...
|
||||||
if ( (rand()&3)==1 ||
|
if ((rand()&3)==1 || !SV_StepDirection (ent, ent->v.ideal_yaw, dist))
|
||||||
!SV_StepDirection (ent, ent->v.ideal_yaw, dist))
|
SV_NewChaseDir (ent, goal, dist);
|
||||||
{
|
|
||||||
SV_NewChaseDir (ent, goal, dist);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
263
source/sv_phys.c
263
source/sv_phys.c
|
@ -71,6 +71,7 @@ void SV_CheckAllEnts (void)
|
||||||
continue;
|
continue;
|
||||||
if (check->v.movetype == MOVETYPE_PUSH
|
if (check->v.movetype == MOVETYPE_PUSH
|
||||||
|| check->v.movetype == MOVETYPE_NONE
|
|| check->v.movetype == MOVETYPE_NONE
|
||||||
|
|| check->v.movetype == MOVETYPE_FOLLOW
|
||||||
|| check->v.movetype == MOVETYPE_NOCLIP)
|
|| check->v.movetype == MOVETYPE_NOCLIP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -123,8 +124,6 @@ Returns false if the entity removed itself.
|
||||||
qboolean SV_RunThink (edict_t *ent)
|
qboolean SV_RunThink (edict_t *ent)
|
||||||
{
|
{
|
||||||
float thinktime;
|
float thinktime;
|
||||||
float oldframe; //johnfitz
|
|
||||||
int i; //johnfitz
|
|
||||||
|
|
||||||
thinktime = ent->v.nextthink;
|
thinktime = ent->v.nextthink;
|
||||||
if (thinktime <= 0 || thinktime > sv.time + host_frametime)
|
if (thinktime <= 0 || thinktime > sv.time + host_frametime)
|
||||||
|
@ -135,7 +134,6 @@ qboolean SV_RunThink (edict_t *ent)
|
||||||
// it is possible to start that way
|
// it is possible to start that way
|
||||||
// by a trigger with a local time.
|
// by a trigger with a local time.
|
||||||
|
|
||||||
oldframe = ent->v.frame; //johnfitz
|
|
||||||
|
|
||||||
ent->v.nextthink = 0;
|
ent->v.nextthink = 0;
|
||||||
pr_global_struct->time = thinktime;
|
pr_global_struct->time = thinktime;
|
||||||
|
@ -143,17 +141,6 @@ qboolean SV_RunThink (edict_t *ent)
|
||||||
pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
|
pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
|
||||||
PR_ExecuteProgram (ent->v.think);
|
PR_ExecuteProgram (ent->v.think);
|
||||||
|
|
||||||
//johnfitz -- PROTOCOL_FITZQUAKE
|
|
||||||
//capture interval to nextthink here and send it to client for better
|
|
||||||
//lerp timing, but only if interval is not 0.1 (which client assumes)
|
|
||||||
ent->sendinterval = false;
|
|
||||||
if (!ent->free && ent->v.nextthink && (ent->v.movetype == MOVETYPE_STEP || ent->v.frame != oldframe))
|
|
||||||
{
|
|
||||||
i = Q_rint((ent->v.nextthink-thinktime)*255);
|
|
||||||
if (i >= 0 && i < 256 && i != 25 && i != 26) //25 and 26 are close enough to 0.1 to not send
|
|
||||||
ent->sendinterval = true;
|
|
||||||
}
|
|
||||||
//johnfitz
|
|
||||||
|
|
||||||
return !ent->free;
|
return !ent->free;
|
||||||
}
|
}
|
||||||
|
@ -406,6 +393,23 @@ PUSHMOVE
|
||||||
===============================================================================
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
SV_AllowPushRotate
|
||||||
|
Allows to change entity yaw?
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
qboolean SV_AllowPushRotate( edict_t *ent )
|
||||||
|
{
|
||||||
|
qmodel_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
|
SV_PushEntity
|
||||||
|
@ -413,7 +417,7 @@ SV_PushEntity
|
||||||
Does not change the entities velocity at all
|
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;
|
trace_t trace;
|
||||||
vec3_t end;
|
vec3_t end;
|
||||||
|
@ -428,7 +432,21 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push)
|
||||||
else
|
else
|
||||||
trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
|
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);
|
SV_LinkEdict (ent, true);
|
||||||
|
|
||||||
if (trace.ent)
|
if (trace.ent)
|
||||||
|
@ -443,9 +461,11 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push)
|
||||||
SV_PushMove
|
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) //sB modified to match dquake
|
||||||
{
|
{
|
||||||
int i, e;
|
int i, e, oldsolid;
|
||||||
edict_t *check, *block;
|
edict_t *check, *block;
|
||||||
vec3_t mins, maxs, move;
|
vec3_t mins, maxs, move;
|
||||||
vec3_t entorig, pushorig;
|
vec3_t entorig, pushorig;
|
||||||
|
@ -457,7 +477,7 @@ void SV_PushMove (edict_t *pusher, float movetime)
|
||||||
if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
|
if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
|
||||||
{
|
{
|
||||||
pusher->v.ltime += movetime;
|
pusher->v.ltime += movetime;
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
|
@ -472,15 +492,20 @@ void SV_PushMove (edict_t *pusher, float movetime)
|
||||||
// move the pusher to it's final position
|
// move the pusher to it's final position
|
||||||
|
|
||||||
VectorAdd (pusher->v.origin, move, pusher->v.origin);
|
VectorAdd (pusher->v.origin, move, pusher->v.origin);
|
||||||
pusher->v.ltime += movetime;
|
|
||||||
SV_LinkEdict (pusher, false);
|
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;
|
||||||
|
/*
|
||||||
//johnfitz -- dynamically allocate
|
//johnfitz -- dynamically allocate
|
||||||
mark = Hunk_LowMark ();
|
mark = Hunk_LowMark ();
|
||||||
moved_edict = (edict_t **) Hunk_Alloc (sv.num_edicts*sizeof(edict_t *));
|
moved_edict = (edict_t **) Hunk_Alloc (sv.num_edicts*sizeof(edict_t *));
|
||||||
moved_from = (vec3_t *) Hunk_Alloc (sv.num_edicts*sizeof(vec3_t));
|
moved_from = (vec3_t *) Hunk_Alloc (sv.num_edicts*sizeof(vec3_t));
|
||||||
//johnfitz
|
//johnfitz
|
||||||
|
*/
|
||||||
// see if any solid entities are inside the final position
|
// see if any solid entities are inside the final position
|
||||||
num_moved = 0;
|
num_moved = 0;
|
||||||
check = NEXT_EDICT(sv.edicts);
|
check = NEXT_EDICT(sv.edicts);
|
||||||
|
@ -521,8 +546,8 @@ void SV_PushMove (edict_t *pusher, float movetime)
|
||||||
|
|
||||||
// try moving the contacted entity
|
// try moving the contacted entity
|
||||||
pusher->v.solid = SOLID_NOT;
|
pusher->v.solid = SOLID_NOT;
|
||||||
SV_PushEntity (check, move);
|
SV_PushEntity (check, move, vec3_origin);
|
||||||
pusher->v.solid = SOLID_BSP;
|
pusher->v.solid = oldsolid;
|
||||||
|
|
||||||
// if it is still inside the pusher, block
|
// if it is still inside the pusher, block
|
||||||
block = SV_TestEntityPosition (check);
|
block = SV_TestEntityPosition (check);
|
||||||
|
@ -557,24 +582,176 @@ void SV_PushMove (edict_t *pusher, float movetime)
|
||||||
for (i=0 ; i<num_moved ; i++)
|
for (i=0 ; i<num_moved ; i++)
|
||||||
{
|
{
|
||||||
VectorCopy (moved_from[i], moved_edict[i]->v.origin);
|
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);
|
||||||
}
|
}
|
||||||
Hunk_FreeToLowMark (mark); //johnfitz
|
//Hunk_FreeToLowMark (mark); //johnfitz
|
||||||
return;
|
return check;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hunk_FreeToLowMark (mark); //johnfitz
|
//Hunk_FreeToLowMark (mark); //johnfitz
|
||||||
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
SV_PushRotate
|
||||||
|
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
edict_t * SV_PushRotate (edict_t *pusher, float movetime)
|
||||||
|
{
|
||||||
|
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 NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
amove[i] = pusher->v.avelocity[i] * movetime;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
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;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|| 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 (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
|
||||||
|
if (!SV_TestEntityPosition (check))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the onground flag for non-players
|
||||||
|
if (check->v.movetype != MOVETYPE_WALK)
|
||||||
|
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
|
||||||
|
//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, amove);
|
||||||
|
pusher->v.solid = oldsolid;
|
||||||
|
|
||||||
|
|
||||||
|
// if it is still inside the pusher, block
|
||||||
|
block = SV_TestEntityPosition (check);
|
||||||
|
|
||||||
|
if (block)
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
check->v.mins[0] = check->v.mins[1] = 0;
|
||||||
|
VectorCopy (check->v.mins, check->v.maxs);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorCopy (entorig, check->v.origin);
|
||||||
|
SV_LinkEdict (check, true);
|
||||||
|
|
||||||
|
VectorCopy (pushorig, pusher->v.angles);
|
||||||
|
SV_LinkEdict (pusher, false);
|
||||||
|
pusher->v.ltime -= movetime;
|
||||||
|
|
||||||
|
// if the pusher has a "blocked" function, call it
|
||||||
|
// 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_ExecuteProgram (pusher->v.blocked);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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], (moved_edict[i] == check) ? true : false);
|
||||||
|
}
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VectorAdd (check->v.angles, amove, check->v.angles);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
SV_Physics_Pusher
|
SV_Physics_Pusher
|
||||||
|
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void SV_Physics_Pusher (edict_t *ent)
|
void SV_Physics_Pusher (edict_t *ent) //sB modified to match dquake
|
||||||
{
|
{
|
||||||
float thinktime;
|
float thinktime;
|
||||||
float oldltime;
|
float oldltime;
|
||||||
|
@ -592,10 +769,12 @@ void SV_Physics_Pusher (edict_t *ent)
|
||||||
else
|
else
|
||||||
movetime = host_frametime;
|
movetime = host_frametime;
|
||||||
|
|
||||||
if (movetime)
|
if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2])
|
||||||
{
|
SV_PushRotate (ent, host_frametime);
|
||||||
SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked
|
|
||||||
}
|
if (movetime)
|
||||||
|
SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked
|
||||||
|
|
||||||
|
|
||||||
if (thinktime > oldltime && thinktime <= ent->v.ltime)
|
if (thinktime > oldltime && thinktime <= ent->v.ltime)
|
||||||
{
|
{
|
||||||
|
@ -770,7 +949,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
|
||||||
case 7: dir[0] = -2; dir[1] = -2; break;
|
case 7: dir[0] = -2; dir[1] = -2; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_PushEntity (ent, dir);
|
SV_PushEntity (ent, dir, vec3_origin);
|
||||||
|
|
||||||
// retry the original move
|
// retry the original move
|
||||||
ent->v.velocity[0] = oldvel[0];
|
ent->v.velocity[0] = oldvel[0];
|
||||||
|
@ -850,7 +1029,7 @@ void SV_WalkMove (edict_t *ent)
|
||||||
downmove[2] = -STEPSIZE + oldvel[2]*host_frametime;
|
downmove[2] = -STEPSIZE + oldvel[2]*host_frametime;
|
||||||
|
|
||||||
// move up
|
// move up
|
||||||
SV_PushEntity (ent, upmove); // FIXME: don't link?
|
SV_PushEntity (ent, upmove, vec3_origin); // FIXME: don't link?
|
||||||
|
|
||||||
// move forward
|
// move forward
|
||||||
ent->v.velocity[0] = oldvel[0];
|
ent->v.velocity[0] = oldvel[0];
|
||||||
|
@ -874,7 +1053,7 @@ void SV_WalkMove (edict_t *ent)
|
||||||
SV_WallFriction (ent, &steptrace);
|
SV_WallFriction (ent, &steptrace);
|
||||||
|
|
||||||
// move down
|
// 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)
|
if (downtrace.plane.normal[2] > 0.7)
|
||||||
{
|
{
|
||||||
|
@ -1102,7 +1281,7 @@ void SV_CheckStuck_IgnoreMonsters (edict_t *ent)
|
||||||
void SV_PushAwayZombies(edict_t *ent)
|
void SV_PushAwayZombies(edict_t *ent)
|
||||||
{
|
{
|
||||||
edict_t *other_ent;
|
edict_t *other_ent;
|
||||||
float rad = 64;//approx. length of bbox corner
|
float rad = 23;//approx. length of bbox corner
|
||||||
float *org = ent->v.origin;
|
float *org = ent->v.origin;
|
||||||
vec3_t eorg;
|
vec3_t eorg;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -1110,8 +1289,8 @@ void SV_PushAwayZombies(edict_t *ent)
|
||||||
other_ent = NEXT_EDICT(sv.edicts);
|
other_ent = NEXT_EDICT(sv.edicts);
|
||||||
for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(other_ent))
|
for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(other_ent))
|
||||||
{
|
{
|
||||||
//if (other_ent->free)
|
if (other_ent->free)
|
||||||
//continue;
|
continue;
|
||||||
//if (ent->v.solid == SOLID_NOT)
|
//if (ent->v.solid == SOLID_NOT)
|
||||||
// continue;
|
// continue;
|
||||||
if( other_ent->v.solid != SOLID_CORPSE)
|
if( other_ent->v.solid != SOLID_CORPSE)
|
||||||
|
@ -1122,7 +1301,7 @@ void SV_PushAwayZombies(edict_t *ent)
|
||||||
eorg[j] = org[j] - (other_ent->v.origin[j] + (other_ent->v.mins[j] + other_ent->v.maxs[j])*0.5);
|
eorg[j] = org[j] - (other_ent->v.origin[j] + (other_ent->v.mins[j] + other_ent->v.maxs[j])*0.5);
|
||||||
if (Length(eorg) > rad)
|
if (Length(eorg) > rad)
|
||||||
{
|
{
|
||||||
Con_Printf ("Length Greater than bbox corner. \n");
|
//Con_Printf ("Length Greater than bbox corner. \n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//Process nearby zombie
|
//Process nearby zombie
|
||||||
|
@ -1391,7 +1570,7 @@ void SV_Physics_Toss (edict_t *ent)
|
||||||
|
|
||||||
// move origin
|
// move origin
|
||||||
VectorScale (ent->v.velocity, host_frametime, move);
|
VectorScale (ent->v.velocity, host_frametime, move);
|
||||||
trace = SV_PushEntity (ent, move);
|
trace = SV_PushEntity (ent, move, vec3_origin);
|
||||||
if (trace.fraction == 1)
|
if (trace.fraction == 1)
|
||||||
return;
|
return;
|
||||||
if (ent->free)
|
if (ent->free)
|
||||||
|
@ -1502,8 +1681,8 @@ void SV_Physics (void)
|
||||||
else
|
else
|
||||||
entity_cap = sv.num_edicts;
|
entity_cap = sv.num_edicts;
|
||||||
|
|
||||||
//for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
|
for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
|
||||||
for (i=0 ; i<entity_cap ; i++, ent = NEXT_EDICT(ent))
|
//for (i=0 ; i<entity_cap ; i++, ent = NEXT_EDICT(ent))
|
||||||
{
|
{
|
||||||
if (ent->free)
|
if (ent->free)
|
||||||
continue;
|
continue;
|
||||||
|
|
1731
source/sv_phys.c.bak
Normal file
1731
source/sv_phys.c.bak
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue