Path: blob/master/editor/scene/3d/path_3d_editor_plugin.h
21138 views
/**************************************************************************/1/* path_3d_editor_plugin.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "editor/plugins/editor_plugin.h"33#include "editor/scene/3d/node_3d_editor_gizmos.h"34#include "scene/3d/camera_3d.h"35#include "scene/3d/path_3d.h"3637class HBoxContainer;38class MenuButton;39class ConfirmationDialog;4041class Path3DGizmo : public EditorNode3DGizmo {42GDCLASS(Path3DGizmo, EditorNode3DGizmo);4344// Map handle id to control point id and handle type.45enum HandleType {46HANDLE_TYPE_IN,47HANDLE_TYPE_OUT,48HANDLE_TYPE_TILT,49};5051struct HandleInfo {52int point_idx; // Index of control point.53HandleType type; // Type of this handle.54};5556Path3D *path = nullptr;57Ref<StandardMaterial3D> debug_material;58mutable Vector3 original;59mutable float orig_in_length;60mutable float orig_out_length;6162// Index that should have swapped control points for achieving an outwards curve.63int swapped_control_points_idx = -1;64bool control_points_overlapped = false;6566// Cache information of secondary handles.67Vector<HandleInfo> _secondary_handles_info;6869void _update_transform_gizmo();7071public:72virtual String get_handle_name(int p_id, bool p_secondary) const override;73virtual Variant get_handle_value(int p_id, bool p_secondary) const override;74virtual void set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;75virtual void commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;7677virtual void redraw() override;78Path3DGizmo(Path3D *p_path = nullptr);79};8081class Path3DGizmoPlugin : public EditorNode3DGizmoPlugin {82GDCLASS(Path3DGizmoPlugin, EditorNode3DGizmoPlugin);8384// Locking basis is meant to ensure a predictable behavior during translation of the curve points in "local space transform mode".85// Without the locking, the gizmo/point, in "local space transform mode", wouldn't follow a straight path and would curve and twitch in an unpredictable way.86HashMap<int, Basis> transformation_locked_basis;8788protected:89Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial) override;9091public:92virtual bool has_gizmo(Node3D *p_spatial) override;93String get_gizmo_name() const override;9495virtual void redraw(EditorNode3DGizmo *p_gizmo) override;9697virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const override;98virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const override;99virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const override;100virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) override;101virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) override;102103int get_priority() const override;104Path3DGizmoPlugin();105};106107class Path3DEditorPlugin : public EditorPlugin {108GDCLASS(Path3DEditorPlugin, EditorPlugin);109110friend class Path3DGizmo;111friend class Path3DGizmoPlugin;112113Ref<Path3DGizmoPlugin> path_3d_gizmo_plugin;114115HBoxContainer *topmenu_bar = nullptr;116117HBoxContainer *toolbar = nullptr;118Button *curve_create = nullptr;119Button *curve_edit = nullptr;120Button *curve_edit_curve = nullptr;121Button *curve_edit_tilt = nullptr;122Button *curve_del = nullptr;123Button *curve_closed = nullptr;124Button *curve_clear_points = nullptr;125MenuButton *handle_menu = nullptr;126127Button *create_curve_button = nullptr;128ConfirmationDialog *clear_points_dialog = nullptr;129130enum Mode {131MODE_CREATE,132MODE_EDIT,133MODE_EDIT_CURVE,134MODE_EDIT_TILT,135MODE_DELETE,136ACTION_CLOSE137};138139Path3D *path = nullptr;140141void _update_theme();142void _update_toolbar();143144void _mode_changed(int p_mode);145void _toggle_closed_curve();146void _handle_option_pressed(int p_option);147bool handle_clicked = false;148bool mirror_handle_angle = true;149bool mirror_handle_length = true;150bool snap_to_collider = true;151152void _create_curve();153void _confirm_clear_points();154void _clear_points();155void _clear_curve_points();156void _restore_curve_points(const PackedVector3Array &p_points);157158enum HandleOption {159HANDLE_OPTION_ANGLE,160HANDLE_OPTION_LENGTH,161HANDLE_OPTION_SNAP_COLLIDER,162};163164protected:165virtual void _notification(int p_what);166static void _bind_methods();167168public:169Path3D *get_edited_path() { return path; }170171inline static Path3DEditorPlugin *singleton = nullptr;172virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override;173174virtual String get_plugin_name() const override { return "Path3D"; }175bool has_main_screen() const override { return false; }176virtual void edit(Object *p_object) override;177virtual bool handles(Object *p_object) const override;178virtual void make_visible(bool p_visible) override;179180bool mirror_angle_enabled() { return mirror_handle_angle; }181bool mirror_length_enabled() { return mirror_handle_length; }182bool is_handle_clicked() { return handle_clicked; }183void set_handle_clicked(bool clicked) { handle_clicked = clicked; }184185Path3DEditorPlugin();186187private:188struct EditData {189Vector3 click_ray_dir;190Vector3 click_ray_pos;191Vector3 origin;192Point2 mouse_pos;193bool show_rotation_line = false;194Ref<Path3DGizmo> gizmo;195int gizmo_handle = 0;196bool gizmo_handle_secondary = false;197Camera3D *gizmo_camera;198bool waiting_point_physics = false;199bool waiting_handle_physics = false;200bool in_physics_frame = false;201} _edit;202};203204205