-
Notifications
You must be signed in to change notification settings - Fork 3k
Fixes terrain origin computing in the inverted pyramid slope terrain #4470
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
base: main
Are you sure you want to change the base?
Conversation
Greptile OverviewGreptile SummaryFixes terrain origin calculation for inverted pyramid slope terrain by introducing a configurable Key Changes:
Issues Found:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant pyramid_sloped_terrain
participant height_field_to_mesh_v2
participant convert_height_field_to_mesh
User->>pyramid_sloped_terrain: Call with difficulty, cfg
Note over pyramid_sloped_terrain: Decorated with @height_field_to_mesh_v2(terrain_origin_judge_width=1.0)
pyramid_sloped_terrain->>height_field_to_mesh_v2: Execute decorator wrapper
height_field_to_mesh_v2->>height_field_to_mesh_v2: Validate border_width
height_field_to_mesh_v2->>height_field_to_mesh_v2: Allocate height field buffer with border
height_field_to_mesh_v2->>pyramid_sloped_terrain: Call original function with adjusted cfg
pyramid_sloped_terrain-->>height_field_to_mesh_v2: Return height field array (z_gen)
height_field_to_mesh_v2->>convert_height_field_to_mesh: Convert heights to mesh
convert_height_field_to_mesh-->>height_field_to_mesh_v2: Return vertices, triangles
height_field_to_mesh_v2->>height_field_to_mesh_v2: Compute origin using terrain_origin_judge_width=1.0
Note over height_field_to_mesh_v2: Uses 1.0m square area instead of default 2.0m<br/>to avoid sampling outside platform in inverted pyramid
height_field_to_mesh_v2-->>User: Return [mesh], origin
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 files reviewed, 3 comments
| def height_field_to_mesh_v2(terrain_origin_judge_width: float = 2.0): | ||
| """ | ||
| the terrain origin is computed as the max in the square area around the center of the terrain, | ||
| the square width is `terrain_origin_judge_width` | ||
| """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docstring doesn't follow the same format as height_field_to_mesh. Should include Args, Returns sections and proper capitalization/punctuation
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| x1 = int((cfg.size[0] * 0.5 - terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | ||
| x2 = int((cfg.size[0] * 0.5 + terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | ||
| y1 = int((cfg.size[1] * 0.5 - terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | ||
| y2 = int((cfg.size[1] * 0.5 + terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | ||
| origin_z = np.max(heights[x1:x2, y1:y2]) * cfg.vertical_scale |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
potential index out of bounds if terrain_origin_judge_width is larger than the terrain size. Consider adding validation
| x1 = int((cfg.size[0] * 0.5 - terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | |
| x2 = int((cfg.size[0] * 0.5 + terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | |
| y1 = int((cfg.size[1] * 0.5 - terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | |
| y2 = int((cfg.size[1] * 0.5 + terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | |
| origin_z = np.max(heights[x1:x2, y1:y2]) * cfg.vertical_scale | |
| # compute origin | |
| if terrain_origin_judge_width > min(cfg.size[0], cfg.size[1]): | |
| raise ValueError( | |
| f"The terrain origin judge width ({terrain_origin_judge_width}) must be smaller than " | |
| f"the minimum terrain size ({min(cfg.size[0], cfg.size[1])})." | |
| ) | |
| x1 = int((cfg.size[0] * 0.5 - terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | |
| x2 = int((cfg.size[0] * 0.5 + terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | |
| y1 = int((cfg.size[1] * 0.5 - terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | |
| y2 = int((cfg.size[1] * 0.5 + terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) |
| x2 = int((cfg.size[0] * 0.5 + terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | ||
| y1 = int((cfg.size[1] * 0.5 - terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | ||
| y2 = int((cfg.size[1] * 0.5 + terrain_origin_judge_width / 2.0) / cfg.horizontal_scale) | ||
| origin_z = np.max(heights[x1:x2, y1:y2]) * cfg.vertical_scale |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if x1 >= x2 or y1 >= y2 due to rounding, np.max(heights[x1:x2, y1:y2]) will fail. Check that indices form valid slices
| @@ -77,6 +76,59 @@ def wrapper(difficulty: float, cfg: HfTerrainBaseCfg): | |||
| return wrapper | |||
|
|
|||
|
|
|||
| def height_field_to_mesh_v2(terrain_origin_judge_width: float = 2.0): | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, thank you for sharing the bug and potential fix.
This parameter terrain_origin_judge_width seems to depend a lot on the choice of the platform width size. I don't think hard-coding it here like this is the right solution.
The proper solution should be that the height-field generator also returns the origin. Then all this hard-coding logic inside height_field_to_mesh can be avoided.
2ef7fc8 to
f3061a4
Compare
Description
In
height_field_to_meshfunction, the terrain origin is computed as the max in the square area around the center of the terrain,and the square has a fixed width of 2 meters.
In inverted pyramid slope terrain, the default
platform_widthis1.0meter. Therefore the area outside the platform is also calculated in thenp.maxfunction. This caused the terrain origin to be a little higher than the ground. See theScreenshotsbelow. Non-inverted pyramid terrain do not have this problem because the function ismax.To fix, a param
terrain_origin_judge_widthis added to theheight_field_to_meshwrapper (default is 2.0 so the behaviour is same as before) and we can use decorator@height_field_to_mesh_v2(terrain_origin_judge_width=1.0)to change themaxfunction area. For the default platform 1.0 meter in inverted pyramid slope terrain, a half widthterrain_origin_judge_width=1.0is ok.Type of change
Screenshots
Please attach before and after screenshots of the change if applicable.
Checklist
pre-commitchecks with./isaaclab.sh --formatconfig/extension.tomlfileCONTRIBUTORS.mdor my name already exists there