Finally, an actually good unfake animation <3
This commit is contained in:
parent
4c4d59838a
commit
08bd3ecdf1
3 changed files with 256 additions and 80 deletions
|
|
@ -4,8 +4,6 @@ ENT.Type = "anim"
|
||||||
ENT.Base = "base_anim"
|
ENT.Base = "base_anim"
|
||||||
ENT.AutomaticFrameAdvance = true
|
ENT.AutomaticFrameAdvance = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local bones_to_animate = {
|
local bones_to_animate = {
|
||||||
"ValveBiped.Bip01_Pelvis",
|
"ValveBiped.Bip01_Pelvis",
|
||||||
"ValveBiped.Bip01_Spine2",
|
"ValveBiped.Bip01_Spine2",
|
||||||
|
|
@ -24,6 +22,15 @@ local bones_to_animate = {
|
||||||
"ValveBiped.Bip01_L_Hand",
|
"ValveBiped.Bip01_L_Hand",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Copy pasted directly from the GMOD wiki with small edits
|
||||||
|
local function SetRagdollPos(ragdoll, pos)
|
||||||
|
for i = 0, ragdoll:GetPhysicsObjectCount() - 1 do
|
||||||
|
local phys = ragdoll:GetPhysicsObjectNum(i)
|
||||||
|
local localPos = ragdoll:WorldToLocal( phys:GetPos() )
|
||||||
|
phys:SetPos(pos + localPos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function ENT:Initialize()
|
function ENT:Initialize()
|
||||||
if SERVER then
|
if SERVER then
|
||||||
print("I AM SERVERSIDE")
|
print("I AM SERVERSIDE")
|
||||||
|
|
@ -32,116 +39,92 @@ function ENT:Initialize()
|
||||||
|
|
||||||
if CLIENT then
|
if CLIENT then
|
||||||
print("I AM CLIENTSIDE")
|
print("I AM CLIENTSIDE")
|
||||||
timer.Simple(0.2, function()
|
|
||||||
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ENT:Draw()
|
function ENT:Think()
|
||||||
if CLIENT then
|
if CLIENT then
|
||||||
|
|
||||||
|
hook.Add("physics")
|
||||||
local old_ragdoll = self:GetNWEntity("parent")
|
local old_ragdoll = self:GetNWEntity("parent")
|
||||||
local old_npc = self:GetNWEntity("parent_npc")
|
local old_npc = self:GetNWEntity("parent_npc")
|
||||||
if IsValid(old_ragdoll) and IsValid(old_npc) then
|
if IsValid(old_ragdoll) and IsValid(old_npc) then
|
||||||
if !self.ready_to_unfake then
|
local ragdoll = self.ragdoll
|
||||||
self:SetModel(old_ragdoll:GetModel())
|
|
||||||
|
|
||||||
self.bone_list = {}
|
if !self.ready_to_animate then
|
||||||
self.bone_list_end = {}
|
self.ragdoll = ClientsideRagdoll(old_ragdoll:GetModel())
|
||||||
|
|
||||||
self:SetupBones()
|
|
||||||
|
|
||||||
local i = 0
|
ragdoll = self.ragdoll
|
||||||
while i < self:GetBoneCount() do
|
|
||||||
local name = self:GetBoneName(i)
|
|
||||||
if name == "__INVALIDBONE__" then
|
|
||||||
i = i + 1
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
|
|
||||||
table.insert(bones_to_animate, name)
|
self.ragdoll:SetNoDraw(false)
|
||||||
|
self.ragdoll:DrawShadow(true)
|
||||||
|
|
||||||
|
SetRagdollPos(self.ragdoll, old_ragdoll:GetPos())
|
||||||
local matrix = Matrix()
|
|
||||||
|
|
||||||
local position, angle = old_ragdoll:GetBonePosition(i)
|
|
||||||
if position == old_ragdoll:GetPos() then
|
|
||||||
get_matrix = old_ragdoll:GetBoneMatrix(i)
|
|
||||||
if get_matrix then
|
|
||||||
position = get_matrix:GetTranslation()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
matrix:Translate(position)
|
|
||||||
matrix:Rotate(angle)
|
|
||||||
|
|
||||||
self.bone_list[name] = matrix
|
print(self.ragdoll)
|
||||||
|
print("SHOW UP YOU PIECE OF SHIT")
|
||||||
|
|
||||||
local matrix = Matrix()
|
for i, name in pairs(bones_to_animate) do
|
||||||
|
local object = ragdoll:GetPhysicsObjectNum(ragdoll:TranslateBoneToPhysBone(ragdoll:LookupBone(name)))
|
||||||
|
local parent_object = old_ragdoll:GetBoneMatrix(old_ragdoll:LookupBone(name))
|
||||||
|
print(old_ragdoll)
|
||||||
|
|
||||||
local position, angle = old_npc:GetBonePosition(i)
|
--if !IsValid(parent_object) then continue end
|
||||||
if position == old_npc:GetPos() then
|
|
||||||
get_matrix = old_npc:GetBoneMatrix(i)
|
|
||||||
if get_matrix then
|
|
||||||
position = get_matrix:GetTranslation()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
matrix:Translate(position)
|
|
||||||
matrix:Rotate(angle)
|
|
||||||
|
|
||||||
|
|
||||||
self.bone_list_end[name] = matrix
|
object:SetPos(parent_object:GetTranslation())
|
||||||
|
object:SetAngles(parent_object:GetAngles())
|
||||||
i = i + 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
PrintTable(bones_to_animate)
|
self.ready_to_animate = true
|
||||||
|
|
||||||
--[[for i,name in pairs(bones_to_animate) do
|
|
||||||
local bone_index = old_ragdoll:LookupBone(name)
|
|
||||||
if bone_index == nil then continue end
|
|
||||||
|
|
||||||
self.bone_list[name] = Matrix(old_ragdoll:GetBoneMatrix(bone_index))
|
|
||||||
end]]
|
|
||||||
|
|
||||||
print("BONES:"..self:GetBoneCount())
|
|
||||||
|
|
||||||
self.ready_to_unfake = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local fake_start = self:GetNWFloat("fake_start")
|
||||||
|
local fake_end = self:GetNWFloat("fake_end")
|
||||||
|
|
||||||
self:SetPos(old_ragdoll:GetPos())
|
local progress = (CurTime() - fake_start) / (fake_end - fake_start)
|
||||||
|
|
||||||
self:SetupBones()
|
for i, name in pairs(bones_to_animate) do
|
||||||
|
local object = ragdoll:GetPhysicsObjectNum(ragdoll:TranslateBoneToPhysBone(ragdoll:LookupBone(name)))
|
||||||
|
local parent_bone = old_npc:LookupBone(name)
|
||||||
|
|
||||||
for name,matrix in pairs(self.bone_list) do
|
if parent_bone == -1 then continue end
|
||||||
local bone_index = self:LookupBone(name)
|
|
||||||
if bone_index == -1 then
|
|
||||||
print(name.." does not exist, skipping...")
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
|
|
||||||
|
local parent_bone_matrix = old_npc:GetBoneMatrix(parent_bone)
|
||||||
|
if !parent_bone_matrix then continue end
|
||||||
|
|
||||||
--print(name)
|
local parent_bone_pos, parent_bone_angle = parent_bone_matrix:GetTranslation(), parent_bone_matrix:GetAngles()
|
||||||
--local bone_matrix = old_ragdoll:GetBoneMatrix(bone_index)
|
local old_bone_pos, old_bone_angle = object:GetPos(), object:GetAngles()
|
||||||
|
--parent_bone_angle.y = parent_bone_angle.y + 90
|
||||||
|
|
||||||
if matrix:GetTranslation():DistToSqr(self:GetPos()) == 1 then continue end
|
local shadow_data = {
|
||||||
|
secondstoarrive = 0.01,
|
||||||
|
pos = LerpVector(progress, old_bone_pos, parent_bone_pos),
|
||||||
|
angle = LerpAngle(progress, old_bone_angle, parent_bone_angle),
|
||||||
|
maxspeed = 400 * 4,
|
||||||
|
maxangular = 2000 * 4,
|
||||||
|
maxspeeddamp = 120 * 4,
|
||||||
|
maxangularspeeddamp = 600 * 4,
|
||||||
|
}
|
||||||
|
|
||||||
self:SetBoneMatrix(bone_index, matrix)
|
-- Can't set position inside physics tick, crashes the game instantly.
|
||||||
|
-- Instead, send a shadow for it to follow (I think? I don't know GMod is kinda funky)
|
||||||
|
object:ComputeShadowControl(shadow_data)
|
||||||
|
|
||||||
|
object:Wake()
|
||||||
|
|
||||||
|
--i = i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:DrawModel()
|
self:NextThink(CurTime() + 0.1)
|
||||||
end
|
|
||||||
|
|
||||||
function ENT:Think()
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function ENT:OnRemove()
|
function ENT:OnRemove()
|
||||||
if CLIENT then
|
if CLIENT then
|
||||||
--[[if self.anim_ragdoll then
|
if self.ragdoll then
|
||||||
self.anim_ragdoll:Remove()
|
self.ragdoll:Remove()
|
||||||
end]]
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
191
lua/entities/v4.old
Normal file
191
lua/entities/v4.old
Normal file
|
|
@ -0,0 +1,191 @@
|
||||||
|
AddCSLuaFile()
|
||||||
|
|
||||||
|
ENT.Type = "anim"
|
||||||
|
ENT.Base = "base_anim"
|
||||||
|
ENT.AutomaticFrameAdvance = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local bones_to_animate = {
|
||||||
|
"ValveBiped.Bip01_Pelvis",
|
||||||
|
"ValveBiped.Bip01_Spine2",
|
||||||
|
"ValveBiped.Bip01_Head1",
|
||||||
|
"ValveBiped.Bip01_R_Thigh",
|
||||||
|
"ValveBiped.Bip01_L_Thigh",
|
||||||
|
"ValveBiped.Bip01_L_Calf",
|
||||||
|
"ValveBiped.Bip01_R_Calf",
|
||||||
|
"ValveBiped.Bip01_R_Foot",
|
||||||
|
"ValveBiped.Bip01_L_Foot",
|
||||||
|
"ValveBiped.Bip01_R_Upperarm",
|
||||||
|
"ValveBiped.Bip01_L_Upperarm",
|
||||||
|
"ValveBiped.Bip01_R_Forearm",
|
||||||
|
"ValveBiped.Bip01_L_Forearm",
|
||||||
|
"ValveBiped.Bip01_R_Hand",
|
||||||
|
"ValveBiped.Bip01_L_Hand",
|
||||||
|
}
|
||||||
|
|
||||||
|
local function GetBoneLocalOffsetMatrix(ent, bone_index)
|
||||||
|
local parent = ent:GetBoneParent(bone_index)
|
||||||
|
local parent_matrix = Matrix(ent:GetBoneMatrix(parent))
|
||||||
|
parent_matrix:Invert()
|
||||||
|
parent_matrix:Mul(ent:GetBoneMatrix(bone_index))
|
||||||
|
|
||||||
|
return parent_matrix
|
||||||
|
end
|
||||||
|
|
||||||
|
local function GetGlobalMatrixFromLocal(ent, bone_index, local_matrix)
|
||||||
|
local parent = ent:GetBoneParent(bone_index)
|
||||||
|
local parent_matrix = Matrix(ent:GetBoneMatrix(parent))
|
||||||
|
parent_matrix:Mul(local_matrix)
|
||||||
|
|
||||||
|
return parent_matrix
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Initialize()
|
||||||
|
if SERVER then
|
||||||
|
print("I AM SERVERSIDE")
|
||||||
|
self:SetModel("models/dav0r/hoverball.mdl")
|
||||||
|
end
|
||||||
|
|
||||||
|
if CLIENT then
|
||||||
|
print("I AM CLIENTSIDE")
|
||||||
|
timer.Simple(0.2, function()
|
||||||
|
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Draw()
|
||||||
|
if CLIENT then
|
||||||
|
local old_ragdoll = self:GetNWEntity("parent")
|
||||||
|
local old_npc = self:GetNWEntity("parent_npc")
|
||||||
|
if IsValid(old_ragdoll) and IsValid(old_npc) then
|
||||||
|
if !self.ready_to_unfake then
|
||||||
|
self:SetModel(old_ragdoll:GetModel())
|
||||||
|
|
||||||
|
self.bone_list = {}
|
||||||
|
self.bone_list_end = {}
|
||||||
|
self.bone_list_end_offset = {}
|
||||||
|
|
||||||
|
self:SetupBones()
|
||||||
|
|
||||||
|
local i = 0
|
||||||
|
while i < self:GetBoneCount() do
|
||||||
|
local name = self:GetBoneName(i)
|
||||||
|
if name == "__INVALIDBONE__" then
|
||||||
|
i = i + 1
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(bones_to_animate, name)
|
||||||
|
|
||||||
|
local matrix = Matrix()
|
||||||
|
|
||||||
|
local position, angle = old_ragdoll:GetBonePosition(i)
|
||||||
|
if position == old_ragdoll:GetPos() then
|
||||||
|
get_matrix = old_ragdoll:GetBoneMatrix(i)
|
||||||
|
if get_matrix then
|
||||||
|
position = get_matrix:GetTranslation()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
matrix:Translate(position)
|
||||||
|
matrix:Rotate(angle)
|
||||||
|
|
||||||
|
self.bone_list[name] = matrix
|
||||||
|
|
||||||
|
local matrix = Matrix()
|
||||||
|
|
||||||
|
local npc_bone_index = old_npc:LookupBone(name)
|
||||||
|
|
||||||
|
local position, angle = old_npc:GetBonePosition(npc_bone_index)
|
||||||
|
if position == old_npc:GetPos() then
|
||||||
|
print("DINGUS!!!! "..name)
|
||||||
|
self.bone_list_end_offset[name] = GetBoneLocalOffsetMatrix(self, npc_bone_index)
|
||||||
|
|
||||||
|
get_matrix = old_npc:GetBoneMatrix(npc_bone_index)
|
||||||
|
if get_matrix then
|
||||||
|
position = get_matrix:GetTranslation()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
matrix:Translate(position)
|
||||||
|
matrix:Rotate(angle)
|
||||||
|
|
||||||
|
|
||||||
|
self.bone_list_end[name] = matrix
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
PrintTable(bones_to_animate)
|
||||||
|
|
||||||
|
--[[for i,name in pairs(bones_to_animate) do
|
||||||
|
local bone_index = old_ragdoll:LookupBone(name)
|
||||||
|
if bone_index == nil then continue end
|
||||||
|
|
||||||
|
self.bone_list[name] = Matrix(old_ragdoll:GetBoneMatrix(bone_index))
|
||||||
|
end]]
|
||||||
|
|
||||||
|
print("BONES:"..self:GetBoneCount())
|
||||||
|
|
||||||
|
self.ready_to_unfake = true
|
||||||
|
end
|
||||||
|
|
||||||
|
self:SetPos(old_ragdoll:GetPos())
|
||||||
|
|
||||||
|
self:SetupBones()
|
||||||
|
|
||||||
|
local fake_start = self:GetNWFloat("fake_start")
|
||||||
|
local fake_end = self:GetNWFloat("fake_end")
|
||||||
|
|
||||||
|
local progress = (CurTime() - fake_start) / (fake_end - fake_start)
|
||||||
|
|
||||||
|
for name,matrix in pairs(self.bone_list) do
|
||||||
|
local bone_index = self:LookupBone(name)
|
||||||
|
if bone_index == -1 then
|
||||||
|
print(name.." does not exist, skipping...")
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
local matrix_end = self.bone_list_end[name]
|
||||||
|
|
||||||
|
if matrix_end == nil then
|
||||||
|
if (self.bone_list_end_offset[name] == nil) then
|
||||||
|
print("OH FUCKKKKKKKK! No matrix end for "..name)
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
matrix_end = GetGlobalMatrixFromLocal(self, bone_index, self.bone_list_end_offset[name])
|
||||||
|
end
|
||||||
|
|
||||||
|
local final_matrix = Matrix()
|
||||||
|
final_matrix:Translate(LerpVector(progress, matrix:GetTranslation(), matrix_end:GetTranslation()))
|
||||||
|
final_matrix:Rotate(LerpAngle(progress, matrix:GetAngles(), matrix_end:GetAngles()))
|
||||||
|
|
||||||
|
--print(name)
|
||||||
|
--local bone_matrix = old_ragdoll:GetBoneMatrix(bone_index)
|
||||||
|
|
||||||
|
if matrix:GetTranslation():DistToSqr(self:GetPos()) == 1 then continue end
|
||||||
|
|
||||||
|
self:SetBoneMatrix(bone_index, final_matrix)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:DrawModel()
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:Think()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function ENT:OnRemove()
|
||||||
|
if CLIENT then
|
||||||
|
--[[if self.anim_ragdoll then
|
||||||
|
self.anim_ragdoll:Remove()
|
||||||
|
end]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -494,6 +494,8 @@ function MODULE:PhysicsSimulate(phys, dt)
|
||||||
self.unfaker:SetPos(target:GetPos())
|
self.unfaker:SetPos(target:GetPos())
|
||||||
self.unfaker:SetNWEntity("parent", target)
|
self.unfaker:SetNWEntity("parent", target)
|
||||||
self.unfaker:SetNWEntity("parent_npc", ent)
|
self.unfaker:SetNWEntity("parent_npc", ent)
|
||||||
|
self.unfaker:SetNWFloat("fake_start", self.FakeUpStart)
|
||||||
|
self.unfaker:SetNWFloat("fake_end", self.FakeUpEnd)
|
||||||
|
|
||||||
|
|
||||||
target:SetRenderMode(RENDERMODE_NONE)
|
target:SetRenderMode(RENDERMODE_NONE)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue