PDA

View Full Version : TraceRays - finding the floor from a position


labelmaker
04-04-2009, 06:50
I stayed up all night figuring this one out. Just how do you find the floor from a position. Well Ive got your answer. :mrgreen:

As you can see angles are not x,y,z. Its actually pitch,yaw,roll
new Float:pos[3];
new Float:floor[3];
new Float:ceiling[3];
new Float:direction[3];
new Handle:trace;
new Float:totalHeight;

for(new i = 0; i < 11; ++i)
{
pos[0] = GetRandomFloat(MapX[0],MapX[1]);
pos[1] = GetRandomFloat(MapY[0],MapY[1]);
pos[2] = GetRandomFloat(MapZ[0],MapZ[1]);
direction[0] = 89.0;//thats right you'd think its a z value - this will point you down
trace = TR_TraceRayEx(pos, direction,MASK_PLAYERSOLID_BRUSHONLY, RayType_Infinite);
if(TR_DidHit(trace))
{
TR_GetEndPosition(floor, trace);
}
direction[0] = -89.0;//this will point you up
trace = TR_TraceRayEx(pos, direction,MASK_PLAYERSOLID_BRUSHONLY, RayType_Infinite);
if(TR_DidHit(trace))
{
TR_GetEndPosition(ceiling, trace);
}
//I find the height below to prevent players from becoming stuck
if (ceiling[2] < 0 && floor[2] < 0)
{
totalHeight = FloatAbs(ceiling[2]) - FloatAbs(floor[2]);
}
else if (ceiling[2] > 0 && floor[2] > 0)
{
totalHeight = ceiling[2] - floor[2];
}
else
{
totalHeight = FloatAbs(ceiling[2]) + FloatAbs(floor[2]);
}
if (FloatAbs(totalHeight) > 75.0)
{
pos[2] = floor[2] + 20;//once again keep those players out of the dirt
i = 11;
}
}

raydan
04-04-2009, 10:55
what mean "finding the floor from a position" ??

PM
04-04-2009, 15:16
Letting the code speak, he means tracing a ray from a player's position down and finding the first intersection with map geometry.

The reason why you need that value is that probably, TR_TraceRayEx takes an angles structure as its direction parameter when used this way,
ie. pitch/yaw/roll (in that order). Pitch is rotation around the Y-axis, yaw around the Z-axis, roll around the X-axis according to Valve's dev wiki (http://developer.valvesoftware.com/wiki/Angles) (all in degrees). What is being rotated is the normal vector in X-direction ( ie. the vector 1.0 / 0.0 / 0.0 ) (that is the forward output of the AngleVectors function). So what you need is 90 degrees clockwise or counter-clockwise around the Y axis.

Disclaimer: I have never used TR_TraceRayEx so I may be wrong.

Dragonshadow
07-20-2009, 08:47
I know this is old, but it looks interesting, what could it be used for?

FeuerSturm
07-20-2009, 11:15
you can use this if you're for example teleporting players and don't
want them to end up midair falling down the ground and die,
so you can directly teleport them on the ground.

Machine
06-27-2012, 22:06
I was using this in a plugin of mine until I realized it was causing my l4d2 server to crash.

After investigating, I saw that the traceray was using up handles until all of them were filled up and weird things would happen.

It seems you need to CloseHandle all tracerays period. Doesn't even matter if its a global handle or not, it will even happen if you try to assign the same handle to another traceray and will use up addresses in memory.

This fixed it for me:

new Float:pos[3];
new Float:floor[3];
new Float:ceiling[3];
new Float:direction[3];
new Handle:trace;
new Float:totalHeight;

for(new i = 0; i < 11; ++i)
{
pos[0] = GetRandomFloat(MapX[0],MapX[1]);
pos[1] = GetRandomFloat(MapY[0],MapY[1]);
pos[2] = GetRandomFloat(MapZ[0],MapZ[1]);
direction[0] = 89.0;//thats right you'd think its a z value - this will point you down
trace = TR_TraceRayEx(pos, direction,MASK_PLAYERSOLID_BRUSHONLY, RayType_Infinite);
if(TR_DidHit(trace))
{
TR_GetEndPosition(floor, trace);
}
CloseHandle(trace);
direction[0] = -89.0;//this will point you up
trace = TR_TraceRayEx(pos, direction,MASK_PLAYERSOLID_BRUSHONLY, RayType_Infinite);
if(TR_DidHit(trace))
{
TR_GetEndPosition(ceiling, trace);
}
CloseHandle(trace);
//I find the height below to prevent players from becoming stuck
if (ceiling[2] < 0 && floor[2] < 0)
{
totalHeight = FloatAbs(ceiling[2]) - FloatAbs(floor[2]);
}
else if (ceiling[2] > 0 && floor[2] > 0)
{
totalHeight = ceiling[2] - floor[2];
}
else
{
totalHeight = FloatAbs(ceiling[2]) + FloatAbs(floor[2]);
}
if (FloatAbs(totalHeight) > 75.0)
{
pos[2] = floor[2] + 20;//once again keep those players out of the dirt
i = 11;
}
}

TheAvengers2
06-28-2012, 09:34
You're using the "Ex" versions which open a local handle. If you use the normal ones i.e. TR_TraceRay() then it uses a global handle which closes itself.

Machine
06-28-2012, 16:28
Ahh, thanks for the tip.