1 | /**************************************************************************/ |
2 | /* node_3d_editor_gizmos.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef NODE_3D_EDITOR_GIZMOS_H |
32 | #define NODE_3D_EDITOR_GIZMOS_H |
33 | |
34 | #include "core/templates/hash_map.h" |
35 | #include "core/templates/local_vector.h" |
36 | #include "scene/3d/camera_3d.h" |
37 | #include "scene/3d/node_3d.h" |
38 | #include "scene/3d/skeleton_3d.h" |
39 | |
40 | class Timer; |
41 | class EditorNode3DGizmoPlugin; |
42 | |
43 | class EditorNode3DGizmo : public Node3DGizmo { |
44 | GDCLASS(EditorNode3DGizmo, Node3DGizmo); |
45 | |
46 | struct Instance { |
47 | RID instance; |
48 | Ref<Mesh> mesh; |
49 | Ref<Material> material; |
50 | Ref<SkinReference> skin_reference; |
51 | bool = false; |
52 | Transform3D xform; |
53 | |
54 | void create_instance(Node3D *p_base, bool p_hidden = false); |
55 | }; |
56 | |
57 | bool selected; |
58 | |
59 | Vector<Vector3> collision_segments; |
60 | Ref<TriangleMesh> collision_mesh; |
61 | |
62 | Vector<Vector3> handles; |
63 | Vector<int> handle_ids; |
64 | Vector<Vector3> secondary_handles; |
65 | Vector<int> secondary_handle_ids; |
66 | |
67 | real_t selectable_icon_size; |
68 | bool billboard_handle; |
69 | |
70 | bool valid; |
71 | bool hidden; |
72 | Vector<Instance> instances; |
73 | Node3D *spatial_node = nullptr; |
74 | |
75 | void _set_node_3d(Node *p_node) { set_node_3d(Object::cast_to<Node3D>(p_node)); } |
76 | |
77 | protected: |
78 | static void _bind_methods(); |
79 | |
80 | EditorNode3DGizmoPlugin *gizmo_plugin = nullptr; |
81 | |
82 | GDVIRTUAL0(_redraw) |
83 | GDVIRTUAL2RC(String, _get_handle_name, int, bool) |
84 | GDVIRTUAL2RC(bool, _is_handle_highlighted, int, bool) |
85 | GDVIRTUAL2RC(Variant, _get_handle_value, int, bool) |
86 | GDVIRTUAL2(_begin_handle_action, int, bool) |
87 | GDVIRTUAL4(_set_handle, int, bool, const Camera3D *, Vector2) |
88 | GDVIRTUAL4(_commit_handle, int, bool, Variant, bool) |
89 | |
90 | GDVIRTUAL2RC(int, _subgizmos_intersect_ray, const Camera3D *, Vector2) |
91 | GDVIRTUAL2RC(Vector<int>, _subgizmos_intersect_frustum, const Camera3D *, TypedArray<Plane>) |
92 | GDVIRTUAL1RC(Transform3D, _get_subgizmo_transform, int) |
93 | GDVIRTUAL2(_set_subgizmo_transform, int, Transform3D) |
94 | GDVIRTUAL3(_commit_subgizmos, Vector<int>, TypedArray<Transform3D>, bool) |
95 | public: |
96 | void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); |
97 | void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); |
98 | void add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>()); |
99 | void add_collision_segments(const Vector<Vector3> &p_lines); |
100 | void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); |
101 | void add_unscaled_billboard(const Ref<Material> &p_material, real_t p_scale = 1, const Color &p_modulate = Color(1, 1, 1)); |
102 | void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, const Vector<int> &p_ids = Vector<int>(), bool p_billboard = false, bool p_secondary = false); |
103 | void add_solid_box(const Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3(), const Transform3D &p_xform = Transform3D()); |
104 | |
105 | virtual bool is_handle_highlighted(int p_id, bool p_secondary) const; |
106 | virtual String get_handle_name(int p_id, bool p_secondary) const; |
107 | virtual Variant get_handle_value(int p_id, bool p_secondary) const; |
108 | virtual void begin_handle_action(int p_id, bool p_secondary); |
109 | virtual void set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point); |
110 | virtual void commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false); |
111 | |
112 | virtual int subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const; |
113 | virtual Vector<int> subgizmos_intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) const; |
114 | virtual Transform3D get_subgizmo_transform(int p_id) const; |
115 | virtual void set_subgizmo_transform(int p_id, Transform3D p_transform); |
116 | virtual void commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false); |
117 | |
118 | void set_selected(bool p_selected) { selected = p_selected; } |
119 | bool is_selected() const { return selected; } |
120 | |
121 | void set_node_3d(Node3D *p_node); |
122 | Node3D *get_node_3d() const { return spatial_node; } |
123 | Ref<EditorNode3DGizmoPlugin> get_plugin() const { return gizmo_plugin; } |
124 | bool intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum); |
125 | void handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id, bool &r_secondary); |
126 | bool intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal); |
127 | bool is_subgizmo_selected(int p_id) const; |
128 | Vector<int> get_subgizmo_selection() const; |
129 | |
130 | virtual void clear() override; |
131 | virtual void create() override; |
132 | virtual void transform() override; |
133 | virtual void redraw() override; |
134 | virtual void free() override; |
135 | |
136 | virtual bool is_editable() const; |
137 | |
138 | void set_hidden(bool p_hidden); |
139 | void set_plugin(EditorNode3DGizmoPlugin *p_plugin); |
140 | |
141 | EditorNode3DGizmo(); |
142 | ~EditorNode3DGizmo(); |
143 | }; |
144 | |
145 | class EditorNode3DGizmoPlugin : public Resource { |
146 | GDCLASS(EditorNode3DGizmoPlugin, Resource); |
147 | |
148 | public: |
149 | static const int VISIBLE = 0; |
150 | static const int HIDDEN = 1; |
151 | static const int ON_TOP = 2; |
152 | |
153 | protected: |
154 | int current_state; |
155 | List<EditorNode3DGizmo *> current_gizmos; |
156 | HashMap<String, Vector<Ref<StandardMaterial3D>>> materials; |
157 | |
158 | static void _bind_methods(); |
159 | virtual bool has_gizmo(Node3D *p_spatial); |
160 | virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial); |
161 | |
162 | GDVIRTUAL1RC(bool, _has_gizmo, Node3D *) |
163 | GDVIRTUAL1RC(Ref<EditorNode3DGizmo>, _create_gizmo, Node3D *) |
164 | |
165 | GDVIRTUAL0RC(String, _get_gizmo_name) |
166 | GDVIRTUAL0RC(int, _get_priority) |
167 | GDVIRTUAL0RC(bool, _can_be_hidden) |
168 | GDVIRTUAL0RC(bool, _is_selectable_when_hidden) |
169 | |
170 | GDVIRTUAL1(_redraw, Ref<EditorNode3DGizmo>) |
171 | GDVIRTUAL3RC(String, _get_handle_name, Ref<EditorNode3DGizmo>, int, bool) |
172 | GDVIRTUAL3RC(bool, _is_handle_highlighted, Ref<EditorNode3DGizmo>, int, bool) |
173 | GDVIRTUAL3RC(Variant, _get_handle_value, Ref<EditorNode3DGizmo>, int, bool) |
174 | |
175 | GDVIRTUAL3(_begin_handle_action, Ref<EditorNode3DGizmo>, int, bool) |
176 | GDVIRTUAL5(_set_handle, Ref<EditorNode3DGizmo>, int, bool, const Camera3D *, Vector2) |
177 | GDVIRTUAL5(_commit_handle, Ref<EditorNode3DGizmo>, int, bool, Variant, bool) |
178 | |
179 | GDVIRTUAL3RC(int, _subgizmos_intersect_ray, Ref<EditorNode3DGizmo>, const Camera3D *, Vector2) |
180 | GDVIRTUAL3RC(Vector<int>, _subgizmos_intersect_frustum, Ref<EditorNode3DGizmo>, const Camera3D *, TypedArray<Plane>) |
181 | GDVIRTUAL2RC(Transform3D, _get_subgizmo_transform, Ref<EditorNode3DGizmo>, int) |
182 | GDVIRTUAL3(_set_subgizmo_transform, Ref<EditorNode3DGizmo>, int, Transform3D) |
183 | GDVIRTUAL4(_commit_subgizmos, Ref<EditorNode3DGizmo>, Vector<int>, TypedArray<Transform3D>, bool) |
184 | |
185 | public: |
186 | void create_material(const String &p_name, const Color &p_color, bool p_billboard = false, bool p_on_top = false, bool p_use_vertex_color = false); |
187 | void create_icon_material(const String &p_name, const Ref<Texture2D> &p_texture, bool p_on_top = false, const Color &p_albedo = Color(1, 1, 1, 1)); |
188 | void create_handle_material(const String &p_name, bool p_billboard = false, const Ref<Texture2D> &p_texture = nullptr); |
189 | void add_material(const String &p_name, Ref<StandardMaterial3D> p_material); |
190 | |
191 | Ref<StandardMaterial3D> get_material(const String &p_name, const Ref<EditorNode3DGizmo> &p_gizmo = Ref<EditorNode3DGizmo>()); |
192 | |
193 | virtual String get_gizmo_name() const; |
194 | virtual int get_priority() const; |
195 | virtual bool can_be_hidden() const; |
196 | virtual bool is_selectable_when_hidden() const; |
197 | |
198 | virtual void redraw(EditorNode3DGizmo *p_gizmo); |
199 | virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const; |
200 | virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const; |
201 | virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const; |
202 | virtual void begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary); |
203 | virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point); |
204 | virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false); |
205 | |
206 | virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const; |
207 | virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const; |
208 | virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const; |
209 | virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform); |
210 | virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false); |
211 | |
212 | Ref<EditorNode3DGizmo> get_gizmo(Node3D *p_spatial); |
213 | void set_state(int p_state); |
214 | int get_state() const; |
215 | void unregister_gizmo(EditorNode3DGizmo *p_gizmo); |
216 | |
217 | EditorNode3DGizmoPlugin(); |
218 | virtual ~EditorNode3DGizmoPlugin(); |
219 | }; |
220 | |
221 | #endif // NODE_3D_EDITOR_GIZMOS_H |
222 | |