Wed, Apr 24, 5:50 PM CDT

Welcome to the Poser 11 / Poser Pro 11 OFFICIAL Technical Forum

Forum Moderators: nerd

Poser 11 / Poser Pro 11 OFFICIAL Technical F.A.Q (Last Updated: 2024 Apr 15 3:14 am)

banner

Welcome to the Poser Forums! Need help with these versions, advice on upgrading? Etc...you've arrived at the right place!


Looking for Poser Tutorials? Find those HERE



Subject: Creating a new master parameter that works modulo 360 - can it be done ?


3dcheapskate ( ) posted Mon, 13 September 2021 at 12:50 AM · edited Tue, 23 April 2024 at 11:52 PM

I don't personally like the way the "Create New Master Parameter" option from the parameters tab works (just a personal thing), so I create new dials by manually editing the CR2 and/or using my own scripts such as this addDeltaAddDelta.py freebie at ShareCG.

I need to create a new master dial that works modulo 360 in the same way as the x/y/zRotate. However, I can't find any way to do this. There doesn't appear to be anything in the x/y/zRotate sections of the CR2 to flag that they're modulo 360.

Would somebody enlighten me please.


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Mon, 13 September 2021 at 4:07 AM

What I'm trying to do you ask ?

I'm trying to control all the legs of a millipede from a single dial, details over at HiveWire - The first four segments of a millipede - not sure if this'll go anywhere :)

I'm doing all the maths within the CR2 itself using valueOps. Part of this involves calculating sines/cosines, which I'm doing via a simple valueOpKey lookup table. The table has values from 0 to 360 in steps of 10, which seems sufficiently accurate for my purposes. Like this:

valueOpKey.png

The key value, marked by the red box in that screenshot, is calculated by adding two values which each have ranges of 0-360, giving a resultant range of 0-720. So I've temporarily concocted a Heath-Robinsonesque set of valueOps to ensure that the result of adding two 0-360 numbers will be modulo 360.

However, I want one of those two numbers being added together to have an unlimited range in order to represent multiple cycles - i.e. 360 is one cycle, 720 is two cycles, etc. My Heath-Robinsonesquerie will be unmamnageable if I try to extend it.

Therefore I'm looking for an alternative way to do the modulo 360. I found this Computing Mod Without Mod paper on the internet, but I don't think that any of those approaches can be taken using valueOps.

Another idea I had was to use another valueOpKey lookup table to reduce the input value to the 0-360 range, like this:

ReduceModulo.png

However, the interpolation is NOT linear as I thought, and goes totally haywire. Maybe I'm missing something simple here ?

Any thoughts, ideas, suggestions would be appreciated. Except for "do it in Python" - that's the coward's way out ! :)


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Mon, 13 September 2021 at 4:21 AM · edited Mon, 13 September 2021 at 4:22 AM

Also I've just realized that, of course, there's nothing special about the x/y/zRotate dials - no modulo 360 stuff going on there.

It is, of course, the way that they're used in the 3D simulation code that does it.

So my question is actually really simple:

"How can I add two numbers modulo 360 using valueOp maths ?"


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Mon, 13 September 2021 at 11:38 AM · edited Mon, 13 September 2021 at 11:38 AM

As a last resort I tried using the RTFM approach.

To start with I searched for "valueOpKey" in the Poserr 11 Manual to see if it says anything about the interpolation between OpKey values - it does:

SplineInterp.png

So that explains why my attempt at a linear interpolation sawtooth lookup with a valueOpKey, well... doesn't.

Then I searched for "modulus" and "modulo". Only appears in the section about material room nodes.

So it appears that there's no obvious way to add two numbers modulo 360 using valueOp maths.

So how about less obvious ways ? Does anybody have any ideas or suggestions ?


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Mon, 13 September 2021 at 12:10 PM

Reading up a bit (but not much) on spline interpolation it seems that providing more key values near the angular bits of the sawtooth that I want might enable me to do a modulo 360 valueOpKey lookup table for a limited range - especially if Poser's using cubic spline interpolation (which it probably isn't).

Something like this perhaps ?

            valueOpKey
                Figure 6
                BODY:6
                angle 0 to 1440
                strength 1.000000
                beginValueKeys
                    valueKey 0 0
                    valueKey 1 1
                    valueKey 2 2
                    valueKey 358 358
                    valueKey 359 359
                    valueKey 360 360
                    valueKey 360.002777777778 0.00277777777777778
                    valueKey 360.005555555556 0.00555555555555556
                    valueKey 360.994444444444 0.716666666666667
                    valueKey 360.997222222222 0.719444444444444
                    valueKey 361 1
                    valueKey 362 2
                    valueKey 363 3
                    valueKey 718 358
                    valueKey 719 359
                    valueKey 720 360
                    valueKey 720.002777777778 0.00277777777777778
                    valueKey 720.005555555556 0.00555555555555556
                    valueKey 720.994444444444 0.716666666666667
                    valueKey 720.997222222222 0.719444444444444
                    valueKey 721 1
                    valueKey 722 2
                    valueKey 723 3
                    valueKey 1078 358
                    valueKey 1079 359
                    valueKey 1080 360
                    valueKey 1080.00277777778 0.00277777777777778
                    valueKey 1080.00555555556 0.00555555555555556
                    valueKey 1080.99444444444 0.716666666666667
                    valueKey 1080.99722222222 0.719444444444444
                    valueKey 1081 1
                    valueKey 1082 2
                    valueKey 1083 3
                    valueKey 1438 358
                    valueKey 1439 359
                    valueKey 1440 360
                endValueKeys

Trying that out, the result doesn't go quite as wild as my previous attempt, but it still goes fairly wild, getting up to 600 at certain points.


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



nerd ( ) posted Mon, 13 September 2021 at 7:38 PM
Forum Moderator

Yeah, no. We need a spline type choice in the valueKeys. Then we couild set the interpolation to linear and that would solve this riddle. We don't have that yet. But, that would be an interesting enhancement. I've submitted an enhancement bug for this already.


3dcheapskate ( ) posted Tue, 14 September 2021 at 4:44 AM · edited Tue, 14 September 2021 at 4:50 AM

Thanks. Do you know what type of spline interpolation is currently used ?

I noticed a stupid mistake repeated on every falling edge of the sawtooth in my previous post which could explain why my result was still fairly wild on the second attempt.

I was assuming a cubic spline interpolation (i.e. 3 points, if I understand correctly) so I want three points in a straight line each side of each of the two repeating angles on the sawtooth. The three points with the angle at the centre point will still be a problem but maybe I can jiggle that to something reasonable once (if?) I get the main upslope and dropoff working more or less correctly.

They shouldn't be this:

                    valueKey 360 360
                    valueKey 360.002777777778 0.00277777777777778
                    valueKey 360.005555555556 0.00555555555555556
                    valueKey 360.994444444444 0.716666666666667
                    valueKey 360.997222222222 0.719444444444444
                    valueKey 361 1

I think they should be more like this:

                    valueKey 360 360
                    valueKey 360.002777777778 359
                    valueKey 360.005555555556 358
                    valueKey 360.994444444444 3
                    valueKey 360.997222222222 2
                    valueKey 361 1

And I've been wondering about the best way to test output of this - watching the numbers on the parameters tab dials isn't a good way. Maybe create a texture map showing the sawtooth and apply that, at the appropriate scale, to an appropriately sized groundplane, then use the valueOpKey sequence key/value to drive the xTranslation/zTranslation of a small red ball. The ball should follow the sawtooth. I think I'll give that a try.


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



nerd ( ) posted Tue, 14 September 2021 at 6:22 AM
Forum Moderator

Well for visualizing it, that's what the keyed dependency graph in the Dependency Editor is for. You can see exactly what it's doing over the full range of values. It's very easy to spot outliers. Cubic I guess, whatever it is I've always felt that linear interpolation would be much friendlier.


3dcheapskate ( ) posted Tue, 14 September 2021 at 10:46 AM · edited Tue, 14 September 2021 at 10:47 AM

My idea for testing seems to work, so I'm going to do sketches of the interpolations I get with various valueKey sets and post them here. The stuff above is far too weird, so I'm starting with the basics:

Untitled.png


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Tue, 14 September 2021 at 11:00 AM

Trying to move the "valueKey 720 0" left towards the 360 to get the vertical black line - the interpolator doesn't like that:

Untitled.png


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Thu, 16 September 2021 at 12:59 AM

Despite what I said in the first post I decided to try the "Create New Master Parameter" via the Poser UI approach. I have to say that it's much easier to see exactly what the spline interpolation does this way.

Teaching.jpg

But why isn't there a title on the pop-up window, and why doesn't the graph have any numbers on the scales ?


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Thu, 16 September 2021 at 1:12 AM · edited Thu, 16 September 2021 at 1:19 AM

...but I'm having no luck trying to create a sawtooth wave this way either. When I try to edit keys Poser changes adjacent keys to values I don't want, and sometimes ignores the key or value that I type in.

Problem.jpg

Even if I succeed there'll be curves at the two angles in the sawtooth waveform, and the vertical part won't be vertical, so the modulo values I get when the input is around Nx360 (N being an integer, so 360, 720, 1080, etc) will be incorrect.

I'm fairly sure that I'm onto a loser trying to do this with valueOpKey


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



adp001 ( ) posted Thu, 16 September 2021 at 11:57 AM · edited Thu, 16 September 2021 at 11:57 AM

Why not a callback with a Python script?


kValueOpTypeCodePYTHONCALLBACK is a regular Poser Python Parameter.


Like this

5Gj0yz8Y6HV2ChHJIDrADz7HCR27QDHMvxKJSDej.png

Sorry for the image, but the new editor does not preserve spaces on the left side (indentation).




adp001 ( ) posted Thu, 16 September 2021 at 12:02 PM

After starting the script, you can at any time set "__freq" to a new value (use Posers Python Console). or type "set_cb(45)".

Just make sure you have a figure loaded and that figure has an actor with internal name "head" :)




3dcheapskate ( ) posted Thu, 16 September 2021 at 10:33 PM · edited Thu, 16 September 2021 at 10:37 PM

adp001 posted at 11:57 AM Thu, 16 September 2021 - #4427549

Why not a callback with a Python script?


Why not indeed ! Python's definitely the most logical way to do it... but then logical isn't one of my strong points (and neither is scripting - if you've ever looked at my Python coding you'll know what I mean ! ;o) )

However, the main "why not Python" reason is mentioned in the final paragraph of the second post - "Any thoughts, ideas, suggestions would be appreciated. Except for "do it in Python" - that's the coward's way out ! :)"

I'll probably end up having to do it in Python anyway, but I just like the challenge of doing maths with valueOps (repeat previous observation - "logical isn't one of my strong points")

One problem that I recall with callbacks is that there's no way provided by the PoserPython API to keep track of them - no 'listActiveCallbacks()' function



adp001 posted at 11:57 AM Thu, 16 September 2021 - #4427549

...Sorry for the image, but the new editor does not preserve spaces on the left side (indentation).


Spaces, backslashes, etc - I'm convinced that the main goal of Renderosity's forum s***ware is to irritate people who try to use it ! :)

(edit: you said "new editor" - has it changed again ? I just noticed when I posted this reply that it the WYSINWYG is still NWYG, but different from what it was before)


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Fri, 17 September 2021 at 9:19 PM · edited Fri, 17 September 2021 at 9:24 PM

You'll have to excuse the obtuseness on my part - I've only just realized the main point of your suggestion...


adp001 posted at 11:57 AM Thu, 16 September 2021 - #4427549

...kValueOpTypeCodePYTHONCALLBACK is a regular Poser Python Parameter...


Just before I fell asleep last night a part of my brain that I'd been ignoring suddenly said "That's one of the valueOps that actually go in the CR2, like valueOpKey and valueOpTimes!". So this is a way to do it in the CR2 using valueOps... but with a tiny little bit of Python.

The only problem that I can can really foresee is that this won't work in DAZ Studio (that's one of the main reasons I didn't want to use Python - a Python solution would require me doing a DAZ Script version if I want it to work in DAZ Studio, and I lost interest in doing both Python and DAZ Script versions of things several years ago). So I think maybe I'll make this Poser only.

Thanks again adp001 :)


P.S. I've also just realized that the post editor has definitely changed very recently. It seems to be an improvement (finally scrapping Markdown!) but as you pointed out it's introduced different problems. Ho-hum.




The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Fri, 17 September 2021 at 10:05 PM

nerd posted at 7:38 PM Mon, 13 September 2021 - #4427341

Yeah, no. We need a spline type choice in the valueKeys. Then we couild set the interpolation to linear and that would solve this riddle. We don't have that yet. But, that would be an interesting enhancement. I've submitted an enhancement bug for this already.

While looking at the Poser 11 Reference Manual  to check up on the valueOp for a Python callback I noticed this...

 2bwPCDRJ2YZE4FRHYVsLLoTv8q9LoIazEdHXmqVV.png)

On page 818 it says "Type (7): There are two types of Master Parameter dials: Keyed: This master parameter type is the only type of dial that you can create in the Dependent Parameter palette. You can create linear links or curved links that have varying driven values at any value of the master parameter."

So apparently Poser 11 DOES allow linear interpolation between keys, but I can't find anything that says HOW to do it. 

(adp001's callback approach has the advantage of working for an unspecified range of inputs, whereas a keyed approach requires keyed values for the full range of inputs)


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



3dcheapskate ( ) posted Tue, 21 September 2021 at 10:43 PM


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



bagginsbill ( ) posted Thu, 23 September 2021 at 8:57 AM

I've never looked into value ops. What are the operators you have available? Are they listed somewhere?

Modulus can be constructed from some fairly common operators: division, floor, multiplication, subtraction. For example: (using Python infix notation (%) for modulus)

p % q == p - floor(p / q) * q


Renderosity forum reply notifications are wonky. If I read a follow-up in a thread, but I don't myself reply, then notifications no longer happen AT ALL on that thread. So if I seem to be ignoring a question, that's why. (Updated September 23, 2019)


3dcheapskate ( ) posted Fri, 24 September 2021 at 6:30 AM · edited Fri, 24 September 2021 at 6:36 AM

Page 31 of the Poser 11 PoserPython Manual - basically it's just the four most common operators, i.e. +, -, ×, ÷ (the latter either as divisor or dividend), plus a key/value pair option (which uses some sort of spline interpolation, with no option for linear) and a Python callback option (which appears to be spurious as a valueOp because simply setting up a callback via script does that job). I did google for alternative modulo algorithms, but none seem possible using valueOps, even the one you suggest - no 'floor' operator (the best result was this - 755.pdf (iacr.org))

gxgnfteNSirx4rCh6XpEosfMzX1un56tywDMkOlz.png

It appears that writing a small Python callback is going to be the best way to do this.


The 3Dcheapskate* occasionally posts sensible stuff. Usually by accident.

*also available in ShareCG, DAZ, and CGBytes flavours.



Privacy Notice

This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.