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...
    0_1556545818783_JustLean.jpg



  • (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.
    0_1556564856365_a91c6af3-9219-4276-ae42-b8490a3ed637-image.png
    I find 5x scale is about right from Poser to Blender but I temd to work at x 100



  • @amethystpendant said in Freebie: A Few Books By The Cheapskate...:

    @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 !



  • @anomalaus said in Freebie: A Few Books By The Cheapskate...:

    @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!"



  • @3dcheapskate said in Freebie: A Few Books By The Cheapskate...:

    ... 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...
    0_1557670695380_ThinkTooMuch.jpg
    (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 ?
    0_1557812183721_odd.jpg
    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.
    0_1557847208704_MoreFunWithBooks.jpg

    0_1557847385412_Shader.jpg

    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.

    0_1557927024940_PrincipleWorks.jpg
    (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