diff --git a/core/math/basis.cpp b/core/math/basis.cpp index f8e7c4710756..bc50d0e64cd1 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -749,67 +749,6 @@ Quaternion Basis::get_quaternion() const { return Quaternion(temp[0], temp[1], temp[2], temp[3]); } -static const Basis _ortho_bases[24] = { - Basis(1, 0, 0, 0, 1, 0, 0, 0, 1), - Basis(0, -1, 0, 1, 0, 0, 0, 0, 1), - Basis(-1, 0, 0, 0, -1, 0, 0, 0, 1), - Basis(0, 1, 0, -1, 0, 0, 0, 0, 1), - Basis(1, 0, 0, 0, 0, -1, 0, 1, 0), - Basis(0, 0, 1, 1, 0, 0, 0, 1, 0), - Basis(-1, 0, 0, 0, 0, 1, 0, 1, 0), - Basis(0, 0, -1, -1, 0, 0, 0, 1, 0), - Basis(1, 0, 0, 0, -1, 0, 0, 0, -1), - Basis(0, 1, 0, 1, 0, 0, 0, 0, -1), - Basis(-1, 0, 0, 0, 1, 0, 0, 0, -1), - Basis(0, -1, 0, -1, 0, 0, 0, 0, -1), - Basis(1, 0, 0, 0, 0, 1, 0, -1, 0), - Basis(0, 0, -1, 1, 0, 0, 0, -1, 0), - Basis(-1, 0, 0, 0, 0, -1, 0, -1, 0), - Basis(0, 0, 1, -1, 0, 0, 0, -1, 0), - Basis(0, 0, 1, 0, 1, 0, -1, 0, 0), - Basis(0, -1, 0, 0, 0, 1, -1, 0, 0), - Basis(0, 0, -1, 0, -1, 0, -1, 0, 0), - Basis(0, 1, 0, 0, 0, -1, -1, 0, 0), - Basis(0, 0, 1, 0, -1, 0, 1, 0, 0), - Basis(0, 1, 0, 0, 0, 1, 1, 0, 0), - Basis(0, 0, -1, 0, 1, 0, 1, 0, 0), - Basis(0, -1, 0, 0, 0, -1, 1, 0, 0) -}; - -int Basis::get_orthogonal_index() const { - //could be sped up if i come up with a way - Basis orth = *this; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - real_t v = orth[i][j]; - if (v > 0.5f) { - v = 1.0f; - } else if (v < -0.5f) { - v = -1.0f; - } else { - v = 0; - } - - orth[i][j] = v; - } - } - - for (int i = 0; i < 24; i++) { - if (_ortho_bases[i] == orth) { - return i; - } - } - - return 0; -} - -void Basis::set_orthogonal_index(int p_index) { - //there only exist 24 orthogonal bases in r3 - ERR_FAIL_INDEX(p_index, 24); - - *this = _ortho_bases[p_index]; -} - void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { /* checking this is a bad idea, because obtaining from scaled transform is a valid use case #ifdef MATH_CHECKS diff --git a/core/math/basis.h b/core/math/basis.h index 4be325cdd2ef..2853947ba74f 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -149,9 +149,6 @@ struct _NO_DISCARD_ Basis { _FORCE_INLINE_ void operator*=(const real_t p_val); _FORCE_INLINE_ Basis operator*(const real_t p_val) const; - int get_orthogonal_index() const; - void set_orthogonal_index(int p_index); - bool is_orthogonal() const; bool is_diagonal() const; bool is_rotation() const; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index eba12b68bb0c..32d10f9dddd9 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1916,7 +1916,6 @@ static void _register_variant_builtin_methods() { bind_method(Basis, tdotx, sarray("with"), varray()); bind_method(Basis, tdoty, sarray("with"), varray()); bind_method(Basis, tdotz, sarray("with"), varray()); - bind_method(Basis, get_orthogonal_index, sarray(), varray()); bind_method(Basis, slerp, sarray("to", "weight"), varray()); bind_method(Basis, is_equal_approx, sarray("b"), varray()); bind_method(Basis, get_rotation_quaternion, sarray(), varray()); diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index 8aa6278296d7..d62f704528a2 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -87,12 +87,6 @@ Consider using the [method get_rotation_quaternion] method instead, which returns a [Quaternion] quaternion instead of Euler angles. - - - - This function considers a discretization of rotations into 24 points on unit sphere, lying along the vectors (x,y,z) with each component being either -1, 0, or 1, and returns the index of the point best representing the orientation of the object. It is mainly used by the [GridMap] editor. For further details, refer to the Godot source code. - - diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index d102970932f5..6a6de40fbb1f 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -5442,7 +5442,7 @@ void GLTFDocument::_convert_grid_map_to_gltf(GridMap *p_grid_map, GLTFNodeIndex int32_t cell = p_grid_map->get_cell_item( Vector3(cell_location.x, cell_location.y, cell_location.z)); Transform3D cell_xform; - cell_xform.basis.set_orthogonal_index( + cell_xform.basis = p_grid_map->get_basis_with_orthogonal_index( p_grid_map->get_cell_item_orientation( Vector3(cell_location.x, cell_location.y, cell_location.z))); cell_xform.basis.scale(Vector3(p_grid_map->get_cell_scale(), diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 5552b5b00972..209890a33343 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -39,6 +39,13 @@ Returns an array of [ArrayMesh]es and [Transform3D] references of all bake meshes that exist within the current GridMap. + + + + + Returns one of 24 possible rotations that lie along the vectors (x,y,z) with each component being either -1, 0, or 1. For further details, refer to the Godot source code. + + @@ -46,6 +53,13 @@ The [MeshLibrary] item index located at the given grid coordinates. If the cell is empty, [constant INVALID_CELL_ITEM] will be returned. + + + + + Returns the basis that gives the specificed cell its orientation. + + @@ -80,6 +94,13 @@ Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [code]layer_number[/code] between 1 and 32. + + + + + This function considers a discretization of rotations into 24 points on unit sphere, lying along the vectors (x,y,z) with each component being either -1, 0, or 1, and returns the index (in the range from 0 to 23) of the point best representing the orientation of the object. For further details, refer to the Godot source code. + + @@ -121,7 +142,7 @@ 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]. + Optionally, the item's orientation can be passed. For valid orientation values, see [method get_orthogonal_index_from_basis]. diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index 518e2cf97de6..7471bae09307 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -94,91 +94,91 @@ void GridMapEditor::_menu_option(int p_option) { case MENU_OPTION_CURSOR_ROTATE_Y: { Basis r; if (input_action == INPUT_PASTE) { - r.set_orthogonal_index(paste_indicator.orientation); + r = node->get_basis_with_orthogonal_index(paste_indicator.orientation); r.rotate(Vector3(0, 1, 0), -Math_PI / 2.0); - paste_indicator.orientation = r.get_orthogonal_index(); + paste_indicator.orientation = node->get_orthogonal_index_from_basis(r); _update_paste_indicator(); break; } - r.set_orthogonal_index(cursor_rot); + r = node->get_basis_with_orthogonal_index(cursor_rot); r.rotate(Vector3(0, 1, 0), -Math_PI / 2.0); - cursor_rot = r.get_orthogonal_index(); + cursor_rot = node->get_orthogonal_index_from_basis(r); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_ROTATE_X: { Basis r; if (input_action == INPUT_PASTE) { - r.set_orthogonal_index(paste_indicator.orientation); + r = node->get_basis_with_orthogonal_index(paste_indicator.orientation); r.rotate(Vector3(1, 0, 0), -Math_PI / 2.0); - paste_indicator.orientation = r.get_orthogonal_index(); + paste_indicator.orientation = node->get_orthogonal_index_from_basis(r); _update_paste_indicator(); break; } - r.set_orthogonal_index(cursor_rot); + r = node->get_basis_with_orthogonal_index(cursor_rot); r.rotate(Vector3(1, 0, 0), -Math_PI / 2.0); - cursor_rot = r.get_orthogonal_index(); + cursor_rot = node->get_orthogonal_index_from_basis(r); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_ROTATE_Z: { Basis r; if (input_action == INPUT_PASTE) { - r.set_orthogonal_index(paste_indicator.orientation); + r = node->get_basis_with_orthogonal_index(paste_indicator.orientation); r.rotate(Vector3(0, 0, 1), -Math_PI / 2.0); - paste_indicator.orientation = r.get_orthogonal_index(); + paste_indicator.orientation = node->get_orthogonal_index_from_basis(r); _update_paste_indicator(); break; } - r.set_orthogonal_index(cursor_rot); + r = node->get_basis_with_orthogonal_index(cursor_rot); r.rotate(Vector3(0, 0, 1), -Math_PI / 2.0); - cursor_rot = r.get_orthogonal_index(); + cursor_rot = node->get_orthogonal_index_from_basis(r); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_Y: { Basis r; if (input_action == INPUT_PASTE) { - r.set_orthogonal_index(paste_indicator.orientation); + r = node->get_basis_with_orthogonal_index(paste_indicator.orientation); r.rotate(Vector3(0, 1, 0), Math_PI / 2.0); - paste_indicator.orientation = r.get_orthogonal_index(); + paste_indicator.orientation = node->get_orthogonal_index_from_basis(r); _update_paste_indicator(); break; } - r.set_orthogonal_index(cursor_rot); + r = node->get_basis_with_orthogonal_index(cursor_rot); r.rotate(Vector3(0, 1, 0), Math_PI / 2.0); - cursor_rot = r.get_orthogonal_index(); + cursor_rot = node->get_orthogonal_index_from_basis(r); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_X: { Basis r; if (input_action == INPUT_PASTE) { - r.set_orthogonal_index(paste_indicator.orientation); + r = node->get_basis_with_orthogonal_index(paste_indicator.orientation); r.rotate(Vector3(1, 0, 0), Math_PI / 2.0); - paste_indicator.orientation = r.get_orthogonal_index(); + paste_indicator.orientation = node->get_orthogonal_index_from_basis(r); _update_paste_indicator(); break; } - r.set_orthogonal_index(cursor_rot); + r = node->get_basis_with_orthogonal_index(cursor_rot); r.rotate(Vector3(1, 0, 0), Math_PI / 2.0); - cursor_rot = r.get_orthogonal_index(); + cursor_rot = node->get_orthogonal_index_from_basis(r); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_Z: { Basis r; if (input_action == INPUT_PASTE) { - r.set_orthogonal_index(paste_indicator.orientation); + r = node->get_basis_with_orthogonal_index(paste_indicator.orientation); r.rotate(Vector3(0, 0, 1), Math_PI / 2.0); - paste_indicator.orientation = r.get_orthogonal_index(); + paste_indicator.orientation = node->get_orthogonal_index_from_basis(r); _update_paste_indicator(); break; } - r.set_orthogonal_index(cursor_rot); + r = node->get_basis_with_orthogonal_index(cursor_rot); r.rotate(Vector3(0, 0, 1), Math_PI / 2.0); - cursor_rot = r.get_orthogonal_index(); + cursor_rot = node->get_orthogonal_index_from_basis(r); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_CLEAR_ROTATION: { @@ -242,7 +242,7 @@ void GridMapEditor::_menu_option(int p_option) { void GridMapEditor::_update_cursor_transform() { cursor_transform = Transform3D(); cursor_transform.origin = cursor_origin; - cursor_transform.basis.set_orthogonal_index(cursor_rot); + cursor_transform.basis = node->get_basis_with_orthogonal_index(cursor_rot); cursor_transform.basis *= node->get_cell_scale(); cursor_transform = node->get_global_transform() * cursor_transform; @@ -543,7 +543,7 @@ void GridMapEditor::_update_paste_indicator() { xf.scale(scale); xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size(); Basis rot; - rot.set_orthogonal_index(paste_indicator.orientation); + rot = node->get_basis_with_orthogonal_index(paste_indicator.orientation); xf.basis = rot * xf.basis; xf.translate_local((-center * node->get_cell_size()) / scale); @@ -556,7 +556,7 @@ void GridMapEditor::_update_paste_indicator() { xf.translate_local(item.grid_offset * node->get_cell_size()); Basis item_rot; - item_rot.set_orthogonal_index(item.orientation); + item_rot = node->get_basis_with_orthogonal_index(item.orientation); xf.basis = item_rot * xf.basis * node->get_cell_scale(); RenderingServer::get_singleton()->instance_set_transform(item.instance, node->get_global_transform() * xf); @@ -568,7 +568,7 @@ void GridMapEditor::_do_paste() { bool reselect = options->get_popup()->is_item_checked(idx); Basis rot; - rot.set_orthogonal_index(paste_indicator.orientation); + rot = node->get_basis_with_orthogonal_index(paste_indicator.orientation); Vector3 ofs = paste_indicator.current - paste_indicator.click; undo_redo->create_action(TTR("GridMap Paste Selection")); @@ -577,10 +577,10 @@ void GridMapEditor::_do_paste() { Vector3 position = rot.xform(item.grid_offset) + paste_indicator.begin + ofs; Basis orm; - orm.set_orthogonal_index(item.orientation); + orm = node->get_basis_with_orthogonal_index(item.orientation); orm = rot * orm; - undo_redo->add_do_method(node, "set_cell_item", position, item.cell_item, orm.get_orthogonal_index()); + undo_redo->add_do_method(node, "set_cell_item", position, item.cell_item, node->get_orthogonal_index_from_basis(orm)); undo_redo->add_undo_method(node, "set_cell_item", position, node->get_cell_item(position), node->get_cell_item_orientation(position)); } diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 7d80cbef7ceb..6384446bce72 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -428,6 +428,75 @@ int GridMap::get_cell_item_orientation(const Vector3i &p_position) const { return cell_map[key].rot; } +static const Basis _ortho_bases[24] = { + Basis(1, 0, 0, 0, 1, 0, 0, 0, 1), + Basis(0, -1, 0, 1, 0, 0, 0, 0, 1), + Basis(-1, 0, 0, 0, -1, 0, 0, 0, 1), + Basis(0, 1, 0, -1, 0, 0, 0, 0, 1), + Basis(1, 0, 0, 0, 0, -1, 0, 1, 0), + Basis(0, 0, 1, 1, 0, 0, 0, 1, 0), + Basis(-1, 0, 0, 0, 0, 1, 0, 1, 0), + Basis(0, 0, -1, -1, 0, 0, 0, 1, 0), + Basis(1, 0, 0, 0, -1, 0, 0, 0, -1), + Basis(0, 1, 0, 1, 0, 0, 0, 0, -1), + Basis(-1, 0, 0, 0, 1, 0, 0, 0, -1), + Basis(0, -1, 0, -1, 0, 0, 0, 0, -1), + Basis(1, 0, 0, 0, 0, 1, 0, -1, 0), + Basis(0, 0, -1, 1, 0, 0, 0, -1, 0), + Basis(-1, 0, 0, 0, 0, -1, 0, -1, 0), + Basis(0, 0, 1, -1, 0, 0, 0, -1, 0), + Basis(0, 0, 1, 0, 1, 0, -1, 0, 0), + Basis(0, -1, 0, 0, 0, 1, -1, 0, 0), + Basis(0, 0, -1, 0, -1, 0, -1, 0, 0), + Basis(0, 1, 0, 0, 0, -1, -1, 0, 0), + Basis(0, 0, 1, 0, -1, 0, 1, 0, 0), + Basis(0, 1, 0, 0, 0, 1, 1, 0, 0), + Basis(0, 0, -1, 0, 1, 0, 1, 0, 0), + Basis(0, -1, 0, 0, 0, -1, 1, 0, 0) +}; + +Basis GridMap::get_cell_item_basis(const Vector3i &p_position) const { + int orientation = get_cell_item_orientation(p_position); + + if (orientation == -1) { + return Basis(); + } + + return get_basis_with_orthogonal_index(orientation); +} + +Basis GridMap::get_basis_with_orthogonal_index(int p_index) const { + ERR_FAIL_INDEX_V(p_index, 24, Basis()); + + return _ortho_bases[p_index]; +} + +int GridMap::get_orthogonal_index_from_basis(const Basis &p_basis) const { + Basis orth = p_basis; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + real_t v = orth[i][j]; + if (v > 0.5) { + v = 1.0; + } else if (v < -0.5) { + v = -1.0; + } else { + v = 0; + } + + orth[i][j] = v; + } + } + + for (int i = 0; i < 24; i++) { + if (_ortho_bases[i] == orth) { + return i; + } + } + + return 0; +} + Vector3i GridMap::world_to_map(const Vector3 &p_world_position) const { Vector3 map_position = (p_world_position / cell_size).floor(); return Vector3i(map_position); @@ -529,7 +598,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Transform3D xform; - xform.basis.set_orthogonal_index(c.rot); + xform.basis = _ortho_bases[c.rot]; xform.set_origin(cellpos * cell_size + ofs); xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); if (baked_meshes.size() == 0) { @@ -921,6 +990,9 @@ void GridMap::_bind_methods() { 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("get_cell_item_basis", "position"), &GridMap::get_cell_item_basis); + ClassDB::bind_method(D_METHOD("get_basis_with_orthogonal_index", "index"), &GridMap::get_basis_with_orthogonal_index); + ClassDB::bind_method(D_METHOD("get_orthogonal_index_from_basis", "basis"), &GridMap::get_orthogonal_index_from_basis); 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); @@ -1025,7 +1097,7 @@ Array GridMap::get_meshes() const { Transform3D xform; - xform.basis.set_orthogonal_index(E.value.rot); + xform.basis = _ortho_bases[E.value.rot]; xform.set_origin(cellpos * cell_size + ofs); xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); @@ -1079,7 +1151,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe Transform3D xform; - xform.basis.set_orthogonal_index(E.value.rot); + xform.basis = _ortho_bases[E.value.rot]; xform.set_origin(cellpos * cell_size + ofs); xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 078a1d9de580..00cebd35e986 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -263,6 +263,9 @@ public: 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; + Basis get_cell_item_basis(const Vector3i &p_position) const; + Basis get_basis_with_orthogonal_index(int p_index) const; + int get_orthogonal_index_from_basis(const Basis &p_basis) const; Vector3i world_to_map(const Vector3 &p_world_position) const; Vector3 map_to_world(const Vector3i &p_map_position) const;