Repository: godotengine/godot
File: editor/plugins/node_3d_editor_plugin.cpp (C++)

Code before:
					continue;
				}

				Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
				if (!se) {
					continue;
				}

				if (sp->has_meta("_edit_lock_")) {
					continue;
				}

				Vector3 compute_axis = local_coords ? local_axis : global_axis;
				if (se->gizmo.is_valid()) {
					for (KeyValue<int, Transform3D> &GE : se->subgizmos) {
						Transform3D xform = GE.value;

						Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original * xform, xform, compute_axis, angle, local_coords, true); // Force orthogonal with subgizmo.
						if (!local_coords) {
							new_xform = se->original.affine_inverse() * new_xform;
						}
						se->gizmo->set_subgizmo_transform(GE.key, new_xform);
					}
				} else {
					Transform3D new_xform = _compute_transform(TRANSFORM_ROTATE, se->original, se->original_local, compute_axis, angle, local_coords, sp->get_rotation_edit_mode() != Node3D::ROTATION_EDIT_MODE_BASIS);
					_transform_gizmo_apply(se->sp, new_xform, local_coords);
				}
			}

			spatial_editor->update_transform_gizmo();
			surface->queue_redraw();

		} break;
		default: {
		}
	}
}

// Perform cleanup after a transform operation is committed or canceled.
void Node3DEditorViewport::finish_transform() {
	spatial_editor->set_local_coords_enabled(_edit.original_local);
	_edit.mode = TRANSFORM_NONE;
	_edit.instant = false;
	spatial_editor->update_transform_gizmo();
	surface->queue_redraw();
	set_process_input(false);
}

// Register a shortcut and also add it as an input action with the same events.
void Node3DEditorViewport::register_shortcut_action(const String &p_path, const String &p_name, Key p_keycode, bool p_physical) {
	Ref<Shortcut> sc = ED_SHORTCUT(p_path, p_name, p_keycode, p_physical);

Review comment (bug):
```suggestion
					ERR_FAIL_MSG("_edit.mode cannot be TRANSFORM_NONE in update_transform_numeric.");
```

Code after:

			Vector3 compute_axis = local_coords ? local_axis : global_axis;
			apply_transform(compute_axis, angle);
		} break;
		default: {
		}
	}
}

void Node3DEditorViewport::update_transform_numeric() {
	Vector3 motion;
	switch (_edit.plane) {
		case TRANSFORM_VIEW: {
			switch (_edit.mode) {
				case TRANSFORM_TRANSLATE:
					motion = Vector3(1, 0, 0);
					break;
				case TRANSFORM_ROTATE:
					motion = spatial_editor->get_gizmo_transform().basis.xform_inv(_get_camera_normal()).normalized();
					break;
				case TRANSFORM_SCALE:
					motion = Vector3(1, 1, 1);
					break;
				case TRANSFORM_NONE:
					ERR_FAIL_MSG("_edit.mode cannot be TRANSFORM_NONE in update_transform_numeric.");
			}
			break;
		}
		case TRANSFORM_X_AXIS:
			motion = Vector3(1, 0, 0);
			break;
		case TRANSFORM_Y_AXIS:
			motion = Vector3(0, 1, 0);
			break;
		case TRANSFORM_Z_AXIS:
			motion = Vector3(0, 0, 1);
			break;
		case TRANSFORM_XY:
			motion = Vector3(1, 1, 0);
			break;
		case TRANSFORM_XZ:
			motion = Vector3(1, 0, 1);
			break;
		case TRANSFORM_YZ:
			motion = Vector3(0, 1, 1);
			break;
	}

	double value = _edit.numeric_input * (_edit.numeric_negate ? -1 : 1);
	double extra = 0.0;
	switch (_edit.mode) {