25 May 2008
This commit is contained in:
parent
9f130597d8
commit
b3fb246eda
|
@ -63,5 +63,5 @@ if exist viewer\viewer.plg del /f /q viewer\viewer.plg
|
|||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
xash.exe -log -game tmpQuArK -debug -dev 3 +map qctest
|
||||
xash.exe -log -game tmpQuArK -debug -dev 3 +map start
|
||||
:done
|
|
@ -214,9 +214,6 @@ void CL_PredictMovement (void)
|
|||
memset (&pm, 0, sizeof(pm));
|
||||
pm.trace = CL_PMTrace;
|
||||
pm.pointcontents = CL_PMpointcontents;
|
||||
|
||||
pm_airaccelerate = atof(cl.configstrings[CS_AIRACCEL]);
|
||||
|
||||
pm.ps = cl.frame.playerstate;
|
||||
|
||||
// SCR_DebugGraph (current - ack - 1, COLOR_0);
|
||||
|
@ -230,7 +227,7 @@ void CL_PredictMovement (void)
|
|||
cmd = &cl.cmds[frame];
|
||||
|
||||
pm.cmd = *cmd;
|
||||
Pmove (&pm);
|
||||
pe->PlayerMove( &pm, true );
|
||||
|
||||
// save for debug checking
|
||||
VectorCopy (pm.ps.origin, cl.predicted_origins[frame]);
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// collision.h - base collision detect
|
||||
//=======================================================================
|
||||
#ifndef COLLISION_H
|
||||
#define COLLISION_H
|
||||
|
||||
// content masks
|
||||
#define MASK_ALL (-1)
|
||||
#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_WINDOW)
|
||||
#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER)
|
||||
#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW)
|
||||
#define MASK_MONSTERSOLID (CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER)
|
||||
#define MASK_WATER (CONTENTS_WATER|CONTENTS_LAVA|CONTENTS_SLIME)
|
||||
#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_LAVA)
|
||||
#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEADMONSTER)
|
||||
#define MASK_CURRENT (CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN)
|
||||
#define AREA_SOLID 1
|
||||
#define AREA_TRIGGERS 2
|
||||
|
||||
// pmove->pm_flags
|
||||
#define PMF_DUCKED 1
|
||||
#define PMF_JUMP_HELD 2
|
||||
#define PMF_ON_GROUND 4
|
||||
#define PMF_TIME_WATERJUMP 8 // pm_time is waterjump
|
||||
#define PMF_TIME_LAND 16 // pm_time is time before rejump
|
||||
#define PMF_TIME_TELEPORT 32 // pm_time is non-moving time
|
||||
#define PMF_NO_PREDICTION 64 // temporarily disables prediction (used for grappling hook)
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
PLAYER MOVEMENT CODE
|
||||
|
||||
Common between server and client so prediction matches
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
// button bits
|
||||
#define BUTTON_ATTACK 1
|
||||
#define BUTTON_USE 2
|
||||
#define BUTTON_ATTACK2 4
|
||||
#define BUTTONS_ATTACK (BUTTON_ATTACK | BUTTON_ATTACK2)
|
||||
#define BUTTON_ANY 128 // any key whatsoever
|
||||
|
||||
extern float pm_airaccelerate;
|
||||
void Pmove(pmove_t *pmove);
|
||||
|
||||
#endif//COLLISION_H
|
|
@ -210,10 +210,6 @@ SOURCE=.\net_wins.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\pmove.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\uimenu\qmenu.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "net_msg.h"
|
||||
#include "screen.h"
|
||||
#include "keycodes.h"
|
||||
#include "pmove.h"
|
||||
|
||||
extern stdlib_api_t com;
|
||||
extern physic_exp_t *pe;
|
||||
|
|
|
@ -115,6 +115,7 @@ void Host_InitPhysic( void )
|
|||
// phys callback
|
||||
pi.api_size = sizeof(physic_imp_t);
|
||||
pi.Transform = SV_Transform;
|
||||
pi.ClientMove = SV_PlayerMove;
|
||||
pi.GetModelVerts = SV_GetModelVerts;
|
||||
|
||||
Sys_LoadLibrary( &physic_dll );
|
||||
|
|
|
@ -85,32 +85,6 @@ typedef enum
|
|||
#define CM_BUTTONS (1<<6)
|
||||
#define CM_IMPULSE (1<<7)
|
||||
|
||||
// player_state->stats[] indexes
|
||||
enum player_stats
|
||||
{
|
||||
STAT_HEALTH_ICON = 0,
|
||||
STAT_HEALTH,
|
||||
STAT_AMMO_ICON,
|
||||
STAT_AMMO,
|
||||
STAT_ARMOR_ICON,
|
||||
STAT_ARMOR,
|
||||
STAT_SELECTED_ICON,
|
||||
STAT_PICKUP_ICON,
|
||||
STAT_PICKUP_STRING,
|
||||
STAT_TIMER_ICON,
|
||||
STAT_TIMER,
|
||||
STAT_HELPICON,
|
||||
STAT_SELECTED_ITEM,
|
||||
STAT_LAYOUTS,
|
||||
STAT_FRAGS,
|
||||
STAT_FLASHES, // cleared each frame, 1 = health, 2 = armor
|
||||
STAT_CHASE,
|
||||
STAT_SPECTATOR,
|
||||
STAT_SPEED = 22,
|
||||
STAT_ZOOM,
|
||||
MAX_STATS = 32,
|
||||
};
|
||||
|
||||
// dmflags->value flags
|
||||
#define DF_NO_HEALTH 0x00000001 // 1
|
||||
#define DF_NO_ITEMS 0x00000002 // 2
|
||||
|
|
145
engine/pmove.h
145
engine/pmove.h
|
@ -1,145 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// pmove.h - base player physic
|
||||
//=======================================================================
|
||||
#ifndef COLLISION_H
|
||||
#define COLLISION_H
|
||||
|
||||
// encoded bmodel mask
|
||||
#define SOLID_BMODEL 0xffffff
|
||||
|
||||
// content masks
|
||||
#define MASK_ALL (-1)
|
||||
#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_WINDOW)
|
||||
#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER)
|
||||
#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW)
|
||||
#define MASK_MONSTERSOLID (CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER)
|
||||
#define MASK_WATER (CONTENTS_WATER|CONTENTS_LAVA|CONTENTS_SLIME)
|
||||
#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_LAVA)
|
||||
#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEADMONSTER)
|
||||
#define MASK_CURRENT (CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN)
|
||||
|
||||
// pmove_state_t is the information necessary for client side movement
|
||||
#define PM_NORMAL 0 // can accelerate and turn
|
||||
#define PM_SPECTATOR 1
|
||||
#define PM_DEAD 2 // no acceleration or turning
|
||||
#define PM_GIB 3 // different bounding box
|
||||
#define PM_FREEZE 4
|
||||
#define PM_INTERMISSION 5
|
||||
#define PM_NOCLIP 6
|
||||
|
||||
// pmove->pm_flags
|
||||
#define PMF_DUCKED 1
|
||||
#define PMF_JUMP_HELD 2
|
||||
#define PMF_ON_GROUND 4
|
||||
#define PMF_TIME_WATERJUMP 8 // pm_time is waterjump
|
||||
#define PMF_TIME_LAND 16 // pm_time is time before rejump
|
||||
#define PMF_TIME_TELEPORT 32 // pm_time is non-moving time
|
||||
#define PMF_NO_PREDICTION 64 // temporarily disables prediction (used for grappling hook)
|
||||
#define PMF_ALL_TIMES (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_TELEPORT)
|
||||
|
||||
// viewmodel state
|
||||
typedef struct
|
||||
{
|
||||
int index; // client modelindex
|
||||
vec3_t angles; // can be some different with viewangles
|
||||
vec3_t offset; // center offset
|
||||
int sequence; // studio animation sequence
|
||||
int frame; // studio frame
|
||||
int body; // weapon body
|
||||
int skin; // weapon skin
|
||||
} vmodel_state_t;
|
||||
|
||||
// thirdperson model state
|
||||
typedef struct
|
||||
{
|
||||
int index; // client modelindex
|
||||
int sequence; // studio animation sequence
|
||||
int frame; // studio frame
|
||||
} pmodel_state_t;
|
||||
|
||||
// player_state_t communication
|
||||
typedef struct
|
||||
{
|
||||
int bobcycle; // for view bobbing and footstep generation
|
||||
float bobtime;
|
||||
byte pm_type; // player movetype
|
||||
byte pm_flags; // ducked, jump_held, etc
|
||||
byte pm_time; // each unit = 8 ms
|
||||
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
vec3_t delta_angles; // add to command angles to get view direction
|
||||
short gravity; // gravity value
|
||||
short speed; // maxspeed
|
||||
edict_t *groundentity; // current ground entity
|
||||
int viewheight; // height over ground
|
||||
int effects; // copied to entity_state_t->effects
|
||||
int weapon; // copied to entity_state_t->weapon
|
||||
vec3_t viewangles; // for fixed views
|
||||
vec3_t viewoffset; // add to pmovestate->origin
|
||||
vec3_t kick_angles; // add to view direction to get render angles
|
||||
vec3_t oldviewangles; // for lerping viewmodel position
|
||||
vec4_t blend; // rgba full screen effect
|
||||
short stats[MAX_STATS];
|
||||
float fov; // horizontal field of view
|
||||
|
||||
// player model and viewmodel
|
||||
vmodel_state_t vmodel;
|
||||
pmodel_state_t pmodel;
|
||||
|
||||
} player_state_t;
|
||||
|
||||
// user_cmd_t communication
|
||||
typedef struct usercmd_s
|
||||
{
|
||||
byte msec;
|
||||
byte buttons;
|
||||
short angles[3];
|
||||
byte impulse; // remove?
|
||||
byte lightlevel; // light level the player is standing on
|
||||
short forwardmove, sidemove, upmove;
|
||||
} usercmd_t;
|
||||
|
||||
#define MAXTOUCH 32
|
||||
typedef struct
|
||||
{
|
||||
player_state_t ps; // state (in / out)
|
||||
|
||||
// command (in)
|
||||
usercmd_t cmd;
|
||||
|
||||
// results (out)
|
||||
int numtouch;
|
||||
edict_t *touchents[MAXTOUCH];
|
||||
|
||||
vec3_t mins, maxs; // bounding box size
|
||||
int watertype;
|
||||
int waterlevel;
|
||||
float xyspeed; // avoid to compute it twice
|
||||
|
||||
// callbacks to test the world
|
||||
trace_t (*trace)( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end );
|
||||
int (*pointcontents)( vec3_t point );
|
||||
} pmove_t;
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
PLAYER MOVEMENT CODE
|
||||
|
||||
Common between server and client so prediction matches
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
// button bits
|
||||
#define BUTTON_ATTACK 1
|
||||
#define BUTTON_USE 2
|
||||
#define BUTTON_ATTACK2 4
|
||||
#define BUTTONS_ATTACK (BUTTON_ATTACK | BUTTON_ATTACK2)
|
||||
#define BUTTON_ANY 128 // any key whatsoever
|
||||
|
||||
extern float pm_airaccelerate;
|
||||
void Pmove( pmove_t *pmove );
|
||||
|
||||
#endif//COLLISION_H
|
|
@ -29,7 +29,6 @@ The code uses void pointers instead.
|
|||
#ifndef PROGSVM_H
|
||||
#define PROGSVM_H
|
||||
|
||||
#include "pmove.h"
|
||||
#include "sv_edict.h" // server progs
|
||||
#include "cl_edict.h" // client progs
|
||||
#include "ui_edict.h" // uimenu progs
|
||||
|
|
|
@ -253,6 +253,7 @@ void SV_VM_End(void);
|
|||
//
|
||||
// sv_phys.c
|
||||
//
|
||||
void SV_PlayerMove( sv_edict_t *ed );
|
||||
void SV_PrepWorldFrame (void);
|
||||
void SV_Physics (edict_t *ent);
|
||||
void SV_DropToFloor (edict_t *ent);
|
||||
|
|
|
@ -33,6 +33,7 @@ typedef struct worldsector_s
|
|||
struct gclient_s
|
||||
{
|
||||
player_state_t ps; // communicated by server to clients
|
||||
usercmd_t ucmd; // memeber current frame commands
|
||||
int ping;
|
||||
};
|
||||
|
||||
|
|
|
@ -160,19 +160,12 @@ void SV_SpawnServer (char *server, char *savename, sv_state_t serverstate )
|
|||
|
||||
// save name for levels that don't set message
|
||||
strcpy (sv.configstrings[CS_NAME], server);
|
||||
if (Cvar_VariableValue ("deathmatch"))
|
||||
{
|
||||
sprintf(sv.configstrings[CS_AIRACCEL], "%g", sv_airaccelerate->value);
|
||||
pm_airaccelerate = sv_airaccelerate->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(sv.configstrings[CS_AIRACCEL], "0");
|
||||
pm_airaccelerate = 0;
|
||||
}
|
||||
if( Cvar_VariableValue ("deathmatch") )
|
||||
com.sprintf( sv.configstrings[CS_AIRACCEL], "%g", sv_airaccelerate->value );
|
||||
else com.strcpy( sv.configstrings[CS_AIRACCEL], "0" );
|
||||
|
||||
SZ_Init(&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
|
||||
strcpy (sv.name, server);
|
||||
com.strcpy( sv.name, server );
|
||||
|
||||
SV_VM_Begin();
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ void SV_PutClientInServer (edict_t *ent)
|
|||
memset (&ent->priv.sv->client->ps, 0, sizeof(client->ps));
|
||||
|
||||
// info_player_start
|
||||
VectorCopy(ent->progs.sv->origin, client->ps.origin);
|
||||
VectorCopy( ent->progs.sv->origin, client->ps.origin );
|
||||
|
||||
client->ps.fov = 90;
|
||||
client->ps.fov = bound(1, client->ps.fov, 160);
|
||||
|
@ -81,8 +81,10 @@ void SV_PutClientInServer (edict_t *ent)
|
|||
ent->progs.sv->angles[ROLL] = 0;
|
||||
}
|
||||
|
||||
VectorCopy(ent->progs.sv->angles, client->ps.viewangles);
|
||||
VectorCopy( ent->progs.sv->angles, client->ps.viewangles );
|
||||
|
||||
SV_LinkEdict(ent);
|
||||
ent->priv.sv->physbody = pe->CreatePlayer( ent->priv.sv, SV_GetModelPtr( ent ), ent->progs.sv->m_pmatrix );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -512,6 +514,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
else client->ps.pm_flags &= ~PMF_TIME_TELEPORT;
|
||||
|
||||
pm.ps = client->ps;
|
||||
memcpy( &client->ucmd, ucmd, sizeof(usercmd_t));//IMPORTANT!!!
|
||||
|
||||
VectorCopy(ent->progs.sv->origin, pm.ps.origin );
|
||||
VectorCopy(ent->progs.sv->velocity, pm.ps.velocity );
|
||||
|
@ -522,7 +525,7 @@ void ClientThink (edict_t *ent, usercmd_t *ucmd)
|
|||
pm.pointcontents = PM_pointcontents;
|
||||
|
||||
// perform a pmove
|
||||
Pmove (&pm);
|
||||
pe->PlayerMove( &pm, false );
|
||||
|
||||
// save results of pmove
|
||||
client->ps = pm.ps;
|
||||
|
@ -669,7 +672,7 @@ void Cmd_Say_f (edict_t *ent, bool team, bool arg0)
|
|||
// don't let text be too long for malicious reasons
|
||||
if (strlen(text) > 150) text[150] = 0;
|
||||
|
||||
strcat(text, "\n");
|
||||
com.strcat(text, "\n");
|
||||
|
||||
if (dedicated->value)
|
||||
PF_cprintf(NULL, PRINT_CHAT, "%s", text);
|
||||
|
@ -789,4 +792,50 @@ void SV_Transform( sv_edict_t *ed, matrix4x3 transform )
|
|||
// refresh force and torque
|
||||
pe->GetForce( ed->physbody, edict->progs.sv->velocity, edict->progs.sv->avelocity, edict->progs.sv->force, edict->progs.sv->torque );
|
||||
pe->GetMassCentre( ed->physbody, edict->progs.sv->m_pcentre );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
CV_ClientMove
|
||||
|
||||
grab user cmd from player_state_t
|
||||
send it to transform callback
|
||||
==============
|
||||
*/
|
||||
void SV_PlayerMove( sv_edict_t *ed )
|
||||
{
|
||||
pmove_t pm;
|
||||
gclient_t *client;
|
||||
edict_t *player;
|
||||
|
||||
client = ed->client;
|
||||
player = PRVM_PROG_TO_EDICT( ed->serialnumber );
|
||||
memset( &pm, 0, sizeof(pm) );
|
||||
|
||||
if( player->progs.sv->movetype == MOVETYPE_NOCLIP )
|
||||
client->ps.pm_type = PM_SPECTATOR;
|
||||
else client->ps.pm_type = PM_NORMAL;
|
||||
client->ps.gravity = sv_gravity->value;
|
||||
|
||||
if( player->progs.sv->teleport_time )
|
||||
client->ps.pm_flags |= PMF_TIME_TELEPORT;
|
||||
else client->ps.pm_flags &= ~PMF_TIME_TELEPORT;
|
||||
|
||||
pm.ps = client->ps;
|
||||
pm.cmd = client->ucmd;
|
||||
pm.body = ed->physbody; // member body ptr
|
||||
|
||||
VectorCopy( player->progs.sv->origin, pm.ps.origin );
|
||||
VectorCopy( player->progs.sv->velocity, pm.ps.velocity );
|
||||
|
||||
pe->ServerMove( &pm );
|
||||
|
||||
// save results of pmove
|
||||
client->ps = pm.ps;
|
||||
|
||||
VectorCopy(pm.ps.origin, player->progs.sv->origin);
|
||||
VectorCopy(pm.ps.velocity, player->progs.sv->velocity);
|
||||
VectorCopy(pm.mins, player->progs.sv->mins);
|
||||
VectorCopy(pm.maxs, player->progs.sv->maxs);
|
||||
VectorCopy(pm.ps.viewangles, client->ps.viewangles);
|
||||
}
|
|
@ -52,8 +52,8 @@ void Sys_Error( const char *error, ... )
|
|||
|
||||
// prepare host to close
|
||||
sprintf( host.finalmsg, "Server fatal crashed: %s\n", errorstring );
|
||||
host.state = HOST_ERROR; // lock shutdown state
|
||||
Host_FreeRender();
|
||||
host.state = HOST_ERROR; // lock shutdown state
|
||||
Host_FreeRender(); // close render to show message error
|
||||
|
||||
com.error("%s", errorstring );
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// cm_callback.c - game callbacks
|
||||
// cm_callback.c - generic callbacks
|
||||
//=======================================================================
|
||||
|
||||
#include "physic.h"
|
||||
#include "cm_local.h"
|
||||
|
||||
|
||||
void Callback_ApplyForce( const NewtonBody* body )
|
||||
{
|
||||
float mass;
|
||||
vec3_t size, force, torque;
|
||||
vec3_t m_size, force, torque;
|
||||
|
||||
NewtonBodyGetMassMatrix (body, &mass, &size[0], &size[1], &size[2]);
|
||||
NewtonBodyGetMassMatrix (body, &mass, &m_size[0], &m_size[1], &m_size[2]);
|
||||
|
||||
VectorSet( torque, 0.0f, 0.0f, 0.0f );
|
||||
VectorSet( force, 0.0f, -9.8f * mass, 0.0f );
|
||||
|
@ -20,6 +20,12 @@ void Callback_ApplyForce( const NewtonBody* body )
|
|||
NewtonBodyAddTorque (body, torque);
|
||||
}
|
||||
|
||||
void Callback_PmoveApplyForce( const NewtonBody* body )
|
||||
{
|
||||
// grab state and jump to CM_ServerMove
|
||||
pi.ClientMove((sv_edict_t *)NewtonBodyGetUserData( body ));
|
||||
}
|
||||
|
||||
void Callback_ApplyTransform( const NewtonBody* body, const float* matrix )
|
||||
{
|
||||
sv_edict_t *edict = (sv_edict_t *)NewtonBodyGetUserData( body );
|
||||
|
|
|
@ -192,6 +192,20 @@ extern physic_t ph;
|
|||
|
||||
extern cvar_t *cm_noareas;
|
||||
|
||||
// test variables
|
||||
extern int characterID;
|
||||
extern uint m_jumpTimer;
|
||||
extern bool m_isStopped;
|
||||
extern bool m_isAirBorne;
|
||||
extern float m_maxStepHigh;
|
||||
extern float m_yawAngle;
|
||||
extern float m_maxTranslation;
|
||||
extern vec3_t m_size;
|
||||
extern vec3_t m_stepContact;
|
||||
extern vec3_t m_forceVector;
|
||||
extern matrix4x4 m_matrix;
|
||||
extern float *m_upVector;
|
||||
|
||||
//
|
||||
// cm_test.c
|
||||
//
|
||||
|
|
|
@ -1,26 +1,22 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// cm_pmove.c - player movement code
|
||||
//=======================================================================
|
||||
|
||||
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 2
|
||||
of the License, or (at your option) any later version.
|
||||
#include "cm_local.h"
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "engine.h"
|
||||
#include "pmove.h"
|
||||
#include "mathlib.h"
|
||||
int characterID;
|
||||
uint m_jumpTimer;
|
||||
bool m_isStopped;
|
||||
bool m_isAirBorne;
|
||||
float m_maxStepHigh;
|
||||
float m_yawAngle;
|
||||
float m_maxTranslation;
|
||||
vec3_t m_size;
|
||||
vec3_t m_stepContact;
|
||||
vec3_t m_forceVector;
|
||||
float *m_upVector;
|
||||
matrix4x4 m_matrix;
|
||||
|
||||
#define PM_SPEED 160.f
|
||||
#define STEPSIZE 18
|
||||
|
@ -74,6 +70,16 @@ float pm_friction = 6.0f;
|
|||
float pm_waterfriction = 1.0f;
|
||||
float pm_flightfriction = 3.0f;
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
PLAYER MOVEMENT CODE
|
||||
|
||||
Common between server and client so prediction matches
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
walking up a step should kill some velocity
|
||||
*/
|
||||
|
@ -108,7 +114,7 @@ void PM_AddTouchEnt( edict_t *entity )
|
|||
{
|
||||
int i;
|
||||
|
||||
if( pm->numtouch == MAXTOUCH )
|
||||
if( pm->numtouch == PM_MAXTOUCH )
|
||||
return;
|
||||
|
||||
// see if it is already added
|
||||
|
@ -1474,7 +1480,7 @@ Pmove
|
|||
Can be called by either the server or the client
|
||||
================
|
||||
*/
|
||||
void Pmove( pmove_t *pmove )
|
||||
void Quake_PMove( pmove_t *pmove )
|
||||
{
|
||||
pm = pmove;
|
||||
|
||||
|
@ -1584,4 +1590,232 @@ void Pmove( pmove_t *pmove )
|
|||
pmove->cmd.upmove = 20;
|
||||
}
|
||||
//PM_CheckStuck();
|
||||
}
|
||||
|
||||
void CM_CmdUpdateForce( usercmd_t *cmd )
|
||||
{
|
||||
m_forceVector[0] = cmd->forwardmove;// / 200;
|
||||
m_forceVector[2] = cmd->sidemove;// / 200;
|
||||
|
||||
if( cmd->upmove != 0.0f)
|
||||
{
|
||||
m_jumpTimer = 4;
|
||||
}
|
||||
}
|
||||
|
||||
void CM_ServerMove( pmove_t *pmove )
|
||||
{
|
||||
float mass, Ixx, Iyy, Izz, dist, floor, accelY;
|
||||
float newScale, deltaHeight, steerAngle, timestep, timestepInv;
|
||||
vec3_t force, add_force, torque, omega, heading, velocity, step;
|
||||
matrix4x4 matrix, collisionPaddingMatrix;
|
||||
vec3_t head1, head2, vec_view, pin;
|
||||
NewtonCollision *col;
|
||||
NewtonBody *body;
|
||||
|
||||
pm = pmove;
|
||||
body = pm->body;
|
||||
|
||||
PM_UpdateViewAngles( &pm->ps, &pm->cmd );
|
||||
CM_CmdUpdateForce( &pm->cmd );
|
||||
|
||||
// get the current world timestep
|
||||
timestep = NewtonGetTimeStep( gWorld );
|
||||
timestepInv = 1.0f / timestep;
|
||||
col = NewtonBodyGetCollision( body );
|
||||
|
||||
// get the character mass
|
||||
NewtonBodyGetMassMatrix( body, &mass, &Ixx, &Iyy, &Izz);
|
||||
VectorSet( force, 0.0f, mass * -9.8f, 0.0f);
|
||||
NewtonBodyGetVelocity( body, &velocity[0] ); // get the velocity vector
|
||||
NewtonBodyGetMatrix( body, &matrix[0][0] );
|
||||
|
||||
// if the floor is with in reach then the character must be snap to the ground
|
||||
// the max allow distance for snapping i 0.25 of a meter
|
||||
if( m_isAirBorne && !m_jumpTimer )
|
||||
{
|
||||
floor = CM_FindFloor( matrix[3], m_size[2] + 0.25f );
|
||||
deltaHeight = (matrix[3][2] - m_size[2]) - floor;
|
||||
if((deltaHeight < (0.25f - 0.001f)) && (deltaHeight > 0.01f))
|
||||
{
|
||||
// snap to floor only if the floor is lower than the character feet
|
||||
accelY = - (deltaHeight * timestepInv + velocity[2]) * timestepInv;
|
||||
force[2] = mass * accelY;
|
||||
}
|
||||
}
|
||||
else if( m_jumpTimer == 4 ) //JUMP_TIMER
|
||||
{
|
||||
vec3_t veloc;
|
||||
VectorSet( veloc, 0.0f, 0.4f, 0.0f );
|
||||
NewtonAddBodyImpulse( body, &veloc[0], &matrix[3][0] );
|
||||
}
|
||||
|
||||
m_jumpTimer = m_jumpTimer ? m_jumpTimer - 1 : 0;
|
||||
|
||||
// rotate the force direction to align with the camera
|
||||
VectorIRotate( m_forceVector, m_matrix, heading );
|
||||
|
||||
newScale = 1.0f / sqrt( DotProduct(heading, heading) + 1.0e-6f );
|
||||
VectorScale( heading, newScale, heading );
|
||||
VectorScale( heading, mass * 30.0f, head1 );
|
||||
VectorScale( heading, 2.0f * DotProduct( velocity, heading ), head2 );
|
||||
|
||||
VectorSubtract( head1, head2, add_force );
|
||||
VectorAdd( force, add_force, force );
|
||||
NewtonBodySetForce( body, &force[0] );
|
||||
|
||||
// estimate the final horizontal translation for to next force and velocity
|
||||
VectorScale( force, timestep / mass, force );
|
||||
VectorAdd( force, velocity, step );
|
||||
VectorScale( step, timestep, step );
|
||||
|
||||
VectorSet( step, DotProduct(step, m_matrix[0]), DotProduct(step, m_matrix[2]), DotProduct(step, m_matrix[1]));
|
||||
MatrixLoadIdentity( collisionPaddingMatrix );
|
||||
|
||||
step[2] = 0.0f;
|
||||
dist = DotProduct( step, step );
|
||||
|
||||
if( dist > m_maxTranslation * m_maxTranslation )
|
||||
{
|
||||
matrix4x4 transp;
|
||||
|
||||
// when the velocity is high enough that can miss collision we will enlarge the collision
|
||||
// long the vector velocity
|
||||
dist = sqrt( dist );
|
||||
VectorScale( step, 1.0f / dist, step );
|
||||
|
||||
// make a rotation matrix that will align the velocity vector with the front vector
|
||||
collisionPaddingMatrix[0][0] = step[0];
|
||||
collisionPaddingMatrix[0][2] = -step[2];
|
||||
collisionPaddingMatrix[2][0] = step[2];
|
||||
collisionPaddingMatrix[2][2] = step[0];
|
||||
|
||||
// get the transpose of the matrix
|
||||
MatrixTranspose( transp, collisionPaddingMatrix );
|
||||
|
||||
VectorScale( transp[0], dist/m_maxTranslation, transp[0] );
|
||||
|
||||
// calculate and oblique scale matrix by using a similar transformation matrix of the for, R'* S * R
|
||||
MatrixConcat( collisionPaddingMatrix, collisionPaddingMatrix, transp );
|
||||
}
|
||||
|
||||
// set the collision modifierMatrix;
|
||||
NewtonConvexHullModifierSetMatrix( col, &collisionPaddingMatrix[0][0] );
|
||||
|
||||
// calculate the torque vector
|
||||
VectorMultiply( m_matrix[0], pm->ps.viewangles, vec_view );
|
||||
steerAngle = bound( -1.0f, vec_view[2], -1.0f );
|
||||
steerAngle = asin( steerAngle );
|
||||
NewtonBodyGetOmega( body, &omega[0] );
|
||||
|
||||
VectorSet( torque, 0.0f, 0.5f * Iyy * (steerAngle * timestepInv - omega[2]) * timestepInv, 0.0f );
|
||||
NewtonBodySetTorque( body, &torque[0] );
|
||||
|
||||
// assume the character is on the air. this variable will be set to false if the contact detect
|
||||
//the character is landed
|
||||
m_isAirBorne = true;
|
||||
VectorSet( m_stepContact, 0.0f, -m_size[2], 0.0f );
|
||||
|
||||
VectorSet( pin, 0.0f, 1.0f, 0.0f);
|
||||
NewtonUpVectorSetPin( m_upVector, &pin[0] );
|
||||
}
|
||||
|
||||
void CM_ClientMove( pmove_t *pmove )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// find floor for character placement
|
||||
float CM_FindFloor( vec3_t p0, float maxDist )
|
||||
{
|
||||
// shot a vertical ray from a high altitude and collected the intersection parameter.
|
||||
vec3_t p1;
|
||||
|
||||
VectorCopy( p0, p1 );
|
||||
p1[2] -= INCH2METER( maxDist ); // FIXME
|
||||
|
||||
NewtonWorldRayCast( gWorld, &p0[0], &p1[0], NULL, NULL );
|
||||
|
||||
// the intersection is the interpolated value
|
||||
return p0[2] - maxDist * INCH2METER( 1.2f ); //FIXME
|
||||
}
|
||||
|
||||
physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform )
|
||||
{
|
||||
NewtonCollision *col, *hull;
|
||||
NewtonBody *body;
|
||||
|
||||
matrix4x4 trans;
|
||||
vec3_t radius, mins, maxs, upDirection;
|
||||
|
||||
if( !cm_physics_model->integer )
|
||||
return NULL;
|
||||
|
||||
// setup matrixes
|
||||
MatrixLoadIdentity( trans );
|
||||
|
||||
if( mod )
|
||||
{
|
||||
// player m_size
|
||||
VectorCopy( mod->mins, mins );
|
||||
VectorCopy( mod->maxs, maxs );
|
||||
VectorSubtract( maxs, mins, m_size );
|
||||
VectorScale( m_size, 0.5f, radius );
|
||||
}
|
||||
ConvertDimensionToPhysic( m_size );
|
||||
ConvertDimensionToPhysic( radius );
|
||||
|
||||
VectorSet( m_stepContact, 0.0f, -m_size[2], 0.0f );
|
||||
m_maxTranslation = m_size[0] * 0.25f;
|
||||
m_maxStepHigh = -m_size[2] * 0.5f;
|
||||
|
||||
// setup translation matrix
|
||||
VectorCopy( transform[0], trans[0] );
|
||||
VectorCopy( transform[1], trans[1] );
|
||||
VectorCopy( transform[2], trans[2] );
|
||||
VectorCopy( transform[3], trans[3] );
|
||||
|
||||
trans[3][2] = CM_FindFloor( trans[3], 100 ) + radius[2]; // merge floor position
|
||||
|
||||
// place a sphere at the center
|
||||
col = NewtonCreateSphere( gWorld, radius[0], radius[2], radius[1], NULL );
|
||||
|
||||
// wrap the character collision under a transform, modifier for tunneling trught walls avoidance
|
||||
hull = NewtonCreateConvexHullModifier( gWorld, col );
|
||||
NewtonReleaseCollision( gWorld, col );
|
||||
body = NewtonCreateBody( gWorld, hull ); // create the rigid body
|
||||
NewtonBodySetAutoFreeze( body, 0 ); // disable auto freeze management for the player
|
||||
NewtonWorldUnfreezeBody( gWorld, body ); // keep the player always active
|
||||
|
||||
// reset angular and linear damping
|
||||
NewtonBodySetLinearDamping( body, 0.0f );
|
||||
NewtonBodySetAngularDamping( body, vec3_origin );
|
||||
NewtonBodySetMaterialGroupID( body, characterID );// set material Id for this object
|
||||
|
||||
// setup generic callback to engine.dll
|
||||
NewtonBodySetUserData( body, ed );
|
||||
NewtonBodySetTransformCallback( body, Callback_ApplyTransform );
|
||||
NewtonBodySetForceAndTorqueCallback( body, Callback_PmoveApplyForce );
|
||||
NewtonBodySetMassMatrix( body, 10.0f, m_size[0], m_size[1], m_size[2] ); // 10 kg
|
||||
NewtonBodySetMatrix(body, &trans[0][0] );// origin
|
||||
|
||||
// release the collision geometry when not need it
|
||||
NewtonReleaseCollision( gWorld, hull );
|
||||
|
||||
// add and up vector constraint to help in keeping the body upright
|
||||
VectorSet( upDirection, 0.0f, 1.0f, 0.0f );
|
||||
m_upVector = (float *)NewtonConstraintCreateUpVector( gWorld, &upDirection[0], body );
|
||||
|
||||
return (physbody_t *)body;
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
PMOVE ENTRY POINT
|
||||
===============================================================================
|
||||
*/
|
||||
void CM_PlayerMove( pmove_t *pmove, bool clientmove )
|
||||
{
|
||||
if( !cm_physics_model->integer )
|
||||
Quake_PMove( pmove );
|
||||
}
|
|
@ -57,5 +57,10 @@ int CM_LeafArea( int leafnum );
|
|||
bool CM_AreasConnected( int area1, int area2 );
|
||||
int CM_WriteAreaBits( byte *buffer, int area );
|
||||
void CM_ModelBounds( cmodel_t *model, vec3_t mins, vec3_t maxs );
|
||||
float CM_FindFloor( vec3_t p0, float maxDist );
|
||||
|
||||
void CM_PlayerMove( pmove_t *pmove, bool clientmove );
|
||||
void CM_ServerMove( pmove_t *pmove );
|
||||
void CM_ClientMove( pmove_t *pmove );
|
||||
|
||||
#endif//CM_UTILS_H
|
|
@ -15,17 +15,19 @@ NewtonWorld *gWorld;
|
|||
cvar_t *cm_use_triangles;
|
||||
cvar_t *cm_solver_model;
|
||||
cvar_t *cm_friction_model;
|
||||
cvar_t *cm_physics_model;
|
||||
|
||||
bool InitPhysics( void )
|
||||
{
|
||||
physpool = Mem_AllocPool("Physics Pool");
|
||||
cmappool = Mem_AllocPool("CM Zone");
|
||||
gWorld = NewtonCreate (Palloc, Pfree); // alloc world
|
||||
gWorld = NewtonCreate( Palloc, Pfree ); // alloc world
|
||||
|
||||
cm_noareas = Cvar_Get( "cm_noareas", "0", 0 );
|
||||
cm_use_triangles = Cvar_Get("cm_convert_polygons", "1", CVAR_INIT|CVAR_SYSTEMINFO );//, "convert bsp polygons to triangles, slowly but more safety way" );
|
||||
cm_solver_model = Cvar_Get("cm_solver", "0", CVAR_ARCHIVE );//, "change solver model: 0 - precision, 1 - adaptive, 2 - fast. (changes need restart server to take effect)" );
|
||||
cm_friction_model = Cvar_Get("cm_friction", "0", CVAR_ARCHIVE );//, "change solver model: 0 - precision, 1 - adaptive. (changes need restart server to take effect)" );
|
||||
cm_physics_model = Cvar_Get("cm_physic", "1", CVAR_ARCHIVE );//, "change physic model: 0 - Classic Quake Physic, 1 - Physics Engine" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -91,6 +93,12 @@ physic_exp_t DLLEXPORT *CreateAPI ( stdlib_api_t *input, physic_imp_t *engfuncs
|
|||
|
||||
Phys.Frame = PhysFrame;
|
||||
Phys.CreateBody = Phys_CreateBody;
|
||||
Phys.CreatePlayer = Phys_CreatePlayer;
|
||||
|
||||
Phys.PlayerMove = CM_PlayerMove;
|
||||
Phys.ServerMove = CM_ServerMove;
|
||||
Phys.ClientMove = CM_ClientMove;
|
||||
|
||||
Phys.GetForce = Phys_GetForce;
|
||||
Phys.SetForce = Phys_SetForce;
|
||||
Phys.GetMassCentre = Phys_GetMassCentre;
|
||||
|
|
|
@ -56,8 +56,8 @@ LINK32=link.exe
|
|||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 user32.lib msvcrt.lib newton.lib opengl32.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /libpath:"../public/libs/"
|
||||
# Begin Custom Build
|
||||
TargetDir=\XASH3D\src_main\temp\physic\!release
|
||||
InputPath=\XASH3D\src_main\temp\physic\!release\physic.dll
|
||||
TargetDir=\Xash3D\src_main\temp\physic\!release
|
||||
InputPath=\Xash3D\src_main\temp\physic\!release\physic.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\physic.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
|
@ -93,8 +93,8 @@ LINK32=link.exe
|
|||
# ADD LINK32 user32.lib msvcrtd.lib newton.lib opengl32.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libc.lib" /pdbtype:sept /libpath:"../public/libs/"
|
||||
# SUBTRACT LINK32 /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetDir=\XASH3D\src_main\temp\physic\!debug
|
||||
InputPath=\XASH3D\src_main\temp\physic\!debug\physic.dll
|
||||
TargetDir=\Xash3D\src_main\temp\physic\!debug
|
||||
InputPath=\Xash3D\src_main\temp\physic\!debug\physic.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\physic.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
|
@ -125,6 +125,10 @@ SOURCE=.\cm_model.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cm_pmove.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cm_portals.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -30,6 +30,7 @@ extern NewtonWorld *gWorld;
|
|||
extern cvar_t *cm_use_triangles;
|
||||
extern cvar_t *cm_solver_model;
|
||||
extern cvar_t *cm_friction_model;
|
||||
extern cvar_t *cm_physics_model; // 0 - classic Quake Physic, 1 - Newton Physic
|
||||
|
||||
long _ftol2( double dblSource );
|
||||
void Phys_LoadBSP( uint *buffer );
|
||||
|
@ -41,6 +42,7 @@ void Phys_Frame( float time );
|
|||
// cm_rigidbody.c
|
||||
//
|
||||
physbody_t *Phys_CreateBody( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform, int solid );
|
||||
physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform );
|
||||
bool Phys_GetForce( physbody_t *body, vec3_t velocity, vec3_t avelocity, vec3_t force, vec3_t torque );
|
||||
void Phys_SetForce( physbody_t *body, vec3_t velocity, vec3_t avelocity, vec3_t force, vec3_t torque );
|
||||
bool Phys_GetMassCentre( physbody_t *body, matrix3x3 mass );
|
||||
|
@ -51,6 +53,7 @@ void Phys_RemoveBody( physbody_t *body );
|
|||
// cm_callback.c
|
||||
//
|
||||
void Callback_ApplyForce( const NewtonBody* body );
|
||||
void Callback_PmoveApplyForce( const NewtonBody* body );
|
||||
void Callback_ApplyTransform( const NewtonBody* body, const float* matrix );
|
||||
|
||||
#define Host_Error com.error
|
||||
|
|
163
public/dllapi.h
163
public/dllapi.h
|
@ -29,6 +29,74 @@
|
|||
#define RDF_IRGOGGLES 2
|
||||
#define RDF_PAIN 4
|
||||
|
||||
// encoded bmodel mask
|
||||
#define SOLID_BMODEL 0xffffff
|
||||
|
||||
// content masks
|
||||
#define MASK_ALL (-1)
|
||||
#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_WINDOW)
|
||||
#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER)
|
||||
#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW)
|
||||
#define MASK_MONSTERSOLID (CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER)
|
||||
#define MASK_WATER (CONTENTS_WATER|CONTENTS_LAVA|CONTENTS_SLIME)
|
||||
#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_LAVA)
|
||||
#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEADMONSTER)
|
||||
#define MASK_CURRENT (CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN)
|
||||
|
||||
// pmove_state_t is the information necessary for client side movement
|
||||
#define PM_NORMAL 0 // can accelerate and turn
|
||||
#define PM_SPECTATOR 1
|
||||
#define PM_DEAD 2 // no acceleration or turning
|
||||
#define PM_GIB 3 // different bounding box
|
||||
#define PM_FREEZE 4
|
||||
#define PM_INTERMISSION 5
|
||||
#define PM_NOCLIP 6
|
||||
|
||||
// pmove->pm_flags
|
||||
#define PMF_DUCKED 1
|
||||
#define PMF_JUMP_HELD 2
|
||||
#define PMF_ON_GROUND 4
|
||||
#define PMF_TIME_WATERJUMP 8 // pm_time is waterjump
|
||||
#define PMF_TIME_LAND 16 // pm_time is time before rejump
|
||||
#define PMF_TIME_TELEPORT 32 // pm_time is non-moving time
|
||||
#define PMF_NO_PREDICTION 64 // temporarily disables prediction (used for grappling hook)
|
||||
#define PMF_ALL_TIMES (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_TELEPORT)
|
||||
|
||||
// button bits
|
||||
#define BUTTON_ATTACK 1
|
||||
#define BUTTON_USE 2
|
||||
#define BUTTON_ATTACK2 4
|
||||
#define BUTTONS_ATTACK (BUTTON_ATTACK | BUTTON_ATTACK2)
|
||||
#define BUTTON_ANY 128 // any key whatsoever
|
||||
|
||||
#define PM_MAXTOUCH 32
|
||||
|
||||
// player_state->stats[] indexes
|
||||
enum player_stats
|
||||
{
|
||||
STAT_HEALTH_ICON = 0,
|
||||
STAT_HEALTH,
|
||||
STAT_AMMO_ICON,
|
||||
STAT_AMMO,
|
||||
STAT_ARMOR_ICON,
|
||||
STAT_ARMOR,
|
||||
STAT_SELECTED_ICON,
|
||||
STAT_PICKUP_ICON,
|
||||
STAT_PICKUP_STRING,
|
||||
STAT_TIMER_ICON,
|
||||
STAT_TIMER,
|
||||
STAT_HELPICON,
|
||||
STAT_SELECTED_ITEM,
|
||||
STAT_LAYOUTS,
|
||||
STAT_FRAGS,
|
||||
STAT_FLASHES, // cleared each frame, 1 = health, 2 = armor
|
||||
STAT_CHASE,
|
||||
STAT_SPECTATOR,
|
||||
STAT_SPEED = 22,
|
||||
STAT_ZOOM,
|
||||
MAX_STATS = 32,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
R_BEAM,
|
||||
|
@ -145,6 +213,92 @@ typedef struct
|
|||
|
||||
} refdef_t;
|
||||
|
||||
// viewmodel state
|
||||
typedef struct vmodel_state_s
|
||||
{
|
||||
int index; // client modelindex
|
||||
vec3_t angles; // can be some different with viewangles
|
||||
vec3_t offset; // center offset
|
||||
int sequence; // studio animation sequence
|
||||
int frame; // studio frame
|
||||
int body; // weapon body
|
||||
int skin; // weapon skin
|
||||
} vmodel_state_t;
|
||||
|
||||
// thirdperson model state
|
||||
typedef struct pmodel_state_s
|
||||
{
|
||||
int index; // client modelindex
|
||||
int sequence; // studio animation sequence
|
||||
int frame; // studio frame
|
||||
} pmodel_state_t;
|
||||
|
||||
// player_state_t communication
|
||||
typedef struct player_state_s
|
||||
{
|
||||
int bobcycle; // for view bobbing and footstep generation
|
||||
float bobtime;
|
||||
byte pm_type; // player movetype
|
||||
byte pm_flags; // ducked, jump_held, etc
|
||||
byte pm_time; // each unit = 8 ms
|
||||
|
||||
vec3_t origin;
|
||||
vec3_t velocity;
|
||||
vec3_t delta_angles; // add to command angles to get view direction
|
||||
short gravity; // gravity value
|
||||
short speed; // maxspeed
|
||||
edict_t *groundentity; // current ground entity
|
||||
int viewheight; // height over ground
|
||||
int effects; // copied to entity_state_t->effects
|
||||
int weapon; // copied to entity_state_t->weapon
|
||||
vec3_t viewangles; // for fixed views
|
||||
vec3_t viewoffset; // add to pmovestate->origin
|
||||
vec3_t kick_angles; // add to view direction to get render angles
|
||||
vec3_t oldviewangles; // for lerping viewmodel position
|
||||
vec4_t blend; // rgba full screen effect
|
||||
short stats[MAX_STATS];
|
||||
float fov; // horizontal field of view
|
||||
|
||||
// player model and viewmodel
|
||||
vmodel_state_t vmodel;
|
||||
pmodel_state_t pmodel;
|
||||
|
||||
} player_state_t;
|
||||
|
||||
// user_cmd_t communication
|
||||
typedef struct usercmd_s
|
||||
{
|
||||
byte msec;
|
||||
byte buttons;
|
||||
short angles[3];
|
||||
byte impulse; // remove?
|
||||
byte lightlevel; // light level the player is standing on
|
||||
short forwardmove, sidemove, upmove;
|
||||
} usercmd_t;
|
||||
|
||||
typedef struct pmove_s
|
||||
{
|
||||
player_state_t ps; // state (in / out)
|
||||
|
||||
// command (in)
|
||||
usercmd_t cmd;
|
||||
|
||||
physbody_t *body; // pointer to physobject
|
||||
|
||||
// results (out)
|
||||
int numtouch;
|
||||
edict_t *touchents[PM_MAXTOUCH]; // max touch
|
||||
|
||||
vec3_t mins, maxs; // bounding box size
|
||||
int watertype;
|
||||
int waterlevel;
|
||||
float xyspeed; // avoid to compute it twice
|
||||
|
||||
// callbacks to test the world
|
||||
trace_t (*trace)( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end );
|
||||
int (*pointcontents)( vec3_t point );
|
||||
} pmove_t;
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
@ -283,9 +437,17 @@ typedef struct physic_exp_s
|
|||
int (*LeafArea)( int leafnum );
|
||||
bool (*AreasConnected)( int area1, int area2 );
|
||||
int (*WriteAreaBits)( byte *buffer, int area );
|
||||
|
||||
// player movement code
|
||||
void (*PlayerMove)( pmove_t *pmove, bool clientmove );
|
||||
|
||||
void (*ServerMove)( pmove_t *pmove );
|
||||
void (*ClientMove)( pmove_t *pmove );
|
||||
|
||||
// simple objects
|
||||
physbody_t *(*CreateBody)( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform, int solid );
|
||||
physbody_t *(*CreatePlayer)( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform );
|
||||
|
||||
bool (*GetForce)(physbody_t *body, vec3_t vel, vec3_t avel, vec3_t force, vec3_t torque );
|
||||
void (*SetForce)(physbody_t *body, vec3_t vel, vec3_t avel, vec3_t force, vec3_t torque );
|
||||
bool (*GetMassCentre)( physbody_t *body, matrix3x3 mass );
|
||||
|
@ -298,6 +460,7 @@ typedef struct physic_imp_s
|
|||
// interface validator
|
||||
size_t api_size; // must matched with sizeof(physic_imp_t)
|
||||
|
||||
void (*ClientMove)( sv_edict_t *ed );
|
||||
void (*Transform)( sv_edict_t *ed, matrix4x3 transform );
|
||||
float *(*GetModelVerts)( sv_edict_t *ent, int *numvertices );
|
||||
} physic_imp_t;
|
||||
|
|
|
@ -307,6 +307,26 @@ _inline void VectorVectors(vec3_t forward, vec3_t right, vec3_t up)
|
|||
CrossProduct(right, forward, up);
|
||||
}
|
||||
|
||||
_inline void MatrixTranspose( 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];
|
||||
}
|
||||
|
||||
_inline void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
|
||||
{
|
||||
float angle;
|
||||
|
@ -837,6 +857,26 @@ _inline void R_ConcatTransforms( matrix3x4 in1, matrix3x4 in2, matrix3x4 out )
|
|||
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
|
||||
}
|
||||
|
||||
_inline void MatrixConcat( 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] + in1[0][3] * in2[3][0];
|
||||
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1] + in1[0][3] * in2[3][1];
|
||||
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2] + in1[0][3] * in2[3][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] * in2[3][3];
|
||||
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0] + in1[1][3] * in2[3][0];
|
||||
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1] + in1[1][3] * in2[3][1];
|
||||
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2] + in1[1][3] * in2[3][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] * in2[3][3];
|
||||
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0] + in1[2][3] * in2[3][0];
|
||||
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1] + in1[2][3] * in2[3][1];
|
||||
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2] + in1[2][3] * in2[3][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] * in2[3][3];
|
||||
out[3][0] = in1[3][0] * in2[0][0] + in1[3][1] * in2[1][0] + in1[3][2] * in2[2][0] + in1[3][3] * in2[3][0];
|
||||
out[3][1] = in1[3][0] * in2[0][1] + in1[3][1] * in2[1][1] + in1[3][2] * in2[2][1] + in1[3][3] * in2[3][1];
|
||||
out[3][2] = in1[3][0] * in2[0][2] + in1[3][1] * in2[1][2] + in1[3][2] * in2[2][2] + in1[3][3] * in2[3][2];
|
||||
out[3][3] = in1[3][0] * in2[0][3] + in1[3][1] * in2[1][3] + in1[3][2] * in2[2][3] + in1[3][3] * in2[3][3];
|
||||
}
|
||||
|
||||
_inline void TransformRGB( vec3_t in, vec3_t out )
|
||||
{
|
||||
out[0] = in[0]/255.0f;
|
||||
|
|
Reference in New Issue