LDraw.org Discussion Forums
Problem with transformation matrices on some parts - Printable Version

+- LDraw.org Discussion Forums (https://forums.ldraw.org)
+-- Forum: LDraw Programs (https://forums.ldraw.org/forum-7.html)
+--- Forum: LDraw File Processing and Conversion (https://forums.ldraw.org/forum-22.html)
+--- Thread: Problem with transformation matrices on some parts (/thread-27276.html)



Problem with transformation matrices on some parts - Florentin - 2023-04-08

Howdy!
I hope I am on the correct forum with this post Tongue
 
So I am trying to program a 3d viewer for my files for my website. And I got most stuff working, but now I noticed that when loading some parts, such as 4733 (Brick, Modified 1 x 1 with Studs on 4 Sides), two of the studs are oriented the wrong way (as you can see in the picture i uploaded): they are flipped on their axes, the other studs aren't though.
And so I looked into the ldr file of the part 4733 itself where the studs themselves are being rotated (line 116-120) and I noticed that the studs that are wrongly rotated on my viewer are the 2nd and 5th entry (line 117 and 120) there. And I looked at their transformation matrices and they seem kinda wrong.
So I looked into those matrices more and it kinda looks like the axis that those matrices flip (which is what the "-" does), should be on the other axis, so the entry in line 117 should actually be "1 16 10 10 0 0 1 0 -1 0 0 0 0 1 stud2a.dat" and in line 120 it should be "1 16 0 10 10 1 0 0 0 0 -1 0 1 0 stud2a.dat".
The matrices look like the creator of the ldr part switched up the matrix multiplication, like the flipping of the two axes and the invertion of the axis, cause if you take those matrices apart and switch them around (you flip the part where the "-" is as explained above) you end up with the correct transformation matrix.

Is it normal that those matrices are just wrong? Or do I not completely understand the ldraw standard in a way that you can't just take the vertices and transform them using those matrices?

Thanks for your help!

(I also have some problems with some of the "4-4ndis.dat" transformations in this and a few other parts, though I haven't looked into that yet, you can kinda see it on the attached picture though that the scaling in the y direction is wrong, might just be an error in my code who knows, I'll look into that )
(If I haven't explained some stuff properly feel free to ask!)
(If you want to look at the code I wrote for this: link, but it's not optimised yet and I've commented some stuff out since I work directly in the deployment branch Tongue and the zip library makes my automatic deployment fail xD)


RE: Problem with transformation matrices on some parts - Magnus Forsberg - 2023-04-08

No, you are correct. Two stud primitives are incorrectly flipped in 4733, and should be corrected.
Stud primitives should be rotated into the wanted position. Never fipped.
(The only exception is the bottom stud that is always used mirrored, but only on the y-axis.  https://www.ldraw.org/library/primref/#studstud )


LDraw uses a right-handed co-ordinate system where -Y is "up".
https://www.ldraw.org/article/218.html#coords


RE: Problem with transformation matrices on some parts - Florentin - 2023-04-08

first
(2023-04-08, 11:57)Magnus Forsberg Wrote: No, you are correct. Two stud primitives are incorrectly flipped in 4733, and should be corrected.
Stud primitives should be rotated into the wanted position. Never fipped.
(The only exception is the bottom stud that is always used mirrored, but only on the y-axis.  https://www.ldraw.org/library/primref/#studstud )


LDraw uses a right-handed co-ordinate system where -Y is "up".
https://www.ldraw.org/article/218.html#coords

How come that softwares that use ldraw (like Studio) render them correctly? Do they manually check each part if they are correct and so they pretty much have their own library or how does that work?
Almost every brick that I render has some kind of problem (I put an Studio vs my software example into the attachements).
So is there a general rule how to deal with this? I mean even the website here is rendering the stuff correctly: https://library.ldraw.org/official/9458
So there must be some kind of trickery to fix that.

Mabye my code is just poo, though I just can't figure out what exactly is wrong, it's pretty much only parsing the lines and then recusively multiplying the matrices with the vertices, not very complex, oh well

EDIT: Ok i fixed the studs issues: I flipped the matrix intake around, not reading in the first 3x3 part where the rotation happens column first but row first and now I just have some random triangles flying around on some parts, so it's better but not fully correct yet (see last 2 pictures)!


RE: Problem with transformation matrices on some parts - Travis Cobbs - 2023-04-09

(2023-04-08, 12:25)Florentin Wrote: How come that softwares that use ldraw (like Studio) render them correctly? Do they manually check each part if they are correct and so they pretty much have their own library or how does that work?

No. You're not reading the matrices correctly. They are all consistent in LDraw parts.


(2023-04-08, 12:25)Florentin Wrote: EDIT: Ok i fixed the studs issues: I flipped the matrix intake around, not reading in the first 3x3 part where the rotation happens column first but row first and now I just have some random triangles flying around on some parts, so it's better but not fully correct yet (see last 2 pictures)!

I think you still aren't reading the matrix information correctly. LDView reads the components from the type 1 line in the following order:

Code:
lineType colorNumber x y z a b c d e f g h i

These then go into a 16-float transformation matrix like so:

Code:
    m_matrix[3] = 0.0f;
    m_matrix[7] = 0.0f;
    m_matrix[11] = 0.0f;
    m_matrix[15] = 1.0f;
    m_matrix[0] = a;
    m_matrix[4] = b;
    m_matrix[8] = c;
    m_matrix[1] = d;
    m_matrix[5] = e;
    m_matrix[9] = f;
    m_matrix[2] = g;
    m_matrix[6] = h;
    m_matrix[10] = i;
    m_matrix[12] = x;
    m_matrix[13] = y;
    m_matrix[14] = z;

If I had to guess, your x y z values are in the wrong place, but I could be wrong.


RE: Problem with transformation matrices on some parts - Florentin - 2023-04-10

So you want me to read in the values like this?
Code:
const splittedLine = this.splitter(line, " ", 14);
let transform = new Matrix4();

transform.set(
  parseFloat(splittedLine[5]), parseFloat(splittedLine[8]), parseFloat(splittedLine[11]), 0,
  parseFloat(splittedLine[6]), parseFloat(splittedLine[9]), parseFloat(splittedLine[12]), 0,
  parseFloat(splittedLine[7]), parseFloat(splittedLine[10]), parseFloat(splittedLine[13]), 0,
  parseFloat(splittedLine[2]), parseFloat(splittedLine[3]), parseFloat(splittedLine[4]), 1
);

I use Threejs so the set method puts in the values row first into the matrix (I assume that's how you put the values into your matrix).
That results in an also incorrect result (see pic 1).

I think your reading of the values is wrong, because this is how i learned that you multiply homogeneous matrices and points the 3d space (unless you meant column first inserting into the matrix, cause then I'd be the same as I read in the values first but well that's because I made this post Big Grin):
Code:
a b c x         u
d e f y     *   v
g h i z         w
0 0 0 1         1



RE: Problem with transformation matrices on some parts - Jonathan N - 2023-04-10

(2023-04-10, 11:00)Florentin Wrote: So you want me to read in the values like this?
Code:
const splittedLine = this.splitter(line, " ", 14);
let transform = new Matrix4();

transform.set(
  parseFloat(splittedLine[5]), parseFloat(splittedLine[8]), parseFloat(splittedLine[11]), 0,
  parseFloat(splittedLine[6]), parseFloat(splittedLine[9]), parseFloat(splittedLine[12]), 0,
  parseFloat(splittedLine[7]), parseFloat(splittedLine[10]), parseFloat(splittedLine[13]), 0,
  parseFloat(splittedLine[2]), parseFloat(splittedLine[3]), parseFloat(splittedLine[4]), 1
);

I use Threejs so the set method puts in the values row first into the matrix (I assume that's how you put the values into your matrix).
That results in an also incorrect result (see pic 1).

I think your reading of the values is wrong, because this is how i learned that you multiply homogeneous matrices and points the 3d space (unless you meant column first inserting into the matrix, cause then I'd be the same as I read in the values first but well that's because I made this post Big Grin):
Code:
a b c x         u
d e f y     *   v
g h i z         w
0 0 0 1         1

Different libraries have different conventions for how the matrix entries are initialized and accessed. You should be able to call the decompose function on your matrix to double check that it's working properly. The translation, scale, and rotation vectors should match what you expect if everything is working properly. I would also double check the matrix multiplication itself since A*B != B*A in general.


RE: Problem with transformation matrices on some parts - Florentin - 2023-04-10

(2023-04-10, 14:07)Jonathan N Wrote: Different libraries have different conventions for how the matrix entries are initialized and accessed. You should be able to call the decompose function on your matrix to double check that it's working properly. The translation, scale, and rotation vectors should match what you expect if everything is working properly. I would also double check the matrix multiplication itself since A*B != B*A in general.
I may have found the problem....
So I am writing an io file parser, not one for specifically an ldr file. And those .io files have three ldr files in them. One of them has all resolved subparts (or whatever you call them Big Grin) in them so you don't need to load all the needed files for that but have them all things you need in just one. And I was always working with that file (it's the "model2.ldr" one).
And what could be is that this file just has wrong values in it... at least that's what I do expect rn Tongue


RE: Problem with transformation matrices on some parts - Max Murtazin - 2023-04-10

(2023-04-10, 15:05)Florentin Wrote: I may have found the problem....
So I am writing an io file parser, not one for specifically an ldr file. And those .io files have three ldr files in them. One of them has all resolved subparts (or whatever you call them Big Grin) in them so you don't need to load all the needed files for that but have them all things you need in just one. And I was always working with that file (it's the "model2.ldr" one).
And what could be is that this file just has wrong values in it... at least that's what I do expect rn Tongue

You should use model.ldr file for .io-s


RE: Problem with transformation matrices on some parts - Florentin - 2023-04-12

(2023-04-10, 18:29)Max Murtazin Wrote: You should use model.ldr file for .io-s

So I have to resolve all of the parts and subparts manually to get a full mesh to display it ok.
Is there a way to differentiate if a reference (a Line Type 1) is leading to a part, a subpart or a primitive for easier fetching of the part? Is there a list or something where a program could look up each filename and find out what kind is being meant?


RE: Problem with transformation matrices on some parts - Max Murtazin - 2023-04-12

(2023-04-12, 18:43)Florentin Wrote: So I have to resolve all of the parts and subparts manually to get a full mesh to display it ok.
Is there a way to differentiate if a reference (a Line Type 1) is leading to a part, a subpart or a primitive for easier fetching of the part? Is there a list or something where a program could look up each filename and find out what kind is being meant?

Subparts always have the subparts directory in the filename, example:
1 16 0 0 0 1 0 0 0 1 0 0 0 1 s\subpart.dat

For primitives and parts, there is no way to differentiate. You should look up part in one directory, then, if failed, in other. You can cache paths to each part/primitive tho, and look up paths in it after — Studio does that for example, and since you work with it's file format you can grab it's cache from it's LDraw directory