mirror of https://github.com/godotengine/godot
Move `RuntimeNodeSelect` to its own files
This commit is contained in:
parent
5ad8b27d8d
commit
6862edcede
|
|
@ -35,7 +35,7 @@
|
|||
#include "core/io/stream_peer_tcp.h"
|
||||
#include "core/io/tcp_server.h"
|
||||
#include "editor/debugger/debug_adapter/debug_adapter_types.h"
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/debugger/scene_debugger_object.h"
|
||||
|
||||
#define DAP_MAX_BUFFER_SIZE 4194304 // 4MB
|
||||
#define DAP_MAX_CLIENTS 8
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include "editor/docks/inspector_dock.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_undo_redo_manager.h"
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/debugger/scene_debugger_object.h"
|
||||
|
||||
bool EditorDebuggerRemoteObjects::_set(const StringName &p_name, const Variant &p_value) {
|
||||
return _set_impl(p_name, p_value, "");
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "editor/gui/editor_file_dialog.h"
|
||||
#include "editor/gui/editor_toaster.h"
|
||||
#include "editor/settings/editor_settings.h"
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/debugger/scene_debugger_object.h"
|
||||
#include "scene/gui/texture_rect.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "servers/display/display_server.h"
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
#include "editor/themes/editor_scale.h"
|
||||
#include "main/performance.h"
|
||||
#include "scene/3d/camera_3d.h"
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/debugger/scene_debugger_object.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/dialogs.h"
|
||||
#include "scene/gui/grid_container.h"
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/debugger/debugger_marshalls.h"
|
||||
#include "core/debugger/engine_debugger.h"
|
||||
#include "core/string/translation_server.h"
|
||||
#include "editor/debugger/editor_debugger_node.h"
|
||||
#include "editor/debugger/script_editor_debugger.h"
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "editor/debugger/editor_debugger_plugin.h"
|
||||
#include "editor/editor_main_screen.h"
|
||||
#include "editor/plugins/editor_plugin.h"
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/debugger/runtime_node_select.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
|
||||
class EmbeddedProcessBase;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "editor_network_profiler.h"
|
||||
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "editor/editor_string_names.h"
|
||||
#include "editor/run/editor_run_bar.h"
|
||||
#include "editor/settings/editor_settings.h"
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
#include "core/core_bind.h"
|
||||
#include "core/io/compression.h"
|
||||
#include "core/object/script_language.h"
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/debugger/scene_debugger_object.h"
|
||||
|
||||
#if defined(MODULE_GDSCRIPT_ENABLED) && defined(DEBUG_ENABLED)
|
||||
#include "modules/gdscript/gdscript.h"
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "scene/debugger/scene_debugger.h"
|
||||
#include "scene/debugger/scene_debugger_object.h"
|
||||
|
||||
struct SnapshotDataTransportObject : public SceneDebuggerObject {
|
||||
SnapshotDataTransportObject() :
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,248 @@
|
|||
/**************************************************************************/
|
||||
/* runtime_node_select.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
#include "scene/gui/view_panner.h"
|
||||
#ifndef _3D_DISABLED
|
||||
#include "scene/resources/mesh.h"
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
class PopupMenu;
|
||||
|
||||
class RuntimeNodeSelect : public Object {
|
||||
GDCLASS(RuntimeNodeSelect, Object);
|
||||
|
||||
public:
|
||||
enum NodeType {
|
||||
NODE_TYPE_NONE,
|
||||
NODE_TYPE_2D,
|
||||
NODE_TYPE_3D,
|
||||
NODE_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum SelectMode {
|
||||
SELECT_MODE_SINGLE,
|
||||
SELECT_MODE_LIST,
|
||||
SELECT_MODE_MAX,
|
||||
};
|
||||
|
||||
private:
|
||||
friend class SceneDebugger;
|
||||
|
||||
NodeType node_select_type = NODE_TYPE_2D;
|
||||
SelectMode node_select_mode = SELECT_MODE_SINGLE;
|
||||
|
||||
struct SelectResult {
|
||||
Node *item = nullptr;
|
||||
real_t order = 0;
|
||||
_FORCE_INLINE_ bool operator<(const SelectResult &p_rr) const { return p_rr.order < order; }
|
||||
};
|
||||
|
||||
const int SELECTION_MIN_AREA = 8 * 8;
|
||||
enum SelectionDragState {
|
||||
SELECTION_DRAG_NONE,
|
||||
SELECTION_DRAG_MOVE,
|
||||
SELECTION_DRAG_END,
|
||||
};
|
||||
SelectionDragState selection_drag_state = SELECTION_DRAG_NONE;
|
||||
|
||||
bool has_selection = false;
|
||||
int max_selection = 1;
|
||||
Point2 selection_position = Point2(Math::INF, Math::INF);
|
||||
Rect2 selection_drag_area;
|
||||
PopupMenu *selection_list = nullptr;
|
||||
Color selection_area_fill;
|
||||
Color selection_area_outline;
|
||||
bool selection_visible = true;
|
||||
bool selection_update_queued = false;
|
||||
|
||||
bool avoid_locked_nodes = false;
|
||||
bool prefer_group_selection = false;
|
||||
|
||||
bool multi_shortcut_pressed = false;
|
||||
bool list_shortcut_pressed = false;
|
||||
RID draw_canvas;
|
||||
RID sel_drag_ci;
|
||||
|
||||
bool camera_override = false;
|
||||
bool camera_first_override = true;
|
||||
|
||||
// Values taken from EditorZoomWidget.
|
||||
const float VIEW_2D_MIN_ZOOM = 1.0 / 128;
|
||||
const float VIEW_2D_MAX_ZOOM = 128;
|
||||
|
||||
Ref<ViewPanner> panner;
|
||||
Vector2 view_2d_offset;
|
||||
real_t view_2d_zoom = 1.0;
|
||||
bool warped_panning = false;
|
||||
|
||||
LocalVector<ObjectID> selected_ci_nodes;
|
||||
real_t sel_2d_grab_dist = 0;
|
||||
int sel_2d_scale = 1;
|
||||
|
||||
RID sbox_2d_ci;
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
struct Cursor {
|
||||
Vector3 pos;
|
||||
real_t x_rot, y_rot, distance, fov_scale;
|
||||
Vector3 eye_pos; // Used in freelook mode.
|
||||
|
||||
Cursor() {
|
||||
// These rotations place the camera in +X +Y +Z, aka south east, facing north west.
|
||||
x_rot = 0.5;
|
||||
y_rot = -0.5;
|
||||
distance = 4;
|
||||
fov_scale = 1.0;
|
||||
}
|
||||
};
|
||||
Cursor cursor;
|
||||
|
||||
// Values taken from Node3DEditor.
|
||||
const float VIEW_3D_MIN_ZOOM = 0.01;
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
const double VIEW_3D_MAX_ZOOM = 1'000'000'000'000;
|
||||
#else
|
||||
const float VIEW_3D_MAX_ZOOM = 10'000;
|
||||
#endif // REAL_T_IS_DOUBLE
|
||||
|
||||
const float CAMERA_MIN_FOV_SCALE = 0.1;
|
||||
const float CAMERA_MAX_FOV_SCALE = 2.5;
|
||||
|
||||
bool camera_freelook = false;
|
||||
|
||||
real_t camera_fov = 0;
|
||||
real_t camera_znear = 0;
|
||||
real_t camera_zfar = 0;
|
||||
|
||||
bool invert_x_axis = false;
|
||||
bool invert_y_axis = false;
|
||||
bool warped_mouse_panning_3d = false;
|
||||
|
||||
real_t freelook_base_speed = 0;
|
||||
real_t freelook_sensitivity = 0;
|
||||
real_t orbit_sensitivity = 0;
|
||||
real_t translation_sensitivity = 0;
|
||||
|
||||
Vector2 previous_mouse_position;
|
||||
|
||||
struct SelectionBox3D : public RefCounted {
|
||||
RID instance;
|
||||
RID instance_ofs;
|
||||
RID instance_xray;
|
||||
RID instance_xray_ofs;
|
||||
|
||||
Transform3D transform;
|
||||
AABB bounds;
|
||||
|
||||
~SelectionBox3D() {
|
||||
if (instance.is_valid()) {
|
||||
RS::get_singleton()->free_rid(instance);
|
||||
RS::get_singleton()->free_rid(instance_ofs);
|
||||
RS::get_singleton()->free_rid(instance_xray);
|
||||
RS::get_singleton()->free_rid(instance_xray_ofs);
|
||||
}
|
||||
}
|
||||
};
|
||||
HashMap<ObjectID, Ref<SelectionBox3D>> selected_3d_nodes;
|
||||
|
||||
Color sbox_3d_color;
|
||||
Ref<ArrayMesh> sbox_3d_mesh;
|
||||
Ref<ArrayMesh> sbox_3d_mesh_xray;
|
||||
RID sbox_3d;
|
||||
RID sbox_3d_ofs;
|
||||
RID sbox_3d_xray;
|
||||
RID sbox_3d_xray_ofs;
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
void _setup(const Dictionary &p_settings);
|
||||
|
||||
void _node_set_type(NodeType p_type);
|
||||
void _select_set_mode(SelectMode p_mode);
|
||||
|
||||
void _set_camera_override_enabled(bool p_enabled);
|
||||
|
||||
void _root_window_input(const Ref<InputEvent> &p_event);
|
||||
void _items_popup_index_pressed(int p_index, PopupMenu *p_popup);
|
||||
void _update_input_state();
|
||||
|
||||
void _process_frame();
|
||||
void _physics_frame();
|
||||
|
||||
void _send_ids(const Vector<Node *> &p_picked_nodes, bool p_invert_new_selections = true);
|
||||
void _set_selected_nodes(const Vector<Node *> &p_nodes);
|
||||
void _queue_selection_update();
|
||||
void _update_selection();
|
||||
void _clear_selection();
|
||||
void _update_selection_drag(const Point2 &p_end_pos = Point2());
|
||||
void _set_selection_visible(bool p_visible);
|
||||
void _set_avoid_locked(bool p_enabled);
|
||||
void _set_prefer_group(bool p_enabled);
|
||||
|
||||
void _open_selection_list(const Vector<SelectResult> &p_items, const Point2 &p_pos);
|
||||
void _close_selection_list();
|
||||
|
||||
void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<SelectResult> &r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
|
||||
void _find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_node, Vector<SelectResult> &r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
|
||||
void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event);
|
||||
void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event);
|
||||
void _reset_camera_2d();
|
||||
void _update_view_2d();
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
void _find_3d_items_at_pos(const Point2 &p_pos, Vector<SelectResult> &r_items);
|
||||
void _find_3d_items_at_rect(const Rect2 &p_rect, Vector<SelectResult> &r_items);
|
||||
Vector3 _get_screen_to_space(const Vector3 &p_vector3);
|
||||
|
||||
bool _handle_3d_input(const Ref<InputEvent> &p_event);
|
||||
void _set_camera_freelook_enabled(bool p_enabled);
|
||||
void _cursor_scale_distance(real_t p_scale);
|
||||
void _scale_freelook_speed(real_t p_scale);
|
||||
void _cursor_look(Ref<InputEventWithModifiers> p_event);
|
||||
void _cursor_pan(Ref<InputEventWithModifiers> p_event);
|
||||
void _cursor_orbit(Ref<InputEventWithModifiers> p_event);
|
||||
Point2 _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_event, Rect2 p_border) const;
|
||||
Transform3D _get_cursor_transform();
|
||||
void _reset_camera_3d();
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
RuntimeNodeSelect() { singleton = this; }
|
||||
|
||||
inline static RuntimeNodeSelect *singleton = nullptr;
|
||||
|
||||
public:
|
||||
static RuntimeNodeSelect *get_singleton();
|
||||
|
||||
~RuntimeNodeSelect();
|
||||
};
|
||||
#endif // DEBUG_ENABLED
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -33,12 +33,7 @@
|
|||
#include "core/input/shortcut.h"
|
||||
#include "core/object/ref_counted.h"
|
||||
#include "core/string/ustring.h"
|
||||
#include "core/templates/pair.h"
|
||||
#include "core/variant/array.h"
|
||||
#include "scene/gui/view_panner.h"
|
||||
#ifndef _3D_DISABLED
|
||||
#include "scene/resources/mesh.h"
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
class CanvasItem;
|
||||
class LiveEditor;
|
||||
|
|
@ -46,9 +41,6 @@ class PopupMenu;
|
|||
class RuntimeNodeSelect;
|
||||
class Script;
|
||||
class SceneTree;
|
||||
#ifndef _3D_DISABLED
|
||||
class Node3D;
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
class SceneDebugger {
|
||||
private:
|
||||
|
|
@ -135,62 +127,6 @@ public:
|
|||
};
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
class SceneDebuggerObject {
|
||||
private:
|
||||
void _parse_script_properties(Script *p_script, ScriptInstance *p_instance);
|
||||
|
||||
public:
|
||||
typedef Pair<PropertyInfo, Variant> SceneDebuggerProperty;
|
||||
ObjectID id;
|
||||
String class_name;
|
||||
List<SceneDebuggerProperty> properties;
|
||||
|
||||
SceneDebuggerObject(ObjectID p_id);
|
||||
SceneDebuggerObject(Object *p_obj);
|
||||
SceneDebuggerObject() {}
|
||||
|
||||
void serialize(Array &r_arr, int p_max_size = 1 << 20);
|
||||
void deserialize(const Array &p_arr);
|
||||
void deserialize(uint64_t p_id, const String &p_class_name, const Array &p_props);
|
||||
};
|
||||
|
||||
class SceneDebuggerTree {
|
||||
public:
|
||||
struct RemoteNode {
|
||||
int child_count = 0;
|
||||
String name;
|
||||
String type_name;
|
||||
ObjectID id;
|
||||
String scene_file_path;
|
||||
uint8_t view_flags = 0;
|
||||
|
||||
enum ViewFlags {
|
||||
VIEW_HAS_VISIBLE_METHOD = 1 << 1,
|
||||
VIEW_VISIBLE = 1 << 2,
|
||||
VIEW_VISIBLE_IN_TREE = 1 << 3,
|
||||
};
|
||||
|
||||
RemoteNode(int p_child, const String &p_name, const String &p_type, ObjectID p_id, const String p_scene_file_path, int p_view_flags) {
|
||||
child_count = p_child;
|
||||
name = p_name;
|
||||
type_name = p_type;
|
||||
id = p_id;
|
||||
|
||||
scene_file_path = p_scene_file_path;
|
||||
view_flags = p_view_flags;
|
||||
}
|
||||
|
||||
RemoteNode() {}
|
||||
};
|
||||
|
||||
List<RemoteNode> nodes;
|
||||
|
||||
void serialize(Array &r_arr);
|
||||
void deserialize(const Array &p_arr);
|
||||
SceneDebuggerTree(Node *p_root);
|
||||
SceneDebuggerTree() {}
|
||||
};
|
||||
|
||||
class LiveEditor {
|
||||
private:
|
||||
friend class SceneDebugger;
|
||||
|
|
@ -234,211 +170,4 @@ private:
|
|||
public:
|
||||
static LiveEditor *get_singleton();
|
||||
};
|
||||
|
||||
class RuntimeNodeSelect : public Object {
|
||||
GDCLASS(RuntimeNodeSelect, Object);
|
||||
|
||||
public:
|
||||
enum NodeType {
|
||||
NODE_TYPE_NONE,
|
||||
NODE_TYPE_2D,
|
||||
NODE_TYPE_3D,
|
||||
NODE_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum SelectMode {
|
||||
SELECT_MODE_SINGLE,
|
||||
SELECT_MODE_LIST,
|
||||
SELECT_MODE_MAX,
|
||||
};
|
||||
|
||||
private:
|
||||
friend class SceneDebugger;
|
||||
|
||||
NodeType node_select_type = NODE_TYPE_2D;
|
||||
SelectMode node_select_mode = SELECT_MODE_SINGLE;
|
||||
|
||||
struct SelectResult {
|
||||
Node *item = nullptr;
|
||||
real_t order = 0;
|
||||
_FORCE_INLINE_ bool operator<(const SelectResult &p_rr) const { return p_rr.order < order; }
|
||||
};
|
||||
|
||||
const int SELECTION_MIN_AREA = 8 * 8;
|
||||
enum SelectionDragState {
|
||||
SELECTION_DRAG_NONE,
|
||||
SELECTION_DRAG_MOVE,
|
||||
SELECTION_DRAG_END,
|
||||
};
|
||||
SelectionDragState selection_drag_state = SELECTION_DRAG_NONE;
|
||||
|
||||
bool has_selection = false;
|
||||
int max_selection = 1;
|
||||
Point2 selection_position = Point2(Math::INF, Math::INF);
|
||||
Rect2 selection_drag_area;
|
||||
PopupMenu *selection_list = nullptr;
|
||||
Color selection_area_fill;
|
||||
Color selection_area_outline;
|
||||
bool selection_visible = true;
|
||||
bool selection_update_queued = false;
|
||||
|
||||
bool avoid_locked_nodes = false;
|
||||
bool prefer_group_selection = false;
|
||||
|
||||
bool multi_shortcut_pressed = false;
|
||||
bool list_shortcut_pressed = false;
|
||||
RID draw_canvas;
|
||||
RID sel_drag_ci;
|
||||
|
||||
bool camera_override = false;
|
||||
bool camera_first_override = true;
|
||||
|
||||
// Values taken from EditorZoomWidget.
|
||||
const float VIEW_2D_MIN_ZOOM = 1.0 / 128;
|
||||
const float VIEW_2D_MAX_ZOOM = 128;
|
||||
|
||||
Ref<ViewPanner> panner;
|
||||
Vector2 view_2d_offset;
|
||||
real_t view_2d_zoom = 1.0;
|
||||
bool warped_panning = false;
|
||||
|
||||
LocalVector<ObjectID> selected_ci_nodes;
|
||||
real_t sel_2d_grab_dist = 0;
|
||||
int sel_2d_scale = 1;
|
||||
|
||||
RID sbox_2d_ci;
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
struct Cursor {
|
||||
Vector3 pos;
|
||||
real_t x_rot, y_rot, distance, fov_scale;
|
||||
Vector3 eye_pos; // Used in freelook mode.
|
||||
|
||||
Cursor() {
|
||||
// These rotations place the camera in +X +Y +Z, aka south east, facing north west.
|
||||
x_rot = 0.5;
|
||||
y_rot = -0.5;
|
||||
distance = 4;
|
||||
fov_scale = 1.0;
|
||||
}
|
||||
};
|
||||
Cursor cursor;
|
||||
|
||||
// Values taken from Node3DEditor.
|
||||
const float VIEW_3D_MIN_ZOOM = 0.01;
|
||||
#ifdef REAL_T_IS_DOUBLE
|
||||
const double VIEW_3D_MAX_ZOOM = 1'000'000'000'000;
|
||||
#else
|
||||
const float VIEW_3D_MAX_ZOOM = 10'000;
|
||||
#endif // REAL_T_IS_DOUBLE
|
||||
|
||||
const float CAMERA_MIN_FOV_SCALE = 0.1;
|
||||
const float CAMERA_MAX_FOV_SCALE = 2.5;
|
||||
|
||||
bool camera_freelook = false;
|
||||
|
||||
real_t camera_fov = 0;
|
||||
real_t camera_znear = 0;
|
||||
real_t camera_zfar = 0;
|
||||
|
||||
bool invert_x_axis = false;
|
||||
bool invert_y_axis = false;
|
||||
bool warped_mouse_panning_3d = false;
|
||||
|
||||
real_t freelook_base_speed = 0;
|
||||
real_t freelook_sensitivity = 0;
|
||||
real_t orbit_sensitivity = 0;
|
||||
real_t translation_sensitivity = 0;
|
||||
|
||||
Vector2 previous_mouse_position;
|
||||
|
||||
struct SelectionBox3D : public RefCounted {
|
||||
RID instance;
|
||||
RID instance_ofs;
|
||||
RID instance_xray;
|
||||
RID instance_xray_ofs;
|
||||
|
||||
Transform3D transform;
|
||||
AABB bounds;
|
||||
|
||||
~SelectionBox3D() {
|
||||
if (instance.is_valid()) {
|
||||
RS::get_singleton()->free_rid(instance);
|
||||
RS::get_singleton()->free_rid(instance_ofs);
|
||||
RS::get_singleton()->free_rid(instance_xray);
|
||||
RS::get_singleton()->free_rid(instance_xray_ofs);
|
||||
}
|
||||
}
|
||||
};
|
||||
HashMap<ObjectID, Ref<SelectionBox3D>> selected_3d_nodes;
|
||||
|
||||
Color sbox_3d_color;
|
||||
Ref<ArrayMesh> sbox_3d_mesh;
|
||||
Ref<ArrayMesh> sbox_3d_mesh_xray;
|
||||
RID sbox_3d;
|
||||
RID sbox_3d_ofs;
|
||||
RID sbox_3d_xray;
|
||||
RID sbox_3d_xray_ofs;
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
void _setup(const Dictionary &p_settings);
|
||||
|
||||
void _node_set_type(NodeType p_type);
|
||||
void _select_set_mode(SelectMode p_mode);
|
||||
|
||||
void _set_camera_override_enabled(bool p_enabled);
|
||||
|
||||
void _root_window_input(const Ref<InputEvent> &p_event);
|
||||
void _items_popup_index_pressed(int p_index, PopupMenu *p_popup);
|
||||
void _update_input_state();
|
||||
|
||||
void _process_frame();
|
||||
void _physics_frame();
|
||||
|
||||
void _send_ids(const Vector<Node *> &p_picked_nodes, bool p_invert_new_selections = true);
|
||||
void _set_selected_nodes(const Vector<Node *> &p_nodes);
|
||||
void _queue_selection_update();
|
||||
void _update_selection();
|
||||
void _clear_selection();
|
||||
void _update_selection_drag(const Point2 &p_end_pos = Point2());
|
||||
void _set_selection_visible(bool p_visible);
|
||||
void _set_avoid_locked(bool p_enabled);
|
||||
void _set_prefer_group(bool p_enabled);
|
||||
|
||||
void _open_selection_list(const Vector<SelectResult> &p_items, const Point2 &p_pos);
|
||||
void _close_selection_list();
|
||||
|
||||
void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<SelectResult> &r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
|
||||
void _find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_node, Vector<SelectResult> &r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
|
||||
void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event);
|
||||
void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event);
|
||||
void _reset_camera_2d();
|
||||
void _update_view_2d();
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
void _find_3d_items_at_pos(const Point2 &p_pos, Vector<SelectResult> &r_items);
|
||||
void _find_3d_items_at_rect(const Rect2 &p_rect, Vector<SelectResult> &r_items);
|
||||
Vector3 _get_screen_to_space(const Vector3 &p_vector3);
|
||||
|
||||
bool _handle_3d_input(const Ref<InputEvent> &p_event);
|
||||
void _set_camera_freelook_enabled(bool p_enabled);
|
||||
void _cursor_scale_distance(real_t p_scale);
|
||||
void _scale_freelook_speed(real_t p_scale);
|
||||
void _cursor_look(Ref<InputEventWithModifiers> p_event);
|
||||
void _cursor_pan(Ref<InputEventWithModifiers> p_event);
|
||||
void _cursor_orbit(Ref<InputEventWithModifiers> p_event);
|
||||
Point2 _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_event, Rect2 p_border) const;
|
||||
Transform3D _get_cursor_transform();
|
||||
void _reset_camera_3d();
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
RuntimeNodeSelect() { singleton = this; }
|
||||
|
||||
inline static RuntimeNodeSelect *singleton = nullptr;
|
||||
|
||||
public:
|
||||
static RuntimeNodeSelect *get_singleton();
|
||||
|
||||
~RuntimeNodeSelect();
|
||||
};
|
||||
#endif // DEBUG_ENABLED
|
||||
|
|
|
|||
|
|
@ -0,0 +1,319 @@
|
|||
/**************************************************************************/
|
||||
/* scene_debugger_object.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
#include "scene_debugger_object.h"
|
||||
|
||||
#include "core/io/marshalls.h"
|
||||
#include "core/object/script_language.h"
|
||||
|
||||
SceneDebuggerObject::SceneDebuggerObject(Object *p_obj) {
|
||||
if (!p_obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
id = p_obj->get_instance_id();
|
||||
class_name = p_obj->get_class();
|
||||
|
||||
if (ScriptInstance *si = p_obj->get_script_instance()) {
|
||||
// Read script instance constants and variables.
|
||||
if (!si->get_script().is_null()) {
|
||||
Script *s = si->get_script().ptr();
|
||||
_parse_script_properties(s, si);
|
||||
}
|
||||
}
|
||||
|
||||
if (Node *node = Object::cast_to<Node>(p_obj)) {
|
||||
// For debugging multiplayer.
|
||||
{
|
||||
PropertyInfo pi(Variant::INT, String("Node/multiplayer_authority"), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY);
|
||||
properties.push_back(SceneDebuggerProperty(pi, node->get_multiplayer_authority()));
|
||||
}
|
||||
|
||||
// Add specialized NodePath info (if inside tree).
|
||||
if (node->is_inside_tree()) {
|
||||
PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
|
||||
properties.push_back(SceneDebuggerProperty(pi, node->get_path()));
|
||||
} else { // Can't ask for path if a node is not in tree.
|
||||
PropertyInfo pi(Variant::STRING, String("Node/path"));
|
||||
properties.push_back(SceneDebuggerProperty(pi, "[Orphan]"));
|
||||
}
|
||||
} else if (Script *s = Object::cast_to<Script>(p_obj)) {
|
||||
// Add script constants (no instance).
|
||||
_parse_script_properties(s, nullptr);
|
||||
}
|
||||
|
||||
// Add base object properties.
|
||||
List<PropertyInfo> pinfo;
|
||||
p_obj->get_property_list(&pinfo, true);
|
||||
for (const PropertyInfo &E : pinfo) {
|
||||
if (E.usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) {
|
||||
properties.push_back(SceneDebuggerProperty(E, p_obj->get(E.name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneDebuggerObject::_parse_script_properties(Script *p_script, ScriptInstance *p_instance) {
|
||||
typedef HashMap<const Script *, HashSet<StringName>> ScriptMemberMap;
|
||||
typedef HashMap<const Script *, HashMap<StringName, Variant>> ScriptConstantsMap;
|
||||
|
||||
ScriptMemberMap members;
|
||||
if (p_instance) {
|
||||
members[p_script] = HashSet<StringName>();
|
||||
p_script->get_members(&(members[p_script]));
|
||||
}
|
||||
|
||||
ScriptConstantsMap constants;
|
||||
constants[p_script] = HashMap<StringName, Variant>();
|
||||
p_script->get_constants(&(constants[p_script]));
|
||||
|
||||
Ref<Script> base = p_script->get_base_script();
|
||||
while (base.is_valid()) {
|
||||
if (p_instance) {
|
||||
members[base.ptr()] = HashSet<StringName>();
|
||||
base->get_members(&(members[base.ptr()]));
|
||||
}
|
||||
|
||||
constants[base.ptr()] = HashMap<StringName, Variant>();
|
||||
base->get_constants(&(constants[base.ptr()]));
|
||||
|
||||
base = base->get_base_script();
|
||||
}
|
||||
|
||||
HashSet<String> exported_members;
|
||||
|
||||
if (p_instance) {
|
||||
List<PropertyInfo> pinfo;
|
||||
p_instance->get_property_list(&pinfo);
|
||||
for (const PropertyInfo &E : pinfo) {
|
||||
if (E.usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) {
|
||||
exported_members.insert(E.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Members
|
||||
for (KeyValue<const Script *, HashSet<StringName>> sm : members) {
|
||||
for (const StringName &E : sm.value) {
|
||||
if (exported_members.has(E)) {
|
||||
continue; // Exported variables already show up in the inspector.
|
||||
}
|
||||
if (String(E).begins_with("@")) {
|
||||
continue; // Skip groups.
|
||||
}
|
||||
|
||||
Variant m;
|
||||
if (p_instance->get(E, m)) {
|
||||
String script_path = sm.key == p_script ? "" : sm.key->get_path().get_file() + "/";
|
||||
PropertyInfo pi(m.get_type(), "Members/" + script_path + E);
|
||||
properties.push_back(SceneDebuggerProperty(pi, m));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Constants
|
||||
for (KeyValue<const Script *, HashMap<StringName, Variant>> &sc : constants) {
|
||||
for (const KeyValue<StringName, Variant> &E : sc.value) {
|
||||
String script_path = sc.key == p_script ? "" : sc.key->get_path().get_file() + "/";
|
||||
if (E.value.get_type() == Variant::OBJECT) {
|
||||
Variant inst_id = ((Object *)E.value)->get_instance_id();
|
||||
PropertyInfo pi(inst_id.get_type(), "Constants/" + E.key, PROPERTY_HINT_OBJECT_ID, "Object");
|
||||
properties.push_back(SceneDebuggerProperty(pi, inst_id));
|
||||
} else {
|
||||
PropertyInfo pi(E.value.get_type(), "Constants/" + script_path + E.key);
|
||||
properties.push_back(SceneDebuggerProperty(pi, E.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneDebuggerObject::serialize(Array &r_arr, int p_max_size) {
|
||||
Array send_props;
|
||||
for (SceneDebuggerProperty &property : properties) {
|
||||
const PropertyInfo &pi = property.first;
|
||||
Variant &var = property.second;
|
||||
|
||||
Ref<Resource> res = var;
|
||||
|
||||
Array prop = { pi.name, pi.type };
|
||||
PropertyHint hint = pi.hint;
|
||||
String hint_string = pi.hint_string;
|
||||
if (res.is_valid() && !res->get_path().is_empty()) {
|
||||
var = res->get_path();
|
||||
} else { //only send information that can be sent..
|
||||
int len = 0; //test how big is this to encode
|
||||
encode_variant(var, nullptr, len);
|
||||
if (len > p_max_size) { //limit to max size
|
||||
hint = PROPERTY_HINT_OBJECT_TOO_BIG;
|
||||
hint_string = "";
|
||||
var = Variant();
|
||||
}
|
||||
}
|
||||
prop.push_back(hint);
|
||||
prop.push_back(hint_string);
|
||||
prop.push_back(pi.usage);
|
||||
prop.push_back(var);
|
||||
send_props.push_back(prop);
|
||||
}
|
||||
r_arr.push_back(uint64_t(id));
|
||||
r_arr.push_back(class_name);
|
||||
r_arr.push_back(send_props);
|
||||
}
|
||||
|
||||
#define CHECK_TYPE(p_what, p_type) ERR_FAIL_COND(p_what.get_type() != Variant::p_type)
|
||||
|
||||
void SceneDebuggerObject::deserialize(const Array &p_arr) {
|
||||
ERR_FAIL_COND(p_arr.size() < 3);
|
||||
CHECK_TYPE(p_arr[0], INT);
|
||||
CHECK_TYPE(p_arr[1], STRING);
|
||||
CHECK_TYPE(p_arr[2], ARRAY);
|
||||
|
||||
deserialize(uint64_t(p_arr[0]), p_arr[1], p_arr[2]);
|
||||
}
|
||||
|
||||
void SceneDebuggerObject::deserialize(uint64_t p_id, const String &p_class_name, const Array &p_props) {
|
||||
id = p_id;
|
||||
class_name = p_class_name;
|
||||
|
||||
for (int i = 0; i < p_props.size(); i++) {
|
||||
CHECK_TYPE(p_props[i], ARRAY);
|
||||
Array prop = p_props[i];
|
||||
|
||||
ERR_FAIL_COND(prop.size() != 6);
|
||||
CHECK_TYPE(prop[0], STRING);
|
||||
CHECK_TYPE(prop[1], INT);
|
||||
CHECK_TYPE(prop[2], INT);
|
||||
CHECK_TYPE(prop[3], STRING);
|
||||
CHECK_TYPE(prop[4], INT);
|
||||
|
||||
PropertyInfo pinfo;
|
||||
pinfo.name = prop[0];
|
||||
pinfo.type = Variant::Type(int(prop[1]));
|
||||
pinfo.hint = PropertyHint(int(prop[2]));
|
||||
pinfo.hint_string = prop[3];
|
||||
pinfo.usage = PropertyUsageFlags(int(prop[4]));
|
||||
Variant var = prop[5];
|
||||
|
||||
if (pinfo.type == Variant::OBJECT) {
|
||||
if (var.is_zero()) {
|
||||
var = Ref<Resource>();
|
||||
} else if (var.get_type() == Variant::OBJECT) {
|
||||
if (((Object *)var)->is_class("EncodedObjectAsID")) {
|
||||
var = Object::cast_to<EncodedObjectAsID>(var)->get_object_id();
|
||||
pinfo.type = var.get_type();
|
||||
pinfo.hint = PROPERTY_HINT_OBJECT_ID;
|
||||
pinfo.hint_string = "Object";
|
||||
}
|
||||
}
|
||||
}
|
||||
properties.push_back(SceneDebuggerProperty(pinfo, var));
|
||||
}
|
||||
}
|
||||
|
||||
SceneDebuggerTree::SceneDebuggerTree(Node *p_root) {
|
||||
// Flatten tree into list, depth first, use stack to avoid recursion.
|
||||
List<Node *> stack;
|
||||
stack.push_back(p_root);
|
||||
bool is_root = true;
|
||||
const StringName &is_visible_sn = SNAME("is_visible");
|
||||
const StringName &is_visible_in_tree_sn = SNAME("is_visible_in_tree");
|
||||
while (stack.size()) {
|
||||
Node *n = stack.front()->get();
|
||||
stack.pop_front();
|
||||
|
||||
int count = n->get_child_count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
stack.push_front(n->get_child(count - i - 1));
|
||||
}
|
||||
|
||||
int view_flags = 0;
|
||||
if (is_root) {
|
||||
// Prevent root window visibility from being changed.
|
||||
is_root = false;
|
||||
} else if (n->has_method(is_visible_sn)) {
|
||||
const Variant visible = n->call(is_visible_sn);
|
||||
if (visible.get_type() == Variant::BOOL) {
|
||||
view_flags = RemoteNode::VIEW_HAS_VISIBLE_METHOD;
|
||||
view_flags |= uint8_t(visible) * RemoteNode::VIEW_VISIBLE;
|
||||
}
|
||||
if (n->has_method(is_visible_in_tree_sn)) {
|
||||
const Variant visible_in_tree = n->call(is_visible_in_tree_sn);
|
||||
if (visible_in_tree.get_type() == Variant::BOOL) {
|
||||
view_flags |= uint8_t(visible_in_tree) * RemoteNode::VIEW_VISIBLE_IN_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String class_name;
|
||||
ScriptInstance *script_instance = n->get_script_instance();
|
||||
if (script_instance) {
|
||||
Ref<Script> script = script_instance->get_script();
|
||||
if (script.is_valid()) {
|
||||
class_name = script->get_global_name();
|
||||
|
||||
if (class_name.is_empty()) {
|
||||
// If there is no class_name in this script we just take the script path.
|
||||
class_name = script->get_path();
|
||||
}
|
||||
}
|
||||
}
|
||||
nodes.push_back(RemoteNode(count, n->get_name(), class_name.is_empty() ? n->get_class() : class_name, n->get_instance_id(), n->get_scene_file_path(), view_flags));
|
||||
}
|
||||
}
|
||||
|
||||
void SceneDebuggerTree::serialize(Array &p_arr) {
|
||||
for (const RemoteNode &n : nodes) {
|
||||
p_arr.push_back(n.child_count);
|
||||
p_arr.push_back(n.name);
|
||||
p_arr.push_back(n.type_name);
|
||||
p_arr.push_back(n.id);
|
||||
p_arr.push_back(n.scene_file_path);
|
||||
p_arr.push_back(n.view_flags);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneDebuggerTree::deserialize(const Array &p_arr) {
|
||||
int idx = 0;
|
||||
while (p_arr.size() > idx) {
|
||||
ERR_FAIL_COND(p_arr.size() < 6);
|
||||
CHECK_TYPE(p_arr[idx], INT); // child_count.
|
||||
CHECK_TYPE(p_arr[idx + 1], STRING); // name.
|
||||
CHECK_TYPE(p_arr[idx + 2], STRING); // type_name.
|
||||
CHECK_TYPE(p_arr[idx + 3], INT); // id.
|
||||
CHECK_TYPE(p_arr[idx + 4], STRING); // scene_file_path.
|
||||
CHECK_TYPE(p_arr[idx + 5], INT); // view_flags.
|
||||
nodes.push_back(RemoteNode(p_arr[idx], p_arr[idx + 1], p_arr[idx + 2], p_arr[idx + 3], p_arr[idx + 4], p_arr[idx + 5]));
|
||||
idx += 6;
|
||||
}
|
||||
}
|
||||
|
||||
#undef CHECK_TYPE
|
||||
|
||||
#endif // DEBUG_ENABLED
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/**************************************************************************/
|
||||
/* scene_debugger_object.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
#include "scene/main/node.h"
|
||||
|
||||
class SceneDebuggerObject {
|
||||
private:
|
||||
void _parse_script_properties(Script *p_script, ScriptInstance *p_instance);
|
||||
|
||||
public:
|
||||
typedef Pair<PropertyInfo, Variant> SceneDebuggerProperty;
|
||||
ObjectID id;
|
||||
String class_name;
|
||||
List<SceneDebuggerProperty> properties;
|
||||
|
||||
SceneDebuggerObject(ObjectID p_id);
|
||||
SceneDebuggerObject(Object *p_obj);
|
||||
SceneDebuggerObject() {}
|
||||
|
||||
void serialize(Array &r_arr, int p_max_size = 1 << 20);
|
||||
void deserialize(const Array &p_arr);
|
||||
void deserialize(uint64_t p_id, const String &p_class_name, const Array &p_props);
|
||||
};
|
||||
|
||||
class SceneDebuggerTree {
|
||||
public:
|
||||
struct RemoteNode {
|
||||
int child_count = 0;
|
||||
String name;
|
||||
String type_name;
|
||||
ObjectID id;
|
||||
String scene_file_path;
|
||||
uint8_t view_flags = 0;
|
||||
|
||||
enum ViewFlags {
|
||||
VIEW_HAS_VISIBLE_METHOD = 1 << 1,
|
||||
VIEW_VISIBLE = 1 << 2,
|
||||
VIEW_VISIBLE_IN_TREE = 1 << 3,
|
||||
};
|
||||
|
||||
RemoteNode(int p_child, const String &p_name, const String &p_type, ObjectID p_id, const String p_scene_file_path, int p_view_flags) {
|
||||
child_count = p_child;
|
||||
name = p_name;
|
||||
type_name = p_type;
|
||||
id = p_id;
|
||||
|
||||
scene_file_path = p_scene_file_path;
|
||||
view_flags = p_view_flags;
|
||||
}
|
||||
|
||||
RemoteNode() {}
|
||||
};
|
||||
|
||||
List<RemoteNode> nodes;
|
||||
|
||||
void serialize(Array &r_arr);
|
||||
void deserialize(const Array &p_arr);
|
||||
SceneDebuggerTree(Node *p_root);
|
||||
SceneDebuggerTree() {}
|
||||
};
|
||||
#endif // DEBUG_ENABLED
|
||||
Loading…
Reference in New Issue