How to create a rigid ragdoll with similar pose to a player?
1 replies, posted
I would like to create a rigid ragdoll in the same position as a player, with a similar position and pose. I was previously attempting to make the ragdoll rigid by modified code from this old tool that moved ragdolls without changing their pose, but to no avail.
[CODE]TOOL.AddToMenu = false
TOOL.Category = "Poser"
TOOL.Name = "#Statue"
TOOL.Command = nil
TOOL.ConfigName = nil
TOOL.ClientConVar[ "unfreeze" ] = "1"
function TOOL:LeftClick( trace )
if (!trace.Entity) then return false end
if (!trace.Entity:IsValid()) then return false end
if (trace.Entity:IsPlayer()) then return false end
if (trace.Entity:GetClass() != "prop_ragdoll" ) then return false end
if ( CLIENT ) then return true end
if (trace.Entity:GetPhysicsObjectCount() < 2 ) then return false end
local ent = trace.Entity
local unfreeze = utilx.tobool( self:GetClientNumber( "unfreeze" ) )
// If it already has a StatueInfo table then it's already statued
if ( ent:GetTable().StatueInfo != nil ) then return false end
ent:GetTable().StatueInfo = {}
ent:GetTable().StatueInfo.Welds = {}
local bones = ent:GetPhysicsObjectCount()
local forcelimit = 0
// Weld each physics object together
for bone=1, bones do
local bone1 = bone - 1
local bone2 = bones - bone
// Don't do identical two welds
if ( !ent:GetTable().StatueInfo.Welds[bone2] ) then
local constraint1 = constraint.Weld( ent, ent, bone1, bone2, forcelimit )
if ( constraint1 ) then
ent:GetTable().StatueInfo.Welds[bone1] = constraint1
self:GetOwner():AddCleanup( "constraints", constraint1 )
end
end
local constraint2 = constraint.Weld( ent, ent, bone1, 0, forcelimit )
if ( constraint2 ) then
ent:GetTable().StatueInfo.Welds[bone1+bones] = constraint2
self:GetOwner():AddCleanup( "constraints", constraint2 )
end
local effectdata = EffectData()
effectdata:SetOrigin( ent:GetPhysicsObjectNum( bone1 ):GetPos() )
effectdata:SetScale( 1 )
effectdata:SetMagnitude( 1 )
util.Effect( "GlassImpact", effectdata, true, true )
end
if ( unfreeze == true ) then
for bone=1,bones do
local bone1 = bone - 1
ent:GetPhysicsObjectNum( bone1 ):EnableMotion( true )
ent:GetPhysicsObjectNum( bone1 ):Wake()
end
end
return true
end
function TOOL:RightClick( trace )
if (!trace.Entity) then return end
if (!trace.Entity:IsValid()) then return end
if (trace.Entity:IsPlayer()) then return end
if (trace.Entity:GetClass() != "prop_ragdoll" ) then return false end
if ( CLIENT ) then return true end
if (trace.Entity:GetPhysicsObjectCount() < 2 ) then return false end
if (trace.Entity:GetTable().StatueInfo == nil ) then return false end
local ent = trace.Entity
// Remove each weld
for key, val in pairs (ent:GetTable().StatueInfo.Welds) do
if ( val && val:IsValid() ) then val:Remove() end
end
// Delete the statue table - it's no longer a statue
ent:GetTable().StatueInfo = nil
local bones = ent:GetPhysicsObjectCount()
for bone=1, bones do
local bone1 = bone - 1
local effectdata = EffectData()
effectdata:SetOrigin( ent:GetPhysicsObjectNum( bone1 ):GetPos() )
effectdata:SetScale( 1 )
effectdata:SetMagnitude( 1 )
util.Effect( "WheelDust", effectdata, true, true )
end
return true
end
[/CODE]
I was wondering if there was any relatively simple solution to this quandry, and if not, I can simply fall back on attempting to create constraints between the bones of the ragdoll. Thanks!
I don't know how much access we have to a player's playermodel's pose, but here is some code I used to duplicate a server-side ragdoll to a client-side ragdoll, before I learned of [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Entity/BecomeRagdollOnClient]Entity:BecomeRagdollOnClient[/url] which did 90% of the work for me.
[lua]local csrag = ClientsideRagdoll(ent:GetModel(), ent:GetRenderGroup())
csrag:SetPos(ent:GetPos())
csrag:SetAngles(ent:GetAngles())
for b = 0, csrag:GetPhysicsObjectCount()-1 do
csrag:GetPhysicsObjectNum(b):SetPos(ent:GetPhysicsObjectNum(b):GetPos())
csrag:GetPhysicsObjectNum(b):SetAngles(ent:GetPhysicsObjectNum(b):GetAngles())
csrag:GetPhysicsObjectNum(b):EnableMotion(false)
end
csrag:SetNoDraw(false) -- why the fuck is it true by default?
-- for bone = 0, ent:GetBoneCount()-1 do
-- csrag:SetBonePosition(bone, ent:GetBonePosition(bone)) -- does both position and angles :)
-- end
for bone = 0, ent:GetBoneCount()-1 do
csrag:ManipulateBoneAngles(bone, ent:GetManipulateBoneAngles(bone))
csrag:ManipulateBonePosition(bone, ent:GetManipulateBonePosition(bone))
csrag:ManipulateBoneJiggle(bone, ent:GetManipulateBoneJiggle(bone))
csrag:ManipulateBoneScale(bone, ent:GetManipulateBoneScale(bone))
end
csrag:SetupBones()
-- csrag:GetPhysicsObject():Sleep()[/lua]
I don't remember how it works, why it works, what exactly each part does, or anything. You'll have to figure that out yourself. What I DO remember is that face-posing doesn't work because clientside ragdolls don't support flex, but if you're adapting this to server-side ragdolls, add some code to copy over the flex values with [img]http://wiki.garrysmod.com/favicon.ico[/img] [url=http://wiki.garrysmod.com/page/Entity/SetFlexWeight]Entity:SetFlexWeight[/url] and related functions.
Edit: wait, is your problem about creating and positioning the ragdoll, or just making it rigid? As far as rigidness goes, I'm pretty sure that there's no way to do it other than making lots of welds. See the 'Statue' source code: [url]https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/autorun/properties/statue.lua[/url]
Sorry, you need to Log In to post a reply to this thread.