rewritten vast chunks of code to support MOVE_HITMODEL as well as clean some of it up a bit. Dedicated server should build now.

A couple of minor bugs fixed too.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1146 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-07-16 00:53:08 +00:00
parent f1ea7c0c06
commit 50a59ff11f
24 changed files with 673 additions and 434 deletions

View file

@ -2108,10 +2108,9 @@ guess_pm_type:
state->pm_type = PM_DEAD; state->pm_type = PM_DEAD;
else else
state->pm_type = PM_NORMAL; state->pm_type = PM_NORMAL;
TP_ParsePlayerInfo(oldstate, state, info);
} }
TP_ParsePlayerInfo(oldstate, state, info);
} }
void CL_ParseClientPersist(void) void CL_ParseClientPersist(void)

View file

@ -814,7 +814,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y)
memset(&tr, 0, sizeof(tr)); memset(&tr, 0, sizeof(tr));
tr.fraction = 1; tr.fraction = 1;
cl.worldmodel->hulls->funcs.RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, start, end, &tr); cl.worldmodel->funcs.Trace(cl.worldmodel, 0, 0, start, end, vec3_origin, vec3_origin, &tr);
start[2]-=16; start[2]-=16;
if (tr.fraction == 1) if (tr.fraction == 1)
{ {

View file

@ -200,7 +200,7 @@ void CL_InitTEnts (void)
int i; int i;
for (i = 0; i < sizeof(tentsfx)/sizeof(tentsfx[0]); i++) for (i = 0; i < sizeof(tentsfx)/sizeof(tentsfx[0]); i++)
{ {
if (COM_FCheckExists(tentsfx[i].efname)) if (COM_FCheckExists(va("sound/%s", tentsfx[i].efname)))
*tentsfx[i].sfx = S_PrecacheSound (tentsfx[i].efname); *tentsfx[i].sfx = S_PrecacheSound (tentsfx[i].efname);
else else
*tentsfx[i].sfx = NULL; *tentsfx[i].sfx = NULL;

View file

@ -643,12 +643,11 @@ void Key_Message (int key)
if (key == K_ENTER) if (key == K_ENTER)
{ {
if (chat_team) if (chat_buffer[0])
Cbuf_AddText ("say_team ", RESTRICT_LOCAL); { //send it straight into the command.
else Cmd_TokenizeString(va("%s %s", chat_team?"say_team":"say", chat_buffer), true, false);
Cbuf_AddText ("say ", RESTRICT_LOCAL); CL_Say(chat_team, "");
Cbuf_AddText(chat_buffer, RESTRICT_LOCAL); }
Cbuf_AddText("\n", RESTRICT_LOCAL);
key_dest = key_game; key_dest = key_game;
chat_bufferlen = 0; chat_bufferlen = 0;

View file

@ -7,7 +7,7 @@ struct texture_s;
#if defined(SERVERONLY) #if defined(SERVERONLY)
#define qrenderer QR_NONE #define qrenderer QR_NONE
#define FNC(n) (n) #define FNC(n) (n) //FNC is defined as 'pointer if client build, direct if dedicated server'
#else #else
#define FNC(n) (*n) #define FNC(n) (*n)
extern r_qrenderer_t qrenderer; extern r_qrenderer_t qrenderer;
@ -102,8 +102,8 @@ extern qbyte *FNC(Mod_Q1LeafPVS) (struct mleaf_s *leaf, struct model_s *mode
extern void FNC(Mod_NowLoadExternal) (void); extern void FNC(Mod_NowLoadExternal) (void);
extern void FNC(Mod_Think) (void); extern void FNC(Mod_Think) (void);
extern qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms); extern qboolean FNC(Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
extern int (*Mod_TagNumForName) (struct model_s *model, char *name); extern int FNC(Mod_TagNumForName) (struct model_s *model, char *name);
#undef FNC #undef FNC

View file

@ -354,7 +354,7 @@ trace_t CL_Move(vec3_t v1, vec3_t mins, vec3_t maxs, vec3_t v2, float nomonsters
memset(&trace, 0, sizeof(trace)); memset(&trace, 0, sizeof(trace));
trace.fraction = 1; trace.fraction = 1;
cl.worldmodel->hulls->funcs.RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, v1, v2, &trace); cl.worldmodel->funcs.Trace(cl.worldmodel, 0, 0, v1, v2, vec3_origin, vec3_origin, &trace);
//why use trace.endpos instead? //why use trace.endpos instead?
//so that if we hit a wall early, we don't have a box covering the whole world because of a shotgun trace. //so that if we hit a wall early, we don't have a box covering the whole world because of a shotgun trace.

View file

@ -2779,7 +2779,7 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
memset (&trace, 0, sizeof(trace)); memset (&trace, 0, sizeof(trace));
VectorSubtract(start, pe->origin, ts); VectorSubtract(start, pe->origin, ts);
VectorSubtract(end, pe->origin, te); VectorSubtract(end, pe->origin, te);
if (!hull->funcs.RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, ts, te, &trace)) if (!pe->model->funcs.Trace(pe->model, 0, 0, ts, te, vec3_origin, vec3_origin, &trace))
{ {
VectorSubtract(trace.endpos, ts, delta); VectorSubtract(trace.endpos, ts, delta);
len = Length(delta); len = Length(delta);

View file

@ -2894,9 +2894,17 @@ void TP_StatChanged (int stat, int value)
if (i & (IT_KEY1|IT_KEY2)) { if (i & (IT_KEY1|IT_KEY2)) {
if (cl.teamfortress && !cl.spectator) if (cl.teamfortress && !cl.spectator)
{
ExecTookTrigger (tp_name_flag.string, it_flag, ExecTookTrigger (tp_name_flag.string, it_flag,
cl.frames[cl.validsequence&UPDATE_MASK].playerstate[cl.playernum[SP]].origin); cl.frames[cl.validsequence&UPDATE_MASK].playerstate[cl.playernum[SP]].origin);
} }
}
if (!cl.spectator && cl.teamfortress && ~value & vars.items & (IT_KEY1|IT_KEY2))
{
vars.lastdrop_time = realtime;
strcpy (vars.lastdroploc, Macro_Location());
}
vars.olditems = vars.items; vars.olditems = vars.items;
vars.items = value; vars.items = value;
@ -3133,7 +3141,7 @@ qboolean TP_SuppressMessage(char *buf) {
return false; return false;
} }
static void CL_Say (qboolean team, char *extra) void CL_Say (qboolean team, char *extra)
{ {
extern cvar_t cl_fakename; extern cvar_t cl_fakename;
char text[2048], sendtext[2048], *s; char text[2048], sendtext[2048], *s;

View file

@ -43,6 +43,7 @@ void SWMod_LoadLighting (lump_t *l);
void Q2BSP_SetHullFuncs(hull_t *hull); void Q2BSP_SetHullFuncs(hull_t *hull);
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace);
qbyte areabits[MAX_Q2MAP_AREAS/8]; qbyte areabits[MAX_Q2MAP_AREAS/8];
@ -3594,6 +3595,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode; loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode;
loadmodel->funcs.MarkLights = Q2BSP_MarkLights; loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
#endif #endif
loadmodel->funcs.Trace = CM_Trace;
#ifndef SERVERONLY #ifndef SERVERONLY
//light grid info //light grid info
@ -3670,6 +3672,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.MarkLights = NULL; loadmodel->funcs.MarkLights = NULL;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum; loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum;
loadmodel->funcs.Trace = CM_Trace;
break; break;
#if defined(RGLQUAKE) #if defined(RGLQUAKE)
@ -3707,6 +3710,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.MarkLights = Q2BSP_MarkLights; loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum; loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum;
loadmodel->funcs.Trace = CM_Trace;
break; break;
#endif #endif
#if defined(SWQUAKE) #if defined(SWQUAKE)
@ -3745,6 +3749,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.MarkLights = Q2BSP_MarkLights; loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum; loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum;
loadmodel->funcs.Trace = CM_Trace;
break; break;
#endif #endif
default: default:
@ -3770,8 +3775,6 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->numsubmodels = CM_NumInlineModels(); loadmodel->numsubmodels = CM_NumInlineModels();
{ {
model_t *mod = loadmodel; model_t *mod = loadmodel;
@ -4984,6 +4987,11 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
return trace_trace; return trace_trace;
} }
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
*trace = CM_BoxTrace(start, end, mins, maxs, model->hulls[0].firstclipnode, MASK_PLAYERSOLID);
return trace->fraction != 1;
}
/* /*
================== ==================
@ -5498,7 +5506,6 @@ int Q2BSP_HullPointContents(hull_t *hull, vec3_t p)
} }
void Q2BSP_SetHullFuncs(hull_t *hull) void Q2BSP_SetHullFuncs(hull_t *hull)
{ {
hull->funcs.RecursiveHullCheck = Q2BSP_RecursiveHullCheck;
hull->funcs.HullPointContents = Q2BSP_HullPointContents; hull->funcs.HullPointContents = Q2BSP_HullPointContents;
} }

View file

@ -148,7 +148,7 @@ LINE TESTING IN HULLS
vec3_t trace_extents; vec3_t trace_extents;
qboolean PM_TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_t *trace, vec3_t origin, vec3_t angles) qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, trace_t *trace, vec3_t origin, vec3_t angles)
{ {
vec3_t start_l, end_l; vec3_t start_l, end_l;
vec3_t a; vec3_t a;
@ -161,14 +161,8 @@ qboolean PM_TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_
VectorSubtract (start, origin, start_l); VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l); VectorSubtract (end, origin, end_l);
if (!player_mins[2]) //hmm.. hull bigger than player? Or is this hexen2?
{
start_l[2] -= hull->clip_mins[2]+0.1;
end_l[2] -= hull->clip_mins[2]+0.1;
}
// rotate start and end into the models frame of reference // rotate start and end into the models frame of reference
if (hull != &box_hull && if (model &&
(angles[0] || angles[1] || angles[2]) ) (angles[0] || angles[1] || angles[2]) )
rotated = true; rotated = true;
else else
@ -189,7 +183,11 @@ qboolean PM_TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_
end_l[2] = DotProduct (temp, up); end_l[2] = DotProduct (temp, up);
} }
// sweep the box through the model // sweep the box through the model
result = hull->funcs.RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
if (model)
result = model->funcs.Trace(model, 0, 0, start_l, end_l, player_mins, player_maxs, trace);
else
result = Q1BSP_RecursiveHullCheck (&box_hull, box_hull.firstclipnode, 0, 1, start_l, end_l, trace);
if (rotated && trace->fraction != 1.0) if (rotated && trace->fraction != 1.0)
{ {
@ -209,8 +207,6 @@ qboolean PM_TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_
trace->endpos[0] = start[0] + trace->fraction * (end[0] - start[0]); trace->endpos[0] = start[0] + trace->fraction * (end[0] - start[0]);
trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]); trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]);
trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]); trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]);
// if (!player_mins[2]) //hmm.. hull bigger than player? Or is this hexen2?
// trace->endpos[2] += hull->clip_mins[2]+0.1;
return result; return result;
} }
@ -287,41 +283,9 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end)
{ {
pe = &pmove.physents[i]; pe = &pmove.physents[i];
// get the clipping hull // get the clipping hull
if (pe->model)
{
hull = &pmove.physents[i].model->hulls[pmove.hullnum];
if (!hull->available || !hull->clipnodes || !hull->planes)
hull = &pmove.physents[i].model->hulls[1]; //fallback
}
else
{
VectorSubtract (pe->mins, player_maxs, mins);
VectorSubtract (pe->maxs, player_mins, maxs);
hull = PM_HullForBox (mins, maxs);
}
// fill in a default trace
memset (&trace, 0, sizeof(trace_t));
trace.fraction = 1;
trace.allsolid = true;
// trace.startsolid = true;
VectorCopy (end, trace.endpos);
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
#ifdef Q2BSPS PM_TransformedHullCheck (pe->model, start, end, &trace, pe->origin, pe->angles);
if (pmove.physents[i].model && (pmove.physents[i].model->fromgame == fg_quake2 || pmove.physents[i].model->fromgame == fg_quake3))
{
trace_t tr;
tr = CM_TransformedBoxTrace (start, end, player_mins, player_maxs, pmove.physents[i].model->hulls[0].firstclipnode, MASK_PLAYERSOLID, pe->origin, pe->angles);
trace.startsolid = tr.startsolid;
trace.allsolid = tr.allsolid;
trace.fraction = tr.fraction;
memcpy(&trace.plane, &tr.plane, sizeof(tr.plane));
VectorCopy(tr.endpos, trace.endpos);
}
else
#endif
PM_TransformedHullCheck (hull, start, end, &trace, pe->origin, pe->angles);
if (trace.allsolid) if (trace.allsolid)
trace.startsolid = true; trace.startsolid = true;

View file

@ -204,10 +204,70 @@ int Q1BSP_HullPointContents(hull_t *hull, vec3_t p)
void Q1BSP_SetHullFuncs(hull_t *hull) void Q1BSP_SetHullFuncs(hull_t *hull)
{ {
hull->funcs.RecursiveHullCheck = Q1BSP_RecursiveHullCheck;
hull->funcs.HullPointContents = Q1BSP_HullPointContents; hull->funcs.HullPointContents = Q1BSP_HullPointContents;
} }
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
hull_t *hull;
vec3_t size;
vec3_t start_l, end_l;
vec3_t offset;
memset (trace, 0, sizeof(trace_t));
trace->fraction = 1;
trace->allsolid = true;
VectorSubtract (maxs, mins, size);
if (forcehullnum >= 1 && forcehullnum <= MAX_MAP_HULLSM && model->hulls[forcehullnum-1].available)
hull = &model->hulls[forcehullnum-1];
else
{
if (model->hulls[5].available)
{ //choose based on hexen2 sizes.
if (size[0] < 3) // Point
hull = &model->hulls[0];
else if (size[0] <= 32 && size[2] <= 28) // Half Player
hull = &model->hulls[3];
else if (size[0] <= 32) // Full Player
hull = &model->hulls[1];
else // Golumn
hull = &model->hulls[5];
}
else
{
if (size[0] < 3 || !model->hulls[1].available)
hull = &model->hulls[0];
else if (size[0] <= 32)
{
if (size[2] < 54 && model->hulls[3].available)
hull = &model->hulls[3]; // 32x32x36 (half-life's crouch)
else
hull = &model->hulls[1];
}
else
hull = &model->hulls[2];
}
}
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorSubtract(start, offset, start_l);
VectorSubtract(end, offset, end_l);
Q1BSP_RecursiveHullCheck(hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
if (trace->fraction == 1)
{
VectorCopy (end, trace->endpos);
}
else
{
VectorAdd (trace->endpos, offset, trace->endpos);
}
return trace->fraction != 1;
}
/* /*
Physics functions (common) Physics functions (common)

View file

@ -1,5 +1,5 @@
#include "quakedef.h" #include "quakedef.h"
#ifdef RGLQUAKE #if defined(RGLQUAKE) || defined(SERVERONLY)
#include "glquake.h" #include "glquake.h"
#include "shader.h" #include "shader.h"
#include "hash.h" #include "hash.h"
@ -10,6 +10,8 @@
#define MAX_BONES 256 #define MAX_BONES 256
static model_t *loadmodel;
//FIXME //FIXME
typedef struct typedef struct
{ {
@ -75,14 +77,18 @@ typedef struct {
int ofs_trineighbours; int ofs_trineighbours;
int numskins; int numskins;
#ifndef SERVERONLY
int ofsskins; int ofsskins;
#endif
qboolean sharesverts; //used with models with two shaders using the same vertex. qboolean sharesverts; //used with models with two shaders using the same vertex.
int numverts; int numverts;
#ifndef SERVERONLY
int ofs_st_array; int ofs_st_array;
#endif
int groups; int groups;
int groupofs; int groupofs;
@ -113,7 +119,9 @@ typedef struct {
typedef struct { typedef struct {
int ofsverts; int ofsverts;
#ifndef SERVERONLY
int ofsnormals; int ofsnormals;
#endif
vec3_t scale; vec3_t scale;
vec3_t scale_origin; vec3_t scale_origin;
@ -135,6 +143,7 @@ typedef struct {
//we can't be bothered with animating skins. //we can't be bothered with animating skins.
//We'll load up to four of them but after that you're on your own //We'll load up to four of them but after that you're on your own
#ifndef SERVERONLY
typedef struct { typedef struct {
int skinwidth; int skinwidth;
int skinheight; int skinheight;
@ -159,7 +168,141 @@ typedef struct {
int skinnum; int skinnum;
bucket_t bucket; bucket_t bucket;
} galiascolourmapped_t; } galiascolourmapped_t;
#endif
static void R_LerpBones(float *plerp, float **pose, int poses, galiasbone_t *bones, int bonecount, float bonepose[MAX_BONES][12]);
static void R_TransformVerticies(float bonepose[MAX_BONES][12], galisskeletaltransforms_t *weights, int numweights, float *xyzout);
void Mod_DoCRC(model_t *mod, char *buffer, int buffersize)
{
#ifndef SERVERONLY
//we've got to have this bit
if (!strcmp(loadmodel->name, "progs/player.mdl") ||
!strcmp(loadmodel->name, "progs/eyes.mdl"))
{
unsigned short crc;
qbyte *p;
int len;
char st[40];
CRC_Init(&crc);
for (len = buffersize, p = buffer; len; len--, p++)
CRC_ProcessByte(&crc, *p);
sprintf(st, "%d", (int) crc);
Info_SetValueForKey (cls.userinfo,
!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected)
{
CL_SendClientCommand(true, "setinfo %s %d",
!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
(int)crc);
}
}
#endif
}
#include <malloc.h>
qboolean GLMod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
galiasinfo_t *mod = Mod_Extradata(model);
galiasgroup_t *group;
galiaspose_t *pose;
int i;
float *p1, *p2, *p3;
vec3_t edge1, edge2, edge3;
vec3_t normal;
vec3_t edgenormal;
float planedist;
float diststart, distend;
float frac;
float temp;
vec3_t impactpoint;
float *posedata;
int *indexes;
while(mod)
{
indexes = (int*)((char*)mod + mod->ofs_indexes);
group = (galiasgroup_t*)((char*)mod + mod->groupofs);
pose = (galiaspose_t*)((char*)&group[0] + group[0].poseofs);
posedata = (float*)((char*)pose + pose->ofsverts);
if (group->isskeletal && !mod->sharesverts)
{
float bonepose[MAX_BONES][12];
posedata = alloca(mod->numverts*sizeof(vec3_t));
frac = 1;
R_LerpBones(&frac, (float**)posedata, 1, (galiasbone_t*)((char*)mod + mod->ofsbones), mod->numbones, bonepose);
R_TransformVerticies(bonepose, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
}
for (i = 0; i < mod->numindexes; i+=3)
{
p1 = posedata + 3*indexes[i+0];
p2 = posedata + 3*indexes[i+1];
p3 = posedata + 3*indexes[i+2];
VectorSubtract(p1, p2, edge1);
VectorSubtract(p3, p2, edge2);
CrossProduct(edge1, edge2, normal);
planedist = DotProduct(p1, normal);
diststart = DotProduct(start, normal);
if (diststart <= planedist)
continue; //start on back side.
distend = DotProduct(end, normal);
if (distend >= planedist)
continue; //end on front side (as must start - doesn't cross).
frac = (diststart - planedist) / (diststart-distend);
if (frac >= trace->fraction) //already found one closer.
continue;
impactpoint[0] = start[0] + frac*(end[0] - start[0]);
impactpoint[1] = start[1] + frac*(end[1] - start[1]);
impactpoint[2] = start[2] + frac*(end[2] - start[2]);
temp = DotProduct(impactpoint, normal)-planedist;
CrossProduct(edge1, normal, edgenormal);
temp = DotProduct(impactpoint, edgenormal)-DotProduct(p2, edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p2, edgenormal))
continue;
CrossProduct(normal, edge2, edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p3, edgenormal))
continue;
VectorSubtract(p1, p3, edge3);
CrossProduct(normal, edge3, edgenormal);
if (DotProduct(impactpoint, edgenormal) > DotProduct(p1, edgenormal))
continue;
trace->fraction = frac;
VectorCopy(impactpoint, trace->endpos);
VectorCopy(normal, trace->plane.normal);
}
if (mod->nextsurf)
mod = (galiasinfo_t*)((char*)mod + mod->nextsurf);
else
mod = NULL;
}
trace->allsolid = false;
return trace->fraction != 1;
}
#ifndef SERVERONLY
static hashtable_t skincolourmapped; static hashtable_t skincolourmapped;
static vec3_t shadevector; static vec3_t shadevector;
@ -288,17 +431,12 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
} }
} }
} }
#endif
#ifdef SKELETALMODELS #ifdef SKELETALMODELS
static void R_BuildSkeletalMesh(mesh_t *mesh, float *plerp, float **pose, int poses, galiasbone_t *bones, int bonecount, galisskeletaltransforms_t *weights, int numweights) static void R_LerpBones(float *plerp, float **pose, int poses, galiasbone_t *bones, int bonecount, float bonepose[MAX_BONES][12])
{ {
float bonepose[MAX_BONES][12];
float *outhead;
galisskeletaltransforms_t *v;
int i, k, b; int i, k, b;
float *out, *matrix, m[12]; float *matrix, m[12];
// vertex weighted skeletal // vertex weighted skeletal
// interpolate matrices and concatenate them to their parents // interpolate matrices and concatenate them to their parents
@ -319,10 +457,35 @@ static void R_BuildSkeletalMesh(mesh_t *mesh, float *plerp, float **pose, int po
for (k = 0;k < 12;k++) //parentless for (k = 0;k < 12;k++) //parentless
bonepose[i][k] = m[k]; bonepose[i][k] = m[k];
} }
}
static void R_TransformVerticies(float bonepose[MAX_BONES][12], galisskeletaltransforms_t *weights, int numweights, float *xyzout)
{
int i;
float *out, *matrix;
galisskeletaltransforms_t *v = weights;
for (i = 0;i < numweights;i++, v++)
{
out = xyzout + v->vertexindex * 3;
matrix = bonepose[v->boneindex];
// FIXME: this can very easily be optimized with SSE or 3DNow
out[0] += v->org[0] * matrix[0] + v->org[1] * matrix[1] + v->org[2] * matrix[ 2] + v->org[3] * matrix[ 3];
out[1] += v->org[0] * matrix[4] + v->org[1] * matrix[5] + v->org[2] * matrix[ 6] + v->org[3] * matrix[ 7];
out[2] += v->org[0] * matrix[8] + v->org[1] * matrix[9] + v->org[2] * matrix[10] + v->org[3] * matrix[11];
}
}
#ifndef SERVERONLY
static void R_BuildSkeletalMesh(mesh_t *mesh, float *plerp, float **pose, int poses, galiasbone_t *bones, int bonecount, galisskeletaltransforms_t *weights, int numweights)
{
float bonepose[MAX_BONES][12];
int i, k;
float *matrix, m[12];
R_LerpBones(plerp, pose, poses, bones, bonecount, bonepose);
outhead = (float*)mesh->xyz_array;
// blend the vertex bone weights // blend the vertex bone weights
memset(outhead, 0, mesh->numvertexes * sizeof(mesh->xyz_array[0])); // memset(outhead, 0, mesh->numvertexes * sizeof(mesh->xyz_array[0]));
for (i = 0; i < mesh->numvertexes; i++) for (i = 0; i < mesh->numvertexes; i++)
{ {
@ -342,19 +505,12 @@ static void R_BuildSkeletalMesh(mesh_t *mesh, float *plerp, float **pose, int po
*/ */
} }
v = weights; R_TransformVerticies(bonepose, weights, numweights, (float*)mesh->xyz_array);
for (i = 0;i < numweights;i++, v++)
{
out = outhead + v->vertexindex * 3;
matrix = bonepose[v->boneindex];
// FIXME: this can very easily be optimized with SSE or 3DNow
out[0] += v->org[0] * matrix[0] + v->org[1] * matrix[1] + v->org[2] * matrix[ 2] + v->org[3] * matrix[ 3];
out[1] += v->org[0] * matrix[4] + v->org[1] * matrix[5] + v->org[2] * matrix[ 6] + v->org[3] * matrix[ 7];
out[2] += v->org[0] * matrix[8] + v->org[1] * matrix[9] + v->org[2] * matrix[10] + v->org[3] * matrix[11];
}
} }
#endif #endif
#endif
#ifndef SERVERONLY
static void R_GAliasAddDlights(mesh_t *mesh, vec3_t org, vec3_t angles) static void R_GAliasAddDlights(mesh_t *mesh, vec3_t org, vec3_t angles)
{ {
int l, v; int l, v;
@ -486,14 +642,14 @@ static qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, i
if (inf->sharesverts) if (inf->sharesverts)
return false; //don't generate the new vertex positions. We still have them all. return false; //don't generate the new vertex positions. We still have them all.
#ifndef SERVERONLY
mesh->st_array = (vec2_t*)((char *)inf + inf->ofs_st_array); mesh->st_array = (vec2_t*)((char *)inf + inf->ofs_st_array);
mesh->lmst_array = NULL; mesh->lmst_array = NULL;
mesh->colors_array = tempColours; mesh->colors_array = tempColours;
mesh->xyz_array = tempVertexCoords;
mesh->trneighbors = (int *)((char *)inf + inf->ofs_trineighbours); mesh->trneighbors = (int *)((char *)inf + inf->ofs_trineighbours);
mesh->normals_array = tempNormals; mesh->normals_array = tempNormals;
#endif
mesh->xyz_array = tempVertexCoords;
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1); g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1);
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2); g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2);
@ -2061,8 +2217,6 @@ void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum)
} }
} }
static model_t *loadmodel;
void GL_LoadSkinFile(galiastexnum_t *texnum, char *surfacename, int skinnumber, unsigned char *rawdata, int width, int height, unsigned char *palette) void GL_LoadSkinFile(galiastexnum_t *texnum, char *surfacename, int skinnumber, unsigned char *rawdata, int width, int height, unsigned char *palette)
{ {
char shadername[MAX_QPATH]; char shadername[MAX_QPATH];
@ -2073,6 +2227,8 @@ void GL_LoadSkinFile(galiastexnum_t *texnum, char *surfacename, int skinnumber,
texnum->base = Mod_LoadHiResTexture(shadername, "models", true, true, true); texnum->base = Mod_LoadHiResTexture(shadername, "models", true, true, true);
} }
#endif //SERVERONLY
//Q1 model loading //Q1 model loading
#if 1 #if 1
@ -2108,16 +2264,18 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps)
verts = (vec3_t *)(pose+1); verts = (vec3_t *)(pose+1);
normals = &verts[galias->numverts]; normals = &verts[galias->numverts];
pose->ofsverts = (char *)verts - (char *)pose; pose->ofsverts = (char *)verts - (char *)pose;
#ifndef SERVERONLY
pose->ofsnormals = (char *)normals - (char *)pose; pose->ofsnormals = (char *)normals - (char *)pose;
#endif
for (j = 0; j < pq1inmodel->numverts; j++) for (j = 0; j < pq1inmodel->numverts; j++)
{ {
verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0]; verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1]; verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2]; verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]); VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]);
#endif
if (seamremaps[j] != j) if (seamremaps[j] != j)
{ {
VectorCopy(verts[j], verts[seamremaps[j]]); VectorCopy(verts[j], verts[seamremaps[j]]);
@ -2149,7 +2307,9 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps)
for (k = 0; k < frame->numposes; k++) for (k = 0; k < frame->numposes; k++)
{ {
pose->ofsverts = (char *)verts - (char *)pose; pose->ofsverts = (char *)verts - (char *)pose;
#ifndef SERVERONLY
pose->ofsnormals = (char *)normals - (char *)pose; pose->ofsnormals = (char *)normals - (char *)pose;
#endif
pinframe = (dtrivertx_t *)((char *)pinframe + sizeof(daliasframe_t)); pinframe = (dtrivertx_t *)((char *)pinframe + sizeof(daliasframe_t));
for (j = 0; j < pq1inmodel->numverts; j++) for (j = 0; j < pq1inmodel->numverts; j++)
@ -2157,8 +2317,9 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps)
verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0]; verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1]; verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2]; verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]); VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]);
#endif
if (seamremaps[j] != j) if (seamremaps[j] != j)
{ {
VectorCopy(verts[j], verts[seamremaps[j]]); VectorCopy(verts[j], verts[seamremaps[j]]);
@ -2184,6 +2345,37 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps)
return pframetype; return pframetype;
} }
#ifdef SERVERONLY //greatly reduced version of Q1_LoadSkins (too many #ifdefs
static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
{
int i;
int s;
int *count;
float *intervals;
qbyte *data;
s = pq1inmodel->skinwidth*pq1inmodel->skinheight;
for (i = 0; i < pq1inmodel->numskins; i++)
{
switch(LittleLong(pskintype->type))
{
case ALIAS_SKIN_SINGLE:
pskintype = (daliasskintype_t *)((char *)(pskintype+1)+s);
break;
default:
count = (int *)(pskintype+1);
intervals = (float *)(count+1);
data = (qbyte *)(intervals + LittleLong(*count));
data += s*LittleLong(*count);
pskintype = (daliasskintype_t *)data;
break;
}
}
galias->numskins=pq1inmodel->numskins;
return pskintype;
}
#else
static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
{ {
extern int gl_bumpmappingpossible; extern int gl_bumpmappingpossible;
@ -2343,13 +2535,17 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
galias->numskins=pq1inmodel->numskins; galias->numskins=pq1inmodel->numskins;
return pskintype; return pskintype;
} }
#endif
void GL_LoadQ1Model (model_t *mod, void *buffer) void GL_LoadQ1Model (model_t *mod, void *buffer)
{ {
#ifndef SERVERONLY
vec2_t *st_array; vec2_t *st_array;
int j;
#endif
int hunkstart, hunkend, hunktotal; int hunkstart, hunkend, hunktotal;
int version; int version;
int i, j, onseams; int i, onseams;
dstvert_t *pinstverts; dstvert_t *pinstverts;
dtriangle_t *pintriangles; dtriangle_t *pintriangles;
int *seamremap; int *seamremap;
@ -2359,31 +2555,7 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
loadmodel=mod; loadmodel=mod;
//we've got to have this bit Mod_DoCRC(loadmodel, buffer, com_filesize);
if (!strcmp(loadmodel->name, "progs/player.mdl") ||
!strcmp(loadmodel->name, "progs/eyes.mdl"))
{
unsigned short crc;
qbyte *p;
int len;
char st[40];
CRC_Init(&crc);
for (len = com_filesize, p = buffer; len; len--, p++)
CRC_ProcessByte(&crc, *p);
sprintf(st, "%d", (int) crc);
Info_SetValueForKey (cls.userinfo,
!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected)
{
CL_SendClientCommand(true, "setinfo %s %d",
!strcmp(loadmodel->name, "progs/player.mdl") ? pmodel_name : emodel_name,
(int)crc);
}
}
hunkstart = Hunk_LowMark (); hunkstart = Hunk_LowMark ();
@ -2409,12 +2581,16 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
mod->flags = pq1inmodel->flags; mod->flags = pq1inmodel->flags;
size = sizeof(galiasinfo_t) size = sizeof(galiasinfo_t)
+ pq1inmodel->numframes*sizeof(galiasgroup_t) #ifndef SERVERONLY
+ pq1inmodel->numskins*sizeof(galiasskin_t); + pq1inmodel->numskins*sizeof(galiasskin_t)
#endif
+ pq1inmodel->numframes*sizeof(galiasgroup_t);
galias = Hunk_Alloc(size); galias = Hunk_Alloc(size);
galias->groupofs = sizeof(*galias); galias->groupofs = sizeof(*galias);
#ifndef SERVERONLY
galias->ofsskins = sizeof(*galias)+pq1inmodel->numframes*sizeof(galiasgroup_t); galias->ofsskins = sizeof(*galias)+pq1inmodel->numframes*sizeof(galiasgroup_t);
#endif
galias->nextsurf = 0; galias->nextsurf = 0;
//skins //skins
@ -2438,7 +2614,9 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
seamremap = BZ_Malloc(sizeof(int)*pq1inmodel->numverts); seamremap = BZ_Malloc(sizeof(int)*pq1inmodel->numverts);
galias->numverts = pq1inmodel->numverts+onseams; galias->numverts = pq1inmodel->numverts+onseams;
//st //st
#ifndef SERVERONLY
st_array = Hunk_Alloc(sizeof(*st_array)*(pq1inmodel->numverts+onseams)); st_array = Hunk_Alloc(sizeof(*st_array)*(pq1inmodel->numverts+onseams));
galias->ofs_st_array = (char *)st_array - (char *)galias; galias->ofs_st_array = (char *)st_array - (char *)galias;
for (j=pq1inmodel->numverts,i = 0; i < pq1inmodel->numverts; i++) for (j=pq1inmodel->numverts,i = 0; i < pq1inmodel->numverts; i++)
@ -2456,6 +2634,7 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
else else
seamremap[i] = i; seamremap[i] = i;
} }
#endif
//trianglelists; //trianglelists;
pintriangles = (dtriangle_t *)&pinstverts[pq1inmodel->numverts]; pintriangles = (dtriangle_t *)&pinstverts[pq1inmodel->numverts];
@ -2482,7 +2661,7 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
//frames //frames
Q1_LoadFrameGroup((daliasframetype_t *)&pintriangles[pq1inmodel->numtris], seamremap); Q1_LoadFrameGroup((daliasframetype_t *)&pintriangles[pq1inmodel->numtris], seamremap);
BZ_Free(seamremap); BZ_Free(seamremap);
#ifndef SERVERONLY
if (r_shadows.value) if (r_shadows.value)
{ {
int *neighbours; int *neighbours;
@ -2490,7 +2669,7 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias; galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias;
R_BuildTriangleNeighbours(neighbours, indexes, pq1inmodel->numtris); R_BuildTriangleNeighbours(neighbours, indexes, pq1inmodel->numtris);
} }
#endif
VectorCopy (pq1inmodel->scale_origin, mod->mins); VectorCopy (pq1inmodel->scale_origin, mod->mins);
VectorMA (mod->mins, 255, pq1inmodel->scale, mod->maxs); VectorMA (mod->mins, 255, pq1inmodel->scale, mod->maxs);
// //
@ -2511,6 +2690,7 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart); Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = GLMod_Trace;
} }
#endif #endif
@ -2554,10 +2734,10 @@ extern vec3_t bytedirs[Q2NUMVERTEXNORMALS];
static void Q2_LoadSkins(char *skins) static void Q2_LoadSkins(char *skins)
{ {
#ifndef SERVERONLY
int i; int i;
galiastexnum_t *texnums; galiastexnum_t *texnums;
galiasskin_t *outskin = (galiasskin_t *)((char *)galias + galias->ofsskins); galiasskin_t *outskin = (galiasskin_t *)((char *)galias + galias->ofsskins);
galias->numskins = pq2inmodel->num_skins;
for (i = 0; i < pq2inmodel->num_skins; i++, outskin++) for (i = 0; i < pq2inmodel->num_skins; i++, outskin++)
{ {
@ -2573,15 +2753,22 @@ static void Q2_LoadSkins(char *skins)
skins += MD2MAX_SKINNAME; skins += MD2MAX_SKINNAME;
} }
#endif
galias->numskins = pq2inmodel->num_skins;
} }
#define MD2_MAX_TRIANGLES 4096 #define MD2_MAX_TRIANGLES 4096
void GL_LoadQ2Model (model_t *mod, void *buffer) void GL_LoadQ2Model (model_t *mod, void *buffer)
{ {
#ifndef SERVERONLY
dmd2stvert_t *pinstverts;
vec2_t *st_array;
vec3_t *normals;
#endif
int hunkstart, hunkend, hunktotal; int hunkstart, hunkend, hunktotal;
int version; int version;
int i, j; int i, j;
dmd2stvert_t *pinstverts;
dmd2triangle_t *pintri; dmd2triangle_t *pintri;
index_t *indexes; index_t *indexes;
int numindexes; int numindexes;
@ -2594,8 +2781,6 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
dmd2aliasframe_t *pinframe; dmd2aliasframe_t *pinframe;
int framesize; int framesize;
vec3_t *verts; vec3_t *verts;
vec3_t *normals;
vec2_t *st_array;
int indremap[MD2_MAX_TRIANGLES*3]; int indremap[MD2_MAX_TRIANGLES*3];
unsigned short ptempindex[MD2_MAX_TRIANGLES*3], ptempstindex[MD2_MAX_TRIANGLES*3]; unsigned short ptempindex[MD2_MAX_TRIANGLES*3], ptempstindex[MD2_MAX_TRIANGLES*3];
@ -2607,6 +2792,8 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
loadmodel=mod; loadmodel=mod;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark (); hunkstart = Hunk_LowMark ();
pq2inmodel = (md2_t *)buffer; pq2inmodel = (md2_t *)buffer;
@ -2632,12 +2819,16 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
loadmodel->numframes = pq2inmodel->num_frames; loadmodel->numframes = pq2inmodel->num_frames;
size = sizeof(galiasinfo_t) size = sizeof(galiasinfo_t)
+ pq2inmodel->num_frames*sizeof(galiasgroup_t) #ifndef SERVERONLY
+ pq2inmodel->num_skins*sizeof(galiasskin_t); + pq2inmodel->num_skins*sizeof(galiasskin_t)
#endif
+ pq2inmodel->num_frames*sizeof(galiasgroup_t);
galias = Hunk_Alloc(size); galias = Hunk_Alloc(size);
galias->groupofs = sizeof(*galias); galias->groupofs = sizeof(*galias);
#ifndef SERVERONLY
galias->ofsskins = sizeof(*galias)+pq2inmodel->num_frames*sizeof(galiasgroup_t); galias->ofsskins = sizeof(*galias)+pq2inmodel->num_frames*sizeof(galiasgroup_t);
#endif
galias->nextsurf = 0; galias->nextsurf = 0;
//skins //skins
@ -2704,6 +2895,7 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
} }
// s and t vertices // s and t vertices
#ifndef SERVERONLY
pinstverts = ( dmd2stvert_t * ) ( ( qbyte * )pq2inmodel + LittleLong (pq2inmodel->ofs_st) ); pinstverts = ( dmd2stvert_t * ) ( ( qbyte * )pq2inmodel + LittleLong (pq2inmodel->ofs_st) );
st_array = Hunk_Alloc(sizeof(*st_array)*(numverts)); st_array = Hunk_Alloc(sizeof(*st_array)*(numverts));
galias->ofs_st_array = (char *)st_array - (char *)galias; galias->ofs_st_array = (char *)st_array - (char *)galias;
@ -2713,6 +2905,7 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
st_array[indexes[j]][0] = (float)(((double)LittleShort (pinstverts[ptempstindex[indremap[j]]].s) + 0.5f) /pq2inmodel->skinwidth); st_array[indexes[j]][0] = (float)(((double)LittleShort (pinstverts[ptempstindex[indremap[j]]].s) + 0.5f) /pq2inmodel->skinwidth);
st_array[indexes[j]][1] = (float)(((double)LittleShort (pinstverts[ptempstindex[indremap[j]]].t) + 0.5f) /pq2inmodel->skinheight); st_array[indexes[j]][1] = (float)(((double)LittleShort (pinstverts[ptempstindex[indremap[j]]].t) + 0.5f) /pq2inmodel->skinheight);
} }
#endif
//frames //frames
ClearBounds ( mod->mins, mod->maxs ); ClearBounds ( mod->mins, mod->maxs );
@ -2721,15 +2914,21 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
framesize = LittleLong (pq2inmodel->framesize); framesize = LittleLong (pq2inmodel->framesize);
for (i=0 ; i<pq2inmodel->num_frames ; i++) for (i=0 ; i<pq2inmodel->num_frames ; i++)
{ {
pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*2*numverts); pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*numverts
#ifndef SERVERONLY
+ sizeof(vec3_t)*numverts
#endif
);
poutframe->poseofs = (char *)pose - (char *)poutframe; poutframe->poseofs = (char *)pose - (char *)poutframe;
poutframe->numposes = 1; poutframe->numposes = 1;
galias->groups++; galias->groups++;
verts = (vec3_t *)(pose+1); verts = (vec3_t *)(pose+1);
normals = &verts[galias->numverts];
pose->ofsverts = (char *)verts - (char *)pose; pose->ofsverts = (char *)verts - (char *)pose;
#ifndef SERVERONLY
normals = &verts[galias->numverts];
pose->ofsnormals = (char *)normals - (char *)pose; pose->ofsnormals = (char *)normals - (char *)pose;
#endif
pinframe = ( dmd2aliasframe_t * )( ( qbyte * )pq2inmodel + LittleLong (pq2inmodel->ofs_frames) + i * framesize ); pinframe = ( dmd2aliasframe_t * )( ( qbyte * )pq2inmodel + LittleLong (pq2inmodel->ofs_frames) + i * framesize );
@ -2746,7 +2945,9 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
verts[indexes[j]][0] = pose->scale_origin[0]+pose->scale[0]*pinframe->verts[ptempindex[indremap[j]]].v[0]; verts[indexes[j]][0] = pose->scale_origin[0]+pose->scale[0]*pinframe->verts[ptempindex[indremap[j]]].v[0];
verts[indexes[j]][1] = pose->scale_origin[1]+pose->scale[1]*pinframe->verts[ptempindex[indremap[j]]].v[1]; verts[indexes[j]][1] = pose->scale_origin[1]+pose->scale[1]*pinframe->verts[ptempindex[indremap[j]]].v[1];
verts[indexes[j]][2] = pose->scale_origin[2]+pose->scale[2]*pinframe->verts[ptempindex[indremap[j]]].v[2]; verts[indexes[j]][2] = pose->scale_origin[2]+pose->scale[2]*pinframe->verts[ptempindex[indremap[j]]].v[2];
#ifndef SERVERONLY
VectorCopy(bytedirs[pinframe->verts[ptempindex[indremap[j]]].lightnormalindex], normals[indexes[j]]); VectorCopy(bytedirs[pinframe->verts[ptempindex[indremap[j]]].lightnormalindex], normals[indexes[j]]);
#endif
} }
// Mod_AliasCalculateVertexNormals ( numindexes, poutindex, numverts, poutvertex, qfalse ); // Mod_AliasCalculateVertexNormals ( numindexes, poutindex, numverts, poutvertex, qfalse );
@ -2767,7 +2968,7 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
#ifndef SERVERONLY
if (r_shadows.value) if (r_shadows.value)
{ {
int *neighbours; int *neighbours;
@ -2775,7 +2976,7 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias; galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias;
R_BuildTriangleNeighbours(neighbours, indexes, pq2inmodel->num_tris); R_BuildTriangleNeighbours(neighbours, indexes, pq2inmodel->num_tris);
} }
#endif
/* /*
VectorCopy (pq2inmodel->scale_origin, mod->mins); VectorCopy (pq2inmodel->scale_origin, mod->mins);
VectorMA (mod->mins, 255, pq2inmodel->scale, mod->maxs); VectorMA (mod->mins, 255, pq2inmodel->scale, mod->maxs);
@ -2798,6 +2999,7 @@ void GL_LoadQ2Model (model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart); Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = GLMod_Trace;
} }
#endif #endif
@ -2825,8 +3027,11 @@ typedef struct {
#ifndef SERVERONLY
qboolean GLMod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result) qboolean GLMod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result)
#else
qboolean Mod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result)
#endif
{ {
galiasinfo_t *inf; galiasinfo_t *inf;
@ -2981,7 +3186,11 @@ qboolean GLMod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float
return false; return false;
} }
#ifndef SERVERONLY
int GLMod_TagNumForName(model_t *model, char *name) int GLMod_TagNumForName(model_t *model, char *name)
#else
int Mod_TagNumForName(model_t *model, char *name)
#endif
{ {
int i; int i;
galiasinfo_t *inf; galiasinfo_t *inf;
@ -3096,6 +3305,15 @@ typedef struct {
void GL_LoadQ3Model(model_t *mod, void *buffer) void GL_LoadQ3Model(model_t *mod, void *buffer)
{ {
#ifndef SERVERONLY
galiasskin_t *skin;
galiastexnum_t *texnum;
float lat, lng;
md3St_t *inst;
vec3_t *normals;
vec2_t *st_array;
md3Shader_t *inshader;
#endif
int hunkstart, hunkend, hunktotal; int hunkstart, hunkend, hunktotal;
// int version; // int version;
int s, i, j, d; int s, i, j, d;
@ -3109,19 +3327,10 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
galiasinfo_t *parent, *root; galiasinfo_t *parent, *root;
galiasgroup_t *group; galiasgroup_t *group;
galiasskin_t *skin;
galiastexnum_t *texnum;
vec3_t *verts; vec3_t *verts;
vec3_t *normals;
vec2_t *st_array;
float lat, lng;
md3St_t *inst;
md3Triangle_t *intris; md3Triangle_t *intris;
md3XyzNormal_t *invert; md3XyzNormal_t *invert;
md3Shader_t *inshader;
int size; int size;
@ -3132,6 +3341,8 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
loadmodel=mod; loadmodel=mod;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark (); hunkstart = Hunk_LowMark ();
header = buffer; header = buffer;
@ -3163,15 +3374,16 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
root = galias; root = galias;
parent = galias; parent = galias;
#ifndef SERVERONLY
st_array = Hunk_Alloc(sizeof(vec2_t)*galias->numindexes); st_array = Hunk_Alloc(sizeof(vec2_t)*galias->numindexes);
galias->ofs_st_array = (qbyte*)st_array - (qbyte*)galias; galias->ofs_st_array = (qbyte*)st_array - (qbyte*)galias;
inst = (md3St_t*)((qbyte*)surf + surf->ofsSt); inst = (md3St_t*)((qbyte*)surf + surf->ofsSt);
for (i = 0; i < galias->numverts; i++) for (i = 0; i < galias->numverts; i++)
{ {
st_array[i][0] = inst[i].s; st_array[i][0] = inst[i].s;
st_array[i][1] = inst[i].t; st_array[i][1] = inst[i].t;
} }
#endif
indexes = Hunk_Alloc(sizeof(*indexes)*galias->numindexes); indexes = Hunk_Alloc(sizeof(*indexes)*galias->numindexes);
galias->ofs_indexes = (qbyte*)indexes - (qbyte*)galias; galias->ofs_indexes = (qbyte*)indexes - (qbyte*)galias;
@ -3187,21 +3399,28 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
invert = (md3XyzNormal_t *)((qbyte*)surf + surf->ofsXyzNormals); invert = (md3XyzNormal_t *)((qbyte*)surf + surf->ofsXyzNormals);
for (i = 0; i < surf->numFrames; i++) for (i = 0; i < surf->numFrames; i++)
{ {
pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*2*surf->numVerts); pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*surf->numVerts
normals = (vec3_t*)(pose+1); #ifndef SERVERONLY
verts = normals + surf->numVerts; + sizeof(vec3_t)*surf->numVerts
#endif
);
pose->ofsnormals = (qbyte*)normals - (qbyte*)pose; verts = (vec3_t*)(pose+1);
pose->ofsverts = (qbyte*)verts - (qbyte*)pose; pose->ofsverts = (qbyte*)verts - (qbyte*)pose;
#ifndef SERVERONLY
normals = verts + surf->numVerts;
pose->ofsnormals = (qbyte*)normals - (qbyte*)pose;
#endif
for (j = 0; j < surf->numVerts; j++) for (j = 0; j < surf->numVerts; j++)
{ {
#ifndef SERVERONLY
lat = (float)invert[j].latlong[0] * (2 * M_PI)*(1.0 / 255.0); lat = (float)invert[j].latlong[0] * (2 * M_PI)*(1.0 / 255.0);
lng = (float)invert[j].latlong[1] * (2 * M_PI)*(1.0 / 255.0); lng = (float)invert[j].latlong[1] * (2 * M_PI)*(1.0 / 255.0);
normals[j][0] = cos ( lng ) * sin ( lat ); normals[j][0] = cos ( lng ) * sin ( lat );
normals[j][1] = sin ( lng ) * sin ( lat ); normals[j][1] = sin ( lng ) * sin ( lat );
normals[j][2] = cos ( lat ); normals[j][2] = cos ( lat );
#endif
for (d = 0; d < 3; d++) for (d = 0; d < 3; d++)
{ {
verts[j][d] = invert[j].xyz[d]/64.0f; verts[j][d] = invert[j].xyz[d]/64.0f;
@ -3228,6 +3447,7 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
invert += surf->numVerts; invert += surf->numVerts;
} }
#ifndef SERVERONLY
if (surf->numShaders) if (surf->numShaders)
{ {
#ifndef Q3SHADERS #ifndef Q3SHADERS
@ -3309,12 +3529,13 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
texnum++; texnum++;
} }
} }
#endif
VectorCopy(min, loadmodel->mins); VectorCopy(min, loadmodel->mins);
VectorCopy(max, loadmodel->maxs); VectorCopy(max, loadmodel->maxs);
#ifndef SERVERONLY
if (r_shadows.value) if (r_shadows.value)
{ {
int *neighbours; int *neighbours;
@ -3322,6 +3543,7 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias; galias->ofs_trineighbours = (qbyte *)neighbours - (qbyte *)galias;
R_BuildTriangleNeighbours(neighbours, indexes, surf->numTriangles); R_BuildTriangleNeighbours(neighbours, indexes, surf->numTriangles);
} }
#endif
surf = (md3Surface_t *)((qbyte *)surf + surf->ofsEnd); surf = (md3Surface_t *)((qbyte *)surf + surf->ofsEnd);
} }
@ -3356,6 +3578,8 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
memcpy (mod->cache.data, root, hunktotal); memcpy (mod->cache.data, root, hunktotal);
Hunk_FreeToLowMark (hunkstart); Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = GLMod_Trace;
} }
#endif #endif
@ -3421,7 +3645,14 @@ typedef struct zymvertex_s
//but only one set of transforms are ever generated. //but only one set of transforms are ever generated.
void GLMod_LoadZymoticModel(model_t *mod, void *buffer) void GLMod_LoadZymoticModel(model_t *mod, void *buffer)
{ {
int i, j; #ifndef SERVERONLY
galiasskin_t *skin;
galiastexnum_t *texnum;
int skinfiles;
int j;
#endif
int i;
int hunkstart, hunkend, hunktotal; int hunkstart, hunkend, hunktotal;
zymtype1header_t *header; zymtype1header_t *header;
@ -3430,9 +3661,6 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer)
galisskeletaltransforms_t *transforms; galisskeletaltransforms_t *transforms;
zymvertex_t *intrans; zymvertex_t *intrans;
galiasskin_t *skin;
galiastexnum_t *texnum;
galiasbone_t *bone; galiasbone_t *bone;
zymbone_t *inbone; zymbone_t *inbone;
int v; int v;
@ -3452,11 +3680,11 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer)
char *surfname; char *surfname;
int skinfiles;
loadmodel=mod; loadmodel=mod;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark (); hunkstart = Hunk_LowMark ();
header = buffer; header = buffer;
@ -3563,17 +3791,23 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer)
stcoords[i][1] = 1-BigFloat(inst[i][1]); //hmm. upside down skin coords? stcoords[i][1] = 1-BigFloat(inst[i][1]); //hmm. upside down skin coords?
} }
#ifndef SERVERONLY
skinfiles = GL_BuildSkinFileList(loadmodel->name); skinfiles = GL_BuildSkinFileList(loadmodel->name);
if (skinfiles < 1) if (skinfiles < 1)
skinfiles = 1; skinfiles = 1;
#endif
for (i = 0; i < header->numsurfaces; i++, surfname+=32) for (i = 0; i < header->numsurfaces; i++, surfname+=32)
{ {
root[i].ofs_st_array = (char*)stcoords - (char*)&root[i];
root[i].groups = header->numscenes; root[i].groups = header->numscenes;
root[i].groupofs = (char*)grp - (char*)&root[i]; root[i].groupofs = (char*)grp - (char*)&root[i];
#ifdef SERVERONLY
root[i].numskins = 1;
#else
root[i].ofs_st_array = (char*)stcoords - (char*)&root[i];
root[i].numskins = skinfiles;
skin = Hunk_Alloc((sizeof(galiasskin_t)+sizeof(galiastexnum_t))*skinfiles); skin = Hunk_Alloc((sizeof(galiasskin_t)+sizeof(galiastexnum_t))*skinfiles);
texnum = (galiastexnum_t*)(skin+skinfiles); texnum = (galiastexnum_t*)(skin+skinfiles);
for (j = 0; j < skinfiles; j++, texnum++) for (j = 0; j < skinfiles; j++, texnum++)
@ -3583,8 +3817,9 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer)
GL_LoadSkinFile(texnum, surfname, j, NULL, 0, 0, NULL); GL_LoadSkinFile(texnum, surfname, j, NULL, 0, 0, NULL);
} }
root[i].numskins = j;
root[i].ofsskins = (char *)skin - (char *)&root[i]; root[i].ofsskins = (char *)skin - (char *)&root[i];
#endif
} }
@ -3634,6 +3869,9 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer)
memcpy (mod->cache.data, root, hunktotal); memcpy (mod->cache.data, root, hunktotal);
Hunk_FreeToLowMark (hunkstart); Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = GLMod_Trace;
} }
#endif #endif

View file

@ -2528,6 +2528,7 @@ void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
void Q1BSP_FatPVS (vec3_t org, qboolean add); void Q1BSP_FatPVS (vec3_t org, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct edict_s *ent); qboolean Q1BSP_EdictInFatPVS(struct edict_s *ent);
void Q1BSP_FindTouchedLeafs(struct edict_s *ent); void Q1BSP_FindTouchedLeafs(struct edict_s *ent);
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace);
void GLQ1BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void GLQ1BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
@ -2650,6 +2651,7 @@ void GLMod_LoadBrushModel (model_t *mod, void *buffer)
mod->funcs.LightPointValues = GLQ1BSP_LightPointValues; mod->funcs.LightPointValues = GLQ1BSP_LightPointValues;
mod->funcs.StainNode = Q1BSP_StainNode; mod->funcs.StainNode = Q1BSP_StainNode;
mod->funcs.MarkLights = Q1BSP_MarkLights; mod->funcs.MarkLights = Q1BSP_MarkLights;
mod->funcs.Trace = Q1BSP_Trace;
mod->funcs.LeafForPoint = GLMod_LeafForPoint; mod->funcs.LeafForPoint = GLMod_LeafForPoint;
mod->funcs.LeafPVS = GLMod_LeafnumPVS; mod->funcs.LeafPVS = GLMod_LeafnumPVS;

View file

@ -29,11 +29,13 @@ struct trace_s;
struct edict_s; struct edict_s;
typedef struct { typedef struct {
qboolean (*RecursiveHullCheck) (struct hull_s *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace); // qboolean (*RecursiveHullCheck) (struct hull_s *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
int (*HullPointContents) (struct hull_s *hull, vec3_t p); //return FTE contents int (*HullPointContents) (struct hull_s *hull, vec3_t p); //return FTE contents
} hullfuncs_t; } hullfuncs_t;
typedef struct { typedef struct {
qboolean (*Trace) (struct model_s *model, int hulloverride, int frame, vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, struct trace_s *trace);
void (*FatPVS) (vec3_t org, qboolean add); void (*FatPVS) (vec3_t org, qboolean add);
qboolean (*EdictInFatPVS) (struct edict_s *edict); qboolean (*EdictInFatPVS) (struct edict_s *edict);
void (*FindTouchedLeafs_Q1) (struct edict_s *ent); //edict system as opposed to q2 game dll system. void (*FindTouchedLeafs_Q1) (struct edict_s *ent); //edict system as opposed to q2 game dll system.

View file

@ -66,7 +66,7 @@ vec_t CastRay (vec3_t p1, vec3_t p2)
hull = &lightmodel->hulls[0]; hull = &lightmodel->hulls[0];
memset (&trace, 0, sizeof(trace)); memset (&trace, 0, sizeof(trace));
if (!hull->funcs.RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, p1, p2, &trace)) if (!lightmodel->funcs.Trace (lightmodel, 0, 0, p1, p2, vec3_origin, vec3_origin, &trace))
return -1; return -1;
VectorSubtract(p1, p2, move); VectorSubtract(p1, p2, move);

View file

@ -2191,7 +2191,7 @@ pbool PR_TestRecompile(progfuncs_t *progfuncs)
return true; return true;
return false; return false;
} }
/*
#ifdef _DEBUG #ifdef _DEBUG
//this is for debugging. //this is for debugging.
//I'm using this to detect incorrect string types while converting 32bit string pointers with bias to bound indexes. //I'm using this to detect incorrect string types while converting 32bit string pointers with bias to bound indexes.
@ -2225,7 +2225,7 @@ void PR_TestForWierdness(progfuncs_t *progfuncs)
} }
} }
#endif #endif
*/
char *decode(int complen, int len, int method, char *info, char *buffer); char *decode(int complen, int len, int method, char *info, char *buffer);
/* /*
=============== ===============

View file

@ -245,12 +245,11 @@ int PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum)
pr_depth--; pr_depth--;
PR_StackTrace (progfuncs); PR_StackTrace (progfuncs);
printf ("stack overflow on call to %s\n", f->s_name); printf ("stack overflow on call to %s\n", progfuncs->stringtable+f->s_name);
//comment this out if you want the progs to try to continue anyway (could cause infinate loops) //comment this out if you want the progs to try to continue anyway (could cause infinate loops)
Abort("Stack Overflow\n");
PR_AbortStack(progfuncs); PR_AbortStack(progfuncs);
Abort("Stack Overflow in %s\n", progfuncs->stringtable+f->s_name);
return pr_xstatement; return pr_xstatement;
} }

View file

@ -798,7 +798,7 @@ void PR_BreakPoint_f(void)
Con_Printf("Breakpoint has been cleared\n"); Con_Printf("Breakpoint has been cleared\n");
} }
/*
#ifdef _DEBUG #ifdef _DEBUG
void QCLibTest(void) void QCLibTest(void)
{ {
@ -811,7 +811,7 @@ void QCLibTest(void)
PR_TestForWierdness(svprogfuncs); PR_TestForWierdness(svprogfuncs);
} }
#endif #endif
*/
typedef char char32[32]; typedef char char32[32];
char32 sv_addonname[MAXADDONS]; char32 sv_addonname[MAXADDONS];
void PR_Init(void) void PR_Init(void)
@ -821,9 +821,11 @@ void PR_Init(void)
Cmd_AddCommand ("decompile", PR_Decompile_f); Cmd_AddCommand ("decompile", PR_Decompile_f);
Cmd_AddCommand ("compile", PR_Compile_f); Cmd_AddCommand ("compile", PR_Compile_f);
Cmd_AddCommand ("applycompile", PR_ApplyCompilation_f); Cmd_AddCommand ("applycompile", PR_ApplyCompilation_f);
/*
#ifdef _DEBUG #ifdef _DEBUG
Cmd_AddCommand ("svtestprogs", QCLibTest); Cmd_AddCommand ("svtestprogs", QCLibTest);
#endif #endif
*/
Cvar_Register(&pr_maxedicts, cvargroup_progs); Cvar_Register(&pr_maxedicts, cvargroup_progs);
Cvar_Register(&pr_imitatemvdsv, cvargroup_progs); Cvar_Register(&pr_imitatemvdsv, cvargroup_progs);
Cvar_Register(&pr_fixbrokenqccarrays, cvargroup_progs); Cvar_Register(&pr_fixbrokenqccarrays, cvargroup_progs);
@ -3713,6 +3715,7 @@ void PF_droptofloor (progfuncs_t *prinst, struct globalvars_s *pr_globals)
end[2] -= 512; end[2] -= 512;
VectorCopy (ent->v->origin, start); VectorCopy (ent->v->origin, start);
start[2] += 1;
trace = SV_Move (start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); trace = SV_Move (start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
if (trace.fraction == 1 || trace.allsolid) if (trace.fraction == 1 || trace.allsolid)
@ -8644,12 +8647,19 @@ void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)
if (tagentity != sv.edicts && tagname && tagname[0]) if (tagentity != sv.edicts && tagname && tagname[0])
{ {
modelindex = (int)tagentity->v->modelindex; modelindex = (int)tagentity->v->modelindex;
if (modelindex > 0 && modelindex < MAX_MODELS && sv.model_precache[modelindex]) if (modelindex > 0 && modelindex < MAX_MODELS)
{
if (!sv.models[modelindex])
sv.models[modelindex] = Mod_ForName(sv.model_precache[modelindex], false);
if (sv.models[modelindex])
{ {
tagidx = SV_TagForName(modelindex, tagname); tagidx = SV_TagForName(modelindex, tagname);
if (tagidx == 0) if (tagidx == 0)
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), sv.models[modelindex]->name); Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), sv.models[modelindex]->name);
} }
else
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): Couldn't load model %s\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, sv.modelname[modelindex]);
}
else else
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity)); Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity));

View file

@ -2620,11 +2620,11 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
{ {
if (ent->v->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, client->edict)) if (ent->v->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, client->edict))
state->dpflags |= RENDER_VIEWMODEL; state->dpflags |= RENDER_VIEWMODEL;
// else else
// { //noone else sees it. { //noone else sees it.
// pack->num_entities--; pack->num_entities--;
// continue; continue;
// } }
} }
if (ent->v->exteriormodeltoclient) if (ent->v->exteriormodeltoclient)
{ {

View file

@ -1641,7 +1641,7 @@ client_t *SVC_DirectConnect(void)
newcl->netchan.compress = false; newcl->netchan.compress = false;
newcl->protocol = protocol; newcl->protocol = protocol;
#ifdef NQNET #ifdef NQPROT
newcl->netchan.isnqprotocol = ISNQCLIENT(newcl); newcl->netchan.isnqprotocol = ISNQCLIENT(newcl);
#endif #endif

View file

@ -1031,6 +1031,7 @@ void SV_Physics_Toss (edict_t *ent)
VectorCopy(ent->v->origin, temporg); VectorCopy(ent->v->origin, temporg);
VectorCopy(temporg, ent->v->origin); VectorCopy(temporg, ent->v->origin);
trace = SV_PushEntity (ent, move); trace = SV_PushEntity (ent, move);
if (trace.allsolid) if (trace.allsolid)
trace.fraction = 0; trace.fraction = 0;
if (trace.fraction == 1) if (trace.fraction == 1)

View file

@ -3575,10 +3575,9 @@ void AddLinksToPmove ( areanode_t *node )
int pl; int pl;
int i; int i;
physent_t *pe; physent_t *pe;
float os, omt;
hull_t *hull; model_t *model;
vec3_t offset;
pl = EDICT_TO_PROG(svprogfuncs, sv_player); pl = EDICT_TO_PROG(svprogfuncs, sv_player);
// touch linked edicts // touch linked edicts
@ -3648,17 +3647,10 @@ vec3_t offset;
if (!((int)sv_player->v->dimension_hit & (int)check->v->dimension_solid)) if (!((int)sv_player->v->dimension_hit & (int)check->v->dimension_solid))
continue; continue;
// check->v->model = "a"; model = sv.models[(int)check->v->modelindex];
os = check->v->solid; if (model)
omt = check->v->movetype;
check->v->solid = SOLID_BSP;
check->v->movetype = MOVETYPE_PUSH;
hull = SV_HullForEntity (check, 0, sv_player->v->mins, sv_player->v->maxs, offset);
check->v->movetype = omt;
check->v->solid = os;
// test the point // test the point
if ( hull->funcs.HullPointContents (hull, sv_player->v->origin) == FTECONTENTS_SOLID ) if ( model->hulls[0].funcs.HullPointContents (&model->hulls[0], sv_player->v->origin) == FTECONTENTS_SOLID )
sv_player->v->fteflags = (int)sv_player->v->fteflags | FF_LADDER; //touch that ladder! sv_player->v->fteflags = (int)sv_player->v->fteflags | FF_LADDER; //touch that ladder!
} }
} }

View file

@ -282,6 +282,26 @@ model_t *Mod_LoadModel (model_t *mod, qboolean crash)
Mod_LoadBrushModel (mod, buf); Mod_LoadBrushModel (mod, buf);
break; break;
case IDPOLYHEADER:
GL_LoadQ1Model(mod, buf);
break;
#ifdef MD2MODELS
case MD2IDALIASHEADER:
GL_LoadQ2Model(mod, buf);
break;
#endif
#ifdef MD3MODELS
case MD3_IDENT:
GL_LoadQ3Model (mod, buf);
break;
#endif
#ifdef ZYMOTICMODELS
case (('O'<<24)+('M'<<16)+('Y'<<8)+'Z'):
GLMod_LoadZymoticModel(mod, buf);
break;
#endif
default: default:
if (crash) if (crash)
SV_Error ("Mod_NumForName: %s: format not recognised", mod->name); SV_Error ("Mod_NumForName: %s: format not recognised", mod->name);
@ -1319,5 +1339,28 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
} }
} }
} }
void *Mod_Extradata (model_t *mod)
{
void *r;
r = Cache_Check (&mod->cache);
if (r)
return r;
Mod_LoadModel (mod, true);
if (!mod->cache.data)
Sys_Error ("Mod_Extradata: caching failed");
return mod->cache.data;
}
#endif #endif

View file

@ -119,150 +119,6 @@ hull_t *SV_HullForBox (vec3_t mins, vec3_t maxs)
return &box_hull; return &box_hull;
} }
/*
================
SV_HullForEntity
Returns a hull that can be used for testing or clipping an object of mins/maxs
size.
Offset is filled in to contain the adjustment that must be added to the
testing object's origin to get a point to use with the returned hull.
================
*/
hull_t *SV_HullForEntity (edict_t *ent, int hullnum, vec3_t mins, vec3_t maxs, vec3_t offset)
{
model_t *model;
vec3_t size;
vec3_t hullmins, hullmaxs;
hull_t *hull;
// decide which clipping hull to use, based on the size
if (ent->v->solid == SOLID_BSP)
{ // explicit hulls in the BSP model
if (ent->v->movetype != MOVETYPE_PUSH)
SV_Error ("SOLID_BSP without MOVETYPE_PUSH (%s)", ent->v->classname + svprogfuncs->stringtable);
model = sv.models[ (int)ent->v->modelindex ];
if (!model || model->type != mod_brush)
SV_Error ("SOLID_BSP with a non bsp model");
VectorSubtract (maxs, mins, size);
if (hullnum >= 1 && hullnum <= MAX_MAP_HULLSM && model->hulls[hullnum-1].available)
hull = &model->hulls[hullnum-1];
else
{
if (model->hulls[5].available)
{
if (size[0] < 3) // Point
hull = &model->hulls[0];
else if (size[0] <= 32 && size[2] <= 28) // Half Player
hull = &model->hulls[3];
else if (size[0] <= 32) // Full Player
hull = &model->hulls[1];
else // Golumn
hull = &model->hulls[5];
}
else
{
if (size[0] < 3 || !model->hulls[1].available)
hull = &model->hulls[0];
else if (size[0] <= 32)
{
if (size[2] < 54 && model->hulls[3].available)
hull = &model->hulls[3]; // 32x32x36
else
hull = &model->hulls[1];
}
else
hull = &model->hulls[2];
}
}
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, ent->v->origin, offset);
}
else
{ // create a temp hull from bounding box sizes
VectorSubtract (ent->v->mins, maxs, hullmins);
VectorSubtract (ent->v->maxs, mins, hullmaxs);
hull = SV_HullForBox (hullmins, hullmaxs);
VectorCopy (ent->v->origin, offset);
}
return hull;
}
#ifdef Q2SERVER
hull_t *SVQ2_HullForEntity (q2edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
{
model_t *model;
vec3_t size;
vec3_t hullmins, hullmaxs;
hull_t *hull;
// decide which clipping hull to use, based on the size
if (ent->s.solid == Q2SOLID_BSP)
{ // explicit hulls in the BSP model
model = sv.models[ (int)ent->s.modelindex ];
if (!model || model->type != mod_brush)
SV_Error ("SOLID_BSP with a non bsp model");
VectorSubtract (maxs, mins, size);
if (model->fromgame == fg_halflife)
{
if (size[0] < 3)
hull = &model->hulls[0]; // 0x0x0
else if (size[0] <= 32)
{
if (size[2] < 54) // pick the nearest of 36 or 72
hull = &model->hulls[3]; // 32x32x36
else
hull = &model->hulls[1]; // 32x32x72
}
else
hull = &model->hulls[2]; // 64x64x64
}
else
{
if (size[0] < 3)
hull = &model->hulls[0];
else if (size[0] <= 32)
{
if (size[2] < 54 && model->hulls[3].firstclipnode) // pick the nearest of 36 or 72
hull = &model->hulls[3]; // 32x32x36
else
hull = &model->hulls[1];
}
else
hull = &model->hulls[2];
}
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, ent->s.origin, offset);
}
else
{ // create a temp hull from bounding box sizes
VectorSubtract (ent->mins, maxs, hullmins);
VectorSubtract (ent->maxs, mins, hullmaxs);
hull = SV_HullForBox (hullmins, hullmaxs);
VectorCopy (ent->s.origin, offset);
}
return hull;
}
#endif
/* /*
=============================================================================== ===============================================================================
@ -1056,32 +912,52 @@ edict_t *SV_TestEntityPosition (edict_t *ent)
return NULL; return NULL;
} }
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace);
//wrapper function. Rotates the start and end positions around the angles if needed. //wrapper function. Rotates the start and end positions around the angles if needed.
qboolean TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_t *trace, vec3_t angles) //qboolean TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_t *trace, vec3_t angles)
qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace, vec3_t origin, vec3_t angles)
{ {
qboolean rotated;
vec3_t start_l, end_l; vec3_t start_l, end_l;
vec3_t a; vec3_t a;
vec3_t forward, right, up; vec3_t forward, right, up;
vec3_t temp; vec3_t temp;
qboolean result; qboolean result;
memset (trace, 0, sizeof(trace_t));
trace->fraction = 1;
trace->allsolid = false;
trace->startsolid = false;
trace->inopen = true; //probably wrong...
VectorCopy (end, trace->endpos);
// don't rotate non bsp ents. Too small to bother. // don't rotate non bsp ents. Too small to bother.
if (hull != &box_hull && (angles[0] || angles[1] || angles[2]) ) if (model)
{
rotated = (angles[0] || angles[1] || angles[2]);
if (rotated)
{ {
AngleVectors (angles, forward, right, up); AngleVectors (angles, forward, right, up);
VectorCopy (start, temp); VectorSubtract (start, origin, temp);
start_l[0] = DotProduct (temp, forward); start_l[0] = DotProduct (temp, forward);
start_l[1] = -DotProduct (temp, right); start_l[1] = -DotProduct (temp, right);
start_l[2] = DotProduct (temp, up); start_l[2] = DotProduct (temp, up);
VectorCopy (end, temp); VectorSubtract (end, origin, temp);
end_l[0] = DotProduct (temp, forward); end_l[0] = DotProduct (temp, forward);
end_l[1] = -DotProduct (temp, right); end_l[1] = -DotProduct (temp, right);
end_l[2] = DotProduct (temp, up); end_l[2] = DotProduct (temp, up);
}
result = hull->funcs.RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace); else
{
VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l);
}
result = model->funcs.Trace (model, hulloverride, frame, start_l, end_l, mins, maxs, trace);
if (rotated)
{
// FIXME: figure out how to do this with existing angles // FIXME: figure out how to do this with existing angles
// VectorNegate (angles, a); // VectorNegate (angles, a);
a[0] = -angles[0]; a[0] = -angles[0];
@ -1098,14 +974,26 @@ qboolean TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_t *
trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]); trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]);
trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]); trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]);
} }
VectorAdd (trace->endpos, origin, trace->endpos);
}
else else
result = hull->funcs.RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start, end, trace); {
hull_t *hull = &box_hull;
memset (trace, 0, sizeof(trace_t));
trace->fraction = 1;
trace->allsolid = true;
VectorCopy (end, trace->endpos);
VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l);
result = Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
VectorAdd (trace->endpos, origin, trace->endpos);
}
return result; return result;
} }
/* /*
================== ==================
SV_ClipMoveToEntity SV_ClipMoveToEntity
@ -1114,14 +1002,12 @@ Handles selection or creation of a clipping hull, and offseting (and
eventually rotation) of the end points eventually rotation) of the end points
================== ==================
*/ */
trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hullnum) //hullnum overrides min/max for q1 style bsps trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hullnum, qboolean hitmodel) //hullnum overrides min/max for q1 style bsps
{ {
trace_t trace; trace_t trace;
vec3_t offset; model_t *model;
vec3_t start_l, end_l;
hull_t *hull;
/*
#ifdef Q2BSPS #ifdef Q2BSPS
if (ent->v->solid == SOLID_BSP) if (ent->v->solid == SOLID_BSP)
if (sv.models[(int)ent->v->modelindex] && (sv.models[(int)ent->v->modelindex]->fromgame == fg_quake2 || sv.models[(int)ent->v->modelindex]->fromgame == fg_quake3)) if (sv.models[(int)ent->v->modelindex] && (sv.models[(int)ent->v->modelindex]->fromgame == fg_quake2 || sv.models[(int)ent->v->modelindex]->fromgame == fg_quake3))
@ -1132,35 +1018,66 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
return trace; return trace;
} }
#endif #endif
*/
// fill in a default trace
memset (&trace, 0, sizeof(trace_t));
trace.fraction = 1;
trace.allsolid = true;
VectorCopy (end, trace.endpos);
// get the clipping hull // get the clipping hull
hull = SV_HullForEntity (ent, hullnum, mins, maxs, offset); if (ent->v->solid == SOLID_BSP)
{
VectorSubtract (start, offset, start_l); model = sv.models[(int)ent->v->modelindex];
VectorSubtract (end, offset, end_l); if (!model || model->type != mod_brush)
SV_Error("SOLID_BSP with non bsp model (classname: %s)", svprogfuncs->stringtable + ent->v->classname);
}
else
{
vec3_t boxmins, boxmaxs;
VectorSubtract (ent->v->mins, maxs, boxmins);
VectorSubtract (ent->v->maxs, mins, boxmaxs);
SV_HullForBox(boxmins, boxmaxs);
model = NULL;
}
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
if (progstype == PROG_H2 && ent->v->solid == SOLID_BSP) if (progstype == PROG_H2 && ent->v->solid == SOLID_BSP)
{ {
ent->v->angles[0]*=-1; ent->v->angles[0]*=-1;
TransformedHullCheck(hull, start_l, end_l, &trace, ent->v->angles); TransformedTrace(model, 0, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
ent->v->angles[0]*=-1; ent->v->angles[0]*=-1;
} }
else else
{ {
TransformedHullCheck(hull, start_l, end_l, &trace, ent->v->angles); TransformedTrace(model, 0, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
} }
// fix trace up by the offset // fix trace up by the offset
if (trace.fraction != 1) if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos); {
if (!model && hitmodel && ent->v->solid != SOLID_BSP && ent->v->modelindex > 0)
{
//okay, we hit the bbox
model_t *model;
if (ent->v->modelindex < 1 || ent->v->modelindex >= MAX_MODELS)
SV_Error("SV_ClipMoveToEntity: modelindex out of range\n");
model = sv.models[ (int)ent->v->modelindex ];
if (!model)
{ //if the model isn't loaded, load it.
//this saves on memory requirements with mods that don't ever use this.
model = sv.models[(int)ent->v->modelindex] = Mod_ForName(sv.model_precache[(int)ent->v->modelindex], false);
}
if (model && model->funcs.Trace)
{
//do the second trace
TransformedTrace(model, 0, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles);
}
}
if (trace.startsolid)
{
if (ent != sv.edicts)
Con_Printf("Trace started solid\n");
}
}
// did we clip the move? // did we clip the move?
if (trace.fraction < 1 || trace.startsolid ) if (trace.fraction < 1 || trace.startsolid )
@ -1172,23 +1089,11 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
trace_t SVQ2_ClipMoveToEntity (q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) trace_t SVQ2_ClipMoveToEntity (q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
{ {
trace_t trace; trace_t trace;
/*
vec3_t offset; vec3_t offset;
vec3_t start_l, end_l; vec3_t start_l, end_l;
hull_t *hull; hull_t *hull;
/*
#ifdef Q2BSPS
if (ent->s.solid == Q2SOLID_BSP)
if (sv.models[(int)ent->s.modelindex] && (sv.models[(int)ent->s.modelindex]->fromgame == fg_quake2 || sv.models[(int)ent->s.modelindex]->fromgame == fg_quake3))
{
trace = CM_TransformedBoxTrace (start, end, mins, maxs, sv.models[(int)ent->s.modelindex]->hulls[0].firstclipnode, MASK_PLAYERSOLID, ent->s.origin, ent->s.angles);
if (trace.fraction < 1 || trace.startsolid )
trace.ent = (edict_t *)ent;
return trace;
}
#endif
*/
// fill in a default trace // fill in a default trace
memset (&trace, 0, sizeof(trace_t)); memset (&trace, 0, sizeof(trace_t));
trace.fraction = 1; trace.fraction = 1;
@ -1202,7 +1107,7 @@ trace_t SVQ2_ClipMoveToEntity (q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t
VectorSubtract (end, offset, end_l); VectorSubtract (end, offset, end_l);
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
TransformedHullCheck(hull, start_l, end_l, &trace, ent->s.angles); TransformedTrace(ent->s.modelindex, start_l, end_l, &trace, ent->s.angles);
// fix trace up by the offset // fix trace up by the offset
if (trace.fraction != 1) if (trace.fraction != 1)
@ -1211,7 +1116,7 @@ trace_t SVQ2_ClipMoveToEntity (q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t
// did we clip the move? // did we clip the move?
if (trace.fraction < 1 || trace.startsolid ) if (trace.fraction < 1 || trace.startsolid )
trace.ent = (edict_t *)ent; trace.ent = (edict_t *)ent;
*/
return trace; return trace;
} }
#endif #endif
@ -1420,7 +1325,7 @@ int SVQ2_HeadnodeForEntity (q2edict_t *ent)
return CM_HeadnodeForBox (ent->mins, ent->maxs); return CM_HeadnodeForBox (ent->mins, ent->maxs);
} }
#endif #endif
/*
void SV_ClipMoveToEntities ( moveclip_t *clip ) void SV_ClipMoveToEntities ( moveclip_t *clip )
{ {
int i, num; int i, num;
@ -1488,19 +1393,43 @@ void SV_ClipMoveToEntities ( moveclip_t *clip )
if (trace.allsolid || trace.startsolid || if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction) trace.fraction < clip->trace.fraction)
{ {
trace.ent = touch; if (clip->type & MOVE_HITMODEL && touch->v->solid != SOLID_BSP)
if (clip->trace.startsolid)
{ {
model_t *model;
if (touch->v->modelindex < 1 || touch->v->modelindex >= MAX_MODELS)
SV_Error("SV_ClipMoveToEntity: modelindex out of range\n");
model = sv.models[ (int)touch->v->modelindex ];
if (!model)
{ //if the model isn't loaded, load it.
//this saves on memory requirements with mods that don't ever use this.
model = sv.models[(int)touch->v->modelindex] = Mod_ForName(sv.model_precache[(int)touch->v->modelindex], false);
}
if (model && model->hulls[0].available)
{
hull_t *hull = &model->hulls[0];
//do the second trace
memset (&trace, 0, sizeof(trace_t));
trace.fraction = 1;
trace.allsolid = true;
TransformedHullCheck(hull, clip->start, clip->end, &trace, touch->v->angles);
if (trace.fraction < clip->trace.fraction)
{
trace.ent = touch;
clip->trace = trace; clip->trace = trace;
clip->trace.startsolid = true; }
}
} }
else else
{
trace.ent = touch;
clip->trace = trace; clip->trace = trace;
} }
else if (trace.startsolid)
clip->trace.startsolid = true;
} }
} }
}
*/
#ifdef Q2SERVER #ifdef Q2SERVER
void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask ) void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask )
{ {
@ -1636,23 +1565,15 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
} }
if ((int)touch->v->flags & FL_MONSTER) if ((int)touch->v->flags & FL_MONSTER)
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum); trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
else else
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum); trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
if (trace.allsolid || trace.startsolid || if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction) trace.fraction < clip->trace.fraction)
{ {
trace.ent = touch; trace.ent = touch;
if (clip->trace.startsolid)
{
clip->trace = trace;
clip->trace.startsolid = true;
}
else
clip->trace = trace; clip->trace = trace;
} }
else if (trace.startsolid)
clip->trace.startsolid = true;
} }
// recurse down both sides // recurse down both sides
@ -1712,20 +1633,13 @@ void SVQ2_ClipToLinks ( areanode_t *node, moveclip_t *clip )
// trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end); // trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);
// else // else
trace = SVQ2_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end); trace = SVQ2_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end);
if (trace.allsolid || trace.startsolid || if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction) trace.fraction < clip->trace.fraction)
{ {
trace.ent = (edict_t *)touch; trace.ent = (edict_t *)touch;
if (clip->trace.startsolid)
{
clip->trace = trace;
clip->trace.startsolid = true;
}
else
clip->trace = trace; clip->trace = trace;
} }
else if (trace.startsolid)
clip->trace.startsolid = true;
} }
// recurse down both sides // recurse down both sides
@ -1812,13 +1726,13 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
} }
// clip to world // clip to world
clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end, hullnum); clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end, hullnum, false);
clip.start = start; clip.start = start;
clip.end = end; clip.end = end;
clip.mins = mins; clip.mins = mins;
clip.maxs = maxs; clip.maxs = maxs;
clip.type = type; clip.type = type|4;
clip.passedict = passedict; clip.passedict = passedict;
clip.hullnum = hullnum; clip.hullnum = hullnum;
#ifdef Q2SERVER #ifdef Q2SERVER
@ -1843,11 +1757,12 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs );
// clip to entities // clip to entities
#ifdef Q2BSPS /*#ifdef Q2BSPS
if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3)
SV_ClipMoveToEntities(&clip); SV_ClipMoveToEntities(&clip);
else else
#endif #endif
*/
SV_ClipToLinks ( sv_areanodes, &clip ); SV_ClipToLinks ( sv_areanodes, &clip );
if (clip.trace.startsolid) if (clip.trace.startsolid)