2022-04-11 13:42:49 +02:00
|
|
|
/*
|
|
|
|
Copyright (c) 2019-2022 Péter Magyar
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "mdi_gizmo.h"
|
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
#include "../mesh_data_resource.h"
|
|
|
|
#include "../nodes/mesh_data_instance.h"
|
|
|
|
#include "./utilities/mdr_ed_mesh_decompose.h"
|
|
|
|
#include "./utilities/mdr_ed_mesh_outline.h"
|
|
|
|
#include "./utilities/mdr_ed_mesh_utils.h"
|
|
|
|
#include "core/math/geometry.h"
|
|
|
|
#include "editor/editor_node.h"
|
|
|
|
#include "modules/mesh_utils/mesh_utils.h"
|
|
|
|
#include "scene/3d/camera.h"
|
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::setup() {
|
2022-04-13 02:08:30 +02:00
|
|
|
MeshDataInstance *mdi = Object::cast_to<MeshDataInstance>(get_spatial_node());
|
|
|
|
|
|
|
|
ERR_FAIL_COND(!mdi);
|
|
|
|
|
|
|
|
mdi->connect("mesh_data_resource_changed", this, "on_mesh_data_resource_changed");
|
|
|
|
|
|
|
|
on_mesh_data_resource_changed(mdi->get_mesh_data());
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_editor_plugin(EditorPlugin *editor_plugin) {
|
2022-04-13 02:08:30 +02:00
|
|
|
_editor_plugin = editor_plugin;
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_undo_redo = EditorNode::get_undo_redo();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::set_handle(int index, Camera *camera, Vector2 point) {
|
2022-04-13 02:08:30 +02:00
|
|
|
Vector2 relative = point - previous_point;
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!_handle_drag_op) {
|
|
|
|
relative = Vector2();
|
|
|
|
_handle_drag_op = true;
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (edit_mode == EditMode::EDIT_MODE_SCALE) {
|
|
|
|
_drag_op_accumulator = Vector3(1, 1, 1);
|
|
|
|
} else {
|
|
|
|
_drag_op_accumulator = Vector3();
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_drag_op_accumulator_quat = Quat();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_drag_op_orig_verices = copy_mdr_verts_array();
|
|
|
|
setup_op_drag_indices();
|
|
|
|
_drag_op_pivot = get_drag_op_pivot();
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (edit_mode == EditMode::EDIT_MODE_NONE) {
|
|
|
|
return;
|
|
|
|
} else if (edit_mode == EditMode::EDIT_MODE_TRANSLATE) {
|
|
|
|
Vector3 ofs;
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
ofs = camera->get_global_transform().basis.get_axis(0);
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_X) != 0) {
|
|
|
|
ofs.x *= relative.x * 0.01;
|
|
|
|
} else {
|
|
|
|
ofs.x = 0;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_Y) != 0) {
|
|
|
|
ofs.y = relative.y * -0.01;
|
|
|
|
} else {
|
|
|
|
ofs.y = 0;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_Z) != 0) {
|
|
|
|
ofs.z *= relative.x * 0.01;
|
|
|
|
} else {
|
|
|
|
ofs.z = 0;
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_drag_op_accumulator += ofs;
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
add_to_all_selected(_drag_op_accumulator);
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
apply();
|
|
|
|
redraw();
|
|
|
|
} else if (edit_mode == EditMode::EDIT_MODE_SCALE) {
|
|
|
|
float r = ((relative.x + relative.y) * 0.05);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Vector3 vs;
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_X) != 0) {
|
|
|
|
vs.x = r;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_Y) != 0) {
|
|
|
|
vs.y = r;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_Z) != 0) {
|
|
|
|
vs.z = r;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_drag_op_accumulator += vs;
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Basis b = Basis().scaled(_drag_op_accumulator);
|
|
|
|
Transform t = Transform(Basis(), _drag_op_pivot);
|
|
|
|
t *= Transform(b, Vector3());
|
|
|
|
t *= Transform(Basis(), _drag_op_pivot).inverse();
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
mul_all_selected_with_transform(t);
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
apply();
|
|
|
|
redraw();
|
|
|
|
} else if (edit_mode == EditMode::EDIT_MODE_ROTATE) {
|
|
|
|
Quat yrot = Quat(Vector3(0, 1, 0), relative.x * 0.01);
|
|
|
|
Quat xrot = Quat(camera->get_global_transform().basis.get_axis(0), relative.y * 0.01);
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_drag_op_accumulator_quat *= yrot;
|
|
|
|
_drag_op_accumulator_quat *= xrot;
|
|
|
|
_drag_op_accumulator_quat = _drag_op_accumulator_quat.normalized();
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Basis b = Basis(_drag_op_accumulator_quat);
|
|
|
|
Transform t = Transform(Basis(), _drag_op_pivot);
|
|
|
|
t *= Transform(b, Vector3());
|
|
|
|
t *= Transform(Basis(), _drag_op_pivot).inverse();
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
mul_all_selected_with_transform(t);
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
apply();
|
|
|
|
redraw();
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
previous_point = point;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-13 02:08:30 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::redraw() {
|
2022-04-13 02:08:30 +02:00
|
|
|
clear();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!_mdr.is_valid()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Array array = _mdr->get_array();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (array.size() != ArrayMesh::ARRAY_MAX) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!get_plugin().is_valid()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Ref<SpatialMaterial> handles_material = get_plugin()->get_material("handles", Ref<EditorSpatialGizmo>(this));
|
|
|
|
Ref<SpatialMaterial> material = get_plugin()->get_material("main", Ref<EditorSpatialGizmo>(this));
|
|
|
|
Ref<SpatialMaterial> seam_material = get_plugin()->get_material("seam", Ref<EditorSpatialGizmo>(this));
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_mesh_outline_generator->setup(_mdr);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (selection_mode == SELECTION_MODE_EDGE) {
|
|
|
|
_mesh_outline_generator->generate_mark_edges(visual_indicator_outline, visual_indicator_handle);
|
|
|
|
} else if (selection_mode == SELECTION_MODE_FACE) {
|
|
|
|
_mesh_outline_generator->generate_mark_faces(visual_indicator_outline, visual_indicator_handle);
|
|
|
|
} else {
|
|
|
|
_mesh_outline_generator->generate(visual_indicator_outline, visual_indicator_handle);
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (visual_indicator_outline || visual_indicator_handle) {
|
|
|
|
add_lines(_mesh_outline_generator->lines, material, false);
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (visual_indicator_seam) {
|
|
|
|
add_lines(_mesh_outline_generator->seam_lines, seam_material, false);
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (_selected_points.size() > 0) {
|
|
|
|
Vector<Vector3> vs;
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 0; i < _selected_points.size(); ++i) {
|
|
|
|
vs.push_back(_handle_points[_selected_points[i]]);
|
|
|
|
}
|
|
|
|
|
|
|
|
add_handles(vs, handles_material);
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::apply() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!_mdr.is_valid()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
disable_change_event();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Array arrs = _mdr->get_array();
|
|
|
|
arrs[ArrayMesh::ARRAY_VERTEX] = _vertices;
|
|
|
|
arrs[ArrayMesh::ARRAY_INDEX] = _indices;
|
|
|
|
_mdr->set_array(arrs);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
enable_change_event();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::select_all() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (_selected_points.size() == _handle_points.size()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_selected_points.resize(_handle_points.size());
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolIntArray::Write w = _selected_points.write();
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 0; i < _selected_points.size(); ++i) {
|
|
|
|
w[i] = i;
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
bool MDIGizmo::selection_click(int index, Camera *camera, const Ref<InputEventMouse> &event) {
|
|
|
|
if (handle_selection_type == HANDLE_SELECTION_TYPE_FRONT) {
|
|
|
|
return selection_click_select_front_or_back(index, camera, event);
|
|
|
|
} else if (handle_selection_type == HANDLE_SELECTION_TYPE_BACK) {
|
|
|
|
return selection_click_select_front_or_back(index, camera, event);
|
|
|
|
} else {
|
|
|
|
return selection_click_select_through(index, camera, event);
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
return false;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-13 02:08:30 +02:00
|
|
|
bool MDIGizmo::is_point_visible(Vector3 point_orig, Vector3 camera_pos, Transform gt) {
|
|
|
|
Vector3 point = gt.xform(point_orig);
|
|
|
|
|
|
|
|
// go from the given point to the origin (camera_pos -> camera)
|
|
|
|
Vector3 dir = camera_pos - point;
|
|
|
|
dir = dir.normalized();
|
|
|
|
// Might need to reduce z fighting
|
|
|
|
//point += dir * 0.5
|
|
|
|
|
|
|
|
for (int i = 0; i < _indices.size(); i += 3) {
|
|
|
|
int i0 = _indices[i];
|
|
|
|
int i1 = _indices[i + 1];
|
|
|
|
int i2 = _indices[i + 2];
|
|
|
|
|
|
|
|
Vector3 v0 = _vertices[i0];
|
|
|
|
Vector3 v1 = _vertices[i1];
|
|
|
|
Vector3 v2 = _vertices[i2];
|
|
|
|
|
|
|
|
v0 = gt.xform(v0);
|
|
|
|
v1 = gt.xform(v1);
|
|
|
|
v2 = gt.xform(v2);
|
|
|
|
|
|
|
|
bool intersects = Geometry::ray_intersects_triangle(point, dir, v0, v1, v2);
|
|
|
|
|
|
|
|
if (intersects) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MDIGizmo::selection_click_select_front_or_back(int index, Camera *camera, const Ref<InputEventMouse> &event) {
|
|
|
|
Transform gt = get_spatial_node()->get_global_transform();
|
|
|
|
Vector3 ray_from = camera->get_global_transform().origin;
|
|
|
|
Vector2 gpoint = event->get_position();
|
|
|
|
float grab_threshold = 8;
|
|
|
|
|
|
|
|
// select vertex
|
|
|
|
int closest_idx = -1;
|
|
|
|
float closest_dist = 1e10;
|
|
|
|
|
|
|
|
for (int i = 0; i < _handle_points.size(); ++i) {
|
|
|
|
Vector3 vert_pos_3d = gt.xform(_handle_points[i]);
|
|
|
|
Vector2 vert_pos_2d = camera->unproject_position(vert_pos_3d);
|
|
|
|
float dist_3d = ray_from.distance_to(vert_pos_3d);
|
|
|
|
float dist_2d = gpoint.distance_to(vert_pos_2d);
|
|
|
|
|
|
|
|
if (dist_2d < grab_threshold && dist_3d < closest_dist) {
|
|
|
|
bool point_visible = is_point_visible(_handle_points[i], ray_from, gt);
|
|
|
|
|
|
|
|
if (handle_selection_type == HANDLE_SELECTION_TYPE_FRONT) {
|
|
|
|
if (!point_visible) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else if (handle_selection_type == HANDLE_SELECTION_TYPE_BACK) {
|
|
|
|
if (point_visible) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
closest_dist = dist_3d;
|
|
|
|
closest_idx = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (closest_idx >= 0) {
|
|
|
|
for (int si = 0; si < _selected_points.size(); ++si) {
|
|
|
|
if (_selected_points[si] == closest_idx) {
|
|
|
|
if (event->get_alt() || event->get_control()) {
|
|
|
|
_selected_points.remove(si);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event->get_alt() || event->get_control()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event->get_shift()) {
|
|
|
|
_selected_points.append(closest_idx);
|
|
|
|
} else {
|
|
|
|
// Select new point only
|
|
|
|
_selected_points.resize(0);
|
|
|
|
_selected_points.append(closest_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
apply();
|
|
|
|
redraw();
|
|
|
|
} else {
|
|
|
|
// Don't unselect all if either control or shift is held down
|
|
|
|
if (event->get_shift() || event->get_control() || event->get_alt()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_selected_points.size() == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Unselect all
|
|
|
|
_selected_points.resize(0);
|
|
|
|
|
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool MDIGizmo::selection_click_select_through(int index, Camera *camera, const Ref<InputEventMouse> &event) {
|
|
|
|
Transform gt = get_spatial_node()->get_global_transform();
|
|
|
|
Vector3 ray_from = camera->get_global_transform().origin;
|
|
|
|
Vector2 gpoint = event->get_position();
|
|
|
|
float grab_threshold = 8;
|
|
|
|
|
|
|
|
// select vertex
|
|
|
|
int closest_idx = -1;
|
|
|
|
float closest_dist = 1e10;
|
|
|
|
|
|
|
|
for (int i = 0; i < _handle_points.size(); ++i) {
|
|
|
|
Vector3 vert_pos_3d = gt.xform(_handle_points[i]);
|
|
|
|
Vector2 vert_pos_2d = camera->unproject_position(vert_pos_3d);
|
|
|
|
float dist_3d = ray_from.distance_to(vert_pos_3d);
|
|
|
|
float dist_2d = gpoint.distance_to(vert_pos_2d);
|
|
|
|
|
|
|
|
if (dist_2d < grab_threshold && dist_3d < closest_dist) {
|
|
|
|
closest_dist = dist_3d;
|
|
|
|
closest_idx = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (closest_idx >= 0) {
|
|
|
|
for (int si = 0; si < _selected_points.size(); ++si) {
|
|
|
|
if (_selected_points[si] == closest_idx) {
|
|
|
|
if (event->get_alt() || event->get_control()) {
|
|
|
|
_selected_points.remove(si);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event->get_alt() || event->get_control()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event->get_shift()) {
|
|
|
|
_selected_points.append(closest_idx);
|
|
|
|
} else {
|
|
|
|
// Select new point only
|
|
|
|
_selected_points.resize(0);
|
|
|
|
_selected_points.append(closest_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
apply();
|
|
|
|
redraw();
|
|
|
|
} else {
|
|
|
|
// Don't unselect all if either control or shift is held down
|
|
|
|
if (event->get_shift() || event->get_control() || event->get_alt()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_selected_points.size() == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Unselect all
|
|
|
|
_selected_points.resize(0);
|
|
|
|
|
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void MDIGizmo::selection_drag(int index, Camera *camera, const Ref<InputEventMouse> &event) {
|
|
|
|
if (handle_selection_type == HANDLE_SELECTION_TYPE_FRONT) {
|
|
|
|
selection_drag_rect_select_front_back(index, camera, event);
|
|
|
|
} else if (handle_selection_type == HANDLE_SELECTION_TYPE_BACK) {
|
|
|
|
selection_drag_rect_select_front_back(index, camera, event);
|
|
|
|
} else {
|
|
|
|
selection_drag_rect_select_through(index, camera, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void MDIGizmo::selection_drag_rect_select_front_back(int index, Camera *camera, const Ref<InputEventMouse> &event) {
|
|
|
|
Transform gt = get_spatial_node()->get_global_transform();
|
|
|
|
Vector3 ray_from = camera->get_global_transform().origin;
|
|
|
|
|
|
|
|
Vector2 mouse_pos = event->get_position();
|
|
|
|
Vector2 rect_size = _rect_drag_start_point - mouse_pos;
|
|
|
|
rect_size.x = ABS(rect_size.x);
|
|
|
|
rect_size.y = ABS(rect_size.y);
|
|
|
|
|
|
|
|
Rect2 rect = Rect2(_rect_drag_start_point, rect_size);
|
|
|
|
|
|
|
|
// This is needed so selection works even when you drag from bottom to top, and from right to left
|
|
|
|
Vector2 rect_ofs = _rect_drag_start_point - mouse_pos;
|
|
|
|
|
|
|
|
if (rect_ofs.x > 0) {
|
|
|
|
rect.position.x -= rect_ofs.x;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rect_ofs.y > 0) {
|
|
|
|
rect.position.y -= rect_ofs.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
PoolIntArray selected;
|
|
|
|
|
|
|
|
for (int i = 0; i < _handle_points.size(); ++i) {
|
|
|
|
Vector3 vert_pos_3d = gt.xform(_handle_points[i]);
|
|
|
|
Vector2 vert_pos_2d = camera->unproject_position(vert_pos_3d);
|
|
|
|
|
|
|
|
if (rect.has_point(vert_pos_2d)) {
|
|
|
|
bool point_visible = is_point_visible(_handle_points[i], ray_from, gt);
|
|
|
|
|
|
|
|
if (handle_selection_type == HANDLE_SELECTION_TYPE_FRONT) {
|
|
|
|
if (!point_visible) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else if (handle_selection_type == HANDLE_SELECTION_TYPE_BACK) {
|
|
|
|
if (point_visible) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
selected.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event->get_alt() || event->get_control()) {
|
|
|
|
PoolIntArray::Read r = selected.read();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int is = 0; is < selected.size(); ++is) {
|
|
|
|
int isel = r[is];
|
|
|
|
|
|
|
|
for (int i = 0; i < _selected_points.size(); ++i) {
|
|
|
|
if (_selected_points[i] == isel) {
|
|
|
|
_selected_points.remove(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
r.release();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (event->get_shift()) {
|
|
|
|
PoolIntArray::Read r = selected.read();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int is = 0; is < selected.size(); ++is) {
|
|
|
|
int isel = r[is];
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!pool_int_arr_contains(_selected_points, isel)) {
|
|
|
|
_selected_points.push_back(isel);
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
r.release();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
redraw();
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_selected_points.resize(0);
|
|
|
|
_selected_points.append_array(selected);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-13 02:08:30 +02:00
|
|
|
void MDIGizmo::selection_drag_rect_select_through(int index, Camera *camera, const Ref<InputEventMouse> &event) {
|
2022-04-11 13:42:49 +02:00
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var gt : Transform = get_spatial_node().global_transform
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var mouse_pos : Vector2 = event.get_position()
|
|
|
|
var rect_size : Vector2 = _rect_drag_start_point - mouse_pos
|
|
|
|
rect_size.x = abs(rect_size.x)
|
|
|
|
rect_size.y = abs(rect_size.y)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var rect : Rect2 = Rect2(_rect_drag_start_point, rect_size)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# This is needed so selection works even when you drag from bottom to top, and from right to left
|
|
|
|
var rect_ofs : Vector2 = _rect_drag_start_point - mouse_pos
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if rect_ofs.x > 0:
|
|
|
|
rect.position.x -= rect_ofs.x
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if rect_ofs.y > 0:
|
|
|
|
rect.position.y -= rect_ofs.y
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var selected : PoolIntArray = PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(_handle_points.size()):
|
|
|
|
var vert_pos_3d : Vector3 = gt.xform(_handle_points[i])
|
|
|
|
var vert_pos_2d : Vector2 = camera.unproject_position(vert_pos_3d)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if rect.has_point(vert_pos_2d):
|
|
|
|
selected.push_back(i)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if event.alt || event.control:
|
|
|
|
for isel in selected:
|
|
|
|
for i in range(_selected_points.size()):
|
|
|
|
if _selected_points[i] == isel:
|
|
|
|
_selected_points.remove(i)
|
|
|
|
break
|
|
|
|
redraw()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if event.shift:
|
|
|
|
for isel in selected:
|
|
|
|
if !pool_int_arr_contains(_selected_points, isel):
|
|
|
|
_selected_points.push_back(isel)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
redraw()
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_selected_points.resize(0)
|
|
|
|
_selected_points.append_array(selected)
|
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
redraw()
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
bool MDIGizmo::forward_spatial_gui_input(int index, Camera *camera, const Ref<InputEvent> &event) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
_last_known_camera_facing = camera.transform.basis.xform(Vector3(0, 0, -1))
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if event is InputEventMouseButton:
|
|
|
|
if event.get_button_index() == BUTTON_LEFT:
|
|
|
|
if _handle_drag_op:
|
|
|
|
if !event.is_pressed():
|
|
|
|
_handle_drag_op = false
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# If a handle was being dragged only run these
|
2022-04-13 02:08:30 +02:00
|
|
|
if _mdr && _mdr.array.size() == ArrayMesh::ARRAY_MAX && _mdr.array[ArrayMesh::ARRAY_VERTEX] != null && _mdr.array[ArrayMesh::ARRAY_VERTEX].size() == _drag_op_orig_verices.size():
|
2022-04-10 21:14:56 +02:00
|
|
|
_undo_redo.create_action("Drag")
|
2022-04-13 02:08:30 +02:00
|
|
|
_undo_redo.add_do_method(self, "apply_vertex_array", _mdr, _mdr.array[ArrayMesh::ARRAY_VERTEX])
|
2022-04-10 21:14:56 +02:00
|
|
|
_undo_redo.add_undo_method(self, "apply_vertex_array", _mdr, _drag_op_orig_verices)
|
|
|
|
_undo_redo.commit_action()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
|
|
|
# Dont consume the event here, because the handles will get stuck
|
2022-04-10 21:14:56 +02:00
|
|
|
# to the mouse pointer if we return true
|
|
|
|
return false
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if !event.is_pressed():
|
|
|
|
# See whether we should check for a click or a selection box
|
|
|
|
var mouse_pos : Vector2 = event.get_position()
|
|
|
|
var rect_size : Vector2 = _rect_drag_start_point - mouse_pos
|
|
|
|
rect_size.x = abs(rect_size.x)
|
|
|
|
rect_size.y = abs(rect_size.y)
|
|
|
|
var had_rect_drag : bool = false
|
|
|
|
|
|
|
|
if rect_size.x > _rect_drag_min_ofset || rect_size.y > _rect_drag_min_ofset:
|
|
|
|
had_rect_drag = true
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if !had_rect_drag:
|
|
|
|
return selection_click(index, camera, event)
|
|
|
|
else:
|
|
|
|
selection_drag(index, camera, event)
|
|
|
|
# Always return false here, so the drag rect thing disappears in the editor
|
|
|
|
return false
|
|
|
|
else:
|
|
|
|
# event is pressed
|
|
|
|
_rect_drag = true
|
|
|
|
_rect_drag_start_point = event.get_position()
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::add_to_all_selected(Vector3 ofs) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in _selected_points:
|
|
|
|
var v : Vector3 = _handle_points[i]
|
|
|
|
v += ofs
|
|
|
|
_handle_points.set(i, v)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for indx in _drag_op_indices:
|
|
|
|
var v : Vector3 = _drag_op_orig_verices[indx]
|
|
|
|
v += ofs
|
|
|
|
_vertices.set(indx, v)
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::mul_all_selected_with_basis(Basis b) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in _selected_points:
|
|
|
|
var v : Vector3 = _handle_points[i]
|
|
|
|
v = b * v
|
|
|
|
_handle_points.set(i, v)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for indx in _drag_op_indices:
|
|
|
|
var v : Vector3 = _drag_op_orig_verices[indx]
|
|
|
|
v = b * v
|
|
|
|
_vertices.set(indx, v)
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::mul_all_selected_with_transform(Transform t) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in _selected_points:
|
|
|
|
var v : Vector3 = _handle_points[i]
|
|
|
|
v = t * v
|
|
|
|
_handle_points.set(i, v)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for indx in _drag_op_indices:
|
|
|
|
var v : Vector3 = _drag_op_orig_verices[indx]
|
|
|
|
v = t * v
|
|
|
|
_vertices.set(indx, v)
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::mul_all_selected_with_transform_acc(Transform t) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in _selected_points:
|
|
|
|
var v : Vector3 = _handle_points[i]
|
|
|
|
v = t * v
|
|
|
|
_handle_points.set(i, v)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for indx in _drag_op_indices:
|
|
|
|
var v : Vector3 = _vertices[indx]
|
|
|
|
v = t * v
|
|
|
|
_vertices.set(indx, v)
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::set_translate() {
|
2022-04-13 02:08:30 +02:00
|
|
|
edit_mode = EDIT_MODE_TRANSLATE;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_scale() {
|
2022-04-13 02:08:30 +02:00
|
|
|
edit_mode = EDIT_MODE_SCALE;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_rotate() {
|
2022-04-13 02:08:30 +02:00
|
|
|
edit_mode = EDIT_MODE_ROTATE;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_edit_mode(int em) {
|
2022-04-13 02:08:30 +02:00
|
|
|
edit_mode = em;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::set_axis_x(bool on) {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (on) {
|
|
|
|
axis_constraint |= AXIS_CONSTRAINT_X;
|
|
|
|
} else {
|
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_X) != 0) {
|
|
|
|
axis_constraint ^= AXIS_CONSTRAINT_X;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_axis_y(bool on) {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (on) {
|
|
|
|
axis_constraint |= AXIS_CONSTRAINT_Y;
|
|
|
|
} else {
|
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_Y) != 0) {
|
|
|
|
axis_constraint ^= AXIS_CONSTRAINT_Y;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_axis_z(bool on) {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (on) {
|
|
|
|
axis_constraint |= AXIS_CONSTRAINT_Z;
|
|
|
|
} else {
|
|
|
|
if ((axis_constraint & AXIS_CONSTRAINT_Z) != 0) {
|
|
|
|
axis_constraint ^= AXIS_CONSTRAINT_Z;
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::set_selection_mode_vertex() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (selection_mode == SELECTION_MODE_VERTEX) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
selection_mode = SELECTION_MODE_VERTEX;
|
|
|
|
_selected_points.resize(0);
|
|
|
|
recalculate_handle_points();
|
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_selection_mode_edge() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (selection_mode == SELECTION_MODE_EDGE) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
selection_mode = SELECTION_MODE_EDGE;
|
|
|
|
_selected_points.resize(0);
|
|
|
|
recalculate_handle_points();
|
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_selection_mode_face() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (selection_mode == SELECTION_MODE_FACE) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
selection_mode = SELECTION_MODE_FACE;
|
|
|
|
_selected_points.resize(0);
|
|
|
|
recalculate_handle_points();
|
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::_notification(int what) {
|
|
|
|
/*
|
2022-04-13 02:08:30 +02:00
|
|
|
if (what == NOTIFICATION_PREDELETE) {
|
|
|
|
if (this != nullptr && get_plugin().is_valid()) {
|
|
|
|
get_plugin()->unregister_gizmo(this);
|
|
|
|
}
|
|
|
|
}*/
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::recalculate_handle_points() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
_handle_points.resize(0)
|
|
|
|
_handle_to_vertex_map.resize(0)
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var mdr_arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX] == null || mdr_arr[ArrayMesh::ARRAY_VERTEX].size() == 0:
|
2022-04-10 21:14:56 +02:00
|
|
|
_handle_points.resize(0)
|
|
|
|
_handle_to_vertex_map.resize(0)
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var arr : Array = Array()
|
2022-04-13 02:08:30 +02:00
|
|
|
arr.resize(ArrayMesh::ARRAY_MAX)
|
|
|
|
arr[ArrayMesh::ARRAY_VERTEX] = mdr_arr[ArrayMesh::ARRAY_VERTEX]
|
|
|
|
arr[ArrayMesh::ARRAY_INDEX] = mdr_arr[ArrayMesh::ARRAY_INDEX]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
|
|
|
var merged_arrays : Array = MeshUtils::merge_mesh_array(arr)
|
|
|
|
_handle_points = merged_arrays[ArrayMesh::ARRAY_VERTEX]
|
2022-04-10 21:14:56 +02:00
|
|
|
_handle_to_vertex_map = MeshDecompose.get_handle_vertex_to_vertex_map(mdr_arr, _handle_points)
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
var result : Array = MeshDecompose.get_handle_edge_to_vertex_map(arr)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_handle_points = result[0]
|
|
|
|
_handle_to_vertex_map = result[1]
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_FACE:
|
2022-04-10 21:14:56 +02:00
|
|
|
var result : Array = MeshDecompose.get_handle_face_to_vertex_map(arr)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_handle_points = result[0]
|
|
|
|
_handle_to_vertex_map = result[1]
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::on_mesh_data_resource_changed(Ref<MeshDataResource> mdr) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if _mdr:
|
|
|
|
_mdr.disconnect("changed", self, "on_mdr_changed")
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_mdr = mdr
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if _mdr && _mdr.array.size() == ArrayMesh::ARRAY_MAX && _mdr.array[ArrayMesh::ARRAY_VERTEX] != null:
|
|
|
|
_vertices = _mdr.array[ArrayMesh::ARRAY_VERTEX]
|
|
|
|
_indices = _mdr.array[ArrayMesh::ARRAY_INDEX]
|
2022-04-10 21:14:56 +02:00
|
|
|
else:
|
|
|
|
_vertices.resize(0)
|
|
|
|
_indices.resize(0)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if _mdr:
|
|
|
|
_mdr.connect("changed", self, "on_mdr_changed")
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
recalculate_handle_points()
|
|
|
|
redraw()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::on_mdr_changed() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!_mdr.is_valid()) {
|
|
|
|
_vertices.resize(0);
|
|
|
|
_indices.resize(0);
|
|
|
|
recalculate_handle_points();
|
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
Array arr = _mdr->get_array();
|
|
|
|
|
|
|
|
if (arr.size() == ArrayMesh::ARRAY_MAX && !arr[ArrayMesh::ARRAY_VERTEX].is_null()) {
|
|
|
|
_vertices = arr[ArrayMesh::ARRAY_VERTEX];
|
|
|
|
_indices = arr[ArrayMesh::ARRAY_INDEX];
|
|
|
|
} else {
|
|
|
|
_vertices.resize(0);
|
|
|
|
_indices.resize(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
recalculate_handle_points();
|
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::disable_change_event() {
|
2022-04-13 02:08:30 +02:00
|
|
|
_mdr->disconnect("changed", this, "on_mdr_changed");
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::enable_change_event(bool update = true) {
|
2022-04-13 02:08:30 +02:00
|
|
|
_mdr->connect("changed", this, "on_mdr_changed");
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (update) {
|
|
|
|
on_mdr_changed();
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::add_triangle() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (_mdr.is_valid()) {
|
|
|
|
Array orig_arr = copy_arrays(_mdr->get_array());
|
|
|
|
MDREDMeshUtils::add_triangle(_mdr);
|
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr->get_array(), "Add Triangle");
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::add_quad() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (_mdr.is_valid()) {
|
|
|
|
Array orig_arr = copy_arrays(_mdr->get_array());
|
|
|
|
MDREDMeshUtils::add_quad(_mdr);
|
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr->get_array(), "Add Quad");
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
bool MDIGizmo::is_verts_equal(Vector3 v0, Vector3 v1) {
|
2022-04-13 02:08:30 +02:00
|
|
|
return Math::is_equal_approx(v0.x, v1.x) && Math::is_equal_approx(v0.y, v1.y) && Math::is_equal_approx(v0.z, v1.z);
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-13 02:08:30 +02:00
|
|
|
Vector3 MDIGizmo::find_other_vertex_for_edge(int edge, Vector3 v0) {
|
|
|
|
PoolIntArray ps = _handle_to_vertex_map[edge];
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Vector3 vert;
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 0; i < ps.size(); ++i) {
|
|
|
|
vert = _vertices[ps[i]];
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!is_verts_equal(v0, vert)) {
|
|
|
|
return vert;
|
|
|
|
}
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
return v0;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-13 02:08:30 +02:00
|
|
|
Array MDIGizmo::split_edge_indices(int edge) {
|
|
|
|
PoolIntArray ps = _handle_to_vertex_map[edge];
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (ps.size() == 0) {
|
|
|
|
return Array();
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Vector3 v0 = _vertices[ps[0]];
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolIntArray v0ei;
|
|
|
|
v0ei.append(ps[0]);
|
|
|
|
PoolIntArray v1ei;
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 1; i < ps.size(); ++i) {
|
|
|
|
Vector3 vert = _vertices[ps[i]];
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (is_verts_equal(v0, vert)) {
|
|
|
|
v0ei.append(ps[i]);
|
|
|
|
} else {
|
|
|
|
v1ei.append(ps[i]);
|
|
|
|
}
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Array arr;
|
|
|
|
arr.push_back(v0ei);
|
|
|
|
arr.push_back(v1ei);
|
|
|
|
|
|
|
|
return arr;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
bool MDIGizmo::pool_int_arr_contains(PoolIntArray arr, int val) {
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolIntArray::Read r = arr.read();
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 0; i < arr.size(); ++i) {
|
|
|
|
if (r[i] == val) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
PoolIntArray MDIGizmo::find_triangles_for_edge(int edge) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var eisarr : Array = split_edge_indices(edge)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if eisarr.size() == 0:
|
|
|
|
return PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# these should have the same size
|
|
|
|
var v0ei : PoolIntArray = eisarr[0]
|
|
|
|
var v1ei : PoolIntArray = eisarr[1]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var res : PoolIntArray = PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(0, _indices.size(), 3):
|
|
|
|
var i0 : int = _indices[i]
|
|
|
|
var i1 : int = _indices[i + 1]
|
|
|
|
var i2 : int = _indices[i + 2]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2):
|
|
|
|
if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2):
|
|
|
|
res.append(i / 3)
|
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
return res
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
int MDIGizmo::find_first_triangle_for_edge(int edge) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var eisarr : Array = split_edge_indices(edge)
|
|
|
|
|
|
|
|
if eisarr.size() == 0:
|
|
|
|
return -1
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# these should have the same size
|
|
|
|
var v0ei : PoolIntArray = eisarr[0]
|
|
|
|
var v1ei : PoolIntArray = eisarr[1]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var res : PoolIntArray = PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(0, _indices.size(), 3):
|
|
|
|
var i0 : int = _indices[i]
|
|
|
|
var i1 : int = _indices[i + 1]
|
|
|
|
var i2 : int = _indices[i + 2]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2):
|
|
|
|
if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2):
|
|
|
|
return i / 3
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
return -1
|
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::add_triangle_to_edge(int edge) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var triangle_index : int = find_first_triangle_for_edge(edge)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var inds : int = triangle_index * 3
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var ti0 : int = _indices[inds]
|
|
|
|
var ti1 : int = _indices[inds + 1]
|
|
|
|
var ti2 : int = _indices[inds + 2]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var ps : PoolIntArray = _handle_to_vertex_map[edge]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if ps.size() == 0:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var ei0 : int = 0
|
|
|
|
var ei1 : int = 0
|
|
|
|
var erefind : int = 0
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if !pool_int_arr_contains(ps, ti0):
|
|
|
|
ei0 = ti1
|
|
|
|
ei1 = ti2
|
|
|
|
erefind = ti0
|
|
|
|
elif !pool_int_arr_contains(ps, ti1):
|
|
|
|
ei0 = ti0
|
|
|
|
ei1 = ti2
|
|
|
|
erefind = ti1
|
|
|
|
elif !pool_int_arr_contains(ps, ti2):
|
|
|
|
ei0 = ti0
|
|
|
|
ei1 = ti1
|
|
|
|
erefind = ti2
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var fo : Vector3 = MDREDMeshUtils::get_face_normal(_vertices[ti0], _vertices[ti1], _vertices[ti2])
|
|
|
|
var fn : Vector3 = MDREDMeshUtils::get_face_normal(_vertices[ei0], _vertices[ei1], _vertices[erefind])
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if fo.dot(fn) < 0:
|
|
|
|
var t : int = ei0
|
|
|
|
ei0 = ei1
|
|
|
|
ei1 = t
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::append_triangle_to_tri_edge(_mdr, _vertices[ei0], _vertices[ei1], _vertices[erefind])
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::add_quad_to_edge(int edge) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var triangle_index : int = find_first_triangle_for_edge(edge)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var inds : int = triangle_index * 3
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var ti0 : int = _indices[inds]
|
|
|
|
var ti1 : int = _indices[inds + 1]
|
|
|
|
var ti2 : int = _indices[inds + 2]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var ps : PoolIntArray = _handle_to_vertex_map[edge]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if ps.size() == 0:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var ei0 : int = 0
|
|
|
|
var ei1 : int = 0
|
|
|
|
var erefind : int = 0
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if !pool_int_arr_contains(ps, ti0):
|
|
|
|
ei0 = ti1
|
|
|
|
ei1 = ti2
|
|
|
|
erefind = ti0
|
|
|
|
elif !pool_int_arr_contains(ps, ti1):
|
|
|
|
ei0 = ti0
|
|
|
|
ei1 = ti2
|
|
|
|
erefind = ti1
|
|
|
|
elif !pool_int_arr_contains(ps, ti2):
|
|
|
|
ei0 = ti0
|
|
|
|
ei1 = ti1
|
|
|
|
erefind = ti2
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var fo : Vector3 = MDREDMeshUtils::get_face_normal(_vertices[ti0], _vertices[ti1], _vertices[ti2])
|
|
|
|
var fn : Vector3 = MDREDMeshUtils::get_face_normal(_vertices[ei0], _vertices[ei1], _vertices[erefind])
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if fo.dot(fn) < 0:
|
|
|
|
var t : int = ei0
|
|
|
|
ei0 = ei1
|
|
|
|
ei1 = t
|
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::append_quad_to_tri_edge(_mdr, _vertices[ei0], _vertices[ei1], _vertices[erefind])
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::add_triangle_at() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
#todo
|
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for sp in _selected_points:
|
|
|
|
add_triangle_to_edge(sp)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_selected_points.resize(0)
|
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Add Triangle At")
|
|
|
|
enable_change_event()
|
|
|
|
else:
|
|
|
|
add_triangle()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::add_quad_at() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
#todo
|
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for sp in _selected_points:
|
|
|
|
add_quad_to_edge(sp)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_selected_points.resize(0)
|
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Add Quad At")
|
|
|
|
enable_change_event()
|
|
|
|
else:
|
|
|
|
add_quad()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::extrude() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if _mdr.array.size() != ArrayMesh::ARRAY_MAX || _mdr.array[ArrayMesh::ARRAY_VERTEX] == null:
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-13 02:08:30 +02:00
|
|
|
var original_size : int = orig_arr[ArrayMesh::ARRAY_VERTEX].size()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for sp in _selected_points:
|
|
|
|
add_quad_to_edge(sp)
|
|
|
|
|
|
|
|
var arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# Note: This algorithm depends heavily depends on the inner workings of add_quad_to_edge!
|
2022-04-13 02:08:30 +02:00
|
|
|
var new_verts : PoolVector3Array = arr[ArrayMesh::ARRAY_VERTEX]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# every 4 vertex is a quad
|
|
|
|
# 1 ---- 2
|
|
|
|
# | |
|
|
|
|
# | |
|
|
|
|
# 0 ---- 3
|
|
|
|
# vertex 1, and 2 are the created new ones, 0, and 3 are duplicated from the original edge
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# Don't reallocate it every time
|
|
|
|
var found_verts : PoolIntArray = PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# Go through every new created 0th vertex
|
|
|
|
for i in range(original_size, new_verts.size(), 4):
|
|
|
|
var v0 : Vector3 = new_verts[i]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
found_verts.resize(0)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# Find a pair for it (has to be the 3th).
|
|
|
|
for j in range(original_size, new_verts.size(), 4):
|
|
|
|
if i == j:
|
|
|
|
continue
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# +3 offset to 3rd vert
|
|
|
|
var v3 : Vector3 = new_verts[j + 3]
|
|
|
|
|
|
|
|
if is_verts_equal(v0, v3):
|
|
|
|
# +2 offset to 2rd vert
|
|
|
|
found_verts.append(j + 2)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if found_verts.size() == 0:
|
|
|
|
continue
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# Also append the first vertex index to simplify logic
|
|
|
|
found_verts.append(i + 1)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# Calculate avg
|
|
|
|
var vavg : Vector3 = Vector3()
|
|
|
|
for ind in found_verts:
|
|
|
|
vavg += new_verts[ind]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
vavg /= found_verts.size()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# set back
|
|
|
|
for ind in found_verts:
|
|
|
|
new_verts[ind] = vavg
|
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
arr[ArrayMesh::ARRAY_VERTEX] = new_verts
|
2022-04-10 21:14:56 +02:00
|
|
|
_mdr.array = arr
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_selected_points.resize(0)
|
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Extrude")
|
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# The selection alo will take care of the duplicates
|
|
|
|
var new_handle_points : PoolVector3Array = PoolVector3Array()
|
|
|
|
for i in range(original_size, new_verts.size(), 4):
|
|
|
|
var vavg : Vector3 = new_verts[i + 1]
|
|
|
|
vavg += new_verts[i + 2]
|
|
|
|
vavg /= 2
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
new_handle_points.append(vavg)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
select_handle_points(new_handle_points)
|
|
|
|
else:
|
|
|
|
add_quad()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::add_box() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if _mdr:
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::add_box(_mdr)
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Add Box")
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::split() {
|
|
|
|
}
|
|
|
|
void MDIGizmo::disconnect_action() {
|
|
|
|
}
|
|
|
|
int MDIGizmo::get_first_triangle_index_for_vertex(int indx) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(_indices.size()):
|
|
|
|
if _indices[i] == indx:
|
|
|
|
return i / 3
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
return -1
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void MDIGizmo::create_face() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if _selected_points.size() <= 2:
|
|
|
|
return
|
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var points : PoolVector3Array = PoolVector3Array()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for sp in _selected_points:
|
|
|
|
points.push_back(_handle_points[sp])
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if points.size() == 3:
|
|
|
|
var i0 : int = _handle_to_vertex_map[_selected_points[0]][0]
|
|
|
|
var i1 : int = _handle_to_vertex_map[_selected_points[1]][0]
|
|
|
|
var i2 : int = _handle_to_vertex_map[_selected_points[2]][0]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var v0 : Vector3 = points[0]
|
|
|
|
var v1 : Vector3 = points[1]
|
|
|
|
var v2 : Vector3 = points[2]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var tfn : Vector3 = Vector3()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if orig_arr[ArrayMesh::ARRAY_NORMAL] != null && orig_arr[ArrayMesh::ARRAY_NORMAL].size() == orig_arr[ArrayMesh::ARRAY_VERTEX].size():
|
|
|
|
var normals : PoolVector3Array = orig_arr[ArrayMesh::ARRAY_NORMAL]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
tfn += normals[i0]
|
|
|
|
tfn += normals[i1]
|
|
|
|
tfn += normals[i2]
|
|
|
|
tfn /= 3
|
|
|
|
tfn = tfn.normalized()
|
|
|
|
else:
|
2022-04-13 02:08:30 +02:00
|
|
|
tfn = MDREDMeshUtils::get_face_normal(_vertices[i0], _vertices[i1], _vertices[i2])
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var flip : bool = !MDREDMeshUtils::should_triangle_flip(v0, v1, v2, tfn)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::add_triangle_at(_mdr, v0, v1, v2, flip)
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Create Face")
|
|
|
|
enable_change_event()
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if !MDREDMeshUtils::add_triangulated_mesh_from_points_delaunay(_mdr, points, _last_known_camera_facing):
|
2022-04-10 21:14:56 +02:00
|
|
|
enable_change_event()
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Create Face")
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
#_selected_points.resize(0)
|
|
|
|
enable_change_event()
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_FACE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
Array MDIGizmo::split_face_indices(int face) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var ps : PoolIntArray = _handle_to_vertex_map[face]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if ps.size() == 0:
|
|
|
|
return [ ]
|
|
|
|
|
|
|
|
var v0 : Vector3 = _vertices[ps[0]]
|
|
|
|
var v1 : Vector3 = Vector3()
|
|
|
|
var v1found : bool = false
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var v0ei : PoolIntArray = PoolIntArray()
|
|
|
|
v0ei.append(ps[0])
|
|
|
|
var v1ei : PoolIntArray = PoolIntArray()
|
|
|
|
var v2ei : PoolIntArray = PoolIntArray()
|
|
|
|
|
|
|
|
for i in range(1, ps.size()):
|
|
|
|
var vert : Vector3 = _vertices[ps[i]]
|
|
|
|
|
|
|
|
if is_verts_equal(v0, vert):
|
|
|
|
v0ei.append(ps[i])
|
|
|
|
else:
|
|
|
|
if v1found:
|
|
|
|
if is_verts_equal(v1, vert):
|
|
|
|
v1ei.append(ps[i])
|
|
|
|
else:
|
|
|
|
v2ei.append(ps[i])
|
|
|
|
else:
|
|
|
|
v1found = true
|
|
|
|
v1 = _vertices[ps[i]]
|
|
|
|
v1ei.append(ps[i])
|
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
return [ v0ei, v1ei, v2ei ]
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
int MDIGizmo::find_first_triangle_index_for_face(int face) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var split_indices_arr : Array = split_face_indices(face)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if split_indices_arr.size() == 0:
|
|
|
|
return -1
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var v0ei : PoolIntArray = split_indices_arr[0]
|
|
|
|
var v1ei : PoolIntArray = split_indices_arr[1]
|
|
|
|
var v2ei : PoolIntArray = split_indices_arr[2]
|
|
|
|
var tri_index : int = -1
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(0, _indices.size(), 3):
|
|
|
|
var i0 : int = _indices[i]
|
|
|
|
var i1 : int = _indices[i + 1]
|
|
|
|
var i2 : int = _indices[i + 2]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2):
|
|
|
|
if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2):
|
|
|
|
if pool_int_arr_contains(v2ei, i0) || pool_int_arr_contains(v2ei, i1) || pool_int_arr_contains(v2ei, i2):
|
|
|
|
return i / 3
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
return -1
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::delete_selected() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if _selected_points.size() == 0:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
#todo
|
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
#todo
|
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_FACE:
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var triangle_indexes : Array = Array()
|
|
|
|
for sp in _selected_points:
|
|
|
|
var triangle_index : int = find_first_triangle_index_for_face(sp)
|
|
|
|
triangle_indexes.append(triangle_index)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
#delete in reverse triangle index order
|
|
|
|
triangle_indexes.sort()
|
|
|
|
|
|
|
|
for i in range(triangle_indexes.size() - 1, -1, -1):
|
|
|
|
var triangle_index : int = triangle_indexes[i]
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::remove_triangle(_mdr, triangle_index)
|
2022-04-10 21:14:56 +02:00
|
|
|
|
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Delete")
|
|
|
|
|
|
|
|
_selected_points.resize(0)
|
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::generate_normals() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
|
|
|
|
|
|
|
var mdr_arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX] == null || mdr_arr[ArrayMesh::ARRAY_VERTEX].size() == 0:
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
|
|
|
var orig_seams = copy_pool_int_array(_mdr.seams)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var seam_points : PoolVector3Array = MDREDMeshUtils::seams_to_points(_mdr)
|
|
|
|
MDREDMeshUtils::generate_normals_mdr(_mdr)
|
|
|
|
MDREDMeshUtils::points_to_seams(_mdr, seam_points)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_seam_change_undo_redo(orig_arr, orig_seams, _mdr.array, _mdr.seams, "Generate Normals")
|
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::generate_tangents() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var mdr_arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX] == null || mdr_arr[ArrayMesh::ARRAY_VERTEX].size() == 0:
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
|
|
|
var orig_seams = copy_pool_int_array(_mdr.seams)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var seam_points : PoolVector3Array = MDREDMeshUtils::seams_to_points(_mdr)
|
|
|
|
MDREDMeshUtils::generate_tangents(_mdr)
|
|
|
|
MDREDMeshUtils::points_to_seams(_mdr, seam_points)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_seam_change_undo_redo(orig_arr, orig_seams, _mdr.array, _mdr.seams, "Generate Tangents")
|
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::remove_doubles() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var mdr_arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX] == null || mdr_arr[ArrayMesh::ARRAY_VERTEX].size() == 0:
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
|
|
|
var orig_seams = copy_pool_int_array(_mdr.seams)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var seam_points : PoolVector3Array = MDREDMeshUtils::seams_to_points(_mdr)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var merged_arrays : Array = MeshUtils::remove_doubles(mdr_arr)
|
2022-04-10 21:14:56 +02:00
|
|
|
_mdr.array = merged_arrays
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::points_to_seams(_mdr, seam_points)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_seam_change_undo_redo(orig_arr, orig_seams, _mdr.array, _mdr.seams, "Remove Doubles")
|
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::merge_optimize() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var mdr_arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX] == null || mdr_arr[ArrayMesh::ARRAY_VERTEX].size() == 0:
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
|
|
|
var orig_seams = copy_pool_int_array(_mdr.seams)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var seam_points : PoolVector3Array = MDREDMeshUtils::seams_to_points(_mdr)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var merged_arrays : Array = MeshUtils::merge_mesh_array(mdr_arr)
|
2022-04-10 21:14:56 +02:00
|
|
|
_mdr.array = merged_arrays
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::points_to_seams(_mdr, seam_points)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_seam_change_undo_redo(orig_arr, orig_seams, _mdr.array, _mdr.seams, "Merge Optimize")
|
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void MDIGizmo::connect_to_first_selected() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if _selected_points.size() < 2:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var mdr_arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX] == null || mdr_arr[ArrayMesh::ARRAY_VERTEX].size() == 0:
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var vertices : PoolVector3Array = mdr_arr[ArrayMesh::ARRAY_VERTEX]
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
var mpos : Vector3 = _handle_points[_selected_points[0]]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(1, _selected_points.size()):
|
|
|
|
var ps : PoolIntArray = _handle_to_vertex_map[_selected_points[i]]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for indx in ps:
|
|
|
|
vertices[indx] = mpos
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_selected_points.resize(0)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
mdr_arr[ArrayMesh::ARRAY_VERTEX] = vertices
|
2022-04-10 21:14:56 +02:00
|
|
|
_mdr.array = mdr_arr
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Connect to first selected")
|
|
|
|
enable_change_event()
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_FACE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::connect_to_avg() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if _selected_points.size() < 2:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var mdr_arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX] == null || mdr_arr[ArrayMesh::ARRAY_VERTEX].size() == 0:
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var vertices : PoolVector3Array = mdr_arr[ArrayMesh::ARRAY_VERTEX]
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
var mpos : Vector3 = Vector3()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for sp in _selected_points:
|
|
|
|
mpos += _handle_points[sp]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
mpos /= _selected_points.size()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(_selected_points.size()):
|
|
|
|
var ps : PoolIntArray = _handle_to_vertex_map[_selected_points[i]]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for indx in ps:
|
|
|
|
vertices[indx] = mpos
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_selected_points.resize(0)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
mdr_arr[ArrayMesh::ARRAY_VERTEX] = vertices
|
2022-04-10 21:14:56 +02:00
|
|
|
_mdr.array = mdr_arr
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Connect to average")
|
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_FACE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::connect_to_last_selected() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if _selected_points.size() < 2:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var orig_arr = copy_arrays(_mdr.array)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var mdr_arr : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX] == null || mdr_arr[ArrayMesh::ARRAY_VERTEX].size() == 0:
|
2022-04-10 21:14:56 +02:00
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var vertices : PoolVector3Array = mdr_arr[ArrayMesh::ARRAY_VERTEX]
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
var mpos : Vector3 = _handle_points[_selected_points[_selected_points.size() - 1]]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(0, _selected_points.size() - 1):
|
|
|
|
var ps : PoolIntArray = _handle_to_vertex_map[_selected_points[i]]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for indx in ps:
|
|
|
|
vertices[indx] = mpos
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_selected_points.resize(0)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
mdr_arr[ArrayMesh::ARRAY_VERTEX] = vertices
|
2022-04-10 21:14:56 +02:00
|
|
|
_mdr.array = mdr_arr
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "Connect to last selected")
|
|
|
|
enable_change_event()
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_FACE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
PoolIntArray MDIGizmo::get_first_index_pair_for_edge(int edge) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var ret : PoolIntArray = PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var eisarr : Array = split_edge_indices(edge)
|
|
|
|
|
|
|
|
if eisarr.size() == 0:
|
|
|
|
return ret
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# these should have the same size
|
|
|
|
var v0ei : PoolIntArray = eisarr[0]
|
|
|
|
var v1ei : PoolIntArray = eisarr[1]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var res : PoolIntArray = PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(0, _indices.size(), 3):
|
|
|
|
var i0 : int = _indices[i]
|
|
|
|
var i1 : int = _indices[i + 1]
|
|
|
|
var i2 : int = _indices[i + 2]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2):
|
|
|
|
if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2):
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v0ei, i0):
|
|
|
|
ret.push_back(i0)
|
|
|
|
elif pool_int_arr_contains(v0ei, i1):
|
|
|
|
ret.push_back(i1)
|
|
|
|
elif pool_int_arr_contains(v0ei, i2):
|
|
|
|
ret.push_back(i2)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v1ei, i0):
|
|
|
|
ret.push_back(i0)
|
|
|
|
elif pool_int_arr_contains(v1ei, i1):
|
|
|
|
ret.push_back(i1)
|
|
|
|
elif pool_int_arr_contains(v1ei, i2):
|
|
|
|
ret.push_back(i2)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
return ret
|
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
return ret
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
PoolIntArray MDIGizmo::get_all_index_pairs_for_edge(int edge) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
var ret : PoolIntArray = PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var eisarr : Array = split_edge_indices(edge)
|
|
|
|
|
|
|
|
if eisarr.size() == 0:
|
|
|
|
return ret
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
# these should have the same size
|
|
|
|
var v0ei : PoolIntArray = eisarr[0]
|
|
|
|
var v1ei : PoolIntArray = eisarr[1]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var res : PoolIntArray = PoolIntArray()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for i in range(0, _indices.size(), 3):
|
|
|
|
var i0 : int = _indices[i]
|
|
|
|
var i1 : int = _indices[i + 1]
|
|
|
|
var i2 : int = _indices[i + 2]
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2):
|
|
|
|
if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2):
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v0ei, i0):
|
|
|
|
ret.push_back(i0)
|
|
|
|
elif pool_int_arr_contains(v0ei, i1):
|
|
|
|
ret.push_back(i1)
|
|
|
|
elif pool_int_arr_contains(v0ei, i2):
|
|
|
|
ret.push_back(i2)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if pool_int_arr_contains(v1ei, i0):
|
|
|
|
ret.push_back(i0)
|
|
|
|
elif pool_int_arr_contains(v1ei, i1):
|
|
|
|
ret.push_back(i1)
|
|
|
|
elif pool_int_arr_contains(v1ei, i2):
|
|
|
|
ret.push_back(i2)
|
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
return ret
|
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::mark_seam() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if _selected_points.size() == 0:
|
|
|
|
return
|
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var prev_seams : PoolIntArray = copy_pool_int_array(_mdr.seams)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for se in _selected_points:
|
2022-04-13 02:08:30 +02:00
|
|
|
var eis : PoolIntArray = MDREDMeshUtils::order_seam_indices(get_first_index_pair_for_edge(se))
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if eis.size() == 0:
|
|
|
|
continue
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::add_seam(_mdr, eis[0], eis[1])
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_undo_redo.create_action("mark_seam")
|
|
|
|
_undo_redo.add_do_method(self, "set_seam", _mdr, copy_pool_int_array(_mdr.seams))
|
|
|
|
_undo_redo.add_undo_method(self, "set_seam", _mdr, prev_seams)
|
|
|
|
_undo_redo.commit_action()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
enable_change_event()
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_FACE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::unmark_seam() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if _selected_points.size() == 0:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if selection_mode == SELECTION_MODE_VERTEX:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_EDGE:
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var prev_seams : PoolIntArray = copy_pool_int_array(_mdr.seams)
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
for se in _selected_points:
|
2022-04-13 02:08:30 +02:00
|
|
|
var eis : PoolIntArray = MDREDMeshUtils::order_seam_indices(get_all_index_pairs_for_edge(se))
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
if eis.size() == 0:
|
|
|
|
continue
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::remove_seam(_mdr, eis[0], eis[1])
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
_undo_redo.create_action("unmark_seam")
|
|
|
|
_undo_redo.add_do_method(self, "set_seam", _mdr, copy_pool_int_array(_mdr.seams))
|
|
|
|
_undo_redo.add_undo_method(self, "set_seam", _mdr, prev_seams)
|
|
|
|
_undo_redo.commit_action()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
enable_change_event()
|
2022-04-13 02:08:30 +02:00
|
|
|
elif selection_mode == SELECTION_MODE_FACE:
|
2022-04-10 21:14:56 +02:00
|
|
|
pass
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::set_seam(Ref<MeshDataResource> mdr, PoolIntArray arr) {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
mdr.seams = arr
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
void MDIGizmo::apply_seam() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var orig_arr : Array = copy_arrays(_mdr.array)
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::apply_seam(_mdr)
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr.array, "apply_seam")
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::clean_mesh() {
|
|
|
|
/*
|
2022-04-10 21:14:56 +02:00
|
|
|
if !_mdr:
|
|
|
|
return
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var arrays : Array = _mdr.array
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if arrays.size() != ArrayMesh::ARRAY_MAX:
|
2022-04-10 21:14:56 +02:00
|
|
|
return arrays
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if arrays[ArrayMesh::ARRAY_VERTEX] == null || arrays[ArrayMesh::ARRAY_INDEX] == null:
|
2022-04-10 21:14:56 +02:00
|
|
|
return arrays
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
var old_vert_size : int = arrays[ArrayMesh::ARRAY_VERTEX].size()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
disable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var orig_arr : Array = copy_arrays(arrays)
|
2022-04-13 02:08:30 +02:00
|
|
|
arrays = MDREDMeshUtils::remove_used_vertices(arrays)
|
|
|
|
var new_vert_size : int = arrays[ArrayMesh::ARRAY_VERTEX].size()
|
2022-04-10 21:14:56 +02:00
|
|
|
add_mesh_change_undo_redo(orig_arr, arrays, "clean_mesh")
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
enable_change_event()
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
var d : int = old_vert_size - new_vert_size
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-10 21:14:56 +02:00
|
|
|
print("MDRED: Removed " + str(d) + " unused vertices.")
|
2022-04-11 13:42:49 +02:00
|
|
|
*/
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::uv_unwrap() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!_mdr.is_valid()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Array mdr_arr = _mdr->get_array();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX].is_null()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolVector3Array verts = mdr_arr[ArrayMesh::ARRAY_VERTEX];
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (verts.size() == 0) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
disable_change_event();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolVector2Array uvs = MeshUtils::get_singleton()->uv_unwrap(mdr_arr);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (uvs.size() != verts.size()) {
|
|
|
|
ERR_PRINT("Error: Could not unwrap mesh!");
|
|
|
|
enable_change_event(false);
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Array orig_arr = copy_arrays(mdr_arr);
|
|
|
|
|
|
|
|
mdr_arr[ArrayMesh::ARRAY_TEX_UV] = uvs;
|
|
|
|
|
|
|
|
add_mesh_change_undo_redo(orig_arr, mdr_arr, "uv_unwrap");
|
|
|
|
enable_change_event();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::flip_selected_faces() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!_mdr.is_valid()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (_selected_points.size() == 0) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (selection_mode == SELECTION_MODE_VERTEX) {
|
|
|
|
} else if (selection_mode == SELECTION_MODE_EDGE) {
|
|
|
|
} else if (selection_mode == SELECTION_MODE_FACE) {
|
|
|
|
disable_change_event();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Array orig_arr = copy_arrays(_mdr->get_array());
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolIntArray::Read r = _selected_points.read();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 0; i < _selected_points.size(); ++i) {
|
|
|
|
int sp = r[i];
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
int triangle_index = find_first_triangle_index_for_face(sp);
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
MDREDMeshUtils::flip_triangle_ti(_mdr, triangle_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
add_mesh_change_undo_redo(orig_arr, _mdr->get_array(), "Flip Faces");
|
|
|
|
|
|
|
|
enable_change_event();
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::add_mesh_change_undo_redo(Array orig_arr, Array new_arr, String action_name) {
|
2022-04-13 02:08:30 +02:00
|
|
|
_undo_redo->create_action(action_name);
|
|
|
|
Array nac = copy_arrays(new_arr);
|
|
|
|
_undo_redo->add_do_method(this, "apply_mesh_change", _mdr, nac);
|
|
|
|
_undo_redo->add_undo_method(this, "apply_mesh_change", _mdr, orig_arr);
|
|
|
|
_undo_redo->commit_action();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::add_mesh_seam_change_undo_redo(Array orig_arr, PoolIntArray orig_seams, Array new_arr, PoolIntArray new_seams, String action_name) {
|
2022-04-13 02:08:30 +02:00
|
|
|
_undo_redo->create_action(action_name);
|
|
|
|
Array nac = copy_arrays(new_arr);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_undo_redo->add_do_method(this, "apply_mesh_change", _mdr, nac);
|
|
|
|
_undo_redo->add_undo_method(this, "apply_mesh_change", _mdr, orig_arr);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_undo_redo->add_do_method(this, "set_seam", _mdr, copy_pool_int_array(new_seams));
|
|
|
|
_undo_redo->add_undo_method(this, "set_seam", _mdr, orig_seams);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
_undo_redo->commit_action();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::apply_mesh_change(Ref<MeshDataResource> mdr, Array arr) {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!mdr.is_valid()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
mdr->set_array(copy_arrays(arr));
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::apply_vertex_array(Ref<MeshDataResource> mdr, PoolVector3Array verts) {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!mdr.is_valid()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Array mdr_arr = mdr->get_array();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (mdr_arr.size() != ArrayMesh::ARRAY_MAX) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
mdr_arr[ArrayMesh::ARRAY_VERTEX] = verts;
|
|
|
|
mdr->set_array(mdr_arr);
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
Array MDIGizmo::copy_arrays(Array arr) {
|
2022-04-13 02:08:30 +02:00
|
|
|
return arr.duplicate(true);
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
PoolIntArray MDIGizmo::copy_pool_int_array(PoolIntArray pia) {
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolIntArray ret;
|
|
|
|
ret.resize(pia.size());
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolIntArray::Read r = pia.read();
|
|
|
|
PoolIntArray::Write w = ret.write();
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 0; i < pia.size(); ++i) {
|
|
|
|
w[i] = r[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
r.release();
|
|
|
|
w.release();
|
|
|
|
|
|
|
|
return ret;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
PoolVector3Array MDIGizmo::copy_mdr_verts_array() {
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolVector3Array ret;
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (!_mdr.is_valid()) {
|
|
|
|
return ret;
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
Array mdr_arr = _mdr->get_array();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
if (mdr_arr.size() != ArrayMesh::ARRAY_MAX || mdr_arr[ArrayMesh::ARRAY_VERTEX].is_null()) {
|
|
|
|
return ret;
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolVector3Array vertices = mdr_arr[ArrayMesh::ARRAY_VERTEX];
|
|
|
|
ret.append_array(vertices);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
return ret;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::setup_op_drag_indices() {
|
2022-04-13 02:08:30 +02:00
|
|
|
_drag_op_indices.resize(0);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolIntArray::Read r = _selected_points.read();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 0; i < _selected_points.size(); ++i) {
|
|
|
|
int sp = r[i];
|
|
|
|
PoolIntArray pi = _handle_to_vertex_map[sp];
|
|
|
|
|
|
|
|
PoolIntArray::Read pir = pi.read();
|
|
|
|
|
|
|
|
for (int j = 0; j < pi.size(); ++j) {
|
|
|
|
int indx = pir[j];
|
|
|
|
if (!pool_int_arr_contains(_drag_op_indices, indx)) {
|
|
|
|
_drag_op_indices.append(indx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pir.release();
|
|
|
|
}
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
Vector3 MDIGizmo::get_drag_op_pivot() {
|
2022-04-13 02:08:30 +02:00
|
|
|
if (pivot_type == PIVOT_TYPE_AVERAGED) {
|
|
|
|
Vector3 avg = Vector3();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolIntArray::Read r = _drag_op_indices.read();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int i = 0; i < _drag_op_indices.size(); ++i) {
|
|
|
|
avg += _vertices[r[i]];
|
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
r.release();
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
avg /= _drag_op_indices.size();
|
|
|
|
|
|
|
|
return avg;
|
|
|
|
} else if (pivot_type == PIVOT_TYPE_MDI_ORIGIN) {
|
|
|
|
return Vector3();
|
|
|
|
} else if (pivot_type == PIVOT_TYPE_WORLD_ORIGIN) {
|
|
|
|
return get_spatial_node()->to_local(Vector3());
|
|
|
|
}
|
|
|
|
|
|
|
|
return Vector3();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::select_handle_points(PoolVector3Array points) {
|
2022-04-13 02:08:30 +02:00
|
|
|
_selected_points.resize(0);
|
2022-04-11 13:42:49 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
PoolVector3Array::Read r = points.read();
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
for (int ip = 0; ip < points.size(); ++ip) {
|
|
|
|
Vector3 p = r[ip];
|
|
|
|
|
|
|
|
PoolVector3Array::Read hpr = _handle_points.read();
|
|
|
|
|
|
|
|
for (int i = 0; i < _handle_points.size(); ++i) {
|
|
|
|
if (is_verts_equal(p, hpr[i])) {
|
|
|
|
if (!pool_int_arr_contains(_selected_points, i)) {
|
|
|
|
_selected_points.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hpr.release();
|
|
|
|
}
|
|
|
|
|
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::set_pivot_averaged() {
|
2022-04-13 02:08:30 +02:00
|
|
|
pivot_type = PIVOT_TYPE_AVERAGED;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_pivot_mdi_origin() {
|
2022-04-13 02:08:30 +02:00
|
|
|
pivot_type = PIVOT_TYPE_MDI_ORIGIN;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::set_pivot_world_origin() {
|
2022-04-13 02:08:30 +02:00
|
|
|
pivot_type = PIVOT_TYPE_WORLD_ORIGIN;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-13 02:08:30 +02:00
|
|
|
void MDIGizmo::transfer_state_from(const Ref<MDIGizmo> &other) {
|
|
|
|
edit_mode = other->edit_mode;
|
|
|
|
pivot_type = other->pivot_type;
|
|
|
|
axis_constraint = other->axis_constraint;
|
|
|
|
selection_mode = other->selection_mode;
|
|
|
|
handle_selection_type = other->handle_selection_type;
|
|
|
|
|
|
|
|
visual_indicator_outline = other->visual_indicator_outline;
|
|
|
|
visual_indicator_seam = other->visual_indicator_seam;
|
|
|
|
visual_indicator_handle = other->visual_indicator_handle;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
void MDIGizmo::visual_indicator_outline_set(bool on) {
|
2022-04-13 02:08:30 +02:00
|
|
|
visual_indicator_outline = on;
|
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::visual_indicator_seam_set(bool on) {
|
2022-04-13 02:08:30 +02:00
|
|
|
visual_indicator_seam = on;
|
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::visual_indicator_handle_set(bool on) {
|
2022-04-13 02:08:30 +02:00
|
|
|
visual_indicator_handle = on;
|
|
|
|
redraw();
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MDIGizmo::handle_selection_type_front() {
|
2022-04-13 02:08:30 +02:00
|
|
|
handle_selection_type = HANDLE_SELECTION_TYPE_FRONT;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::handle_selection_type_back() {
|
2022-04-13 02:08:30 +02:00
|
|
|
handle_selection_type = HANDLE_SELECTION_TYPE_BACK;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
void MDIGizmo::handle_selection_type_all() {
|
2022-04-13 02:08:30 +02:00
|
|
|
handle_selection_type = HANDLE_SELECTION_TYPE_ALL;
|
2022-04-11 13:42:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
MDIGizmo::MDIGizmo() {
|
|
|
|
gizmo_size = 3.0;
|
|
|
|
|
|
|
|
edit_mode = EDIT_MODE_TRANSLATE;
|
|
|
|
pivot_type = PIVOT_TYPE_AVERAGED;
|
|
|
|
axis_constraint = AXIS_CONSTRAINT_X | AXIS_CONSTRAINT_Y | AXIS_CONSTRAINT_Z;
|
|
|
|
selection_mode = SELECTION_MODE_VERTEX;
|
|
|
|
handle_selection_type = HANDLE_SELECTION_TYPE_FRONT;
|
|
|
|
visual_indicator_outline = true;
|
|
|
|
visual_indicator_seam = true;
|
|
|
|
visual_indicator_handle = true;
|
|
|
|
|
|
|
|
_last_known_camera_facing = Vector3(0, 0, -1);
|
|
|
|
|
|
|
|
_rect_drag = false;
|
|
|
|
_rect_drag_min_ofset = 10;
|
2022-04-10 21:14:56 +02:00
|
|
|
|
2022-04-11 13:42:49 +02:00
|
|
|
_mesh_outline_generator.instance();
|
|
|
|
|
|
|
|
_handle_drag_op = false;
|
|
|
|
|
|
|
|
_editor_plugin = nullptr;
|
|
|
|
_undo_redo = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MDIGizmo::~MDIGizmo() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void MDIGizmo::_bind_methods() {
|
|
|
|
}
|