Generalized hitnormal functions (where possible).
This commit is contained in:
parent
1d759a109a
commit
b1683dae8e
24 changed files with 206 additions and 785 deletions
|
|
@ -348,7 +348,7 @@ extend Class SWWMUtility
|
|||
}
|
||||
|
||||
// the stupidest thing ever, it's called BlockingLine but it's not always blocking us
|
||||
static play bool BlockingLineIsBlocking( Actor a, int blockflags = Line.ML_BLOCKEVERYTHING, Line testline = null )
|
||||
static clearscope bool BlockingLineIsBlocking( Actor a, int blockflags = Line.ML_BLOCKEVERYTHING, Line testline = null )
|
||||
{
|
||||
Line l = testline?testline:a.BlockingLine;
|
||||
// not blocked
|
||||
|
|
@ -537,6 +537,136 @@ extend Class SWWMUtility
|
|||
return (al+ah+bl+bh)*.25;
|
||||
}
|
||||
|
||||
// gets the hit normal vector for projectiles and hitscan
|
||||
// bNoBounce: actor didn't just bounce, meaning the fallback normal shouldn't be the inverse of velocity
|
||||
static clearscope Vector3 GetActorHitNormal( Actor a, bool bNoBounce = false )
|
||||
{
|
||||
Vector3 HitNormal = (0,0,0);
|
||||
F3DFloor ff;
|
||||
if ( a.BlockingMobj )
|
||||
{
|
||||
let mo = a.BlockingMobj;
|
||||
Vector3 diff = level.Vec3Diff(mo.pos,a.pos);
|
||||
if ( diff.x >= mo.radius ) HitNormal += (1,0,0);
|
||||
else if ( diff.x <= -mo.radius ) HitNormal += (-1,0,0);
|
||||
if ( diff.y >= mo.radius ) HitNormal += (0,1,0);
|
||||
else if ( diff.y <= -mo.radius ) HitNormal += (0,-1,0);
|
||||
if ( diff.z >= mo.height ) HitNormal += (0,0,1);
|
||||
else if ( diff.z <= 0. ) HitNormal += (0,0,-1);
|
||||
double len = HitNormal.length();
|
||||
if ( len < double.epsilon ) HitNormal = Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90));
|
||||
else HitNormal /= len;
|
||||
}
|
||||
else if ( a.BlockingFloor )
|
||||
{
|
||||
// find closest 3d floor for its normal
|
||||
for ( int i=0; i<a.BlockingFloor.Get3DFloorCount(); i++ )
|
||||
{
|
||||
if ( !(a.BlockingFloor.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
|
||||
if ( !(a.BlockingFloor.Get3DFloor(i).top.ZAtPoint(a.pos.xy) ~== a.floorz) ) continue;
|
||||
ff = a.BlockingFloor.Get3DFloor(i);
|
||||
break;
|
||||
}
|
||||
if ( ff ) HitNormal = -ff.top.Normal;
|
||||
else HitNormal = a.BlockingFloor.floorplane.Normal;
|
||||
}
|
||||
else if ( a.BlockingCeiling )
|
||||
{
|
||||
// find closest 3d floor for its normal
|
||||
for ( int i=0; i<a.BlockingCeiling.Get3DFloorCount(); i++ )
|
||||
{
|
||||
if ( !(a.BlockingCeiling.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
|
||||
if ( !(a.BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(a.pos.xy) ~== a.ceilingz) ) continue;
|
||||
ff = a.BlockingCeiling.Get3DFloor(i);
|
||||
break;
|
||||
}
|
||||
if ( ff ) HitNormal = -ff.bottom.Normal;
|
||||
else HitNormal = a.BlockingCeiling.ceilingplane.Normal;
|
||||
}
|
||||
else if ( a.BlockingLine && BlockingLineIsBlocking(a,Line.ML_BLOCKEVERYTHING|Line.ML_BLOCKPROJECTILE,a.BlockingLine) )
|
||||
{
|
||||
HitNormal = (-a.BlockingLine.delta.y,a.BlockingLine.delta.x,0).unit();
|
||||
if ( !SWWMUtility.PointOnLineSide(a.pos.xy,a.BlockingLine) )
|
||||
HitNormal *= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
double len = a.vel.length();
|
||||
if ( len > 0. ) HitNormal = bNoBounce?(-a.vel/len):(a.vel/len);
|
||||
}
|
||||
return HitNormal;
|
||||
}
|
||||
static clearscope Vector3 GetLineTraceHitNormal( FLineTraceData d )
|
||||
{
|
||||
Vector3 HitNormal = (0,0,0);
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
let mo = d.HitActor;
|
||||
Vector3 diff = level.Vec3Diff(mo.pos,d.HitLocation);
|
||||
if ( diff.x >= mo.radius ) HitNormal += (1,0,0);
|
||||
else if ( diff.x <= -mo.radius ) HitNormal += (-1,0,0);
|
||||
if ( diff.y >= mo.radius ) HitNormal += (0,1,0);
|
||||
else if ( diff.y <= -mo.radius ) HitNormal += (0,-1,0);
|
||||
if ( diff.z >= mo.height ) HitNormal += (0,0,1);
|
||||
else if ( diff.z <= 0. ) HitNormal += (0,0,-1);
|
||||
double len = HitNormal.length();
|
||||
if ( len < double.epsilon ) HitNormal = Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90));
|
||||
else HitNormal /= len;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( d.Hit3DFloor ) HitNormal = -d.Hit3DFloor.top.Normal;
|
||||
else HitNormal = d.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( d.Hit3DFloor ) HitNormal = -d.Hit3DFloor.bottom.Normal;
|
||||
else HitNormal = d.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitWall )
|
||||
{
|
||||
HitNormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
|
||||
if ( !d.LineSide ) HitNormal *= -1;
|
||||
}
|
||||
else HitNormal = -d.HitDir;
|
||||
return HitNormal;
|
||||
}
|
||||
static clearscope Vector3 GetLineTracerHitNormal( TraceResults r )
|
||||
{
|
||||
Vector3 HitNormal = (0,0,0);
|
||||
if ( r.HitType == TRACE_HitActor )
|
||||
{
|
||||
let mo = r.HitActor;
|
||||
Vector3 diff = level.Vec3Diff(mo.pos,r.HitPos);
|
||||
if ( diff.x >= mo.radius ) HitNormal += (1,0,0);
|
||||
else if ( diff.x <= -mo.radius ) HitNormal += (-1,0,0);
|
||||
if ( diff.y >= mo.radius ) HitNormal += (0,1,0);
|
||||
else if ( diff.y <= -mo.radius ) HitNormal += (0,-1,0);
|
||||
if ( diff.z >= mo.height ) HitNormal += (0,0,1);
|
||||
else if ( diff.z <= 0. ) HitNormal += (0,0,-1);
|
||||
double len = HitNormal.length();
|
||||
if ( len < double.epsilon ) HitNormal = Vec3FromAngles(FRandom[ExploS](0,360),FRandom[ExploS](-90,90));
|
||||
else HitNormal /= len;
|
||||
}
|
||||
else if ( r.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( r.ffloor ) HitNormal = -r.ffloor.top.Normal;
|
||||
else HitNormal = r.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( r.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( r.ffloor ) HitNormal = -r.ffloor.bottom.Normal;
|
||||
else HitNormal = r.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( r.HitType == TRACE_HitWall )
|
||||
{
|
||||
HitNormal = (-r.HitLine.delta.y,r.HitLine.delta.x,0).unit();
|
||||
if ( !r.Side ) HitNormal *= -1;
|
||||
}
|
||||
else HitNormal = -r.HitVector;
|
||||
return HitNormal;
|
||||
}
|
||||
|
||||
static bool, TextureID DefaceTexture( TextureID checkme )
|
||||
{
|
||||
String tn = TexMan.GetName(checkme);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue