Skip to content

Fix multiple issues with CSGPolygon #49313

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

Merged
merged 1 commit into from
Aug 12, 2021
Merged

Conversation

madmiraal
Copy link
Contributor

Currently, there are a number of issues with the way face vertices and UV mappings are created in CSGPolygon. This results in normals being inverted, UVs repeating when they shouldn't, and extrusions rotating when they shouldn't. This makes CSGPolygon practically unusable. Furthermore, each CSGPolygon extrusion mode has its own code, which not only results in a lot of duplicated code, but requires fixes to be applied in multiple places or issues occurring in one mode and not another. This PR fixes the issues and consolidates the code to provide a standard way of creating CSGPolygons.

To prevent the UV mapping from simply repeating on each end and each extrusion, I've taken the liberty of defining a UV mapping for the entire CSGPolygon: the top half is rolled around the extrusions (u along the the length of the extrusions and v around the outline of the 2D polygon shape) and the bottom half left and right sides are used for the front and end caps respectively.

So, for example this texture:
WoodFloor043_1K_Color
Maps to a sample CSGPolygon in MODE_SPIN, 270° like this:
CSGPolygon-Spin

In MODE_PATH, the path_continuous_u parameter (which now defaults to true to make it consistent with the other extrusion modes) can be set to false to create a repeating pattern along the length of the path as before:

path_continuous_u = true path_continuous_u = false
CSGPolygon-Path CSGPolygon-Path-Repeating

MODE_PATH's Path Rotation modes have been fixed so they do what I believe they were intended to do:

  • PATH_ROTATION_POLYGON: The polygon shape is not rotated.
  • PATH_ROTATION_PATH: The polygon shape is rotated along the path, but it is not rotated around the path axis.
  • PATH_ROTATION_PATH_FOLLOW: The polygon shape follows the path and it's rotations around the path axis.

In addition to making MODE_PATH's path_continuous_u parameter default to true, MODE_PATH's Path Rotation mode now defaults to PathFollow, because this is the mode most likely to provide a viable shape from a Path3D, and MODE_PATH's Path Interval property is now constrained to (0; 1].

Finally, the documentation has been updated to reflect both these changes and make some of the other settings clearer.

Closes #23257
Fixes #48233
Fixes #48408
Supersedes #48412

@stebulba
Copy link
Contributor

stebulba commented Jun 4, 2021

The code is clearer, I like it.
But my pull request have to rewrite : #41499

@madmiraal
Copy link
Contributor Author

@stebulba I haven't looked at #41499, but hopefully these changes will actually make it easier to implement godotengine/godot-proposals#1062 for all modes.

ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spin_degrees", PROPERTY_HINT_RANGE, "1,360,0.1"), "set_spin_degrees", "get_spin_degrees");
ADD_PROPERTY(PropertyInfo(Variant::INT, "spin_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_spin_sides", "get_spin_sides");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Path3D"), "set_path_node", "get_path_node");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_interval", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_path_interval", "get_path_interval");
Copy link
Contributor

@stebulba stebulba Jul 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change the range of path_interval from "0.001,1000.0,0.001,or_greater" to "0.1,1.0,0.1" ?
For exemple In my slide of my proposal I am using around "0.145".
at least should be "0.01,1.0,0.01" but in same time that limit us a lot in possibility.
Maybe can be "( 0.005 or 0.01 ),1.0,0.001" to save us a lot of process if we set path_interval to "0.001" accidentally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stebulba I assume you agree that it should never need to be greater than 1. Therefore, the question is about the minimum and the step size.

What is your use case for having a smaller minimum and/or smaller step sizes? Since path_interval simply sub-divides each extrusion without adding fidelity. If a user wants to increase the number of extrusions, I would expect the preferred approach to be to increase the number of points on the curve and leave path_interval at 1.

It's also worth pointing out that this is just a limitation in the editor. A minimum of 0.1 and a step size of 0.1 seemed reasonable for making adjustments in the editor. However, the user can always set the path interval to any value between (0:1] in code using set_path_interval() or the property path_interval.

Copy link
Contributor

@stebulba stebulba Jul 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand.

  • I used path_interval 0.152 and 360 points to do the 360 degrees.
  • For approximately the same result path_interval 1 and 60 points to do the 360 degrees.
    And the render I a lot better. This point is ok.

Edit [no bug found anymore]

@BastiaanOlij
Copy link
Contributor

I'm not sure I get the change for path_continuous_u, this was introduced to have the U follow the length of the extruded path. So it would be 0 at the start, and equal to the length of the path at the end. This allows using a tiled texture over the length of the path. A use case here is using CSGPolygon to extrude a road for a driving game where there is a nice repeating road texture.

It sounds like you're changing that behavior which is going to break peoples games.

I do agree that the UV mapping in CSGPolygon leaves a lot to be desired.

@madmiraal
Copy link
Contributor Author

I'm not sure I get the change for path_continuous_u

The only change made to path_continuous_u is the default. It now defaults to true. This makes it consistent with the other extrusion modes. Setting it to false still results in the old behaviour of creating a repeating pattern along the length of the path.

@stebulba
Copy link
Contributor

I found a bug. When you reverse the polygon like a mirror or you reverse one point, the mesh is not created as the previous version. This bug, broke my game.
What this change do :

bug_csg_3.X_after.change.mp4

What should do before your change :

no-bug_csg_3.3.2_stable_before.change.mp4

In my game this bug force me to invert face when this pull suppose to fixe it and the front and the back face is inverted with the sides faces.
image

@madmiraal
Copy link
Contributor Author

Fixed bug identified by @stebulba above, and increased the granularity of path_interval in the editor to 0.05 to allow values like 0.25.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with that code but from a quick look it seems sensible, and it fixes important issues.

@madmiraal
Copy link
Contributor Author

madmiraal commented Aug 12, 2021

Updated with suggested changes to the documentation and the error message.

@akien-mga akien-mga merged commit 2eb3c95 into godotengine:master Aug 12, 2021
@akien-mga
Copy link
Member

Thanks!

@madmiraal madmiraal deleted the fix-48408 branch August 12, 2021 09:43
@@ -2228,11 +2053,11 @@ void CSGPolygon3D::_bind_methods() {

ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Depth,Spin,Path"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_depth", "get_depth");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.01,100.0,0.01,or_greater,exp"), "set_depth", "get_depth");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there any particular reason to make this less granular, raise the minimum, and lower the maximum?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants