Notifications
Clear all

[Closed] World Space <-> FFD Space with a rotated lattice?

Has anyone managed to convert from the FFD’s modifier space to world space and back again with a rotated lattice? I’ve managed to get it to work with a moved lattice, but as soon as I adjust the rotation my code falls apart.

* Draw a box
* Put a FFD 2x2x2 on it
* run this code
  • The point helper should now be aligned with FFD Control Point 3.
  • rotate the lattice
  • run this code again
  • the point helper is not where it should be.
(
    
    	fn GetFFDPoint obj ffd controlPoint =
    	(
    		if classOf controlPoint != Point3 then
    		(
    			print "Error: You need to pass in a point 3"
    			return undefined
    		)
    		
    		objTM = obj.objecttransform
    		modTM = (getModContextTM obj ffd) * ffd.lattice_transform.value
    		modBBMin = getModContextBBoxMin obj ffd
    		modBBMax = getModContextBBoxMax obj ffd
    		size = (modBBMax - modBBMin)
    		thePoint = modBBMin + (controlPoint * size) * modTM * objTM
    		print ("Starting Position " + controlPoint as string)
    		return thePoint
    	)
    	
    	fn SetFFDPoint obj ffd worldSpace controlPoint =
    	(
    		objTM = obj.objecttransform
    		modTM = (getModContextTM obj ffd) * ffd.lattice_transform.value
    		modBBMin = getModContextBBoxMin obj ffd
    		modBBMax = getModContextBBoxMax obj ffd
    		size = (modBBMax - modBBMin)
    		thePoint = (worldSpace * (inverse objTM) * modTM - modBBMin) / size
    		print ("FFD Space: " + thePoint as string)
    		ffd.control_point_3 = thePoint
    	)
    	
    	while $tester != undefined do
    	(
    		delete $tester
    	)
    	
    	obj = $Box01
    	animateAll obj.modifiers[1]
    	thePoint = GetFFDPoint obj obj.modifiers[1] obj.modifiers[1].control_point_3
    	if thePoint != undefined then
    	(
    		print ("WorldSpace: " + thePoint as string)
    		point name:"tester" pos:thePoint
    		--SetFFDPoint obj obj.modifiers[1] thePoint obj.modifiers[1].control_point_3
    	)
    )
1 Reply

Figured it out. Had to multiply the inverse quaternion of the lattice in the equation. I also fixed a bug or two when converting back. Hope this helps someone else out in the future.


 (
 	-- This script converts from FFD space to world space and back again.
 	-- Neil Marshall 12/31/2011
 
 	fn FFDSpaceToWorldSpace obj ffd controlPoint =
 	(
 		if classOf controlPoint != Point3 then
 		(
 			print "Error: You need to pass in a point 3 to properly convert a FFD to world space"
 			return undefined
 		)
 		
 		objTM = obj.objecttransform
 		modTM = (getModContextTM obj ffd) * ffd.lattice_transform.value
 		modBBMin = getModContextBBoxMin obj ffd
 		modBBMax = getModContextBBoxMax obj ffd
 		size = modBBMax - modBBMin
 		thePoint = modBBMin * inverse ffd.lattice_transform.rotation + (controlPoint * size) * modTM * objTM
 		return thePoint
 	)
 	
 	fn WorldSpaceToFFDSpace obj ffd worldSpace =
 	(
 		objTM = obj.objecttransform
 		modTM = (getModContextTM obj ffd) * ffd.lattice_transform.value
 		modBBMin = getModContextBBoxMin obj ffd
 		modBBMax = getModContextBBoxMax obj ffd
 		size = modBBMax - modBBMin
 		thePoint = (worldSpace * (inverse objTM) * (inverse modTM) - modBBMin) / size
 		return thePoint
 	)
 	
 	while $tester != undefined do
 	(
 		delete $tester
 	)
 	
 	obj = $Box01
 	animateAll obj.modifiers[1]
 	
 	print ("Before FFD Space: " + obj.modifiers[1].control_point_3 as string)
 	thePoint = FFDSpaceToWorldSpace obj obj.modifiers[1] obj.modifiers[1].control_point_3
 	
 	if thePoint != undefined then
 	(
 		print ("WorldSpace: " + thePoint as string)
 		point name:"tester" pos:thePoint
 		obj.modifiers[1].control_point_3 = WorldSpaceToFFDSpace obj obj.modifiers[1] thePoint
 		print ("After FFD Space: " + obj.modifiers[1].control_point_3 as string)
 	)
 	
 	""
 )