SmartBone 2 - Simulated Physics and Collision solution for Bones

You were correct about the issues I would run into with my modified script I just wanted to say your new version works incredibly great! I am on a second run making animated hair because it went so well! I now have 45 animated hair models. This system is such a game changer. I have 850 unanimated hair models scraped from the catalogue, and all my new ones are colorable and animated, tagged with Colorable so when I have like 100 animated hairs I can get rid of all the old hair and replace them with the new animated colorable styles. :slight_smile:
IF anyone wants to make a trade of 45 animated hair accessories for 45 animated hair accessories LMK. I also would do a trade for a cape library. You can contact me via dev forum or roblox.

Do you know what causes the hair models Rigs to go sideways?
image

No colliders on the character in this example.
I’ve been also having issues with the model bones doing this jagged pattern
image
The handle is an accessory but it is sized as the original size in the example. So it’s not a scaling issue.
I’m still trying to figure out how to use this SmartBone 2 properly.
All the hair models have the same smartbone attributes in this example.

V 0.3.1
image

This is a test with 1 stiffness. IDK if it reveals what’s going on but the bones appear crushed with 1 stiffness in the above.

I think the bug is cause by something in the bone cframe calculation not taking into account the initial CFrame of a bone, it appears to reset to orientation 0,0,0.

1 Like

Hey, I was wondering if anyone knew how to start Smart bone, then stop it, and then be able to start it again? The example code:

local BonePhysics = Smartbone.Start()
BonePhysics.Stop()
BonePhysics = Smartbone.Start()

just results with the warning:
Cannot call Smartbone.Start() multiple times

V0.3.1 incorrectly implemented the stop function, if you look at the V0.4.0 impl and copy it over it should work, it should be at the bottom of src/init.lua

2 Likes

Is there any chance we can get support for the initial rotation of a bone ? I tried implementing it myself and noticed you are calculating the cframe of the bone from the world cframe which makes it a more complicated issue. This is a major issue with compatibility of this module for a wider range of available 3-d models. I tried to implement this banner but since the orientation of the model’s bones were not initialized at 0,0,0 the model deforms into this mess.
image
This is also the same cause of the issue with the hair models I shared above. I spent some time trying to fix it but the creator of this module hasn’t gotten back to me. I don’t mean to be a burden I just want to use this system so far, I have about 28 hair models but I wasn’t able to include over 20 others due to this issue. I’m going to try to implement a fix myself once again… It’s very important for compatibility causing the issue with jagged geometry no matching the initial transformation.
I think the way to solve it would be to multiply the result by the initial orientation or multiply the initial cframe used for calculations with the initial orientation…
I managed to make a modification that made the bones render a bit differently by incorporating the initial orientation but it doesn’t seem quite right…
Maybe I’m suppose to offset it by the entire initial cframe?
image

I had sent the creator a library of 28 hair 3-D models and I’ll share them here if he helps me with this issue :slight_smile:

1 Like

I’ll open source the library of animated 28 hair 3-D models I sent you here to support your system if you help me with this issue! :slight_smile: Sounds like a great deal! I have over 20 others I cannot use currently due to the issue. Sorry if I made a bad impression!

3 Likes

Has anyone had any bone issues while using streaming enabled? My game is pretty large so we utilize streaming enabled and the capes go inside the humanoidrootpart when a player teleports.

1 Like

Hello, I have a problem: when I’m not looking at the ojbects it starts work really weird:

1 Like

Getting NaN calc world frame error

After testing, found out that the error happens if you do this in replicatedfirst:

hrp.CFrame=workspace:WaitForChild(‘Spawn’).CFrame*CFrame.new(0,3,0)

So, SmartBone 2 just completely breaks my model for whatever reason?

This is how SmartBone 2 interacts with my character:

Notice how the coat and pouches have sporadic and glitchy movement.

This is the expected result, and what the original SmartBone module does:

How would I fix this? This is so infuriating!!

Try v0.3.1‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎

could you add support for the initial orientation of bones and multiply the result by that

Im short of time right now which is why I haven’t been able to patch any bugs in Sb2, my advice as of right now is if you experience issues with >0.4.0 revert to 0.3.1, but do still report the bug.

Okay the bug is
this is supposed to be a hanging tapestry but since the system doesn’t use the initial orientation of the bones it causes this to happen.
image
Which in turn causes this to happen.
image
I tried patching it twice and failed.
This was my attempt to fix it. It caused no issues with the other ones, but it wasn’t quite right.
image

Basically, sometimes hair rigs use bones to shape the initial position of the hair likely to cut down polygons.
image
If you could fix it I will open source 80 rigged and formatted hair models for your SmartBone system as thanks for the help. Currently I cannot use over half of my models due to this issue.

1 Like

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

This is an incredible system, however I am running into some issues with bones Infront of the player - what provisions can I make to prevent clipping?

I have tried adding collision & limiting angles however both of these dont work as well as I would like

Is there any alternatives to these?

Many thanks :slight_smile: !

1 Like

Add the tag SmartCollider to the legs of your character or your entire character

CollectionService=game:GetService("CollectionService")
CollectionService:AddTag(object,"SmartCollider")
1 Like

I appreciate you taking a look at this:

Sorry for the miscommunication, when I said I had made allowance for Collision what I meant was that I had already enabled and tried the SmartCollider.

I have been reconfiguring the bones & changing the Collision shapes, but to no avail.

Do you have any advice beyond this point? Do you have any examples of successful Smartbones & collision when the clothing is “Skirt-like”.

Many thanks,

1 Like

The creator told somebody to try increasing the bone radius of your smart bones.
I did write this module to assist me in bulk smartbone asset creation. On looking at it appears you can use the SetBoneRadius function to help debug your asset.
SmartBoneUtility.lua (4.8 KB)

local module = {}
local CollectionService = game:GetService("CollectionService")

-- Function to add a tag to an object
function module.AddTagToObject(object, tagName)
	if not CollectionService:HasTag(object, tagName) then
		CollectionService:AddTag(object, tagName)
	end
end

function module.setRoots(targetObject)	
	local str=""
	local t=0
	for i,v in targetObject:GetChildren() do
		if v:IsA("Bone") then
			t+=1
			if t~=1 then
				str..=","..v.Name
			else 
				str..=v.Name
			end		
		end 
	end
	targetObject:SetAttribute("Roots",str)
end

function module.copyAttributes(sourceObject, targetObject)
	local attributes = sourceObject:GetAttributes()
	for attributeName, attributeValue in pairs(attributes) do
		targetObject:SetAttribute(attributeName, attributeValue)
	end
	module.AddTagToObject(targetObject,"SmartBone")
end

function module.FormatChar(char)
	module.AddTagToObject(char.Head,"SmartCollider")
	module.AddTagToObject(char.UpperTorso,"SmartCollider")	
	module.AddTagToObject(char.LowerTorso,"SmartCollider")	
	module.AddTagToObject(char.LeftUpperArm,"SmartCollider")
	module.AddTagToObject(char.RightUpperArm,"SmartCollider")	
end

function module.SetBoneRadius(object,radius)
	for i,v in object:GetDescendants() do
		if v:IsA("Bone") then
			v:SetAttribute("Radius",radius)
		end
	end 
end 

function module.ConvertModelToAccessory(Dir,output)
for i,v in Dir:GetChildren() do
	local c= v:FindFirstChildOfClass("MeshPart") 
	if c then 
		local d = Instance.new("Accessory")
		local p=Instance.new("Attachment")
		p.Name="HairAttachment"
		c.Parent=d
		p.Parent=c c.Name="Handle"
		d.Parent=output
	end
end
end


return module

I find this module to be crucial when developing smartbone assets in bulk.
That was because at the time I discovered this there was no access to the plugin.

3 Likes