# Freebie: A Few Books By The Cheapskate...

• by the way, the valueParm trig stuff I just mentioned started in the "ValueOperation Codes -What exactly is the maths?" thread, and this is where I ended up...

• (Note: the picture in the previous post shows the default book position and the position after simply setting the "LeanAngle(zRotate)" dial to 30, 45, 60 and 90).
For the valueParm stuff I was using a book whose origin was at the centre of gravity. This made the maths over-complicated: the required xTran was (H/2)sinL+(W/2)cosL-W/2, and yTran was (H/2)cosL+(W/2)sinL
By just moving the book origin to the bottom left rear corner the xTran became simply HsinL, and no yTran was required.
If we then add another vertical (i.e. non-leaning) book to the right it's quite simple to calculate the xTran we need to apply: HsinL+WcosL-W.
However, if we also want that book to lean...
that's where I gave up.

• @3dcheapskate valueOperation conditionals are indeed a total pain. There are some workarounds using multiple parameters and complementary limits (0..+max on one and -max..0 on the other), but I was never able to convince myself that it was worthwhile trying to figure out a way to do modulo arithmetic. Python callbacks can be a big performance penalty, and there's no way to individually clear a single callback. It's all or nothing, unfortunately.

However, it does occur to me that using a Python script to read a master parameter on a group of books and set their attitudes and positions is something that doesn't really require a callback, since it's only one click to run a script, unless you're planning to do a lot of adjustments in a scene. Simply having keyframed parameters calculated for the current frame might be all that's required, rather than maintaining the elegant, but potentially unwieldy valueOperations for dozens to grosses of books.

Of course, I'd never begrudge the endless hours of amusement and achievement that can be had tweaking valueOperations, if that's cataloguing your library for you ;-)

• @3dcheapskate If you do any scaling in Blender in Object mode. you must apply the scaling if you are going to do any sort of collisions etc. that saves you having to export / re-import.

I find 5x scale is about right from Poser to Blender but I temd to work at x 100

• @3dcheapskate If you do any scaling in Blender in Object mode. you must apply the scaling if you are going to do any sort of collisions etc. that saves you having to export / re-import.

Thanks, I was misunderstanding. When he said (at around 2m25) "...Blender does not work well if these are tiny little objects..." I assumed that you just needed objects with a size of the order of 1 Blender unit (as opposed to say 0.01 or 100 units) and scaled my books accordingly - and they fell through the floor. When I googled for something like 'blender rigid body falls through floor' most results had somebody saying something like "don't forget to apply scale to the object", which by my reading I was already doing - S, drag, left-click. What they obviously meant was "don't forget to actually apply any scaling (Ctl-A >Scale) to the object",.
They'd obviously reckoned without idiots like me !

• @3dcheapskate valueOperation conditionals are indeed a total pain. There are some workarounds using multiple parameters and complementary limits (0..+max on one and -max..0 on the other), but I was never able to convince myself that it was worthwhile trying to figure out a way to do modulo arithmetic. Python callbacks can be a big performance penalty, and there's no way to individually clear a single callback. It's all or nothing, unfortunately.

However, it does occur to me that using a Python script to read a master parameter on a group of books and set their attitudes and positions is something that doesn't really require a callback, since it's only one click to run a script, unless you're planning to do a lot of adjustments in a scene. Simply having keyframed parameters calculated for the current frame might be all that's required, rather than maintaining the elegant, but potentially unwieldy valueOperations for dozens to grosses of books.

Of course, I'd never begrudge the endless hours of amusement and achievement that can be had tweaking valueOperations, if that's cataloguing your library for you ;-)

I'd agree that a Python script (as opposed to callback) is probably the best way to do the lean. I consider this valueOps thingy as more of an ineffectual intellectual* challenge. Although I think it might be worth considering for the bookspine of an opening hardback, posted in this thread about three months ago

By the way, I actually found a reason to prefer the MINUS, PLUS, TIMES, DIVIDEBY and DIVIDEINTO valueOps over the DELTAADDDELTA: they made it easier to spot the inevitable mistakes I'd made in hand-coding, surprisingly few actually.

*If you can call what goes on in my head 'intellectual' - "Mmmm... brain need coffee!"

• ... I think it might be worth considering for the bookspine of an opening hardback, posted in this thread about three months ago...

Scratch that - it would require a cosine numerical approximation valid for the 0-180° range... and also an arctangent !

• @3dcheapskate I have actually done exactly that (explicitly keyed valueOp for cosine every 10 degrees between -720 and +720) as an orbit hack for a user created Dolly camera (the camera DollyX, DollyZ position is re-parameterised as FocusDistance(radius), Yaw(theta) ), so I can keyframe one camera over a whole animation in either dolly or orbit mode, as required. I even have a script which will add the necessary hidden parameters to any Dolly camera in the scene.

I can't imagine any extra difficulty with a keyed interpolation of a sine curve, but arcsine and arctangent both have discontinuities in them, IIRC, so their interpolation will require a lot more key, value pairs surrounding the discontinuities to maintain accuracy.

• I've obviously been thinking about this (thinking's so much easier than doing). 'This' being the valueOp approach to my an opening book.The idea of a single 'Open Book' dial that spreads the pages and bends the gutters and spine realistically has a certain irritating appealtoit...

(The two little right-angle triangles at each end of MN in the bottom left hand picture would also need a keyed valueOp asin to determine the angles for the gutters AM and DN)
I'm imagining a simple skeleton like this where there are two N's at the end of two separate 'limbs'...
Body

• AB
-BC
-CD
-DN
• AM
-MN
...and if I can get the calculations right I should be able to get them to appear as good as coincident.

• For my sin(α), sin(α+β), sin(α+β+γ), cos(α), cos(α+β), cos(α+β+γ), not forgetting sin(δ) or cos(δ) too, I think a keyed valueOp may be the way to go (just as anomalaus suggested way, way back - and several times since. ;o)
Assuming that (α), (α+β), and(α+β+γ) will all be in the 0° to +180° range seems a good start (although the upper limit might need to be extended to say +270° for the philistines who like to damage the books !).
That would mean δ is 0° to +90° (or 0° to +135°), so I'd have to take account of the atan discontinuity at +90° (just as anomalaus has said).
The gutter angle (M to A to a-perpendicular-dropped-from-A-to-MN) should be in the range 0° to slightly-less-than +90°, so I think I can ignore the asin +90° point of inflexion (if I recallmy maths terms correctly?)
Anyway, here's some code for sin and cos keyed valueOps at 5°steps, created from a spreadsheet sin/cos

``````
valueParm A (Angle in degrees 0 to 180)
{
name A (Angle in degrees 0 to 180)
initValue 0
hidden 0
enabled 1
forceLimits 0
min -100000
max 100000
trackingScale 0.004
keys
{
static  0
k  0  180
}
interpStyleLocked 0
}
valueParm Sin(A)
{
name Sin(A)
initValue 0
hidden 0
enabled 1
forceLimits 0
min -100000
max 100000
trackingScale 0.004
keys
{
static  0
k  0  0
}
interpStyleLocked 0
valueOpKey
_NO_FIG_
One-Sided 1PNU Square
A (Angle in degrees 0 to 180)
beginValueKeys
valueKey  0 0
valueKey  5 0.0872
valueKey  10 0.1736
valueKey  15 0.2588
valueKey  20 0.342
valueKey  25 0.4226
valueKey  30 0.5
valueKey  35 0.5736
valueKey  40 0.6428
valueKey  45 0.7071
valueKey  50 0.766
valueKey  55 0.8192
valueKey  60 0.866
valueKey  65 0.9063
valueKey  70 0.9397
valueKey  75 0.9659
valueKey  80 0.9848
valueKey  85 0.9962
valueKey  90 1
valueKey  95 0.9962
valueKey  100 0.9848
valueKey  105 0.9659
valueKey  110 0.9397
valueKey  115 0.9063
valueKey  120 0.866
valueKey  125 0.8192
valueKey  130 0.766
valueKey  135 0.7071
valueKey  140 0.6428
valueKey  145 0.5736
valueKey  150 0.5
valueKey  155 0.4226
valueKey  160 0.342
valueKey  165 0.2588
valueKey  170 0.1736
valueKey  175 0.0872
valueKey  180 0
endValueKeys
}
valueParm Cos(A)
{
name Cos(A)
initValue 0
hidden 0
enabled 1
forceLimits 0
min -100000
max 100000
trackingScale 0.004
keys
{
static  0
k  0  0
}
interpStyleLocked 0
valueOpKey
_NO_FIG_
One-Sided 1PNU Square
A (Angle in degrees 0 to 180)
beginValueKeys
valueKey  0 1
valueKey  5 0.9962
valueKey  10 0.9848
valueKey  15 0.9659
valueKey  20 0.9397
valueKey  25 0.9063
valueKey  30 0.866
valueKey  35 0.8192
valueKey  40 0.766
valueKey  45 0.7071
valueKey  50 0.6428
valueKey  55 0.5736
valueKey  60 0.5
valueKey  65 0.4226
valueKey  70 0.342
valueKey  75 0.2588
valueKey  80 0.1736
valueKey  85 0.0872
valueKey  90 0
valueKey  95 -0.0872
valueKey  100 -0.1736
valueKey  105 -0.2588
valueKey  110 -0.342
valueKey  115 -0.4226
valueKey  120 -0.5
valueKey  125 -0.5736
valueKey  130 -0.6428
valueKey  135 -0.7071
valueKey  140 -0.766
valueKey  145 -0.8192
valueKey  150 -0.866
valueKey  155 -0.9063
valueKey  160 -0.9397
valueKey  165 -0.9659
valueKey  170 -0.9848
valueKey  175 -0.9962
valueKey  180 -1
endValueKeys
}
``````

• Something odd happening when I try to do an atan... what sort of atan value is -1.#IO ?

Here's the relevant bit in the CR2 - the 'S (SumOfSines/SumOfCosines)' and 'Atan(S) in Degrees' valueParm stuff, just in case anybody fancies pointing out a obvious/stupid mistake that I can't see.(the calculation of S appears to work, it's just the Atan that spurts out garbage !

``````
valueParm S (SumOfSines/SumOfCosines)
{
name S (SumOfSines/SumOfCosines)
initValue 0
hidden 0
enabled 1
forceLimits 0
min -100000
max 100000
trackingScale 0.01
keys
{
static  0
k  0  1
}
interpStyleLocked 0
valueOpTimes
Figure 8
BODY
Sum Of Sines
valueOpDivideBy
Figure 8
BODY
Sum Of Cosines
}
valueParm Atan(S) in Degrees
{
name Atan(S) in Degrees
initValue 0
hidden 0
enabled 1
forceLimits 0
min -100000
max 100000
trackingScale 0.01
keys
{
static  0
k  0  0
}
interpStyleLocked 0
valueOpKey
Figure 8
BODY
S (SumOfSines/SumOfCosines)
beginValueKeys
valueKey -1000 90.1
valueKey -57.29 91
valueKey -28.6363 92
valueKey -19.0811 93
valueKey -14.3007 94
valueKey -11.4301 95
valueKey -9.5144 96
valueKey -8.1443 97
valueKey -7.1154 98
valueKey -6.3138 99
valueKey -5.6713 100
valueKey -5.1446 101
valueKey -4.7046 102
valueKey -4.3315 103
valueKey -4.0108 104
valueKey -3.7321 105
valueKey -3.4874 106
valueKey -3.2709 107
valueKey -3.0777 108
valueKey -2.9042 109
valueKey -2.7475 110
valueKey -2.6051 111
valueKey -2.4751 112
valueKey -2.3559 113
valueKey -2.246 114
valueKey -2.1445 115
valueKey -2.0503 116
valueKey -1.9626 117
valueKey -1.8807 118
valueKey -1.804 119
valueKey -1.7321 120
valueKey -1.6643 121
valueKey -1.6003 122
valueKey -1.5399 123
valueKey -1.4826 124
valueKey -1.4281 125
valueKey -1.3764 126
valueKey -1.327 127
valueKey -1.2799 128
valueKey -1.2349 129
valueKey -1.1918 130
valueKey -1.1504 131
valueKey -1.1106 132
valueKey -1.0724 133
valueKey -1.0355 134
valueKey -1 135
valueKey -0.9657 136
valueKey -0.9325 137
valueKey -0.9004 138
valueKey -0.8693 139
valueKey -0.8391 140
valueKey -0.8098 141
valueKey -0.7813 142
valueKey -0.7536 143
valueKey -0.7265 144
valueKey -0.7002 145
valueKey -0.6745 146
valueKey -0.6494 147
valueKey -0.6249 148
valueKey -0.6009 149
valueKey -0.5774 150
valueKey -0.5543 151
valueKey -0.5317 152
valueKey -0.5095 153
valueKey -0.4877 154
valueKey -0.4663 155
valueKey -0.4452 156
valueKey -0.4245 157
valueKey -0.404 158
valueKey -0.3839 159
valueKey -0.364 160
valueKey -0.3443 161
valueKey -0.3249 162
valueKey -0.3057 163
valueKey -0.2867 164
valueKey -0.2679 165
valueKey -0.2493 166
valueKey -0.2309 167
valueKey -0.2126 168
valueKey -0.1944 169
valueKey -0.1763 170
valueKey -0.1584 171
valueKey -0.1405 172
valueKey -0.1228 173
valueKey -0.1051 174
valueKey -0.0875 175
valueKey -0.0699 176
valueKey -0.0524 177
valueKey -0.0349 178
valueKey -0.0175 179
valueKey 0 0
valueKey 0.0175 1
valueKey 0.0349 2
valueKey 0.0524 3
valueKey 0.0699 4
valueKey 0.0875 5
valueKey 0.1051 6
valueKey 0.1228 7
valueKey 0.1405 8
valueKey 0.1584 9
valueKey 0.1763 10
valueKey 0.1944 11
valueKey 0.2126 12
valueKey 0.2309 13
valueKey 0.2493 14
valueKey 0.2679 15
valueKey 0.2867 16
valueKey 0.3057 17
valueKey 0.3249 18
valueKey 0.3443 19
valueKey 0.364 20
valueKey 0.3839 21
valueKey 0.404 22
valueKey 0.4245 23
valueKey 0.4452 24
valueKey 0.4663 25
valueKey 0.4877 26
valueKey 0.5095 27
valueKey 0.5317 28
valueKey 0.5543 29
valueKey 0.5774 30
valueKey 0.6009 31
valueKey 0.6249 32
valueKey 0.6494 33
valueKey 0.6745 34
valueKey 0.7002 35
valueKey 0.7265 36
valueKey 0.7536 37
valueKey 0.7813 38
valueKey 0.8098 39
valueKey 0.8391 40
valueKey 0.8693 41
valueKey 0.9004 42
valueKey 0.9325 43
valueKey 0.9657 44
valueKey 1 45
valueKey 1.0355 46
valueKey 1.0724 47
valueKey 1.1106 48
valueKey 1.1504 49
valueKey 1.1918 50
valueKey 1.2349 51
valueKey 1.2799 52
valueKey 1.327 53
valueKey 1.3764 54
valueKey 1.4281 55
valueKey 1.4826 56
valueKey 1.5399 57
valueKey 1.6003 58
valueKey 1.6643 59
valueKey 1.7321 60
valueKey 1.804 61
valueKey 1.8807 62
valueKey 1.9626 63
valueKey 2.0503 64
valueKey 2.1445 65
valueKey 2.246 66
valueKey 2.3559 67
valueKey 2.4751 68
valueKey 2.6051 69
valueKey 2.7475 70
valueKey 2.9042 71
valueKey 3.0777 72
valueKey 3.2709 73
valueKey 3.4874 74
valueKey 3.7321 75
valueKey 4.0108 76
valueKey 4.3315 77
valueKey 4.7046 78
valueKey 5.1446 79
valueKey 5.6713 80
valueKey 6.3138 81
valueKey 7.1154 82
valueKey 8.1443 83
valueKey 9.5144 84
valueKey 11.4301 85
valueKey 14.3007 86
valueKey 19.0811 87
valueKey 28.6363 88
valueKey 57.29 89
ValueKey 1000 89.9
endValueKeys
}
``````

As a test I tried cutting down the atan keys to just two. If I do this the value seems to remain fixed at -2000.

``````
valueParm Atan(S) in Degrees
{
name Atan(S) in Degrees
initValue 0
hidden 0
enabled 1
forceLimits 0
min -100000
max 100000
trackingScale 0.01
keys
{
static  0
k  0  0
}
interpStyleLocked 0
valueOpKey
Figure 8
BODY
S (SumOfSines/SumOfCosines)
beginValueKeys
valueKey -10 -2000
ValueKey 10 2000
endValueKeys
}
``````

• Putting all that valueOp stuff aside for a moment, I just found the 64 book stack that I thought I'd lost. I also made it fall over in Blender. Here's both, with a sort-of-improved-ish shader based on Bagginsbill's procedural hair shader. I think I did something wrong with the one I released before.

I think I should probably release this soon, before I lose it again for real.

• Back to the valueOp stuff for a moment, specifically that pesky -1.#IO.
It seems that Poser simply doesn't like negative 'values' for the 'value'/'key' pair (assuming the first number is 'value' and the second is 'key',which would be logical based on the name 'valueKey', so it probably isn't -it's probably key/value which might make more sense, sort of ... -ish).

Just to be clear, It's the '-10' in the bit below, and any/every other negative number in that place.

``````			beginValueKeys
valueKey -10 -2000
ValueKey 10 2000
endValueKeys
``````

Bang goes the atan then !

• Bang goes the atan then for 90° to 180° !
(New post just for that extra bit - thank you edit timeout!)

• Well, the principle (of the valueOp stuff) appears to be working. It's just that I've made a mistake or two in the maths and/or valueOp implementation.
Here are three pictures of the book figure that I used for trying things out earlier in this thread, with the maths based on my scribbled note implemented with valueOps.
The only difference is the setting of the 'Open Book' dial.

(do you see the picture above?)

• Fixed, and it works beautifully !

• @3dcheapskate That is a really excellent implementation, congrats on sticking with it!

• Thank you.:o)
For anybody who's interested I've uploaded the CR2 of the opening book to ShareCG for you to play with, take apart, build on, or whatever you like:
Proof Of Principle - Poser ERC Opening Book
https://sharecg.com/v/93811/view/11/Poser/Proof-Of-Principle-Poser-ERC-Opening-Book