The animations I was given to work with had the bone structure incorrectly set up, resulting in some slightly messed up animations when combining multiple at once. (A sword swing while walking)
Our animator isn’t available to fix it and I decided I’d try and figure out the math to fix it myself. Turns out it’s a bit harder then I thought. After writing everything up I realized CFrames were a lot more complicated then I thought.
I figured out they aren’t communitive.
I can almost explain what each of the elements in the CFrame represent, I can do the math to combine them, and I understand combining them is assuming the 1st CFrame is effectively the new world origin that the 2nd CFrame traverses through.
It’s still just a bit to complicated to wrap my head around I’m struggling to fix the issues with my code. I keep trying to simplify it in my head, but when I do I lose the necessary complexity added by rotation.
FixPoseRecursive = function(OldPose, NewPose, NewModelNode, NewParentHRPOffset)
NewParentHRPOffset = NewParentHRPOffset and NewParentHRPOffset or CFrame.new()
local OldModelNode = NewModelNode.Link
--| Get CFrame in HRP's Space of the Object in the OldPose
local TotalOffset = CFrame.new()
local Current = OldModelNode
--| Head up through the ancestors calculating total offset as you go
while Current.Parent do
local Bone = Current.Motor6D
local OldPoseLink = OldPose:FindFirstChild(Current.Value.Name, true)
TotalOffset = TotalOffset * Bone.C0 * OldPoseLink.CFrame * Bone.C1:Inverse()
Current = Current.Parent
end
local HumanoidRootPartOffset = TotalOffset
--| Find HRP Offset needed for the NewPose Object to equal the old pose HRP offset
local ObjectOffset = NewParentHRPOffset * NewModelNode.Motor6D.C0 * NewModelNode.Motor6D.C1:Inverse()
local OffsetDifference = ObjectOffset:Inverse() * TotalOffset
--| Set the new pose's value
CopyPoseInfo(OldPose:FindFirstChild(NewPose.Name, true), NewPose)
NewPose.CFrame = OffsetDifference
--| Handle Children
for _, Child in ipairs(NewPose:GetChildren()) do
FixPoseRecursive(OldPose, Child, NewModelNode.Children[Child.Name], TotalOffset)
end
end
Perameters
- OldPose is always the HRP Pose for the old bone structure
- NewPose is a ChildPose of the New Structure set up previously, It’s recursively searched depth first.
- New Model Node was a Tree ADT I set up, It’s structure is identical to the Fixed Pose’s structure, just has useful links to motor6Ds and the old model’s structure.
- NewParentHRPOffset Is the offset I calculated in the previous step, It’s not calculated correctly but it’s intended to be the Parent’s - (In terms of the bone structure); HRP offset for the current keyframe.
HRP is humanoid root part
Just calculating the OldHRPOffset for a direct child of the HRP results is a offset that is off by a bit (About most 0.005) I assume this is just precision lost from complex math, I don’t see how there can be an error at that stage but I’m not sure.
Here’s what it looks like:
Here’s what it’s supposed to look like:
I’d be faster at this point to just go into blender and learn how to re-wire the bones myself, I’ve seen it’s doable there. I’m just so far in I have to finish it this way, I plan to give this out as a community resource once it’s fixed.


