@@ -69,8 +69,10 @@ void NavigationObstacle3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
6969 }
7070
7171 float height = obstacle->get_height ();
72- Basis gbi = obstacle->get_global_basis ().inverse ();
7372
73+ const Basis safe_basis = Basis (Vector3 (0.0 , 1.0 , 0.0 ), obstacle->get_global_rotation ().y , obstacle->get_global_basis ().get_scale ().abs ().maxf (0.001 ));
74+ const Basis gbi = obstacle->get_global_basis ().inverse ();
75+ const Basis safe_global_basis = gbi * safe_basis;
7476 const int vertex_count = vertices.size ();
7577
7678 Vector<Vector3> lines_mesh_vertices;
@@ -83,21 +85,22 @@ void NavigationObstacle3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
8385 Vector3 point = vertices[i];
8486 Vector3 next_point = vertices[(i + 1 ) % vertex_count];
8587
86- Vector3 direction = next_point.direction_to (point);
88+ Vector3 direction = safe_basis. xform ( next_point.direction_to (point) );
8789 Vector3 arrow_dir = direction.cross (Vector3 (0.0 , 1.0 , 0.0 ));
8890 Vector3 edge_middle = point + ((next_point - point) * 0.5 );
8991
90- lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform (edge_middle);
91- lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform (edge_middle + (arrow_dir * 0.5 ));
92+ // Ensure vector stays perpendicular even when scaled non-uniformly.
93+ lines_mesh_vertices_ptrw[vertex_index++] = safe_global_basis.xform (edge_middle);
94+ lines_mesh_vertices_ptrw[vertex_index++] = safe_global_basis.xform (edge_middle) + gbi.xform (arrow_dir) * 0.5 ;
9295
93- lines_mesh_vertices_ptrw[vertex_index++] = gbi .xform (point);
94- lines_mesh_vertices_ptrw[vertex_index++] = gbi .xform (next_point);
96+ lines_mesh_vertices_ptrw[vertex_index++] = safe_global_basis .xform (point);
97+ lines_mesh_vertices_ptrw[vertex_index++] = safe_global_basis .xform (next_point);
9598
96- lines_mesh_vertices_ptrw[vertex_index++] = gbi .xform (Vector3 (point.x , height, point.z ));
97- lines_mesh_vertices_ptrw[vertex_index++] = gbi .xform (Vector3 (next_point.x , height, next_point.z ));
99+ lines_mesh_vertices_ptrw[vertex_index++] = safe_global_basis .xform (Vector3 (point.x , height, point.z ));
100+ lines_mesh_vertices_ptrw[vertex_index++] = safe_global_basis .xform (Vector3 (next_point.x , height, next_point.z ));
98101
99- lines_mesh_vertices_ptrw[vertex_index++] = gbi .xform (point);
100- lines_mesh_vertices_ptrw[vertex_index++] = gbi .xform (Vector3 (point.x , height, point.z ));
102+ lines_mesh_vertices_ptrw[vertex_index++] = safe_global_basis .xform (point);
103+ lines_mesh_vertices_ptrw[vertex_index++] = safe_global_basis .xform (Vector3 (point.x , height, point.z ));
101104 }
102105
103106 Vector<Vector2> polygon_2d_vertices;
@@ -138,7 +141,8 @@ int NavigationObstacle3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DG
138141 NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d ());
139142 ERR_FAIL_NULL_V (obstacle_node, -1 );
140143
141- Transform3D gt = Transform3D (Basis (), obstacle_node->get_global_position ());
144+ const Vector3 safe_scale = obstacle_node->get_global_basis ().get_scale ().abs ().maxf (0.001 );
145+ const Transform3D gt = Transform3D (Basis ().scaled (safe_scale).rotated (Vector3 (0.0 , 1.0 , 0.0 ), obstacle_node->get_global_rotation ().y ), obstacle_node->get_global_position ());
142146 const Vector<Vector3> &vertices = obstacle_node->get_vertices ();
143147
144148 for (int idx = 0 ; idx < vertices.size (); ++idx) {
@@ -160,7 +164,8 @@ Vector<int> NavigationObstacle3DGizmoPlugin::subgizmos_intersect_frustum(const E
160164 NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d ());
161165 ERR_FAIL_NULL_V (obstacle_node, contained_points);
162166
163- Transform3D gt = Transform3D (Basis (), obstacle_node->get_global_position ());
167+ const Vector3 safe_scale = obstacle_node->get_global_basis ().get_scale ().abs ().maxf (0.001 );
168+ const Transform3D gt = Transform3D (Basis ().scaled (safe_scale).rotated (Vector3 (0.0 , 1.0 , 0.0 ), obstacle_node->get_global_rotation ().y ), obstacle_node->get_global_position ());
164169 const Vector<Vector3> &vertices = obstacle_node->get_vertices ();
165170
166171 for (int idx = 0 ; idx < vertices.size (); ++idx) {
@@ -188,24 +193,22 @@ Transform3D NavigationObstacle3DGizmoPlugin::get_subgizmo_transform(const Editor
188193 const Vector<Vector3> &vertices = obstacle_node->get_vertices ();
189194 ERR_FAIL_INDEX_V (p_id, vertices.size (), Transform3D ());
190195
191- Basis gbi = obstacle_node->get_global_basis ().inverse ();
192-
193- Transform3D subgizmo_transform = Transform3D (Basis (), gbi.xform (vertices[p_id]));
196+ const Basis safe_basis_inverse = Basis (Vector3 (0.0 , 1.0 , 0.0 ), obstacle_node->get_global_rotation ().y , obstacle_node->get_global_basis ().get_scale ().abs ().maxf (0.001 )).inverse ();
197+ Transform3D subgizmo_transform = Transform3D (Basis (), safe_basis_inverse.xform (vertices[p_id]));
194198 return subgizmo_transform;
195199}
196200
197201void NavigationObstacle3DGizmoPlugin::set_subgizmo_transform (const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) {
198202 NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d ());
199203 ERR_FAIL_NULL (obstacle_node);
200204
201- Basis gb = obstacle_node->get_global_basis ();
202-
205+ const Basis safe_basis = Basis (Vector3 (0.0 , 1.0 , 0.0 ), obstacle_node->get_global_rotation ().y , obstacle_node->get_global_basis ().get_scale ().abs ().maxf (0.001 ));
203206 Vector3 new_vertex_pos = p_transform.origin ;
204207
205208 Vector<Vector3> vertices = obstacle_node->get_vertices ();
206209 ERR_FAIL_INDEX (p_id, vertices.size ());
207210
208- Vector3 vertex = gb .xform (new_vertex_pos);
211+ Vector3 vertex = safe_basis .xform (new_vertex_pos);
209212 vertex.y = 0.0 ;
210213 vertices.write [p_id] = vertex;
211214
@@ -216,14 +219,14 @@ void NavigationObstacle3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *
216219 NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d ());
217220 ERR_FAIL_NULL (obstacle_node);
218221
219- Basis gb = obstacle_node->get_global_basis ();
222+ const Basis safe_basis = Basis ( Vector3 ( 0.0 , 1.0 , 0.0 ), obstacle_node->get_global_rotation (). y , obstacle_node-> get_global_basis (). get_scale (). abs (). maxf ( 0.001 ) );
220223
221224 Vector<Vector3> vertices = obstacle_node->get_vertices ();
222225 Vector<Vector3> restore_vertices = vertices;
223226
224227 for (int i = 0 ; i < p_ids.size (); ++i) {
225228 const int idx = p_ids[i];
226- Vector3 vertex = gb .xform (p_restore[i].origin );
229+ Vector3 vertex = safe_basis .xform (p_restore[i].origin );
227230 vertex.y = 0.0 ;
228231 restore_vertices.write [idx] = vertex;
229232 }
@@ -446,7 +449,8 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditorPlugin::forward_3d_gui_inp
446449 Vector3 ray_from = p_camera->project_ray_origin (mouse_position);
447450 Vector3 ray_dir = p_camera->project_ray_normal (mouse_position);
448451
449- Transform3D gt = Transform3D (Basis (), obstacle_node->get_global_position ());
452+ const Vector3 safe_scale = obstacle_node->get_global_basis ().get_scale ().abs ().maxf (0.001 );
453+ const Transform3D gt = Transform3D (Basis ().scaled (safe_scale).rotated (Vector3 (0.0 , 1.0 , 0.0 ), obstacle_node->get_global_rotation ().y ), obstacle_node->get_global_position ());
450454 Transform3D gi = gt.affine_inverse ();
451455 Plane projection_plane (Vector3 (0.0 , 1.0 , 0.0 ), gt.origin );
452456
@@ -666,7 +670,8 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditorPlugin::forward_3d_gui_inp
666670 Vector3 ray_from = p_camera->project_ray_origin (mouse_position);
667671 Vector3 ray_dir = p_camera->project_ray_normal (mouse_position);
668672
669- Transform3D gt = Transform3D (Basis (), obstacle_node->get_global_position ());
673+ const Vector3 safe_scale = obstacle_node->get_global_basis ().get_scale ().abs ().maxf (0.001 );
674+ const Transform3D gt = Transform3D (Basis ().scaled (safe_scale).rotated (Vector3 (0.0 , 1.0 , 0.0 ), obstacle_node->get_global_rotation ().y ), obstacle_node->get_global_position ());
670675 Transform3D gi = gt.affine_inverse ();
671676 Plane projection_plane (Vector3 (0.0 , 1.0 , 0.0 ), gt.origin );
672677
@@ -762,7 +767,9 @@ void NavigationObstacle3DEditorPlugin::redraw() {
762767
763768 rs->mesh_add_surface_from_arrays (point_lines_mesh_rid, RS::PRIMITIVE_LINES, point_lines_mesh_array);
764769 rs->instance_set_surface_override_material (point_lines_instance_rid, 0 , line_material->get_rid ());
765- rs->instance_set_transform (point_lines_instance_rid, Transform3D (Basis (), obstacle_node->get_global_position ()));
770+ const Vector3 safe_scale = obstacle_node->get_global_basis ().get_scale ().abs ().maxf (0.001 );
771+ const Transform3D gt = Transform3D (Basis ().scaled (safe_scale).rotated (Vector3 (0.0 , 1.0 , 0.0 ), obstacle_node->get_global_rotation ().y ), obstacle_node->get_global_position ());
772+ rs->instance_set_transform (point_lines_instance_rid, gt);
766773
767774 Array point_handle_mesh_array;
768775 point_handle_mesh_array.resize (Mesh::ARRAY_MAX);
@@ -787,7 +794,7 @@ void NavigationObstacle3DEditorPlugin::redraw() {
787794
788795 rs->mesh_add_surface_from_arrays (point_handle_mesh_rid, RS::PRIMITIVE_POINTS, point_handle_mesh_array);
789796 rs->instance_set_surface_override_material (point_handles_instance_rid, 0 , handle_material->get_rid ());
790- rs->instance_set_transform (point_handles_instance_rid, Transform3D ( Basis (), obstacle_node-> get_global_position ()) );
797+ rs->instance_set_transform (point_handles_instance_rid, gt );
791798}
792799
793800NavigationObstacle3DEditorPlugin *NavigationObstacle3DEditorPlugin::singleton = nullptr ;
0 commit comments