I've been here before but I'm looking to find a single-pass method to input the LRS [[0,0,0],[0,0,0],[1,1,1]] and get a basic 3x4 (at least) matrix in return:

[
    [1,0,0,0],
    [0,1,0,0],
    [0,0,1,0]
]

^ matrix is NOT transposed (I'll never understand why we use column-major)

anyone got anything on this??

I've been here before

trust me, you don't want to see my current code. :P

also, please don't provide math references such as wikipedia...
I can read programming, not math.

meaning I can read v = sqrt( x ), not:
insert math algorithm here

Recommended Answers

All 20 Replies

not sure if this is right or not:

# ((lx,ly,lz),(rx,ry,rz),(sx,sy,sz))
cosx = cos(radians(rx)); sinx = sin(radians(rx))
cosy = cos(radians(ry)); siny = sin(radians(ry))
cosz = cos(radians(rz)); sinz = sin(radians(rz))
m = [
    [
        sx*(cosy*cosz),
        sx*(sinz*cosy),
        sx*-siny,
        sx*lx],
    [
        sy*(sinx * cosz * siny - cosx * sinz),
        sy*(sinx * sinz * siny + cosz * cosx),
        sy*(sinx * cosy),
        sy*ly],
    [
        sz*(sinx * sinz + cosx * cosz * siny),
        sz*(cosx * sinz * siny - sinx * cosz),
        sz*(cosx * cosy),
        sz*lz],
    [0.0,0.0,0.0,1.0]
]

there's also this, which doesn't work correctly:

cosx = cos(radians(rx)); sinx = sin(radians(rx))
cosy = cos(radians(ry)); siny = sin(radians(ry))
cosz = cos(radians(rz)); sinz = sin(radians(rz))
m = [
    [
        sx*cosy*cosz,
        sx*sinz*cosy,
        -sx*siny,
        0.0],
    [
        sy*(sinx*cosz*siny-cosx*sinz),
        sy*(sinx*sinz*siny+cosz*cosx),
        sy*sinx*cosy,
        0.0],
    [
        sz*(sinx*sinz+cosx*cosz*siny),
        sz*(cosx*sinz*siny-sinx*cosz),
        sz*cosx*cosy,
        0.0],
    [0.0,0.0,0.0,1.0]
]
m[0][3]= (lx*m[0][0]) + (ly*m[0][1]) + (lz*m[0][2])
m[1][3]= (lx*m[1][0]) + (ly*m[1][1]) + (lz*m[1][2])
m[2][3]= (lx*m[2][0]) + (ly*m[2][1]) + (lz*m[2][2])

I suppose you want to do rotations in 3D etc.?
The math involved can get quite complicated. (Try "quaternion")
So the only advise I can give is -you can hardly get around it- study some math about 3D matrix transformations. Alas, I believe there is no way around it.

I'm not provided a quaternion, I'm trying to calculate a bind matrix from eular LRS coords.

study some math about 3D matrix transformations

I've been trying, I can't read half the stuff out there (I can't read math)
and the other half doesn't work as everyone says it does.

the 2nd code I've tried was provided from BrawlBox:

[10:08:32 PM] BlackJax96: public static Matrix ReverseTransformMatrix(Vector3 scale, Vector3 rotation, Vector3 translation)
    {
        float cosx = (float)Math.Cos(rotation._x * Maths._deg2radf);
        float sinx = (float)Math.Sin(rotation._x * Maths._deg2radf);
        float cosy = (float)Math.Cos(rotation._y * Maths._deg2radf);
        float siny = (float)Math.Sin(rotation._y * Maths._deg2radf);
        float cosz = (float)Math.Cos(rotation._z * Maths._deg2radf);
        float sinz = (float)Math.Sin(rotation._z * Maths._deg2radf);

        scale._x = 1 / scale._x;
        scale._y = 1 / scale._y;
        scale._z = 1 / scale._z;
        translation._x = -translation._x;
        translation._y = -translation._y;
        translation._z = -translation._z;

        Matrix m;
        float* p = (float*)&m;

        p[0] = scale._x  cosy  cosz;
        p[1] = scale._y  (sinx  siny  cosz - cosx  sinz);
        p[2] = scale._z  (cosx  siny  cosz + sinx  sinz);
        p[3] = 0.0f;

        p[4] = scale._x  cosy  sinz;
        p[5] = scale._y  (sinx  siny  sinz + cosx  cosz);
        p[6] = scale._z  (cosx  siny  sinz - sinx  cosz);
        p[7] = 0.0f;

        p[8] = -scale._x * siny;
        p[9] = scale._y  sinx  cosy;
        p[10] = scale._z  cosx  cosy;
        p[11] = 0.0f;

        p[12] = (translation._x  p[0]) + (translation._y  p[4]) + (translation._z * p[8]);
        p[13] = (translation._x  p[1]) + (translation._y  p[5]) + (translation._z * p[9]);
        p[14] = (translation._x  p[2]) + (translation._y  p[6]) + (translation._z * p[10]);
        p[15] = 1.0f;

        return m;
    }
[10:08:47 PM] BlackJax96: sets it up inverted right away

and here's another one that was a transpose of my first code which I also tried: (didn't work)

[9:10:47 PM] BlackJax96: public static Matrix TransformMatrix(Vector3 scale, Vector3 rotate, Vector3 translate)
    {
        Matrix m;
        float* d = (float*)&m;

        float cosx = (float)Math.Cos(rotate._x * Maths._deg2radf);
        float sinx = (float)Math.Sin(rotate._x * Maths._deg2radf);
        float cosy = (float)Math.Cos(rotate._y * Maths._deg2radf);
        float siny = (float)Math.Sin(rotate._y * Maths._deg2radf);
        float cosz = (float)Math.Cos(rotate._z * Maths._deg2radf);
        float sinz = (float)Math.Sin(rotate._z * Maths._deg2radf);

        d[0] = scale._x  cosy  cosz;
        d[1] = scale._x  sinz  cosy;
        d[2] = -scale._x * siny;
        d[3] = 0.0f;
        d[4] = scale._y  (sinx  cosz  siny - cosx  sinz);
        d[5] = scale._y  (sinx  sinz  siny + cosz  cosx);
        d[6] = scale._y  sinx  cosy;
        d[7] = 0.0f;
        d[8] = scale._z  (sinx  sinz + cosx  cosz  siny);
        d[9] = scale._z  (cosx  sinz  siny - sinx  cosz);
        d[10] = scale._z  cosx  cosy;
        d[11] = 0.0f;
        d[12] = translate._x;
        d[13] = translate._y;
        d[14] = translate._z;
        d[15] = 1.0f;

        return m;
    }

EDIT: obtw, skype removed the * in most of his code, just think of them as there (I'd fixed them in my 2nd code)

What does eular LRS coords exactly mean? Are those Euler coordinates? Don't know what LRS is either.
I truly believe you that your code does not work.
Could I know WHAT is not working, I mean what error messages or strange behaviour do you get when you run or compile your program?

LRS = Loc Rot Sca:
[[LX,LY,LZ],[RX,RY,RZ],[SX,SY,SZ]]
defaulted LRS transformations look like this:
[[ 0.0, 0.0, 0.0 ],[ 0.0, 0.0, 0.0 ],[ 1.0, 1.0, 1.0 ]]

what's happening is the transformation from these to a local bind matrix does not equal the supplied bind matrix (in some model formats)
(VBN files only supply a bone's LRS whilst MDL0 everything needed)

what is "everything needed"?
- LRS (parent relation)
- Bind (parent relation)
- Inverse (world relation)

all that's needed for major application is the LRS, which calculates the bind matrix, which then calculates the inverse matrix.

also, I don't need to worry about compilation as I'm using Python 2.7
(don't scoff, it runs better than most would expect)
^ I don't follow the slow pythonic readability standards for one.

the error I'm getting is a zero division error, ultimately indicating the bind matrix was not calculated correctly (the world bind matrix (parent world bind * local bind) cannot be inverted)

EDIT: also excuse my typo, I'm used to seeing eular rather than euler

I'm used to seeing eular rather than euler

It's neither eular nor euler, it's Euler, as in, Leonhard Euler, one of the greatest mathematicians to ever walk this Earth. You can at least spell his name correctly, with a capital letter, he earned it. The greatest tragedy is probably that his name is most often heard as part of "Euler angles", when it's probably one of his least important contribution, and one he would probably want to retract from or eliminate if he was alive today (or at any time after Sir Hamilton's work, who came 100 years after Euler).

LRS = Loc Rot Sca:

Oh.... you wouldn't believe how much I hate the hap-hazard way in which all these 3D graphics people butcher their way through all this math. They always use the worst possible things, and making sure to pour a maximum amount of confusion over everything by omitting important details (that they might not even be aware of) and inventing their own stupid terms. And yes, they all say that they "don't read math" as an excuse for skipping the math, and thus, the understanding of what they're doing. As if saying that you are not an electrician is an excuse for making a fire-hazard out of your house's electrical wiring.

Here are a couple of important facts that are missing:

  • For the "location" vector (aka, a translation vector), in what coordinate system is it defined? Is it in "body-fixed" (pre-transform) frame? Or in "global" (post-transform) frame?
  • For the "rotation" angles, which kind of Euler angles does it refer to? There are 12 distinct kinds of Euler angles. People tend to refer to Euler angles as just one thing (often, without saying which), but Euler angles can have 12 distinct (and mutually incompatible) definitions. 3-2-1 (z-y-x) Euler angles are most often used in aeronautics (often called Tait-Bryan angles). 1-2-3 (x-y-z) Euler angles are sometimes used in 3D graphics due to mathematically-illiterate people mistaking them for 3-2-1 angles. And 3-1-3 (z-x-z) Euler angles are often used in robotics due to their connection with DH-parameters used to describe robots.
  • For the "scale" vector, in what coordinate system is it defined?
  • And finally, is the translation pre-scale or post-scale?

Basically, each of these transformations can be applied independently. Let's say t is the translation vector. Let's say R is the rotation matrix (3x3). Let's say S is the scaling matrix (3x3). And let's say that u is the pre-transform vector (aka body-fixed vector) and v is the post-transform vector (aka world / global coord. vector). Then, here are the different possibilities:

v = S * R * ( u + t )         (1)
v = S * ( R * u + t )         (2)
v = S * R * u + t             (3)
v = R * S * ( u + t )         (4)
v = R * ( S * u + t )         (5)
v = R * S * u + t             (6)

Each one of these will lead to a different homogeneous transformation matrix (the 4x4 matrix that you are trying to create). For example, the first formulation that you've posted (in your second post overall) corresponds to number (2) S * ( R * u + t ). And your second formulation (in your third post overall) corresponds to number (1) S * R * (u + t). And in both cases, you have formed your rotation matrix according to the formula for 3-2-1 (z-y-x) Euler angles (aka Tait-Bryan angles), which may or may not be correct for the Euler angles that you have.

If you want to remain oblivious about the math, or if you have insufficient details (those questions I asked, which will determine exactly what formulas you need to use), then you could simple try every possible combination (the equations (1)-(6) above) for every possible kind of Euler angles (the 12 kinds on the link I gave). At worst, there are 72 possibilities to try.

Here are some basic explanations of those six combinations that I put above:

  • When you see S applied after R, i.e. as S * R * .. or S * ( R *.., that corresponds to the scaling being applied in the post-transform / global / parent coordinate frame. Those are the equations (1)-(2)-(3). And in the opposite case, when scaling is applied in the pre-transform / body-fixed / local coordinate frame, you get equations (4)-(5)-(6).
  • When you see R being applied to t, like in equations (1), (4) and (5), then it means that the translation vector is applied in the body-fixed / local frame. And if not, like in equations (2), (3), and (6), then it means that the translation is done in the global / parent frame.
  • When you see S being applied to t, like in equations (1), (2) and (4), then it means that the translation vector is pre-scale (i.e., still needs to be scaled). And if not, like in equations (3), (5) and (6), then it means that the translation vector is post-scale (i.e., has already been scaled, doesn't need to be scaled again).

So, as you see, if you can answer my questions, you'll know exactly which combination to use, and if you can find out which Euler angles you are supposed to use, then that will tell you what the final formula to generate the 4x4 transformation matrix should be.

commented: Respect! +15

It's neither eular nor euler, it's Euler

oh bite me. lol
I know it's Euler, it's just the very first time I saw his name, it was commonly spelt Eular used in "Eular Angles" (sombody made a typo and used it throughout the page)

I've been more recently seeing Euler after constant corrections.
as far as the lowercase euler/eular, you'll see alot of that as you'll notice I don't use Shift much other than programming.

so yes, I know Euler is correct ok ;)

And yes, they all say that they "don't read math" as an excuse for skipping the math, and thus, the understanding of what they're doing.

I honestly havn't seen 1 person say they couldn't read math unless they were like age 12 or so.

I'm 23 and the highest math I can actually somewhat read is pre-algebra.
I blame my school on this for not working with me, I could do the work, but not fast, inevitably I failed the class 4 times over being caught up with a mountain of expected work that never got finished because of new work being piled on top of it.

so what happens when you put a slow person behind a mountain of paperwork?
they get overwhelmed trying to tackle all of it as demanded.

part 2 of that, I'm autistic to the point of I can't simply work on 1 thing w/o my mind drifting to another during the process of working on another thing...
yea, naturally I work on everything at once...

blah blah

so I literally can't read math, but I can read some programming ;)

also, whenever somebody tells me how to do something, once the thing works I (unlike alot of people) actually LIKE looking into and understanding the logic behind how it works (this is prbly another part of my autism).

so I don't just shove it aside and forget about it, I try to modify it and make it better (if I can see the logic, I can rule out what's not needed).
I have a visual mind, so making a 3D model of the logic to a process is easy for me. :)
___

anyways, continuing on our topic:

-for each factor of the LRS, like I said, it's parent relation (transformation applies to the parent bone or object).

-for rotation, I'm only guessing the data I typically work with for 3D models is XYZ, but this is required for my program, though expanding to make format support easier.

-the scale should be relatively obvious considering I'm working with 3D bones on animated models, but other than the top, I don't know much beyond what should be obvious:
[1.0,1.0,1.0] given as 3 32bit IEEE754 float values

And finally, is the translation pre-scale or post-scale?
parent relation.

if it was a pre-transformed (post-scale) coord, it would be either object or world relation.
___

I'll be honest when I say I've defined some of my own terms that just make sense for working with 3D data with a very basic level of understanding.
it really helps a basic noob understand what's what and then look into the details when they're ready.

I absolutely love the info you've provided, it'll really help aid in UMC's development :)

UMC = Universal Model Converter
it aids in providing a common interface between model formats with a very simple frontend for I/O conversion.

the problem I'm having... as I've stated above how bones are supplied with the LRS:
ugeSetBoneLoc( [X,Y,Z], Rel=UGE_PARENT )
among other relations: UGE_OBJECT and UGE_WORLD which also include inverse relation (6 total relations)

the issue is after the import process is complete and the supplied data is validated (and possibly transformed) accordingly.

during the validation is when the bind matrix is calculated from the LRS based on the relation.

also, my matrices are mainly 3x4 row-major, BlackJax used column-major which I had to transpose.
to give a better understanding:

m = [
    [1.0,0.0,0.0,0.0],
    [0.0,1.0,0.0,0.0],
    [0.0,0.0,1.0,0.0]
]

these specs were originaly derrived from Nintendo's GX standards.

EDIT:
oh yea, UGE is the final future name for my program, everything's labled UGE in UMC for future compatibility.

Ok.... Since none of what you said is particularly relevant, nor does it answer the critical questions, so I guess all I can say is good luck trying out those 72 possibilities until you find the one that works.

I tried to search for that VBN format and any reference to "LRS" transformations, but I didn't find anything at all. Do you have a link to the specifications for that file format? I would imagine that the specs would provide the answers that are needed to find the correct way to get a homogeneous transformation matrix out of these three vectors.

I'll be honest when I say I've defined some of my own terms that just make sense for working with 3D data with a very basic level of understanding.

Well, those invented terms might be more intuitive to you, but they just confuse everyone else, and when you need help, this becomes a real problem.

I'll never understand why we use column-major

It probably has something to do with the fact that you can do a Matrix-Vector multiplication with 7 SIMD instructions (e.g. in SSE or GLSL), instead of 16 instructions when the matrix is row-major. Such an optimization would significantly increase the frame rate you can get in a typical 3D game.

It probably has something to do with the fact that you can do a Matrix-Vector multiplication with 7 SIMD instructions (e.g. in SSE or GLSL), instead of 16 instructions when the matrix is row-major. Such an optimization would significantly increase the frame rate you can get in a typical 3D game.

ah, that explains alot, thanks :)

I tried to search for that VBN format

yea... good luck with that... it's a non-standard format used in WiiU games. (Smash 4 in particular)

Do you have a link to the specifications for that file format? I would imagine that the specs would provide the answers that are needed to find the correct way to get a homogeneous transformation matrix out of these three vectors.

best I got is a max-script which I made more readable: (I did not write this)
https://copy.com/wnsFsqIgMTMCQYCa

I only assume the format would be similar to GX which is practically a copy of GL.

hopefully this clears up alot of confusion. :)

EDIT:
also, those 72 possibilities, is that in total of everything or generalized for the local relations I've mentioned above??

The max-script clears up everything. The construction of the transformation is very easy to find and is very obvious (except that it is a row-major convention (and row-major memory layout too, see below), i.e., as in Direct3D):

append Trans_array [tx,ty,tz]
append Rotation_array [rx,ry,rz]
append Scale_array [sx,sy,sz]

tfm = scaleMatrix [Scale_array[x].x,Scale_array[x].y,Scale_array[x].z]
tfm = tfm * (rotateXMatrix (radToDeg Rotation_array[x].x)) * (rotateYMatrix (radToDeg Rotation_array[x].y)) * (rotateZMatrix (radToDeg Rotation_array[x].z))
tfm.row4 = [tx, ty, tz]

So, this is using the following case (case number (6) in my previous post):

v = R * S * u + t

and it is using 3-2-1 (Z-Y-X) Euler angles.

This corresponds to the following formula for the transformation matrix (taken straight from the wikipedia page):

# ((lx,ly,lz),(rx,ry,rz),(sx,sy,sz))
cosx = cos(radians(rx)); sinx = sin(radians(rx))
cosy = cos(radians(ry)); siny = sin(radians(ry))
cosz = cos(radians(rz)); sinz = sin(radians(rz))
m = [
    [
        sx*(cosy * cosz),
        sy*(cosz * siny * sinx - cosx * sinz),
        sz*(sinz * sinx + cosz * cosx * siny),
        lx],
    [
        sx*(cosy * sinz),
        sy*(cosz * cosx + sinz * siny * sinx),
        sz*(cosx * sinz * siny - cosz * sinx),
        ly],
    [
        sx*(-siny),
        sy*(cosy * sinx),
        sz*(cosy * cosx),
        lz],
    [0.0,0.0,0.0,1.0]
]

However, the max-script uses "radToDeg" function, which would seem to imply that the angles in the file are in radians, which would mean that you probably don't have to use the radians() function (which I assume converts degrees to radians), this is something that you can easily test whether you need it or not (if the angles in the file are between [-180,180] (deg) or [-3.14159,3.14159] (rad)).

N.B.: About the conventions and memory-layouts. Basically, the first one is a mathematical convention (how you work out the math) and the second is the physical layout of the values in memory. If, in your mathematical analysis, you adopt a row-major convention, it means that you treat vectors as row-vectors, and you apply rotations with a vector-matrix multiplication, like v = u * A. In this case, you would typically adopt a row-major memory layout for the rotation matrix A, this is what Direct3D uses in its documentation and implementation. However, if you adopt a column-major convention for your mathematical equations, it means that you treat vectors as column-vectors, and you apply rotations with a matrix-vector multiplication, like v = R * u. This is by far the most common convention used everywhere (in fact, Direct3D's documentation is the only place I have ever seen the row-major convention being used, which has, unfortunately, infected a large portion of game development and confused countless programmers). When using a column-major convention, it makes most sense to adopt a column-major memory layout, which is what OpenGL uses. As it turns out, in terms of memory layout, both are equivalent in the sense that numbers all end up at the same place in memory, that is, the last 4 values are the three translation values and the value 1.0, which is more efficient, as I pointed out earlier (i.e., "row-major convention" + "row-major layout" == "column-major convention" + "column-major layout"). This is because transpose(A) == R. Where it gets confusing is that the order of multiplication gets reversed when applying chains of transformations. For example, in the max-script that you posted, the matrices are multiplied as S * Ax * Ay * Az in row-major convention, which is equivalent to Rz * Ry * Rx * S in column-major convention, which is how I know that they are using 3-2-1 Euler angles because the rotation matrix is R = Rz * Ry * Rx.

If you haven't realized by now... there is no way that you can avoid the math in this line of work.

If you haven't realized by now... there is no way that you can avoid the math in this line of work.

it just has to be written in a language I can understand ;)
that's why I say, I can read programming, not "math" (generalized from Algebra, Geometry, Calculus, etc...)

I know enough to distinguish multiplication:

programming:

X * Y

math:

XY (most common)
X(dot)Y

X x Y (idk why kids are brought up with this useless form)

and somewhat up to abs(x):

|x|

anything else beyond that is VERY spotty and likely inaccurate.

so how I understand math is more in the form of visual logic (connected wires or plumbing) rather than scribblings.

if you could draw me an animated logical diagram of the matrix compisition, I could understand the logic right off ;)
(don't worry, I'm not actually asking this) XD

this is something that you can easily test whether you need it or not (if the angles in the file are between [-180,180] (deg) or [-3.14159,3.14159] (rad)).

nice, thanks for the trick, I'll be sure to automate that. :)

many thanks for your help btw, and credit to you in my program. ;)

I'll definitely be looking back on this thread ;D

hmm... it's not working for me, but I guess that's because I'm working with HAL_Labs data for testing as I don't have my Sm4sh script finished yet...
(I'm still getting a zero-division error when trying to invert the calculated matrix)

I'm actually working with 2 formats, one of which supplies a pre-calculated bind matrix...

if you like, I could pick a few random bones, and give you the LRS and bind matrix from each. :)

the final result of the LRS should be equal to the bind matrix.
(Nintendo has followed these standards for a while, and I would assume they're the same for the WiiU)

you know what... screw it, I'll supply them anyways... lol
(better to have and not need than need and not have)

so here's a few I've gathered:

L,R,S = [
    [0.44889798760414124, 0.1223910003900528, 0.0013589999871328473],
    [0.0, 0.0, -16.0],
    [1.0, 1.0, 1.0]
]
Bind = [
    [0.6608956456184387, 0.33116647601127625, -0.6729009747505188, 4.059491157531738], 
    [-0.6165885329246521, 0.7504630088806152, -0.23627883195877075, 4.750514507293701], 
    [0.42688220739364624, 0.571261465549469, 0.7004483938217163, 2.9311227798461914]
]

___

L,R,S = [
    [0.1946679949760437, -0.12830199301242828, 0.1703529953956604], 
    [0.0, 0.0, -30.999998092651367], 
    [1.0, 1.0, 1.0]
]
Bind = [
    [0.5526965260505676, 0.4909632205963135, -0.6729009747505188, 3.726905345916748], 
    [-0.7898590564727783, 0.5653401017189026, -0.23627883195877075, 4.5852155685424805], 
    [0.26449888944625854, 0.6623201370239258, 0.7004483938217163, 2.79695725440979]
]

___

L,R,S = [
    [2.1202890872955322, 0.15831099450588226, 1.5395879745483398], 
    [1.4400010108947754, -40.128997802734375, -5.828000068664551], 
    [1.0, 1.0, 1.0]
]
Bind = [
    [0.7605575919151306, 0.08539483696222305, -0.6434523463249207, 2.5371899604797363], 
    [-0.29965633153915405, 0.925436794757843, -0.23139162361621857, 5.243940830230713], 
    [0.5757672786712646, 0.36885541677474976, 0.7294885516166687, 1.3892587423324585]
]

hmm... I've just taken a look at something peculiar...
I think the bind matrix might be world-related like the inverse matrix:

LRS = [
    [0.5683010220527649, -0.0074629997834563255, -0.0009960000170394778],
    [0.8040000200271606, -1.0989999771118164, -4.820000171661377], [1.0, 1.0, 1.0]
]
Bind = [
    [0.7266270518302917, 0.13617964088916779, -0.6729009747505188, 3.717557191848755], 
    [-0.38587450981140137, 0.8914094567298889, -0.23627883195877075, 4.814953327178955], 
    [0.5678468346595764, 0.4314975440502167, 0.7004483938217163, 2.6224541664123535]
]
Inv = [
    [0.7270913124084473, -0.3861408829689026, 0.5682410597801208, -2.33393931388855], 
    [0.13625577092170715, 0.8919910192489624, 0.43178805708885193, -5.933778285980225], 
    [-0.6733837127685547, -0.23645290732383728, 0.7009947299957275, 1.803525686264038]
]

I'm gonna run some tests and figure some stuff out...
this certainly makes things more challenging >_>

ok, so after clearing up some things, I tested inverting both matrices.
they're extremely close, but not quite exact...
there's a number of things that could be affecting these results:

>>> C.MtxInvert([
    [0.7266270518302917, 0.13617964088916779, -0.6729009747505188, 3.717557191848755], 
    [-0.38587450981140137, 0.8914094567298889, -0.23627883195877075, 4.814953327178955], 
    [0.5678468346595764, 0.4314975440502167, 0.7004483938217163, 2.6224541664123535], [0,0,0,1]
]) # Bind

[[0.7270912904162441, -0.38614089044439986, 0.5682410338844875, -2.33393915744923], [0.136255773589964, 0.8919910472590854, 0.43178804933502485, -5.933778260839959], [-0.6733836833641111, -0.2364529140140324, 0.7009947471900231, 1.80352550461523], [0.0, 0.0, 0.0, 1.0]]

>>> C.MtxInvert([
    [0.7270913124084473, -0.3861408829689026, 0.5682410597801208, -2.33393931388855],
    [0.13625577092170715, 0.8919910192489624, 0.43178805708885193, -5.933778285980225],
    [-0.6733837127685547, -0.23645290732383728, 0.7009947299957275, 1.803525686264038], [0,0,0,1]
]) # Inv

[[0.7266270071379957, 0.13617962507179462, -0.6729009736330908, 3.7175572309958467], [-0.3858745188805423, 0.891409483077186, -0.2362788422370335, 4.814953485852354], [0.5678468367592743, 0.4314975455318444, 0.7004483826380686, 2.622454172720487], [0.0, 0.0, 0.0, 1.0]]

sure enough though, it's just as expected...
I'm guessing this must be for calculating exact matrix influences for weights...
idk though, but this is not what I was told before hand >_>

I'm such an idiot, IK what would help!

here's a bunch of bones (LRS and Bind) from the first translation to the first rotation:

[[0.0, 5.219711780548096, 0.0], [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]]
[[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 5.219711780548096], [0.0, 0.0, 1.0, 0.0]]

[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]]
[[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 5.219711780548096], [0.0, 0.0, 1.0, 0.0]]

[[0.0, -1.6129790544509888, -0.8781309723854065], [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]]
[[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 3.6067328453063965], [0.0, 0.0, 1.0, -0.8781309723854065]]

[[0.0, -0.6638270020484924, 0.1786549985408783], [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]]
[[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 2.942905902862549], [0.0, 0.0, 1.0, -0.6994760036468506]]

[[2.069999933242798, -0.44999998807907104, 0.4500359892845154], [2.9179999828338623, 26.40399932861328, -2.7890000343322754], [1.0, 1.0, 1.0]]
[[0.8945686221122742, 0.07120262086391449, 0.4410834014415741, 2.069999933242798], [-0.043578967452049255, 0.9963932633399963, -0.07245336472988129, 3.1567327976226807], [-0.44467437267303467, 0.045592956244945526, 0.8944531083106995, -0.4280949831008911]]

also, here's the MDL0 file I'm working with:
https://copy.com/6n2112LdYCgYYWby
for some info about the MDL0 format, you can take a look at my import script:
https://copy.com/yInBLKMOLfMnvQmP
it's not anything too legit... heh
but it should be able to tell you some of what you need to know up to MDL0 bones. :)

also, the reason it's called "MDL02", UMC accepts 2 types of vertices:
UnTransformed: (UT)
http://lh3.ggpht.com/-BpJs9PuVehA/VTHZs1EYmdI/AAAAAAAAI4E/vOQac0xlBRQ/s1152/trans2.png
PreTransformed: (PT)
http://lh3.ggpht.com/-jcAe5o-65KQ/VTEs44JFE7I/AAAAAAAAI3k/nt5Nm6G6RqE/s1152/bones.png

^I'm using the HAL_Labs scripts for those, but it's the same supplied data either way

so yea, the MDL0 script uses the PT methods, while MDL02 uses the new UT methods.

as far as UMC is currently concerned (until the rebuild where everything is much better), the bones and vertices are 2 completely separate things.

@mike_2000_17:
instead of doing this, would you like to help me out with my program's development??

otherwize, could you provided me some more descriptive notes about all of your knowledge :)
(I know this is a big thing, so I don't expect anything in short time)

if you could write out the algorithm's in python (not asking you to do my work), it would help out alot. :)
(I say python because I'm not good at reading anything other than JS, which I still suck at)

thanks. :)

so transformations.py as trans got me closer to what I wanted, though the positioning is still messed up:
[img]http://lh3.ggpht.com/-svj_HyX0QSk/VWPsXGVBqEI/AAAAAAAAJMI/17Htkvwp1yw/s802/HL_Bones.png[/img]
^ the bones are drawn using the inverse bind (the display method does not suppurt animation)

my code:

m = trans.compose_matrix(s,None,r,l,None)
dot = sys.modules['data.COMMON'].numpy.dot
inv = sys.modules['data.COMMON'].numpy.linalg.inv
if Rel==UGE_PARENT:
    bind = m
    wbind = dot(bind,pbind)
    invrs = inv(wbind)
#if Rel==UGE_OBJECT:
if Rel==UGE_WORLD:
    wbind = m
    invrs = inv(wbind)
    bind =  inv(dot(invrs,pbind))
if Rel==UGE_INVERSE_PARENT: # might be incorrect
    bind = inv(m)
    wbind = dot(bind,pbind)
    invrs = inv(wbind)
#if Rel==UGE_INVERSE_OBJECT:
if Rel==UGE_INVERSE_WORLD:
    invrs = m
    wbind = inv(wbind)
    bind = inv(dot(invrs,pbind))

bind=bind.tolist()
wbind=wbind.tolist()
invrs=invrs.tolist()

matrix format:

[
    [SX, R01, R02, LX],
    [R10, SY, R12, LY],
    [R20, R21, SZ, LZ],
    [0, 0, 0, 1]
]
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.