THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 01/09/2006 at 22:58, xxxxxxxx wrote:
Cinema 4D Version: 9.102
Platform: Windows ; Mac OSX ;
Language(s) : C++ ;
As much as Shoemake is thorough, C is soooo 1980's and his code is, to say the least, cryptic and full of junk that would go out the window quickly. There are already Quaternions in the SDK; already Matrices; already draw routines; already mouseinput routines, etc. and so on. Boiling down the 14 PAGES of code could take weeks.
What I need is a way to have the basic code necessary to implement arcball rotation - sort of like that already available with the Rotate tool for HPB.
Amazing. Interactive translation took an hour, scaling took a few more, constrained rotations minutes (borrowing from the other code). Free-rotations could take weeks - because I'm feeding into Euler sliders and not matrices. 3D Rotations suck, suck, suck!!! And I have no choice but Euler representation to sliders - otherwise the standard C4D tools would be used instead.
More amazing is that D|S does this - but then they are using OGL and some other 3D SDK.
On 04/09/2006 at 00:22, xxxxxxxx wrote:
Hm... it's not so hard to come up with something yourself. How about this:
Your Ball lives in camera or worldspace, pick one
The mouse moves from point a to b ( Screenspace )
Shoot Rays from a,b in Screen-z direction towards the sphere ( before that transform the rays in the right space ). That gives you the intersection points x,y.
If c is the center of the sphere, compute the angle between x-c and y-c, and also the rotation axis cross(x-c,y-c)
Transform the rot.axis to worldspace ( bd->CW_V ) if not already in.
Build a rotation matrix mr using RotAxisToMatrix
Build a matrix mg from your euler angles using
Go back to euler angles MatrixToHPB( mg*mr )
I guess that should work, and it's quite easy to code. Now you still have the problem how to choose the size of the ball. For that i have no idea.
On 04/09/2006 at 08:38, xxxxxxxx wrote:
Nope. HPB cannot be used in any form - as it is not consistent with the Cardan angles represented by the sliders (believe me - I know). Whatever Cinema 4D does to avoid gimbal lock in their system is indeterminate (and troublesome) as well. This was already tried and the expected 'flips' occurred - not good for posing rigged figures.
I do have Shoemake's Arcball code (but what a mess - he's good at spaghetti code) and his Euler Angle conversions (already being used to convert the quaternion results into ordered Euler angles from the to-be-mentioned attempt). I've tried a simpler ArcBall (Terence J. Grant), but since its final result is a matrix fed into the object matrix (using all GLUT code), my adaptation of it is showing anomalies. He doesn't seem to consider the virtual sphere's rotation in world space or it is taken up by the matrix concatenations. Not much explanation of the finer details.
Cinema 4D chooses 1/4 the smallest dimension of the view as the sphere's radius. Most arcball code uses some sort of unit sphere and maps the viewport to that. You'll also notice that rotations outside of their 'yellow circle' representing the sphere rotate about the axis formed by the center of rotation and the orthogonal to the screen.
On 04/09/2006 at 11:11, xxxxxxxx wrote:
I'm going to explain in more depth why the simple approaches fail.
To extend the problem with HPB, it also tends not to care about delta range. That is, if the object is initially rotated (0,0,0), even small mouse movements can return values like (-359, 0, 357). This is using something like: Vector v = MatrixToHPB(SM(quat.GetMatrix())) where the quaternion represents the direct spherical arc from point A to B. The rotation values do not respect delta - they are just rotations in the most expedient notation.
The other problem is that my final arbiters here are the Cardan angle sliders (in degrees, negated Z rotations). These representations MUST remain because the entire plugin depends on these values remaining this way for deformations and control of slave values (other sliders). Transformation matrices used for rotation and bending depend on them - not vice versa. As anyone knows, extracting Euler angles out of a rotation matrix has no singular solution (there are many Euler rotations that could be represented by a single rotation matrix). That is why extracting Euler rotations from rotation matrices is unacceptable. Setting some matrix and extracting Cardan rotations fails in two places with C4D - HPB is not Cardan and matrices are bad for getting delta range Cardan rotations.
Both Poser and Daz|Studio seem to handle this. Do you think that either's company would provide the code/algorithm for doing free rotation of Euler-Cardan angles? Highly unlikely.
Looks like I'll be winging some half-arsed approach that is more directly using the Cardan angles rather than Axis/Angle, quaternions, and esp. matrices.
On 04/09/2006 at 12:47, xxxxxxxx wrote:
OOps.. that arcball work a bit different than i thought. When you go from inside to outside the ball, it somehow seems to map those mouse coords also to the ball. I have an idea how to do this.. but i guess you have it working more or less already.
About the conversion to matrix<->angles. You are right.. if you want to animate those angle sliders, it is a bad idea to go from matrix to angles.
Except if you do some special trickery.. I've noticed that depending how fast you move the mouse in Cinema, the rotation angles are different. I move the mouse slow from the center to the right, and i get a rotation of 900° or so. If i move the mouse very very fast, i get 200°.. I think Cinema is extracting angles from quats/matrices. But they check if going from the last value to the new value crosses a multiple of 360°. If so, then newvalue += 360°. If you move very quickly, you skip entire 360° intervalls in the mouse poll iterations, and so the final value is lower.
No idea if it would work. But i can't think of any other way.
On 04/09/2006 at 15:54, xxxxxxxx wrote:
I'm completely stupified by these arcball thingies. Most consider that the object being rotated is at the World origin - the one I'm using that the center of the sphere is at the center of the view - perposterous for real world usage. All suppose RH systems. Shoemake's code suspiciously looks like he considers pixel Y=0 to be at the screen bottom and makes no compensatory fixes for the defacto, universal standard that XY=0,0 is top,left. Never let a mathematician near a computer without programmer supervision!
I don't understand his mouse coordinate conversion:
mouseNow.x = val;
vNow.x = 2.0*(mouseNow.x - winorig.x)/winsize.x - 1.0;
mouseNow.y = val;
vNow.y = 2.0*(mouseNow.y - winorig.y)/winsize.y - 1.0;
and how it affects the declared sphere center (in pixels supposedly - but have never seen it set to anything other than (0,0)). I'm accused of sparse commentation, but stuff of this complexity requires comments at every mathematical operation (and there isn't much more in the GGIV article about the specifics of the implementation).
I like the Arcball idea, esp. that quaternions remove hysteresis. But the math should be supplemented by the real world application - considering general conditions and not those purely ideal mathematical ones that the mathematicians love to push.
Already, I see the four hours to implement scale, translate, and constrained rotations and then the two weeks, 16 hour-days trying to do just this one thing - free mouse rotations. Point me to the straight jacket.
On 05/09/2006 at 00:11, xxxxxxxx wrote:
Well, scientist prefer the coordinate origin at the bottom left, that the most natural thing for them.
The mouse coordinates.. but that's a simple affine linear mapping.
I suspect mouseNow is in the range from winorig to winorig+winsize.
Then the resulting vNow has values in the [-1,1] intervall. -1 for mouseNow == winorig ( bottom left ? ) and 1 if mouseNow.x == winorig.x+winsize.x ( top right ? ), and 0 if the mouse is in the center of the window.
Sure the sphere is at (0,0) of the "normalized" coordinates. So it's at the center of the screen.
In Cinema you don't need the winorigin. When you poll the mouse coords you just need to do this:
LONG left, top, right, bottom;
bd->GetFrame(&left;, ⊤, &right;, ⊥);
LONG width = right - left + 1;
LONG height = bottom - top + 1;
vNow.x = mx/width * 2.0 - 1.0
vNow.y = my/height * 2.0 - 1.0
// reverse the sign if of y coord if (0,0)
// happens to be the top left
vNow.y = -vNow.y;
On 05/09/2006 at 07:10, xxxxxxxx wrote:
As do mathematicians (with that stupid Cartesian coordinate thing). ;D
My problem is that to decipher his code, I'd need to get my hands on the gl version he used. winorig/winsize could be the screen or the window or the display area (most likely the second, but a simple comment would have sufficed).
At least Shoemake provides the configuration for changing the sphere's center. This Arcball that I'm currently using (based on his, but simplified) always considers the sphere at the screen center. It should coincide with the center of rotation projected onto the screen - otherwise the mouse actions and the corresponding 3D rotations don't match.
Yep, already know about the BaseView Frame from ViewportSelect (if you remember me going on about that).
For the moment, I've backtracked to a simpler approach that uses 'rotate' for the Joint rotations and 'twist' for Twist rotation. Not particularly intuitive, but it doesn't have the anomalies and flips encountered with the Arcball code - which is more tuned to matrix concatenation than setting absolute rotation angles.
Something to keep going back to and work out a suitable algorithm I suppose.