convert vector normals to angles-maxscript
Moderator: Moderators
convert vector normals to angles-maxscript
I am working on a maxscript for gmax to import cod xmodel_export files and I need to know how to convert vectors to angles
BONE 70
OFFSET -19.514948 -16.768861 39.989041
SCALE 1.000001 1.000000 1.000000
X 0.836715 0.280328 -0.470451
Y 0.071690 0.795593 0.601575
Z 0.542926 -0.537073 0.645588
x , y and z are vectors I need to be able to find angles so that I can rotate the bones the offset is the position in the editor
BONE 70
OFFSET -19.514948 -16.768861 39.989041
SCALE 1.000001 1.000000 1.000000
X 0.836715 0.280328 -0.470451
Y 0.071690 0.795593 0.601575
Z 0.542926 -0.537073 0.645588
x , y and z are vectors I need to be able to find angles so that I can rotate the bones the offset is the position in the editor
To do this, you need to know the exact convention for the angles you need.
You need to know:
- The order in which the rotations are applied.
- The axis around which each rotation is applied.
Determining the order of rotation is tricky but absolutely necessary. One way to find out which order is used is by applying a rotation of 90 degrees on 2 angles, and from the end result determine which was applied first. Do this another 2 times on the remaining set of angles and you know the order.
You need to know:
- The order in which the rotations are applied.
- The axis around which each rotation is applied.
Determining the order of rotation is tricky but absolutely necessary. One way to find out which order is used is by applying a rotation of 90 degrees on 2 angles, and from the end result determine which was applied first. Do this another 2 times on the remaining set of angles and you know the order.
Well math is not my strong suit all I want to do is rotate the bone useing the x , y and z values given . I am afraid you have lost me already
In the gmax listener window I get
$.rotation
(quat 0.0606951 -0.00584427 0.138267 0.289882)
$.rotation.x
0.0606951
$.rotation.y
-0.00584427
$.rotation.z
0.138267
where $ is the selcted object . I can use rotate $ 90 [1,0,0] to rotate on the x axis or just use $.rotation.x = 90 I am lost on this .
$.rotation
(quat 0.0606951 -0.00584427 0.138267 0.289882)
$.rotation.x
0.0606951
$.rotation.y
-0.00584427
$.rotation.z
0.138267
where $ is the selcted object . I can use rotate $ 90 [1,0,0] to rotate on the x axis or just use $.rotation.x = 90 I am lost on this .
hmm found this in another script
$.rotation = quat (matrix3 [0.554198, -0.245197, -0.795452][0.453435, 0.890324, 0.041473][0.698040, -0.383671 ,0.604596][-19.604893, -17.765507 ,41.269524])
(quat -0.121736 -0.427647 0.200047 0.873086)
The max script reference has in part
so what I did was use the x ,y z and offset from the bone seemed to work at least gmax didn't complainlocal x = ReadFloat bstream
local y = ReadFloat bstream
local z = ReadFloat bstream
origin = [x, y, z]
x = ReadFloat bstream
y = ReadFloat bstream
z = ReadFloat bstream
axisRow1 = [x, y, z]
x = ReadFloat bstream
y = ReadFloat bstream
z = ReadFloat bstream
axisRow2 = [x, y, z]
x = ReadFloat bstream
y = ReadFloat bstream
z = ReadFloat bstream
axisRow3 = [x, y, z]
tagMatrix = matrix3 axisRow1 axisRow2 axisRow3 origin
$.rotation = quat (matrix3 [0.554198, -0.245197, -0.795452][0.453435, 0.890324, 0.041473][0.698040, -0.383671 ,0.604596][-19.604893, -17.765507 ,41.269524])
(quat -0.121736 -0.427647 0.200047 0.873086)
The max script reference has in part
Matrix3 Values
The Matrix3 class implements a 4x3 3D transformation matrix object. The transform matrix is a 3D homogeneous matrix typically used to hold object coordinate systems and transformations.
Constructors
matrix3 <row1_point3> <row2_point3> <row3_point3> <row4_point3>
matrix from row vectors
I don't totally understand it but I knew I could set the rotation from a quat . I wonder if this is what I was looking forQuat Values
The Quat class provides a compact representation for orientation in three space and provides methods to perform Quaternion algebra. Quaternions are used to store object rotations in 3ds max. A quaternion is made up of four terms: a real scalar part which specifies the amount of rotation and an imaginary vector part which defines the axis of rotation. If the quaternion is normalized, the scalar term equals the cosine of half the angle of rotation, the vector term is the axis of rotation, and the magnitude of the vector term equals the sine of half the angle of rotation.
Interpolation between two key frame orientations is much easier using quaternions and produces smooth and natural motion. Unlike Euler angles, no numerical integration is necessary; quaternions provide an analytic result (no approximations).
Rotations in MAXScript follow the right-hand-rule, namely positive angles rotate counter-clockwise about positive axes, consistent with the convention in the 3ds max UI.
Constructors
quat <x_float> <y_float> <z_float> <w_float>
The x, y, z values make up the vector portion. w is the angle of rotation about the vector.
quat <degrees_float> <axis_point3>
<angleaxis> as quat
<eulerangle> as quat
<matrix3> as quat -- extracts the rotation component as a quat
Hmm well there is a 1-to-1 correspondence between the orthonormal matrix [X Y Z] and the associated normalized quaternion, but whether this approach is convenient really depends on the application.
Where are you getting the X Y Z data from?
Can't you rotate the bone directly using the [X Y Z] matrix?
P.S. I'm unfamiliar with the scripting language but it seems like
<matrix3> as quat
would do the conversion from matrix to quaternion.
Where are you getting the X Y Z data from?
Can't you rotate the bone directly using the [X Y Z] matrix?
P.S. I'm unfamiliar with the scripting language but it seems like
<matrix3> as quat
would do the conversion from matrix to quaternion.
well that was wrong anyway . The x y z are from the xmodel_export file for cod
BONE 41
OFFSET 19.040640 -13.171670 43.321545
SCALE 1.000000 1.000000 1.000000
X -0.766464 -0.594188 -0.243871
Y 0.525111 -0.361068 -0.770641
Z 0.369852 -0.718728 0.588762
and this is from the anim file
FRAME 1
PART 0
OFFSET 58.057384 -11.493357 31.342108
SCALE 1.000000 1.000000 1.000000
X -0.149580 -0.500161 -0.852915
Y 0.732539 -0.635432 0.244158
Z -0.664088 -0.588272 0.461436
it starts off with a frame number then bone number I guess then the position and rotation I assume . Maybe this will help I don't understand it but you may it is a tut that rotates a ball on a path http://cuneytozdas.com/tutorials/maxscript/
BONE 41
OFFSET 19.040640 -13.171670 43.321545
SCALE 1.000000 1.000000 1.000000
X -0.766464 -0.594188 -0.243871
Y 0.525111 -0.361068 -0.770641
Z 0.369852 -0.718728 0.588762
and this is from the anim file
FRAME 1
PART 0
OFFSET 58.057384 -11.493357 31.342108
SCALE 1.000000 1.000000 1.000000
X -0.149580 -0.500161 -0.852915
Y 0.732539 -0.635432 0.244158
Z -0.664088 -0.588272 0.461436
it starts off with a frame number then bone number I guess then the position and rotation I assume . Maybe this will help I don't understand it but you may it is a tut that rotates a ball on a path http://cuneytozdas.com/tutorials/maxscript/
Ok well this maybe above me but anyway this is from the xmodel_export file
and this is in the dumpfile from lr3dNUMBONES 73
BONE 0 -1 "TAG_ORIGIN"
BONE 1 0 "Bip01 Pelvis"
....
BONE 0
OFFSET 0.000002 -2.222280 0.000042
SCALE 1.000000 1.000000 1.000000
X 0.000000 -1.000000 -0.000001
Y 1.000000 0.000000 0.000000
Z -0.000000 -0.000001 1.000000
BONE 1
OFFSET 0.000000 1.218488 37.227966
SCALE 1.000000 1.000000 1.000000
X -0.000001 -0.000000 1.000000
Y 0.000003 -1.000000 0.000000
Z 1.000000 0.000003 0.000001
I just want to be able to figure out how they did that in lr3d how to convert the information into angles etc for rotation . How did they get WRot = (0.000000,90.000000,180.000000) or LRot = (-42.001240,90.000000,129.411743) with just the offsett and x y z values , offset being it's location in the world from 0,0,0 like I said I am a total math idiot at this level so I need help . Another thing the bone has 4 values the first one is the x value with 0.0000 at the end makeing 4 values ok that maybe the quat or matrix3 values or something the last one is the offset with 1.000000 at the end the bones seem to follow that pattern x y z with 0 at the end and offset again with 1 at the end . so you can see how I am getting lost .Bone 2 of 73 <Bip01 Pelvis> parent <TAG_ORIGIN>:
WPos = (0.000000,1.218488,37.227966)
WRot = (0.000000,90.000000,180.000000)
--> Bone
-0.000001 -0.000000 1.000000 0.000000
0.000003 -1.000000 -0.000000 0.000000
1.000000 0.000003 0.000001 0.000000
0.000000 1.218488 37.227966 1.000000
--> Parent
0.000000 -1.000000 -0.000001 0.000000
1.000000 0.000000 0.000000 0.000000
0.000000 -0.000001 1.000000 0.000000
0.000002 -2.222280 0.000042 1.000000
--> Inverse Parent
0.000000 1.000000 0.000000 0.000000
-1.000000 0.000000 -0.000001 0.000000
-0.000001 0.000000 1.000000 0.000000
-2.222280 -0.000002 -0.000044 1.000000
--> Local
-0.000001 -0.000001 1.000000 0.000000
1.000000 0.000003 0.000001 0.000000
-0.000003 1.000000 0.000001 0.000000
-3.440805 -0.000002 37.227921 1.000000
LPos = (-3.440805,-0.000002,37.227921)
LRot = (-42.001240,90.000000,129.411743)
Hi me again 
Well I think I have something here
The bone in the xmodel_export file
Thanks for your time jv I appreciate it .
Well I think I have something here
The bone in the xmodel_export file
The same bone in the lr3d dump fileBONE 3
OFFSET -4.866636 1.218480 37.227966
SCALE 1.000000 1.000000 1.000000
X 0.008941 0.033732 -0.999391
Y 0.004871 -0.999420 -0.033689
Z -0.999948 -0.004567 -0.009100
The gmax listener windowBone 3 of 73 <Bip01 L Thigh> parent <Bip01 Pelvis>:
WPos = (4.866636,1.218493,37.227966)
WRot = (74.884132,-88.000313,-104.845436)
The angles seem reversed in gmax but are simular$.rotation = (matrix3 [0.008941,0.033732,-0.999391][0.004871,-0.999420,-0.033689][-0.999948,-0.004567,-0.009100][0,0,1])
(matrix3 [0.008941,0.033732,-0.999391] [0.004871,-0.99942,-0.033689] [-0.999948,-0.004567,-0.0091] [0,0,1])
b=$.rotation as eulerangles
(eulerAngles -105.116 88.0002 75.1548)
Ok smart guy you seem to know what you are talking about too bad I don'tjv_map wrote:Hmm well there is a 1-to-1 correspondence between the orthonormal matrix [X Y Z] and the associated normalized quaternion, but whether this approach is convenient really depends on the application.
....
....
Can't you rotate the bone directly using the [X Y Z] matrix?
Hmm well just to clarify things.. 3 angles mean nothing unless you know which convention is applied... similarly you cannot find 'the' 3 angles unless you specify the convention. Different programs can use different conventions. In this case there seems to be good correspondence between the numbers but in theory they could be completely different and still relate to the same rotation.
Matrices and quaternions are not bound to a specific convention. A quaternion can directly be converted to a 3x3 matrix and vice-versa. A matrix cannot always be converted to a set of angles, even if the convention is specified. This is because a fixed set of angles cannot describe all orientations (this is the Euler angle singularity a.k.a gimbal lock). The other way around (from angles to 3x3 matrix) is always possible (provided the convention is known).
WRot is world rotation, LRot is local rotation. WRot describes the orientation of the bone with respect to a global, fixed coordinate system (the origin of the model). LRot describes the orientation of the bone w.r.t to its parent bone.
I honestly don't know why lr3d gives you 4x4 matrices. In 3D space, there are only 6 degrees of freedom (3 translations and 3 rotations), so that in a 4x4 matrix there are 10 variables with redundant information.
It looks like the 3x3 section on the top left corner is the rotation matrix and the bottom row (the 1x3 section) is the offset. The 4th column seems to add no information.
Well hope at least this little story clarifies why you cannot compare lr3d angles with gmax angles
Matrices and quaternions are not bound to a specific convention. A quaternion can directly be converted to a 3x3 matrix and vice-versa. A matrix cannot always be converted to a set of angles, even if the convention is specified. This is because a fixed set of angles cannot describe all orientations (this is the Euler angle singularity a.k.a gimbal lock). The other way around (from angles to 3x3 matrix) is always possible (provided the convention is known).
WRot is world rotation, LRot is local rotation. WRot describes the orientation of the bone with respect to a global, fixed coordinate system (the origin of the model). LRot describes the orientation of the bone w.r.t to its parent bone.
I honestly don't know why lr3d gives you 4x4 matrices. In 3D space, there are only 6 degrees of freedom (3 translations and 3 rotations), so that in a 4x4 matrix there are 10 variables with redundant information.
It looks like the 3x3 section on the top left corner is the rotation matrix and the bottom row (the 1x3 section) is the offset. The 4th column seems to add no information.
Well hope at least this little story clarifies why you cannot compare lr3d angles with gmax angles
well still don't understand but
xmodel_export ( bones listed 0 to 72)
xmodel_export ( bones listed 0 to 72)
lr3d dump file ( bones listed 1 to 73)BONE 51
OFFSET 18.615028 -13.125027 40.729116
SCALE 1.000000 1.000000 1.000000
X 0.521571 -0.691415 -0.499909
Y 0.718469 0.039903 0.694413
Z -0.460180 -0.721355 0.517573
my maxscript mbones[bn][10] to [12] are x values [13] to [15] are y values and [16] to [18] are z values from xmodel_export fileBone 52 of 73 <TAG_WEAPON_LEFT> parent <Bip01 L Hand>:
WPos = (18.615028,-13.125027,40.729115)
WRot = (-53.301407,-29.993980,52.970814)
gmax listener window
a=b.pos
b.rotation= inverse ( matrix3[mbones[bn][10],mbones[bn][11],mbones[bn][12]][mbones[bn][13],mbones[bn][14],mbones[bn][15]][mbones[bn][16],mbones[bn][17],mbones[bn][18]][0,0,1])
--inverse(matrix3 x y z [0,0,1]))
b.pos = a
rotateing in gmax seems to change the position of the model but after restoreing it's position the ( inverse ) angles from gmax match the angles from the lr3d dump file although not exactly . I am just wondering how this relates to animation which will be a change in position and angles . If I apply the rotation first then set the position and then the key frame I wonder if I can reproduce the animation that is in this form$.rotation as eulerangles
(eulerAngles -54.3405 27.3987 54.0223)
FRAME 26
PART 0
OFFSET 31.521326 -12.612732 38.596418
SCALE 1.000000 1.000000 1.000000
X -0.867006 -0.365461 -0.338731
Y 0.497697 -0.601747 -0.624659
Z 0.024458 -0.710168 0.703607
PART 1
OFFSET 47.410333 -2.438188 35.440558
SCALE 1.000000 1.000000 1.000000
X -0.476539 -0.877572 -0.052698
Y 0.876466 -0.469545 -0.106465
Z 0.068686 -0.096923 0.992919


