diff options
-rw-r--r-- | demos/3d/inverse_kinematics/engine.cfg | 0 | ||||
-rw-r--r-- | demos/3d/inverse_kinematics/main.scn | bin | 0 -> 503 bytes | |||
-rw-r--r-- | modules/ik/SCsub | 3 | ||||
-rw-r--r-- | modules/ik/config.py | 11 | ||||
-rw-r--r-- | modules/ik/ik.cpp | 326 | ||||
-rw-r--r-- | modules/ik/ik.h | 74 | ||||
-rw-r--r-- | modules/ik/register_types.cpp | 47 | ||||
-rw-r--r-- | modules/ik/register_types.h | 30 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 6 | ||||
-rw-r--r-- | scene/3d/physics_body.cpp | 6 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 40 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 6 | ||||
-rw-r--r-- | scene/scene_string_names.cpp | 1 | ||||
-rw-r--r-- | scene/scene_string_names.h | 1 | ||||
-rw-r--r-- | tools/editor/editor_data.cpp | 10 | ||||
-rw-r--r-- | tools/editor/editor_data.h | 1 | ||||
-rw-r--r-- | tools/editor/editor_node.cpp | 116 | ||||
-rw-r--r-- | tools/editor/editor_node.h | 36 | ||||
-rw-r--r-- | tools/editor/editor_settings.cpp | 1 | ||||
-rw-r--r-- | tools/editor/plugins/canvas_item_editor_plugin.cpp | 6 | ||||
-rw-r--r-- | tools/editor/plugins/script_editor_plugin.cpp | 13 | ||||
-rw-r--r-- | tools/editor/plugins/spatial_editor_plugin.cpp | 102 | ||||
-rw-r--r-- | tools/editor/scene_tree_dock.cpp | 3 |
23 files changed, 755 insertions, 84 deletions
diff --git a/demos/3d/inverse_kinematics/engine.cfg b/demos/3d/inverse_kinematics/engine.cfg new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/demos/3d/inverse_kinematics/engine.cfg diff --git a/demos/3d/inverse_kinematics/main.scn b/demos/3d/inverse_kinematics/main.scn Binary files differnew file mode 100644 index 0000000000..918fd09a3a --- /dev/null +++ b/demos/3d/inverse_kinematics/main.scn diff --git a/modules/ik/SCsub b/modules/ik/SCsub new file mode 100644 index 0000000000..211a043468 --- /dev/null +++ b/modules/ik/SCsub @@ -0,0 +1,3 @@ +Import('env') + +env.add_source_files(env.modules_sources,"*.cpp") diff --git a/modules/ik/config.py b/modules/ik/config.py new file mode 100644 index 0000000000..f9bd7da08d --- /dev/null +++ b/modules/ik/config.py @@ -0,0 +1,11 @@ + + +def can_build(platform): + return True + + +def configure(env): + pass + + + diff --git a/modules/ik/ik.cpp b/modules/ik/ik.cpp new file mode 100644 index 0000000000..6c383fdb55 --- /dev/null +++ b/modules/ik/ik.cpp @@ -0,0 +1,326 @@ +/*************************************************************************/ +/* ik.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* This file is Copyright (c) 2016 Sergey Lapin <slapinid@gmail.com> */ +/* */ +/* 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 "ik.h" + +bool InverseKinematics::_get(const StringName& p_name,Variant &r_ret) const +{ + + if (String(p_name)=="ik_bone") { + + r_ret=get_bone_name(); + return true; + } + + return false; +} + +bool InverseKinematics::_set(const StringName& p_name, const Variant& p_value) +{ + + if (String(p_name)=="ik_bone") { + + set_bone_name(p_value); + changed = true; + return true; + } + + return false; +} + +void InverseKinematics::_get_property_list( List<PropertyInfo>* p_list ) const +{ + + Skeleton *parent=NULL; + if(get_parent()) + parent=get_parent()->cast_to<Skeleton>(); + + if (parent) { + + String names; + for(int i=0;i<parent->get_bone_count();i++) { + if(i>0) + names+=","; + names+=parent->get_bone_name(i); + } + + p_list->push_back(PropertyInfo(Variant::STRING,"ik_bone",PROPERTY_HINT_ENUM,names)); + } else { + + p_list->push_back(PropertyInfo(Variant::STRING,"ik_bone")); + + } + +} + +void InverseKinematics::_check_bind() +{ + + if (get_parent() && get_parent()->cast_to<Skeleton>()) { + Skeleton *sk = get_parent()->cast_to<Skeleton>(); + int idx = sk->find_bone(ik_bone); + if (idx!=-1) { + ik_bone_no = idx; + bound=true; + } + skel = sk; + } +} + +void InverseKinematics::_check_unbind() +{ + + if (bound) { + + if (get_parent() && get_parent()->cast_to<Skeleton>()) { + Skeleton *sk = get_parent()->cast_to<Skeleton>(); + int idx = sk->find_bone(ik_bone); + if (idx!=-1) + ik_bone_no = idx; + else + ik_bone_no = 0; + skel = sk; + + } + bound=false; + } +} + + +void InverseKinematics::set_bone_name(const String& p_name) +{ + + if (is_inside_tree()) + _check_unbind(); + + ik_bone=p_name; + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +String InverseKinematics::get_bone_name() const +{ + + return ik_bone; +} + +void InverseKinematics::set_iterations(int itn) +{ + + if (is_inside_tree()) + _check_unbind(); + + iterations=itn; + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +int InverseKinematics::get_iterations() const +{ + + return iterations; +} + +void InverseKinematics::set_chain_size(int cs) +{ + if (is_inside_tree()) + _check_unbind(); + + chain_size=cs; + chain.clear(); + if (bound) + update_parameters(); + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +int InverseKinematics::get_chain_size() const +{ + + return chain_size; +} + +void InverseKinematics::set_precision(float p) +{ + + if (is_inside_tree()) + _check_unbind(); + + precision=p; + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +float InverseKinematics::get_precision() const +{ + + return precision; +} + +void InverseKinematics::set_speed(float p) +{ + + if (is_inside_tree()) + _check_unbind(); + + speed=p; + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +float InverseKinematics::get_speed() const +{ + + return speed; +} + +void InverseKinematics::update_parameters() +{ + tail_bone = -1; + for (int i = 0; i < skel->get_bone_count(); i++) + if (skel->get_bone_parent(i) == ik_bone_no) + tail_bone = i; + int cur_bone = ik_bone_no; + int its = chain_size; + while (its > 0 && cur_bone >= 0) { + chain.push_back(cur_bone); + cur_bone = skel->get_bone_parent(cur_bone); + its--; + } +} + +void InverseKinematics::_notification(int p_what) +{ + + switch(p_what) { + + case NOTIFICATION_ENTER_TREE: { + + _check_bind(); + if (bound) { + update_parameters(); + changed = false; + set_process(true); + } + } break; + case NOTIFICATION_PROCESS: { + float delta = get_process_delta_time(); + Spatial *sksp = skel->cast_to<Spatial>(); + if (!bound) + break; + if (!sksp) + break; + if (changed) { + update_parameters(); + changed = false; + } + Vector3 to = get_translation(); + for (int hump = 0; hump < iterations; hump++) { + int depth = 0; + float olderr = 1000.0; + float psign = 1.0; + bool reached = false; + + for (List<int>::Element *b = chain.front(); b; b = b->next()) { + int cur_bone = b->get(); + Vector3 d = skel->get_bone_global_pose(tail_bone).origin; + Vector3 rg = to; + float err = d.distance_squared_to(rg); + if (err < precision) { + if (!reached && err < precision) + reached = true; + break; + } else + if (reached) + reached = false; + if (err > olderr) + psign = -psign; + Transform mod = skel->get_bone_global_pose(cur_bone); + Quat q1 = Quat(mod.basis).normalized(); + Transform mod2 = mod.looking_at(to, Vector3(0.0, 1.0, 0.0)); + Quat q2 = Quat(mod2.basis).normalized(); + if (psign < 0.0) + q2 = q2.inverse(); + Quat q = q1.slerp(q2, speed / (1.0 + 500.0 * depth)).normalized(); + Transform fin = Transform(q); + fin.origin = mod.origin; + skel->set_bone_global_pose(cur_bone, fin); + depth++; + } + if (reached) + break; + + } + + } break; + case NOTIFICATION_EXIT_TREE: { + set_process(false); + + _check_unbind(); + } break; + } +} +void InverseKinematics::_bind_methods() { + ObjectTypeDB::bind_method(_MD("set_bone_name","ik_bone"),&InverseKinematics::set_bone_name); + ObjectTypeDB::bind_method(_MD("get_bone_name"),&InverseKinematics::get_bone_name); + ObjectTypeDB::bind_method(_MD("set_iterations","iterations"),&InverseKinematics::set_iterations); + ObjectTypeDB::bind_method(_MD("get_iterations"),&InverseKinematics::get_iterations); + ObjectTypeDB::bind_method(_MD("set_chain_size","chain_size"),&InverseKinematics::set_chain_size); + ObjectTypeDB::bind_method(_MD("get_chain_size"),&InverseKinematics::get_chain_size); + ObjectTypeDB::bind_method(_MD("set_precision","precision"),&InverseKinematics::set_precision); + ObjectTypeDB::bind_method(_MD("get_precision"),&InverseKinematics::get_precision); + ObjectTypeDB::bind_method(_MD("set_speed","speed"),&InverseKinematics::set_speed); + ObjectTypeDB::bind_method(_MD("get_speed"),&InverseKinematics::get_speed); + ADD_PROPERTY(PropertyInfo(Variant::INT, "iterations"), _SCS("set_iterations"), _SCS("get_iterations")); + ADD_PROPERTY(PropertyInfo(Variant::INT, "chain_size"), _SCS("set_chain_size"), _SCS("get_chain_size")); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "precision"), _SCS("set_precision"), _SCS("get_precision")); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed"), _SCS("set_speed"), _SCS("get_speed")); +} + +InverseKinematics::InverseKinematics() +{ + bound=false; + chain_size = 2; + iterations = 100; + precision = 0.001; + speed = 0.2; + +} + diff --git a/modules/ik/ik.h b/modules/ik/ik.h new file mode 100644 index 0000000000..9daddb229d --- /dev/null +++ b/modules/ik/ik.h @@ -0,0 +1,74 @@ +/*************************************************************************/ +/* ik.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* This file is (c) 2016 Sergey Lapin <slapinid@gmail.com> */ +/* */ +/* 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 IK_H +#define IK_H + +#include "scene/3d/skeleton.h" +class InverseKinematics : public Spatial { + OBJ_TYPE(InverseKinematics, Spatial); + bool bound; + String ik_bone; + int ik_bone_no; + int tail_bone; + int chain_size; + Skeleton *skel; + List<int> chain; + void _check_bind(); + void _check_unbind(); + int iterations; + float precision; + float speed; + bool changed; + +protected: + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List<PropertyInfo> *p_list) const; + + void _notification(int p_what); + static void _bind_methods(); + void update_parameters(); +public: + Skeleton *get_skeleton(); + void set_bone_name(const String& p_name); + String get_bone_name() const; + void set_iterations(int itn); + int get_iterations() const; + void set_chain_size(int cs); + int get_chain_size() const; + void set_precision(float p); + float get_precision() const; + void set_speed(float p); + float get_speed() const; + InverseKinematics(); +}; + +#endif + diff --git a/modules/ik/register_types.cpp b/modules/ik/register_types.cpp new file mode 100644 index 0000000000..e7df7f55b2 --- /dev/null +++ b/modules/ik/register_types.cpp @@ -0,0 +1,47 @@ +/*************************************************************************/ +/* register_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 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 "register_types.h" +#ifndef _3D_DISABLED +#include "object_type_db.h" +#include "ik.h" +#endif + +void register_ik_types() { + +#ifndef _3D_DISABLED + ObjectTypeDB::register_type<InverseKinematics>(); +#endif +} + + + +void unregister_ik_types() { + + +} diff --git a/modules/ik/register_types.h b/modules/ik/register_types.h new file mode 100644 index 0000000000..828917ade7 --- /dev/null +++ b/modules/ik/register_types.h @@ -0,0 +1,30 @@ +/*************************************************************************/ +/* register_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 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. */ +/*************************************************************************/ +void register_ik_types(); +void unregister_ik_types(); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index cc2e5c0d72..dc038f010c 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -544,7 +544,10 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { set_global_transform(state->get_transform()); linear_velocity=state->get_linear_velocity(); angular_velocity=state->get_angular_velocity(); - sleeping=state->is_sleeping(); + if(sleeping!=state->is_sleeping()) { + sleeping=state->is_sleeping(); + emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + } if (get_script_instance()) get_script_instance()->call("_integrate_forces",state); set_block_transform_notify(false); // want it back @@ -934,6 +937,7 @@ void RigidBody2D::_bind_methods() { ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape"))); ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body"))); ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body"))); + ADD_SIGNAL( MethodInfo("sleeping_state_changed")); BIND_CONSTANT( MODE_STATIC ); BIND_CONSTANT( MODE_KINEMATIC ); diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 1a2665b6ad..bc637eed44 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -419,7 +419,10 @@ void RigidBody::_direct_state_changed(Object *p_state) { set_global_transform(state->get_transform()); linear_velocity=state->get_linear_velocity(); angular_velocity=state->get_angular_velocity(); - sleeping=state->is_sleeping(); + if(sleeping!=state->is_sleeping()) { + sleeping=state->is_sleeping(); + emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + } if (get_script_instance()) get_script_instance()->call("_integrate_forces",state); set_ignore_transform_notification(false); @@ -811,6 +814,7 @@ void RigidBody::_bind_methods() { ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape"))); ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body"))); ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body"))); + ADD_SIGNAL( MethodInfo("sleeping_state_changed")); BIND_CONSTANT( MODE_STATIC ); BIND_CONSTANT( MODE_KINEMATIC ); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 321bbb9338..1a29e6c5f1 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -672,6 +672,7 @@ void TextEdit::_notification(int p_what) { bool in_keyword=false; bool in_word = false; bool in_function_name = false; + bool in_member_variable = false; Color keyword_color; // check if line contains highlighted word @@ -803,14 +804,28 @@ void TextEdit::_notification(int p_what) { } } + if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) { + int k = j; + while(k > 0 && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k--; + } + + if (str[k] == '.') { + in_member_variable = true; + } + } + if (is_symbol) { in_function_name = false; + in_member_variable = false; } if (in_region>=0) color=color_regions[in_region].color; else if (in_keyword) color=keyword_color; + else if (in_member_variable) + color=cache.member_variable_color; else if (in_function_name) color=cache.function_color; else if (is_symbol) @@ -1132,7 +1147,7 @@ void TextEdit::_consume_pair_symbol(CharType ch) { int new_column,new_line; - _begin_complex_operation(); + begin_complex_operation(); _insert_text(get_selection_from_line(), get_selection_from_column(), ch_single, &new_line, &new_column); @@ -1145,7 +1160,7 @@ void TextEdit::_consume_pair_symbol(CharType ch) { get_selection_to_column() + to_col_offset, ch_single_pair, &new_line,&new_column); - _end_complex_operation(); + end_complex_operation(); cursor_set_line(get_selection_to_line()); cursor_set_column(get_selection_to_column() + to_col_offset); @@ -1599,7 +1614,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { // remove the old character if in insert mode if (insert_mode) { - _begin_complex_operation(); + begin_complex_operation(); // make sure we don't try and remove empty space if (cursor.column < get_line(cursor.line).length()) { @@ -1610,7 +1625,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { _insert_text_at_cursor(chr); if (insert_mode) { - _end_complex_operation(); + end_complex_operation(); } } } @@ -1686,10 +1701,10 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { cursor_set_line(selection.from_line); cursor_set_column(selection.from_column); - _begin_complex_operation(); + begin_complex_operation(); _remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column); _insert_text_at_cursor(txt); - _end_complex_operation(); + end_complex_operation(); selection.active=true; selection.from_column=sel_column; selection.from_line=sel_line; @@ -1747,7 +1762,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } if (clear) { - _begin_complex_operation(); + begin_complex_operation(); selection.active=false; update(); _remove_text(selection.from_line,selection.from_column,selection.to_line,selection.to_column); @@ -2396,7 +2411,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { // remove the old character if in insert mode and no selection if (insert_mode && !had_selection) { - _begin_complex_operation(); + begin_complex_operation(); // make sure we don't try and remove empty space if (cursor.column < get_line(cursor.line).length()) { @@ -2416,11 +2431,11 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } if (insert_mode && !had_selection) { - _end_complex_operation(); + end_complex_operation(); } if (selection.active != had_selection) { - _end_complex_operation(); + end_complex_operation(); } accept_event(); } else { @@ -3050,6 +3065,7 @@ void TextEdit::_update_caches() { cache.font_selected_color=get_color("font_selected_color"); cache.keyword_color=get_color("keyword_color"); cache.function_color=get_color("function_color"); + cache.member_variable_color=get_color("member_variable_color"); cache.number_color=get_color("number_color"); cache.selection_color=get_color("selection_color"); cache.mark_color=get_color("mark_color"); @@ -3614,12 +3630,12 @@ void TextEdit::clear_undo_history() { } -void TextEdit::_begin_complex_operation() { +void TextEdit::begin_complex_operation() { _push_current_op(); next_operation_is_complex=true; } -void TextEdit::_end_complex_operation() { +void TextEdit::end_complex_operation() { _push_current_op(); ERR_FAIL_COND(undo_stack.size() == 0); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index cd27469914..3b85ef0b23 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -79,6 +79,7 @@ class TextEdit : public Control { Color keyword_color; Color number_color; Color function_color; + Color member_variable_color; Color selection_color; Color mark_color; Color breakpoint_color; @@ -266,8 +267,6 @@ class TextEdit : public Control { void _cursor_changed_emit(); void _text_changed_emit(); - void _begin_complex_operation(); - void _end_complex_operation(); void _push_current_op(); /* super internal api, undo/redo builds on it */ @@ -319,6 +318,9 @@ public: //void delete_char(); //void delete_line(); + void begin_complex_operation(); + void end_complex_operation(); + void set_text(String p_text); void insert_text_at_cursor(const String& p_text); void insert_at(const String& p_text, int at); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 57bde00de4..f47b61001c 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -48,6 +48,7 @@ SceneStringNames::SceneStringNames() { item_rect_changed=StaticCString::create("item_rect_changed"); size_flags_changed=StaticCString::create("size_flags_changed"); minimum_size_changed=StaticCString::create("minimum_size_changed"); + sleeping_state_changed=StaticCString::create("sleeping_state_changed"); finished=StaticCString::create("finished"); animation_changed=StaticCString::create("animation_changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index b2c0e9abf0..fc45351c33 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -62,6 +62,7 @@ public: StringName exit_tree; StringName size_flags_changed; StringName minimum_size_changed; + StringName sleeping_state_changed; StringName idle; StringName iteration; StringName update; diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp index f78ab93c30..8bb2d60cab 100644 --- a/tools/editor/editor_data.cpp +++ b/tools/editor/editor_data.cpp @@ -260,6 +260,16 @@ EditorPlugin* EditorData::get_subeditor(Object *p_object) { return NULL; } +Vector<EditorPlugin*> EditorData::get_subeditors(Object* p_object) { + Vector<EditorPlugin*> sub_plugins; + for (int i = 0; i < editor_plugins.size(); i++) { + if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) { + sub_plugins.push_back(editor_plugins[i]); + } + } + return sub_plugins; +} + EditorPlugin* EditorData::get_editor(String p_name) { for(int i=0;i<editor_plugins.size();i++) { diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h index 5814ae8f5c..79843c4df5 100644 --- a/tools/editor/editor_data.h +++ b/tools/editor/editor_data.h @@ -150,6 +150,7 @@ public: EditorPlugin* get_editor(Object *p_object); EditorPlugin* get_subeditor(Object *p_object); + Vector<EditorPlugin*> get_subeditors(Object *p_object); EditorPlugin* get_editor(String p_name); void copy_object_params(Object *p_object); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 6d033a5c25..aa47e97622 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -1571,15 +1571,27 @@ void EditorNode::_imported(Node *p_node) { } +void EditorNode::_hide_top_editors() { + _display_top_editors(false); -void EditorNode::_hide_top_editors() { + editor_plugins_over->clear(); +} + +void EditorNode::_display_top_editors(bool p_display) { + editor_plugins_over->make_visible(p_display); +} + +void EditorNode::_set_top_editors(Vector<EditorPlugin*> p_editor_plugins_over) { + editor_plugins_over->set_plugins_list(p_editor_plugins_over); +} - if (editor_plugin_over) - editor_plugin_over->make_visible(false); - editor_plugin_over=NULL; +void EditorNode::_set_editing_top_editors(Object* p_current_object) { + editor_plugins_over->edit(p_current_object); } + + void EditorNode::_edit_current() { uint32_t current = editor_history.get_current(); @@ -1598,8 +1610,7 @@ void EditorNode::_edit_current() { property_editor->edit( NULL ); object_menu->set_disabled(true); - if (editor_plugin_over) - editor_plugin_over->make_visible(false); + _display_top_editors(false); return; } @@ -1679,20 +1690,18 @@ void EditorNode::_edit_current() { } - EditorPlugin *sub_plugin = editor_data.get_subeditor(current_obj); - - if (sub_plugin) { + Vector<EditorPlugin*> sub_plugins = editor_data.get_subeditors(current_obj); + if (!sub_plugins.empty()) { + _display_top_editors(false); - if (editor_plugin_over) - editor_plugin_over->make_visible(false); - editor_plugin_over=sub_plugin; - editor_plugin_over->edit(current_obj); - editor_plugin_over->make_visible(true); - } else if (editor_plugin_over) { + _set_top_editors(sub_plugins); + _set_editing_top_editors(current_obj); + _display_top_editors(true); + + } else if (!editor_plugins_over->get_plugins_list().empty()) { - editor_plugin_over->make_visible(false); - editor_plugin_over=NULL; + _hide_top_editors(); } /* @@ -2583,10 +2592,9 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { } editor_data.get_undo_redo().clear_history(); - if (editor_plugin_over) { //reload editor plugin - editor_plugin_over->edit(NULL); - editor_plugin_over->edit(current); - } + + _set_editing_top_editors(NULL); + _set_editing_top_editors(current); } break; case OBJECT_CALL_METHOD: { @@ -6138,7 +6146,7 @@ EditorNode::EditorNode() { _rebuild_import_menu(); editor_plugin_screen=NULL; - editor_plugin_over=NULL; + editor_plugins_over = memnew(EditorPluginList); // force_top_viewport(true); _edit_current(); @@ -6270,12 +6278,72 @@ EditorNode::EditorNode() { EditorNode::~EditorNode() { - - + memdelete( EditorHelp::get_doc_data() ); memdelete(editor_selection); + memdelete(editor_plugins_over); memdelete(file_server); EditorSettings::destroy(); } +/* + * EDITOR PLUGIN LIST + */ + + +void EditorPluginList::make_visible(bool p_visible) { + if (!plugins_list.empty()) { + for (int i = 0; i < plugins_list.size(); i++) { + plugins_list[i]->make_visible(p_visible); + } + } +} + +void EditorPluginList::edit(Object* p_object) { + if (!plugins_list.empty()) { + for (int i = 0; i < plugins_list.size(); i++) { + plugins_list[i]->edit(p_object); + } + } +} + +bool EditorPluginList::forward_input_event(const InputEvent& p_event) { + bool discard = false; + if (!plugins_list.empty()) { + for (int i = 0; i < plugins_list.size(); i++) { + if (plugins_list[i]->forward_input_event(p_event)) { + discard = true; + } + } + } + return discard; +} + +bool EditorPluginList::forward_spatial_input_event(Camera* p_camera, const InputEvent& p_event) { + bool discard = false; + if (!plugins_list.empty()) { + for (int i = 0; i < plugins_list.size(); i++) { + if (plugins_list[i]->forward_spatial_input_event(p_camera, p_event)) { + discard = true; + } + } + } + return discard; +} + +bool EditorPluginList::empty() { + return plugins_list.empty(); +} + +void EditorPluginList::clear() { + plugins_list.clear(); +} + +EditorPluginList::EditorPluginList() { +} + +EditorPluginList::~EditorPluginList() { +} + + diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index b8fabb4c55..e4939afd34 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -95,7 +95,7 @@ typedef void (*EditorNodeInitCallback)(); - +class EditorPluginList; class EditorNode : public Node { @@ -372,7 +372,7 @@ private: Vector<EditorPlugin*> editor_plugins; EditorPlugin *editor_plugin_screen; - EditorPlugin *editor_plugin_over; + EditorPluginList *editor_plugins_over; EditorHistory editor_history; EditorData editor_data; @@ -449,6 +449,10 @@ private: void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); void _hide_top_editors(); + void _display_top_editors(bool p_display); + void _set_top_editors(Vector<EditorPlugin*> p_editor_plugins_over); + void _set_editing_top_editors(Object * p_current_object); + void _quick_opened(); void _quick_run(); @@ -575,7 +579,7 @@ public: EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; } - EditorPlugin *get_editor_plugin_over() { return editor_plugin_over; } + EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; } PropertyEditor *get_property_editor() { return property_editor; } static void add_editor_plugin(EditorPlugin *p_editor); @@ -710,6 +714,32 @@ struct EditorProgress { ~EditorProgress() { EditorNode::progress_end_task(task); } }; +class EditorPluginList : public Object { +private: + Vector<EditorPlugin*> plugins_list; + +public: + + void set_plugins_list(Vector<EditorPlugin*> p_plugins_list) { + plugins_list = p_plugins_list; + } + + Vector<EditorPlugin*> get_plugins_list() { + return plugins_list; + } + + void make_visible(bool p_visible); + void edit(Object *p_object); + bool forward_input_event(const InputEvent& p_event); + bool forward_spatial_input_event(Camera* p_camera, const InputEvent& p_event); + void clear(); + bool empty(); + + EditorPluginList(); + ~EditorPluginList(); + +} ; + struct EditorProgressBG { String task; diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 4ef50b72c2..8402a60438 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -399,6 +399,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("text_editor/base_type_color",Color::html("a4ffd4")); set("text_editor/engine_type_color",Color::html("83d3ff")); set("text_editor/function_color",Color::html("66a2ce")); + set("text_editor/member_variable_color",Color::html("e64e59")); set("text_editor/comment_color",Color::html("983d1b")); set("text_editor/string_color",Color::html("ef6ebe")); set("text_editor/number_color",Color::html("EB9532")); diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index 6eb26542be..b5059e5299 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -1037,10 +1037,10 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) { { EditorNode *en = editor; - EditorPlugin *over_plugin = en->get_editor_plugin_over(); + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - if (over_plugin) { - bool discard = over_plugin->forward_input_event(p_event); + if (!over_plugin_list->empty()) { + bool discard = over_plugin_list->forward_input_event(p_event); if (discard) { accept_event(); return; diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index d6d5afd166..625dcd697f 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -296,6 +296,7 @@ void ScriptTextEditor::_load_theme_settings() { get_text_edit()->add_color_override("word_highlighted_color",EDITOR_DEF("text_editor/word_highlighted_color",Color(0.8,0.9,0.9,0.15))); get_text_edit()->add_color_override("number_color",EDITOR_DEF("text_editor/number_color",Color(0.9,0.6,0.0,2))); get_text_edit()->add_color_override("function_color",EDITOR_DEF("text_editor/function_color",Color(0.4,0.6,0.8))); + get_text_edit()->add_color_override("member_variable_color",EDITOR_DEF("text_editor/member_variable_color",Color(0.9,0.3,0.3))); Color keyword_color= EDITOR_DEF("text_editor/keyword_color",Color(0.5,0.0,0.2)); @@ -1072,6 +1073,7 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; + tx->begin_complex_operation(); if (tx->is_selection_active()) { int from_line = tx->get_selection_from_line(); @@ -1103,6 +1105,7 @@ void ScriptEditor::_menu_option(int p_option) { swap_lines(tx, line_id, next_id); } + tx->end_complex_operation(); tx->update(); } break; @@ -1113,6 +1116,7 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; + tx->begin_complex_operation(); if (tx->is_selection_active()) { int from_line = tx->get_selection_from_line(); @@ -1144,6 +1148,7 @@ void ScriptEditor::_menu_option(int p_option) { swap_lines(tx, line_id, next_id); } + tx->end_complex_operation(); tx->update(); } break; @@ -1154,7 +1159,7 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; - + tx->begin_complex_operation(); if (tx->is_selection_active()) { int begin = tx->get_selection_from_line(); @@ -1193,6 +1198,7 @@ void ScriptEditor::_menu_option(int p_option) { tx->set_line(begin, line_text); } } + tx->end_complex_operation(); tx->update(); //tx->deselect(); @@ -1204,6 +1210,7 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; + tx->begin_complex_operation(); if (tx->is_selection_active()) { int begin = tx->get_selection_from_line(); @@ -1222,6 +1229,7 @@ void ScriptEditor::_menu_option(int p_option) { line_text = '\t' + line_text; tx->set_line(begin, line_text); } + tx->end_complex_operation(); tx->update(); //tx->deselect(); @@ -1253,7 +1261,7 @@ void ScriptEditor::_menu_option(int p_option) { return; - + tx->begin_complex_operation(); if (tx->is_selection_active()) { int begin = tx->get_selection_from_line(); @@ -1285,6 +1293,7 @@ void ScriptEditor::_menu_option(int p_option) { line_text = "#" + line_text; tx->set_line(begin, line_text); } + tx->end_complex_operation(); tx->update(); //tx->deselect(); diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp index 79ff78ca0d..9ab7aafeb2 100644 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ b/tools/editor/plugins/spatial_editor_plugin.cpp @@ -51,7 +51,31 @@ #define GIZMO_SCALE_DEFAULT 0.15 -//void SpatialEditorViewport::_update_camera(); +void SpatialEditorViewport::_update_camera() { + if (orthogonal) { + Size2 size = get_size(); + Size2 vpsize = Point2(cursor.distance*size.get_aspect(), cursor.distance / size.get_aspect()); + //camera->set_orthogonal(size.width*cursor.distance,get_znear(),get_zfar()); + camera->set_orthogonal(2 * cursor.distance, 0.1, 8192); + } + else + camera->set_perspective(get_fov(), get_znear(), get_zfar()); + + Transform camera_transform; + camera_transform.translate(cursor.pos); + camera_transform.basis.rotate(Vector3(0, 1, 0), cursor.y_rot); + camera_transform.basis.rotate(Vector3(1, 0, 0), cursor.x_rot); + + if (orthogonal) + camera_transform.translate(0, 0, 4096); + else + camera_transform.translate(0, 0, cursor.distance); + + if (camera->get_global_transform() != camera_transform) { + camera->set_global_transform(camera_transform); + update_transform_gizmo_view(); + } +} String SpatialEditorGizmo::get_handle_name(int p_idx) const { @@ -810,16 +834,15 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { { EditorNode *en = editor; - EditorPlugin *over_plugin = en->get_editor_plugin_over(); + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - if (over_plugin) { - bool discard = over_plugin->forward_spatial_input_event(camera,p_event); + if (!over_plugin_list->empty()) { + bool discard = over_plugin_list->forward_spatial_input_event(camera,p_event); if (discard) return; } } - switch(p_event.type) { case InputEvent::MOUSE_BUTTON: { @@ -1204,11 +1227,9 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { } } break; case InputEvent::MOUSE_MOTION: { - const InputEventMouseMotion &m=p_event.mouse_motion; _edit.mouse_pos=Point2(p_event.mouse_motion.x,p_event.mouse_motion.y); - - + if (spatial_editor->get_selected()) { @@ -1244,7 +1265,7 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { NavigationScheme nav_scheme = _get_navigation_schema("3d_editor/navigation_scheme"); NavigationMode nav_mode = NAVIGATION_NONE; - + if (_edit.gizmo.is_valid()) { Plane plane=Plane(_edit.gizmo_initial_pos,_get_camera_normal()); @@ -1558,6 +1579,26 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { if (m.mod.alt) nav_mode = NAVIGATION_PAN; } + }else{ + // Handle trackpad (no external mouse) use case + int mod = 0; + if (m.mod.shift) + mod=KEY_SHIFT; + if (m.mod.alt) + mod=KEY_ALT; + if (m.mod.control) + mod=KEY_CONTROL; + if (m.mod.meta) + mod=KEY_META; + + if(mod){ + if (mod == _get_key_modifier("3d_editor/pan_modifier")) + nav_mode = NAVIGATION_PAN; + else if (mod == _get_key_modifier("3d_editor/zoom_modifier")) + nav_mode = NAVIGATION_ZOOM; + else if (mod == _get_key_modifier("3d_editor/orbit_modifier")) + nav_mode = NAVIGATION_ORBIT; + } } switch(nav_mode) { @@ -1770,6 +1811,10 @@ void SpatialEditorViewport::_notification(int p_what) { bool visible=is_visible(); set_process(visible); + + if (visible) + _update_camera(); + call_deferred("update_transform_gizmo_view"); } @@ -1791,28 +1836,7 @@ void SpatialEditorViewport::_notification(int p_what) { } */ - if (orthogonal) { - Size2 size=get_size(); - Size2 vpsize = Point2(cursor.distance*size.get_aspect(),cursor.distance/size.get_aspect()); - //camera->set_orthogonal(size.width*cursor.distance,get_znear(),get_zfar()); - camera->set_orthogonal(2*cursor.distance,0.1,8192); - } else - camera->set_perspective(get_fov(),get_znear(),get_zfar()); - - Transform camera_transform; - camera_transform.translate( cursor.pos ); - camera_transform.basis.rotate(Vector3(0,1,0),cursor.y_rot); - camera_transform.basis.rotate(Vector3(1,0,0),cursor.x_rot); - - if (orthogonal) - camera_transform.translate(0,0,4096); - else - camera_transform.translate(0,0,cursor.distance); - - if (camera->get_global_transform()!=camera_transform) { - camera->set_global_transform( camera_transform ); - update_transform_gizmo_view(); - } + _update_camera(); Map<Node*,Object*> &selection = editor_selection->get_selection(); @@ -1915,7 +1939,6 @@ void SpatialEditorViewport::_notification(int p_what) { surface->connect("mouse_enter",this,"_smouseenter"); preview_camera->set_icon(get_icon("Camera","EditorIcons")); _init_gizmo_instance(index); - } if (p_what==NOTIFICATION_EXIT_TREE) { @@ -3553,9 +3576,9 @@ void SpatialEditor::_unhandled_key_input(InputEvent p_event) { { EditorNode *en = editor; - EditorPlugin *over_plugin = en->get_editor_plugin_over(); + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - if (over_plugin && over_plugin->forward_input_event(p_event)) { + if (!over_plugin_list->empty() && over_plugin_list->forward_input_event(p_event)) { return; //ate the over input event } @@ -3579,6 +3602,17 @@ void SpatialEditor::_unhandled_key_input(InputEvent p_event) { case KEY_E: _menu_item_pressed(MENU_TOOL_ROTATE); break; case KEY_R: _menu_item_pressed(MENU_TOOL_SCALE); break; + case KEY_Z: { + if (k.mod.shift || k.mod.control || k.mod.command) + break; + + if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME))) { + _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL); + } else { + _menu_item_pressed(MENU_VIEW_DISPLAY_WIREFRAME); + } + } break; + #if 0 #endif } diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 5877ce1a43..6b2961ea72 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -1098,8 +1098,7 @@ void SceneTreeDock::_delete_confirm() { return; - if (editor->get_editor_plugin_over()) - editor->get_editor_plugin_over()->make_visible(false); + editor->get_editor_plugins_over()->make_visible(false); editor_data->get_undo_redo().create_action("Remove Node(s)"); |