used this solution.
PHP Code:
bool:IsRectangleVisible(const Float:start[3], const Float:end[3], const Float:mins[3], const Float:maxs[3], Float:scale=1.0)
{
new Float:ZpozOffset = maxs[2];
new Float:ZnegOffset = mins[2];
new Float:WideOffset = ((maxs[0] - mins[0]) + (maxs[1] - mins[1])) / 4.0;
// This rectangle is just a point!
if (ZpozOffset == 0.0 && ZnegOffset == 0.0 && WideOffset == 0.0)
{
return IsPointVisible(start, end);
}
// Adjust to scale.
ZpozOffset *= scale;
ZnegOffset *= scale;
WideOffset *= scale;
// Prepare rotation matrix.
decl Float:angles[3], Float:fwd[3], Float:right[3];
SubtractVectors(start, end, fwd);
NormalizeVector(fwd, fwd);
GetVectorAngles(fwd, angles);
GetAngleVectors(angles, fwd, right, NULL_VECTOR);
decl Float:vRectangle[4][3], Float:vTemp[3];
// If the player is on the same level as us, we can optimize by only rotating on the z-axis.
if (FloatAbs(fwd[2]) <= 0.7071)
{
ScaleVector(right, WideOffset);
// Corner 1, 2
vTemp = end;
vTemp[2] += ZpozOffset;
AddVectors(vTemp, right, vRectangle[0]);
SubtractVectors(vTemp, right, vRectangle[1]);
// Corner 3, 4
vTemp = end;
vTemp[2] += ZnegOffset;
AddVectors(vTemp, right, vRectangle[2]);
SubtractVectors(vTemp, right, vRectangle[3]);
}
else if (fwd[2] > 0.0) // Player is below us.
{
fwd[2] = 0.0;
NormalizeVector(fwd, fwd);
ScaleVector(fwd, scale);
ScaleVector(fwd, WideOffset);
ScaleVector(right, WideOffset);
// Corner 1
vTemp = end;
vTemp[2] += ZpozOffset;
AddVectors(vTemp, right, vTemp);
SubtractVectors(vTemp, fwd, vRectangle[0]);
// Corner 2
vTemp = end;
vTemp[2] += ZpozOffset;
SubtractVectors(vTemp, right, vTemp);
SubtractVectors(vTemp, fwd, vRectangle[1]);
// Corner 3
vTemp = end;
vTemp[2] += ZnegOffset;
AddVectors(vTemp, right, vTemp);
AddVectors(vTemp, fwd, vRectangle[2]);
// Corner 4
vTemp = end;
vTemp[2] += ZnegOffset;
SubtractVectors(vTemp, right, vTemp);
AddVectors(vTemp, fwd, vRectangle[3]);
}
else // Player is above us.
{
fwd[2] = 0.0;
NormalizeVector(fwd, fwd);
ScaleVector(fwd, scale);
ScaleVector(fwd, WideOffset);
ScaleVector(right, WideOffset);
// Corner 1
vTemp = end;
vTemp[2] += ZpozOffset;
AddVectors(vTemp, right, vTemp);
AddVectors(vTemp, fwd, vRectangle[0]);
// Corner 2
vTemp = end;
vTemp[2] += ZpozOffset;
SubtractVectors(vTemp, right, vTemp);
AddVectors(vTemp, fwd, vRectangle[1]);
// Corner 3
vTemp = end;
vTemp[2] += ZnegOffset;
AddVectors(vTemp, right, vTemp);
SubtractVectors(vTemp, fwd, vRectangle[2]);
// Corner 4
vTemp = end;
vTemp[2] += ZnegOffset;
SubtractVectors(vTemp, right, vTemp);
SubtractVectors(vTemp, fwd, vRectangle[3]);
}
// Run traces on all corners.
for (new i = 0; i < 4; i++)
{
if (IsPointVisible(start, vRectangle[i]))
{
return true;
}
}
return false;
}