[hlcoders] Client-Side Hitbox Tracing

2003-07-07 Thread Jonah Sherman
--
--
As some of you know valve disabled hit-box tests for client-side
tracelines.  This causes problems with inconsistent hits between the
client and server, leading to many OMG HAXXOR I SHOT YOU!!111s.  To fix
this, I implemented my own hitbox tests using the ray-polyhedron
intersection algorithm from Graphics Gems II.  Code is attached.
g_BonePositions[n] is the stored value of m_pbonetransform after
StudioDrawPlayer for player index n+1.

Jonah
--
extern floatg_BonePositions[32][ MAXSTUDIOBONES ][ 3 ][ 4 ];
void RealTrace(vec3_t start, vec3_t end,pmtrace_t *tr)
{
vec3_t dir,c[2],vec[3],o;
int idx,i,x;
cl_entity_t *ent;
studiohdr_t *hdr;
mstudiobbox_t *bbox;
float t_near,t_far,t_max,t,vd,vn;
gEngfuncs.pEventAPI-EV_PlayerTrace(start,end,PM_NORMAL,-1,tr);
if(tr-fraction==1.0f)
return;
idx=gEngfuncs.pEventAPI-EV_IndexFromTrace(tr);
if(idx1 || idx  gEngfuncs.GetMaxClients())
return;
ent=gEngfuncs.GetEntityByIndex(idx);
if(!ent)
return;
hdr=(studiohdr_t*)IEngineStudio.Mod_Extradata(ent-model);
bbox=(mstudiobbox_t*)((unsigned long)hdr + hdr-hitboxindex);
idx--;
VectorSubtract(end,start,dir);
VectorScale(dir,1/Length(dir),dir);
for(i=hdr-numhitboxes-1;i=0;i--,bbox++) {
vec[0][0]=g_BonePositions[idx][bbox-bone][0][0];
vec[0][1]=g_BonePositions[idx][bbox-bone][1][0];
vec[0][2]=g_BonePositions[idx][bbox-bone][2][0];
vec[1][0]=g_BonePositions[idx][bbox-bone][0][1];
vec[1][1]=g_BonePositions[idx][bbox-bone][1][1];
vec[1][2]=g_BonePositions[idx][bbox-bone][2][1];
vec[2][0]=g_BonePositions[idx][bbox-bone][0][2];
vec[2][1]=g_BonePositions[idx][bbox-bone][1][2];
vec[2][2]=g_BonePositions[idx][bbox-bone][2][2];
o[0]=g_BonePositions[idx][bbox-bone][0][3];
o[1]=g_BonePositions[idx][bbox-bone][1][3];
o[2]=g_BonePositions[idx][bbox-bone][2][3];
VectorMA(o,bbox-bbmax[0],vec[0],c[0]);
VectorMA(c[0],bbox-bbmax[1],vec[1],c[0]);
VectorMA(c[0],bbox-bbmax[2],vec[2],c[0]);
VectorMA(o,bbox-bbmin[0],vec[0],c[1]);
VectorMA(c[1],bbox-bbmin[1],vec[1],c[1]);
VectorMA(c[1],bbox-bbmin[2],vec[2],c[1]);
t_near=-9.0;
t_far=9.0;
t_max=9.0f;
for(x=0;x2;x++) {
if(x)  {
VectorInverse(vec[0]);
VectorInverse(vec[1]);
VectorInverse(vec[2]);
}
for(int j=0;j3;j++) {
vd=DotProduct(dir,vec[j]);
if(vd==0.0f)
continue;
vn=DotProduct(vec[j],start)-DotProduct(vec[j],c[x]);
t=-vn/vd;
if(vd0.0tt_far)
t_far=t;
else if(vd0.0ftt_near)
t_near=t;
if(t_neart_far)
goto box_end;
}
}
tr-fraction=0.5f;
return;
box_end:
do { } while(0);
}
tr-fraction=1.0f;
}

--
[ Content of type application/pgp-signature deleted ]
___
To unsubscribe, edit your list preferences, or view the list archives, please visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders



[hlcoders] Client-Side Hitbox Tracing

2003-07-07 Thread Jonah Sherman
Sorry if this got sent a second time, my first message did not go
through as of a day later...

Anyway, as some of you know valve removed client-side hitbox tracing
from 1110 for whatever reason, meaning that if any traceline hits a
player hull, it will count as hitting a player, leading to eg players
seeing other players bleed when they shoot them between the legs or
above the shoulder.  This becomes quite annoying...here is how you can
get hitbox testing on the client for more consistent hit detection:

g_BonePositions are bonetransform values for each player, saved
from StudioDrawPlayer.

extern floatg_BonePositions[32][ MAXSTUDIOBONES ][ 3 ][ 4 ];
void RealTrace(vec3_t start, vec3_t end,pmtrace_t *tr)
{
vec3_t dir,c[2],vec[3],o;
int idx,i,x;
cl_entity_t *ent;
studiohdr_t *hdr;
mstudiobbox_t *bbox;
float t_near,t_far,t_max,t,vd,vn;
gEngfuncs.pEventAPI-EV_PlayerTrace(start,end,PM_NORMAL,-1,tr);
if(tr-fraction==1.0f)
return;
idx=gEngfuncs.pEventAPI-EV_IndexFromTrace(tr);
if(idx1 || idx  gEngfuncs.GetMaxClients())
return;
ent=gEngfuncs.GetEntityByIndex(idx);
if(!ent)
return;
hdr=(studiohdr_t*)IEngineStudio.Mod_Extradata(ent-model);
bbox=(mstudiobbox_t*)((unsigned long)hdr + hdr-hitboxindex);
idx--;
VectorSubtract(end,start,dir);
VectorScale(dir,1/Length(dir),dir);
for(i=hdr-numhitboxes-1;i=0;i--,bbox++) {
vec[0][0]=g_BonePositions[idx][bbox-bone][0][0];
vec[0][1]=g_BonePositions[idx][bbox-bone][1][0];
vec[0][2]=g_BonePositions[idx][bbox-bone][2][0];
vec[1][0]=g_BonePositions[idx][bbox-bone][0][1];
vec[1][1]=g_BonePositions[idx][bbox-bone][1][1];
vec[1][2]=g_BonePositions[idx][bbox-bone][2][1];
vec[2][0]=g_BonePositions[idx][bbox-bone][0][2];
vec[2][1]=g_BonePositions[idx][bbox-bone][1][2];
vec[2][2]=g_BonePositions[idx][bbox-bone][2][2];
o[0]=g_BonePositions[idx][bbox-bone][0][3];
o[1]=g_BonePositions[idx][bbox-bone][1][3];
o[2]=g_BonePositions[idx][bbox-bone][2][3];
VectorMA(o,bbox-bbmax[0],vec[0],c[0]);
VectorMA(c[0],bbox-bbmax[1],vec[1],c[0]);
VectorMA(c[0],bbox-bbmax[2],vec[2],c[0]);
VectorMA(o,bbox-bbmin[0],vec[0],c[1]);
VectorMA(c[1],bbox-bbmin[1],vec[1],c[1]);
VectorMA(c[1],bbox-bbmin[2],vec[2],c[1]);
t_near=-9.0;
t_far=9.0;
t_max=9.0f;
for(x=0;x2;x++) {
if(x)  {
VectorInverse(vec[0]);
VectorInverse(vec[1]);
VectorInverse(vec[2]);
}
for(int j=0;j3;j++) {
vd=DotProduct(dir,vec[j]);
if(vd==0.0f)
continue;
vn=DotProduct(vec[j],start)-DotProduct(vec[j],c[x]);
t=-vn/vd;
if(vd0.0tt_far)
t_far=t;
else if(vd0.0ftt_near)
t_near=t;
if(t_neart_far)
goto box_end;
}
}
tr-fraction=0.5f;
return;
box_end:
do { } while(0);
}
tr-fraction=1.0f;
}

___
To unsubscribe, edit your list preferences, or view the list archives, please visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders