Merge pull request #19 from penolakushari/small_enhance

Small enhancements
This commit is contained in:
penolakushari 2023-03-12 23:45:10 +03:00 committed by GitHub
commit 0dd10124f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 697 additions and 181 deletions

View File

@ -510,12 +510,91 @@ end
function DrawBoneName(ent,bone)
local name = ent:GetBoneName(bone)
local _pos,_ang = ent:GetBonePosition(bone)
if not _pos or not _ang then
_pos,_ang = ent:GetPos(),ent:GetAngles()
local _pos = ent:GetBonePosition(bone)
if not _pos then
_pos = ent:GetPos()
end
_pos = _pos:ToScreen()
local textpos = {x = _pos.x+5,y = _pos.y-5}
surface.DrawCircle(_pos.x,_pos.y,2.5,Color(0,200,0,255))
surface.DrawCircle(_pos.x,_pos.y,3.5,Color(0,200,0,255))
draw.SimpleText(name,"Default",textpos.x,textpos.y,Color(0,200,0,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_BOTTOM)
end
function DrawEntName(ent)
local name = ent:GetClass()
local pos
if name == "prop_ragdoll" then
pos = ent:GetBonePosition(0)
if not pos then pos = ent:GetPos() end
elseif IsValid(ent:GetParent()) then
local parent = ent:GetParent()
pos = parent:LocalToWorld(ent:GetLocalPos())
else
pos = ent:GetPos()
end
pos = pos:ToScreen()
local textpos = { x = pos.x+5, y = pos.y-5 }
surface.DrawCircle(pos.x, pos.y, 3.5, Color(0, 200, 0, 255))
draw.SimpleText(name,"Default",textpos.x,textpos.y,Color(0,200,0,255),TEXT_ALIGN_LEFT,TEXT_ALIGN_BOTTOM)
end
function DrawBoneConnections(ent, bone)
local mainpos = ent:GetBonePosition(bone)
if not mainpos then
mainpos = ent:GetPos()
end
mainpos = mainpos:ToScreen()
surface.SetDrawColor( 0, 200, 0, 255 )
for _, childbone in ipairs(ent:GetChildBones(bone)) do
local pos = ent:GetBonePosition(childbone)
pos = pos:ToScreen()
surface.DrawLine(mainpos.x, mainpos.y, pos.x, pos.y)
end
if ent:GetBoneParent(bone) ~= -1 then
surface.SetDrawColor( 0, 0, 200, 255 )
local pos = ent:GetBonePosition(ent:GetBoneParent(bone))
pos = pos:ToScreen()
surface.DrawLine(mainpos.x, mainpos.y, pos.x, pos.y)
end
end
local function DrawRecursiveBones(ent, bone)
local mainpos = ent:GetBonePosition(bone)
mainpos = mainpos:ToScreen()
for _, boneid in ipairs(ent:GetChildBones(bone)) do
local pos = ent:GetBonePosition(boneid)
pos = pos:ToScreen()
surface.SetDrawColor( 255, 255, 255, 255 )
surface.DrawLine(mainpos.x, mainpos.y, pos.x, pos.y)
DrawRecursiveBones(ent, boneid)
surface.DrawCircle(pos.x, pos.y, 2.5, Color(0, 200, 0, 255))
end
end
function DrawSkeleton(ent)
local num = ent:GetBoneCount() - 1
for v = 0, num do
if ent:GetBoneName(v) == "__INVALIDBONE__" then continue end
if ent:GetBoneParent(v) == -1 then
local pos = ent:GetBonePosition(v)
if not pos then
pos = ent:GetPos()
end
DrawRecursiveBones(ent, v)
pos = pos:ToScreen()
surface.DrawCircle(pos.x, pos.y, 2.5, Color(0, 200, 0, 255))
end
end
end

View File

@ -235,7 +235,9 @@ function ENT:Think()
local scale = pl.rgm.Scale or false
local offset, offsetlocal = pl.rgm.GizmoOffset, self.localizedoffset
if pl.rgm.IsPhysBone then
if IsValid(ent:GetParent()) and pl.rgm.Bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not (ent:GetClass() == "prop_ragdoll") then
pos = ent:GetParent():LocalToWorld(ent:GetLocalPos())
elseif pl.rgm.IsPhysBone then
local physobj = ent:GetPhysicsObjectNum(bone)
if physobj == nil then return end
@ -253,7 +255,9 @@ function ENT:Think()
pos = pl.rgm.GizmoPos
end
end
if pl.rgm.IsPhysBone and not scale then
if IsValid(ent:GetParent()) and pl.rgm.Bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not (ent:GetClass() == "prop_ragdoll") and not scale then
ang = ent:GetParent():LocalToWorldAngles(ent:GetLocalAngles())
elseif pl.rgm.IsPhysBone and not scale then
local physobj = ent:GetPhysicsObjectNum(bone)
if physobj == nil then return end
@ -306,7 +310,7 @@ function ENT:Think()
if not pl.rgm.Moving then -- Prevent whole thing from rotating when we do localized rotation - needed for proper angle reading
if localstate or scale or not pl.rgm.IsPhysBone then -- Non phys bones don't go well with world coordinates. Well, I didn't make them to behave with those
self:SetAngles(ang or Angle(0,0,0))
if (ent:GetClass() == "prop_ragdoll" or (ent:GetClass() == "prop_dynamic" and pl.rgm.ParentEntity:GetClass() == "prop_effect") or ent:GetClass() == "ent_bonemerged") and (not pl.rgm.IsPhysBone) then -- those things are meant to work for nonphysical bones of any entity, but man i can't figure out how to do that as GetBonePosition returns angles differently for ragdolls and any other entity. please help
if (ent:GetClass() == "prop_ragdoll" or ent:GetClass() == "prop_dynamic" or ent:GetClass() == "ent_bonemerged") and (not pl.rgm.IsPhysBone) then
self.DiscP:SetLocalAngles(Angle(0, 90 + ent:GetManipulateBoneAngles(bone).y, 0)) -- Pitch follows Yaw angles
self.DiscR:SetLocalAngles(Angle(0 + ent:GetManipulateBoneAngles(bone).x, 0 + ent:GetManipulateBoneAngles(bone).y, 0)) -- Roll follows Pitch and Yaw angles
else

View File

@ -3,7 +3,7 @@ include("shared.lua")
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, isphys, StartGrab, NPhysPos)
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, movetype, StartGrab, NPhysPos)
local intersect = self:GetGrabPos(eyepos,eyeang,ppos)
local localized = self:WorldToLocal(intersect)
local axis = self:GetParent()
@ -14,19 +14,24 @@ function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, is
end
local pos, ang
if isphys then
local _a
if movetype == 1 then
local obj = ent:GetPhysicsObjectNum(bone)
localized = Vector(localized.x,0,0)
intersect = self:LocalToWorld(localized)
ang = obj:GetAngles()
pos,_a = LocalToWorld(Vector(offpos.x,0,0),Angle(0,0,0),intersect - offset,self:GetAngles())
else
pos = LocalToWorld(Vector(offpos.x,0,0),Angle(0,0,0),intersect - offset,self:GetAngles())
elseif movetype == 2 then
pos = ent:GetManipulateBonePosition(bone)
localized = Vector(localized.x - StartGrab.x,0,0)
local posadd = NPhysPos[self.axistype] + localized.x
ang = ent:GetManipulateBoneAngles(bone)
pos[self.axistype] = posadd
elseif movetype == 0 then
localized = Vector(localized.x,0,0)
intersect = self:LocalToWorld(localized)
ang = ent:GetLocalAngles()
pos = LocalToWorld(Vector(offpos.x,0,0),Angle(0,0,0),intersect - offset, self:GetAngles())
pos = ent:GetParent():WorldToLocal(pos)
end
return pos,ang
end

View File

@ -19,7 +19,7 @@ local function ConvertVector(vec, axistype)
return result
end
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, isphys, startAngle, garbage, NPhysAngle) -- initially i had a table instead of separate things for initial bone pos and angle, but sync command can't handle tables and i thought implementing a way to handle those would be too much hassle
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, movetype, startAngle, garbage, NPhysAngle) -- initially i had a table instead of separate things for initial bone pos and angle, but sync command can't handle tables and i thought implementing a way to handle those would be too much hassle
local intersect = self:GetGrabPos(eyepos,eyeang,ppos,pnorm)
local localized = self:WorldToLocal(intersect)
local _p, _a
@ -32,7 +32,7 @@ function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, is
}
if isphys then
if movetype == 1 then
local axis = self:GetParent()
local offset = axis.Owner.rgm.GizmoOffset
if axis.localizedoffset and not axis.relativerotate then
@ -51,7 +51,7 @@ function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, is
_p,_a = LocalToWorld(Vector(0,0,0),offang,pos,ang)
_p = pos - offset
end
else
elseif movetype == 2 then
local rotateang, axisangle
axisangle = axistable[self.axistype]
@ -76,6 +76,29 @@ function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, is
end
_p = ent:GetManipulateBonePosition(bone)
elseif movetype == 0 then
local axis = self:GetParent()
local offset = axis.Owner.rgm.GizmoOffset
if axis.localizedoffset and not axis.relativerotate then
offset = LocalToWorld(offset, Angle(0,0,0), axis:GetPos(), axis.LocalAngles)
offset = offset - axis:GetPos()
end
localized = Vector(localized.y,localized.z,0):Angle()
local pos = self:GetPos()
local ang = self:LocalToWorldAngles(Angle(0,0,localized.y))
if axis.relativerotate then
offset = WorldToLocal(axis.BonePos, Angle(0, 0, 0), axis:GetPos(), axis.LocalAngles)
_p,_a = LocalToWorld(Vector(0,0,0),offang,pos,ang)
_p = LocalToWorld(offset, _a, pos, _a)
_a = ent:GetParent():WorldToLocalAngles(_a)
_p = ent:GetParent():WorldToLocal(_p)
else
_p,_a = LocalToWorld(Vector(0,0,0),offang,pos,ang)
_p = pos - offset
_a = ent:GetParent():WorldToLocalAngles(_a)
_p = ent:GetParent():WorldToLocal(_p)
end
end
return _p,_a

View File

@ -3,7 +3,7 @@ include("shared.lua")
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, isphys, StartGrab, garbage, garbage, NPhysScale)
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, movetype, StartGrab, garbage, garbage, NPhysScale)
local intersect = self:GetGrabPos(eyepos,eyeang,ppos)
local localized = self:WorldToLocal(intersect)
local pos, ang

View File

@ -3,7 +3,7 @@ include("shared.lua")
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, isphys, startGrab, garbage, garbage, NPhysScale)
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, movetype, startGrab, garbage, garbage, NPhysScale)
local intersect = self:GetGrabPos(eyepos,eyeang,ppos,pnorm)
local pos, ang
local pl = self:GetParent().Owner

View File

@ -3,7 +3,7 @@ include("shared.lua")
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, isphys, startGrab, NPhysPos)
function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, movetype, startGrab, NPhysPos)
local intersect = self:GetGrabPos(eyepos,eyeang,ppos,pnorm)
local axis = self:GetParent()
local offset = axis.Owner.rgm.GizmoOffset
@ -14,11 +14,11 @@ function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, is
local pos, ang
local pl = self:GetParent().Owner
if isphys then
if movetype == 1 then
local obj = ent:GetPhysicsObjectNum(bone)
ang = obj:GetAngles()
pos = LocalToWorld(offpos,Angle(0,0,0),intersect - offset,self:GetAngles())
else
elseif movetype == 2 then
local localized, startmove, finalpos, boneang
if ent:GetBoneParent(bone) ~= -1 then
local matrix = ent:GetBoneMatrix(ent:GetBoneParent(bone))
@ -37,6 +37,10 @@ function ENT:ProcessMovement(offpos,offang,eyepos,eyeang,ent,bone,ppos,pnorm, is
finalpos = NPhysPos + localized
ang = ent:GetManipulateBoneAngles(bone)
pos = finalpos
elseif movetype == 0 then
ang = ent:GetLocalAngles()
pos = LocalToWorld(offpos,Angle(0,0,0),intersect - offset,self:GetAngles())
pos = ent:GetParent():WorldToLocal(pos)
end
return pos,ang

View File

@ -12,7 +12,8 @@ TOOL.ClientConVar["scale"] = 10
TOOL.ClientConVar["width"] = 0.5
TOOL.ClientConVar["fulldisc"] = 0
TOOL.ClientConVar["disablefilter"] = 0
TOOL.ClientConVar["disablechildbone"] = 0
TOOL.ClientConVar["scalechildren"] = 0
TOOL.ClientConVar["drawskeleton"] = 0
TOOL.ClientConVar["ik_leg_L"] = 0
TOOL.ClientConVar["ik_leg_R"] = 0
@ -67,6 +68,8 @@ util.AddNetworkString("rgmUpdateBones")
util.AddNetworkString("rgmAskForPhysbones")
util.AddNetworkString("rgmAskForPhysbonesResponse")
util.AddNetworkString("rgmAskForNodeUpdatePhysics")
util.AddNetworkString("rgmAskForNodeUpdatePhysicsResponse")
util.AddNetworkString("rgmAskForParented")
util.AddNetworkString("rgmAskForParentedResponse")
@ -84,7 +87,9 @@ util.AddNetworkString("rgmOperationSwitch")
util.AddNetworkString("rgmSetGizmoToBone")
util.AddNetworkString("rgmUpdateGizmo")
util.AddNetworkString("rgmResetBone")
util.AddNetworkString("rgmResetAll")
util.AddNetworkString("rgmResetPos")
util.AddNetworkString("rgmResetAng")
util.AddNetworkString("rgmResetScale")
util.AddNetworkString("rgmScaleZero")
util.AddNetworkString("rgmAdjustBone")
@ -103,7 +108,29 @@ net.Receive("rgmAskForPhysbones", function(len, pl)
for i = 0, count do
local bone = ent:TranslatePhysBoneToBone(i)
if bone == -1 then bone = 0 end
net.WriteUInt(bone, 32)
net.WriteUInt(bone, 8)
end
net.Send(pl)
end
end)
net.Receive("rgmAskForNodeUpdatePhysics", function(len, pl)
local isphys = net.ReadBool()
local ent = net.ReadEntity()
if not IsValid(ent) then return end
local count = ent:GetPhysicsObjectCount() - 1
if count ~= -1 then
net.Start("rgmAskForNodeUpdatePhysicsResponse")
net.WriteBool(isphys)
net.WriteEntity(ent)
net.WriteUInt(count, 8)
for i = 0, count do
local bone = ent:TranslatePhysBoneToBone(i)
if bone == -1 then bone = 0 end
net.WriteUInt(bone, 8)
end
net.Send(pl)
end
@ -111,12 +138,12 @@ end)
net.Receive("rgmAskForParented", function(len, pl)
local ent = net.ReadEntity()
if not IsValid(ent) or not IsValid(pl.rgm.ParentEntity) then return end
if not IsValid(ent) or not IsValid(ent:GetParent()) then return end
local parented = {}
for i = 0, ent:GetBoneCount() - 1 do
if pl.rgm.ParentEntity:LookupBone(ent:GetBoneName(i)) then
if ent:GetParent():LookupBone(ent:GetBoneName(i)) then
table.insert(parented, i)
end
end
@ -134,6 +161,8 @@ end)
net.Receive("rgmSelectBone", function(len, pl)
local ent = net.ReadEntity()
local bone = net.ReadUInt(32)
pl.rgm.BoneToResetTo = 0
RGMGetBone(pl, ent, bone)
pl:rgmSync()
@ -147,27 +176,30 @@ end)
net.Receive("rgmLockBone", function(len, pl)
local mode = net.ReadUInt(2)
local ent = pl.rgm.Entity
if not IsValid(ent) or not pl.rgm.IsPhysBone then return end
local bone = net.ReadUInt(8)
if not IsValid(ent) or ent:TranslateBoneToPhysBone(bone) == -1 then return end
if ent:GetClass() ~= "prop_ragdoll" then return end
bone = ent:TranslateBoneToPhysBone(bone)
if mode == 1 then
if not pl.rgmPosLocks[pl.rgm.PhysBone] then
pl.rgmPosLocks[pl.rgm.PhysBone] = ent:GetPhysicsObjectNum(pl.rgm.PhysBone)
if not pl.rgmPosLocks[bone] then
pl.rgmPosLocks[bone] = ent:GetPhysicsObjectNum(bone)
else
pl.rgmPosLocks[pl.rgm.PhysBone] = nil
pl.rgmPosLocks[bone] = nil
end
elseif mode == 2 then
if not pl.rgmAngLocks[pl.rgm.PhysBone] then
pl.rgmAngLocks[pl.rgm.PhysBone] = ent:GetPhysicsObjectNum(pl.rgm.PhysBone)
if not pl.rgmAngLocks[bone] then
pl.rgmAngLocks[bone] = ent:GetPhysicsObjectNum(bone)
else
pl.rgmAngLocks[pl.rgm.PhysBone] = nil
pl.rgmAngLocks[bone] = nil
end
end
local poslock, anglock = IsValid(pl.rgmPosLocks[pl.rgm.PhysBone]), IsValid(pl.rgmAngLocks[pl.rgm.PhysBone])
local poslock, anglock = IsValid(pl.rgmPosLocks[bone]), IsValid(pl.rgmAngLocks[bone])
net.Start("rgmLockBoneResponse")
net.WriteUInt(ent:TranslatePhysBoneToBone(pl.rgm.PhysBone), 32)
net.WriteUInt(ent:TranslatePhysBoneToBone(bone), 32)
net.WriteBool(poslock)
net.WriteBool(anglock)
net.Send(pl)
@ -178,6 +210,7 @@ net.Receive("rgmSelectEntity", function(len, pl)
if not IsValid(ent) then return end
pl.rgm.Entity = ent
pl.rgm.BoneToResetTo = 0
if not ent.rgmbonecached then -- also taken from locrotscale. some hacky way to cache the bones?
local p = pl.rgmSwep:GetParent()
@ -233,26 +266,86 @@ net.Receive("rgmSetGizmoToBone", function(len, pl)
net.Send(pl)
end)
net.Receive("rgmResetBone", function(len, pl)
ent = pl.rgm.Entity
ent:ManipulateBoneAngles(pl.rgm.Bone, Angle(0, 0, 0))
ent:ManipulateBonePosition(pl.rgm.Bone, Vector(0, 0, 0))
local function RecursiveBoneFunc(bone, ent, func, param)
func(bone, param)
for _, id in ipairs(ent:GetChildBones(bone)) do
RecursiveBoneFunc(id, ent, func, param)
end
end
net.Receive("rgmResetAll", function(len, pl)
if not pl.rgm or not IsValid(pl.rgm.Entity) then net.ReadUInt(8) net.ReadBool() return end
local ent = pl.rgm.Entity
local bone = net.ReadUInt(8)
if net.ReadBool() then
RecursiveBoneFunc(bone, ent, function(bon)
ent:ManipulateBonePosition(bon, Vector(0, 0, 0))
ent:ManipulateBoneAngles(bon, Angle(0, 0, 0))
ent:ManipulateBoneScale(bon, Vector(1, 1, 1))
end)
else
ent:ManipulateBonePosition(bone, Vector(0, 0, 0))
ent:ManipulateBoneAngles(bone, Angle(0, 0, 0))
ent:ManipulateBoneScale(bone, Vector(1, 1, 1))
end
net.Start("rgmUpdateSliders")
net.Send(pl)
end)
net.Receive("rgmResetPos", function(len, pl)
if not pl.rgm or not IsValid(pl.rgm.Entity) then net.ReadBool() net.ReadUInt(8) return end
local ent = pl.rgm.Entity
if net.ReadBool() then
RecursiveBoneFunc(net.ReadUInt(8), ent, function(bone, param) ent:ManipulateBonePosition(bone, param) end, Vector(0, 0, 0))
else
ent:ManipulateBonePosition(net.ReadUInt(8), Vector(0, 0, 0))
end
net.Start("rgmUpdateSliders")
net.Send(pl)
end)
net.Receive("rgmResetAng", function(len, pl)
if not pl.rgm or not IsValid(pl.rgm.Entity) then net.ReadBool() net.ReadUInt(8) return end
local ent = pl.rgm.Entity
if net.ReadBool() then
RecursiveBoneFunc(net.ReadUInt(8), ent, function(bone, param) ent:ManipulateBoneAngles(bone, param) end, Angle(0, 0, 0))
else
ent:ManipulateBoneAngles(net.ReadUInt(8), Angle(0, 0, 0))
end
net.Start("rgmUpdateSliders")
net.Send(pl)
end)
net.Receive("rgmResetScale", function(len, pl)
ent = pl.rgm.Entity
ent:ManipulateBoneScale(pl.rgm.Bone, Vector(1, 1, 1))
if not pl.rgm or not IsValid(pl.rgm.Entity) then net.ReadBool() net.ReadUInt(8) return end
local ent = pl.rgm.Entity
if net.ReadBool() then
RecursiveBoneFunc(net.ReadUInt(8), ent, function(bone, param) ent:ManipulateBoneScale(bone, param) end, Vector(1, 1, 1))
else
ent:ManipulateBoneScale(net.ReadUInt(8), Vector(1, 1, 1))
end
net.Start("rgmUpdateSliders")
net.Send(pl)
end)
net.Receive("rgmScaleZero", function(len, pl)
ent = pl.rgm.Entity
ent:ManipulateBoneScale(pl.rgm.Bone, Vector(0, 0, 0))
if not pl.rgm or not IsValid(pl.rgm.Entity) then net.ReadBool() net.ReadUInt(8) return end
local ent = pl.rgm.Entity
if net.ReadBool() then
RecursiveBoneFunc(net.ReadUInt(8), ent, function(bone, param) ent:ManipulateBoneScale(bone, param) end, Vector(0, 0, 0))
else
ent:ManipulateBoneScale(net.ReadUInt(8), Vector(0, 0, 0))
end
net.Start("rgmUpdateSliders")
net.Send(pl)
@ -278,10 +371,27 @@ net.Receive("rgmAdjustBone", function(len, pl)
end
ManipulateBone[3] = function(axis, value)
local Change = ent:GetManipulateBoneScale(pl.rgm.Bone)
local rgmaxis, bone = pl.rgm.Axis, pl.rgm.Bone
local PrevScale = ent:GetManipulateBoneScale(bone)
local Change = ent:GetManipulateBoneScale(bone)
Change[axis] = value
ent:ManipulateBoneScale(pl.rgm.Bone, Change)
if rgmaxis.scalechildren then
local scalediff = Change - PrevScale
local function RecursiveBoneScale(ent, bone, scale)
local oldscale = ent:GetManipulateBoneScale(bone)
ent:ManipulateBoneScale(bone, oldscale + scale)
for _, cbone in ipairs(ent:GetChildBones(bone)) do
RecursiveBoneScale(ent, cbone, scale)
end
end
RecursiveBoneScale(ent, bone, scalediff)
else
ent:ManipulateBoneScale(bone, Change)
end
end
local mode, axis, value = net.ReadInt(3), net.ReadInt(3), net.ReadFloat()
@ -306,8 +416,11 @@ end
concommand.Add("ragdollmover_resetroot", function(pl)
if not IsValid(pl.rgm.Entity) then return end
local bone = pl.rgm.Bone
RGMGetBone(pl, pl.rgm.Entity, pl.rgm.BoneToResetTo)
pl.rgm.BoneToResetTo = bone
RGMGetBone(pl, pl.rgm.Entity, 0)
pl:rgmSync()
net.Start("rgmSelectBoneResponse")
@ -333,12 +446,17 @@ end
local function rgmFindEntityChildren(parent)
local children = {}
for k, ent in pairs(parent:GetChildren()) do
if not IsValid(ent) or ent:IsWorld() or ent:IsConstraint() or not isstring(ent:GetModel()) or not util.IsValidModel(ent:GetModel()) then continue end
local function RecursiveFindChildren(entity)
for k, ent in pairs(entity:GetChildren()) do
if not IsValid(ent) or ent:IsWorld() or ent:IsConstraint() or not isstring(ent:GetModel()) or not util.IsValidModel(ent:GetModel()) then continue end
table.insert(children, ent)
table.insert(children, ent)
RecursiveFindChildren(ent)
end
end
RecursiveFindChildren(parent)
return children
end
@ -425,6 +543,10 @@ function TOOL:LeftClick(tr)
_p,pl.rgmOffsetAng = WorldToLocal(apart:GetPos(),obj:GetAngles(),apart:GetPos(),grabang)
pl.rgmOffsetTable = rgm.GetOffsetTable(self, ent, pl.rgm.Rotate)
end
if IsValid(ent:GetParent()) and not (ent:GetClass() == "prop_ragdoll") then -- ragdolls don't seem to care about parenting
local pang = ent:GetParent():LocalToWorldAngles(ent:GetLocalAngles())
_, pl.rgmOffsetAng = WorldToLocal(apart:GetPos(),pang,apart:GetPos(),grabang)
end
pl.rgm.StartAngle = WorldToLocal(collision.hitpos, Angle(0,0,0), apart:GetPos(), apart:GetAngles())
if ent:GetClass() ~= "prop_ragdoll" and pl.rgm.IsPhysBone then
@ -459,6 +581,7 @@ function TOOL:LeftClick(tr)
end
RGMGetBone(pl, entity, entity:TranslatePhysBoneToBone(tr.PhysicsBone))
pl.rgm.BoneToResetTo = 0 -- used for quickswitching to root bone and back
if ent ~= pl.rgm.ParentEntity then
local children = rgmFindEntityChildren(pl.rgm.ParentEntity)
@ -606,6 +729,9 @@ if SERVER then
if axis.relativerotate ~= tobool(self:GetClientNumber("relativerotate",1)) then
axis.relativerotate = tobool(self:GetClientNumber("relativerotate",1))
end
if axis.scalechildren ~= tobool(self:GetClientNumber("scalechildren",1)) then
axis.scalechildren = tobool(self:GetClientNumber("scalechildren",1))
end
end
local moving = pl.rgm.Moving or false
@ -629,6 +755,8 @@ if SERVER then
pl.rgm.Moving = false
pl:rgmSyncOne("Moving")
net.Start("rgmUpdateSliders")
net.Send(pl)
return
end
@ -648,11 +776,15 @@ if SERVER then
if physbonecount == nil then return end
if not scale then
if pl.rgm.IsPhysBone then
if IsValid(ent:GetParent()) and bone == 0 and not ent:IsEffectActive(EF_BONEMERGE) and not (ent:GetClass() == "prop_ragdoll") then
local pos, ang = apart:ProcessMovement(pl.rgmOffsetPos,pl.rgmOffsetAng,eyepos,eyeang,ent,bone,pl.rgmISPos,pl.rgmISDir,0)
ent:SetLocalPos(pos)
ent:SetLocalAngles(ang)
elseif pl.rgm.IsPhysBone then
local isik,iknum = rgm.IsIKBone(self,ent,bone)
local pos,ang = apart:ProcessMovement(pl.rgmOffsetPos,pl.rgmOffsetAng,eyepos,eyeang,ent,bone,pl.rgmISPos,pl.rgmISDir, true)
local pos,ang = apart:ProcessMovement(pl.rgmOffsetPos,pl.rgmOffsetAng,eyepos,eyeang,ent,bone,pl.rgmISPos,pl.rgmISDir, 1)
local obj = ent:GetPhysicsObjectNum(bone)
if not isik or iknum == 3 or (rotate and (iknum == 1 or iknum == 2)) then
@ -702,17 +834,32 @@ if SERVER then
-- if not pl:GetNWBool("ragdollmover_keydown") then
else
local pos, ang = apart:ProcessMovement(pl.rgmOffsetPos,pl.rgmOffsetAng,eyepos,eyeang,ent,bone,pl.rgmISPos,pl.rgmISDir, false, pl.rgm.StartAngle, pl.rgm.NPhysBonePos, pl.rgm.NPhysBoneAng) -- if a bone is not physics one, we pass over "start angle" thing
local pos, ang = apart:ProcessMovement(pl.rgmOffsetPos,pl.rgmOffsetAng,eyepos,eyeang,ent,bone,pl.rgmISPos,pl.rgmISDir, 2, pl.rgm.StartAngle, pl.rgm.NPhysBonePos, pl.rgm.NPhysBoneAng) -- if a bone is not physics one, we pass over "start angle" thing
ent:ManipulateBoneAngles(bone, ang)
ent:ManipulateBonePosition(bone, pos)
end
else
bone = pl.rgm.Bone
local sc, ang = apart:ProcessMovement(pl.rgmOffsetPos,pl.rgmOffsetAng,eyepos,eyeang,ent,bone,pl.rgmISPos,pl.rgmISDir, false, pl.rgm.StartAngle, pl.rgm.NPhysBonePos, pl.rgm.NPhysBoneAng, pl.rgm.NPhysBoneScale)
local prevscale = ent:GetManipulateBoneScale(bone)
local sc, ang = apart:ProcessMovement(pl.rgmOffsetPos,pl.rgmOffsetAng,eyepos,eyeang,ent,bone,pl.rgmISPos,pl.rgmISDir, 2, pl.rgm.StartAngle, pl.rgm.NPhysBonePos, pl.rgm.NPhysBoneAng, pl.rgm.NPhysBoneScale)
ent:ManipulateBoneScale(bone, sc)
if axis.scalechildren then
local scalediff = sc - prevscale
local function RecursiveBoneScale(ent, bone, scale)
local oldscale = ent:GetManipulateBoneScale(bone)
ent:ManipulateBoneScale(bone, oldscale + scale)
for _, cbone in ipairs(ent:GetChildBones(bone)) do
RecursiveBoneScale(ent, cbone, scale)
end
end
RecursiveBoneScale(ent, bone, scalediff)
else
ent:ManipulateBoneScale(bone, sc)
end
end
@ -753,14 +900,6 @@ local function GetRecursiveBones(ent, boneid, tab)
if ent:BoneHasFlag(v, 4) then -- BONE_ALWAYS_PROCEDURAL flag
bone.Type = BONE_PROCEDURAL
else
for i = 0, ent:GetPhysicsObjectCount() - 1 do
local b = ent:TranslatePhysBoneToBone(i)
if v == b then
bone.Type = BONE_PHYSICAL
break
end
end
end
table.insert(tab, bone)
@ -768,6 +907,26 @@ local function GetRecursiveBones(ent, boneid, tab)
end
end
local function GetRecursiveBonesExclusive(ent, boneid, lastvalidbone, tab, physcheck, isphys)
for k, v in ipairs(ent:GetChildBones(boneid)) do
local bone = {id = v, Type = BONE_NONPHYSICAL, parent = lastvalidbone}
local newlastvalid = lastvalidbone
if ent:BoneHasFlag(v, 4) then -- BONE_ALWAYS_PROCEDURAL flag
bone.Type = BONE_PROCEDURAL
elseif physcheck[v] then
bone.Type = BONE_PHYSICAL
end
if (isphys and bone.Type == BONE_PHYSICAL) or (not isphys and bone.Type ~= BONE_PHYSICAL) then
newlastvalid = v
table.insert(tab, bone)
end
GetRecursiveBonesExclusive(ent, v, newlastvalid, tab, physcheck, isphys)
end
end
local function GetModelName(ent)
local name = ent:GetModel()
local splitname = string.Split(name, "/")
@ -919,38 +1078,6 @@ local function RGMGizmoMode()
net.SendToServer()
end
local function RGMResetBone()
local pl = LocalPlayer()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetBone")
net.SendToServer()
end
local function RGMResetScale()
local pl = LocalPlayer()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetScale")
net.SendToServer()
end
local function RGMScaleZero()
local pl = LocalPlayer()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmScaleZero")
net.SendToServer()
end
local function RGMLockPBone(mode)
local pl = LocalPlayer()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) or not pl.rgm.IsPhysBone then return end
net.Start("rgmLockBone")
net.WriteUInt(mode, 2)
net.SendToServer()
end
local function AddHBar(self) -- There is no horizontal scrollbars in gmod, so I guess we'll override vertical one from GMod
self.HBar = vgui.Create("DVScrollBar")
@ -1092,30 +1219,11 @@ end
local BonePanel, EntPanel
local Pos1, Pos2, Pos3, Rot1, Rot2, Rot3, Scale1, Scale2, Scale3
local Gizmo1, Gizmo2, Gizmo3
local LockRotB, LockPosB
local nodes, entnodes
local HoveredBone
local HoveredBone, HoveredEnt
local Col4
local function RGMBuildBoneMenu(ent, bonepanel)
bonepanel:Clear()
if not IsValid(ent) then return end
local sortedbones = {}
local num = ent:GetBoneCount() - 1 -- first we find all rootbones and their children
for v = 0, num do
if ent:GetBoneName(v) == "__INVALIDBONE__" then continue end
if ent:GetBoneParent(v) == -1 then
local bone = { id = v, Type = BONE_NONPHYSICAL }
if ent:BoneHasFlag(v, 4) then -- BONE_ALWAYS_PROCEDURAL flag
bone.Type = BONE_PROCEDURAL
end
table.insert(sortedbones, bone)
local bonesadd = GetRecursiveBones(ent, v, sortedbones)
end
end
local function SetBoneNodes(bonepanel, ent, sortedbones)
nodes = {}
@ -1136,6 +1244,9 @@ local function RGMBuildBoneMenu(ent, bonepanel)
elseif nodes[v.id].Type == BONE_PROCEDURAL then
nodes[v.id]:SetIcon("icon16/error.png")
nodes[v.id].Label:SetToolTip("#tool.ragdollmover.proceduralbone")
elseif nodes[v.id].Type == BONE_PHYSICAL then
nodes[v.id]:SetIcon("icon16/brick.png")
nodes[v.id].Label:SetToolTip("#tool.ragdollmover.physbone")
end
nodes[v.id].DoClick = function()
@ -1146,9 +1257,141 @@ local function RGMBuildBoneMenu(ent, bonepanel)
end
nodes[v.id].DoRightClick = function()
local pl = LocalPlayer()
local bonemenu = DermaMenu(false, bonepanel)
bonemenu:AddOption("Put Gizmo offset here", function()
local ResetMenu = bonemenu:AddSubMenu("#tool.ragdollmover.resetmenu")
local option = ResetMenu:AddOption("#tool.ragdollmover.resetpos", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetPos")
net.WriteBool(false)
net.WriteUInt(v.id, 8) -- with SFM studiomdl, it seems like upper limit for bones is 256 (counting 0)
net.SendToServer()
end)
option:SetIcon("icon16/connect.png")
option = ResetMenu:AddOption("#tool.ragdollmover.resetrot", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetAng")
net.WriteBool(false)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon("icon16/connect.png")
option = ResetMenu:AddOption("#tool.ragdollmover.resetscale", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetScale")
net.WriteBool(false)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon("icon16/connect.png")
option = ResetMenu:AddOption("#tool.ragdollmover.reset", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetAll")
net.WriteUInt(v.id, 8)
net.WriteBool(false)
net.SendToServer()
end)
option:SetIcon("icon16/connect.png")
option = ResetMenu:AddOption("#tool.ragdollmover.resetposchildren", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetPos")
net.WriteBool(true)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon("icon16/bricks.png")
option = ResetMenu:AddOption("#tool.ragdollmover.resetrotchildren", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetAng")
net.WriteBool(true)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon("icon16/bricks.png")
option = ResetMenu:AddOption("#tool.ragdollmover.resetscalechildren", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetScale")
net.WriteBool(true)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon("icon16/bricks.png")
option = ResetMenu:AddOption("#tool.ragdollmover.resetchildren", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmResetAll")
net.WriteUInt(v.id, 8)
net.WriteBool(true)
net.SendToServer()
end)
option:SetIcon("icon16/bricks.png")
local ScaleZeroMenu = bonemenu:AddSubMenu("#tool.ragdollmover.scalezero")
option = ScaleZeroMenu:AddOption("#tool.ragdollmover.bone", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmScaleZero")
net.WriteBool(false)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon("icon16/connect.png")
option = ScaleZeroMenu:AddOption("#tool.ragdollmover.bonechildren", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmScaleZero")
net.WriteBool(true)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon("icon16/bricks.png")
bonemenu:AddSpacer()
if nodes[v.id].Type == BONE_PHYSICAL and IsValid(pl.rgm.Entity) and pl.rgm.Entity:GetClass() == "prop_ragdoll" then
option = bonemenu:AddOption(nodes[v.id].poslock and "#tool.ragdollmover.unlockpos" or "#tool.ragdollmover.lockpos", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmLockBone")
net.WriteUInt(1, 2)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon(nodes[v.id].poslock and "icon16/lock.png" or "icon16/brick.png")
option = bonemenu:AddOption(nodes[v.id].anglock and "#tool.ragdollmover.unlockang" or "#tool.ragdollmover.lockang", function()
if not pl.rgm then return end
if not IsValid(pl.rgm.Entity) then return end
net.Start("rgmLockBone")
net.WriteUInt(2, 2)
net.WriteUInt(v.id, 8)
net.SendToServer()
end)
option:SetIcon(nodes[v.id].anglock and "icon16/lock.png" or "icon16/brick.png")
bonemenu:AddSpacer()
end
bonemenu:AddOption("#tool.ragdollmover.putgizmopos", function()
local pl = LocalPlayer()
if not pl.rgm or not IsValid(pl.rgm.Entity) then return end
@ -1165,7 +1408,9 @@ local function RGMBuildBoneMenu(ent, bonepanel)
net.SendToServer()
end)
bonemenu:Open()
local x, y = bonepanel:LocalToScreen(5, 0)
bonemenu:Open(x)
end
nodes[v.id].Label.OnCursorEntered = function()
@ -1177,6 +1422,30 @@ local function RGMBuildBoneMenu(ent, bonepanel)
end
end
end
local function RGMBuildBoneMenu(ent, bonepanel)
bonepanel:Clear()
if not IsValid(ent) then return end
local sortedbones = {}
local num = ent:GetBoneCount() - 1 -- first we find all rootbones and their children
for v = 0, num do
if ent:GetBoneName(v) == "__INVALIDBONE__" then continue end
if ent:GetBoneParent(v) == -1 then
local bone = { id = v, Type = BONE_NONPHYSICAL }
if ent:BoneHasFlag(v, 4) then -- BONE_ALWAYS_PROCEDURAL flag
bone.Type = BONE_PROCEDURAL
end
table.insert(sortedbones, bone)
GetRecursiveBones(ent, v, sortedbones)
end
end
SetBoneNodes(bonepanel, ent, sortedbones)
net.Start("rgmAskForPhysbones")
net.WriteEntity(ent)
net.SendToServer()
@ -1188,6 +1457,55 @@ local function RGMBuildBoneMenu(ent, bonepanel)
end
end
local function ShowOnlyPhysNodes(ent, bonepanel)
bonepanel:Clear()
if not IsValid(ent) then return end
net.Start("rgmAskForNodeUpdatePhysics")
net.WriteBool(true)
net.WriteEntity(ent)
net.SendToServer()
end
local function ShowOnlyNonPhysNodes(ent, bonepanel)
bonepanel:Clear()
if not IsValid(ent) then return end
net.Start("rgmAskForNodeUpdatePhysics")
net.WriteBool(false)
net.WriteEntity(ent)
net.SendToServer()
end
local function UpdateBoneNodes(ent, bonepanel, physIDs, isphys)
local sortedbones = {}
local num = ent:GetBoneCount() - 1
for v = 0, num do
if ent:GetBoneName(v) == "__INVALIDBONE__" then continue end
if ent:GetBoneParent(v) == -1 then
local bone = { id = v, Type = BONE_NONPHYSICAL }
if ent:BoneHasFlag(v, 4) then
bone.Type = BONE_PROCEDURAL
elseif physIDs[v] then
bone.Type = BONE_PHYSICAL
end
table.insert(sortedbones, bone)
GetRecursiveBonesExclusive(ent, v, v, sortedbones, physIDs, isphys)
end
end
SetBoneNodes(bonepanel, ent, sortedbones)
if ent:IsEffectActive(EF_BONEMERGE) then
net.Start("rgmAskForParented")
net.WriteEntity(ent)
net.SendToServer()
end
end
local function RGMBuildEntMenu(parent, children, entpanel)
entpanel:Clear()
if not IsValid(parent) then return end
@ -1203,17 +1521,90 @@ local function RGMBuildEntMenu(parent, children, entpanel)
net.SendToServer()
end
for k, v in ipairs(children) do
if not IsValid(v) or not isstring(v:GetModel()) then continue end
entnodes[parent].Label.OnCursorEntered = function()
HoveredEnt = parent
end
entnodes[v] = entnodes[parent]:AddNode(GetModelName(v))
entnodes[parent].Label.OnCursorExited = function()
HoveredEnt = nil
end
entnodes[v].DoClick = function()
net.Start("rgmSelectEntity")
net.WriteEntity(v)
net.SendToServer()
local sortchildren = {}
local function RecursiveChildrenSort(parent, sorttable)
for k, v in ipairs(children) do
if v:GetParent() ~= parent then continue end
table.insert(sorttable, v)
sorttable[v] = {}
RecursiveChildrenSort(v, sorttable[v])
end
end
RecursiveChildrenSort(parent, sortchildren)
local function MakeChildrenList(parent, sorttable)
for k, v in ipairs(sorttable) do
if not IsValid(v) or not isstring(v:GetModel()) then continue end
entnodes[v] = entnodes[parent]:AddNode(GetModelName(v))
entnodes[v]:SetExpanded(true)
entnodes[v].DoClick = function()
net.Start("rgmSelectEntity")
net.WriteEntity(v)
net.SendToServer()
end
entnodes[v].Label.OnCursorEntered = function()
HoveredEnt = v
end
entnodes[v].Label.OnCursorExited = function()
HoveredEnt = nil
end
MakeChildrenList(v, sorttable[v])
end
end
MakeChildrenList(parent, sortchildren)
end
local function RGMMakeBoneButtonPanel(cat, cpanel)
local parentpanel = vgui.Create("Panel", cat)
parentpanel:SetSize(100, 30)
cat:AddItem(parentpanel)
parentpanel.ShowAll = vgui.Create("DButton", parentpanel)
parentpanel.ShowAll:Dock(FILL)
parentpanel.ShowAll:SetZPos(0)
parentpanel.ShowAll:SetText("#tool.ragdollmover.listshowall")
parentpanel.ShowAll.DoClick = function()
local ent = LocalPlayer().rgm.Entity
if not IsValid(ent) or not IsValid(BonePanel) then return end
RGMBuildBoneMenu(ent, BonePanel)
end
parentpanel.ShowPhys = vgui.Create("DButton", parentpanel)
parentpanel.ShowPhys:Dock(LEFT)
parentpanel.ShowPhys:SetZPos(1)
parentpanel.ShowPhys:SetText("#tool.ragdollmover.listshowphys")
parentpanel.ShowPhys.DoClick = function()
local ent = LocalPlayer().rgm.Entity
if not IsValid(ent) or not IsValid(BonePanel) then return end
ShowOnlyPhysNodes(ent, BonePanel)
end
parentpanel.ShowNonphys = vgui.Create("DButton", parentpanel)
parentpanel.ShowNonphys:Dock(RIGHT)
parentpanel.ShowNonphys:SetZPos(1)
parentpanel.ShowNonphys:SetText("#tool.ragdollmover.listshownonphys")
parentpanel.ShowNonphys.DoClick = function()
local ent = LocalPlayer().rgm.Entity
if not IsValid(ent) or not IsValid(BonePanel) then return end
ShowOnlyNonPhysNodes(ent, BonePanel)
end
return parentpanel
end
function TOOL.BuildCPanel(CPanel)
@ -1245,6 +1636,7 @@ function TOOL.BuildCPanel(CPanel)
CB:SetToolTip("#tool.ragdollmover.unfreezetip")
local DisFil = CCheckBox(Col3, "#tool.ragdollmover.disablefilter","ragdollmover_disablefilter")
DisFil:SetToolTip("#tool.ragdollmover.disablefiltertip")
CCheckBox(Col3, "#tool.ragdollmover.drawskeleton", "ragdollmover_drawskeleton")
CNumSlider(Col3,"#tool.ragdollmover.updaterate","ragdollmover_updaterate",0.01,1.0,2)
CBinder(CPanel)
@ -1271,19 +1663,10 @@ function TOOL.BuildCPanel(CPanel)
Scale2 = CManipSlider(ColManip, "#tool.ragdollmover.scale2", 3, 2, -100, 100, 2) --y
Scale3 = CManipSlider(ColManip, "#tool.ragdollmover.scale3", 3, 3, -100, 100, 2) --z
CButton(Col4, "#tool.ragdollmover.resetbone", RGMResetBone)
CButton(Col4, "#tool.ragdollmover.resetscale", RGMResetScale)
CButton(Col4, "#tool.ragdollmover.scalezero", RGMScaleZero)
LockPosB = CButton(Col4, "#tool.ragdollmover.lockpos", RGMLockPBone, 1)
LockPosB:SetVisible(false)
LockRotB = CButton(Col4, "#tool.ragdollmover.lockang", RGMLockPBone, 2)
LockRotB:SetVisible(false)
CCheckBox(Col4,"#tool.ragdollmover.scalechildren","ragdollmover_scalechildren")
local colbones = CCol(Col4, "#tool.ragdollmover.bonelist")
RGMMakeBoneButtonPanel(colbones, CPanel)
BonePanel = vgui.Create("DTree", colbones)
BonePanel:SetTall(600)
AddHBar(BonePanel)
@ -1301,17 +1684,21 @@ end
local function UpdateManipulationSliders(boneid, ent)
if not IsValid(Pos1) then return end
Pos1:SetValue(ent:GetManipulateBonePosition(boneid)[1])
Pos2:SetValue(ent:GetManipulateBonePosition(boneid)[2])
Pos3:SetValue(ent:GetManipulateBonePosition(boneid)[3])
local pos, rot, scale = ent:GetManipulateBonePosition(boneid), ent:GetManipulateBoneAngles(boneid), ent:GetManipulateBoneScale(boneid)
rot:Normalize()
Rot1:SetValue(ent:GetManipulateBoneAngles(boneid)[1])
Rot2:SetValue(ent:GetManipulateBoneAngles(boneid)[2])
Rot3:SetValue(ent:GetManipulateBoneAngles(boneid)[3])
Pos1:SetValue(pos[1])
Pos2:SetValue(pos[2])
Pos3:SetValue(pos[3])
Rot1:SetValue(rot[1])
Rot2:SetValue(rot[2])
Rot3:SetValue(rot[3])
Scale1:SetValue(scale[1])
Scale2:SetValue(scale[2])
Scale3:SetValue(scale[3])
Scale1:SetValue(ent:GetManipulateBoneScale(boneid)[1])
Scale2:SetValue(ent:GetManipulateBoneScale(boneid)[2])
Scale3:SetValue(ent:GetManipulateBoneScale(boneid)[3])
end
net.Receive("rgmUpdateSliders", function(len)
@ -1355,7 +1742,7 @@ end)
net.Receive("rgmAskForPhysbonesResponse", function(len)
local count = net.ReadUInt(8)
for i = 0, count do
local bone = net.ReadUInt(32)
local bone = net.ReadUInt(8)
if bone then
nodes[bone].Type = BONE_PHYSICAL
nodes[bone]:SetIcon("icon16/brick.png")
@ -1393,25 +1780,12 @@ net.Receive("rgmLockBoneResponse", function(len)
nodes[boneid]:SetIcon("icon16/brick.png")
nodes[boneid].Label:SetToolTip("#tool.ragdollmover.physbone")
end
if nodes[boneid].poslock then
LockPosB:SetText("#tool.ragdollmover.unlockpos")
else
LockPosB:SetText("#tool.ragdollmover.lockpos")
end
if nodes[boneid].anglock then
LockRotB:SetText("#tool.ragdollmover.unlockang")
else
LockRotB:SetText("#tool.ragdollmover.lockang")
end
end)
net.Receive("rgmSelectBoneResponse", function(len)
local function SetVisiblePhysControls(bool)
local inverted = not bool
LockPosB:SetVisible(bool)
LockRotB:SetVisible(bool)
Pos1:SetVisible(inverted)
Pos2:SetVisible(inverted)
Pos3:SetVisible(inverted)
@ -1428,20 +1802,9 @@ net.Receive("rgmSelectBoneResponse", function(len)
UpdateManipulationSliders(boneid, ent)
end
if IsValid(LockPosB) and IsValid(LockRotB) and nodes then
if nodes then
if ent:GetClass() == "prop_ragdoll" and isphys and nodes[boneid] then
SetVisiblePhysControls(true)
if nodes[boneid].poslock then
LockPosB:SetText("#tool.ragdollmover.unlockpos")
else
LockPosB:SetText("#tool.ragdollmover.lockpos")
end
if nodes[boneid].anglock then
LockRotB:SetText("#tool.ragdollmover.unlockang")
else
LockRotB:SetText("#tool.ragdollmover.lockang")
end
else
SetVisiblePhysControls(false)
end
@ -1454,6 +1817,19 @@ net.Receive("rgmSelectBoneResponse", function(len)
end
end)
net.Receive("rgmAskForNodeUpdatePhysicsResponse", function(len)
local isphys = net.ReadBool()
local ent = net.ReadEntity()
local physIDs = {}
for i = 0, net.ReadUInt(8) do
physIDs[net.ReadUInt(8)] = true
end
if not IsValid(ent) or not IsValid(BonePanel) then return end
UpdateBoneNodes(ent, BonePanel, physIDs, isphys)
end)
local material = CreateMaterial("rgmGizmoMaterial", "UnlitGeneric", {
["$basetexture"] = "color/white",
["$model"] = 1,
@ -1502,14 +1878,21 @@ function TOOL:DrawHUD()
axis:DrawLines(scale,width)
cam.End()
end
if collision then return end
end
local tr = pl:GetEyeTrace()
local aimedbone = pl.rgm.AimedBone or 0
if IsValid(pl.rgm.Entity) and EntityFilter(pl.rgm.Entity) and HoveredBone then
rgm.DrawBoneName(pl.rgm.Entity,HoveredBone)
local aimedbone = IsValid(tr.Entity) and (tr.Entity:GetClass() == "prop_ragdoll" and pl.rgm.AimedBone or 0) or 0
if IsValid(ent) and EntityFilter(ent) and tobool(self:GetClientNumber("drawskeleton",0)) then
rgm.DrawSkeleton(ent)
end
if IsValid(ent) and EntityFilter(ent) and HoveredBone then
rgm.DrawBoneConnections(ent, HoveredBone)
rgm.DrawBoneName(ent,HoveredBone)
elseif IsValid(HoveredEnt) and EntityFilter(HoveredEnt) then
rgm.DrawEntName(HoveredEnt)
elseif IsValid(tr.Entity) and EntityFilter(tr.Entity) and (not bone or aimedbone ~= bone or tr.Entity ~= pl.rgm.Entity) and not moving then
rgm.DrawBoneConnections(tr.Entity, aimedbone)
rgm.DrawBoneName(tr.Entity,aimedbone)
end

View File

@ -37,6 +37,7 @@ tool.ragdollmover.unfreeze=Unfreeze on release.
tool.ragdollmover.unfreezetip=Unfreeze bones that were unfrozen before grabbing the ragdoll.
tool.ragdollmover.disablefilter=Disable entity filter.
tool.ragdollmover.disablefiltertip=Disable entity filter to select ANY entity. CAUTION - may be buggy
tool.ragdollmover.drawskeleton=Draw Skeleton
tool.ragdollmover.updaterate=Tool update rate.
tool.ragdollmover.bindrot=Rotate toggle button
@ -55,15 +56,32 @@ tool.ragdollmover.scale1=Scale X
tool.ragdollmover.scale2=Scale Y
tool.ragdollmover.scale3=Scale Z
tool.ragdollmover.resetbone=Reset Non-Physics Bone
tool.ragdollmover.resetscale=Reset Bone Scale
tool.ragdollmover.scalezero=Scale Bone to Zero
tool.ragdollmover.lockpos=Lock PhysBone Position
tool.ragdollmover.unlockpos=Unlock PhysBone Position
tool.ragdollmover.lockang=Lock PhysBone Rotation
tool.ragdollmover.unlockang=Unlock PhysBone Rotation
tool.ragdollmover.scalechildren=Scale children bones
tool.ragdollmover.resetmenu=Reset
tool.ragdollmover.resetpos=Position
tool.ragdollmover.resetrot=Rotation
tool.ragdollmover.resetscale=Scale
tool.ragdollmover.reset=All
tool.ragdollmover.resetposchildren=+Children Position
tool.ragdollmover.resetrotchildren=+Children Rotation
tool.ragdollmover.resetscalechildren=+Children Scale
tool.ragdollmover.resetchildren=+Children All
tool.ragdollmover.scalezero=Scale to Zero
tool.ragdollmover.bone=Bone
tool.ragdollmover.bonechildren=Bone + Children
tool.ragdollmover.lockpos=Lock Position
tool.ragdollmover.unlockpos=Unlock Position
tool.ragdollmover.lockang=Lock Rotation
tool.ragdollmover.unlockang=Unlock Rotation
tool.ragdollmover.putgizmopos=Put Gizmo offset here
tool.ragdollmover.bonelist=Bone List
tool.ragdollmover.listshowall=All
tool.ragdollmover.listshowphys=Phys
tool.ragdollmover.listshownonphys=Nonphys
tool.ragdollmover.entchildren=Entity Children
tool.ragdollmover.physbone=Physical Bone