mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
328
lua/pac3/core/client/parts/bone.lua
Normal file
328
lua/pac3/core/client/parts/bone.lua
Normal file
@@ -0,0 +1,328 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
local NULL = NULL
|
||||
local pairs = pairs
|
||||
local Matrix = Matrix
|
||||
local vector_origin = vector_origin
|
||||
local Vector = Vector
|
||||
local Angle = Angle
|
||||
|
||||
for _, v in pairs(ents.GetAll()) do
|
||||
v.pac_bone_setup_data = nil
|
||||
end
|
||||
|
||||
local BUILDER, PART = pac.PartTemplate("base_movable")
|
||||
|
||||
PART.FriendlyName = "bone"
|
||||
PART.ClassName = "bone3"
|
||||
PART.Groups = {'entity', 'model'}
|
||||
PART.Icon = 'icon16/connect.png'
|
||||
PART.is_bone_part = true
|
||||
|
||||
BUILDER:StartStorableVars()
|
||||
BUILDER:SetPropertyGroup("generic")
|
||||
BUILDER:PropertyOrder("Name")
|
||||
BUILDER:PropertyOrder("Hide")
|
||||
BUILDER:PropertyOrder("ParentName")
|
||||
BUILDER:GetSet("ScaleChildren", false)
|
||||
BUILDER:GetSet("MoveChildrenToOrigin", false)
|
||||
BUILDER:GetSet("FollowAnglesOnly", false)
|
||||
BUILDER:GetSet("HideMesh", false)
|
||||
BUILDER:GetSet("InvertHideMesh", false)
|
||||
BUILDER:GetSetPart("FollowPart")
|
||||
|
||||
BUILDER:SetPropertyGroup("orientation")
|
||||
BUILDER:PropertyOrder("AimPartName")
|
||||
BUILDER:PropertyOrder("Bone")
|
||||
BUILDER:PropertyOrder("Position")
|
||||
BUILDER:PropertyOrder("Angles")
|
||||
BUILDER:PropertyOrder("EyeAngles")
|
||||
BUILDER:GetSet("Size", 1, {editor_sensitivity = 0.25})
|
||||
BUILDER:GetSet("Scale", Vector(1,1,1), {editor_sensitivity = 0.25})
|
||||
BUILDER:PropertyOrder("PositionOffset")
|
||||
BUILDER:PropertyOrder("AngleOffset")
|
||||
|
||||
BUILDER:SetPropertyGroup("appearance")
|
||||
|
||||
BUILDER:SetPropertyGroup("other")
|
||||
BUILDER:PropertyOrder("DrawOrder")
|
||||
|
||||
BUILDER:EndStorableVars()
|
||||
|
||||
function PART:GetNiceName()
|
||||
return self:GetBone()
|
||||
end
|
||||
|
||||
function PART:SetBone(val)
|
||||
self.Bone = val
|
||||
self.bone_index = self:GetModelBoneIndex(self.Bone)
|
||||
end
|
||||
|
||||
function PART:OnShow()
|
||||
self:SetBone(self:GetBone())
|
||||
|
||||
local ent = self:GetOwner()
|
||||
if not ent:IsValid() then return end
|
||||
|
||||
ent.pac_bone_parts = ent.pac_bone_parts or {}
|
||||
if not table.HasValue(ent.pac_bone_parts, self) then
|
||||
table.insert(ent.pac_bone_parts, self)
|
||||
end
|
||||
|
||||
if ent.pac_build_bone_id then
|
||||
ent:RemoveCallback("BuildBonePositions", ent.pac_build_bone_id)
|
||||
end
|
||||
|
||||
local id
|
||||
id = ent:AddCallback("BuildBonePositions", function(ent, ...)
|
||||
if not self:IsValid() or not ent.pac_bone_parts or not ent.pac_bone_parts[1] then
|
||||
ent:RemoveCallback("BuildBonePositions", id)
|
||||
return
|
||||
end
|
||||
|
||||
for _, bone in ipairs(ent.pac_bone_parts) do
|
||||
bone:BuildBonePositions2(ent)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
ent.pac_build_bone_id = id
|
||||
end
|
||||
|
||||
function PART:OnParent()
|
||||
self:OnShow()
|
||||
end
|
||||
|
||||
function PART:OnHide()
|
||||
local ent = self:GetOwner()
|
||||
if not ent:IsValid() then return end
|
||||
|
||||
if ent.pac_bone_parts then
|
||||
for i,v in ipairs(ent.pac_bone_parts) do
|
||||
if v == self then
|
||||
table.remove(ent.pac_bone_parts, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local inf_scale = Vector(math.huge, math.huge, math.huge)
|
||||
|
||||
local function get_children_bones(ent, root_index, bone_count, out)
|
||||
ent:SetLOD(0)
|
||||
for child_index = 0, bone_count - 1 do
|
||||
if ent:GetBoneParent(child_index) == root_index then
|
||||
if ent:GetBoneMatrix(child_index) then
|
||||
table.insert(out, child_index)
|
||||
end
|
||||
get_children_bones(ent, child_index, bone_count, out)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_children_bones_cached(ent, root_index)
|
||||
ent.pac_cached_child_bones = ent.pac_cached_child_bones or {}
|
||||
|
||||
if not ent.pac_cached_child_bones[root_index] then
|
||||
ent.pac_cached_child_bones[root_index] = {}
|
||||
get_children_bones(ent, root_index, ent:GetBoneCount(), ent.pac_cached_child_bones[root_index])
|
||||
end
|
||||
|
||||
return ent.pac_cached_child_bones[root_index]
|
||||
end
|
||||
|
||||
local function scale_children(ent, root_index, bone_count, scale, move_to_origin)
|
||||
for child_index = 0, bone_count - 1 do
|
||||
if ent:GetBoneParent(child_index) == root_index then
|
||||
local m = ent:GetBoneMatrix(child_index)
|
||||
|
||||
if m then
|
||||
if move_to_origin then
|
||||
m:SetTranslation(move_to_origin)
|
||||
end
|
||||
|
||||
m:Scale(scale)
|
||||
ent:SetBoneMatrix(child_index, m)
|
||||
end
|
||||
|
||||
scale_children(ent, child_index, bone_count, scale, move_to_origin)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local temp_matrix_1 = Matrix()
|
||||
local temp_matrix_2 = Matrix()
|
||||
local temp_vector = Vector()
|
||||
local temp_vector_2 = Vector()
|
||||
local temp_angle = Angle()
|
||||
|
||||
local function temp_vector_add(a, b)
|
||||
temp_vector:Set(a)
|
||||
temp_vector:Add(b)
|
||||
return temp_vector
|
||||
end
|
||||
|
||||
local function temp_vector_scale(a, b)
|
||||
temp_vector_2:Set(a)
|
||||
temp_vector_2:Mul(b)
|
||||
return temp_vector_2
|
||||
end
|
||||
|
||||
|
||||
local function temp_angle_add(a, b)
|
||||
temp_angle:Set(a)
|
||||
temp_angle:Add(b)
|
||||
return temp_angle
|
||||
end
|
||||
|
||||
function PART:BuildBonePositions2(ent)
|
||||
local index = self.bone_index
|
||||
|
||||
if not index then return end
|
||||
|
||||
local world_matrix = ent:GetBoneMatrix(index)
|
||||
|
||||
if not world_matrix then return end
|
||||
|
||||
temp_matrix_2:Set(world_matrix)
|
||||
local unmodified_world_matrix = temp_matrix_2
|
||||
|
||||
self.bone_matrix = self.bone_matrix or Matrix()
|
||||
self.bone_matrix:Set(unmodified_world_matrix)
|
||||
|
||||
if self.FollowPart:IsValid() and self.FollowPart.GetWorldPosition then
|
||||
local pos, ang
|
||||
if self.FollowPart.ClassName == "jiggle" then
|
||||
pos = self.FollowPart.pos
|
||||
ang = self.FollowPart.ang
|
||||
else
|
||||
pos = self.FollowPart:GetWorldPosition()
|
||||
ang = self.FollowPart:GetWorldAngles()
|
||||
end
|
||||
|
||||
if not self.FollowAnglesOnly then
|
||||
world_matrix:SetTranslation(pos)
|
||||
end
|
||||
|
||||
world_matrix:SetAngles(temp_angle_add(ang, self.AngleOffset))
|
||||
world_matrix:Rotate(self.Angles)
|
||||
else
|
||||
world_matrix:Translate(temp_vector_add(self.Position, self.PositionOffset))
|
||||
world_matrix:Rotate(temp_angle_add(self.Angles, self.AngleOffset))
|
||||
end
|
||||
|
||||
local scale = temp_vector_scale(self.Scale, self.Size)
|
||||
|
||||
if self.ScaleChildren or self.MoveChildrenToOrigin then
|
||||
local scale_origin = self.MoveChildrenToOrigin and unmodified_world_matrix:GetTranslation()
|
||||
|
||||
for _, child_index in ipairs(get_children_bones_cached(ent, index)) do
|
||||
local world_matrix = ent:GetBoneMatrix(child_index)
|
||||
if not world_matrix then continue end
|
||||
|
||||
if scale_origin then
|
||||
world_matrix:SetTranslation(scale_origin)
|
||||
end
|
||||
|
||||
if self.ScaleChildren then
|
||||
world_matrix:Scale(scale)
|
||||
end
|
||||
|
||||
ent:SetBoneMatrix(child_index, world_matrix)
|
||||
end
|
||||
end
|
||||
|
||||
local parent_world_matrix = world_matrix
|
||||
unmodified_world_matrix:Invert()
|
||||
local last_inverted_world_matrix = unmodified_world_matrix
|
||||
|
||||
for _, child_index in ipairs(get_children_bones_cached(ent, index)) do
|
||||
local child_world_matrix = ent:GetBoneMatrix(child_index)
|
||||
if not child_world_matrix then continue end
|
||||
|
||||
temp_matrix_1:Set(parent_world_matrix)
|
||||
temp_matrix_1:Mul(last_inverted_world_matrix)
|
||||
temp_matrix_1:Mul(child_world_matrix)
|
||||
|
||||
local world_matrix = temp_matrix_1
|
||||
|
||||
ent:SetBoneMatrix(child_index, world_matrix)
|
||||
|
||||
parent_world_matrix = world_matrix
|
||||
|
||||
child_world_matrix:Invert()
|
||||
last_inverted_world_matrix = child_world_matrix
|
||||
end
|
||||
|
||||
world_matrix:Scale(scale)
|
||||
|
||||
ent:SetBoneMatrix(index, world_matrix)
|
||||
|
||||
if self.HideMesh then
|
||||
local inf_scale = inf_scale
|
||||
|
||||
if ent.GetRagdollEntity and ent:GetRagdollEntity():IsValid() then
|
||||
inf_scale = vector_origin
|
||||
end
|
||||
|
||||
ent.pac_inf_scale = true
|
||||
|
||||
if self.InvertHideMesh then
|
||||
local count = ent:GetBoneCount()
|
||||
|
||||
for i = 0, count - 1 do
|
||||
if i ~= index then
|
||||
ent:ManipulateBoneScale(i, inf_scale)
|
||||
end
|
||||
end
|
||||
else
|
||||
ent:ManipulateBoneScale(index, inf_scale)
|
||||
end
|
||||
else
|
||||
ent.pac_inf_scale = false
|
||||
end
|
||||
end
|
||||
|
||||
function PART:GetBonePosition()
|
||||
local ent = self:GetOwner()
|
||||
|
||||
if not ent:IsValid() then return Vector(), Angle() end
|
||||
|
||||
if not self.bone_index then return ent:GetPos(), ent:GetAngles() end
|
||||
|
||||
local m = ent:GetBoneMatrix(self.bone_index)
|
||||
if not m then return ent:GetPos(), ent:GetAngles() end
|
||||
|
||||
local pos = m:GetTranslation()
|
||||
local ang = m:GetAngles()
|
||||
|
||||
return pos, ang
|
||||
end
|
||||
|
||||
function PART:GetBoneMatrix()
|
||||
return self.bone_matrix or Matrix()
|
||||
end
|
||||
|
||||
BUILDER:Register()
|
||||
|
||||
pac.AddHook("OnEntityCreated", "hide_mesh_no_crash", function(ent)
|
||||
local ply = ent:GetRagdollOwner()
|
||||
if ply:IsPlayer() and ply.pac_inf_scale then
|
||||
for i = 0, ply:GetBoneCount() - 1 do
|
||||
local scale = ply:GetManipulateBoneScale(i)
|
||||
if scale == inf_scale then
|
||||
scale = Vector(0,0,0)
|
||||
end
|
||||
ply:ManipulateBoneScale(i, scale)
|
||||
end
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user