Added advanced bonemerge compatibility, gizmo offset set through toolgun now works with nonphysical bones

This commit is contained in:
penolakushari 2024-04-13 12:39:56 +03:00
parent a761e5618e
commit e84d5f8241
8 changed files with 416 additions and 99 deletions

View File

@ -229,8 +229,15 @@ function ENT:Think()
local ent = pl.rgm.Entity
local bone = pl.rgm.PhysBone
if not IsValid(ent) or not pl.rgm.Bone or not self.Axises then return end
local parent = ent:GetParent()
if pl.rgm.GizmoParentID and pl.rgm.GizmoParentID ~= -1 and pl.rgm.GizmoParent then
local ent = ent
if self.EntAdvMerged then
if not IsValid(parent) then return end
ent = parent
if ent.AttachedEntity then ent = ent.AttachedEntity end
end
local physobj = ent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
if physobj then
_, self.GizmoParent = LocalToWorld(vector_origin, pl.rgm.GizmoParent, physobj:GetPos(), physobj:GetAngles())
@ -243,13 +250,18 @@ function ENT:Think()
self.GizmoParent = angle_zero
end
local advbones = nil
if ent:GetClass() == "ent_advbonemerge" then
advbones = ent.AdvBone_BoneInfo
end
local pos, ang
local rotate = pl.rgm.Rotate or false
local scale = pl.rgm.Scale or false
local offset, offsetlocal = pl.rgm.GizmoOffset, self.localoffset
if IsValid(ent:GetParent()) and pl.rgm.Bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not ent:IsEffectActive(EF_FOLLOWBONE) and not (ent:GetClass() == "prop_ragdoll") then
pos = ent:GetParent():LocalToWorld(ent:GetLocalPos())
if IsValid(parent) and pl.rgm.Bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not ent:IsEffectActive(EF_FOLLOWBONE) and not (ent:GetClass() == "prop_ragdoll") then
pos = parent:LocalToWorld(ent:GetLocalPos())
elseif pl.rgm.IsPhysBone then
local physobj = ent:GetPhysicsObjectNum(bone)
@ -258,14 +270,20 @@ function ENT:Think()
else
bone = pl.rgm.Bone
if not self.GizmoPos then
local matrix = ent:GetBoneMatrix(bone)
pos = ent:GetBonePosition(bone)
if pos == ent:GetPos() then
pos = matrix:GetTranslation()
end
if not self.GizmoPos or not self.GizmoAng then
return
else
if pl.rgm.GizmoParentID then
if self.EntAdvMerged then
local parent = parent
if parent.AttachedEntity then parent = parent.AttachedEntity end
if pl.rgm.GizmoParentID ~= -1 then
local physobj = parent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
pos = LocalToWorld(self.GizmoPos, self.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
pos = LocalToWorld(self.GizmoPos, self.GizmoAng, parent:GetPos(), parent:GetAngles())
end
elseif pl.rgm.GizmoParentID then
if pl.rgm.GizmoParentID ~= -1 then
local physobj = ent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
pos = LocalToWorld(self.GizmoPos, self.GizmoAng, physobj:GetPos(), physobj:GetAngles())
@ -278,8 +296,10 @@ function ENT:Think()
end
end
if IsValid(ent:GetParent()) and pl.rgm.Bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not ent:IsEffectActive(EF_FOLLOWBONE) and not (ent:GetClass() == "prop_ragdoll") and not scale then
ang = ent:GetParent():LocalToWorldAngles(ent:GetLocalAngles())
if IsValid(parent) and pl.rgm.Bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not ent:IsEffectActive(EF_FOLLOWBONE) and not (ent:GetClass() == "prop_ragdoll") and not scale then
ang = parent:LocalToWorldAngles(ent:GetLocalAngles())
elseif pl.rgm.IsPhysBone and not scale then
local physobj = ent:GetPhysicsObjectNum(bone)
@ -288,7 +308,16 @@ function ENT:Think()
else
if rotate then
if ent:GetBoneParent(bone) ~= -1 then
if self.EntAdvMerged then
local parent = parent
if parent.AttachedEntity then parent = parent.AttachedEntity end
if pl.rgm.GizmoParentID ~= -1 then
local physobj = parent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, ang = LocalToWorld(vector_origin, self.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, ang = LocalToWorld(vector_origin, self.GizmoAng, parent:GetPos(), parent:GetAngles())
end
elseif ent:GetBoneParent(bone) ~= -1 then
if not pl.rgm.GizmoParent then -- dunno if there is a need for these failsafes
_ , ang = ent:GetBonePosition(bone)
else
@ -299,7 +328,7 @@ function ENT:Think()
local _, diff = WorldToLocal(vector_origin, ang, vector_origin, pang)
_, ang = LocalToWorld(vector_origin, diff, vector_origin, self.GizmoParent)
else
local manang = ent:GetManipulateBoneAngles(bone)
local manang = ent:GetManipulateBoneAngles(bone)*1
manang:Normalize()
_, ang = ent:GetBonePosition(bone)
@ -309,30 +338,45 @@ function ENT:Think()
end
end
else
_ , ang = ent:GetBonePosition(bone)
ang = self.GizmoAng
if ent:GetClass() == "prop_physics" then
local manang = ent:GetManipulateBoneAngles(bone)
manang:Normalize()
local manang = ent:GetManipulateBoneAngles(bone)*1
manang:Normalize()
_, ang = LocalToWorld(vector_origin, Angle(0, 0, -manang[3]), vector_origin, ang)
_, ang = LocalToWorld(vector_origin, Angle(-manang[1], 0, 0), vector_origin, ang)
_, ang = LocalToWorld(vector_origin, Angle(0, -manang[2], 0), vector_origin, ang)
end
_, ang = LocalToWorld(vector_origin, Angle(0, 0, -manang[3]), vector_origin, ang)
_, ang = LocalToWorld(vector_origin, Angle(-manang[1], 0, 0), vector_origin, ang)
_, ang = LocalToWorld(vector_origin, Angle(0, -manang[2], 0), vector_origin, ang)
end
elseif scale and self.GizmoAng then
elseif scale then
if pl.rgm.GizmoParentID then
local funent = ent
if self.EntAdvMerged then
funent = parent
if funent.AttachedEntity then funent = funent.AttachedEntity end
end
if pl.rgm.GizmoParentID ~= -1 then
local physobj = ent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
local physobj = funent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, ang = LocalToWorld(vector_origin, self.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, ang = LocalToWorld(vector_origin, self.GizmoAng, ent:GetPos(), ent:GetAngles())
_, ang = LocalToWorld(vector_origin, self.GizmoAng, funent:GetPos(), funent:GetAngles())
end
if self.EntAdvMerged then
_, ang = LocalToWorld(vector_origin, ent:GetManipulateBoneAngles(bone), vector_origin, ang)
end
else
ang = self.GizmoAng
end
else
if ent:GetBoneParent(bone) ~= -1 then
if self.EntAdvMerged then
local parent = parent
if parent.AttachedEntity then parent = parent.AttachedEntity end
if pl.rgm.GizmoParentID ~= -1 then
local physobj = parent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, ang = LocalToWorld(vector_origin, self.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, ang = LocalToWorld(vector_origin, self.GizmoAng, parent:GetPos(), parent:GetAngles())
end
elseif ent:GetBoneParent(bone) ~= -1 then
if not pl.rgm.GizmoParent then
local matrix = ent:GetBoneMatrix(ent:GetBoneParent(bone)) -- never would have guessed that when moving bones they use angles of their parent bone rather than their own angles. happened to get to know that after looking at vanilla bone manipulator!
ang = matrix:GetAngles()
@ -341,7 +385,7 @@ function ENT:Think()
end
else
if IsValid(ent) then
ang = ent:GetAngles()
ang = self.GizmoAng
end
end
end
@ -354,14 +398,34 @@ function ENT:Think()
end
if offsetlocal then
if IsValid(ent:GetParent()) and pl.rgm.Bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not ent:IsEffectActive(EF_FOLLOWBONE) and not (ent:GetClass() == "prop_ragdoll") then
self:SetPos(LocalToWorld(offset + entoffset, angle_zero, pos, ent:GetParent():LocalToWorldAngles(ent:GetLocalAngles())))
if IsValid(parent) and pl.rgm.Bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not ent:IsEffectActive(EF_FOLLOWBONE) and not (ent:GetClass() == "prop_ragdoll") then
self:SetPos(LocalToWorld(offset + entoffset, angle_zero, pos, parent:LocalToWorldAngles(ent:GetLocalAngles())))
else
if pl.rgm.IsPhysBone then
if self.EntAdvMerged then
local funent = parent
if funent.AttachedEntity then funent = funent.AttachedEntity end
local offsetang
if pl.rgm.GizmoParentID ~= -1 then
local physobj = funent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, offsetang = LocalToWorld(vector_origin, self.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, offsetang = LocalToWorld(vector_origin, self.GizmoAng, funent:GetPos(), funent:GetAngles())
end
_, offsetang = LocalToWorld(vector_origin, ent:GetManipulateBoneAngles(bone), vector_origin, offsetang)
self:SetPos(LocalToWorld(offset + entoffset, angle_zero, pos, offsetang))
elseif pl.rgm.IsPhysBone then
self:SetPos(LocalToWorld(offset + entoffset, angle_zero, pos, ang))
else
local offsetang
if pl.rgm.GizmoParentID then
local ent = ent
if self.EntAdvMerged then
ent = parent
if ent.AttachedEntity then ent = ent.AttachedEntity end
end
if pl.rgm.GizmoParentID ~= -1 then
local physobj = ent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, offsetang = LocalToWorld(vector_origin, self.GizmoAng, physobj:GetPos(), physobj:GetAngles())

View File

@ -6,6 +6,7 @@ AddCSLuaFile("shared.lua")
function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, _, movetype, _, _, nphyspos)
local intersect = self:GetGrabPos(eyepos, eyeang, ppos)
local axis = self:GetParent()
local parent = ent:GetParent()
local arrowAng = axis:LocalToWorldAngles(self.DefAngle)
local localized = WorldToLocal(intersect, angle_zero, axis:GetPos(), arrowAng)
local offset = axis.Owner.rgm.GizmoOffset
@ -31,8 +32,30 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, _, move
elseif movetype == 2 then
local finalpos, boneang
local pl = self:GetParent().Owner
local advbones = nil
if ent:GetClass() == "ent_advbonemerge" then
advbones = ent.AdvBone_BoneInfo
end
if ent:GetBoneParent(bone) ~= -1 then
if axis.EntAdvMerged then
if parent.AttachedEntity then parent = parent.AttachedEntity end
local funang
if pl.rgm.GizmoParentID ~= -1 then
local physobj = parent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, funang = LocalToWorld(vector_origin, axis.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, funang = LocalToWorld(vector_origin, axis.GizmoAng, parent:GetPos(), parent:GetAngles())
end
local pbone = parent:LookupBone(advbones[bone].parent) -- may need to make an exception if the bone doesn't exist for some reason, but i think adv bonemerge would handle that already
local matrix = parent:GetBoneMatrix(pbone)
boneang = matrix:GetAngles()
local _ , pang = parent:GetBonePosition(pbone)
local _, diff = WorldToLocal(vector_origin, boneang, vector_origin, pang)
_, boneang = LocalToWorld(vector_origin, diff, vector_origin, funang)
elseif ent:GetBoneParent(bone) ~= -1 then
local matrix = ent:GetBoneMatrix(ent:GetBoneParent(bone))
boneang = matrix:GetAngles()
if not (ent:GetClass() == "prop_physics") then
@ -61,7 +84,7 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, _, move
intersect = self:LocalToWorld(localized)
ang = ent:GetLocalAngles()
pos = LocalToWorld(Vector(offpos.x, 0, 0), angle_zero, intersect - offset, selfangle)
pos = ent:GetParent():WorldToLocal(pos)
pos = parent:WorldToLocal(pos)
end
return pos, ang
end

View File

@ -25,16 +25,21 @@ function ENT:ProcessMovement(_, offang, eyepos, eyeang, ent, bone, ppos, pnorm,
local intersect = self:GetGrabPos(eyepos, eyeang, ppos, pnorm)
local localized = self:WorldToLocal(intersect)
local _p, _a
local pl = self:GetParent().Owner
local axis = self:GetParent()
local pl = axis.Owner
local axistable = {
(self:GetParent():LocalToWorld(VECTOR_SIDE) - self:GetPos()):Angle(),
(self:GetParent():LocalToWorld(vector_up) - self:GetPos()):Angle(),
(self:GetParent():LocalToWorld(VECTOR_FRONT) - self:GetPos()):Angle(),
(self:GetParent():LocalToWorld(VECTOR_SIDE) - self:GetPos()):Angle(), --axis:LocalToWorldAngles(axis.DiscP:GetLocalAngles()),
(self:GetParent():LocalToWorld(vector_up) - self:GetPos()):Angle(), --axis:LocalToWorldAngles(axis.DiscY:GetLocalAngles()),
(self:GetParent():LocalToWorld(VECTOR_FRONT) - self:GetPos()):Angle(), --axis:LocalToWorldAngles(axis.DiscR:GetLocalAngles()),
(self:GetPos() - pl:EyePos()):Angle()
}
axistable[1]:Normalize()
axistable[2]:Normalize()
axistable[3]:Normalize()
axistable[4]:Normalize()
local mfmod = math.fmod
local axis = self:GetParent()
if movetype == 1 then
local offset = axis.Owner.rgm.GizmoOffset
@ -88,11 +93,20 @@ function ENT:ProcessMovement(_, offang, eyepos, eyeang, ent, bone, ppos, pnorm,
end
elseif movetype == 2 then
local rotateang, axisangle
local parent = ent:GetParent()
axisangle = axistable[self.axistype]
local _, boneang = ent:GetBonePosition(bone)
if ent:GetClass() == "prop_physics" then
local manang = ent:GetManipulateBoneAngles(bone)
if axis.EntAdvMerged then
if parent.AttachedEntity then parent = parent.AttachedEntity end
if pl.rgm.GizmoParentID ~= -1 then
local physobj = parent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, boneang = LocalToWorld(vector_origin, axis.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, boneang = LocalToWorld(vector_origin, axis.GizmoAng, parent:GetPos(), parent:GetAngles())
end
elseif ent:GetClass() == "prop_physics" then
local manang = ent:GetManipulateBoneAngles(bone)*1
manang:Normalize()
_, boneang = LocalToWorld(vector_origin, Angle(0, 0, -manang[3]), vector_origin, boneang)
@ -104,6 +118,8 @@ function ENT:ProcessMovement(_, offang, eyepos, eyeang, ent, bone, ppos, pnorm,
local _, diff = WorldToLocal(vector_origin, boneang, vector_origin, pang)
_, boneang = LocalToWorld(vector_origin, diff, vector_origin, axis.GizmoParent)
else
boneang = axis.LocalAngles
end
end
local startlocal = LocalToWorld(startangle, startangle:Angle(), vector_origin, axisangle) -- first we get our vectors into world coordinates, relative to the axis angles
@ -133,6 +149,7 @@ function ENT:ProcessMovement(_, offang, eyepos, eyeang, ent, bone, ppos, pnorm,
_a = rotateang
else
_a = ent:GetManipulateBoneAngles(bone)
_a = _a*1 -- do this to copy angle in case if we're rotating advanced bonemerged stuff
rotateang = nphysangle[self.axistype] + rotationangle
_a[self.axistype] = rotateang
end

View File

@ -9,6 +9,7 @@ function ENT:ProcessMovement(offpos, offang, eyepos, eyeang, ent, bone, ppos, pn
local pos, ang
pos = ent:GetManipulateBoneScale(bone)
pos = pos*1 -- multiply by 1 to make a copy of the vector, in case if we scale advanced bonemerged item - those currently use modified ManipulateBoneX functions which seem to cause a bug if I keep altering vector given from GetManipulateBoneX stuff
localized = Vector(localized.x - startgrab.x, 0, 0)
local posadd = nphysscale[self.axistype] + localized.x
ang = ent:GetManipulateBoneAngles(bone)

View File

@ -10,7 +10,20 @@ function ENT:ProcessMovement(offpos, offang, eyepos, eyeang, ent, bone, ppos, pn
local axis = self:GetParent()
local localized, finalpos, boneang
if ent:GetBoneCount() ~= 0 then
if axis.EntAdvMerged then
local parent = ent:GetParent()
if parent.AttachedEntity then parent = parent.AttachedEntity end
local funang
if pl.rgm.GizmoParentID ~= -1 then
local physobj = parent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, boneang = LocalToWorld(vector_origin, axis.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, boneang = LocalToWorld(vector_origin, axis.GizmoAng, parent:GetPos(), parent:GetAngles())
end
if axis.EntAdvMerged then
_, boneang = LocalToWorld(vector_origin, ent:GetManipulateBoneAngles(bone), vector_origin, boneang)
end
elseif ent:GetBoneCount() ~= 0 then
if axis.GizmoAng then
if pl.rgm.GizmoParentID ~= -1 then
local physobj = ent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)

View File

@ -6,6 +6,7 @@ AddCSLuaFile("shared.lua")
function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, pnorm, movetype, _, _, nphyspos)
local intersect = self:GetGrabPos(eyepos, eyeang, ppos, pnorm)
local axis = self:GetParent()
local parent = ent:GetParent()
local offset = axis.Owner.rgm.GizmoOffset
local entoffset = vector_origin
if axis.localoffset then
@ -18,7 +19,6 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, pnorm,
offset = offset + entoffset
end
local pos, ang
local pl = self:GetParent().Owner
if movetype == 1 then
local obj = ent:GetPhysicsObjectNum(bone)
@ -26,7 +26,31 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, pnorm,
pos = LocalToWorld(offpos, angle_zero, intersect - offset, self:GetAngles())
elseif movetype == 2 then
local localized, finalpos, boneang
if ent:GetBoneParent(bone) ~= -1 then
local advbones = nil
if ent:GetClass() == "ent_advbonemerge" then
advbones = ent.AdvBone_BoneInfo
end
if axis.EntAdvMerged then
if parent.AttachedEntity then parent = parent.AttachedEntity end
local pl = self:GetParent().Owner
local funang
if pl.rgm.GizmoParentID ~= -1 then
local physobj = parent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, funang = LocalToWorld(vector_origin, axis.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, funang = LocalToWorld(vector_origin, axis.GizmoAng, parent:GetPos(), parent:GetAngles())
end
local pbone = parent:LookupBone(advbones[bone].parent) -- may need to make an exception if the bone doesn't exist for some reason, but i think adv bonemerge would handle that already
local matrix = parent:GetBoneMatrix(pbone)
boneang = matrix:GetAngles()
local _ , pang = parent:GetBonePosition(pbone)
local _, diff = WorldToLocal(vector_origin, boneang, vector_origin, pang)
_, boneang = LocalToWorld(vector_origin, diff, vector_origin, funang)
elseif ent:GetBoneParent(bone) ~= -1 then
local matrix = ent:GetBoneMatrix(ent:GetBoneParent(bone))
boneang = matrix:GetAngles()
if not (ent:GetClass() == "prop_physics") then
@ -52,7 +76,7 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, pnorm,
elseif movetype == 0 then
ang = ent:GetLocalAngles()
pos = LocalToWorld(offpos, angle_zero, intersect - offset, self:GetAngles())
pos = ent:GetParent():WorldToLocal(pos)
pos = parent:WorldToLocal(pos)
end
return pos, ang

View File

@ -10,6 +10,7 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, pnorm,
end
local axis = self:GetParent()
local parent = ent:GetParent()
local offset = axis.Owner.rgm.GizmoOffset
local entoffset = vector_origin
if axis.localoffset then
@ -22,7 +23,6 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, pnorm,
offset = offset + entoffset
end
local pos, ang
local pl = self:GetParent().Owner
if movetype == 1 then
local obj = ent:GetPhysicsObjectNum(bone)
@ -30,7 +30,31 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, pnorm,
pos = LocalToWorld(offpos, angle_zero, intersect - offset, self:GetAngles())
elseif movetype == 2 then
local localized, startmove, finalpos, boneang
if ent:GetBoneParent(bone) ~= -1 then
local advbones = nil
if ent:GetClass() == "ent_advbonemerge" then
advbones = ent.AdvBone_BoneInfo
end
if axis.EntAdvMerged then
if parent.AttachedEntity then parent = parent.AttachedEntity end
local pl = self:GetParent().Owner
local funang
if pl.rgm.GizmoParentID ~= -1 then
local physobj = parent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
_, funang = LocalToWorld(vector_origin, axis.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
_, funang = LocalToWorld(vector_origin, axis.GizmoAng, parent:GetPos(), parent:GetAngles())
end
local pbone = parent:LookupBone(advbones[bone].parent) -- may need to make an exception if the bone doesn't exist for some reason, but i think adv bonemerge would handle that already
local matrix = parent:GetBoneMatrix(pbone)
boneang = matrix:GetAngles()
local _ , pang = parent:GetBonePosition(pbone)
local _, diff = WorldToLocal(vector_origin, boneang, vector_origin, pang)
_, boneang = LocalToWorld(vector_origin, diff, vector_origin, funang)
elseif ent:GetBoneParent(bone) ~= -1 then
local matrix = ent:GetBoneMatrix(ent:GetBoneParent(bone))
boneang = matrix:GetAngles()
if not (ent:GetClass() == "prop_physics") then
@ -56,7 +80,7 @@ function ENT:ProcessMovement(offpos, _, eyepos, eyeang, ent, bone, ppos, pnorm,
elseif movetype == 0 then
ang = ent:GetLocalAngles()
pos = LocalToWorld(offpos, angle_zero, intersect - offset, self:GetAngles())
pos = ent:GetParent():WorldToLocal(pos)
pos = parent:WorldToLocal(pos)
end
return pos, ang

View File

@ -155,9 +155,14 @@ local function rgmGetConstrainedEntities(parent)
end
end
if parent:GetParent() then
conents[parent:GetParent()] = nil
end
local count = 1
for _, ent in pairs(conents) do
if not IsValid(ent) or ent:IsWorld() or ent:IsConstraint() or not util.IsValidModel(ent:GetModel()) or IsValid(ent:GetParent()) then continue end
if ent:GetPhysicsObjectCount() > 0 then
children[count] = ent
@ -170,28 +175,39 @@ end
local function rgmCalcGizmoPos(pl)
if not pl.rgm or not pl.rgm.GizmoAng then return end
local axis, ent = pl.rgm.Axis, pl.rgm.Entity
local axis, entog = pl.rgm.Axis, pl.rgm.Entity
local ent = entog
local bone = pl.rgm.Bone
if axis.EntAdvMerged then
ent = ent:GetParent()
if ent.AttachedEntity then ent = ent.AttachedEntity end
end
axis.GizmoAng = pl.rgm.GizmoAng
local manang = ent:GetManipulateBoneAngles(bone)
manang:Normalize()
local ppos, pang = pl.rgm.GizmoPParent, pl.rgm.GizmoParent
_, axis.GizmoAng = LocalToWorld(vector_origin, Angle(0, manang[2], 0), vector_origin, axis.GizmoAng)
_, axis.GizmoAng = LocalToWorld(vector_origin, Angle(manang[1], 0, 0), vector_origin, axis.GizmoAng)
_, axis.GizmoAng = LocalToWorld(vector_origin, Angle(0, 0, manang[3]), vector_origin, axis.GizmoAng)
if not (axis.EntAdvMerged) then
local manang = entog:GetManipulateBoneAngles(bone)
manang:Normalize()
_, axis.GizmoAng = LocalToWorld(vector_origin, Angle(0, manang[2], 0), vector_origin, axis.GizmoAng)
_, axis.GizmoAng = LocalToWorld(vector_origin, Angle(manang[1], 0, 0), vector_origin, axis.GizmoAng)
_, axis.GizmoAng = LocalToWorld(vector_origin, Angle(0, 0, manang[3]), vector_origin, axis.GizmoAng)
end
local nonpos
if pl.rgm.GizmoParentID ~= -1 then
local physobj = ent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
if not physobj then return end
local ppos, pang = LocalToWorld(pl.rgm.GizmoPParent, pl.rgm.GizmoParent, physobj:GetPos(), physobj:GetAngles())
nonpos = LocalToWorld(ent:GetManipulateBonePosition(bone), angle_zero, ppos, pang)
ppos, pang = LocalToWorld(ppos, pang, physobj:GetPos(), physobj:GetAngles())
nonpos = LocalToWorld(entog:GetManipulateBonePosition(bone), angle_zero, ppos, pang)
nonpos = WorldToLocal(nonpos, pang, physobj:GetPos(), physobj:GetAngles())
else
local ppos, pang = LocalToWorld(pl.rgm.GizmoPParent, pl.rgm.GizmoParent, ent:GetPos(), ent:GetAngles())
nonpos = LocalToWorld(ent:GetManipulateBonePosition(bone), angle_zero, ppos, pang)
ppos, pang = LocalToWorld(ppos, pang, ent:GetPos(), ent:GetAngles())
nonpos = LocalToWorld(entog:GetManipulateBonePosition(bone), angle_zero, ppos, pang)
nonpos = WorldToLocal(nonpos, pang, ent:GetPos(), ent:GetAngles())
end
@ -352,9 +368,21 @@ net.Receive("rgmAskForParented", function(len, pl)
parented[ent] = {}
pcount = pcount + 1
for i = 0, ent:GetBoneCount() - 1 do
if ent:GetParent():LookupBone(ent:GetBoneName(i)) then
table.insert(parented[ent], i)
if ent:GetClass() ~= "ent_advbonemerge" then
for i = 0, ent:GetBoneCount() - 1 do
if ent:GetParent():LookupBone(ent:GetBoneName(i)) then
table.insert(parented[ent], i)
end
end
else
local advbones = ent.AdvBone_BoneInfo
if advbones and next(advbones) then
for i = 0, ent:GetBoneCount() - 1 do
if advbones[i].parent ~= "" then
table.insert(parented[ent], i)
end
end
end
end
end
@ -379,6 +407,7 @@ net.Receive("rgmSelectBone", function(len, pl)
pl.rgm.BoneToResetTo = (ent:GetClass() == "prop_ragdoll") and ent:TranslatePhysBoneToBone(0) or 0
pl.rgm.Entity = ent
pl.rgm.Axis.EntAdvMerged = false
RGMGetBone(pl, ent, bone)
pl:rgmSync()
@ -640,6 +669,7 @@ net.Receive("rgmSelectEntity", function(len, pl)
if not IsValid(ent) then return end
pl.rgm.Entity = ent
pl.rgm.Axis.EntAdvMerged = false
pl.rgm.BoneToResetTo = (ent:GetClass() == "prop_ragdoll") and ent:TranslatePhysBoneToBone(0) or 0
pl.rgmPosLocks = {}
pl.rgmAngLocks = {}
@ -745,9 +775,25 @@ net.Receive("rgmSendBonePos", function(len, pl)
childbones[parent][id] = pos
end
if not pl.rgm then return end
local ent = pl.rgm.Entity
local entog = pl.rgm.Entity
local ent = entog
local axis = pl.rgm.Axis
local boneog = pl.rgm.Bone
local bone = boneog
axis.EntAdvMerged = false
local advbones = nil
if ent:GetClass() == "ent_advbonemerge" then
advbones = ent.AdvBone_BoneInfo
if advbones and advbones[boneog] and advbones[boneog].parent and advbones[boneog].parent ~= "" then
axis.EntAdvMerged = true
ent = ent:GetParent()
if ent.AttachedEntity then ent = ent.AttachedEntity end
end
end
local physbones = {}
for i = 0, ent:GetPhysicsObjectCount() - 1 do
@ -764,15 +810,17 @@ net.Receive("rgmSendBonePos", function(len, pl)
return FindPhysParentRecursive(ent, parent, physbones)
end
end
local bone = pl.rgm.Bone
if axis.EntAdvMerged then
bone = ent:LookupBone(advbones[boneog].parent)
end
local parent = FindPhysParentRecursive(ent, bone, physbones)
local physobj
if parent ~= -1 then physobj = ent:GetPhysicsObjectNum(parent) end
pl.rgm.GizmoParentID = parent
local newpos, newang, nonpos
nonpos = LocalToWorld(ent:GetManipulateBonePosition(bone), angle_zero, ppos, pang)
nonpos = LocalToWorld(entog:GetManipulateBonePosition(boneog), angle_zero, ppos, pang)
if parent ~= -1 then
newpos, newang = WorldToLocal(pos, ang, physobj:GetPos(), physobj:GetAngles())
pl.rgm.GizmoPParent, pl.rgm.GizmoParent = WorldToLocal(ppos, pang, physobj:GetPos(), physobj:GetAngles())
@ -787,12 +835,16 @@ net.Receive("rgmSendBonePos", function(len, pl)
axis.GizmoPos = newpos
pl.rgm.GizmoPos = newpos - nonpos
local manang = ent:GetManipulateBoneAngles(bone)
manang:Normalize()
if not (axis.EntAdvMerged) then
local manang = entog:GetManipulateBoneAngles(boneog)
manang:Normalize()
_, pl.rgm.GizmoAng = LocalToWorld(vector_origin, Angle(0, 0, -manang[3]), vector_origin, newang)
_, pl.rgm.GizmoAng = LocalToWorld(vector_origin, Angle(-manang[1], 0, 0), vector_origin, pl.rgm.GizmoAng)
_, pl.rgm.GizmoAng = LocalToWorld(vector_origin, Angle(0, -manang[2], 0), vector_origin, pl.rgm.GizmoAng)
_, pl.rgm.GizmoAng = LocalToWorld(vector_origin, Angle(0, 0, -manang[3]), vector_origin, newang)
_, pl.rgm.GizmoAng = LocalToWorld(vector_origin, Angle(-manang[1], 0, 0), vector_origin, pl.rgm.GizmoAng)
_, pl.rgm.GizmoAng = LocalToWorld(vector_origin, Angle(0, -manang[2], 0), vector_origin, pl.rgm.GizmoAng)
else
pl.rgm.GizmoAng = axis.GizmoAng
end
pl.rgmBoneChildren = {}
if next(childbones) then
@ -840,11 +892,11 @@ net.Receive("rgmSetGizmoToBone", function(len, pl)
net.Send(pl)
end)
local function RecursiveBoneFunc(bone, ent, func, param)
func(bone, param)
local function RecursiveBoneFunc(bone, ent, func)
func(bone)
for _, id in ipairs(ent:GetChildBones(bone)) do
RecursiveBoneFunc(id, ent, func, param)
RecursiveBoneFunc(id, ent, func)
end
end
@ -852,9 +904,14 @@ net.Receive("rgmResetAllBones", function(len, pl)
local ent = net.ReadEntity()
for i = 0, ent:GetBoneCount() - 1 do
ent:ManipulateBonePosition(i, vector_origin)
ent:ManipulateBoneAngles(i, angle_zero)
ent:ManipulateBoneScale(i, VECTOR_SCALEDEF)
local pos, ang, scale = ent:GetManipulateBonePosition(i), ent:GetManipulateBoneAngles(i), ent:GetManipulateBoneScale(i) -- Grabbing existing vectors as to not create new ones, in case ManipulateBone functions were overriden by something like Advanced Bonemerge
pos:Set(vector_origin)
ang:Set(angle_zero)
scale:Set(VECTOR_SCALEDEF)
ent:ManipulateBonePosition(i, pos)
ent:ManipulateBoneAngles(i, ang)
ent:ManipulateBoneScale(i, scale)
end
net.Start("rgmUpdateSliders")
@ -875,14 +932,24 @@ net.Receive("rgmResetAll", function(len, pl)
if children then
RecursiveBoneFunc(bone, ent, function(bon)
ent:ManipulateBonePosition(bon, vector_origin)
ent:ManipulateBoneAngles(bon, angle_zero)
ent:ManipulateBoneScale(bon, VECTOR_SCALEDEF)
local pos, ang, scale = ent:GetManipulateBonePosition(bon), ent:GetManipulateBoneAngles(bon), ent:GetManipulateBoneScale(bon)
pos:Set(vector_origin)
ang:Set(angle_zero)
scale:Set(VECTOR_SCALEDEF)
ent:ManipulateBonePosition(bon, pos)
ent:ManipulateBoneAngles(bon, ang)
ent:ManipulateBoneScale(bon, scale)
end)
else
ent:ManipulateBonePosition(bone, vector_origin)
ent:ManipulateBoneAngles(bone, angle_zero)
ent:ManipulateBoneScale(bone, VECTOR_SCALEDEF)
local pos, ang, scale = ent:GetManipulateBonePosition(bone), ent:GetManipulateBoneAngles(bone), ent:GetManipulateBoneScale(bone)
pos:Set(vector_origin)
ang:Set(angle_zero)
scale:Set(VECTOR_SCALEDEF)
ent:ManipulateBonePosition(bone, pos)
ent:ManipulateBoneAngles(bone, ang)
ent:ManipulateBoneScale(bone, scale)
end
net.Start("rgmUpdateSliders")
@ -902,9 +969,17 @@ net.Receive("rgmResetPos", function(len, pl)
if not IsValid(ent) then return end
if children then
RecursiveBoneFunc(bone, ent, function(bone, param) ent:ManipulateBonePosition(bone, param) end, vector_origin)
RecursiveBoneFunc(bone, ent, function(bon)
local pos = ent:GetManipulateBonePosition(bon)
pos:Set(vector_origin)
ent:ManipulateBonePosition(bon, pos)
end)
else
ent:ManipulateBonePosition(bone, vector_origin)
local pos = ent:GetManipulateBonePosition(bone)
pos:Set(vector_origin)
ent:ManipulateBonePosition(bone, pos)
end
net.Start("rgmUpdateSliders")
@ -922,9 +997,17 @@ net.Receive("rgmResetAng", function(len, pl)
local bone = net.ReadUInt(10)
if children then
RecursiveBoneFunc(bone, ent, function(bone, param) ent:ManipulateBoneAngles(bone, param) end, angle_zero)
RecursiveBoneFunc(bone, ent, function(bon)
local ang = ent:GetManipulateBoneAngles(bon)
ang:Set(angle_zero)
ent:ManipulateBoneAngles(bon, ang)
end)
else
ent:ManipulateBoneAngles(bone, angle_zero)
local ang = ent:GetManipulateBoneAngles(bone)
ang:Set(angle_zero)
ent:ManipulateBoneAngles(bone, ang)
end
net.Start("rgmUpdateSliders")
@ -942,9 +1025,17 @@ net.Receive("rgmResetScale", function(len, pl)
local bone = net.ReadUInt(10)
if children then
RecursiveBoneFunc(bone, ent, function(bone, param) ent:ManipulateBoneScale(bone, param) end, VECTOR_SCALEDEF)
RecursiveBoneFunc(bone, ent, function(bon)
local scale = ent:GetManipulateBoneScale(bon)
scale:Set(VECTOR_SCALEDEF)
ent:ManipulateBoneScale(bon, scale)
end)
else
ent:ManipulateBoneScale(bone, VECTOR_SCALEDEF)
local scale = ent:GetManipulateBoneScale(bone)
scale:Set(VECTOR_SCALEDEF)
ent:ManipulateBoneScale(bone, scale)
end
net.Start("rgmUpdateSliders")
@ -964,9 +1055,17 @@ net.Receive("rgmScaleZero", function(len, pl)
local bone = net.ReadUInt(10)
if children then
RecursiveBoneFunc(bone, ent, function(bone, param) ent:ManipulateBoneScale(bone, param) end, VECTOR_NEARZERO)
RecursiveBoneFunc(bone, ent, function(bon)
local scale = ent:GetManipulateBoneScale(bon)
scale:Set(VECTOR_NEARZERO)
ent:ManipulateBoneScale(bon, scale)
end)
else
ent:ManipulateBoneScale(bone, VECTOR_NEARZERO)
local scale = ent:GetManipulateBoneScale(bone)
scale:Set(VECTOR_NEARZERO)
ent:ManipulateBoneScale(bone, scale)
end
net.Start("rgmUpdateSliders")
@ -1178,7 +1277,7 @@ net.Receive("rgmAdjustBone", function(len, pl)
local change = ent:GetManipulateBoneScale(bone)
change[axis] = value
if rgmaxis.scalechildren then
if rgmaxis.scalechildren and not (ent:GetClass() == "ent_advbonemerge") then
local scalediff = change - prevscale
local diff
local noscale = pl.rgmScaleLocks
@ -1221,7 +1320,7 @@ net.Receive("rgmAdjustBone", function(len, pl)
RecursiveBoneScale(ent, bone, scalediff)
else
if rgmaxis.smovechildren and childbones and childbones[bone] then
if rgmaxis.smovechildren and childbones and childbones[bone] and not (ent:GetClass() == "ent_advbonemerge") then
local diff = Vector(change.x / prevscale.x, change.y / prevscale.y, change.z / prevscale.z)
for cbone, pos in pairs(childbones[bone]) do
local bonepos = ent:GetManipulateBonePosition(cbone)
@ -1335,6 +1434,7 @@ hook.Add("EntityRemoved", "RGMDeselectEntity", function(ent)
for id, pl in ipairs(player.GetAll()) do
if pl.rgm and pl.rgm.Entity == ent then
pl.rgm.Entity = nil
pl.rgm.Axis.EntAdvMerged = false
net.Start("rgmDeselectEntity")
net.Send(pl)
end
@ -1399,17 +1499,31 @@ function TOOL:LeftClick(tr)
if not IsValid(axis) or not IsValid(ent) then self:SetOperation(0) return true end
local offset = tr.HitPos
local ogpos, ogang
if ent:GetClass() == "prop_ragdoll" and pl.rgm.IsPhysBone then
if not pl.rgm.IsPhysBone then
if axis.EntAdvMerged then
ent = ent:GetParent()
if ent.AttachedEntity then ent = ent.AttachedEntity end
end
if pl.rgm.GizmoParentID ~= -1 then
local physobj = ent:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
ogpos, ogang = LocalToWorld(axis.GizmoPos, axis.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
ogpos, ogang = LocalToWorld(axis.GizmoPos, axis.GizmoAng, ent:GetPos(), ent:GetAngles())
end
elseif ent:GetClass() == "prop_ragdoll" then
ent = ent:GetPhysicsObjectNum(pl.rgm.PhysBone)
ogpos, ogang = ent:GetPos(), ent:GetAngles()
elseif ent:GetClass() == "prop_physics" then
ent = ent:GetPhysicsObjectNum(0)
ogpos, ogang = ent:GetPos(), ent:GetAngles()
end
if axis.localoffset then
offset = WorldToLocal(offset, angle_zero, ent:GetPos(), ent:GetAngles())
offset = WorldToLocal(offset, angle_zero, ogpos, ogang)
else
offset = WorldToLocal(offset, angle_zero, ent:GetPos(), angle_zero)
offset = WorldToLocal(offset, angle_zero, ogpos, angle_zero)
end
pl.rgm.GizmoOffset = offset
@ -1543,6 +1657,7 @@ function TOOL:LeftClick(tr)
end
pl.rgm.Entity = entity
axis.EntAdvMerged = false
if not entity.rgmbonecached then -- also taken from locrotscale. some hacky way to cache the bones?
pl.rgmSwep = self.SWEP
@ -1658,16 +1773,31 @@ function TOOL:RightClick(tr)
offset = tr.HitPos
end
if rgment:GetClass() == "prop_ragdoll" and pl.rgm.IsPhysBone then
local ogpos, ogang
if not pl.rgm.IsPhysBone then
if axis.EntAdvMerged then
rgment = rgment:GetParent()
if rgment.AttachedEntity then rgment = rgment.AttachedEntity end
end
if pl.rgm.GizmoParentID ~= -1 then
local physobj = rgment:GetPhysicsObjectNum(pl.rgm.GizmoParentID)
ogpos, ogang = LocalToWorld(axis.GizmoPos, axis.GizmoAng, physobj:GetPos(), physobj:GetAngles())
else
ogpos, ogang = LocalToWorld(axis.GizmoPos, axis.GizmoAng, rgment:GetPos(), rgment:GetAngles())
end
elseif rgment:GetClass() == "prop_ragdoll" then
rgment = rgment:GetPhysicsObjectNum(pl.rgm.PhysBone)
ogpos, ogang = rgment:GetPos(), rgment:GetAngles()
elseif rgment:GetClass() == "prop_physics" then
rgment = rgment:GetPhysicsObjectNum(0)
ogpos, ogang = rgment:GetPos(), rgment:GetAngles()
end
if axis.localoffset then
offset = WorldToLocal(offset, angle_zero, rgment:GetPos(), rgment:GetAngles())
offset = WorldToLocal(offset, angle_zero, ogpos, ogang)
else
offset = WorldToLocal(offset, angle_zero, rgment:GetPos(), angle_zero)
offset = WorldToLocal(offset, angle_zero, ogpos, angle_zero)
end
pl.rgm.GizmoOffset = offset
@ -1924,7 +2054,7 @@ if SERVER then
local sc, ang = apart:ProcessMovement(pl.rgmOffsetPos, pl.rgmOffsetAng, eyepos, eyeang, ent, bone, pl.rgmISPos, pl.rgmISDir, 2, snapamount, pl.rgm.StartAngle, pl.rgm.NPhysBonePos, pl.rgm.NPhysBoneAng, pl.rgm.NPhysBoneScale)
local childbones = pl.rgmBoneChildren
if axis.scalechildren then
if axis.scalechildren and not (ent:GetClass() == "ent_advbonemerge") then
local scalediff = sc - prevscale
local diff
local noscale = pl.rgmScaleLocks
@ -1967,7 +2097,7 @@ if SERVER then
RecursiveBoneScale(ent, bone, scalediff)
else
if axis.smovechildren and childbones and childbones[bone] then
if axis.smovechildren and childbones and childbones[bone] and not (ent:GetClass() == "ent_advbonemerge") then
local diff = Vector(sc.x / prevscale.x, sc.y / prevscale.y, sc.z / prevscale.z)
for cbone, pos in pairs(childbones[bone]) do
local bonepos = ent:GetManipulateBonePosition(cbone)
@ -2234,7 +2364,27 @@ local function rgmSendBonePos(pl, ent, boneid)
pos = matrix:GetTranslation()
ang = matrix:GetAngles()
if ent:GetBoneParent(boneid) ~= -1 then
if ent:GetClass() == "ent_advbonemerge" and ent.AdvBone_BoneInfo then -- an exception for advanced bonemerged stuff
local advbones = ent.AdvBone_BoneInfo
local parent = ent:GetParent()
if parent.AttachedEntity then parent = parent.AttachedEntity end
if IsValid(parent) and advbones[boneid].parent and advbones[boneid].parent ~= "" then
gizmoppos = pos
gizmopang = ang
else
if ent:GetBoneParent(boneid) ~= -1 then
local matrix = ent:GetBoneMatrix(ent:GetBoneParent(boneid))
local scale = ent:GetManipulateBoneScale(boneid)
scale = Vector(1 / scale.x, 1 / scale.y, 1 / scale.z)
matrix:Scale(scale)
gizmoppos = matrix:GetTranslation()
gizmopang = matrix:GetAngles()
else
gizmoppos = ent:GetPos()
gizmopang = ent:GetAngles()
end
end
elseif ent:GetBoneParent(boneid) ~= -1 then
local matrix = ent:GetBoneMatrix(ent:GetBoneParent(boneid))
local scale = ent:GetManipulateBoneScale(boneid)
scale = Vector(1 / scale.x, 1 / scale.y, 1 / scale.z)
@ -3148,7 +3298,7 @@ local function RGMBuildBoneMenu(ents, selectedent, bonepanel)
net.SendToServer()
for ent, _ in pairs(ents) do
if ent:IsEffectActive(EF_BONEMERGE) then
if ent:IsEffectActive(EF_BONEMERGE) or ent:GetClass() == "ent_advbonemerge" then
net.Start("rgmAskForParented")
net.WriteUInt(count, 13)
for ent, _ in pairs(ents) do
@ -3616,6 +3766,7 @@ net.Receive("rgmDeselectEntity", function(len)
if IsValid(ConEntPanel) then ConEntPanel:Clear() end
if pl.rgm and pl.rgm.Entity then
pl.rgm.Entity = nil
pl.rgm.Axis.EntAdvMerged = false
end
IsPropRagdoll = false
TreeEntities = {}