bool Polygon3DEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) {

	if (!node)
		return false;

	Transform gt = node->get_global_transform();
	Transform gi = gt.affine_inverse();
	float depth = _get_depth() * 0.5;
	Vector3 n = gt.basis.get_axis(2).normalized();
	Plane p(gt.origin + n * depth, n);

	Ref<InputEventMouseButton> mb = p_event;

	if (mb.is_valid()) {

		Vector2 gpoint = mb->get_position();
		Vector3 ray_from = p_camera->project_ray_origin(gpoint);
		Vector3 ray_dir = p_camera->project_ray_normal(gpoint);

		Vector3 spoint;

		if (!p.intersects_ray(ray_from, ray_dir, &spoint))
			return false;

		spoint = gi.xform(spoint);

		Vector2 cpoint(spoint.x, spoint.y);

		//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);

		Vector<Vector2> poly = node->call("get_polygon");

		//first check if a point is to be added (segment split)
		real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);

		switch (mode) {

			case MODE_CREATE: {

				if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {

					if (!wip_active) {

						wip.clear();
						wip.push_back(cpoint);
						wip_active = true;
						edited_point_pos = cpoint;
						snap_ignore = false;
						_polygon_draw();
						edited_point = 1;
						return true;
					} else {

						if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, wip[0].y, depth))).distance_to(gpoint) < grab_threshold) {
							//wip closed
							_wip_close();

							return true;
						} else {

							wip.push_back(cpoint);
							edited_point = wip.size();
							snap_ignore = false;
							_polygon_draw();
							return true;
						}
					}
				} else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) {
					_wip_close();
				}

			} break;

			case MODE_EDIT: {

				if (mb->get_button_index() == BUTTON_LEFT) {
					if (mb->is_pressed()) {

						if (mb->get_control()) {

							if (poly.size() < 3) {

								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;
							}

							//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);
								if (d < closest_dist && d < grab_threshold) {
									closest_dist = d;
									closest_pos = cp;
									closest_idx = i;
								}
							}

							if (closest_idx >= 0) {

								pre_move_edit = poly;
								poly.insert(closest_idx + 1, cpoint);
								edited_point = closest_idx + 1;
								edited_point_pos = cpoint;
								node->call("set_polygon", poly);
								_polygon_draw();
								snap_ignore = true;

								return true;
							}
						} else {

							//look for points to move

							int closest_idx = -1;
							Vector2 closest_pos;
							real_t closest_dist = 1e10;
							for (int i = 0; i < poly.size(); i++) {

								Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth)));

								real_t d = cp.distance_to(gpoint);
								if (d < closest_dist && d < grab_threshold) {
									closest_dist = d;
									closest_pos = cp;
									closest_idx = i;
								}
							}

							if (closest_idx >= 0) {

								pre_move_edit = poly;
								edited_point = closest_idx;
								edited_point_pos = poly[closest_idx];
								_polygon_draw();
								snap_ignore = false;
								return true;
							}
						}
					} else {

						snap_ignore = false;

						if (edited_point != -1) {

							//apply

							ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
							poly[edited_point] = edited_point_pos;
							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");
							undo_redo->commit_action();

							edited_point = -1;
							return true;
						}
					}
				}
				if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) {

					int closest_idx = -1;
					Vector2 closest_pos;
					real_t closest_dist = 1e10;
					for (int i = 0; i < poly.size(); i++) {

						Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth)));

						real_t d = cp.distance_to(gpoint);
						if (d < closest_dist && d < grab_threshold) {
							closest_dist = d;
							closest_pos = cp;
							closest_idx = i;
						}
					}

					if (closest_idx >= 0) {

						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;
					}
				}

			} break;
		}
	}

	Ref<InputEventMouseMotion> mm = p_event;

	if (mm.is_valid()) {
		if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) {

			Vector2 gpoint = mm->get_position();

			Vector3 ray_from = p_camera->project_ray_origin(gpoint);
			Vector3 ray_dir = p_camera->project_ray_normal(gpoint);

			Vector3 spoint;

			if (!p.intersects_ray(ray_from, ray_dir, &spoint))
				return false;

			spoint = gi.xform(spoint);

			Vector2 cpoint(spoint.x, spoint.y);

			if (snap_ignore && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
				snap_ignore = false;
			}

			if (!snap_ignore) {
				cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint);
			}
			edited_point_pos = cpoint;

			_polygon_draw();
		}
	}

	return false;
}
float AudioEffectChorus::get_voice_cutoff_hz(int p_voice) const {

	ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);

	return voice[p_voice].cutoff;
}
Beispiel #3
0
Vector<int> NavigationMesh::get_polygon(int p_idx) {

	ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
	return polygons[p_idx].indices;
}
Beispiel #4
0
int Camera2D::get_limit(Margin p_margin) const{

	ERR_FAIL_INDEX_V(p_margin,4,0);
	return limit[p_margin];

}
float AudioEffectChorus::get_voice_depth_ms(int p_voice) const {

	ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);

	return voice[p_voice].depth;
}
Beispiel #6
0
NodePath EditorData::get_edited_scene_live_edit_root() {

	ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), String());

	return edited_scene[current_edited_scene].live_edit_root;
}
Beispiel #7
0
bool Environment::is_fx_enabled(Fx p_effect) const {

	ERR_FAIL_INDEX_V(p_effect, FX_MAX, false);
	return fx_enabled[p_effect];
}
String VisualScriptBuiltinFunc::get_func_name(BuiltinFunc p_func) {

	ERR_FAIL_INDEX_V(p_func, FUNC_MAX, String());
	return func_name[p_func];
}
bool VisibilityEnabler2D::is_enabler_enabled(Enabler p_enabler) const{

	ERR_FAIL_INDEX_V(p_enabler,ENABLER_MAX,false);
	return enabler[p_enabler];

}
Beispiel #10
0
float Curve3D::get_point_tilt(int p_index) const {

	ERR_FAIL_INDEX_V(p_index,points.size(),0);
	return points[p_index].tilt;

}
Beispiel #11
0
Vector3 Curve3D::get_point_out(int p_index) const {

	ERR_FAIL_INDEX_V(p_index,points.size(),Vector3());
	return points[p_index].out;

}
Beispiel #12
0
Vector2 Curve2D::get_point_in(int p_index) const {

	ERR_FAIL_INDEX_V(p_index,points.size(),Vector2());
	return points[p_index].in;

}
Beispiel #13
0
Ref<ResourceImportMetadata> EditorData::get_edited_scene_import_metadata() const{

	ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),Ref<ResourceImportMetadata>());
	return edited_scene[current_edited_scene].medatata;
}
Beispiel #14
0
Node* EditorData::get_edited_scene_root(){

	ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),NULL);

	return edited_scene[current_edited_scene].root;
}
Beispiel #15
0
uint64_t EditorData::get_edited_scene_version() const {

	ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), 0);
	return edited_scene[current_edited_scene].version;
}
Beispiel #16
0
bool SpriteBase3D::get_draw_flag(DrawFlags p_flag) const{
	ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false);
	return flags[p_flag];
}
Beispiel #17
0
uint64_t EditorData::get_scene_version(int p_idx) const {
	ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), false);
	return edited_scene[p_idx].version;
}
float SoundRoomParams::get_param(Params p_param) const {

    ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
    return params[p_param];
}
Beispiel #19
0
Variant Environment::get_background_param(BGParam p_param) const {

	ERR_FAIL_INDEX_V(p_param, BG_PARAM_MAX, Variant());
	return bg_param[p_param];
}
Beispiel #20
0
ScriptLanguage* ScriptServer::get_language(int p_idx) {

	ERR_FAIL_INDEX_V(p_idx,_language_count,NULL);

	return _languages[p_idx];
}
Beispiel #21
0
Variant Environment::fx_get_param(FxParam p_param) const {

	ERR_FAIL_INDEX_V(p_param, FX_PARAM_MAX, Variant());
	return fx_param[p_param];
}
Beispiel #22
0
bool EditorHistory::is_history_obj_inspector_only(int p_obj) const {

	ERR_FAIL_INDEX_V(p_obj, history.size(), false);
	ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), false);
	return history[p_obj].path[history[p_obj].level].inspector_only;
}
Beispiel #23
0
float Camera2D::get_drag_margin(Margin p_margin) const{

	ERR_FAIL_INDEX_V(p_margin,4,0);
	return drag_margin[p_margin];

}
Beispiel #24
0
ObjectID EditorHistory::get_history_obj(int p_obj) const {
	ERR_FAIL_INDEX_V(p_obj, history.size(), 0);
	ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), 0);
	return history[p_obj].path[history[p_obj].level].object;
}
float AudioEffectChorus::get_voice_level_db(int p_voice) const {

	ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);

	return voice[p_voice].level;
}
Beispiel #26
0
Dictionary EditorData::get_scene_editor_states(int p_idx) const {
	ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), Dictionary());
	EditedScene es = edited_scene[p_idx];
	return es.editor_states;
}
float AudioEffectChorus::get_voice_pan(int p_voice) const {

	ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);

	return voice[p_voice].pan;
}
Beispiel #28
0
EditorPlugin *EditorData::get_editor_plugin(int p_idx) {

	ERR_FAIL_INDEX_V(p_idx, editor_plugins.size(), NULL);
	return editor_plugins[p_idx];
}
Beispiel #29
0
Vector<String> EditorFileSystemDirectory::get_file_deps(int p_idx) const {

	ERR_FAIL_INDEX_V(p_idx, files.size(), Vector<String>());
	return files[p_idx]->deps;
}
Beispiel #30
0
StringName NodePath::get_subname(int p_idx) const {

	ERR_FAIL_COND_V(!data, StringName());
	ERR_FAIL_INDEX_V(p_idx, data->subpath.size(), StringName());
	return data->subpath[p_idx];
}