mirror of
https://github.com/wiremod/wire.git
synced 2025-03-04 03:03:04 -05:00
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:
commit
d6ddc396d0
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user