Skip to content
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

Add manual slope painting tool #456

Merged
merged 9 commits into from
Oct 9, 2024
Merged

Conversation

Ryan-000
Copy link
Contributor

@Ryan-000 Ryan-000 commented Aug 15, 2024

Admin edit:
Fixes #282

  • Implements slope filtered painting, foliage
  • Reduces Brush / Advanced buttons to just icons to conserve space
  • Advanced button no longer pops up on hover
  • Removes picker icon file and uses icon embedded in the editor

It's useful when you need to paint slopes with different types of materials (because autoshader only supports 1 material).

exampleusage.webm

@TokisanGames
Copy link
Owner

TokisanGames commented Aug 15, 2024

Thank you. Please see issue #282. This should be a tool setting, similar to paintable scale and rotation, not a tool. That will allow it to provide a slider to adjust slope amount, or invert it, and affect all relevant tools such as overlay, base, color, wetness, holes, navigation, etc.

@Ryan-000
Copy link
Contributor Author

toolsetting.mp4

@az-raven
Copy link
Contributor

This looks really really helpful, thank you so so much for putting in the time to make this!

@TokisanGames
Copy link
Owner

TokisanGames commented Aug 19, 2024

Thank you for the changes. I tested it today. It's not very intuitive so I need to think about it and how to improve it or document it.

Some initial notes:

  • The effect of the default value of 70% is off from the effect of the shader auto_slope default value of 1. The numbers can be different, but the effect should be the same when using the default values. Then you could manually paint to perfectly align with the autoshader. If the numbers are the same even, better. We could adjust the shader calculation as well because 1 is meaningless. But what does 70% mean? Maybe both should represent an angle of 0-180 degrees. 🤔
  • Filling in holes (with CTRL) doesn't work while slope painting is enabled.
  • Painting holes w/ slope I think can be useful if you want to make a cave entrance in a wall without touching the floor. However there seems to be some inaccuracies in the calculation, producing this. I cannot get rid of this without disabling slope and painting regular. These inaccuracies may exist in all of the other tools as well, but I haven't noticed other than what is here:
    image
  • Slope 100% should be identical to off, right? So we could potentially leave it enabled all the time (removing the checkbox and skipping the get_normal code if slope ==100%). However it seems to be inaccurate. Here I used the nav brush to remove w/ slope @ 100% and it ignored the flattest areas
    image
  • Slope applying to foliage would also be useful. Are you leaving it for me to implement?

@TokisanGames TokisanGames added enhancement New feature or request usability UI interface labels Aug 19, 2024
@TokisanGames TokisanGames modified the milestone: Beta 0.9.x Aug 19, 2024
@Ryan-000
Copy link
Contributor Author

  • Slope applying to foliage would also be useful. Are you leaving it for me to implement?

Yes

@Ryan-000
Copy link
Contributor Author

image

It now uses degrees as an input when it's set to 0, slope painting is disabled.

@TokisanGames
Copy link
Owner

TokisanGames commented Aug 24, 2024

Oh, you definitely do not want to ever merge. That makes the commit history messy and breaks this PR. The proper operation is to rebase using the Godot PR Workflow linked in our contributing document. However that merge commit you just made needs to be removed first before we can rebase or merge this PR.

@Ryan-000 Ryan-000 force-pushed the paint_slope branch 2 times, most recently from e4a8303 to 52e47c9 Compare August 24, 2024 21:30
@TokisanGames TokisanGames changed the title Add manual slope painting tool WIP: Add manual slope painting tool Sep 14, 2024
@TokisanGames TokisanGames marked this pull request as draft September 14, 2024 14:03
@TokisanGames TokisanGames self-assigned this Sep 14, 2024
src/terrain_3d_editor.cpp Outdated Show resolved Hide resolved
@az-raven
Copy link
Contributor

Hi - I just wanted to check in, is there any way I can help out with this? I'm super excited to see this as a feature, it already seems incredibly helpful.

@TokisanGames
Copy link
Owner

It needs to be finished to work with the instancer. Now that I'm done with regions, I can work on this sometime before the next release.

If you want to help, you could do the legwork on the needed code. Should just be a matter of checking the slope and not calling the instancer, done all within Terrain3DEditor. It's probably 2-4 lines of code.

@az-raven
Copy link
Contributor

Great! If I get the chance (I have some IRL things tomorrow) I'll take a shot at it. Thanks for the update. If I get it working, should I comment with a patch or request changes?

@TokisanGames
Copy link
Owner

Comment here. Only Op and I can make changes to the PR.

@az-raven
Copy link
Contributor

az-raven commented Sep 28, 2024

I did not get the chance to work on this tonight as I got super swamped today, but I will do my best to get things working tomorrow.

@az-raven
Copy link
Contributor

Here's what I've gotten working:

I put the diff within this fold-out to keep things less cluttered.
diff --git a/project/addons/terrain_3d/src/ui.gd b/project/addons/terrain_3d/src/ui.gd
index f8d170a..de97f32 100644
--- a/project/addons/terrain_3d/src/ui.gd
+++ b/project/addons/terrain_3d/src/ui.gd
@@ -220,10 +220,9 @@ func _on_tool_changed(p_tool: Terrain3DEditor.Tool, p_operation: Terrain3DEditor
                        to_show.push_back("remove")
 
                Terrain3DEditor.INSTANCER:
-                       # if you want, you can add this, but you'll have to modify terrain_3d_instances.cpp to support it
-                       # eg, it would be useful to avoid placing instances on steep hills
-                       #to_show.push_back("invert_slope_paint")
-                       #to_show.push_back("minimum_slope_paint_angle_degrees")
+                       to_show.push_back("invert_slope_paint")
+                       to_show.push_back("minimum_slope_paint_angle_degrees")
+                       set_menu_visibility(tool_settings.slope_list, true)
                        to_show.push_back("size")
                        to_show.push_back("strength")
                        set_menu_visibility(tool_settings.height_list, true)
diff --git a/src/terrain_3d_editor.cpp b/src/terrain_3d_editor.cpp
index 2e61e81..db003bc 100644
--- a/src/terrain_3d_editor.cpp
+++ b/src/terrain_3d_editor.cpp
@@ -297,7 +297,7 @@ void Terrain3DEditor::_operate_map(const Vector3 &p_global_position, const real_
                                        // Shader scale array is aligned to match this.
                                        std::array<uint32_t, 8> scale_align = { 5, 6, 7, 0, 1, 2, 3, 4 };
 
-                                       if (!_can_operate_on_slope(brush_global_position)) {
+                                       if (!can_operate_on_slope(brush_global_position)) {
                                                continue;
                                        }
 
@@ -409,7 +409,7 @@ void Terrain3DEditor::_operate_map(const Vector3 &p_global_position, const real_
                                        dest = Color(as_float(bits), 0.f, 0.f, 1.f);
 
                                } else if (map_type == Terrain3DStorage::TYPE_COLOR) {
-                                       if (!_can_operate_on_slope(brush_global_position)) {
+                                       if (!can_operate_on_slope(brush_global_position)) {
                                                continue;
                                        }
 
@@ -445,7 +445,7 @@ void Terrain3DEditor::_operate_map(const Vector3 &p_global_position, const real_
        storage->add_edited_area(edited_area);
 }
 
-bool Terrain3DEditor::_can_operate_on_slope(const Vector3 &p_brush_global_position) {
+bool Terrain3DEditor::can_operate_on_slope(const Vector3 &p_brush_global_position) {
        const real_t minimum_slope_paint_angle_degrees = _brush_data["minimum_slope_paint_angle_degrees"];
        const bool invert_slope_paint = _brush_data["invert_slope_paint"];
 
diff --git a/src/terrain_3d_editor.h b/src/terrain_3d_editor.h
index f09caa3..438d0d1 100644
--- a/src/terrain_3d_editor.h
+++ b/src/terrain_3d_editor.h
@@ -82,7 +82,6 @@ private:
        void _region_modified(const Vector3 &p_global_position, const Vector2 &p_height_range = Vector2());
        void _operate_region(const Vector3 &p_global_position);
        void _operate_map(const Vector3 &p_global_position, const real_t p_camera_direction);
-       bool _can_operate_on_slope(const Vector3 &p_brush_global_position);
        bool _is_in_bounds(const Vector2i &p_position, const Vector2i &p_max_position) const;
        real_t _get_brush_alpha(const Vector2i &p_position) const;
        Vector2 _get_uv_position(const Vector3 &p_global_position, const int p_region_size) const;
@@ -109,6 +108,7 @@ public:
        void operate(const Vector3 &p_global_position, const real_t p_camera_direction);
        void stop_operation();
        bool is_operating() const { return _pending_undo; }
+       bool can_operate_on_slope(const Vector3 &p_brush_global_position);
 
 protected:
        static void _bind_methods();
diff --git a/src/terrain_3d_instancer.cpp b/src/terrain_3d_instancer.cpp
index 8dbcac0..6b5248a 100644
--- a/src/terrain_3d_instancer.cpp
+++ b/src/terrain_3d_instancer.cpp
@@ -222,6 +222,8 @@ void Terrain3DInstancer::add_instances(const Vector3 &p_global_position, const D
        real_t random_hue = CLAMP(real_t(p_params.get("random_hue", 0.f)) / 360.f, 0.f, 1.f); // degrees -> 0-1
        real_t random_darken = CLAMP(real_t(p_params.get("random_darken", 0.f)) * .01f, 0.f, 1.f); // 0-100%
 
+       Terrain3DEditor* editor = _terrain->get_editor();
+
        TypedArray<Transform3D> xforms;
        TypedArray<Color> colors;
        for (int i = 0; i < count; i++) {
@@ -240,6 +242,10 @@ void Terrain3DInstancer::add_instances(const Vector3 &p_global_position, const D
                        position.y = height;
                }
 
+               if (!editor->can_operate_on_slope(position)) {
+                       continue;
+               }
+
                // Orientation
                Vector3 normal = Vector3(0.f, 1.f, 0.f);
                if (align_to_normal) {

I made _can_operate_on_slope into a public method (wasn't sure if this is the right way, but it prevents a lot of code duplication) and used it to filter each instance based on its position. If you have a more preferred way to go about this, please let me know!

Super happy to help out!

@az-raven
Copy link
Contributor

az-raven commented Sep 29, 2024

Ahh I'm so sorry. I had forgotten about that use-case. I'll do my best to revise it to work properly.

@az-raven
Copy link
Contributor

I may be misunderstanding something here, but it seems as though putting the call there would not work as intended. Since that section of terrain_3d_editor works based off the brush position (rather than the per-instance position) it would just filter the entire brush based off its center rather than each instance based off its position. Was that the intended behavior, or am I misinterpreting your advice?

@TokisanGames
Copy link
Owner

TokisanGames commented Sep 30, 2024

That's probably true. Alright then I'd say Editor::can_operate_on_slope(position) should be moved to Storage::is_in_slope(position, angle) then both editor and instancer can call it, and it can access Storage directly. Instancer should be able to operate entirely without the editor. The only call is a backup function specifically for the editor's needs, that nullifies itself when not in use. However this PR is a bit out of date with the new structure and you can't update it. So I'd suggest letting me get to it in a while, I'll rebase it, look at your patch, and refactor it.

@az-raven What would help us move closer to releasing 0.9.3 is helping to wrap up the things in the left column on the project board. Any of the bottom 5 issues would be great to tackle.

@az-raven
Copy link
Contributor

Great! I'll do my best to help out with those as soon as I handle my homework for the week.

@TokisanGames TokisanGames added this to the Beta 0.9.x milestone Oct 6, 2024
@TokisanGames
Copy link
Owner

@Ryan-000 Thanks for taking it on. The improvements are much better and simpler.

The priority for this has finally come up.

I don't think there's any need for slope on auto/navigation/holes. It will just lead to missing vertices that don't get filled in. I limited it to paint, spray, color, wetness, foliage.

This update:

  • Removed some old slope UI code
  • Reduced the size of brush and advanced buttons down to the texture and dots
  • UI now sets all three modifiers in the brush_settings dictionary
  • Removed normal interpolation

Todo:

  • foliage

@az-raven
Copy link
Contributor

az-raven commented Oct 8, 2024

I don't think there's any need for slope on auto/navigation/holes.

Hi - I don't mean to intrude, but I feel as though slope filtering on navigation would be extremely useful for a variety of use cases. I believe it would particularly simplify the workflow for large terrains or when trying to be consistent with what areas are navigable. That said, I would still love to hear your thoughts on the matter.

@TokisanGames
Copy link
Owner

Godot navigation is not robust. One shouldn't just draw a massive area covering all paths and pass that to Godot and expect it will generate a good result. It needs to be refined a bit, and segmented into areas.

Second, slope occurs per pixel, so will produce non-contiguous application. This is fine for texturing but terrible for holes and navigation generation.

Third, when users remove slope enabled navigation, they're going to leave pixels behind. We don't need to create more problems and complaints due to the navigation server doing weird things because we're feeding it garbage data.

@az-raven
Copy link
Contributor

az-raven commented Oct 8, 2024

That makes sense. Thank you for the clarification!

@TokisanGames
Copy link
Owner

TokisanGames commented Oct 8, 2024

Updated the slope method based on discord discussions. This has resulted in a double slider that eliminates the need for invert. Set the range you want and paint. It's the most intuitive option I've seen so far. Please try it out in the push build (edit: Oh, actually Ryan has his builds disabled and I haven't enabled pull request builds yet, so you'll have to build from source or just take my word for it).

image

{5BA0CA78-9023-48F9-91E0-F99EF3B3823C}

I'll tackle foliage tomorrow probably.

@Ryan-000
Copy link
Contributor Author

Ryan-000 commented Oct 9, 2024

Sadly, I can't compile it and test it out right now. But I’ll mention that it’s very important to have a feature to quickly invert/uninvert the slope range. For example, if it was set to 0-45°, inverting it (maybe by pressing "slope" or using the current angle range) would switch it to 45-90°.

This would make it much easier to paint as users can quickly switch between painting the steep slope, and the flat top surface, without having to fiddle with the slider every time.

It would be even nicer to have the option to set different slope ranges for each material, so instead of needing two clicks (selecting the texture and inverting the slope), it could be done in one.

scons: Reading SConscript files ...
Auto-detected 24 CPU cores available for build parallelism. Using 23 cores by default. You can override it with the -j argument.
Building for architecture x86_64 on platform linux
scons: done reading SConscript files.
scons: Building targets ...
scons: `godot-cpp/bin/libgodot-cpp.linux.template_debug.x86_64.a' is up to date.
Compiling shared src/generated_texture.cpp ...
Compiling shared src/geoclipmap.cpp ...
Compiling shared src/register_types.cpp ...
Compiling shared src/terrain_3d.cpp ...
Compiling shared src/terrain_3d_assets.cpp ...
Compiling shared src/terrain_3d_data.cpp ...
Compiling shared src/terrain_3d_editor.cpp ...
Compiling shared src/terrain_3d_instancer.cpp ...
Compiling shared src/terrain_3d_material.cpp ...
Compiling shared src/terrain_3d_mesh_asset.cpp ...
Compiling shared src/terrain_3d_region.cpp ...
Compiling shared src/terrain_3d_storage.cpp ...
Compiling shared src/terrain_3d_texture_asset.cpp ...
Compiling shared src/terrain_3d_util.cpp ...
In file included from src/terrain_3d.h:17,
                 from src/register_types.cpp:7:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/core/object.hpp:38,
                 from godot-cpp/include/godot_cpp/core/method_ptrcall.hpp:36,
                 from godot-cpp/include/godot_cpp/core/binder_common.hpp:36,
                 from godot-cpp/include/godot_cpp/core/method_bind.hpp:34,
                 from godot-cpp/include/godot_cpp/core/class_db.hpp:38,
                 from src/register_types.cpp:4:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/generated_texture.cpp:6:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/image.hpp:37,
                 from godot-cpp/gen/include/godot_cpp/classes/rendering_server.hpp:36,
                 from src/generated_texture.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_instancer.cpp:5:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/resource_saver.hpp:37,
                 from src/terrain_3d_instancer.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_region.cpp:5:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/resource_saver.hpp:37,
                 from src/terrain_3d_region.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_assets.cpp:8:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/environment.hpp:36,
                 from src/terrain_3d_assets.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_storage.cpp:9:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/file_access.hpp:37,
                 from src/terrain_3d_storage.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_editor.cpp:7:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/core/object.hpp:38,
                 from godot-cpp/gen/include/godot_cpp/classes/undo_redo.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/editor_undo_redo_manager.hpp:36,
                 from src/terrain_3d_editor.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_instancer.cpp: In member function 'void Terrain3DInstancer::add_instances(const godot::Vector3&, const godot::Dictionary&)':
src/terrain_3d_instancer.cpp:264:21: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  264 |                 if (isnan(height)) {
      |                     ^~~~~
      |                     std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_instancer.cpp:274:29: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  274 |                         if (isnan(normal.x)) {
      |                             ^~~~~
      |                             std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/geoclipmap.cpp:6:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/image.hpp:37,
                 from godot-cpp/gen/include/godot_cpp/classes/rendering_server.hpp:36,
                 from src/geoclipmap.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_material.cpp:13:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/core/object.hpp:38,
                 from godot-cpp/gen/include/godot_cpp/classes/engine.hpp:37,
                 from src/terrain_3d_material.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_instancer.cpp: In member function 'void Terrain3DInstancer::update_transforms(const godot::AABB&)':
src/terrain_3d_instancer.cpp:542:53: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  542 |                                                 if (isnan(height)) {
      |                                                     ^~~~~
      |                                                     std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_editor.cpp: In member function 'void Terrain3DEditor::_operate_map(const godot::Vector3&, real_t)':
src/terrain_3d_editor.cpp:231:77: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  231 |                                                 } else if (modifier_alt && !isnan(p_global_position.y)) {
      |                                                                             ^~~~~
      |                                                                             std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_editor.cpp:245:77: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  245 |                                                 } else if (modifier_alt && !isnan(p_global_position.y)) {
      |                                                                             ^~~~~
      |                                                                             std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_editor.cpp:261:53: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  261 |                                                 if (isnan(left)) {
      |                                                     ^~~~~
      |                                                     std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_editor.cpp:265:53: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  265 |                                                 if (isnan(right)) {
      |                                                     ^~~~~
      |                                                     std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_editor.cpp:269:53: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  269 |                                                 if (isnan(up)) {
      |                                                     ^~~~~
      |                                                     std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_editor.cpp:273:53: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  273 |                                                 if (isnan(down)) {
      |                                                     ^~~~~
      |                                                     std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d_editor.cpp: In lambda function:
src/terrain_3d_editor.cpp:525:32: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  525 |                         return isnan(height) ? 0.f : height;
      |                                ^~~~~
      |                                std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d.cpp:21:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/node.hpp:37,
                 from godot-cpp/gen/include/godot_cpp/classes/node3d.hpp:37,
                 from godot-cpp/gen/include/godot_cpp/classes/collision_shape3d.hpp:36,
                 from src/terrain_3d.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d.cpp: In member function 'void Terrain3D::_generate_triangle_pair(godot::PackedVector3Array&, godot::PackedVector2Array*, int32_t, Terrain3DData::HeightFilter, bool, int32_t, int32_t) const':
src/terrain_3d.cpp:696:22: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  696 |                 if (!isnan(v1.y) && !isnan(v2.y) && !isnan(v3.y)) {
      |                      ^~~~~
      |                      std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d.cpp:715:22: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  715 |                 if (!isnan(v1.y) && !isnan(v2.y) && !isnan(v3.y)) {
      |                      ^~~~~
      |                      std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d.cpp: In member function 'void Terrain3D::update_region_labels()':
src/terrain_3d.cpp:886:34: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  886 |                         pos.y = (isnan(height)) ? 0 : height;
      |                                  ^~~~~
      |                                  std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
src/terrain_3d.cpp: In member function 'godot::Vector3 Terrain3D::get_intersection(const godot::Vector3&, const godot::Vector3&)':
src/terrain_3d.cpp:1204:21: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
 1204 |                 if (isnan(point.y)) {
      |                     ^~~~~
      |                     std::isnan
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
scons: *** [src/generated_texture.os] Error 1
scons: *** [src/register_types.os] Error 1
scons: *** [src/geoclipmap.os] Error 1
scons: *** [src/terrain_3d_storage.os] Error 1
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_data.cpp:10:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/dir_access.hpp:37,
                 from src/terrain_3d_data.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_texture_asset.cpp:5:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/image.hpp:37,
                 from src/terrain_3d_texture_asset.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_util.cpp:6:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/core/object.hpp:38,
                 from godot-cpp/gen/include/godot_cpp/classes/engine.hpp:37,
                 from src/terrain_3d_util.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
In file included from src/terrain_3d.h:17,
                 from src/logger.h:8,
                 from src/terrain_3d_mesh_asset.cpp:12:
src/terrain_3d_data.h: In member function 'uint32_t Terrain3DData::get_control(const godot::Vector3&) const':
src/terrain_3d_data.h:266:17: error: 'isnan' was not declared in this scope; did you mean 'std::isnan'?
  266 |         return (isnan(val)) ? UINT32_MAX : as_uint(val);
      |                 ^~~~~
      |                 std::isnan
In file included from godot-cpp/include/godot_cpp/core/math.hpp:38,
                 from godot-cpp/include/godot_cpp/variant/vector3.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/plane.hpp:35,
                 from godot-cpp/include/godot_cpp/variant/aabb.hpp:34,
                 from godot-cpp/gen/include/godot_cpp/variant/builtin_types.hpp:36,
                 from godot-cpp/include/godot_cpp/variant/variant.hpp:36,
                 from godot-cpp/include/godot_cpp/core/property_info.hpp:38,
                 from godot-cpp/include/godot_cpp/classes/wrapped.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/object.hpp:37,
                 from godot-cpp/include/godot_cpp/classes/ref.hpp:36,
                 from godot-cpp/gen/include/godot_cpp/classes/editor_interface.hpp:37,
                 from src/terrain_3d_mesh_asset.cpp:3:
/usr/include/c++/12/cmath:632:5: note: 'std::isnan' declared here
  632 |     isnan(_Tp __x)
      |     ^~~~~
scons: *** [src/terrain_3d_region.os] Error 1
scons: *** [src/terrain_3d_editor.os] Error 1
scons: *** [src/terrain_3d_assets.os] Error 1
scons: *** [src/terrain_3d_instancer.os] Error 1
scons: *** [src/terrain_3d_texture_asset.os] Error 1
scons: *** [src/terrain_3d_material.os] Error 1
scons: *** [src/terrain_3d_mesh_asset.os] Error 1
scons: *** [src/terrain_3d_util.os] Error 1
scons: *** [src/terrain_3d.os] Error 1
scons: *** [src/terrain_3d_data.os] Error 1
scons: building terminated because of errors.

@TokisanGames
Copy link
Owner

TokisanGames commented Oct 9, 2024

I have reinstated the std:: namespace on isnan for linux. You should be able to build now.

I have enabled the invert key CTRL to inverse the operation, so now if the range is 37-60 the inverted range will be "not 37-60" or 0-37 and 60-90.

Pressing "Slope" resets the values to default (0-90/disabled) as it does for all non-checkbox options.

@TokisanGames
Copy link
Owner

TokisanGames commented Oct 9, 2024

Instancer has been implemented. Thanks @az-raven.

I instead used Alt to reverse the slope. Paint color + CTRL, Instancer + CTRL already removes, so conflicted. I need to document all of the keyboard operations, so drafted them below.

This is almost ready to merge. The last thing is that the embedded editor picker icon doesn't work in compatibility mode. I might have to revert the file.

General Keys

  • LMB - Click the terrain to positively apply the current tool.
  • Ctrl + LMB - Inverse the tool. Removes regions, height, color, wetness, autoshader, holes, navigation, foliage.
  • Shift + LMB - Change to the Smooth sculpting tool if shift is the only modifier pressed.
  • Ctrl + Z - Undo. You can also view the operations in Godot's History panel.
  • Ctrl + Shift + Z - Redo.
  • Ctrl + S - Save the scene and all data.

Sculpting Specific

  • Alt + LMB - Lift floors. This lifts up lower portions of the terrain without affecting higher terrain around it. Use it along the bottom of cliff faces. See videos demonstrating before and after.
  • Ctrl + Alt + LMB - Flatten peaks. The inverse of the above. This reduces peaks and ridges without affecting lower terrain around it.

Slope Operations Specific

These operations support slope: Paint, Spray, Color, Wetness, Instancer.

  • LMB - Operate within the set slope.
  • Alt + LMB - Operate outside the set slope.
  • Ctrl + Alt + LMB - Inversely operate outside the set slope. eg. Remove color or foliage outside the defined slope setting.

Instancer Specific

  • LMB - Add the selected mesh instance to the terrain.
  • Ctrl + LMB - Remove instances of the selected type.
  • Ctrl + Shift + LMB - Remove instances of any type.

@TokisanGames TokisanGames changed the title WIP: Add manual slope painting tool Add manual slope painting tool Oct 9, 2024
@TokisanGames TokisanGames marked this pull request as ready for review October 9, 2024 12:24
@TokisanGames
Copy link
Owner

  • Fixed the wonky slider.
  • Fixed the broken slope sculpt brush picker icons

This one is finished. Thanks for the help guys. Any more bug fixes or improvements can go in another PR. Good job everyone.

@TokisanGames TokisanGames merged commit 8955064 into TokisanGames:main Oct 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request usability UI interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Imlement Painting by Slope tool setting
4 participants