From 3e6aaec19342367304d4ded3bcfb0cc91a8124c4 Mon Sep 17 00:00:00 2001 From: MarianoGNU Date: Mon, 28 Sep 2015 00:06:06 -0300 Subject: Add SpriteRegionEditor and update Polygon2DUVEditor Both with snap and grid support --- tools/editor/editor_node.cpp | 2 + tools/editor/icons/icon_grid.png | Bin 0 -> 354 bytes tools/editor/icons/icon_region_edit.png | Bin 0 -> 171 bytes tools/editor/plugins/polygon_2d_editor_plugin.cpp | 157 +++++- tools/editor/plugins/polygon_2d_editor_plugin.h | 17 + .../editor/plugins/sprite_region_editor_plugin.cpp | 565 +++++++++++++++++++++ tools/editor/plugins/sprite_region_editor_plugin.h | 125 +++++ 7 files changed, 863 insertions(+), 3 deletions(-) create mode 100644 tools/editor/icons/icon_grid.png create mode 100644 tools/editor/icons/icon_region_edit.png create mode 100644 tools/editor/plugins/sprite_region_editor_plugin.cpp create mode 100644 tools/editor/plugins/sprite_region_editor_plugin.h (limited to 'tools/editor') diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 03d1dfb743..f946471702 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -58,6 +58,7 @@ // plugins #include "plugins/sprite_frames_editor_plugin.h" +#include "plugins/sprite_region_editor_plugin.h" #include "plugins/canvas_item_editor_plugin.h" #include "plugins/spatial_editor_plugin.h" #include "plugins/sample_editor_plugin.h" @@ -5471,6 +5472,7 @@ EditorNode::EditorNode() { add_editor_plugin( memnew( TileSetEditorPlugin(this) ) ); add_editor_plugin( memnew( TileMapEditorPlugin(this) ) ); add_editor_plugin( memnew( SpriteFramesEditorPlugin(this) ) ); + add_editor_plugin( memnew( SpriteRegionEditorPlugin(this) ) ); add_editor_plugin( memnew( Particles2DEditorPlugin(this) ) ); add_editor_plugin( memnew( Path2DEditorPlugin(this) ) ); add_editor_plugin( memnew( PathEditorPlugin(this) ) ); diff --git a/tools/editor/icons/icon_grid.png b/tools/editor/icons/icon_grid.png new file mode 100644 index 0000000000..dcdd86c9b5 Binary files /dev/null and b/tools/editor/icons/icon_grid.png differ diff --git a/tools/editor/icons/icon_region_edit.png b/tools/editor/icons/icon_region_edit.png new file mode 100644 index 0000000000..824607f2cc Binary files /dev/null and b/tools/editor/icons/icon_region_edit.png differ diff --git a/tools/editor/plugins/polygon_2d_editor_plugin.cpp b/tools/editor/plugins/polygon_2d_editor_plugin.cpp index d25880fdff..3029dcf2ab 100644 --- a/tools/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/tools/editor/plugins/polygon_2d_editor_plugin.cpp @@ -50,6 +50,9 @@ void Polygon2DEditor::_notification(int p_what) { uv_button[UV_MODE_ROTATE]->set_icon(get_icon("ToolRotate","EditorIcons")); uv_button[UV_MODE_SCALE]->set_icon(get_icon("ToolScale","EditorIcons")); + b_snap_grid->set_icon( get_icon("Grid", "EditorIcons")); + b_snap_enable->set_icon( get_icon("Snap", "EditorIcons")); + uv_icon_zoom->set_texture( get_icon("Zoom", "EditorIcons")); } break; case NOTIFICATION_FIXED_PROCESS: { @@ -158,6 +161,41 @@ void Polygon2DEditor::_menu_option(int p_option) { } } +void Polygon2DEditor::_set_use_snap(bool p_use) +{ + use_snap=p_use; +} + +void Polygon2DEditor::_set_show_grid(bool p_show) +{ + snap_show_grid=p_show; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_set_snap_off_x(float p_val) +{ + snap_offset.x=p_val; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_set_snap_off_y(float p_val) +{ + snap_offset.y=p_val; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_set_snap_step_x(float p_val) +{ + snap_step.x=p_val; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_set_snap_step_y(float p_val) +{ + snap_step.y=p_val; + uv_edit_draw->update(); +} + void Polygon2DEditor::_wip_close() { undo_redo->create_action("Create Poly"); @@ -494,7 +532,7 @@ void Polygon2DEditor::_uv_input(const InputEvent& p_input) { Vector2 tuv=mtx.xform(uv_prev[i]); if (tuv.distance_to(Vector2(mb.x,mb.y))<8) { - + uv_drag_from=tuv; uv_drag_index=i; } } @@ -545,7 +583,7 @@ void Polygon2DEditor::_uv_input(const InputEvent& p_input) { } else if (uv_drag) { - Vector2 uv_drag_to(mm.x,mm.y); + Vector2 uv_drag_to=snap_point(Vector2(mm.x,mm.y)); Vector2 drag = mtx.affine_inverse().xform(uv_drag_to) - mtx.affine_inverse().xform(uv_drag_from); @@ -649,6 +687,33 @@ void Polygon2DEditor::_uv_draw() { uv_edit_draw->draw_texture(base_tex,Point2()); VS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(),Matrix32()); + if (snap_show_grid) { + Size2 s = uv_edit_draw->get_size(); + int last_cell; + + if (snap_step.x!=0) { + for(int i=0;idraw_line(Point2(i,0),Point2(i,s.height),Color(0.3,0.7,1,0.3)); + last_cell=cell; + } + } + + if (snap_step.y!=0) { + for(int i=0;idraw_line(Point2(0,i),Point2(s.width,i),Color(0.3,0.7,1,0.3)); + last_cell=cell; + } + } + } + DVector uvs = node->get_uv(); Ref handle = get_icon("EditorHandle","EditorIcons"); @@ -720,8 +785,27 @@ void Polygon2DEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_uv_input"),&Polygon2DEditor::_uv_input); ObjectTypeDB::bind_method(_MD("_uv_scroll_changed"),&Polygon2DEditor::_uv_scroll_changed); ObjectTypeDB::bind_method(_MD("_node_removed"),&Polygon2DEditor::_node_removed); + ObjectTypeDB::bind_method(_MD("_set_use_snap"),&Polygon2DEditor::_set_use_snap); + ObjectTypeDB::bind_method(_MD("_set_show_grid"),&Polygon2DEditor::_set_show_grid); + ObjectTypeDB::bind_method(_MD("_set_snap_off_x"),&Polygon2DEditor::_set_snap_off_x); + ObjectTypeDB::bind_method(_MD("_set_snap_off_y"),&Polygon2DEditor::_set_snap_off_y); + ObjectTypeDB::bind_method(_MD("_set_snap_step_x"),&Polygon2DEditor::_set_snap_step_x); + ObjectTypeDB::bind_method(_MD("_set_snap_step_y"),&Polygon2DEditor::_set_snap_step_y); + +} +inline float _snap_scalar(float p_offset, float p_step, float p_target) { + return p_step != 0 ? Math::stepify(p_target - p_offset, p_step) + p_offset : p_target; +} + +Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const { + if (use_snap) { + p_target.x = _snap_scalar(snap_offset.x*uv_draw_zoom-uv_draw_ofs.x, snap_step.x*uv_draw_zoom, p_target.x); + p_target.y = _snap_scalar(snap_offset.y*uv_draw_zoom-uv_draw_ofs.y, snap_step.y*uv_draw_zoom, p_target.y); + } + + return p_target; } Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) { @@ -731,6 +815,10 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) { editor=p_editor; undo_redo = editor->get_undo_redo(); + snap_step=Vector2(10,10); + use_snap=false; + snap_show_grid=false; + add_child( memnew( VSeparator )); button_create = memnew( ToolButton ); add_child(button_create); @@ -800,9 +888,72 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) { uv_menu->get_popup()->add_separator(); uv_menu->get_popup()->add_item("Clear UV",UVEDIT_UV_CLEAR); uv_menu->get_popup()->connect("item_pressed",this,"_menu_option"); + + uv_mode_hb->add_child( memnew( VSeparator )); + + b_snap_enable = memnew( ToolButton ); + uv_mode_hb->add_child(b_snap_enable); + b_snap_enable->set_text("Snap"); + b_snap_enable->set_focus_mode(FOCUS_NONE); + b_snap_enable->set_toggle_mode(true); + b_snap_enable->set_pressed(use_snap); + b_snap_enable->set_tooltip("Enable Snap"); + b_snap_enable->connect("toggled",this,"_set_use_snap"); + + b_snap_grid = memnew( ToolButton ); + uv_mode_hb->add_child(b_snap_grid); + b_snap_grid->set_text("Grid"); + b_snap_grid->set_focus_mode(FOCUS_NONE); + b_snap_grid->set_toggle_mode(true); + b_snap_grid->set_pressed(snap_show_grid); + b_snap_grid->set_tooltip("Show Grid"); + b_snap_grid->connect("toggled",this,"_set_show_grid"); + + uv_mode_hb->add_child( memnew( VSeparator )); + uv_mode_hb->add_child( memnew( Label("Grid Offset:") ) ); + + SpinBox *sb_off_x = memnew( SpinBox ); + sb_off_x->set_min(-256); + sb_off_x->set_max(256); + sb_off_x->set_step(1); + sb_off_x->set_val(snap_offset.x); + sb_off_x->set_suffix("px"); + sb_off_x->connect("value_changed", this, "_set_snap_off_x"); + uv_mode_hb->add_child(sb_off_x); + + SpinBox *sb_off_y = memnew( SpinBox ); + sb_off_y->set_min(-256); + sb_off_y->set_max(256); + sb_off_y->set_step(1); + sb_off_y->set_val(snap_offset.y); + sb_off_y->set_suffix("px"); + sb_off_y->connect("value_changed", this, "_set_snap_off_y"); + uv_mode_hb->add_child(sb_off_y); + + uv_mode_hb->add_child( memnew( VSeparator )); + uv_mode_hb->add_child( memnew( Label("Grid Step:") ) ); + + SpinBox *sb_step_x = memnew( SpinBox ); + sb_step_x->set_min(-256); + sb_step_x->set_max(256); + sb_step_x->set_step(1); + sb_step_x->set_val(snap_step.x); + sb_step_x->set_suffix("px"); + sb_step_x->connect("value_changed", this, "_set_snap_step_x"); + uv_mode_hb->add_child(sb_step_x); + + SpinBox *sb_step_y = memnew( SpinBox ); + sb_step_y->set_min(-256); + sb_step_y->set_max(256); + sb_step_y->set_step(1); + sb_step_y->set_val(snap_step.y); + sb_step_y->set_suffix("px"); + sb_step_y->connect("value_changed", this, "_set_snap_step_y"); + uv_mode_hb->add_child(sb_step_y); + uv_mode_hb->add_child( memnew( VSeparator )); uv_icon_zoom = memnew( TextureFrame ); - uv_main_hb->add_child( uv_icon_zoom ); + uv_mode_hb->add_child( uv_icon_zoom ); uv_zoom = memnew( HSlider ); uv_zoom->set_min(0.01); uv_zoom->set_max(4); diff --git a/tools/editor/plugins/polygon_2d_editor_plugin.h b/tools/editor/plugins/polygon_2d_editor_plugin.h index 8f807cb7e8..0939c44264 100644 --- a/tools/editor/plugins/polygon_2d_editor_plugin.h +++ b/tools/editor/plugins/polygon_2d_editor_plugin.h @@ -41,6 +41,8 @@ class Polygon2DEditor : public HBoxContainer { UVMode uv_mode; AcceptDialog *uv_edit; ToolButton *uv_button[4]; + ToolButton *b_snap_enable; + ToolButton *b_snap_grid; Control *uv_edit_draw; HSlider *uv_zoom; SpinBox *uv_zoom_value; @@ -78,6 +80,11 @@ class Polygon2DEditor : public HBoxContainer { Vector wip; bool wip_active; + bool use_snap; + bool snap_show_grid; + Vector2 snap_offset; + Vector2 snap_step; + void _uv_scroll_changed(float); void _uv_input(const InputEvent& p_input); void _uv_draw(); @@ -86,10 +93,20 @@ class Polygon2DEditor : public HBoxContainer { void _canvas_draw(); void _menu_option(int p_option); + void _set_use_snap(bool p_use); + void _set_show_grid(bool p_show); + void _set_snap_off_x(float p_val); + void _set_snap_off_y(float p_val); + void _set_snap_step_x(float p_val); + void _set_snap_step_y(float p_val); + protected: void _notification(int p_what); void _node_removed(Node *p_node); static void _bind_methods(); + + Vector2 snap_point(Vector2 p_target) const; + public: bool forward_input_event(const InputEvent& p_event); diff --git a/tools/editor/plugins/sprite_region_editor_plugin.cpp b/tools/editor/plugins/sprite_region_editor_plugin.cpp new file mode 100644 index 0000000000..35c53cf562 --- /dev/null +++ b/tools/editor/plugins/sprite_region_editor_plugin.cpp @@ -0,0 +1,565 @@ +/*************************************************************************/ +/* sprite_region_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Author: Mariano Suligoy */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "sprite_region_editor_plugin.h" +#include "scene/gui/check_box.h" +#include "os/input.h" +#include "os/keyboard.h" + +void SpriteRegionEditor::_region_draw() +{ + Ref base_tex = node->get_texture(); + if (base_tex.is_null()) + return; + + Matrix32 mtx; + mtx.elements[2]=-draw_ofs; + mtx.scale_basis(Vector2(draw_zoom,draw_zoom)); + + VS::get_singleton()->canvas_item_set_clip(edit_draw->get_canvas_item(),true); + VS::get_singleton()->canvas_item_add_set_transform(edit_draw->get_canvas_item(),mtx); + edit_draw->draw_texture(base_tex,Point2()); + VS::get_singleton()->canvas_item_add_set_transform(edit_draw->get_canvas_item(),Matrix32()); + + if (snap_show_grid) { + Size2 s = edit_draw->get_size(); + int last_cell; + + if (snap_step.x!=0) { + for(int i=0;idraw_line(Point2(i,0),Point2(i,s.height),Color(0.3,0.7,1,0.3)); + last_cell=cell; + } + } + + if (snap_step.y!=0) { + for(int i=0;idraw_line(Point2(0,i),Point2(s.width,i),Color(0.3,0.7,1,0.3)); + last_cell=cell; + } + } + } + + Ref select_handle = get_icon("EditorHandle","EditorIcons"); + + Rect2 scroll_rect(Point2(),mtx.basis_xform(base_tex->get_size())); + scroll_rect.expand_to(mtx.basis_xform(edit_draw->get_size())); + + Vector2 endpoints[4]={ + mtx.basis_xform(rect.pos), + mtx.basis_xform(rect.pos+Vector2(rect.size.x,0)), + mtx.basis_xform(rect.pos+rect.size), + mtx.basis_xform(rect.pos+Vector2(0,rect.size.y)) + }; + + for(int i=0;i<4;i++) { + + int prev = (i+3)%4; + int next = (i+1)%4; + + Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); + ofs*=1.4144*(select_handle->get_size().width/2); + + edit_draw->draw_line(endpoints[i]-draw_ofs, endpoints[next]-draw_ofs, Color(0.9,0.5,0.5), 2); + + edit_draw->draw_texture(select_handle,(endpoints[i]+ofs-(select_handle->get_size()/2)).floor()-draw_ofs); + + ofs = (endpoints[next]-endpoints[i])/2; + ofs += (endpoints[next]-endpoints[i]).tangent().normalized()*(select_handle->get_size().width/2); + + edit_draw->draw_texture(select_handle,(endpoints[i]+ofs-(select_handle->get_size()/2)).floor()-draw_ofs); + + scroll_rect.expand_to(endpoints[i]); + } + + scroll_rect=scroll_rect.grow(200); + updating_scroll=true; + hscroll->set_min(scroll_rect.pos.x); + hscroll->set_max(scroll_rect.pos.x+scroll_rect.size.x); + hscroll->set_page(edit_draw->get_size().x); + hscroll->set_val(draw_ofs.x); + hscroll->set_step(0.001); + + vscroll->set_min(scroll_rect.pos.y); + vscroll->set_max(scroll_rect.pos.y+scroll_rect.size.y); + vscroll->set_page(edit_draw->get_size().y); + vscroll->set_val(draw_ofs.y); + vscroll->set_step(0.001); + updating_scroll=false; +} + +void SpriteRegionEditor::_region_input(const InputEvent& p_input) +{ + Matrix32 mtx; + mtx.elements[2]=-draw_ofs; + mtx.scale_basis(Vector2(draw_zoom,draw_zoom)); + + Vector2 endpoints[8]={ + mtx.xform(rect.pos)+Vector2(-4,-4), + mtx.xform(rect.pos+Vector2(rect.size.x/2,0))+Vector2(0,-4), + mtx.xform(rect.pos+Vector2(rect.size.x,0))+Vector2(4,-4), + mtx.xform(rect.pos+Vector2(rect.size.x,rect.size.y/2))+Vector2(4,0), + mtx.xform(rect.pos+rect.size)+Vector2(4,4), + mtx.xform(rect.pos+Vector2(rect.size.x/2,rect.size.y))+Vector2(0,4), + mtx.xform(rect.pos+Vector2(0,rect.size.y))+Vector2(-4,4), + mtx.xform(rect.pos+Vector2(0,rect.size.y/2))+Vector2(-4,0) + }; + + if (p_input.type==InputEvent::MOUSE_BUTTON) { + + + const InputEventMouseButton &mb=p_input.mouse_button; + + if (mb.button_index==BUTTON_LEFT) { + + + if (mb.pressed) { + + drag_from=mtx.affine_inverse().xform(Vector2(mb.x,mb.y)); + drag_from=snap_point(drag_from); + drag=true; + rect_prev=node->get_region_rect(); + + drag_index=-1; + for(int i=0;i<8;i++) { + + Vector2 tuv=endpoints[i]; + if (tuv.distance_to(Vector2(mb.x,mb.y))<8) { + drag_index=i; + creating = false; + } + } + + if (drag_index==-1) { + creating = true; + rect = Rect2(drag_from,Size2()); + } + + } else if (drag) { + + undo_redo->create_action("Set region_rect"); + undo_redo->add_do_method(node,"set_region_rect",node->get_region_rect()); + undo_redo->add_undo_method(node,"set_region_rect",rect_prev); + undo_redo->add_do_method(edit_draw,"update"); + undo_redo->add_undo_method(edit_draw,"update"); + undo_redo->commit_action(); + + drag=false; + } + + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed) { + + if (drag) { + drag=false; + node->set_region_rect(rect_prev); + rect=rect_prev; + edit_draw->update(); + } + + } else if (mb.button_index==BUTTON_WHEEL_UP && mb.pressed) { + + zoom->set_val( zoom->get_val()/0.9 ); + } else if (mb.button_index==BUTTON_WHEEL_DOWN && mb.pressed) { + + zoom->set_val( zoom->get_val()*0.9); + } + + } else if (p_input.type==InputEvent::MOUSE_MOTION) { + + const InputEventMouseMotion &mm=p_input.mouse_motion; + + if (mm.button_mask&BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + + Vector2 draged(mm.relative_x,mm.relative_y); + hscroll->set_val( hscroll->get_val()-draged.x ); + vscroll->set_val( vscroll->get_val()-draged.y ); + + } else if (drag) { + + Vector2 new_pos = mtx.affine_inverse().xform(Vector2(mm.x,mm.y)); + new_pos = snap_point(new_pos); + + if (creating) { + rect = Rect2(drag_from,Size2()); + rect.expand_to(new_pos); + node->set_region_rect(rect); + edit_draw->update(); + return; + } + + switch(drag_index) { + case 0: { + Vector2 p=rect_prev.pos+rect_prev.size; + rect = Rect2(p,Size2()); + rect.expand_to(new_pos); + node->set_region_rect(rect); + } break; + case 1: { + Vector2 p=rect_prev.pos+Vector2(0,rect_prev.size.y); + rect = Rect2(p,Size2(rect_prev.size.x,0)); + rect.expand_to(new_pos); + node->set_region_rect(rect); + } break; + case 2: { + Vector2 p=rect_prev.pos+Vector2(0,rect_prev.size.y); + rect = Rect2(p,Size2()); + rect.expand_to(new_pos); + node->set_region_rect(rect); + } break; + case 3: { + Vector2 p=rect_prev.pos; + rect = Rect2(p,Size2(0,rect_prev.size.y)); + rect.expand_to(new_pos); + node->set_region_rect(rect); + } break; + case 4: { + Vector2 p=rect_prev.pos; + rect = Rect2(p,Size2()); + rect.expand_to(new_pos); + node->set_region_rect(rect); + } break; + case 5: { + Vector2 p=rect_prev.pos; + rect = Rect2(p,Size2(rect_prev.size.x,0)); + rect.expand_to(new_pos); + node->set_region_rect(rect); + } break; + case 6: { + Vector2 p=rect_prev.pos+Vector2(rect_prev.size.x,0); + rect = Rect2(p,Size2()); + rect.expand_to(new_pos); + node->set_region_rect(rect); + } break; + case 7: { + Vector2 p=rect_prev.pos+Vector2(rect_prev.size.x,0); + rect = Rect2(p,Size2(0,rect_prev.size.y)); + rect.expand_to(new_pos); + node->set_region_rect(rect); + } break; + + } + edit_draw->update(); + } + + } +} + +void SpriteRegionEditor::_scroll_changed(float) +{ + if (updating_scroll) + return; + + draw_ofs.x=hscroll->get_val(); + draw_ofs.y=vscroll->get_val(); + draw_zoom=zoom->get_val(); + print_line("_scroll_changed"); + edit_draw->update(); +} + +void SpriteRegionEditor::_set_use_snap(bool p_use) +{ + use_snap=p_use; +} + +void SpriteRegionEditor::_set_show_grid(bool p_show) +{ + snap_show_grid=p_show; + edit_draw->update(); +} + +void SpriteRegionEditor::_set_snap_off_x(float p_val) +{ + snap_offset.x=p_val; + edit_draw->update(); +} + +void SpriteRegionEditor::_set_snap_off_y(float p_val) +{ + snap_offset.y=p_val; + edit_draw->update(); +} + +void SpriteRegionEditor::_set_snap_step_x(float p_val) +{ + snap_step.x=p_val; + edit_draw->update(); +} + +void SpriteRegionEditor::_set_snap_step_y(float p_val) +{ + snap_step.y=p_val; + edit_draw->update(); +} + +void SpriteRegionEditor::_notification(int p_what) +{ + switch(p_what) { + + case NOTIFICATION_READY: { + edit_node->set_icon( get_icon("RegionEdit","EditorIcons")); + b_snap_grid->set_icon( get_icon("Grid", "EditorIcons")); + b_snap_enable->set_icon( get_icon("Snap", "EditorIcons")); + icon_zoom->set_texture( get_icon("Zoom", "EditorIcons")); + } break; + } +} + +void SpriteRegionEditor::_node_removed(Node *p_node) +{ + if(p_node==node) { + node=NULL; + hide(); + } +} + +void SpriteRegionEditor::_bind_methods() +{ + ObjectTypeDB::bind_method(_MD("_edit_node"),&SpriteRegionEditor::_edit_node); + ObjectTypeDB::bind_method(_MD("_region_draw"),&SpriteRegionEditor::_region_draw); + ObjectTypeDB::bind_method(_MD("_region_input"),&SpriteRegionEditor::_region_input); + ObjectTypeDB::bind_method(_MD("_scroll_changed"),&SpriteRegionEditor::_scroll_changed); + ObjectTypeDB::bind_method(_MD("_node_removed"),&SpriteRegionEditor::_node_removed); + ObjectTypeDB::bind_method(_MD("_set_use_snap"),&SpriteRegionEditor::_set_use_snap); + ObjectTypeDB::bind_method(_MD("_set_show_grid"),&SpriteRegionEditor::_set_show_grid); + ObjectTypeDB::bind_method(_MD("_set_snap_off_x"),&SpriteRegionEditor::_set_snap_off_x); + ObjectTypeDB::bind_method(_MD("_set_snap_off_y"),&SpriteRegionEditor::_set_snap_off_y); + ObjectTypeDB::bind_method(_MD("_set_snap_step_x"),&SpriteRegionEditor::_set_snap_step_x); + ObjectTypeDB::bind_method(_MD("_set_snap_step_y"),&SpriteRegionEditor::_set_snap_step_y); +} + +void SpriteRegionEditor::edit(Node *p_sprite) +{ + if (p_sprite) { + node=p_sprite->cast_to(); + node->connect("exit_tree",this,"_node_removed",varray(),CONNECT_ONESHOT); + } else { + if (node) + node->disconnect("exit_tree",this,"_node_removed"); + node=NULL; + } + +} +void SpriteRegionEditor::_edit_node() +{ + if (node->get_texture().is_null()) { + + error->set_text("No texture in this sprite.\nSet a texture to be able to edit Region."); + error->popup_centered_minsize(); + return; + } + + rect=node->get_region_rect(); + dlg_editor->popup_centered_ratio(0.85); +} + +inline float _snap_scalar(float p_offset, float p_step, float p_target) { + return p_step != 0 ? Math::stepify(p_target - p_offset, p_step) + p_offset : p_target; +} + +Vector2 SpriteRegionEditor::snap_point(Vector2 p_target) const { + if (use_snap) { + p_target.x = _snap_scalar(snap_offset.x, snap_step.x, p_target.x); + p_target.y = _snap_scalar(snap_offset.y, snap_step.y, p_target.y); + } + p_target = p_target.snapped(Size2(1, 1)); + + return p_target; +} + +SpriteRegionEditor::SpriteRegionEditor(EditorNode* p_editor) +{ + node=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + snap_step=Vector2(10,10); + use_snap=false; + snap_show_grid=false; + + add_child( memnew( VSeparator )); + edit_node = memnew( ToolButton ); + add_child(edit_node); + edit_node->connect("pressed",this,"_edit_node"); + + dlg_editor = memnew( AcceptDialog ); + add_child(dlg_editor); + dlg_editor->set_title("Sprite Region Editor"); + dlg_editor->set_self_opacity(0.9); + + VBoxContainer *main_vb = memnew( VBoxContainer ); + dlg_editor->add_child(main_vb); + dlg_editor->set_child_rect(main_vb); + HBoxContainer *hb_tools = memnew( HBoxContainer ); + main_vb->add_child(hb_tools); + + b_snap_enable = memnew( ToolButton ); + hb_tools->add_child(b_snap_enable); + b_snap_enable->set_text("Snap"); + b_snap_enable->set_focus_mode(FOCUS_NONE); + b_snap_enable->set_toggle_mode(true); + b_snap_enable->set_pressed(use_snap); + b_snap_enable->set_tooltip("Enable Snap"); + b_snap_enable->connect("toggled",this,"_set_use_snap"); + + b_snap_grid = memnew( ToolButton ); + hb_tools->add_child(b_snap_grid); + b_snap_grid->set_text("Grid"); + b_snap_grid->set_focus_mode(FOCUS_NONE); + b_snap_grid->set_toggle_mode(true); + b_snap_grid->set_pressed(snap_show_grid); + b_snap_grid->set_tooltip("Show Grid"); + b_snap_grid->connect("toggled",this,"_set_show_grid"); + + hb_tools->add_child( memnew( VSeparator )); + hb_tools->add_child( memnew( Label("Grid Offset:") ) ); + + SpinBox *sb_off_x = memnew( SpinBox ); + sb_off_x->set_min(-256); + sb_off_x->set_max(256); + sb_off_x->set_step(1); + sb_off_x->set_val(snap_offset.x); + sb_off_x->set_suffix("px"); + sb_off_x->connect("value_changed", this, "_set_snap_off_x"); + hb_tools->add_child(sb_off_x); + + SpinBox *sb_off_y = memnew( SpinBox ); + sb_off_y->set_min(-256); + sb_off_y->set_max(256); + sb_off_y->set_step(1); + sb_off_y->set_val(snap_offset.y); + sb_off_y->set_suffix("px"); + sb_off_y->connect("value_changed", this, "_set_snap_off_y"); + hb_tools->add_child(sb_off_y); + + hb_tools->add_child( memnew( VSeparator )); + hb_tools->add_child( memnew( Label("Grid Step:") ) ); + + SpinBox *sb_step_x = memnew( SpinBox ); + sb_step_x->set_min(-256); + sb_step_x->set_max(256); + sb_step_x->set_step(1); + sb_step_x->set_val(snap_step.x); + sb_step_x->set_suffix("px"); + sb_step_x->connect("value_changed", this, "_set_snap_step_x"); + hb_tools->add_child(sb_step_x); + + SpinBox *sb_step_y = memnew( SpinBox ); + sb_step_y->set_min(-256); + sb_step_y->set_max(256); + sb_step_y->set_step(1); + sb_step_y->set_val(snap_step.y); + sb_step_y->set_suffix("px"); + sb_step_y->connect("value_changed", this, "_set_snap_step_y"); + hb_tools->add_child(sb_step_y); + +// MARIANOGNU::TODO: Add more tools? + + HBoxContainer *main_hb = memnew( HBoxContainer ); + main_vb->add_child(main_hb); + edit_draw = memnew( Control ); + main_hb->add_child(edit_draw); + main_hb->set_v_size_flags(SIZE_EXPAND_FILL); + edit_draw->set_h_size_flags(SIZE_EXPAND_FILL); + + + hb_tools->add_child( memnew( VSeparator )); + icon_zoom = memnew( TextureFrame ); + hb_tools->add_child(icon_zoom); + + zoom = memnew( HSlider ); + zoom->set_min(0.01); + zoom->set_max(4); + zoom->set_val(1); + zoom->set_step(0.01); + hb_tools->add_child(zoom); + zoom->set_custom_minimum_size(Size2(200,0)); + zoom_value = memnew( SpinBox ); + zoom->share(zoom_value); + zoom_value->set_custom_minimum_size(Size2(50,0)); + hb_tools->add_child(zoom_value); + zoom->connect("value_changed",this,"_scroll_changed"); + + + + vscroll = memnew( VScrollBar); + main_hb->add_child(vscroll); + vscroll->connect("value_changed",this,"_scroll_changed"); + hscroll = memnew( HScrollBar ); + main_vb->add_child(hscroll); + hscroll->connect("value_changed",this,"_scroll_changed"); + + edit_draw->connect("draw",this,"_region_draw"); + edit_draw->connect("input_event",this,"_region_input"); + draw_zoom=1.0; + updating_scroll=false; + + error = memnew( AcceptDialog); + add_child(error); + +} + +void SpriteRegionEditorPlugin::edit(Object *p_node) +{ + region_editor->edit(p_node->cast_to()); +} + +bool SpriteRegionEditorPlugin::handles(Object *p_node) const +{ + return p_node->is_type("Sprite"); +} + +void SpriteRegionEditorPlugin::make_visible(bool p_visible) +{ + if (p_visible) { + region_editor->show(); + } else { + region_editor->hide(); + region_editor->edit(NULL); + } +} + +SpriteRegionEditorPlugin::SpriteRegionEditorPlugin(EditorNode *p_node) +{ + editor = p_node; + region_editor= memnew ( SpriteRegionEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(region_editor); + + region_editor->hide(); +} + diff --git a/tools/editor/plugins/sprite_region_editor_plugin.h b/tools/editor/plugins/sprite_region_editor_plugin.h new file mode 100644 index 0000000000..cf69395f40 --- /dev/null +++ b/tools/editor/plugins/sprite_region_editor_plugin.h @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* sprite_region_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Author: Mariano Suligoy */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SPRITE_REGION_EDITOR_PLUGIN_H +#define SPRITE_REGION_EDITOR_PLUGIN_H + +#include "canvas_item_editor_plugin.h" +#include "tools/editor/editor_plugin.h" +#include "tools/editor/editor_node.h" +#include "scene/2d/sprite.h" + +class SpriteRegionEditor : public HBoxContainer { + + OBJ_TYPE(SpriteRegionEditor, HBoxContainer ); + + ToolButton *edit_node; +// Button *use_region; + ToolButton *b_snap_enable; + ToolButton *b_snap_grid; + TextureFrame *icon_zoom; + HSlider *zoom; + SpinBox *zoom_value; + Control *edit_draw; + + VScrollBar *vscroll; + HScrollBar *hscroll; + + Sprite *node; + EditorNode *editor; + AcceptDialog *dlg_editor; + UndoRedo* undo_redo; + + Vector2 draw_ofs; + float draw_zoom; + bool updating_scroll; + + bool use_snap; + bool snap_show_grid; + Vector2 snap_offset; + Vector2 snap_step; + + Rect2 rect; + Rect2 rect_prev; + bool drag; + bool creating; + Vector2 drag_from; + int drag_index; + + AcceptDialog *error; + + void _set_use_snap(bool p_use); + void _set_show_grid(bool p_show); + void _set_snap_off_x(float p_val); + void _set_snap_off_y(float p_val); + void _set_snap_step_x(float p_val); + void _set_snap_step_y(float p_val); + +protected: + + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); + + Vector2 snap_point(Vector2 p_target) const; + +public: + + void edit(); + void _edit_node(); + void _region_draw(); + void _region_input(const InputEvent &p_input); + void _scroll_changed(float); + + void edit(Node *p_sprite); + SpriteRegionEditor(EditorNode* p_editor); + +}; + +class SpriteRegionEditorPlugin : public EditorPlugin +{ + + OBJ_TYPE( SpriteRegionEditorPlugin, EditorPlugin ); + + SpriteRegionEditor *region_editor; + EditorNode *editor; +public: + + virtual String get_name() const { return "Sprite"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + SpriteRegionEditorPlugin(EditorNode *p_node); +}; + +#endif // SPRITE_REGION_EDITOR_PLUGIN_H -- cgit v1.2.3 From e055247b17dc9b9d7239b95da2207388d05fd770 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 1 Oct 2015 16:25:36 -0300 Subject: -Added ability to use cubic interpolation on image resize (little more quality on non-po2 resizing) -Added ability for exporter to shrink images to non-integer values. Helps if you want to convert your game artwork from 1080->720 or similar --- tools/editor/editor_import_export.cpp | 8 ++++---- tools/editor/editor_import_export.h | 12 ++++++------ tools/editor/io_plugins/editor_texture_import_plugin.cpp | 8 ++++---- tools/editor/io_plugins/editor_texture_import_plugin.h | 2 +- tools/editor/project_export.cpp | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'tools/editor') diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp index 3b5b8fba81..b13473e61c 100644 --- a/tools/editor/editor_import_export.cpp +++ b/tools/editor/editor_import_export.cpp @@ -1420,12 +1420,12 @@ EditorImportExport::ImageAction EditorImportExport::get_export_image_action() co return image_action; } -void EditorImportExport::set_export_image_shrink(int p_shrink) { +void EditorImportExport::set_export_image_shrink(float p_shrink) { image_shrink=p_shrink; } -int EditorImportExport::get_export_image_shrink() const{ +float EditorImportExport::get_export_image_shrink() const{ return image_shrink; } @@ -1496,12 +1496,12 @@ bool EditorImportExport::image_export_group_get_make_atlas(const StringName& p_e return image_groups[p_export_group].make_atlas; } -void EditorImportExport::image_export_group_set_shrink(const StringName& p_export_group,int p_amount){ +void EditorImportExport::image_export_group_set_shrink(const StringName& p_export_group,float p_amount){ ERR_FAIL_COND(!image_groups.has(p_export_group)); image_groups[p_export_group].shrink=p_amount; } -int EditorImportExport::image_export_group_get_shrink(const StringName& p_export_group) const{ +float EditorImportExport::image_export_group_get_shrink(const StringName& p_export_group) const{ ERR_FAIL_COND_V(!image_groups.has(p_export_group),1); return image_groups[p_export_group].shrink; diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h index 9de6509605..245adffbfd 100644 --- a/tools/editor/editor_import_export.h +++ b/tools/editor/editor_import_export.h @@ -252,7 +252,7 @@ protected: ImageAction action; bool make_atlas; float lossy_quality; - int shrink; + float shrink; }; Vector > export_plugins; @@ -260,7 +260,7 @@ protected: Map by_idx; ImageAction image_action; float image_action_compress_quality; - int image_shrink; + float image_shrink; Set image_formats; ExportFilter export_filter; @@ -310,8 +310,8 @@ public: void set_export_image_action(ImageAction p_action); ImageAction get_export_image_action() const; - void set_export_image_shrink(int p_shrink); - int get_export_image_shrink() const; + void set_export_image_shrink(float p_shrink); + float get_export_image_shrink() const; void set_export_image_quality(float p_quality); float get_export_image_quality() const; @@ -326,8 +326,8 @@ public: ImageAction image_export_group_get_image_action(const StringName& p_export_group) const; void image_export_group_set_make_atlas(const StringName& p_export_group,bool p_make); bool image_export_group_get_make_atlas(const StringName& p_export_group) const; - void image_export_group_set_shrink(const StringName& p_export_group,int p_amount); - int image_export_group_get_shrink(const StringName& p_export_group) const; + void image_export_group_set_shrink(const StringName& p_export_group,float p_amount); + float image_export_group_get_shrink(const StringName& p_export_group) const; void image_export_group_set_lossy_quality(const StringName& p_export_group,float p_quality); float image_export_group_get_lossy_quality(const StringName& p_export_group) const; diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 436725f6fb..c0887ab40a 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -828,7 +828,7 @@ Error EditorTextureImportPlugin::import(const String& p_path, const Ref &texture,int format, float quality,int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,int shrink) { +Error EditorTextureImportPlugin::_process_texture_data(Ref &texture,int format, float quality,int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink) { if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { @@ -866,7 +866,7 @@ Error EditorTextureImportPlugin::_process_texture_data(Ref &textur int orig_w=image.get_width(); int orig_h=image.get_height(); - image.resize(orig_w/shrink,orig_h/shrink); + image.resize(orig_w/shrink,orig_h/shrink,Image::INTERPOLATE_CUBIC); texture->create_from_image(image,tex_flags); texture->set_size_override(Size2(orig_w,orig_h)); @@ -926,7 +926,7 @@ Error EditorTextureImportPlugin::_process_texture_data(Ref &textur int orig_h=image.get_height(); if (shrink>1) { - image.resize(orig_w/shrink,orig_h/shrink); + image.resize(orig_w/shrink,orig_h/shrink,Image::INTERPOLATE_CUBIC); texture->create_from_image(image,tex_flags); texture->set_size_override(Size2(orig_w,orig_h)); } @@ -987,7 +987,7 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Refhas_option("shrink")) shrink=from->get_option("shrink"); diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index 02d09d9e17..78383d1d77 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -70,7 +70,7 @@ private: static EditorTextureImportPlugin *singleton[MODE_MAX]; //used by other importers such as mesh - Error _process_texture_data(Ref &texture, int format, float quality, int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,int shrink); + Error _process_texture_data(Ref &texture, int format, float quality, int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink); void compress_image(EditorExportPlatform::ImageCompression p_mode,Image& image,bool p_smaller); public: diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp index 9f871fd3ab..6003b976aa 100644 --- a/tools/editor/project_export.cpp +++ b/tools/editor/project_export.cpp @@ -1156,7 +1156,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) { image_shrink = memnew( SpinBox ); image_shrink->set_min(1); image_shrink->set_max(8); - image_shrink->set_step(1); + image_shrink->set_step(0.1); image_vb->add_margin_child("Shrink All Images:",image_shrink); sections->add_child(image_vb); @@ -1237,7 +1237,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) { group_shrink->set_min(1); group_shrink->set_max(8); group_shrink->set_val(1); - group_shrink->set_step(1); + group_shrink->set_step(0.001); group_options->add_margin_child("Shrink By:",group_shrink); group_shrink->connect("value_changed",this,"_group_changed"); -- cgit v1.2.3 From 6e87314d83a9beab56fdd115277e230ef683c53d Mon Sep 17 00:00:00 2001 From: George Marques Date: Fri, 2 Oct 2015 14:20:50 -0300 Subject: Add support for Opus audio format --- tools/editor/icons/icon_audio_stream_opus.png | Bin 0 -> 559 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tools/editor/icons/icon_audio_stream_opus.png (limited to 'tools/editor') diff --git a/tools/editor/icons/icon_audio_stream_opus.png b/tools/editor/icons/icon_audio_stream_opus.png new file mode 100644 index 0000000000..69b0c83b4d Binary files /dev/null and b/tools/editor/icons/icon_audio_stream_opus.png differ -- cgit v1.2.3 From aad2bbdb6fb7c8217d7e75480b38e45f00cb3abd Mon Sep 17 00:00:00 2001 From: reduz Date: Thu, 8 Oct 2015 15:00:40 -0300 Subject: newline fixes --- tools/editor/plugins/path_editor_plugin.cpp | 1194 ++--- tools/editor/spatial_editor_gizmos.cpp | 6382 +++++++++++++-------------- tools/editor/spatial_editor_gizmos.h | 982 ++--- 3 files changed, 4279 insertions(+), 4279 deletions(-) (limited to 'tools/editor') diff --git a/tools/editor/plugins/path_editor_plugin.cpp b/tools/editor/plugins/path_editor_plugin.cpp index 4af22e956f..f4bdf50fe9 100644 --- a/tools/editor/plugins/path_editor_plugin.cpp +++ b/tools/editor/plugins/path_editor_plugin.cpp @@ -1,597 +1,597 @@ -/*************************************************************************/ -/* path_editor_plugin.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "path_editor_plugin.h" -#include "spatial_editor_plugin.h" -#include "scene/resources/curve.h" -#include "os/keyboard.h" - -String PathSpatialGizmo::get_handle_name(int p_idx) const { - - Ref c = path->get_curve(); - if (c.is_null()) - return ""; - - if (p_idxget_point_count()) { - - return "Curve Point #"+itos(p_idx); - } - - p_idx=p_idx-c->get_point_count()+1; - - int idx=p_idx/2; - int t=p_idx%2; - String n = "Curve Point #"+itos(idx); - if (t==0) - n+=" In"; - else - n+=" Out"; - - return n; - - -} -Variant PathSpatialGizmo::get_handle_value(int p_idx) const{ - - Ref c = path->get_curve(); - if (c.is_null()) - return Variant(); - - if (p_idxget_point_count()) { - - original=c->get_point_pos(p_idx); - return original; - } - - p_idx=p_idx-c->get_point_count()+1; - - int idx=p_idx/2; - int t=p_idx%2; - - Vector3 ofs; - if (t==0) - ofs=c->get_point_in(idx); - else - ofs= c->get_point_out(idx); - - original=ofs+c->get_point_pos(idx); - - return ofs; - -} -void PathSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){ - - Ref c = path->get_curve(); - if (c.is_null()) - return; - - Transform gt = path->get_global_transform(); - Transform gi = gt.affine_inverse(); - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); - - if (p_idxget_point_count()) { - - Plane p(gt.xform(original),p_camera->get_transform().basis.get_axis(2)); - - Vector3 inters; - - if (p.intersects_ray(ray_from,ray_dir,&inters)) { - - Vector3 local = gi.xform(inters); - c->set_point_pos(p_idx,local); - } - - return; - } - - p_idx=p_idx-c->get_point_count()+1; - - int idx=p_idx/2; - int t=p_idx%2; - - Vector3 base = c->get_point_pos(idx); - - Plane p(gt.xform(original),p_camera->get_transform().basis.get_axis(2)); - - Vector3 inters; - - if (p.intersects_ray(ray_from,ray_dir,&inters)) { - - Vector3 local = gi.xform(inters)-base; - if (t==0) { - c->set_point_in(idx,local); - } else { - c->set_point_out(idx,local); - } - } - -} - -void PathSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ - - Ref c = path->get_curve(); - if (c.is_null()) - return; - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - - if (p_idxget_point_count()) { - - if (p_cancel) { - - c->set_point_pos(p_idx,p_restore); - return; - } - ur->create_action("Set Curve Point Pos"); - ur->add_do_method(c.ptr(),"set_point_pos",p_idx,c->get_point_pos(p_idx)); - ur->add_undo_method(c.ptr(),"set_point_pos",p_idx,p_restore); - ur->commit_action(); - - return; - } - - p_idx=p_idx-c->get_point_count()+1; - - int idx=p_idx/2; - int t=p_idx%2; - - Vector3 ofs; - - if (p_cancel) { - - - - return; - } - - - - if (t==0) { - - if (p_cancel) { - - c->set_point_in(p_idx,p_restore); - return; - } - ur->create_action("Set Curve In Pos"); - ur->add_do_method(c.ptr(),"set_point_in",idx,c->get_point_in(idx)); - ur->add_undo_method(c.ptr(),"set_point_in",idx,p_restore); - ur->commit_action(); - - - } else { - if (p_cancel) { - - c->set_point_out(idx,p_restore); - return; - } - ur->create_action("Set Curve Out Pos"); - ur->add_do_method(c.ptr(),"set_point_out",idx,c->get_point_out(idx)); - ur->add_undo_method(c.ptr(),"set_point_out",idx,p_restore); - ur->commit_action(); - - } - -} - - -void PathSpatialGizmo::redraw(){ - - clear(); - - Ref c = path->get_curve(); - if (c.is_null()) - return; - - Vector3Array v3a=c->tesselate(); - //Vector3Array v3a=c->get_baked_points(); - - int v3s = v3a.size(); - if (v3s==0) - return; - Vector v3p; - Vector3Array::Read r = v3a.read(); - - for(int i=0;ipath_material); - add_collision_segments(v3p); - - if (PathEditorPlugin::singleton->get_edited_path()==path) { - v3p.clear(); - Vector handles; - Vector sec_handles; - - for(int i=0;iget_point_count();i++) { - - Vector3 p = c->get_point_pos(i); - handles.push_back(p); - if (i>0) { - v3p.push_back(p); - v3p.push_back(p+c->get_point_in(i)); - sec_handles.push_back(p+c->get_point_in(i)); - } - - if (iget_point_count()-1) { - v3p.push_back(p); - v3p.push_back(p+c->get_point_out(i)); - sec_handles.push_back(p+c->get_point_out(i)); - } - } - - add_lines(v3p,PathEditorPlugin::singleton->path_thin_material); - add_handles(handles); - add_handles(sec_handles,false,true); - } - -} - -PathSpatialGizmo::PathSpatialGizmo(Path* p_path){ - - path=p_path; - set_spatial_node(p_path); - - - -} - -bool PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) { - - if (p_spatial->cast_to()) { - - - Ref psg = memnew( PathSpatialGizmo(p_spatial->cast_to())); - p_spatial->set_gizmo(psg); - return true; - } - - return false; -} - -bool PathEditorPlugin::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) { - - if (!path) - return false; - Ref c=path->get_curve(); - if (c.is_null()) - return false; - Transform gt = path->get_global_transform(); - Transform it = gt.affine_inverse(); - - static const int click_dist = 10; //should make global - - - if (p_event.type==InputEvent::MOUSE_BUTTON) { - - const InputEventMouseButton &mb=p_event.mouse_button; - Point2 mbpos(mb.x,mb.y); - - if (mb.pressed && mb.button_index==BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb.mod.control))) { - //click into curve, break it down - Vector3Array v3a = c->tesselate(); - int idx=0; - int rc=v3a.size(); - int closest_seg=-1; - Vector3 closest_seg_point; - float closest_d=1e20; - - if (rc>=2) { - Vector3Array::Read r = v3a.read(); - - if (p_camera->unproject_position(gt.xform(c->get_point_pos(0))).distance_to(mbpos)get_point_count()-1;i++) { - //find the offset and point index of the place to break up - int j=idx; - if (p_camera->unproject_position(gt.xform(c->get_point_pos(i+1))).distance_to(mbpos)get_point_pos(i+1)!=r[j]) { - - Vector3 from =r[j]; - Vector3 to =r[j+1]; - real_t cdist = from.distance_to(to); - from=gt.xform(from); - to=gt.xform(to); - if (cdist>0) { - Vector2 s[2]; - s[0] = p_camera->unproject_position(from); - s[1] = p_camera->unproject_position(to); - Vector2 inters = Geometry::get_closest_point_to_segment_2d(mbpos,s); - float d = inters.distance_to(mbpos); - - if (d<10 && dproject_ray_origin(mbpos); - Vector3 ray_dir=p_camera->project_ray_normal(mbpos); - - Vector3 ra,rb; - Geometry::get_closest_points_between_segments(ray_from,ray_from+ray_dir*4096,from,to,ra,rb); - - closest_seg_point=it.xform(rb); - } - - } - j++; - - } - if (idx==j) - idx++; //force next - else - idx=j; //swap - - - if (j==rc) - break; - } - } - - UndoRedo *ur = editor->get_undo_redo(); - if (closest_seg!=-1) { - //subdivide - - ur->create_action("Split Path"); - ur->add_do_method(c.ptr(),"add_point",closest_seg_point,Vector3(),Vector3(),closest_seg+1); - ur->add_undo_method(c.ptr(),"remove_point",closest_seg+1); - ur->commit_action();; - return true; - - } else { - - Vector3 org; - if (c->get_point_count()==0) - org=path->get_transform().get_origin(); - else - org=gt.xform(c->get_point_pos(c->get_point_count())); - Plane p(org,p_camera->get_transform().basis.get_axis(2)); - Vector3 ray_from=p_camera->project_ray_origin(mbpos); - Vector3 ray_dir=p_camera->project_ray_normal(mbpos); - - Vector3 inters; - if (p.intersects_ray(ray_from,ray_dir,&inters)) { - - ur->create_action("Add Point to Curve"); - ur->add_do_method(c.ptr(),"add_point",it.xform(inters),Vector3(),Vector3(),-1); - ur->add_undo_method(c.ptr(),"remove_point",c->get_point_count()); - ur->commit_action();; - return true; - } - - //add new at pos - } - - } else if (mb.pressed && ((mb.button_index==BUTTON_LEFT && curve_del->is_pressed()) || (mb.button_index==BUTTON_RIGHT && curve_edit->is_pressed()))) { - - int erase_idx=-1; - for(int i=0;iget_point_count();i++) { - //find the offset and point index of the place to break up - if (p_camera->unproject_position(gt.xform(c->get_point_pos(i))).distance_to(mbpos)get_undo_redo(); - ur->create_action("Remove Path Point"); - ur->add_do_method(c.ptr(),"remove_point",erase_idx); - ur->add_undo_method(c.ptr(),"add_point",c->get_point_pos(erase_idx),c->get_point_in(erase_idx),c->get_point_out(erase_idx),erase_idx); - ur->commit_action(); - return true; - } - } - - } - - return false; -} - - -void PathEditorPlugin::edit(Object *p_object) { - - if (p_object) { - path=p_object->cast_to(); - if (path) { - - if (path->get_curve().is_valid()) { - path->get_curve()->emit_signal("changed"); - } - } - } else { - Path *pre=path; - path=NULL; - if (pre) { - pre->get_curve()->emit_signal("changed"); - } - } -// collision_polygon_editor->edit(p_object->cast_to()); -} - -bool PathEditorPlugin::handles(Object *p_object) const { - - return p_object->is_type("Path"); -} - -void PathEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - - curve_create->show(); - curve_edit->show(); - curve_del->show(); - curve_close->show(); - sep->show(); - } else { - - curve_create->hide(); - curve_edit->hide(); - curve_del->hide(); - curve_close->hide(); - sep->hide(); - - { - Path *pre=path; - path=NULL; - if (pre && pre->get_curve().is_valid()) { - pre->get_curve()->emit_signal("changed"); - } - } - } - -} - -void PathEditorPlugin::_mode_changed(int p_idx) { - - curve_create->set_pressed(p_idx==0); - curve_edit->set_pressed(p_idx==1); - curve_del->set_pressed(p_idx==2); -} - -void PathEditorPlugin::_close_curve() { - - Ref c = path->get_curve(); - if (c.is_null()) - return ; - if (c->get_point_count()<2) - return; - c->add_point(c->get_point_pos(0),c->get_point_in(0),c->get_point_out(0)); - -} - -void PathEditorPlugin::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - curve_create->connect("pressed",this,"_mode_changed",make_binds(0)); - curve_edit->connect("pressed",this,"_mode_changed",make_binds(1)); - curve_del->connect("pressed",this,"_mode_changed",make_binds(2)); - curve_close->connect("pressed",this,"_close_curve"); - } -} - -void PathEditorPlugin::_bind_methods() { - - ObjectTypeDB::bind_method(_MD("_mode_changed"),&PathEditorPlugin::_mode_changed); - ObjectTypeDB::bind_method(_MD("_close_curve"),&PathEditorPlugin::_close_curve); -} - -PathEditorPlugin* PathEditorPlugin::singleton=NULL; - - -PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) { - - path=NULL; - editor=p_node; - singleton=this; - - path_material = Ref( memnew( FixedMaterial )); - path_material->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) ); - path_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - path_material->set_line_width(3); - path_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); - path_material->set_flag(Material::FLAG_UNSHADED,true); - - path_thin_material = Ref( memnew( FixedMaterial )); - path_thin_material->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) ); - path_thin_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - path_thin_material->set_line_width(1); - path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); - path_thin_material->set_flag(Material::FLAG_UNSHADED,true); - - SpatialEditor::get_singleton()->add_gizmo_plugin(this); - - sep = memnew( VSeparator); - sep->hide(); - SpatialEditor::get_singleton()->add_control_to_menu_panel(sep); - curve_edit = memnew( ToolButton ); - curve_edit->set_icon(SpatialEditor::get_singleton()->get_icon("CurveEdit","EditorIcons")); - curve_edit->set_toggle_mode(true); - curve_edit->hide(); - curve_edit->set_focus_mode(Control::FOCUS_NONE); - curve_edit->set_tooltip("Select Points\nShift+Drag: Select Control Points\n"+keycode_get_string(KEY_MASK_CMD)+"Click: Add Point\nRight Click: Delete Point."); - SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_edit); - curve_create = memnew( ToolButton ); - curve_create->set_icon(SpatialEditor::get_singleton()->get_icon("CurveCreate","EditorIcons")); - curve_create->set_toggle_mode(true); - curve_create->hide(); - curve_create->set_focus_mode(Control::FOCUS_NONE); - curve_create->set_tooltip("Add Point (in empty space)\nSplit Segment (in curve)."); - SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_create); - curve_del = memnew( ToolButton ); - curve_del->set_icon(SpatialEditor::get_singleton()->get_icon("CurveDelete","EditorIcons")); - curve_del->set_toggle_mode(true); - curve_del->hide(); - curve_del->set_focus_mode(Control::FOCUS_NONE); - curve_del->set_tooltip("Delete Point."); - SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_del); - curve_close = memnew( ToolButton ); - curve_close->set_icon(SpatialEditor::get_singleton()->get_icon("CurveClose","EditorIcons")); - curve_close->hide(); - curve_close->set_focus_mode(Control::FOCUS_NONE); - curve_close->set_tooltip("Close Curve"); - SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_close); - - - - curve_edit->set_pressed(true); - /* - 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(); - */ - - -} - - -PathEditorPlugin::~PathEditorPlugin() -{ -} - +/*************************************************************************/ +/* path_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "path_editor_plugin.h" +#include "spatial_editor_plugin.h" +#include "scene/resources/curve.h" +#include "os/keyboard.h" + +String PathSpatialGizmo::get_handle_name(int p_idx) const { + + Ref c = path->get_curve(); + if (c.is_null()) + return ""; + + if (p_idxget_point_count()) { + + return "Curve Point #"+itos(p_idx); + } + + p_idx=p_idx-c->get_point_count()+1; + + int idx=p_idx/2; + int t=p_idx%2; + String n = "Curve Point #"+itos(idx); + if (t==0) + n+=" In"; + else + n+=" Out"; + + return n; + + +} +Variant PathSpatialGizmo::get_handle_value(int p_idx) const{ + + Ref c = path->get_curve(); + if (c.is_null()) + return Variant(); + + if (p_idxget_point_count()) { + + original=c->get_point_pos(p_idx); + return original; + } + + p_idx=p_idx-c->get_point_count()+1; + + int idx=p_idx/2; + int t=p_idx%2; + + Vector3 ofs; + if (t==0) + ofs=c->get_point_in(idx); + else + ofs= c->get_point_out(idx); + + original=ofs+c->get_point_pos(idx); + + return ofs; + +} +void PathSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){ + + Ref c = path->get_curve(); + if (c.is_null()) + return; + + Transform gt = path->get_global_transform(); + Transform gi = gt.affine_inverse(); + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); + + if (p_idxget_point_count()) { + + Plane p(gt.xform(original),p_camera->get_transform().basis.get_axis(2)); + + Vector3 inters; + + if (p.intersects_ray(ray_from,ray_dir,&inters)) { + + Vector3 local = gi.xform(inters); + c->set_point_pos(p_idx,local); + } + + return; + } + + p_idx=p_idx-c->get_point_count()+1; + + int idx=p_idx/2; + int t=p_idx%2; + + Vector3 base = c->get_point_pos(idx); + + Plane p(gt.xform(original),p_camera->get_transform().basis.get_axis(2)); + + Vector3 inters; + + if (p.intersects_ray(ray_from,ray_dir,&inters)) { + + Vector3 local = gi.xform(inters)-base; + if (t==0) { + c->set_point_in(idx,local); + } else { + c->set_point_out(idx,local); + } + } + +} + +void PathSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ + + Ref c = path->get_curve(); + if (c.is_null()) + return; + + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + + if (p_idxget_point_count()) { + + if (p_cancel) { + + c->set_point_pos(p_idx,p_restore); + return; + } + ur->create_action("Set Curve Point Pos"); + ur->add_do_method(c.ptr(),"set_point_pos",p_idx,c->get_point_pos(p_idx)); + ur->add_undo_method(c.ptr(),"set_point_pos",p_idx,p_restore); + ur->commit_action(); + + return; + } + + p_idx=p_idx-c->get_point_count()+1; + + int idx=p_idx/2; + int t=p_idx%2; + + Vector3 ofs; + + if (p_cancel) { + + + + return; + } + + + + if (t==0) { + + if (p_cancel) { + + c->set_point_in(p_idx,p_restore); + return; + } + ur->create_action("Set Curve In Pos"); + ur->add_do_method(c.ptr(),"set_point_in",idx,c->get_point_in(idx)); + ur->add_undo_method(c.ptr(),"set_point_in",idx,p_restore); + ur->commit_action(); + + + } else { + if (p_cancel) { + + c->set_point_out(idx,p_restore); + return; + } + ur->create_action("Set Curve Out Pos"); + ur->add_do_method(c.ptr(),"set_point_out",idx,c->get_point_out(idx)); + ur->add_undo_method(c.ptr(),"set_point_out",idx,p_restore); + ur->commit_action(); + + } + +} + + +void PathSpatialGizmo::redraw(){ + + clear(); + + Ref c = path->get_curve(); + if (c.is_null()) + return; + + Vector3Array v3a=c->tesselate(); + //Vector3Array v3a=c->get_baked_points(); + + int v3s = v3a.size(); + if (v3s==0) + return; + Vector v3p; + Vector3Array::Read r = v3a.read(); + + for(int i=0;ipath_material); + add_collision_segments(v3p); + + if (PathEditorPlugin::singleton->get_edited_path()==path) { + v3p.clear(); + Vector handles; + Vector sec_handles; + + for(int i=0;iget_point_count();i++) { + + Vector3 p = c->get_point_pos(i); + handles.push_back(p); + if (i>0) { + v3p.push_back(p); + v3p.push_back(p+c->get_point_in(i)); + sec_handles.push_back(p+c->get_point_in(i)); + } + + if (iget_point_count()-1) { + v3p.push_back(p); + v3p.push_back(p+c->get_point_out(i)); + sec_handles.push_back(p+c->get_point_out(i)); + } + } + + add_lines(v3p,PathEditorPlugin::singleton->path_thin_material); + add_handles(handles); + add_handles(sec_handles,false,true); + } + +} + +PathSpatialGizmo::PathSpatialGizmo(Path* p_path){ + + path=p_path; + set_spatial_node(p_path); + + + +} + +bool PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) { + + if (p_spatial->cast_to()) { + + + Ref psg = memnew( PathSpatialGizmo(p_spatial->cast_to())); + p_spatial->set_gizmo(psg); + return true; + } + + return false; +} + +bool PathEditorPlugin::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) { + + if (!path) + return false; + Ref c=path->get_curve(); + if (c.is_null()) + return false; + Transform gt = path->get_global_transform(); + Transform it = gt.affine_inverse(); + + static const int click_dist = 10; //should make global + + + if (p_event.type==InputEvent::MOUSE_BUTTON) { + + const InputEventMouseButton &mb=p_event.mouse_button; + Point2 mbpos(mb.x,mb.y); + + if (mb.pressed && mb.button_index==BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb.mod.control))) { + //click into curve, break it down + Vector3Array v3a = c->tesselate(); + int idx=0; + int rc=v3a.size(); + int closest_seg=-1; + Vector3 closest_seg_point; + float closest_d=1e20; + + if (rc>=2) { + Vector3Array::Read r = v3a.read(); + + if (p_camera->unproject_position(gt.xform(c->get_point_pos(0))).distance_to(mbpos)get_point_count()-1;i++) { + //find the offset and point index of the place to break up + int j=idx; + if (p_camera->unproject_position(gt.xform(c->get_point_pos(i+1))).distance_to(mbpos)get_point_pos(i+1)!=r[j]) { + + Vector3 from =r[j]; + Vector3 to =r[j+1]; + real_t cdist = from.distance_to(to); + from=gt.xform(from); + to=gt.xform(to); + if (cdist>0) { + Vector2 s[2]; + s[0] = p_camera->unproject_position(from); + s[1] = p_camera->unproject_position(to); + Vector2 inters = Geometry::get_closest_point_to_segment_2d(mbpos,s); + float d = inters.distance_to(mbpos); + + if (d<10 && dproject_ray_origin(mbpos); + Vector3 ray_dir=p_camera->project_ray_normal(mbpos); + + Vector3 ra,rb; + Geometry::get_closest_points_between_segments(ray_from,ray_from+ray_dir*4096,from,to,ra,rb); + + closest_seg_point=it.xform(rb); + } + + } + j++; + + } + if (idx==j) + idx++; //force next + else + idx=j; //swap + + + if (j==rc) + break; + } + } + + UndoRedo *ur = editor->get_undo_redo(); + if (closest_seg!=-1) { + //subdivide + + ur->create_action("Split Path"); + ur->add_do_method(c.ptr(),"add_point",closest_seg_point,Vector3(),Vector3(),closest_seg+1); + ur->add_undo_method(c.ptr(),"remove_point",closest_seg+1); + ur->commit_action();; + return true; + + } else { + + Vector3 org; + if (c->get_point_count()==0) + org=path->get_transform().get_origin(); + else + org=gt.xform(c->get_point_pos(c->get_point_count())); + Plane p(org,p_camera->get_transform().basis.get_axis(2)); + Vector3 ray_from=p_camera->project_ray_origin(mbpos); + Vector3 ray_dir=p_camera->project_ray_normal(mbpos); + + Vector3 inters; + if (p.intersects_ray(ray_from,ray_dir,&inters)) { + + ur->create_action("Add Point to Curve"); + ur->add_do_method(c.ptr(),"add_point",it.xform(inters),Vector3(),Vector3(),-1); + ur->add_undo_method(c.ptr(),"remove_point",c->get_point_count()); + ur->commit_action();; + return true; + } + + //add new at pos + } + + } else if (mb.pressed && ((mb.button_index==BUTTON_LEFT && curve_del->is_pressed()) || (mb.button_index==BUTTON_RIGHT && curve_edit->is_pressed()))) { + + int erase_idx=-1; + for(int i=0;iget_point_count();i++) { + //find the offset and point index of the place to break up + if (p_camera->unproject_position(gt.xform(c->get_point_pos(i))).distance_to(mbpos)get_undo_redo(); + ur->create_action("Remove Path Point"); + ur->add_do_method(c.ptr(),"remove_point",erase_idx); + ur->add_undo_method(c.ptr(),"add_point",c->get_point_pos(erase_idx),c->get_point_in(erase_idx),c->get_point_out(erase_idx),erase_idx); + ur->commit_action(); + return true; + } + } + + } + + return false; +} + + +void PathEditorPlugin::edit(Object *p_object) { + + if (p_object) { + path=p_object->cast_to(); + if (path) { + + if (path->get_curve().is_valid()) { + path->get_curve()->emit_signal("changed"); + } + } + } else { + Path *pre=path; + path=NULL; + if (pre) { + pre->get_curve()->emit_signal("changed"); + } + } +// collision_polygon_editor->edit(p_object->cast_to()); +} + +bool PathEditorPlugin::handles(Object *p_object) const { + + return p_object->is_type("Path"); +} + +void PathEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + + curve_create->show(); + curve_edit->show(); + curve_del->show(); + curve_close->show(); + sep->show(); + } else { + + curve_create->hide(); + curve_edit->hide(); + curve_del->hide(); + curve_close->hide(); + sep->hide(); + + { + Path *pre=path; + path=NULL; + if (pre && pre->get_curve().is_valid()) { + pre->get_curve()->emit_signal("changed"); + } + } + } + +} + +void PathEditorPlugin::_mode_changed(int p_idx) { + + curve_create->set_pressed(p_idx==0); + curve_edit->set_pressed(p_idx==1); + curve_del->set_pressed(p_idx==2); +} + +void PathEditorPlugin::_close_curve() { + + Ref c = path->get_curve(); + if (c.is_null()) + return ; + if (c->get_point_count()<2) + return; + c->add_point(c->get_point_pos(0),c->get_point_in(0),c->get_point_out(0)); + +} + +void PathEditorPlugin::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + curve_create->connect("pressed",this,"_mode_changed",make_binds(0)); + curve_edit->connect("pressed",this,"_mode_changed",make_binds(1)); + curve_del->connect("pressed",this,"_mode_changed",make_binds(2)); + curve_close->connect("pressed",this,"_close_curve"); + } +} + +void PathEditorPlugin::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("_mode_changed"),&PathEditorPlugin::_mode_changed); + ObjectTypeDB::bind_method(_MD("_close_curve"),&PathEditorPlugin::_close_curve); +} + +PathEditorPlugin* PathEditorPlugin::singleton=NULL; + + +PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) { + + path=NULL; + editor=p_node; + singleton=this; + + path_material = Ref( memnew( FixedMaterial )); + path_material->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) ); + path_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + path_material->set_line_width(3); + path_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); + path_material->set_flag(Material::FLAG_UNSHADED,true); + + path_thin_material = Ref( memnew( FixedMaterial )); + path_thin_material->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) ); + path_thin_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + path_thin_material->set_line_width(1); + path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); + path_thin_material->set_flag(Material::FLAG_UNSHADED,true); + + SpatialEditor::get_singleton()->add_gizmo_plugin(this); + + sep = memnew( VSeparator); + sep->hide(); + SpatialEditor::get_singleton()->add_control_to_menu_panel(sep); + curve_edit = memnew( ToolButton ); + curve_edit->set_icon(SpatialEditor::get_singleton()->get_icon("CurveEdit","EditorIcons")); + curve_edit->set_toggle_mode(true); + curve_edit->hide(); + curve_edit->set_focus_mode(Control::FOCUS_NONE); + curve_edit->set_tooltip("Select Points\nShift+Drag: Select Control Points\n"+keycode_get_string(KEY_MASK_CMD)+"Click: Add Point\nRight Click: Delete Point."); + SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_edit); + curve_create = memnew( ToolButton ); + curve_create->set_icon(SpatialEditor::get_singleton()->get_icon("CurveCreate","EditorIcons")); + curve_create->set_toggle_mode(true); + curve_create->hide(); + curve_create->set_focus_mode(Control::FOCUS_NONE); + curve_create->set_tooltip("Add Point (in empty space)\nSplit Segment (in curve)."); + SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_create); + curve_del = memnew( ToolButton ); + curve_del->set_icon(SpatialEditor::get_singleton()->get_icon("CurveDelete","EditorIcons")); + curve_del->set_toggle_mode(true); + curve_del->hide(); + curve_del->set_focus_mode(Control::FOCUS_NONE); + curve_del->set_tooltip("Delete Point."); + SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_del); + curve_close = memnew( ToolButton ); + curve_close->set_icon(SpatialEditor::get_singleton()->get_icon("CurveClose","EditorIcons")); + curve_close->hide(); + curve_close->set_focus_mode(Control::FOCUS_NONE); + curve_close->set_tooltip("Close Curve"); + SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_close); + + + + curve_edit->set_pressed(true); + /* + 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(); + */ + + +} + + +PathEditorPlugin::~PathEditorPlugin() +{ +} + diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp index 521a10bbd0..4dc9c4f43e 100644 --- a/tools/editor/spatial_editor_gizmos.cpp +++ b/tools/editor/spatial_editor_gizmos.cpp @@ -1,3191 +1,3191 @@ -/*************************************************************************/ -/* spatial_editor_gizmos.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "spatial_editor_gizmos.h" -#include "geometry.h" -#include "scene/3d/camera.h" -#include "scene/resources/surface_tool.h" -#include "scene/resources/sphere_shape.h" -#include "scene/resources/box_shape.h" -#include "scene/resources/capsule_shape.h" -#include "scene/resources/ray_shape.h" -#include "scene/resources/convex_polygon_shape.h" -#include "scene/resources/plane_shape.h" -#include "quick_hull.h" - -// Keep small children away from this file. -// It's so ugly it will eat them alive - -#define HANDLE_HALF_SIZE 0.05 - -void SpatialGizmoTool::clear() { - - for(int i=0;ifree(instances[i].instance); - - - } - - billboard_handle=false; - collision_segments.clear(); - collision_mesh=Ref(); - instances.clear(); - handles.clear(); - secondary_handles.clear(); -} - -void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) { - - 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()); - if (billboard) - VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_BILLBOARD,true); - if (unscaled) - VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_DEPH_SCALE,true); - if (skeleton.is_valid()) - VS::get_singleton()->instance_attach_skeleton(instance,skeleton); - if (extra_margin) - VS::get_singleton()->instance_set_extra_visibility_margin(instance,1); - VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_CAST_SHADOW,false); - VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_RECEIVE_SHADOWS,false); - VS::get_singleton()->instance_set_layer_mask(instance,1<& p_mesh,bool p_billboard, const RID &p_skeleton) { - - ERR_FAIL_COND(!spatial_node); - Instance ins; - - ins.billboard=p_billboard; - ins.mesh=p_mesh; - ins.skeleton=p_skeleton; - if (valid) { - ins.create_instance(spatial_node); - VS::get_singleton()->instance_set_transform(ins.instance,spatial_node->get_global_transform()); - } - - instances.push_back(ins); - -} - -void SpatialGizmoTool::add_lines(const Vector &p_lines, const Ref &p_material,bool p_billboard){ - - ERR_FAIL_COND(!spatial_node); - Instance ins; - - Ref mesh = memnew( Mesh ); - Array a; - a.resize(Mesh::ARRAY_MAX); - - a[Mesh::ARRAY_VERTEX]=p_lines; - - DVector color; - color.resize(p_lines.size()); - { - DVector::Write w = color.write(); - for(int i=0;iadd_surface(Mesh::PRIMITIVE_LINES,a); - mesh->surface_set_material(0,p_material); - - if (p_billboard) { - float md=0; - for(int i=0;iset_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0)); - } - } - - ins.billboard=p_billboard; - ins.mesh=mesh; - if (valid) { - ins.create_instance(spatial_node); - VS::get_singleton()->instance_set_transform(ins.instance,spatial_node->get_global_transform()); - } - - instances.push_back(ins); - -} - -void SpatialGizmoTool::add_unscaled_billboard(const Ref& p_material,float p_scale) { - - ERR_FAIL_COND(!spatial_node); - Instance ins; - - Vector vs; - Vector uv; - - vs.push_back(Vector3(-p_scale,p_scale,0)); - vs.push_back(Vector3(p_scale,p_scale,0)); - vs.push_back(Vector3(p_scale,-p_scale,0)); - vs.push_back(Vector3(-p_scale,-p_scale,0)); - - uv.push_back(Vector2(1,0)); - uv.push_back(Vector2(0,0)); - uv.push_back(Vector2(0,1)); - uv.push_back(Vector2(1,1)); - - Ref mesh = memnew( Mesh ); - Array a; - a.resize(Mesh::ARRAY_MAX); - a[Mesh::ARRAY_VERTEX]=vs; - a[Mesh::ARRAY_TEX_UV]=uv; - mesh->add_surface(Mesh::PRIMITIVE_TRIANGLE_FAN,a); - mesh->surface_set_material(0,p_material); - - if (true) { - float md=0; - for(int i=0;iset_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0)); - } - } - - ins.mesh=mesh; - ins.unscaled=true; - ins.billboard=true; - if (valid) { - ins.create_instance(spatial_node); - VS::get_singleton()->instance_set_transform(ins.instance,spatial_node->get_global_transform()); - } - - instances.push_back(ins); - - -} - -void SpatialGizmoTool::add_collision_triangles(const Ref& p_tmesh) { - - collision_mesh=p_tmesh; -} - -void SpatialGizmoTool::add_collision_segments(const Vector &p_lines) { - - int from=collision_segments.size(); - collision_segments.resize(from+p_lines.size()); - for(int i=0;i &p_handles, bool p_billboard,bool p_secondary){ - - billboard_handle=p_billboard; - - if (!is_selected()) - return; - - ERR_FAIL_COND(!spatial_node); - - ERR_FAIL_COND(!spatial_node); - Instance ins; - - - Ref mesh = memnew( Mesh ); -#if 1 - - Array a; - a.resize(VS::ARRAY_MAX); - a[VS::ARRAY_VERTEX]=p_handles; - DVector colors; - { - colors.resize(p_handles.size()); - DVector::Write w=colors.write(); - for(int i=0;iget_over_gizmo_handle()!=i) - col=Color(0.9,0.9,0.9,0.9); - w[i]=col; - } - - } - a[VS::ARRAY_COLOR]=colors; - mesh->add_surface(Mesh::PRIMITIVE_POINTS,a); - mesh->surface_set_material(0,SpatialEditorGizmos::singleton->handle2_material); - - if (p_billboard) { - float md=0; - for(int i=0;iset_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0)); - } - } - - - -#else - for(int ih=0;ih vertices; - Vector normals; - - int vtx_idx=0; -#define ADD_VTX(m_idx);\ - vertices.push_back( (face_points[m_idx]*HANDLE_HALF_SIZE+p_handles[ih]) );\ - normals.push_back( normal_points[m_idx] );\ - vtx_idx++;\ - - for (int i=0;i<6;i++) { - - - Vector3 face_points[4]; - Vector3 normal_points[4]; - float uv_points[8]={0,0,0,1,1,1,1,0}; - - 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]*(i>=3?-1:1); - else - face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); - } - normal_points[j]=Vector3(); - normal_points[j][i%3]=(i>=3?-1:1); - } - //tri 1 - ADD_VTX(0); - ADD_VTX(1); - ADD_VTX(2); - //tri 2 - ADD_VTX(2); - ADD_VTX(3); - ADD_VTX(0); - - } - - - Array d; - d.resize(VS::ARRAY_MAX); - d[VisualServer::ARRAY_NORMAL]= normals ; - d[VisualServer::ARRAY_VERTEX]= vertices ; - - mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d); - mesh->surface_set_material(ih,SpatialEditorGizmos::singleton->handle_material); - - - } -#endif - ins.mesh=mesh; - ins.billboard=p_billboard; - ins.extra_margin=true; - if (valid) { - ins.create_instance(spatial_node); - VS::get_singleton()->instance_set_transform(ins.instance,spatial_node->get_global_transform()); - } - instances.push_back(ins); - if (!p_secondary) { - int chs=handles.size(); - handles.resize(chs+p_handles.size()); - for(int i=0;i &p_frustum) { - - ERR_FAIL_COND_V(!spatial_node,false); - ERR_FAIL_COND_V(!valid,false); - - if (collision_segments.size()) { - - const Plane *p=p_frustum.ptr(); - int fc=p_frustum.size(); - - int vc=collision_segments.size(); - const Vector3* vptr=collision_segments.ptr(); - Transform t = spatial_node->get_global_transform(); - - for(int i=0;i 0 && p[j].distance_to(b) >0) { - - any_out=true; - break; - } - } - - if (!any_out) - return true; - } - - return false; - } - - return false; -} - - -bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) { - - ERR_FAIL_COND_V(!spatial_node,false); - ERR_FAIL_COND_V(!valid,false); - - if (r_gizmo_handle) { - - Transform t = spatial_node->get_global_transform(); - t.orthonormalize(); - if (billboard_handle) { - t.set_look_at(t.origin,t.origin+p_camera->get_transform().basis.get_axis(2),p_camera->get_transform().basis.get_axis(1)); - } - Transform ti=t.affine_inverse(); - - Vector3 ray_from=ti.xform(p_camera->project_ray_origin(p_point)); - Vector3 ray_dir=t.basis.xform_inv(p_camera->project_ray_normal(p_point)).normalized(); - Vector3 ray_to = ray_from+ray_dir*4096; - - float min_d=1e20; - int idx=-1; - - for(int i=0;iunproject_position(hpos); - if (p.distance_to(p_point)handle_t->get_width()*0.6) { - - - real_t dp = p_camera->get_transform().origin.distance_to(hpos); - if (dpget_transform().basis.get_axis(2); - min_d=dp; - idx=i+handles.size(); - - } - - } - -#else - AABB aabb; - aabb.pos=Vector3(-1,-1,-1)*HANDLE_HALF_SIZE; - aabb.size=aabb.pos*-2; - aabb.pos+=secondary_handles[i]; - - - Vector3 rpos,rnorm; - - if (aabb.intersects_segment(ray_from,ray_to,&rpos,&rnorm)) { - - real_t dp = ray_dir.dot(rpos); - if (dpunproject_position(hpos); - if (p.distance_to(p_point)handle_t->get_width()*0.6) { - - - real_t dp = p_camera->get_transform().origin.distance_to(hpos); - if (dpget_transform().basis.get_axis(2); - min_d=dp; - idx=i; - - } - - } - -#else - - AABB aabb; - aabb.pos=Vector3(-1,-1,-1)*HANDLE_HALF_SIZE; - aabb.size=aabb.pos*-2; - aabb.pos+=handles[i]; - - - Vector3 rpos,rnorm; - - if (aabb.intersects_segment(ray_from,ray_to,&rpos,&rnorm)) { - - real_t dp = ray_dir.dot(rpos); - if (dp=0) { - *r_gizmo_handle=idx; - return true; - } - - - } - - if (collision_segments.size()) { - - Plane camp(p_camera->get_transform().origin,(-p_camera->get_transform().basis.get_axis(2)).normalized()); - - int vc=collision_segments.size(); - const Vector3* vptr=collision_segments.ptr(); - Transform t = spatial_node->get_global_transform(); - if (billboard_handle) { - t.set_look_at(t.origin,t.origin+p_camera->get_transform().basis.get_axis(2),p_camera->get_transform().basis.get_axis(1)); - } - - Vector3 cp; - float cpd=1e20; - - for(int i=0;iunproject_position(a); - s[1] = p_camera->unproject_position(b); - - - Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point,s); - - float pd = p.distance_to(p_point); - - if (pd0) { - - float d2=s[0].distance_to(p)/d; - tcp = a+(b-a)*d2; - - } else { - tcp=a; - - } - - if (camp.distance_to(tcp)get_znear()) - continue; - cp=tcp; - cpd=pd; - } - } - - if (cpd<8) { - - r_pos=cp; - r_normal=-p_camera->project_ray_normal(p_point); - return true; - } - - return false; - } - - - if (collision_mesh.is_valid()) { - Transform gt = spatial_node->get_global_transform(); - - if (billboard_handle) { - gt.set_look_at(gt.origin,gt.origin+p_camera->get_transform().basis.get_axis(2),p_camera->get_transform().basis.get_axis(1)); - } - - Transform ai=gt.affine_inverse(); - Vector3 ray_from = ai.xform(p_camera->project_ray_origin(p_point)); - Vector3 ray_dir=ai.basis.xform(p_camera->project_ray_normal(p_point)).normalized(); - Vector3 rpos,rnorm; - -#if 1 - - - - if (collision_mesh->intersect_ray(ray_from,ray_dir,rpos,rnorm)) { - - r_pos=gt.xform(rpos); - r_normal=gt.basis.xform(rnorm).normalized(); - return true; - } -#else - - if (collision_mesh->intersect_segment(ray_from,ray_from+ray_dir*4906.0,rpos,rnorm)) { - - r_pos=gt.xform(rpos); - r_normal=gt.basis.xform(rnorm).normalized(); - return true; - } - -#endif - } - - return false; - -} - - - -void SpatialGizmoTool::create() { - - ERR_FAIL_COND(!spatial_node); - ERR_FAIL_COND(valid); - valid=true; - - for(int i=0;iinstance_set_transform(instances[i].instance,spatial_node->get_global_transform()); - } - -} - - -void SpatialGizmoTool::free(){ - - ERR_FAIL_COND(!spatial_node); - ERR_FAIL_COND(!valid); - - for(int i=0;ifree(instances[i].instance); - instances[i].instance=RID(); - } - - valid=false; - - -} - - - -SpatialGizmoTool::SpatialGizmoTool() { - valid=false; - billboard_handle=false; - -} - -SpatialGizmoTool::~SpatialGizmoTool(){ - - clear(); -} - -Vector3 SpatialGizmoTool::get_handle_pos(int p_idx) const { - - ERR_FAIL_INDEX_V(p_idx,handles.size(),Vector3()); - - return handles[p_idx]; - -} - -//// light gizmo - - -String LightSpatialGizmo::get_handle_name(int p_idx) const { - - if (p_idx==0) - return "Radius"; - else - return "Aperture"; -} - - -Variant LightSpatialGizmo::get_handle_value(int p_idx) const{ - - if (p_idx==0) - return light->get_parameter(Light::PARAM_RADIUS); - if (p_idx==1) - return light->get_parameter(Light::PARAM_SPOT_ANGLE); - - return Variant(); -} - - -static float _find_closest_angle_to_half_pi_arc(const Vector3& p_from, const Vector3& p_to, float p_arc_radius,const Transform& p_arc_xform) { - - //bleh, discrete is simpler - static const int arc_test_points=64; - float min_d = 1e20; - Vector3 min_p; - - - for(int i=0;iget_global_transform(); - gt.orthonormalize(); - Transform gi = gt.affine_inverse(); - - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); - - Vector3 s[2]={gi.xform(ray_from),gi.xform(ray_from+ray_dir*4096)}; - if (p_idx==0) { - - if (light->cast_to()) { - Vector3 ra,rb; - Geometry::get_closest_points_between_segments(Vector3(),Vector3(0,0,-4096),s[0],s[1],ra,rb); - - float d = -ra.z; - if (d<0) - d=0; - - light->set_parameter(Light::PARAM_RADIUS,d); - } else if (light->cast_to()) { - - Plane cp=Plane( gt.origin, p_camera->get_transform().basis.get_axis(2)); - - Vector3 inters; - if (cp.intersects_ray(ray_from,ray_dir,&inters)) { - - float r = inters.distance_to(gt.origin); - light->set_parameter(Light::PARAM_RADIUS,r); - } - - } - - } else if (p_idx==1) { - - float a = _find_closest_angle_to_half_pi_arc(s[0],s[1],light->get_parameter(Light::PARAM_RADIUS),gt); - light->set_parameter(Light::PARAM_SPOT_ANGLE,CLAMP(a,0.01,89.99)); - } -} - -void LightSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ - - if (p_cancel) { - - light->set_parameter(p_idx==0?Light::PARAM_RADIUS:Light::PARAM_SPOT_ANGLE,p_restore); - - } else if (p_idx==0) { - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action("Change Light Radius"); - ur->add_do_method(light,"set_parameter",Light::PARAM_RADIUS,light->get_parameter(Light::PARAM_RADIUS)); - ur->add_undo_method(light,"set_parameter",Light::PARAM_RADIUS,p_restore); - ur->commit_action(); - } else if (p_idx==1) { - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action("Change Light Radius"); - ur->add_do_method(light,"set_parameter",Light::PARAM_SPOT_ANGLE,light->get_parameter(Light::PARAM_SPOT_ANGLE)); - ur->add_undo_method(light,"set_parameter",Light::PARAM_SPOT_ANGLE,p_restore); - ur->commit_action(); - - } -} - - - -void LightSpatialGizmo::redraw() { - - - if (light->cast_to()) { - - - - const int arrow_points=5; - Vector3 arrow[arrow_points]={ - Vector3(0,0,2), - Vector3(1,1,2), - Vector3(1,1,-1), - Vector3(2,2,-1), - Vector3(0,0,-3) - }; - - int arrow_sides=4; - - Vector lines; - - - for(int i = 0; i < arrow_sides ; i++) { - - - Matrix3 ma(Vector3(0,0,1),Math_PI*2*float(i)/arrow_sides); - Matrix3 mb(Vector3(0,0,1),Math_PI*2*float(i+1)/arrow_sides); - - - for(int j=1;jlight_material); - add_collision_segments(lines); - add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_directional_icon,0.05); - - } - - if (light->cast_to()) { - - clear(); - - - OmniLight *on = light->cast_to(); - - float r = on->get_parameter(Light::PARAM_RADIUS); - - Vector points; - - for(int i=0;i<=360;i++) { - - float ra=Math::deg2rad(i); - float rb=Math::deg2rad(i+1); - Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*r; - Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*r; - - /*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)); - - } - - add_lines(points,SpatialEditorGizmos::singleton->light_material,true); - add_collision_segments(points); - - add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_omni_icon,0.05); - - Vector handles; - handles.push_back(Vector3(r,0,0)); - add_handles(handles,true); - - - } - - - if (light->cast_to()) { - - clear(); - - Vector points; - SpotLight *on = light->cast_to(); - - float r = on->get_parameter(Light::PARAM_RADIUS); - float w = r*Math::sin(Math::deg2rad(on->get_parameter(Light::PARAM_SPOT_ANGLE))); - float d = r*Math::cos(Math::deg2rad(on->get_parameter(Light::PARAM_SPOT_ANGLE))); - - - - for(int i=0;i<360;i++) { - - float ra=Math::deg2rad(i); - float rb=Math::deg2rad(i+1); - Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*w; - Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*w; - - /*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,-d)); - points.push_back(Vector3(b.x,b.y,-d)); - - if (i%90==0) { - - points.push_back(Vector3(a.x,a.y,-d)); - points.push_back(Vector3()); - - } - - - } - - points.push_back(Vector3(0,0,-r)); - points.push_back(Vector3()); - - add_lines(points,SpatialEditorGizmos::singleton->light_material); - - Vector handles; - handles.push_back(Vector3(0,0,-r)); - - Vector collision_segments; - - for(int i=0;i<64;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))*w; - Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*w; - - collision_segments.push_back(Vector3(a.x,a.y,-d)); - collision_segments.push_back(Vector3(b.x,b.y,-d)); - - if (i%16==0) { - - collision_segments.push_back(Vector3(a.x,a.y,-d)); - collision_segments.push_back(Vector3()); - - } - - if (i==16) { - - handles.push_back(Vector3(a.x,a.y,-d)); - } - - } - - collision_segments.push_back(Vector3(0,0,-r)); - collision_segments.push_back(Vector3()); - - - add_handles(handles); - add_collision_segments(collision_segments); - add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_omni_icon,0.05); - - } - -} - -LightSpatialGizmo::LightSpatialGizmo(Light* p_light){ - - light=p_light; - set_spatial_node(p_light); - -} - -////// - -String CameraSpatialGizmo::get_handle_name(int p_idx) const { - - if (camera->get_projection()==Camera::PROJECTION_PERSPECTIVE) { - return "FOV"; - } else { - return "Size"; - } -} -Variant CameraSpatialGizmo::get_handle_value(int p_idx) const{ - - if (camera->get_projection()==Camera::PROJECTION_PERSPECTIVE) { - return camera->get_fov(); - } else { - - return camera->get_size(); - } -} -void CameraSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){ - - Transform gt = camera->get_global_transform(); - gt.orthonormalize(); - Transform gi = gt.affine_inverse(); - - Vector3 ray_from = p_camera->project_ray_origin(p_point); - Vector3 ray_dir = p_camera->project_ray_normal(p_point); - - Vector3 s[2]={gi.xform(ray_from),gi.xform(ray_from+ray_dir*4096)}; - - if (camera->get_projection()==Camera::PROJECTION_PERSPECTIVE) { - Transform gt=camera->get_global_transform(); - float a = _find_closest_angle_to_half_pi_arc(s[0],s[1],1.0,gt); - camera->set("fov",a); - } else { - - Vector3 ra,rb; - Geometry::get_closest_points_between_segments(Vector3(0,0,-1),Vector3(4096,0,-1),s[0],s[1],ra,rb); - float d = ra.x * 2.0; - if (d<0) - d=0; - - camera->set("size",d); - } - -} -void CameraSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ - - if (camera->get_projection()==Camera::PROJECTION_PERSPECTIVE) { - - if (p_cancel) { - - camera->set("fov",p_restore); - } else { - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action("Change Camera FOV"); - ur->add_do_property(camera,"fov",camera->get_fov()); - ur->add_undo_property(camera,"fov",p_restore); - ur->commit_action(); - } - - } else { - - if (p_cancel) { - - camera->set("size",p_restore); - } else { - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action("Change Camera Size"); - ur->add_do_property(camera,"size",camera->get_size()); - ur->add_undo_property(camera,"size",p_restore); - ur->commit_action(); - } - - } - -} - -void CameraSpatialGizmo::redraw(){ - - clear(); - - Vector lines; - Vector handles; - - - switch(camera->get_projection()) { - - case Camera::PROJECTION_PERSPECTIVE: { - - float fov = camera->get_fov(); - - Vector3 side=Vector3( Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)) ); - Vector3 nside=side; - nside.x=-nside.x; - Vector3 up=Vector3(0,side.x,0); - - -#define ADD_TRIANGLE( m_a, m_b, m_c)\ -{\ - lines.push_back(m_a);\ - lines.push_back(m_b);\ - lines.push_back(m_b);\ - lines.push_back(m_c);\ - lines.push_back(m_c);\ - lines.push_back(m_a);\ -} - - ADD_TRIANGLE( Vector3(), side+up, side-up ); - ADD_TRIANGLE( Vector3(), nside+up, nside-up ); - ADD_TRIANGLE( Vector3(), side+up, nside+up ); - ADD_TRIANGLE( Vector3(), side-up, nside-up ); - - handles.push_back(side); - side.x*=0.25; - nside.x*=0.25; - Vector3 tup( 0, up.y*3/2,side.z); - ADD_TRIANGLE( tup, side+up, nside+up ); - - } break; - case Camera::PROJECTION_ORTHOGONAL: { - -#define ADD_QUAD( m_a, m_b, m_c, m_d)\ -{\ - lines.push_back(m_a);\ - lines.push_back(m_b);\ - lines.push_back(m_b);\ - lines.push_back(m_c);\ - lines.push_back(m_c);\ - lines.push_back(m_d);\ - lines.push_back(m_d);\ - lines.push_back(m_a);\ -} - float size = camera->get_size(); - - float hsize=size*0.5; - Vector3 right(hsize,0,0); - Vector3 up(0,hsize,0); - Vector3 back(0,0,-1.0); - Vector3 front(0,0,0); - - ADD_QUAD( -up-right,-up+right,up+right,up-right); - ADD_QUAD( -up-right+back,-up+right+back,up+right+back,up-right+back); - ADD_QUAD( up+right,up+right+back,up-right+back,up-right); - ADD_QUAD( -up+right,-up+right+back,-up-right+back,-up-right); - handles.push_back(right+back); - - right.x*=0.25; - Vector3 tup( 0, up.y*3/2,back.z ); - ADD_TRIANGLE( tup, right+up+back, -right+up+back ); - - } break; - - } - - add_lines(lines,SpatialEditorGizmos::singleton->camera_material); - add_collision_segments(lines); - add_handles(handles); -} - - -CameraSpatialGizmo::CameraSpatialGizmo(Camera* p_camera){ - - camera=p_camera; - set_spatial_node(camera); -} - - - - -////// - -void MeshInstanceSpatialGizmo::redraw() { - - 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); -} - -MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance* p_mesh) { - - mesh=p_mesh; - set_spatial_node(p_mesh); -} - -///// - - -void Position3DSpatialGizmo::redraw() { - - clear(); - add_mesh(SpatialEditorGizmos::singleton->pos3d_mesh); - Vector cursor_points; - 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)); - add_collision_segments(cursor_points); - -} - - -Position3DSpatialGizmo::Position3DSpatialGizmo(Position3D* p_p3d) { - - p3d=p_p3d; - set_spatial_node(p3d); -} - - -///// - -void SkeletonSpatialGizmo::redraw() { - - clear(); - - Ref surface_tool( memnew( SurfaceTool )); - - - surface_tool->begin(Mesh::PRIMITIVE_LINES); - surface_tool->set_material(SpatialEditorGizmos::singleton->skeleton_material); - Vector grests; - grests.resize(skel->get_bone_count()); - - Vector bones; - Vector weights; - bones.resize(4); - weights.resize(4); - - for(int i=0;i<4;i++) { - bones[i]=0; - weights[i]=0; - } - - weights[0]=1; - - - AABB aabb; - - Color bonecolor = Color(1.0,0.4,0.4,0.3); - Color rootcolor = Color(0.4,1.0,0.4,0.1); - - for (int i=0;iget_bone_count();i++) { - - int parent = skel->get_bone_parent(i); - - if (parent>=0) { - grests[i]=grests[parent] * skel->get_bone_rest(i); - - Vector3 v0 = grests[parent].origin; - Vector3 v1 = grests[i].origin; - Vector3 d = (v1-v0).normalized(); - float dist = v0.distance_to(v1); - - //find closest axis - int closest=-1; - float closest_d = 0.0; - - for(int j=0;j<3;j++) { - float dp = Math::abs(grests[parent].basis[j].normalized().dot(d)); - if (j==0 || dp>closest_d) - closest=j; - } - - //find closest other - Vector3 first; - Vector3 points[4]; - int pointidx=0; - for(int j=0;j<3;j++) { - - bones[0]=parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(rootcolor); - surface_tool->add_vertex(v0-grests[parent].basis[j].normalized()*dist*0.05); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(rootcolor); - surface_tool->add_vertex(v0+grests[parent].basis[j].normalized()*dist*0.05); - - if (j==closest) - continue; - - Vector3 axis; - if (first==Vector3()) { - axis = d.cross(d.cross(grests[parent].basis[j])).normalized(); - first=axis; - } else { - axis = d.cross(first).normalized(); - } - - for(int k=0;k<2;k++) { - - if (k==1) - axis=-axis; - Vector3 point = v0+d*dist*0.2; - point+=axis*dist*0.1; - - - bones[0]=parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); - surface_tool->add_vertex(v0); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); - surface_tool->add_vertex(point); - - bones[0]=parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); - surface_tool->add_vertex(point); - bones[0]=i; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); - surface_tool->add_vertex(v1); - points[pointidx++]=point; - - } - - } - - SWAP( points[1],points[2] ); - for(int j=0;j<4;j++) { - - - bones[0]=parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); - surface_tool->add_vertex(points[j]); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); - surface_tool->add_vertex(points[(j+1)%4]); - } - - -/* - bones[0]=parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(Color(0.4,1,0.4,0.4)); - surface_tool->add_vertex(v0); - bones[0]=i; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(Color(0.4,1,0.4,0.4)); - surface_tool->add_vertex(v1); -*/ - } else { - - grests[i]=skel->get_bone_rest(i); - bones[0]=i; - } -/* - Transform t = grests[i]; - t.orthonormalize(); - - 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]*(i>=3?-1:1); - else - face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); - } - } - - for(int j=0;j<4;j++) { - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(Color(1.0,0.4,0.4,0.4)); - surface_tool->add_vertex(t.xform(face_points[j]*0.04)); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(Color(1.0,0.4,0.4,0.4)); - surface_tool->add_vertex(t.xform(face_points[(j+1)%4]*0.04)); - } - - } - */ - } - - Ref m = surface_tool->commit(); - add_mesh(m,false,skel->get_skeleton()); - -} - -SkeletonSpatialGizmo::SkeletonSpatialGizmo(Skeleton* p_skel) { - - skel=p_skel; - set_spatial_node(p_skel); -} - -///// - - -void SpatialPlayerSpatialGizmo::redraw() { - - clear(); - if (splayer->cast_to()) { - - add_unscaled_billboard(SpatialEditorGizmos::singleton->stream_player_icon,0.05); - - } else if (splayer->cast_to()) { - - add_unscaled_billboard(SpatialEditorGizmos::singleton->sample_player_icon,0.05); - - } - -} - -SpatialPlayerSpatialGizmo::SpatialPlayerSpatialGizmo(SpatialPlayer* p_splayer){ - - set_spatial_node(p_splayer); - splayer=p_splayer; -} - - -///// - - -void RoomSpatialGizmo::redraw() { - - clear(); - Ref roomie = room->get_room(); - if (roomie.is_null()) - return; - DVector faces = roomie->get_geometry_hint(); - - Vector lines; - int fc=faces.size(); - DVector::Read r =faces.read(); - - Map<_EdgeKey,Vector3> edge_map; - - for(int i=0;i::Element *E=edge_map.find(ek); - - if (E) { - - if (E->get().dot(fn) >0.9) { - - E->get()=Vector3(); - } - - } else { - - 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); - } - } - - add_lines(lines,SpatialEditorGizmos::singleton->room_material); - add_collision_segments(lines); - -} - -RoomSpatialGizmo::RoomSpatialGizmo(Room* p_room){ - - set_spatial_node(p_room); - room=p_room; -} - -///// - - -void PortalSpatialGizmo::redraw() { - - clear(); - - Vector points = portal->get_shape(); - if (points.size()==0) { - return; - } - - Vector lines; - - Vector3 center; - for(int i=0;iportal_material); - add_collision_segments(lines); - -} - -PortalSpatialGizmo::PortalSpatialGizmo(Portal* p_portal){ - - set_spatial_node(p_portal); - portal=p_portal; -} - -///// - - -void RayCastSpatialGizmo::redraw() { - - clear(); - - - Vector lines; - - lines.push_back(Vector3()); - lines.push_back(raycast->get_cast_to()); - - add_lines(lines,SpatialEditorGizmos::singleton->raycast_material); - add_collision_segments(lines); - -} - -RayCastSpatialGizmo::RayCastSpatialGizmo(RayCast* p_raycast){ - - set_spatial_node(p_raycast); - raycast=p_raycast; -} - - - -///// - - -void VehicleWheelSpatialGizmo::redraw() { - - clear(); - - - Vector points; - - float r = car_wheel->get_radius(); - const int skip=10; - for(int i=0;i<=360;i+=skip) { - - float ra=Math::deg2rad(i); - float rb=Math::deg2rad(i+skip); - Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*r; - Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*r; - - points.push_back(Vector3(0,a.x,a.y)); - points.push_back(Vector3(0,b.x,b.y)); - - const int springsec=4; - - for(int j=0;jget_suspension_rest_length()*5; - points.push_back(Vector3(a.x,i/360.0*t/springsec+j*(t/springsec),a.y)*0.2); - points.push_back(Vector3(b.x,(i+skip)/360.0*t/springsec+j*(t/springsec),b.y)*0.2); - } - - - } - - //travel - points.push_back(Vector3(0,0,0)); - points.push_back(Vector3(0,car_wheel->get_suspension_rest_length(),0)); - - //axis - points.push_back(Vector3(r*0.2,car_wheel->get_suspension_rest_length(),0)); - points.push_back(Vector3(-r*0.2,car_wheel->get_suspension_rest_length(),0)); - //axis - points.push_back(Vector3(r*0.2,0,0)); - points.push_back(Vector3(-r*0.2,0,0)); - - //forward line - points.push_back(Vector3(0,-r,0)); - points.push_back(Vector3(0,-r,r*2)); - points.push_back(Vector3(0,-r,r*2)); - points.push_back(Vector3(r*2*0.2,-r,r*2*0.8)); - points.push_back(Vector3(0,-r,r*2)); - points.push_back(Vector3(-r*2*0.2,-r,r*2*0.8)); - - add_lines(points,SpatialEditorGizmos::singleton->car_wheel_material); - add_collision_segments(points); - -} - -VehicleWheelSpatialGizmo::VehicleWheelSpatialGizmo(VehicleWheel* p_car_wheel){ - - set_spatial_node(p_car_wheel); - car_wheel=p_car_wheel; -} - - - -/// - -void TestCubeSpatialGizmo::redraw() { - - clear(); - add_collision_triangles(SpatialEditorGizmos::singleton->test_cube_tm); -} - -TestCubeSpatialGizmo::TestCubeSpatialGizmo(TestCube* p_tc) { - - tc=p_tc; - set_spatial_node(p_tc); -} - - -/////////// - - - - - - -String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const { - - Ref s = cs->get_shape(); - if (s.is_null()) - return ""; - - if (s->cast_to()) { - - return "Radius"; - } - - if (s->cast_to()) { - - return "Extents"; - } - - if (s->cast_to()) { - - return p_idx==0?"Radius":"Height"; - } - - if (s->cast_to()) { - - return "Length"; - } - - return ""; -} -Variant CollisionShapeSpatialGizmo::get_handle_value(int p_idx) const{ - - Ref s = cs->get_shape(); - if (s.is_null()) - return Variant(); - - if (s->cast_to()) { - - Ref ss = s; - return ss->get_radius(); - } - - if (s->cast_to()) { - - Ref bs = s; - return bs->get_extents(); - } - - if (s->cast_to()) { - - Ref cs = s; - return p_idx==0?cs->get_radius():cs->get_height(); - } - - if (s->cast_to()) { - - Ref cs = s; - return cs->get_length(); - } - - return Variant(); -} -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(); - - 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)}; - - if (s->cast_to()) { - - 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); - } - - if (s->cast_to()) { - - 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; - - rs->set_length(d); - } - - - if (s->cast_to()) { - - 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 (s->cast_to()) { - - 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); - - } - -} -void CollisionShapeSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ - Ref s = cs->get_shape(); - if (s.is_null()) - return; - - if (s->cast_to()) { - - Ref ss=s; - if (p_cancel) { - ss->set_radius(p_restore); - return; - } - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action("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(); - - } - - if (s->cast_to()) { - - Ref ss=s; - if (p_cancel) { - ss->set_extents(p_restore); - return; - } - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action("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(); - } - - if (s->cast_to()) { - - Ref ss=s; - if (p_cancel) { - if (p_idx==0) - ss->set_radius(p_restore); - else - ss->set_height(p_restore); - return; - } - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - if (p_idx==0) { - ur->create_action("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("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); - - } - - ur->commit_action(); - - } - - if (s->cast_to()) { - - Ref ss=s; - if (p_cancel) { - ss->set_length(p_restore); - return; - } - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action("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 CollisionShapeSpatialGizmo::redraw(){ - - clear(); - - Ref s = cs->get_shape(); - if (s.is_null()) - return; - - if (s->cast_to()) { - - Ref sp= s; - float r=sp->get_radius(); - - Vector points; - - for(int i=0;i<=360;i++) { - - float ra=Math::deg2rad(i); - float rb=Math::deg2rad(i+1); - Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*r; - Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*r; - - 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)); - - } - - Vector collision_segments; - - for(int i=0;i<64;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; - - 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)); - } - - add_lines(points,SpatialEditorGizmos::singleton->shape_material); - add_collision_segments(collision_segments); - Vector handles; - handles.push_back(Vector3(r,0,0)); - add_handles(handles); - - } - - if (s->cast_to()) { - - Ref bs=s; - Vector lines; - AABB aabb; - aabb.pos=-bs->get_extents(); - aabb.size=aabb.pos*-2; - - 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++) { - - Vector3 ax; - ax[i]=bs->get_extents()[i]; - handles.push_back(ax); - } - - add_lines(lines,SpatialEditorGizmos::singleton->shape_material); - add_collision_segments(lines); - add_handles(handles); - - } - - if (s->cast_to()) { - - Ref cs=s; - float radius = cs->get_radius(); - float height = cs->get_height(); - - - Vector points; - - Vector3 d(0,0,height*0.5); - for(int i=0;i<360;i++) { - - float ra=Math::deg2rad(i); - float rb=Math::deg2rad(i+1); - Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*radius; - Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*radius; - - points.push_back(Vector3(a.x,a.y,0)+d); - points.push_back(Vector3(b.x,b.y,0)+d); - - points.push_back(Vector3(a.x,a.y,0)-d); - points.push_back(Vector3(b.x,b.y,0)-d); - - if (i%90==0) { - - points.push_back(Vector3(a.x,a.y,0)+d); - points.push_back(Vector3(a.x,a.y,0)-d); - } - - Vector3 dud = i<180?d:-d; - - 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); - - } - - add_lines(points,SpatialEditorGizmos::singleton->shape_material); - - Vector collision_segments; - - for(int i=0;i<64;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))*radius; - Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*radius; - - collision_segments.push_back(Vector3(a.x,a.y,0)+d); - collision_segments.push_back(Vector3(b.x,b.y,0)+d); - - collision_segments.push_back(Vector3(a.x,a.y,0)-d); - collision_segments.push_back(Vector3(b.x,b.y,0)-d); - - if (i%16==0) { - - collision_segments.push_back(Vector3(a.x,a.y,0)+d); - collision_segments.push_back(Vector3(a.x,a.y,0)-d); - } - - Vector3 dud = i<32?d:-d; - - 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); - - } - - add_collision_segments(collision_segments); - - 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); - - - } - - if (s->cast_to()) { - - Ref ps=s; - Plane p = ps->get_plane(); - Vector points; - - Vector3 n1 = p.get_any_perpendicular_normal(); - Vector3 n2 = p.normal.cross(n1).normalized(); - - 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, - }; - - 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); - - add_lines(points,SpatialEditorGizmos::singleton->shape_material); - add_collision_segments(points); - - } - - - if (s->cast_to()) { - - DVector points = s->cast_to()->get_points(); - - if (points.size()>3) { - - 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;ishape_material); - add_collision_segments(points); - - } - } - - } - - - if (s->cast_to()) { - - Ref rs=s; - - Vector points; - points.push_back(Vector3()); - points.push_back(Vector3(0,0,rs->get_length())); - add_lines(points,SpatialEditorGizmos::singleton->shape_material); - add_collision_segments(points); - Vector handles; - handles.push_back(Vector3(0,0,rs->get_length())); - add_handles(handles); - - - } - -} -CollisionShapeSpatialGizmo::CollisionShapeSpatialGizmo(CollisionShape* p_cs) { - - cs=p_cs; - set_spatial_node(p_cs); -} - - - -///// - - -void CollisionPolygonSpatialGizmo::redraw() { - - clear(); - - Vector points = polygon->get_polygon(); - float depth = polygon->get_depth()*0.5; - - Vector lines; - for(int i=0;ishape_material); - add_collision_segments(lines); -} - -CollisionPolygonSpatialGizmo::CollisionPolygonSpatialGizmo(CollisionPolygon* p_polygon){ - - set_spatial_node(p_polygon); - polygon=p_polygon; -} -/// - - -String VisibilityNotifierGizmo::get_handle_name(int p_idx) const { - - switch(p_idx) { - case 0: return "X"; - case 1: return "Y"; - case 2: return "Z"; - } - - return ""; -} -Variant VisibilityNotifierGizmo::get_handle_value(int p_idx) const{ - - return notifier->get_aabb(); -} -void VisibilityNotifierGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){ - - - Transform gt = notifier->get_global_transform(); - //gt.orthonormalize(); - Transform gi = gt.affine_inverse(); - - 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); - - Vector3 sg[2]={gi.xform(ray_from),gi.xform(ray_from+ray_dir*4096)}; - Vector3 ofs = aabb.pos+aabb.size*0.5;; - - 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); - float d = ra[p_idx]; - if (d<0.001) - d=0.001; - - Vector3 he = aabb.size; - aabb.pos[p_idx]=(aabb.pos[p_idx]+aabb.size[p_idx]*0.5)-d; - aabb.size[p_idx]=d*2; - notifier->set_aabb(aabb); -} - -void VisibilityNotifierGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ - - - if (p_cancel) { - notifier->set_aabb(p_restore); - return; - } - - UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); - ur->create_action("Change Notifier Extents"); - ur->add_do_method(notifier,"set_aabb",notifier->get_aabb()); - ur->add_undo_method(notifier,"set_aabb",p_restore); - ur->commit_action(); - -} - -void VisibilityNotifierGizmo::redraw(){ - - clear(); - - Vector lines; - AABB aabb = notifier->get_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); - } - - Vector handles; - - - for(int i=0;i<3;i++) { - - Vector3 ax; - ax[i]=aabb.pos[i]+aabb.size[i]; - handles.push_back(ax); - } - - add_lines(lines,SpatialEditorGizmos::singleton->visibility_notifier_material); - //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05); - add_collision_segments(lines); - add_handles(handles); - -} -VisibilityNotifierGizmo::VisibilityNotifierGizmo(VisibilityNotifier* p_notifier){ - - notifier=p_notifier; - set_spatial_node(p_notifier); -} - -//////// - - - -void NavigationMeshSpatialGizmo::redraw() { - - clear(); - Ref navmeshie = navmesh->get_navigation_mesh(); - if (navmeshie.is_null()) - return; - - DVector vertices = navmeshie->get_vertices(); - DVector::Read vr=vertices.read(); - List faces; - for(int i=0;iget_polygon_count();i++) { - Vector p = navmeshie->get_polygon(i); - - for(int j=2;j edge_map; - DVector tmeshfaces; - tmeshfaces.resize(faces.size()*3); - - { - DVector::Write tw=tmeshfaces.write(); - int tidx=0; - - - for(List::Element *E=faces.front();E;E=E->next()) { - - const Face3 &f = E->get(); - - for(int j=0;j<3;j++) { - - tw[tidx++]=f.vertex[j]; - _EdgeKey ek; - ek.from=f.vertex[j].snapped(CMP_EPSILON); - ek.to=f.vertex[(j+1)%3].snapped(CMP_EPSILON); - if (ek.from::Element *E=edge_map.find(ek); - - if (E) { - - E->get()=false; - - } else { - - edge_map[ek]=true; - } - - } - } - } - Vector lines; - - for(Map<_EdgeKey,bool>::Element *E=edge_map.front();E;E=E->next()) { - - if (E->get()) { - lines.push_back(E->key().from); - lines.push_back(E->key().to); - } - } - - Ref tmesh = memnew( TriangleMesh); - tmesh->create(tmeshfaces); - - if (lines.size()) - add_lines(lines,navmesh->is_enabled()?SpatialEditorGizmos::singleton->navmesh_edge_material:SpatialEditorGizmos::singleton->navmesh_edge_material_disabled); - add_collision_triangles(tmesh); - Ref m = memnew( Mesh ); - Array a; - a.resize(Mesh::ARRAY_MAX); - a[0]=tmeshfaces; - m->add_surface(Mesh::PRIMITIVE_TRIANGLES,a); - m->surface_set_material(0,navmesh->is_enabled()?SpatialEditorGizmos::singleton->navmesh_solid_material:SpatialEditorGizmos::singleton->navmesh_solid_material_disabled); - add_mesh(m); - add_collision_segments(lines); - -} - -NavigationMeshSpatialGizmo::NavigationMeshSpatialGizmo(NavigationMeshInstance *p_navmesh){ - - set_spatial_node(p_navmesh); - navmesh=p_navmesh; -} - -////// -/// -/// - - - -void PinJointSpatialGizmo::redraw() { - - clear(); - Vector cursor_points; - 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)); - add_collision_segments(cursor_points); - add_lines(cursor_points,SpatialEditorGizmos::singleton->joint_material); - -} - - -PinJointSpatialGizmo::PinJointSpatialGizmo(PinJoint* p_p3d) { - - p3d=p_p3d; - set_spatial_node(p3d); -} - -//// - -void HingeJointSpatialGizmo::redraw() { - - clear(); - Vector cursor_points; - 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*2)); - cursor_points.push_back(Vector3(0,0,-cs*2)); - - float ll = p3d->get_param(HingeJoint::PARAM_LIMIT_LOWER); - float ul = p3d->get_param(HingeJoint::PARAM_LIMIT_UPPER); - - if (p3d->get_flag(HingeJoint::FLAG_USE_LIMIT) && lljoint_material); - -} - - -HingeJointSpatialGizmo::HingeJointSpatialGizmo(HingeJoint* p_p3d) { - - p3d=p_p3d; - set_spatial_node(p3d); -} - -/////// -/// -//// - -void SliderJointSpatialGizmo::redraw() { - - clear(); - Vector cursor_points; - 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*2)); - cursor_points.push_back(Vector3(0,0,-cs*2)); - - float ll = p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_LOWER); - float ul = p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_UPPER); - float lll = -p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_LOWER); - float lul = -p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_UPPER); - - if (lll>lul) { - - cursor_points.push_back(Vector3(lul,0,0)); - cursor_points.push_back(Vector3(lll,0,0)); - - cursor_points.push_back(Vector3(lul,-cs,-cs)); - cursor_points.push_back(Vector3(lul,-cs,cs)); - cursor_points.push_back(Vector3(lul,-cs,cs)); - cursor_points.push_back(Vector3(lul,cs,cs)); - cursor_points.push_back(Vector3(lul,cs,cs)); - cursor_points.push_back(Vector3(lul,cs,-cs)); - cursor_points.push_back(Vector3(lul,cs,-cs)); - cursor_points.push_back(Vector3(lul,-cs,-cs)); - - - cursor_points.push_back(Vector3(lll,-cs,-cs)); - cursor_points.push_back(Vector3(lll,-cs,cs)); - cursor_points.push_back(Vector3(lll,-cs,cs)); - cursor_points.push_back(Vector3(lll,cs,cs)); - cursor_points.push_back(Vector3(lll,cs,cs)); - cursor_points.push_back(Vector3(lll,cs,-cs)); - cursor_points.push_back(Vector3(lll,cs,-cs)); - cursor_points.push_back(Vector3(lll,-cs,-cs)); - - - } else { - - cursor_points.push_back(Vector3(+cs*2,0,0)); - cursor_points.push_back(Vector3(-cs*2,0,0)); - - } - - if (lljoint_material); - -} - - -SliderJointSpatialGizmo::SliderJointSpatialGizmo(SliderJoint* p_p3d) { - - p3d=p_p3d; - set_spatial_node(p3d); -} - -/////// -/// -//// - -void ConeTwistJointSpatialGizmo::redraw() { - - clear(); - float cs = 0.25; - Vector points; - - float r = 1.0; - float w = r*Math::sin(p3d->get_param(ConeTwistJoint::PARAM_SWING_SPAN)); - float d = r*Math::cos(p3d->get_param(ConeTwistJoint::PARAM_SWING_SPAN)); - - - //swing - for(int i=0;i<360;i+=10) { - - float ra=Math::deg2rad(i); - float rb=Math::deg2rad(i+10); - Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*w; - Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*w; - - /*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(d,a.x,a.y)); - points.push_back(Vector3(d,b.x,b.y)); - - if (i%90==0) { - - points.push_back(Vector3(d,a.x,a.y)); - points.push_back(Vector3()); - - } - } - - points.push_back(Vector3()); - points.push_back(Vector3(1,0,0)); - - //twist - /* - */ - float ts=Math::rad2deg(p3d->get_param(ConeTwistJoint::PARAM_TWIST_SPAN)); - ts=MIN(ts,720); - - - for(int i=0;ijoint_material); - -} - - -ConeTwistJointSpatialGizmo::ConeTwistJointSpatialGizmo(ConeTwistJoint* p_p3d) { - - p3d=p_p3d; - set_spatial_node(p3d); -} - -//////// -/// \brief SpatialEditorGizmos::singleton -/// -/////// -/// -//// - -void Generic6DOFJointSpatialGizmo::redraw() { - - clear(); - Vector cursor_points; - float cs = 0.25; - - for(int ax=0;ax<3;ax++) { - /*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*2)); - cursor_points.push_back(Vector3(0,0,-cs*2)); */ - - float ll; - float ul; - float lll; - float lul; - - int a1,a2,a3; - bool enable_ang; - bool enable_lin; - - switch(ax) { - case 0: - ll = p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT); - ul = p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT); - lll = -p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT); - lul = -p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT); - enable_ang = p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT); - enable_lin = p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT); - a1=0; - a2=1; - a3=2; - break; - case 1: - ll = p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT); - ul = p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT); - lll = -p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT); - lul = -p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT); - enable_ang = p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT); - enable_lin = p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT); - a1=2; - a2=0; - a3=1; - break; - case 2: - ll = p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT); - ul = p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT); - lll = -p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT); - lul = -p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT); - enable_ang = p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT); - enable_lin = p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT); - - a1=1; - a2=2; - a3=0; - break; - } - -#define ADD_VTX(x,y,z)\ - {\ - Vector3 v;\ - v[a1]=(x);\ - v[a2]=(y);\ - v[a3]=(z);\ - cursor_points.push_back(v);\ - } - -#define SET_VTX(what,x,y,z)\ - {\ - Vector3 v;\ - v[a1]=(x);\ - v[a2]=(y);\ - v[a3]=(z);\ - what=v;\ - } - - - - - if (enable_lin && lll>=lul) { - - ADD_VTX(lul,0,0); - ADD_VTX(lll,0,0); - - ADD_VTX(lul,-cs,-cs); - ADD_VTX(lul,-cs,cs); - ADD_VTX(lul,-cs,cs); - ADD_VTX(lul,cs,cs); - ADD_VTX(lul,cs,cs); - ADD_VTX(lul,cs,-cs); - ADD_VTX(lul,cs,-cs); - ADD_VTX(lul,-cs,-cs); - - - ADD_VTX(lll,-cs,-cs); - ADD_VTX(lll,-cs,cs); - ADD_VTX(lll,-cs,cs); - ADD_VTX(lll,cs,cs); - ADD_VTX(lll,cs,cs); - ADD_VTX(lll,cs,-cs); - ADD_VTX(lll,cs,-cs); - ADD_VTX(lll,-cs,-cs); - - - } else { - - ADD_VTX(+cs*2,0,0); - ADD_VTX(-cs*2,0,0); - - } - - if (enable_ang && ll<=ul) { - - const int points = 32; - float step = (ul-ll)/points; - - - for(int i=0;ijoint_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 (p_spatial->cast_to()) { - - Ref lsg = memnew( LightSpatialGizmo(p_spatial->cast_to()) ); - return lsg; - } - - if (p_spatial->cast_to()) { - - Ref lsg = memnew( CameraSpatialGizmo(p_spatial->cast_to()) ); - return lsg; - } - - if (p_spatial->cast_to()) { - - Ref lsg = memnew( SkeletonSpatialGizmo(p_spatial->cast_to()) ); - return lsg; - } - - - if (p_spatial->cast_to()) { - - Ref lsg = memnew( Position3DSpatialGizmo(p_spatial->cast_to()) ); - return lsg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( MeshInstanceSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( RoomSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( NavigationMeshSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( RayCastSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( PortalSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - - if (p_spatial->cast_to()) { - - Ref misg = memnew( TestCubeSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( SpatialPlayerSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( CollisionShapeSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( VisibilityNotifierGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( VehicleWheelSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - if (p_spatial->cast_to()) { - - Ref misg = memnew( PinJointSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( HingeJointSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( SliderJointSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( ConeTwistJointSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( Generic6DOFJointSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - if (p_spatial->cast_to()) { - - Ref misg = memnew( CollisionPolygonSpatialGizmo(p_spatial->cast_to()) ); - return misg; - } - - - return Ref(); -} - - -Ref SpatialEditorGizmos::create_line_material(const Color& p_base_color) { - - Ref line_material = Ref( memnew( FixedMaterial )); - line_material->set_flag(Material::FLAG_UNSHADED, true); - line_material->set_line_width(3.0); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); - line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,p_base_color); - - return line_material; - -} - -Ref SpatialEditorGizmos::create_solid_material(const Color& p_base_color) { - - Ref line_material = Ref( memnew( FixedMaterial )); - line_material->set_flag(Material::FLAG_UNSHADED, true); - line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,p_base_color); - - return line_material; - -} - -SpatialEditorGizmos::SpatialEditorGizmos() { - - singleton=this; - - handle_material = Ref( memnew( FixedMaterial )); - handle_material->set_flag(Material::FLAG_UNSHADED, true); - handle_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.8)); - - handle2_material = Ref( memnew( FixedMaterial )); - handle2_material->set_flag(Material::FLAG_UNSHADED, true); - handle2_material->set_fixed_flag(FixedMaterial::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(FixedMaterial::PARAM_DIFFUSE,handle_t); - handle2_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1)); - handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); - - light_material = create_line_material(Color(1,1,0.2)); - - light_material_omni_icon = Ref( memnew( FixedMaterial )); - light_material_omni_icon->set_flag(Material::FLAG_UNSHADED, true); - light_material_omni_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - light_material_omni_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - light_material_omni_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - light_material_omni_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); - light_material_omni_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoLight","EditorIcons")); - - - light_material_directional_icon = Ref( memnew( FixedMaterial )); - light_material_directional_icon->set_flag(Material::FLAG_UNSHADED, true); - light_material_directional_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - light_material_directional_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - light_material_directional_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - light_material_directional_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); - light_material_directional_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight","EditorIcons")); - - 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_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, false); - navmesh_solid_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); - - 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_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, false); - navmesh_solid_material_disabled->set_flag(Material::FLAG_DOUBLE_SIDED,true); - - skeleton_material = create_line_material(Color(0.6,1.0,0.3)); - skeleton_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); - skeleton_material->set_flag(Material::FLAG_UNSHADED,true); - skeleton_material->set_flag(Material::FLAG_ONTOP,true); - skeleton_material->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - - //position 3D Shared mesh - - pos3d_mesh = Ref( memnew( Mesh ) ); - { - - DVector cursor_points; - DVector 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( FixedMaterial ); - mat->set_flag(Material::FLAG_UNSHADED,true); - mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true); - mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,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(Mesh::PRIMITIVE_LINES,d); - pos3d_mesh->surface_set_material(0,mat); - } - - - sample_player_icon = Ref( memnew( FixedMaterial )); - sample_player_icon->set_flag(Material::FLAG_UNSHADED, true); - sample_player_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - sample_player_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - sample_player_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - sample_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); - sample_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer","EditorIcons")); - - 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)); - joint_material = create_line_material(Color(0.6,0.8,1.0)); - - stream_player_icon = Ref( memnew( FixedMaterial )); - stream_player_icon->set_flag(Material::FLAG_UNSHADED, true); - stream_player_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - stream_player_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - stream_player_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - stream_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); - stream_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer","EditorIcons")); - - visibility_notifier_icon = Ref( memnew( FixedMaterial )); - visibility_notifier_icon->set_flag(Material::FLAG_UNSHADED, true); - visibility_notifier_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); - visibility_notifier_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - visibility_notifier_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); - visibility_notifier_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); - visibility_notifier_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("Visible","EditorIcons")); - - { - - DVector 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]*(i>=3?-1:1); - else - face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); - } - } - //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)); - - -} - +/*************************************************************************/ +/* spatial_editor_gizmos.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "spatial_editor_gizmos.h" +#include "geometry.h" +#include "scene/3d/camera.h" +#include "scene/resources/surface_tool.h" +#include "scene/resources/sphere_shape.h" +#include "scene/resources/box_shape.h" +#include "scene/resources/capsule_shape.h" +#include "scene/resources/ray_shape.h" +#include "scene/resources/convex_polygon_shape.h" +#include "scene/resources/plane_shape.h" +#include "quick_hull.h" + +// Keep small children away from this file. +// It's so ugly it will eat them alive + +#define HANDLE_HALF_SIZE 0.05 + +void SpatialGizmoTool::clear() { + + for(int i=0;ifree(instances[i].instance); + + + } + + billboard_handle=false; + collision_segments.clear(); + collision_mesh=Ref(); + instances.clear(); + handles.clear(); + secondary_handles.clear(); +} + +void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) { + + 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()); + if (billboard) + VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_BILLBOARD,true); + if (unscaled) + VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_DEPH_SCALE,true); + if (skeleton.is_valid()) + VS::get_singleton()->instance_attach_skeleton(instance,skeleton); + if (extra_margin) + VS::get_singleton()->instance_set_extra_visibility_margin(instance,1); + VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_CAST_SHADOW,false); + VS::get_singleton()->instance_geometry_set_flag(instance,VS::INSTANCE_FLAG_RECEIVE_SHADOWS,false); + VS::get_singleton()->instance_set_layer_mask(instance,1<& p_mesh,bool p_billboard, const RID &p_skeleton) { + + ERR_FAIL_COND(!spatial_node); + Instance ins; + + ins.billboard=p_billboard; + ins.mesh=p_mesh; + ins.skeleton=p_skeleton; + if (valid) { + ins.create_instance(spatial_node); + VS::get_singleton()->instance_set_transform(ins.instance,spatial_node->get_global_transform()); + } + + instances.push_back(ins); + +} + +void SpatialGizmoTool::add_lines(const Vector &p_lines, const Ref &p_material,bool p_billboard){ + + ERR_FAIL_COND(!spatial_node); + Instance ins; + + Ref mesh = memnew( Mesh ); + Array a; + a.resize(Mesh::ARRAY_MAX); + + a[Mesh::ARRAY_VERTEX]=p_lines; + + DVector color; + color.resize(p_lines.size()); + { + DVector::Write w = color.write(); + for(int i=0;iadd_surface(Mesh::PRIMITIVE_LINES,a); + mesh->surface_set_material(0,p_material); + + if (p_billboard) { + float md=0; + for(int i=0;iset_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0)); + } + } + + ins.billboard=p_billboard; + ins.mesh=mesh; + if (valid) { + ins.create_instance(spatial_node); + VS::get_singleton()->instance_set_transform(ins.instance,spatial_node->get_global_transform()); + } + + instances.push_back(ins); + +} + +void SpatialGizmoTool::add_unscaled_billboard(const Ref& p_material,float p_scale) { + + ERR_FAIL_COND(!spatial_node); + Instance ins; + + Vector vs; + Vector uv; + + vs.push_back(Vector3(-p_scale,p_scale,0)); + vs.push_back(Vector3(p_scale,p_scale,0)); + vs.push_back(Vector3(p_scale,-p_scale,0)); + vs.push_back(Vector3(-p_scale,-p_scale,0)); + + uv.push_back(Vector2(1,0)); + uv.push_back(Vector2(0,0)); + uv.push_back(Vector2(0,1)); + uv.push_back(Vector2(1,1)); + + Ref mesh = memnew( Mesh ); + Array a; + a.resize(Mesh::ARRAY_MAX); + a[Mesh::ARRAY_VERTEX]=vs; + a[Mesh::ARRAY_TEX_UV]=uv; + mesh->add_surface(Mesh::PRIMITIVE_TRIANGLE_FAN,a); + mesh->surface_set_material(0,p_material); + + if (true) { + float md=0; + for(int i=0;iset_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0)); + } + } + + ins.mesh=mesh; + ins.unscaled=true; + ins.billboard=true; + if (valid) { + ins.create_instance(spatial_node); + VS::get_singleton()->instance_set_transform(ins.instance,spatial_node->get_global_transform()); + } + + instances.push_back(ins); + + +} + +void SpatialGizmoTool::add_collision_triangles(const Ref& p_tmesh) { + + collision_mesh=p_tmesh; +} + +void SpatialGizmoTool::add_collision_segments(const Vector &p_lines) { + + int from=collision_segments.size(); + collision_segments.resize(from+p_lines.size()); + for(int i=0;i &p_handles, bool p_billboard,bool p_secondary){ + + billboard_handle=p_billboard; + + if (!is_selected()) + return; + + ERR_FAIL_COND(!spatial_node); + + ERR_FAIL_COND(!spatial_node); + Instance ins; + + + Ref mesh = memnew( Mesh ); +#if 1 + + Array a; + a.resize(VS::ARRAY_MAX); + a[VS::ARRAY_VERTEX]=p_handles; + DVector colors; + { + colors.resize(p_handles.size()); + DVector::Write w=colors.write(); + for(int i=0;iget_over_gizmo_handle()!=i) + col=Color(0.9,0.9,0.9,0.9); + w[i]=col; + } + + } + a[VS::ARRAY_COLOR]=colors; + mesh->add_surface(Mesh::PRIMITIVE_POINTS,a); + mesh->surface_set_material(0,SpatialEditorGizmos::singleton->handle2_material); + + if (p_billboard) { + float md=0; + for(int i=0;iset_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0)); + } + } + + + +#else + for(int ih=0;ih vertices; + Vector normals; + + int vtx_idx=0; +#define ADD_VTX(m_idx);\ + vertices.push_back( (face_points[m_idx]*HANDLE_HALF_SIZE+p_handles[ih]) );\ + normals.push_back( normal_points[m_idx] );\ + vtx_idx++;\ + + for (int i=0;i<6;i++) { + + + Vector3 face_points[4]; + Vector3 normal_points[4]; + float uv_points[8]={0,0,0,1,1,1,1,0}; + + 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]*(i>=3?-1:1); + else + face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); + } + normal_points[j]=Vector3(); + normal_points[j][i%3]=(i>=3?-1:1); + } + //tri 1 + ADD_VTX(0); + ADD_VTX(1); + ADD_VTX(2); + //tri 2 + ADD_VTX(2); + ADD_VTX(3); + ADD_VTX(0); + + } + + + Array d; + d.resize(VS::ARRAY_MAX); + d[VisualServer::ARRAY_NORMAL]= normals ; + d[VisualServer::ARRAY_VERTEX]= vertices ; + + mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d); + mesh->surface_set_material(ih,SpatialEditorGizmos::singleton->handle_material); + + + } +#endif + ins.mesh=mesh; + ins.billboard=p_billboard; + ins.extra_margin=true; + if (valid) { + ins.create_instance(spatial_node); + VS::get_singleton()->instance_set_transform(ins.instance,spatial_node->get_global_transform()); + } + instances.push_back(ins); + if (!p_secondary) { + int chs=handles.size(); + handles.resize(chs+p_handles.size()); + for(int i=0;i &p_frustum) { + + ERR_FAIL_COND_V(!spatial_node,false); + ERR_FAIL_COND_V(!valid,false); + + if (collision_segments.size()) { + + const Plane *p=p_frustum.ptr(); + int fc=p_frustum.size(); + + int vc=collision_segments.size(); + const Vector3* vptr=collision_segments.ptr(); + Transform t = spatial_node->get_global_transform(); + + for(int i=0;i 0 && p[j].distance_to(b) >0) { + + any_out=true; + break; + } + } + + if (!any_out) + return true; + } + + return false; + } + + return false; +} + + +bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) { + + ERR_FAIL_COND_V(!spatial_node,false); + ERR_FAIL_COND_V(!valid,false); + + if (r_gizmo_handle) { + + Transform t = spatial_node->get_global_transform(); + t.orthonormalize(); + if (billboard_handle) { + t.set_look_at(t.origin,t.origin+p_camera->get_transform().basis.get_axis(2),p_camera->get_transform().basis.get_axis(1)); + } + Transform ti=t.affine_inverse(); + + Vector3 ray_from=ti.xform(p_camera->project_ray_origin(p_point)); + Vector3 ray_dir=t.basis.xform_inv(p_camera->project_ray_normal(p_point)).normalized(); + Vector3 ray_to = ray_from+ray_dir*4096; + + float min_d=1e20; + int idx=-1; + + for(int i=0;iunproject_position(hpos); + if (p.distance_to(p_point)handle_t->get_width()*0.6) { + + + real_t dp = p_camera->get_transform().origin.distance_to(hpos); + if (dpget_transform().basis.get_axis(2); + min_d=dp; + idx=i+handles.size(); + + } + + } + +#else + AABB aabb; + aabb.pos=Vector3(-1,-1,-1)*HANDLE_HALF_SIZE; + aabb.size=aabb.pos*-2; + aabb.pos+=secondary_handles[i]; + + + Vector3 rpos,rnorm; + + if (aabb.intersects_segment(ray_from,ray_to,&rpos,&rnorm)) { + + real_t dp = ray_dir.dot(rpos); + if (dpunproject_position(hpos); + if (p.distance_to(p_point)handle_t->get_width()*0.6) { + + + real_t dp = p_camera->get_transform().origin.distance_to(hpos); + if (dpget_transform().basis.get_axis(2); + min_d=dp; + idx=i; + + } + + } + +#else + + AABB aabb; + aabb.pos=Vector3(-1,-1,-1)*HANDLE_HALF_SIZE; + aabb.size=aabb.pos*-2; + aabb.pos+=handles[i]; + + + Vector3 rpos,rnorm; + + if (aabb.intersects_segment(ray_from,ray_to,&rpos,&rnorm)) { + + real_t dp = ray_dir.dot(rpos); + if (dp=0) { + *r_gizmo_handle=idx; + return true; + } + + + } + + if (collision_segments.size()) { + + Plane camp(p_camera->get_transform().origin,(-p_camera->get_transform().basis.get_axis(2)).normalized()); + + int vc=collision_segments.size(); + const Vector3* vptr=collision_segments.ptr(); + Transform t = spatial_node->get_global_transform(); + if (billboard_handle) { + t.set_look_at(t.origin,t.origin+p_camera->get_transform().basis.get_axis(2),p_camera->get_transform().basis.get_axis(1)); + } + + Vector3 cp; + float cpd=1e20; + + for(int i=0;iunproject_position(a); + s[1] = p_camera->unproject_position(b); + + + Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point,s); + + float pd = p.distance_to(p_point); + + if (pd0) { + + float d2=s[0].distance_to(p)/d; + tcp = a+(b-a)*d2; + + } else { + tcp=a; + + } + + if (camp.distance_to(tcp)get_znear()) + continue; + cp=tcp; + cpd=pd; + } + } + + if (cpd<8) { + + r_pos=cp; + r_normal=-p_camera->project_ray_normal(p_point); + return true; + } + + return false; + } + + + if (collision_mesh.is_valid()) { + Transform gt = spatial_node->get_global_transform(); + + if (billboard_handle) { + gt.set_look_at(gt.origin,gt.origin+p_camera->get_transform().basis.get_axis(2),p_camera->get_transform().basis.get_axis(1)); + } + + Transform ai=gt.affine_inverse(); + Vector3 ray_from = ai.xform(p_camera->project_ray_origin(p_point)); + Vector3 ray_dir=ai.basis.xform(p_camera->project_ray_normal(p_point)).normalized(); + Vector3 rpos,rnorm; + +#if 1 + + + + if (collision_mesh->intersect_ray(ray_from,ray_dir,rpos,rnorm)) { + + r_pos=gt.xform(rpos); + r_normal=gt.basis.xform(rnorm).normalized(); + return true; + } +#else + + if (collision_mesh->intersect_segment(ray_from,ray_from+ray_dir*4906.0,rpos,rnorm)) { + + r_pos=gt.xform(rpos); + r_normal=gt.basis.xform(rnorm).normalized(); + return true; + } + +#endif + } + + return false; + +} + + + +void SpatialGizmoTool::create() { + + ERR_FAIL_COND(!spatial_node); + ERR_FAIL_COND(valid); + valid=true; + + for(int i=0;iinstance_set_transform(instances[i].instance,spatial_node->get_global_transform()); + } + +} + + +void SpatialGizmoTool::free(){ + + ERR_FAIL_COND(!spatial_node); + ERR_FAIL_COND(!valid); + + for(int i=0;ifree(instances[i].instance); + instances[i].instance=RID(); + } + + valid=false; + + +} + + + +SpatialGizmoTool::SpatialGizmoTool() { + valid=false; + billboard_handle=false; + +} + +SpatialGizmoTool::~SpatialGizmoTool(){ + + clear(); +} + +Vector3 SpatialGizmoTool::get_handle_pos(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,handles.size(),Vector3()); + + return handles[p_idx]; + +} + +//// light gizmo + + +String LightSpatialGizmo::get_handle_name(int p_idx) const { + + if (p_idx==0) + return "Radius"; + else + return "Aperture"; +} + + +Variant LightSpatialGizmo::get_handle_value(int p_idx) const{ + + if (p_idx==0) + return light->get_parameter(Light::PARAM_RADIUS); + if (p_idx==1) + return light->get_parameter(Light::PARAM_SPOT_ANGLE); + + return Variant(); +} + + +static float _find_closest_angle_to_half_pi_arc(const Vector3& p_from, const Vector3& p_to, float p_arc_radius,const Transform& p_arc_xform) { + + //bleh, discrete is simpler + static const int arc_test_points=64; + float min_d = 1e20; + Vector3 min_p; + + + for(int i=0;iget_global_transform(); + gt.orthonormalize(); + Transform gi = gt.affine_inverse(); + + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); + + Vector3 s[2]={gi.xform(ray_from),gi.xform(ray_from+ray_dir*4096)}; + if (p_idx==0) { + + if (light->cast_to()) { + Vector3 ra,rb; + Geometry::get_closest_points_between_segments(Vector3(),Vector3(0,0,-4096),s[0],s[1],ra,rb); + + float d = -ra.z; + if (d<0) + d=0; + + light->set_parameter(Light::PARAM_RADIUS,d); + } else if (light->cast_to()) { + + Plane cp=Plane( gt.origin, p_camera->get_transform().basis.get_axis(2)); + + Vector3 inters; + if (cp.intersects_ray(ray_from,ray_dir,&inters)) { + + float r = inters.distance_to(gt.origin); + light->set_parameter(Light::PARAM_RADIUS,r); + } + + } + + } else if (p_idx==1) { + + float a = _find_closest_angle_to_half_pi_arc(s[0],s[1],light->get_parameter(Light::PARAM_RADIUS),gt); + light->set_parameter(Light::PARAM_SPOT_ANGLE,CLAMP(a,0.01,89.99)); + } +} + +void LightSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ + + if (p_cancel) { + + light->set_parameter(p_idx==0?Light::PARAM_RADIUS:Light::PARAM_SPOT_ANGLE,p_restore); + + } else if (p_idx==0) { + + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action("Change Light Radius"); + ur->add_do_method(light,"set_parameter",Light::PARAM_RADIUS,light->get_parameter(Light::PARAM_RADIUS)); + ur->add_undo_method(light,"set_parameter",Light::PARAM_RADIUS,p_restore); + ur->commit_action(); + } else if (p_idx==1) { + + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action("Change Light Radius"); + ur->add_do_method(light,"set_parameter",Light::PARAM_SPOT_ANGLE,light->get_parameter(Light::PARAM_SPOT_ANGLE)); + ur->add_undo_method(light,"set_parameter",Light::PARAM_SPOT_ANGLE,p_restore); + ur->commit_action(); + + } +} + + + +void LightSpatialGizmo::redraw() { + + + if (light->cast_to()) { + + + + const int arrow_points=5; + Vector3 arrow[arrow_points]={ + Vector3(0,0,2), + Vector3(1,1,2), + Vector3(1,1,-1), + Vector3(2,2,-1), + Vector3(0,0,-3) + }; + + int arrow_sides=4; + + Vector lines; + + + for(int i = 0; i < arrow_sides ; i++) { + + + Matrix3 ma(Vector3(0,0,1),Math_PI*2*float(i)/arrow_sides); + Matrix3 mb(Vector3(0,0,1),Math_PI*2*float(i+1)/arrow_sides); + + + for(int j=1;jlight_material); + add_collision_segments(lines); + add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_directional_icon,0.05); + + } + + if (light->cast_to()) { + + clear(); + + + OmniLight *on = light->cast_to(); + + float r = on->get_parameter(Light::PARAM_RADIUS); + + Vector points; + + for(int i=0;i<=360;i++) { + + float ra=Math::deg2rad(i); + float rb=Math::deg2rad(i+1); + Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*r; + Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*r; + + /*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)); + + } + + add_lines(points,SpatialEditorGizmos::singleton->light_material,true); + add_collision_segments(points); + + add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_omni_icon,0.05); + + Vector handles; + handles.push_back(Vector3(r,0,0)); + add_handles(handles,true); + + + } + + + if (light->cast_to()) { + + clear(); + + Vector points; + SpotLight *on = light->cast_to(); + + float r = on->get_parameter(Light::PARAM_RADIUS); + float w = r*Math::sin(Math::deg2rad(on->get_parameter(Light::PARAM_SPOT_ANGLE))); + float d = r*Math::cos(Math::deg2rad(on->get_parameter(Light::PARAM_SPOT_ANGLE))); + + + + for(int i=0;i<360;i++) { + + float ra=Math::deg2rad(i); + float rb=Math::deg2rad(i+1); + Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*w; + Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*w; + + /*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,-d)); + points.push_back(Vector3(b.x,b.y,-d)); + + if (i%90==0) { + + points.push_back(Vector3(a.x,a.y,-d)); + points.push_back(Vector3()); + + } + + + } + + points.push_back(Vector3(0,0,-r)); + points.push_back(Vector3()); + + add_lines(points,SpatialEditorGizmos::singleton->light_material); + + Vector handles; + handles.push_back(Vector3(0,0,-r)); + + Vector collision_segments; + + for(int i=0;i<64;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))*w; + Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*w; + + collision_segments.push_back(Vector3(a.x,a.y,-d)); + collision_segments.push_back(Vector3(b.x,b.y,-d)); + + if (i%16==0) { + + collision_segments.push_back(Vector3(a.x,a.y,-d)); + collision_segments.push_back(Vector3()); + + } + + if (i==16) { + + handles.push_back(Vector3(a.x,a.y,-d)); + } + + } + + collision_segments.push_back(Vector3(0,0,-r)); + collision_segments.push_back(Vector3()); + + + add_handles(handles); + add_collision_segments(collision_segments); + add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_omni_icon,0.05); + + } + +} + +LightSpatialGizmo::LightSpatialGizmo(Light* p_light){ + + light=p_light; + set_spatial_node(p_light); + +} + +////// + +String CameraSpatialGizmo::get_handle_name(int p_idx) const { + + if (camera->get_projection()==Camera::PROJECTION_PERSPECTIVE) { + return "FOV"; + } else { + return "Size"; + } +} +Variant CameraSpatialGizmo::get_handle_value(int p_idx) const{ + + if (camera->get_projection()==Camera::PROJECTION_PERSPECTIVE) { + return camera->get_fov(); + } else { + + return camera->get_size(); + } +} +void CameraSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){ + + Transform gt = camera->get_global_transform(); + gt.orthonormalize(); + Transform gi = gt.affine_inverse(); + + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); + + Vector3 s[2]={gi.xform(ray_from),gi.xform(ray_from+ray_dir*4096)}; + + if (camera->get_projection()==Camera::PROJECTION_PERSPECTIVE) { + Transform gt=camera->get_global_transform(); + float a = _find_closest_angle_to_half_pi_arc(s[0],s[1],1.0,gt); + camera->set("fov",a); + } else { + + Vector3 ra,rb; + Geometry::get_closest_points_between_segments(Vector3(0,0,-1),Vector3(4096,0,-1),s[0],s[1],ra,rb); + float d = ra.x * 2.0; + if (d<0) + d=0; + + camera->set("size",d); + } + +} +void CameraSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ + + if (camera->get_projection()==Camera::PROJECTION_PERSPECTIVE) { + + if (p_cancel) { + + camera->set("fov",p_restore); + } else { + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action("Change Camera FOV"); + ur->add_do_property(camera,"fov",camera->get_fov()); + ur->add_undo_property(camera,"fov",p_restore); + ur->commit_action(); + } + + } else { + + if (p_cancel) { + + camera->set("size",p_restore); + } else { + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action("Change Camera Size"); + ur->add_do_property(camera,"size",camera->get_size()); + ur->add_undo_property(camera,"size",p_restore); + ur->commit_action(); + } + + } + +} + +void CameraSpatialGizmo::redraw(){ + + clear(); + + Vector lines; + Vector handles; + + + switch(camera->get_projection()) { + + case Camera::PROJECTION_PERSPECTIVE: { + + float fov = camera->get_fov(); + + Vector3 side=Vector3( Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)) ); + Vector3 nside=side; + nside.x=-nside.x; + Vector3 up=Vector3(0,side.x,0); + + +#define ADD_TRIANGLE( m_a, m_b, m_c)\ +{\ + lines.push_back(m_a);\ + lines.push_back(m_b);\ + lines.push_back(m_b);\ + lines.push_back(m_c);\ + lines.push_back(m_c);\ + lines.push_back(m_a);\ +} + + ADD_TRIANGLE( Vector3(), side+up, side-up ); + ADD_TRIANGLE( Vector3(), nside+up, nside-up ); + ADD_TRIANGLE( Vector3(), side+up, nside+up ); + ADD_TRIANGLE( Vector3(), side-up, nside-up ); + + handles.push_back(side); + side.x*=0.25; + nside.x*=0.25; + Vector3 tup( 0, up.y*3/2,side.z); + ADD_TRIANGLE( tup, side+up, nside+up ); + + } break; + case Camera::PROJECTION_ORTHOGONAL: { + +#define ADD_QUAD( m_a, m_b, m_c, m_d)\ +{\ + lines.push_back(m_a);\ + lines.push_back(m_b);\ + lines.push_back(m_b);\ + lines.push_back(m_c);\ + lines.push_back(m_c);\ + lines.push_back(m_d);\ + lines.push_back(m_d);\ + lines.push_back(m_a);\ +} + float size = camera->get_size(); + + float hsize=size*0.5; + Vector3 right(hsize,0,0); + Vector3 up(0,hsize,0); + Vector3 back(0,0,-1.0); + Vector3 front(0,0,0); + + ADD_QUAD( -up-right,-up+right,up+right,up-right); + ADD_QUAD( -up-right+back,-up+right+back,up+right+back,up-right+back); + ADD_QUAD( up+right,up+right+back,up-right+back,up-right); + ADD_QUAD( -up+right,-up+right+back,-up-right+back,-up-right); + handles.push_back(right+back); + + right.x*=0.25; + Vector3 tup( 0, up.y*3/2,back.z ); + ADD_TRIANGLE( tup, right+up+back, -right+up+back ); + + } break; + + } + + add_lines(lines,SpatialEditorGizmos::singleton->camera_material); + add_collision_segments(lines); + add_handles(handles); +} + + +CameraSpatialGizmo::CameraSpatialGizmo(Camera* p_camera){ + + camera=p_camera; + set_spatial_node(camera); +} + + + + +////// + +void MeshInstanceSpatialGizmo::redraw() { + + 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); +} + +MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance* p_mesh) { + + mesh=p_mesh; + set_spatial_node(p_mesh); +} + +///// + + +void Position3DSpatialGizmo::redraw() { + + clear(); + add_mesh(SpatialEditorGizmos::singleton->pos3d_mesh); + Vector cursor_points; + 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)); + add_collision_segments(cursor_points); + +} + + +Position3DSpatialGizmo::Position3DSpatialGizmo(Position3D* p_p3d) { + + p3d=p_p3d; + set_spatial_node(p3d); +} + + +///// + +void SkeletonSpatialGizmo::redraw() { + + clear(); + + Ref surface_tool( memnew( SurfaceTool )); + + + surface_tool->begin(Mesh::PRIMITIVE_LINES); + surface_tool->set_material(SpatialEditorGizmos::singleton->skeleton_material); + Vector grests; + grests.resize(skel->get_bone_count()); + + Vector bones; + Vector weights; + bones.resize(4); + weights.resize(4); + + for(int i=0;i<4;i++) { + bones[i]=0; + weights[i]=0; + } + + weights[0]=1; + + + AABB aabb; + + Color bonecolor = Color(1.0,0.4,0.4,0.3); + Color rootcolor = Color(0.4,1.0,0.4,0.1); + + for (int i=0;iget_bone_count();i++) { + + int parent = skel->get_bone_parent(i); + + if (parent>=0) { + grests[i]=grests[parent] * skel->get_bone_rest(i); + + Vector3 v0 = grests[parent].origin; + Vector3 v1 = grests[i].origin; + Vector3 d = (v1-v0).normalized(); + float dist = v0.distance_to(v1); + + //find closest axis + int closest=-1; + float closest_d = 0.0; + + for(int j=0;j<3;j++) { + float dp = Math::abs(grests[parent].basis[j].normalized().dot(d)); + if (j==0 || dp>closest_d) + closest=j; + } + + //find closest other + Vector3 first; + Vector3 points[4]; + int pointidx=0; + for(int j=0;j<3;j++) { + + bones[0]=parent; + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(rootcolor); + surface_tool->add_vertex(v0-grests[parent].basis[j].normalized()*dist*0.05); + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(rootcolor); + surface_tool->add_vertex(v0+grests[parent].basis[j].normalized()*dist*0.05); + + if (j==closest) + continue; + + Vector3 axis; + if (first==Vector3()) { + axis = d.cross(d.cross(grests[parent].basis[j])).normalized(); + first=axis; + } else { + axis = d.cross(first).normalized(); + } + + for(int k=0;k<2;k++) { + + if (k==1) + axis=-axis; + Vector3 point = v0+d*dist*0.2; + point+=axis*dist*0.1; + + + bones[0]=parent; + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(bonecolor); + surface_tool->add_vertex(v0); + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(bonecolor); + surface_tool->add_vertex(point); + + bones[0]=parent; + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(bonecolor); + surface_tool->add_vertex(point); + bones[0]=i; + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(bonecolor); + surface_tool->add_vertex(v1); + points[pointidx++]=point; + + } + + } + + SWAP( points[1],points[2] ); + for(int j=0;j<4;j++) { + + + bones[0]=parent; + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(bonecolor); + surface_tool->add_vertex(points[j]); + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(bonecolor); + surface_tool->add_vertex(points[(j+1)%4]); + } + + +/* + bones[0]=parent; + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(Color(0.4,1,0.4,0.4)); + surface_tool->add_vertex(v0); + bones[0]=i; + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(Color(0.4,1,0.4,0.4)); + surface_tool->add_vertex(v1); +*/ + } else { + + grests[i]=skel->get_bone_rest(i); + bones[0]=i; + } +/* + Transform t = grests[i]; + t.orthonormalize(); + + 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]*(i>=3?-1:1); + else + face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); + } + } + + for(int j=0;j<4;j++) { + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(Color(1.0,0.4,0.4,0.4)); + surface_tool->add_vertex(t.xform(face_points[j]*0.04)); + surface_tool->add_bones(bones); + surface_tool->add_weights(weights); + surface_tool->add_color(Color(1.0,0.4,0.4,0.4)); + surface_tool->add_vertex(t.xform(face_points[(j+1)%4]*0.04)); + } + + } + */ + } + + Ref m = surface_tool->commit(); + add_mesh(m,false,skel->get_skeleton()); + +} + +SkeletonSpatialGizmo::SkeletonSpatialGizmo(Skeleton* p_skel) { + + skel=p_skel; + set_spatial_node(p_skel); +} + +///// + + +void SpatialPlayerSpatialGizmo::redraw() { + + clear(); + if (splayer->cast_to()) { + + add_unscaled_billboard(SpatialEditorGizmos::singleton->stream_player_icon,0.05); + + } else if (splayer->cast_to()) { + + add_unscaled_billboard(SpatialEditorGizmos::singleton->sample_player_icon,0.05); + + } + +} + +SpatialPlayerSpatialGizmo::SpatialPlayerSpatialGizmo(SpatialPlayer* p_splayer){ + + set_spatial_node(p_splayer); + splayer=p_splayer; +} + + +///// + + +void RoomSpatialGizmo::redraw() { + + clear(); + Ref roomie = room->get_room(); + if (roomie.is_null()) + return; + DVector faces = roomie->get_geometry_hint(); + + Vector lines; + int fc=faces.size(); + DVector::Read r =faces.read(); + + Map<_EdgeKey,Vector3> edge_map; + + for(int i=0;i::Element *E=edge_map.find(ek); + + if (E) { + + if (E->get().dot(fn) >0.9) { + + E->get()=Vector3(); + } + + } else { + + 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); + } + } + + add_lines(lines,SpatialEditorGizmos::singleton->room_material); + add_collision_segments(lines); + +} + +RoomSpatialGizmo::RoomSpatialGizmo(Room* p_room){ + + set_spatial_node(p_room); + room=p_room; +} + +///// + + +void PortalSpatialGizmo::redraw() { + + clear(); + + Vector points = portal->get_shape(); + if (points.size()==0) { + return; + } + + Vector lines; + + Vector3 center; + for(int i=0;iportal_material); + add_collision_segments(lines); + +} + +PortalSpatialGizmo::PortalSpatialGizmo(Portal* p_portal){ + + set_spatial_node(p_portal); + portal=p_portal; +} + +///// + + +void RayCastSpatialGizmo::redraw() { + + clear(); + + + Vector lines; + + lines.push_back(Vector3()); + lines.push_back(raycast->get_cast_to()); + + add_lines(lines,SpatialEditorGizmos::singleton->raycast_material); + add_collision_segments(lines); + +} + +RayCastSpatialGizmo::RayCastSpatialGizmo(RayCast* p_raycast){ + + set_spatial_node(p_raycast); + raycast=p_raycast; +} + + + +///// + + +void VehicleWheelSpatialGizmo::redraw() { + + clear(); + + + Vector points; + + float r = car_wheel->get_radius(); + const int skip=10; + for(int i=0;i<=360;i+=skip) { + + float ra=Math::deg2rad(i); + float rb=Math::deg2rad(i+skip); + Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*r; + Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*r; + + points.push_back(Vector3(0,a.x,a.y)); + points.push_back(Vector3(0,b.x,b.y)); + + const int springsec=4; + + for(int j=0;jget_suspension_rest_length()*5; + points.push_back(Vector3(a.x,i/360.0*t/springsec+j*(t/springsec),a.y)*0.2); + points.push_back(Vector3(b.x,(i+skip)/360.0*t/springsec+j*(t/springsec),b.y)*0.2); + } + + + } + + //travel + points.push_back(Vector3(0,0,0)); + points.push_back(Vector3(0,car_wheel->get_suspension_rest_length(),0)); + + //axis + points.push_back(Vector3(r*0.2,car_wheel->get_suspension_rest_length(),0)); + points.push_back(Vector3(-r*0.2,car_wheel->get_suspension_rest_length(),0)); + //axis + points.push_back(Vector3(r*0.2,0,0)); + points.push_back(Vector3(-r*0.2,0,0)); + + //forward line + points.push_back(Vector3(0,-r,0)); + points.push_back(Vector3(0,-r,r*2)); + points.push_back(Vector3(0,-r,r*2)); + points.push_back(Vector3(r*2*0.2,-r,r*2*0.8)); + points.push_back(Vector3(0,-r,r*2)); + points.push_back(Vector3(-r*2*0.2,-r,r*2*0.8)); + + add_lines(points,SpatialEditorGizmos::singleton->car_wheel_material); + add_collision_segments(points); + +} + +VehicleWheelSpatialGizmo::VehicleWheelSpatialGizmo(VehicleWheel* p_car_wheel){ + + set_spatial_node(p_car_wheel); + car_wheel=p_car_wheel; +} + + + +/// + +void TestCubeSpatialGizmo::redraw() { + + clear(); + add_collision_triangles(SpatialEditorGizmos::singleton->test_cube_tm); +} + +TestCubeSpatialGizmo::TestCubeSpatialGizmo(TestCube* p_tc) { + + tc=p_tc; + set_spatial_node(p_tc); +} + + +/////////// + + + + + + +String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const { + + Ref s = cs->get_shape(); + if (s.is_null()) + return ""; + + if (s->cast_to()) { + + return "Radius"; + } + + if (s->cast_to()) { + + return "Extents"; + } + + if (s->cast_to()) { + + return p_idx==0?"Radius":"Height"; + } + + if (s->cast_to()) { + + return "Length"; + } + + return ""; +} +Variant CollisionShapeSpatialGizmo::get_handle_value(int p_idx) const{ + + Ref s = cs->get_shape(); + if (s.is_null()) + return Variant(); + + if (s->cast_to()) { + + Ref ss = s; + return ss->get_radius(); + } + + if (s->cast_to()) { + + Ref bs = s; + return bs->get_extents(); + } + + if (s->cast_to()) { + + Ref cs = s; + return p_idx==0?cs->get_radius():cs->get_height(); + } + + if (s->cast_to()) { + + Ref cs = s; + return cs->get_length(); + } + + return Variant(); +} +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(); + + 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)}; + + if (s->cast_to()) { + + 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); + } + + if (s->cast_to()) { + + 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; + + rs->set_length(d); + } + + + if (s->cast_to()) { + + 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 (s->cast_to()) { + + 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); + + } + +} +void CollisionShapeSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ + Ref s = cs->get_shape(); + if (s.is_null()) + return; + + if (s->cast_to()) { + + Ref ss=s; + if (p_cancel) { + ss->set_radius(p_restore); + return; + } + + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action("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(); + + } + + if (s->cast_to()) { + + Ref ss=s; + if (p_cancel) { + ss->set_extents(p_restore); + return; + } + + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action("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(); + } + + if (s->cast_to()) { + + Ref ss=s; + if (p_cancel) { + if (p_idx==0) + ss->set_radius(p_restore); + else + ss->set_height(p_restore); + return; + } + + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + if (p_idx==0) { + ur->create_action("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("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); + + } + + ur->commit_action(); + + } + + if (s->cast_to()) { + + Ref ss=s; + if (p_cancel) { + ss->set_length(p_restore); + return; + } + + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action("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 CollisionShapeSpatialGizmo::redraw(){ + + clear(); + + Ref s = cs->get_shape(); + if (s.is_null()) + return; + + if (s->cast_to()) { + + Ref sp= s; + float r=sp->get_radius(); + + Vector points; + + for(int i=0;i<=360;i++) { + + float ra=Math::deg2rad(i); + float rb=Math::deg2rad(i+1); + Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*r; + Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*r; + + 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)); + + } + + Vector collision_segments; + + for(int i=0;i<64;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; + + 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)); + } + + add_lines(points,SpatialEditorGizmos::singleton->shape_material); + add_collision_segments(collision_segments); + Vector handles; + handles.push_back(Vector3(r,0,0)); + add_handles(handles); + + } + + if (s->cast_to()) { + + Ref bs=s; + Vector lines; + AABB aabb; + aabb.pos=-bs->get_extents(); + aabb.size=aabb.pos*-2; + + 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++) { + + Vector3 ax; + ax[i]=bs->get_extents()[i]; + handles.push_back(ax); + } + + add_lines(lines,SpatialEditorGizmos::singleton->shape_material); + add_collision_segments(lines); + add_handles(handles); + + } + + if (s->cast_to()) { + + Ref cs=s; + float radius = cs->get_radius(); + float height = cs->get_height(); + + + Vector points; + + Vector3 d(0,0,height*0.5); + for(int i=0;i<360;i++) { + + float ra=Math::deg2rad(i); + float rb=Math::deg2rad(i+1); + Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*radius; + Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*radius; + + points.push_back(Vector3(a.x,a.y,0)+d); + points.push_back(Vector3(b.x,b.y,0)+d); + + points.push_back(Vector3(a.x,a.y,0)-d); + points.push_back(Vector3(b.x,b.y,0)-d); + + if (i%90==0) { + + points.push_back(Vector3(a.x,a.y,0)+d); + points.push_back(Vector3(a.x,a.y,0)-d); + } + + Vector3 dud = i<180?d:-d; + + 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); + + } + + add_lines(points,SpatialEditorGizmos::singleton->shape_material); + + Vector collision_segments; + + for(int i=0;i<64;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))*radius; + Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*radius; + + collision_segments.push_back(Vector3(a.x,a.y,0)+d); + collision_segments.push_back(Vector3(b.x,b.y,0)+d); + + collision_segments.push_back(Vector3(a.x,a.y,0)-d); + collision_segments.push_back(Vector3(b.x,b.y,0)-d); + + if (i%16==0) { + + collision_segments.push_back(Vector3(a.x,a.y,0)+d); + collision_segments.push_back(Vector3(a.x,a.y,0)-d); + } + + Vector3 dud = i<32?d:-d; + + 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); + + } + + add_collision_segments(collision_segments); + + 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); + + + } + + if (s->cast_to()) { + + Ref ps=s; + Plane p = ps->get_plane(); + Vector points; + + Vector3 n1 = p.get_any_perpendicular_normal(); + Vector3 n2 = p.normal.cross(n1).normalized(); + + 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, + }; + + 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); + + add_lines(points,SpatialEditorGizmos::singleton->shape_material); + add_collision_segments(points); + + } + + + if (s->cast_to()) { + + DVector points = s->cast_to()->get_points(); + + if (points.size()>3) { + + 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;ishape_material); + add_collision_segments(points); + + } + } + + } + + + if (s->cast_to()) { + + Ref rs=s; + + Vector points; + points.push_back(Vector3()); + points.push_back(Vector3(0,0,rs->get_length())); + add_lines(points,SpatialEditorGizmos::singleton->shape_material); + add_collision_segments(points); + Vector handles; + handles.push_back(Vector3(0,0,rs->get_length())); + add_handles(handles); + + + } + +} +CollisionShapeSpatialGizmo::CollisionShapeSpatialGizmo(CollisionShape* p_cs) { + + cs=p_cs; + set_spatial_node(p_cs); +} + + + +///// + + +void CollisionPolygonSpatialGizmo::redraw() { + + clear(); + + Vector points = polygon->get_polygon(); + float depth = polygon->get_depth()*0.5; + + Vector lines; + for(int i=0;ishape_material); + add_collision_segments(lines); +} + +CollisionPolygonSpatialGizmo::CollisionPolygonSpatialGizmo(CollisionPolygon* p_polygon){ + + set_spatial_node(p_polygon); + polygon=p_polygon; +} +/// + + +String VisibilityNotifierGizmo::get_handle_name(int p_idx) const { + + switch(p_idx) { + case 0: return "X"; + case 1: return "Y"; + case 2: return "Z"; + } + + return ""; +} +Variant VisibilityNotifierGizmo::get_handle_value(int p_idx) const{ + + return notifier->get_aabb(); +} +void VisibilityNotifierGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){ + + + Transform gt = notifier->get_global_transform(); + //gt.orthonormalize(); + Transform gi = gt.affine_inverse(); + + 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); + + Vector3 sg[2]={gi.xform(ray_from),gi.xform(ray_from+ray_dir*4096)}; + Vector3 ofs = aabb.pos+aabb.size*0.5;; + + 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); + float d = ra[p_idx]; + if (d<0.001) + d=0.001; + + Vector3 he = aabb.size; + aabb.pos[p_idx]=(aabb.pos[p_idx]+aabb.size[p_idx]*0.5)-d; + aabb.size[p_idx]=d*2; + notifier->set_aabb(aabb); +} + +void VisibilityNotifierGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ + + + if (p_cancel) { + notifier->set_aabb(p_restore); + return; + } + + UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo(); + ur->create_action("Change Notifier Extents"); + ur->add_do_method(notifier,"set_aabb",notifier->get_aabb()); + ur->add_undo_method(notifier,"set_aabb",p_restore); + ur->commit_action(); + +} + +void VisibilityNotifierGizmo::redraw(){ + + clear(); + + Vector lines; + AABB aabb = notifier->get_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); + } + + Vector handles; + + + for(int i=0;i<3;i++) { + + Vector3 ax; + ax[i]=aabb.pos[i]+aabb.size[i]; + handles.push_back(ax); + } + + add_lines(lines,SpatialEditorGizmos::singleton->visibility_notifier_material); + //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05); + add_collision_segments(lines); + add_handles(handles); + +} +VisibilityNotifierGizmo::VisibilityNotifierGizmo(VisibilityNotifier* p_notifier){ + + notifier=p_notifier; + set_spatial_node(p_notifier); +} + +//////// + + + +void NavigationMeshSpatialGizmo::redraw() { + + clear(); + Ref navmeshie = navmesh->get_navigation_mesh(); + if (navmeshie.is_null()) + return; + + DVector vertices = navmeshie->get_vertices(); + DVector::Read vr=vertices.read(); + List faces; + for(int i=0;iget_polygon_count();i++) { + Vector p = navmeshie->get_polygon(i); + + for(int j=2;j edge_map; + DVector tmeshfaces; + tmeshfaces.resize(faces.size()*3); + + { + DVector::Write tw=tmeshfaces.write(); + int tidx=0; + + + for(List::Element *E=faces.front();E;E=E->next()) { + + const Face3 &f = E->get(); + + for(int j=0;j<3;j++) { + + tw[tidx++]=f.vertex[j]; + _EdgeKey ek; + ek.from=f.vertex[j].snapped(CMP_EPSILON); + ek.to=f.vertex[(j+1)%3].snapped(CMP_EPSILON); + if (ek.from::Element *E=edge_map.find(ek); + + if (E) { + + E->get()=false; + + } else { + + edge_map[ek]=true; + } + + } + } + } + Vector lines; + + for(Map<_EdgeKey,bool>::Element *E=edge_map.front();E;E=E->next()) { + + if (E->get()) { + lines.push_back(E->key().from); + lines.push_back(E->key().to); + } + } + + Ref tmesh = memnew( TriangleMesh); + tmesh->create(tmeshfaces); + + if (lines.size()) + add_lines(lines,navmesh->is_enabled()?SpatialEditorGizmos::singleton->navmesh_edge_material:SpatialEditorGizmos::singleton->navmesh_edge_material_disabled); + add_collision_triangles(tmesh); + Ref m = memnew( Mesh ); + Array a; + a.resize(Mesh::ARRAY_MAX); + a[0]=tmeshfaces; + m->add_surface(Mesh::PRIMITIVE_TRIANGLES,a); + m->surface_set_material(0,navmesh->is_enabled()?SpatialEditorGizmos::singleton->navmesh_solid_material:SpatialEditorGizmos::singleton->navmesh_solid_material_disabled); + add_mesh(m); + add_collision_segments(lines); + +} + +NavigationMeshSpatialGizmo::NavigationMeshSpatialGizmo(NavigationMeshInstance *p_navmesh){ + + set_spatial_node(p_navmesh); + navmesh=p_navmesh; +} + +////// +/// +/// + + + +void PinJointSpatialGizmo::redraw() { + + clear(); + Vector cursor_points; + 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)); + add_collision_segments(cursor_points); + add_lines(cursor_points,SpatialEditorGizmos::singleton->joint_material); + +} + + +PinJointSpatialGizmo::PinJointSpatialGizmo(PinJoint* p_p3d) { + + p3d=p_p3d; + set_spatial_node(p3d); +} + +//// + +void HingeJointSpatialGizmo::redraw() { + + clear(); + Vector cursor_points; + 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*2)); + cursor_points.push_back(Vector3(0,0,-cs*2)); + + float ll = p3d->get_param(HingeJoint::PARAM_LIMIT_LOWER); + float ul = p3d->get_param(HingeJoint::PARAM_LIMIT_UPPER); + + if (p3d->get_flag(HingeJoint::FLAG_USE_LIMIT) && lljoint_material); + +} + + +HingeJointSpatialGizmo::HingeJointSpatialGizmo(HingeJoint* p_p3d) { + + p3d=p_p3d; + set_spatial_node(p3d); +} + +/////// +/// +//// + +void SliderJointSpatialGizmo::redraw() { + + clear(); + Vector cursor_points; + 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*2)); + cursor_points.push_back(Vector3(0,0,-cs*2)); + + float ll = p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_LOWER); + float ul = p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_UPPER); + float lll = -p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_LOWER); + float lul = -p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_UPPER); + + if (lll>lul) { + + cursor_points.push_back(Vector3(lul,0,0)); + cursor_points.push_back(Vector3(lll,0,0)); + + cursor_points.push_back(Vector3(lul,-cs,-cs)); + cursor_points.push_back(Vector3(lul,-cs,cs)); + cursor_points.push_back(Vector3(lul,-cs,cs)); + cursor_points.push_back(Vector3(lul,cs,cs)); + cursor_points.push_back(Vector3(lul,cs,cs)); + cursor_points.push_back(Vector3(lul,cs,-cs)); + cursor_points.push_back(Vector3(lul,cs,-cs)); + cursor_points.push_back(Vector3(lul,-cs,-cs)); + + + cursor_points.push_back(Vector3(lll,-cs,-cs)); + cursor_points.push_back(Vector3(lll,-cs,cs)); + cursor_points.push_back(Vector3(lll,-cs,cs)); + cursor_points.push_back(Vector3(lll,cs,cs)); + cursor_points.push_back(Vector3(lll,cs,cs)); + cursor_points.push_back(Vector3(lll,cs,-cs)); + cursor_points.push_back(Vector3(lll,cs,-cs)); + cursor_points.push_back(Vector3(lll,-cs,-cs)); + + + } else { + + cursor_points.push_back(Vector3(+cs*2,0,0)); + cursor_points.push_back(Vector3(-cs*2,0,0)); + + } + + if (lljoint_material); + +} + + +SliderJointSpatialGizmo::SliderJointSpatialGizmo(SliderJoint* p_p3d) { + + p3d=p_p3d; + set_spatial_node(p3d); +} + +/////// +/// +//// + +void ConeTwistJointSpatialGizmo::redraw() { + + clear(); + float cs = 0.25; + Vector points; + + float r = 1.0; + float w = r*Math::sin(p3d->get_param(ConeTwistJoint::PARAM_SWING_SPAN)); + float d = r*Math::cos(p3d->get_param(ConeTwistJoint::PARAM_SWING_SPAN)); + + + //swing + for(int i=0;i<360;i+=10) { + + float ra=Math::deg2rad(i); + float rb=Math::deg2rad(i+10); + Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*w; + Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*w; + + /*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(d,a.x,a.y)); + points.push_back(Vector3(d,b.x,b.y)); + + if (i%90==0) { + + points.push_back(Vector3(d,a.x,a.y)); + points.push_back(Vector3()); + + } + } + + points.push_back(Vector3()); + points.push_back(Vector3(1,0,0)); + + //twist + /* + */ + float ts=Math::rad2deg(p3d->get_param(ConeTwistJoint::PARAM_TWIST_SPAN)); + ts=MIN(ts,720); + + + for(int i=0;ijoint_material); + +} + + +ConeTwistJointSpatialGizmo::ConeTwistJointSpatialGizmo(ConeTwistJoint* p_p3d) { + + p3d=p_p3d; + set_spatial_node(p3d); +} + +//////// +/// \brief SpatialEditorGizmos::singleton +/// +/////// +/// +//// + +void Generic6DOFJointSpatialGizmo::redraw() { + + clear(); + Vector cursor_points; + float cs = 0.25; + + for(int ax=0;ax<3;ax++) { + /*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*2)); + cursor_points.push_back(Vector3(0,0,-cs*2)); */ + + float ll; + float ul; + float lll; + float lul; + + int a1,a2,a3; + bool enable_ang; + bool enable_lin; + + switch(ax) { + case 0: + ll = p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT); + ul = p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT); + lll = -p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT); + lul = -p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT); + enable_ang = p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT); + enable_lin = p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT); + a1=0; + a2=1; + a3=2; + break; + case 1: + ll = p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT); + ul = p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT); + lll = -p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT); + lul = -p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT); + enable_ang = p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT); + enable_lin = p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT); + a1=2; + a2=0; + a3=1; + break; + case 2: + ll = p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT); + ul = p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT); + lll = -p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT); + lul = -p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT); + enable_ang = p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT); + enable_lin = p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT); + + a1=1; + a2=2; + a3=0; + break; + } + +#define ADD_VTX(x,y,z)\ + {\ + Vector3 v;\ + v[a1]=(x);\ + v[a2]=(y);\ + v[a3]=(z);\ + cursor_points.push_back(v);\ + } + +#define SET_VTX(what,x,y,z)\ + {\ + Vector3 v;\ + v[a1]=(x);\ + v[a2]=(y);\ + v[a3]=(z);\ + what=v;\ + } + + + + + if (enable_lin && lll>=lul) { + + ADD_VTX(lul,0,0); + ADD_VTX(lll,0,0); + + ADD_VTX(lul,-cs,-cs); + ADD_VTX(lul,-cs,cs); + ADD_VTX(lul,-cs,cs); + ADD_VTX(lul,cs,cs); + ADD_VTX(lul,cs,cs); + ADD_VTX(lul,cs,-cs); + ADD_VTX(lul,cs,-cs); + ADD_VTX(lul,-cs,-cs); + + + ADD_VTX(lll,-cs,-cs); + ADD_VTX(lll,-cs,cs); + ADD_VTX(lll,-cs,cs); + ADD_VTX(lll,cs,cs); + ADD_VTX(lll,cs,cs); + ADD_VTX(lll,cs,-cs); + ADD_VTX(lll,cs,-cs); + ADD_VTX(lll,-cs,-cs); + + + } else { + + ADD_VTX(+cs*2,0,0); + ADD_VTX(-cs*2,0,0); + + } + + if (enable_ang && ll<=ul) { + + const int points = 32; + float step = (ul-ll)/points; + + + for(int i=0;ijoint_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 (p_spatial->cast_to()) { + + Ref lsg = memnew( LightSpatialGizmo(p_spatial->cast_to()) ); + return lsg; + } + + if (p_spatial->cast_to()) { + + Ref lsg = memnew( CameraSpatialGizmo(p_spatial->cast_to()) ); + return lsg; + } + + if (p_spatial->cast_to()) { + + Ref lsg = memnew( SkeletonSpatialGizmo(p_spatial->cast_to()) ); + return lsg; + } + + + if (p_spatial->cast_to()) { + + Ref lsg = memnew( Position3DSpatialGizmo(p_spatial->cast_to()) ); + return lsg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( MeshInstanceSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( RoomSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( NavigationMeshSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( RayCastSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( PortalSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + + if (p_spatial->cast_to()) { + + Ref misg = memnew( TestCubeSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( SpatialPlayerSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( CollisionShapeSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( VisibilityNotifierGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( VehicleWheelSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + if (p_spatial->cast_to()) { + + Ref misg = memnew( PinJointSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( HingeJointSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( SliderJointSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( ConeTwistJointSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( Generic6DOFJointSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + if (p_spatial->cast_to()) { + + Ref misg = memnew( CollisionPolygonSpatialGizmo(p_spatial->cast_to()) ); + return misg; + } + + + return Ref(); +} + + +Ref SpatialEditorGizmos::create_line_material(const Color& p_base_color) { + + Ref line_material = Ref( memnew( FixedMaterial )); + line_material->set_flag(Material::FLAG_UNSHADED, true); + line_material->set_line_width(3.0); + line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); + line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,p_base_color); + + return line_material; + +} + +Ref SpatialEditorGizmos::create_solid_material(const Color& p_base_color) { + + Ref line_material = Ref( memnew( FixedMaterial )); + line_material->set_flag(Material::FLAG_UNSHADED, true); + line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,p_base_color); + + return line_material; + +} + +SpatialEditorGizmos::SpatialEditorGizmos() { + + singleton=this; + + handle_material = Ref( memnew( FixedMaterial )); + handle_material->set_flag(Material::FLAG_UNSHADED, true); + handle_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(0.8,0.8,0.8)); + + handle2_material = Ref( memnew( FixedMaterial )); + handle2_material->set_flag(Material::FLAG_UNSHADED, true); + handle2_material->set_fixed_flag(FixedMaterial::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(FixedMaterial::PARAM_DIFFUSE,handle_t); + handle2_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1)); + handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true); + + light_material = create_line_material(Color(1,1,0.2)); + + light_material_omni_icon = Ref( memnew( FixedMaterial )); + light_material_omni_icon->set_flag(Material::FLAG_UNSHADED, true); + light_material_omni_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); + light_material_omni_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + light_material_omni_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + light_material_omni_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); + light_material_omni_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoLight","EditorIcons")); + + + light_material_directional_icon = Ref( memnew( FixedMaterial )); + light_material_directional_icon->set_flag(Material::FLAG_UNSHADED, true); + light_material_directional_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); + light_material_directional_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + light_material_directional_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + light_material_directional_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); + light_material_directional_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight","EditorIcons")); + + 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_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, false); + navmesh_solid_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); + + 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_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, false); + navmesh_solid_material_disabled->set_flag(Material::FLAG_DOUBLE_SIDED,true); + + skeleton_material = create_line_material(Color(0.6,1.0,0.3)); + skeleton_material->set_flag(Material::FLAG_DOUBLE_SIDED,true); + skeleton_material->set_flag(Material::FLAG_UNSHADED,true); + skeleton_material->set_flag(Material::FLAG_ONTOP,true); + skeleton_material->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + + //position 3D Shared mesh + + pos3d_mesh = Ref( memnew( Mesh ) ); + { + + DVector cursor_points; + DVector 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( FixedMaterial ); + mat->set_flag(Material::FLAG_UNSHADED,true); + mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true); + mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,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(Mesh::PRIMITIVE_LINES,d); + pos3d_mesh->surface_set_material(0,mat); + } + + + sample_player_icon = Ref( memnew( FixedMaterial )); + sample_player_icon->set_flag(Material::FLAG_UNSHADED, true); + sample_player_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); + sample_player_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + sample_player_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + sample_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); + sample_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer","EditorIcons")); + + 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)); + joint_material = create_line_material(Color(0.6,0.8,1.0)); + + stream_player_icon = Ref( memnew( FixedMaterial )); + stream_player_icon->set_flag(Material::FLAG_UNSHADED, true); + stream_player_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); + stream_player_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + stream_player_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + stream_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); + stream_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer","EditorIcons")); + + visibility_notifier_icon = Ref( memnew( FixedMaterial )); + visibility_notifier_icon->set_flag(Material::FLAG_UNSHADED, true); + visibility_notifier_icon->set_flag(Material::FLAG_DOUBLE_SIDED, true); + visibility_notifier_icon->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + visibility_notifier_icon->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true); + visibility_notifier_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9)); + visibility_notifier_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("Visible","EditorIcons")); + + { + + DVector 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]*(i>=3?-1:1); + else + face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); + } + } + //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)); + + +} + diff --git a/tools/editor/spatial_editor_gizmos.h b/tools/editor/spatial_editor_gizmos.h index 02f60db7f8..bc7e8ad21d 100644 --- a/tools/editor/spatial_editor_gizmos.h +++ b/tools/editor/spatial_editor_gizmos.h @@ -1,491 +1,491 @@ -/*************************************************************************/ -/* spatial_editor_gizmos.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef SPATIAL_EDITOR_GIZMOS_H -#define SPATIAL_EDITOR_GIZMOS_H - - -#include "tools/editor/plugins/spatial_editor_plugin.h" -#include "scene/3d/light.h" -#include "scene/3d/camera.h" -#include "scene/3d/position_3d.h" -#include "scene/3d/spatial_sample_player.h" -#include "scene/3d/spatial_stream_player.h" -#include "scene/3d/test_cube.h" -#include "scene/3d/mesh_instance.h" -#include "scene/3d/body_shape.h" -#include "scene/3d/room_instance.h" -#include "scene/3d/visibility_notifier.h" -#include "scene/3d/portal.h" -#include "scene/3d/ray_cast.h" -#include "scene/3d/navigation_mesh.h" - -#include "scene/3d/vehicle_body.h" -#include "scene/3d/collision_polygon.h" -#include "scene/3d/physics_joint.h" - - -class Camera; - -class SpatialGizmoTool : public SpatialEditorGizmo { - - OBJ_TYPE(SpatialGizmoTool,SpatialGizmo); - - 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; - bool billboard_handle; - - bool valid; - Spatial *base; - Vector instances; - Spatial *spatial_node; -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 set_spatial_node(Spatial *p_node); - -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(const 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(); - //void redraw(); - void free(); - - SpatialGizmoTool(); - ~SpatialGizmoTool(); -}; - - - -class LightSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(LightSpatialGizmo,SpatialGizmoTool); - - Light* light; - -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(); - LightSpatialGizmo(Light* p_light=NULL); - -}; - -class CameraSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(CameraSpatialGizmo,SpatialGizmoTool); - - Camera* camera; - -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(); - CameraSpatialGizmo(Camera* p_camera=NULL); - -}; - - - -class MeshInstanceSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(MeshInstanceSpatialGizmo,SpatialGizmoTool); - - MeshInstance* mesh; - -public: - - void redraw(); - MeshInstanceSpatialGizmo(MeshInstance* p_mesh=NULL); - -}; - -class Position3DSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(Position3DSpatialGizmo,SpatialGizmoTool); - - Position3D* p3d; - -public: - - void redraw(); - Position3DSpatialGizmo(Position3D* p_p3d=NULL); - -}; - -class SkeletonSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(SkeletonSpatialGizmo,SpatialGizmoTool); - - Skeleton* skel; - -public: - - void redraw(); - SkeletonSpatialGizmo(Skeleton* p_skel=NULL); - -}; - - - - -class SpatialPlayerSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(SpatialPlayerSpatialGizmo,SpatialGizmoTool); - - SpatialPlayer* splayer; - -public: - - void redraw(); - SpatialPlayerSpatialGizmo(SpatialPlayer* p_splayer=NULL); - -}; - - - -class TestCubeSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(TestCubeSpatialGizmo,SpatialGizmoTool); - - TestCube* tc; - -public: - void redraw(); - TestCubeSpatialGizmo(TestCube* p_tc=NULL); - -}; - - -class RoomSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(RoomSpatialGizmo,SpatialGizmoTool); - - - struct _EdgeKey { - - Vector3 from; - Vector3 to; - - bool operator<(const _EdgeKey& p_with) const { return from==p_with.from ? to < p_with.to : from < p_with.from; } - }; - - - - Room* room; - -public: - - void redraw(); - RoomSpatialGizmo(Room* p_room=NULL); - -}; - - -class PortalSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(PortalSpatialGizmo,SpatialGizmoTool); - - Portal* portal; - -public: - - void redraw(); - PortalSpatialGizmo(Portal* p_portal=NULL); - -}; - - -class VisibilityNotifierGizmo : public SpatialGizmoTool { - - OBJ_TYPE(VisibilityNotifierGizmo ,SpatialGizmoTool); - - - VisibilityNotifier* notifier; - -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(); - VisibilityNotifierGizmo(VisibilityNotifier* p_notifier=NULL); - -}; - - - -class CollisionShapeSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(CollisionShapeSpatialGizmo,SpatialGizmoTool); - - CollisionShape* cs; - -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); - -}; - - -class CollisionPolygonSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(CollisionPolygonSpatialGizmo,SpatialGizmoTool); - - CollisionPolygon* polygon; - -public: - - void redraw(); - CollisionPolygonSpatialGizmo(CollisionPolygon* p_polygon=NULL); - -}; - - -class RayCastSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(RayCastSpatialGizmo,SpatialGizmoTool); - - RayCast* raycast; - -public: - - void redraw(); - RayCastSpatialGizmo(RayCast* p_raycast=NULL); - -}; - - - -class VehicleWheelSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(VehicleWheelSpatialGizmo,SpatialGizmoTool); - - VehicleWheel* car_wheel; - -public: - - void redraw(); - VehicleWheelSpatialGizmo(VehicleWheel* p_car_wheel=NULL); - -}; - - -class NavigationMeshSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(NavigationMeshSpatialGizmo,SpatialGizmoTool); - - - struct _EdgeKey { - - Vector3 from; - Vector3 to; - - 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); - -}; - - -class PinJointSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(PinJointSpatialGizmo,SpatialGizmoTool); - - PinJoint* p3d; - -public: - - void redraw(); - PinJointSpatialGizmo(PinJoint* p_p3d=NULL); - -}; - - -class HingeJointSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(HingeJointSpatialGizmo,SpatialGizmoTool); - - HingeJoint* p3d; - -public: - - void redraw(); - HingeJointSpatialGizmo(HingeJoint* p_p3d=NULL); - -}; - -class SliderJointSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(SliderJointSpatialGizmo,SpatialGizmoTool); - - SliderJoint* p3d; - -public: - - void redraw(); - SliderJointSpatialGizmo(SliderJoint* p_p3d=NULL); - -}; - -class ConeTwistJointSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(ConeTwistJointSpatialGizmo,SpatialGizmoTool); - - ConeTwistJoint* p3d; - -public: - - void redraw(); - ConeTwistJointSpatialGizmo(ConeTwistJoint* p_p3d=NULL); - -}; - - -class Generic6DOFJointSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(Generic6DOFJointSpatialGizmo,SpatialGizmoTool); - - Generic6DOFJoint* p3d; - -public: - - void redraw(); - Generic6DOFJointSpatialGizmo(Generic6DOFJoint* p_p3d=NULL); - -}; - - -class SpatialEditorGizmos { -public: - - Ref create_line_material(const Color& p_base_color); - Ref create_solid_material(const Color& p_base_color); - Ref handle2_material; - Ref handle_material; - Ref light_material; - Ref light_material_omni_icon; - Ref light_material_directional_icon; - Ref camera_material; - Ref skeleton_material; - Ref room_material; - Ref portal_material; - Ref raycast_material; - Ref visibility_notifier_material; - Ref car_wheel_material; - Ref joint_material; - - Ref navmesh_edge_material; - Ref navmesh_solid_material; - Ref navmesh_edge_material_disabled; - Ref navmesh_solid_material_disabled; - - - Ref sample_player_icon; - Ref stream_player_icon; - Ref visibility_notifier_icon; - - Ref shape_material; - Ref handle_t; - - Ref pos3d_mesh; - static SpatialEditorGizmos *singleton; - - Ref test_cube_tm; - - - Ref get_gizmo(Spatial *p_spatial); - - SpatialEditorGizmos(); -}; - -#endif // SPATIAL_EDITOR_GIZMOS_H - +/*************************************************************************/ +/* spatial_editor_gizmos.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef SPATIAL_EDITOR_GIZMOS_H +#define SPATIAL_EDITOR_GIZMOS_H + + +#include "tools/editor/plugins/spatial_editor_plugin.h" +#include "scene/3d/light.h" +#include "scene/3d/camera.h" +#include "scene/3d/position_3d.h" +#include "scene/3d/spatial_sample_player.h" +#include "scene/3d/spatial_stream_player.h" +#include "scene/3d/test_cube.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/body_shape.h" +#include "scene/3d/room_instance.h" +#include "scene/3d/visibility_notifier.h" +#include "scene/3d/portal.h" +#include "scene/3d/ray_cast.h" +#include "scene/3d/navigation_mesh.h" + +#include "scene/3d/vehicle_body.h" +#include "scene/3d/collision_polygon.h" +#include "scene/3d/physics_joint.h" + + +class Camera; + +class SpatialGizmoTool : public SpatialEditorGizmo { + + OBJ_TYPE(SpatialGizmoTool,SpatialGizmo); + + 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; + bool billboard_handle; + + bool valid; + Spatial *base; + Vector instances; + Spatial *spatial_node; +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 set_spatial_node(Spatial *p_node); + +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(const 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(); + //void redraw(); + void free(); + + SpatialGizmoTool(); + ~SpatialGizmoTool(); +}; + + + +class LightSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(LightSpatialGizmo,SpatialGizmoTool); + + Light* light; + +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(); + LightSpatialGizmo(Light* p_light=NULL); + +}; + +class CameraSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(CameraSpatialGizmo,SpatialGizmoTool); + + Camera* camera; + +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(); + CameraSpatialGizmo(Camera* p_camera=NULL); + +}; + + + +class MeshInstanceSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(MeshInstanceSpatialGizmo,SpatialGizmoTool); + + MeshInstance* mesh; + +public: + + void redraw(); + MeshInstanceSpatialGizmo(MeshInstance* p_mesh=NULL); + +}; + +class Position3DSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(Position3DSpatialGizmo,SpatialGizmoTool); + + Position3D* p3d; + +public: + + void redraw(); + Position3DSpatialGizmo(Position3D* p_p3d=NULL); + +}; + +class SkeletonSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(SkeletonSpatialGizmo,SpatialGizmoTool); + + Skeleton* skel; + +public: + + void redraw(); + SkeletonSpatialGizmo(Skeleton* p_skel=NULL); + +}; + + + + +class SpatialPlayerSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(SpatialPlayerSpatialGizmo,SpatialGizmoTool); + + SpatialPlayer* splayer; + +public: + + void redraw(); + SpatialPlayerSpatialGizmo(SpatialPlayer* p_splayer=NULL); + +}; + + + +class TestCubeSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(TestCubeSpatialGizmo,SpatialGizmoTool); + + TestCube* tc; + +public: + void redraw(); + TestCubeSpatialGizmo(TestCube* p_tc=NULL); + +}; + + +class RoomSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(RoomSpatialGizmo,SpatialGizmoTool); + + + struct _EdgeKey { + + Vector3 from; + Vector3 to; + + bool operator<(const _EdgeKey& p_with) const { return from==p_with.from ? to < p_with.to : from < p_with.from; } + }; + + + + Room* room; + +public: + + void redraw(); + RoomSpatialGizmo(Room* p_room=NULL); + +}; + + +class PortalSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(PortalSpatialGizmo,SpatialGizmoTool); + + Portal* portal; + +public: + + void redraw(); + PortalSpatialGizmo(Portal* p_portal=NULL); + +}; + + +class VisibilityNotifierGizmo : public SpatialGizmoTool { + + OBJ_TYPE(VisibilityNotifierGizmo ,SpatialGizmoTool); + + + VisibilityNotifier* notifier; + +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(); + VisibilityNotifierGizmo(VisibilityNotifier* p_notifier=NULL); + +}; + + + +class CollisionShapeSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(CollisionShapeSpatialGizmo,SpatialGizmoTool); + + CollisionShape* cs; + +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); + +}; + + +class CollisionPolygonSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(CollisionPolygonSpatialGizmo,SpatialGizmoTool); + + CollisionPolygon* polygon; + +public: + + void redraw(); + CollisionPolygonSpatialGizmo(CollisionPolygon* p_polygon=NULL); + +}; + + +class RayCastSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(RayCastSpatialGizmo,SpatialGizmoTool); + + RayCast* raycast; + +public: + + void redraw(); + RayCastSpatialGizmo(RayCast* p_raycast=NULL); + +}; + + + +class VehicleWheelSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(VehicleWheelSpatialGizmo,SpatialGizmoTool); + + VehicleWheel* car_wheel; + +public: + + void redraw(); + VehicleWheelSpatialGizmo(VehicleWheel* p_car_wheel=NULL); + +}; + + +class NavigationMeshSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(NavigationMeshSpatialGizmo,SpatialGizmoTool); + + + struct _EdgeKey { + + Vector3 from; + Vector3 to; + + 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); + +}; + + +class PinJointSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(PinJointSpatialGizmo,SpatialGizmoTool); + + PinJoint* p3d; + +public: + + void redraw(); + PinJointSpatialGizmo(PinJoint* p_p3d=NULL); + +}; + + +class HingeJointSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(HingeJointSpatialGizmo,SpatialGizmoTool); + + HingeJoint* p3d; + +public: + + void redraw(); + HingeJointSpatialGizmo(HingeJoint* p_p3d=NULL); + +}; + +class SliderJointSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(SliderJointSpatialGizmo,SpatialGizmoTool); + + SliderJoint* p3d; + +public: + + void redraw(); + SliderJointSpatialGizmo(SliderJoint* p_p3d=NULL); + +}; + +class ConeTwistJointSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(ConeTwistJointSpatialGizmo,SpatialGizmoTool); + + ConeTwistJoint* p3d; + +public: + + void redraw(); + ConeTwistJointSpatialGizmo(ConeTwistJoint* p_p3d=NULL); + +}; + + +class Generic6DOFJointSpatialGizmo : public SpatialGizmoTool { + + OBJ_TYPE(Generic6DOFJointSpatialGizmo,SpatialGizmoTool); + + Generic6DOFJoint* p3d; + +public: + + void redraw(); + Generic6DOFJointSpatialGizmo(Generic6DOFJoint* p_p3d=NULL); + +}; + + +class SpatialEditorGizmos { +public: + + Ref create_line_material(const Color& p_base_color); + Ref create_solid_material(const Color& p_base_color); + Ref handle2_material; + Ref handle_material; + Ref light_material; + Ref light_material_omni_icon; + Ref light_material_directional_icon; + Ref camera_material; + Ref skeleton_material; + Ref room_material; + Ref portal_material; + Ref raycast_material; + Ref visibility_notifier_material; + Ref car_wheel_material; + Ref joint_material; + + Ref navmesh_edge_material; + Ref navmesh_solid_material; + Ref navmesh_edge_material_disabled; + Ref navmesh_solid_material_disabled; + + + Ref sample_player_icon; + Ref stream_player_icon; + Ref visibility_notifier_icon; + + Ref shape_material; + Ref handle_t; + + Ref pos3d_mesh; + static SpatialEditorGizmos *singleton; + + Ref test_cube_tm; + + + Ref get_gizmo(Spatial *p_spatial); + + SpatialEditorGizmos(); +}; + +#endif // SPATIAL_EDITOR_GIZMOS_H + -- cgit v1.2.3