ArrayMesh created from GDScript uses +z as forward axis, is this intended?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Svalokai

Hi, I am working on a 3D platformer, and I have a need to generate 3D meshes from code. I built a simple helper tool in GDScript that runs as a scene in any project, and it will generate geometry based on different variables which can be set in the editor before running the scene (See link below for the script that I am using).

Before I start, here’s some system info: I am running Godot 3.2.1 stable on Arch Linux with an AMD Radeon RX580 GPU. I’m using the linux binary of Godot from the download page, not the package from Arch Linux’s User Repositories. I’m not using a DE, I’m running fluxbox via xinit as a window manager with pulseaudio for my interface to ALSA, and I’m running compton for window composition, not that any of that should have an effect on Godot, but who knows? I’m using the GLES 3.0 backend right now.

I normally just google things until I figure them out, but I couldn’t find anything in even the darkest crevices of the internet that clarified this issue, so if there is a link to the appropriate information, please provide it.

Also, I am asking this question here because I don’t think that this is a bug, but I am not completely sure about that, so if it is in actuality a bug, I can open an issue for it on github.

Here is my issue, I created a Star mesh to use as a KinematicBody in the project, but the “forward” axis of the generated mesh itself appears to be +z not -z. I’m designing my game with -z as forward, so that when I use the built-ins like look_at(), I get the expected behavior, so it’s important that I am able to consistently generate meshes with the correct “forward” axis.

The Star mesh that I am generating has two surfaces, one for the front of the star and one for the back, and I assign test materials to each of them to determine which is which when running the project. For some reason, the surface with vertices in positive z is considered the “forward” surface of the mesh, and the surface with vertices in negative z is considered the “backward” surface. I discovered this when I used the mesh as my character, and my follow camera showed what is supposed to be the front of the mesh (it should show the back of the mesh).

I also tested to make sure that it wasn’t an issue with my follow camera by adding another MeshInstance to the scene and having it look_at() the player character when the scene is loaded. The second mesh turns what is supposed to be the back of the mesh to face the player.

I made sure that there were no scaling or rotation issues with any of the involved transforms, and scaling the z-axis of the transform of the MeshInstance that contains the Star mesh to -1 flips it to the correct orientation as I would expect, so my only conclusion left is that the mesh resource being generated has +z as its forward axis.

I took a look at the source code on github for several of the involved classes: mesh, spatial, triangle_mesh, face3, geometry, etc… to see if I could find anything that indicates how generated meshes are assigned orientation axes, but I don’t have much experience with C++, so I had a lot of difficulty understanding the details of what each function was really doing. From what I did understand, it doesn’t look like this is a bug, but I could be wrong.

A quick disclaimer: I understand that both the front and back surface of the Star mesh are identical, and so it isn’t a big deal to have them flipped, but that is not the case for all geometry, and I want to make sure that I understand what the code is doing, so that I can accurately design my meshes.

If possible, please clarify which vertices should comprise the “forward” surface of a generated mesh.

Here’s a link to the full script that I am using:
https://gitlab.com/Svalokai/exampleprojects/-/blob/master/ScriptedGeometry.gd

I tried to include the script with tags, but it hit the character count.

I linked to the entire script for the tool in case there was something else in the script that was causing problems.
A few disclaimers:

  1. Sorry for the heavy use of comments. I’m pretty new to Trig and 3D programming, so I have to keep notes to myself about what each calculation is for.
  2. I know that this script doesn’t technically constitute a “tool” in GDScript, but I am using it as one, and I don’t want the code to actually run in the editor, only when I want to generate a new mesh, so I didn’t use the tool keyword on it.
  3. I realize that my functions might not be the best, and I certainly appreciate any constructive criticism that I can get on my code, but that is beyond the scope of this question, so I’m not worried about the quality of the script at this point, only its errors.

Lastly, I am currently working around this issue by swapping the surface0 and surface1 variables when assigning them to the Mesh.ARRAY_VERTEX array for surface generation. This gives me the correct surface orientations, but I need to make sure that this will be consistent.

Thanks in advance!

P.S. This is my first question for the Godot Community, so if I made any formatting/context errors, please let me know, and I will fix them.

:bust_in_silhouette: Reply From: Svalokai

Okay, I feel pretty stupid now.
I just figured out what the problem was.
Apparently, I messed up the winding order for the vertices in the triangles, so the reason why I thought that the vertices were mirrored on the z-axis is actually because I was looking at the back of the “front” face from behind, and the back of the “back” face from the front. I didn’t notice this because the mesh didn’t have normals for lighting calculation, since I was just doing basic testing.

I added manually calculated normals to the mesh generation script today, and I noticed that I was looking at the wrong side of the triangles that had been drawn. Reversing the winding order of the triangles in the script fixed the issue.

Thanks to anyone who took a look at this question.
I’m closing it out now.

Cheers.