04 Jun 2008

This commit is contained in:
g-cont 2008-06-04 00:00:00 +04:00 committed by Alibek Omarov
parent a5b7ffbf24
commit 11da3ddb7d
14 changed files with 252 additions and 40 deletions

View File

@ -129,7 +129,7 @@ static void ParseShaderFile( char *filename )
if ( !Com_GetToken( true )) break;
si = AllocShaderInfo();
strcpy( si->name, com_token );
com.strcpy( si->name, com_token );
Com_GetToken( true );
if(!Com_MatchToken( "{" ))

View File

@ -671,7 +671,7 @@ bool CG_ParseArgs( int num_argc )
{
cls.cg_argc = 0;
memset(cls.cg_argv, 0, MAX_PARMS * MAX_QPATH );
strncpy( cls.cg_builtin, com_token, MAX_QPATH );
com.strncpy( cls.cg_builtin, com_token, MAX_QPATH );
// bound range silently
num_argc = bound(0, num_argc, MAX_PARMS - 1);
@ -688,7 +688,7 @@ bool CG_ParseArgs( int num_argc )
else if(Com_MatchToken(",")) cls.cg_argc++; // new argument
else if(Com_MatchToken("(") || Com_MatchToken(")"))
continue; // skip punctuation
else strncpy(cls.cg_argv[cls.cg_argc], com_token, MAX_QPATH ); // fill stack
else com.strncpy(cls.cg_argv[cls.cg_argc], com_token, MAX_QPATH ); // fill stack
}
if(num_argc > 0 && cls.cg_argc < num_argc - 1)
@ -958,7 +958,7 @@ void CG_ExecuteProgram( char *section )
bool skip = true;
Com_ResetScript();
strncpy( cls.cg_function, section, MAX_QPATH );
com.strncpy( cls.cg_function, section, MAX_QPATH );
cls.cg_depth = 0;
// not loaded

View File

@ -160,14 +160,17 @@ CL_Pause_f
*/
void CL_Pause_f (void)
{
if(!Host_ServerState() && !cls.demoplayback )
return; // but allow pause in demos
// never pause in multiplayer
if (Cvar_VariableValue ("maxclients") > 1 || !Host_ServerState ())
if( Cvar_VariableValue ("maxclients") > 1 )
{
Cvar_SetValue ("paused", 0);
return;
}
Cvar_SetValue ("paused", !cl_paused->value);
Cvar_SetValue( "paused", !cl_paused->value );
}
/*
@ -767,13 +770,18 @@ void CL_ReadPackets (void)
//
// check timeout
//
if (cls.state >= ca_connected && cls.realtime - cls.netchan.last_received > cl_timeout->value)
if( cls.state >= ca_connected && !cls.demoplayback )
{
if (++cl.timeoutcount > 5) // timeoutcount saves debugger
if( cls.realtime - cls.netchan.last_received > cl_timeout->value)
{
Msg ("\nServer connection timed out.\n");
CL_Disconnect ();
return;
cl.timeoutcount++; // timeoutcount saves debugger
if( cl.timeoutcount > 5 )
{
Msg ("\nServer connection timed out.\n");
CL_Disconnect ();
return;
}
}
}
else cl.timeoutcount = 0;
@ -857,20 +865,13 @@ static const char *env_suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
void CL_RequestNextDownload (void)
{
unsigned map_checksum; // for detecting cheater maps
char fn[MAX_OSPATH];
studiohdr_t *pheader;
uint map_checksum; // for detecting cheater maps
char fn[MAX_OSPATH];
studiohdr_t *pheader;
if(cls.state != ca_connected)
return;
if( cls.demoplayback )
{
CL_RegisterSounds();
CL_PrepRefresh();
return;
}
if (!allow_download->value && precache_check < ENV_CNT)
precache_check = ENV_CNT;
@ -1100,17 +1101,6 @@ before allowing the client into the server
*/
void CL_Precache_f (void)
{
// Yet another hack to let old demos work
// the old precache sequence
if(Cmd_Argc() < 2)
{
uint map_checksum; // for detecting cheater maps
pe->BeginRegistration( cl.configstrings[CS_MODELS+1], true, &map_checksum );
CL_RegisterSounds();
CL_PrepRefresh();
return;
}
precache_check = CS_MODELS;
precache_spawncount = com.atoi(Cmd_Argv(1));
precache_model = 0;

View File

@ -284,6 +284,8 @@ void CL_PrepRefresh( void )
if (!cl.configstrings[CS_MODELS+1][0])
return; // no map loaded
Msg("CL_PrepRefresh: %s\n", cl.configstrings[CS_NAME] );
// get splash name
Cvar_Set( "cl_levelshot_name", va("background/%s.tga", cl.configstrings[CS_NAME]));
if(!FS_FileExists(va("graphics/%s", Cvar_VariableString("cl_levelshot_name"))))

View File

@ -115,6 +115,7 @@ void Host_InitPhysic( void )
// phys callback
pi.api_size = sizeof(physic_imp_t);
pi.Transform = SV_Transform;
pi.PlaySound = SV_PlaySound;
pi.ClientMove = SV_PlayerMove;
pi.GetModelVerts = SV_GetModelVerts;

View File

@ -329,6 +329,7 @@ bool SV_CreateMeshBuffer( edict_t *in, cmodel_t *out );
void SV_SpawnEntities( const char *mapname, const char *entities );
void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count);
void SV_Transform( sv_edict_t *ed, matrix4x3 transform );
void SV_PlaySound( sv_edict_t *ed, float volume, const char *sample );
void SV_FreeEdict (edict_t *ed);
void SV_InitEdict (edict_t *e);
edict_t *SV_Spawn (void);

View File

@ -838,4 +838,15 @@ void SV_PlayerMove( sv_edict_t *ed )
VectorCopy(pm.mins, player->progs.sv->mins);
VectorCopy(pm.maxs, player->progs.sv->maxs);
VectorCopy(pm.ps.viewangles, client->ps.viewangles);
}
void SV_PlaySound( sv_edict_t *ed, float volume, const char *sample )
{
float vol = bound( 0.0f, volume/255.0f, 255.0f );
int sound_idx = SV_SoundIndex( sample );
edict_t *ent;
if( !ed ) ed = prog->edicts->priv.sv;
ent = PRVM_PROG_TO_EDICT( ed->serialnumber );
SV_StartSound( ent->progs.sv->origin, ent, CHAN_BODY, sound_idx, vol, 1.0f, 0 );
}

View File

@ -5,6 +5,72 @@
#include "cm_local.h"
int Callback_ContactBegin( const NewtonMaterial* material, const NewtonBody* body0, const NewtonBody* body1 )
{
// save the collision bodies
cm.touch_info.m_body0 = (NewtonBody*) body0;
cm.touch_info.m_body1 = (NewtonBody*) body1;
cm.touch_info.normal_speed = 0.0f;// clear the contact normal speed
cm.touch_info.tangent_speed = 0.0f;// clear the contact sliding speed
// return one the tell Newton the application wants to process this contact
return 1;
}
// this callback is called for every contact between the two bodies
int Callback_ContactProcess( const NewtonMaterial* material, const NewtonContact* contact )
{
float speed0, speed1;
vec3_t normal;
// get the maximum normal speed of this impact. this can be used for particles of playing collision sound
speed0 = NewtonMaterialGetContactNormalSpeed( material, contact );
if( speed0 > cm.touch_info.normal_speed )
{
// save the position of the contact (for 3d sound of particles effects)
cm.touch_info.normal_speed = speed0;
NewtonMaterialGetContactPositionAndNormal( material, &cm.touch_info.position[0], &normal[0] );
}
// get the maximum of the two sliding contact speed
speed0 = NewtonMaterialGetContactTangentSpeed( material, contact, 0 );
speed1 = NewtonMaterialGetContactTangentSpeed( material, contact, 1 );
if( speed1 > speed0 ) speed0 = speed1;
// Get the maximum tangent speed of this contact. this can be used for particles(sparks) of playing scratch sounds
if( speed0 > cm.touch_info.tangent_speed )
{
// save the position of the contact (for 3d sound of particles effects)
cm.touch_info.tangent_speed = speed0;
NewtonMaterialGetContactPositionAndNormal( material, &cm.touch_info.position[0], &normal[0] );
}
// return one to tell Newton we want to accept this contact
return 1;
}
// this function is call after all contacts for this pairs is processed
void Callback_ContactEnd( const NewtonMaterial* material )
{
sv_edict_t *edict = (sv_edict_t *)NewtonBodyGetUserData( cm.touch_info.m_body0 );
// if the max contact speed is larger than some minimum value. play a sound
if( cm.touch_info.normal_speed > 15.0f )
{
float pitch = cm.touch_info.normal_speed - 15.0f;
// TODO: play impact sound here
pi.PlaySound( edict, pitch, "materials/metal/bustmetal1.wav" );
}
// if the max contact speed is larger than some minimum value. play a sound
if( cm.touch_info.normal_speed > 5.0f )
{
float pitch = cm.touch_info.normal_speed - 5.0f;
// TODO: play scratch sound here
pi.PlaySound( edict, pitch, "materials/metal/pushmetal1.wav" );
}
}
void Callback_ApplyForce( const NewtonBody* body )
{

View File

@ -8,6 +8,7 @@
#include "physic.h"
#include "basefiles.h"
#define MAX_MATERIALS 64
#define CAPSULE_MODEL_HANDLE MAX_MODELS - 2
#define BOX_MODEL_HANDLE MAX_MODELS - 1
@ -40,6 +41,25 @@ typedef struct
int floodvalid;
} carea_t;
typedef struct material_info_s
{
string name;
float softness;
float elasticity;
float friction_static;
float friction_kinetic;
} material_info_t;
typedef struct collide_info_s
{
NewtonBody *m_body0;
NewtonBody *m_body1;
vec3_t position;
float normal_speed;
float tangent_speed;
} collide_info_t;
typedef struct clipmap_s
{
string name;
@ -99,6 +119,9 @@ typedef struct clipmap_s
NewtonBody *body;
matrix4x4 matrix; // world matrix
NewtonJoint *upVector; // world upvector
material_info_t mat[MAX_MATERIALS];
uint num_materials; // number of parsed materials
collide_info_t touch_info; // global info about two touching objects
bool loaded; // map is loaded?
bool tree_build; // phys tree is created ?
bool use_thread; // bsplib use thread
@ -204,7 +227,6 @@ 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;
@ -220,5 +242,16 @@ int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsiz
int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **list, int listsize );
cmodel_t *CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, bool capsule );
//
// cm_callbacks.c
//
int Callback_ContactBegin( const NewtonMaterial* material, const NewtonBody* body0, const NewtonBody* body1 );
int Callback_ContactProcess( const NewtonMaterial* material, const NewtonContact* contact );
void Callback_ContactEnd( const NewtonMaterial* material );
//
// cm_materials.c
//
void CM_InitMaterials( void );
#endif//CM_LOCAL_H

100
physic/cm_materials.c Normal file
View File

@ -0,0 +1,100 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// cm_materials.c - server materials system
//=======================================================================
#include "cm_local.h"
bool CM_ParseMaterial( void )
{
uint num = cm.num_materials;
if( num > MAX_MATERIALS - 1 )
{
Msg( "materials limit exceeded\n" );
return false;
}
if(!Com_MatchToken( "materialgroup" ))
return false; // not a material description
Com_GetToken( false );
if(Com_MatchToken( "default" ))
num = 0; // write default material first
// member material name
com.strncpy( cm.mat[num].name, com_token, MAX_STRING );
// setup default values
while(!Com_MatchToken( "}" ))
{
if(!Com_GetToken( true ))
return false; // unfinished material description
if( Com_MatchToken( "elasticity" ))
{
Com_GetToken( false );
cm.mat[num].elasticity = com.atof( com_token );
}
else if( Com_MatchToken( "softness" ))
{
Com_GetToken( false );
cm.mat[num].softness = com.atof( com_token );
}
else if( Com_MatchToken( "friction" ))
{
Com_GetToken( false );
cm.mat[num].friction_static = com.atof( com_token );
if(Com_TryToken())
cm.mat[num].friction_kinetic = com.atof( com_token );
else cm.mat[num].friction_kinetic = cm.mat[num].friction_static; // same as static friction
}
}
// set default values if needed
if( cm.mat[num].softness == 0.0f ) cm.mat[num].softness = cm.mat[0].softness;
if( cm.mat[num].elasticity == 0.0f ) cm.mat[num].elasticity = cm.mat[0].elasticity;
if( cm.mat[num].friction_static == 0.0f ) cm.mat[num].friction_static = cm.mat[0].friction_static;
if( cm.mat[num].friction_kinetic == 0.0f ) cm.mat[num].friction_kinetic = cm.mat[0].friction_kinetic;
cm.num_materials++;
// material will be parsed sucessfully
return true;
}
void CM_InitMaterials( void )
{
bool load = Com_LoadScript( "scripts/materials.txt", NULL, 0 );
int i, j;
if( !load )
{
// nothing to parse
MsgDev( D_WARN, "scripts/materials.txt not found!\n" );
return;
}
cm.num_materials = 0;
memset( cm.mat, 0, sizeof(material_info_t) * MAX_MATERIALS );
while( Com_GetToken( true ))
CM_ParseMaterial();
// assume IDs are in order and we don't need to remember them
for ( i = 1; i < cm.num_materials; i++ )
NewtonMaterialCreateGroupID( gWorld );
for ( i = 0; i < cm.num_materials; i++ )
{
for ( j = 0; j < cm.num_materials; j++ )
{
NewtonMaterialSetDefaultCollidable( gWorld, i, j, true );
NewtonMaterialSetDefaultSoftness( gWorld, i, j, cm.mat[i].softness / 2.0f + cm.mat[j].softness / 2.0f );
NewtonMaterialSetDefaultElasticity( gWorld, i, j, cm.mat[i].elasticity / 2.0f + cm.mat[j].elasticity / 2.0f );
NewtonMaterialSetDefaultFriction( gWorld, i, j, cm.mat[i].friction_static / 2.0f + cm.mat[j].friction_static / 2.0f, cm.mat[i].friction_kinetic / 2.0f + cm.mat[j].friction_kinetic / 2.0f );
NewtonMaterialSetCollisionCallback( gWorld, i, j, NULL, Callback_ContactBegin, Callback_ContactProcess, Callback_ContactEnd );
}
}
Msg( "num materials %d\n", cm.num_materials );
}

View File

@ -14,7 +14,6 @@ float m_yawAngle;
float m_maxTranslation;
vec3_t m_size;
vec3_t m_stepContact;
vec3_t m_forceVector;
matrix4x4 m_matrix;
@ -37,6 +36,8 @@ typedef struct
vec3_t forward, right, up;
vec3_t previous_origin;
vec3_t previous_velocity;
vec3_t movedir; // already aligned by world
int previous_waterlevel;
float impact_speed;
trace_t groundtrace;
@ -1607,9 +1608,9 @@ void CM_CmdUpdateForce( void )
VectorNormalize( pml.right );
for( i = 0; i < 3; i++ )
m_forceVector[i] = pml.forward[i] * fmove + pml.right[i] * smove;
pml.movedir[i] = pml.forward[i] * fmove + pml.right[i] * smove;
ConvertDirectionToPhysic( m_forceVector );
ConvertDirectionToPhysic( pml.movedir );
if( pm->cmd.upmove > 0.0f )
{
@ -1672,8 +1673,8 @@ void CM_ServerMove( pmove_t *pmove )
float speed_factor;
vec3_t tmp1, tmp2, result;
speed_factor = sqrt( DotProduct( m_forceVector, m_forceVector ) + 1.0e-6f );
VectorScale( m_forceVector, 1.0f / speed_factor, heading );
speed_factor = sqrt( DotProduct( pml.movedir, pml.movedir ) + 1.0e-6f );
VectorScale( pml.movedir, 1.0f / speed_factor, heading );
VectorScale( heading, mass * 20.0f, tmp1 );
VectorScale( heading, 2.0f * DotProduct( velocity, heading ), tmp2 );

View File

@ -23,6 +23,8 @@ bool InitPhysics( void )
cmappool = Mem_AllocPool("CM Zone");
gWorld = NewtonCreate( Palloc, Pfree ); // alloc world
CM_InitMaterials();
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)" );

View File

@ -121,6 +121,10 @@ SOURCE=.\cm_debug.c
# End Source File
# Begin Source File
SOURCE=.\cm_materials.c
# End Source File
# Begin Source File
SOURCE=.\cm_model.c
# End Source File
# Begin Source File
@ -145,11 +149,11 @@ SOURCE=.\cm_trace.c
# End Source File
# Begin Source File
SOURCE=.\physic.c
SOURCE=.\cm_utils.c
# End Source File
# Begin Source File
SOURCE=.\cm_utils.c
SOURCE=.\physic.c
# End Source File
# End Group
# Begin Group "Header Files"

View File

@ -463,6 +463,7 @@ typedef struct physic_imp_s
void (*ClientMove)( sv_edict_t *ed );
void (*Transform)( sv_edict_t *ed, matrix4x3 transform );
void (*PlaySound)( sv_edict_t *ed, float volume, const char *sample );
float *(*GetModelVerts)( sv_edict_t *ent, int *numvertices );
} physic_imp_t;