diff --git a/core/math/aabb.h b/core/math/aabb.h index e16246902a..97d92fbe37 100644 --- a/core/math/aabb.h +++ b/core/math/aabb.h @@ -118,6 +118,10 @@ public: return position + size; } + _FORCE_INLINE_ Vector3 get_center() const { + return position + (size * 0.5); + } + operator String() const; _FORCE_INLINE_ AABB() {} diff --git a/core/math/delaunay_2d.h b/core/math/delaunay_2d.h index 95064e5700..2f80cb5634 100644 --- a/core/math/delaunay_2d.h +++ b/core/math/delaunay_2d.h @@ -101,7 +101,7 @@ public: } float delta_max = MAX(rect.size.width, rect.size.height); - Vector2 center = rect.position + rect.size * 0.5; + Vector2 center = rect.get_center(); points.push_back(Vector2(center.x - 20 * delta_max, center.y - delta_max)); points.push_back(Vector2(center.x, center.y + 20 * delta_max)); diff --git a/core/math/rect2.h b/core/math/rect2.h index ab0b489b4a..2557959fa2 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -46,6 +46,8 @@ struct Rect2 { real_t get_area() const { return size.width * size.height; } + _FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5); } + inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const { if (p_include_borders) { if (position.x > (p_rect.position.x + p_rect.size.width)) { @@ -259,7 +261,7 @@ struct Rect2 { } _FORCE_INLINE_ bool intersects_filled_polygon(const Vector2 *p_points, int p_point_count) const { - Vector2 center = position + size * 0.5; + Vector2 center = get_center(); int side_plus = 0; int side_minus = 0; Vector2 end = position + size; @@ -344,6 +346,8 @@ struct Rect2i { int get_area() const { return size.width * size.height; } + _FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); } + inline bool intersects(const Rect2i &p_rect) const { if (position.x > (p_rect.position.x + p_rect.size.width)) { return false; diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index bf06c848c5..16d9652ef2 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -76,7 +76,7 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in int index = r_max_alloc++; BVH *_new = &p_bvh[index]; _new->aabb = aabb; - _new->center = aabb.position + aabb.size * 0.5; + _new->center = aabb.get_center(); _new->face_index = -1; _new->left = left; _new->right = right; @@ -152,7 +152,7 @@ void TriangleMesh::create(const Vector &p_faces) { bw[i].left = -1; bw[i].right = -1; bw[i].face_index = i; - bw[i].center = bw[i].aabb.position + bw[i].aabb.size * 0.5; + bw[i].center = bw[i].aabb.get_center(); } vertices.resize(db.size()); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 49a0b455df..7bce060044 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1513,6 +1513,7 @@ static void _register_variant_builtin_methods() { /* Rect2 */ + bind_method(Rect2, get_center, sarray(), varray()); bind_method(Rect2, get_area, sarray(), varray()); bind_method(Rect2, has_no_area, sarray(), varray()); bind_method(Rect2, has_point, sarray("point"), varray()); @@ -1529,6 +1530,7 @@ static void _register_variant_builtin_methods() { /* Rect2i */ + bind_method(Rect2i, get_center, sarray(), varray()); bind_method(Rect2i, get_area, sarray(), varray()); bind_method(Rect2i, has_no_area, sarray(), varray()); bind_method(Rect2i, has_point, sarray("point"), varray()); @@ -1736,6 +1738,7 @@ static void _register_variant_builtin_methods() { /* AABB */ bind_method(AABB, abs, sarray(), varray()); + bind_method(AABB, get_center, sarray(), varray()); bind_method(AABB, get_area, sarray(), varray()); bind_method(AABB, has_no_area, sarray(), varray()); bind_method(AABB, has_no_surface, sarray(), varray()); diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml index 46fb446881..818d159d36 100644 --- a/doc/classes/AABB.xml +++ b/doc/classes/AABB.xml @@ -61,6 +61,12 @@ Returns the volume of the [AABB]. + + + + Returns the center of the [AABB], which is equal to [member position] + ([member size] / 2). + + diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml index 915099dc1c..fa8c57cd0c 100644 --- a/doc/classes/Rect2.xml +++ b/doc/classes/Rect2.xml @@ -78,6 +78,12 @@ Returns the area of the [Rect2]. + + + + Returns the center of the [Rect2], which is equal to [member position] + ([member size] / 2). + + diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml index 2a98e0c087..00a8cf01c6 100644 --- a/doc/classes/Rect2i.xml +++ b/doc/classes/Rect2i.xml @@ -76,6 +76,13 @@ Returns the area of the [Rect2i]. + + + + Returns the center of the [Rect2i], which is equal to [member position] + ([member size] / 2). + If [member size] is an odd number, the returned center value will be rounded towards [member position]. + + diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 5baffb6f9d..99b917107e 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -104,7 +104,7 @@ Vector> EditorInterface::make_mesh_previews(const Vectorinstance_set_transform(inst, mesh_xform); AABB aabb = mesh->get_aabb(); - Vector3 ofs = aabb.position + aabb.size * 0.5; + Vector3 ofs = aabb.get_center(); aabb.position -= ofs; Transform3D xform; xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI / 6); diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 8cd636ddf3..afeba4f6fb 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -328,7 +328,7 @@ void EditorSpinSlider::_draw_spin_slider() { Rect2 grabber_rect = Rect2(ofs + gofs, svofs + 1, grabber_w, 2 * EDSCALE); draw_rect(grabber_rect, c); - grabbing_spinner_mouse_pos = get_global_position() + grabber_rect.position + grabber_rect.size * 0.5; + grabbing_spinner_mouse_pos = get_global_position() + grabber_rect.get_center(); bool display_grabber = (mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !(value_input_popup && value_input_popup->is_visible()); if (grabber->is_visible() != display_grabber) { @@ -354,7 +354,7 @@ void EditorSpinSlider::_draw_spin_slider() { Vector2 scale = get_global_transform_with_canvas().get_scale(); grabber->set_scale(scale); grabber->set_size(Size2(0, 0)); - grabber->set_position(get_global_position() + (grabber_rect.position + grabber_rect.size * 0.5 - grabber->get_size() * 0.5) * scale); + grabber->set_position(get_global_position() + (grabber_rect.get_center() - grabber->get_size() * 0.5) * scale); if (mousewheel_over_grabber) { Input::get_singleton()->warp_mouse_position(grabber->get_position() + grabber_rect.size); diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 4bcb6863fb..f99ab9888a 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -434,7 +434,7 @@ void SceneImportSettings::_update_camera() { } } - Vector3 center = camera_aabb.position + camera_aabb.size * 0.5; + Vector3 center = camera_aabb.get_center(); float camera_size = camera_aabb.get_longest_axis_size(); camera->set_orthogonal(camera_size * zoom, 0.0001, camera_size * 2); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index db5be94fd2..04192efecd 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -387,7 +387,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig // Self center if ((is_snap_active && snap_node_center && (p_modes & SNAP_NODE_CENTER)) || (p_forced_modes & SNAP_NODE_CENTER)) { if (p_self_canvas_item->_edit_use_rect()) { - Point2 center = p_self_canvas_item->get_global_transform_with_canvas().xform(p_self_canvas_item->_edit_get_rect().get_position() + p_self_canvas_item->_edit_get_rect().get_size() / 2.0); + Point2 center = p_self_canvas_item->get_global_transform_with_canvas().xform(p_self_canvas_item->_edit_get_rect().get_center()); _snap_if_closer_point(p_target, output, snap_target, center, SNAP_TARGET_SELF, rotation); } else { Point2 position = p_self_canvas_item->get_global_transform_with_canvas().xform(Point2()); @@ -525,7 +525,7 @@ Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List p_li // Handles the first element CanvasItem *canvas_item = p_list.front()->get(); - Rect2 rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_rect().position + canvas_item->_edit_get_rect().size / 2), Size2()); + Rect2 rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_rect().get_center()), Size2()); // Expand with the other ones for (CanvasItem *canvas_item2 : p_list) { @@ -564,7 +564,7 @@ void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, c Transform2D xform = p_parent_xform * p_canvas_xform * canvas_item->get_transform(); Rect2 rect = canvas_item->_edit_get_rect(); if (r_first) { - r_rect = Rect2(xform.xform(rect.position + rect.size / 2), Size2()); + r_rect = Rect2(xform.xform(rect.get_center()), Size2()); r_first = false; } r_rect.expand_to(xform.xform(rect.position)); @@ -4896,7 +4896,7 @@ void CanvasItemEditor::_focus_selection(int p_op) { }; if (p_op == VIEW_CENTER_TO_SELECTION) { - center = rect.position + rect.size / 2; + center = rect.get_center(); Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center); view_offset.x -= Math::round(offset.x / zoom); view_offset.y -= Math::round(offset.y / zoom); diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 415832ab3b..4cb2c0a76b 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -718,7 +718,7 @@ Ref EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 RS::get_singleton()->instance_set_base(mesh_instance, mesh->get_rid()); AABB aabb = mesh->get_aabb(); - Vector3 ofs = aabb.position + aabb.size * 0.5; + Vector3 ofs = aabb.get_center(); aabb.position -= ofs; Transform3D xform; xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI * 0.125); diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 768f29e15a..dc16a7a325 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -80,7 +80,7 @@ void MeshEditor::edit(Ref p_mesh) { _update_rotation(); AABB aabb = mesh->get_aabb(); - Vector3 ofs = aabb.position + aabb.size * 0.5; + Vector3 ofs = aabb.get_center(); float m = aabb.get_longest_axis_size(); if (m != 0) { m = 1.0 / m; diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 0f98629370..eb771f2bc4 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -2652,7 +2652,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; - Vector3 ofs = aabb.position + aabb.size * 0.5; + Vector3 ofs = aabb.get_center(); Vector3 axis; axis[p_id] = 1.0; @@ -2728,7 +2728,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { handles.push_back(ax); } - Vector3 center = aabb.position + aabb.size * 0.5; + Vector3 center = aabb.get_center(); for (int i = 0; i < 3; i++) { Vector3 ax; ax[i] = 1.0; @@ -2744,7 +2744,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (p_gizmo->is_selected()) { Ref solid_material = get_material("visibility_notifier_solid_material", p_gizmo); - p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0); + p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_center()); } p_gizmo->add_handles(handles, get_material("handles")); @@ -2843,7 +2843,7 @@ void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; - Vector3 ofs = aabb.position + aabb.size * 0.5; + Vector3 ofs = aabb.get_center(); Vector3 axis; axis[p_id] = 1.0; @@ -2919,7 +2919,7 @@ void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { handles.push_back(ax); } - Vector3 center = aabb.position + aabb.size * 0.5; + Vector3 center = aabb.get_center(); for (int i = 0; i < 3; i++) { Vector3 ax; ax[i] = 1.0; @@ -2935,7 +2935,7 @@ void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (p_gizmo->is_selected()) { Ref solid_material = get_material("particles_solid_material", p_gizmo); - p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0); + p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_center()); } p_gizmo->add_handles(handles, get_material("handles")); diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp index d54906c98c..d75013cfcf 100644 --- a/editor/plugins/tiles/atlas_merging_dialog.cpp +++ b/editor/plugins/tiles/atlas_merging_dialog.cpp @@ -99,7 +99,7 @@ void AtlasMergingDialog::_generate_merged(Vector> p_atla if (dst_rect_wide.get_end().x > output_image->get_width() || dst_rect_wide.get_end().y > output_image->get_height()) { output_image->crop(MAX(dst_rect_wide.get_end().x, output_image->get_width()), MAX(dst_rect_wide.get_end().y, output_image->get_height())); } - output_image->blit_rect(atlas_source->get_texture()->get_image(), src_rect, (dst_rect_wide.get_position() + dst_rect_wide.get_end()) / 2 - src_rect.size / 2); + output_image->blit_rect(atlas_source->get_texture()->get_image(), src_rect, dst_rect_wide.get_center() - src_rect.size / 2); } // Compute the atlas offset. diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 6e0a5b00b9..8d76f5f1b4 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -330,7 +330,7 @@ void TileAtlasView::_draw_base_tiles_shape_grid() { // Draw only if the tile shape fits in the texture region Transform2D tile_xform; - tile_xform.set_origin(texture_region.position + texture_region.size / 2 + in_tile_base_offset); + tile_xform.set_origin(texture_region.get_center() + in_tile_base_offset); tile_xform.set_scale(tile_shape_size); tile_set->draw_tile_shape(base_tiles_shape_grid, tile_xform, grid_color); } diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 2a75a743a7..ea7ca787c8 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -1495,7 +1495,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas TileData *tile_data = Object::cast_to(p_tile_set_atlas_source->get_tile_data(hovered_coords, 0)); int terrain_set = tile_data->get_terrain_set(); Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(hovered_coords); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(hovered_coords, 0); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(hovered_coords, 0); if (terrain_set >= 0 && terrain_set == int(dummy_object->get("terrain_set"))) { // Draw hovered bit. @@ -1540,7 +1540,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas // Text p_canvas_item->draw_set_transform_matrix(Transform2D()); Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(coords); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); Color color = Color(1, 1, 1); String text; @@ -1632,7 +1632,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas Vector2i coords = E->get().get_atlas_coords(); Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(coords); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); @@ -1668,7 +1668,7 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til TileData *tile_data = Object::cast_to(p_tile_set_atlas_source->get_tile_data(hovered_coords, hovered_alternative)); int terrain_set = tile_data->get_terrain_set(); Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(hovered_coords, hovered_alternative); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(hovered_coords, hovered_alternative); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(hovered_coords, hovered_alternative); if (terrain_set == int(dummy_object->get("terrain_set"))) { // Draw hovered bit. @@ -1715,7 +1715,7 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til // Text p_canvas_item->draw_set_transform_matrix(Transform2D()); Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); Color color = Color(1, 1, 1); String text; @@ -1796,7 +1796,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t // Set the terrains bits. Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(coords); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); for (int j = 0; j < TileSet::CELL_NEIGHBOR_MAX; j++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(j); if (tile_data->is_valid_peering_bit_terrain(bit)) { @@ -1824,7 +1824,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t TileData *tile_data = Object::cast_to(p_tile_set_atlas_source->get_tile_data(coords, 0)); int terrain_set = tile_data->get_terrain_set(); Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(coords); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); dummy_object->set("terrain_set", terrain_set); dummy_object->set("terrain", -1); for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { @@ -1922,7 +1922,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t // Set the terrain bit. Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(coords); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); @@ -2055,7 +2055,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); if (tile_set->is_valid_peering_bit_terrain(terrain_set, bit)) { Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(coords); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); Vector polygon = tile_set->get_terrain_bit_polygon(terrain_set, bit); for (int j = 0; j < polygon.size(); j++) { @@ -2138,7 +2138,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi // Set the terrains bits. Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); for (int j = 0; j < TileSet::CELL_NEIGHBOR_MAX; j++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(j); if (tile_data->is_valid_peering_bit_terrain(bit)) { @@ -2167,7 +2167,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi TileData *tile_data = Object::cast_to(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile)); int terrain_set = tile_data->get_terrain_set(); Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); dummy_object->set("terrain_set", terrain_set); dummy_object->set("terrain", -1); for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { @@ -2242,7 +2242,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi // Set the terrain bit. Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); + Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile); for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { TileSet::CellNeighbor bit = TileSet::CellNeighbor(i); if (tile_set->is_valid_peering_bit_terrain(terrain_set, bit)) { diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index c3a3f40e00..9370708a3e 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -1638,7 +1638,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_unscaled_draw() { for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) { Vector2i coords = tile_set_atlas_source->get_tile_id(i); Rect2i texture_region = tile_set_atlas_source->get_tile_texture_region(coords); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); + Vector2i position = texture_region.get_center() + tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); Transform2D xform = tile_atlas_control->get_parent_control()->get_transform(); xform.translate(position); @@ -1661,7 +1661,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_unscaled_draw() { continue; } Rect2i texture_region = tile_set_atlas_source->get_tile_texture_region(E->get().tile); - Vector2i position = (texture_region.position + texture_region.get_end()) / 2 + tile_set_atlas_source->get_tile_effective_texture_offset(E->get().tile, 0); + Vector2i position = texture_region.get_center() + tile_set_atlas_source->get_tile_effective_texture_offset(E->get().tile, 0); Transform2D xform = tile_atlas_control->get_parent_control()->get_transform(); xform.translate(position); @@ -1805,7 +1805,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { continue; } Rect2i rect = tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile); - Vector2 position = (rect.get_position() + rect.get_end()) / 2; + Vector2 position = rect.get_center(); Transform2D xform = alternative_tiles_control->get_parent_control()->get_transform(); xform.translate(position); @@ -1829,7 +1829,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { continue; } Rect2i rect = tile_atlas_view->get_alternative_tile_rect(E->get().tile, E->get().alternative); - Vector2 position = (rect.get_position() + rect.get_end()) / 2; + Vector2 position = rect.get_center(); Transform2D xform = alternative_tiles_control->get_parent_control()->get_transform(); xform.translate(position); diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index cb82b65307..cbe41a1310 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -517,7 +517,7 @@ int CSGBrushOperation::MeshMerge::_create_bvh(FaceBVH *facebvhptr, FaceBVH **fac int index = r_max_alloc++; FaceBVH *_new = &facebvhptr[index]; _new->aabb = aabb; - _new->center = aabb.position + aabb.size * 0.5; + _new->center = aabb.get_center(); _new->face = -1; _new->left = left; _new->right = right; @@ -678,7 +678,7 @@ void CSGBrushOperation::MeshMerge::mark_inside_faces() { facebvh[i].aabb.position = points[faces[i].points[0]]; facebvh[i].aabb.expand_to(points[faces[i].points[1]]); facebvh[i].aabb.expand_to(points[faces[i].points[2]]); - facebvh[i].center = facebvh[i].aabb.position + facebvh[i].aabb.size * 0.5; + facebvh[i].center = facebvh[i].aabb.get_center(); facebvh[i].aabb.grow_by(vertex_snap); facebvh[i].next = -1; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs index 8b12537f7f..70a2cf5695 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs @@ -66,6 +66,16 @@ namespace Godot return new AABB(topLeft, _size.Abs()); } + /// + /// Returns the center of the , which is equal + /// to + ( / 2). + /// + /// The center. + public Vector3 GetCenter() + { + return _position + (_size * 0.5f); + } + /// /// Returns if this completely encloses another one. /// diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs index 1d001fba2d..af94484577 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs @@ -164,6 +164,16 @@ namespace Godot return _size.x * _size.y; } + /// + /// Returns the center of the , which is equal + /// to + ( / 2). + /// + /// The center. + public Vector2 GetCenter() + { + return _position + (_size * 0.5f); + } + /// /// Returns a copy of the grown by the specified amount /// on all sides. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs index 250b0d0baf..03f406a910 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs @@ -151,7 +151,7 @@ namespace Godot } /// - /// Returns the area of the . + /// Returns the area of the . /// /// The area. public int GetArea() @@ -159,6 +159,18 @@ namespace Godot return _size.x * _size.y; } + /// + /// Returns the center of the , which is equal + /// to + ( / 2). + /// If is an odd number, the returned center + /// value will be rounded towards . + /// + /// The center. + public Vector2i GetCenter() + { + return _position + (_size / 2); + } + /// /// Returns a copy of the grown by the specified amount /// on all sides. diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index bf91ce8e65..8195d98f55 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -198,7 +198,7 @@ Transform2D Camera2D::get_camera_transform() { screen_rect.position += offset; } - camera_screen_center = screen_rect.position + screen_rect.size * 0.5; + camera_screen_center = screen_rect.get_center(); Transform2D xform; xform.scale_basis(zoom); diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index a34a30913e..4fa34615bf 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -420,7 +420,7 @@ Ref GPUParticlesCollisionSDF::bake() { } //test against original bounds - if (!Geometry3D::triangle_box_overlap(aabb.position + aabb.size * 0.5, aabb.size * 0.5, face.vertex)) { + if (!Geometry3D::triangle_box_overlap(aabb.get_center(), aabb.size * 0.5, face.vertex)) { continue; } @@ -438,7 +438,7 @@ Ref GPUParticlesCollisionSDF::bake() { } //test against original bounds - if (!Geometry3D::triangle_box_overlap(aabb.position + aabb.size * 0.5, aabb.size * 0.5, face.vertex)) { + if (!Geometry3D::triangle_box_overlap(aabb.get_center(), aabb.size * 0.5, face.vertex)) { continue; } diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 7dd083e314..b56f0fd145 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -467,7 +467,7 @@ int32_t LightmapGI::_compute_bsp_tree(const Vector &p_points, const Loc } } if (i == 0) { - centers.push_back(bounds.position + bounds.size * 0.5); + centers.push_back(bounds.get_center()); } else { bounds_all.merge_with(bounds); } @@ -555,7 +555,7 @@ void LightmapGI::_plot_triangle_into_octree(GenProbesOctree *p_cell, float p_cel subcell.position = Vector3(pos) * p_cell_size; subcell.size = Vector3(half_size, half_size, half_size) * p_cell_size; - if (!Geometry3D::triangle_box_overlap(subcell.position + subcell.size * 0.5, subcell.size * 0.5, p_triangle)) { + if (!Geometry3D::triangle_box_overlap(subcell.get_center(), subcell.size * 0.5, p_triangle)) { continue; } diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 2d32379d69..04f371f4b2 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -173,7 +173,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co //could not in any way get texture information.. so use closest point to center Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]); - Vector3 inters = f.get_closest_point_to(p_aabb.position + p_aabb.size * 0.5); + Vector3 inters = f.get_closest_point_to(p_aabb.get_center()); Vector3 lnormal; Vector2 uv; @@ -434,7 +434,7 @@ void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref &p_mesh, const V } //test against original bounds - if (!Geometry3D::triangle_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) { + if (!Geometry3D::triangle_box_overlap(original_bounds.get_center(), original_bounds.size * 0.5, vtxs)) { continue; } //plot @@ -466,7 +466,7 @@ void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref &p_mesh, const V } //test against original bounds - if (!Geometry3D::triangle_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) { + if (!Geometry3D::triangle_box_overlap(original_bounds.get_center(), original_bounds.size * 0.5, vtxs)) { continue; } //plot face @@ -885,7 +885,7 @@ Vector Voxelizer::get_sdf_3d_image() const { void Voxelizer::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref &p_multimesh, int &idx) { if (p_level == cell_subdiv - 1) { - Vector3 center = p_aabb.position + p_aabb.size * 0.5; + Vector3 center = p_aabb.get_center(); Transform3D xform; xform.origin = center; xform.basis.scale(p_aabb.size * 0.5); diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index 1533d6e592..7deddb000e 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -1576,7 +1576,7 @@ void ConcavePolygonShape3DSW::_setup(const Vector &p_faces, bool p_back Face3 face(facesr[i * 3 + 0], facesr[i * 3 + 1], facesr[i * 3 + 2]); bvh_arrayw[i].aabb = face.get_aabb(); - bvh_arrayw[i].center = bvh_arrayw[i].aabb.position + bvh_arrayw[i].aabb.size * 0.5; + bvh_arrayw[i].center = bvh_arrayw[i].aabb.get_center(); bvh_arrayw[i].face_index = i; facesw[i].indices[0] = i * 3 + 0; facesw[i].indices[1] = i * 3 + 1; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 3c66fadbe9..f507a83072 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1621,7 +1621,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh Vector2 light_dir = p_light_xform.elements[1].normalized(); - Vector2 center = p_clip_rect.position + p_clip_rect.size * 0.5; + Vector2 center = p_clip_rect.get_center(); float to_edge_distance = ABS(light_dir.dot(p_clip_rect.get_support(light_dir)) - light_dir.dot(center)); diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp index 36943c5e5c..fb308da38d 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp @@ -2575,7 +2575,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c Vector3 render_dir = render_z[j]; Vector3 up_dir = render_up[j]; - Vector3 center = aabb.position + aabb.size * 0.5; + Vector3 center = aabb.get_center(); Transform3D xform; xform.set_look_at(center - aabb.size * 0.5 * render_dir, center, up_dir); diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index cd8014632d..a4e4715292 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1286,7 +1286,7 @@ void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_ins vd.range_end = p_instance->visibility_range_end; vd.range_begin_margin = p_instance->visibility_range_begin_margin; vd.range_end_margin = p_instance->visibility_range_end_margin; - vd.position = p_instance->transformed_aabb.get_position() + p_instance->transformed_aabb.get_size() / 2.0f; + vd.position = p_instance->transformed_aabb.get_center(); vd.array_index = p_instance->array_index; InstanceGeometryData *geom_data = static_cast(p_instance->base_data); @@ -1636,7 +1636,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { } if (p_instance->visibility_index != -1) { - p_instance->scenario->instance_visibility[p_instance->visibility_index].position = p_instance->transformed_aabb.get_position() + p_instance->transformed_aabb.get_size() / 2.0f; + p_instance->scenario->instance_visibility[p_instance->visibility_index].position = p_instance->transformed_aabb.get_center(); } //move instance and repair @@ -1851,7 +1851,7 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) } Transform3D to_bounds = lightmap->transform.affine_inverse(); - Vector3 center = p_instance->transform.xform(p_instance->aabb.position + p_instance->aabb.size * 0.5); //use aabb center + Vector3 center = p_instance->transform.xform(p_instance->aabb.get_center()); //use aabb center Vector3 lm_pos = to_bounds.xform(center); diff --git a/tests/test_aabb.h b/tests/test_aabb.h index c4daa56e5a..2724d9481a 100644 --- a/tests/test_aabb.h +++ b/tests/test_aabb.h @@ -65,6 +65,9 @@ TEST_CASE("[AABB] Basic getters") { CHECK_MESSAGE( aabb.get_end().is_equal_approx(Vector3(2.5, 7, 3.5)), "get_end() should return the expected value."); + CHECK_MESSAGE( + aabb.get_center().is_equal_approx(Vector3(0.5, 4.5, 0.5)), + "get_center() should return the expected value."); } TEST_CASE("[AABB] Basic setters") { diff --git a/tests/test_rect2.h b/tests/test_rect2.h index c5740167db..3d9fe5a32e 100644 --- a/tests/test_rect2.h +++ b/tests/test_rect2.h @@ -76,6 +76,12 @@ TEST_CASE("[Rect2] Basic getters") { CHECK_MESSAGE( rect.get_end().is_equal_approx(Vector2(1280, 820)), "get_end() should return the expected value."); + CHECK_MESSAGE( + rect.get_center().is_equal_approx(Vector2(640, 460)), + "get_center() should return the expected value."); + CHECK_MESSAGE( + Rect2(0, 100, 1281, 721).get_center().is_equal_approx(Vector2(640.5, 460.5)), + "get_center() should return the expected value."); } TEST_CASE("[Rect2] Basic setters") { @@ -288,6 +294,12 @@ TEST_CASE("[Rect2i] Basic getters") { CHECK_MESSAGE( rect.get_end() == Vector2i(1280, 820), "get_end() should return the expected value."); + CHECK_MESSAGE( + rect.get_center() == Vector2i(640, 460), + "get_center() should return the expected value."); + CHECK_MESSAGE( + Rect2i(0, 100, 1281, 721).get_center() == Vector2i(640, 460), + "get_center() should return the expected value."); } TEST_CASE("[Rect2i] Basic setters") {