| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  collision_polygon_editor_plugin.cpp                                  */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-01 14:40:08 +01:00
										 |  |  | /* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* 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.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "collision_polygon_editor_plugin.h"
 | 
					
						
							| 
									
										
										
										
											2017-01-16 08:04:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include "canvas_item_editor_plugin.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/os/file_access.h"
 | 
					
						
							|  |  |  | #include "core/os/input.h"
 | 
					
						
							|  |  |  | #include "core/os/keyboard.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-05 14:21:25 +01:00
										 |  |  | #include "editor/editor_settings.h"
 | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | #include "scene/3d/camera.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include "spatial_editor_plugin.h"
 | 
					
						
							| 
									
										
										
										
											2015-02-13 20:49:21 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | void Polygon3DEditor::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	switch (p_what) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case NOTIFICATION_READY: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			button_create->set_icon(get_icon("Edit", "EditorIcons")); | 
					
						
							|  |  |  | 			button_edit->set_icon(get_icon("MovePoint", "EditorIcons")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			button_edit->set_pressed(true); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			get_tree()->connect("node_removed", this, "_node_removed"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		case NOTIFICATION_PROCESS: { | 
					
						
							| 
									
										
										
										
											2017-08-26 22:50:15 +02:00
										 |  |  | 			if (!node) { | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 			if (_get_depth() != prev_depth) { | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 				_polygon_draw(); | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 				prev_depth = _get_depth(); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | void Polygon3DEditor::_node_removed(Node *p_node) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	if (p_node == node) { | 
					
						
							|  |  |  | 		node = NULL; | 
					
						
							|  |  |  | 		if (imgeom->get_parent() == p_node) | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 			p_node->remove_child(imgeom); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		hide(); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		set_process(false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | void Polygon3DEditor::_menu_option(int p_option) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	switch (p_option) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case MODE_CREATE: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			mode = MODE_CREATE; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			button_create->set_pressed(true); | 
					
						
							|  |  |  | 			button_edit->set_pressed(false); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case MODE_EDIT: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			mode = MODE_EDIT; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			button_create->set_pressed(false); | 
					
						
							|  |  |  | 			button_edit->set_pressed(true); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | void Polygon3DEditor::_wip_close() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-24 02:38:26 -02:00
										 |  |  | 	undo_redo->create_action(TTR("Create Polygon3D")); | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	undo_redo->add_undo_method(node, "set_polygon", node->call("get_polygon")); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	undo_redo->add_do_method(node, "set_polygon", wip); | 
					
						
							|  |  |  | 	undo_redo->add_do_method(this, "_polygon_draw"); | 
					
						
							|  |  |  | 	undo_redo->add_undo_method(this, "_polygon_draw"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	wip.clear(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	wip_active = false; | 
					
						
							|  |  |  | 	mode = MODE_EDIT; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	button_edit->set_pressed(true); | 
					
						
							|  |  |  | 	button_create->set_pressed(false); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	edited_point = -1; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 	undo_redo->commit_action(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | bool Polygon3DEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) { | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-16 22:31:57 -03:00
										 |  |  | 	if (!node) | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Transform gt = node->get_global_transform(); | 
					
						
							| 
									
										
										
										
											2015-09-07 08:20:33 -03:00
										 |  |  | 	Transform gi = gt.affine_inverse(); | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	float depth = _get_depth() * 0.5; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 	Vector3 n = gt.basis.get_axis(2).normalized(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	Plane p(gt.origin + n * depth, n); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	Ref<InputEventMouseButton> mb = p_event; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	if (mb.is_valid()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		Vector2 gpoint = mb->get_position(); | 
					
						
							|  |  |  | 		Vector3 ray_from = p_camera->project_ray_origin(gpoint); | 
					
						
							|  |  |  | 		Vector3 ray_dir = p_camera->project_ray_normal(gpoint); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		Vector3 spoint; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		if (!p.intersects_ray(ray_from, ray_dir, &spoint)) | 
					
						
							|  |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		spoint = gi.xform(spoint); | 
					
						
							| 
									
										
										
										
											2015-09-07 08:20:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		Vector2 cpoint(spoint.x, spoint.y); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 11:22:22 -03:00
										 |  |  | 		//DO NOT snap here, it's confusing in 3D for adding points.
 | 
					
						
							|  |  |  | 		//Let the snap happen when the point is being moved, instead.
 | 
					
						
							|  |  |  | 		//cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 		Vector<Vector2> poly = node->call("get_polygon"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		//first check if a point is to be added (segment split)
 | 
					
						
							| 
									
										
										
										
											2018-02-21 11:30:55 -05:00
										 |  |  | 		real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		switch (mode) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			case MODE_CREATE: { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 				if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 					if (!wip_active) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 						wip.clear(); | 
					
						
							|  |  |  | 						wip.push_back(cpoint); | 
					
						
							|  |  |  | 						wip_active = true; | 
					
						
							|  |  |  | 						edited_point_pos = cpoint; | 
					
						
							| 
									
										
										
										
											2018-04-28 11:22:22 -03:00
										 |  |  | 						snap_ignore = false; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 						_polygon_draw(); | 
					
						
							|  |  |  | 						edited_point = 1; | 
					
						
							|  |  |  | 						return true; | 
					
						
							|  |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 11:30:55 -05:00
										 |  |  | 						if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, wip[0].y, depth))).distance_to(gpoint) < grab_threshold) { | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							//wip closed
 | 
					
						
							|  |  |  | 							_wip_close(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							return true; | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							wip.push_back(cpoint); | 
					
						
							|  |  |  | 							edited_point = wip.size(); | 
					
						
							| 
									
										
										
										
											2018-04-28 11:22:22 -03:00
										 |  |  | 							snap_ignore = false; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							_polygon_draw(); | 
					
						
							|  |  |  | 							return true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 				} else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) { | 
					
						
							|  |  |  | 					_wip_close(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			} break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			case MODE_EDIT: { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 				if (mb->get_button_index() == BUTTON_LEFT) { | 
					
						
							|  |  |  | 					if (mb->is_pressed()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 						if (mb->get_control()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							if (poly.size() < 3) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 								undo_redo->create_action(TTR("Edit Poly")); | 
					
						
							|  |  |  | 								undo_redo->add_undo_method(node, "set_polygon", poly); | 
					
						
							|  |  |  | 								poly.push_back(cpoint); | 
					
						
							|  |  |  | 								undo_redo->add_do_method(node, "set_polygon", poly); | 
					
						
							|  |  |  | 								undo_redo->add_do_method(this, "_polygon_draw"); | 
					
						
							|  |  |  | 								undo_redo->add_undo_method(this, "_polygon_draw"); | 
					
						
							|  |  |  | 								undo_redo->commit_action(); | 
					
						
							|  |  |  | 								return true; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							//search edges
 | 
					
						
							|  |  |  | 							int closest_idx = -1; | 
					
						
							|  |  |  | 							Vector2 closest_pos; | 
					
						
							|  |  |  | 							real_t closest_dist = 1e10; | 
					
						
							|  |  |  | 							for (int i = 0; i < poly.size(); i++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								Vector2 points[2] = { | 
					
						
							|  |  |  | 									p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))), | 
					
						
							|  |  |  | 									p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, poly[(i + 1) % poly.size()].y, depth))) | 
					
						
							|  |  |  | 								}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points); | 
					
						
							|  |  |  | 								if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) | 
					
						
							|  |  |  | 									continue; //not valid to reuse point
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								real_t d = cp.distance_to(gpoint); | 
					
						
							| 
									
										
										
										
											2018-02-21 11:30:55 -05:00
										 |  |  | 								if (d < closest_dist && d < grab_threshold) { | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 									closest_dist = d; | 
					
						
							|  |  |  | 									closest_pos = cp; | 
					
						
							|  |  |  | 									closest_idx = i; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							if (closest_idx >= 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 								pre_move_edit = poly; | 
					
						
							|  |  |  | 								poly.insert(closest_idx + 1, cpoint); | 
					
						
							|  |  |  | 								edited_point = closest_idx + 1; | 
					
						
							|  |  |  | 								edited_point_pos = cpoint; | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 								node->call("set_polygon", poly); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 								_polygon_draw(); | 
					
						
							| 
									
										
										
										
											2018-04-28 11:22:22 -03:00
										 |  |  | 								snap_ignore = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 								return true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							//look for points to move
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							int closest_idx = -1; | 
					
						
							|  |  |  | 							Vector2 closest_pos; | 
					
						
							|  |  |  | 							real_t closest_dist = 1e10; | 
					
						
							|  |  |  | 							for (int i = 0; i < poly.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 								Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 								real_t d = cp.distance_to(gpoint); | 
					
						
							| 
									
										
										
										
											2018-02-21 11:30:55 -05:00
										 |  |  | 								if (d < closest_dist && d < grab_threshold) { | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 									closest_dist = d; | 
					
						
							|  |  |  | 									closest_pos = cp; | 
					
						
							|  |  |  | 									closest_idx = i; | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							if (closest_idx >= 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 								pre_move_edit = poly; | 
					
						
							|  |  |  | 								edited_point = closest_idx; | 
					
						
							|  |  |  | 								edited_point_pos = poly[closest_idx]; | 
					
						
							|  |  |  | 								_polygon_draw(); | 
					
						
							| 
									
										
										
										
											2018-04-28 11:22:22 -03:00
										 |  |  | 								snap_ignore = false; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 								return true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 11:22:22 -03:00
										 |  |  | 						snap_ignore = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 						if (edited_point != -1) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							//apply
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							ERR_FAIL_INDEX_V(edited_point, poly.size(), false); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 							poly.write[edited_point] = edited_point_pos; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							undo_redo->create_action(TTR("Edit Poly")); | 
					
						
							|  |  |  | 							undo_redo->add_do_method(node, "set_polygon", poly); | 
					
						
							|  |  |  | 							undo_redo->add_undo_method(node, "set_polygon", pre_move_edit); | 
					
						
							|  |  |  | 							undo_redo->add_do_method(this, "_polygon_draw"); | 
					
						
							|  |  |  | 							undo_redo->add_undo_method(this, "_polygon_draw"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							undo_redo->commit_action(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							edited_point = -1; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 							return true; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 					int closest_idx = -1; | 
					
						
							|  |  |  | 					Vector2 closest_pos; | 
					
						
							|  |  |  | 					real_t closest_dist = 1e10; | 
					
						
							|  |  |  | 					for (int i = 0; i < poly.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 						Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 						real_t d = cp.distance_to(gpoint); | 
					
						
							| 
									
										
										
										
											2018-02-21 11:30:55 -05:00
										 |  |  | 						if (d < closest_dist && d < grab_threshold) { | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 							closest_dist = d; | 
					
						
							|  |  |  | 							closest_pos = cp; | 
					
						
							|  |  |  | 							closest_idx = i; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 					if (closest_idx >= 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 						undo_redo->create_action(TTR("Edit Poly (Remove Point)")); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(node, "set_polygon", poly); | 
					
						
							|  |  |  | 						poly.remove(closest_idx); | 
					
						
							|  |  |  | 						undo_redo->add_do_method(node, "set_polygon", poly); | 
					
						
							|  |  |  | 						undo_redo->add_do_method(this, "_polygon_draw"); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(this, "_polygon_draw"); | 
					
						
							|  |  |  | 						undo_redo->commit_action(); | 
					
						
							|  |  |  | 						return true; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	Ref<InputEventMouseMotion> mm = p_event; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	if (mm.is_valid()) { | 
					
						
							|  |  |  | 		if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) { | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			Vector2 gpoint = mm->get_position(); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			Vector3 ray_from = p_camera->project_ray_origin(gpoint); | 
					
						
							|  |  |  | 			Vector3 ray_dir = p_camera->project_ray_normal(gpoint); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			Vector3 spoint; | 
					
						
							| 
									
										
										
										
											2015-09-07 08:20:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			if (!p.intersects_ray(ray_from, ray_dir, &spoint)) | 
					
						
							|  |  |  | 				return false; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			spoint = gi.xform(spoint); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			Vector2 cpoint(spoint.x, spoint.y); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 11:22:22 -03:00
										 |  |  | 			if (snap_ignore && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { | 
					
						
							|  |  |  | 				snap_ignore = false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!snap_ignore) { | 
					
						
							|  |  |  | 				cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			edited_point_pos = cpoint; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			_polygon_draw(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | float Polygon3DEditor::_get_depth() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (bool(node->call("_has_editable_3d_polygon_no_depth"))) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return float(node->call("get_depth")); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Polygon3DEditor::_polygon_draw() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!node) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Vector<Vector2> poly; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (wip_active) | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		poly = wip; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 		poly = node->call("get_polygon"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	float depth = _get_depth() * 0.5; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	imgeom->clear(); | 
					
						
							|  |  |  | 	imgeom->set_material_override(line_material); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	imgeom->begin(Mesh::PRIMITIVE_LINES, Ref<Texture>()); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Rect2 rect; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	for (int i = 0; i < poly.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		Vector2 p, p2; | 
					
						
							|  |  |  | 		p = i == edited_point ? edited_point_pos : poly[i]; | 
					
						
							|  |  |  | 		if ((wip_active && i == poly.size() - 1) || (((i + 1) % poly.size()) == edited_point)) | 
					
						
							|  |  |  | 			p2 = edited_point_pos; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			p2 = poly[(i + 1) % poly.size()]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		if (i == 0) | 
					
						
							|  |  |  | 			rect.position = p; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			rect.expand_to(p); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		Vector3 point = Vector3(p.x, p.y, depth); | 
					
						
							|  |  |  | 		Vector3 next_point = Vector3(p2.x, p2.y, depth); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		imgeom->set_color(Color(1, 0.3, 0.1, 0.8)); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		imgeom->add_vertex(point); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		imgeom->set_color(Color(1, 0.3, 0.1, 0.8)); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		imgeom->add_vertex(next_point); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		//Color col=Color(1,0.3,0.1,0.8);
 | 
					
						
							|  |  |  | 		//vpc->draw_line(point,next_point,col,2);
 | 
					
						
							|  |  |  | 		//vpc->draw_texture(handle,point-handle->get_size()*0.5);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	rect = rect.grow(1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | 	AABB r; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	r.position.x = rect.position.x; | 
					
						
							|  |  |  | 	r.position.y = rect.position.y; | 
					
						
							|  |  |  | 	r.position.z = depth; | 
					
						
							|  |  |  | 	r.size.x = rect.size.x; | 
					
						
							|  |  |  | 	r.size.y = rect.size.y; | 
					
						
							|  |  |  | 	r.size.z = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(0.3, 0, 0)); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(0.0, 0.3, 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0)); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0) - Vector3(0.3, 0, 0)); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0)); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0) + Vector3(0, 0.3, 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0)); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0) - Vector3(0, 0.3, 0)); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0)); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0) + Vector3(0.3, 0, 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + r.size); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + r.size - Vector3(0.3, 0, 0)); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + r.size); | 
					
						
							|  |  |  | 	imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2)); | 
					
						
							|  |  |  | 	imgeom->add_vertex(r.position + r.size - Vector3(0.0, 0.3, 0)); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	imgeom->end(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	while (m->get_surface_count()) { | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		m->surface_remove(0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	if (poly.size() == 0) | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Array a; | 
					
						
							|  |  |  | 	a.resize(Mesh::ARRAY_MAX); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 	PoolVector<Vector3> va; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		va.resize(poly.size()); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		PoolVector<Vector3>::Write w = va.write(); | 
					
						
							|  |  |  | 		for (int i = 0; i < poly.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			Vector2 p, p2; | 
					
						
							|  |  |  | 			p = i == edited_point ? edited_point_pos : poly[i]; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			Vector3 point = Vector3(p.x, p.y, depth); | 
					
						
							|  |  |  | 			w[i] = point; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	a[Mesh::ARRAY_VERTEX] = va; | 
					
						
							|  |  |  | 	m->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, a); | 
					
						
							|  |  |  | 	m->surface_set_material(0, handle_material); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | void Polygon3DEditor::edit(Node *p_collision_polygon) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (p_collision_polygon) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 		node = Object::cast_to<Spatial>(p_collision_polygon); | 
					
						
							| 
									
										
										
										
											2017-08-25 19:51:07 +02:00
										 |  |  | 		//Enable the pencil tool if the polygon is empty
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 		if (Vector<Vector2>(node->call("get_polygon")).size() == 0) { | 
					
						
							| 
									
										
										
										
											2017-08-25 19:51:07 +02:00
										 |  |  | 			_menu_option(MODE_CREATE); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		wip.clear(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		wip_active = false; | 
					
						
							|  |  |  | 		edited_point = -1; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		p_collision_polygon->add_child(imgeom); | 
					
						
							|  |  |  | 		_polygon_draw(); | 
					
						
							|  |  |  | 		set_process(true); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		prev_depth = -1; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		node = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		if (imgeom->get_parent()) | 
					
						
							|  |  |  | 			imgeom->get_parent()->remove_child(imgeom); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 		set_process(false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | void Polygon3DEditor::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_menu_option"), &Polygon3DEditor::_menu_option); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_polygon_draw"), &Polygon3DEditor::_polygon_draw); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_node_removed"), &Polygon3DEditor::_node_removed); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | Polygon3DEditor::Polygon3DEditor(EditorNode *p_editor) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	node = NULL; | 
					
						
							|  |  |  | 	editor = p_editor; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	undo_redo = editor->get_undo_redo(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	add_child(memnew(VSeparator)); | 
					
						
							|  |  |  | 	button_create = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	add_child(button_create); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	button_create->connect("pressed", this, "_menu_option", varray(MODE_CREATE)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	button_create->set_toggle_mode(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	button_edit = memnew(ToolButton); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	add_child(button_edit); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	button_edit->connect("pressed", this, "_menu_option", varray(MODE_EDIT)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	button_edit->set_toggle_mode(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mode = MODE_EDIT; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	wip_active = false; | 
					
						
							|  |  |  | 	imgeom = memnew(ImmediateGeometry); | 
					
						
							|  |  |  | 	imgeom->set_transform(Transform(Basis(), Vector3(0, 0, 0.00001))); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); | 
					
						
							|  |  |  | 	line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 	line_material->set_line_width(3.0); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); | 
					
						
							|  |  |  | 	line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); | 
					
						
							|  |  |  | 	line_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); | 
					
						
							|  |  |  | 	line_material->set_albedo(Color(1, 1, 1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); | 
					
						
							|  |  |  | 	handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); | 
					
						
							|  |  |  | 	handle_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true); | 
					
						
							|  |  |  | 	handle_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); | 
					
						
							|  |  |  | 	handle_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); | 
					
						
							|  |  |  | 	handle_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); | 
					
						
							|  |  |  | 	Ref<Texture> handle = editor->get_gui_base()->get_icon("Editor3DHandle", "EditorIcons"); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 	handle_material->set_point_size(handle->get_width()); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	handle_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, handle); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	pointsm = memnew(MeshInstance); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 	imgeom->add_child(pointsm); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	m.instance(); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 	pointsm->set_mesh(m); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	pointsm->set_transform(Transform(Basis(), Vector3(0, 0, 0.00001))); | 
					
						
							| 
									
										
										
										
											2018-04-28 11:22:22 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	snap_ignore = false; | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | Polygon3DEditor::~Polygon3DEditor() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	memdelete(imgeom); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | void Polygon3DEditorPlugin::edit(Object *p_object) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 	collision_polygon_editor->edit(Object::cast_to<Node>(p_object)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | bool Polygon3DEditorPlugin::handles(Object *p_object) const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	return Object::cast_to<Spatial>(p_object) && bool(p_object->call("_is_editable_3d_polygon")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | void Polygon3DEditorPlugin::make_visible(bool p_visible) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (p_visible) { | 
					
						
							|  |  |  | 		collision_polygon_editor->show(); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		collision_polygon_editor->hide(); | 
					
						
							|  |  |  | 		collision_polygon_editor->edit(NULL); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | Polygon3DEditorPlugin::Polygon3DEditorPlugin(EditorNode *p_node) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	editor = p_node; | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	collision_polygon_editor = memnew(Polygon3DEditor(p_node)); | 
					
						
							| 
									
										
										
										
											2014-09-16 21:19:54 -03:00
										 |  |  | 	SpatialEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	collision_polygon_editor->hide(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | Polygon3DEditorPlugin::~Polygon3DEditorPlugin() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |