Node3D gizmo improvements

* Clean-up of node_3d_editor_plugin.{h,cpp}: removed unused code, fixed some bugs.
* Moved node_3d_editor_gizmos.{h,cpp} to editor/plugins.
* Added support for multiple gizmos per node. This means custom gizmos will no longer override the built-in ones and that multiple gizmos can be used in more complex nodes.
* Added support for handle IDs. When adding handles to a gizmo, an ID can be specified for each one, making it easier to work with gizmos that have a variable number of handles.
* Added support for subgizmos, selectable elements that can be transformed without needing a node of their own. By overriding _subgizmo_intersect_frustum() and/or _subgizmo_intersect_ray() gizmos can define which subgizmos should be selected on a region or click selection. Subgizmo transformations are applied using get/set/commit virtual methods, similar to how handles work.
This commit is contained in:
jfons 2021-06-23 16:49:50 +02:00
parent 88bf6e1c6d
commit cfb555a081
41 changed files with 2039 additions and 1405 deletions

View file

@ -32,9 +32,9 @@
#include "core/templates/sort_array.h"
int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) {
if (p_depth > max_depth) {
max_depth = p_depth;
int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc) {
if (p_depth > r_max_depth) {
r_max_depth = p_depth;
}
if (p_size == 1) {
@ -70,10 +70,10 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in
} break;
}
int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, max_depth, max_alloc);
int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, max_depth, max_alloc);
int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, r_max_depth, r_max_alloc);
int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, r_max_depth, r_max_alloc);
int index = max_alloc++;
int index = r_max_alloc++;
BVH *_new = &p_bvh[index];
_new->aabb = aabb;
_new->center = aabb.position + aabb.size * 0.5;

View file

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorNode3DGizmo" inherits="Node3DGizmo" version="4.0">
<brief_description>
Custom gizmo for editing Node3D objects.
Gizmo for editing Node3D objects.
</brief_description>
<description>
Custom gizmo that is used for providing custom visualization and editing (handles) for Node3D objects. See [EditorNode3DGizmoPlugin] for more information.
Gizmo that is used for providing custom visualization and editing (handles and subgizmos) for Node3D objects. Can be overridden to create custom gizmos, but for simple gizmos creating a [EditorNode3DGizmoPlugin] is usually recommended.
</description>
<tutorials>
</tutorials>
@ -12,64 +12,119 @@
<method name="_commit_handle" qualifiers="virtual">
<return type="void">
</return>
<argument index="0" name="index" type="int">
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="restore" type="Variant">
</argument>
<argument index="2" name="cancel" type="bool" default="false">
</argument>
<description>
Commit a handle being edited (handles must have been previously added by [method add_handles]).
If the [code]cancel[/code] parameter is [code]true[/code], an option to restore the edited value to the original is provided.
Override this method to commit a handle being edited (handles must have been previously added by [method add_handles]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action.
</description>
</method>
<method name="_commit_subgizmos" qualifiers="virtual">
<return type="void">
</return>
<argument index="0" name="ids" type="PackedInt32Array">
</argument>
<argument index="1" name="restore" type="Array">
</argument>
<argument index="2" name="cancel" type="bool" default="false">
</argument>
<description>
Override this method to commit a group of subgizmos being edited (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). This usually means creating an [UndoRedo] action for the change, using the current transforms as "do" and the [code]restore[/code] transforms as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] transforms should be directly set, without any [UndoRedo] action.
</description>
</method>
<method name="_get_handle_name" qualifiers="virtual">
<return type="String">
</return>
<argument index="0" name="index" type="int">
<argument index="0" name="id" type="int">
</argument>
<description>
Gets the name of an edited handle (handles must have been previously added by [method add_handles]).
Override this method to return the name of an edited handle (handles must have been previously added by [method add_handles]).
Handles can be named for reference to the user when editing.
</description>
</method>
<method name="_get_handle_value" qualifiers="virtual">
<return type="Variant">
</return>
<argument index="0" name="index" type="int">
<argument index="0" name="id" type="int">
</argument>
<description>
Gets actual value of a handle. This value can be anything and used for eventually undoing the motion when calling [method _commit_handle].
Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle].
</description>
</method>
<method name="_get_subgizmo_transform" qualifiers="virtual">
<return type="Transform3D">
</return>
<argument index="0" name="id" type="int">
</argument>
<description>
Override this method to return the current transform of a subgizmo. This transform will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_subgizmos].
</description>
</method>
<method name="_is_handle_highlighted" qualifiers="virtual">
<return type="bool">
</return>
<argument index="0" name="index" type="int">
<argument index="0" name="id" type="int">
</argument>
<description>
Returns [code]true[/code] if the handle at index [code]index[/code] is highlighted by being hovered with the mouse.
Override this method to return [code]true[/code] whenever the given handle should be highlighted in the editor.
</description>
</method>
<method name="_redraw" qualifiers="virtual">
<return type="void">
</return>
<description>
This function is called when the [Node3D] this gizmo refers to changes (the [method Node3D.update_gizmo] is called).
Override this method to add all the gizmo elements whenever a gizmo update is requested. It's common to call [method clear] at the beginning of this method and then add visual elements depending on the node's properties.
</description>
</method>
<method name="_set_handle" qualifiers="virtual">
<return type="void">
</return>
<argument index="0" name="index" type="int">
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="camera" type="Camera3D">
</argument>
<argument index="2" name="point" type="Vector2">
</argument>
<description>
This function is used when the user drags a gizmo handle (previously added with [method add_handles]) in screen coordinates.
The [Camera3D] is also provided so screen coordinates can be converted to raycasts.
Override this method to update the node properties when the user drags a gizmo handle (previously added with [method add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts.
</description>
</method>
<method name="_set_subgizmo_transform" qualifiers="virtual">
<return type="void">
</return>
<argument index="0" name="id" type="int">
</argument>
<argument index="1" name="transform" type="Transform3D">
</argument>
<description>
Override this method to update the node properties during subgizmo editing (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). The [code]transform[/code] is given in the Node3D's local coordinate system.
</description>
</method>
<method name="_subgizmos_intersect_frustum" qualifiers="virtual">
<return type="PackedInt32Array">
</return>
<argument index="0" name="camera" type="Camera3D">
</argument>
<argument index="1" name="frustum" type="Array">
</argument>
<description>
Override this method to allow selecting subgizmos using mouse drag box selection. Given a [code]camera[/code] and a [code]frustum[/code], this method should return which subgizmos are contained within the frustum. The [code]frustum[/code] argument consists of an [code]Array[/code] with all the [code]Plane[/code]s that make up the selection frustum. The returned value should contain a list of unique subgizmo identifiers, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos].
</description>
</method>
<method name="_subgizmos_intersect_ray" qualifiers="virtual">
<return type="int">
</return>
<argument index="0" name="camera" type="Camera3D">
</argument>
<argument index="1" name="point" type="Vector2">
</argument>
<description>
Override this method to allow selecting subgizmos using mouse clicks. Given a [code]camera[/code] and a [code]point[/code] in screen coordinates, this method should return which subgizmo should be selected. The returned value should be a unique subgizmo identifier, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos].
</description>
</method>
<method name="add_collision_segments">
@ -78,7 +133,7 @@
<argument index="0" name="segments" type="PackedVector3Array">
</argument>
<description>
Adds the specified [code]segments[/code] to the gizmo's collision shape for picking. Call this function during [method _redraw].
Adds the specified [code]segments[/code] to the gizmo's collision shape for picking. Call this method during [method _redraw].
</description>
</method>
<method name="add_collision_triangles">
@ -87,7 +142,7 @@
<argument index="0" name="triangles" type="TriangleMesh">
</argument>
<description>
Adds collision triangles to the gizmo for picking. A [TriangleMesh] can be generated from a regular [Mesh] too. Call this function during [method _redraw].
Adds collision triangles to the gizmo for picking. A [TriangleMesh] can be generated from a regular [Mesh] too. Call this method during [method _redraw].
</description>
</method>
<method name="add_handles">
@ -97,13 +152,15 @@
</argument>
<argument index="1" name="material" type="Material">
</argument>
<argument index="2" name="billboard" type="bool" default="false">
<argument index="2" name="ids" type="PackedInt32Array">
</argument>
<argument index="3" name="secondary" type="bool" default="false">
<argument index="3" name="billboard" type="bool" default="false">
</argument>
<argument index="4" name="secondary" type="bool" default="false">
</argument>
<description>
Adds a list of handles (points) which can be used to deform the object being edited.
There are virtual functions which will be called upon editing of these handles. Call this function during [method _redraw].
Adds a list of handles (points) which can be used to edit the properties of the gizmo's Node3D. The [code]ids[/code] argument can be used to specify a custom identifier for each handle, if an empty [code]Array[/code] is passed, the ids will be assigned automatically from the [code]handles[/code] argument order.
There are virtual methods which will be called upon editing of these handles. Call this method during [method _redraw].
</description>
</method>
<method name="add_lines">
@ -118,7 +175,7 @@
<argument index="3" name="modulate" type="Color" default="Color(1, 1, 1, 1)">
</argument>
<description>
Adds lines to the gizmo (as sets of 2 points), with a given material. The lines are used for visualizing the gizmo. Call this function during [method _redraw].
Adds lines to the gizmo (as sets of 2 points), with a given material. The lines are used for visualizing the gizmo. Call this method during [method _redraw].
</description>
</method>
<method name="add_mesh">
@ -126,14 +183,14 @@
</return>
<argument index="0" name="mesh" type="ArrayMesh">
</argument>
<argument index="1" name="billboard" type="bool" default="false">
<argument index="1" name="material" type="Material" default="null">
</argument>
<argument index="2" name="skeleton" type="SkinReference" default="null">
<argument index="2" name="transform" type="Transform3D" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)">
</argument>
<argument index="3" name="material" type="Material" default="null">
<argument index="3" name="skeleton" type="SkinReference" default="null">
</argument>
<description>
Adds a mesh to the gizmo with the specified [code]billboard[/code] state, [code]skeleton[/code] and [code]material[/code]. If [code]billboard[/code] is [code]true[/code], the mesh will rotate to always face the camera. Call this function during [method _redraw].
Adds a mesh to the gizmo with the specified [code]material[/code], local [code]transform[/code] and [code]skeleton[/code]. Call this method during [method _redraw].
</description>
</method>
<method name="add_unscaled_billboard">
@ -146,7 +203,7 @@
<argument index="2" name="modulate" type="Color" default="Color(1, 1, 1, 1)">
</argument>
<description>
Adds an unscaled billboard for visualization. Call this function during [method _redraw].
Adds an unscaled billboard for visualization and selection. Call this method during [method _redraw].
</description>
</method>
<method name="clear">
@ -170,6 +227,22 @@
Returns the Node3D node associated with this gizmo.
</description>
</method>
<method name="get_subgizmo_selection" qualifiers="const">
<return type="PackedInt32Array">
</return>
<description>
Returns a list of the currently selected subgizmos. Can be used to highlight selected elements during [method _redraw].
</description>
</method>
<method name="is_subgizmo_selected" qualifiers="const">
<return type="bool">
</return>
<argument index="0" name="arg0" type="int">
</argument>
<description>
Returns [code]true[/code] if the given subgizmo is currently selected. Can be used to highlight selected elements during [method _redraw].
</description>
</method>
<method name="set_hidden">
<return type="void">
</return>

View file

@ -14,7 +14,7 @@
<return type="bool">
</return>
<description>
Override this method to define whether the gizmo can be hidden or not. Returns [code]true[/code] if not overridden.
Override this method to define whether the gizmos handled by this plugin can be hidden or not. Returns [code]true[/code] if not overridden.
</description>
</method>
<method name="_commit_handle" qualifiers="virtual">
@ -22,14 +22,31 @@
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="index" type="int">
<argument index="1" name="id" type="int">
</argument>
<argument index="2" name="restore" type="Variant">
</argument>
<argument index="3" name="cancel" type="bool" default="false">
</argument>
<description>
Override this method to commit gizmo handles. Called for this plugin's active gizmos.
Override this method to commit a handle being edited (handles must have been previously added by [method EditorNode3DGizmo.add_handles] during [method _redraw]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action. Called for this plugin's active gizmos.
</description>
</method>
<method name="_commit_subgizmos" qualifiers="virtual">
<return type="void">
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="ids" type="PackedInt32Array">
</argument>
<argument index="2" name="restore" type="Array">
</argument>
<argument index="3" name="cancel" type="bool" default="false">
</argument>
<description>
Override this method to commit a group of subgizmos being edited (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). This usually means creating an [UndoRedo] action for the change, using the current transforms as "do" and the [code]restore[/code] transforms as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] transforms should be directly set, without any [UndoRedo] action. Called for this plugin's active gizmos.
</description>
</method>
<method name="_create_gizmo" qualifiers="virtual">
@ -53,7 +70,7 @@
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="index" type="int">
<argument index="1" name="id" type="int">
</argument>
<description>
Override this method to provide gizmo's handle names. Called for this plugin's active gizmos.
@ -64,18 +81,29 @@
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="index" type="int">
<argument index="1" name="id" type="int">
</argument>
<description>
Gets actual value of a handle from gizmo. Called for this plugin's active gizmos.
Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle]. Called for this plugin's active gizmos.
</description>
</method>
<method name="_get_priority" qualifiers="virtual">
<return type="int">
</return>
<description>
Override this method to set the gizmo's priority. Higher values correspond to higher priority. If a gizmo with higher priority conflicts with another gizmo, only the gizmo with higher priority will be used.
All built-in editor gizmos return a priority of [code]-1[/code]. If not overridden, this method will return [code]0[/code], which means custom gizmos will automatically override built-in gizmos.
Override this method to set the gizmo's priority. Gizmos with higher priority will have precedence when processing inputs like handles or subgizmos selection.
All built-in editor gizmos return a priority of [code]-1[/code]. If not overridden, this method will return [code]0[/code], which means custom gizmos will automatically get higher priority than built-in gizmos.
</description>
</method>
<method name="_get_subgizmo_transform" qualifiers="virtual">
<return type="Transform3D">
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="id" type="int">
</argument>
<description>
Override this method to return the current transform of a subgizmo. This transform will be requested at the start of an edit and used in the [code]restore[/code] argument in [method _commit_subgizmos]. Called for this plugin's active gizmos.
</description>
</method>
<method name="_has_gizmo" qualifiers="virtual">
@ -92,10 +120,10 @@
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="index" type="int">
<argument index="1" name="id" type="int">
</argument>
<description>
Gets whether a handle is highlighted or not. Called for this plugin's active gizmos.
Override this method to return [code]true[/code] whenever to given handle should be highlighted in the editor. Called for this plugin's active gizmos.
</description>
</method>
<method name="_is_selectable_when_hidden" qualifiers="virtual">
@ -111,7 +139,7 @@
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<description>
Callback to redraw the provided gizmo. Called for this plugin's active gizmos.
Override this method to add all the gizmo elements whenever a gizmo update is requested. It's common to call [method EditorNode3DGizmo.clear] at the beginning of this method and then add visual elements depending on the node's properties.
</description>
</method>
<method name="_set_handle" qualifiers="virtual">
@ -119,14 +147,53 @@
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="index" type="int">
<argument index="1" name="id" type="int">
</argument>
<argument index="2" name="camera" type="Camera3D">
</argument>
<argument index="3" name="point" type="Vector2">
</argument>
<description>
Update the value of a handle after it has been updated. Called for this plugin's active gizmos.
Override this method to update the node's properties when the user drags a gizmo handle (previously added with [method EditorNode3DGizmo.add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts. Called for this plugin's active gizmos.
</description>
</method>
<method name="_set_subgizmo_transform" qualifiers="virtual">
<return type="void">
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="id" type="int">
</argument>
<argument index="2" name="transform" type="Transform3D">
</argument>
<description>
Override this method to update the node properties during subgizmo editing (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). The [code]transform[/code] is given in the Node3D's local coordinate system. Called for this plugin's active gizmos.
</description>
</method>
<method name="_subgizmos_intersect_frustum" qualifiers="virtual">
<return type="PackedInt32Array">
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="camera" type="Camera3D">
</argument>
<argument index="2" name="frustum" type="Array">
</argument>
<description>
Override this method to allow selecting subgizmos using mouse drag box selection. Given a [code]camera[/code] and a [code]frustum[/code], this method should return which subgizmos are contained within the frustum. The [code]frustum[/code] argument consists of an [code]Array[/code] with all the [code]Plane[/code]s that make up the selection frustum. The returned value should contain a list of unique subgizmo identifiers, these identifiers can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos]. Called for this plugin's active gizmos.
</description>
</method>
<method name="_subgizmos_intersect_ray" qualifiers="virtual">
<return type="int">
</return>
<argument index="0" name="gizmo" type="EditorNode3DGizmo">
</argument>
<argument index="1" name="camera" type="Camera3D">
</argument>
<argument index="2" name="point" type="Vector2">
</argument>
<description>
Override this method to allow selecting subgizmos using mouse clicks. Given a [code]camera[/code] and a [code]point[/code] in screen coordinates, this method should return which subgizmo should be selected. The returned value should be a unique subgizmo identifier, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos]. Called for this plugin's active gizmos.
</description>
</method>
<method name="add_material">

View file

@ -13,6 +13,29 @@
<link title="All 3D Demos">https://github.com/godotengine/godot-demo-projects/tree/master/3d</link>
</tutorials>
<methods>
<method name="add_gizmo">
<return type="void">
</return>
<argument index="0" name="gizmo" type="Node3DGizmo">
</argument>
<description>
Attach a gizmo to this [code]Node3D[/code].
</description>
</method>
<method name="clear_gizmos">
<return type="void">
</return>
<description>
Clear all gizmos attached to this [code]Node3D[/code].
</description>
</method>
<method name="clear_subgizmo_selection">
<return type="void">
</return>
<description>
Clears subgizmo selection for this node in the editor. Useful when subgizmo IDs become invalid after a property change.
</description>
</method>
<method name="force_update_transform">
<return type="void">
</return>
@ -20,6 +43,13 @@
Forces the transform to update. Transform changes in physics are not instant for performance reasons. Transforms are accumulated and then set. Use this if you need an up-to-date transform when doing physics operations.
</description>
</method>
<method name="get_gizmos" qualifiers="const">
<return type="Array">
</return>
<description>
Returns all the gizmos attached to this [code]Node3D[/code].
</description>
</method>
<method name="get_parent_node_3d" qualifiers="const">
<return type="Node3D">
</return>
@ -276,18 +306,15 @@
Changes the node's position by the given offset [Vector3] in local space.
</description>
</method>
<method name="update_gizmo">
<method name="update_gizmos">
<return type="void">
</return>
<description>
Updates the [Node3DGizmo] of this node.
Updates all the [Node3DGizmo]s attached to this node.
</description>
</method>
</methods>
<members>
<member name="gizmo" type="Node3DGizmo" setter="set_gizmo" getter="get_gizmo">
The [Node3DGizmo] for this node. Used for example in [EditorNode3DGizmo] as custom visualization and editing handles in Editor.
</member>
<member name="global_transform" type="Transform3D" setter="set_global_transform" getter="get_global_transform">
World3D space (global) [Transform3D] of this node.
</member>
@ -324,7 +351,7 @@
<constants>
<constant name="NOTIFICATION_TRANSFORM_CHANGED" value="2000">
Node3D nodes receives this notification when their global transform changes. This means that either the current or a parent node changed its transform.
In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_transform]. The notification is also sent if the node is in the editor context and it has a valid gizmo.
In order for [constant NOTIFICATION_TRANSFORM_CHANGED] to work, users first need to ask for it, with [method set_notify_transform]. The notification is also sent if the node is in the editor context and it has at least one valid gizmo.
</constant>
<constant name="NOTIFICATION_ENTER_WORLD" value="41">
Node3D nodes receives this notification when they are registered to new [World3D] resource.

View file

@ -28,13 +28,156 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef SPATIAL_EDITOR_GIZMOS_H
#define SPATIAL_EDITOR_GIZMOS_H
#ifndef NODE_3D_EDITOR_GIZMOS_H
#define NODE_3D_EDITOR_GIZMOS_H
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
#include "core/templates/ordered_hash_map.h"
#include "scene/3d/node_3d.h"
#include "scene/3d/skeleton_3d.h"
class Camera3D;
class Timer;
class EditorNode3DGizmoPlugin;
class EditorNode3DGizmo : public Node3DGizmo {
GDCLASS(EditorNode3DGizmo, Node3DGizmo);
struct Instance {
RID instance;
Ref<ArrayMesh> mesh;
Ref<Material> material;
Ref<SkinReference> skin_reference;
bool extra_margin = false;
Transform3D xform;
void create_instance(Node3D *p_base, bool p_hidden = false);
};
bool selected;
Vector<Vector3> collision_segments;
Ref<TriangleMesh> collision_mesh;
Vector<Vector3> handles;
Vector<int> handle_ids;
Vector<Vector3> secondary_handles;
Vector<int> secondary_handle_ids;
float selectable_icon_size;
bool billboard_handle;
bool valid;
bool hidden;
Vector<Instance> instances;
Node3D *spatial_node;
void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to<Node3D>(p_node)); }
protected:
static void _bind_methods();
EditorNode3DGizmoPlugin *gizmo_plugin;
public:
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));
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));
void add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1, const Color &p_modulate = Color(1, 1, 1));
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);
void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3(), const Transform3D &p_xform = Transform3D());
virtual bool is_handle_highlighted(int p_id) const;
virtual String get_handle_name(int p_id) const;
virtual Variant get_handle_value(int p_id) const;
virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const;
virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) const;
virtual int subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const;
virtual Vector<int> subgizmos_intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) const;
virtual Transform3D get_subgizmo_transform(int p_id) const;
virtual void set_subgizmo_transform(int p_id, Transform3D p_transform) const;
virtual void commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) const;
void set_selected(bool p_selected) { selected = p_selected; }
bool is_selected() const { return selected; }
void set_spatial_node(Node3D *p_node);
Node3D *get_spatial_node() const { return spatial_node; }
Ref<EditorNode3DGizmoPlugin> get_plugin() const { return gizmo_plugin; }
bool intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum);
void handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id);
bool intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal);
bool is_subgizmo_selected(int p_id) const;
Vector<int> get_subgizmo_selection() const;
virtual void clear() override;
virtual void create() override;
virtual void transform() override;
virtual void redraw() override;
virtual void free() override;
virtual bool is_editable() const;
void set_hidden(bool p_hidden);
void set_plugin(EditorNode3DGizmoPlugin *p_plugin);
EditorNode3DGizmo();
~EditorNode3DGizmo();
};
class EditorNode3DGizmoPlugin : public Resource {
GDCLASS(EditorNode3DGizmoPlugin, Resource);
public:
static const int VISIBLE = 0;
static const int HIDDEN = 1;
static const int ON_TOP = 2;
protected:
int current_state;
List<EditorNode3DGizmo *> current_gizmos;
HashMap<String, Vector<Ref<StandardMaterial3D>>> materials;
static void _bind_methods();
virtual bool has_gizmo(Node3D *p_spatial);
virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial);
public:
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);
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));
void create_handle_material(const String &p_name, bool p_billboard = false, const Ref<Texture2D> &p_texture = nullptr);
void add_material(const String &p_name, Ref<StandardMaterial3D> p_material);
Ref<StandardMaterial3D> get_material(const String &p_name, const Ref<EditorNode3DGizmo> &p_gizmo = Ref<EditorNode3DGizmo>());
virtual String get_gizmo_name() const;
virtual int get_priority() const;
virtual bool can_be_hidden() const;
virtual bool is_selectable_when_hidden() const;
virtual void redraw(EditorNode3DGizmo *p_gizmo);
virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const;
virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const;
virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const;
virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const;
virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const;
virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const;
virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const;
virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const;
virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) const;
virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) const;
Ref<EditorNode3DGizmo> get_gizmo(Node3D *p_spatial);
void set_state(int p_state);
int get_state() const;
void unregister_gizmo(EditorNode3DGizmo *p_gizmo);
EditorNode3DGizmoPlugin();
virtual ~EditorNode3DGizmoPlugin();
};
class Light3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(Light3DGizmoPlugin, EditorNode3DGizmoPlugin);
@ -44,10 +187,10 @@ public:
String get_gizmo_name() const override;
int get_priority() const override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
Light3DGizmoPlugin();
@ -61,10 +204,10 @@ public:
String get_gizmo_name() const override;
int get_priority() const override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
AudioStreamPlayer3DGizmoPlugin();
@ -78,10 +221,10 @@ public:
String get_gizmo_name() const override;
int get_priority() const override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
Camera3DGizmoPlugin();
@ -210,10 +353,10 @@ public:
bool is_selectable_when_hidden() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) override;
bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int idx) const override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
SoftBody3DGizmoPlugin();
};
@ -227,10 +370,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
VisibleOnScreenNotifier3DGizmoPlugin();
};
@ -257,10 +400,10 @@ public:
bool is_selectable_when_hidden() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
GPUParticles3DGizmoPlugin();
};
@ -274,10 +417,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
GPUParticlesCollision3DGizmoPlugin();
};
@ -291,10 +434,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
ReflectionProbeGizmoPlugin();
};
@ -308,10 +451,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
DecalGizmoPlugin();
};
@ -325,10 +468,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
VoxelGIGizmoPlugin();
};
@ -342,10 +485,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
LightmapGIGizmoPlugin();
};
@ -359,10 +502,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
LightmapProbeGizmoPlugin();
};
@ -388,10 +531,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
CollisionShape3DGizmoPlugin();
};
@ -489,4 +632,4 @@ public:
Joint3DGizmoPlugin();
};
#endif // SPATIAL_EDITOR_GIZMOS_H
#endif // NODE_3D_EDITOR_GIZMOS_H

File diff suppressed because it is too large Load diff

View file

@ -34,6 +34,7 @@
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "editor/editor_scale.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
#include "scene/3d/light_3d.h"
#include "scene/3d/visual_instance_3d.h"
#include "scene/3d/world_environment.h"
@ -43,96 +44,10 @@
class Camera3D;
class Node3DEditor;
class EditorNode3DGizmoPlugin;
class Node3DEditorViewport;
class SubViewportContainer;
class EditorNode3DGizmo : public Node3DGizmo {
GDCLASS(EditorNode3DGizmo, Node3DGizmo);
bool selected;
bool instantiated;
public:
void set_selected(bool p_selected) { selected = p_selected; }
bool is_selected() const { return selected; }
struct Instance {
RID instance;
Ref<ArrayMesh> mesh;
Ref<Material> material;
Ref<SkinReference> skin_reference;
RID skeleton;
bool billboard = false;
bool unscaled = false;
bool can_intersect = false;
bool extra_margin = false;
void create_instance(Node3D *p_base, bool p_hidden = false);
};
Vector<Vector3> collision_segments;
Ref<TriangleMesh> collision_mesh;
struct Handle {
Vector3 pos;
bool billboard = false;
};
Vector<Vector3> handles;
Vector<Vector3> secondary_handles;
float selectable_icon_size;
bool billboard_handle;
bool valid;
bool hidden;
Node3D *base;
Vector<Instance> instances;
Node3D *spatial_node;
EditorNode3DGizmoPlugin *gizmo_plugin;
void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to<Node3D>(p_node)); }
protected:
static void _bind_methods();
public:
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));
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));
void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>(), const Ref<Material> &p_material = Ref<Material>());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1, const Color &p_modulate = Color(1, 1, 1));
void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard = false, bool p_secondary = false);
void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3());
virtual bool is_handle_highlighted(int p_idx) const;
virtual String get_handle_name(int p_idx) const;
virtual Variant get_handle_value(int p_idx);
virtual void set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point);
virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
void set_spatial_node(Node3D *p_node);
Node3D *get_spatial_node() const { return spatial_node; }
Ref<EditorNode3DGizmoPlugin> get_plugin() const { return gizmo_plugin; }
Vector3 get_handle_pos(int p_idx) const;
bool intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum);
bool intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = nullptr, bool p_sec_first = false);
virtual void clear() override;
virtual void create() override;
virtual void transform() override;
virtual void redraw() override;
virtual void free() override;
virtual bool is_editable() const;
void set_hidden(bool p_hidden);
void set_plugin(EditorNode3DGizmoPlugin *p_plugin);
EditorNode3DGizmo();
~EditorNode3DGizmo();
};
class DirectionalLight3D;
class WorldEnvironment;
class ViewportRotationControl : public Control {
GDCLASS(ViewportRotationControl, Control);
@ -307,17 +222,15 @@ private:
struct _RayResult {
Node3D *item = nullptr;
float depth = 0;
int handle = 0;
_FORCE_INLINE_ bool operator<(const _RayResult &p_rr) const { return depth < p_rr.depth; }
};
void _update_name();
void _compute_edit(const Point2 &p_point);
void _clear_selected();
void _select_clicked(bool p_append, bool p_single, bool p_allow_locked = false);
void _select(Node *p_node, bool p_append, bool p_single);
ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = nullptr, bool p_alt_select = false);
void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false, bool p_include_locked_nodes = false);
void _select_clicked(bool p_allow_locked);
ObjectID _select_ray(const Point2 &p_pos);
void _find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked);
Vector3 _get_ray_pos(const Vector2 &p_pos) const;
Vector3 _get_ray(const Vector2 &p_pos) const;
Point2 _point_to_screen(const Vector3 &p_point);
@ -329,7 +242,8 @@ private:
Vector3 _get_screen_to_space(const Vector3 &p_vector3);
void _select_region();
bool _gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only = false);
bool _transform_gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only = false);
void _transform_gizmo_apply(Node3D *p_node, const Transform3D &p_transform, bool p_local);
void _nav_pan(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
void _nav_zoom(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative);
@ -342,7 +256,6 @@ private:
ObjectID clicked;
Vector<_RayResult> selection_results;
bool clicked_includes_current;
bool clicked_wants_append;
PopupMenu *selection_menu;
@ -383,15 +296,12 @@ private:
Vector3 click_ray;
Vector3 click_ray_pos;
Vector3 center;
Vector3 orig_gizmo_pos;
int edited_gizmo = 0;
Point2 mouse_pos;
Point2 original_mouse_pos;
bool snap = false;
Ref<EditorNode3DGizmo> gizmo;
int gizmo_handle = 0;
Variant gizmo_initial_value;
Vector3 gizmo_initial_pos;
} _edit;
struct Cursor {
@ -472,6 +382,8 @@ private:
void _project_settings_changed();
Transform3D _compute_transform(TransformMode p_mode, const Transform3D &p_original, const Transform3D &p_original_local, Vector3 p_motion, double p_extra, bool p_local);
protected:
void _notification(int p_what);
static void _bind_methods();
@ -512,6 +424,8 @@ public:
Node3D *sp;
RID sbox_instance;
RID sbox_instance_xray;
Ref<EditorNode3DGizmo> gizmo;
Map<int, Transform3D> subgizmos; // map ID -> initial transform
Node3DEditorSelectedItem() {
sp = nullptr;
@ -617,7 +531,9 @@ private:
Ref<StandardMaterial3D> plane_gizmo_color_hl[3];
Ref<ShaderMaterial> rotate_gizmo_color_hl[3];
int over_gizmo_handle;
Ref<Node3DGizmo> current_hover_gizmo;
int current_hover_gizmo_handle;
float snap_translate_value;
float snap_rotate_value;
float snap_scale_value;
@ -688,7 +604,6 @@ private:
LineEdit *snap_translate;
LineEdit *snap_rotate;
LineEdit *snap_scale;
PanelContainer *menu_panel;
LineEdit *xform_translate[3];
LineEdit *xform_rotate[3];
@ -734,6 +649,7 @@ private:
Node3D *selected;
void _request_gizmo(Object *p_obj);
void _clear_subgizmo_selection(Object *p_obj = nullptr);
static Node3DEditor *singleton;
@ -746,8 +662,7 @@ private:
Node3DEditor();
bool is_any_freelook_active() const;
void _selection_changed();
void _refresh_menu_icons();
// Preview Sun and Environment
@ -861,10 +776,16 @@ public:
VSplitContainer *get_shader_split();
HSplitContainer *get_palette_split();
Node3D *get_selected() { return selected; }
Node3D *get_single_selected_node() { return selected; }
bool is_current_selected_gizmo(const EditorNode3DGizmo *p_gizmo);
bool is_subgizmo_selected(int p_id);
Vector<int> get_subgizmo_selection();
int get_over_gizmo_handle() const { return over_gizmo_handle; }
void set_over_gizmo_handle(int idx) { over_gizmo_handle = idx; }
Ref<EditorNode3DGizmo> get_current_hover_gizmo() const { return current_hover_gizmo; }
void set_current_hover_gizmo(Ref<EditorNode3DGizmo> p_gizmo) { current_hover_gizmo = p_gizmo; }
void set_current_hover_gizmo_handle(int p_id) { current_hover_gizmo_handle = p_id; }
int get_current_hover_gizmo_handle() const { return current_hover_gizmo_handle; }
void set_can_preview(Camera3D *p_preview);
@ -907,50 +828,4 @@ public:
~Node3DEditorPlugin();
};
class EditorNode3DGizmoPlugin : public Resource {
GDCLASS(EditorNode3DGizmoPlugin, Resource);
public:
static const int VISIBLE = 0;
static const int HIDDEN = 1;
static const int ON_TOP = 2;
protected:
int current_state;
List<EditorNode3DGizmo *> current_gizmos;
HashMap<String, Vector<Ref<StandardMaterial3D>>> materials;
static void _bind_methods();
virtual bool has_gizmo(Node3D *p_spatial);
virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial);
public:
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);
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));
void create_handle_material(const String &p_name, bool p_billboard = false, const Ref<Texture2D> &p_texture = nullptr);
void add_material(const String &p_name, Ref<StandardMaterial3D> p_material);
Ref<StandardMaterial3D> get_material(const String &p_name, const Ref<EditorNode3DGizmo> &p_gizmo = Ref<EditorNode3DGizmo>());
virtual String get_gizmo_name() const;
virtual int get_priority() const;
virtual bool can_be_hidden() const;
virtual bool is_selectable_when_hidden() const;
virtual void redraw(EditorNode3DGizmo *p_gizmo);
virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const;
virtual Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const;
virtual void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point);
virtual void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_idx) const;
Ref<EditorNode3DGizmo> get_gizmo(Node3D *p_spatial);
void set_state(int p_state);
int get_state() const;
void unregister_gizmo(EditorNode3DGizmo *p_gizmo);
EditorNode3DGizmoPlugin();
virtual ~EditorNode3DGizmoPlugin();
};
#endif // NODE_3D_EDITOR_PLUGIN_H

View file

@ -36,20 +36,20 @@
#include "node_3d_editor_plugin.h"
#include "scene/resources/curve.h"
String Path3DGizmo::get_handle_name(int p_idx) const {
String Path3DGizmo::get_handle_name(int p_id) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return "";
}
if (p_idx < c->get_point_count()) {
return TTR("Curve Point #") + itos(p_idx);
if (p_id < c->get_point_count()) {
return TTR("Curve Point #") + itos(p_id);
}
p_idx = p_idx - c->get_point_count() + 1;
p_id = p_id - c->get_point_count() + 1;
int idx = p_idx / 2;
int t = p_idx % 2;
int idx = p_id / 2;
int t = p_id % 2;
String n = TTR("Curve Point #") + itos(idx);
if (t == 0) {
n += " In";
@ -60,21 +60,21 @@ String Path3DGizmo::get_handle_name(int p_idx) const {
return n;
}
Variant Path3DGizmo::get_handle_value(int p_idx) {
Variant Path3DGizmo::get_handle_value(int p_id) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return Variant();
}
if (p_idx < c->get_point_count()) {
original = c->get_point_position(p_idx);
if (p_id < c->get_point_count()) {
original = c->get_point_position(p_id);
return original;
}
p_idx = p_idx - c->get_point_count() + 1;
p_id = p_id - c->get_point_count() + 1;
int idx = p_idx / 2;
int t = p_idx % 2;
int idx = p_id / 2;
int t = p_id % 2;
Vector3 ofs;
if (t == 0) {
@ -88,7 +88,7 @@ Variant Path3DGizmo::get_handle_value(int p_idx) {
return ofs;
}
void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point) {
void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return;
@ -100,7 +100,7 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin
Vector3 ray_dir = p_camera->project_ray_normal(p_point);
// Setting curve point positions
if (p_idx < c->get_point_count()) {
if (p_id < c->get_point_count()) {
Plane p(gt.xform(original), p_camera->get_transform().basis.get_axis(2));
Vector3 inters;
@ -112,16 +112,16 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin
}
Vector3 local = gi.xform(inters);
c->set_point_position(p_idx, local);
c->set_point_position(p_id, local);
}
return;
}
p_idx = p_idx - c->get_point_count() + 1;
p_id = p_id - c->get_point_count() + 1;
int idx = p_idx / 2;
int t = p_idx % 2;
int idx = p_id / 2;
int t = p_id % 2;
Vector3 base = c->get_point_position(idx);
@ -157,7 +157,7 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin
}
}
void Path3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return;
@ -165,27 +165,27 @@ void Path3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_canc
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
if (p_idx < c->get_point_count()) {
if (p_id < c->get_point_count()) {
if (p_cancel) {
c->set_point_position(p_idx, p_restore);
c->set_point_position(p_id, p_restore);
return;
}
ur->create_action(TTR("Set Curve Point Position"));
ur->add_do_method(c.ptr(), "set_point_position", p_idx, c->get_point_position(p_idx));
ur->add_undo_method(c.ptr(), "set_point_position", p_idx, p_restore);
ur->add_do_method(c.ptr(), "set_point_position", p_id, c->get_point_position(p_id));
ur->add_undo_method(c.ptr(), "set_point_position", p_id, p_restore);
ur->commit_action();
return;
}
p_idx = p_idx - c->get_point_count() + 1;
p_id = p_id - c->get_point_count() + 1;
int idx = p_idx / 2;
int t = p_idx % 2;
int idx = p_id / 2;
int t = p_id % 2;
if (t == 0) {
if (p_cancel) {
c->set_point_in(p_idx, p_restore);
c->set_point_in(p_id, p_restore);
return;
}
@ -282,7 +282,7 @@ void Path3DGizmo::redraw() {
add_handles(handles, handles_material);
}
if (sec_handles.size()) {
add_handles(sec_handles, sec_handles_material, false, true);
add_handles(sec_handles, sec_handles_material, Vector<int>(), false, true);
}
}
}

View file

@ -31,7 +31,9 @@
#ifndef PATH_EDITOR_PLUGIN_H
#define PATH_EDITOR_PLUGIN_H
#include "editor/node_3d_editor_gizmos.h"
#include "editor/editor_plugin.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
#include "scene/3d/camera_3d.h"
#include "scene/3d/path_3d.h"
class Path3DGizmo : public EditorNode3DGizmo {
@ -44,9 +46,9 @@ class Path3DGizmo : public EditorNode3DGizmo {
public:
virtual String get_handle_name(int p_idx) const override;
virtual Variant get_handle_value(int p_idx) override;
virtual void set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false) override;
virtual Variant get_handle_value(int p_id) const override;
virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) const override;
virtual void redraw() override;
Path3DGizmo(Path3D *p_path = nullptr);

View file

@ -29,6 +29,8 @@
/*************************************************************************/
#include "csg_gizmos.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "scene/3d/camera_3d.h"
///////////
@ -48,7 +50,7 @@ CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() {
create_handle_material("handles");
}
String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
@ -60,17 +62,17 @@ String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo,
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
return p_idx == 0 ? "Radius" : "Height";
return p_id == 0 ? "Radius" : "Height";
}
if (Object::cast_to<CSGTorus3D>(cs)) {
return p_idx == 0 ? "InnerRadius" : "OuterRadius";
return p_id == 0 ? "InnerRadius" : "OuterRadius";
}
return "";
}
Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
@ -85,18 +87,18 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int
if (Object::cast_to<CSGCylinder3D>(cs)) {
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
return p_idx == 0 ? s->get_radius() : s->get_height();
return p_id == 0 ? s->get_radius() : s->get_height();
}
if (Object::cast_to<CSGTorus3D>(cs)) {
CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
return p_idx == 0 ? s->get_inner_radius() : s->get_outer_radius();
return p_id == 0 ? s->get_inner_radius() : s->get_outer_radius();
}
return Variant();
}
void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
Transform3D gt = cs->get_global_transform();
@ -129,10 +131,10 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
Vector3 axis;
axis[p_idx] = 1.0;
axis[p_id] = 1.0;
Vector3 ra, rb;
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = ra[p_idx];
float d = ra[p_id];
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
@ -142,7 +144,7 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
}
Vector3 h = s->get_size();
h[p_idx] = d * 2;
h[p_id] = d * 2;
s->set_size(h);
}
@ -150,7 +152,7 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
Vector3 axis;
axis[p_idx == 0 ? 0 : 1] = 1.0;
axis[p_id == 0 ? 0 : 1] = 1.0;
Vector3 ra, rb;
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
@ -162,9 +164,9 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
d = 0.001;
}
if (p_idx == 0) {
if (p_id == 0) {
s->set_radius(d);
} else if (p_idx == 1) {
} else if (p_id == 1) {
s->set_height(d * 2.0);
}
}
@ -185,15 +187,15 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
d = 0.001;
}
if (p_idx == 0) {
if (p_id == 0) {
s->set_inner_radius(d);
} else if (p_idx == 1) {
} else if (p_id == 1) {
s->set_outer_radius(d);
}
}
}
void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
@ -227,7 +229,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
if (Object::cast_to<CSGCylinder3D>(cs)) {
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
if (p_cancel) {
if (p_idx == 0) {
if (p_id == 0) {
s->set_radius(p_restore);
} else {
s->set_height(p_restore);
@ -236,7 +238,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
if (p_idx == 0) {
if (p_id == 0) {
ur->create_action(TTR("Change Cylinder Radius"));
ur->add_do_method(s, "set_radius", s->get_radius());
ur->add_undo_method(s, "set_radius", p_restore);
@ -252,7 +254,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
if (Object::cast_to<CSGTorus3D>(cs)) {
CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
if (p_cancel) {
if (p_idx == 0) {
if (p_id == 0) {
s->set_inner_radius(p_restore);
} else {
s->set_outer_radius(p_restore);
@ -261,7 +263,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
}
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
if (p_idx == 0) {
if (p_id == 0) {
ur->create_action(TTR("Change Torus Inner Radius"));
ur->add_do_method(s, "set_inner_radius", s->get_inner_radius());
ur->add_undo_method(s, "set_inner_radius", p_restore);
@ -356,7 +358,7 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
break;
}
p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), solid_material);
p_gizmo->add_mesh(mesh, solid_material);
}
if (Object::cast_to<CSGSphere3D>(cs)) {

View file

@ -33,22 +33,22 @@
#include "csg_shape.h"
#include "editor/editor_plugin.h"
#include "editor/node_3d_editor_gizmos.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
class CSGShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(CSGShape3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
bool has_gizmo(Node3D *p_spatial) override;
String get_gizmo_name() const override;
int get_priority() const override;
bool is_selectable_when_hidden() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
virtual bool has_gizmo(Node3D *p_spatial) override;
virtual String get_gizmo_name() const override;
virtual int get_priority() const override;
virtual bool is_selectable_when_hidden() const override;
virtual void redraw(EditorNode3DGizmo *p_gizmo) override;
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const override;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const override;
void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) override;
virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const override;
CSGShape3DGizmoPlugin();
};

View file

@ -548,7 +548,7 @@ void CSGShape3D::_notification(int p_what) {
void CSGShape3D::set_operation(Operation p_operation) {
operation = p_operation;
_make_dirty();
update_gizmo();
update_gizmos();
}
CSGShape3D::Operation CSGShape3D::get_operation() const {
@ -845,7 +845,7 @@ CSGBrush *CSGMesh3D::_build_brush() {
void CSGMesh3D::_mesh_changed() {
_make_dirty();
update_gizmo();
update_gizmos();
}
void CSGMesh3D::set_material(const Ref<Material> &p_material) {
@ -1034,7 +1034,7 @@ void CSGSphere3D::set_radius(const float p_radius) {
ERR_FAIL_COND(p_radius <= 0);
radius = p_radius;
_make_dirty();
update_gizmo();
update_gizmos();
}
float CSGSphere3D::get_radius() const {
@ -1044,7 +1044,7 @@ float CSGSphere3D::get_radius() const {
void CSGSphere3D::set_radial_segments(const int p_radial_segments) {
radial_segments = p_radial_segments > 4 ? p_radial_segments : 4;
_make_dirty();
update_gizmo();
update_gizmos();
}
int CSGSphere3D::get_radial_segments() const {
@ -1054,7 +1054,7 @@ int CSGSphere3D::get_radial_segments() const {
void CSGSphere3D::set_rings(const int p_rings) {
rings = p_rings > 1 ? p_rings : 1;
_make_dirty();
update_gizmo();
update_gizmos();
}
int CSGSphere3D::get_rings() const {
@ -1203,7 +1203,7 @@ void CSGBox3D::_bind_methods() {
void CSGBox3D::set_size(const Vector3 &p_size) {
size = p_size;
_make_dirty();
update_gizmo();
update_gizmos();
}
Vector3 CSGBox3D::get_size() const {
@ -1213,7 +1213,7 @@ Vector3 CSGBox3D::get_size() const {
void CSGBox3D::set_material(const Ref<Material> &p_material) {
material = p_material;
_make_dirty();
update_gizmo();
update_gizmos();
}
Ref<Material> CSGBox3D::get_material() const {
@ -1384,7 +1384,7 @@ void CSGCylinder3D::_bind_methods() {
void CSGCylinder3D::set_radius(const float p_radius) {
radius = p_radius;
_make_dirty();
update_gizmo();
update_gizmos();
}
float CSGCylinder3D::get_radius() const {
@ -1394,7 +1394,7 @@ float CSGCylinder3D::get_radius() const {
void CSGCylinder3D::set_height(const float p_height) {
height = p_height;
_make_dirty();
update_gizmo();
update_gizmos();
}
float CSGCylinder3D::get_height() const {
@ -1405,7 +1405,7 @@ void CSGCylinder3D::set_sides(const int p_sides) {
ERR_FAIL_COND(p_sides < 3);
sides = p_sides;
_make_dirty();
update_gizmo();
update_gizmos();
}
int CSGCylinder3D::get_sides() const {
@ -1415,7 +1415,7 @@ int CSGCylinder3D::get_sides() const {
void CSGCylinder3D::set_cone(const bool p_cone) {
cone = p_cone;
_make_dirty();
update_gizmo();
update_gizmos();
}
bool CSGCylinder3D::is_cone() const {
@ -1603,7 +1603,7 @@ void CSGTorus3D::_bind_methods() {
void CSGTorus3D::set_inner_radius(const float p_inner_radius) {
inner_radius = p_inner_radius;
_make_dirty();
update_gizmo();
update_gizmos();
}
float CSGTorus3D::get_inner_radius() const {
@ -1613,7 +1613,7 @@ float CSGTorus3D::get_inner_radius() const {
void CSGTorus3D::set_outer_radius(const float p_outer_radius) {
outer_radius = p_outer_radius;
_make_dirty();
update_gizmo();
update_gizmos();
}
float CSGTorus3D::get_outer_radius() const {
@ -1624,7 +1624,7 @@ void CSGTorus3D::set_sides(const int p_sides) {
ERR_FAIL_COND(p_sides < 3);
sides = p_sides;
_make_dirty();
update_gizmo();
update_gizmos();
}
int CSGTorus3D::get_sides() const {
@ -1635,7 +1635,7 @@ void CSGTorus3D::set_ring_sides(const int p_ring_sides) {
ERR_FAIL_COND(p_ring_sides < 3);
ring_sides = p_ring_sides;
_make_dirty();
update_gizmo();
update_gizmos();
}
int CSGTorus3D::get_ring_sides() const {
@ -2172,7 +2172,7 @@ void CSGPolygon3D::_validate_property(PropertyInfo &property) const {
void CSGPolygon3D::_path_changed() {
_make_dirty();
update_gizmo();
update_gizmos();
}
void CSGPolygon3D::_path_exited() {
@ -2248,7 +2248,7 @@ void CSGPolygon3D::_bind_methods() {
void CSGPolygon3D::set_polygon(const Vector<Vector2> &p_polygon) {
polygon = p_polygon;
_make_dirty();
update_gizmo();
update_gizmos();
}
Vector<Vector2> CSGPolygon3D::get_polygon() const {
@ -2258,7 +2258,7 @@ Vector<Vector2> CSGPolygon3D::get_polygon() const {
void CSGPolygon3D::set_mode(Mode p_mode) {
mode = p_mode;
_make_dirty();
update_gizmo();
update_gizmos();
notify_property_list_changed();
}
@ -2270,7 +2270,7 @@ void CSGPolygon3D::set_depth(const float p_depth) {
ERR_FAIL_COND(p_depth < 0.001);
depth = p_depth;
_make_dirty();
update_gizmo();
update_gizmos();
}
float CSGPolygon3D::get_depth() const {
@ -2290,7 +2290,7 @@ void CSGPolygon3D::set_spin_degrees(const float p_spin_degrees) {
ERR_FAIL_COND(p_spin_degrees < 0.01 || p_spin_degrees > 360);
spin_degrees = p_spin_degrees;
_make_dirty();
update_gizmo();
update_gizmos();
}
float CSGPolygon3D::get_spin_degrees() const {
@ -2301,7 +2301,7 @@ void CSGPolygon3D::set_spin_sides(const int p_spin_sides) {
ERR_FAIL_COND(p_spin_sides < 3);
spin_sides = p_spin_sides;
_make_dirty();
update_gizmo();
update_gizmos();
}
int CSGPolygon3D::get_spin_sides() const {
@ -2311,7 +2311,7 @@ int CSGPolygon3D::get_spin_sides() const {
void CSGPolygon3D::set_path_node(const NodePath &p_path) {
path_node = p_path;
_make_dirty();
update_gizmo();
update_gizmos();
}
NodePath CSGPolygon3D::get_path_node() const {
@ -2322,7 +2322,7 @@ void CSGPolygon3D::set_path_interval(float p_interval) {
ERR_FAIL_COND_MSG(p_interval < 0.001, "Path interval cannot be smaller than 0.001.");
path_interval = p_interval;
_make_dirty();
update_gizmo();
update_gizmos();
}
float CSGPolygon3D::get_path_interval() const {
@ -2332,7 +2332,7 @@ float CSGPolygon3D::get_path_interval() const {
void CSGPolygon3D::set_path_rotation(PathRotation p_rotation) {
path_rotation = p_rotation;
_make_dirty();
update_gizmo();
update_gizmos();
}
CSGPolygon3D::PathRotation CSGPolygon3D::get_path_rotation() const {
@ -2342,7 +2342,7 @@ CSGPolygon3D::PathRotation CSGPolygon3D::get_path_rotation() const {
void CSGPolygon3D::set_path_local(bool p_enable) {
path_local = p_enable;
_make_dirty();
update_gizmo();
update_gizmos();
}
bool CSGPolygon3D::is_path_local() const {
@ -2352,7 +2352,7 @@ bool CSGPolygon3D::is_path_local() const {
void CSGPolygon3D::set_path_joined(bool p_enable) {
path_joined = p_enable;
_make_dirty();
update_gizmo();
update_gizmos();
}
bool CSGPolygon3D::is_path_joined() const {

View file

@ -65,7 +65,7 @@ void NavigationMeshEditor::_bake_pressed() {
NavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
NavigationMeshGenerator::get_singleton()->bake(node->get_navigation_mesh(), node);
node->update_gizmo();
node->update_gizmos();
}
void NavigationMeshEditor::_clear_pressed() {
@ -77,7 +77,7 @@ void NavigationMeshEditor::_clear_pressed() {
bake_info->set_text("");
if (node) {
node->update_gizmo();
node->update_gizmos();
}
}

View file

@ -794,7 +794,7 @@ uint32_t AudioStreamPlayer3D::get_area_mask() const {
void AudioStreamPlayer3D::set_emission_angle_enabled(bool p_enable) {
emission_angle_enabled = p_enable;
update_gizmo();
update_gizmos();
}
bool AudioStreamPlayer3D::is_emission_angle_enabled() const {
@ -804,7 +804,7 @@ bool AudioStreamPlayer3D::is_emission_angle_enabled() const {
void AudioStreamPlayer3D::set_emission_angle(float p_angle) {
ERR_FAIL_COND(p_angle < 0 || p_angle > 90);
emission_angle = p_angle;
update_gizmo();
update_gizmos();
}
float AudioStreamPlayer3D::get_emission_angle() const {

View file

@ -164,7 +164,7 @@ void Camera3D::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_f
mode = PROJECTION_PERSPECTIVE;
RenderingServer::get_singleton()->camera_set_perspective(camera, fov, near, far);
update_gizmo();
update_gizmos();
force_change = false;
}
@ -181,7 +181,7 @@ void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) {
force_change = false;
RenderingServer::get_singleton()->camera_set_orthogonal(camera, size, near, far);
update_gizmo();
update_gizmos();
}
void Camera3D::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float p_z_far) {
@ -198,7 +198,7 @@ void Camera3D::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float
force_change = false;
RenderingServer::get_singleton()->camera_set_frustum(camera, size, frustum_offset, near, far);
update_gizmo();
update_gizmos();
}
void Camera3D::set_projection(Camera3D::Projection p_mode) {
@ -755,7 +755,7 @@ void ClippedCamera3D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
update_gizmo();
update_gizmos();
}
}

View file

@ -122,7 +122,7 @@ void CollisionPolygon3D::set_polygon(const Vector<Point2> &p_polygon) {
_build_polygon();
}
update_configuration_warnings();
update_gizmo();
update_gizmos();
}
Vector<Point2> CollisionPolygon3D::get_polygon() const {
@ -136,7 +136,7 @@ AABB CollisionPolygon3D::get_item_rect() const {
void CollisionPolygon3D::set_depth(real_t p_depth) {
depth = p_depth;
_build_polygon();
update_gizmo();
update_gizmos();
}
real_t CollisionPolygon3D::get_depth() const {
@ -145,7 +145,7 @@ real_t CollisionPolygon3D::get_depth() const {
void CollisionPolygon3D::set_disabled(bool p_disabled) {
disabled = p_disabled;
update_gizmo();
update_gizmos();
if (parent) {
parent->shape_owner_set_disabled(owner_id, p_disabled);

View file

@ -117,7 +117,7 @@ void CollisionShape3D::_notification(int p_what) {
}
void CollisionShape3D::resource_changed(RES res) {
update_gizmo();
update_gizmos();
}
TypedArray<String> CollisionShape3D::get_configuration_warnings() const {
@ -166,7 +166,7 @@ void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) {
if (!shape.is_null()) {
shape->register_owner(this);
}
update_gizmo();
update_gizmos();
if (parent) {
parent->shape_owner_clear_shapes(owner_id);
if (shape.is_valid()) {
@ -187,7 +187,7 @@ Ref<Shape3D> CollisionShape3D::get_shape() const {
void CollisionShape3D::set_disabled(bool p_disabled) {
disabled = p_disabled;
update_gizmo();
update_gizmos();
if (parent) {
parent->shape_owner_set_disabled(owner_id, p_disabled);
}

View file

@ -33,7 +33,7 @@
void Decal::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->decal_set_extents(decal, p_extents);
update_gizmo();
update_gizmos();
}
Vector3 Decal::get_extents() const {

View file

@ -99,7 +99,7 @@ void GPUParticles3D::set_randomness_ratio(float p_ratio) {
void GPUParticles3D::set_visibility_aabb(const AABB &p_aabb) {
visibility_aabb = p_aabb;
RS::get_singleton()->particles_set_custom_aabb(particles, visibility_aabb);
update_gizmo();
update_gizmos();
}
void GPUParticles3D::set_use_local_coordinates(bool p_enable) {

View file

@ -73,7 +73,7 @@ void GPUParticlesCollisionSphere::_bind_methods() {
void GPUParticlesCollisionSphere::set_radius(float p_radius) {
radius = p_radius;
RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius);
update_gizmo();
update_gizmos();
}
float GPUParticlesCollisionSphere::get_radius() const {
@ -103,7 +103,7 @@ void GPUParticlesCollisionBox::_bind_methods() {
void GPUParticlesCollisionBox::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmo();
update_gizmos();
}
Vector3 GPUParticlesCollisionBox::get_extents() const {
@ -545,7 +545,7 @@ float GPUParticlesCollisionSDF::get_thickness() const {
void GPUParticlesCollisionSDF::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmo();
update_gizmos();
}
Vector3 GPUParticlesCollisionSDF::get_extents() const {
@ -554,7 +554,7 @@ Vector3 GPUParticlesCollisionSDF::get_extents() const {
void GPUParticlesCollisionSDF::set_resolution(Resolution p_resolution) {
resolution = p_resolution;
update_gizmo();
update_gizmos();
}
GPUParticlesCollisionSDF::Resolution GPUParticlesCollisionSDF::get_resolution() const {
@ -680,7 +680,7 @@ float GPUParticlesCollisionHeightField::get_follow_camera_push_ratio() const {
void GPUParticlesCollisionHeightField::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmo();
update_gizmos();
RS::get_singleton()->particles_collision_height_field_update(_get_collision());
}
@ -691,7 +691,7 @@ Vector3 GPUParticlesCollisionHeightField::get_extents() const {
void GPUParticlesCollisionHeightField::set_resolution(Resolution p_resolution) {
resolution = p_resolution;
RS::get_singleton()->particles_collision_set_height_field_resolution(_get_collision(), RS::ParticlesCollisionHeightfieldResolution(resolution));
update_gizmo();
update_gizmos();
RS::get_singleton()->particles_collision_height_field_update(_get_collision());
}
@ -761,7 +761,7 @@ float GPUParticlesAttractor3D::get_attenuation() const {
void GPUParticlesAttractor3D::set_directionality(float p_directionality) {
directionality = p_directionality;
RS::get_singleton()->particles_collision_set_attractor_directionality(collision, p_directionality);
update_gizmo();
update_gizmos();
}
float GPUParticlesAttractor3D::get_directionality() const {
@ -808,7 +808,7 @@ void GPUParticlesAttractorSphere::_bind_methods() {
void GPUParticlesAttractorSphere::set_radius(float p_radius) {
radius = p_radius;
RS::get_singleton()->particles_collision_set_sphere_radius(_get_collision(), radius);
update_gizmo();
update_gizmos();
}
float GPUParticlesAttractorSphere::get_radius() const {
@ -838,7 +838,7 @@ void GPUParticlesAttractorBox::_bind_methods() {
void GPUParticlesAttractorBox::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmo();
update_gizmos();
}
Vector3 GPUParticlesAttractorBox::get_extents() const {
@ -872,7 +872,7 @@ void GPUParticlesAttractorVectorField::_bind_methods() {
void GPUParticlesAttractorVectorField::set_extents(const Vector3 &p_extents) {
extents = p_extents;
RS::get_singleton()->particles_collision_set_box_extents(_get_collision(), extents);
update_gizmo();
update_gizmos();
}
Vector3 GPUParticlesAttractorVectorField::get_extents() const {

View file

@ -45,7 +45,7 @@ void Light3D::set_param(Param p_param, float p_value) {
RS::get_singleton()->light_set_param(light, RS::LightParam(p_param), p_value);
if (p_param == PARAM_SPOT_ANGLE || p_param == PARAM_RANGE) {
update_gizmo();
update_gizmos();
if (p_param == PARAM_SPOT_ANGLE) {
update_configuration_warnings();
@ -95,7 +95,7 @@ void Light3D::set_color(const Color &p_color) {
color = p_color;
RS::get_singleton()->light_set_color(light, p_color);
// The gizmo color depends on the light color, so update it.
update_gizmo();
update_gizmos();
}
Color Light3D::get_color() const {

View file

@ -1250,7 +1250,7 @@ void LightmapGI::set_light_data(const Ref<LightmapGIData> &p_data) {
}
}
update_gizmo();
update_gizmos();
}
Ref<LightmapGIData> LightmapGI::get_light_data() const {

View file

@ -133,7 +133,7 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
set_base(RID());
}
update_gizmo();
update_gizmos();
notify_property_list_changed();
}
@ -356,7 +356,7 @@ Ref<Material> MeshInstance3D::get_active_material(int p_surface) const {
void MeshInstance3D::_mesh_changed() {
ERR_FAIL_COND(mesh.is_null());
surface_override_materials.resize(mesh->get_surface_count());
update_gizmo();
update_gizmos();
}
void MeshInstance3D::create_debug_tangents() {

View file

@ -59,7 +59,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) {
}
}
update_gizmo();
update_gizmos();
}
bool NavigationRegion3D::is_enabled() const {
@ -134,7 +134,7 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmes
emit_signal(SNAME("navigation_mesh_changed"));
update_gizmo();
update_gizmos();
update_configuration_warnings();
}
@ -211,7 +211,7 @@ void NavigationRegion3D::_bind_methods() {
}
void NavigationRegion3D::_navigation_changed() {
update_gizmo();
update_gizmos();
update_configuration_warnings();
}

View file

@ -76,7 +76,7 @@ Node3DGizmo::Node3DGizmo() {
void Node3D::_notify_dirty() {
#ifdef TOOLS_ENABLED
if ((data.gizmo.is_valid() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) {
if ((!data.gizmos.is_empty() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) {
#else
if (data.notify_transform && !data.ignore_notification && !xform_change.in_list()) {
@ -110,7 +110,7 @@ void Node3D::_propagate_transform_changed(Node3D *p_origin) {
E->get()->_propagate_transform_changed(p_origin);
}
#ifdef TOOLS_ENABLED
if ((data.gizmo.is_valid() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) {
if ((!data.gizmos.is_empty() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) {
#else
if (data.notify_transform && !data.ignore_notification && !xform_change.in_list()) {
#endif
@ -181,15 +181,14 @@ void Node3D::_notification(int p_what) {
}
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {
//get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this);
get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
if (!data.gizmo_disabled) {
if (data.gizmo.is_valid()) {
data.gizmo->create();
if (!data.gizmos_disabled) {
for (int i = 0; i < data.gizmos.size(); i++) {
data.gizmos.write[i]->create();
if (is_visible_in_tree()) {
data.gizmo->redraw();
data.gizmos.write[i]->redraw();
}
data.gizmo->transform();
data.gizmos.write[i]->transform();
}
}
}
@ -198,10 +197,7 @@ void Node3D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_WORLD: {
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
data.gizmo->free();
data.gizmo.unref();
}
clear_gizmos();
#endif
if (get_script_instance()) {
@ -215,8 +211,8 @@ void Node3D::_notification(int p_what) {
case NOTIFICATION_TRANSFORM_CHANGED: {
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
data.gizmo->transform();
for (int i = 0; i < data.gizmos.size(); i++) {
data.gizmos.write[i]->transform();
}
#endif
} break;
@ -368,80 +364,119 @@ Vector3 Node3D::get_scale() const {
return data.scale;
}
void Node3D::update_gizmo() {
void Node3D::update_gizmos() {
#ifdef TOOLS_ENABLED
if (!is_inside_world()) {
return;
}
if (!data.gizmo.is_valid()) {
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
}
if (!data.gizmo.is_valid()) {
if (data.gizmos.is_empty()) {
return;
}
if (data.gizmo_dirty) {
return;
}
data.gizmo_dirty = true;
MessageQueue::get_singleton()->push_call(this, "_update_gizmo");
data.gizmos_dirty = true;
MessageQueue::get_singleton()->push_callable(callable_mp(this, &Node3D::_update_gizmos));
#endif
}
void Node3D::set_gizmo(const Ref<Node3DGizmo> &p_gizmo) {
void Node3D::clear_subgizmo_selection() {
#ifdef TOOLS_ENABLED
if (data.gizmo_disabled) {
if (!is_inside_world()) {
return;
}
if (data.gizmo.is_valid() && is_inside_world()) {
data.gizmo->free();
if (data.gizmos.is_empty()) {
return;
}
data.gizmo = p_gizmo;
if (data.gizmo.is_valid() && is_inside_world()) {
data.gizmo->create();
if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {
get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_clear_subgizmo_selection, this);
}
#endif
}
void Node3D::add_gizmo(Ref<Node3DGizmo> p_gizmo) {
#ifdef TOOLS_ENABLED
if (data.gizmos_disabled || p_gizmo.is_null()) {
return;
}
data.gizmos.push_back(p_gizmo);
if (p_gizmo.is_valid() && is_inside_world()) {
p_gizmo->create();
if (is_visible_in_tree()) {
data.gizmo->redraw();
p_gizmo->redraw();
}
data.gizmo->transform();
p_gizmo->transform();
}
#endif
}
Ref<Node3DGizmo> Node3D::get_gizmo() const {
void Node3D::remove_gizmo(Ref<Node3DGizmo> p_gizmo) {
#ifdef TOOLS_ENABLED
return data.gizmo;
int idx = data.gizmos.find(p_gizmo);
if (idx != -1) {
p_gizmo->free();
data.gizmos.remove(idx);
}
#endif
}
void Node3D::clear_gizmos() {
#ifdef TOOLS_ENABLED
for (int i = 0; i < data.gizmos.size(); i++) {
data.gizmos.write[i]->free();
}
data.gizmos.clear();
#endif
}
Array Node3D::get_gizmos_bind() const {
Array ret;
#ifdef TOOLS_ENABLED
for (int i = 0; i < data.gizmos.size(); i++) {
ret.push_back(Variant(data.gizmos[i].ptr()));
}
#endif
return ret;
}
Vector<Ref<Node3DGizmo>> Node3D::get_gizmos() const {
#ifdef TOOLS_ENABLED
return data.gizmos;
#else
return Ref<Node3DGizmo>();
return Vector<Ref<Node3DGizmo>>();
#endif
}
void Node3D::_update_gizmo() {
void Node3D::_update_gizmos() {
#ifdef TOOLS_ENABLED
if (!is_inside_world()) {
if (data.gizmos_disabled || !is_inside_world() || !data.gizmos_dirty) {
return;
}
data.gizmo_dirty = false;
if (data.gizmo.is_valid()) {
data.gizmos_dirty = false;
for (int i = 0; i < data.gizmos.size(); i++) {
if (is_visible_in_tree()) {
data.gizmo->redraw();
data.gizmos.write[i]->redraw();
} else {
data.gizmo->clear();
data.gizmos.write[i]->clear();
}
}
#endif
}
#ifdef TOOLS_ENABLED
void Node3D::set_disable_gizmo(bool p_enabled) {
data.gizmo_disabled = p_enabled;
if (!p_enabled && data.gizmo.is_valid()) {
data.gizmo = Ref<Node3DGizmo>();
void Node3D::set_disable_gizmos(bool p_enabled) {
data.gizmos_disabled = p_enabled;
if (!p_enabled) {
clear_gizmos();
}
}
#endif
void Node3D::set_disable_scale(bool p_enabled) {
@ -486,8 +521,9 @@ void Node3D::_propagate_visibility_changed() {
notification(NOTIFICATION_VISIBILITY_CHANGED);
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
_update_gizmo();
if (!data.gizmos.is_empty()) {
data.gizmos_dirty = true;
_update_gizmos();
}
#endif
@ -758,11 +794,11 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_visibility_parent", "path"), &Node3D::set_visibility_parent);
ClassDB::bind_method(D_METHOD("get_visibility_parent"), &Node3D::get_visibility_parent);
ClassDB::bind_method(D_METHOD("_update_gizmo"), &Node3D::_update_gizmo);
ClassDB::bind_method(D_METHOD("update_gizmo"), &Node3D::update_gizmo);
ClassDB::bind_method(D_METHOD("set_gizmo", "gizmo"), &Node3D::set_gizmo);
ClassDB::bind_method(D_METHOD("get_gizmo"), &Node3D::get_gizmo);
ClassDB::bind_method(D_METHOD("update_gizmos"), &Node3D::update_gizmos);
ClassDB::bind_method(D_METHOD("add_gizmo", "gizmo"), &Node3D::add_gizmo);
ClassDB::bind_method(D_METHOD("get_gizmos"), &Node3D::get_gizmos_bind);
ClassDB::bind_method(D_METHOD("clear_gizmos"), &Node3D::clear_gizmos);
ClassDB::bind_method(D_METHOD("clear_subgizmo_selection"), &Node3D::clear_subgizmo_selection);
ClassDB::bind_method(D_METHOD("set_visible", "visible"), &Node3D::set_visible);
ClassDB::bind_method(D_METHOD("is_visible"), &Node3D::is_visible);
@ -813,7 +849,6 @@ void Node3D::_bind_methods() {
ADD_GROUP("Visibility", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "Node3DGizmo", PROPERTY_USAGE_NONE), "set_gizmo", "get_gizmo");
ADD_SIGNAL(MethodInfo("visibility_changed"));
}

View file

@ -90,16 +90,16 @@ class Node3D : public Node {
bool disable_scale = false;
#ifdef TOOLS_ENABLED
Ref<Node3DGizmo> gizmo;
bool gizmo_disabled = false;
bool gizmo_dirty = false;
Vector<Ref<Node3DGizmo>> gizmos;
bool gizmos_disabled = false;
bool gizmos_dirty = false;
#endif
} data;
NodePath visibility_parent_path;
void _update_gizmo();
void _update_gizmos();
void _notify_dirty();
void _propagate_transform_changed(Node3D *p_origin);
@ -154,10 +154,14 @@ public:
void set_disable_scale(bool p_enabled);
bool is_scale_disabled() const;
void set_disable_gizmo(bool p_enabled);
void update_gizmo();
void set_gizmo(const Ref<Node3DGizmo> &p_gizmo);
Ref<Node3DGizmo> get_gizmo() const;
void set_disable_gizmos(bool p_enabled);
void update_gizmos();
void clear_subgizmo_selection();
Vector<Ref<Node3DGizmo>> get_gizmos() const;
Array get_gizmos_bind() const;
void add_gizmo(Ref<Node3DGizmo> p_gizmo);
void remove_gizmo(Ref<Node3DGizmo> p_gizmo);
void clear_gizmos();
_FORCE_INLINE_ bool is_inside_world() const { return data.inside_world; }

View file

@ -173,12 +173,12 @@ void OccluderInstance3D::set_occluder(const Ref<Occluder3D> &p_occluder) {
set_base(RID());
}
update_gizmo();
update_gizmos();
update_configuration_warnings();
}
void OccluderInstance3D::_occluder_changed() {
update_gizmo();
update_gizmos();
update_configuration_warnings();
}

View file

@ -38,7 +38,7 @@ void Path3D::_notification(int p_what) {
void Path3D::_curve_changed() {
if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
update_gizmo();
update_gizmos();
}
if (is_inside_tree()) {
emit_signal(SNAME("curve_changed"));

View file

@ -2181,9 +2181,7 @@ bool PhysicalBone3D::_set(const StringName &p_name, const Variant &p_value) {
if (joint_data) {
if (joint_data->_set(p_name, p_value, joint)) {
#ifdef TOOLS_ENABLED
if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
}
update_gizmos();
#endif
return true;
}
@ -2371,9 +2369,7 @@ void PhysicalBone3D::_update_joint_offset() {
set_ignore_transform_notification(false);
#ifdef TOOLS_ENABLED
if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
}
update_gizmos();
#endif
}
@ -2540,9 +2536,7 @@ void PhysicalBone3D::set_joint_type(JointType p_joint_type) {
#ifdef TOOLS_ENABLED
notify_property_list_changed();
if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
}
update_gizmos();
#endif
}

View file

@ -348,7 +348,7 @@ void HingeJoint3D::set_param(Param p_param, real_t p_value) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(get_joint(), PhysicsServer3D::HingeJointParam(p_param), p_value);
}
update_gizmo();
update_gizmos();
}
real_t HingeJoint3D::get_param(Param p_param) const {
@ -363,7 +363,7 @@ void HingeJoint3D::set_flag(Flag p_flag, bool p_value) {
PhysicsServer3D::get_singleton()->hinge_joint_set_flag(get_joint(), PhysicsServer3D::HingeJointFlag(p_flag), p_value);
}
update_gizmo();
update_gizmos();
}
bool HingeJoint3D::get_flag(Flag p_flag) const {
@ -497,7 +497,7 @@ void SliderJoint3D::set_param(Param p_param, real_t p_value) {
if (is_configured()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(get_joint(), PhysicsServer3D::SliderJointParam(p_param), p_value);
}
update_gizmo();
update_gizmos();
}
real_t SliderJoint3D::get_param(Param p_param) const {
@ -602,7 +602,7 @@ void ConeTwistJoint3D::set_param(Param p_param, real_t p_value) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(get_joint(), PhysicsServer3D::ConeTwistJointParam(p_param), p_value);
}
update_gizmo();
update_gizmos();
}
real_t ConeTwistJoint3D::get_param(Param p_param) const {
@ -857,7 +857,7 @@ void Generic6DOFJoint3D::set_param_x(Param p_param, real_t p_value) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
update_gizmos();
}
real_t Generic6DOFJoint3D::get_param_x(Param p_param) const {
@ -871,7 +871,7 @@ void Generic6DOFJoint3D::set_param_y(Param p_param, real_t p_value) {
if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
update_gizmos();
}
real_t Generic6DOFJoint3D::get_param_y(Param p_param) const {
@ -885,7 +885,7 @@ void Generic6DOFJoint3D::set_param_z(Param p_param, real_t p_value) {
if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
}
update_gizmo();
update_gizmos();
}
real_t Generic6DOFJoint3D::get_param_z(Param p_param) const {
@ -899,7 +899,7 @@ void Generic6DOFJoint3D::set_flag_x(Flag p_flag, bool p_enabled) {
if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
update_gizmos();
}
bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const {
@ -913,7 +913,7 @@ void Generic6DOFJoint3D::set_flag_y(Flag p_flag, bool p_enabled) {
if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
update_gizmos();
}
bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const {
@ -927,7 +927,7 @@ void Generic6DOFJoint3D::set_flag_z(Flag p_flag, bool p_enabled) {
if (is_configured()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
}
update_gizmo();
update_gizmos();
}
bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const {

View file

@ -37,7 +37,7 @@
void RayCast3D::set_target_position(const Vector3 &p_point) {
target_position = p_point;
update_gizmo();
update_gizmos();
if (Engine::get_singleton()->is_editor_hint()) {
if (is_inside_tree()) {
@ -102,7 +102,7 @@ Vector3 RayCast3D::get_collision_normal() const {
void RayCast3D::set_enabled(bool p_enabled) {
enabled = p_enabled;
update_gizmo();
update_gizmos();
if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
set_physics_process_internal(p_enabled);
@ -366,7 +366,7 @@ void RayCast3D::_update_debug_shape_vertices() {
void RayCast3D::set_debug_shape_thickness(const float p_debug_shape_thickness) {
debug_shape_thickness = p_debug_shape_thickness;
update_gizmo();
update_gizmos();
if (Engine::get_singleton()->is_editor_hint()) {
if (is_inside_tree()) {

View file

@ -101,7 +101,7 @@ void ReflectionProbe::set_extents(const Vector3 &p_extents) {
RS::get_singleton()->reflection_probe_set_extents(probe, extents);
RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset);
update_gizmo();
update_gizmos();
}
Vector3 ReflectionProbe::get_extents() const {
@ -119,7 +119,7 @@ void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) {
RS::get_singleton()->reflection_probe_set_extents(probe, extents);
RS::get_singleton()->reflection_probe_set_origin_offset(probe, origin_offset);
update_gizmo();
update_gizmos();
}
Vector3 ReflectionProbe::get_origin_offset() const {

View file

@ -404,7 +404,7 @@ void Skeleton3D::add_bone(const String &p_name) {
process_order_dirty = true;
version++;
_make_dirty();
update_gizmo();
update_gizmos();
}
int Skeleton3D::find_bone(const String &p_name) const {

View file

@ -84,7 +84,7 @@ real_t SpringArm3D::get_length() const {
void SpringArm3D::set_length(real_t p_length) {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update_gizmo();
update_gizmos();
}
spring_length = p_length;

View file

@ -174,7 +174,7 @@ void SpriteBase3D::_queue_update() {
}
triangle_mesh.unref();
update_gizmo();
update_gizmos();
pending_update = true;
call_deferred(SceneStringNames::get_singleton()->_im_update);

View file

@ -149,7 +149,7 @@ void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) {
void VehicleWheel3D::set_radius(real_t p_radius) {
m_wheelRadius = p_radius;
update_gizmo();
update_gizmos();
}
real_t VehicleWheel3D::get_radius() const {
@ -158,7 +158,7 @@ real_t VehicleWheel3D::get_radius() const {
void VehicleWheel3D::set_suspension_rest_length(real_t p_length) {
m_suspensionRestLength = p_length;
update_gizmo();
update_gizmos();
}
real_t VehicleWheel3D::get_suspension_rest_length() const {

View file

@ -63,7 +63,7 @@ void VisibleOnScreenNotifier3D::set_aabb(const AABB &p_aabb) {
RS::get_singleton()->visibility_notifier_set_aabb(get_base(), aabb);
update_gizmo();
update_gizmos();
}
AABB VisibleOnScreenNotifier3D::get_aabb() const {

View file

@ -265,7 +265,7 @@ Ref<VoxelGIData> VoxelGI::get_probe_data() const {
void VoxelGI::set_subdiv(Subdiv p_subdiv) {
ERR_FAIL_INDEX(p_subdiv, SUBDIV_MAX);
subdiv = p_subdiv;
update_gizmo();
update_gizmos();
}
VoxelGI::Subdiv VoxelGI::get_subdiv() const {
@ -274,7 +274,7 @@ VoxelGI::Subdiv VoxelGI::get_subdiv() const {
void VoxelGI::set_extents(const Vector3 &p_extents) {
extents = p_extents;
update_gizmo();
update_gizmos();
}
Vector3 VoxelGI::get_extents() const {

View file

@ -136,6 +136,7 @@ SceneStringNames::SceneStringNames() {
_spatial_editor_group = StaticCString::create("_spatial_editor_group");
_request_gizmo = StaticCString::create("_request_gizmo");
_clear_subgizmo_selection = StaticCString::create("_clear_subgizmo_selection");
offset = StaticCString::create("offset");
unit_offset = StaticCString::create("unit_offset");

View file

@ -156,6 +156,7 @@ public:
StringName _spatial_editor_group;
StringName _request_gizmo;
StringName _clear_subgizmo_selection;
StringName offset;
StringName unit_offset;