[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?
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
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.
The only way that I found is working with key array.
for k in Controller.keys do
(
k.intangenttype=#Step
k.outtangenttype=#Step
)
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.
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
-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?
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.
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.