Skip to content

Dumping world mesh into .obj files - inverted X and Z axis #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Elgcahlxukuth opened this issue Aug 17, 2023 · 9 comments
Open

Dumping world mesh into .obj files - inverted X and Z axis #2

Elgcahlxukuth opened this issue Aug 17, 2023 · 9 comments
Assignees
Labels
bug Something isn't working

Comments

@Elgcahlxukuth
Copy link

Elgcahlxukuth commented Aug 17, 2023

Hi,

I'm not sure if you are aware of this, but in Gothic .zen file for some reason the vertices in world mesh are stored in a funny order, that is: Z, Y, X. Therefore, when you dump world mesh inso .obj file you must consider that when writing v ... ... ... line to the file.

So here:

out << "v " << item.x << " " << item.y << " " << item.z << "\n";

it should rather be out << "v " << item.z << " " << item.y << " " << item.x << "\n";,
but only in case if we are dealing with world mesh. (I think other meshes have the proper order)

The world mesh .obj file rendered currently:
image
as you can see the world looks as if seen in a mirror - things that should be on the left side are on the right. Moreover, both the normal vectors (the vn ... ... lines in .obj) and texture coordinates (the vt ... ... lines) seem to be defined with the above assumptions regarding the vertice orders. Hence, you can notice some strange artifacts when rendering, like objects being seen through, objects being lit on the bottom even though I set a source of directional sun light from above the scene, etc.

Here is how the .obj file is rendered after making the change in the source code:
image
looks correct.

Cheers :)

@lmichaelis
Copy link
Member

Hey! Yes that's a good point :) Do you know whether that applies to normals too?

@Elgcahlxukuth
Copy link
Author

Elgcahlxukuth commented Aug 17, 2023

image

Do you know whether that applies to normals too?

Normals and textures coordinates are OK the way they are now in the code.
The only line that requires a modification is the one i referenced.

@Elgcahlxukuth Elgcahlxukuth changed the title Dumping world mesh into .obj files - inverted X and Y axis Dumping world mesh into .obj files - inverted X and Z axis Aug 17, 2023
@lmichaelis lmichaelis self-assigned this Aug 17, 2023
@lmichaelis lmichaelis added the bug Something isn't working label Aug 17, 2023
@Elgcahlxukuth
Copy link
Author

Elgcahlxukuth commented Aug 17, 2023

Fun fact:
it is possible to make the mesh work properly, that is without artifacts or lighting errors, while still keeping the XYZ order of vertices. The world will ofcourse still look inverted as in mirror, but in case anyone would like to introduce hard difficulty mode to the game by mirroring the world :)
image
to achieve that, one must revert the order of vertices in polygon definition (the f ... ... ... line in .obj).
(This is because by default in .obj file vertices are put in clockwise order, and that defines the "front" and "back" sides of a polygon. When the X and Z axis are swapped, the polygon gets flipped in the space, and that must be reflected in its definition as well)

@Elgcahlxukuth
Copy link
Author

Elgcahlxukuth commented Aug 18, 2023

I made some additional tests with increased lighting (higher value of specular Ks in .mtl file, more intensive sun light source above the scene). Turns out the axis of normals (vn ... ... ... in .obj) should also be swapped.

Current normals look:
image
Seems weird that surface that is seen from angle is more lit.

Swapped axis normals look:
image
Seems natural that surface I'm facing directly is more lit (sun rays goes from above, vertically, no angle, vector [0, -1, 0]).
The effect is more obvious when moving the camera around.

So this line also needs modification:

out << "vn " << feat.normal.x << " " << feat.normal.y << " " << feat.normal.z << "\n";

Sorry for missleading you before.
I also double checked the texture coordinates, but these are fine.

@Elgcahlxukuth
Copy link
Author

BTW. if the glm::vec3::z in phoenix::mesh::vertices[] stores the x value, then it is actually the phoenix lib that represents the data in a wrong way... so I would consider fixing the other repo instead. Although I know it may be inconvenient since the lib is already used by people. Funny thing is that I was unable to find x/z coords swapping in Open Gothic project. I asked Try if he dealt with that issue.

@lmichaelis
Copy link
Member

Yea I mean that can also be solved by swapping the coordinates in a shader. Anyways, this is how it was intended in the original format so I'll load it as-is I think.

@Elgcahlxukuth
Copy link
Author

Elgcahlxukuth commented Aug 18, 2023

(...), this is how it was intended in the original format so I'll load it as-is I think.

The original format does not contain names for the values. It is the phoenix who gives names to values, so it should do this properly. Next person who will use phoenix might be confused becouse of this. I figured this out relatively soon since I remember the mirror world effect from one of the discussion over ReGoth project few years ago.

But I'm not gonna insist, just sharing my point of view, the decision is yours :)

@Elgcahlxukuth
Copy link
Author

I would create a pull request myself, but I'm haveing some issues with github authentication :/
So just letting you know, the proto_mesh seems to also require the fix (I just loaded HUM_BODY_NAKED0.MDM and found that out):

out << "v " << item.x << " " << item.y << " " << item.z << "\n";

out << "vn " << item.normal.x << " " << item.normal.y << " " << item.normal.z << "\n";

@Elgcahlxukuth
Copy link
Author

Elgcahlxukuth commented Sep 29, 2023

OK... so yesterday I've learnt what is the source of that issue. Previously I thought this is just Gothic being weird, storing [x,y,z] values in reverse order for no reason. That is not the case.

In general, there are different coordinates systems used in software. For example, DirectX uses left-handed coordinate system while OpenGL uses right-handed.
image

It seems Gothic uses left-hand coordinate system.
From phoenix lib user perspective, depending on what renderer he uses, the Gothic data will be suited for him, or it will require a coversion to another coordinate system.
In my case I needed a conversion. At first tried to swap X and Z coordinates, but now I realised a better solution is to just negate the Z coordinate (Z = -Z), as that makes it easier to deal with rotation matrix (also stored for VOBs positions in .zen files), and other things.

Conclusion:

  • we should not swap X and Z coordinates

  • it is up to the user to adapt Gothic data to his needs, depending on what renderer he uses.

btw. I'm sorry for missleading you with this topic :-/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants