Notifications
Clear all

[Closed] baking lookAt constraint via maxscript?

i have a bone(child of dummy). it has rotation list as controller for rotation.
1st in rotation list is, euler xyz. >> kind of frozen
2nd in rotation list is, lookAt constraint with one target object
3rd is euler xyz again with intentions of saving baked data (keyframes from 2nd controller), currently weighted to zero.

i tried reading rotation values from 2nd controller, converting them into euler. then assinging to 3rd controller. and at end of loop, toggling weights of second and third controller. but results are different. it seems bone have some offsets 90 degrees or so… in some random axis…
any ideas. what easiest or logical solution would be?
or
what exactly i am missing?

huge thanks in advance

4 Replies

Have you tried the CollapseController function? It may not be suitable for you since it removes the list controller. But it does asks bake the animation.

i can’t even find that function. but it seems, as u explained, it won’t help much…
any other suggestions / ideas??

fn bakeOri o src dest fstart fend =
   (
   	local p = o.parent
   	o[3][2][#weights][dest].value = 0.0
   	for i = fstart to fend do (
   		at time i (
   			local m = (if (p!=undefined) then p.transform else (matrix3 1))
   			local frzm = o[3][2][1].controller.value as matrix3
   			local currm = o.transform
   			local newm = currm * (inverse m) * (inverse frzm)
   			with animate on (o[3][2][dest].value = newm.rotationpart)
   		)
   	)
   	o[3][2][#weights][dest].value = 100.0
   	o[3][2][#weights][src].value = 0.0
   )
   
 bakeOri $bone01 2 3 0 100

src: channel to bake
dest: channel to receive baked keys
fstart: first frame of baked time
fend: last frame of baked time

Constraints in max always return values in world space, so it’s not actually very useful in trying to convert it to a local value.

We take the world transform of the object you want to collapse, then multiply it through the inverse of the world transform of its parent, and the inverse of the frozen channel, and that should give you the local transform/rotation for the lookat.

edit: added “with animate” context, forgot I had autokey on when I tested it.

rotu, huge thanks man. u saved my day…
i owe you a gift…
here is final code with changes and details

fn bakeBoneLookAt o src dest bakeStep =
			(
				local p = o.parent
				o[3][2][#weights][dest].value = 0
				o[3][2][#weights][src].value = 100
				
				for i = animationRange.start to animationRange.end by bakeStep do (
					--print i
					with animate on (
						at time i 
						(
							local m = (if (p!= undefined) then p.transform else (Matrix3 1))
							--local frzm = o[3][2][1].controller.value as Matrix3
							local currm = o.transform
							local newm = currm * (Inverse m) --* (inverse frzm)
							o[3][2][dest].value  = newm.rotationpart
						)
					)
				)
				o[3][2][#weights][dest].value = 100
				o[3][2][#weights][src].value = 0
				o[3][2].controller.setActive(dest)
			)

Details: i prefer to use user time range. only step value is used…
after baking data to third controller in rotation list. it won’t allow ease of editing, because of two first controllers(even spring was diabled) but orientation gizmo is behaving odd. so i took decision of deleting third controller, and baking to first controller ( which was orignally working as frozen layer)
to make it work, i removed inverse multiplication of frozen part and rest is same.
once again, huge thanks