Notifications
Clear all

[Closed] Getting rotations from FFD cages

I’ve been trying to convert an animated FFD to a skinned bone based animation.

Creating a bone for each point and animating them to match the position of each control point is easy, but unless I handle rotation I get shearing.

I thought about doing this by sending a vector along each “edge” in the FFD and then bisecting the angles where these intersect, but as far as I can see the FFD is a point cloud has no knowledge of connecting points.

Has anyone managed to figure out a method of converting an FFD animation to bones?

7 Replies
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

the topology of FFD gizmo depends on its type and dimension. But the rule of creation is always the same. So you can make the list of edges yourself.

Thanks denisT, I’ll give that a go.

Another idea struck me last night – since this is just an approximation I could simply use a mesh that matched the FFD, bake the FFD animation onto that and then create the bone animation from the vertexnormals.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

i’m not sure that is possible to convert lattice (FFD) deformation to skin deformation and get one-to-one matching. these two methods handle weights very different.

 PEN

I agree on the weights. It will be the skinning that will change the results drastically not just the rotations on the bones. Will be interesting to see what you come up with.

Yeah, the whole 1 to 1 would never work, but with skinning and adjusting the bone animations it should be possible to get a close enough approximations.

This is probably quite a hacky way and I’ve not thought it thru totally, but have you thought about trying lookat controllers for one bone to look at the bone next to it and using the bone above/below as an upnode? Not sure how you’d get around the cyclic dependency problem on the last one though. Maybe just doubling up one of the bones for this.

Or making a piece of mesh the same as the FFD and using that as a skin wrap instead of bones with skin.

Cg.

OK, I have this working as part of the script, so I thought I’d paste the transform code for others.

I’m sending in a bonelist whihc is an array of bone objects, plus an proxy object that has the vertex deformations baked onto it.

This system is using a bone per vert, so the number of bones in the bone list match the number of bones in the proxymesh.

This loop is also inside an active time range loop.


for arrayIndex = 1 to bonelist.count do
				(
					
					baseVertPos=(getVert proxyobj.mesh arrayIndex) * proxyobj.objectTransform 
					basevertexNormal = getNormal proxyobj.mesh arrayIndex	
					
					-- Pick a random edge connected to this vert
					allConnectedEdges = (polyop.getEdgesUsingVert proxyobj arrayIndex) as array
					firstConnectedEdge = allConnectedEdges[1]

					-- Stick the known vert into the vert list for that edge
					-- This is one I want to ignore
					connectedVertlist = #(arrayIndex)

					-- Find all verts on that edge, append if unique to connectedVertlist 
					allConnectedVerts = (polyop.getVertsUsingEdge proxyobj firstConnectedEdge) as array
					for v = 1 to allConnectedVerts.count do appendifunique connectedVertlist allConnectedVerts[v]
						
					-- the last vert in the new list is the connected vert, thants the one we want
					-- This will probably not be perpendicular, but it will give me a vector
					secondvert = connectedVertlist[connectedVertlist.count]
					secondvertpos = (getVert proxyobj.mesh secondvert)* proxyobj.objectTransform
					secondVector =  secondvertpos - baseVertPos
										
					-- I now have 2 vectors, these describe a plane, and I can get the cross product of that to get third vector and create another place
					-- Then I can cross product that plane to get the 3rd 
					row1=basevertexNormal
					row2=normalize (cross row1 secondVector)
					row3=normalize (cross row1 row2)
					finalTransform = matrix3 row1 row2 row3 baseVertPos

					thebone = bonelist[arrayIndex]
					thebone.transform = finalTransform
				)	-- end bone loop