SmartBone 2 - Simulated Physics and Collision solution for Bones

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.

1 Like