I'm attempting to detect when the player is aiming inside of a rectangle I'm drawing onto an entity using 3D2D drawing. I created a simple intersection test that returns true/false depending on if the position passed as is intersecting another position. (It does take size into account)
However the result isn't quite working as I expected.
The intersection function returns true even though the player isn't looking at the rectangle. It seems like the intersection is totally inaccurate. The only way to make it return false is to look way off into another direction.
Here's the intersection testing function:
function checkBounds2D(entPos, targetPos, targetSize, intersectPos)
targetPos = entPos + targetPos
return (targetPos.x < intersectPos.x and targetPos.y < intersectPos.y and (targetSize.x + targetPos.x) > intersectPos.x and (targetSize.y + targetPos.y) > intersectPos.y)
end
And here's the ENT:Draw function:
function ENT:Draw()
self:DrawModel() -- Draws the model for the client.
local ply = LocalPlayer()
local minDist = 400
if (ply:GetPos():Distance(self:GetPos()) < minDist) then
local pos = self:GetPos() + Vector(0, -22, 0)
local ang1 = Angle( 0, 0, 90 )
local t = {}
t.start = ply:GetShootPos()
t.endpos = ply:GetAimVector() * 32 + t.start
t.filter = ply
local tr = util.TraceLine(t)
local isInBounds = checkBounds2D(pos, Vector(-117, -216, 0), Vector(235, 470, 0), tr.HitPos)
print (tr.HitPos)
print(isInBounds)
local bkgColor = Color(255, 255, 0, 255)
if (isInBounds == true) then
bkgColor = Color(255, 165, 0, 255)
end
cam.Start3D2D(pos, ang1, 0.2)
surface.SetDrawColor( bkgColor )
surface.DrawRect(-117, -216, 235, 470) -- X, Y,
cam.End3D2D()
end
end
I'm not really sure what I'm doing wrong. I've been playing around with the code for a few hours but I can't get it to work.
If I'm reading this right, you need to test if the player's GetEyeTrace().Entity is your entity.
I tried redoing the intersection function, however I still get the same result.
Here's the new intersection function:
function ENT:IsAimIntersecting(xPos, yPos, width, height)
local tr = LocalPlayer():GetEyeTrace()
if (tr.Entity == nil) then
return false
end
print(tr.Entity)
if (tr.Entity:GetClass() != self:GetClass()) then
return false
end
local aimPos = tr.HitPos
if (xPos > aimPos.x and xPos + width < aimPos.x and yPos > aimPos.y and yPos + height < aimPos.y) then
return true
else
return false
end
end
And this is the ENT:Draw function:
function ENT:Draw()
self:DrawModel()
local ply = LocalPlayer()
local minDist = 400
if (ply:GetPos():Distance(self:GetPos()) < minDist) then
local pos = self:LocalToWorld(Vector(13.1, -8, 0))
local ang1 = self:LocalToWorldAngles(Angle(0, 90, 90))
local scale = 0.1
cam.Start3D2D(pos, ang1, scale)
surface.SetDrawColor(REALPRINTER.UIBtnColor)
surface.DrawRect(160, -246, 80, 20)
if (IsAimIntersecting(pos.x + 160, pos.y - 246, 80, 20)) then
print("INTERSECTING")
else
print("NOT INTERSECTING")
end
cam.End3D2D()
end
end
You should be using util.IntersectRayWithPlane and check if it is inside your rect.
Hm, can't figure out how I should be using that function.
I found a forum post about it here. It didn't show the full implementation, but this is what mine ended up looking like (which also doesn't work)
function ENT:IsAimIntersecting(xPos, yPos, width, height)
local trace = LocalPlayer():GetEyeTrace()
local ply = LocalPlayer()
local isec = util.IntersectRayWithPlane( self:EyePos(), self:EyeAngles():Forward(), Vector(xPos, yPos), trace.HitNormal )
if isec then
local ap = pos - isec
local ab = pos - Vector(xPos, yPos + height)
local ad = pos - Vector(xPos + width, yPos + height)
local ap_ab = Dot( ap, ab )
local ab_ab = Dot( ab, ab )
local ap_ad = Dot( ap, ad )
local ad_ad = Dot( ad, ad )
if 0 < ap_ab and ap_ab < ab_ab and 0 < ap_ad and ap_ad < ad_ad
and IsLineOfSightClear( ply, isec ) then
return true
else
return false
end
end
Sorry, you need to Log In to post a reply to this thread.