I understand that it would be easier to figure it out with a place file. So I’m looking into my development file for the second iteration of my hair library.
I almost had it but what has me scratching my head is how do I appropriately add the calculation.
Given just the rotational elements of the bone
function Class.new(Bone: Bone, RootBone: Bone, RootPart: BasePart): IBone
local ParentCFrame = Bone.Parent:IsA("Bone") and Bone.Parent.TransformedWorldCFrame or RootPart.CFrame
local InitialOrientation=CFrame.new(0,0,0)
if Bone~=RootBone then
InitialOrientation=Bone.CFrame-Bone.CFrame.Position
end
end
local self = setmetatable({
Bone = Bone,
FreeLength = -1,
Weight = 0.7,
ParentIndex = -1,
HeirarchyLength = 0,
--etc
TransformCFrame=InitialOrientation
AnimatedWorldCFrame = Bone.TransformedWorldCFrame,
StartingCFrame = Bone.TransformedCFrame,
TransformOffset = CFrame.identity,
LocalTransformOffset = CFrame.identity,
RestPosition = Vector3.zero,
CalculatedWorldCFrame = Bone.TransformedWorldCFrame,
Position = Bone.TransformedWorldCFrame.Position,
LastPosition = Bone.TransformedWorldCFrame.Position,
function Class:ApplyTransform(BoneTree)
do end
self.SolvedAnimatedCFrame = false
if self.ParentIndex < 1 then
do end
return
end
local ParentBone: IBone = BoneTree.Bones[self.ParentIndex]
local BoneParent = ParentBone.Bone
-- We check if the magnitude of rotation sum is zero because that tells us if it has already been averaged by another bone.
-- if ParentBone.NumberOfChildren > 1 and ParentBone.RotationSum.Magnitude ~= 0 then
-- local AverageRotation = ParentBone.RotationSum / ParentBone.NumberOfChildren
-- ParentBone.CalculatedWorldCFrame = CFrame.new(ParentBone.Position)
-- * CFrame.fromEulerAnglesXYZ(AverageRotation.X, AverageRotation.Y, AverageRotation.Z)
-- ParentBone.RotationSum = Vector3.zero
-- end
if ParentBone and BoneParent then
if ParentBone.Anchored and BoneTree.Settings.AnchorsRotate == false then -- Anchored and anchors do not rotate
--if BoneParent~=ParentBone.RootBone then
-- BoneParent.Transform =ParentBone.TransformCFrame
--end
BoneParent.WorldCFrame = ParentBone.TransformOffset
BoneParent.CFrame*=ParentBone.TransformCFrame
-- BoneParent.WorldCFrame = CFrame.new(ParentBone.Position) * ParentBone.CalculatedWorldCFrame.Rotation
else -- Not anchored
BoneParent.WorldCFrame = ParentBone.CalculatedWorldCFrame
BoneParent.CFrame*=ParentBone.TransformCFrame--*ParentBone.TransformCFrame
end
end
do end
end
To me it made sense since the World Position is being calculated and after that is done I multiply the bone’s CFrame by the orientation of the bone.
But It doesn’t seem to work. I also tried the of the angle orientation Inverse() as a sanity check.
Smart Bone Turned off
As you can see this rig has bones
wth initial Orientations as designed by the developers.
If they were all set to 0 as per the limitations of the current version
With the patch I mentioned enabled and smart bone running.
I disable the patch
Now it’s point the other direction.
I think part of the issue is how the WorldUp CFrame is calculated. To get that done I imagine you would simply multiply the InitialOrientation. But I’m just reverse engineering your system! I really do not know or do I have the time to spend another several hours trying to figure out how to fix it.
I forgot to mention this patch and issue does not affect previous SmartBone objects except by increasing the compatibility of the system to it’s actual completion.
This is because a bone with an initial orientation of 0,0,0 will calculate to the same sum.
In conclusion I think the issue is partially solved by the snippets I showed you and would be completely solved by including it into the WorldUp calculations made to determine gravity.