diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 843267d673d3..a9264015588a 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -479,15 +479,6 @@ void EditorPlugin::notify_resource_saved(const Ref &p_resource) { emit_signal("resource_saved", p_resource); } -Ref EditorPlugin::create_spatial_gizmo(Spatial *p_spatial) { - //?? - if (get_script_instance() && get_script_instance()->has_method("create_spatial_gizmo")) { - return get_script_instance()->call("create_spatial_gizmo", p_spatial); - } - - return Ref(); -} - bool EditorPlugin::forward_canvas_gui_input(const Ref &p_event) { if (get_script_instance() && get_script_instance()->has_method("forward_canvas_gui_input")) { @@ -765,10 +756,6 @@ void EditorPlugin::_bind_methods() { ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); - MethodInfo gizmo = MethodInfo(Variant::OBJECT, "create_spatial_gizmo", PropertyInfo(Variant::OBJECT, "for_spatial", PROPERTY_HINT_RESOURCE_TYPE, "Spatial")); - gizmo.return_val.hint = PROPERTY_HINT_RESOURCE_TYPE; - gizmo.return_val.hint_string = "EditorSpatialGizmo"; - ClassDB::add_virtual_method(get_class_static(), gizmo); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_plugin_name")); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::OBJECT, "get_plugin_icon")); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "has_main_screen")); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 72e21b2f7fea..c417f487dc6d 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -51,7 +51,6 @@ class Camera; class EditorSelection; class EditorExport; class EditorSettings; -class SpatialEditorGizmo; class EditorImportPlugin; class EditorExportPlugin; class EditorResourcePreview; @@ -171,7 +170,6 @@ class EditorPlugin : public Node { void notify_scene_closed(const String &scene_filepath); void notify_resource_saved(const Ref &p_resource); - virtual Ref create_spatial_gizmo(Spatial *p_spatial); virtual bool forward_canvas_gui_input(const Ref &p_event); virtual void forward_draw_over_viewport(Control *p_overlay); virtual void forward_force_draw_over_viewport(Control *p_overlay); diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp index 72a8b55a526e..618c70d1a140 100644 --- a/editor/plugins/path_editor_plugin.cpp +++ b/editor/plugins/path_editor_plugin.cpp @@ -215,6 +215,10 @@ void PathSpatialGizmo::redraw() { clear(); + Ref path_material = gizmo_plugin->get_material("path_material"); + Ref path_thin_material = gizmo_plugin->get_material("path_thin_material"); + Ref handles_material = gizmo_plugin->get_material("handles"); + Ref c = path->get_curve(); if (c.is_null()) return; @@ -238,7 +242,7 @@ void PathSpatialGizmo::redraw() { } if (v3p.size() > 1) { - add_lines(v3p, PathEditorPlugin::singleton->path_material); + add_lines(v3p, path_material); add_collision_segments(v3p); } @@ -265,13 +269,13 @@ void PathSpatialGizmo::redraw() { } if (v3p.size() > 1) { - add_lines(v3p, PathEditorPlugin::singleton->path_thin_material); + add_lines(v3p, path_thin_material); } if (handles.size()) { - add_handles(handles); + add_handles(handles, handles_material); } if (sec_handles.size()) { - add_handles(sec_handles, false, true); + add_handles(sec_handles, handles_material, false, true); } } } @@ -282,16 +286,6 @@ PathSpatialGizmo::PathSpatialGizmo(Path *p_path) { set_spatial_node(p_path); } -Ref PathEditorPlugin::create_spatial_gizmo(Spatial *p_spatial) { - - if (Object::cast_to(p_spatial)) { - - return memnew(PathSpatialGizmo(Object::cast_to(p_spatial))); - } - - return Ref(); -} - bool PathEditorPlugin::forward_spatial_gui_input(Camera *p_camera, const Ref &p_event) { if (!path) @@ -567,21 +561,9 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) { mirror_handle_angle = true; mirror_handle_length = true; - path_material = Ref(memnew(SpatialMaterial)); - path_material->set_albedo(Color(0.5, 0.5, 1.0, 0.8)); - path_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - path_material->set_line_width(3); - path_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); - path_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - - path_thin_material = Ref(memnew(SpatialMaterial)); - path_thin_material->set_albedo(Color(0.5, 0.5, 1.0, 0.4)); - path_thin_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - path_thin_material->set_line_width(1); - path_thin_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); - path_thin_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - - //SpatialEditor::get_singleton()->add_gizmo_plugin(this); + Ref gizmo_plugin; + gizmo_plugin.instance(); + SpatialEditor::get_singleton()->register_gizmo_plugin(gizmo_plugin); sep = memnew(VSeparator); sep->hide(); @@ -630,18 +612,53 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) { curve_edit->set_pressed(true); /* - collision_polygon_editor = memnew( PathEditor(p_node) ); - editor->get_viewport()->add_child(collision_polygon_editor); + collision_polygon_editor = memnew( PathEditor(p_node) ); + editor->get_viewport()->add_child(collision_polygon_editor); + collision_polygon_editor->set_margin(MARGIN_LEFT,200); + collision_polygon_editor->set_margin(MARGIN_RIGHT,230); + collision_polygon_editor->set_margin(MARGIN_TOP,0); + collision_polygon_editor->set_margin(MARGIN_BOTTOM,10); + collision_polygon_editor->hide(); + */ +} - collision_polygon_editor->set_margin(MARGIN_LEFT,200); - collision_polygon_editor->set_margin(MARGIN_RIGHT,230); - collision_polygon_editor->set_margin(MARGIN_TOP,0); - collision_polygon_editor->set_margin(MARGIN_BOTTOM,10); +PathEditorPlugin::~PathEditorPlugin() { +} + +Ref PathSpatialGizmoPlugin::create_gizmo(Spatial *p_spatial) { + Ref ref; + Path *path = Object::cast_to(p_spatial); + if (path) ref = Ref(memnew(PathSpatialGizmo(path))); - collision_polygon_editor->hide(); - */ + return ref; } -PathEditorPlugin::~PathEditorPlugin() { +String PathSpatialGizmoPlugin::get_name() const { + return "Path"; +} + +PathSpatialGizmoPlugin::PathSpatialGizmoPlugin() { + + Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8)); + + Ref path_material = Ref(memnew(SpatialMaterial)); + path_color.a = 0.8; + path_material->set_albedo(path_color); + path_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + path_material->set_line_width(3); + path_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); + path_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + + Ref path_thin_material = Ref(memnew(SpatialMaterial)); + path_color.a = 0.4; + path_thin_material->set_albedo(path_color); + path_thin_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + path_thin_material->set_line_width(1); + path_thin_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); + path_thin_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + + add_material("path_material", path_material); + add_material("path_thin_material", path_thin_material); + create_handle_material("handles"); } diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h index 52dfb78b6128..61f309e79455 100644 --- a/editor/plugins/path_editor_plugin.h +++ b/editor/plugins/path_editor_plugin.h @@ -49,10 +49,22 @@ class PathSpatialGizmo : public EditorSpatialGizmo { virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); - void redraw(); + virtual void redraw(); PathSpatialGizmo(Path *p_path = NULL); }; +class PathSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { + + GDCLASS(PathSpatialGizmoPlugin, EditorSpatialGizmoPlugin); + +protected: + Ref create_gizmo(Spatial *p_spatial); + +public: + String get_name() const; + PathSpatialGizmoPlugin(); +}; + class PathEditorPlugin : public EditorPlugin { GDCLASS(PathEditorPlugin, EditorPlugin); @@ -88,12 +100,10 @@ class PathEditorPlugin : public EditorPlugin { Path *get_edited_path() { return path; } static PathEditorPlugin *singleton; - Ref path_material; - Ref path_thin_material; virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref &p_event); //virtual bool forward_gui_input(const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } - virtual Ref create_spatial_gizmo(Spatial *p_spatial); + //virtual Ref create_spatial_gizmo(Spatial *p_spatial); virtual String get_name() const { return "Path"; } bool has_main_screen() const { return false; } virtual void edit(Object *p_object); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 47f10d977a03..8871d8ac7e13 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -184,49 +184,6 @@ Transform SpatialEditorViewport::to_camera_transform(const Cursor &p_cursor) con return camera_transform; } -String SpatialEditorGizmo::get_handle_name(int p_idx) const { - - if (get_script_instance() && get_script_instance()->has_method("get_handle_name")) - return get_script_instance()->call("get_handle_name", p_idx); - - return ""; -} - -Variant SpatialEditorGizmo::get_handle_value(int p_idx) const { - - if (get_script_instance() && get_script_instance()->has_method("get_handle_value")) - return get_script_instance()->call("get_handle_value", p_idx); - - return Variant(); -} - -void SpatialEditorGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { - - if (get_script_instance() && get_script_instance()->has_method("set_handle")) - get_script_instance()->call("set_handle", p_idx, p_camera, p_point); -} - -void SpatialEditorGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { - - if (get_script_instance() && get_script_instance()->has_method("commit_handle")) - get_script_instance()->call("commit_handle", p_idx, p_restore, p_cancel); -} - -bool SpatialEditorGizmo::intersect_frustum(const Camera *p_camera, const Vector &p_frustum) { - - return false; -} - -bool SpatialEditorGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) { - - return false; -} - -SpatialEditorGizmo::SpatialEditorGizmo() { - - selected = false; -} - int SpatialEditorViewport::get_selected_count() const { Map &selection = editor_selection->get_selection(); @@ -346,7 +303,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, Vector3 pos = _get_ray_pos(p_pos); Vector instances = VisualServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario()); - Set > found_gizmos; + Set > found_gizmos; Node *edited_scene = get_tree()->get_edited_scene_root(); ObjectID closest = 0; @@ -361,7 +318,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, if (!spat) continue; - Ref seg = spat->get_gizmo(); + Ref seg = spat->get_gizmo(); if ((!seg.is_valid()) || found_gizmos.has(seg)) { continue; @@ -418,7 +375,7 @@ void SpatialEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_incl Vector3 pos = _get_ray_pos(p_pos); Vector instances = VisualServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario()); - Set > found_gizmos; + Set > found_gizmos; r_includes_current = false; @@ -429,7 +386,7 @@ void SpatialEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_incl if (!spat) continue; - Ref seg = spat->get_gizmo(); + Ref seg = spat->get_gizmo(); if (!seg.is_valid()) continue; @@ -559,7 +516,7 @@ void SpatialEditorViewport::_select_region() { if (selected.find(root_sp) != -1) continue; - Ref seg = sp->get_gizmo(); + Ref seg = sp->get_gizmo(); if (!seg.is_valid()) continue; @@ -963,7 +920,7 @@ void SpatialEditorViewport::_sinput(const Ref &p_event) { if (b->is_pressed() && _edit.gizmo.is_valid()) { //restore _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, true); - _edit.gizmo = Ref(); + _edit.gizmo = Ref(); } if (_edit.mode == TRANSFORM_NONE && b->is_pressed()) { @@ -1079,7 +1036,7 @@ void SpatialEditorViewport::_sinput(const Ref &p_event) { if (can_select_gizmos && spatial_editor->get_selected()) { - Ref seg = spatial_editor->get_selected()->get_gizmo(); + Ref seg = spatial_editor->get_selected()->get_gizmo(); if (seg.is_valid()) { int handle = -1; Vector3 point; @@ -1158,7 +1115,7 @@ void SpatialEditorViewport::_sinput(const Ref &p_event) { Spatial *spa = Object::cast_to(ObjectDB::get_instance(clicked)); if (spa) { - Ref seg = spa->get_gizmo(); + Ref seg = spa->get_gizmo(); if (seg.is_valid()) { _edit.gizmo = seg; @@ -1175,7 +1132,7 @@ void SpatialEditorViewport::_sinput(const Ref &p_event) { if (_edit.gizmo.is_valid()) { _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, false); - _edit.gizmo = Ref(); + _edit.gizmo = Ref(); break; } if (clicked) { @@ -1233,7 +1190,7 @@ void SpatialEditorViewport::_sinput(const Ref &p_event) { if (spatial_editor->get_selected()) { - Ref seg = spatial_editor->get_selected()->get_gizmo(); + Ref seg = spatial_editor->get_selected()->get_gizmo(); if (seg.is_valid()) { int selected_handle = -1; @@ -3099,7 +3056,7 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const Vector3 world_pos = _get_ray_pos(p_pos); Vector instances = VisualServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world()->get_scenario()); - Set > found_gizmos; + Set > found_gizmos; float closest_dist = MAX_DISTANCE; @@ -3113,7 +3070,7 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const if (!mesh_instance) continue; - Ref seg = mesh_instance->get_gizmo(); + Ref seg = mesh_instance->get_gizmo(); if ((!seg.is_valid()) || found_gizmos.has(seg)) { continue; @@ -4048,6 +4005,16 @@ Dictionary SpatialEditor::get_state() const { d["znear"] = get_znear(); d["zfar"] = get_zfar(); + Dictionary gizmos_status; + for (int i = 0; i < gizmo_plugins.size(); i++) { + if (!gizmo_plugins[i]->can_be_hidden()) continue; + bool checked = gizmos_menu->get_popup()->is_item_checked(gizmos_menu->get_popup()->get_item_index(i)); + String name = gizmo_plugins[i]->get_name(); + gizmos_status[name] = checked; + } + + d["gizmos_status"] = gizmos_status; + return d; } void SpatialEditor::set_state(const Dictionary &p_state) { @@ -4121,6 +4088,24 @@ void SpatialEditor::set_state(const Dictionary &p_state) { VisualServer::get_singleton()->instance_set_visible(origin_instance, use); } } + + if (d.has("gizmos_status")) { + Dictionary gizmos_status = d["gizmos_status"]; + List keys; + gizmos_status.get_key_list(&keys); + + for (int j = 0; j < gizmo_plugins.size(); ++j) { + if (!gizmo_plugins[j]->can_be_hidden()) continue; + bool checked = true; + for (uint32_t i = 0; i < keys.size(); i++) { + if (gizmo_plugins.write[j]->get_name() == keys[i]) { + checked = gizmos_status[keys[i]]; + } + } + gizmos_menu->get_popup()->set_item_checked(gizmos_menu->get_popup()->get_item_index(j), checked); + gizmo_plugins.write[j]->set_hidden(!checked); + } + } } void SpatialEditor::edit(Spatial *p_spatial) { @@ -4128,7 +4113,7 @@ void SpatialEditor::edit(Spatial *p_spatial) { if (p_spatial != selected) { if (selected) { - Ref seg = selected->get_gizmo(); + Ref seg = selected->get_gizmo(); if (seg.is_valid()) { seg->set_selected(false); selected->update_gizmo(); @@ -4140,7 +4125,7 @@ void SpatialEditor::edit(Spatial *p_spatial) { if (selected) { - Ref seg = selected->get_gizmo(); + Ref seg = selected->get_gizmo(); if (seg.is_valid()) { seg->set_selected(true); selected->update_gizmo(); @@ -4214,6 +4199,15 @@ void SpatialEditor::_menu_item_toggled(bool pressed, int p_option) { } } +void SpatialEditor::_menu_gizmo_toggled(int p_option) { + bool is_checked = gizmos_menu->get_popup()->is_item_checked(gizmos_menu->get_popup()->get_item_index(p_option)); + + is_checked = !is_checked; + gizmo_plugins.write[p_option]->set_hidden(!is_checked); + + gizmos_menu->get_popup()->set_item_checked(gizmos_menu->get_popup()->get_item_index(p_option), is_checked); +} + void SpatialEditor::_menu_item_pressed(int p_option) { switch (p_option) { @@ -4725,6 +4719,27 @@ void SpatialEditor::_init_indicators() { _generate_selection_box(); } +struct _GizmoPluginComparator { + + bool operator()(const Ref &p_a, const Ref &p_b) const { + return p_a->get_name() < p_b->get_name(); + } +}; + +void SpatialEditor::_init_gizmos_menu() { + _register_all_gizmos(); + + PopupMenu *p = gizmos_menu->get_popup(); + + gizmo_plugins.sort_custom<_GizmoPluginComparator>(); + + for (int i = 0; i < gizmo_plugins.size(); ++i) { + if (!gizmo_plugins[i]->can_be_hidden()) continue; + String plugin_name = gizmo_plugins[i]->get_name(); + p->add_check_item(TTR(plugin_name), i); + } +} + void SpatialEditor::_init_grid() { PoolVector grid_colors[3]; @@ -5018,14 +5033,13 @@ void SpatialEditor::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - gizmos = memnew(SpatialEditorGizmos); + _init_gizmos_menu(); _init_indicators(); } if (p_what == NOTIFICATION_EXIT_TREE) { _finish_indicators(); - memdelete(gizmos); } if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { tool_button[SpatialEditor::TOOL_MODE_SELECT]->set_icon(get_icon("ToolSelect", "EditorIcons")); @@ -5084,25 +5098,21 @@ void SpatialEditor::_request_gizmo(Object *p_obj) { return; if (editor->get_edited_scene() && (sp == editor->get_edited_scene() || (sp->get_owner() && editor->get_edited_scene()->is_a_parent_of(sp)))) { - Ref seg; + Ref seg; - for (int i = 0; i < EditorNode::get_singleton()->get_editor_data().get_editor_plugin_count(); i++) { + for (int i = 0; i < gizmo_plugins.size(); ++i) { + seg = gizmo_plugins.write[i]->get_gizmo(sp); - seg = EditorNode::get_singleton()->get_editor_data().get_editor_plugin(i)->create_spatial_gizmo(sp); - if (seg.is_valid()) - break; - } + if (seg.is_valid()) { + sp->set_gizmo(seg); - if (!seg.is_valid()) { - seg = gizmos->get_gizmo(sp); - } - if (seg.is_valid()) { - sp->set_gizmo(seg); - } + if (sp == selected) { + seg->set_selected(true); + selected->update_gizmo(); + } - if (seg.is_valid() && sp == selected) { - seg->set_selected(true); - selected->update_gizmo(); + break; + } } } } @@ -5158,11 +5168,35 @@ void SpatialEditor::_node_removed(Node *p_node) { selected = NULL; } +void SpatialEditor::_register_all_gizmos() { + register_gizmo_plugin(Ref(memnew(CameraSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(LightSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(AudioStreamPlayer3DSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(MeshInstanceSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(SoftBodySpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(Sprite3DSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(Position3DSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(SkeletonSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(RayCastSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(VehicleWheelSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(VisibilityNotifierGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(ParticlesGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(ReflectionProbeGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(GIProbeGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(BakedIndirectLightGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(CollisionShapeSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(CollisionPolygonSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(NavigationMeshSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(JointSpatialGizmoPlugin))); + register_gizmo_plugin(Ref(memnew(PhysicalBoneSpatialGizmoPlugin))); +} + void SpatialEditor::_bind_methods() { ClassDB::bind_method("_unhandled_key_input", &SpatialEditor::_unhandled_key_input); ClassDB::bind_method("_node_removed", &SpatialEditor::_node_removed); ClassDB::bind_method("_menu_item_pressed", &SpatialEditor::_menu_item_pressed); + ClassDB::bind_method("_menu_gizmo_toggled", &SpatialEditor::_menu_gizmo_toggled); ClassDB::bind_method("_menu_item_toggled", &SpatialEditor::_menu_item_toggled); ClassDB::bind_method("_xform_dialog_action", &SpatialEditor::_xform_dialog_action); ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data); @@ -5376,6 +5410,12 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { p->connect("id_pressed", this, "_menu_item_pressed"); + gizmos_menu = memnew(MenuButton); + gizmos_menu->set_text(TTR("Gizmos")); + hbc_menu->add_child(gizmos_menu); + gizmos_menu->get_popup()->set_hide_on_checkable_item_selection(false); + gizmos_menu->get_popup()->connect("id_pressed", this, "_menu_gizmo_toggled"); + /* REST OF MENU */ palette_split = memnew(HSplitContainer); @@ -5583,6 +5623,10 @@ void SpatialEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) { spatial_editor->snap_cursor_to_plane(p_plane); } +void SpatialEditor::register_gizmo_plugin(Ref ref) { + gizmo_plugins.push_back(ref); +} + SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) { editor = p_node; @@ -5596,3 +5640,171 @@ SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) { SpatialEditorPlugin::~SpatialEditorPlugin() { } + +void EditorSpatialGizmoPlugin::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) { + + Color instanced_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced"); + + Vector > mats; + + for (int i = 0; i < 4; i++) { + bool selected = i % 2 == 1; + bool instanced = i < 2; + + Ref material = Ref(memnew(SpatialMaterial)); + + Color color = instanced ? instanced_color : p_color; + + if (!selected) { + color.a *= 0.3; + } + + material->set_albedo(color); + material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + + if (p_use_vertex_color) { + material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); + } + + if (p_billboard) { + material->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); + } + + if (p_on_top && selected) { + material->set_on_top_of_alpha(); + } + + mats.push_back(material); + } + + materials[p_name] = mats; +} + +void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const Ref &p_texture, bool p_on_top, const Color &p_albedo) { + + Color instanced_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced"); + + Vector > icons; + + for (int i = 0; i < 4; i++) { + bool selected = i % 2 == 1; + bool instanced = i < 2; + + Ref icon = Ref(memnew(SpatialMaterial)); + + Color color = instanced ? instanced_color : p_albedo; + + if (!selected) { + color.a *= 0.3; + } + + icon->set_albedo(color); + + icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + icon->set_cull_mode(SpatialMaterial::CULL_DISABLED); + icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); + icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, p_texture); + icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true); + icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); + + if (p_on_top && selected) { + icon->set_on_top_of_alpha(); + } + + icons.push_back(icon); + } + + materials[p_name] = icons; +} + +void EditorSpatialGizmoPlugin::create_handle_material(const String &p_name, bool p_billboard) { + Ref handle_material = Ref(memnew(SpatialMaterial)); + + handle_material = Ref(memnew(SpatialMaterial)); + handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + handle_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true); + Ref handle_t = SpatialEditor::get_singleton()->get_icon("Editor3DHandle", "EditorIcons"); + handle_material->set_point_size(handle_t->get_width()); + handle_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, handle_t); + handle_material->set_albedo(Color(1, 1, 1)); + handle_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + handle_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + handle_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); + handle_material->set_on_top_of_alpha(); + if (p_billboard) { + handle_material->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); + handle_material->set_on_top_of_alpha(); + } + + materials[p_name] = Vector >(); + materials[p_name].push_back(handle_material); +} + +void EditorSpatialGizmoPlugin::add_material(const String &p_name, Ref p_material) { + materials[p_name] = Vector >(); + materials[p_name].push_back(p_material); +} + +Ref EditorSpatialGizmoPlugin::get_material(const String &p_name, EditorSpatialGizmo *p_gizmo) { + ERR_FAIL_COND_V(!materials.has(p_name), Ref()); + ERR_FAIL_COND_V(materials[p_name].size() == 0, Ref()); + + if (p_gizmo == NULL) return materials[p_name][0]; + + int index = (p_gizmo->is_selected() ? 1 : 0) + (p_gizmo->is_editable() ? 2 : 0); + return materials[p_name][index]; +} + +Ref EditorSpatialGizmoPlugin::get_gizmo(Spatial *p_spatial) { + + Ref ref = create_gizmo(p_spatial); + + if (ref.is_null()) return ref; + + ref->set_plugin(this); + ref->set_spatial_node(p_spatial); + ref->set_hidden(hidden); + + current_gizmos.push_back(ref.ptr()); + return ref; +} + +bool EditorSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return false; +} + +Ref EditorSpatialGizmoPlugin::create_gizmo(Spatial *p_spatial) { + + Ref ref; + if (has_gizmo(p_spatial)) ref.instance(); + return ref; +} + +bool EditorSpatialGizmoPlugin::can_be_hidden() const { + return true; +} + +bool EditorSpatialGizmoPlugin::is_selectable_when_hidden() const { + return false; +} + +void EditorSpatialGizmoPlugin::set_hidden(bool p_hidden) { + hidden = p_hidden; + for (int i = 0; i < current_gizmos.size(); ++i) { + current_gizmos[i]->set_hidden(hidden); + } +} + +void EditorSpatialGizmoPlugin::unregister_gizmo(EditorSpatialGizmo *p_gizmo) { + current_gizmos.erase(p_gizmo); +} + +EditorSpatialGizmoPlugin::EditorSpatialGizmoPlugin() { + hidden = false; +} + +EditorSpatialGizmoPlugin::~EditorSpatialGizmoPlugin() { +} diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index bd449a28df94..42e6a24bc56d 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -43,11 +43,11 @@ class Camera; class SpatialEditor; -class SpatialEditorGizmos; +class EditorSpatialGizmoPlugin; -class SpatialEditorGizmo : public SpatialGizmo { +class EditorSpatialGizmo : public SpatialGizmo { - GDCLASS(SpatialEditorGizmo, SpatialGizmo); + GDCLASS(EditorSpatialGizmo, SpatialGizmo); bool selected; bool instanced; @@ -56,15 +56,86 @@ class SpatialEditorGizmo : public SpatialGizmo { void set_selected(bool p_selected) { selected = p_selected; } bool is_selected() const { return selected; } + struct Instance { + + RID instance; + Ref mesh; + RID skeleton; + bool billboard; + bool unscaled; + bool can_intersect; + bool extra_margin; + Instance() { + + billboard = false; + unscaled = false; + can_intersect = false; + extra_margin = false; + } + + void create_instance(Spatial *p_base, bool p_hidden = false); + }; + + Vector collision_segments; + Ref collision_mesh; + + struct Handle { + Vector3 pos; + bool billboard; + }; + + Vector handles; + Vector secondary_handles; + float selectable_icon_size = -1.0f; + bool billboard_handle; + + bool valid; + bool hidden; + Spatial *base; + Vector instances; + Spatial *spatial_node; + EditorSpatialGizmoPlugin *gizmo_plugin; + + void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to(p_node)); } + +protected: + static void _bind_methods(); + +public: + void add_lines(const Vector &p_lines, const Ref &p_material, bool p_billboard = false); + void add_mesh(const Ref &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID()); + void add_collision_segments(const Vector &p_lines); + void add_collision_triangles(const Ref &p_tmesh); + void add_unscaled_billboard(const Ref &p_material, float p_scale = 1); + void add_handles(const Vector &p_handles, const Ref &p_material, bool p_billboard = false, bool p_secondary = false); + void add_solid_box(Ref &p_material, Vector3 p_size, Vector3 p_position = Vector3()); + virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; + virtual Variant get_handle_value(int p_idx); virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); - virtual bool is_gizmo_handle_highlighted(int idx) const { return false; } - virtual bool intersect_frustum(const Camera *p_camera, const Vector &p_frustum); - virtual bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false); - SpatialEditorGizmo(); + void set_spatial_node(Spatial *p_node); + Spatial *get_spatial_node() const { return spatial_node; } + Vector3 get_handle_pos(int p_idx) const; + bool intersect_frustum(const Camera *p_camera, const Vector &p_frustum); + bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false); + + virtual void clear(); + virtual void create(); + virtual void transform(); + virtual void redraw(); + virtual void free(); + + //TODO remove (?) + virtual bool is_editable() const; + virtual bool can_draw() const; + + void set_hidden(bool p_hidden); + void set_plugin(EditorSpatialGizmoPlugin *p_gizmo); + + EditorSpatialGizmo(); + ~EditorSpatialGizmo(); }; class SpatialEditorViewport : public Control { @@ -233,7 +304,7 @@ class SpatialEditorViewport : public Control { int edited_gizmo; Point2 mouse_pos; bool snap; - Ref gizmo; + Ref gizmo; int gizmo_handle; Variant gizmo_initial_value; Vector3 gizmo_initial_pos; @@ -500,6 +571,7 @@ class SpatialEditor : public VBoxContainer { Button *tool_option_button[TOOL_OPT_MAX]; MenuButton *transform_menu; + MenuButton *gizmos_menu; MenuButton *view_menu; ToolButton *lock_button; @@ -531,6 +603,7 @@ class SpatialEditor : public VBoxContainer { void _xform_dialog_action(); void _menu_item_pressed(int p_option); void _menu_item_toggled(bool pressed, int p_option); + void _menu_gizmo_toggled(int p_option); HBoxContainer *hbc_menu; @@ -539,6 +612,7 @@ class SpatialEditor : public VBoxContainer { void _instance_scene(); void _init_indicators(); + void _init_gizmos_menu(); void _init_grid(); void _finish_indicators(); void _finish_grid(); @@ -558,7 +632,10 @@ class SpatialEditor : public VBoxContainer { static SpatialEditor *singleton; void _node_removed(Node *p_node); - SpatialEditorGizmos *gizmos; + Vector > gizmo_plugins; + + void _register_all_gizmos(); + SpatialEditor(); bool is_any_freelook_active() const; @@ -632,6 +709,8 @@ class SpatialEditor : public VBoxContainer { return viewports[p_idx]; } + void register_gizmo_plugin(Ref ref); + Camera *get_camera() { return NULL; } void edit(Spatial *p_spatial); void clear(); @@ -668,4 +747,43 @@ class SpatialEditorPlugin : public EditorPlugin { ~SpatialEditorPlugin(); }; +class EditorSpatialGizmoPlugin : public Resource { + + GDCLASS(EditorSpatialGizmoPlugin, Resource); + + bool hidden; + List current_gizmos; + HashMap > > materials; + +protected: + virtual bool has_gizmo(Spatial *p_spatial); + virtual Ref create_gizmo(Spatial *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 &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); + void add_material(const String &p_name, Ref p_material); + + Ref get_material(const String &p_name, EditorSpatialGizmo *p_gizmo = NULL); + + virtual String get_name() const = 0; + virtual bool can_be_hidden() const; + virtual bool is_selectable_when_hidden() const; + + virtual void redraw(EditorSpatialGizmo *p_gizmo) {} + virtual String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { return ""; } + virtual Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { return Variant(); } + virtual void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {} + virtual void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) {} + virtual bool is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const { return false; } + + Ref get_gizmo(Spatial *p_spatial); + void set_hidden(bool p_hidden); + void unregister_gizmo(EditorSpatialGizmo *p_gizmo); + + EditorSpatialGizmoPlugin(); + virtual ~EditorSpatialGizmoPlugin(); +}; + #endif diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 9970f434ce4a..b0505eebda86 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -47,7 +47,10 @@ // Keep small children away from this file. // It's so ugly it will eat them alive -#define HANDLE_HALF_SIZE 0.05 +// The previous comment is kept only for historical reasons. +// No children will be harmed by the visioning of this file... hopefully. + +#define HANDLE_HALF_SIZE 9.5 bool EditorSpatialGizmo::can_draw() const { return is_editable(); @@ -85,11 +88,37 @@ void EditorSpatialGizmo::clear() { void EditorSpatialGizmo::redraw() { - if (get_script_instance() && get_script_instance()->has_method("redraw")) - get_script_instance()->call("redraw"); + ERR_FAIL_COND(!gizmo_plugin); + gizmo_plugin->redraw(this); +} + +String EditorSpatialGizmo::get_handle_name(int p_idx) const { + ERR_FAIL_COND_V(!gizmo_plugin, ""); + return gizmo_plugin->get_handle_name(this, p_idx); +} + +Variant EditorSpatialGizmo::get_handle_value(int p_idx) { + ERR_FAIL_COND_V(!gizmo_plugin, Variant()); + return gizmo_plugin->get_handle_value(this, p_idx); +} + +void EditorSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { + ERR_FAIL_COND(!gizmo_plugin); + return gizmo_plugin->set_handle(this, p_idx, p_camera, p_point); +} + +void EditorSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { + ERR_FAIL_COND(!gizmo_plugin); + return gizmo_plugin->commit_handle(this, p_idx, p_restore, p_cancel); +} + +void EditorSpatialGizmo::set_spatial_node(Spatial *p_node) { + + ERR_FAIL_NULL(p_node); + spatial_node = p_node; } -void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) { +void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base, bool p_hidden) { instance = VS::get_singleton()->instance_create2(mesh->get_rid(), p_base->get_world()->get_scenario()); VS::get_singleton()->instance_attach_object_instance_id(instance, p_base->get_instance_id()); @@ -98,7 +127,8 @@ void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) { if (extra_margin) VS::get_singleton()->instance_set_extra_visibility_margin(instance, 1); VS::get_singleton()->instance_geometry_set_cast_shadows_setting(instance, VS::SHADOW_CASTING_SETTING_OFF); - VS::get_singleton()->instance_set_layer_mask(instance, 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER); //gizmos are 26 + int layer = p_hidden ? 0 : 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER; + VS::get_singleton()->instance_set_layer_mask(instance, layer); //gizmos are 26 } void EditorSpatialGizmo::add_mesh(const Ref &p_mesh, bool p_billboard, const RID &p_skeleton) { @@ -110,7 +140,7 @@ void EditorSpatialGizmo::add_mesh(const Ref &p_mesh, bool p_billboard ins.mesh = p_mesh; ins.skeleton = p_skeleton; if (valid) { - ins.create_instance(spatial_node); + ins.create_instance(spatial_node, hidden); VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform()); } @@ -159,7 +189,7 @@ void EditorSpatialGizmo::add_lines(const Vector &p_lines, const Refinstance_set_transform(ins.instance, spatial_node->get_global_transform()); } @@ -210,7 +240,7 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref &p_material, ins.unscaled = true; ins.billboard = true; if (valid) { - ins.create_instance(spatial_node); + ins.create_instance(spatial_node, hidden); VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform()); } @@ -233,7 +263,7 @@ void EditorSpatialGizmo::add_collision_segments(const Vector &p_lines) } } -void EditorSpatialGizmo::add_handles(const Vector &p_handles, bool p_billboard, bool p_secondary) { +void EditorSpatialGizmo::add_handles(const Vector &p_handles, const Ref &p_material, bool p_billboard, bool p_secondary) { billboard_handle = p_billboard; @@ -257,7 +287,7 @@ void EditorSpatialGizmo::add_handles(const Vector &p_handles, bool p_bi for (int i = 0; i < p_handles.size(); i++) { Color col(1, 1, 1, 1); - if (is_gizmo_handle_highlighted(i)) + if (gizmo_plugin->is_gizmo_handle_highlighted(this, i)) col = Color(0, 0, 1, 0.9); if (SpatialEditor::get_singleton()->get_over_gizmo_handle() != i) @@ -268,10 +298,7 @@ void EditorSpatialGizmo::add_handles(const Vector &p_handles, bool p_bi } a[VS::ARRAY_COLOR] = colors; mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, a); - if (p_billboard) - mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material_billboard); - else - mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material); + mesh->surface_set_material(0, p_material); if (p_billboard) { float md = 0; @@ -288,7 +315,7 @@ void EditorSpatialGizmo::add_handles(const Vector &p_handles, bool p_bi ins.billboard = p_billboard; ins.extra_margin = true; if (valid) { - ins.create_instance(spatial_node); + ins.create_instance(spatial_node, hidden); VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform()); } instances.push_back(ins); @@ -330,17 +357,13 @@ void EditorSpatialGizmo::add_solid_box(Ref &p_material, Vector3 p_size add_mesh(m); } -void EditorSpatialGizmo::set_spatial_node(Spatial *p_node) { - - ERR_FAIL_NULL(p_node); - spatial_node = p_node; -} - bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera, const Vector &p_frustum) { ERR_FAIL_COND_V(!spatial_node, false); ERR_FAIL_COND_V(!valid, false); + if (hidden && !gizmo_plugin->is_selectable_when_hidden()) return false; + if (selectable_icon_size > 0.0f) { Vector3 origin = spatial_node->get_global_transform().get_origin(); @@ -413,7 +436,9 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, ERR_FAIL_COND_V(!spatial_node, false); ERR_FAIL_COND_V(!valid, false); - if (r_gizmo_handle) { + if (hidden && !gizmo_plugin->is_selectable_when_hidden()) return false; + + if (r_gizmo_handle && !hidden) { Transform t = spatial_node->get_global_transform(); t.orthonormalize(); @@ -428,7 +453,8 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 hpos = t.xform(secondary_handles[i]); Vector2 p = p_camera->unproject_position(hpos); - if (p.distance_to(p_point) < SpatialEditorGizmos::singleton->handle_t->get_width() * 0.6) { + + if (p.distance_to(p_point) < HANDLE_HALF_SIZE) { real_t dp = p_camera->get_transform().origin.distance_to(hpos); if (dp < min_d) { @@ -453,7 +479,8 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 hpos = t.xform(handles[i]); Vector2 p = p_camera->unproject_position(hpos); - if (p.distance_to(p_point) < SpatialEditorGizmos::singleton->handle_t->get_width() * 0.6) { + + if (p.distance_to(p_point) < HANDLE_HALF_SIZE) { real_t dp = p_camera->get_transform().origin.distance_to(hpos); if (dp < min_d) { @@ -597,7 +624,7 @@ void EditorSpatialGizmo::create() { for (int i = 0; i < instances.size(); i++) { - instances.write[i].create_instance(spatial_node); + instances.write[i].create_instance(spatial_node, hidden); } transform(); @@ -624,96 +651,21 @@ void EditorSpatialGizmo::free() { instances.write[i].instance = RID(); } + clear(); + valid = false; } -Ref EditorSpatialGizmo::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) { - - String name = p_name; - - if (!is_editable()) { - name += "@readonly"; - } else if (is_selected()) { - name += "@selected"; - } - - if (SpatialEditorGizmos::singleton->material_cache.has(name)) { - return SpatialEditorGizmos::singleton->material_cache[name]; - } - - Color color = p_color; - - if (!is_editable()) { - color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced"); - } - if (!is_selected()) { - color.a *= 0.3; - } - - Ref line_material; - line_material.instance(); - line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - if (p_use_vertex_color) { - line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - line_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - } - - if (p_billboard) { - line_material->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - } - - if (p_on_top && is_selected()) { - line_material->set_on_top_of_alpha(); +void EditorSpatialGizmo::set_hidden(bool p_hidden) { + hidden = p_hidden; + int layer = hidden ? 0 : 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER; + for (int i = 0; i < instances.size(); ++i) { + VS::get_singleton()->instance_set_layer_mask(instances[i].instance, layer); } - - line_material->set_albedo(color); - - SpatialEditorGizmos::singleton->material_cache[name] = line_material; - - return line_material; } -Ref EditorSpatialGizmo::create_icon_material(const String &p_name, const Ref &p_texture, bool p_on_top, const Color &p_albedo) { - - String name = p_name; - - if (!is_editable()) { - name += "@readonly"; - } else if (is_selected()) { - name += "@selected"; - } - - if (SpatialEditorGizmos::singleton->material_cache.has(name)) { - return SpatialEditorGizmos::singleton->material_cache[name]; - } - - Color color = p_albedo; - - if (!is_editable()) { - color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced"); - } else if (!is_selected()) { - color.a *= 0.3; - } - - Ref icon; - icon.instance(); - icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - icon->set_cull_mode(SpatialMaterial::CULL_DISABLED); - icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); - icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - icon->set_albedo(color); - icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, p_texture); - icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true); - icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - - if (p_on_top && is_selected()) { - icon->set_on_top_of_alpha(); - } - - SpatialEditorGizmos::singleton->material_cache[name] = icon; - - return icon; +void EditorSpatialGizmo::set_plugin(EditorSpatialGizmoPlugin *p_plugin) { + gizmo_plugin = p_plugin; } void EditorSpatialGizmo::_bind_methods() { @@ -726,6 +678,7 @@ void EditorSpatialGizmo::_bind_methods() { ClassDB::bind_method(D_METHOD("add_handles", "handles", "billboard", "secondary"), &EditorSpatialGizmo::add_handles, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node); ClassDB::bind_method(D_METHOD("clear"), &EditorSpatialGizmo::clear); + ClassDB::bind_method(D_METHOD("set_hidden", "hidden"), &EditorSpatialGizmo::set_hidden); BIND_VMETHOD(MethodInfo("redraw")); BIND_VMETHOD(MethodInfo(Variant::STRING, "get_handle_name", PropertyInfo(Variant::INT, "index"))); @@ -743,12 +696,17 @@ void EditorSpatialGizmo::_bind_methods() { EditorSpatialGizmo::EditorSpatialGizmo() { valid = false; billboard_handle = false; + hidden = false; base = NULL; + selected = false; + instanced = false; spatial_node = NULL; + gizmo_plugin = NULL; } EditorSpatialGizmo::~EditorSpatialGizmo() { + if (gizmo_plugin != NULL) gizmo_plugin->unregister_gizmo(this); clear(); } @@ -761,7 +719,30 @@ Vector3 EditorSpatialGizmo::get_handle_pos(int p_idx) const { //// light gizmo -String LightSpatialGizmo::get_handle_name(int p_idx) const { +LightSpatialGizmoPlugin::LightSpatialGizmoPlugin() { + + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.2)); + + create_material("lines", gizmo_color); + create_material("lines_billboard", gizmo_color, true); + + create_icon_material("light_directional_icon", SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons")); + create_icon_material("light_omni_icon", SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons")); + create_icon_material("light_spot_icon", SpatialEditor::get_singleton()->get_icon("GizmoSpotLight", "EditorIcons")); + + create_handle_material("handles"); + create_handle_material("handles_billboard", true); +} + +bool LightSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} + +String LightSpatialGizmoPlugin::get_name() const { + return "Lights"; +} + +String LightSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { if (p_idx == 0) return "Radius"; @@ -769,8 +750,9 @@ String LightSpatialGizmo::get_handle_name(int p_idx) const { return "Aperture"; } -Variant LightSpatialGizmo::get_handle_value(int p_idx) const { +Variant LightSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { + Light *light = Object::cast_to(p_gizmo->get_spatial_node()); if (p_idx == 0) return light->get_param(Light::PARAM_RANGE); if (p_idx == 1) @@ -808,8 +790,9 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec return a * 180.0 / Math_PI; } -void LightSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { +void LightSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { + Light *light = Object::cast_to(p_gizmo->get_spatial_node()); Transform gt = light->get_global_transform(); gt.orthonormalize(); Transform gi = gt.affine_inverse(); @@ -848,8 +831,9 @@ void LightSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_ } } -void LightSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { +void LightSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + Light *light = Object::cast_to(p_gizmo->get_spatial_node()); if (p_cancel) { light->set_param(p_idx == 0 ? Light::PARAM_RANGE : Light::PARAM_SPOT_ANGLE, p_restore); @@ -871,14 +855,16 @@ void LightSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool } } -void LightSpatialGizmo::redraw() { +void LightSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/light"); + Light *light = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); if (Object::cast_to(light)) { - Ref material = create_material("light_directional_material", gizmo_color); - Ref icon = create_icon_material("light_directional_icon", SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons")); + Ref material = get_material("lines", p_gizmo); + Ref icon = get_material("light_directional_icon", p_gizmo); const int arrow_points = 7; const float arrow_length = 1.5; @@ -909,16 +895,15 @@ void LightSpatialGizmo::redraw() { } } - add_lines(lines, material); - add_collision_segments(lines); - add_unscaled_billboard(icon, 0.05); + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); + p_gizmo->add_unscaled_billboard(icon, 0.05); } if (Object::cast_to(light)) { - Ref material = create_material("light_omni_material", gizmo_color, true); - Ref icon = create_icon_material("light_omni_icon", SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons")); - clear(); + Ref material = get_material("lines_billboard", p_gizmo); + Ref icon = get_material("light_omni_icon", p_gizmo); OmniLight *on = Object::cast_to(light); @@ -941,29 +926,27 @@ void LightSpatialGizmo::redraw() { points.push_back(Vector3(b.x, b.y, 0)); } - add_lines(points, material, true); - add_collision_segments(points); + p_gizmo->add_lines(points, material, true); + p_gizmo->add_collision_segments(points); - add_unscaled_billboard(icon, 0.05); + p_gizmo->add_unscaled_billboard(icon, 0.05); Vector handles; handles.push_back(Vector3(r, 0, 0)); - add_handles(handles, true); + p_gizmo->add_handles(handles, get_material("handles_billboard"), true); } if (Object::cast_to(light)) { - Ref material = create_material("light_spot_material", gizmo_color); - Ref icon = create_icon_material("light_spot_icon", SpatialEditor::get_singleton()->get_icon("GizmoSpotLight", "EditorIcons")); - - clear(); + Ref material = get_material("lines", p_gizmo); + Ref icon = get_material("light_spot_icon", p_gizmo); Vector points; - SpotLight *on = Object::cast_to(light); + SpotLight *sl = Object::cast_to(light); - float r = on->get_param(Light::PARAM_RANGE); - float w = r * Math::sin(Math::deg2rad(on->get_param(Light::PARAM_SPOT_ANGLE))); - float d = r * Math::cos(Math::deg2rad(on->get_param(Light::PARAM_SPOT_ANGLE))); + float r = sl->get_param(Light::PARAM_RANGE); + float w = r * Math::sin(Math::deg2rad(sl->get_param(Light::PARAM_SPOT_ANGLE))); + float d = r * Math::cos(Math::deg2rad(sl->get_param(Light::PARAM_SPOT_ANGLE))); for (int i = 0; i < 360; i++) { @@ -985,7 +968,7 @@ void LightSpatialGizmo::redraw() { points.push_back(Vector3(0, 0, -r)); points.push_back(Vector3()); - add_lines(points, material); + p_gizmo->add_lines(points, material); Vector handles; handles.push_back(Vector3(0, 0, -r)); @@ -1017,33 +1000,45 @@ void LightSpatialGizmo::redraw() { collision_segments.push_back(Vector3(0, 0, -r)); collision_segments.push_back(Vector3()); - add_handles(handles); - add_collision_segments(collision_segments); - add_unscaled_billboard(icon, 0.05); + p_gizmo->add_handles(handles, get_material("handles")); + p_gizmo->add_collision_segments(collision_segments); + p_gizmo->add_unscaled_billboard(icon, 0.05); } } -LightSpatialGizmo::LightSpatialGizmo(Light *p_light) { +////// + +//// player gizmo +AudioStreamPlayer3DSpatialGizmoPlugin::AudioStreamPlayer3DSpatialGizmoPlugin() { + + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1)); - light = p_light; - set_spatial_node(p_light); + create_icon_material("stream_player_3d_icon", SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer", "EditorIcons")); + create_material("stream_player_3d_material", gizmo_color); + create_handle_material("handles"); } -////// +bool AudioStreamPlayer3DSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} -//// player gizmo +String AudioStreamPlayer3DSpatialGizmoPlugin::get_name() const { + return "AudioStreamPlayer3D"; +} -String AudioStreamPlayer3DSpatialGizmo::get_handle_name(int p_idx) const { +String AudioStreamPlayer3DSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { return "Emission Radius"; } -Variant AudioStreamPlayer3DSpatialGizmo::get_handle_value(int p_idx) const { - +Variant AudioStreamPlayer3DSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { + AudioStreamPlayer3D *player = Object::cast_to(p_gizmo->get_spatial_node()); return player->get_emission_angle(); } -void AudioStreamPlayer3DSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { +void AudioStreamPlayer3DSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { + + AudioStreamPlayer3D *player = Object::cast_to(p_gizmo->get_spatial_node()); Transform gt = player->get_global_transform(); gt.orthonormalize(); @@ -1081,7 +1076,9 @@ void AudioStreamPlayer3DSpatialGizmo::set_handle(int p_idx, Camera *p_camera, co } } -void AudioStreamPlayer3DSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { +void AudioStreamPlayer3DSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + + AudioStreamPlayer3D *player = Object::cast_to(p_gizmo->get_spatial_node()); if (p_cancel) { @@ -1097,16 +1094,17 @@ void AudioStreamPlayer3DSpatialGizmo::commit_handle(int p_idx, const Variant &p_ } } -void AudioStreamPlayer3DSpatialGizmo::redraw() { +void AudioStreamPlayer3DSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - clear(); + AudioStreamPlayer3D *player = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); - Ref icon = create_icon_material("stream_player_3d_material", SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer", "EditorIcons")); + Ref icon = get_material("stream_player_3d_icon", p_gizmo); if (player->is_emission_angle_enabled()) { - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/stream_player_3d"); - Ref material = create_material("stream_player_3d_material", gizmo_color); + Ref material = get_material("stream_player_3d_material", p_gizmo); float pc = player->get_emission_angle(); @@ -1138,27 +1136,40 @@ void AudioStreamPlayer3DSpatialGizmo::redraw() { points.write[200 + i * 2 + 1] = Vector3(); } - add_lines(points, material); - add_collision_segments(points); + p_gizmo->add_lines(points, material); + p_gizmo->add_collision_segments(points); Vector handles; float ha = Math::deg2rad(player->get_emission_angle()); handles.push_back(Vector3(Math::sin(ha), 0, -Math::cos(ha))); - add_handles(handles); + p_gizmo->add_handles(handles, get_material("handles")); } - add_unscaled_billboard(icon, 0.05); + p_gizmo->add_unscaled_billboard(icon, 0.05); +} + +////// + +CameraSpatialGizmoPlugin::CameraSpatialGizmoPlugin() { + + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8)); + + create_material("camera_material", gizmo_color); + create_icon_material("camera_icon", SpatialEditor::get_singleton()->get_icon("GizmoCamera", "EditorIcons")); + create_handle_material("handles"); } -AudioStreamPlayer3DSpatialGizmo::AudioStreamPlayer3DSpatialGizmo(AudioStreamPlayer3D *p_player) { +bool CameraSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} - player = p_player; - set_spatial_node(p_player); +String CameraSpatialGizmoPlugin::get_name() const { + return "Camera"; } -////// +String CameraSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { -String CameraSpatialGizmo::get_handle_name(int p_idx) const { + Camera *camera = Object::cast_to(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) { return "FOV"; @@ -1166,7 +1177,10 @@ String CameraSpatialGizmo::get_handle_name(int p_idx) const { return "Size"; } } -Variant CameraSpatialGizmo::get_handle_value(int p_idx) const { + +Variant CameraSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { + + Camera *camera = Object::cast_to(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) { return camera->get_fov(); @@ -1175,7 +1189,10 @@ Variant CameraSpatialGizmo::get_handle_value(int p_idx) const { return camera->get_size(); } } -void CameraSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { + +void CameraSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { + + Camera *camera = Object::cast_to(p_gizmo->get_spatial_node()); Transform gt = camera->get_global_transform(); gt.orthonormalize(); @@ -1201,7 +1218,10 @@ void CameraSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p camera->set("size", d); } } -void CameraSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { + +void CameraSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + + Camera *camera = Object::cast_to(p_gizmo->get_spatial_node()); if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) { @@ -1231,16 +1251,17 @@ void CameraSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool } } -void CameraSpatialGizmo::redraw() { +void CameraSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - clear(); + Camera *camera = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); Vector lines; Vector handles; - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/camera"); - Ref material = create_material("camera_material", gizmo_color); - Ref icon = create_icon_material("camera_icon", SpatialEditor::get_singleton()->get_icon("GizmoCamera", "EditorIcons")); + Ref material = get_material("camera_material", p_gizmo); + Ref icon = get_material("camera_icon", p_gizmo); switch (camera->get_projection()) { @@ -1310,71 +1331,81 @@ void CameraSpatialGizmo::redraw() { } break; } - add_lines(lines, material); - add_collision_segments(lines); - add_unscaled_billboard(icon, 0.05); - add_handles(handles); + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); + p_gizmo->add_unscaled_billboard(icon, 0.05); + p_gizmo->add_handles(handles, get_material("handles")); } -CameraSpatialGizmo::CameraSpatialGizmo(Camera *p_camera) { +////// + +MeshInstanceSpatialGizmoPlugin::MeshInstanceSpatialGizmoPlugin() { +} - camera = p_camera; - set_spatial_node(camera); +bool MeshInstanceSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL && Object::cast_to(p_spatial) == NULL; } -////// +String MeshInstanceSpatialGizmoPlugin::get_name() const { + return "MeshInstance"; +} -bool MeshInstanceSpatialGizmo::can_draw() const { - return true; //mesh can always draw (even though nothing is displayed) +bool MeshInstanceSpatialGizmoPlugin::can_be_hidden() const { + return false; } -void MeshInstanceSpatialGizmo::redraw() { - clear(); +void MeshInstanceSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + + MeshInstance *mesh = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); Ref m = mesh->get_mesh(); + if (!m.is_valid()) return; //none Ref tm = m->generate_triangle_mesh(); if (tm.is_valid()) { - add_collision_triangles(tm); + p_gizmo->add_collision_triangles(tm); } } -MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance *p_mesh) { +///// +Sprite3DSpatialGizmoPlugin::Sprite3DSpatialGizmoPlugin() { +} - mesh = p_mesh; - set_spatial_node(p_mesh); +bool Sprite3DSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; } -///// +String Sprite3DSpatialGizmoPlugin::get_name() const { + return "Sprite3D"; +} -bool Sprite3DSpatialGizmo::can_draw() const { - return true; +bool Sprite3DSpatialGizmoPlugin::can_be_hidden() const { + return false; } -void Sprite3DSpatialGizmo::redraw() { - clear(); +void Sprite3DSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + + Sprite3D *sprite = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); Ref tm = sprite->generate_triangle_mesh(); if (tm.is_valid()) { - add_collision_triangles(tm); + p_gizmo->add_collision_triangles(tm); } } -Sprite3DSpatialGizmo::Sprite3DSpatialGizmo(SpriteBase3D *p_sprite) { - - sprite = p_sprite; - set_spatial_node(p_sprite); -} - /// -void Position3DSpatialGizmo::redraw() { +Position3DSpatialGizmoPlugin::Position3DSpatialGizmoPlugin() { + pos3d_mesh = Ref(memnew(ArrayMesh)); + cursor_points = Vector(); - clear(); - add_mesh(SpatialEditorGizmos::singleton->pos3d_mesh); - Vector cursor_points; + PoolVector cursor_colors; float cs = 0.25; cursor_points.push_back(Vector3(+cs, 0, 0)); cursor_points.push_back(Vector3(-cs, 0, 0)); @@ -1382,23 +1413,65 @@ void Position3DSpatialGizmo::redraw() { cursor_points.push_back(Vector3(0, -cs, 0)); cursor_points.push_back(Vector3(0, 0, +cs)); cursor_points.push_back(Vector3(0, 0, -cs)); - add_collision_segments(cursor_points); + cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7)); + cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7)); + cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7)); + cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7)); + cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7)); + cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7)); + + Ref mat = memnew(SpatialMaterial); + mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); + mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + mat->set_line_width(3); + Array d; + d.resize(VS::ARRAY_MAX); + d[Mesh::ARRAY_VERTEX] = cursor_points; + d[Mesh::ARRAY_COLOR] = cursor_colors; + pos3d_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d); + pos3d_mesh->surface_set_material(0, mat); } -Position3DSpatialGizmo::Position3DSpatialGizmo(Position3D *p_p3d) { +bool Position3DSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} + +String Position3DSpatialGizmoPlugin::get_name() const { + return "Position3D"; +} + +void Position3DSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - p3d = p_p3d; - set_spatial_node(p3d); + p_gizmo->clear(); + p_gizmo->add_mesh(pos3d_mesh); + p_gizmo->add_collision_segments(cursor_points); } ///// -void SkeletonSpatialGizmo::redraw() { +SkeletonSpatialGizmoPlugin::SkeletonSpatialGizmoPlugin() { - clear(); + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4)); + create_material("skeleton_material", gizmo_color); +} + +bool SkeletonSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/skeleton"); - Ref material = create_material("skeleton_material", gizmo_color); +String SkeletonSpatialGizmoPlugin::get_name() const { + return "Skeleton"; +} + +void SkeletonSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + + Skeleton *skel = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); + + Ref material = get_material("skeleton_material", p_gizmo); SpatialMaterial *sm = Object::cast_to(material.ptr()); { // Reset @@ -1606,24 +1679,28 @@ void SkeletonSpatialGizmo::redraw() { } Ref m = surface_tool->commit(); - add_mesh(m, false, skel->get_skeleton()); + p_gizmo->add_mesh(m, false, skel->get_skeleton()); } -SkeletonSpatialGizmo::SkeletonSpatialGizmo(Skeleton *p_skel) { +//// - skel = p_skel; - set_spatial_node(p_skel); +PhysicalBoneSpatialGizmoPlugin::PhysicalBoneSpatialGizmoPlugin() { + create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1))); } -PhysicalBoneSpatialGizmo::PhysicalBoneSpatialGizmo(PhysicalBone *p_pb) : - EditorSpatialGizmo(), - physical_bone(p_pb) { - set_spatial_node(p_pb); +bool PhysicalBoneSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; } -void PhysicalBoneSpatialGizmo::redraw() { +String PhysicalBoneSpatialGizmoPlugin::get_name() const { + return "PhysicalBones"; +} - clear(); +void PhysicalBoneSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + + p_gizmo->clear(); + + PhysicalBone *physical_bone = Object::cast_to(p_gizmo->get_spatial_node()); if (!physical_bone) return; @@ -1637,26 +1714,25 @@ void PhysicalBoneSpatialGizmo::redraw() { switch (physical_bone->get_joint_type()) { case PhysicalBone::JOINT_TYPE_PIN: { - PinJointSpatialGizmo::CreateGizmo(physical_bone->get_joint_offset(), points); + JointSpatialGizmoPlugin::CreatePinJointGizmo(physical_bone->get_joint_offset(), points); } break; case PhysicalBone::JOINT_TYPE_CONE: { const PhysicalBone::ConeJointData *cjd(static_cast(physical_bone->get_joint_data())); - ConeTwistJointSpatialGizmo::CreateGizmo( + JointSpatialGizmoPlugin::CreateConeTwistJointGizmo( physical_bone->get_joint_offset(), physical_bone->get_global_transform() * physical_bone->get_joint_offset(), pb ? pb->get_global_transform() : Transform(), pbp ? pbp->get_global_transform() : Transform(), cjd->swing_span, cjd->twist_span, - points, pb ? &points : NULL, pbp ? &points : NULL); } break; case PhysicalBone::JOINT_TYPE_HINGE: { const PhysicalBone::HingeJointData *hjd(static_cast(physical_bone->get_joint_data())); - HingeJointSpatialGizmo::CreateGizmo( + JointSpatialGizmoPlugin::CreateHingeJointGizmo( physical_bone->get_joint_offset(), physical_bone->get_global_transform() * physical_bone->get_joint_offset(), pb ? pb->get_global_transform() : Transform(), @@ -1671,7 +1747,7 @@ void PhysicalBoneSpatialGizmo::redraw() { case PhysicalBone::JOINT_TYPE_SLIDER: { const PhysicalBone::SliderJointData *sjd(static_cast(physical_bone->get_joint_data())); - SliderJointSpatialGizmo::CreateGizmo( + JointSpatialGizmoPlugin::CreateSliderJointGizmo( physical_bone->get_joint_offset(), physical_bone->get_global_transform() * physical_bone->get_joint_offset(), pb ? pb->get_global_transform() : Transform(), @@ -1687,7 +1763,7 @@ void PhysicalBoneSpatialGizmo::redraw() { case PhysicalBone::JOINT_TYPE_6DOF: { const PhysicalBone::SixDOFJointData *sdofjd(static_cast(physical_bone->get_joint_data())); - Generic6DOFJointSpatialGizmo::CreateGizmo( + JointSpatialGizmoPlugin::CreateGeneric6DOFJointGizmo( physical_bone->get_joint_offset(), physical_bone->get_global_transform() * physical_bone->get_joint_offset(), @@ -1723,14 +1799,15 @@ void PhysicalBoneSpatialGizmo::redraw() { return; } - Ref material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint")); + Ref material = get_material("joint_material", p_gizmo); - add_collision_segments(points); - add_lines(points, material); + p_gizmo->add_collision_segments(points); + p_gizmo->add_lines(points, material); } // FIXME: Kept as reference for reimplementation in 3.1+ #if 0 + void RoomSpatialGizmo::redraw() { clear(); @@ -1747,41 +1824,41 @@ void RoomSpatialGizmo::redraw() { for (int i = 0; i < fc; i++) { - Vector3 fn = r[i].get_plane().normal; + Vector3 fn = r[i].get_plane().normal; - for (int j = 0; j < 3; j++) { + for (int j = 0; j < 3; j++) { - _EdgeKey ek; - ek.from = r[i].vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON)); - ek.to = r[i].vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON)); - if (ek.from < ek.to) - SWAP(ek.from, ek.to); + _EdgeKey ek; + ek.from = r[i].vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON)); + ek.to = r[i].vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON)); + if (ek.from < ek.to) + SWAP(ek.from, ek.to); - Map<_EdgeKey, Vector3>::Element *E = edge_map.find(ek); + Map<_EdgeKey, Vector3>::Element *E = edge_map.find(ek); - if (E) { + if (E) { - if (E->get().dot(fn) > 0.9) { + if (E->get().dot(fn) > 0.9) { - E->get() = Vector3(); - } + E->get() = Vector3(); + } - } else { + } else { - edge_map[ek] = fn; - } + edge_map[ek] = fn; + } + } } - } for (Map<_EdgeKey, Vector3>::Element *E = edge_map.front(); E; E = E->next()) { - if (E->get() != Vector3()) { - lines.push_back(E->key().from); - lines.push_back(E->key().to); + if (E->get() != Vector3()) { + lines.push_back(E->key().from); + lines.push_back(E->key().to); + } } - } - add_lines(lines, SpatialEditorGizmos::singleton->room_material); + add_lines(lines, EditorSpatialGizmos::singleton->room_material); add_collision_segments(lines); } @@ -1799,31 +1876,31 @@ void PortalSpatialGizmo::redraw() { Vector points = portal->get_shape(); if (points.size() == 0) { - return; - } + return; + } Vector lines; Vector3 center; for (int i = 0; i < points.size(); i++) { - Vector3 f; - f.x = points[i].x; - f.y = points[i].y; - Vector3 fn; - fn.x = points[(i + 1) % points.size()].x; - fn.y = points[(i + 1) % points.size()].y; - center += f; + Vector3 f; + f.x = points[i].x; + f.y = points[i].y; + Vector3 fn; + fn.x = points[(i + 1) % points.size()].x; + fn.y = points[(i + 1) % points.size()].y; + center += f; - lines.push_back(f); - lines.push_back(fn); - } + lines.push_back(f); + lines.push_back(fn); + } center /= points.size(); lines.push_back(center); lines.push_back(center + Vector3(0, 0, 1)); - add_lines(lines, SpatialEditorGizmos::singleton->portal_material); + add_lines(lines, EditorSpatialGizmos::singleton->portal_material); add_collision_segments(lines); } @@ -1836,33 +1913,58 @@ PortalSpatialGizmo::PortalSpatialGizmo(Portal *p_portal) { #endif ///// -void RayCastSpatialGizmo::redraw() { +RayCastSpatialGizmoPlugin::RayCastSpatialGizmoPlugin() { - clear(); + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); + create_material("shape_material", gizmo_color); +} + +bool RayCastSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} + +String RayCastSpatialGizmoPlugin::get_name() const { + return "RayCast"; +} + +void RayCastSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + + RayCast *raycast = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); Vector lines; lines.push_back(Vector3()); lines.push_back(raycast->get_cast_to()); - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape"); - Ref material = create_material("shape_material", gizmo_color); + Ref material = get_material("shape_material", p_gizmo); - add_lines(lines, material); - add_collision_segments(lines); + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); +} + +///// + +VehicleWheelSpatialGizmoPlugin::VehicleWheelSpatialGizmoPlugin() { + + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); + create_material("shape_material", gizmo_color); } -RayCastSpatialGizmo::RayCastSpatialGizmo(RayCast *p_raycast) { +bool VehicleWheelSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} - set_spatial_node(p_raycast); - raycast = p_raycast; +String VehicleWheelSpatialGizmoPlugin::get_name() const { + return "VehicleWheel"; } -///// +void VehicleWheelSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { -void VehicleWheelSpatialGizmo::redraw() { + VehicleWheel *car_wheel = Object::cast_to(p_gizmo->get_spatial_node()); - clear(); + p_gizmo->clear(); Vector points; @@ -1906,23 +2008,36 @@ void VehicleWheelSpatialGizmo::redraw() { points.push_back(Vector3(0, -r, r * 2)); points.push_back(Vector3(-r * 2 * 0.2, -r, r * 2 * 0.8)); - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape"); - Ref material = create_material("shape_material", gizmo_color); + Ref material = get_material("shape_material", p_gizmo); - add_lines(points, material); - add_collision_segments(points); + p_gizmo->add_lines(points, material); + p_gizmo->add_collision_segments(points); } -VehicleWheelSpatialGizmo::VehicleWheelSpatialGizmo(VehicleWheel *p_car_wheel) { +/////////// - set_spatial_node(p_car_wheel); - car_wheel = p_car_wheel; +SoftBodySpatialGizmoPlugin::SoftBodySpatialGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); + create_material("shape_material", gizmo_color); + create_handle_material("handles"); } -/////////// +bool SoftBodySpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} -void SoftBodySpatialGizmo::redraw() { - clear(); +String SoftBodySpatialGizmoPlugin::get_name() const { + return "SoftBody"; +} + +bool SoftBodySpatialGizmoPlugin::is_selectable_when_hidden() const { + return true; +} + +void SoftBodySpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + SoftBody *soft_body = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); if (!soft_body || soft_body->get_mesh().is_null()) { return; @@ -1938,741 +2053,793 @@ void SoftBodySpatialGizmo::redraw() { return; } + Ref tm = soft_body->get_mesh()->generate_triangle_mesh(); + Vector points; soft_body->get_mesh()->generate_debug_mesh_indices(points); - soft_body->get_mesh()->clear_cache(); - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape"); - Ref material = create_material("shape_material", gizmo_color); + Ref material = get_material("shape_material", p_gizmo); - add_lines(lines, material); - add_collision_segments(lines); - add_handles(points); -} - -bool SoftBodySpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) { - return EditorSpatialGizmo::intersect_ray(p_camera, p_point, r_pos, r_normal, r_gizmo_handle, p_sec_first); - - /* Perform a shape cast but doesn't work with softbody - PhysicsDirectSpaceState *space_state = PhysicsServer::get_singleton()->space_get_direct_state(SceneTree::get_singleton()->get_root()->get_world()->get_space()); - if (!physics_sphere_shape.is_valid()) { - physics_sphere_shape = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE); - real_t radius = 0.02; - PhysicsServer::get_singleton()->shape_set_data(physics_sphere_shape, radius); - } - - Vector3 sphere_motion(p_camera->project_ray_normal(p_point)); - real_t closest_safe; - real_t closest_unsafe; - PhysicsDirectSpaceState::ShapeRestInfo result; - bool collided = space_state->cast_motion( - physics_sphere_shape, - p_camera->get_transform(), - sphere_motion * Vector3(1000, 1000, 1000), - 0.f, - closest_safe, - closest_unsafe, - Set(), - 0xFFFFFFFF, - 0xFFFFFFFF, - &result); - - if (collided) { - - if (result.collider_id == soft_body->get_instance_id()) { - print_line("Collided"); - } else { - print_line("Collided but with wrong object: " + itos(result.collider_id)); - } - } else { - print_line("Not collided, motion: x: " + rtos(sphere_motion[0]) + " y: " + rtos(sphere_motion[1]) + " z: " + rtos(sphere_motion[2])); - } - return false; - */ + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); + p_gizmo->add_handles(points, get_material("handles")); + p_gizmo->add_collision_triangles(tm); } -void SoftBodySpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { - soft_body->pin_point_toggle(p_idx); - redraw(); +String SoftBodySpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { + return "SoftBody pin point"; } -bool SoftBodySpatialGizmo::is_gizmo_handle_highlighted(int idx) const { - return soft_body->is_point_pinned(idx); +Variant SoftBodySpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { + SoftBody *soft_body = Object::cast_to(p_gizmo->get_spatial_node()); + return Variant(soft_body->is_point_pinned(p_idx)); } -SoftBodySpatialGizmo::SoftBodySpatialGizmo(SoftBody *p_soft_physics_body) : - EditorSpatialGizmo(), - soft_body(p_soft_physics_body) { - set_spatial_node(p_soft_physics_body); +void SoftBodySpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + SoftBody *soft_body = Object::cast_to(p_gizmo->get_spatial_node()); + soft_body->pin_point_toggle(p_idx); } -SoftBodySpatialGizmo::~SoftBodySpatialGizmo() { - //if (!physics_sphere_shape.is_valid()) { - // PhysicsServer::get_singleton()->free(physics_sphere_shape); - //} +bool SoftBodySpatialGizmoPlugin::is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const { + SoftBody *soft_body = Object::cast_to(p_gizmo->get_spatial_node()); + return soft_body->is_point_pinned(idx); } /////////// -String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const { - - Ref s = cs->get_shape(); - if (s.is_null()) - return ""; +VisibilityNotifierGizmoPlugin::VisibilityNotifierGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/visibility_notifier", Color(0.8, 0.5, 0.7)); + create_material("visibility_notifier_material", gizmo_color); + gizmo_color.a = 0.1; + create_material("visibility_notifier_solid_material", gizmo_color); + create_handle_material("handles"); +} - if (Object::cast_to(*s)) { +bool VisibilityNotifierGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} - return "Radius"; - } +String VisibilityNotifierGizmoPlugin::get_name() const { + return "VisibilityNotifier"; +} - if (Object::cast_to(*s)) { +String VisibilityNotifierGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { - return "Extents"; + switch (p_idx) { + case 0: return "Size X"; + case 1: return "Size Y"; + case 2: return "Size Z"; + case 3: return "Pos X"; + case 4: return "Pos Y"; + case 5: return "Pos Z"; } - if (Object::cast_to(*s)) { - - return p_idx == 0 ? "Radius" : "Height"; - } + return ""; +} - if (Object::cast_to(*s)) { +Variant VisibilityNotifierGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { - return p_idx == 0 ? "Radius" : "Height"; - } + VisibilityNotifier *notifier = Object::cast_to(p_gizmo->get_spatial_node()); + return notifier->get_aabb(); +} +void VisibilityNotifierGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { - if (Object::cast_to(*s)) { + VisibilityNotifier *notifier = Object::cast_to(p_gizmo->get_spatial_node()); - return "Length"; - } + Transform gt = notifier->get_global_transform(); - return ""; -} -Variant CollisionShapeSpatialGizmo::get_handle_value(int p_idx) const { + Transform gi = gt.affine_inverse(); - Ref s = cs->get_shape(); - if (s.is_null()) - return Variant(); + bool move = p_idx >= 3; + p_idx = p_idx % 3; - if (Object::cast_to(*s)) { + AABB aabb = notifier->get_aabb(); + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); - Ref ss = s; - return ss->get_radius(); - } + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; - if (Object::cast_to(*s)) { + Vector3 ofs = aabb.position + aabb.size * 0.5; - Ref bs = s; - return bs->get_extents(); - } + Vector3 axis; + axis[p_idx] = 1.0; - if (Object::cast_to(*s)) { + if (move) { - Ref cs = s; - return p_idx == 0 ? cs->get_radius() : cs->get_height(); - } + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); - if (Object::cast_to(*s)) { + float d = ra[p_idx]; - Ref cs = s; - return p_idx == 0 ? cs->get_radius() : cs->get_height(); + aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5; + notifier->set_aabb(aabb); + + } else { + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); + + float d = ra[p_idx] - ofs[p_idx]; + if (d < 0.001) + d = 0.001; + //resize + aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d; + aabb.size[p_idx] = d * 2; + notifier->set_aabb(aabb); } +} - if (Object::cast_to(*s)) { +void VisibilityNotifierGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { - Ref cs = s; - return cs->get_length(); + VisibilityNotifier *notifier = Object::cast_to(p_gizmo->get_spatial_node()); + + if (p_cancel) { + notifier->set_aabb(p_restore); + return; } - return Variant(); + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Notifier AABB")); + ur->add_do_method(notifier, "set_aabb", notifier->get_aabb()); + ur->add_undo_method(notifier, "set_aabb", p_restore); + ur->commit_action(); } -void CollisionShapeSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { - Ref s = cs->get_shape(); - if (s.is_null()) - return; - Transform gt = cs->get_global_transform(); - gt.orthonormalize(); - Transform gi = gt.affine_inverse(); +void VisibilityNotifierGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); + VisibilityNotifier *notifier = Object::cast_to(p_gizmo->get_spatial_node()); - Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; + p_gizmo->clear(); - if (Object::cast_to(*s)) { + Vector lines; + AABB aabb = notifier->get_aabb(); - Ref ss = s; - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb); - float d = ra.x; - if (d < 0.001) - d = 0.001; + for (int i = 0; i < 12; i++) { + Vector3 a, b; + aabb.get_edge(i, a, b); + lines.push_back(a); + lines.push_back(b); + } - ss->set_radius(d); + Vector handles; + + for (int i = 0; i < 3; i++) { + + Vector3 ax; + ax[i] = aabb.position[i] + aabb.size[i]; + ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5; + ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5; + handles.push_back(ax); } - if (Object::cast_to(*s)) { + Vector3 center = aabb.position + aabb.size * 0.5; + for (int i = 0; i < 3; i++) { - Ref rs = s; - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb); - float d = ra.z; - if (d < 0.001) - d = 0.001; + Vector3 ax; + ax[i] = 1.0; + handles.push_back(center + ax); + lines.push_back(center); + lines.push_back(center + ax); + } - rs->set_length(d); + Ref material = get_material("visibility_notifier_material", p_gizmo); + + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); + + if (p_gizmo->is_selected()) { + Ref solid_material = get_material("visibility_notifier_solid_material", p_gizmo); + p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0); } - if (Object::cast_to(*s)) { + p_gizmo->add_handles(handles, get_material("handles")); +} - Vector3 axis; - axis[p_idx] = 1.0; - Ref bs = s; - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; - if (d < 0.001) - d = 0.001; +//// - Vector3 he = bs->get_extents(); - he[p_idx] = d; - bs->set_extents(he); +ParticlesGizmoPlugin::ParticlesGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4)); + create_material("particles_material", gizmo_color); + gizmo_color.a = 0.1; + create_material("particles_solid_material", gizmo_color); + create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_icon("GizmoParticles", "EditorIcons")); + create_handle_material("handles"); +} + +bool ParticlesGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} + +String ParticlesGizmoPlugin::get_name() const { + return "Particles"; +} + +bool ParticlesGizmoPlugin::is_selectable_when_hidden() const { + return true; +} + +String ParticlesGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { + + switch (p_idx) { + case 0: return "Size X"; + case 1: return "Size Y"; + case 2: return "Size Z"; + case 3: return "Pos X"; + case 4: return "Pos Y"; + case 5: return "Pos Z"; } - if (Object::cast_to(*s)) { + return ""; +} +Variant ParticlesGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { + + Particles *particles = Object::cast_to(p_gizmo->get_spatial_node()); + return particles->get_visibility_aabb(); +} +void ParticlesGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { + + Particles *particles = Object::cast_to(p_gizmo->get_spatial_node()); + + Transform gt = particles->get_global_transform(); + //gt.orthonormalize(); + Transform gi = gt.affine_inverse(); + + bool move = p_idx >= 3; + p_idx = p_idx % 3; + + AABB aabb = particles->get_visibility_aabb(); + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); + + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; + + Vector3 ofs = aabb.position + aabb.size * 0.5; + + Vector3 axis; + axis[p_idx] = 1.0; + + if (move) { - Vector3 axis; - axis[p_idx == 0 ? 0 : 2] = 1.0; - Ref cs = s; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = axis.dot(ra); - if (p_idx == 1) - d -= cs->get_radius(); - if (d < 0.001) - d = 0.001; + Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); - if (p_idx == 0) - cs->set_radius(d); - else if (p_idx == 1) - cs->set_height(d * 2.0); - } + float d = ra[p_idx]; - if (Object::cast_to(*s)) { + aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5; + particles->set_visibility_aabb(aabb); - Vector3 axis; - axis[p_idx == 0 ? 0 : 1] = 1.0; - Ref cs = s; + } else { Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = axis.dot(ra); + Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); + float d = ra[p_idx] - ofs[p_idx]; if (d < 0.001) d = 0.001; - - if (p_idx == 0) - cs->set_radius(d); - else if (p_idx == 1) - cs->set_height(d * 2.0); + //resize + aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d; + aabb.size[p_idx] = d * 2; + particles->set_visibility_aabb(aabb); } } -void CollisionShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { - Ref s = cs->get_shape(); - if (s.is_null()) + +void ParticlesGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + + Particles *particles = Object::cast_to(p_gizmo->get_spatial_node()); + + if (p_cancel) { + particles->set_visibility_aabb(p_restore); return; + } - if (Object::cast_to(*s)) { + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Particles AABB")); + ur->add_do_method(particles, "set_custom_aabb", particles->get_visibility_aabb()); + ur->add_undo_method(particles, "set_custom_aabb", p_restore); + ur->commit_action(); +} - Ref ss = s; - if (p_cancel) { - ss->set_radius(p_restore); - return; - } +void ParticlesGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Sphere Shape Radius")); - ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); - ur->add_undo_method(ss.ptr(), "set_radius", p_restore); - ur->commit_action(); + Particles *particles = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); + + Vector lines; + AABB aabb = particles->get_visibility_aabb(); + + for (int i = 0; i < 12; i++) { + Vector3 a, b; + aabb.get_edge(i, a, b); + lines.push_back(a); + lines.push_back(b); } - if (Object::cast_to(*s)) { + Vector handles; - Ref ss = s; - if (p_cancel) { - ss->set_extents(p_restore); - return; - } + for (int i = 0; i < 3; i++) { - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Box Shape Extents")); - ur->add_do_method(ss.ptr(), "set_extents", ss->get_extents()); - ur->add_undo_method(ss.ptr(), "set_extents", p_restore); - ur->commit_action(); + Vector3 ax; + ax[i] = aabb.position[i] + aabb.size[i]; + ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5; + ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5; + handles.push_back(ax); } - if (Object::cast_to(*s)) { + Vector3 center = aabb.position + aabb.size * 0.5; + for (int i = 0; i < 3; i++) { - Ref ss = s; - if (p_cancel) { - if (p_idx == 0) - ss->set_radius(p_restore); - else - ss->set_height(p_restore); - return; - } + Vector3 ax; + ax[i] = 1.0; + handles.push_back(center + ax); + lines.push_back(center); + lines.push_back(center + ax); + } - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - if (p_idx == 0) { - ur->create_action(TTR("Change Capsule Shape Radius")); - ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); - ur->add_undo_method(ss.ptr(), "set_radius", p_restore); - } else { - ur->create_action(TTR("Change Capsule Shape Height")); - ur->add_do_method(ss.ptr(), "set_height", ss->get_height()); - ur->add_undo_method(ss.ptr(), "set_height", p_restore); - } + Ref material = get_material("particles_material", p_gizmo); + Ref icon = get_material("particles_icon", p_gizmo); - ur->commit_action(); + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); + + if (p_gizmo->is_selected()) { + Ref solid_material = get_material("particles_solid_material", p_gizmo); + p_gizmo->add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0); } - if (Object::cast_to(*s)) { + p_gizmo->add_handles(handles, get_material("handles")); + p_gizmo->add_unscaled_billboard(icon, 0.05); +} +//// - Ref ss = s; - if (p_cancel) { - if (p_idx == 0) - ss->set_radius(p_restore); - else - ss->set_height(p_restore); - return; - } +ReflectionProbeGizmoPlugin::ReflectionProbeGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/reflection_probe", Color(0.6, 1, 0.5)); - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - if (p_idx == 0) { - ur->create_action(TTR("Change Cylinder Shape Radius")); - ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); - ur->add_undo_method(ss.ptr(), "set_radius", p_restore); - } else { - ur->create_action(TTR("Change Cylinder Shape Height")); - ur->add_do_method(ss.ptr(), "set_height", ss->get_height()); - ur->add_undo_method(ss.ptr(), "set_height", p_restore); - } + create_material("reflection_probe_material", gizmo_color); - ur->commit_action(); - } + gizmo_color.a = 0.5; + create_material("reflection_internal_material", gizmo_color); - if (Object::cast_to(*s)) { + gizmo_color.a = 0.1; + create_material("reflection_probe_solid_material", gizmo_color); - Ref ss = s; - if (p_cancel) { - ss->set_length(p_restore); - return; - } + create_icon_material("reflection_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoReflectionProbe", "EditorIcons")); + create_handle_material("handles"); +} - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Ray Shape Length")); - ur->add_do_method(ss.ptr(), "set_length", ss->get_length()); - ur->add_undo_method(ss.ptr(), "set_length", p_restore); - ur->commit_action(); - } +bool ReflectionProbeGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; } -void CollisionShapeSpatialGizmo::redraw() { - clear(); +String ReflectionProbeGizmoPlugin::get_name() const { + return "ReflectionProbe"; +} - Ref s = cs->get_shape(); - if (s.is_null()) - return; +String ReflectionProbeGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape"); - Ref material = create_material("shape_material", gizmo_color); + switch (p_idx) { + case 0: return "Extents X"; + case 1: return "Extents Y"; + case 2: return "Extents Z"; + case 3: return "Origin X"; + case 4: return "Origin Y"; + case 5: return "Origin Z"; + } - if (Object::cast_to(*s)) { + return ""; +} +Variant ReflectionProbeGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { - Ref sp = s; - float r = sp->get_radius(); + ReflectionProbe *probe = Object::cast_to(p_gizmo->get_spatial_node()); + return AABB(probe->get_extents(), probe->get_origin_offset()); +} +void ReflectionProbeGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { - Vector points; + ReflectionProbe *probe = Object::cast_to(p_gizmo->get_spatial_node()); + Transform gt = probe->get_global_transform(); - for (int i = 0; i <= 360; i++) { + Transform gi = gt.affine_inverse(); - float ra = Math::deg2rad((float)i); - float rb = Math::deg2rad((float)i + 1); - Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; - Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; + if (p_idx < 3) { + Vector3 extents = probe->get_extents(); - points.push_back(Vector3(a.x, 0, a.y)); - points.push_back(Vector3(b.x, 0, b.y)); - points.push_back(Vector3(0, a.x, a.y)); - points.push_back(Vector3(0, b.x, b.y)); - points.push_back(Vector3(a.x, a.y, 0)); - points.push_back(Vector3(b.x, b.y, 0)); - } + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); - Vector collision_segments; + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; - for (int i = 0; i < 64; i++) { + Vector3 axis; + axis[p_idx] = 1.0; - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; - Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; - Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); + float d = ra[p_idx]; + if (d < 0.001) + d = 0.001; - collision_segments.push_back(Vector3(a.x, 0, a.y)); - collision_segments.push_back(Vector3(b.x, 0, b.y)); - collision_segments.push_back(Vector3(0, a.x, a.y)); - collision_segments.push_back(Vector3(0, b.x, b.y)); - collision_segments.push_back(Vector3(a.x, a.y, 0)); - collision_segments.push_back(Vector3(b.x, b.y, 0)); - } + extents[p_idx] = d; + probe->set_extents(extents); + } else { - add_lines(points, material); - add_collision_segments(collision_segments); - Vector handles; - handles.push_back(Vector3(r, 0, 0)); - add_handles(handles); - } + p_idx -= 3; - if (Object::cast_to(*s)) { + Vector3 origin = probe->get_origin_offset(); + origin[p_idx] = 0; - Ref bs = s; - Vector lines; - AABB aabb; - aabb.position = -bs->get_extents(); - aabb.size = aabb.position * -2; + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); - for (int i = 0; i < 12; i++) { - Vector3 a, b; - aabb.get_edge(i, a, b); - lines.push_back(a); - lines.push_back(b); - } + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; - Vector handles; + Vector3 axis; + axis[p_idx] = 1.0; - for (int i = 0; i < 3; i++) { + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb); + float d = ra[p_idx]; + d += 0.25; - Vector3 ax; - ax[i] = bs->get_extents()[i]; - handles.push_back(ax); - } + origin[p_idx] = d; + probe->set_origin_offset(origin); + } +} + +void ReflectionProbeGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + + ReflectionProbe *probe = Object::cast_to(p_gizmo->get_spatial_node()); + + AABB restore = p_restore; - add_lines(lines, material); - add_collision_segments(lines); - add_handles(handles); + if (p_cancel) { + probe->set_extents(restore.position); + probe->set_origin_offset(restore.size); + return; } - if (Object::cast_to(*s)) { - - Ref cs = s; - float radius = cs->get_radius(); - float height = cs->get_height(); + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Probe Extents")); + ur->add_do_method(probe, "set_extents", probe->get_extents()); + ur->add_do_method(probe, "set_origin_offset", probe->get_origin_offset()); + ur->add_undo_method(probe, "set_extents", restore.position); + ur->add_undo_method(probe, "set_origin_offset", restore.size); + ur->commit_action(); +} - Vector points; +void ReflectionProbeGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - Vector3 d(0, 0, height * 0.5); - for (int i = 0; i < 360; i++) { + ReflectionProbe *probe = Object::cast_to(p_gizmo->get_spatial_node()); - float ra = Math::deg2rad((float)i); - float rb = Math::deg2rad((float)i + 1); - Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; - Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; + p_gizmo->clear(); - points.push_back(Vector3(a.x, a.y, 0) + d); - points.push_back(Vector3(b.x, b.y, 0) + d); + Vector lines; + Vector internal_lines; + Vector3 extents = probe->get_extents(); - points.push_back(Vector3(a.x, a.y, 0) - d); - points.push_back(Vector3(b.x, b.y, 0) - d); + AABB aabb; + aabb.position = -extents; + aabb.size = extents * 2; - if (i % 90 == 0) { + for (int i = 0; i < 12; i++) { + Vector3 a, b; + aabb.get_edge(i, a, b); + lines.push_back(a); + lines.push_back(b); + } - points.push_back(Vector3(a.x, a.y, 0) + d); - points.push_back(Vector3(a.x, a.y, 0) - d); - } + for (int i = 0; i < 8; i++) { + Vector3 ep = aabb.get_endpoint(i); + internal_lines.push_back(probe->get_origin_offset()); + internal_lines.push_back(ep); + } - Vector3 dud = i < 180 ? d : -d; + Vector handles; - points.push_back(Vector3(0, a.y, a.x) + dud); - points.push_back(Vector3(0, b.y, b.x) + dud); - points.push_back(Vector3(a.y, 0, a.x) + dud); - points.push_back(Vector3(b.y, 0, b.x) + dud); - } + for (int i = 0; i < 3; i++) { - add_lines(points, material); + Vector3 ax; + ax[i] = aabb.position[i] + aabb.size[i]; + handles.push_back(ax); + } - Vector collision_segments; + for (int i = 0; i < 3; i++) { - for (int i = 0; i < 64; i++) { + Vector3 orig_handle = probe->get_origin_offset(); + orig_handle[i] -= 0.25; + lines.push_back(orig_handle); + handles.push_back(orig_handle); - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; - Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; - Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; + orig_handle[i] += 0.5; + lines.push_back(orig_handle); + } - collision_segments.push_back(Vector3(a.x, a.y, 0) + d); - collision_segments.push_back(Vector3(b.x, b.y, 0) + d); + Ref material = get_material("reflection_probe_material", p_gizmo); + Ref material_internal = get_material("reflection_internal_material", p_gizmo); + Ref icon = get_material("reflection_probe_icon", p_gizmo); - collision_segments.push_back(Vector3(a.x, a.y, 0) - d); - collision_segments.push_back(Vector3(b.x, b.y, 0) - d); + p_gizmo->add_lines(lines, material); + p_gizmo->add_lines(internal_lines, material_internal); - if (i % 16 == 0) { + if (p_gizmo->is_selected()) { + Ref solid_material = get_material("reflection_probe_solid_material", p_gizmo); + p_gizmo->add_solid_box(solid_material, probe->get_extents() * 2.0); + } - collision_segments.push_back(Vector3(a.x, a.y, 0) + d); - collision_segments.push_back(Vector3(a.x, a.y, 0) - d); - } + p_gizmo->add_unscaled_billboard(icon, 0.05); + p_gizmo->add_collision_segments(lines); + p_gizmo->add_handles(handles, get_material("handles")); +} - Vector3 dud = i < 32 ? d : -d; +GIProbeGizmoPlugin::GIProbeGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/gi_probe", Color(0.5, 1, 0.6)); - collision_segments.push_back(Vector3(0, a.y, a.x) + dud); - collision_segments.push_back(Vector3(0, b.y, b.x) + dud); - collision_segments.push_back(Vector3(a.y, 0, a.x) + dud); - collision_segments.push_back(Vector3(b.y, 0, b.x) + dud); - } + create_material("gi_probe_material", gizmo_color); - add_collision_segments(collision_segments); + gizmo_color.a = 0.5; + create_material("gi_probe_internal_material", gizmo_color); - Vector handles; - handles.push_back(Vector3(cs->get_radius(), 0, 0)); - handles.push_back(Vector3(0, 0, cs->get_height() * 0.5 + cs->get_radius())); - add_handles(handles); - } + gizmo_color.a = 0.1; + create_material("gi_probe_solid_material", gizmo_color); - if (Object::cast_to(*s)) { + create_icon_material("gi_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoGIProbe", "EditorIcons")); + create_handle_material("handles"); +} - Ref cs = s; - float radius = cs->get_radius(); - float height = cs->get_height(); +bool GIProbeGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} - Vector points; +String GIProbeGizmoPlugin::get_name() const { + return "GIProbe"; +} - Vector3 d(0, height * 0.5, 0); - for (int i = 0; i < 360; i++) { +String GIProbeGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { - float ra = Math::deg2rad((float)i); - float rb = Math::deg2rad((float)i + 1); - Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; - Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; + switch (p_idx) { + case 0: return "Extents X"; + case 1: return "Extents Y"; + case 2: return "Extents Z"; + } - points.push_back(Vector3(a.x, 0, a.y) + d); - points.push_back(Vector3(b.x, 0, b.y) + d); + return ""; +} +Variant GIProbeGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { - points.push_back(Vector3(a.x, 0, a.y) - d); - points.push_back(Vector3(b.x, 0, b.y) - d); + GIProbe *probe = Object::cast_to(p_gizmo->get_spatial_node()); + return probe->get_extents(); +} +void GIProbeGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { - if (i % 90 == 0) { + GIProbe *probe = Object::cast_to(p_gizmo->get_spatial_node()); - points.push_back(Vector3(a.x, 0, a.y) + d); - points.push_back(Vector3(a.x, 0, a.y) - d); - } - } + Transform gt = probe->get_global_transform(); + //gt.orthonormalize(); + Transform gi = gt.affine_inverse(); - add_lines(points, material); + Vector3 extents = probe->get_extents(); - Vector collision_segments; + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); - for (int i = 0; i < 64; i++) { + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; - float ra = i * Math_PI * 2.0 / 64.0; - float rb = (i + 1) * Math_PI * 2.0 / 64.0; - Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; - Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; + Vector3 axis; + axis[p_idx] = 1.0; - collision_segments.push_back(Vector3(a.x, 0, a.y) + d); - collision_segments.push_back(Vector3(b.x, 0, b.y) + d); + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); + float d = ra[p_idx]; + if (d < 0.001) + d = 0.001; - collision_segments.push_back(Vector3(a.x, 0, a.y) - d); - collision_segments.push_back(Vector3(b.x, 0, b.y) - d); + extents[p_idx] = d; + probe->set_extents(extents); +} - if (i % 16 == 0) { +void GIProbeGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { - collision_segments.push_back(Vector3(a.x, 0, a.y) + d); - collision_segments.push_back(Vector3(a.x, 0, a.y) - d); - } - } + GIProbe *probe = Object::cast_to(p_gizmo->get_spatial_node()); - add_collision_segments(collision_segments); + Vector3 restore = p_restore; - Vector handles; - handles.push_back(Vector3(cs->get_radius(), 0, 0)); - handles.push_back(Vector3(0, cs->get_height() * 0.5, 0)); - add_handles(handles); + if (p_cancel) { + probe->set_extents(restore); + return; } - if (Object::cast_to(*s)) { + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Probe Extents")); + ur->add_do_method(probe, "set_extents", probe->get_extents()); + ur->add_undo_method(probe, "set_extents", restore); + ur->commit_action(); +} - Ref ps = s; - Plane p = ps->get_plane(); - Vector points; +void GIProbeGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - Vector3 n1 = p.get_any_perpendicular_normal(); - Vector3 n2 = p.normal.cross(n1).normalized(); + GIProbe *probe = Object::cast_to(p_gizmo->get_spatial_node()); - Vector3 pface[4] = { - p.normal * p.d + n1 * 10.0 + n2 * 10.0, - p.normal * p.d + n1 * 10.0 + n2 * -10.0, - p.normal * p.d + n1 * -10.0 + n2 * -10.0, - p.normal * p.d + n1 * -10.0 + n2 * 10.0, - }; + Ref material = get_material("gi_probe_material", p_gizmo); + Ref icon = get_material("gi_probe_icon", p_gizmo); + Ref material_internal = get_material("gi_probe_internal_material", p_gizmo); - points.push_back(pface[0]); - points.push_back(pface[1]); - points.push_back(pface[1]); - points.push_back(pface[2]); - points.push_back(pface[2]); - points.push_back(pface[3]); - points.push_back(pface[3]); - points.push_back(pface[0]); - points.push_back(p.normal * p.d); - points.push_back(p.normal * p.d + p.normal * 3); + p_gizmo->clear(); + + Vector lines; + Vector3 extents = probe->get_extents(); + + static const int subdivs[GIProbe::SUBDIV_MAX] = { 64, 128, 256, 512 }; + + AABB aabb = AABB(-extents, extents * 2); + int subdiv = subdivs[probe->get_subdiv()]; + float cell_size = aabb.get_longest_axis_size() / subdiv; - add_lines(points, material); - add_collision_segments(points); + for (int i = 0; i < 12; i++) { + Vector3 a, b; + aabb.get_edge(i, a, b); + lines.push_back(a); + lines.push_back(b); } - if (Object::cast_to(*s)) { + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); - PoolVector points = Object::cast_to(*s)->get_points(); + lines.clear(); - if (points.size() > 3) { + for (int i = 1; i < subdiv; i++) { - QuickHull qh; - Vector varr = Variant(points); - Geometry::MeshData md; - Error err = qh.build(varr, md); - if (err == OK) { - Vector points; - points.resize(md.edges.size() * 2); - for (int i = 0; i < md.edges.size(); i++) { - points.write[i * 2 + 0] = md.vertices[md.edges[i].a]; - points.write[i * 2 + 1] = md.vertices[md.edges[i].b]; - } + for (int j = 0; j < 3; j++) { - add_lines(points, material); - add_collision_segments(points); + if (cell_size * i > aabb.size[j]) { + continue; } - } - } - if (Object::cast_to(*s)) { + Vector2 dir; + dir[j] = 1.0; + Vector2 ta, tb; + int j_n1 = (j + 1) % 3; + int j_n2 = (j + 2) % 3; + ta[j_n1] = 1.0; + tb[j_n2] = 1.0; - Ref rs = s; + for (int k = 0; k < 4; k++) { - Vector points; - points.push_back(Vector3()); - points.push_back(Vector3(0, 0, rs->get_length())); - add_lines(points, material); - add_collision_segments(points); - Vector handles; - handles.push_back(Vector3(0, 0, rs->get_length())); - add_handles(handles); - } -} -CollisionShapeSpatialGizmo::CollisionShapeSpatialGizmo(CollisionShape *p_cs) { + Vector3 from = aabb.position, to = aabb.position; + from[j] += cell_size * i; + to[j] += cell_size * i; - cs = p_cs; - set_spatial_node(p_cs); -} + if (k & 1) { + to[j_n1] += aabb.size[j_n1]; + } else { + + to[j_n2] += aabb.size[j_n2]; + } -///// + if (k & 2) { + from[j_n1] += aabb.size[j_n1]; + from[j_n2] += aabb.size[j_n2]; + } -void CollisionPolygonSpatialGizmo::redraw() { + lines.push_back(from); + lines.push_back(to); + } + } + } - clear(); + p_gizmo->add_lines(lines, material_internal); - Vector points = polygon->get_polygon(); - float depth = polygon->get_depth() * 0.5; + Vector handles; - Vector lines; - for (int i = 0; i < points.size(); i++) { + for (int i = 0; i < 3; i++) { - int n = (i + 1) % points.size(); - lines.push_back(Vector3(points[i].x, points[i].y, depth)); - lines.push_back(Vector3(points[n].x, points[n].y, depth)); - lines.push_back(Vector3(points[i].x, points[i].y, -depth)); - lines.push_back(Vector3(points[n].x, points[n].y, -depth)); - lines.push_back(Vector3(points[i].x, points[i].y, depth)); - lines.push_back(Vector3(points[i].x, points[i].y, -depth)); + Vector3 ax; + ax[i] = aabb.position[i] + aabb.size[i]; + handles.push_back(ax); } - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape"); - Ref material = create_material("shape_material", gizmo_color); + if (p_gizmo->is_selected()) { + Ref solid_material = get_material("gi_probe_solid_material", p_gizmo); + p_gizmo->add_solid_box(solid_material, aabb.get_size()); + } - add_lines(lines, material); - add_collision_segments(lines); + p_gizmo->add_unscaled_billboard(icon, 0.05); + p_gizmo->add_handles(handles, get_material("handles")); } -CollisionPolygonSpatialGizmo::CollisionPolygonSpatialGizmo(CollisionPolygon *p_polygon) { +//// + +BakedIndirectLightGizmoPlugin::BakedIndirectLightGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/baked_indirect_light", Color(0.5, 0.6, 1)); + + create_material("baked_indirect_light_material", gizmo_color); - set_spatial_node(p_polygon); - polygon = p_polygon; + gizmo_color.a = 0.1; + create_material("baked_indirect_light_internal_material", gizmo_color); + + create_icon_material("baked_indirect_light_icon", SpatialEditor::get_singleton()->get_icon("GizmoBakedLightmap", "EditorIcons")); + create_handle_material("handles"); } -/// -String VisibilityNotifierGizmo::get_handle_name(int p_idx) const { +String BakedIndirectLightGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { switch (p_idx) { - case 0: return "X"; - case 1: return "Y"; - case 2: return "Z"; + case 0: return "Extents X"; + case 1: return "Extents Y"; + case 2: return "Extents Z"; } return ""; } -Variant VisibilityNotifierGizmo::get_handle_value(int p_idx) const { +Variant BakedIndirectLightGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { - return notifier->get_aabb(); + BakedLightmap *baker = Object::cast_to(p_gizmo->get_spatial_node()); + return baker->get_extents(); } -void VisibilityNotifierGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { +void BakedIndirectLightGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { - Transform gt = notifier->get_global_transform(); + BakedLightmap *baker = Object::cast_to(p_gizmo->get_spatial_node()); + + Transform gt = baker->get_global_transform(); //gt.orthonormalize(); Transform gi = gt.affine_inverse(); - AABB aabb = notifier->get_aabb(); + Vector3 extents = baker->get_extents(); + Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); - Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; - Vector3 ofs = aabb.position + aabb.size * 0.5; + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; Vector3 axis; axis[p_idx] = 1.0; Vector3 ra, rb; - Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); + Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); float d = ra[p_idx]; if (d < 0.001) d = 0.001; - aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d; - aabb.size[p_idx] = d * 2; - notifier->set_aabb(aabb); + extents[p_idx] = d; + baker->set_extents(extents); } -void VisibilityNotifierGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { +void BakedIndirectLightGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + + BakedLightmap *baker = Object::cast_to(p_gizmo->get_spatial_node()); + + Vector3 restore = p_restore; if (p_cancel) { - notifier->set_aabb(p_restore); + baker->set_extents(restore); return; } UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Notifier Extents")); - ur->add_do_method(notifier, "set_aabb", notifier->get_aabb()); - ur->add_undo_method(notifier, "set_aabb", p_restore); + ur->create_action(TTR("Change Probe Extents")); + ur->add_do_method(baker, "set_extents", baker->get_extents()); + ur->add_undo_method(baker, "set_extents", restore); ur->commit_action(); } -void VisibilityNotifierGizmo::redraw() { +bool BakedIndirectLightGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/visibility_notifier"); - Ref material = create_material("visibility_notifier_material", gizmo_color); +String BakedIndirectLightGizmoPlugin::get_name() const { + return "BakedLightmap"; +} - clear(); +void BakedIndirectLightGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + + BakedLightmap *baker = Object::cast_to(p_gizmo->get_spatial_node()); + + Ref material = get_material("baked_indirect_light_material", p_gizmo); + Ref icon = get_material("baked_indirect_light_icon", p_gizmo); + Ref material_internal = get_material("baked_indirect_light_internal_material", p_gizmo); + + p_gizmo->clear(); Vector lines; - AABB aabb = notifier->get_aabb(); + Vector3 extents = baker->get_extents(); + + AABB aabb = AABB(-extents, extents * 2); for (int i = 0; i < 12; i++) { Vector3 a, b; @@ -2681,6 +2848,9 @@ void VisibilityNotifierGizmo::redraw() { lines.push_back(b); } + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); + Vector handles; for (int i = 0; i < 3; i++) { @@ -2690,600 +2860,670 @@ void VisibilityNotifierGizmo::redraw() { handles.push_back(ax); } - add_lines(lines, material); - //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05); - add_collision_segments(lines); - add_handles(handles); + if (p_gizmo->is_selected()) { + p_gizmo->add_solid_box(material_internal, aabb.get_size()); + } + + p_gizmo->add_unscaled_billboard(icon, 0.05); + p_gizmo->add_handles(handles, get_material("handles")); } -VisibilityNotifierGizmo::VisibilityNotifierGizmo(VisibilityNotifier *p_notifier) { - notifier = p_notifier; - set_spatial_node(p_notifier); +//// + +CollisionShapeSpatialGizmoPlugin::CollisionShapeSpatialGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); + create_material("shape_material", gizmo_color); + create_handle_material("handles"); } -//////// +bool CollisionShapeSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} -/// +String CollisionShapeSpatialGizmoPlugin::get_name() const { + return "CollisionShape"; +} -String ParticlesGizmo::get_handle_name(int p_idx) const { +String CollisionShapeSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { - switch (p_idx) { - case 0: return "Size X"; - case 1: return "Size Y"; - case 2: return "Size Z"; - case 3: return "Pos X"; - case 4: return "Pos Y"; - case 5: return "Pos Z"; + const CollisionShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); + + Ref s = cs->get_shape(); + if (s.is_null()) + return ""; + + if (Object::cast_to(*s)) { + + return "Radius"; + } + + if (Object::cast_to(*s)) { + + return "Extents"; + } + + if (Object::cast_to(*s)) { + + return p_idx == 0 ? "Radius" : "Height"; + } + + if (Object::cast_to(*s)) { + + return p_idx == 0 ? "Radius" : "Height"; + } + + if (Object::cast_to(*s)) { + + return "Length"; } return ""; } -Variant ParticlesGizmo::get_handle_value(int p_idx) const { - return particles->get_visibility_aabb(); -} -void ParticlesGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { +Variant CollisionShapeSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { - Transform gt = particles->get_global_transform(); - //gt.orthonormalize(); - Transform gi = gt.affine_inverse(); + CollisionShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); - bool move = p_idx >= 3; - p_idx = p_idx % 3; + Ref s = cs->get_shape(); + if (s.is_null()) + return Variant(); - AABB aabb = particles->get_visibility_aabb(); - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); + if (Object::cast_to(*s)) { - Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; + Ref ss = s; + return ss->get_radius(); + } - Vector3 ofs = aabb.position + aabb.size * 0.5; + if (Object::cast_to(*s)) { - Vector3 axis; - axis[p_idx] = 1.0; + Ref bs = s; + return bs->get_extents(); + } - if (move) { + if (Object::cast_to(*s)) { - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); + Ref cs = s; + return p_idx == 0 ? cs->get_radius() : cs->get_height(); + } - float d = ra[p_idx]; + if (Object::cast_to(*s)) { - aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5; - particles->set_visibility_aabb(aabb); + Ref cs = s; + return p_idx == 0 ? cs->get_radius() : cs->get_height(); + } - } else { - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); + if (Object::cast_to(*s)) { - float d = ra[p_idx] - ofs[p_idx]; - if (d < 0.001) - d = 0.001; - //resize - aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d; - aabb.size[p_idx] = d * 2; - particles->set_visibility_aabb(aabb); + Ref cs = s; + return cs->get_length(); } + + return Variant(); } +void CollisionShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { -void ParticlesGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { + CollisionShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); - if (p_cancel) { - particles->set_visibility_aabb(p_restore); + Ref s = cs->get_shape(); + if (s.is_null()) return; - } - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Particles AABB")); - ur->add_do_method(particles, "set_custom_aabb", particles->get_visibility_aabb()); - ur->add_undo_method(particles, "set_custom_aabb", p_restore); - ur->commit_action(); -} + Transform gt = cs->get_global_transform(); + gt.orthonormalize(); + Transform gi = gt.affine_inverse(); -void ParticlesGizmo::redraw() { + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); - clear(); + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) }; - Vector lines; - AABB aabb = particles->get_visibility_aabb(); + if (Object::cast_to(*s)) { - for (int i = 0; i < 12; i++) { - Vector3 a, b; - aabb.get_edge(i, a, b); - lines.push_back(a); - lines.push_back(b); + Ref ss = s; + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb); + float d = ra.x; + if (d < 0.001) + d = 0.001; + + ss->set_radius(d); } - Vector handles; + if (Object::cast_to(*s)) { - for (int i = 0; i < 3; i++) { + Ref rs = s; + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb); + float d = ra.z; + if (d < 0.001) + d = 0.001; - Vector3 ax; - ax[i] = aabb.position[i] + aabb.size[i]; - ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5; - ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5; - handles.push_back(ax); + rs->set_length(d); } - Vector3 center = aabb.position + aabb.size * 0.5; - for (int i = 0; i < 3; i++) { + if (Object::cast_to(*s)) { - Vector3 ax; - ax[i] = 1.0; - handles.push_back(center + ax); - lines.push_back(center); - lines.push_back(center + ax); + Vector3 axis; + axis[p_idx] = 1.0; + Ref bs = s; + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); + float d = ra[p_idx]; + if (d < 0.001) + d = 0.001; + + Vector3 he = bs->get_extents(); + he[p_idx] = d; + bs->set_extents(he); + } + + if (Object::cast_to(*s)) { + + Vector3 axis; + axis[p_idx == 0 ? 0 : 2] = 1.0; + Ref cs = s; + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); + float d = axis.dot(ra); + if (p_idx == 1) + d -= cs->get_radius(); + if (d < 0.001) + d = 0.001; + + if (p_idx == 0) + cs->set_radius(d); + else if (p_idx == 1) + cs->set_height(d * 2.0); } - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/particles"); - Ref material = create_material("particles_material", gizmo_color); - Ref icon = create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_icon("GizmoParticles", "EditorIcons")); + if (Object::cast_to(*s)) { - add_lines(lines, material); - add_collision_segments(lines); + Vector3 axis; + axis[p_idx == 0 ? 0 : 1] = 1.0; + Ref cs = s; + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); + float d = axis.dot(ra); - if (is_selected()) { + if (d < 0.001) + d = 0.001; - gizmo_color.a = 0.1; - Ref solid_material = create_material("particles_solid_material", gizmo_color); - add_solid_box(solid_material, aabb.get_size(), aabb.get_position() + aabb.get_size() / 2.0); + if (p_idx == 0) + cs->set_radius(d); + else if (p_idx == 1) + cs->set_height(d * 2.0); } - - //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05); - - add_handles(handles); - add_unscaled_billboard(icon, 0.05); } -ParticlesGizmo::ParticlesGizmo(Particles *p_particles) { +void CollisionShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { - particles = p_particles; - set_spatial_node(p_particles); -} + CollisionShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); -//////// + Ref s = cs->get_shape(); + if (s.is_null()) + return; -/// + if (Object::cast_to(*s)) { -String ReflectionProbeGizmo::get_handle_name(int p_idx) const { + Ref ss = s; + if (p_cancel) { + ss->set_radius(p_restore); + return; + } - switch (p_idx) { - case 0: return "Extents X"; - case 1: return "Extents Y"; - case 2: return "Extents Z"; - case 3: return "Origin X"; - case 4: return "Origin Y"; - case 5: return "Origin Z"; + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Sphere Shape Radius")); + ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); + ur->add_undo_method(ss.ptr(), "set_radius", p_restore); + ur->commit_action(); } - return ""; -} -Variant ReflectionProbeGizmo::get_handle_value(int p_idx) const { - - return AABB(probe->get_extents(), probe->get_origin_offset()); -} -void ReflectionProbeGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { + if (Object::cast_to(*s)) { - Transform gt = probe->get_global_transform(); - //gt.orthonormalize(); - Transform gi = gt.affine_inverse(); + Ref ss = s; + if (p_cancel) { + ss->set_extents(p_restore); + return; + } - if (p_idx < 3) { - Vector3 extents = probe->get_extents(); + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Box Shape Extents")); + ur->add_do_method(ss.ptr(), "set_extents", ss->get_extents()); + ur->add_undo_method(ss.ptr(), "set_extents", p_restore); + ur->commit_action(); + } - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); + if (Object::cast_to(*s)) { - Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; + Ref ss = s; + if (p_cancel) { + if (p_idx == 0) + ss->set_radius(p_restore); + else + ss->set_height(p_restore); + return; + } - Vector3 axis; - axis[p_idx] = 1.0; + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + if (p_idx == 0) { + ur->create_action(TTR("Change Capsule Shape Radius")); + ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); + ur->add_undo_method(ss.ptr(), "set_radius", p_restore); + } else { + ur->create_action(TTR("Change Capsule Shape Height")); + ur->add_do_method(ss.ptr(), "set_height", ss->get_height()); + ur->add_undo_method(ss.ptr(), "set_height", p_restore); + } - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; - if (d < 0.001) - d = 0.001; + ur->commit_action(); + } - extents[p_idx] = d; - probe->set_extents(extents); - } else { + if (Object::cast_to(*s)) { - p_idx -= 3; + Ref ss = s; + if (p_cancel) { + if (p_idx == 0) + ss->set_radius(p_restore); + else + ss->set_height(p_restore); + return; + } - Vector3 origin = probe->get_origin_offset(); - origin[p_idx] = 0; + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + if (p_idx == 0) { + ur->create_action(TTR("Change Cylinder Shape Radius")); + ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); + ur->add_undo_method(ss.ptr(), "set_radius", p_restore); + } else { + ur->create_action( + /// - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); + //////// + TTR("Change Cylinder Shape Height")); + ur->add_do_method(ss.ptr(), "set_height", ss->get_height()); + ur->add_undo_method(ss.ptr(), "set_height", p_restore); + } - Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; + ur->commit_action(); + } - Vector3 axis; - axis[p_idx] = 1.0; + if (Object::cast_to(*s)) { - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; - d += 0.25; + Ref ss = s; + if (p_cancel) { + ss->set_length(p_restore); + return; + } - origin[p_idx] = d; - probe->set_origin_offset(origin); + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Ray Shape Length")); + ur->add_do_method(ss.ptr(), "set_length", ss->get_length()); + ur->add_undo_method(ss.ptr(), "set_length", p_restore); + ur->commit_action(); } } +void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { -void ReflectionProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { + CollisionShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); - AABB restore = p_restore; + p_gizmo->clear(); - if (p_cancel) { - probe->set_extents(restore.position); - probe->set_origin_offset(restore.size); + Ref s = cs->get_shape(); + if (s.is_null()) return; - } - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Probe Extents")); - ur->add_do_method(probe, "set_extents", probe->get_extents()); - ur->add_do_method(probe, "set_origin_offset", probe->get_origin_offset()); - ur->add_undo_method(probe, "set_extents", restore.position); - ur->add_undo_method(probe, "set_origin_offset", restore.size); - ur->commit_action(); -} -void ReflectionProbeGizmo::redraw() { + Ref material = get_material("shape_material", p_gizmo); + Ref handles_material = get_material("handles"); - clear(); + if (Object::cast_to(*s)) { - Vector lines; - Vector internal_lines; - Vector3 extents = probe->get_extents(); + Ref sp = s; + float r = sp->get_radius(); - AABB aabb; - aabb.position = -extents; - aabb.size = extents * 2; + Vector points; - for (int i = 0; i < 12; i++) { - Vector3 a, b; - aabb.get_edge(i, a, b); - lines.push_back(a); - lines.push_back(b); - } + for (int i = 0; i <= 360; i++) { - for (int i = 0; i < 8; i++) { - Vector3 ep = aabb.get_endpoint(i); - internal_lines.push_back(probe->get_origin_offset()); - internal_lines.push_back(ep); - } + float ra = Math::deg2rad((float)i); + float rb = Math::deg2rad((float)i + 1); + Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; + Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; - Vector handles; + points.push_back(Vector3(a.x, 0, a.y)); + points.push_back(Vector3(b.x, 0, b.y)); + points.push_back(Vector3(0, a.x, a.y)); + points.push_back(Vector3(0, b.x, b.y)); + points.push_back(Vector3(a.x, a.y, 0)); + points.push_back(Vector3(b.x, b.y, 0)); + } - for (int i = 0; i < 3; i++) { + Vector collision_segments; - Vector3 ax; - ax[i] = aabb.position[i] + aabb.size[i]; - handles.push_back(ax); - } + for (int i = 0; i < 64; i++) { - for (int i = 0; i < 3; i++) { + float ra = i * Math_PI * 2.0 / 64.0; + float rb = (i + 1) * Math_PI * 2.0 / 64.0; + Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; + Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; - Vector3 orig_handle = probe->get_origin_offset(); - orig_handle[i] -= 0.25; - lines.push_back(orig_handle); - handles.push_back(orig_handle); + collision_segments.push_back(Vector3(a.x, 0, a.y)); + collision_segments.push_back(Vector3(b.x, 0, b.y)); + collision_segments.push_back(Vector3(0, a.x, a.y)); + collision_segments.push_back(Vector3(0, b.x, b.y)); + collision_segments.push_back(Vector3(a.x, a.y, 0)); + collision_segments.push_back(Vector3(b.x, b.y, 0)); + } - orig_handle[i] += 0.5; - lines.push_back(orig_handle); + p_gizmo->add_lines(points, material); + p_gizmo->add_collision_segments(collision_segments); + Vector handles; + handles.push_back(Vector3(r, 0, 0)); + p_gizmo->add_handles(handles, handles_material); } - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/reflection_probe"); - Ref material = create_material("reflection_probe_material", gizmo_color); - Ref icon = create_icon_material("reflection_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoReflectionProbe", "EditorIcons")); - - Color gizmo_color_internal = gizmo_color; - gizmo_color_internal.a = 0.5; - Ref material_internal = create_material("reflection_internal_material", gizmo_color_internal); - - add_lines(lines, material); - add_lines(internal_lines, material_internal); - - if (is_selected()) { - - gizmo_color.a = 0.1; - Ref solid_material = create_material("reflection_probe_solid_material", gizmo_color); - add_solid_box(solid_material, probe->get_extents() * 2.0); - } + if (Object::cast_to(*s)) { - //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05); - add_unscaled_billboard(icon, 0.05); - add_collision_segments(lines); - add_handles(handles); -} -ReflectionProbeGizmo::ReflectionProbeGizmo(ReflectionProbe *p_probe) { + Ref bs = s; + Vector lines; + AABB aabb; + aabb.position = -bs->get_extents(); + aabb.size = aabb.position * -2; - probe = p_probe; - set_spatial_node(p_probe); -} + for (int i = 0; i < 12; i++) { + Vector3 a, b; + aabb.get_edge(i, a, b); + lines.push_back(a); + lines.push_back(b); + } -//////// + Vector handles; -/// + for (int i = 0; i < 3; i++) { -String GIProbeGizmo::get_handle_name(int p_idx) const { + Vector3 ax; + ax[i] = bs->get_extents()[i]; + handles.push_back(ax); + } - switch (p_idx) { - case 0: return "Extents X"; - case 1: return "Extents Y"; - case 2: return "Extents Z"; + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); + p_gizmo->add_handles(handles, handles_material); } - return ""; -} -Variant GIProbeGizmo::get_handle_value(int p_idx) const { + if (Object::cast_to(*s)) { - return probe->get_extents(); -} -void GIProbeGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { + Ref cs = s; + float radius = cs->get_radius(); + float height = cs->get_height(); - Transform gt = probe->get_global_transform(); - //gt.orthonormalize(); - Transform gi = gt.affine_inverse(); + Vector points; - Vector3 extents = probe->get_extents(); + Vector3 d(0, 0, height * 0.5); + for (int i = 0; i < 360; i++) { - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); + float ra = Math::deg2rad((float)i); + float rb = Math::deg2rad((float)i + 1); + Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; + Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; - Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; + points.push_back(Vector3(a.x, a.y, 0) + d); + points.push_back(Vector3(b.x, b.y, 0) + d); - Vector3 axis; - axis[p_idx] = 1.0; + points.push_back(Vector3(a.x, a.y, 0) - d); + points.push_back(Vector3(b.x, b.y, 0) - d); - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; - if (d < 0.001) - d = 0.001; + if (i % 90 == 0) { - extents[p_idx] = d; - probe->set_extents(extents); -} + points.push_back(Vector3(a.x, a.y, 0) + d); + points.push_back(Vector3(a.x, a.y, 0) - d); + } -void GIProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { + Vector3 dud = i < 180 ? d : -d; - Vector3 restore = p_restore; + points.push_back(Vector3(0, a.y, a.x) + dud); + points.push_back(Vector3(0, b.y, b.x) + dud); + points.push_back(Vector3(a.y, 0, a.x) + dud); + points.push_back(Vector3(b.y, 0, b.x) + dud); + } - if (p_cancel) { - probe->set_extents(restore); - return; - } + p_gizmo->add_lines(points, material); - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Probe Extents")); - ur->add_do_method(probe, "set_extents", probe->get_extents()); - ur->add_undo_method(probe, "set_extents", restore); - ur->commit_action(); -} + Vector collision_segments; -void GIProbeGizmo::redraw() { + for (int i = 0; i < 64; i++) { - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/gi_probe"); - Ref material = create_material("gi_probe_material", gizmo_color); - Ref icon = create_icon_material("gi_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoGIProbe", "EditorIcons")); - Color gizmo_color_internal = gizmo_color; - gizmo_color_internal.a = 0.1; - Ref material_internal = create_material("gi_probe_internal_material", gizmo_color_internal); + float ra = i * Math_PI * 2.0 / 64.0; + float rb = (i + 1) * Math_PI * 2.0 / 64.0; + Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; + Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; - clear(); + collision_segments.push_back(Vector3(a.x, a.y, 0) + d); + collision_segments.push_back(Vector3(b.x, b.y, 0) + d); - Vector lines; - Vector3 extents = probe->get_extents(); + collision_segments.push_back(Vector3(a.x, a.y, 0) - d); + collision_segments.push_back(Vector3(b.x, b.y, 0) - d); - static const int subdivs[GIProbe::SUBDIV_MAX] = { 64, 128, 256, 512 }; + if (i % 16 == 0) { - AABB aabb = AABB(-extents, extents * 2); - int subdiv = subdivs[probe->get_subdiv()]; - float cell_size = aabb.get_longest_axis_size() / subdiv; + collision_segments.push_back(Vector3(a.x, a.y, 0) + d); + collision_segments.push_back(Vector3(a.x, a.y, 0) - d); + } - for (int i = 0; i < 12; i++) { - Vector3 a, b; - aabb.get_edge(i, a, b); - lines.push_back(a); - lines.push_back(b); - } + Vector3 dud = i < 32 ? d : -d; - add_lines(lines, material); - add_collision_segments(lines); + collision_segments.push_back(Vector3(0, a.y, a.x) + dud); + collision_segments.push_back(Vector3(0, b.y, b.x) + dud); + collision_segments.push_back(Vector3(a.y, 0, a.x) + dud); + collision_segments.push_back(Vector3(b.y, 0, b.x) + dud); + } - lines.clear(); + p_gizmo->add_collision_segments(collision_segments); - for (int i = 1; i < subdiv; i++) { + Vector handles; + handles.push_back(Vector3(cs->get_radius(), 0, 0)); + handles.push_back(Vector3(0, 0, cs->get_height() * 0.5 + cs->get_radius())); + p_gizmo->add_handles(handles, handles_material); + } - for (int j = 0; j < 3; j++) { + if (Object::cast_to(*s)) { - if (cell_size * i > aabb.size[j]) { - continue; - } + Ref cs = s; + float radius = cs->get_radius(); + float height = cs->get_height(); - Vector2 dir; - dir[j] = 1.0; - Vector2 ta, tb; - int j_n1 = (j + 1) % 3; - int j_n2 = (j + 2) % 3; - ta[j_n1] = 1.0; - tb[j_n2] = 1.0; + Vector points; - for (int k = 0; k < 4; k++) { + Vector3 d(0, height * 0.5, 0); + for (int i = 0; i < 360; i++) { - Vector3 from = aabb.position, to = aabb.position; - from[j] += cell_size * i; - to[j] += cell_size * i; + float ra = Math::deg2rad((float)i); + float rb = Math::deg2rad((float)i + 1); + Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; + Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; - if (k & 1) { - to[j_n1] += aabb.size[j_n1]; - } else { + points.push_back(Vector3(a.x, 0, a.y) + d); + points.push_back(Vector3(b.x, 0, b.y) + d); - to[j_n2] += aabb.size[j_n2]; - } + points.push_back(Vector3(a.x, 0, a.y) - d); + points.push_back(Vector3(b.x, 0, b.y) - d); - if (k & 2) { - from[j_n1] += aabb.size[j_n1]; - from[j_n2] += aabb.size[j_n2]; - } + if (i % 90 == 0) { - lines.push_back(from); - lines.push_back(to); + points.push_back(Vector3(a.x, 0, a.y) + d); + points.push_back(Vector3(a.x, 0, a.y) - d); } } - } - add_lines(lines, material_internal); + p_gizmo->add_lines(points, material); - Vector handles; + Vector collision_segments; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 64; i++) { - Vector3 ax; - ax[i] = aabb.position[i] + aabb.size[i]; - handles.push_back(ax); - } + float ra = i * Math_PI * 2.0 / 64.0; + float rb = (i + 1) * Math_PI * 2.0 / 64.0; + Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; + Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; - if (is_selected()) { + collision_segments.push_back(Vector3(a.x, 0, a.y) + d); + collision_segments.push_back(Vector3(b.x, 0, b.y) + d); - gizmo_color.a = 0.1; - Ref solid_material = create_material("gi_probe_solid_material", gizmo_color); - add_solid_box(solid_material, aabb.get_size()); - } + collision_segments.push_back(Vector3(a.x, 0, a.y) - d); + collision_segments.push_back(Vector3(b.x, 0, b.y) - d); - add_unscaled_billboard(icon, 0.05); - add_handles(handles); -} -GIProbeGizmo::GIProbeGizmo(GIProbe *p_probe) { + if (i % 16 == 0) { - probe = p_probe; - set_spatial_node(p_probe); -} + collision_segments.push_back(Vector3(a.x, 0, a.y) + d); + collision_segments.push_back(Vector3(a.x, 0, a.y) - d); + } + } -//////// -//////// + p_gizmo->add_collision_segments(collision_segments); -/// + Vector handles; + handles.push_back(Vector3(cs->get_radius(), 0, 0)); + handles.push_back(Vector3(0, cs->get_height() * 0.5, 0)); + p_gizmo->add_handles(handles, handles_material); + } -String BakedIndirectLightGizmo::get_handle_name(int p_idx) const { + if (Object::cast_to(*s)) { - switch (p_idx) { - case 0: return "Extents X"; - case 1: return "Extents Y"; - case 2: return "Extents Z"; - } + Ref ps = s; + Plane p = ps->get_plane(); + Vector points; - return ""; -} -Variant BakedIndirectLightGizmo::get_handle_value(int p_idx) const { + Vector3 n1 = p.get_any_perpendicular_normal(); + Vector3 n2 = p.normal.cross(n1).normalized(); - return baker->get_extents(); -} -void BakedIndirectLightGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { + Vector3 pface[4] = { + p.normal * p.d + n1 * 10.0 + n2 * 10.0, + p.normal * p.d + n1 * 10.0 + n2 * -10.0, + p.normal * p.d + n1 * -10.0 + n2 * -10.0, + p.normal * p.d + n1 * -10.0 + n2 * 10.0, + }; - Transform gt = baker->get_global_transform(); - //gt.orthonormalize(); - Transform gi = gt.affine_inverse(); + points.push_back(pface[0]); + points.push_back(pface[1]); + points.push_back(pface[1]); + points.push_back(pface[2]); + points.push_back(pface[2]); + points.push_back(pface[3]); + points.push_back(pface[3]); + points.push_back(pface[0]); + points.push_back(p.normal * p.d); + points.push_back(p.normal * p.d + p.normal * 3); - Vector3 extents = baker->get_extents(); + p_gizmo->add_lines(points, material); + p_gizmo->add_collision_segments(points); + } - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); + if (Object::cast_to(*s)) { - Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; + PoolVector points = Object::cast_to(*s)->get_points(); - Vector3 axis; - axis[p_idx] = 1.0; + if (points.size() > 3) { - Vector3 ra, rb; - Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; - if (d < 0.001) - d = 0.001; + QuickHull qh; + Vector varr = Variant(points); + Geometry::MeshData md; + Error err = qh.build(varr, md); + if (err == OK) { + Vector points; + points.resize(md.edges.size() * 2); + for (int i = 0; i < md.edges.size(); i++) { + points.write[i * 2 + 0] = md.vertices[md.edges[i].a]; + points.write[i * 2 + 1] = md.vertices[md.edges[i].b]; + } - extents[p_idx] = d; - baker->set_extents(extents); -} + p_gizmo->add_lines(points, material); + p_gizmo->add_collision_segments(points); + } + } + } -void BakedIndirectLightGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { + if (Object::cast_to(*s)) { - Vector3 restore = p_restore; + Ref rs = s; - if (p_cancel) { - baker->set_extents(restore); - return; + Vector points; + points.push_back(Vector3()); + points.push_back(Vector3(0, 0, rs->get_length())); + p_gizmo->add_lines(points, material); + p_gizmo->add_collision_segments(points); + Vector handles; + handles.push_back(Vector3(0, 0, rs->get_length())); + p_gizmo->add_handles(handles, handles_material); } - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Change Probe Extents")); - ur->add_do_method(baker, "set_extents", baker->get_extents()); - ur->add_undo_method(baker, "set_extents", restore); - ur->commit_action(); } -void BakedIndirectLightGizmo::redraw() { +///// - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/baked_indirect_light"); - Ref material = create_material("baked_indirect_light_material", gizmo_color); - Ref icon = create_icon_material("baked_indirect_light_icon", SpatialEditor::get_singleton()->get_icon("GizmoBakedLightmap", "EditorIcons")); - Color gizmo_color_internal = gizmo_color; - gizmo_color_internal.a = 0.1; - Ref material_internal = create_material("baked_indirect_light_internal_material", gizmo_color_internal); +CollisionPolygonSpatialGizmoPlugin::CollisionPolygonSpatialGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); + create_material("shape_material", gizmo_color); +} - clear(); +bool CollisionPolygonSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} - Vector lines; - Vector3 extents = baker->get_extents(); +String CollisionPolygonSpatialGizmoPlugin::get_name() const { + return "CollisionPolygon"; +} - AABB aabb = AABB(-extents, extents * 2); +void CollisionPolygonSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - for (int i = 0; i < 12; i++) { - Vector3 a, b; - aabb.get_edge(i, a, b); - lines.push_back(a); - lines.push_back(b); - } + CollisionPolygon *polygon = Object::cast_to(p_gizmo->get_spatial_node()); - add_lines(lines, material); - add_collision_segments(lines); + p_gizmo->clear(); - Vector handles; + Vector points = polygon->get_polygon(); + float depth = polygon->get_depth() * 0.5; - for (int i = 0; i < 3; i++) { + Vector lines; + for (int i = 0; i < points.size(); i++) { - Vector3 ax; - ax[i] = aabb.position[i] + aabb.size[i]; - handles.push_back(ax); + int n = (i + 1) % points.size(); + lines.push_back(Vector3(points[i].x, points[i].y, depth)); + lines.push_back(Vector3(points[n].x, points[n].y, depth)); + lines.push_back(Vector3(points[i].x, points[i].y, -depth)); + lines.push_back(Vector3(points[n].x, points[n].y, -depth)); + lines.push_back(Vector3(points[i].x, points[i].y, depth)); + lines.push_back(Vector3(points[i].x, points[i].y, -depth)); } - if (is_selected()) { + Ref material = get_material("shape_material", p_gizmo); - gizmo_color.a = 0.1; - Ref solid_material = create_material("baked_indirect_light_solid_material", gizmo_color); - add_solid_box(solid_material, aabb.get_size()); - } + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); +} + +//// + +NavigationMeshSpatialGizmoPlugin::NavigationMeshSpatialGizmoPlugin() { + create_material("navigation_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge", Color(0.5, 1, 1))); + create_material("navigation_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled", Color(0.7, 0.7, 0.7))); + create_material("navigation_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid", Color(0.5, 1, 1, 0.4))); + create_material("navigation_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled", Color(0.7, 0.7, 0.7, 0.4))); +} - add_unscaled_billboard(icon, 0.05); - add_handles(handles); +bool NavigationMeshSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; } -BakedIndirectLightGizmo::BakedIndirectLightGizmo(BakedLightmap *p_baker) { - baker = p_baker; - set_spatial_node(p_baker); +String NavigationMeshSpatialGizmoPlugin::get_name() const { + return "NavigationMeshInstance"; } -//////// -void NavigationMeshSpatialGizmo::redraw() { +void NavigationMeshSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - Ref edge_material = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_edge")); - Ref edge_material_disabled = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled")); - Ref solid_material = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_solid")); - Ref solid_material_disabled = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled")); + NavigationMeshInstance *navmesh = Object::cast_to(p_gizmo->get_spatial_node()); - clear(); + Ref edge_material = get_material("navigation_material", p_gizmo); + Ref edge_material_disabled = get_material("navigation_material", p_gizmo); + Ref solid_material = get_material("navigation_material", p_gizmo); + Ref solid_material_disabled = get_material("navigation_material", p_gizmo); + + p_gizmo->clear(); Ref navmeshie = navmesh->get_navigation_mesh(); if (navmeshie.is_null()) return; @@ -3355,28 +3595,19 @@ void NavigationMeshSpatialGizmo::redraw() { tmesh->create(tmeshfaces); if (lines.size()) - add_lines(lines, navmesh->is_enabled() ? edge_material : edge_material_disabled); - add_collision_triangles(tmesh); + p_gizmo->add_lines(lines, navmesh->is_enabled() ? edge_material : edge_material_disabled); + p_gizmo->add_collision_triangles(tmesh); Ref m = memnew(ArrayMesh); Array a; a.resize(Mesh::ARRAY_MAX); a[0] = tmeshfaces; m->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a); m->surface_set_material(0, navmesh->is_enabled() ? solid_material : solid_material_disabled); - add_mesh(m); - add_collision_segments(lines); -} - -NavigationMeshSpatialGizmo::NavigationMeshSpatialGizmo(NavigationMeshInstance *p_navmesh) { - - set_spatial_node(p_navmesh); - navmesh = p_navmesh; + p_gizmo->add_mesh(m); + p_gizmo->add_collision_segments(lines); } - ////// - /// - /// - /// +////// #define BODY_A_RADIUS 0.25 #define BODY_B_RADIUS 0.27 @@ -3627,38 +3858,169 @@ void JointGizmosDrawer::draw_cone(const Transform &p_offset, const Basis &p_base } } -void PinJointSpatialGizmo::CreateGizmo(const Transform &p_offset, Vector &r_cursor_points) { - float cs = 0.25; +//// - r_cursor_points.push_back(p_offset.translated(Vector3(+cs, 0, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(-cs, 0, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, +cs, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, -cs, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, +cs)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, -cs)).origin); +JointSpatialGizmoPlugin::JointSpatialGizmoPlugin() { + create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1))); + create_material("joint_body_a_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1))); + create_material("joint_body_b_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1))); } -void PinJointSpatialGizmo::redraw() { +bool JointSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) != NULL; +} - clear(); - Vector cursor_points; - CreateGizmo(Transform(), cursor_points); - add_collision_segments(cursor_points); +String JointSpatialGizmoPlugin::get_name() const { + return "Joints"; +} - Ref material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint")); +void JointSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + Joint *joint = Object::cast_to(p_gizmo->get_spatial_node()); - add_lines(cursor_points, material); -} + p_gizmo->clear(); -PinJointSpatialGizmo::PinJointSpatialGizmo(PinJoint *p_p3d) { + const Spatial *node_body_a = Object::cast_to(joint->get_node(joint->get_node_a())); + const Spatial *node_body_b = Object::cast_to(joint->get_node(joint->get_node_b())); - p3d = p_p3d; - set_spatial_node(p3d); -} + Ref common_material = get_material("joint_material", p_gizmo); + Ref body_a_material = get_material("joint_body_a_material", p_gizmo); + Ref body_b_material = get_material("joint_body_b_material", p_gizmo); -//// + Vector points; + Vector body_a_points; + Vector body_b_points; + + if (Object::cast_to(joint)) { + CreatePinJointGizmo(Transform(), points); + p_gizmo->add_collision_segments(points); + p_gizmo->add_lines(points, common_material); + } + + HingeJoint *hinge = Object::cast_to(joint); + if (hinge) { + + CreateHingeJointGizmo( + Transform(), + hinge->get_global_transform(), + node_body_a ? node_body_a->get_global_transform() : Transform(), + node_body_b ? node_body_b->get_global_transform() : Transform(), + hinge->get_param(HingeJoint::PARAM_LIMIT_LOWER), + hinge->get_param(HingeJoint::PARAM_LIMIT_UPPER), + hinge->get_flag(HingeJoint::FLAG_USE_LIMIT), + points, + node_body_a ? &body_a_points : NULL, + node_body_b ? &body_b_points : NULL); + + p_gizmo->add_collision_segments(points); + p_gizmo->add_collision_segments(body_a_points); + p_gizmo->add_collision_segments(body_b_points); + + p_gizmo->add_lines(points, common_material); + p_gizmo->add_lines(body_a_points, body_a_material); + p_gizmo->add_lines(body_b_points, body_b_material); + } + + SliderJoint *slider = Object::cast_to(joint); + if (slider) { + + CreateSliderJointGizmo( + Transform(), + slider->get_global_transform(), + node_body_a ? node_body_a->get_global_transform() : Transform(), + node_body_b ? node_body_b->get_global_transform() : Transform(), + slider->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_LOWER), + slider->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_UPPER), + slider->get_param(SliderJoint::PARAM_LINEAR_LIMIT_LOWER), + slider->get_param(SliderJoint::PARAM_LINEAR_LIMIT_UPPER), + points, + node_body_a ? &body_a_points : NULL, + node_body_b ? &body_b_points : NULL); + + p_gizmo->add_collision_segments(points); + p_gizmo->add_collision_segments(body_a_points); + p_gizmo->add_collision_segments(body_b_points); + + p_gizmo->add_lines(points, common_material); + p_gizmo->add_lines(body_a_points, body_a_material); + p_gizmo->add_lines(body_b_points, body_b_material); + } + + ConeTwistJoint *cone = Object::cast_to(joint); + if (cone) { + + CreateConeTwistJointGizmo( + Transform(), + cone->get_global_transform(), + node_body_a ? node_body_a->get_global_transform() : Transform(), + node_body_b ? node_body_b->get_global_transform() : Transform(), + cone->get_param(ConeTwistJoint::PARAM_SWING_SPAN), + cone->get_param(ConeTwistJoint::PARAM_TWIST_SPAN), + node_body_a ? &body_a_points : NULL, + node_body_b ? &body_b_points : NULL); + + p_gizmo->add_collision_segments(body_a_points); + p_gizmo->add_collision_segments(body_b_points); + + p_gizmo->add_lines(body_a_points, body_a_material); + p_gizmo->add_lines(body_b_points, body_b_material); + } + + Generic6DOFJoint *gen = Object::cast_to(joint); + if (gen) { + + CreateGeneric6DOFJointGizmo( + Transform(), + gen->get_global_transform(), + node_body_a ? node_body_a->get_global_transform() : Transform(), + node_body_b ? node_body_b->get_global_transform() : Transform(), + + gen->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT), + gen->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT), + gen->get_param_x(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT), + gen->get_param_x(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT), + gen->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT), + gen->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT), + + gen->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT), + gen->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT), + gen->get_param_y(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT), + gen->get_param_y(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT), + gen->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT), + gen->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT), + + gen->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT), + gen->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT), + gen->get_param_z(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT), + gen->get_param_z(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT), + gen->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT), + gen->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT), + + points, + node_body_a ? &body_a_points : NULL, + node_body_a ? &body_b_points : NULL); + + p_gizmo->add_collision_segments(points); + p_gizmo->add_collision_segments(body_a_points); + p_gizmo->add_collision_segments(body_b_points); + + p_gizmo->add_lines(points, common_material); + p_gizmo->add_lines(body_a_points, body_a_material); + p_gizmo->add_lines(body_b_points, body_b_material); + } +} + +void JointSpatialGizmoPlugin::CreatePinJointGizmo(const Transform &p_offset, Vector &r_cursor_points) { + float cs = 0.25; + + r_cursor_points.push_back(p_offset.translated(Vector3(+cs, 0, 0)).origin); + r_cursor_points.push_back(p_offset.translated(Vector3(-cs, 0, 0)).origin); + r_cursor_points.push_back(p_offset.translated(Vector3(0, +cs, 0)).origin); + r_cursor_points.push_back(p_offset.translated(Vector3(0, -cs, 0)).origin); + r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, +cs)).origin); + r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, -cs)).origin); +} -void HingeJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector &r_common_points, Vector *r_body_a_points, Vector *r_body_b_points) { +void JointSpatialGizmoPlugin::CreateHingeJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector &r_common_points, Vector *r_body_a_points, Vector *r_body_b_points) { r_common_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin); r_common_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin); @@ -3690,52 +4052,7 @@ void HingeJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Transf } } -void HingeJointSpatialGizmo::redraw() { - - const Spatial *node_body_a = Object::cast_to(p3d->get_node(p3d->get_node_a())); - const Spatial *node_body_b = Object::cast_to(p3d->get_node(p3d->get_node_b())); - - Vector points; - Vector body_a_points; - Vector body_b_points; - CreateGizmo( - Transform(), - p3d->get_global_transform(), - node_body_a ? node_body_a->get_global_transform() : Transform(), - node_body_b ? node_body_b->get_global_transform() : Transform(), - p3d->get_param(HingeJoint::PARAM_LIMIT_LOWER), - p3d->get_param(HingeJoint::PARAM_LIMIT_UPPER), - p3d->get_flag(HingeJoint::FLAG_USE_LIMIT), - points, - node_body_a ? &body_a_points : NULL, - node_body_b ? &body_b_points : NULL); - - clear(); - - Ref common_material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint")); - Ref body_a_material = create_material("joint_body_a_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_a")); - Ref body_b_material = create_material("joint_body_b_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_b")); - - add_collision_segments(points); - add_collision_segments(body_a_points); - add_collision_segments(body_b_points); - - add_lines(points, common_material); - add_lines(body_a_points, body_a_material); - add_lines(body_b_points, body_b_material); -} - -HingeJointSpatialGizmo::HingeJointSpatialGizmo(HingeJoint *p_p3d) { - - p3d = p_p3d; - set_spatial_node(p3d); -} - -/////// -/// -//// - -void SliderJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector &r_points, Vector *r_body_a_points, Vector *r_body_b_points) { +void JointSpatialGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector &r_points, Vector *r_body_a_points, Vector *r_body_b_points) { p_linear_limit_lower = -p_linear_limit_lower; p_linear_limit_upper = -p_linear_limit_upper; @@ -3795,53 +4112,7 @@ void SliderJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Trans true); } -void SliderJointSpatialGizmo::redraw() { - - const Spatial *node_body_a = Object::cast_to(p3d->get_node(p3d->get_node_a())); - const Spatial *node_body_b = Object::cast_to(p3d->get_node(p3d->get_node_b())); - - clear(); - Vector cursor_points; - Vector body_a_points; - Vector body_b_points; - - CreateGizmo( - Transform(), - p3d->get_global_transform(), - node_body_a ? node_body_a->get_global_transform() : Transform(), - node_body_b ? node_body_b->get_global_transform() : Transform(), - p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_LOWER), - p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_UPPER), - p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_LOWER), - p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_UPPER), - cursor_points, - node_body_a ? &body_a_points : NULL, - node_body_b ? &body_b_points : NULL); - - Ref material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint")); - Ref body_a_material = create_material("joint_body_a_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_a")); - Ref body_b_material = create_material("joint_body_b_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_b")); - - add_collision_segments(cursor_points); - add_collision_segments(body_a_points); - add_collision_segments(body_b_points); - - add_lines(cursor_points, material); - add_lines(body_a_points, body_a_material); - add_lines(body_b_points, body_b_material); -} - -SliderJointSpatialGizmo::SliderJointSpatialGizmo(SliderJoint *p_p3d) { - - p3d = p_p3d; - set_spatial_node(p3d); -} - -/////// -/// -//// - -void ConeTwistJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector &r_points, Vector *r_body_a_points, Vector *r_body_b_points) { +void JointSpatialGizmoPlugin::CreateConeTwistJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector *r_body_a_points, Vector *r_body_b_points) { if (r_body_a_points) JointGizmosDrawer::draw_cone( @@ -3860,51 +4131,7 @@ void ConeTwistJointSpatialGizmo::CreateGizmo(const Transform &p_offset, const Tr *r_body_b_points); } -void ConeTwistJointSpatialGizmo::redraw() { - - const Spatial *node_body_a = Object::cast_to(p3d->get_node(p3d->get_node_a())); - const Spatial *node_body_b = Object::cast_to(p3d->get_node(p3d->get_node_b())); - - clear(); - Vector points; - Vector body_a_points; - Vector body_b_points; - - CreateGizmo( - Transform(), - p3d->get_global_transform(), - node_body_a ? node_body_a->get_global_transform() : Transform(), - node_body_b ? node_body_b->get_global_transform() : Transform(), - p3d->get_param(ConeTwistJoint::PARAM_SWING_SPAN), - p3d->get_param(ConeTwistJoint::PARAM_TWIST_SPAN), - points, - node_body_a ? &body_a_points : NULL, - node_body_b ? &body_b_points : NULL); - - Ref material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint")); - Ref body_a_material = create_material("joint_body_a_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_a")); - Ref body_b_material = create_material("joint_body_b_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_b")); - - add_collision_segments(points); - add_collision_segments(body_a_points); - add_collision_segments(body_b_points); - - add_lines(points, material); - add_lines(body_a_points, body_a_material); - add_lines(body_b_points, body_b_material); -} - -ConeTwistJointSpatialGizmo::ConeTwistJointSpatialGizmo(ConeTwistJoint *p_p3d) { - - p3d = p_p3d; - set_spatial_node(p3d); -} - -/////// -/// -//// - -void Generic6DOFJointSpatialGizmo::CreateGizmo( +void JointSpatialGizmoPlugin::CreateGeneric6DOFJointGizmo( const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, @@ -4053,510 +4280,3 @@ void Generic6DOFJointSpatialGizmo::CreateGizmo( #undef ADD_VTX } - -void Generic6DOFJointSpatialGizmo::redraw() { - - const Spatial *node_body_a = Object::cast_to(p3d->get_node(p3d->get_node_a())); - const Spatial *node_body_b = Object::cast_to(p3d->get_node(p3d->get_node_b())); - - clear(); - Vector cursor_points; - Vector body_a_points; - Vector body_b_points; - - CreateGizmo( - Transform(), - p3d->get_global_transform(), - node_body_a ? node_body_a->get_global_transform() : Transform(), - node_body_b ? node_body_b->get_global_transform() : Transform(), - - p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT), - p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT), - p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT), - p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT), - p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT), - p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT), - - p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT), - p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT), - p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT), - p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT), - p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT), - p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT), - - p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT), - p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT), - p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT), - p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT), - p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT), - p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT), - - cursor_points, - node_body_a ? &body_a_points : NULL, - node_body_a ? &body_b_points : NULL); - - Ref material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint")); - Ref body_a_material = create_material("joint_body_a_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_a")); - Ref body_b_material = create_material("joint_body_b_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint_body_b")); - - add_collision_segments(cursor_points); - add_collision_segments(body_a_points); - add_collision_segments(body_b_points); - - add_lines(cursor_points, material); - add_lines(body_a_points, body_a_material); - add_lines(body_b_points, body_b_material); -} - -Generic6DOFJointSpatialGizmo::Generic6DOFJointSpatialGizmo(Generic6DOFJoint *p_p3d) { - - p3d = p_p3d; - set_spatial_node(p3d); -} - -/////// -/// -//// - -SpatialEditorGizmos *SpatialEditorGizmos::singleton = NULL; - -Ref SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) { - - if (Object::cast_to(p_spatial)) { - - Ref lsg = memnew(LightSpatialGizmo(Object::cast_to(p_spatial))); - return lsg; - } - - if (Object::cast_to(p_spatial)) { - - Ref lsg = memnew(CameraSpatialGizmo(Object::cast_to(p_spatial))); - return lsg; - } - - if (Object::cast_to(p_spatial)) { - - Ref lsg = memnew(SkeletonSpatialGizmo(Object::cast_to(p_spatial))); - return lsg; - } - - if (Object::cast_to(p_spatial)) { - - Ref pbsg = memnew(PhysicalBoneSpatialGizmo(Object::cast_to(p_spatial))); - return pbsg; - } - - if (Object::cast_to(p_spatial)) { - - Ref lsg = memnew(Position3DSpatialGizmo(Object::cast_to(p_spatial))); - return lsg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(SoftBodySpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(MeshInstanceSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - /*if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(RoomSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - }*/ - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(NavigationMeshSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(RayCastSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - /* - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(PortalSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } -*/ - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(CollisionShapeSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(VisibilityNotifierGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(ParticlesGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(ReflectionProbeGizmo(Object::cast_to(p_spatial))); - return misg; - } - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(GIProbeGizmo(Object::cast_to(p_spatial))); - return misg; - } - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(BakedIndirectLightGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(VehicleWheelSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(PinJointSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(HingeJointSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(SliderJointSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(ConeTwistJointSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(Generic6DOFJointSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(CollisionPolygonSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - if (Object::cast_to(p_spatial)) { - - Ref misg = memnew(AudioStreamPlayer3DSpatialGizmo(Object::cast_to(p_spatial))); - return misg; - } - - return Ref(); -} - -SpatialEditorGizmos::SpatialEditorGizmos() { - - singleton = this; - - handle_material = Ref(memnew(SpatialMaterial)); - handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - handle_material->set_on_top_of_alpha(); - handle_material->set_albedo(Color(0.8, 0.8, 0.8)); - handle_material_billboard = handle_material->duplicate(); - handle_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - - handle2_material = Ref(memnew(SpatialMaterial)); - handle2_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - handle2_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true); - handle_t = SpatialEditor::get_singleton()->get_icon("Editor3DHandle", "EditorIcons"); - handle2_material->set_point_size(handle_t->get_width()); - handle2_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, handle_t); - handle2_material->set_albedo(Color(1, 1, 1)); - handle2_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - handle2_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - handle2_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - handle2_material->set_on_top_of_alpha(); - handle2_material_billboard = handle2_material->duplicate(); - handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - handle2_material_billboard->set_on_top_of_alpha(); - - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.2)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/visibility_notifier", Color(0.8, 0.5, 0.7)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/reflection_probe", Color(0.6, 1, 0.5)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/gi_probe", Color(0.5, 1, 0.6)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/baked_indirect_light", Color(0.5, 0.6, 1)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge", Color(0.5, 1, 1)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled", Color(0.7, 0.7, 0.7)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid", Color(0.5, 1, 1, 0.4)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled", Color(0.7, 0.7, 0.7, 0.4)); - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.5)); - -#if 0 - light_material = create_line_material(Color(1, 1, 0.2)); - light_material_omni = create_line_material(Color(1, 1, 0.2)); - light_material_omni->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - - light_material_omni_icon = Ref(memnew(SpatialMaterial)); - light_material_omni_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - light_material_omni_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED); - light_material_omni_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); - light_material_omni_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - light_material_omni_icon->set_albedo(Color(1, 1, 1, 0.9)); - light_material_omni_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons")); - light_material_omni_icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true); - light_material_omni_icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - - light_material_directional_icon = Ref(memnew(SpatialMaterial)); - light_material_directional_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - light_material_directional_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED); - light_material_directional_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); - light_material_directional_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - light_material_directional_icon->set_albedo(Color(1, 1, 1, 0.9)); - light_material_directional_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons")); - light_material_directional_icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED); - light_material_directional_icon->set_depth_scale(1); - - camera_material = create_line_material(Color(1.0, 0.5, 1.0)); - - navmesh_edge_material = create_line_material(Color(0.1, 0.8, 1.0)); - navmesh_solid_material = create_solid_material(Color(0.1, 0.8, 1.0, 0.4)); - navmesh_edge_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false); - navmesh_edge_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false); - navmesh_solid_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); - - navmesh_edge_material_disabled = create_line_material(Color(1.0, 0.8, 0.1)); - navmesh_solid_material_disabled = create_solid_material(Color(1.0, 0.8, 0.1, 0.4)); - navmesh_edge_material_disabled->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false); - navmesh_edge_material_disabled->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false); - navmesh_solid_material_disabled->set_cull_mode(SpatialMaterial::CULL_DISABLED); - - skeleton_material = create_line_material(Color(0.6, 1.0, 0.3)); - skeleton_material->set_cull_mode(SpatialMaterial::CULL_DISABLED); - skeleton_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - skeleton_material->set_on_top_of_alpha(); - skeleton_material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); - - //position 3D Shared mesh - - pos3d_mesh = Ref(memnew(ArrayMesh)); - { - - PoolVector cursor_points; - PoolVector cursor_colors; - float cs = 0.25; - cursor_points.push_back(Vector3(+cs, 0, 0)); - cursor_points.push_back(Vector3(-cs, 0, 0)); - cursor_points.push_back(Vector3(0, +cs, 0)); - cursor_points.push_back(Vector3(0, -cs, 0)); - cursor_points.push_back(Vector3(0, 0, +cs)); - cursor_points.push_back(Vector3(0, 0, -cs)); - cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7)); - cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7)); - cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7)); - cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7)); - cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7)); - cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7)); - - Ref mat = memnew(SpatialMaterial); - mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - mat->set_line_width(3); - Array d; - d.resize(VS::ARRAY_MAX); - d[Mesh::ARRAY_VERTEX] = cursor_points; - d[Mesh::ARRAY_COLOR] = cursor_colors; - pos3d_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d); - pos3d_mesh->surface_set_material(0, mat); - } - - listener_line_mesh = Ref(memnew(ArrayMesh)); - { - - PoolVector cursor_points; - PoolVector cursor_colors; - cursor_points.push_back(Vector3(0, 0, 0)); - cursor_points.push_back(Vector3(0, 0, -1.0)); - cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7)); - cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7)); - - Ref mat = memnew(SpatialMaterial); - mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - mat->set_line_width(3); - Array d; - d.resize(VS::ARRAY_MAX); - d[Mesh::ARRAY_VERTEX] = cursor_points; - d[Mesh::ARRAY_COLOR] = cursor_colors; - listener_line_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d); - listener_line_mesh->surface_set_material(0, mat); - } - - room_material = create_line_material(Color(1.0, 0.6, 0.9)); - portal_material = create_line_material(Color(1.0, 0.8, 0.6)); - raycast_material = create_line_material(Color(1.0, 0.8, 0.6)); - car_wheel_material = create_line_material(Color(0.6, 0.8, 1.0)); - visibility_notifier_material = create_line_material(Color(1.0, 0.5, 1.0)); - particles_material = create_line_material(Color(1.0, 1.0, 0.5)); - reflection_probe_material = create_line_material(Color(0.5, 1.0, 0.7)); - reflection_probe_material_internal = create_line_material(Color(0.3, 0.8, 0.5, 0.15)); - gi_probe_material = create_line_material(Color(0.7, 1.0, 0.5)); - gi_probe_material_internal = create_line_material(Color(0.5, 0.8, 0.3, 0.1)); - joint_material = create_line_material(Color(0.6, 0.8, 1.0)); - - stream_player_icon = Ref(memnew(SpatialMaterial)); - stream_player_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - stream_player_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED); - stream_player_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); - stream_player_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - stream_player_icon->set_albedo(Color(1, 1, 1, 0.9)); - stream_player_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer", "EditorIcons")); - - visibility_notifier_icon = Ref(memnew(SpatialMaterial)); - visibility_notifier_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - visibility_notifier_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED); - visibility_notifier_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); - visibility_notifier_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - visibility_notifier_icon->set_albedo(Color(1, 1, 1, 0.9)); - visibility_notifier_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("Visible", "EditorIcons")); - - listener_icon = Ref(memnew(SpatialMaterial)); - listener_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - listener_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED); - listener_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED); - listener_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - listener_icon->set_albedo(Color(1, 1, 1, 0.9)); - listener_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoListener", "EditorIcons")); - - { - - PoolVector vertices; - -#undef ADD_VTX -#define ADD_VTX(m_idx) \ - vertices.push_back(face_points[m_idx]); - - for (int i = 0; i < 6; i++) { - - Vector3 face_points[4]; - - for (int j = 0; j < 4; j++) { - - float v[3]; - v[0] = 1.0; - v[1] = 1 - 2 * ((j >> 1) & 1); - v[2] = v[1] * (1 - 2 * (j & 1)); - - for (int k = 0; k < 3; k++) { - - if (i < 3) - face_points[j][(i + k) % 3] = v[k]; - else - face_points[3 - j][(i + k) % 3] = -v[k]; - } - } - //tri 1 - ADD_VTX(0); - ADD_VTX(1); - ADD_VTX(2); - //tri 2 - ADD_VTX(2); - ADD_VTX(3); - ADD_VTX(0); - } - - test_cube_tm = Ref(memnew(TriangleMesh)); - test_cube_tm->create(vertices); - } - - shape_material = create_line_material(Color(0.2, 1, 1.0)); -#endif - - pos3d_mesh = Ref(memnew(ArrayMesh)); - { - - PoolVector cursor_points; - PoolVector cursor_colors; - float cs = 0.25; - cursor_points.push_back(Vector3(+cs, 0, 0)); - cursor_points.push_back(Vector3(-cs, 0, 0)); - cursor_points.push_back(Vector3(0, +cs, 0)); - cursor_points.push_back(Vector3(0, -cs, 0)); - cursor_points.push_back(Vector3(0, 0, +cs)); - cursor_points.push_back(Vector3(0, 0, -cs)); - cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7)); - cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7)); - cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7)); - cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7)); - cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7)); - cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7)); - - Ref mat = memnew(SpatialMaterial); - mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - mat->set_line_width(3); - Array d; - d.resize(VS::ARRAY_MAX); - d[Mesh::ARRAY_VERTEX] = cursor_points; - d[Mesh::ARRAY_COLOR] = cursor_colors; - pos3d_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d); - pos3d_mesh->surface_set_material(0, mat); - } - - listener_line_mesh = Ref(memnew(ArrayMesh)); - { - - PoolVector cursor_points; - PoolVector cursor_colors; - cursor_points.push_back(Vector3(0, 0, 0)); - cursor_points.push_back(Vector3(0, 0, -1.0)); - cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7)); - cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7)); - - Ref mat = memnew(SpatialMaterial); - mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - mat->set_line_width(3); - Array d; - d.resize(VS::ARRAY_MAX); - d[Mesh::ARRAY_VERTEX] = cursor_points; - d[Mesh::ARRAY_COLOR] = cursor_colors; - listener_line_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d); - listener_line_mesh->surface_set_material(0, mat); - } -} diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h index 198d0285167d..877590b91d6f 100644 --- a/editor/spatial_editor_gizmos.h +++ b/editor/spatial_editor_gizmos.h @@ -55,187 +55,120 @@ class Camera; -class EditorSpatialGizmo : public SpatialEditorGizmo { +class LightSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - GDCLASS(EditorSpatialGizmo, SpatialGizmo); + GDCLASS(LightSpatialGizmoPlugin, EditorSpatialGizmoPlugin); - struct Instance { - - RID instance; - Ref mesh; - RID skeleton; - bool billboard; - bool unscaled; - bool can_intersect; - bool extra_margin; - Instance() { - - billboard = false; - unscaled = false; - can_intersect = false; - extra_margin = false; - } - - void create_instance(Spatial *p_base); - }; - - Vector collision_segments; - Ref collision_mesh; - - struct Handle { - Vector3 pos; - bool billboard; - }; - - Vector handles; - Vector secondary_handles; - float selectable_icon_size = -1.0f; - bool billboard_handle; +public: + bool has_gizmo(Spatial *p_spatial); + String get_name() const; - bool valid; - Spatial *base; - Vector instances; - Spatial *spatial_node; + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); + void redraw(EditorSpatialGizmo *p_gizmo); - void _set_spatial_node(Node *p_node) { set_spatial_node(Object::cast_to(p_node)); } + LightSpatialGizmoPlugin(); +}; -protected: - void add_lines(const Vector &p_lines, const Ref &p_material, bool p_billboard = false); - void add_mesh(const Ref &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID()); - void add_collision_segments(const Vector &p_lines); - void add_collision_triangles(const Ref &p_tmesh); - void add_unscaled_billboard(const Ref &p_material, float p_scale = 1); - void add_handles(const Vector &p_handles, bool p_billboard = false, bool p_secondary = false); - void add_solid_box(Ref &p_material, Vector3 p_size, Vector3 p_position = Vector3()); +class AudioStreamPlayer3DSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - void set_spatial_node(Spatial *p_node); - const Spatial *get_spatial_node() const { return spatial_node; } + GDCLASS(AudioStreamPlayer3DSpatialGizmoPlugin, EditorSpatialGizmoPlugin); - static void _bind_methods(); +public: + bool has_gizmo(Spatial *p_spatial); + String get_name() const; - Ref 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); - Ref create_icon_material(const String &p_name, const Ref &p_texture, bool p_on_top = false, const Color &p_albedo = Color(1, 1, 1, 1)); + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); + void redraw(EditorSpatialGizmo *p_gizmo); -public: - virtual Vector3 get_handle_pos(int p_idx) const; - virtual bool intersect_frustum(const Camera *p_camera, const Vector &p_frustum); - virtual bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false); - - void clear(); - void create(); - void transform(); - virtual void redraw(); - void free(); - virtual bool is_editable() const; - virtual bool can_draw() const; - - EditorSpatialGizmo(); - ~EditorSpatialGizmo(); + AudioStreamPlayer3DSpatialGizmoPlugin(); }; -class LightSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(LightSpatialGizmo, EditorSpatialGizmo); +class CameraSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - Light *light; + GDCLASS(CameraSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; - void redraw(); - LightSpatialGizmo(Light *p_light = NULL); -}; + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); + void redraw(EditorSpatialGizmo *p_gizmo); -class AudioStreamPlayer3DSpatialGizmo : public EditorSpatialGizmo { + CameraSpatialGizmoPlugin(); +}; - GDCLASS(AudioStreamPlayer3DSpatialGizmo, EditorSpatialGizmo); +class MeshInstanceSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - AudioStreamPlayer3D *player; + GDCLASS(MeshInstanceSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + bool can_be_hidden() const; + void redraw(EditorSpatialGizmo *p_gizmo); - void redraw(); - AudioStreamPlayer3DSpatialGizmo(AudioStreamPlayer3D *p_player = NULL); + MeshInstanceSpatialGizmoPlugin(); }; -class CameraSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(CameraSpatialGizmo, EditorSpatialGizmo); +class Sprite3DSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - Camera *camera; + GDCLASS(Sprite3DSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + bool can_be_hidden() const; + void redraw(EditorSpatialGizmo *p_gizmo); - void redraw(); - CameraSpatialGizmo(Camera *p_camera = NULL); + Sprite3DSpatialGizmoPlugin(); }; -class MeshInstanceSpatialGizmo : public EditorSpatialGizmo { +class Position3DSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - GDCLASS(MeshInstanceSpatialGizmo, EditorSpatialGizmo); + GDCLASS(Position3DSpatialGizmoPlugin, EditorSpatialGizmoPlugin); - MeshInstance *mesh; + Ref pos3d_mesh; + Vector cursor_points; public: - virtual bool can_draw() const; - void redraw(); - MeshInstanceSpatialGizmo(MeshInstance *p_mesh = NULL); -}; - -class Sprite3DSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(Sprite3DSpatialGizmo, EditorSpatialGizmo); - - SpriteBase3D *sprite; + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); -public: - virtual bool can_draw() const; - void redraw(); - Sprite3DSpatialGizmo(SpriteBase3D *p_sprite = NULL); + Position3DSpatialGizmoPlugin(); }; -class Position3DSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(Position3DSpatialGizmo, EditorSpatialGizmo); +class SkeletonSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - Position3D *p3d; + GDCLASS(SkeletonSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - void redraw(); - Position3DSpatialGizmo(Position3D *p_p3d = NULL); -}; - -class SkeletonSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(SkeletonSpatialGizmo, EditorSpatialGizmo); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); - Skeleton *skel; - -public: - void redraw(); - SkeletonSpatialGizmo(Skeleton *p_skel = NULL); + SkeletonSpatialGizmoPlugin(); }; -class PhysicalBoneSpatialGizmo : public EditorSpatialGizmo { - GDCLASS(PhysicalBoneSpatialGizmo, EditorSpatialGizmo); +class PhysicalBoneSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - PhysicalBone *physical_bone; + GDCLASS(PhysicalBoneSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - //virtual Transform get_global_gizmo_transform(); - virtual void redraw(); - PhysicalBoneSpatialGizmo(PhysicalBone *p_pb = NULL); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); + + PhysicalBoneSpatialGizmoPlugin(); }; #if 0 @@ -251,154 +184,166 @@ class PortalSpatialGizmo : public EditorSpatialGizmo { }; #endif -class VisibilityNotifierGizmo : public EditorSpatialGizmo { - - GDCLASS(VisibilityNotifierGizmo, EditorSpatialGizmo); +class RayCastSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - VisibilityNotifier *notifier; + GDCLASS(RayCastSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); - void redraw(); - VisibilityNotifierGizmo(VisibilityNotifier *p_notifier = NULL); + RayCastSpatialGizmoPlugin(); }; -class ParticlesGizmo : public EditorSpatialGizmo { - - GDCLASS(ParticlesGizmo, EditorSpatialGizmo); +class VehicleWheelSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - Particles *particles; + GDCLASS(VehicleWheelSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); - void redraw(); - ParticlesGizmo(Particles *p_particles = NULL); + VehicleWheelSpatialGizmoPlugin(); }; -class ReflectionProbeGizmo : public EditorSpatialGizmo { - - GDCLASS(ReflectionProbeGizmo, EditorSpatialGizmo); +class SoftBodySpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - ReflectionProbe *probe; + GDCLASS(SoftBodySpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + bool is_selectable_when_hidden() const; + void redraw(EditorSpatialGizmo *p_gizmo); - void redraw(); - ReflectionProbeGizmo(ReflectionProbe *p_probe = NULL); -}; + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel); + bool is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const; -class GIProbeGizmo : public EditorSpatialGizmo { + SoftBodySpatialGizmoPlugin(); +}; - GDCLASS(GIProbeGizmo, EditorSpatialGizmo); +class VisibilityNotifierGizmoPlugin : public EditorSpatialGizmoPlugin { - GIProbe *probe; + GDCLASS(VisibilityNotifierGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); - void redraw(); - GIProbeGizmo(GIProbe *p_probe = NULL); -}; + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); -class BakedIndirectLightGizmo : public EditorSpatialGizmo { + VisibilityNotifierGizmoPlugin(); +}; - GDCLASS(BakedIndirectLightGizmo, EditorSpatialGizmo); +class ParticlesGizmoPlugin : public EditorSpatialGizmoPlugin { - BakedLightmap *baker; + GDCLASS(ParticlesGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + bool is_selectable_when_hidden() const; + void redraw(EditorSpatialGizmo *p_gizmo); - void redraw(); - BakedIndirectLightGizmo(BakedLightmap *p_baker = NULL); + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); + + ParticlesGizmoPlugin(); }; -class SoftBodySpatialGizmo : public EditorSpatialGizmo { - GDCLASS(SoftBodySpatialGizmo, EditorSpatialGizmo); +class ReflectionProbeGizmoPlugin : public EditorSpatialGizmoPlugin { - class SoftBody *soft_body; - //RID physics_sphere_shape; // Used for raycast that doesn't work, in this moment, with softbody + GDCLASS(ReflectionProbeGizmoPlugin, EditorSpatialGizmoPlugin); public: - void redraw(); - virtual bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); - virtual bool is_gizmo_handle_highlighted(int idx) const; + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); - SoftBodySpatialGizmo(SoftBody *p_soft_physics_body = NULL); - ~SoftBodySpatialGizmo(); + ReflectionProbeGizmoPlugin(); }; -class CollisionShapeSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(CollisionShapeSpatialGizmo, EditorSpatialGizmo); +class GIProbeGizmoPlugin : public EditorSpatialGizmoPlugin { - CollisionShape *cs; + GDCLASS(GIProbeGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); - void redraw(); - CollisionShapeSpatialGizmo(CollisionShape *p_cs = NULL); -}; + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); + + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); -class CollisionPolygonSpatialGizmo : public EditorSpatialGizmo { + GIProbeGizmoPlugin(); +}; - GDCLASS(CollisionPolygonSpatialGizmo, EditorSpatialGizmo); +class BakedIndirectLightGizmoPlugin : public EditorSpatialGizmoPlugin { - CollisionPolygon *polygon; + GDCLASS(BakedIndirectLightGizmoPlugin, EditorSpatialGizmoPlugin); public: - void redraw(); - CollisionPolygonSpatialGizmo(CollisionPolygon *p_polygon = NULL); -}; + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); -class RayCastSpatialGizmo : public EditorSpatialGizmo { + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); + + BakedIndirectLightGizmoPlugin(); +}; - GDCLASS(RayCastSpatialGizmo, EditorSpatialGizmo); +class CollisionShapeSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - RayCast *raycast; + GDCLASS(CollisionShapeSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - void redraw(); - RayCastSpatialGizmo(RayCast *p_raycast = NULL); -}; + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); + + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); -class VehicleWheelSpatialGizmo : public EditorSpatialGizmo { + CollisionShapeSpatialGizmoPlugin(); +}; - GDCLASS(VehicleWheelSpatialGizmo, EditorSpatialGizmo); +class CollisionPolygonSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - VehicleWheel *car_wheel; + GDCLASS(CollisionPolygonSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - void redraw(); - VehicleWheelSpatialGizmo(VehicleWheel *p_car_wheel = NULL); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); + + CollisionPolygonSpatialGizmoPlugin(); }; -class NavigationMeshSpatialGizmo : public EditorSpatialGizmo { +class NavigationMeshSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - GDCLASS(NavigationMeshSpatialGizmo, EditorSpatialGizmo); + GDCLASS(NavigationMeshSpatialGizmoPlugin, EditorSpatialGizmoPlugin); struct _EdgeKey { @@ -408,11 +353,12 @@ class NavigationMeshSpatialGizmo : public EditorSpatialGizmo { bool operator<(const _EdgeKey &p_with) const { return from == p_with.from ? to < p_with.to : from < p_with.from; } }; - NavigationMeshInstance *navmesh; - public: - void redraw(); - NavigationMeshSpatialGizmo(NavigationMeshInstance *p_navmesh = NULL); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); + + NavigationMeshSpatialGizmoPlugin(); }; class JointGizmosDrawer { @@ -421,7 +367,7 @@ class JointGizmosDrawer { static Basis look_body_toward(Vector3::Axis p_axis, const Transform &joint_transform, const Transform &body_transform); static Basis look_body_toward_x(const Transform &p_joint_transform, const Transform &p_body_transform); static Basis look_body_toward_y(const Transform &p_joint_transform, const Transform &p_body_transform); - /// Special function just used for physics joints, it that returns a basis constrained toward Joint Z axis + /// Special function just used for physics joints, it returns a basis constrained toward Joint Z axis /// with axis X and Y that are looking toward the body and oriented toward up static Basis look_body_toward_z(const Transform &p_joint_transform, const Transform &p_body_transform); @@ -430,66 +376,20 @@ class JointGizmosDrawer { static void draw_cone(const Transform &p_offset, const Basis &p_base, real_t p_swing, real_t p_twist, Vector &r_points); }; -class PinJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(PinJointSpatialGizmo, EditorSpatialGizmo); - - PinJoint *p3d; - -public: - static void CreateGizmo(const Transform &p_offset, Vector &r_cursor_points); - - void redraw(); - PinJointSpatialGizmo(PinJoint *p_p3d = NULL); -}; - -class HingeJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(HingeJointSpatialGizmo, EditorSpatialGizmo); - - HingeJoint *p3d; - -public: - static void CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector &r_common_points, Vector *r_body_a_points, Vector *r_body_b_points); - - void redraw(); - HingeJointSpatialGizmo(HingeJoint *p_p3d = NULL); -}; - -class SliderJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(SliderJointSpatialGizmo, EditorSpatialGizmo); - - SliderJoint *p3d; - -public: - static void CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector &r_points, Vector *r_body_a_points, Vector *r_body_b_points); - - void redraw(); - SliderJointSpatialGizmo(SliderJoint *p_p3d = NULL); -}; - -class ConeTwistJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(ConeTwistJointSpatialGizmo, EditorSpatialGizmo); +class JointSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - ConeTwistJoint *p3d; + GDCLASS(JointSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - static void CreateGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector &r_points, Vector *r_body_a_points, Vector *r_body_b_points); - - void redraw(); - ConeTwistJointSpatialGizmo(ConeTwistJoint *p_p3d = NULL); -}; - -class Generic6DOFJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(Generic6DOFJointSpatialGizmo, EditorSpatialGizmo); - - Generic6DOFJoint *p3d; - -public: - static void CreateGizmo( + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + void redraw(EditorSpatialGizmo *p_gizmo); + + static void CreatePinJointGizmo(const Transform &p_offset, Vector &r_cursor_points); + static void CreateHingeJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector &r_common_points, Vector *r_body_a_points, Vector *r_body_b_points); + static void CreateSliderJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector &r_points, Vector *r_body_a_points, Vector *r_body_b_points); + static void CreateConeTwistJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector *r_body_a_points, Vector *r_body_b_points); + static void CreateGeneric6DOFJointGizmo( const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, @@ -516,26 +416,7 @@ class Generic6DOFJointSpatialGizmo : public EditorSpatialGizmo { Vector *r_body_a_points, Vector *r_body_b_points); - void redraw(); - Generic6DOFJointSpatialGizmo(Generic6DOFJoint *p_p3d = NULL); + JointSpatialGizmoPlugin(); }; -class SpatialEditorGizmos { - -public: - HashMap > material_cache; - - Ref handle2_material; - Ref handle2_material_billboard; - Ref handle_material; - Ref handle_material_billboard; - Ref handle_t; - Ref pos3d_mesh; - Ref listener_line_mesh; - static SpatialEditorGizmos *singleton; - - Ref get_gizmo(Spatial *p_spatial); - - SpatialEditorGizmos(); -}; #endif // SPATIAL_EDITOR_GIZMOS_H diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index 3b1ddfe4c0f7..f9744c72afee 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -32,7 +32,16 @@ /////////// -String CSGShapeSpatialGizmo::get_handle_name(int p_idx) const { +CSGShapeSpatialGizmoPlugin::CSGShapeSpatialGizmoPlugin() { + + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.2, 0.5, 1, 0.1)); + create_material("shape_material", gizmo_color); + create_handle_material("handles"); +} + +String CSGShapeSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { + + CSGShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); if (Object::cast_to(cs)) { @@ -57,7 +66,9 @@ String CSGShapeSpatialGizmo::get_handle_name(int p_idx) const { return ""; } -Variant CSGShapeSpatialGizmo::get_handle_value(int p_idx) const { +Variant CSGShapeSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { + + CSGShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); if (Object::cast_to(cs)) { @@ -89,10 +100,12 @@ Variant CSGShapeSpatialGizmo::get_handle_value(int p_idx) const { return Variant(); } -void CSGShapeSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { +void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) { + + CSGShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); Transform gt = cs->get_global_transform(); - gt.orthonormalize(); + //gt.orthonormalize(); Transform gi = gt.affine_inverse(); Vector3 ray_from = p_camera->project_ray_origin(p_point); @@ -170,7 +183,9 @@ void CSGShapeSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 s->set_outer_radius(d); } } -void CSGShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { +void CSGShapeSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + + CSGShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); if (Object::cast_to(cs)) { CSGSphere *s = Object::cast_to(cs); @@ -260,12 +275,26 @@ void CSGShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bo ur->commit_action(); } } -void CSGShapeSpatialGizmo::redraw() { +bool CSGShapeSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { + return Object::cast_to(p_spatial) || Object::cast_to(p_spatial) || Object::cast_to(p_spatial) || Object::cast_to(p_spatial) || Object::cast_to(p_spatial) || Object::cast_to(p_spatial); +} - clear(); +String CSGShapeSpatialGizmoPlugin::get_name() const { + return "CSGShapes"; +} + +bool CSGShapeSpatialGizmoPlugin::is_selectable_when_hidden() const { + return true; +} - Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/csg"); - Ref material = create_material("shape_material", gizmo_color); +void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { + + CSGShape *cs = Object::cast_to(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); + + Ref material = get_material("shape_material", p_gizmo); + Ref handles_material = get_material("handles"); PoolVector faces = cs->get_brush_faces(); @@ -284,8 +313,8 @@ void CSGShapeSpatialGizmo::redraw() { } } - add_lines(lines, material); - add_collision_segments(lines); + p_gizmo->add_lines(lines, material); + p_gizmo->add_collision_segments(lines); if (Object::cast_to(cs)) { CSGSphere *s = Object::cast_to(cs); @@ -293,7 +322,7 @@ void CSGShapeSpatialGizmo::redraw() { float r = s->get_radius(); Vector handles; handles.push_back(Vector3(r, 0, 0)); - add_handles(handles); + p_gizmo->add_handles(handles, handles_material); } if (Object::cast_to(cs)) { @@ -303,7 +332,7 @@ void CSGShapeSpatialGizmo::redraw() { handles.push_back(Vector3(s->get_width(), 0, 0)); handles.push_back(Vector3(0, s->get_height(), 0)); handles.push_back(Vector3(0, 0, s->get_depth())); - add_handles(handles); + p_gizmo->add_handles(handles, handles_material); } if (Object::cast_to(cs)) { @@ -312,7 +341,7 @@ void CSGShapeSpatialGizmo::redraw() { Vector handles; handles.push_back(Vector3(s->get_radius(), 0, 0)); handles.push_back(Vector3(0, s->get_height() * 0.5, 0)); - add_handles(handles); + p_gizmo->add_handles(handles, handles_material); } if (Object::cast_to(cs)) { @@ -321,25 +350,11 @@ void CSGShapeSpatialGizmo::redraw() { Vector handles; handles.push_back(Vector3(s->get_inner_radius(), 0, 0)); handles.push_back(Vector3(s->get_outer_radius(), 0, 0)); - add_handles(handles); - } -} -CSGShapeSpatialGizmo::CSGShapeSpatialGizmo(CSGShape *p_cs) { - - cs = p_cs; - set_spatial_node(p_cs); -} - -Ref EditorPluginCSG::create_spatial_gizmo(Spatial *p_spatial) { - if (Object::cast_to(p_spatial) || Object::cast_to(p_spatial) || Object::cast_to(p_spatial) || Object::cast_to(p_spatial) || Object::cast_to(p_spatial) || Object::cast_to(p_spatial)) { - Ref csg = memnew(CSGShapeSpatialGizmo(Object::cast_to(p_spatial))); - return csg; + p_gizmo->add_handles(handles, handles_material); } - - return Ref(); } EditorPluginCSG::EditorPluginCSG(EditorNode *p_editor) { - - EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.2, 0.5, 1, 0.1)); + Ref gizmo_plugin = Ref(memnew(CSGShapeSpatialGizmoPlugin)); + SpatialEditor::get_singleton()->register_gizmo_plugin(gizmo_plugin); } diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h index 68e916823bbc..d65d1f58c110 100644 --- a/modules/csg/csg_gizmos.h +++ b/modules/csg/csg_gizmos.h @@ -35,25 +35,27 @@ #include "editor/editor_plugin.h" #include "editor/spatial_editor_gizmos.h" -class CSGShapeSpatialGizmo : public EditorSpatialGizmo { +class CSGShapeSpatialGizmoPlugin : public EditorSpatialGizmoPlugin { - GDCLASS(CSGShapeSpatialGizmo, EditorSpatialGizmo); - - CSGShape *cs; + GDCLASS(CSGShapeSpatialGizmoPlugin, EditorSpatialGizmoPlugin); public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point); - virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false); - void redraw(); - CSGShapeSpatialGizmo(CSGShape *p_cs = NULL); + bool has_gizmo(Spatial *p_spatial); + String get_name() const; + bool is_selectable_when_hidden() const; + void redraw(EditorSpatialGizmo *p_gizmo); + + String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point); + void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel); + + CSGShapeSpatialGizmoPlugin(); }; class EditorPluginCSG : public EditorPlugin { GDCLASS(EditorPluginCSG, EditorPlugin) public: - virtual Ref create_spatial_gizmo(Spatial *p_spatial); EditorPluginCSG(EditorNode *p_editor); }; diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index 4866611dcec4..3f494264e758 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -202,6 +202,7 @@ void Spatial::_notification(int p_what) { #ifdef TOOLS_ENABLED if (data.gizmo.is_valid()) { data.gizmo->free(); + data.gizmo.unref(); } #endif diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h index 653714dc9805..bc054a87636f 100644 --- a/scene/3d/spatial.h +++ b/scene/3d/spatial.h @@ -51,6 +51,7 @@ class SpatialGizmo : public Reference { virtual bool can_draw() const = 0; SpatialGizmo(); + virtual ~SpatialGizmo() {} }; class Spatial : public Node {