Oscillator the script
Darn it... if Poser allowed a parameter with a string value instead of just numbers, I could allow the user to indicate which parameter on which prop they want to plug in the oscillator. This would make this really generic, as then a parameter like "SwingBack" for the hair could also be controlled by an oscillator.
But, alas, no such luck, so chances are the oscillators are always going to be magnets (unless one wants to go in complicated linking of dependent parameters, like back "SwingBack" to be dependent on the xRotation of some off-screen object. But I find creating these dependencies difficult, as there's no linear dependency that just says value0 at input0, value1 at input1 and that's it; the training thing for dependent parameters is too much hassle for me).
Hmmm.... one thing one could do is this... forget about rotations. Script "Add control" creates a big plane named Controllers, then a child small short box inside named Control_n. It's a child so that the user can move the controls out of the way.
The small short box works as a slide. Slide X left or right, it will cause an impulse on the target. The short box has the K and W parameters, and also Amplitude.
The link to the oscillator is done inside Add control. It presents a dropdown of all actors; once selected an actor, it presents another dropdown with parameters in that actor. Once that's selected, it creates a parameter "Oscillator_n" in the actor, then calls the function
AddValueOperation(kValueOpTypeCodeDELTAADD, pointer to Oscillator_n parameter)
in the target parameter. That makes Oscillator_n to be the master for whatever parameter the user wants. That allows oscillation of pretty much anything, from position to rotations to scales to morphs. Just slide the control and voila the target parameter oscillates adding around whatever value the user has in that parameter.
Actually don't need to create the Oscillator_n in the actor, with polution to its timeline. I understand that a parameter can be a master for parameters in other actors... so Oscillator_n can be a parameter in the Control_n box...I think...
Grrr.. have to redo my math on this.. I took a shortcut and ended up confusing the values; the right equation with no shortcuts is
x''(n) + 2.k.w0.x'(n) + w0^2.x(n) = 0
x"(n) = (x'(n)-x'(n-1))/h = (x(n)-2x(n-1)+x(n-2))/h^2
x'(n) = (x(n)-x(n-1))/h
h = 1/frame rate
[x(n)-2x(n-1)+x(n-2)]/h^2 + 2.k.w0[x(n)-x(n-1]/h + w0^2.x(n) = 0
[x(n)-2x(n-1)+x(n-2)] + 2.k.w0.h.[x(n)-x(n-1]/h + h^2.w0^2.x(n) = 0
[x(n+1)-2x(n)+x(n-1)] + 2.k.w0.h.[x(n+1)-x(n)] + h^2.w0^2.x(n+1) = 0
(1+2.k.w0.h+h^2.w0^2)x(n+1) = (2+2.k.w0.h)x(n) + (-1)x(n-1)
x(n+1) = (A.x(n)-B.x(n-1))/C
A = 2+2.k.w0.h
B = 1
C = 1+2.k.w0.h+2.wo^2)
Oh well... good old Euler method diverges for that guy... Trying again before change to say Runge-Kutta.
x' = u
u' = - 2kwu - w2x
x(n+1) = x(n) + h.u(n)
u(n+1) = u(n) - h.( 2.k.w.u(n) + w2.x(n))
Actually I think that's good enough for a toy. Nobody is trying to send a man to space with this. That second form is better behaved, although it can diverge too. The input is an impulse in the handler on frame 1 with change in X of 0.07. As Poser coordinates are tiny, I added a "Force" parameter that multiplies that input, so I set it to 10 for x10, making the input 0.7.
At 12 fps, a value of w = 20 yields oscillations with a period of about 3.5 frames; that's extremely tight for numerical methods, as a sinusoid in 3.5 frames is pretty much a seesaw, but it behaves itself. With K=0.9 it yields some 10 oscillations or so, so that's good enough.
At w=8 it yields a nice sinusoid with period of about 8 frames; with longer period the curve is much better behaved. But one gets to adjust the K for the desired period, as the thing diverges easily, thanks to old Euler method from 1700s.
So I'm leaving this as is. If I have time in the future I'll modify that to use Runge-Kutta, but I haven't looked at that in 30 years or so, so I'm not extremely inspired to do that now.
Hmm... I'm going to add a special case for very fast cycles, which diverge the equation. I'm going to add an exception for w=-1. That will just make
x(n+1) = -K*x(n)
That way one can make very fast dampened triangular oscillations with period = 2. That's pretty useful at 12 fps. Could even think of a case with period = 4...how to write that.. hmm...
x(n+2) = -K*x(n)
as a difference equation.. hmm...
x(n+1) = Ax(n) + Bu(n)
u(n+1) = Cx(n) + Du(n)
x(n+2) = Ax(n+1)+Bu(n+1) = Ax(n+1)+BCx(n)+BDu(n) = -Kx(n)
A = 0, D = 0, BC = -K
x(n+1) = u(n)
u(n+1) = -Kx(n)
hmm... wonder if that will work...
Demo of Oscillator v0.01:
In this Demo Andy doesn't have a single keyframe. Poinger The Oscillator script created 2 handlers (pink and green boxes) that are linked to Andy's head side-to-side (pink one), and Andy's forearm side-to-side (green one).
Whenever the handlers move in either X or Y direction that generates a dampened impulse that adds to whatever values Andy has in in these parameters, so one can still pose Andy as before with no interference.
The pink handler is set with Force = 200, K = 0.9, W = -1 (that's a forced triangular wave oscillator with period = 2; try W=-2 too). The green handler is set with Force = 300, K=0.6, W=12 (that's a sinusoidal with period of about 6 frames.
W is frequency; higher W means faster oscillations; don't set it too high or you'll break the simulator (can't oscillate at more fps than the frame rate). K is dampening; K=1.0 or >1.0 means critical dampened (it doesn't oscillate, it just comes back to the original position with an impule), K = 0.8 to 0.99 means lotsa dampening; K = 0.2 to 0.5 means very little dampening; K = 0.0 to 0.2 will tend to break the simulator.
If you try to simulate and the thing flies away, it means you've set either a too large W or too small K. If the simulation gives nothing, the force may be too small for you to see the effect, trying increasing the force. Trial and error will get the initial adjustments to whatever parameter this is controlling.
This controls ANY parameter in any figure or actor. It can be position, rotation, morph, lighting, etc...
Oh, the script has 3 buttons:
(a) Create Oscillator to create a new handler and link it a parameter
(b) Oscillate! to calculate the oscillations
(c) Clear Oscillations to remove all that jabberwocking to allow the user to pose again without all these moving parts.
The ControlPanel prop can be placed anywhere. It has no effect, and is the parent of the boxy handlers. Only movements on the boxy handlers have any effect.
Download from here: