diff options
Diffstat (limited to 'modules/gridmap')
-rw-r--r-- | modules/gridmap/config.py | 2 | ||||
-rw-r--r-- | modules/gridmap/doc_classes/GridMap.xml | 178 | ||||
-rw-r--r-- | modules/gridmap/grid_map.cpp | 263 | ||||
-rw-r--r-- | modules/gridmap/grid_map.h | 99 | ||||
-rw-r--r-- | modules/gridmap/grid_map_editor_plugin.cpp | 218 | ||||
-rw-r--r-- | modules/gridmap/grid_map_editor_plugin.h | 68 | ||||
-rw-r--r-- | modules/gridmap/icons/GridMap.svg | 6 | ||||
-rw-r--r-- | modules/gridmap/register_types.cpp | 8 | ||||
-rw-r--r-- | modules/gridmap/register_types.h | 4 |
9 files changed, 395 insertions, 451 deletions
diff --git a/modules/gridmap/config.py b/modules/gridmap/config.py index a6319fe1ea..720401b92d 100644 --- a/modules/gridmap/config.py +++ b/modules/gridmap/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return True + return not env["disable_3d"] def configure(env): diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index a213069e19..c1dbe63628 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -8,187 +8,136 @@ GridMaps use a [MeshLibrary] which contains a list of tiles. Each tile is a mesh with materials plus optional collision and navigation shapes. A GridMap contains a collection of cells. Each grid cell refers to a tile in the [MeshLibrary]. All cells in the map have the same dimensions. Internally, a GridMap is split into a sparse collection of octants for efficient rendering and physics processing. Every octant has the same dimensions and can contain several cells. + [b]Note:[/b] GridMap doesn't extend [VisualInstance3D] and therefore can't be hidden or cull masked based on [member VisualInstance3D.layers]. If you make a light not affect the first layer, the whole GridMap won't be lit by the light in question. </description> <tutorials> - <link>https://docs.godotengine.org/en/latest/tutorials/3d/using_gridmaps.html</link> + <link title="Using gridmaps">https://docs.godotengine.org/en/latest/tutorials/3d/using_gridmaps.html</link> + <link title="3D Platformer Demo">https://godotengine.org/asset-library/asset/125</link> + <link title="3D Kinematic Character Demo">https://godotengine.org/asset-library/asset/126</link> </tutorials> <methods> <method name="clear"> - <return type="void"> - </return> + <return type="void" /> <description> Clear all cells. </description> </method> <method name="clear_baked_meshes"> - <return type="void"> - </return> + <return type="void" /> <description> </description> </method> <method name="get_bake_mesh_instance"> - <return type="RID"> - </return> - <argument index="0" name="idx" type="int"> - </argument> + <return type="RID" /> + <argument index="0" name="idx" type="int" /> <description> </description> </method> <method name="get_bake_meshes"> - <return type="Array"> - </return> + <return type="Array" /> <description> + Returns an array of [ArrayMesh]es and [Transform3D] references of all bake meshes that exist within the current GridMap. </description> </method> <method name="get_cell_item" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="x" type="int"> - </argument> - <argument index="1" name="y" type="int"> - </argument> - <argument index="2" name="z" type="int"> - </argument> + <return type="int" /> + <argument index="0" name="position" type="Vector3i" /> <description> - The [MeshLibrary] item index located at the grid-based X, Y and Z coordinates. If the cell is empty, [constant INVALID_CELL_ITEM] will be returned. + The [MeshLibrary] item index located at the given grid coordinates. If the cell is empty, [constant INVALID_CELL_ITEM] will be returned. </description> </method> <method name="get_cell_item_orientation" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="x" type="int"> - </argument> - <argument index="1" name="y" type="int"> - </argument> - <argument index="2" name="z" type="int"> - </argument> + <return type="int" /> + <argument index="0" name="position" type="Vector3i" /> <description> - The orientation of the cell at the grid-based X, Y and Z coordinates. -1 is returned if the cell is empty. + The orientation of the cell at the given grid coordinates. [code]-1[/code] is returned if the cell is empty. </description> </method> - <method name="get_collision_layer_bit" qualifiers="const"> - <return type="bool"> - </return> - <argument index="0" name="bit" type="int"> - </argument> + <method name="get_collision_layer_value" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="layer_number" type="int" /> <description> - Returns an individual bit on the [member collision_layer]. + Returns whether or not the specified layer of the [member collision_layer] is enabled, given a [code]layer_number[/code] between 1 and 32. </description> </method> - <method name="get_collision_mask_bit" qualifiers="const"> - <return type="bool"> - </return> - <argument index="0" name="bit" type="int"> - </argument> + <method name="get_collision_mask_value" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="layer_number" type="int" /> <description> - Returns an individual bit on the [member collision_mask]. + Returns whether or not the specified layer of the [member collision_mask] is enabled, given a [code]layer_number[/code] between 1 and 32. </description> </method> <method name="get_meshes"> - <return type="Array"> - </return> + <return type="Array" /> <description> - Returns an array of [Transform] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in world space. + Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in world space. </description> </method> <method name="get_used_cells" qualifiers="const"> - <return type="Array"> - </return> + <return type="Array" /> <description> Returns an array of [Vector3] with the non-empty cell coordinates in the grid map. </description> </method> <method name="make_baked_meshes"> - <return type="void"> - </return> - <argument index="0" name="gen_lightmap_uv" type="bool" default="false"> - </argument> - <argument index="1" name="lightmap_uv_texel_size" type="float" default="0.1"> - </argument> + <return type="void" /> + <argument index="0" name="gen_lightmap_uv" type="bool" default="false" /> + <argument index="1" name="lightmap_uv_texel_size" type="float" default="0.1" /> <description> </description> </method> <method name="map_to_world" qualifiers="const"> - <return type="Vector3"> - </return> - <argument index="0" name="x" type="int"> - </argument> - <argument index="1" name="y" type="int"> - </argument> - <argument index="2" name="z" type="int"> - </argument> + <return type="Vector3" /> + <argument index="0" name="map_position" type="Vector3i" /> <description> Returns the position of a grid cell in the GridMap's local coordinate space. </description> </method> <method name="resource_changed"> - <return type="void"> - </return> - <argument index="0" name="resource" type="Resource"> - </argument> + <return type="void" /> + <argument index="0" name="resource" type="Resource" /> <description> </description> </method> <method name="set_cell_item"> - <return type="void"> - </return> - <argument index="0" name="x" type="int"> - </argument> - <argument index="1" name="y" type="int"> - </argument> - <argument index="2" name="z" type="int"> - </argument> - <argument index="3" name="item" type="int"> - </argument> - <argument index="4" name="orientation" type="int" default="0"> - </argument> - <description> - Sets the mesh index for the cell referenced by its grid-based X, Y and Z coordinates. + <return type="void" /> + <argument index="0" name="position" type="Vector3i" /> + <argument index="1" name="item" type="int" /> + <argument index="2" name="orientation" type="int" default="0" /> + <description> + Sets the mesh index for the cell referenced by its grid coordinates. A negative item index such as [constant INVALID_CELL_ITEM] will clear the cell. Optionally, the item's orientation can be passed. For valid orientation values, see [method Basis.get_orthogonal_index]. </description> </method> <method name="set_clip"> - <return type="void"> - </return> - <argument index="0" name="enabled" type="bool"> - </argument> - <argument index="1" name="clipabove" type="bool" default="true"> - </argument> - <argument index="2" name="floor" type="int" default="0"> - </argument> - <argument index="3" name="axis" type="int" enum="Vector3.Axis" default="0"> - </argument> + <return type="void" /> + <argument index="0" name="enabled" type="bool" /> + <argument index="1" name="clipabove" type="bool" default="true" /> + <argument index="2" name="floor" type="int" default="0" /> + <argument index="3" name="axis" type="int" enum="Vector3.Axis" default="0" /> <description> </description> </method> - <method name="set_collision_layer_bit"> - <return type="void"> - </return> - <argument index="0" name="bit" type="int"> - </argument> - <argument index="1" name="value" type="bool"> - </argument> + <method name="set_collision_layer_value"> + <return type="void" /> + <argument index="0" name="layer_number" type="int" /> + <argument index="1" name="value" type="bool" /> <description> - Sets an individual bit on the [member collision_layer]. + Based on [code]value[/code], enables or disables the specified layer in the [member collision_layer], given a [code]layer_number[/code] between 1 and 32. </description> </method> - <method name="set_collision_mask_bit"> - <return type="void"> - </return> - <argument index="0" name="bit" type="int"> - </argument> - <argument index="1" name="value" type="bool"> - </argument> + <method name="set_collision_mask_value"> + <return type="void" /> + <argument index="0" name="layer_number" type="int" /> + <argument index="1" name="value" type="bool" /> <description> - Sets an individual bit on the [member collision_mask]. + Based on [code]value[/code], enables or disables the specified layer in the [member collision_mask], given a [code]layer_number[/code] between 1 and 32. </description> </method> <method name="world_to_map" qualifiers="const"> - <return type="Vector3"> - </return> - <argument index="0" name="pos" type="Vector3"> - </argument> + <return type="Vector3i" /> + <argument index="0" name="world_position" type="Vector3" /> <description> Returns the coordinates of the grid cell containing the given point. [code]pos[/code] should be in the GridMap's local coordinate space. @@ -196,6 +145,9 @@ </method> </methods> <members> + <member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false"> + If [code]true[/code], this GridMap bakes a navigation region. + </member> <member name="cell_center_x" type="bool" setter="set_center_x" getter="get_center_x" default="true"> If [code]true[/code], grid items are centered on the X axis. </member> @@ -212,7 +164,7 @@ The scale of the cell items. This does not affect the size of the grid cells themselves, only the items in them. This can be used to make cell items overlap their neighbors. </member> - <member name="cell_size" type="Vector3" setter="set_cell_size" getter="get_cell_size" default="Vector3( 2, 2, 2 )"> + <member name="cell_size" type="Vector3" setter="set_cell_size" getter="get_cell_size" default="Vector3(2, 2, 2)"> The dimensions of the grid's cells. This does not affect the size of the meshes. See [member cell_scale]. </member> @@ -221,16 +173,18 @@ GridMaps act as static bodies, meaning they aren't affected by gravity or other forces. They only affect other physics bodies that collide with them. </member> <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1"> - The physics layers this GridMap detects collisions in. + The physics layers this GridMap detects collisions in. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. </member> <member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library"> The assigned [MeshLibrary]. </member> + <member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1"> + The navigation layers the GridMap generates its navigable regions in. + </member> </members> <signals> <signal name="cell_size_changed"> - <argument index="0" name="cell_size" type="Vector3"> - </argument> + <argument index="0" name="cell_size" type="Vector3" /> <description> Emitted when [member cell_size] changes. </description> diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 2975a97bfe..8e8b6f14ad 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,7 +31,7 @@ #include "grid_map.h" #include "core/io/marshalls.h" -#include "core/message_queue.h" +#include "core/object/message_queue.h" #include "scene/3d/light_3d.h" #include "scene/resources/mesh_library.h" #include "scene/resources/surface_tool.h" @@ -151,32 +151,58 @@ uint32_t GridMap::get_collision_mask() const { return collision_mask; } -void GridMap::set_collision_mask_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_mask(); +void GridMap::set_collision_layer_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive."); + uint32_t collision_layer = get_collision_layer(); if (p_value) { - mask |= 1 << p_bit; + collision_layer |= 1 << (p_layer_number - 1); } else { - mask &= ~(1 << p_bit); + collision_layer &= ~(1 << (p_layer_number - 1)); } - set_collision_mask(mask); + set_collision_layer(collision_layer); } -bool GridMap::get_collision_mask_bit(int p_bit) const { - return get_collision_mask() & (1 << p_bit); +bool GridMap::get_collision_layer_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive."); + return get_collision_layer() & (1 << (p_layer_number - 1)); } -void GridMap::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_layer(); +void GridMap::set_collision_mask_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive."); + uint32_t mask = get_collision_mask(); if (p_value) { - mask |= 1 << p_bit; + mask |= 1 << (p_layer_number - 1); } else { - mask &= ~(1 << p_bit); + mask &= ~(1 << (p_layer_number - 1)); } - set_collision_layer(mask); + set_collision_mask(mask); +} + +bool GridMap::get_collision_mask_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive."); + return get_collision_mask() & (1 << (p_layer_number - 1)); +} + +void GridMap::set_bake_navigation(bool p_bake_navigation) { + bake_navigation = p_bake_navigation; + _recreate_octant_data(); } -bool GridMap::get_collision_layer_bit(int p_bit) const { - return get_collision_layer() & (1 << p_bit); +bool GridMap::is_baking_navigation() { + return bake_navigation; +} + +void GridMap::set_navigation_layers(uint32_t p_layers) { + navigation_layers = p_layers; + _recreate_octant_data(); +} + +uint32_t GridMap::get_navigation_layers() { + return navigation_layers; } void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) { @@ -189,7 +215,6 @@ void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) { } _recreate_octant_data(); - _change_notify("mesh_library"); } Ref<MeshLibrary> GridMap::get_mesh_library() const { @@ -200,7 +225,7 @@ void GridMap::set_cell_size(const Vector3 &p_size) { ERR_FAIL_COND(p_size.x < 0.001 || p_size.y < 0.001 || p_size.z < 0.001); cell_size = p_size; _recreate_octant_data(); - emit_signal("cell_size_changed", cell_size); + emit_signal(SNAME("cell_size_changed"), cell_size); } Vector3 GridMap::get_cell_size() const { @@ -244,26 +269,26 @@ bool GridMap::get_center_z() const { return center_z; } -void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) { +void GridMap::set_cell_item(const Vector3i &p_position, int p_item, int p_rot) { if (baked_meshes.size() && !recreating_octants) { //if you set a cell item, baked meshes go good bye clear_baked_meshes(); _recreate_octant_data(); } - ERR_FAIL_INDEX(ABS(p_x), 1 << 20); - ERR_FAIL_INDEX(ABS(p_y), 1 << 20); - ERR_FAIL_INDEX(ABS(p_z), 1 << 20); + ERR_FAIL_INDEX(ABS(p_position.x), 1 << 20); + ERR_FAIL_INDEX(ABS(p_position.y), 1 << 20); + ERR_FAIL_INDEX(ABS(p_position.z), 1 << 20); IndexKey key; - key.x = p_x; - key.y = p_y; - key.z = p_z; + key.x = p_position.x; + key.y = p_position.y; + key.z = p_position.z; OctantKey ok; - ok.x = p_x / octant_size; - ok.y = p_y / octant_size; - ok.z = p_z / octant_size; + ok.x = p_position.x / octant_size; + ok.y = p_position.y / octant_size; + ok.z = p_position.z / octant_size; if (p_item < 0) { //erase @@ -286,7 +311,8 @@ void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) { //create octant because it does not exist Octant *g = memnew(Octant); g->dirty = true; - g->static_body = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC); + g->static_body = PhysicsServer3D::get_singleton()->body_create(); + PhysicsServer3D::get_singleton()->body_set_mode(g->static_body, PhysicsServer3D::BODY_MODE_STATIC); PhysicsServer3D::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id()); PhysicsServer3D::get_singleton()->body_set_collision_layer(g->static_body, collision_layer); PhysicsServer3D::get_singleton()->body_set_collision_mask(g->static_body, collision_mask); @@ -318,15 +344,15 @@ void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) { cell_map[key] = c; } -int GridMap::get_cell_item(int p_x, int p_y, int p_z) const { - ERR_FAIL_INDEX_V(ABS(p_x), 1 << 20, INVALID_CELL_ITEM); - ERR_FAIL_INDEX_V(ABS(p_y), 1 << 20, INVALID_CELL_ITEM); - ERR_FAIL_INDEX_V(ABS(p_z), 1 << 20, INVALID_CELL_ITEM); +int GridMap::get_cell_item(const Vector3i &p_position) const { + ERR_FAIL_INDEX_V(ABS(p_position.x), 1 << 20, INVALID_CELL_ITEM); + ERR_FAIL_INDEX_V(ABS(p_position.y), 1 << 20, INVALID_CELL_ITEM); + ERR_FAIL_INDEX_V(ABS(p_position.z), 1 << 20, INVALID_CELL_ITEM); IndexKey key; - key.x = p_x; - key.y = p_y; - key.z = p_z; + key.x = p_position.x; + key.y = p_position.y; + key.z = p_position.z; if (!cell_map.has(key)) { return INVALID_CELL_ITEM; @@ -334,15 +360,15 @@ int GridMap::get_cell_item(int p_x, int p_y, int p_z) const { return cell_map[key].item; } -int GridMap::get_cell_item_orientation(int p_x, int p_y, int p_z) const { - ERR_FAIL_INDEX_V(ABS(p_x), 1 << 20, -1); - ERR_FAIL_INDEX_V(ABS(p_y), 1 << 20, -1); - ERR_FAIL_INDEX_V(ABS(p_z), 1 << 20, -1); +int GridMap::get_cell_item_orientation(const Vector3i &p_position) const { + ERR_FAIL_INDEX_V(ABS(p_position.x), 1 << 20, -1); + ERR_FAIL_INDEX_V(ABS(p_position.y), 1 << 20, -1); + ERR_FAIL_INDEX_V(ABS(p_position.z), 1 << 20, -1); IndexKey key; - key.x = p_x; - key.y = p_y; - key.z = p_z; + key.x = p_position.x; + key.y = p_position.y; + key.z = p_position.z; if (!cell_map.has(key)) { return -1; @@ -350,20 +376,20 @@ int GridMap::get_cell_item_orientation(int p_x, int p_y, int p_z) const { return cell_map[key].rot; } -Vector3 GridMap::world_to_map(const Vector3 &p_world_pos) const { - Vector3 map_pos = p_world_pos / cell_size; - map_pos.x = floor(map_pos.x); - map_pos.y = floor(map_pos.y); - map_pos.z = floor(map_pos.z); - return map_pos; +Vector3i GridMap::world_to_map(const Vector3 &p_world_position) const { + Vector3 map_position = p_world_position / cell_size; + map_position.x = floor(map_position.x); + map_position.y = floor(map_position.y); + map_position.z = floor(map_position.z); + return Vector3i(map_position); } -Vector3 GridMap::map_to_world(int p_x, int p_y, int p_z) const { +Vector3 GridMap::map_to_world(const Vector3i &p_map_position) const { Vector3 offset = _get_offset(); Vector3 world_pos( - p_x * cell_size.x + offset.x, - p_y * cell_size.y + offset.y, - p_z * cell_size.z + offset.z); + p_map_position.x * cell_size.x + offset.x, + p_map_position.y * cell_size.y + offset.y, + p_map_position.z * cell_size.z + offset.z); return world_pos; } @@ -424,7 +450,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { * and set said multimesh bounding box to one containing all cells which have this item */ - Map<int, List<Pair<Transform, IndexKey>>> multimesh_items; + Map<int, List<Pair<Transform3D, IndexKey>>> multimesh_items; for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) { ERR_CONTINUE(!cell_map.has(E->get())); @@ -437,7 +463,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Vector3 cellpos = Vector3(E->get().x, E->get().y, E->get().z); Vector3 ofs = _get_offset(); - Transform xform; + Transform3D xform; xform.basis.set_orthogonal_index(c.rot); xform.set_origin(cellpos * cell_size + ofs); @@ -445,10 +471,10 @@ bool GridMap::_octant_update(const OctantKey &p_key) { if (baked_meshes.size() == 0) { if (mesh_library->get_item_mesh(c.item).is_valid()) { if (!multimesh_items.has(c.item)) { - multimesh_items[c.item] = List<Pair<Transform, IndexKey>>(); + multimesh_items[c.item] = List<Pair<Transform3D, IndexKey>>(); } - Pair<Transform, IndexKey> p; + Pair<Transform3D, IndexKey> p; p.first = xform; p.second = E->get(); multimesh_items[c.item].push_back(p); @@ -474,35 +500,37 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Octant::NavMesh nm; nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item); - if (navigation) { + if (bake_navigation) { RID region = NavigationServer3D::get_singleton()->region_create(); + NavigationServer3D::get_singleton()->region_set_layers(region, navigation_layers); NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh); - NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * nm.xform); - NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid()); + NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * mesh_library->get_item_navmesh_transform(c.item)); + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); nm.region = region; } + g.navmesh_ids[E->get()] = nm; } } //update multimeshes, only if not baked if (baked_meshes.size() == 0) { - for (Map<int, List<Pair<Transform, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) { + for (Map<int, List<Pair<Transform3D, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) { Octant::MultimeshInstance mmi; RID mm = RS::get_singleton()->multimesh_create(); - RS::get_singleton()->multimesh_allocate(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D); + RS::get_singleton()->multimesh_allocate_data(mm, E->get().size(), RS::MULTIMESH_TRANSFORM_3D); RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid()); int idx = 0; - for (List<Pair<Transform, IndexKey>>::Element *F = E->get().front(); F; F = F->next()) { - RS::get_singleton()->multimesh_instance_set_transform(mm, idx, F->get().first); + for (const Pair<Transform3D, IndexKey> &F : E->get()) { + RS::get_singleton()->multimesh_instance_set_transform(mm, idx, F.first); #ifdef TOOLS_ENABLED Octant::MultimeshInstance::Item it; it.index = idx; - it.transform = F->get().first; - it.key = F->get().second; + it.transform = F.first; + it.key = F.second; mmi.items.push_back(it); #endif @@ -564,15 +592,17 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform()); } - if (navigation && mesh_library.is_valid()) { + if (bake_navigation && mesh_library.is_valid()) { for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) { if (cell_map.has(F->key()) && F->get().region.is_valid() == false) { Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item); if (nm.is_valid()) { RID region = NavigationServer3D::get_singleton()->region_create(); + NavigationServer3D::get_singleton()->region_set_layers(region, navigation_layers); NavigationServer3D::get_singleton()->region_set_navmesh(region, nm); - NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * F->get().xform); - NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid()); + NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F->get().xform); + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); + F->get().region = region; } } @@ -594,12 +624,10 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID()); } - if (navigation) { - for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) { - if (F->get().region.is_valid()) { - NavigationServer3D::get_singleton()->free(F->get().region); - F->get().region = RID(); - } + for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) { + if (F->get().region.is_valid()) { + NavigationServer3D::get_singleton()->free(F->get().region); + F->get().region = RID(); } } } @@ -635,16 +663,6 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { void GridMap::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { - Node3D *c = this; - while (c) { - navigation = Object::cast_to<Navigation3D>(c); - if (navigation) { - break; - } - - c = Object::cast_to<Node3D>(c->get_parent()); - } - last_transform = get_global_transform(); for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { @@ -658,7 +676,7 @@ void GridMap::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - Transform new_xform = get_global_transform(); + Transform3D new_xform = get_global_transform(); if (new_xform == last_transform) { break; } @@ -672,15 +690,12 @@ void GridMap::_notification(int p_what) { for (int i = 0; i < baked_meshes.size(); i++) { RS::get_singleton()->instance_set_transform(baked_meshes[i].instance, get_global_transform()); } - } break; case NOTIFICATION_EXIT_WORLD: { for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) { _octant_exit_world(E->key()); } - navigation = nullptr; - //_queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS); //_update_octants_callback(); //_update_area_instances(); @@ -700,15 +715,17 @@ void GridMap::_update_visibility() { return; } - _change_notify("visible"); - for (Map<OctantKey, Octant *>::Element *e = octant_map.front(); e; e = e->next()) { Octant *octant = e->value(); for (int i = 0; i < octant->multimesh_instances.size(); i++) { const Octant::MultimeshInstance &mi = octant->multimesh_instances[i]; - RS::get_singleton()->instance_set_visible(mi.instance, is_visible()); + RS::get_singleton()->instance_set_visible(mi.instance, is_visible_in_tree()); } } + + for (int i = 0; i < baked_meshes.size(); i++) { + RS::get_singleton()->instance_set_visible(baked_meshes[i].instance, is_visible_in_tree()); + } } void GridMap::_queue_octants_dirty() { @@ -725,7 +742,7 @@ void GridMap::_recreate_octant_data() { Map<IndexKey, Cell> cell_copy = cell_map; _clear_internal(); for (Map<IndexKey, Cell>::Element *E = cell_copy.front(); E; E = E->next()) { - set_cell_item(E->key().x, E->key().y, E->key().z, E->get().item, E->get().rot); + set_cell_item(Vector3i(E->key()), E->get().item, E->get().rot); } recreating_octants = false; } @@ -767,7 +784,7 @@ void GridMap::_update_octants_callback() { while (to_delete.front()) { octant_map.erase(to_delete.front()->get()); - to_delete.pop_back(); + to_delete.pop_front(); } _update_visibility(); @@ -781,11 +798,17 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &GridMap::set_collision_mask); ClassDB::bind_method(D_METHOD("get_collision_mask"), &GridMap::get_collision_mask); - ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &GridMap::set_collision_mask_bit); - ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &GridMap::get_collision_mask_bit); + ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &GridMap::set_collision_mask_value); + ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &GridMap::get_collision_mask_value); + + ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &GridMap::set_collision_layer_value); + ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &GridMap::get_collision_layer_value); - ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &GridMap::set_collision_layer_bit); - ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &GridMap::get_collision_layer_bit); + ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &GridMap::set_bake_navigation); + ClassDB::bind_method(D_METHOD("is_baking_navigation"), &GridMap::is_baking_navigation); + + ClassDB::bind_method(D_METHOD("set_navigation_layers", "layers"), &GridMap::set_navigation_layers); + ClassDB::bind_method(D_METHOD("get_navigation_layers"), &GridMap::get_navigation_layers); ClassDB::bind_method(D_METHOD("set_mesh_library", "mesh_library"), &GridMap::set_mesh_library); ClassDB::bind_method(D_METHOD("get_mesh_library"), &GridMap::get_mesh_library); @@ -799,12 +822,12 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_octant_size", "size"), &GridMap::set_octant_size); ClassDB::bind_method(D_METHOD("get_octant_size"), &GridMap::get_octant_size); - ClassDB::bind_method(D_METHOD("set_cell_item", "x", "y", "z", "item", "orientation"), &GridMap::set_cell_item, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("get_cell_item", "x", "y", "z"), &GridMap::get_cell_item); - ClassDB::bind_method(D_METHOD("get_cell_item_orientation", "x", "y", "z"), &GridMap::get_cell_item_orientation); + ClassDB::bind_method(D_METHOD("set_cell_item", "position", "item", "orientation"), &GridMap::set_cell_item, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("get_cell_item", "position"), &GridMap::get_cell_item); + ClassDB::bind_method(D_METHOD("get_cell_item_orientation", "position"), &GridMap::get_cell_item_orientation); - ClassDB::bind_method(D_METHOD("world_to_map", "pos"), &GridMap::world_to_map); - ClassDB::bind_method(D_METHOD("map_to_world", "x", "y", "z"), &GridMap::map_to_world); + ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &GridMap::world_to_map); + ClassDB::bind_method(D_METHOD("map_to_world", "map_position"), &GridMap::map_to_world); ClassDB::bind_method(D_METHOD("_update_octants_callback"), &GridMap::_update_octants_callback); ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &GridMap::resource_changed); @@ -840,6 +863,9 @@ void GridMap::_bind_methods() { ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); + ADD_GROUP("Navigation", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); BIND_CONSTANT(INVALID_CELL_ITEM); @@ -911,7 +937,7 @@ Array GridMap::get_meshes() { Vector3 cellpos = Vector3(ik.x, ik.y, ik.z); - Transform xform; + Transform3D xform; xform.basis.set_orthogonal_index(E->get().rot); @@ -965,7 +991,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe Vector3 cellpos = Vector3(key.x, key.y, key.z); Vector3 ofs = _get_offset(); - Transform xform; + Transform3D xform; xform.basis.set_orthogonal_index(E->get().rot); xform.set_origin(cellpos * cell_size + ofs); @@ -990,7 +1016,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe Ref<Material> surf_mat = mesh->surface_get_material(i); if (!mat_map.has(surf_mat)) { Ref<SurfaceTool> st; - st.instance(); + st.instantiate(); st->begin(Mesh::PRIMITIVE_TRIANGLES); st->set_material(surf_mat); mat_map[surf_mat] = st; @@ -1002,7 +1028,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe for (Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>>::Element *E = surface_map.front(); E; E = E->next()) { Ref<ArrayMesh> mesh; - mesh.instance(); + mesh.instantiate(); for (Map<Ref<Material>, Ref<SurfaceTool>>::Element *F = E->get().front(); F; F = F->next()) { F->get()->commit(mesh); } @@ -1034,7 +1060,7 @@ Array GridMap::get_bake_meshes() { Array arr; for (int i = 0; i < baked_meshes.size(); i++) { arr.push_back(baked_meshes[i].mesh); - arr.push_back(Transform()); + arr.push_back(Transform3D()); } return arr; @@ -1046,26 +1072,7 @@ RID GridMap::get_bake_mesh_instance(int p_idx) { } GridMap::GridMap() { - collision_layer = 1; - collision_mask = 1; - - cell_size = Vector3(2, 2, 2); - octant_size = 8; - awaiting_update = false; - _in_tree = false; - center_x = true; - center_y = true; - center_z = true; - - clip = false; - clip_floor = 0; - clip_axis = Vector3::AXIS_Z; - clip_above = true; - cell_scale = 1.0; - - navigation = nullptr; set_notify_transform(true); - recreating_octants = false; } GridMap::~GridMap() { diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 9eb9aee7d1..879489fc70 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,7 +31,6 @@ #ifndef GRID_MAP_H #define GRID_MAP_H -#include "scene/3d/navigation_3d.h" #include "scene/3d/node_3d.h" #include "scene/resources/mesh_library.h" #include "scene/resources/multimesh.h" @@ -53,13 +52,22 @@ class GridMap : public Node3D { int16_t y; int16_t z; }; - uint64_t key; + uint64_t key = 0; _FORCE_INLINE_ bool operator<(const IndexKey &p_key) const { return key < p_key.key; } - IndexKey() { key = 0; } + _FORCE_INLINE_ operator Vector3i() const { + return Vector3i(x, y, z); + } + + IndexKey(Vector3i p_vector) { + x = (int16_t)p_vector.x; + y = (int16_t)p_vector.y; + z = (int16_t)p_vector.z; + } + IndexKey() {} }; /** @@ -71,13 +79,7 @@ class GridMap : public Node3D { unsigned int rot : 5; unsigned int layer : 8; }; - uint32_t cell; - - Cell() { - item = 0; - rot = 0; - layer = 0; - } + uint32_t cell = 0; }; /** @@ -87,15 +89,15 @@ class GridMap : public Node3D { struct Octant { struct NavMesh { RID region; - Transform xform; + Transform3D xform; }; struct MultimeshInstance { RID instance; RID multimesh; struct Item { - int index; - Transform transform; + int index = 0; + Transform3D transform; IndexKey key; }; @@ -107,7 +109,7 @@ class GridMap : public Node3D { RID collision_debug; RID collision_debug_instance; - bool dirty; + bool dirty = false; RID static_body; Map<IndexKey, NavMesh> navmesh_ids; }; @@ -120,35 +122,38 @@ class GridMap : public Node3D { int16_t empty; }; - uint64_t key; + uint64_t key = 0; _FORCE_INLINE_ bool operator<(const OctantKey &p_key) const { return key < p_key.key; } //OctantKey(const IndexKey& p_k, int p_item) { indexkey=p_k.key; item=p_item; } - OctantKey() { key = 0; } + OctantKey() {} }; - uint32_t collision_layer; - uint32_t collision_mask; + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; + bool bake_navigation = false; + uint32_t navigation_layers = 1; - Transform last_transform; + Transform3D last_transform; - bool _in_tree; - Vector3 cell_size; - int octant_size; - bool center_x, center_y, center_z; - float cell_scale; - Navigation3D *navigation; + bool _in_tree = false; + Vector3 cell_size = Vector3(2, 2, 2); + int octant_size = 8; + bool center_x = true; + bool center_y = true; + bool center_z = true; + float cell_scale = 1.0; - bool clip; - bool clip_above; - int clip_floor; + bool clip = false; + bool clip_above = true; + int clip_floor = 0; - bool recreating_octants; + bool recreating_octants = false; - Vector3::Axis clip_axis; + Vector3::Axis clip_axis = Vector3::AXIS_Z; Ref<MeshLibrary> mesh_library; @@ -158,10 +163,10 @@ class GridMap : public Node3D { void _recreate_octant_data(); struct BakeLight { - RS::LightType type; + RS::LightType type = RS::LightType::LIGHT_DIRECTIONAL; Vector3 pos; Vector3 dir; - float param[RS::LIGHT_PARAM_MAX]; + float param[RS::LIGHT_PARAM_MAX] = {}; }; _FORCE_INLINE_ Vector3 _octant_get_offset(const OctantKey &p_key) const { @@ -174,7 +179,7 @@ class GridMap : public Node3D { bool _octant_update(const OctantKey &p_key); void _octant_clean_up(const OctantKey &p_key); void _octant_transform(const OctantKey &p_key); - bool awaiting_update; + bool awaiting_update = false; void _queue_octants_dirty(); void _update_octants_callback(); @@ -212,11 +217,17 @@ public: void set_collision_mask(uint32_t p_mask); uint32_t get_collision_mask() const; - void set_collision_layer_bit(int p_bit, bool p_value); - bool get_collision_layer_bit(int p_bit) const; + void set_collision_layer_value(int p_layer_number, bool p_value); + bool get_collision_layer_value(int p_layer_number) const; + + void set_collision_mask_value(int p_layer_number, bool p_value); + bool get_collision_mask_value(int p_layer_number) const; + + void set_bake_navigation(bool p_bake_navigation); + bool is_baking_navigation(); - void set_collision_mask_bit(int p_bit, bool p_value); - bool get_collision_mask_bit(int p_bit) const; + void set_navigation_layers(uint32_t p_layers); + uint32_t get_navigation_layers(); void set_mesh_library(const Ref<MeshLibrary> &p_mesh_library); Ref<MeshLibrary> get_mesh_library() const; @@ -234,12 +245,12 @@ public: void set_center_z(bool p_enable); bool get_center_z() const; - void set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot = 0); - int get_cell_item(int p_x, int p_y, int p_z) const; - int get_cell_item_orientation(int p_x, int p_y, int p_z) const; + void set_cell_item(const Vector3i &p_position, int p_item, int p_rot = 0); + int get_cell_item(const Vector3i &p_position) const; + int get_cell_item_orientation(const Vector3i &p_position) const; - Vector3 world_to_map(const Vector3 &p_world_pos) const; - Vector3 map_to_world(int p_x, int p_y, int p_z) const; + Vector3i world_to_map(const Vector3 &p_world_position) const; + Vector3 map_to_world(const Vector3i &p_map_position) const; void set_clip(bool p_enabled, bool p_clip_above = true, int p_floor = 0, Vector3::Axis p_axis = Vector3::AXIS_X); diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 3b0e78546d..f101c43e89 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -62,12 +62,6 @@ void GridMapEditor::_menu_option(int p_option) { floor->set_value(floor->get_value() + 1); } break; - case MENU_OPTION_LOCK_VIEW: { - int index = options->get_popup()->get_item_index(MENU_OPTION_LOCK_VIEW); - lock_view = !options->get_popup()->is_item_checked(index); - - options->get_popup()->set_item_checked(index, lock_view); - } break; case MENU_OPTION_CLIP_DISABLED: case MENU_OPTION_CLIP_ABOVE: case MENU_OPTION_CLIP_BELOW: { @@ -255,7 +249,7 @@ void GridMapEditor::_menu_option(int p_option) { } void GridMapEditor::_update_cursor_transform() { - cursor_transform = Transform(); + cursor_transform = Transform3D(); cursor_transform.origin = cursor_origin; cursor_transform.basis.set_orthogonal_index(cursor_rot); cursor_transform.basis *= node->get_cell_scale(); @@ -268,7 +262,7 @@ void GridMapEditor::_update_cursor_transform() { } void GridMapEditor::_update_selection_transform() { - Transform xf_zero; + Transform3D xf_zero; xf_zero.basis.set_zero(); if (!selection.active) { @@ -279,7 +273,7 @@ void GridMapEditor::_update_selection_transform() { return; } - Transform xf; + Transform3D xf; xf.scale((Vector3(1, 1, 1) + (selection.end - selection.begin)) * node->get_cell_size()); xf.origin = selection.begin * node->get_cell_size(); @@ -291,15 +285,15 @@ void GridMapEditor::_update_selection_transform() { } else { Vector3 scale = (selection.end - selection.begin + Vector3(1, 1, 1)); scale[edit_axis] = 1.0; - Vector3 pos = selection.begin; - pos[edit_axis] = edit_floor[edit_axis]; + Vector3 position = selection.begin; + position[edit_axis] = edit_floor[edit_axis]; scale *= node->get_cell_size(); - pos *= node->get_cell_size(); + position *= node->get_cell_size(); - Transform xf2; + Transform3D xf2; xf2.basis.scale(scale); - xf2.origin = pos; + xf2.origin = position; RenderingServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf2); } @@ -362,7 +356,7 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b Camera3D *camera = p_camera; Vector3 from = camera->project_ray_origin(p_point); Vector3 normal = camera->project_ray_normal(p_point); - Transform local_xform = node->get_global_transform().affine_inverse(); + Transform3D local_xform = node->get_global_transform().affine_inverse(); Vector<Plane> planes = camera->get_frustum(); from = local_xform.xform(from); normal = local_xform.basis.xform(normal).normalized(); @@ -386,13 +380,13 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b } int cell[3]; - float cell_size[3] = { node->get_cell_size().x, node->get_cell_size().y, node->get_cell_size().z }; + Vector3 cell_size = node->get_cell_size(); for (int i = 0; i < 3; i++) { if (i == edit_axis) { cell[i] = edit_floor[i]; } else { - cell[i] = inters[i] / node->get_cell_size()[i]; + cell[i] = inters[i] / cell_size[i]; if (inters[i] < 0) { cell[i] -= 1; // Compensate negative. } @@ -414,11 +408,11 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b } if (input_action == INPUT_PASTE) { - paste_indicator.current = Vector3(cell[0], cell[1], cell[2]); + paste_indicator.current = Vector3i(cell[0], cell[1], cell[2]); _update_paste_indicator(); } else if (input_action == INPUT_SELECT) { - selection.current = Vector3(cell[0], cell[1], cell[2]); + selection.current = Vector3i(cell[0], cell[1], cell[2]); if (p_click) { selection.click = selection.current; } @@ -427,7 +421,7 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b return true; } else if (input_action == INPUT_PICK) { - int item = node->get_cell_item(cell[0], cell[1], cell[2]); + int item = node->get_cell_item(Vector3i(cell[0], cell[1], cell[2])); if (item >= 0) { selected_palette = item; mesh_library_palette->set_current(item); @@ -436,25 +430,26 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b } return true; } + if (input_action == INPUT_PAINT) { SetItem si; - si.pos = Vector3(cell[0], cell[1], cell[2]); + si.position = Vector3i(cell[0], cell[1], cell[2]); si.new_value = selected_palette; si.new_orientation = cursor_rot; - si.old_value = node->get_cell_item(cell[0], cell[1], cell[2]); - si.old_orientation = node->get_cell_item_orientation(cell[0], cell[1], cell[2]); + si.old_value = node->get_cell_item(Vector3i(cell[0], cell[1], cell[2])); + si.old_orientation = node->get_cell_item_orientation(Vector3i(cell[0], cell[1], cell[2])); set_items.push_back(si); - node->set_cell_item(cell[0], cell[1], cell[2], selected_palette, cursor_rot); + node->set_cell_item(Vector3i(cell[0], cell[1], cell[2]), selected_palette, cursor_rot); return true; } else if (input_action == INPUT_ERASE) { SetItem si; - si.pos = Vector3(cell[0], cell[1], cell[2]); + si.position = Vector3i(cell[0], cell[1], cell[2]); si.new_value = -1; si.new_orientation = 0; - si.old_value = node->get_cell_item(cell[0], cell[1], cell[2]); - si.old_orientation = node->get_cell_item_orientation(cell[0], cell[1], cell[2]); + si.old_value = node->get_cell_item(Vector3i(cell[0], cell[1], cell[2])); + si.old_orientation = node->get_cell_item_orientation(Vector3i(cell[0], cell[1], cell[2])); set_items.push_back(si); - node->set_cell_item(cell[0], cell[1], cell[2], -1); + node->set_cell_item(Vector3i(cell[0], cell[1], cell[2]), -1); return true; } @@ -470,8 +465,9 @@ void GridMapEditor::_delete_selection() { for (int i = selection.begin.x; i <= selection.end.x; i++) { for (int j = selection.begin.y; j <= selection.end.y; j++) { for (int k = selection.begin.z; k <= selection.end.z; k++) { - undo_redo->add_do_method(node, "set_cell_item", i, j, k, GridMap::INVALID_CELL_ITEM); - undo_redo->add_undo_method(node, "set_cell_item", i, j, k, node->get_cell_item(i, j, k), node->get_cell_item_orientation(i, j, k)); + Vector3i selected = Vector3i(i, j, k); + undo_redo->add_do_method(node, "set_cell_item", selected, GridMap::INVALID_CELL_ITEM); + undo_redo->add_undo_method(node, "set_cell_item", selected, node->get_cell_item(selected), node->get_cell_item_orientation(selected)); } } } @@ -489,8 +485,9 @@ void GridMapEditor::_fill_selection() { for (int i = selection.begin.x; i <= selection.end.x; i++) { for (int j = selection.begin.y; j <= selection.end.y; j++) { for (int k = selection.begin.z; k <= selection.end.z; k++) { - undo_redo->add_do_method(node, "set_cell_item", i, j, k, selected_palette, cursor_rot); - undo_redo->add_undo_method(node, "set_cell_item", i, j, k, node->get_cell_item(i, j, k), node->get_cell_item_orientation(i, j, k)); + Vector3i selected = Vector3i(i, j, k); + undo_redo->add_do_method(node, "set_cell_item", selected, selected_palette, cursor_rot); + undo_redo->add_undo_method(node, "set_cell_item", selected, node->get_cell_item(selected), node->get_cell_item_orientation(selected)); } } } @@ -500,8 +497,8 @@ void GridMapEditor::_fill_selection() { } void GridMapEditor::_clear_clipboard_data() { - for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { - RenderingServer::get_singleton()->free(E->get().instance); + for (const ClipboardItem &E : clipboard_items) { + RenderingServer::get_singleton()->free(E.instance); } clipboard_items.clear(); @@ -515,7 +512,8 @@ void GridMapEditor::_set_clipboard_data() { for (int i = selection.begin.x; i <= selection.end.x; i++) { for (int j = selection.begin.y; j <= selection.end.y; j++) { for (int k = selection.begin.z; k <= selection.end.z; k++) { - int itm = node->get_cell_item(i, j, k); + Vector3i selected = Vector3i(i, j, k); + int itm = node->get_cell_item(selected); if (itm == GridMap::INVALID_CELL_ITEM) { continue; } @@ -524,8 +522,8 @@ void GridMapEditor::_set_clipboard_data() { ClipboardItem item; item.cell_item = itm; - item.grid_offset = Vector3(i, j, k) - selection.begin; - item.orientation = node->get_cell_item_orientation(i, j, k); + item.grid_offset = Vector3(selected) - selection.begin; + item.orientation = node->get_cell_item_orientation(selected); item.instance = RenderingServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world_3d()->get_scenario()); clipboard_items.push_back(item); @@ -536,15 +534,15 @@ void GridMapEditor::_set_clipboard_data() { void GridMapEditor::_update_paste_indicator() { if (input_action != INPUT_PASTE) { - Transform xf; + Transform3D xf; xf.basis.set_zero(); RenderingServer::get_singleton()->instance_set_transform(paste_instance, xf); return; } - Vector3 center = 0.5 * Vector3(float(node->get_center_x()), float(node->get_center_y()), float(node->get_center_z())); + Vector3 center = 0.5 * Vector3(real_t(node->get_center_x()), real_t(node->get_center_y()), real_t(node->get_center_z())); Vector3 scale = (Vector3(1, 1, 1) + (paste_indicator.end - paste_indicator.begin)) * node->get_cell_size(); - Transform xf; + Transform3D xf; xf.scale(scale); xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size(); Basis rot; @@ -554,10 +552,8 @@ void GridMapEditor::_update_paste_indicator() { RenderingServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf); - for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { - ClipboardItem &item = E->get(); - - xf = Transform(); + for (const ClipboardItem &item : clipboard_items) { + xf = Transform3D(); xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size(); xf.basis = rot * xf.basis; xf.translate(item.grid_offset * node->get_cell_size()); @@ -580,17 +576,15 @@ void GridMapEditor::_do_paste() { Vector3 ofs = paste_indicator.current - paste_indicator.click; undo_redo->create_action(TTR("GridMap Paste Selection")); - for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) { - ClipboardItem &item = E->get(); - - Vector3 pos = rot.xform(item.grid_offset) + paste_indicator.begin + ofs; + for (const ClipboardItem &item : clipboard_items) { + Vector3 position = rot.xform(item.grid_offset) + paste_indicator.begin + ofs; Basis orm; orm.set_orthogonal_index(item.orientation); orm = rot * orm; - undo_redo->add_do_method(node, "set_cell_item", pos.x, pos.y, pos.z, item.cell_item, orm.get_orthogonal_index()); - undo_redo->add_undo_method(node, "set_cell_item", pos.x, pos.y, pos.z, node->get_cell_item(pos.x, pos.y, pos.z), node->get_cell_item_orientation(pos.x, pos.y, pos.z)); + undo_redo->add_do_method(node, "set_cell_item", position, item.cell_item, orm.get_orthogonal_index()); + undo_redo->add_undo_method(node, "set_cell_item", position, node->get_cell_item(position), node->get_cell_item_orientation(position)); } if (reselect) { @@ -611,13 +605,13 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - if (mb->get_button_index() == BUTTON_WHEEL_UP && (mb->get_command() || mb->get_shift())) { + if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && (mb->is_command_pressed() || mb->is_shift_pressed())) { if (mb->is_pressed()) { floor->set_value(floor->get_value() + mb->get_factor()); } return true; // Eaten. - } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && (mb->get_command() || mb->get_shift())) { + } else if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && (mb->is_command_pressed() || mb->is_shift_pressed())) { if (mb->is_pressed()) { floor->set_value(floor->get_value() - mb->get_factor()); } @@ -626,24 +620,24 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In if (mb->is_pressed()) { Node3DEditorViewport::NavigationScheme nav_scheme = (Node3DEditorViewport::NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int(); - if ((nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA || nav_scheme == Node3DEditorViewport::NAVIGATION_MODO) && mb->get_alt()) { + if ((nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA || nav_scheme == Node3DEditorViewport::NAVIGATION_MODO) && mb->is_alt_pressed()) { input_action = INPUT_NONE; - } else if (mb->get_button_index() == BUTTON_LEFT) { + } else if (mb->get_button_index() == MOUSE_BUTTON_LEFT) { bool can_edit = (node && node->get_mesh_library().is_valid()); if (input_action == INPUT_PASTE) { _do_paste(); input_action = INPUT_NONE; _update_paste_indicator(); - } else if (mb->get_shift() && can_edit) { + } else if (mb->is_shift_pressed() && can_edit) { input_action = INPUT_SELECT; last_selection = selection; - } else if (mb->get_command() && can_edit) { + } else if (mb->is_command_pressed() && can_edit) { input_action = INPUT_PICK; } else { input_action = INPUT_PAINT; set_items.clear(); } - } else if (mb->get_button_index() == BUTTON_RIGHT) { + } else if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) { if (input_action == INPUT_PASTE) { _clear_clipboard_data(); input_action = INPUT_NONE; @@ -662,16 +656,15 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In return do_input_action(p_camera, Point2(mb->get_position().x, mb->get_position().y), true); } else { - if ((mb->get_button_index() == BUTTON_RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == BUTTON_LEFT && input_action == INPUT_PAINT)) { + if ((mb->get_button_index() == MOUSE_BUTTON_RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action == INPUT_PAINT)) { if (set_items.size()) { undo_redo->create_action(TTR("GridMap Paint")); - for (List<SetItem>::Element *E = set_items.front(); E; E = E->next()) { - const SetItem &si = E->get(); - undo_redo->add_do_method(node, "set_cell_item", si.pos.x, si.pos.y, si.pos.z, si.new_value, si.new_orientation); + for (const SetItem &si : set_items) { + undo_redo->add_do_method(node, "set_cell_item", si.position, si.new_value, si.new_orientation); } for (List<SetItem>::Element *E = set_items.back(); E; E = E->prev()) { const SetItem &si = E->get(); - undo_redo->add_undo_method(node, "set_cell_item", si.pos.x, si.pos.y, si.pos.z, si.old_value, si.old_orientation); + undo_redo->add_undo_method(node, "set_cell_item", si.position, si.old_value, si.old_orientation); } undo_redo->commit_action(); @@ -681,19 +674,19 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In return set_items.size() > 0; } - if (mb->get_button_index() == BUTTON_LEFT && input_action == INPUT_SELECT) { - undo_redo->create_action("GridMap Selection"); + if (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action == INPUT_SELECT) { + undo_redo->create_action(TTR("GridMap Selection")); undo_redo->add_do_method(this, "_set_selection", selection.active, selection.begin, selection.end); undo_redo->add_undo_method(this, "_set_selection", last_selection.active, last_selection.begin, last_selection.end); undo_redo->commit_action(); } - if (mb->get_button_index() == BUTTON_LEFT && input_action != INPUT_NONE) { + if (mb->get_button_index() == MOUSE_BUTTON_LEFT && input_action != INPUT_NONE) { set_items.clear(); input_action = INPUT_NONE; return true; } - if (mb->get_button_index() == BUTTON_RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_PASTE)) { + if (mb->get_button_index() == MOUSE_BUTTON_RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_PASTE)) { input_action = INPUT_NONE; return true; } @@ -721,14 +714,14 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In return true; } else { selected_palette = -1; - mesh_library_palette->unselect_all(); + mesh_library_palette->deselect_all(); update_palette(); _update_cursor_instance(); return true; } } - if (k->get_shift() && selection.active && input_action != INPUT_PASTE) { + if (k->is_shift_pressed() && selection.active && input_action != INPUT_PASTE) { if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) { selection.click[edit_axis]--; _validate_selection(); @@ -745,7 +738,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid()) { - if (pan_gesture->get_alt() && (pan_gesture->get_command() || pan_gesture->get_shift())) { + if (pan_gesture->is_alt_pressed() && (pan_gesture->is_command_pressed() || pan_gesture->is_shift_pressed())) { const real_t delta = pan_gesture->get_delta().y * 0.5; accumulated_floor_delta += delta; int step = 0; @@ -766,7 +759,7 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In struct _CGMEItemSort { String name; - int id; + int id = 0; _FORCE_INLINE_ bool operator<(const _CGMEItemSort &r_it) const { return name < r_it.name; } }; @@ -806,12 +799,12 @@ void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) { const Ref<InputEventMouseButton> mb = p_ie; // Zoom in/out using Ctrl + mouse wheel - if (mb.is_valid() && mb->is_pressed() && mb->get_command()) { - if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) { + if (mb.is_valid() && mb->is_pressed() && mb->is_command_pressed()) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) { size_slider->set_value(size_slider->get_value() + 0.2); } - if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) { + if (mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) { size_slider->set_value(size_slider->get_value() - 0.2); } } @@ -871,8 +864,8 @@ void GridMapEditor::update_palette() { int item = 0; - for (List<_CGMEItemSort>::Element *E = il.front(); E; E = E->next()) { - int id = E->get().id; + for (_CGMEItemSort &E : il) { + int id = E.id; String name = mesh_library->get_item_name(id); Ref<Texture2D> preview = mesh_library->get_item_preview(id); @@ -1027,11 +1020,15 @@ void GridMapEditor::_notification(int p_what) { for (int i = 0; i < 3; i++) { grid[i] = RS::get_singleton()->mesh_create(); grid_instance[i] = RS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(grid_instance[i], 1 << Node3DEditorViewport::MISC_TOOL_LAYER); selection_level_instance[i] = RenderingServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(selection_level_instance[i], 1 << Node3DEditorViewport::MISC_TOOL_LAYER); } selection_instance = RenderingServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(selection_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); paste_instance = RenderingServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(paste_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); _update_selection_transform(); _update_paste_indicator(); @@ -1060,7 +1057,7 @@ void GridMapEditor::_notification(int p_what) { return; } - Transform xf = node->get_global_transform(); + Transform3D xf = node->get_global_transform(); if (xf != grid_xform) { for (int i = 0; i < 3; i++) { @@ -1072,25 +1069,21 @@ void GridMapEditor::_notification(int p_what) { if (cgmt.operator->() != last_mesh_library) { update_palette(); } - - if (lock_view) { - EditorNode *editor = Object::cast_to<EditorNode>(get_tree()->get_root()->get_child(0)); - - Plane p; - p.normal[edit_axis] = 1.0; - p.d = edit_floor[edit_axis] * node->get_cell_size()[edit_axis]; - p = node->get_transform().xform(p); // plane to snap - - Node3DEditorPlugin *sep = Object::cast_to<Node3DEditorPlugin>(editor->get_editor_plugin_screen()); - if (sep) { - sep->snap_cursor_to_plane(p); - } - } } break; case NOTIFICATION_THEME_CHANGED: { - options->set_icon(get_theme_icon("GridMap", "EditorIcons")); - search_box->set_right_icon(get_theme_icon("Search", "EditorIcons")); + options->set_icon(get_theme_icon(SNAME("GridMap"), SNAME("EditorIcons"))); + search_box->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); + } break; + + case NOTIFICATION_APPLICATION_FOCUS_OUT: { + if (input_action == INPUT_PAINT) { + // Simulate mouse released event to stop drawing when editor focus exists. + Ref<InputEventMouseButton> release; + release.instantiate(); + release->set_button_index(MOUSE_BUTTON_LEFT); + forward_spatial_input_event(nullptr, release); + } } break; } } @@ -1144,7 +1137,6 @@ void GridMapEditor::_bind_methods() { } GridMapEditor::GridMapEditor(EditorNode *p_editor) { - input_action = INPUT_NONE; editor = p_editor; undo_redo = p_editor->get_undo_redo(); @@ -1166,7 +1158,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { floor->set_min(-32767); floor->set_max(32767); floor->set_step(1); - floor->get_line_edit()->add_theme_constant_override("minimum_spaces", 16); + floor->get_line_edit()->add_theme_constant_override("minimum_character_width", 16); spatial_editor_hb->add_child(floor); floor->connect("value_changed", callable_mp(this, &GridMapEditor::_floor_changed)); @@ -1180,8 +1172,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { spatial_editor_hb->hide(); options->set_text(TTR("Grid Map")); - options->get_popup()->add_check_item(TTR("Snap View"), MENU_OPTION_LOCK_VIEW); - options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Previous Floor"), MENU_OPTION_PREV_LEVEL, KEY_Q); options->get_popup()->add_item(TTR("Next Floor"), MENU_OPTION_NEXT_LEVEL, KEY_E); options->get_popup()->add_separator(); @@ -1227,7 +1217,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { settings_pick_distance->set_value(EDITOR_DEF("editors/grid_map/pick_distance", 5000.0)); settings_vbc->add_margin_child(TTR("Pick Distance:"), settings_pick_distance); - clip_mode = CLIP_DISABLED; options->get_popup()->connect("id_pressed", callable_mp(this, &GridMapEditor::_menu_option)); HBoxContainer *hb = memnew(HBoxContainer); @@ -1241,17 +1230,19 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { search_box->connect("text_changed", callable_mp(this, &GridMapEditor::_text_changed)); search_box->connect("gui_input", callable_mp(this, &GridMapEditor::_sbox_input)); - mode_thumbnail = memnew(ToolButton); + mode_thumbnail = memnew(Button); + mode_thumbnail->set_flat(true); mode_thumbnail->set_toggle_mode(true); mode_thumbnail->set_pressed(true); - mode_thumbnail->set_icon(p_editor->get_gui_base()->get_theme_icon("FileThumbnail", "EditorIcons")); + mode_thumbnail->set_icon(p_editor->get_gui_base()->get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); hb->add_child(mode_thumbnail); mode_thumbnail->connect("pressed", callable_mp(this, &GridMapEditor::_set_display_mode), varray(DISPLAY_THUMBNAIL)); - mode_list = memnew(ToolButton); + mode_list = memnew(Button); + mode_list->set_flat(true); mode_list->set_toggle_mode(true); mode_list->set_pressed(false); - mode_list->set_icon(p_editor->get_gui_base()->get_theme_icon("FileList", "EditorIcons")); + mode_list->set_icon(p_editor->get_gui_base()->get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); hb->add_child(mode_list); mode_list->connect("pressed", callable_mp(this, &GridMapEditor::_set_display_mode), varray(DISPLAY_LIST)); @@ -1266,8 +1257,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { EDITOR_DEF("editors/grid_map/preview_size", 64); - display_mode = DISPLAY_THUMBNAIL; - mesh_library_palette = memnew(ItemList); add_child(mesh_library_palette); mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL); @@ -1277,9 +1266,9 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes.")); info_message->set_valign(Label::VALIGN_CENTER); info_message->set_align(Label::ALIGN_CENTER); - info_message->set_autowrap(true); + info_message->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART); info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); - info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE); + info_message->set_anchors_and_offsets_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE); mesh_library_palette->add_child(info_message); edit_axis = Vector3::AXIS_Y; @@ -1287,11 +1276,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { edit_floor[1] = -1; edit_floor[2] = -1; - cursor_visible = false; - selected_palette = -1; - lock_view = false; - cursor_rot = 0; - selection_mesh = RenderingServer::get_singleton()->mesh_create(); paste_mesh = RenderingServer::get_singleton()->mesh_create(); @@ -1367,7 +1351,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { Array d; d.resize(RS::ARRAY_MAX); - inner_mat.instance(); + inner_mat.instantiate(); inner_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.2)); inner_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); inner_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); @@ -1376,14 +1360,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { RenderingServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, RS::PRIMITIVE_TRIANGLES, d); RenderingServer::get_singleton()->mesh_surface_set_material(selection_mesh, 0, inner_mat->get_rid()); - outer_mat.instance(); + outer_mat.instantiate(); outer_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.8)); outer_mat->set_on_top_of_alpha(); outer_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); outer_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - selection_floor_mat.instance(); + selection_floor_mat.instantiate(); selection_floor_mat->set_albedo(Color(0.80, 0.80, 1.0, 1)); selection_floor_mat->set_on_top_of_alpha(); selection_floor_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); @@ -1409,10 +1393,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { } _set_selection(false); - updating = false; - accumulated_floor_delta = 0.0; - indicator_mat.instance(); + indicator_mat.instantiate(); indicator_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); indicator_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); indicator_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 19eea18965..4bc849e071 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" -#include "editor/pane_drag.h" #include "grid_map.h" class Node3DEditorPlugin; @@ -42,12 +41,10 @@ class GridMapEditor : public VBoxContainer { GDCLASS(GridMapEditor, VBoxContainer); enum { - GRID_CURSOR_SIZE = 50 }; enum InputAction { - INPUT_NONE, INPUT_PAINT, INPUT_ERASE, @@ -57,7 +54,6 @@ class GridMapEditor : public VBoxContainer { }; enum ClipMode { - CLIP_DISABLED, CLIP_ABOVE, CLIP_BELOW @@ -69,13 +65,13 @@ class GridMapEditor : public VBoxContainer { }; UndoRedo *undo_redo; - InputAction input_action; + InputAction input_action = INPUT_NONE; Panel *panel; MenuButton *options; SpinBox *floor; - double accumulated_floor_delta; - ToolButton *mode_thumbnail; - ToolButton *mode_list; + double accumulated_floor_delta = 0.0; + Button *mode_thumbnail; + Button *mode_list; LineEdit *search_box; HSlider *size_slider; HBoxContainer *spatial_editor_hb; @@ -85,22 +81,21 @@ class GridMapEditor : public VBoxContainer { Label *spin_box_label; struct SetItem { - Vector3 pos; - int new_value; - int new_orientation; - int old_value; - int old_orientation; + Vector3i position; + int new_value = 0; + int new_orientation = 0; + int old_value = 0; + int old_orientation = 0; }; List<SetItem> set_items; - GridMap *node; + GridMap *node = nullptr; MeshLibrary *last_mesh_library; - ClipMode clip_mode; + ClipMode clip_mode = CLIP_DISABLED; - bool lock_view; - Transform grid_xform; - Transform edit_grid_xform; + Transform3D grid_xform; + Transform3D edit_grid_xform; Vector3::Axis edit_axis; int edit_floor[3]; Vector3 grid_ofs; @@ -116,9 +111,9 @@ class GridMapEditor : public VBoxContainer { RID paste_instance; struct ClipboardItem { - int cell_item; + int cell_item = 0; Vector3 grid_offset; - int orientation; + int orientation = 0; RID instance; }; @@ -129,14 +124,14 @@ class GridMapEditor : public VBoxContainer { Ref<StandardMaterial3D> outer_mat; Ref<StandardMaterial3D> selection_floor_mat; - bool updating; + bool updating = false; struct Selection { Vector3 click; Vector3 current; Vector3 begin; Vector3 end; - bool active; + bool active = false; } selection; Selection last_selection; @@ -145,21 +140,20 @@ class GridMapEditor : public VBoxContainer { Vector3 current; Vector3 begin; Vector3 end; - int orientation; + int orientation = 0; }; PasteIndicator paste_indicator; - bool cursor_visible; - Transform cursor_transform; + bool cursor_visible = false; + Transform3D cursor_transform; Vector3 cursor_origin; - int display_mode; - int selected_palette; - int cursor_rot; + int display_mode = DISPLAY_THUMBNAIL; + int selected_palette = -1; + int cursor_rot = 0; enum Menu { - MENU_OPTION_NEXT_LEVEL, MENU_OPTION_PREV_LEVEL, MENU_OPTION_LOCK_VIEW, @@ -256,12 +250,12 @@ protected: void _notification(int p_what); public: - virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); } - virtual String get_name() const { return "GridMap"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_object); - virtual bool handles(Object *p_object) const; - virtual void make_visible(bool p_visible); + virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); } + virtual String get_name() const override { return "GridMap"; } + bool has_main_screen() const override { return false; } + virtual void edit(Object *p_object) override; + virtual bool handles(Object *p_object) const override; + virtual void make_visible(bool p_visible) override; GridMapEditorPlugin(EditorNode *p_node); ~GridMapEditorPlugin(); diff --git a/modules/gridmap/icons/GridMap.svg b/modules/gridmap/icons/GridMap.svg index eafe1211f2..e208257855 100644 --- a/modules/gridmap/icons/GridMap.svg +++ b/modules/gridmap/icons/GridMap.svg @@ -1,5 +1 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m8 1-6 3v8l6 3 6-3v-2l-2-1-4 2-2-1v-4l2-1v-2l2-1zm4 2-2 1v2l2 1 2-1v-2z" fill="#fc9c9c" fill-opacity=".99608"/> -</g> -</svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1-6 3v8l6 3 6-3v-2l-2-1-4 2-2-1v-4l2-1v-2l2-1zm4 2-2 1v2l2 1 2-1v-2z" fill="#fc7f7f" fill-opacity=".99608"/></svg> diff --git a/modules/gridmap/register_types.cpp b/modules/gridmap/register_types.cpp index 906e506b62..85739d202e 100644 --- a/modules/gridmap/register_types.cpp +++ b/modules/gridmap/register_types.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,14 +30,14 @@ #include "register_types.h" #ifndef _3D_DISABLED -#include "core/class_db.h" +#include "core/object/class_db.h" #include "grid_map.h" #include "grid_map_editor_plugin.h" #endif void register_gridmap_types() { #ifndef _3D_DISABLED - ClassDB::register_class<GridMap>(); + GDREGISTER_CLASS(GridMap); #ifdef TOOLS_ENABLED EditorPlugins::add_by_type<GridMapEditorPlugin>(); #endif diff --git a/modules/gridmap/register_types.h b/modules/gridmap/register_types.h index c0e3c39ca8..b977f4c5da 100644 --- a/modules/gridmap/register_types.h +++ b/modules/gridmap/register_types.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ |