Merge pull request #2142 from wiremod/egp-screen-3dtracker

EGP screen support for egp3DTracker and optional directionality parameter for egp3DTracker
This commit is contained in:
Divran 2021-02-14 21:37:33 +01:00 committed by GitHub
commit d6ddc396d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 70 deletions

View File

@ -11,63 +11,78 @@ Obj.g = nil
Obj.b = nil
Obj.a = nil
Obj.parententity = NULL
Obj.Is3DTracker = true
Obj.NeedsConstantUpdate = true
Obj.angle = 0
Obj.directionality = 0
function Obj:Draw(egp)
if egp.gmod_wire_egp_emitter then
local objectPosition
if self.parententity and self.parententity:IsValid() then
objectPosition = self.parententity:LocalToWorld(Vector(self.target_x,self.target_y,self.target_z))
else
objectPosition = Vector(self.target_x,self.target_y,self.target_z)
end
local objectPosition
if self.parententity and self.parententity:IsValid() then
objectPosition = self.parententity:LocalToWorld(Vector(self.target_x,self.target_y,self.target_z))
else
objectPosition = Vector(self.target_x,self.target_y,self.target_z)
end
local eyePosition = EyePos()
local direction = objectPosition-eyePosition
-- localise the positions
eyePosition = egp:WorldToLocal(eyePosition)
direction = egp:WorldToLocal(direction + egp:GetPos())
-- plane/ray intersection:
--[[
screenPosition = eyePosition+direction*fraction | screenPosition.y = 0
0 = eyePosition.y+direction.y*fraction | - eyePosition.y
-eyePosition.y = direction.y*fraction | / direction.y
-eyePosition.y / direction.y = fraction | swap sides
]]
local fraction = -eyePosition.y / direction.y
local screenPosition = eyePosition+direction*fraction
screenPosition = (screenPosition - Vector( -64, 0, 135 )) / 0.25
if fraction < 0 then -- hide for fraction < 0 (maybe for > 1 too?)
self.x = math.huge
self.y = math.huge
else
self.x = screenPosition.x
self.y = -screenPosition.z
end
-- fraction < 0: object-player-screen: player is between object and screen; object is not seen at all when facing the screen
-- fraction 0-1: object-screen-player: screen is between object and player; object is seen behind the screen
-- fraction > 1: screen-object-player: object is between screen and player; object is seen in front of the screen
elseif egp.gmod_wire_egp_hud then
local pos
if self.parententity and self.parententity:IsValid() then
pos = self.parententity:LocalToWorld(Vector(self.target_x,self.target_y,self.target_z))
else
pos = Vector(self.target_x,self.target_y,self.target_z)
end
local pos = pos:ToScreen()
if egp.gmod_wire_egp_hud then
local pos = objectPosition:ToScreen()
self.x = pos.x
self.y = pos.y
elseif egp.gmod_wire_egp then
return
end
local eyePosition = EyePos()
local direction = objectPosition-eyePosition
local ratioX, ratioY
if egp.gmod_wire_egp_emitter then
ratioX = 4
ratioY = 4
-- localise the positions
eyePosition = egp:WorldToLocal(eyePosition) - Vector( -64, 0, 135 )
direction = egp:WorldToLocal(direction + egp:GetPos())
elseif egp.gmod_wire_egp then
local monitor = WireGPU_Monitors[ egp:GetModel() ]
if not monitor then self.x = math.huge self.y = math.huge return end
local Ang = egp:LocalToWorldAngles( monitor.rot )
local Pos = egp:LocalToWorld( monitor.offset )
ratioY = 1 / monitor.RS
ratioX = monitor.RatioX * ratioY
eyePosition = WorldToLocal(eyePosition, Angle(), Pos, Ang)
eyePosition:Rotate(Angle(0,0,90))
eyePosition = eyePosition + Vector(256/ratioX, 0, -256/ratioY)
direction = WorldToLocal(direction, Angle(), Vector(), Ang)
direction:Rotate(Angle(0,0,90))
end
-- plane/ray intersection:
--[[
screenPosition = eyePosition+direction*fraction | screenPosition.y = 0
0 = eyePosition.y+direction.y*fraction | - eyePosition.y
-eyePosition.y = direction.y*fraction | / direction.y
-eyePosition.y / direction.y = fraction | swap sides
]]
local fraction = -eyePosition.y / direction.y
local screenPosition = eyePosition+direction*fraction
if fraction < 0 then -- hide for fraction < 0
self.x = math.huge
self.y = math.huge
elseif (fraction - 1) * self.directionality < 0 then -- hide for fraction > 1 if directionality < 0 and for fraction < 1 if directionality > 0
self.x = math.huge
self.y = math.huge
else
self.x = screenPosition.x * ratioX
self.y = -screenPosition.z * ratioY
end
-- fraction < 0: object-player-screen: player is between object and screen; object is not seen at all when facing the screen
-- fraction 0-1: object-screen-player: screen is between object and player; object is seen behind the screen
-- fraction > 1: screen-object-player: object is between screen and player; object is seen in front of the screen
end
function Obj:Transmit()
@ -76,6 +91,7 @@ function Obj:Transmit()
net.WriteFloat( self.target_z )
net.WriteEntity( self.parententity )
net.WriteInt((self.angle%360)*64, 16)
net.WriteInt( self.directionality, 2 )
end
function Obj:Receive()
@ -86,9 +102,10 @@ function Obj:Receive()
local parententity = net.ReadEntity()
if parententity and parententity:IsValid() then tbl.parententity = parententity end
tbl.angle = net.ReadInt(16)/64
tbl.directionality = net.ReadInt(2)
return tbl
end
function Obj:DataStreamInfo()
return { target_x = self.target_x, target_y = self.target_y, target_z = self.target_z, parententity = self.parententity }
return { target_x = self.target_x, target_y = self.target_y, target_z = self.target_z, parententity = self.parententity, directionality = self.directionality }
end

View File

@ -68,8 +68,8 @@ if CLIENT then
-- the parent checks need to be processed here if we aren't using a GPU
self.UpdateConstantly = nil
if self.GPU == nil then
for k,object in pairs(self.RenderTable) do
if object.parent == -1 or object.Is3DTracker then self.UpdateConstantly = true end -- Check if an object is parented to the cursor (or for 3DTrackers)
for _,object in pairs(self.RenderTable) do
if object.parent == -1 or object.NeedsConstantUpdate then self.UpdateConstantly = true end -- Check if an object is parented to the cursor (or for 3DTrackers)
if object.parent and object.parent ~= 0 then
if not object.IsParented then EGP:SetParent(self, object.index, object.parent) end
local _, data = EGP:GetGlobalPos(self, object.index)

View File

@ -8,22 +8,22 @@ hook.Add("Initialize","EGP_HUD_Initialize",function()
--------------------------------------------------------
local function EGP_Use( um )
local ent = um:ReadEntity()
if (!ent or !ent:IsValid()) then return end
if not ent or not ent:IsValid() then return end
local bool = um:ReadChar()
if (bool == -1) then
if bool == -1 then
ent.On = nil
elseif (bool == 1) then
elseif bool == 1 then
ent.On = true
elseif (bool == 0) then
if (ent.On == true) then
elseif bool == 0 then
if ent.On == true then
ent.On = nil
LocalPlayer():ChatPrint("[EGP] EGP HUD Disconnected.")
else
if (!tbl[ent]) then -- strange... this entity should be in the table. Might have gotten removed due to a lagspike. Add it again
if not tbl[ent] then -- strange... this entity should be in the table. Might have gotten removed due to a lagspike. Add it again
EGP:AddHUDEGP( ent )
end
ent.On = true
if (EGP_HUD_FirstPrint) then
if EGP_HUD_FirstPrint then
LocalPlayer():ChatPrint("[EGP] EGP HUD Connected. NOTE: Type 'wire_egp_hud_unlink' in console to disconnect yourself from all EGP HUDs.")
EGP_HUD_FirstPrint = nil
else
@ -40,7 +40,7 @@ hook.Add("Initialize","EGP_HUD_Initialize",function()
concommand.Add("wire_egp_hud_unlink",function()
local en = ents.FindByClass("gmod_wire_egp_hud")
LocalPlayer():ChatPrint("[EGP] Disconnected from all EGP HUDs.")
for k,v in ipairs( en ) do
for _,v in ipairs( en ) do
v.On = nil
end
end)
@ -61,12 +61,12 @@ hook.Add("Initialize","EGP_HUD_Initialize",function()
--------------------------------------------------------
hook.Add("HUDPaint","EGP_HUDPaint",function()
for Ent,_ in pairs( tbl ) do
if (!Ent or !Ent:IsValid()) then
if not Ent or not Ent:IsValid() then
EGP:RemoveHUDEGP( Ent )
break
else
if (Ent.On == true) then
if (Ent.RenderTable and #Ent.RenderTable > 0) then
if Ent.On == true then
if Ent.RenderTable and #Ent.RenderTable > 0 then
local mat = Ent:GetEGPMatrix()
for _,object in pairs( Ent.RenderTable ) do
@ -75,9 +75,9 @@ hook.Add("Initialize","EGP_HUD_Initialize",function()
EGP:FixMaterial( oldtex )
-- Check for 3DTracker parent
if (object.parent) then
if object.parent then
local hasObject, _, parent = EGP:HasObject( Ent, object.parent )
if (hasObject and parent.Is3DTracker) then
if hasObject and parent.NeedsConstantUpdate then
Ent:EGP_Update()
end
end

View File

@ -543,11 +543,24 @@ end
]]
--------------------------------------------------------
-- 3DHolder
-- 3DTracker
--------------------------------------------------------
e2function void wirelink:egp3DTracker( number index, vector pos )
if (!EGP:IsAllowed( self, this )) then return end
local bool, obj = EGP:CreateObject( this, EGP.Objects.Names["3DTracker"], { index = index, target_x = pos[1], target_y = pos[2], target_z = pos[3] }, self.player )
local bool, obj = EGP:CreateObject( this, EGP.Objects.Names["3DTracker"], { index = index, target_x = pos[1], target_y = pos[2], target_z = pos[3], directionality = 0 }, self.player )
if (bool) then EGP:DoAction( this, self, "SendObject", obj ) Update(self,this) end
end
e2function void wirelink:egp3DTracker( number index, vector pos, number directionality )
if (!EGP:IsAllowed( self, this )) then return end
if directionality > 0 then
directionality = 1
elseif directionality < 0 then
directionality = -1
end
local bool, obj = EGP:CreateObject( this, EGP.Objects.Names["3DTracker"], { index = index, target_x = pos[1], target_y = pos[2], target_z = pos[3], directionality = directionality }, self.player )
if (bool) then EGP:DoAction( this, self, "SendObject", obj ) Update(self,this) end
end
@ -727,7 +740,7 @@ e2function void wirelink:egpParent( number index, entity parent )
if (!EGP:IsAllowed( self, this )) then return end
local bool, k, v = EGP:HasObject( this, index )
if bool and v.Is3DTracker then
if bool and v.NeedsConstantUpdate then
if v.parententity == parent then return end -- Already parented to that
v.parententity = parent
@ -739,7 +752,7 @@ end
-- Returns the entity a tracker is parented to
e2function entity wirelink:egpTrackerParent( number index )
local bool, k, v = EGP:HasObject( this, index )
if bool and v.Is3DTracker then
if bool and v.NeedsConstantUpdate then
return (v.parententity and v.parententity:IsValid()) and v.parententity or nil
end
end

View File

@ -1421,6 +1421,7 @@ E2Helper.Descriptions["egpObjectType(xwl:n)"] = "Returns the type of the object
E2Helper.Descriptions["egpObjectTypes(xwl:)"] = "Returns an array whose keys are bound to object index, and value being the type of particular object"
E2Helper.Descriptions["egp3DTracker(xwl:nv)"] = "Creates a 3D tracker object at specified world position"
E2Helper.Descriptions["egp3DTracker(xwl:nvn)"] = "Creates a 3D tracker object at specified world position that is only visible behind (directionality=-1), in front of (directionality=1) the screen/emitter, or both (directionality=0). HUD is unaffected by directionality."
E2Helper.Descriptions["egpBox(xwl:nxv2xv2)"] = "Creates a box. First 2D vector is the position, second is size"
E2Helper.Descriptions["egpBoxOutline(xwl:nxv2xv2)"] = "Creates an outline box. First 2D vector is the position, second is size"
E2Helper.Descriptions["egpCircle(xwl:nxv2xv2)"] = "Creates a circle. First 2D vector is the position, second is size"