Notifications
Clear all

[Closed] Always Step Bezier Float Controller

Here is an interesting challenge: Make a system (controller) where a specified bezier float controller always and only has all keys with the STEP IN/OUT tangent type.
Any ideas?

20 Replies

first of all – i’ve solved the issue. at the same day when i was asking. but because no one was interested i don’t see a reason to show the solution.
nevertheless… just please discuss where this kind of controller could be useful

1 Reply
(@eugenio)
Joined: 10 months ago

Posts: 0

Well I’m interested in the solution. I thought it was possible to add a callback when a specific controller changed but if that was the case I guess you would not be posting here so…

This kind of controller is particularly useful for animating the object’s pivot point.

 MZ1

The only way that I found is working with key array.

for k in Controller.keys do
(
k.intangenttype=#Step
k.outtangenttype=#Step
)

1 Reply
(@denist)
Joined: 10 months ago

Posts: 0

great! i see an interest…
MZ,
it’s technically easy and clean:


 <c>.keys.intangenttype = <c>.keys.outtangenttype = #step
 

Eugenio,
you got a point! for anyone who wants to make a smarter IK to FK and back swap solution it’s a gift.

 MZ1

I use this method for mirroring(flipping) a cutout character.

Thanks Denis!

1 Reply
(@denist)
Joined: 10 months ago

Posts: 0

what do you thank for? it’s not a problem to set all keys tangents to #step type. the question is how to guaranty that any key of the controller has only #step type and can’t be changed to any other

 MZ1

-Do we have access when adding new key? or we have to use a callback system?

I don’t know if the following solution follows the rules, but it seems to work.


myObj = $Sphere001
list_Controller = myObj.position.controller.z_position.controller = float_list()
list_Controller.available.controller = float_script()
list_Controller.setActive 1
list_Controller[2].AddObject "fCtrl" list_Controller[1]
list_Controller[2].SetExpression "fCtrl.keys.intangenttype = fCtrl.keys.outtangenttype = #step
0"
list_Controller[2].Update()

The same thing, but converted into a function. BTW, is there any better way to pass the path of a controller without passing it as a string?


fn alwaysStep ctrlPath = (
 list_Controller = execute (ctrlPath + " = float_list()")
 list_Controller.available.controller = float_script()
 list_Controller.setActive 1
 list_Controller[2].AddObject "fCtrl" list_Controller[1]
 list_Controller[2].SetExpression "fCtrl.keys.intangenttype = fCtrl.keys.outtangenttype = #step
0"
 list_Controller[2].Update()
)
alwaysStep "$Box001.position.controller.z_position.controller"

Nick,
i really LIKE your expression solution. i thought it might slow everything down and cause some memory leaking but it seems pretty fast and memory friendly… and it works very well. GOOD JOB!
here is a bit cleaner version:

fn alwaysStep sub = if iskindof sub Bezier_Float do
 (
 	c = sub.controller = Float_List()
 	s = c.available.controller = Float_Script()
 	s.addobject "control" c[1]
 	s.setexpression "control.keys.intangenttype = control.keys.outtangenttype = #step
0"
 )
 alwaysStep $.position.controller[#z_position]

Thanks DenisT, so should I suppose that your solution doesn’t include a script controller?

1 Reply
(@denist)
Joined: 10 months ago

Posts: 0

no. my solution is an added to a float controller custom attribute… the CA monitors changes of its owner (float controller) and changes keys in/out tangent type every time when any changes happen. so instead of your solution it updates the controller only when it’s needed.

Cool thread, I use the keys property for this usually, as it is generally on an attribute, ill set them as #step and check the key array on open or close in case they have been changed. I use it for replacement mouth style lipsync morphing, or sprite style UVW shifting on characters.

I would be interested in seeing your CA approach Denis.

1 Reply
(@denist)
Joined: 10 months ago

Posts: 0

here is it:

global StepControlAttr = attributes StepControlAttr 
(
	local handler = undefined
	local updating = off
	fn setStepTangents c = if not updating do if c.keys.count > 0 do 
	(
		updating = on
		c.keys.intangenttype = c.keys.outtangenttype = #step
		updating = off
	)
	fn deconstruct = (if iskindof handler ChangeHandler do deleteChangeHandler handler)
	fn construct = 
	(
		deconstruct()
		if iskindof (c = custattributes.getowner this) Bezier_Float do
		(
			handler = when geometry c change c do setStepTangents c
			setStepTangents c
		)
	)
	
	--on create do construct()
	--on clone origin do construct()
	on postload do construct()
	on update do construct()
	on delete do deconstruct()
)
/*
delete objects
b = box isselected:on
custattributes.add b.pos.controller[3].controller StepControlAttr
b.pos.controller[3].controller.construct()
*/

but playing more with Nick’s (expression) solution i more like it. My CA solution has a big shortcoming – the support of cloning…
the system fires scripted ca “clone” event but … before this ca added to the cloned controller. so i have to manually re-construct the cloned controllers.

Page 1 / 2