diff options
Diffstat (limited to 'tools/editor')
49 files changed, 1795 insertions, 1070 deletions
diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp index daba52be03..76755666eb 100644 --- a/tools/editor/editor_file_system.cpp +++ b/tools/editor/editor_file_system.cpp @@ -142,7 +142,7 @@ void EditorFileSystemDirectory::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_file","idx"),&EditorFileSystemDirectory::get_file); ObjectTypeDB::bind_method(_MD("get_file_path","idx"),&EditorFileSystemDirectory::get_file_path); ObjectTypeDB::bind_method(_MD("get_file_types","idx"),&EditorFileSystemDirectory::get_file_type); - ObjectTypeDB::bind_method(_MD("is_missing_sources","idx"),&EditorFileSystemDirectory::get_file_type); + ObjectTypeDB::bind_method(_MD("is_missing_sources","idx"),&EditorFileSystemDirectory::is_missing_sources); ObjectTypeDB::bind_method(_MD("get_name"),&EditorFileSystemDirectory::get_name); ObjectTypeDB::bind_method(_MD("get_parent"),&EditorFileSystemDirectory::get_parent); diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp index 819da4bb45..42260e70ba 100644 --- a/tools/editor/editor_help.cpp +++ b/tools/editor/editor_help.cpp @@ -293,7 +293,7 @@ void EditorHelpSearch::_bind_methods() { ObjectTypeDB::bind_method(_MD("_text_changed"),&EditorHelpSearch::_text_changed); ObjectTypeDB::bind_method(_MD("_confirmed"),&EditorHelpSearch::_confirmed); ObjectTypeDB::bind_method(_MD("_sbox_input"),&EditorHelpSearch::_sbox_input); - ObjectTypeDB::bind_method(_MD("_update_search"),&EditorHelpSearch::_sbox_input); + ObjectTypeDB::bind_method(_MD("_update_search"),&EditorHelpSearch::_update_search); ADD_SIGNAL(MethodInfo("go_to_help")); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index a137b6cd34..701704fbfa 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -33,8 +33,6 @@ #include "editor_fonts.h" #include "editor_help.h" -#include "scene/io/scene_saver.h" -#include "scene/io/scene_loader.h" #include "core/io/resource_saver.h" #include "core/io/resource_loader.h" #include "servers/physics_2d_server.h" @@ -71,6 +69,7 @@ #include "plugins/item_list_editor_plugin.h" #include "plugins/stream_editor_plugin.h" #include "plugins/multimesh_editor_plugin.h" +#include "plugins/mesh_editor_plugin.h" #include "plugins/theme_editor_plugin.h" #include "plugins/tile_map_editor_plugin.h" @@ -233,25 +232,6 @@ void EditorNode::_notification(int p_what) { if (defer_load_scene!="") { -#ifdef OLD_SCENE_FORMAT_ENABLED - - if (convert_old) { - get_scene()->quit(); - Node *scn = SceneLoader::load(defer_load_scene,true); - ERR_EXPLAIN("Couldn't load scene: "+defer_load_scene); - ERR_FAIL_COND(!scn); - Ref<PackedScene> sdata = memnew( PackedScene ); - Error err = sdata->pack(scn); - ERR_EXPLAIN("Couldn't repack scene: "+defer_load_scene); - ERR_FAIL_COND(err!=OK); - err = ResourceSaver::save(defer_load_scene,sdata); - ERR_EXPLAIN("Couldn't resave scene: "+defer_load_scene); - ERR_FAIL_COND(err!=OK); - - return; - } - -#endif load_scene(defer_load_scene); defer_load_scene=""; } @@ -886,65 +866,6 @@ void EditorNode::_dialog_action(String p_file) { load_scene(p_file); } break; -#ifdef OLD_SCENE_FORMAT_ENABLED - case FILE_OPEN_OLD_SCENE: { - - String lpath = Globals::get_singleton()->localize_path(p_file); - if (!lpath.begins_with("res://")) { - - current_option=-1; - //accept->get_cancel()->hide(); - accept->get_ok()->set_text("Ugh"); - accept->set_text("Error loading scene, it must be inside the project path. Use 'Import' to open the scene, then save it inside the project path."); - accept->popup_centered(Size2(300,120)); - return ; - } - - Node*new_scene=SceneLoader::load(lpath,true); - - if (!new_scene) { - - current_option=-1; - //accept->get_cancel()->hide(); - accept->get_ok()->set_text("Ugh"); - accept->set_text("Error loading scene."); - accept->popup_centered(Size2(300,70));; - return ; - } - - Node *old_scene = edited_scene; - _hide_top_editors(); - set_edited_scene(NULL); - editor_data.clear_editor_states(); - if (old_scene) { - memdelete(old_scene); - } - - set_edited_scene(new_scene); - scene_tree_dock->set_selected(new_scene); - _get_scene_metadata(); - - editor_data.get_undo_redo().clear_history(); - saved_version=editor_data.get_undo_redo().get_version(); - _update_title(); - - _add_to_recent_scenes(lpath); - - if (new_scene->has_meta("__editor_plugin_screen__")) { - - String editor = new_scene->get_meta("__editor_plugin_screen__"); - for(int i=0;i<editor_table.size();i++) { - - if (editor_table[i]->get_name()==editor) { - _editor_select(i); - break; - } - } - } - - - } break; -#endif case FILE_SAVE_OPTIMIZED: { @@ -1679,28 +1600,6 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { open_request(previous_scenes.back()->get()); } break; -#ifdef OLD_SCENE_FORMAT_ENABLED - case FILE_OPEN_OLD_SCENE: { - - //print_tree(); - file->set_mode(FileDialog::MODE_OPEN_FILE); - //not for now? - file->clear_filters(); - file->add_filter("*.xml"); - - - //file->set_current_path(current_path); - Node *scene = edited_scene; - if (scene) { - file->set_current_path(scene->get_filename()); - }; - file->set_title("Open Scene"); - file->popup_centered_ratio(); - - - } break; - -#endif case FILE_SAVE_SCENE: { @@ -2438,6 +2337,8 @@ void EditorNode::set_edited_scene(Node *p_scene) { if (edited_scene && edited_scene->cast_to<Popup>()) edited_scene->cast_to<Popup>()->show(); //show popups scene_tree_dock->set_edited_scene(edited_scene); + if (get_scene()) + get_scene()->set_edited_scene_root(edited_scene); if (edited_scene) { if (p_scene->get_parent()!=scene_root) @@ -3549,9 +3450,6 @@ EditorNode::EditorNode() { p=import_menu->get_popup(); p->add_item("Sub-Scene",FILE_IMPORT_SUBSCENE); -#ifdef OLD_SCENE_FORMAT_ENABLED - p->add_item("Import Old Scene",FILE_OPEN_OLD_SCENE); -#endif p->add_separator(); p->connect("item_pressed",this,"_menu_option"); @@ -4079,6 +3977,7 @@ EditorNode::EditorNode() { add_editor_plugin( memnew( SampleLibraryEditorPlugin(this) ) ); add_editor_plugin( memnew( ThemeEditorPlugin(this) ) ); add_editor_plugin( memnew( MultiMeshEditorPlugin(this) ) ); + add_editor_plugin( memnew( MeshInstanceEditorPlugin(this) ) ); add_editor_plugin( memnew( AnimationTreeEditorPlugin(this) ) ); add_editor_plugin( memnew( SamplePlayerEditorPlugin(this) ) ); add_editor_plugin( memnew( MeshLibraryEditorPlugin(this) ) ); diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 6f1a24d7e8..bc88896ebb 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -30,7 +30,7 @@ #include "os/os.h" #include "os/dir_access.h" #include "os/file_access.h" -#include "io/object_format_xml.h" + #include "version.h" #include "scene/main/scene_main_loop.h" #include "os/os.h" @@ -386,6 +386,8 @@ void EditorSettings::_load_defaults() { set("global/font",""); hints["global/font"]=PropertyInfo(Variant::STRING,"global/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt"); + set("global/autoscan_project_path",""); + hints["global/autoscan_project_path"]=PropertyInfo(Variant::STRING,"global/autoscan_project_path",PROPERTY_HINT_GLOBAL_DIR); 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",""); diff --git a/tools/editor/editor_shape_gizmos.cpp b/tools/editor/editor_shape_gizmos.cpp deleted file mode 100644 index df7332b64a..0000000000 --- a/tools/editor/editor_shape_gizmos.cpp +++ /dev/null @@ -1,468 +0,0 @@ -/*************************************************************************/ -/* editor_shape_gizmos.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "editor_shape_gizmos.h" - - - - - - -String EditableShapeSpatialGizmo::get_handle_name(int p_idx) const { - - if (es->cast_to<EditableSphere>()) { - - return "Radius"; - } -#if 0 - if (es->cast_to<EditableBox>()) { - - return "Extents"; - } - - if (es->cast_to<EditableCapsule>()) { - - return p_idx==0?"Radius":"Height"; - } - - if (es->cast_to<EditableRay>()) { - - return "Length"; - } -#endif - return ""; -} -Variant EditableShapeSpatialGizmo::get_handle_value(int p_idx) const{ - - if (es->cast_to<EditableSphere>()) { - - EditableSphere *ss = es->cast_to<EditableSphere>(); - return ss->get_radius(); - } -#if 0 - if (es->cast_to<EditableBox>()) { - - EditableBox *bs = es->cast_to<EditableBox>(); - return bs->get_extents(); - } - - if (es->cast_to<EditableCapsule>()) { - - EditableCapsule *cs = es->cast_to<EditableCapsule>(); - return p_idx==0?es->get_radius():es->get_height(); - } - - if (es->cast_to<EditableRay>()) { - - EditableRay* cs = es->cast_to<EditableRay>(); - return es->get_length(); - } -#endif - return Variant(); -} -void EditableShapeSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){ - - Transform gt = es->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 (es->cast_to<EditableSphere>()) { - - EditableSphere *ss = es->cast_to<EditableSphere>(); - 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 0 - if (es->cast_to<EditableRay>()) { - - EditableRay*cs = es->cast_to<EditableRay>(); - 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 (es->cast_to<EditableBox>()) { - - Vector3 axis; - axis[p_idx]=1.0; - EditableBox *bs = es->cast_to<EditableBox>(); - 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 (es->cast_to<EditableCapsule>()) { - - Vector3 axis; - axis[p_idx]=1.0; - EditableCapsule *cs = es->cast_to<EditableCapsule>(); - Vector3 ra,rb; - Geometry::get_closest_points_between_segments(Vector3(),axis*4096,sg[0],sg[1],ra,rb); - float d = ra[p_idx]; - if (p_idx==1) - d-=es->get_radius(); - if (d<0.001) - d=0.001; - - if (p_idx==0) - es->set_radius(d); - else if (p_idx==1) - es->set_height(d*2.0); - - } - -#endif - -} -void EditableShapeSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ - - - if (es->cast_to<EditableSphere>()) { - - EditableSphere *ss = es->cast_to<EditableSphere>(); - 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,"set_radius",ss->get_radius()); - ur->add_undo_method(ss,"set_radius",p_restore); - ur->commit_action(); - - } -#if 0 - if (es->cast_to<EditableBox>()) { - - EditableBox *ss = es->cast_to<EditableBox>(); - 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,"set_extents",ss->get_extents()); - ur->add_undo_method(ss,"set_extents",p_restore); - ur->commit_action(); - } - - if (es->cast_to<EditableCapsule>()) { - - EditableCapsule *cs = es->cast_to<EditableCapsule>(); - 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,"set_radius",ss->get_radius()); - ur->add_undo_method(ss,"set_radius",p_restore); - } else { - ur->create_action("Change Capsule Shape Height"); - ur->add_do_method(ss,"set_height",ss->get_height()); - ur->add_undo_method(ss,"set_height",p_restore); - - } - - ur->commit_action(); - - } - - if (es->cast_to<EditableRay>()) { - - EditableRay*rs = es->cast_to<EditableRay>() - 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,"set_length",ss->get_length()); - ur->add_undo_method(ss,"set_length",p_restore); - ur->commit_action(); - - } -#endif -} -void EditableShapeSpatialGizmo::redraw(){ - - clear(); - - if (es->cast_to<EditableSphere>()) { - - EditableSphere* sp= es->cast_to<EditableSphere>(); - float r=sp->get_radius(); - - Vector<Vector3> 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<Vector3> 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<Vector3> handles; - handles.push_back(Vector3(r,0,0)); - add_handles(handles); - - } - -#if 0 - if (es->cast_to<EditableBox>()) { - - EditableBox*bs = es->cast_to<EditableBox>(); - Vector<Vector3> 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<Vector3> 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 (es->cast_to<EditableCapsule>()) { - - EditableCapsule *cs = es->cast_to<EditableCapsule>(); - float radius = es->get_radius(); - float height = es->get_height(); - - - Vector<Vector3> points; - - Vector3 d(0,height*0.5,0); - 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,0,a.y)+d); - points.push_back(Vector3(b.x,0,b.y)+d); - - points.push_back(Vector3(a.x,0,a.y)-d); - points.push_back(Vector3(b.x,0,b.y)-d); - - if (i%90==0) { - - points.push_back(Vector3(a.x,0,a.y)+d); - points.push_back(Vector3(a.x,0,a.y)-d); - } - - Vector3 dud = i<180?d:-d; - - points.push_back(Vector3(0,a.x,a.y)+dud); - points.push_back(Vector3(0,b.x,b.y)+dud); - points.push_back(Vector3(a.y,a.x,0)+dud); - points.push_back(Vector3(b.y,b.x,0)+dud); - - } - - add_lines(points,SpatialEditorGizmos::singleton->shape_material); - - Vector<Vector3> 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,0,a.y)+d); - collision_segments.push_back(Vector3(b.x,0,b.y)+d); - - collision_segments.push_back(Vector3(a.x,0,a.y)-d); - collision_segments.push_back(Vector3(b.x,0,b.y)-d); - - if (i%16==0) { - - collision_segments.push_back(Vector3(a.x,0,a.y)+d); - collision_segments.push_back(Vector3(a.x,0,a.y)-d); - } - - Vector3 dud = i<32?d:-d; - - collision_segments.push_back(Vector3(0,a.x,a.y)+dud); - collision_segments.push_back(Vector3(0,b.x,b.y)+dud); - collision_segments.push_back(Vector3(a.y,a.x,0)+dud); - collision_segments.push_back(Vector3(b.y,b.x,0)+dud); - - } - - add_collision_segments(collision_segments); - - Vector<Vector3> handles; - handles.push_back(Vector3(es->get_radius(),0,0)); - handles.push_back(Vector3(0,es->get_height()*0.5+es->get_radius(),0)); - add_handles(handles); - - - } - - if (es->cast_to<EditablePlane>()) { - - EditablePlane* ps=es->cast_to<EditablePlane(); - Plane p = ps->get_plane(); - Vector<Vector3> 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 (es->cast_to<EditableRay>()) { - - EditableRay*cs = es->cast_to<EditableRay>(); - - Vector<Vector3> 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<Vector3> handles; - handles.push_back(Vector3(0,0,rs->get_length())); - add_handles(handles); - - - } - -#endif - -} -EditableShapeSpatialGizmo::EditableShapeSpatialGizmo(EditableShape* p_cs) { - - es=p_cs; - set_spatial_node(p_cs); -} - - - -EditorShapeGizmos::EditorShapeGizmos() -{ -} diff --git a/tools/editor/editor_shape_gizmos.h b/tools/editor/editor_shape_gizmos.h deleted file mode 100644 index 4b5af49b4e..0000000000 --- a/tools/editor/editor_shape_gizmos.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************/ -/* editor_shape_gizmos.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef EDITOR_SHAPE_GIZMOS_H -#define EDITOR_SHAPE_GIZMOS_H - -#include "spatial_editor_gizmos.h" -#include "scene/3d/editable_shape.h" - - -class EditableShapeSpatialGizmo : public SpatialGizmoTool { - - OBJ_TYPE(EditableShapeSpatialGizmo,SpatialGizmoTool); - - EditableShape *es; - -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(); - EditableShapeSpatialGizmo(EditableShape* p_cs=NULL); - -}; - - - -class EditorShapeGizmos -{ -public: - EditorShapeGizmos(); -}; - -#endif // EDITOR_SHAPE_GIZMOS_H diff --git a/tools/editor/icons/icon_baked_light.png b/tools/editor/icons/icon_baked_light.png Binary files differnew file mode 100644 index 0000000000..48039e264c --- /dev/null +++ b/tools/editor/icons/icon_baked_light.png diff --git a/tools/editor/icons/icon_baked_light_instance.png b/tools/editor/icons/icon_baked_light_instance.png Binary files differnew file mode 100644 index 0000000000..77e53aa8f6 --- /dev/null +++ b/tools/editor/icons/icon_baked_light_instance.png diff --git a/tools/editor/icons/icon_collision_polygon.png b/tools/editor/icons/icon_collision_polygon.png Binary files differnew file mode 100644 index 0000000000..a82b43589e --- /dev/null +++ b/tools/editor/icons/icon_collision_polygon.png diff --git a/tools/editor/icons/icon_immediate_geometry.png b/tools/editor/icons/icon_immediate_geometry.png Binary files differnew file mode 100644 index 0000000000..e7fa8a9e42 --- /dev/null +++ b/tools/editor/icons/icon_immediate_geometry.png diff --git a/tools/editor/icons/icon_kinematic_body.png b/tools/editor/icons/icon_kinematic_body.png Binary files differnew file mode 100644 index 0000000000..7feb38f6ba --- /dev/null +++ b/tools/editor/icons/icon_kinematic_body.png diff --git a/tools/editor/icons/icon_kinematic_body_2d.png b/tools/editor/icons/icon_kinematic_body_2d.png Binary files differnew file mode 100644 index 0000000000..3d8e09a179 --- /dev/null +++ b/tools/editor/icons/icon_kinematic_body_2d.png diff --git a/tools/editor/icons/icon_navigation.png b/tools/editor/icons/icon_navigation.png Binary files differnew file mode 100644 index 0000000000..eeaa660f8d --- /dev/null +++ b/tools/editor/icons/icon_navigation.png diff --git a/tools/editor/icons/icon_navigation_mesh_instance.png b/tools/editor/icons/icon_navigation_mesh_instance.png Binary files differnew file mode 100644 index 0000000000..163bd0cdb3 --- /dev/null +++ b/tools/editor/icons/icon_navigation_mesh_instance.png diff --git a/tools/editor/icons/icon_panels_2_alt.png b/tools/editor/icons/icon_panels_2_alt.png Binary files differnew file mode 100644 index 0000000000..2006f212ce --- /dev/null +++ b/tools/editor/icons/icon_panels_2_alt.png diff --git a/tools/editor/icons/icon_panels_3_alt.png b/tools/editor/icons/icon_panels_3_alt.png Binary files differnew file mode 100644 index 0000000000..5195b799a5 --- /dev/null +++ b/tools/editor/icons/icon_panels_3_alt.png diff --git a/tools/editor/icons/icon_particle_attractor_2d.png b/tools/editor/icons/icon_particle_attractor_2d.png Binary files differnew file mode 100644 index 0000000000..bb66611e45 --- /dev/null +++ b/tools/editor/icons/icon_particle_attractor_2d.png diff --git a/tools/editor/icons/icon_pin_joint.png b/tools/editor/icons/icon_pin_joint.png Binary files differnew file mode 100644 index 0000000000..cdfae660d8 --- /dev/null +++ b/tools/editor/icons/icon_pin_joint.png diff --git a/tools/editor/icons/icon_polygon_2d.png b/tools/editor/icons/icon_polygon_2d.png Binary files differnew file mode 100644 index 0000000000..9deb63a248 --- /dev/null +++ b/tools/editor/icons/icon_polygon_2d.png diff --git a/tools/editor/icons/icon_ray_cast.png b/tools/editor/icons/icon_ray_cast.png Binary files differnew file mode 100644 index 0000000000..a53ef0b516 --- /dev/null +++ b/tools/editor/icons/icon_ray_cast.png diff --git a/tools/editor/icons/icon_slider_joint.png b/tools/editor/icons/icon_slider_joint.png Binary files differnew file mode 100644 index 0000000000..ce35b6bfa2 --- /dev/null +++ b/tools/editor/icons/icon_slider_joint.png diff --git a/tools/editor/icons/icon_touch_screen_button.png b/tools/editor/icons/icon_touch_screen_button.png Binary files differnew file mode 100644 index 0000000000..16e84927f1 --- /dev/null +++ b/tools/editor/icons/icon_touch_screen_button.png diff --git a/tools/editor/icons/icon_vehicle_body.png b/tools/editor/icons/icon_vehicle_body.png Binary files differnew file mode 100644 index 0000000000..1c6af388eb --- /dev/null +++ b/tools/editor/icons/icon_vehicle_body.png diff --git a/tools/editor/icons/icon_vehicle_wheel.png b/tools/editor/icons/icon_vehicle_wheel.png Binary files differnew file mode 100644 index 0000000000..161283e1bf --- /dev/null +++ b/tools/editor/icons/icon_vehicle_wheel.png diff --git a/tools/editor/icons/icon_y_sort.png b/tools/editor/icons/icon_y_sort.png Binary files differnew file mode 100644 index 0000000000..6f80fac156 --- /dev/null +++ b/tools/editor/icons/icon_y_sort.png diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp index 4b3e052907..6a6ee8c614 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp @@ -92,6 +92,7 @@ public: String gradient_image; + bool disable_filter; bool round_advance; @@ -153,6 +154,8 @@ public: color_use_monochrome=p_value; else if (n=="advanced/round_advance") round_advance=p_value; + else if (n=="advanced/disable_filter") + disable_filter=p_value; else return false; @@ -217,6 +220,8 @@ public: r_ret=color_use_monochrome; else if (n=="advanced/round_advance") r_ret=round_advance; + else if (n=="advanced/disable_filter") + r_ret=disable_filter; else return false; @@ -265,6 +270,7 @@ public: } p_list->push_back(PropertyInfo(Variant::BOOL,"color/monochrome")); p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/round_advance")); + p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/disable_filter")); } @@ -302,6 +308,7 @@ public: color_use_monochrome=false; round_advance=true; + disable_filter=false; } @@ -331,6 +338,7 @@ public: color_use_monochrome=false; round_advance=true; + disable_filter=false; } @@ -1260,6 +1268,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata int space_space = from->get_option("extra_space/space"); int top_space = from->get_option("extra_space/top"); int bottom_space = from->get_option("extra_space/bottom"); + bool disable_filter = from->get_option("advanced/disable_filter"); Ref<Font> font; @@ -1279,7 +1288,12 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata //register texures { Ref<ImageTexture> t = memnew(ImageTexture); - t->create_from_image(atlas); + int flags; + if (disable_filter) + flags=0; + else + flags=Texture::FLAG_FILTER; + t->create_from_image(atlas,flags); t->set_storage( ImageTexture::STORAGE_COMPRESS_LOSSLESS ); font->add_texture(t); diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp index 9bee47ca66..e86356ebe9 100644 --- a/tools/editor/io_plugins/editor_import_collada.cpp +++ b/tools/editor/io_plugins/editor_import_collada.cpp @@ -694,6 +694,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co // Must convert to GL/DX format. int _prim_ofs=0; + int vertidx=0; for(int p_i=0;p_i<p.count;p_i++) { @@ -718,6 +719,8 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co ERR_FAIL_INDEX_V(src,p.indices.size(),ERR_INVALID_DATA); Collada::Vertex vertex; + if (p_morph_data) + vertex.uid=vertidx++; int vertex_index=p.indices[src+vertex_ofs]; //used for index field (later used by controllers) int vertex_pos = (vertex_src->stride?vertex_src->stride:3) * vertex_index; @@ -746,7 +749,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co Vector3 tangent =Vector3(tangent_src->array[tangent_pos+0],tangent_src->array[tangent_pos+1],tangent_src->array[tangent_pos+2]); vertex.tangent.normal=tangent; - vertex.tangent.d= vertex.normal.cross(tangent).dot(binormal) > 0 ? -1 : 1; + vertex.tangent.d= vertex.normal.cross(tangent).dot(binormal) > 0 ? 1 : -1; } } @@ -781,6 +784,8 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co vertex.vertex.z = -vertex.vertex.z; SWAP( vertex.normal.z, vertex.normal.y ); vertex.normal.z = -vertex.normal.z; + SWAP( vertex.tangent.normal.z, vertex.tangent.normal.y ); + vertex.tangent.normal.z = -vertex.tangent.normal.z; } @@ -1670,16 +1675,21 @@ void ColladaImport::_fix_param_animation_tracks() { source=skin.base; } else if (collada.state.morph_controller_data_map.has(source)) { + const Collada::MorphControllerData& morph = collada.state.morph_controller_data_map[source]; + if (morph.targets.has("MORPH_WEIGHT") && morph.targets.has("MORPH_TARGET")) { + String weights = morph.targets["MORPH_WEIGHT"]; String targets = morph.targets["MORPH_TARGET"]; + //fails here if (morph.sources.has(targets) && morph.sources.has(weights)) { const Collada::MorphControllerData::Source &weight_src=morph.sources[weights]; const Collada::MorphControllerData::Source &target_src=morph.sources[targets]; + ERR_FAIL_COND(weight_src.array.size() != target_src.sarray.size()); for(int i=0;i<weight_src.array.size();i++) { @@ -1688,6 +1698,7 @@ void ColladaImport::_fix_param_animation_tracks() { String mesh_name = target_src.sarray[i]; if (collada.state.mesh_name_map.has(mesh_name) && collada.state.referenced_tracks.has(track_name)) { + const Vector<int>&rt = collada.state.referenced_tracks[track_name]; for(int rti=0;rti<rt.size();rti++) { @@ -1718,7 +1729,7 @@ void ColladaImport::_fix_param_animation_tracks() { void ColladaImport::create_animations(bool p_make_tracks_in_all_bones) { - print_line("-=-=-=-=-PRE CA"); + _fix_param_animation_tracks(); for(int i=0;i<collada.state.animation_clips.size();i++) { @@ -1731,6 +1742,7 @@ void ColladaImport::create_animations(bool p_make_tracks_in_all_bones) { for(int i=0;i<collada.state.animation_tracks.size();i++) { Collada::AnimationTrack &at = collada.state.animation_tracks[i]; + //print_line("CHANNEL: "+at.target+" PARAM: "+at.param); if (!node_map.has(at.target)) { print_line("Coudlnt find node: "+at.target); continue; @@ -1749,7 +1761,7 @@ void ColladaImport::create_animations(bool p_make_tracks_in_all_bones) { } create_animation(-1,p_make_tracks_in_all_bones); - print_line("clipcount: "+itos(collada.state.animation_clips.size())); + //print_line("clipcount: "+itos(collada.state.animation_clips.size())); for(int i=0;i<collada.state.animation_clips.size();i++) create_animation(i,p_make_tracks_in_all_bones); @@ -1761,10 +1773,10 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones if (p_clip==-1) { - print_line("default"); + //print_line("default"); animation->set_name("default"); } else { - print_line("clip name: "+collada.state.animation_clips[p_clip].name); + //print_line("clip name: "+collada.state.animation_clips[p_clip].name); animation->set_name(collada.state.animation_clips[p_clip].name); } @@ -1829,14 +1841,14 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones if (p_clip>=0 && collada.state.animation_clips[p_clip].end) anim_length=collada.state.animation_clips[p_clip].end; - while(f<collada.state.animation_length) { - if (f>=collada.state.animation_length) - f=collada.state.animation_length; + while(f<anim_length) { + if (f>=anim_length) + f=anim_length; base_snapshots.push_back(f); f+=snapshot_interval; } - print_line("anim len: "+rtos(anim_length)); + //print_line("anim len: "+rtos(anim_length)); animation->set_length(anim_length); bool tracks_found=false; @@ -1861,7 +1873,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones Collada::Node *cn = collada.state.scene_map[E->get()]; if (cn->ignore_anim) { - print_line("warning, ignoring animation on node: "+path); + //print_line("warning, ignoring animation on node: "+path); continue; } diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp index 2482728c87..27400344d3 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp @@ -40,6 +40,7 @@ #include "scene/3d/body_shape.h" #include "scene/3d/physics_body.h" #include "scene/3d/portal.h" +#include "scene/3d/vehicle_body.h" #include "os/os.h" @@ -641,6 +642,7 @@ const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_name {EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,"Materials","Set Alpha in Materials (-alpha)",true}, {EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,"Materials","Set Vert. Color in Materials (-vcol)",true}, {EditorSceneImportPlugin::SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES,"Actions","SRGB->Linear Of Diffuse Textures",false}, + {EditorSceneImportPlugin::SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY,"Actions","Convert Normal Maps to XY",true}, {EditorSceneImportPlugin::SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS,"Actions","Set Material Lightmap to UV2 if Tex2Array Exists",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,"Create","Create Collisions (-col},-colonly)",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,"Create","Create Portals (-portal)",true}, @@ -649,9 +651,10 @@ const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_name {EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,"Create","Create Billboards (-bb)",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,"Create","Create Impostors (-imp:dist)",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,"Create","Create LODs (-lod:dist)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create","Create Cars (-car)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create","Create Car Wheels (-wheel)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create","Create Vehicles (-vehicle)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create","Create Vehicle Wheels (-wheel)",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_NAVMESH,"Create","Create Navigation Meshes (-navmesh)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_DETECT_LIGHTMAP_LAYER,"Create","Detect LightMap Layer (-lm:<int>).",true}, {-1,NULL,NULL,false} }; @@ -896,7 +899,7 @@ static String _fixstr(const String& p_what,const String& p_str) { -void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<ImageTexture>, bool> &image_map) { +void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<ImageTexture>, TextureRole> &image_map,int p_flags) { switch(p_var.get_type()) { @@ -908,7 +911,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag if (res->is_type("Texture") && !image_map.has(res)) { - image_map.insert(res,false); + image_map.insert(res,TEXTURE_ROLE_DEFAULT); } else { @@ -924,11 +927,22 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag Ref<ImageTexture> tex =res->get(E->get().name); if (tex.is_valid()) { - image_map.insert(tex,true); + image_map.insert(tex,TEXTURE_ROLE_DIFFUSE); } + } else if (E->get().type==Variant::OBJECT && res->cast_to<FixedMaterial>() && (E->get().name=="textures/normal")) { + + Ref<ImageTexture> tex =res->get(E->get().name); + if (tex.is_valid()) { + + image_map.insert(tex,TEXTURE_ROLE_NORMALMAP); + if (p_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY) + res->cast_to<FixedMaterial>()->set_fixed_flag(FixedMaterial::FLAG_USE_XY_NORMALMAP,true); + } + + } else { - _find_resources(res->get(E->get().name),image_map); + _find_resources(res->get(E->get().name),image_map,p_flags); } } } @@ -947,8 +961,8 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag for(List<Variant>::Element *E=keys.front();E;E=E->next()) { - _find_resources(E->get(),image_map); - _find_resources(d[E->get()],image_map); + _find_resources(E->get(),image_map,p_flags); + _find_resources(d[E->get()],image_map,p_flags); } @@ -959,7 +973,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag Array a = p_var; for(int i=0;i<a.size();i++) { - _find_resources(a[i],image_map); + _find_resources(a[i],image_map,p_flags); } } break; @@ -969,7 +983,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<Imag } -Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,bool >& image_map) { +Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map) { // children first.. for(int i=0;i<p_node->get_child_count();i++) { @@ -1000,7 +1014,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) { - _find_resources(p_node->get(E->get().name),image_map); + _find_resources(p_node->get(E->get().name),image_map,p_flags); } } @@ -1199,6 +1213,17 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> } } } + + + if (p_flags&SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name,"lm") && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + String str=name; + int layer = str.substr(str.find("lm")+3,str.length()).to_int(); + mi->set_baked_light_texture_id(layer); + } + if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly") && p_node->cast_to<MeshInstance>()) { if (isroot) @@ -1262,6 +1287,46 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> p_node->replace_by(nmi); memdelete(p_node); p_node=nmi; + } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"vehicle")) { + + if (isroot) + return p_node; + + Node *owner = p_node->get_owner(); + Spatial *s = p_node->cast_to<Spatial>(); + VehicleBody *bv = memnew( VehicleBody ); + String n = _fixstr(p_node->get_name(),"vehicle"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform()); + + p_node=bv; + + + } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"wheel")) { + + if (isroot) + return p_node; + + Node *owner = p_node->get_owner(); + Spatial *s = p_node->cast_to<Spatial>(); + VehicleWheel *bv = memnew( VehicleWheel ); + String n = _fixstr(p_node->get_name(),"wheel"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform()); + + p_node=bv; } else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) { @@ -1872,7 +1937,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata); - Map< Ref<ImageTexture>,bool > imagemap; + Map< Ref<ImageTexture>,TextureRole > imagemap; scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap); @@ -1918,7 +1983,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c int image_flags = from->get_option("texture_flags"); float image_quality = from->get_option("texture_quality"); - for (Map< Ref<ImageTexture>,bool >::Element *E=imagemap.front();E;E=E->next()) { + for (Map< Ref<ImageTexture>,TextureRole >::Element *E=imagemap.front();E;E=E->next()) { //texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff //but not yet.. @@ -1954,6 +2019,11 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); print_line("flags: "+itos(image_flags)); uint32_t flags = image_flags; + if (E->get()==TEXTURE_ROLE_DIFFUSE && scene_flags&SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR; + + if (E->get()==TEXTURE_ROLE_NORMALMAP && scene_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_NORMAL_TO_XY; imd->set_option("flags",flags); imd->set_option("format",image_format); diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h index 3b39f0c962..72b4089d89 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.h +++ b/tools/editor/io_plugins/editor_scene_import_plugin.h @@ -100,8 +100,14 @@ class EditorSceneImportPlugin : public EditorImportPlugin { Vector<Ref<EditorSceneImporter> > importers; - void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,bool >& image_map); - Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,bool >& image_map); + enum TextureRole { + TEXTURE_ROLE_DEFAULT, + TEXTURE_ROLE_DIFFUSE, + TEXTURE_ROLE_NORMALMAP + }; + + void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,TextureRole >& image_map,int p_flags); + Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map); void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes); void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes); @@ -125,6 +131,7 @@ public: SCENE_FLAG_DETECT_ALPHA=1<<15, SCENE_FLAG_DETECT_VCOLOR=1<<16, SCENE_FLAG_CREATE_NAVMESH=1<<17, + SCENE_FLAG_DETECT_LIGHTMAP_LAYER=1<<18, SCENE_FLAG_REMOVE_NOIMP=1<<24, SCENE_FLAG_IMPORT_ANIMATIONS=1<<25, @@ -132,6 +139,7 @@ public: SCENE_FLAG_GENERATE_TANGENT_ARRAYS=1<<27, SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES=1<<28, SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS=1<<29, + SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY=1<<30, }; diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 760651bbfd..86f7787a9c 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -46,6 +46,8 @@ static const char *flag_names[]={ "Filter (Magnifying)", "Premultiply Alpha", "Convert SRGB->Linear", + "Convert NormalMap to XY", + "Use Anisotropy", NULL }; @@ -59,6 +61,8 @@ static const char *flag_short_names[]={ "Filter", "PMAlpha", "ToLinear", + "ToRG", + "Anisoropic", NULL }; @@ -725,7 +729,7 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc bool atlas = from->get_option("atlas"); int flags=from->get_option("flags"); - print_line("GET FLAGS: "+itos(flags)); + uint32_t tex_flags=0; if (flags&EditorTextureImportPlugin::IMAGE_FLAG_REPEAT) @@ -734,6 +738,10 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc tex_flags|=Texture::FLAG_FILTER; if (!(flags&EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS)) tex_flags|=Texture::FLAG_MIPMAPS; + if (flags&EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR) + tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR; + if (flags&EditorTextureImportPlugin::IMAGE_FLAG_USE_ANISOTROPY) + tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER; print_line("path: "+p_path+" flags: "+itos(tex_flags)); int shrink=1; @@ -930,11 +938,15 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc image.premultiply_alpha(); } - if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { - - image.srgb_to_linear(); + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); } + //if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { + + // image.srgb_to_linear(); + //} + if (shrink>1) { int orig_w=image.get_width(); @@ -992,12 +1004,16 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc image.premultiply_alpha(); } - if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { - - print_line("CONVERT BECAUSE: "+itos(flags)); - image.srgb_to_linear(); + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); } + //if ((image.get_format()==Image::FORMAT_RGB || image.get_format()==Image::FORMAT_RGBA) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { +// + // print_line("CONVERT BECAUSE: "+itos(flags)); + // image.srgb_to_linear(); + //} + int orig_w=image.get_width(); int orig_h=image.get_height(); @@ -1021,7 +1037,7 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc texture->create_from_image(image,tex_flags); - if (shrink>1) { + if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) { texture->set_size_override(Size2(orig_w,orig_h)); } diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index 9374c6eb0b..d17b3c05c2 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -93,7 +93,9 @@ public: IMAGE_FLAG_REPEAT=32, //usually disabled in 2D IMAGE_FLAG_FILTER=64, //almost always enabled IMAGE_FLAG_PREMULT_ALPHA=128,//almost always enabled - IMAGE_FLAG_CONVERT_TO_LINEAR=256 //convert image to linear + IMAGE_FLAG_CONVERT_TO_LINEAR=256, //convert image to linear + IMAGE_FLAG_CONVERT_NORMAL_TO_XY=512, //convert image to linear + IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear }; virtual String get_name() const; diff --git a/tools/editor/plugins/baked_light_baker.cpp b/tools/editor/plugins/baked_light_baker.cpp index dea83e0ff8..42a185b7c2 100644 --- a/tools/editor/plugins/baked_light_baker.cpp +++ b/tools/editor/plugins/baked_light_baker.cpp @@ -4,6 +4,53 @@ #include <cmath> #include "io/marshalls.h" #include "tools/editor/editor_node.h" +#include "tools/editor/editor_settings.h" + + +void baked_light_baker_add_64f(double *dst,double value); +void baked_light_baker_add_64i(int64_t *dst,int64_t value); + +//-separar en 2 testuras? +//*mejorar performance y threads +//*modos lineales +//*saturacion + +_FORCE_INLINE_ static uint64_t get_uv_normal_bit(const Vector3& p_vector) { + + int lat = Math::fast_ftoi(Math::floor(Math::acos(p_vector.dot(Vector3(0,1,0)))*6.0/Math_PI+0.5)); + + if (lat==0) { + return 60; + } else if (lat==6) { + return 61; + } + + int lon = Math::fast_ftoi(Math::floor( (Math_PI+Math::atan2(p_vector.x,p_vector.z))*12.0/(Math_PI*2.0) + 0.5))%12; + + return lon+(lat-1)*12; +} + + + +_FORCE_INLINE_ static Vector3 get_bit_normal(int p_bit) { + + if (p_bit==61) { + return Vector3(0,1,0); + } else if (p_bit==62){ + return Vector3(0,-1,0); + } + + float latang = ((p_bit / 12)+1)*Math_PI/6.0; + + Vector2 latv(Math::sin(latang),Math::cos(latang)); + + float lonang = ((p_bit%12)*Math_PI*2.0/12.0)-Math_PI; + + Vector2 lonv(Math::sin(lonang),Math::cos(lonang)); + + return Vector3(lonv.x*latv.x,latv.y,lonv.y*latv.x).normalized(); + +} BakedLightBaker::MeshTexture* BakedLightBaker::_get_mat_tex(const Ref<Texture>& p_tex) { @@ -28,6 +75,12 @@ BakedLightBaker::MeshTexture* BakedLightBaker::_get_mat_tex(const Ref<Texture>& image.convert(Image::FORMAT_RGBA); } + if (imgtex->get_flags()&Texture::FLAG_CONVERT_TO_LINEAR) { + Image copy = image; + copy.srgb_to_linear(); + image=copy; + } + DVector<uint8_t> dvt=image.get_data(); DVector<uint8_t>::Read r=dvt.read(); MeshTexture mt; @@ -67,8 +120,13 @@ void BakedLightBaker::_add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_m if (fm.is_valid()) { //fixed route mm.diffuse.color=fm->get_parameter(FixedMaterial::PARAM_DIFFUSE); + if (linear_color) + mm.diffuse.color=mm.diffuse.color.to_linear(); mm.diffuse.tex=_get_mat_tex(fm->get_texture(FixedMaterial::PARAM_DIFFUSE)); mm.specular.color=fm->get_parameter(FixedMaterial::PARAM_SPECULAR); + if (linear_color) + mm.specular.color=mm.specular.color.to_linear(); + mm.specular.tex=_get_mat_tex(fm->get_texture(FixedMaterial::PARAM_SPECULAR)); } else { @@ -232,6 +290,11 @@ void BakedLightBaker::_parse_geometry(Node* p_node) { dirl.type=VS::LightType(dl->get_light_type()); dirl.diffuse=dl->get_color(DirectionalLight::COLOR_DIFFUSE); dirl.specular=dl->get_color(DirectionalLight::COLOR_SPECULAR); + if (linear_color) + dirl.diffuse=dirl.diffuse.to_linear(); + if (linear_color) + dirl.specular=dirl.specular.to_linear(); + dirl.energy=dl->get_parameter(DirectionalLight::PARAM_ENERGY); dirl.pos=dl->get_global_transform().origin; dirl.up=dl->get_global_transform().basis.get_axis(1).normalized(); @@ -434,8 +497,11 @@ void BakedLightBaker::_make_bvh() { } bvh=_parse_bvh(bases.ptr(),bases.size(),1,max_depth); + ray_stack = memnew_arr(uint32_t,max_depth); bvh_stack = memnew_arr(BVH*,max_depth); + + bvh_depth = max_depth; } void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_depth) { @@ -525,6 +591,12 @@ void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_de child->aabb.pos.z+=child->aabb.size.z; + child->full_accum[0]=0; + child->full_accum[1]=0; + child->full_accum[2]=0; + child->sampler_ofs=0; + + if (stack_pos==octree_depth-1) { child->leaf=true; @@ -533,10 +605,12 @@ void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_de child->offset[2]=child->aabb.pos.z+child->aabb.size.z*0.5; child->next_leaf=leaf_list; + for(int ci=0;ci<8;ci++) { child->normal_accum[ci][0]=0; child->normal_accum[ci][1]=0; child->normal_accum[ci][2]=0; + } child->bake_neighbour=0; @@ -545,14 +619,10 @@ void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_de cell_count++; int lz = lights.size(); - child->light = memnew_arr(OctantLight,lz); - - for(int li=0;li<lz;li++) { - for(int ci=0;ci<8;ci++) { - child->light[li].accum[ci][0]=0; - child->light[li].accum[ci][1]=0; - child->light[li].accum[ci][2]=0; - } + for(int ci=0;ci<8;ci++) { + child->light_accum[ci][0]=0; + child->light_accum[ci][1]=0; + child->light_accum[ci][2]=0; } child->parent=ptr_stack[stack_pos]; @@ -593,11 +663,26 @@ void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_de pos.y=floor((pos.y+cell_size*0.5)/cell_size); pos.z=floor((pos.z+cell_size*0.5)/cell_size); - Map<Vector3,Vector3>::Element *E=endpoint_normal.find(pos); - if (!E) { - endpoint_normal[pos]=n; - } else { - E->get()+=n; + { + Map<Vector3,Vector3>::Element *E=endpoint_normal.find(pos); + if (!E) { + endpoint_normal[pos]=n; + } else { + E->get()+=n; + } + } + + { + + uint64_t bit = get_uv_normal_bit(n); + + Map<Vector3,uint64_t>::Element *E=endpoint_normal_bits.find(pos); + if (!E) { + endpoint_normal_bits[pos]=(1<<bit); + } else { + E->get()|=(1<<bit); + } + } } @@ -677,18 +762,58 @@ void BakedLightBaker::_make_octree() { pos.y=floor((pos.y+cell_size*0.5)/cell_size); pos.z=floor((pos.z+cell_size*0.5)/cell_size); - Map<Vector3,Vector3>::Element *E=endpoint_normal.find(pos); - if (!E) { - //? - print_line("lolwut?"); - } else { - Vector3 n = E->get().normalized(); - oct->normal_accum[ci][0]=n.x; - oct->normal_accum[ci][1]=n.y; - oct->normal_accum[ci][2]=n.z; + { + Map<Vector3,Vector3>::Element *E=endpoint_normal.find(pos); + if (!E) { + //? + print_line("lolwut?"); + } else { + Vector3 n = E->get().normalized(); + oct->normal_accum[ci][0]=n.x; + oct->normal_accum[ci][1]=n.y; + oct->normal_accum[ci][2]=n.z; + } + + } + + { + + Map<Vector3,uint64_t>::Element *E=endpoint_normal_bits.find(pos); + if (!E) { + //? + print_line("lolwut?"); + } else { + + float max_aper=0; + for(uint64_t i=0;i<62;i++) { + + if (!(E->get()&(1<<i))) + continue; + Vector3 ang_i = get_bit_normal(i); + + for(uint64_t j=0;j<62;j++) { + + if (i==j) + continue; + if (!(E->get()&(1<<j))) + continue; + Vector3 ang_j = get_bit_normal(j); + float ang = Math::acos(ang_i.dot(ang_j)); + if (ang>max_aper) + max_aper=ang; + } + } + if (max_aper>0.75*Math_PI) { + //angle too wide prevent problems and forget + oct->normal_accum[ci][0]=0; + oct->normal_accum[ci][1]=0; + oct->normal_accum[ci][2]=0; + } + } } + } oct_idx=oct->next_leaf; @@ -702,12 +827,12 @@ void BakedLightBaker::_make_octree() { -void BakedLightBaker::_plot_light(int p_light_index, const Vector3& p_plot_pos, const AABB& p_plot_aabb, const Color& p_light, const Plane& p_plane) { +void BakedLightBaker::_plot_light(ThreadStack& thread_stack,const Vector3& p_plot_pos, const AABB& p_plot_aabb, const Color& p_light,const Color& p_tint_light,bool p_only_full, const Plane& p_plane) { //stackless version - uint32_t *stack=octant_stack; - uint32_t *ptr_stack=octantptr_stack; + uint32_t *stack=thread_stack.octant_stack; + uint32_t *ptr_stack=thread_stack.octantptr_stack; Octant *octants=octant_pool.ptr(); stack[0]=0; @@ -720,6 +845,29 @@ void BakedLightBaker::_plot_light(int p_light_index, const Vector3& p_plot_pos, Octant &octant=octants[ptr_stack[stack_pos]]; + if (stack[stack_pos]==0) { + + + Vector3 pos = octant.aabb.pos + octant.aabb.size*0.5; + float md = 1<<(octree_depth - stack_pos ); + float r=cell_size*plot_size*md; + float div = 1.0/(md*md*md); + //div=1.0; + + + float d = p_plot_pos.distance_to(pos); + + if ((p_plane.distance_to(pos)>-cell_size*1.75*md) && d<=r) { + + + float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. + + baked_light_baker_add_64f(&octant.full_accum[0],p_tint_light.r*intensity*div); + baked_light_baker_add_64f(&octant.full_accum[1],p_tint_light.g*intensity*div); + baked_light_baker_add_64f(&octant.full_accum[2],p_tint_light.b*intensity*div); + } + } + if (octant.leaf) { @@ -727,31 +875,44 @@ void BakedLightBaker::_plot_light(int p_light_index, const Vector3& p_plot_pos, //if (p_plane.normal.dot(octant.aabb.get_support(p_plane.normal)) < p_plane.d-CMP_EPSILON) { //octants behind are no go + if (!p_only_full) { + float r=cell_size*plot_size; + for(int i=0;i<8;i++) { + Vector3 pos=octant.aabb.pos; + if (i&1) + pos.x+=octant.aabb.size.x; + if (i&2) + pos.y+=octant.aabb.size.y; + if (i&4) + pos.z+=octant.aabb.size.z; - float r=cell_size*plot_size; - for(int i=0;i<8;i++) { - Vector3 pos=octant.aabb.pos; - if (i&1) - pos.x+=octant.aabb.size.x; - if (i&2) - pos.y+=octant.aabb.size.y; - if (i&4) - pos.z+=octant.aabb.size.z; + float d = p_plot_pos.distance_to(pos); + + if ((p_plane.distance_to(pos)>-cell_size*1.75) && d<=r) { + - float d = p_plot_pos.distance_to(pos); + float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. + if (edge_damp>0) { + Vector3 normal = Vector3(octant.normal_accum[i][0],octant.normal_accum[i][1],octant.normal_accum[i][2]); + if (normal.x>0 || normal.y>0 || normal.z>0) { - if (d<=r) { + float damp = Math::abs(p_plane.normal.dot(normal)); + intensity*=pow(damp,edge_damp); + } + } - float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. - float damp = Math::abs(p_plane.normal.dot(Vector3(octant.normal_accum[i][0],octant.normal_accum[i][1],octant.normal_accum[i][2]))); - intensity*=pow(damp,edge_damp); - //intensity*=1.0-Math::abs(p_plane.distance_to(pos))/(plot_size*cell_size); - octant.light[p_light_index].accum[i][0]+=p_light.r*intensity; - octant.light[p_light_index].accum[i][1]+=p_light.g*intensity; - octant.light[p_light_index].accum[i][2]+=p_light.b*intensity; + //intensity*=1.0-Math::abs(p_plane.distance_to(pos))/(plot_size*cell_size); + //intensity = Math::cos(d*Math_PI*0.5/r); + + baked_light_baker_add_64f(&octant.light_accum[i][0],p_light.r*intensity); + baked_light_baker_add_64f(&octant.light_accum[i][1],p_light.g*intensity); + baked_light_baker_add_64f(&octant.light_accum[i][2],p_light.b*intensity); + + + } } } @@ -788,11 +949,11 @@ void BakedLightBaker::_plot_light(int p_light_index, const Vector3& p_plot_pos, } -float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce) { +float BakedLightBaker::_throw_ray(ThreadStack& thread_stack,bool p_bake_direct,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce,bool p_only_dist) { - uint32_t* stack = ray_stack; - BVH **bstack = bvh_stack; + uint32_t* stack = thread_stack.ray_stack; + BVH **bstack = thread_stack.bvh_stack; enum { TEST_AABB_BIT=0, @@ -810,6 +971,7 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons n/=len; + real_t d=1e10; bool inters=false; Vector3 r_normal; @@ -918,8 +1080,13 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons } + if (inters) { + if (p_only_dist) { + + return p_begin.distance_to(r_point); + } //should check if there is normals first @@ -933,6 +1100,9 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons } if (n.dot(r_normal)>0) + return -1; + + if (n.dot(r_normal)>0) r_normal=-r_normal; @@ -969,6 +1139,20 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons //the multiplication can happen with more detail in the shader + + if (triangle->material) { + + //triangle->get_uv(r_point); + + diffuse_at_point=triangle->material->diffuse.get_color(uv); + specular_at_point=triangle->material->specular.get_color(uv); + } + + + diffuse_at_point.r=res_light.r*diffuse_at_point.r; + diffuse_at_point.g=res_light.g*diffuse_at_point.g; + diffuse_at_point.b=res_light.b*diffuse_at_point.b; + float ret=1e6; if (p_bounces>0) { @@ -985,18 +1169,6 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons - if (triangle->material) { - - //triangle->get_uv(r_point); - - diffuse_at_point=triangle->material->diffuse.get_color(uv); - specular_at_point=triangle->material->specular.get_color(uv); - } - - - diffuse_at_point.r=res_light.r*diffuse_at_point.r; - diffuse_at_point.g=res_light.g*diffuse_at_point.g; - diffuse_at_point.b=res_light.b*diffuse_at_point.b; specular_at_point.r=res_light.r*specular_at_point.r; specular_at_point.g=res_light.g*specular_at_point.g; @@ -1024,7 +1196,7 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons #endif - ret=_throw_ray(p_light_index,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1); + ret=_throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1); } if (use_specular && (specular_at_point.r>CMP_EPSILON || specular_at_point.g>CMP_EPSILON || specular_at_point.b>CMP_EPSILON)) { @@ -1035,7 +1207,7 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons Vector3 rn = n - r_normal *r_normal.dot(n) * 2.0; - _throw_ray(p_light_index,r_point,r_point+rn*p_rest,p_rest,specular_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1); + _throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,specular_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1); } } @@ -1043,34 +1215,58 @@ float BakedLightBaker::_throw_ray(int p_light_index,const Vector3& p_begin, cons // _plot_light_point(r_point,octree,octree_aabb,p_light); - Color plot_light=res_light; + Color plot_light=res_light.linear_interpolate(diffuse_at_point,tint); plot_light.r*=att; plot_light.g*=att; plot_light.b*=att; + Color tint_light=diffuse_at_point; + tint_light.r*=att; + tint_light.g*=att; + tint_light.b*=att; + + bool skip=false; - if (!p_first_bounce) { + if (!p_first_bounce || p_bake_direct) { - float r = plot_size * cell_size*4; - if (ret<r) { + float r = plot_size * cell_size*2; + if (dist<r) { //avoid accumulaiton of light on corners //plot_light=plot_light.linear_interpolate(Color(0,0,0,0),1.0-sd/plot_size*plot_size); - plot_light=Color(0,0,0,0); + skip-true; + + } else { + + + Vector3 c1=r_normal.cross(n).normalized(); + Vector3 c2=r_normal.cross(c1).normalized(); + double r1 = double(rand())/RAND_MAX; + double r2 = double(rand())/RAND_MAX; + double r3 = double(rand())/RAND_MAX; + Vector3 rn = ((c1*(r1-0.5)) + (c2*(r2-0.5)) + (r_normal*r3*0.25)).normalized(); + float d =_throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1,false,true); + r = plot_size*cell_size*ao_radius; + if (d>0 && d<r) { + //avoid accumulaiton of light on corners + //plot_light=plot_light.linear_interpolate(Color(0,0,0,0),1.0-sd/plot_size*plot_size); + skip=true; + + } else { + //plot_light=Color(0,0,0,0); + } } } - if (!p_first_bounce || lights[p_light_index].bake_direct) { - Plane plane(r_point,r_normal); - //print_line(String(plot_light)+String(" ")+rtos(att)); - _plot_light(p_light_index,r_point,aabb,plot_light,plane); - } + Plane plane(r_point,r_normal); + if (!skip) + _plot_light(thread_stack,r_point,aabb,plot_light,tint_light,!(!p_first_bounce || p_bake_direct),plane); return dist; } - return 0; + return -1; } @@ -1170,79 +1366,100 @@ void BakedLightBaker::_make_octree_texture() { //ok let's try to just create a texture - { + int otex_w=256; - int otex_w=(1<<lattice_size)*(1<<lattice_size)*2; //make sure lattice fits horizontally - Vector3 lattice_cell_size=octree_aabb.size; - for(int i=0;i<lattice_size;i++) { + while (true) { - lattice_cell_size*=0.5; - } + uint32_t oct_idx=leaf_list; - while(true) { + int row=0; - //let's plot the leafs first, given the octree is not so obvious which size it will have - int row=4+4*(1<<lattice_size); + print_line("begin at row "+itos(row)); + int longest_line_reused=0; + int col=0; + int processed=0; - uint32_t oct_idx=leaf_list; + //reset + while(oct_idx) { - //untag - while(oct_idx) { + BakedLightBaker::Octant *oct = &octants[oct_idx]; + oct->texture_x=0; + oct->texture_y=0; + oct_idx=oct->next_leaf; - BakedLightBaker::Octant *oct = &octants[oct_idx]; - //0,0 also means unprocessed - oct->texture_x=0; - oct->texture_y=0; - oct_idx=oct->next_leaf; + } + oct_idx=leaf_list; + //assign + while(oct_idx) { + + BakedLightBaker::Octant *oct = &octants[oct_idx]; + if (oct->first_neighbour && oct->texture_x==0 && oct->texture_y==0) { + //was not processed + uint32_t current_idx=oct_idx; + int reused=0; + + while(current_idx) { + BakedLightBaker::Octant *o = &octants[current_idx]; + if (col+1 >= otex_w) { + col=0; + row+=4; + } + o->texture_x=col; + o->texture_y=row; + processed++; + + if (o->bake_neighbour) { + reused++; + } + col+=o->bake_neighbour ? 1 : 2; //reuse neighbour + current_idx=o->bake_neighbour; + } + + if (reused>longest_line_reused) { + longest_line_reused=reused; + } } + oct_idx=oct->next_leaf; + } - oct_idx=leaf_list; + row+=4; + if (otex_w < row) { - print_line("begin at row "+itos(row)); - int longest_line_reused=0; - int col=0; - int processed=0; + otex_w*=2; + } else { - while(oct_idx) { + baked_light_texture_w=otex_w; + baked_light_texture_h=nearest_power_of_2(row); + print_line("w: "+itos(otex_w)); + print_line("h: "+itos(row)); + break; + } - BakedLightBaker::Octant *oct = &octants[oct_idx]; - if (oct->first_neighbour && oct->texture_x==0 && oct->texture_y==0) { - //was not processed - uint32_t current_idx=oct_idx; - int reused=0; - while(current_idx) { - BakedLightBaker::Octant *o = &octants[current_idx]; - if (col+1 >= otex_w) { - col=0; - row+=4; - } - o->texture_x=col; - o->texture_y=row; - processed++; + } - if (o->bake_neighbour) { - reused++; - } - col+=o->bake_neighbour ? 1 : 2; //reuse neighbour - current_idx=o->bake_neighbour; - } - if (reused>longest_line_reused) { - longest_line_reused=reused; - } - } - oct_idx=oct->next_leaf; - } + { + + otex_w=(1<<lattice_size)*(1<<lattice_size)*2; //make sure lattice fits horizontally + Vector3 lattice_cell_size=octree_aabb.size; + for(int i=0;i<lattice_size;i++) { + + lattice_cell_size*=0.5; + } - print_line("processed "+itos(processed)); - print_line("longest reused: "+itos(longest_line_reused)); + + while(true) { + + //let's plot the leafs first, given the octree is not so obvious which size it will have + int row=4+4*(1<<lattice_size); + int col=0; col=0; row+=4; @@ -1343,7 +1560,25 @@ double BakedLightBaker::get_normalization(int p_light_idx) const { return nrg; } -void BakedLightBaker::throw_rays(int p_amount) { + + +double BakedLightBaker::get_modifier(int p_light_idx) const { + + double nrg=0; + + const LightData &dl=lights[p_light_idx]; + double cell_area = cell_size*cell_size;; + //nrg+= /*dl.energy */ (dl.rays_thrown * cell_area / dl.area); + nrg=cell_area; + nrg*=(Math_PI*plot_size*plot_size)*0.5; // damping of radial linear gradient kernel + nrg*=dl.constant; + //nrg*=5; + + + return nrg; +} + +void BakedLightBaker::throw_rays(ThreadStack& thread_stack,int p_amount) { @@ -1353,6 +1588,8 @@ void BakedLightBaker::throw_rays(int p_amount) { int amount = p_amount * total_light_area / dl.area; + double mod = 1.0/double(get_modifier(i)); + mod*=p_amount/float(amount); switch(dl.type) { @@ -1367,12 +1604,15 @@ void BakedLightBaker::throw_rays(int p_amount) { from+=dl.left*(r2*2.0-1.0); Vector3 to = from+dl.dir*dl.length; Color col=dl.diffuse; - col.r*=dl.energy; - col.g*=dl.energy; - col.b*=dl.energy; + float m = mod*dl.energy; + col.r*=m; + col.g*=m; + col.b*=m; + dl.rays_thrown++; - total_rays++; - _throw_ray(i,from,to,dl.length,col,NULL,0,0,max_bounces,true); + baked_light_baker_add_64i(&total_rays,1); + + _throw_ray(thread_stack,dl.bake_direct,from,to,dl.length,col,NULL,0,0,max_bounces,true); } } break; case VS::LIGHT_OMNI: { @@ -1408,13 +1648,14 @@ void BakedLightBaker::throw_rays(int p_amount) { #endif Vector3 to = dl.pos+dir*dl.radius; Color col=dl.diffuse; - col.r*=dl.energy; - col.g*=dl.energy; - col.b*=dl.energy; + float m = mod*dl.energy; + col.r*=m; + col.g*=m; + col.b*=m; dl.rays_thrown++; - total_rays++; - _throw_ray(i,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true); + baked_light_baker_add_64i(&total_rays,1); + _throw_ray(thread_stack,dl.bake_direct,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true); // _throw_ray(i,from,to,dl.radius,col,NULL,0,dl.radius,max_bounces,true); } @@ -1439,13 +1680,14 @@ void BakedLightBaker::throw_rays(int p_amount) { Vector3 to = dl.pos+dir*dl.radius; Color col=dl.diffuse; - col.r*=dl.energy; - col.g*=dl.energy; - col.b*=dl.energy; + float m = mod*dl.energy; + col.r*=m; + col.g*=m; + col.b*=m; dl.rays_thrown++; - total_rays++; - _throw_ray(i,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true); + baked_light_baker_add_64i(&total_rays,1); + _throw_ray(thread_stack,dl.bake_direct,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true); // _throw_ray(i,from,to,dl.radius,col,NULL,0,dl.radius,max_bounces,true); } @@ -1487,6 +1729,10 @@ void BakedLightBaker::bake(const Ref<BakedLight> &p_light, Node* p_node) { edge_damp=baked_light->get_edge_damp(); normal_damp=baked_light->get_normal_damp(); octree_extra_margin=baked_light->get_cell_extra_margin(); + tint=baked_light->get_tint(); + ao_radius=baked_light->get_ao_radius(); + ao_strength=baked_light->get_ao_strength(); + linear_color=baked_light->get_bake_flag(BakedLight::BAKE_LINEAR_COLOR); baked_textures.clear(); for(int i=0;i<baked_light->get_lightmaps_count();i++) { @@ -1516,13 +1762,134 @@ void BakedLightBaker::bake(const Ref<BakedLight> &p_light, Node* p_node) { } -void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { +void BakedLightBaker::update_octree_sampler(DVector<int> &p_sampler) { + + BakedLightBaker::Octant *octants=octant_pool.ptr(); + double norm = 1.0/double(total_rays); + + + + if (p_sampler.size()==0 || first_bake_to_map) { + + Vector<int> tmp_smp; + tmp_smp.resize(32); //32 for header + + for(int i=0;i<32;i++) { + tmp_smp[i]=0; + } + + for(int i=octant_pool_size-1;i>=0;i--) { + + if (i==0) + tmp_smp[1]=tmp_smp.size(); + + Octant &octant=octants[i]; + octant.sampler_ofs = tmp_smp.size(); + int idxcol[2]={0,0}; + + int r = CLAMP((octant.full_accum[0]*norm)*2048,0,32767); + int g = CLAMP((octant.full_accum[1]*norm)*2048,0,32767); + int b = CLAMP((octant.full_accum[2]*norm)*2048,0,32767); + + idxcol[0]|=r; + idxcol[1]|=(g<<16)|b; + + if (octant.leaf) { + tmp_smp.push_back(idxcol[0]); + tmp_smp.push_back(idxcol[1]); + } else { + + for(int j=0;j<8;j++) { + if (octant.children[j]) { + idxcol[0]|=(1<<(j+16)); + } + } + tmp_smp.push_back(idxcol[0]); + tmp_smp.push_back(idxcol[1]); + for(int j=0;j<8;j++) { + if (octant.children[j]) { + tmp_smp.push_back(octants[octant.children[j]].sampler_ofs); + if (octants[octant.children[j]].sampler_ofs==0) { + print_line("FUUUUUUUUCK"); + } + } + } + } + + } + + p_sampler.resize(tmp_smp.size()); + DVector<int>::Write w = p_sampler.write(); + int ss = tmp_smp.size(); + for(int i=0;i<ss;i++) { + w[i]=tmp_smp[i]; + } + + first_bake_to_map=false; + + } + + double gamma = baked_light->get_gamma_adjust(); + double mult = baked_light->get_energy_multiplier(); + float saturation = baked_light->get_saturation(); + + DVector<int>::Write w = p_sampler.write(); + + encode_uint32(octree_depth,(uint8_t*)&w[2]); + encode_uint32(linear_color,(uint8_t*)&w[3]); + + encode_float(octree_aabb.pos.x,(uint8_t*)&w[4]); + encode_float(octree_aabb.pos.y,(uint8_t*)&w[5]); + encode_float(octree_aabb.pos.z,(uint8_t*)&w[6]); + encode_float(octree_aabb.size.x,(uint8_t*)&w[7]); + encode_float(octree_aabb.size.y,(uint8_t*)&w[8]); + encode_float(octree_aabb.size.z,(uint8_t*)&w[9]); + + //norm*=multiplier; + + for(int i=octant_pool_size-1;i>=0;i--) { + + Octant &octant=octants[i]; + int idxcol[2]={w[octant.sampler_ofs],w[octant.sampler_ofs+1]}; + + double rf=pow(octant.full_accum[0]*norm*mult,gamma); + double gf=pow(octant.full_accum[1]*norm*mult,gamma); + double bf=pow(octant.full_accum[2]*norm*mult,gamma); + + double gray = (rf+gf+bf)/3.0; + rf = gray + (rf-gray)*saturation; + gf = gray + (gf-gray)*saturation; + bf = gray + (bf-gray)*saturation; + + + int r = CLAMP((rf)*2048,0,32767); + int g = CLAMP((gf)*2048,0,32767); + int b = CLAMP((bf)*2048,0,32767); + + idxcol[0]=((idxcol[0]>>16)<<16)|r; + idxcol[1]=(g<<16)|b; + w[octant.sampler_ofs]=idxcol[0]; + w[octant.sampler_ofs+1]=idxcol[1]; + } + +} + +void BakedLightBaker::update_octree_images(DVector<uint8_t> &p_octree,DVector<uint8_t> &p_light) { int len = baked_octree_texture_w*baked_octree_texture_h*4; - p_image.resize(len); - DVector<uint8_t>::Write w = p_image.write(); + p_octree.resize(len); + + int ilen = baked_light_texture_w*baked_light_texture_h*4; + p_light.resize(ilen); + + + DVector<uint8_t>::Write w = p_octree.write(); zeromem(w.ptr(),len); + + DVector<uint8_t>::Write iw = p_light.write(); + zeromem(iw.ptr(),ilen); + float gamma = baked_light->get_gamma_adjust(); float mult = baked_light->get_energy_multiplier(); @@ -1533,6 +1900,13 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { w[i+3]=0xFF; } + for(int i=0;i<ilen;i+=4) { + iw[i+0]=0xFF; + iw[i+1]=0; + iw[i+2]=0xFF; + iw[i+3]=0xFF; + } + float multiplier=1.0; if (baked_light->get_format()==BakedLight::FORMAT_HDR8) @@ -1543,6 +1917,9 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { encode_float(1<<lattice_size,&w[12]); encode_uint32(octree_depth-lattice_size,&w[16]); encode_uint32(multiplier,&w[20]); + encode_uint16(baked_light_texture_w,&w[24]); //if present, use the baked light texture + encode_uint16(baked_light_texture_h,&w[26]); + encode_uint32(0,&w[28]); //baked light texture format encode_float(octree_aabb.pos.x,&w[32]); encode_float(octree_aabb.pos.y,&w[36]); @@ -1555,6 +1932,7 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { BakedLightBaker::Octant *octants=octant_pool.ptr(); int octant_count=octant_pool_size; uint8_t *ptr = w.ptr(); + uint8_t *lptr = iw.ptr(); int child_offsets[8]={ @@ -1568,7 +1946,18 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { baked_octree_texture_w*8+baked_octree_texture_w*4+4, }; - Vector<double> norm_arr; + int lchild_offsets[8]={ + 0, + 4, + baked_light_texture_w*4, + baked_light_texture_w*4+4, + baked_light_texture_w*8+0, + baked_light_texture_w*8+4, + baked_light_texture_w*8+baked_light_texture_w*4, + baked_light_texture_w*8+baked_light_texture_w*4+4, + }; + + /*Vector<double> norm_arr; norm_arr.resize(lights.size()); for(int i=0;i<lights.size();i++) { @@ -1576,39 +1965,43 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { } const double *normptr=norm_arr.ptr(); - +*/ + double norm = 1.0/double(total_rays); int lz=lights.size(); mult/=multiplier; + double saturation = baked_light->get_saturation(); for(int i=0;i<octant_count;i++) { Octant &oct=octants[i]; if (oct.texture_x==0 && oct.texture_y==0) continue; - int ofs = (oct.texture_y * baked_octree_texture_w + oct.texture_x)<<2; + if (oct.leaf) { + int ofs = (oct.texture_y * baked_light_texture_w + oct.texture_x)<<2; + ERR_CONTINUE(ofs<0 || ofs >ilen); //write colors for(int j=0;j<8;j++) { //if (!oct.children[j]) // continue; - uint8_t *iptr=&ptr[ofs+child_offsets[j]]; - float r=0; - float g=0; - float b=0; - - for(int k=0;k<lz;k++) { - r+=oct.light[k].accum[j][0]*normptr[k]; - g+=oct.light[k].accum[j][1]*normptr[k]; - b+=oct.light[k].accum[j][2]*normptr[k]; - } + uint8_t *iptr=&lptr[ofs+lchild_offsets[j]]; + + float r=oct.light_accum[j][0]*norm; + float g=oct.light_accum[j][1]*norm; + float b=oct.light_accum[j][2]*norm; r=pow(r*mult,gamma); g=pow(g*mult,gamma); b=pow(b*mult,gamma); + double gray = (r+g+b)/3.0; + r = gray + (r-gray)*saturation; + g = gray + (g-gray)*saturation; + b = gray + (b-gray)*saturation; + float ic[3]={ r, g, @@ -1622,6 +2015,8 @@ void BakedLightBaker::update_octree_image(DVector<uint8_t> &p_image) { } else { + int ofs = (oct.texture_y * baked_octree_texture_w + oct.texture_x)<<2; + ERR_CONTINUE(ofs<0 || ofs >len); //write indices for(int j=0;j<8;j++) { @@ -1687,49 +2082,61 @@ void BakedLightBaker::_bake_thread_func(void *arg) { BakedLightBaker *ble = (BakedLightBaker*)arg; - ble->rays_at_snap_time=ble->total_rays; - ble->snap_time=OS::get_singleton()->get_ticks_usec(); - while(!ble->bake_thread_exit) { - ble->throw_rays(1000); - uint64_t t=OS::get_singleton()->get_ticks_usec(); - if (t-ble->snap_time>1000000) { + ThreadStack thread_stack; - double time = (t-ble->snap_time)/1000000.0; + thread_stack.ray_stack = memnew_arr(uint32_t,ble->bvh_depth); + thread_stack.bvh_stack = memnew_arr(BVH*,ble->bvh_depth); + thread_stack.octant_stack = memnew_arr(uint32_t,ble->octree_depth*2 ); + thread_stack.octantptr_stack = memnew_arr(uint32_t,ble->octree_depth*2 ); - int rays=ble->total_rays-ble->rays_at_snap_time; - ble->rays_sec=int(rays/time); - ble->snap_time=OS::get_singleton()->get_ticks_usec(); - ble->rays_at_snap_time=ble->total_rays; - } + while(!ble->bake_thread_exit) { + + ble->throw_rays(thread_stack,1000); } + memdelete_arr(thread_stack.ray_stack ); + memdelete_arr(thread_stack.bvh_stack ); + memdelete_arr(thread_stack.octant_stack ); + memdelete_arr(thread_stack.octantptr_stack ); + } void BakedLightBaker::_start_thread() { - if (thread!=NULL) + if (threads.size()!=0) return; bake_thread_exit=false; - thread=Thread::create(_bake_thread_func,this); + int thread_count = EDITOR_DEF("light_baker/custom_bake_threads",0); + if (thread_count<=0 || thread_count>64) + thread_count=OS::get_singleton()->get_processor_count(); + + //thread_count=1; + threads.resize(thread_count); + for(int i=0;i<threads.size();i++) { + threads[i]=Thread::create(_bake_thread_func,this); + } } void BakedLightBaker::_stop_thread() { - if (thread==NULL) + if (threads.size()==0) return; bake_thread_exit=true; - Thread::wait_to_finish(thread); - thread=NULL; + for(int i=0;i<threads.size();i++) { + Thread::wait_to_finish(threads[i]); + } + threads.clear(); } void BakedLightBaker::_plot_pixel_to_lightmap(int x, int y, int width, int height, uint8_t *image, const Vector3& p_pos,const Vector3& p_normal,double *p_norm_ptr,float mult,float gamma) { uint8_t *ptr = &image[(y*width+x)*4]; - int lc = lights.size(); + //int lc = lights.size(); + double norm = 1.0/double(total_rays); Color color; @@ -1753,11 +2160,9 @@ void BakedLightBaker::_plot_pixel_to_lightmap(int x, int y, int width, int heigh for(int i=0;i<8;i++) { - for(int j=0;j<lc;j++) { - cols[i].x+=octant.light[j].accum[i][0]*p_norm_ptr[j]; - cols[i].y+=octant.light[j].accum[i][1]*p_norm_ptr[j]; - cols[i].z+=octant.light[j].accum[i][2]*p_norm_ptr[j]; - } + cols[i].x+=octant.light_accum[i][0]*norm; + cols[i].y+=octant.light_accum[i][1]*norm; + cols[i].z+=octant.light_accum[i][2]*norm; } @@ -2220,12 +2625,13 @@ void BakedLightBaker::clear() { memdelete_arr(octantptr_stack); if (bvh_stack) memdelete_arr(bvh_stack); - +/* + * ??? for(int i=0;i<octant_pool.size();i++) { - if (octant_pool[i].leaf) { - memdelete_arr( octant_pool[i].light ); - } Vector<double> norm_arr; - norm_arr.resize(lights.size()); + //if (octant_pool[i].leaf) { + // memdelete_arr( octant_pool[i].light ); + //} Vector<double> norm_arr; + //norm_arr.resize(lights.size()); for(int i=0;i<lights.size();i++) { norm_arr[i] = 1.0/get_normalization(i); @@ -2233,6 +2639,7 @@ void BakedLightBaker::clear() { const double *normptr=norm_arr.ptr(); } +*/ octant_pool.clear(); octant_pool_size=0; bvh=NULL; @@ -2248,12 +2655,14 @@ void BakedLightBaker::clear() { lights.clear(); triangles.clear();; endpoint_normal.clear(); + endpoint_normal_bits.clear(); baked_octree_texture_w=0; baked_octree_texture_h=0; paused=false; baking=false; - thread=NULL; + bake_thread_exit=false; + first_bake_to_map=true; baked_light=Ref<BakedLight>(); total_rays=0; @@ -2278,12 +2687,11 @@ BakedLightBaker::BakedLightBaker() { baked_octree_texture_h=0; paused=false; baking=false; - thread=NULL; + bake_thread_exit=false; - rays_at_snap_time=0; - snap_time=0; - rays_sec=0; total_rays=0; + first_bake_to_map=true; + linear_color=false; } diff --git a/tools/editor/plugins/baked_light_baker.h b/tools/editor/plugins/baked_light_baker.h index 722255a565..8fbeeddc6a 100644 --- a/tools/editor/plugins/baked_light_baker.h +++ b/tools/editor/plugins/baked_light_baker.h @@ -15,17 +15,19 @@ public: OCTANT_POOL_CHUNK=1000000 }; - struct OctantLight { + //struct OctantLight { - double accum[8][3]; - }; + // double accum[8][3]; + //}; struct Octant { bool leaf; AABB aabb; uint16_t texture_x; uint16_t texture_y; + int sampler_ofs; float normal_accum[8][3]; + double full_accum[3]; int parent; union { struct { @@ -33,7 +35,7 @@ public: float offset[3]; int bake_neighbour; bool first_neighbour; - OctantLight *light; + double light_accum[8][3]; }; int children[8]; }; @@ -234,31 +236,49 @@ public: Transform base_inv; int leaf_list; int octree_depth; + int bvh_depth; int cell_count; uint32_t *ray_stack; + BVH **bvh_stack; uint32_t *octant_stack; uint32_t *octantptr_stack; + + struct ThreadStack { + uint32_t *octant_stack; + uint32_t *octantptr_stack; + uint32_t *ray_stack; + BVH **bvh_stack; + }; + Map<Vector3,Vector3> endpoint_normal; - BVH **bvh_stack; + Map<Vector3,uint64_t> endpoint_normal_bits; + float cell_size; float plot_size; //multiplied by cell size float octree_extra_margin; int max_bounces; - uint64_t total_rays; + int64_t total_rays; bool use_diffuse; bool use_specular; bool use_translucency; + bool linear_color; int baked_octree_texture_w; int baked_octree_texture_h; + int baked_light_texture_w; + int baked_light_texture_h; int lattice_size; float edge_damp; float normal_damp; + float tint; + float ao_radius; + float ao_strength; bool paused; bool baking; + bool first_bake_to_map; Map<Ref<Material>,MeshMaterial*> mat_map; Map<Ref<Texture>,MeshTexture*> tex_map; @@ -284,19 +304,16 @@ public: //void _plot_light(const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,int p_octant=0); - void _plot_light(int p_light_index,const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,const Plane& p_plane); + void _plot_light(ThreadStack& thread_stack,const Vector3& p_plot_pos,const AABB& p_plot_aabb,const Color& p_light,const Color& p_tint_light,bool p_only_full,const Plane& p_plane); //void _plot_light_point(const Vector3& p_plot_pos, Octant *p_octant, const AABB& p_aabb,const Color& p_light); - float _throw_ray(int p_light_index,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce=false); + float _throw_ray(ThreadStack& thread_stack,bool p_bake_direct,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce=false,bool p_only_dist=false); float total_light_area; - uint64_t rays_at_snap_time; - uint64_t snap_time; - int rays_sec; + Vector<Thread*> threads; - Thread *thread; bool bake_thread_exit; static void _bake_thread_func(void *arg); @@ -305,18 +322,20 @@ public: public: - void throw_rays(int p_amount); + void throw_rays(ThreadStack &thread_stack, int p_amount); double get_normalization(int p_light_idx) const; + double get_modifier(int p_light_idx) const; void bake(const Ref<BakedLight>& p_light,Node *p_base); bool is_baking(); void set_pause(bool p_pause); bool is_paused(); - int get_rays_sec() { return rays_sec; } + uint64_t get_rays_thrown() { return total_rays; } Error transfer_to_lightmaps(); - void update_octree_image(DVector<uint8_t> &p_image); + void update_octree_sampler(DVector<int> &p_sampler); + void update_octree_images(DVector<uint8_t> &p_octree,DVector<uint8_t> &p_light); Ref<BakedLight> get_baked_light() { return baked_light; } diff --git a/tools/editor/plugins/baked_light_baker_cmpxchg.cpp b/tools/editor/plugins/baked_light_baker_cmpxchg.cpp new file mode 100644 index 0000000000..d08c9f6484 --- /dev/null +++ b/tools/editor/plugins/baked_light_baker_cmpxchg.cpp @@ -0,0 +1,84 @@ + +#include "typedefs.h" + + +#ifdef WINDOWS_ENABLED + +#include "windows.h" + +void baked_light_baker_add_64f(double *dst,double value) { + + union { + int64_t i; + double f; + } swapy; + + + while(true) { + swapy.f=*dst; + int64_t from = swapy.i; + swapy.f+=value; + int64_t to=swapy.i; + int64_t result = InterlockedCompareExchange64((int64_t*)dst,to,from); + if (result==from) + break; + } + +} + +void baked_light_baker_add_64i(int64_t *dst,int64_t value) { + + while(true) { + int64_t from = *dst; + int64_t to = from+value; + int64_t result = InterlockedCompareExchange64(dst,to,from); + if (result==from) + break; + } +} + +#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100 + +void baked_light_baker_add_64f(double *dst,double value) { + + + union { + int64_t i; + double f; + } swapy; + + + while(true) { + swapy.f=*dst; + int64_t from = swapy.i; + swapy.f+=value; + int64_t to=swapy.i; + if (__sync_bool_compare_and_swap((int64_t*)dst,from,to)) + break; + } +} + +void baked_light_baker_add_64i(int64_t *dst,int64_t value) { + + while(!__sync_bool_compare_and_swap(dst,*dst,(*dst)+value)) {} + +} + +#else + +//in goder (the god of programmers) we trust +#warning seems this platform or compiler does not support safe cmpxchg, your baked lighting may be funny + +void baked_light_baker_add_64f(double *dst,double value) { + + *dst+=value; + +} + +void baked_light_baker_add_64i(int64_t *dst,int64_t value) { + + *dst+=value; + +} + +#endif diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp index 3d48f2e732..2f8393f102 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.cpp +++ b/tools/editor/plugins/baked_light_editor_plugin.cpp @@ -111,7 +111,10 @@ void BakedLightEditor::_notification(int p_option) { #endif ERR_FAIL_COND(node->get_baked_light().is_null()); - baker->update_octree_image(octree_texture); + baker->update_octree_images(octree_texture,light_texture); + baker->update_octree_sampler(octree_sampler); + // print_line("sampler size: "+itos(octree_sampler.size()*4)); + #if 1 //debug Image img(baker->baked_octree_texture_w,baker->baked_octree_texture_h,0,Image::FORMAT_RGBA,octree_texture); @@ -121,11 +124,19 @@ void BakedLightEditor::_notification(int p_option) { #endif - bake_info->set_text("rays/s: "+itos(baker->get_rays_sec())); + + + uint64_t rays_snap = baker->get_rays_thrown(); + int rays_sec = (rays_snap-last_rays_time)*1.0-(update_timeout); + last_rays_time=rays_snap; + + bake_info->set_text("rays/s: "+itos(rays_sec)); update_timeout=1; print_line("MSUPDATE: "+itos(OS::get_singleton()->get_ticks_msec()-t)); t=OS::get_singleton()->get_ticks_msec(); node->get_baked_light()->set_octree(octree_texture); + node->get_baked_light()->set_light(light_texture); + node->get_baked_light()->set_sampler_octree(octree_sampler); node->get_baked_light()->set_edited(true); print_line("MSSET: "+itos(OS::get_singleton()->get_ticks_msec()-t)); @@ -195,6 +206,9 @@ void BakedLightEditor::_bake_pressed() { baker->bake(node->get_baked_light(),node); node->get_baked_light()->set_mode(BakedLight::MODE_OCTREE); update_timeout=0; + + last_rays_time=0; + set_process(true); } diff --git a/tools/editor/plugins/baked_light_editor_plugin.h b/tools/editor/plugins/baked_light_editor_plugin.h index 7912bd92e5..27ab88d70b 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.h +++ b/tools/editor/plugins/baked_light_editor_plugin.h @@ -23,6 +23,8 @@ class BakedLightEditor : public Control { float update_timeout; DVector<uint8_t> octree_texture; + DVector<uint8_t> light_texture; + DVector<int> octree_sampler; BakedLightBaker *baker; AcceptDialog *err_dialog; @@ -33,6 +35,9 @@ class BakedLightEditor : public Control { Button *button_make_lightmaps; Label *bake_info; + uint64_t last_rays_time; + + BakedLightInstance *node; diff --git a/tools/editor/plugins/mesh_editor_plugin.cpp b/tools/editor/plugins/mesh_editor_plugin.cpp new file mode 100644 index 0000000000..b8a5bd3bbe --- /dev/null +++ b/tools/editor/plugins/mesh_editor_plugin.cpp @@ -0,0 +1,227 @@ +#include "mesh_editor_plugin.h" + +#include "tools/editor/editor_plugin.h" +#include "tools/editor/editor_node.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/physics_body.h" +#include "scene/3d/body_shape.h" +#include "scene/gui/spin_box.h" +#include "scene/gui/box_container.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/navigation_mesh.h" +#include "spatial_editor_plugin.h" + +void MeshInstanceEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + options->hide(); + } + +} + + + +void MeshInstanceEditor::edit(MeshInstance *p_mesh) { + + node=p_mesh; + +} + +void MeshInstanceEditor::_menu_option(int p_option) { + + Ref<Mesh> mesh = node->get_mesh(); + if (mesh.is_null()) { + err_dialog->set_text("Mesh is empty!"); + err_dialog->popup_centered(Size2(100,50)); + return; + } + + switch(p_option) { + case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: { + + Ref<Shape> shape = mesh->create_trimesh_shape(); + if (shape.is_null()) + return; + StaticBody *body = memnew( StaticBody ); + CollisionShape *cshape = memnew( CollisionShape ); + cshape->set_shape(shape); + body->add_child(cshape); + Node *owner = node==get_scene()->get_edited_scene_root() ? node : node->get_owner(); + + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Create Static Trimesh"); + ur->add_do_method(node,"add_child",body); + ur->add_do_method(body,"set_owner",owner); + ur->add_do_method(cshape,"set_owner",owner); + ur->add_do_reference(body); + ur->add_undo_method(node,"remove_child",body); + ur->commit_action(); + + } break; + case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: { + + Ref<Shape> shape = mesh->create_convex_shape(); + if (shape.is_null()) + return; + StaticBody *body = memnew( StaticBody ); + CollisionShape *cshape = memnew( CollisionShape ); + cshape->set_shape(shape); + body->add_child(cshape); + Node *owner = node==get_scene()->get_edited_scene_root() ? node : node->get_owner(); + + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Create Static Trimesh"); + ur->add_do_method(node,"add_child",body); + ur->add_do_method(body,"set_owner",owner); + ur->add_do_method(cshape,"set_owner",owner); + ur->add_do_reference(body); + ur->add_undo_method(node,"remove_child",body); + ur->commit_action(); + + } break; + case MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE: { + + + if (node==get_scene()->get_edited_scene_root()) { + err_dialog->set_text("This doesn't work on scene root!"); + err_dialog->popup_centered(Size2(100,50)); + return; + } + Ref<Shape> shape = mesh->create_trimesh_shape(); + if (shape.is_null()) + return; + CollisionShape *cshape = memnew( CollisionShape ); + cshape->set_shape(shape); + + Node *owner = node->get_owner(); + + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Create Static Trimesh"); + ur->add_do_method(node->get_parent(),"add_child",cshape); + ur->add_do_method(node->get_parent(),"move_child",cshape,node->get_index()+1); + ur->add_do_method(cshape,"set_owner",owner); + ur->add_do_reference(cshape); + ur->add_undo_method(node->get_parent(),"remove_child",cshape); + ur->commit_action(); + + } break; + case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: { + + + if (node==get_scene()->get_edited_scene_root()) { + err_dialog->set_text("This doesn't work on scene root!"); + err_dialog->popup_centered(Size2(100,50)); + return; + } + Ref<Shape> shape = mesh->create_convex_shape(); + if (shape.is_null()) + return; + CollisionShape *cshape = memnew( CollisionShape ); + cshape->set_shape(shape); + + Node *owner = node->get_owner(); + + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Create Static Trimesh"); + ur->add_do_method(node->get_parent(),"add_child",cshape); + ur->add_do_method(node->get_parent(),"move_child",cshape,node->get_index()+1); + ur->add_do_method(cshape,"set_owner",owner); + ur->add_do_reference(cshape); + ur->add_undo_method(node->get_parent(),"remove_child",cshape); + ur->commit_action(); + + } break; + case MENU_OPTION_CREATE_NAVMESH: { + + + + + Ref<NavigationMesh> nmesh = memnew( NavigationMesh ); + + if (nmesh.is_null()) + return; + + nmesh->create_from_mesh(mesh); + NavigationMeshInstance *nmi = memnew( NavigationMeshInstance ); + nmi->set_navigation_mesh(nmesh); + + Node *owner = node==get_scene()->get_edited_scene_root() ? node : node->get_owner(); + + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Create Navigation Mesh"); + + ur->add_do_method(node,"add_child",nmi); + ur->add_do_method(nmi,"set_owner",owner); + + ur->add_do_reference(nmi); + ur->add_undo_method(node,"remove_child",nmi); + ur->commit_action(); + } break; + } + +} + +void MeshInstanceEditor::_bind_methods() { + + ObjectTypeDB::bind_method("_menu_option",&MeshInstanceEditor::_menu_option); +} + +MeshInstanceEditor::MeshInstanceEditor() { + + + options = memnew( MenuButton ); + //add_child(options); + SpatialEditor::get_singleton()->add_control_to_menu_panel(options); + + options->set_text("Mesh"); + options->get_popup()->add_item("Create Trimesh Static Body",MENU_OPTION_CREATE_STATIC_TRIMESH_BODY); + options->get_popup()->add_item("Create Convex Static Body",MENU_OPTION_CREATE_STATIC_CONVEX_BODY); + options->get_popup()->add_separator(); + options->get_popup()->add_item("Create Trimesh Collision Sibling",MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE); + options->get_popup()->add_item("Create Convex Collision Sibling",MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE); + options->get_popup()->add_separator(); + options->get_popup()->add_item("Create Navigation Mesh",MENU_OPTION_CREATE_NAVMESH); + + options->get_popup()->connect("item_pressed", this,"_menu_option"); + +} + + +void MeshInstanceEditorPlugin::edit(Object *p_object) { + + mesh_editor->edit(p_object->cast_to<MeshInstance>()); +} + +bool MeshInstanceEditorPlugin::handles(Object *p_object) const { + + return p_object->is_type("MeshInstance"); +} + +void MeshInstanceEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + mesh_editor->options->show(); + } else { + + mesh_editor->options->hide(); + mesh_editor->edit(NULL); + } + +} + +MeshInstanceEditorPlugin::MeshInstanceEditorPlugin(EditorNode *p_node) { + + editor=p_node; + mesh_editor = memnew( MeshInstanceEditor ); + editor->get_viewport()->add_child(mesh_editor); + + mesh_editor->options->hide(); +} + + +MeshInstanceEditorPlugin::~MeshInstanceEditorPlugin() +{ +} + + diff --git a/tools/editor/plugins/mesh_editor_plugin.h b/tools/editor/plugins/mesh_editor_plugin.h new file mode 100644 index 0000000000..557eb90148 --- /dev/null +++ b/tools/editor/plugins/mesh_editor_plugin.h @@ -0,0 +1,68 @@ +#ifndef MESH_EDITOR_PLUGIN_H +#define MESH_EDITOR_PLUGIN_H + + +#include "tools/editor/editor_plugin.h" +#include "tools/editor/editor_node.h" +#include "scene/3d/mesh_instance.h" +#include "scene/gui/spin_box.h" + + +class MeshInstanceEditor : public Node { + + OBJ_TYPE(MeshInstanceEditor, Node ); + + + enum Menu { + + MENU_OPTION_CREATE_STATIC_TRIMESH_BODY, + MENU_OPTION_CREATE_STATIC_CONVEX_BODY, + MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE, + MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE, + MENU_OPTION_CREATE_NAVMESH, + }; + + AcceptDialog *err_dialog; + + + Panel *panel; + MeshInstance *node; + + LineEdit *surface_source; + LineEdit *mesh_source; + + + void _menu_option(int p_option); +friend class MeshInstanceEditorPlugin; + MenuButton * options; + +protected: + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + void edit(MeshInstance *p_mesh); + MeshInstanceEditor(); +}; + +class MeshInstanceEditorPlugin : public EditorPlugin { + + OBJ_TYPE( MeshInstanceEditorPlugin, EditorPlugin ); + + MeshInstanceEditor *mesh_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "MeshInstance"; } + 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); + + MeshInstanceEditorPlugin(EditorNode *p_node); + ~MeshInstanceEditorPlugin(); + +}; + +#endif // MESH_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/sample_player_editor_plugin.cpp b/tools/editor/plugins/sample_player_editor_plugin.cpp index fa8a285e4e..f3d6fe65da 100644 --- a/tools/editor/plugins/sample_player_editor_plugin.cpp +++ b/tools/editor/plugins/sample_player_editor_plugin.cpp @@ -64,6 +64,8 @@ void SamplePlayerEditor::_play() { return; node->call("play",samples->get_item_text( samples->get_selected() )); + stop->set_pressed(false); + play->set_pressed(true); } void SamplePlayerEditor::_stop() { @@ -74,6 +76,9 @@ void SamplePlayerEditor::_stop() { return; node->call("stop_all"); + print_line("STOP ALL!!"); + stop->set_pressed(true); + play->set_pressed(false); } diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 1c87dd0810..24e09111e2 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -1105,6 +1105,8 @@ void ScriptEditor::ensure_select_current() { if (!ste) return; Ref<Script> script = ste->get_edited_script(); + + ste->get_text_edit()->grab_focus(); } } @@ -1284,7 +1286,7 @@ void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const continue; String code = ste->get_text_edit()->get_text(); - int pos = script->get_language()->find_function(code,p_function); + int pos = script->get_language()->find_function(p_function,code); if (pos==-1) { //does not exist diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp index a5cddc20e6..e91e7a94fe 100644 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ b/tools/editor/plugins/spatial_editor_plugin.cpp @@ -860,10 +860,19 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { _edit.snap=false; _edit.mode=TRANSFORM_NONE; + //gizmo has priority over everything + bool can_select_gizmos=true; + + { + int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS); + can_select_gizmos = view_menu->get_popup()->is_item_checked( idx ); + } + + - if (spatial_editor->get_selected()) { + if (can_select_gizmos && spatial_editor->get_selected()) { Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo(); if (seg.is_valid()) { @@ -1925,6 +1934,27 @@ void SpatialEditorViewport::_menu_option(int p_option) { call_deferred("update_transform_gizmo_view"); } break; + case VIEW_AUDIO_LISTENER: { + + int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER); + bool current = view_menu->get_popup()->is_item_checked( idx ); + current=!current; + viewport->set_as_audio_listener(current); + view_menu->get_popup()->set_item_checked( idx, current ); + + } break; + case VIEW_GIZMOS: { + + int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS); + bool current = view_menu->get_popup()->is_item_checked( idx ); + current=!current; + if (current) + camera->set_visible_layers( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+index))|(1<<GIZMO_EDIT_LAYER)|(1<<GIZMO_GRID_LAYER) ); + else + camera->set_visible_layers( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+index))|(1<<GIZMO_GRID_LAYER) ); + view_menu->get_popup()->set_item_checked( idx, current ); + + } break; } @@ -1941,7 +1971,7 @@ void SpatialEditorViewport::_preview_exited_scene() { void SpatialEditorViewport::_init_gizmo_instance(int p_idx) { - uint32_t layer=1<<(GIZMO_BASE_LAYER+p_idx); + uint32_t layer=1<<(GIZMO_BASE_LAYER+p_idx);//|(1<<GIZMO_GRID_LAYER); for(int i=0;i<3;i++) { move_gizmo_instance[i]=VS::get_singleton()->instance_create(); @@ -2055,6 +2085,13 @@ void SpatialEditorViewport::set_state(const Dictionary& p_state) { _menu_option(VIEW_PERSPECTIVE); if (env != camera->get_environment().is_valid()) _menu_option(VIEW_ENVIRONMENT); + if (p_state.has("listener")) { + bool listener = p_state["listener"]; + + int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER); + viewport->set_as_audio_listener(listener); + view_menu->get_popup()->set_item_checked( idx, listener ); + } } @@ -2068,6 +2105,7 @@ Dictionary SpatialEditorViewport::get_state() const { d["distance"]=cursor.distance; d["use_environment"]=camera->get_environment().is_valid(); d["use_orthogonal"]=camera->get_projection()==Camera::PROJECTION_ORTHOGONAL; + d["listener"]=viewport->is_audio_listener(); return d; } @@ -2098,6 +2136,9 @@ void SpatialEditorViewport::reset() { cursor.distance=4; cursor.region_select=false; + + + } SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { @@ -2122,7 +2163,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed surface->set_area_as_parent_rect(); camera = memnew(Camera); camera->set_disable_gizmo(true); - camera->set_visible_layers( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+p_index)) ); + camera->set_visible_layers( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+p_index))|(1<<GIZMO_EDIT_LAYER)|(1<<GIZMO_GRID_LAYER) ); //camera->set_environment(SpatialEditor::get_singleton()->get_viewport_environment()); viewport->add_child(camera); camera->make_current(); @@ -2148,6 +2189,12 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed view_menu->get_popup()->add_check_item("Environment",VIEW_ENVIRONMENT); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT),true); view_menu->get_popup()->add_separator(); + view_menu->get_popup()->add_check_item("Audio Listener",VIEW_AUDIO_LISTENER); + view_menu->get_popup()->add_separator(); + view_menu->get_popup()->add_check_item("Gizmos",VIEW_GIZMOS); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_GIZMOS),true); + + view_menu->get_popup()->add_separator(); view_menu->get_popup()->add_item("Selection (F)",VIEW_CENTER_TO_SELECTION); view_menu->get_popup()->add_item("Align with view (Ctrl+Shift+F)",VIEW_ALIGN_SELECTION_WITH_VIEW); view_menu->get_popup()->connect("item_pressed",this,"_menu_option"); @@ -2163,6 +2210,12 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed previewing=NULL; preview=NULL; gizmo_scale=1.0; + + if (p_index==0) { + view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER),true); + viewport->set_as_audio_listener(true); + } + EditorSettings::get_singleton()->connect("settings_changed",this,"update_transform_gizmo_view"); } @@ -2322,6 +2375,10 @@ Dictionary SpatialEditor::get_state() const { vc=3; else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS) )) vc=4; + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT) )) + vc=5; + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT) )) + vc=6; d["viewport_mode"]=vc; Array vpdata; @@ -2332,11 +2389,16 @@ Dictionary SpatialEditor::get_state() const { d["viewports"]=vpdata; d["default_light"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT) );; + d["ambient_light_color"]=settings_ambient_color->get_color(); + + d["default_srgb"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB) );; d["show_grid"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID) );; d["show_origin"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN) );; d["fov"]=get_fov(); d["znear"]=get_znear(); d["zfar"]=get_zfar(); + d["deflight_rot_x"]=settings_default_light_rot_x; + d["deflight_rot_y"]=settings_default_light_rot_y; return d; } @@ -2363,6 +2425,10 @@ void SpatialEditor::set_state(const Dictionary& p_state) { _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS); else if (vc==4) _menu_item_pressed(MENU_VIEW_USE_4_VIEWPORTS); + else if (vc==5) + _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS_ALT); + else if (vc==6) + _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS_ALT); Array vp = d["viewports"]; ERR_FAIL_COND(vp.size()>4); @@ -2373,11 +2439,12 @@ void SpatialEditor::set_state(const Dictionary& p_state) { if (d.has("zfar")) - settings_zfar->set_text(d["zfar"]); + settings_zfar->set_val(float(d["zfar"])); if (d.has("znear")) - settings_znear->set_text(d["znear"]); + settings_znear->set_val(float(d["znear"])); if (d.has("fov")) - settings_fov->set_text(d["fov"]); + settings_fov->set_val(float(d["fov"])); + if (d.has("default_light")) { bool use = d["default_light"]; @@ -2395,7 +2462,17 @@ void SpatialEditor::set_state(const Dictionary& p_state) { } } + if (d.has("ambient_light_color")) { + settings_ambient_color->set_color(d["ambient_light_color"]); + viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,d["ambient_light_color"]); + } + if (d.has("default_srgb")) { + bool use = d["default_srgb"]; + + viewport_environment->set_enable_fx(Environment::FX_SRGB,use); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB), use ); + } if (d.has("show_grid")) { bool use = d["show_grid"]; @@ -2413,6 +2490,12 @@ void SpatialEditor::set_state(const Dictionary& p_state) { } } + if (d.has("deflight_rot_x")) + settings_default_light_rot_x=d["deflight_rot_x"]; + if (d.has("deflight_rot_y")) + settings_default_light_rot_y=d["deflight_rot_y"]; + + _update_default_light_angle(); } @@ -2575,11 +2658,29 @@ void SpatialEditor::_menu_item_pressed(int p_option) { } else { light_instance=VisualServer::get_singleton()->instance_create2(light,get_scene()->get_root()->get_world()->get_scenario()); VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform); + + _update_default_light_angle(); } view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), light_instance.is_valid() ); } break; + case MENU_VIEW_USE_DEFAULT_SRGB: { + + bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); + + if (is_checked) { + viewport_environment->set_enable_fx(Environment::FX_SRGB,false); + } else { + viewport_environment->set_enable_fx(Environment::FX_SRGB,true); + } + + is_checked = ! is_checked; + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), is_checked ); + + + } break; case MENU_VIEW_USE_1_VIEWPORT: { for(int i=1;i<4;i++) { @@ -2593,6 +2694,8 @@ void SpatialEditor::_menu_item_pressed(int p_option) { view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); } break; case MENU_VIEW_USE_2_VIEWPORTS: { @@ -2615,6 +2718,32 @@ void SpatialEditor::_menu_item_pressed(int p_option) { view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), true ); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); + + } break; + case MENU_VIEW_USE_2_VIEWPORTS_ALT: { + + for(int i=1;i<4;i++) { + + if (i==1 || i==3) + viewports[i]->hide(); + else + viewports[i]->show(); + + + } + viewports[0]->set_area_as_parent_rect(); + viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + viewports[2]->set_area_as_parent_rect(); + viewports[2]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); } break; case MENU_VIEW_USE_3_VIEWPORTS: { @@ -2639,6 +2768,34 @@ void SpatialEditor::_menu_item_pressed(int p_option) { view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), true ); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); + + } break; + case MENU_VIEW_USE_3_VIEWPORTS_ALT: { + + for(int i=1;i<4;i++) { + + if (i==1) + viewports[i]->hide(); + else + viewports[i]->show(); + } + viewports[0]->set_area_as_parent_rect(); + viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); + viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + viewports[2]->set_area_as_parent_rect(); + viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); + viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + viewports[3]->set_area_as_parent_rect(); + viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), true ); } break; case MENU_VIEW_USE_4_VIEWPORTS: { @@ -2664,6 +2821,8 @@ void SpatialEditor::_menu_item_pressed(int p_option) { view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); } break; case MENU_VIEW_DISPLAY_NORMAL: { @@ -2732,7 +2891,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) { } break; case MENU_VIEW_CAMERA_SETTINGS: { - settings_dialog->popup_centered(Size2(200,160)); + settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size()+Size2(50,50)); } break; } @@ -2747,6 +2906,7 @@ void SpatialEditor::_init_indicators() { light_instance=VisualServer::get_singleton()->instance_create2(light,get_scene()->get_root()->get_world()->get_scenario()); + light_transform.rotate(Vector3(1,0,0),Math_PI/5.0); VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform); @@ -2805,10 +2965,12 @@ void SpatialEditor::_init_indicators() { VisualServer::get_singleton()->mesh_add_surface(grid[i],VisualServer::PRIMITIVE_LINES,d); VisualServer::get_singleton()->mesh_surface_set_material(grid[i],0,indicator_mat); grid_instance[i] = VisualServer::get_singleton()->instance_create2(grid[i],get_scene()->get_root()->get_world()->get_scenario()); + grid_visible[i]=false; grid_enable[i]=false; VisualServer::get_singleton()->instance_geometry_set_flag(grid_instance[i],VS::INSTANCE_FLAG_VISIBLE,false); VisualServer::get_singleton()->instance_geometry_set_flag(grid_instance[i],VS::INSTANCE_FLAG_CAST_SHADOW,false); + VS::get_singleton()->instance_set_layer_mask(grid_instance[i],1<<SpatialEditorViewport::GIZMO_GRID_LAYER); } @@ -2827,6 +2989,8 @@ void SpatialEditor::_init_indicators() { // VisualServer::get_singleton()->poly_add_primitive(origin,origin_points,Vector<Vector3>(),origin_colors,Vector<Vector3>()); // VisualServer::get_singleton()->poly_set_material(origin,indicator_mat,true); origin_instance = VisualServer::get_singleton()->instance_create2(origin,get_scene()->get_root()->get_world()->get_scenario()); + VS::get_singleton()->instance_set_layer_mask(origin_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER); + VisualServer::get_singleton()->instance_geometry_set_flag(origin_instance,VS::INSTANCE_FLAG_CAST_SHADOW,false); @@ -2862,6 +3026,8 @@ void SpatialEditor::_init_indicators() { VisualServer::get_singleton()->mesh_surface_set_material(cursor_mesh,0,cmat,true); cursor_instance = VisualServer::get_singleton()->instance_create2(cursor_mesh,get_scene()->get_root()->get_world()->get_scenario()); + VS::get_singleton()->instance_set_layer_mask(cursor_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER); + VisualServer::get_singleton()->instance_geometry_set_flag(cursor_instance,VS::INSTANCE_FLAG_CAST_SHADOW,false); @@ -3133,19 +3299,23 @@ void SpatialEditor::_notification(int p_what) { view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT),get_icon("Panels1","EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS),get_icon("Panels2","EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT),get_icon("Panels2Alt","EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS),get_icon("Panels3","EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT),get_icon("Panels3Alt","EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS),get_icon("Panels4","EditorIcons")); _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); get_scene()->connect("node_removed",this,"_node_removed"); + VS::get_singleton()->scenario_set_fallback_environment(get_viewport()->find_world()->get_scenario(),viewport_environment->get_rid()); + } if (p_what==NOTIFICATION_ENTER_SCENE) { gizmos = memnew( SpatialEditorGizmos ); _init_indicators(); - + _update_default_light_angle(); } if (p_what==NOTIFICATION_EXIT_SCENE) { @@ -3250,8 +3420,12 @@ void SpatialEditor::_toggle_maximize_view(Object* p_viewport) { _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS) )) _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS); + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT) )) + _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS_ALT); else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS) )) _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS); + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT) )) + _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS_ALT); else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS) )) _menu_item_pressed(MENU_VIEW_USE_4_VIEWPORTS); } @@ -3276,7 +3450,8 @@ void SpatialEditor::_bind_methods() { // ObjectTypeDB::bind_method("_update_selection",&SpatialEditor::_update_selection); ObjectTypeDB::bind_method("_get_editor_data",&SpatialEditor::_get_editor_data); ObjectTypeDB::bind_method("_request_gizmo",&SpatialEditor::_request_gizmo); - + ObjectTypeDB::bind_method("_default_light_angle_input",&SpatialEditor::_default_light_angle_input); + ObjectTypeDB::bind_method("_update_ambient_light_color",&SpatialEditor::_update_ambient_light_color); ObjectTypeDB::bind_method("_toggle_maximize_view",&SpatialEditor::_toggle_maximize_view); ADD_SIGNAL( MethodInfo("transform_key_request") ); @@ -3286,9 +3461,9 @@ void SpatialEditor::_bind_methods() { void SpatialEditor::clear() { - settings_fov->set_text(EDITOR_DEF("3d_editor/default_fov",60.0)); - settings_znear->set_text(EDITOR_DEF("3d_editor/default_z_near",0.1)); - settings_zfar->set_text(EDITOR_DEF("3d_editor/default_z_far",1500.0)); + settings_fov->set_val(EDITOR_DEF("3d_editor/default_fov",60.0)); + settings_znear->set_val(EDITOR_DEF("3d_editor/default_z_near",0.1)); + settings_zfar->set_val(EDITOR_DEF("3d_editor/default_z_far",1500.0)); for(int i=0;i<4;i++) { viewports[i]->reset(); @@ -3307,11 +3482,59 @@ void SpatialEditor::clear() { } } + for(int i=0;i<4;i++) { + + viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(SpatialEditorViewport::VIEW_AUDIO_LISTENER),i==0); + viewports[i]->viewport->set_as_audio_listener(i==0); + } + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true ); + settings_default_light_rot_x=Math_PI*0.3; + settings_default_light_rot_y=Math_PI*0.2; + + viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,Color(0.15,0.15,0.15)); + settings_ambient_color->set_color(Color(0.15,0.15,0.15)); + if (!light_instance.is_valid()) + _menu_item_pressed(MENU_VIEW_USE_DEFAULT_LIGHT); + + _update_default_light_angle(); + } + +void SpatialEditor::_update_ambient_light_color(const Color& p_color) { + + viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,settings_ambient_color->get_color()); + +} + +void SpatialEditor::_update_default_light_angle() { + + Transform t; + t.basis.rotate(Vector3(1,0,0),settings_default_light_rot_x); + t.basis.rotate(Vector3(0,1,0),settings_default_light_rot_y); + settings_dlight->set_transform(t); + if (light_instance.is_valid()) { + VS::get_singleton()->instance_set_transform(light_instance,t); + } + +} + +void SpatialEditor::_default_light_angle_input(const InputEvent& p_event) { + + + if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&(0x1|0x2|0x4)) { + + settings_default_light_rot_y = Math::fposmod(settings_default_light_rot_y - p_event.mouse_motion.relative_x*0.01,Math_PI*2.0); + settings_default_light_rot_x = Math::fposmod(settings_default_light_rot_x - p_event.mouse_motion.relative_y*0.01,Math_PI*2.0); + _update_default_light_angle(); + } + +} + + SpatialEditor::SpatialEditor(EditorNode *p_editor) { @@ -3407,11 +3630,14 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { p = view_menu->get_popup(); p->add_check_item("Use Default Light",MENU_VIEW_USE_DEFAULT_LIGHT); + p->add_check_item("Use Default sRGB",MENU_VIEW_USE_DEFAULT_SRGB); p->add_separator(); p->add_check_item("1 Viewport",MENU_VIEW_USE_1_VIEWPORT,KEY_MASK_ALT+KEY_1); p->add_check_item("2 Viewports",MENU_VIEW_USE_2_VIEWPORTS,KEY_MASK_ALT+KEY_2); + p->add_check_item("2 Viewports (Alt)",MENU_VIEW_USE_2_VIEWPORTS_ALT,KEY_MASK_SHIFT+KEY_MASK_ALT+KEY_2); p->add_check_item("3 Viewports",MENU_VIEW_USE_3_VIEWPORTS,KEY_MASK_ALT+KEY_3); + p->add_check_item("3 Viewports (Alt)",MENU_VIEW_USE_3_VIEWPORTS_ALT,KEY_MASK_SHIFT+KEY_MASK_ALT+KEY_3); p->add_check_item("4 Viewports",MENU_VIEW_USE_4_VIEWPORTS,KEY_MASK_ALT+KEY_4); p->add_separator(); @@ -3507,42 +3733,68 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { settings_dialog = memnew( ConfirmationDialog ); settings_dialog->set_title("Viewport Settings"); add_child(settings_dialog); - l = memnew(Label); - l->set_text("Perspective FOV (deg.):"); - l->set_pos(Point2(5,5)); - settings_dialog->add_child(l); - - settings_fov = memnew( LineEdit ); - settings_fov->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - settings_fov->set_begin( Point2(15,22) ); - settings_fov->set_end( Point2(15,35) ); - settings_fov->set_text(EDITOR_DEF("3d_editor/default_fov",60.0)); - settings_dialog->add_child(settings_fov); - - l = memnew(Label); - l->set_text("View Z-Near"); - l->set_pos(Point2(5,45)); - settings_dialog->add_child(l); - - settings_znear = memnew( LineEdit ); - settings_znear->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - settings_znear->set_begin( Point2(15,62) ); - settings_znear->set_end( Point2(15,75) ); - settings_znear->set_text(EDITOR_DEF("3d_editor/default_z_near",0.1)); - settings_dialog->add_child(settings_znear); - - - l = memnew(Label); - l->set_text("View Z-Far"); - l->set_pos(Point2(5,85)); - settings_dialog->add_child(l); - - settings_zfar = memnew( LineEdit ); - settings_zfar->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - settings_zfar->set_begin( Point2(15,102) ); - settings_zfar->set_end( Point2(15,115) ); - settings_zfar->set_text(EDITOR_DEF("3d_editor/default_z_far",1500.0)); - settings_dialog->add_child(settings_zfar); + settings_vbc = memnew( VBoxContainer ); + settings_vbc->set_custom_minimum_size(Size2(200,0)); + settings_dialog->add_child(settings_vbc); + settings_dialog->set_child_rect(settings_vbc); + + + + settings_light_base = memnew( Control ); + settings_light_base->set_custom_minimum_size(Size2(128,128)); + settings_light_base->connect("input_event",this,"_default_light_angle_input"); + settings_vbc->add_margin_child("Default Light Normal:",settings_light_base); + settings_light_vp = memnew( Viewport ); + settings_light_vp->set_use_own_world(true); + settings_light_base->add_child(settings_light_vp); + + settings_dlight = memnew( DirectionalLight ); + settings_light_vp->add_child(settings_dlight); + settings_sphere = memnew( ImmediateGeometry ); + settings_sphere->begin(Mesh::PRIMITIVE_TRIANGLES,Ref<Texture>()); + settings_sphere->set_color(Color(1,1,1)); + settings_sphere->add_sphere(32,16,1); + settings_sphere->end(); + settings_light_vp->add_child(settings_sphere); + settings_camera = memnew( Camera ); + settings_light_vp->add_child(settings_camera); + settings_camera->set_translation(Vector3(0,0,2)); + settings_camera->set_orthogonal(2.1,0.1,5); + + settings_default_light_rot_x=Math_PI*0.3; + settings_default_light_rot_y=Math_PI*0.2; + + + + settings_ambient_color = memnew( ColorPickerButton ); + settings_vbc->add_margin_child("Ambient Light Color:",settings_ambient_color); + settings_ambient_color->connect("color_changed",this,"_update_ambient_light_color"); + + viewport_environment->set_enable_fx(Environment::FX_AMBIENT_LIGHT,true); + viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,Color(0.15,0.15,0.15)); + settings_ambient_color->set_color(Color(0.15,0.15,0.15)); + + + settings_fov = memnew( SpinBox ); + settings_fov->set_max(179); + settings_fov->set_min(1); + settings_fov->set_step(0.01); + settings_fov->set_val(EDITOR_DEF("3d_editor/default_fov",60.0)); + settings_vbc->add_margin_child("Perspective FOV (deg.):",settings_fov); + + settings_znear = memnew( SpinBox ); + settings_znear->set_max(10000); + settings_znear->set_min(0.1); + settings_znear->set_step(0.01); + settings_znear->set_val(EDITOR_DEF("3d_editor/default_z_near",0.1)); + settings_vbc->add_margin_child("View Z-Near:",settings_znear); + + settings_zfar = memnew( SpinBox ); + settings_zfar->set_max(10000); + settings_zfar->set_min(0.1); + settings_zfar->set_step(0.01); + settings_zfar->set_val(EDITOR_DEF("3d_editor/default_z_far",1500)); + settings_vbc->add_margin_child("View Z-Far:",settings_zfar); //settings_dialog->get_cancel()->hide(); /* XFORM DIALOG */ diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h index 4bbddbac58..1fdc97c49d 100644 --- a/tools/editor/plugins/spatial_editor_plugin.h +++ b/tools/editor/plugins/spatial_editor_plugin.h @@ -32,6 +32,8 @@ #include "tools/editor/editor_plugin.h" #include "tools/editor/editor_node.h" #include "scene/3d/visual_instance.h" +#include "scene/3d/immediate_geometry.h" +#include "scene/3d/light.h" #include "scene/gui/panel_container.h" /** @author Juan Linietsky <reduzio@gmail.com> @@ -65,7 +67,7 @@ public: class SpatialEditorViewport : public Control { OBJ_TYPE( SpatialEditorViewport, Control ); - +friend class SpatialEditor; enum { VIEW_TOP, @@ -78,12 +80,17 @@ class SpatialEditorViewport : public Control { VIEW_ALIGN_SELECTION_WITH_VIEW, VIEW_PERSPECTIVE, VIEW_ENVIRONMENT, - VIEW_ORTHOGONAL + VIEW_ORTHOGONAL, + VIEW_AUDIO_LISTENER, + VIEW_GIZMOS, }; +public: enum { - GIZMO_BASE_LAYER=25 + GIZMO_BASE_LAYER=27, + GIZMO_EDIT_LAYER=26, + GIZMO_GRID_LAYER=25 }; - +private: int index; void _menu_option(int p_option); Size2 prev_size; @@ -343,9 +350,12 @@ private: MENU_TRANSFORM_DIALOG, MENU_VIEW_USE_1_VIEWPORT, MENU_VIEW_USE_2_VIEWPORTS, + MENU_VIEW_USE_2_VIEWPORTS_ALT, MENU_VIEW_USE_3_VIEWPORTS, + MENU_VIEW_USE_3_VIEWPORTS_ALT, MENU_VIEW_USE_4_VIEWPORTS, MENU_VIEW_USE_DEFAULT_LIGHT, + MENU_VIEW_USE_DEFAULT_SRGB, MENU_VIEW_DISPLAY_NORMAL, MENU_VIEW_DISPLAY_WIREFRAME, MENU_VIEW_DISPLAY_OVERDRAW, @@ -379,15 +389,28 @@ private: LineEdit *xform_scale[3]; OptionButton *xform_type; - LineEdit *settings_fov; - LineEdit *settings_znear; - LineEdit *settings_zfar; + VBoxContainer *settings_vbc; + SpinBox *settings_fov; + SpinBox *settings_znear; + SpinBox *settings_zfar; + DirectionalLight *settings_dlight; + ImmediateGeometry *settings_sphere; + Camera *settings_camera; + float settings_default_light_rot_x; + float settings_default_light_rot_y; + + Control *settings_light_base; + Viewport *settings_light_vp; + ColorPickerButton *settings_ambient_color; + Image settings_light_dir_image; + void _xform_dialog_action(); void _menu_item_pressed(int p_option); HBoxContainer *hbc_menu; + // // void _generate_selection_box(); @@ -417,6 +440,10 @@ private: SpatialEditorGizmos *gizmos; SpatialEditor(); + void _update_ambient_light_color(const Color& p_color); + void _update_default_light_angle(); + void _default_light_angle_input(const InputEvent& p_event); + protected: @@ -433,9 +460,9 @@ public: static SpatialEditor *get_singleton() { return singleton; } void snap_cursor_to_plane(const Plane& p_plane); - float get_znear() const { return settings_znear->get_text().to_double(); } - float get_zfar() const { return settings_zfar->get_text().to_double(); } - float get_fov() const { return settings_fov->get_text().to_double(); } + float get_znear() const { return settings_znear->get_val(); } + float get_zfar() const { return settings_zfar->get_val(); } + float get_fov() const { return settings_fov->get_val(); } Transform get_gizmo_transform() const { return gizmo.transform; } bool is_gizmo_visible() const { return gizmo.visible; } diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 09f26c8ca0..a25997108b 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -166,7 +166,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); Matrix32 xform_inv = xform.affine_inverse(); - Vector2 snap = Vector2(1,1)*node->get_cell_size(); + Vector2 snap = node->get_cell_size(); switch(p_event.type) { @@ -218,7 +218,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { if (mb.mod.shift) { tool=TOOL_SELECTING; - selection_begin =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor(); + selection_begin =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); selection.pos=selection_begin; selection.size=Point2(0,0); selection_active=true; @@ -229,7 +229,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { int id = get_selected_tile(); if (id!=TileMap::INVALID_CELL) { tool=TOOL_PAINTING; - Point2i local =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor(); + Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y)))); paint_undo.clear(); CellOp op; op.idx = node->get_cell(local.x,local.y); @@ -278,7 +278,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { } else if (mb.pressed && tool==TOOL_NONE) { tool=TOOL_ERASING; - Point2i local =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor(); + Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); paint_undo.clear(); CellOp op; op.idx = node->get_cell(local.x,local.y); @@ -322,7 +322,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { const InputEventMouseMotion &mm=p_event.mouse_motion; - Point2i new_over_tile = (xform_inv.xform(Point2(mm.x,mm.y))/snap).floor(); + Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y)));//(xform_inv.xform(Point2(mm.x,mm.y))/snap).floor(); if (new_over_tile!=over_tile) { over_tile=new_over_tile; @@ -469,44 +469,104 @@ void TileMapEditor::_canvas_draw() { if (!node) return; - int cell_size=node->get_cell_size(); + Size2 cell_size=node->get_cell_size(); + Matrix32 cell_xf = node->get_cell_transform(); Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); Matrix32 xform_inv = xform.affine_inverse(); Size2 screen_size=canvas_item_editor->get_size(); - Rect2 aabb; - aabb.pos=xform_inv.xform(Vector2()); - aabb.expand_to(xform_inv.xform(Vector2(0,screen_size.height))); - aabb.expand_to(xform_inv.xform(Vector2(screen_size.width,0))); - aabb.expand_to(xform_inv.xform(screen_size)); - Rect2i si=aabb; + { + Rect2 aabb; + aabb.pos=node->world_to_map(xform_inv.xform(Vector2())); + aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(0,screen_size.height)))); + aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(screen_size.width,0)))); + aabb.expand_to(node->world_to_map(xform_inv.xform(screen_size))); + Rect2i si=aabb.grow(1.0); - for(int i=(si.pos.x/cell_size)-1;i<=(si.pos.x+si.size.x)/cell_size;i++) { + if (node->get_half_offset()!=TileMap::HALF_OFFSET_X) { - int ofs = i*cell_size; + for(int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) { - Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); - canvas_item_editor->draw_line(xform.xform(Point2(ofs,si.pos.y)),xform.xform(Point2(ofs,si.pos.y+si.size.y)),col,1); + Vector2 from = xform.xform(node->map_to_world(Vector2(i,si.pos.y))); + Vector2 to = xform.xform(node->map_to_world(Vector2(i,si.pos.y+si.size.y+1))); - } + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + + } + } else { - for(int i=(si.pos.y/cell_size)-1;i<=(si.pos.y+si.size.y)/cell_size;i++) { - int ofs = i*cell_size; + for(int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) { + + for(int j=(si.pos.y)-1;j<=(si.pos.y+si.size.y);j++) { + + Vector2 ofs; + if (ABS(j)&1) { + ofs=cell_xf[0]*0.5; + } + + Vector2 from = xform.xform(node->map_to_world(Vector2(i,j),true)+ofs); + Vector2 to = xform.xform(node->map_to_world(Vector2(i,j+1),true)+ofs); + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + } + + } + } + + if (node->get_half_offset()!=TileMap::HALF_OFFSET_Y) { + + for(int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) { + + Vector2 from = xform.xform(node->map_to_world(Vector2(si.pos.x,i))); + Vector2 to = xform.xform(node->map_to_world(Vector2(si.pos.x+si.size.x+1,i))); + + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + + } + } else { + + + for(int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) { + + for(int j=(si.pos.x)-1;j<=(si.pos.x+si.size.x);j++) { + + Vector2 ofs; + if (ABS(j)&1) { + ofs=cell_xf[1]*0.5; + } + + Vector2 from = xform.xform(node->map_to_world(Vector2(j,i),true)+ofs); + Vector2 to = xform.xform(node->map_to_world(Vector2(j+1,i),true)+ofs); + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + } + + } + + + + } +/* + for(int i=(si.pos.y/cell_size.y)-1;i<=(si.pos.y+si.size.y)/cell_size.y;i++) { + + int ofs = i*cell_size.y; Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); - canvas_item_editor->draw_line(xform.xform(Point2(si.pos.x,ofs)),xform.xform(Point2(si.pos.x+si.size.x,ofs)),col,1); + canvas_item_editor->draw_line(xform.xform(Point2(si.pos.x,ofs)),xform.xform(Point2(si.pos.x+si.size.x,ofs)),col,1);*/ } if (selection_active) { Vector<Vector2> points; - points.push_back( xform.xform( selection.pos * cell_size) ); - points.push_back( xform.xform( (selection.pos+Point2(selection.size.x+1,0)) * cell_size) ); - points.push_back( xform.xform( (selection.pos+Point2(selection.size.x+1,selection.size.y+1)) * cell_size) ); - points.push_back( xform.xform( (selection.pos+Point2(0,selection.size.y+1)) * cell_size) ); + points.push_back( xform.xform( node->map_to_world(( selection.pos ) ))); + points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(selection.size.x+1,0)) ) )); + points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(selection.size.x+1,selection.size.y+1)) ) )); + points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(0,selection.size.y+1)) ) )); Color col=Color(0.2,0.8,1,0.4); canvas_item_editor->draw_colored_polygon(points,col); @@ -515,15 +575,22 @@ void TileMapEditor::_canvas_draw() { if (mouse_over){ - const Vector2 endpoints[4]={ - - xform.xform( over_tile * cell_size) , - xform.xform( (over_tile+Point2(1,0)) * cell_size) , - xform.xform( (over_tile+Point2(1,1)) * cell_size) , - xform.xform( (over_tile+Point2(0,1)) * cell_size) , + Vector2 endpoints[4]={ + ( node->map_to_world(over_tile,true) ) , + ( node->map_to_world((over_tile+Point2(1,0)),true ) ), + ( node->map_to_world((over_tile+Point2(1,1)),true ) ), + ( node->map_to_world((over_tile+Point2(0,1)),true ) ) }; + + for(int i=0;i<4;i++) { + if (node->get_half_offset()==TileMap::HALF_OFFSET_X && ABS(over_tile.y)&1) + endpoints[i]+=cell_xf[0]*0.5; + if (node->get_half_offset()==TileMap::HALF_OFFSET_Y && ABS(over_tile.x)&1) + endpoints[i]+=cell_xf[1]*0.5; + endpoints[i]=xform.xform(endpoints[i]); + } Color col; if (node->get_cell(over_tile.x,over_tile.y)!=TileMap::INVALID_CELL) col=Color(0.2,0.8,1.0,0.8); @@ -542,10 +609,10 @@ void TileMapEditor::_canvas_draw() { Vector<Vector2> points; - points.push_back( xform.xform( duplicate.pos * cell_size) ); - points.push_back( xform.xform( (duplicate.pos+Point2(duplicate.size.x+1,0)) * cell_size) ); - points.push_back( xform.xform( (duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1)) * cell_size) ); - points.push_back( xform.xform( (duplicate.pos+Point2(0,duplicate.size.y+1)) * cell_size) ); + points.push_back( xform.xform( node->map_to_world(duplicate.pos ) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,0)) ) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1))) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(0,duplicate.size.y+1))) )); Color col=Color(0.2,1.0,0.8,0.4); canvas_item_editor->draw_colored_polygon(points,col); @@ -562,18 +629,19 @@ void TileMapEditor::_canvas_draw() { Ref<Texture> t = ts->tile_get_texture(st); if (t.is_valid()) { - Rect2 r = ts->tile_get_region(st); - Size2 sc = (endpoints[2]-endpoints[0])/cell_size; + Vector2 from = xform.xform(ts->tile_get_texture_offset(st)+node->map_to_world(over_tile)+node->get_cell_draw_offset()); + Rect2 r = ts->tile_get_region(st); + Size2 sc = xform.get_scale(); if (mirror_x->is_pressed()) sc.x*=-1.0; if (mirror_y->is_pressed()) sc.y*=-1.0; if (r==Rect2()) { - canvas_item_editor->draw_texture_rect(t,Rect2(endpoints[0],t->get_size()*sc),false,Color(1,1,1,0.5)); + canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5)); } else { - canvas_item_editor->draw_texture_rect_region(t,Rect2(endpoints[0],r.get_size()*sc),r,Color(1,1,1,0.5)); + canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5)); } } } diff --git a/tools/editor/plugins/tile_set_editor_plugin.cpp b/tools/editor/plugins/tile_set_editor_plugin.cpp index 6026cda4dc..a51caf7d54 100644 --- a/tools/editor/plugins/tile_set_editor_plugin.cpp +++ b/tools/editor/plugins/tile_set_editor_plugin.cpp @@ -44,6 +44,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me Node *child = scene->get_child(i); + if (!child->cast_to<Sprite>()) { if (child->get_child_count()>0) { child=child->get_child(0); @@ -72,7 +73,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me p_library->tile_set_texture(id,texture); - Vector2 phys_offset = mi->get_offset(); + Vector2 phys_offset; if (mi->is_centered()) { Size2 s; @@ -112,7 +113,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me } - p_library->tile_set_texture_offset(id,Vector2()); + p_library->tile_set_texture_offset(id,mi->get_offset()); } } diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp index 22331c86bf..a0031ff456 100644 --- a/tools/editor/project_export.cpp +++ b/tools/editor/project_export.cpp @@ -31,13 +31,13 @@ #include "os/dir_access.h" #include "os/file_access.h" #include "globals.h" -#include "scene/io/scene_loader.h" + #include "io/resource_loader.h" #include "io/resource_saver.h" #include "os/os.h" #include "scene/gui/box_container.h" #include "default_saver.h" -#include "scene/io/scene_saver.h" + #include "scene/gui/tab_container.h" #include "scene/gui/scroll_container.h" #include "editor_data.h" @@ -529,6 +529,8 @@ void ProjectExportDialog::_group_selected() { _update_group(); //? + + _update_group_tree(); } String ProjectExportDialog::_get_selected_group() { @@ -738,6 +740,8 @@ void ProjectExportDialog::_group_changed(Variant v) { EditorNode::get_undo_redo()->add_undo_method(this,"_save_export_cfg"); EditorNode::get_undo_redo()->commit_action(); updating=false; + // update atlas preview button + _update_group(); } void ProjectExportDialog::_group_item_edited() { diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 5764f9f2d9..0c32a4ba75 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -321,6 +321,7 @@ public: fdialog = memnew( FileDialog ); add_child(fdialog); fdialog->set_access(FileDialog::ACCESS_FILESYSTEM); + fdialog->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_path") ); project_name->connect("text_changed", this,"_text_changed"); project_path->connect("text_changed", this,"_path_text_changed"); fdialog->connect("dir_selected", this,"_path_selected"); @@ -973,6 +974,11 @@ ProjectManager::ProjectManager() { npdialog->connect("project_created", this,"_load_recent_projects"); _load_recent_projects(); + + if ( EditorSettings::get_singleton()->get("global/autoscan_project_path") ) { + _scan_begin( EditorSettings::get_singleton()->get("global/autoscan_project_path") ); + } + //get_ok()->set_text("Open"); //get_ok()->set_text("Exit"); diff --git a/tools/editor/scenes_dock.cpp b/tools/editor/scenes_dock.cpp index a23c9cead7..3f7c82d988 100644 --- a/tools/editor/scenes_dock.cpp +++ b/tools/editor/scenes_dock.cpp @@ -30,7 +30,7 @@ #include "os/dir_access.h" #include "os/file_access.h" #include "globals.h" -#include "scene/io/scene_loader.h" + #include "io/resource_loader.h" #include "os/os.h" #include "editor_node.h" @@ -200,9 +200,11 @@ void ScenesDock::_instance_pressed() { } void ScenesDock::_open_pressed(){ + TreeItem *sel = tree->get_selected(); - if (!sel) + if (!sel) { return; + } String path = sel->get_metadata(0); if (ResourceLoader::get_resource_type(path)=="PackedScene") { @@ -300,6 +302,7 @@ ScenesDock::ScenesDock(EditorNode *p_editor) { tree->set_v_size_flags(SIZE_EXPAND_FILL); tree->connect("item_edited",this,"_favorite_toggled"); + tree->connect("item_activated",this,"_open_pressed"); timer = memnew( Timer ); timer->set_one_shot(true); diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp index 082878655c..04d5888861 100644 --- a/tools/editor/spatial_editor_gizmos.cpp +++ b/tools/editor/spatial_editor_gizmos.cpp @@ -36,7 +36,7 @@ #include "scene/resources/ray_shape.h"
#include "scene/resources/convex_polygon_shape.h"
#include "scene/resources/plane_shape.h"
-#include "editor_shape_gizmos.h"
+#include "quick_hull.h"
// Keep small children away from this file.
// It's so ugly it will eat them alive
@@ -75,6 +75,7 @@ void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) { 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<<SpatialEditorViewport::GIZMO_EDIT_LAYER); //gizmos are 26
}
@@ -1237,6 +1238,10 @@ void SkeletonSpatialGizmo::redraw() { 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;i<skel->get_bone_count();i++) {
@@ -1247,8 +1252,96 @@ void SkeletonSpatialGizmo::redraw() { 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;
+ 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);
@@ -1259,13 +1352,13 @@ void SkeletonSpatialGizmo::redraw() { 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();
@@ -1302,6 +1395,7 @@ void SkeletonSpatialGizmo::redraw() { }
}
+ */
}
Ref<Mesh> m = surface_tool->commit();
@@ -1474,69 +1568,6 @@ RayCastSpatialGizmo::RayCastSpatialGizmo(RayCast* p_raycast){ }
-/////
-
-
-void CarWheelSpatialGizmo::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_travel()*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_travel(),0));
-
- //axis
- points.push_back(Vector3(r*0.2,car_wheel->get_travel(),0));
- points.push_back(Vector3(-r*0.2,car_wheel->get_travel(),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);
-
-}
-
-CarWheelSpatialGizmo::CarWheelSpatialGizmo(CarWheel* p_car_wheel){
-
- set_spatial_node(p_car_wheel);
- car_wheel=p_car_wheel;
-}
-
/////
@@ -2041,6 +2072,34 @@ void CollisionShapeSpatialGizmo::redraw(){ }
+ if (s->cast_to<ConvexPolygonShape>()) {
+
+ DVector<Vector3> points = s->cast_to<ConvexPolygonShape>()->get_points();
+
+ if (points.size()>3) {
+
+ QuickHull qh;
+ Vector<Vector3> varr = Variant(points);
+ Geometry::MeshData md;
+ Error err = qh.build(varr,md);
+ if (err==OK) {
+ Vector<Vector3> points;
+ points.resize(md.edges.size()*2);
+ for(int i=0;i<md.edges.size();i++) {
+ points[i*2+0]=md.vertices[md.edges[i].a];
+ points[i*2+1]=md.vertices[md.edges[i].b];
+ }
+
+
+ add_lines(points,SpatialEditorGizmos::singleton->shape_material);
+ add_collision_segments(points);
+
+ }
+ }
+
+ }
+
+
if (s->cast_to<RayShape>()) {
Ref<RayShape> rs=s;
@@ -2273,7 +2332,8 @@ void NavigationMeshSpatialGizmo::redraw() { Ref<TriangleMesh> tmesh = memnew( TriangleMesh);
tmesh->create(tmeshfaces);
- add_lines(lines,navmesh->is_enabled()?SpatialEditorGizmos::singleton->navmesh_edge_material:SpatialEditorGizmos::singleton->navmesh_edge_material_disabled);
+ 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<Mesh> m = memnew( Mesh );
Array a;
@@ -2888,16 +2948,6 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) { return misg;
}
- if (p_spatial->cast_to<EditableShape>()) {
-
- Ref<EditableShapeSpatialGizmo> misg = memnew( EditableShapeSpatialGizmo(p_spatial->cast_to<EditableShape>()) );
- return misg;
- }
- if (p_spatial->cast_to<CarWheel>()) {
-
- 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>()) );
diff --git a/tools/editor/spatial_editor_gizmos.h b/tools/editor/spatial_editor_gizmos.h index 55e40c7b7c..7f39b648d7 100644 --- a/tools/editor/spatial_editor_gizmos.h +++ b/tools/editor/spatial_editor_gizmos.h @@ -44,7 +44,7 @@ #include "scene/3d/portal.h"
#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"
@@ -332,19 +332,6 @@ public: };
-class CarWheelSpatialGizmo : public SpatialGizmoTool {
-
- OBJ_TYPE(CarWheelSpatialGizmo,SpatialGizmoTool);
-
- CarWheel* car_wheel;
-
-public:
-
- void redraw();
- CarWheelSpatialGizmo(CarWheel* p_car_wheel=NULL);
-
-};
-
class VehicleWheelSpatialGizmo : public SpatialGizmoTool {
|