summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/collada/collada.cpp89
-rw-r--r--tools/collada/collada.h2
-rw-r--r--tools/editor/editor_import_export.cpp12
-rw-r--r--tools/editor/editor_node.cpp2
-rw-r--r--tools/editor/editor_settings.cpp6
-rw-r--r--tools/editor/icons/icon_instance_options.pngbin0 -> 523 bytes
-rw-r--r--tools/editor/io_plugins/editor_import_collada.cpp13
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.cpp6
-rw-r--r--tools/editor/plugins/baked_light_baker.cpp2
-rw-r--r--tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp457
-rw-r--r--tools/editor/plugins/collision_polygon_2d_editor_plugin.h84
-rw-r--r--tools/editor/plugins/collision_polygon_editor_plugin.cpp281
-rw-r--r--tools/editor/plugins/collision_polygon_editor_plugin.h23
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp45
-rw-r--r--tools/editor/project_export.cpp2
-rw-r--r--tools/editor/project_manager.cpp1
-rw-r--r--tools/editor/property_editor.cpp18
-rw-r--r--tools/editor/scene_tree_dock.cpp49
-rw-r--r--tools/editor/scene_tree_dock.h1
-rw-r--r--tools/editor/scene_tree_editor.cpp87
-rw-r--r--tools/editor/scene_tree_editor.h11
-rw-r--r--tools/editor/spatial_editor_gizmos.cpp648
-rw-r--r--tools/editor/spatial_editor_gizmos.h101
-rw-r--r--tools/export/blender25/io_scene_dae/export_dae.py17
-rw-r--r--tools/pck/pck_packer.cpp1
26 files changed, 1868 insertions, 91 deletions
diff --git a/tools/collada/collada.cpp b/tools/collada/collada.cpp
index 9962eed1b2..e29888b433 100644
--- a/tools/collada/collada.cpp
+++ b/tools/collada/collada.cpp
@@ -322,7 +322,7 @@ void Collada::_parse_image(XMLParser& parser) {
String path = parser.get_attribute_value("source").strip_edges();
if (path.find("://")==-1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
- image.path=Globals::get_singleton()->localize_path(state.local_path.get_base_dir()+"/"+path);
+ image.path=Globals::get_singleton()->localize_path(state.local_path.get_base_dir()+"/"+path.percent_decode());
}
} else {
@@ -338,7 +338,7 @@ void Collada::_parse_image(XMLParser& parser) {
if (name=="init_from") {
parser.read();
- String path = parser.get_node_data().strip_edges();
+ String path = parser.get_node_data().strip_edges().percent_decode();
if (path.find("://")==-1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
@@ -1388,8 +1388,11 @@ void Collada::_parse_morph_controller(XMLParser& parser, String p_id) {
state.morph_controller_data_map[p_id]=MorphControllerData();
MorphControllerData &morphdata = state.morph_controller_data_map[p_id];
+ print_line("morph source: "+parser.get_attribute_value("source")+" id: "+p_id);
morphdata.mesh=_uri_to_id(parser.get_attribute_value("source"));
+ print_line("morph source2: "+morphdata.mesh);
morphdata.mode=parser.get_attribute_value("method");
+ printf("JJmorph: %p\n",&morphdata);
String current_source;
while(parser.read()==OK) {
@@ -1680,6 +1683,10 @@ Collada::Node* Collada::_parse_visual_scene_node(XMLParser& parser) {
} else if (state.idref_joints.has(name))
joint->sid=name; //kind of a cheat but..
+ if (joint->sid!="") {
+ state.sid_to_node_map[joint->sid]=id;
+ }
+
node=joint;
@@ -2240,6 +2247,8 @@ void Collada::_create_skeletons(Collada::Node **p_node) {
Node *node = *p_node;
+
+
if (node->type==Node::TYPE_JOINT) {
// ohohohoohoo it's a joint node, time to work!
@@ -2346,6 +2355,79 @@ void Collada::_merge_skeletons(VisualScene *p_vscene,Node *p_node) {
}
+
+void Collada::_merge_skeletons2(VisualScene *p_vscene) {
+
+ for (Map<String,SkinControllerData>::Element *E=state.skin_controller_data_map.front();E;E=E->next()) {
+
+ SkinControllerData &cd=E->get();
+
+ NodeSkeleton *skeleton=NULL;
+
+ for (Map<String,Transform>::Element *F=cd.bone_rest_map.front();F;F=F->next()) {
+
+ String name;
+
+ if (!state.sid_to_node_map.has(F->key())) {
+ continue;
+ }
+
+ name = state.sid_to_node_map[F->key()];
+
+ if (!state.scene_map.has(name)) {
+ print_line("no foundie node for: "+name);
+ }
+
+ ERR_CONTINUE( !state.scene_map.has(name) );
+
+ Node *node=state.scene_map[name];
+ ERR_CONTINUE( node->type!=Node::TYPE_JOINT );
+ if (node->type!=Node::TYPE_JOINT)
+ continue;
+ NodeSkeleton *sk=NULL;
+
+ while(node && !sk) {
+
+ if (node->type==Node::TYPE_SKELETON) {
+ sk=static_cast<NodeSkeleton*>(node);
+ }
+ node=node->parent;
+ }
+ ERR_CONTINUE( !sk );
+
+ if (!sk)
+ continue; //bleh
+
+ if (!skeleton) {
+ skeleton=sk;
+ continue;
+ }
+
+ if (skeleton!=sk) {
+ //whoa.. wtf, merge.
+ print_line("MERGED BONES!!");
+
+ //NodeSkeleton *merged = E->get();
+ _remove_node(p_vscene,sk);
+ for(int i=0;i<sk->children.size();i++) {
+
+ _joint_set_owner(sk->children[i],skeleton);
+ skeleton->children.push_back( sk->children[i] );
+ sk->children[i]->parent=skeleton;
+
+
+ }
+
+ sk->children.clear(); //take children from it
+ memdelete( sk );
+ }
+ }
+ }
+
+
+
+}
+
bool Collada::_optimize_skeletons(VisualScene *p_vscene,Node *p_node) {
Node *node=p_node;
@@ -2537,6 +2619,9 @@ void Collada::_optimize() {
_merge_skeletons(&vs,vs.root_nodes[i]);
}
+ _merge_skeletons2(&vs);
+
+
for(int i=0;i<vs.root_nodes.size();i++) {
_optimize_skeletons(&vs,vs.root_nodes[i]);
}
diff --git a/tools/collada/collada.h b/tools/collada/collada.h
index 69ed05beba..360f54ec05 100644
--- a/tools/collada/collada.h
+++ b/tools/collada/collada.h
@@ -544,6 +544,7 @@ public:
Map<String,VisualScene> visual_scene_map;
Map<String,Node*> scene_map;
Set<String> idref_joints;
+ Map<String,String> sid_to_node_map;
//Map<String,NodeJoint*> bone_map;
Map<String,Transform> bone_rest_map;
@@ -616,6 +617,7 @@ private: // private stuff
void _find_morph_nodes(VisualScene *p_vscene,Node *p_node);
bool _remove_node(Node *p_parent,Node *p_node);
void _remove_node(VisualScene *p_vscene,Node *p_node);
+ void _merge_skeletons2(VisualScene *p_vscene);
void _merge_skeletons(VisualScene *p_vscene,Node *p_node);
bool _optimize_skeletons(VisualScene *p_vscene,Node *p_node);
diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp
index 8f9195110b..6e8cb987e9 100644
--- a/tools/editor/editor_import_export.cpp
+++ b/tools/editor/editor_import_export.cpp
@@ -439,8 +439,8 @@ bool EditorExportPlatformPC::_get(const StringName& p_name,Variant &r_ret) const
void EditorExportPlatformPC::_get_property_list( List<PropertyInfo> *p_list) const {
- p_list->push_back( PropertyInfo( Variant::STRING, "custom_binary/debug", PROPERTY_HINT_FILE,binary_extension));
- p_list->push_back( PropertyInfo( Variant::STRING, "custom_binary/release", PROPERTY_HINT_FILE,binary_extension));
+ p_list->push_back( PropertyInfo( Variant::STRING, "custom_binary/debug", PROPERTY_HINT_GLOBAL_FILE,binary_extension));
+ p_list->push_back( PropertyInfo( Variant::STRING, "custom_binary/release", PROPERTY_HINT_GLOBAL_FILE,binary_extension));
p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Single Exec.,Exec+Pack (.pck),Copy,Bundles (Optical)"));
p_list->push_back( PropertyInfo( Variant::BOOL, "binary/64_bits"));
}
@@ -1009,15 +1009,15 @@ Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug,
String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (use64) {
if (p_debug)
- exe_path+=custom_debug_binary!=""?custom_debug_binary:debug_binary64;
+ exe_path=custom_debug_binary!=""?custom_debug_binary:exe_path+debug_binary64;
else
- exe_path+=custom_release_binary!=""?custom_release_binary:release_binary64;
+ exe_path=custom_release_binary!=""?custom_release_binary:exe_path+release_binary64;
} else {
if (p_debug)
- exe_path+=custom_debug_binary!=""?custom_debug_binary:debug_binary32;
+ exe_path=custom_debug_binary!=""?custom_debug_binary:exe_path+debug_binary32;
else
- exe_path+=custom_release_binary!=""?custom_release_binary:release_binary32;
+ exe_path=custom_release_binary!=""?custom_release_binary:exe_path+release_binary32;
}
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 6ac72fc401..4e2e5118dd 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -79,6 +79,7 @@
#include "plugins/path_editor_plugin.h"
#include "plugins/rich_text_editor_plugin.h"
#include "plugins/collision_polygon_editor_plugin.h"
+#include "plugins/collision_polygon_2d_editor_plugin.h"
#include "plugins/script_editor_plugin.h"
#include "plugins/path_2d_editor_plugin.h"
#include "plugins/particles_editor_plugin.h"
@@ -4086,6 +4087,7 @@ EditorNode::EditorNode() {
add_editor_plugin( memnew( ItemListEditorPlugin(this) ) );
add_editor_plugin( memnew( RichTextEditorPlugin(this) ) );
add_editor_plugin( memnew( CollisionPolygonEditorPlugin(this) ) );
+ add_editor_plugin( memnew( CollisionPolygon2DEditorPlugin(this) ) );
add_editor_plugin( memnew( TileSetEditorPlugin(this) ) );
add_editor_plugin( memnew( TileMapEditorPlugin(this) ) );
add_editor_plugin( memnew( SpriteFramesEditorPlugin(this) ) );
diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp
index 0b896a725e..6f1a24d7e8 100644
--- a/tools/editor/editor_settings.cpp
+++ b/tools/editor/editor_settings.cpp
@@ -386,6 +386,10 @@ void EditorSettings::_load_defaults() {
set("global/font","");
hints["global/font"]=PropertyInfo(Variant::STRING,"global/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt");
+ set("global/default_project_path","");
+ hints["global/default_project_path"]=PropertyInfo(Variant::STRING,"global/default_project_path",PROPERTY_HINT_GLOBAL_DIR);
+ set("global/default_project_export_path","");
+ hints["global/default_project_export_path"]=PropertyInfo(Variant::STRING,"global/default_project_export_path",PROPERTY_HINT_GLOBAL_DIR);
set("text_editor/background_color",Color::html("3b000000"));
set("text_editor/text_color",Color::html("aaaaaa"));
@@ -402,8 +406,8 @@ void EditorSettings::_load_defaults() {
set("text_editor/create_signal_callbacks",true);
set("text_editor/autosave_interval_seconds",60);
set("text_editor/font","");
- set("text_editor/auto_brace_complete", false);
hints["text_editor/font"]=PropertyInfo(Variant::STRING,"text_editor/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt");
+ set("text_editor/auto_brace_complete", false);
set("3d_editor/default_fov",45.0);
diff --git a/tools/editor/icons/icon_instance_options.png b/tools/editor/icons/icon_instance_options.png
new file mode 100644
index 0000000000..2d3e98b2ea
--- /dev/null
+++ b/tools/editor/icons/icon_instance_options.png
Binary files differ
diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp
index 15a671d623..9bee47ca66 100644
--- a/tools/editor/io_plugins/editor_import_collada.cpp
+++ b/tools/editor/io_plugins/editor_import_collada.cpp
@@ -564,6 +564,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co
bool local_xform_mirror=p_local_xform.basis.determinant() < 0;
if (p_morph_data) {
+
//add morphie target
ERR_FAIL_COND_V( !p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA );
String mt = p_morph_data->targets["MORPH_TARGET"];
@@ -1478,8 +1479,11 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
Transform apply_xform;
Vector<int> bone_remap;
+ print_line("mesh: "+String(mi->get_name()));
+
if (ng->controller) {
+ print_line("has controller");
if (collada.state.skin_controller_data_map.has(ng->source)) {
@@ -1524,13 +1528,20 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
for(int i=0;i<bone_remap.size();i++) {
String str = joint_src->sarray[i];
+ if (!bone_remap_map.has(str)) {
+ print_line("bone not found for remap: "+str);
+ print_line("in skeleton: "+skname);
+ }
ERR_FAIL_COND_V( !bone_remap_map.has(str), ERR_INVALID_DATA );
bone_remap[i]=bone_remap_map[str];
}
} else if (collada.state.morph_controller_data_map.has(ng->source)) {
+ print_line("is morph "+ng->source);
//it's a morph!!
- morph = &collada.state.morph_controller_data_map[meshid];
+ morph = &collada.state.morph_controller_data_map[ng->source];
meshid=morph->mesh;
+ printf("KKmorph: %p\n",morph);
+ print_line("morph mshid: "+meshid);
} else {
ERR_EXPLAIN("Controller Instance Source '"+ng->source+"' is neither skin or morph!");
ERR_FAIL_V( ERR_INVALID_DATA );
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
index 170598291a..4a52f4914f 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -418,7 +418,7 @@ void EditorSceneImportDialog::_import(bool p_and_open) {
List<String> missing;
Error err = plugin->import1(rim,&scene,&missing);
- if (err) {
+ if (err || !scene) {
error_dialog->set_text("Error importing scene.");
error_dialog->popup_centered(Size2(200,100));
@@ -878,6 +878,8 @@ static bool _teststr(const String& p_what,const String& p_str) {
return true;
if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters
return true;
+ if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters
+ return true;
return false;
}
@@ -887,6 +889,8 @@ static String _fixstr(const String& p_what,const String& p_str) {
return p_what.replace("$"+p_str,"");
if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters
return p_what.substr(0,p_what.length()-(p_str.length()+1));
+ if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters
+ return p_what.substr(0,p_what.length()-(p_str.length()+1));
return p_what;
}
diff --git a/tools/editor/plugins/baked_light_baker.cpp b/tools/editor/plugins/baked_light_baker.cpp
index 1574ce81d7..dea83e0ff8 100644
--- a/tools/editor/plugins/baked_light_baker.cpp
+++ b/tools/editor/plugins/baked_light_baker.cpp
@@ -338,7 +338,7 @@ void BakedLightBaker::_fix_lights() {
}
if (dl.type==VS::LIGHT_OMNI) {
- dl.area=4.0*Math_PI*pow(dl.radius,2.0);
+ dl.area=4.0*Math_PI*pow(dl.radius,2.0f);
dl.constant=1.0/3.5;
} else {
diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
new file mode 100644
index 0000000000..080ed7d11c
--- /dev/null
+++ b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -0,0 +1,457 @@
+#include "collision_polygon_2d_editor_plugin.h"
+
+#include "canvas_item_editor_plugin.h"
+#include "os/file_access.h"
+#include "tools/editor/editor_settings.h"
+
+void CollisionPolygon2DEditor::_notification(int p_what) {
+
+ switch(p_what) {
+
+ case NOTIFICATION_READY: {
+
+ button_create->set_icon( get_icon("Edit","EditorIcons"));
+ button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
+ button_edit->set_pressed(true);
+
+
+ } break;
+ case NOTIFICATION_FIXED_PROCESS: {
+
+
+ } break;
+ }
+
+}
+void CollisionPolygon2DEditor::_node_removed(Node *p_node) {
+
+ if(p_node==node) {
+ node=NULL;
+ hide();
+ }
+
+}
+
+
+Vector2 CollisionPolygon2DEditor::snap_point(const Vector2& p_point) const {
+
+ if (canvas_item_editor->is_snap_active()) {
+
+ return p_point.snapped(Vector2(1,1)*canvas_item_editor->get_snap());
+
+ } else {
+ return p_point;
+ }
+}
+
+void CollisionPolygon2DEditor::_menu_option(int p_option) {
+
+ switch(p_option) {
+
+ case MODE_CREATE: {
+
+ mode=MODE_CREATE;
+ button_create->set_pressed(true);
+ button_edit->set_pressed(false);
+ } break;
+ case MODE_EDIT: {
+
+ mode=MODE_EDIT;
+ button_create->set_pressed(false);
+ button_edit->set_pressed(true);
+ } break;
+
+ }
+}
+
+void CollisionPolygon2DEditor::_wip_close() {
+
+ undo_redo->create_action("Create Poly");
+ undo_redo->add_undo_method(node,"set_polygon",node->get_polygon());
+ undo_redo->add_do_method(node,"set_polygon",wip);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->commit_action();
+ wip.clear();
+ wip_active=false;
+ mode=MODE_EDIT;
+ button_edit->set_pressed(true);
+ button_create->set_pressed(false);
+ edited_point=-1;
+}
+
+bool CollisionPolygon2DEditor::forward_input_event(const InputEvent& p_event) {
+
+
+ switch(p_event.type) {
+
+ case InputEvent::MOUSE_BUTTON: {
+
+ const InputEventMouseButton &mb=p_event.mouse_button;
+
+ Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+
+
+ Vector2 gpoint = Point2(mb.x,mb.y);
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint=snap_point(cpoint);
+ cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
+
+ Vector<Vector2> poly = node->get_polygon();
+
+ //first check if a point is to be added (segment split)
+ real_t grab_treshold=EDITOR_DEF("poly_editor/point_grab_radius",8);
+
+ switch(mode) {
+
+
+ case MODE_CREATE: {
+
+ if (mb.button_index==BUTTON_LEFT && mb.pressed) {
+
+
+ if (!wip_active) {
+
+ wip.clear();
+ wip.push_back( cpoint );
+ wip_active=true;
+ edited_point_pos=cpoint;
+ canvas_item_editor->get_viewport_control()->update();
+ edited_point=1;
+ return true;
+ } else {
+
+
+ if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) {
+ //wip closed
+ _wip_close();
+
+ return true;
+ } else {
+
+ wip.push_back( cpoint );
+ edited_point=wip.size();
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
+
+ //add wip point
+ }
+ }
+ } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) {
+ _wip_close();
+ }
+
+
+
+ } break;
+
+ case MODE_EDIT: {
+
+ if (mb.button_index==BUTTON_LEFT) {
+ if (mb.pressed) {
+
+ if (mb.mod.control) {
+
+
+ if (poly.size() < 3) {
+
+ undo_redo->create_action("Edit Poly");
+ undo_redo->add_undo_method(node,"set_polygon",poly);
+ poly.push_back(cpoint);
+ undo_redo->add_do_method(node,"set_polygon",poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->commit_action();
+ return true;
+ }
+
+ //search edges
+ int closest_idx=-1;
+ Vector2 closest_pos;
+ real_t closest_dist=1e10;
+ for(int i=0;i<poly.size();i++) {
+
+ Vector2 points[2] ={ xform.xform(poly[i]),
+ xform.xform(poly[(i+1)%poly.size()]) };
+
+ Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points);
+ if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2)
+ continue; //not valid to reuse point
+
+ real_t d = cp.distance_to(gpoint);
+ if (d<closest_dist && d<grab_treshold) {
+ closest_dist=d;
+ closest_pos=cp;
+ closest_idx=i;
+ }
+
+
+ }
+
+ if (closest_idx>=0) {
+
+ pre_move_edit=poly;
+ poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos));
+ edited_point=closest_idx+1;
+ edited_point_pos=xform.affine_inverse().xform(closest_pos);
+ node->set_polygon(poly);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
+ }
+ } else {
+
+ //look for points to move
+
+ int closest_idx=-1;
+ Vector2 closest_pos;
+ real_t closest_dist=1e10;
+ for(int i=0;i<poly.size();i++) {
+
+ Vector2 cp =xform.xform(poly[i]);
+
+ real_t d = cp.distance_to(gpoint);
+ if (d<closest_dist && d<grab_treshold) {
+ closest_dist=d;
+ closest_pos=cp;
+ closest_idx=i;
+ }
+
+ }
+
+ if (closest_idx>=0) {
+
+ pre_move_edit=poly;
+ edited_point=closest_idx;
+ edited_point_pos=xform.affine_inverse().xform(closest_pos);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
+ }
+ }
+ } else {
+
+ if (edited_point!=-1) {
+
+ //apply
+
+ ERR_FAIL_INDEX_V(edited_point,poly.size(),false);
+ poly[edited_point]=edited_point_pos;
+ undo_redo->create_action("Edit Poly");
+ undo_redo->add_do_method(node,"set_polygon",poly);
+ undo_redo->add_undo_method(node,"set_polygon",pre_move_edit);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->commit_action();
+
+ edited_point=-1;
+ return true;
+ }
+ }
+ } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) {
+
+
+
+ int closest_idx=-1;
+ Vector2 closest_pos;
+ real_t closest_dist=1e10;
+ for(int i=0;i<poly.size();i++) {
+
+ Vector2 cp =xform.xform(poly[i]);
+
+ real_t d = cp.distance_to(gpoint);
+ if (d<closest_dist && d<grab_treshold) {
+ closest_dist=d;
+ closest_pos=cp;
+ closest_idx=i;
+ }
+
+ }
+
+ if (closest_idx>=0) {
+
+
+ undo_redo->create_action("Edit Poly (Remove Point)");
+ undo_redo->add_undo_method(node,"set_polygon",poly);
+ poly.remove(closest_idx);
+ undo_redo->add_do_method(node,"set_polygon",poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->commit_action();
+ return true;
+ }
+
+ }
+
+
+
+ } break;
+ }
+
+
+
+ } break;
+ case InputEvent::MOUSE_MOTION: {
+
+ const InputEventMouseMotion &mm=p_event.mouse_motion;
+
+ if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) {
+
+ Vector2 gpoint = Point2(mm.x,mm.y);
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint=snap_point(cpoint);
+ edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
+
+ canvas_item_editor->get_viewport_control()->update();
+
+ }
+
+ } break;
+ }
+
+ return false;
+}
+void CollisionPolygon2DEditor::_canvas_draw() {
+
+ if (!node)
+ return;
+
+ Control *vpc = canvas_item_editor->get_viewport_control();
+
+ Vector<Vector2> poly;
+
+ if (wip_active)
+ poly=wip;
+ else
+ poly=node->get_polygon();
+
+
+ Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Ref<Texture> handle= get_icon("EditorHandle","EditorIcons");
+
+ int len = poly.size();
+
+ for(int i=0;i<poly.size();i++) {
+
+
+ Vector2 p,p2;
+ p = i==edited_point ? edited_point_pos : poly[i];
+ if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point))
+ p2=edited_point_pos;
+ else
+ p2 = poly[(i+1)%poly.size()];
+
+ Vector2 point = xform.xform(p);
+ Vector2 next_point = xform.xform(p2);
+
+ Color col=Color(1,0.3,0.1,0.8);
+ vpc->draw_line(point,next_point,col,2);
+ vpc->draw_texture(handle,point-handle->get_size()*0.5);
+ }
+}
+
+
+
+void CollisionPolygon2DEditor::edit(Node *p_collision_polygon) {
+
+ if (!canvas_item_editor) {
+ canvas_item_editor=CanvasItemEditor::get_singleton();
+ }
+
+ if (p_collision_polygon) {
+
+ node=p_collision_polygon->cast_to<CollisionPolygon2D>();
+ if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
+ canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw");
+ wip.clear();
+ wip_active=false;
+ edited_point=-1;
+
+ } else {
+ node=NULL;
+
+ if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
+ canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw");
+
+ }
+
+}
+
+void CollisionPolygon2DEditor::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("_menu_option"),&CollisionPolygon2DEditor::_menu_option);
+ ObjectTypeDB::bind_method(_MD("_canvas_draw"),&CollisionPolygon2DEditor::_canvas_draw);
+
+}
+
+CollisionPolygon2DEditor::CollisionPolygon2DEditor(EditorNode *p_editor) {
+
+ canvas_item_editor=NULL;
+ editor=p_editor;
+ undo_redo = editor->get_undo_redo();
+
+ add_child( memnew( VSeparator ));
+ button_create = memnew( ToolButton );
+ add_child(button_create);
+ button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE));
+ button_create->set_toggle_mode(true);
+
+ button_edit = memnew( ToolButton );
+ add_child(button_edit);
+ button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT));
+ button_edit->set_toggle_mode(true);
+
+ //add_constant_override("separation",0);
+
+#if 0
+ options = memnew( MenuButton );
+ add_child(options);
+ options->set_area_as_parent_rect();
+ options->set_text("Polygon");
+ //options->get_popup()->add_item("Parse BBCODE",PARSE_BBCODE);
+ options->get_popup()->connect("item_pressed", this,"_menu_option");
+#endif
+
+ mode = MODE_EDIT;
+ wip_active=false;
+
+}
+
+
+void CollisionPolygon2DEditorPlugin::edit(Object *p_object) {
+
+ collision_polygon_editor->edit(p_object->cast_to<Node>());
+}
+
+bool CollisionPolygon2DEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_type("CollisionPolygon2D");
+}
+
+void CollisionPolygon2DEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ collision_polygon_editor->show();
+ } else {
+
+ collision_polygon_editor->hide();
+ collision_polygon_editor->edit(NULL);
+ }
+
+}
+
+CollisionPolygon2DEditorPlugin::CollisionPolygon2DEditorPlugin(EditorNode *p_node) {
+
+ editor=p_node;
+ collision_polygon_editor = memnew( CollisionPolygon2DEditor(p_node) );
+ CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor);
+
+ collision_polygon_editor->hide();
+
+
+
+}
+
+
+CollisionPolygon2DEditorPlugin::~CollisionPolygon2DEditorPlugin()
+{
+}
+
diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.h b/tools/editor/plugins/collision_polygon_2d_editor_plugin.h
new file mode 100644
index 0000000000..052019b6c5
--- /dev/null
+++ b/tools/editor/plugins/collision_polygon_2d_editor_plugin.h
@@ -0,0 +1,84 @@
+#ifndef COLLISION_POLYGON_2D_EDITOR_PLUGIN_H
+#define COLLISION_POLYGON_2D_EDITOR_PLUGIN_H
+
+
+#include "tools/editor/editor_plugin.h"
+#include "tools/editor/editor_node.h"
+#include "scene/2d/collision_polygon_2d.h"
+#include "scene/gui/tool_button.h"
+#include "scene/gui/button_group.h"
+
+/**
+ @author Juan Linietsky <reduzio@gmail.com>
+*/
+class CanvasItemEditor;
+
+class CollisionPolygon2DEditor : public HBoxContainer {
+
+ OBJ_TYPE(CollisionPolygon2DEditor, HBoxContainer );
+
+ UndoRedo *undo_redo;
+ enum Mode {
+
+ MODE_CREATE,
+ MODE_EDIT,
+
+ };
+
+ Mode mode;
+
+ ToolButton *button_create;
+ ToolButton *button_edit;
+
+ CanvasItemEditor *canvas_item_editor;
+ EditorNode *editor;
+ Panel *panel;
+ CollisionPolygon2D *node;
+ MenuButton *options;
+
+ int edited_point;
+ Vector2 edited_point_pos;
+ Vector<Vector2> pre_move_edit;
+ Vector<Vector2> wip;
+ bool wip_active;
+
+
+ void _wip_close();
+ void _canvas_draw();
+ void _menu_option(int p_option);
+
+protected:
+ void _notification(int p_what);
+ void _node_removed(Node *p_node);
+ static void _bind_methods();
+public:
+
+ Vector2 snap_point(const Vector2& p_point) const;
+ bool forward_input_event(const InputEvent& p_event);
+ void edit(Node *p_collision_polygon);
+ CollisionPolygon2DEditor(EditorNode *p_editor);
+};
+
+class CollisionPolygon2DEditorPlugin : public EditorPlugin {
+
+ OBJ_TYPE( CollisionPolygon2DEditorPlugin, EditorPlugin );
+
+ CollisionPolygon2DEditor *collision_polygon_editor;
+ EditorNode *editor;
+
+public:
+
+ virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); }
+
+ virtual String get_name() const { return "CollisionPolygon2D"; }
+ 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);
+
+ CollisionPolygon2DEditorPlugin(EditorNode *p_node);
+ ~CollisionPolygon2DEditorPlugin();
+
+};
+
+#endif // COLLISION_POLYGON_2D_EDITOR_PLUGIN_H
diff --git a/tools/editor/plugins/collision_polygon_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_editor_plugin.cpp
index 93ad918b0e..16b9622312 100644
--- a/tools/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/tools/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -27,10 +27,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "collision_polygon_editor_plugin.h"
-#include "canvas_item_editor_plugin.h"
+#include "spatial_editor_plugin.h"
#include "os/file_access.h"
#include "tools/editor/editor_settings.h"
-
+#include "scene/3d/camera.h"
void CollisionPolygonEditor::_notification(int p_what) {
switch(p_what) {
@@ -40,11 +40,16 @@ void CollisionPolygonEditor::_notification(int p_what) {
button_create->set_icon( get_icon("Edit","EditorIcons"));
button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
button_edit->set_pressed(true);
+ get_scene()->connect("node_removed",this,"_node_removed");
} break;
- case NOTIFICATION_FIXED_PROCESS: {
+ case NOTIFICATION_PROCESS: {
+ if (node->get_depth() != prev_depth) {
+ _polygon_draw();
+ prev_depth=node->get_depth();
+ }
} break;
}
@@ -54,7 +59,10 @@ void CollisionPolygonEditor::_node_removed(Node *p_node) {
if(p_node==node) {
node=NULL;
+ if (imgeom->get_parent()==p_node)
+ p_node->remove_child(imgeom);
hide();
+ set_process(false);
}
}
@@ -62,13 +70,15 @@ void CollisionPolygonEditor::_node_removed(Node *p_node) {
Vector2 CollisionPolygonEditor::snap_point(const Vector2& p_point) const {
+ return p_point;
+ /*
if (canvas_item_editor->is_snap_active()) {
return p_point.snapped(Vector2(1,1)*canvas_item_editor->get_snap());
} else {
return p_point;
- }
+ } ??? */
}
void CollisionPolygonEditor::_menu_option(int p_option) {
@@ -93,21 +103,28 @@ void CollisionPolygonEditor::_menu_option(int p_option) {
void CollisionPolygonEditor::_wip_close() {
- undo_redo->create_action("Create Poly");
+ undo_redo->create_action("Create Poly3D");
undo_redo->add_undo_method(node,"set_polygon",node->get_polygon());
undo_redo->add_do_method(node,"set_polygon",wip);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->commit_action();
+ undo_redo->add_do_method(this,"_polygon_draw");
+ undo_redo->add_undo_method(this,"_polygon_draw");
wip.clear();
wip_active=false;
mode=MODE_EDIT;
button_edit->set_pressed(true);
button_create->set_pressed(false);
edited_point=-1;
+ undo_redo->commit_action();
+
}
-bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
+bool CollisionPolygonEditor::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) {
+
+
+ Transform gt = node->get_global_transform();
+ float depth = node->get_depth()*0.5;
+ Vector3 n = gt.basis.get_axis(2).normalized();
+ Plane p(gt.origin+n*depth,n);
switch(p_event.type) {
@@ -116,13 +133,20 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
const InputEventMouseButton &mb=p_event.mouse_button;
- Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Vector2 gpoint = Point2(mb.x,mb.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint=snap_point(cpoint);
- cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
+ Vector2 gpoint=Point2(mb.x,mb.y);
+ Vector3 ray_from = p_camera->project_ray_origin(gpoint);
+ Vector3 ray_dir = p_camera->project_ray_normal(gpoint);
+
+ Vector3 spoint;
+
+ if (!p.intersects_ray(ray_from,ray_dir,&spoint))
+ break;
+
+ Vector2 cpoint(spoint.x,spoint.y);
+
+ //cpoint=snap_point(cpoint); snap?
Vector<Vector2> poly = node->get_polygon();
@@ -143,13 +167,13 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
wip.push_back( cpoint );
wip_active=true;
edited_point_pos=cpoint;
- canvas_item_editor->get_viewport_control()->update();
+ _polygon_draw();
edited_point=1;
return true;
} else {
- if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) {
+ if (wip.size()>1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x,wip[0].y,depth))).distance_to(gpoint)<grab_treshold) {
//wip closed
_wip_close();
@@ -158,7 +182,7 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
wip.push_back( cpoint );
edited_point=wip.size();
- canvas_item_editor->get_viewport_control()->update();
+ _polygon_draw();
return true;
//add wip point
@@ -186,8 +210,8 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
undo_redo->add_undo_method(node,"set_polygon",poly);
poly.push_back(cpoint);
undo_redo->add_do_method(node,"set_polygon",poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_do_method(this,"_polygon_draw");
+ undo_redo->add_undo_method(this,"_polygon_draw");
undo_redo->commit_action();
return true;
}
@@ -198,8 +222,10 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
real_t closest_dist=1e10;
for(int i=0;i<poly.size();i++) {
- Vector2 points[2] ={ xform.xform(poly[i]),
- xform.xform(poly[(i+1)%poly.size()]) };
+ Vector2 points[2] ={
+ p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth))),
+ p_camera->unproject_position(gt.xform(Vector3(poly[(i+1)%poly.size()].x,poly[(i+1)%poly.size()].y,depth)))
+ };
Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points);
if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2)
@@ -218,11 +244,11 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
if (closest_idx>=0) {
pre_move_edit=poly;
- poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos));
+ poly.insert(closest_idx+1,cpoint);
edited_point=closest_idx+1;
- edited_point_pos=xform.affine_inverse().xform(closest_pos);
+ edited_point_pos=cpoint;
node->set_polygon(poly);
- canvas_item_editor->get_viewport_control()->update();
+ _polygon_draw();
return true;
}
} else {
@@ -234,7 +260,7 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
real_t closest_dist=1e10;
for(int i=0;i<poly.size();i++) {
- Vector2 cp =xform.xform(poly[i]);
+ Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth)));
real_t d = cp.distance_to(gpoint);
if (d<closest_dist && d<grab_treshold) {
@@ -249,8 +275,8 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
pre_move_edit=poly;
edited_point=closest_idx;
- edited_point_pos=xform.affine_inverse().xform(closest_pos);
- canvas_item_editor->get_viewport_control()->update();
+ edited_point_pos=poly[closest_idx];
+ _polygon_draw();
return true;
}
}
@@ -265,8 +291,8 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
undo_redo->create_action("Edit Poly");
undo_redo->add_do_method(node,"set_polygon",poly);
undo_redo->add_undo_method(node,"set_polygon",pre_move_edit);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_do_method(this,"_polygon_draw");
+ undo_redo->add_undo_method(this,"_polygon_draw");
undo_redo->commit_action();
edited_point=-1;
@@ -282,7 +308,7 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
real_t closest_dist=1e10;
for(int i=0;i<poly.size();i++) {
- Vector2 cp =xform.xform(poly[i]);
+ Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth)));
real_t d = cp.distance_to(gpoint);
if (d<closest_dist && d<grab_treshold) {
@@ -300,8 +326,8 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
undo_redo->add_undo_method(node,"set_polygon",poly);
poly.remove(closest_idx);
undo_redo->add_do_method(node,"set_polygon",poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_do_method(this,"_polygon_draw");
+ undo_redo->add_undo_method(this,"_polygon_draw");
undo_redo->commit_action();
return true;
}
@@ -323,11 +349,21 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) {
Vector2 gpoint = Point2(mm.x,mm.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint=snap_point(cpoint);
- edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
- canvas_item_editor->get_viewport_control()->update();
+ Vector3 ray_from = p_camera->project_ray_origin(gpoint);
+ Vector3 ray_dir = p_camera->project_ray_normal(gpoint);
+
+ Vector3 spoint;
+
+ if (!p.intersects_ray(ray_from,ray_dir,&spoint))
+ break;
+
+ Vector2 cpoint(spoint.x,spoint.y);
+
+ //cpoint=snap_point(cpoint);
+ edited_point_pos = cpoint;
+
+ _polygon_draw();
}
@@ -336,13 +372,11 @@ bool CollisionPolygonEditor::forward_input_event(const InputEvent& p_event) {
return false;
}
-void CollisionPolygonEditor::_canvas_draw() {
+void CollisionPolygonEditor::_polygon_draw() {
if (!node)
return;
- Control *vpc = canvas_item_editor->get_viewport_control();
-
Vector<Vector2> poly;
if (wip_active)
@@ -351,10 +385,16 @@ void CollisionPolygonEditor::_canvas_draw() {
poly=node->get_polygon();
- Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Ref<Texture> handle= get_icon("EditorHandle","EditorIcons");
int len = poly.size();
+ float depth = node->get_depth()*0.5;
+
+ imgeom->clear();
+ imgeom->set_material_override(line_material);
+ imgeom->begin(Mesh::PRIMITIVE_LINES,Ref<Texture>());
+
+
+ Rect2 rect;
for(int i=0;i<poly.size();i++) {
@@ -366,38 +406,127 @@ void CollisionPolygonEditor::_canvas_draw() {
else
p2 = poly[(i+1)%poly.size()];
- Vector2 point = xform.xform(p);
- Vector2 next_point = xform.xform(p2);
+ if (i==0)
+ rect.pos=p;
+ else
+ rect.expand_to(p);
+
+ Vector3 point = Vector3(p.x,p.y,depth);
+ Vector3 next_point = Vector3(p2.x,p2.y,depth);
+
+ imgeom->set_color(Color(1,0.3,0.1,0.8));
+ imgeom->add_vertex(point);
+ imgeom->set_color(Color(1,0.3,0.1,0.8));
+ imgeom->add_vertex(next_point);
- Color col=Color(1,0.3,0.1,0.8);
- vpc->draw_line(point,next_point,col,2);
- vpc->draw_texture(handle,point-handle->get_size()*0.5);
+ //Color col=Color(1,0.3,0.1,0.8);
+ //vpc->draw_line(point,next_point,col,2);
+ //vpc->draw_texture(handle,point-handle->get_size()*0.5);
}
+
+ rect=rect.grow(1);
+
+ AABB r;
+ r.pos.x=rect.pos.x;
+ r.pos.y=rect.pos.y;
+ r.pos.z=depth;
+ r.size.x=rect.size.x;
+ r.size.y=rect.size.y;
+ r.size.z=0;
+
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos);
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(0.3,0,0));
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos);
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(0.0,0.3,0));
+
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0));
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)-Vector3(0.3,0,0));
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0));
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)+Vector3(0,0.3,0));
+
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0));
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)-Vector3(0,0.3,0));
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0));
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)+Vector3(0.3,0,0));
+
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+r.size);
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+r.size-Vector3(0.3,0,0));
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+r.size);
+ imgeom->set_color(Color(0.8,0.8,0.8,0.2));
+ imgeom->add_vertex(r.pos+r.size-Vector3(0.0,0.3,0));
+
+ imgeom->end();
+
+
+ while(m->get_surface_count()) {
+ m->surface_remove(0);
+ }
+
+ if (poly.size()==0)
+ return;
+
+ Array a;
+ a.resize(Mesh::ARRAY_MAX);
+ DVector<Vector3> va;
+ {
+
+ va.resize(poly.size());
+ DVector<Vector3>::Write w=va.write();
+ for(int i=0;i<poly.size();i++) {
+
+
+ Vector2 p,p2;
+ p = i==edited_point ? edited_point_pos : poly[i];
+
+ Vector3 point = Vector3(p.x,p.y,depth);
+ w[i]=point;
+ }
+ }
+ a[Mesh::ARRAY_VERTEX]=va;
+ m->add_surface(Mesh::PRIMITIVE_POINTS,a);
+ m->surface_set_material(0,handle_material);
+
}
void CollisionPolygonEditor::edit(Node *p_collision_polygon) {
- if (!canvas_item_editor) {
- canvas_item_editor=CanvasItemEditor::get_singleton();
- }
+
if (p_collision_polygon) {
- node=p_collision_polygon->cast_to<CollisionPolygon2D>();
- if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
- canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw");
+ node=p_collision_polygon->cast_to<CollisionPolygon>();
wip.clear();
wip_active=false;
edited_point=-1;
+ p_collision_polygon->add_child(imgeom);
+ _polygon_draw();
+ set_process(true);
+ prev_depth=-1;
} else {
node=NULL;
- if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
- canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw");
+ if (imgeom->get_parent())
+ imgeom->get_parent()->remove_child(imgeom);
+ set_process(false);
}
}
@@ -405,13 +534,14 @@ void CollisionPolygonEditor::edit(Node *p_collision_polygon) {
void CollisionPolygonEditor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_menu_option"),&CollisionPolygonEditor::_menu_option);
- ObjectTypeDB::bind_method(_MD("_canvas_draw"),&CollisionPolygonEditor::_canvas_draw);
+ ObjectTypeDB::bind_method(_MD("_polygon_draw"),&CollisionPolygonEditor::_polygon_draw);
+ ObjectTypeDB::bind_method(_MD("_node_removed"),&CollisionPolygonEditor::_node_removed);
}
CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) {
- canvas_item_editor=NULL;
+
editor=p_editor;
undo_redo = editor->get_undo_redo();
@@ -439,7 +569,42 @@ CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) {
mode = MODE_EDIT;
wip_active=false;
+ imgeom = memnew( ImmediateGeometry );
+ imgeom->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001)));
+
+
+ line_material = Ref<FixedMaterial>( 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,Color(1,1,1));
+
+
+
+
+ handle_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+ handle_material->set_flag(Material::FLAG_UNSHADED, true);
+ handle_material->set_fixed_flag(FixedMaterial::FLAG_USE_POINT_SIZE, true);
+ handle_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1));
+ handle_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+ handle_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, false);
+ Ref<Texture> handle= SpatialEditor::get_singleton()->get_icon("Editor3DHandle","EditorIcons");
+ handle_material->set_point_size(handle->get_width());
+ handle_material->set_texture(FixedMaterial::PARAM_DIFFUSE,handle);
+
+ pointsm = memnew( MeshInstance );
+ imgeom->add_child(pointsm);
+ m = Ref<Mesh>( memnew( Mesh ) );
+ pointsm->set_mesh(m);
+ pointsm->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001)));
+
+
+}
+
+CollisionPolygonEditor::~CollisionPolygonEditor() {
+ memdelete( imgeom );
}
@@ -450,7 +615,7 @@ void CollisionPolygonEditorPlugin::edit(Object *p_object) {
bool CollisionPolygonEditorPlugin::handles(Object *p_object) const {
- return p_object->is_type("CollisionPolygon2D");
+ return p_object->is_type("CollisionPolygon");
}
void CollisionPolygonEditorPlugin::make_visible(bool p_visible) {
@@ -469,7 +634,7 @@ CollisionPolygonEditorPlugin::CollisionPolygonEditorPlugin(EditorNode *p_node) {
editor=p_node;
collision_polygon_editor = memnew( CollisionPolygonEditor(p_node) );
- CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor);
+ SpatialEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor);
collision_polygon_editor->hide();
diff --git a/tools/editor/plugins/collision_polygon_editor_plugin.h b/tools/editor/plugins/collision_polygon_editor_plugin.h
index a05ac0f8c8..54b0706149 100644
--- a/tools/editor/plugins/collision_polygon_editor_plugin.h
+++ b/tools/editor/plugins/collision_polygon_editor_plugin.h
@@ -31,7 +31,9 @@
#include "tools/editor/editor_plugin.h"
#include "tools/editor/editor_node.h"
-#include "scene/2d/collision_polygon_2d.h"
+#include "scene/3d/collision_polygon.h"
+#include "scene/3d/immediate_geometry.h"
+#include "scene/3d/mesh_instance.h"
#include "scene/gui/tool_button.h"
#include "scene/gui/button_group.h"
@@ -57,10 +59,17 @@ class CollisionPolygonEditor : public HBoxContainer {
ToolButton *button_create;
ToolButton *button_edit;
- CanvasItemEditor *canvas_item_editor;
+
+ Ref<FixedMaterial> line_material;
+ Ref<FixedMaterial> handle_material;
+
EditorNode *editor;
Panel *panel;
- CollisionPolygon2D *node;
+ CollisionPolygon *node;
+ ImmediateGeometry *imgeom;
+ MeshInstance *pointsm;
+ Ref<Mesh> m;
+
MenuButton *options;
int edited_point;
@@ -69,9 +78,10 @@ class CollisionPolygonEditor : public HBoxContainer {
Vector<Vector2> wip;
bool wip_active;
+ float prev_depth;
void _wip_close();
- void _canvas_draw();
+ void _polygon_draw();
void _menu_option(int p_option);
protected:
@@ -81,9 +91,10 @@ protected:
public:
Vector2 snap_point(const Vector2& p_point) const;
- bool forward_input_event(const InputEvent& p_event);
+ virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event);
void edit(Node *p_collision_polygon);
CollisionPolygonEditor(EditorNode *p_editor);
+ ~CollisionPolygonEditor();
};
class CollisionPolygonEditorPlugin : public EditorPlugin {
@@ -95,7 +106,7 @@ class CollisionPolygonEditorPlugin : public EditorPlugin {
public:
- virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); }
+ virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) { return collision_polygon_editor->forward_spatial_input_event(p_camera,p_event); }
virtual String get_name() const { return "CollisionPolygon"; }
bool has_main_screen() const { return false; }
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index 31ccc79d2a..209434440d 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -1102,7 +1102,6 @@ void ScriptEditor::ensure_select_current() {
if (!ste)
return;
Ref<Script> script = ste->get_edited_script();
- editor->call("_resource_selected",script);
}
}
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index e9020c91f5..a097d7c211 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -38,7 +38,7 @@
#include "tools/editor/editor_settings.h"
#include "scene/resources/surface_tool.h"
#include "tools/editor/spatial_editor_gizmos.h"
-
+#include "globals.h"
#define DISTANCE_DEFAULT 4
@@ -690,10 +690,16 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
case BUTTON_WHEEL_UP: {
+
cursor.distance/=1.08;
+ if (cursor.distance<0.001)
+ cursor.distance=0.001;
+
} break;
case BUTTON_WHEEL_DOWN: {
+ if (cursor.distance<0.001)
+ cursor.distance=0.001;
cursor.distance*=1.08;
} break;
@@ -1753,6 +1759,41 @@ void SpatialEditorViewport::_draw() {
}
+ if (previewing) {
+
+
+ Size2 ss = Size2( Globals::get_singleton()->get("display/width"), Globals::get_singleton()->get("display/height") );
+ float aspect = ss.get_aspect();
+ Size2 s = get_size();
+
+ Rect2 draw_rect;
+
+
+ switch(previewing->get_keep_aspect_mode()) {
+ case Camera::KEEP_WIDTH: {
+
+ draw_rect.size = Size2(s.width,s.width/aspect);
+ draw_rect.pos.x=0;
+ draw_rect.pos.y=(s.height-draw_rect.size.y)*0.5;
+
+ } break;
+ case Camera::KEEP_HEIGHT: {
+
+ draw_rect.size = Size2(s.height*aspect,s.height);
+ draw_rect.pos.y=0;
+ draw_rect.pos.x=(s.width-draw_rect.size.x)*0.5;
+
+ } break;
+ }
+
+ draw_rect = Rect2(Vector2(),s).clip(draw_rect);
+
+ surface->draw_line(draw_rect.pos,draw_rect.pos+Vector2(draw_rect.size.x,0),Color(0.6,0.6,0.1,0.5),2.0);
+ surface->draw_line(draw_rect.pos+Vector2(draw_rect.size.x,0),draw_rect.pos+draw_rect.size,Color(0.6,0.6,0.1,0.5),2.0);
+ surface->draw_line(draw_rect.pos+draw_rect.size,draw_rect.pos+Vector2(0,draw_rect.size.y),Color(0.6,0.6,0.1,0.5),2.0);
+ surface->draw_line(draw_rect.pos,draw_rect.pos+Vector2(0,draw_rect.size.y),Color(0.6,0.6,0.1,0.5),2.0);
+ }
+
}
@@ -1936,6 +1977,7 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
if (!preview)
preview_camera->hide();
view_menu->show();
+ surface->update();
} else {
@@ -1943,6 +1985,7 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
previewing->connect("exit_scene",this,"_preview_exited_scene");
VS::get_singleton()->viewport_attach_camera( viewport->get_viewport(), preview->get_camera() ); //replace
view_menu->hide();
+ surface->update();
}
}
diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp
index d757a4c07d..22331c86bf 100644
--- a/tools/editor/project_export.cpp
+++ b/tools/editor/project_export.cpp
@@ -1336,6 +1336,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
file_export = memnew( FileDialog );
add_child(file_export);
file_export->set_access(FileDialog::ACCESS_FILESYSTEM);
+ file_export->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_export_path") );
file_export->set_title("Export Project");
file_export->connect("file_selected", this,"_export_action");
@@ -1353,6 +1354,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
pck_export = memnew( FileDialog );
pck_export->set_access(FileDialog::ACCESS_FILESYSTEM);
+ pck_export->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_export_path") );
pck_export->set_title("Export Project PCK");
pck_export->connect("file_selected", this,"_export_action_pck");
pck_export->add_filter("*.pck ; Data Pack");
diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp
index cd28c6da97..26d7abb745 100644
--- a/tools/editor/project_manager.cpp
+++ b/tools/editor/project_manager.cpp
@@ -900,6 +900,7 @@ ProjectManager::ProjectManager() {
scan_dir = memnew( FileDialog );
scan_dir->set_access(FileDialog::ACCESS_FILESYSTEM);
scan_dir->set_mode(FileDialog::MODE_OPEN_DIR);
+ scan_dir->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_path") );
add_child(scan_dir);
scan_dir->connect("dir_selected",this,"_scan_begin");
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 4ac2ff0594..645d967a4b 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -38,6 +38,7 @@
#include "scene/scene_string_names.h"
#include "editor_settings.h"
#include "editor_import_export.h"
+#include "editor_node.h"
void CustomPropertyEditor::_notification(int p_what) {
@@ -1619,6 +1620,7 @@ CustomPropertyEditor::CustomPropertyEditor() {
scene_tree = memnew( SceneTreeDialog );
add_child(scene_tree);
scene_tree->connect("selected", this,"_node_path_selected");
+ scene_tree->get_tree()->set_show_enabled_subscene(true);
texture_preview = memnew( TextureFrame );
add_child( texture_preview);
@@ -2037,6 +2039,17 @@ void PropertyEditor::update_tree() {
List<PropertyInfo> plist;
obj->get_property_list(&plist,true);
+ bool draw_red=false;
+
+ {
+ Node *nod = obj->cast_to<Node>();
+ Node *es = EditorNode::get_singleton()->get_edited_scene();
+ if (nod && es!=nod && nod->get_owner()!=es) {
+ draw_red=true;
+ }
+ }
+
+
Color sscolor=get_color("prop_subsection","Editor");
TreeItem * current_category=NULL;
@@ -2141,11 +2154,16 @@ void PropertyEditor::update_tree() {
item->set_metadata( 0, d );
item->set_metadata( 1, p.name );
+
+ if (draw_red)
+ item->set_custom_color(0,Color(0.8,0.4,0.20));
+
if (p.name==selected_property) {
item->select(1);
}
+
//printf("property %s type %i\n",p.name.ascii().get_data(),p.type);
switch( p.type ) {
diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp
index c4c3a10f74..e7f4beb46e 100644
--- a/tools/editor/scene_tree_dock.cpp
+++ b/tools/editor/scene_tree_dock.cpp
@@ -108,6 +108,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
case TOOL_NEW: {
+
+ if (!_validate_no_foreign())
+ break;
create_dialog->popup_centered_ratio();
} break;
case TOOL_INSTANCE: {
@@ -124,6 +127,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
+ if (!_validate_no_foreign())
+ break;
+
file->set_mode(FileDialog::MODE_OPEN_FILE);
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions);
@@ -147,6 +153,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!current)
break;
+ if (!_validate_no_foreign())
+ break;
connect_dialog->popup_centered_ratio();
connect_dialog->set_node(current);
@@ -156,6 +164,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *current = scene_tree->get_selected();
if (!current)
break;
+ if (!_validate_no_foreign())
+ break;
groups_editor->set_current(current);
groups_editor->popup_centered_ratio();
} break;
@@ -165,6 +175,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!selected)
break;
+ if (!_validate_no_foreign())
+ break;
+
Ref<Script> existing = selected->get_script();
if (existing.is_valid())
editor->push_item(existing.ptr());
@@ -183,6 +196,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!scene_tree->get_selected())
break;
+
if (scene_tree->get_selected()==edited_scene) {
@@ -195,6 +209,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
+ if (!_validate_no_foreign())
+ break;
+
Node * node=scene_tree->get_selected();
ERR_FAIL_COND(!node->get_parent());
int current_pos = node->get_index();
@@ -214,6 +231,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!edited_scene)
break;
+
if (editor_selection->is_selected(edited_scene)) {
@@ -225,6 +243,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
+ if (!_validate_no_foreign())
+ break;
+
List<Node*> selection = editor_selection->get_selected_node_list();
List<Node*> reselect;
@@ -313,6 +334,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!scene_tree->get_selected())
break;
+
if (editor_selection->is_selected(edited_scene)) {
@@ -324,6 +346,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
+ if (!_validate_no_foreign())
+ break;
+
List<Node*> nodes = editor_selection->get_selected_node_list();
Set<Node*> nodeset;
for(List<Node*>::Element *E=nodes.front();E;E=E->next()) {
@@ -341,6 +366,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (remove_list.empty())
return;
+ if (!_validate_no_foreign())
+ break;
+
if (p_confirm_override) {
_delete_confirm();
@@ -707,6 +735,25 @@ void SceneTreeDock::_node_prerenamed(Node* p_node, const String& p_new_name) {
}
+bool SceneTreeDock::_validate_no_foreign() {
+
+ List<Node*> selection = editor_selection->get_selected_node_list();
+
+ for (List<Node*>::Element *E=selection.front();E;E=E->next()) {
+
+ if (E->get()!=edited_scene && E->get()->get_owner()!=edited_scene) {
+
+ accept->get_ok()->set_text("Makes Sense!");
+ accept->set_text("Can't operate on nodes from a foreign scene!");
+ accept->popup_centered(Size2(300,70));;
+ return false;
+
+ }
+ }
+
+ return true;
+}
+
void SceneTreeDock::_node_reparent(NodePath p_path,bool p_node_only) {
@@ -894,7 +941,7 @@ void SceneTreeDock::_delete_confirm() {
void SceneTreeDock::_update_tool_buttons() {
Node *sel = scene_tree->get_selected();
- bool disable = !sel;
+ bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene);
bool disable_root = disable || sel->get_parent()==scene_root;
tool_buttons[TOOL_INSTANCE]->set_disabled(disable);
diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h
index 99ef16e6f6..e55a54377a 100644
--- a/tools/editor/scene_tree_dock.h
+++ b/tools/editor/scene_tree_dock.h
@@ -115,6 +115,7 @@ class SceneTreeDock : public VBoxContainer {
void _import_subscene();
+ bool _validate_no_foreign();
void _fill_path_renames(Vector<StringName> base_path,Vector<StringName> new_base_path,Node * p_node, List<Pair<NodePath,NodePath> > *p_renames);
diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp
index e0202be84e..59bc24487a 100644
--- a/tools/editor/scene_tree_editor.cpp
+++ b/tools/editor/scene_tree_editor.cpp
@@ -45,6 +45,40 @@ Node *SceneTreeEditor::get_scene_node() {
return NULL;
}
+
+void SceneTreeEditor::_subscene_option(int p_idx) {
+
+ Object *obj = ObjectDB::get_instance(instance_node);
+ if (!obj)
+ return;
+ Node *node = obj->cast_to<Node>();
+ if (!node)
+ return;
+
+ switch(p_idx) {
+
+ case SCENE_MENU_SHOW_CHILDREN: {
+
+ if (node->has_meta("__editor_show_subtree")) {
+ instance_menu->set_item_checked(0,true);
+ node->set_meta("__editor_show_subtree",Variant());
+ _update_tree();
+ } else {
+ node->set_meta("__editor_show_subtree",true);
+ _update_tree();
+ }
+
+ } break;
+ case SCENE_MENU_OPEN: {
+
+ emit_signal("open",node->get_filename());
+ } break;
+
+ }
+
+}
+
+
void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id) {
TreeItem *item=p_item->cast_to<TreeItem>();
@@ -57,7 +91,19 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id)
if (p_id==BUTTON_SUBSCENE) {
//open scene request
- emit_signal("open",n->get_filename());
+ Rect2 item_rect = tree->get_item_rect(item,0);
+ item_rect.pos.y-=tree->get_scroll().y;
+ item_rect.pos+=tree->get_global_pos();
+ instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
+ instance_menu->set_size(Vector2(item_rect.size.x,0));
+ if (n->has_meta("__editor_show_subtree"))
+ instance_menu->set_item_checked(0,true);
+ else
+ instance_menu->set_item_checked(0,false);
+
+ instance_menu->popup();
+ instance_node=n->get_instance_ID();
+ //emit_signal("open",n->get_filename());
} else if (p_id==BUTTON_SCRIPT) {
RefPtr script=n->get_script();
if (!script.is_null())
@@ -119,9 +165,19 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
// only owned nodes are editable, since nodes can create their own (manually owned) child nodes,
// which the editor needs not to know about.
-
- if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node())
- return;
+
+ bool part_of_subscene=false;
+
+ if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) {
+
+ if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && p_node->get_owner()->get_owner()==get_scene_node() && p_node->get_owner()->has_meta("__editor_show_subtree")) {
+
+ part_of_subscene=true;
+ //allow
+ } else {
+ return;
+ }
+ }
TreeItem *item = tree->create_item(p_parent);
item->set_text(0, p_node->get_name() );
@@ -143,8 +199,12 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
icon=get_icon( (has_icon(p_node->get_type(),"EditorIcons")?p_node->get_type():String("Object")),"EditorIcons");
item->set_icon(0, icon );
item->set_metadata( 0,p_node->get_path() );
-
- if (marked.has(p_node)) {
+ if (part_of_subscene) {
+
+ //item->set_selectable(0,marked_selectable);
+ item->set_custom_color(0,Color(0.8,0.4,0.20));
+
+ } else if (marked.has(p_node)) {
item->set_selectable(0,marked_selectable);
item->set_custom_color(0,Color(0.8,0.1,0.10));
@@ -163,7 +223,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) {
- item->add_button(0,get_icon("Load","EditorIcons"),BUTTON_SUBSCENE);
+ item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE);
item->set_tooltip(0,"Instance: "+p_node->get_filename());
}
@@ -425,6 +485,7 @@ void SceneTreeEditor::_notification(int p_what) {
get_scene()->connect("tree_changed",this,"_tree_changed");
get_scene()->connect("node_removed",this,"_node_removed");
+ instance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
tree->connect("item_collapsed",this,"_cell_collapsed");
// get_scene()->connect("tree_changed",this,"_tree_changed",Vector<Variant>(),CONNECT_DEFERRED);
@@ -646,6 +707,7 @@ void SceneTreeEditor::_cell_collapsed(Object *p_obj) {
}
+
void SceneTreeEditor::_bind_methods() {
ObjectTypeDB::bind_method("_tree_changed",&SceneTreeEditor::_tree_changed);
@@ -659,6 +721,7 @@ void SceneTreeEditor::_bind_methods() {
ObjectTypeDB::bind_method("_selection_changed",&SceneTreeEditor::_selection_changed);
ObjectTypeDB::bind_method("_cell_button_pressed",&SceneTreeEditor::_cell_button_pressed);
ObjectTypeDB::bind_method("_cell_collapsed",&SceneTreeEditor::_cell_collapsed);
+ ObjectTypeDB::bind_method("_subscene_option",&SceneTreeEditor::_subscene_option);
ObjectTypeDB::bind_method("_node_script_changed",&SceneTreeEditor::_node_script_changed);
ObjectTypeDB::bind_method("_node_visibility_changed",&SceneTreeEditor::_node_visibility_changed);
@@ -714,10 +777,20 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
error = memnew( AcceptDialog );
add_child(error);
+ show_enabled_subscene=false;
+
last_hash=0;
pending_test_update=false;
updating_tree=false;
blocked=0;
+
+ instance_menu = memnew( PopupMenu );
+ instance_menu->add_check_item("Show Children",SCENE_MENU_SHOW_CHILDREN);
+ instance_menu->add_separator();
+ instance_menu->add_item("Open in Editor",SCENE_MENU_OPEN);
+ instance_menu->connect("item_pressed",this,"_subscene_option");
+ add_child(instance_menu);
+
}
diff --git a/tools/editor/scene_tree_editor.h b/tools/editor/scene_tree_editor.h
index 19375ba638..5e88c5a41d 100644
--- a/tools/editor/scene_tree_editor.h
+++ b/tools/editor/scene_tree_editor.h
@@ -51,8 +51,15 @@ class SceneTreeEditor : public Control {
BUTTON_GROUP=4,
};
+ enum {
+ SCENE_MENU_SHOW_CHILDREN,
+ SCENE_MENU_OPEN,
+ };
+
Tree *tree;
Node *selected;
+ PopupMenu *instance_menu;
+ ObjectID instance_node;
AcceptDialog *error;
@@ -78,6 +85,7 @@ class SceneTreeEditor : public Control {
bool can_rename;
bool can_open_instance;
bool updating_tree;
+ bool show_enabled_subscene;
void _renamed();
UndoRedo *undo_redo;
@@ -95,6 +103,7 @@ class SceneTreeEditor : public Control {
void _update_selection(TreeItem *item);
void _node_script_changed(Node *p_node);
void _node_visibility_changed(Node *p_node);
+ void _subscene_option(int p_idx);
void _selection_changed();
Node *get_scene_node();
@@ -112,6 +121,8 @@ public:
void set_can_rename(bool p_can_rename) { can_rename=p_can_rename; }
void set_editor_selection(EditorSelection *p_selection);
+ void set_show_enabled_subscene(bool p_show) { show_enabled_subscene=p_show; }
+
void update_tree() { _update_tree(); }
SceneTreeEditor(bool p_label=true,bool p_can_rename=false, bool p_can_open_instance=false);
diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp
index c5bf43884e..082878655c 100644
--- a/tools/editor/spatial_editor_gizmos.cpp
+++ b/tools/editor/spatial_editor_gizmos.cpp
@@ -1538,6 +1538,70 @@ CarWheelSpatialGizmo::CarWheelSpatialGizmo(CarWheel* p_car_wheel){
}
+/////
+
+
+void VehicleWheelSpatialGizmo::redraw() {
+
+ clear();
+
+
+ Vector<Vector3> 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;j<springsec;j++) {
+ float t = car_wheel->get_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;
+}
+
+
///
@@ -2002,7 +2066,39 @@ CollisionShapeSpatialGizmo::CollisionShapeSpatialGizmo(CollisionShape* p_cs) {
+/////
+
+
+void CollisionPolygonSpatialGizmo::redraw() {
+ clear();
+
+ Vector<Vector2> points = polygon->get_polygon();
+ float depth = polygon->get_depth()*0.5;
+
+ Vector<Vector3> lines;
+ for(int i=0;i<points.size();i++) {
+
+ int n = (i+1)%points.size();
+ lines.push_back(Vector3(points[i].x,points[i].y,depth));
+ lines.push_back(Vector3(points[n].x,points[n].y,depth));
+ lines.push_back(Vector3(points[i].x,points[i].y,-depth));
+ lines.push_back(Vector3(points[n].x,points[n].y,-depth));
+ lines.push_back(Vector3(points[i].x,points[i].y,depth));
+ lines.push_back(Vector3(points[i].x,points[i].y,-depth));
+
+ }
+
+ add_lines(lines,SpatialEditorGizmos::singleton->shape_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 {
@@ -2196,8 +2292,518 @@ NavigationMeshSpatialGizmo::NavigationMeshSpatialGizmo(NavigationMeshInstance *p
navmesh=p_navmesh;
}
+//////
+///
+///
+
+
+
+void PinJointSpatialGizmo::redraw() {
+
+ clear();
+ Vector<Vector3> 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<Vector3> 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) && ll<ul) {
+
+ const int points = 32;
+ float step = (ul-ll)/points;
+
+
+ for(int i=0;i<points;i++) {
+
+ float s = ll+i*(ul-ll)/points;
+ float n = ll+(i+1)*(ul-ll)/points;
+
+ Vector3 from=Vector3( -Math::sin(s),Math::cos(s), 0 )*cs;
+ Vector3 to=Vector3( -Math::sin(n),Math::cos(n), 0 )*cs;
+
+ if (i==points-1) {
+ cursor_points.push_back(to);
+ cursor_points.push_back(Vector3());
+ }
+ if (i==0) {
+ cursor_points.push_back(from);
+ cursor_points.push_back(Vector3());
+ }
+
+
+ cursor_points.push_back(from);
+ cursor_points.push_back(to);
+
+
+ }
+
+ cursor_points.push_back(Vector3(0,cs*1.5,0));
+ cursor_points.push_back(Vector3());
+
+ } else {
+
+
+ const int points = 32;
+
+ for(int i=0;i<points;i++) {
+
+ float s = ll+i*(Math_PI*2.0)/points;
+ float n = ll+(i+1)*(Math_PI*2.0)/points;
+
+ Vector3 from=Vector3( -Math::sin(s),Math::cos(s), 0 )*cs;
+ Vector3 to=Vector3( -Math::sin(n),Math::cos(n), 0 )*cs;
+
+ cursor_points.push_back(from);
+ cursor_points.push_back(to);
+
+ }
+
+ }
+ add_collision_segments(cursor_points);
+ add_lines(cursor_points,SpatialEditorGizmos::singleton->joint_material);
+
+}
+
+
+HingeJointSpatialGizmo::HingeJointSpatialGizmo(HingeJoint* p_p3d) {
+
+ p3d=p_p3d;
+ set_spatial_node(p3d);
+}
+
+///////
+///
+////
+
+void SliderJointSpatialGizmo::redraw() {
+
+ clear();
+ Vector<Vector3> 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 (ll<ul) {
+
+ const int points = 32;
+ float step = (ul-ll)/points;
+
+
+ for(int i=0;i<points;i++) {
+
+ float s = ll+i*(ul-ll)/points;
+ float n = ll+(i+1)*(ul-ll)/points;
+
+ Vector3 from=Vector3(0, Math::cos(s), -Math::sin(s) )*cs;
+ Vector3 to=Vector3(0,Math::cos(n), -Math::sin(n) )*cs;
+
+ if (i==points-1) {
+ cursor_points.push_back(to);
+ cursor_points.push_back(Vector3());
+ }
+ if (i==0) {
+ cursor_points.push_back(from);
+ cursor_points.push_back(Vector3());
+ }
+
+
+ cursor_points.push_back(from);
+ cursor_points.push_back(to);
+
+
+ }
+
+ cursor_points.push_back(Vector3(0,cs*1.5,0));
+ cursor_points.push_back(Vector3());
+
+ } else {
+
+
+ const int points = 32;
+
+ for(int i=0;i<points;i++) {
+
+ float s = ll+i*(Math_PI*2.0)/points;
+ float n = ll+(i+1)*(Math_PI*2.0)/points;
+
+ Vector3 from=Vector3(0,Math::cos(s),-Math::sin(s) )*cs;
+ Vector3 to=Vector3( 0,Math::cos(n),-Math::sin(n) )*cs;
+
+ cursor_points.push_back(from);
+ cursor_points.push_back(to);
+
+ }
+
+ }
+ add_collision_segments(cursor_points);
+ add_lines(cursor_points,SpatialEditorGizmos::singleton->joint_material);
+
+}
+
+
+SliderJointSpatialGizmo::SliderJointSpatialGizmo(SliderJoint* p_p3d) {
+
+ p3d=p_p3d;
+ set_spatial_node(p3d);
+}
+
+///////
+///
+////
+
+void ConeTwistJointSpatialGizmo::redraw() {
+
+ clear();
+ float cs = 0.25;
+ Vector<Vector3> 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;i<int(ts);i+=5) {
+
+ float ra=Math::deg2rad(i);
+ float rb=Math::deg2rad(i+5);
+ float c = i/720.0;
+ float cn = (i+5)/720.0;
+ Point2 a = Vector2(Math::sin(ra),Math::cos(ra))*w*c;
+ Point2 b = Vector2(Math::sin(rb),Math::cos(rb))*w*cn;
+
+ /*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(c,a.x,a.y));
+ points.push_back(Vector3(cn,b.x,b.y));
+
+ }
+
+
+ add_collision_segments(points);
+ add_lines(points,SpatialEditorGizmos::singleton->joint_material);
+
+}
+
+
+ConeTwistJointSpatialGizmo::ConeTwistJointSpatialGizmo(ConeTwistJoint* p_p3d) {
+
+ p3d=p_p3d;
+ set_spatial_node(p3d);
+}
////////
+/// \brief SpatialEditorGizmos::singleton
+///
+///////
+///
+////
+
+void Generic6DOFJointSpatialGizmo::redraw() {
+
+ clear();
+ Vector<Vector3> 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;i<points;i++) {
+
+ float s = ll+i*(ul-ll)/points;
+ float n = ll+(i+1)*(ul-ll)/points;
+
+ Vector3 from;
+ SET_VTX(from,0, Math::cos(s), -Math::sin(s) );
+ from*=cs;
+ Vector3 to;
+ SET_VTX(to,0,Math::cos(n), -Math::sin(n));
+ to*=cs;
+
+ if (i==points-1) {
+ cursor_points.push_back(to);
+ cursor_points.push_back(Vector3());
+ }
+ if (i==0) {
+ cursor_points.push_back(from);
+ cursor_points.push_back(Vector3());
+ }
+
+
+ cursor_points.push_back(from);
+ cursor_points.push_back(to);
+
+
+ }
+
+ ADD_VTX(0,cs*1.5,0);
+ cursor_points.push_back(Vector3());
+
+ } else {
+
+
+ const int points = 32;
+
+ for(int i=0;i<points;i++) {
+
+ float s = ll+i*(Math_PI*2.0)/points;
+ float n = ll+(i+1)*(Math_PI*2.0)/points;
+
+// Vector3 from=Vector3(0,Math::cos(s),-Math::sin(s) )*cs;
+// Vector3 to=Vector3( 0,Math::cos(n),-Math::sin(n) )*cs;
+
+ Vector3 from;
+ SET_VTX(from,0, Math::cos(s), -Math::sin(s) );
+ from*=cs;
+ Vector3 to;
+ SET_VTX(to,0,Math::cos(n), -Math::sin(n));
+ to*=cs;
+
+ cursor_points.push_back(from);
+ cursor_points.push_back(to);
+
+ }
+
+ }
+ }
+
+#undef ADD_VTX
+#undef SET_VTX
+
+ add_collision_segments(cursor_points);
+ add_lines(cursor_points,SpatialEditorGizmos::singleton->joint_material);
+
+}
+
+
+Generic6DOFJointSpatialGizmo::Generic6DOFJointSpatialGizmo(Generic6DOFJoint* p_p3d) {
+
+ p3d=p_p3d;
+ set_spatial_node(p3d);
+}
+
+///////
+///
+////
+
+
SpatialEditorGizmos *SpatialEditorGizmos::singleton=NULL;
Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
@@ -2292,6 +2898,47 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
Ref<CarWheelSpatialGizmo> misg = memnew( CarWheelSpatialGizmo(p_spatial->cast_to<CarWheel>()) );
return misg;
}
+ if (p_spatial->cast_to<VehicleWheel>()) {
+
+ Ref<VehicleWheelSpatialGizmo> misg = memnew( VehicleWheelSpatialGizmo(p_spatial->cast_to<VehicleWheel>()) );
+ return misg;
+ }
+ if (p_spatial->cast_to<PinJoint>()) {
+
+ Ref<PinJointSpatialGizmo> misg = memnew( PinJointSpatialGizmo(p_spatial->cast_to<PinJoint>()) );
+ return misg;
+ }
+
+ if (p_spatial->cast_to<HingeJoint>()) {
+
+ Ref<HingeJointSpatialGizmo> misg = memnew( HingeJointSpatialGizmo(p_spatial->cast_to<HingeJoint>()) );
+ return misg;
+ }
+
+ if (p_spatial->cast_to<SliderJoint>()) {
+
+ Ref<SliderJointSpatialGizmo> misg = memnew( SliderJointSpatialGizmo(p_spatial->cast_to<SliderJoint>()) );
+ return misg;
+ }
+
+ if (p_spatial->cast_to<ConeTwistJoint>()) {
+
+ Ref<ConeTwistJointSpatialGizmo> misg = memnew( ConeTwistJointSpatialGizmo(p_spatial->cast_to<ConeTwistJoint>()) );
+ return misg;
+ }
+
+ if (p_spatial->cast_to<Generic6DOFJoint>()) {
+
+ Ref<Generic6DOFJointSpatialGizmo> misg = memnew( Generic6DOFJointSpatialGizmo(p_spatial->cast_to<Generic6DOFJoint>()) );
+ return misg;
+ }
+
+ if (p_spatial->cast_to<CollisionPolygon>()) {
+
+ Ref<CollisionPolygonSpatialGizmo> misg = memnew( CollisionPolygonSpatialGizmo(p_spatial->cast_to<CollisionPolygon>()) );
+ return misg;
+ }
+
return Ref<SpatialEditorGizmo>();
}
@@ -2425,6 +3072,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
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<FixedMaterial>( memnew( FixedMaterial ));
stream_player_icon->set_flag(Material::FLAG_UNSHADED, true);
diff --git a/tools/editor/spatial_editor_gizmos.h b/tools/editor/spatial_editor_gizmos.h
index e5c3417166..ac31eb19e9 100644
--- a/tools/editor/spatial_editor_gizmos.h
+++ b/tools/editor/spatial_editor_gizmos.h
@@ -45,6 +45,9 @@
#include "scene/3d/ray_cast.h"
#include "scene/3d/navigation_mesh.h"
#include "scene/3d/car_body.h"
+#include "scene/3d/vehicle_body.h"
+#include "scene/3d/collision_polygon.h"
+#include "scene/3d/physics_joint.h"
class Camera;
@@ -300,6 +303,21 @@ public:
};
+
+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);
@@ -328,6 +346,20 @@ public:
};
+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);
@@ -353,6 +385,74 @@ public:
};
+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:
@@ -370,6 +470,7 @@ public:
Ref<FixedMaterial> raycast_material;
Ref<FixedMaterial> visibility_notifier_material;
Ref<FixedMaterial> car_wheel_material;
+ Ref<FixedMaterial> joint_material;
Ref<FixedMaterial> navmesh_edge_material;
Ref<FixedMaterial> navmesh_solid_material;
diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py
index ec907a998d..cd785fca40 100644
--- a/tools/export/blender25/io_scene_dae/export_dae.py
+++ b/tools/export/blender25/io_scene_dae/export_dae.py
@@ -317,14 +317,14 @@ class DaeExporter:
def export_mesh(self,node,armature=None):
+ if (node.data in self.mesh_cache):
+ return self.mesh_cache[mesh]
+
if (len(node.modifiers) and self.config["use_mesh_modifiers"]):
mesh=node.to_mesh(self.scene,True,"RENDER") #is this allright?
else:
mesh=node.data
- if (mesh in self.mesh_cache):
- return self.mesh_cache[mesh]
-
mesh.update(calc_tessface=True)
vertices=[]
vertex_map={}
@@ -519,7 +519,7 @@ class DaeExporter:
meshdata={}
meshdata["id"]=meshid
meshdata["material_assign"]=mat_assign
- self.mesh_cache[mesh]=meshdata
+ self.mesh_cache[node.data]=meshdata
# Export armature data (if armature exists)
@@ -1094,7 +1094,14 @@ class DaeExporter:
mtx = posebone.matrix.copy()
if (bone.parent):
parent_posebone=node.pose.bones[bone.parent.name]
- mtx = parent_posebone.matrix.inverted() * mtx
+ parent_invisible=False
+
+ for i in range(3):
+ if (parent_posebone.scale[i]==0.0):
+ parent_invisible=True
+
+ if (not parent_invisible):
+ mtx = parent_posebone.matrix.inverted() * mtx
xform_cache[bone_name].append( (key,mtx) )
diff --git a/tools/pck/pck_packer.cpp b/tools/pck/pck_packer.cpp
index aade9fafe1..09611b3a93 100644
--- a/tools/pck/pck_packer.cpp
+++ b/tools/pck/pck_packer.cpp
@@ -137,6 +137,7 @@ Error PCKPacker::flush(bool p_verbose) {
if (p_verbose) {
if (count % 100 == 0) {
printf("%i/%i (%.2f\%)\r", count, files.size(), float(count) / files.size() * 100);
+ fflush(stdout);
};
};
};