Browse Source

Edit default values. WARNING!!!
Do not merge these changes, default values are not compiled into shaders yet!

Mariano Javier Suligoy 10 năm trước cách đây
mục cha
commit
ea448cb779

+ 32 - 32
core/object.h

@@ -49,7 +49,7 @@
 
 enum PropertyHint {
 	PROPERTY_HINT_NONE, ///< no hint provided.
-	PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step"
+	PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step,slider; //slider is optional"
 	PROPERTY_HINT_EXP_RANGE, ///< hint_text = "min,max,step", exponential edit
 	PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
 	PROPERTY_HINT_EXP_EASING, /// exponential easing funciton (Math::ease)
@@ -58,12 +58,12 @@ enum PropertyHint {
 	PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
 	PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
 	PROPERTY_HINT_ALL_FLAGS,
-	PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," 
+	PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
 	PROPERTY_HINT_DIR, ///< a directort path must be passed
 	PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,"
 	PROPERTY_HINT_GLOBAL_DIR, ///< a directort path must be passed
 	PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type
-	PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines	
+	PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines
 	PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color
 	PROPERTY_HINT_IMAGE_COMPRESS_LOSSY,
 	PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS,
@@ -71,7 +71,7 @@ enum PropertyHint {
 };
 
 enum PropertyUsageFlags {
-	
+
 	PROPERTY_USAGE_STORAGE=1,
 	PROPERTY_USAGE_EDITOR=2,
 	PROPERTY_USAGE_NETWORK=4,
@@ -102,15 +102,15 @@ enum PropertyUsageFlags {
 #define ADD_PROPERTYINO( m_property, m_setter, m_getter, m_index ) ObjectTypeDB::add_property( get_type_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONONE), m_setter, m_getter, m_index )
 
 struct PropertyInfo {
-	
-	Variant::Type type;	
+
+	Variant::Type type;
 	String name;
 	PropertyHint hint;
-	String hint_string;	
+	String hint_string;
 	uint32_t usage;
 
 	_FORCE_INLINE_ PropertyInfo added_usage(int p_fl) const { PropertyInfo pi=*this; pi.usage|=p_fl; return pi; }
-	
+
 	PropertyInfo() { type=Variant::NIL; hint=PROPERTY_HINT_NONE; usage = PROPERTY_USAGE_DEFAULT; }
 	PropertyInfo( Variant::Type p_type, const String p_name, PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_string="",uint32_t p_usage=PROPERTY_USAGE_DEFAULT) {
 		type=p_type; name=p_name; hint=p_hint; hint_string=p_hint_string; usage=p_usage;
@@ -125,23 +125,23 @@ struct PropertyInfo {
 Array convert_property_list(const List<PropertyInfo> * p_list);
 
 struct MethodInfo {
-	
+
 	String name;
 	List<PropertyInfo> arguments;
 	Vector<Variant> default_arguments;
 	PropertyInfo return_val;
 	uint32_t flags;
 	int id;
-	
+
 	inline bool  operator<(const MethodInfo& p_method) const { return id==p_method.id?(name < p_method.name):(id<p_method.id); }
-	
+
 	MethodInfo();
 	MethodInfo(const String& p_name);
 	MethodInfo(const String& p_name, const PropertyInfo& p_param1);
 	MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2);
 	MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2,const PropertyInfo& p_param3);
 	MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2,const PropertyInfo& p_param3,const PropertyInfo& p_param4);
-	MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2,const PropertyInfo& p_param3,const PropertyInfo& p_param4,const PropertyInfo& p_param5);															
+	MethodInfo(const String& p_name, const PropertyInfo& p_param1,const PropertyInfo& p_param2,const PropertyInfo& p_param3,const PropertyInfo& p_param4,const PropertyInfo& p_param5);
 	MethodInfo(Variant::Type ret);
 	MethodInfo(Variant::Type ret,const String& p_name);
 	MethodInfo(Variant::Type ret,const String& p_name, const PropertyInfo& p_param1);
@@ -158,7 +158,7 @@ struct MethodInfo {
 //return NULL;
 
 /*
-   the following is an uncomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model. 
+   the following is an uncomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model.
 */
 
 #define REVERSE_GET_PROPERTY_LIST \
@@ -314,7 +314,7 @@ private:
 class ScriptInstance;
 typedef uint32_t ObjectID;
 
-class Object {		
+class Object {
 public:
 
 	enum ConnectFlags {
@@ -404,7 +404,7 @@ friend void postinitialize_handler(Object*);
 
 	void property_list_changed_notify();
 
-protected:	
+protected:
 
 	virtual bool _use_builtin_script() const { return false; }
 	virtual void _initialize_typev() { initialize_type(); }
@@ -412,14 +412,14 @@ protected:
 	virtual bool _getv(const StringName& p_name,Variant &r_property) const { return false; };
 	virtual void _get_property_listv(List<PropertyInfo> *p_list,bool p_reversed) const {};
 	virtual void _notificationv(int p_notification,bool p_reversed) {};
-	
+
 	static String _get_category() { return ""; }
 	static void _bind_methods();
 	bool _set(const StringName& p_name,const Variant &p_property) { return false; };
 	bool _get(const StringName& p_name,Variant &r_property) const { return false;  };
 	void _get_property_list(List<PropertyInfo> *p_list) const {};
 	void _notification(int p_notification) {};
-	
+
 	_FORCE_INLINE_ static void (*_get_bind_methods())() {
 		return &Object::_bind_methods;
 	}
@@ -431,13 +431,13 @@ protected:
 	}
 	_FORCE_INLINE_ void (Object::* (_get_get_property_list() const))(List<PropertyInfo> *p_list) const{
 			return &Object::_get_property_list;
-	}	
+	}
 	_FORCE_INLINE_ void (Object::* (_get_notification() const))(int){
 			return &Object::_notification;
-	}	
+	}
 	static void get_valid_parents_static(List<String> *p_parents);
 	static void _get_valid_parents_static(List<String> *p_parents);
-		
+
 
 	void cancel_delete();
 
@@ -485,7 +485,7 @@ public:
 
 	void add_change_receptor( Object *p_receptor );
 	void remove_change_receptor( Object *p_receptor );
-	
+
 	template<class T>
 	T *cast_to() {
 
@@ -500,7 +500,7 @@ public:
 			return NULL;
 #endif
 	}
-		
+
 	template<class T>
 	const T *cast_to() const {
 
@@ -517,11 +517,11 @@ public:
 	}
 
 	enum {
-		
+
 		NOTIFICATION_POSTINITIALIZE=0,
 		NOTIFICATION_PREDELETE=1
 	};
-	
+
 	/* TYPE API */
 	static void get_inheritance_list_static(List<String>* p_inheritance_list) {  p_inheritance_list->push_back("Object"); }
 
@@ -545,7 +545,7 @@ public:
 			return *_type_ptr;
 		}
 	}
-	
+
 	/* IAPI */
 //	void set(const String& p_name, const Variant& p_value);
 //	Variant get(const String& p_name) const;
@@ -554,7 +554,7 @@ public:
 	Variant get(const StringName& p_name, bool *r_valid=NULL) const;
 
 	void get_property_list(List<PropertyInfo> *p_list,bool p_reversed=false) const;
-	
+
 	bool has_method(const StringName& p_method) const;
 	void get_method_list(List<MethodInfo> *p_list) const;
 	Variant callv(const StringName& p_method,const Array& p_args);
@@ -564,14 +564,14 @@ public:
 	Variant call(const StringName& p_name, VARIANT_ARG_LIST); // C++ helper
 	void call_multilevel(const StringName& p_name, VARIANT_ARG_LIST); // C++ helper
 
-	void notification(int p_notification,bool p_reversed=false);	
+	void notification(int p_notification,bool p_reversed=false);
 
 	//used mainly by script, get and set all INCLUDING string
 	virtual Variant getvar(const Variant& p_key, bool *r_valid=NULL) const;
 	virtual void setvar(const Variant& p_key, const Variant& p_value,bool *r_valid=NULL);
 
 	/* SCRIPT */
-	
+
 	void set_script(const RefPtr& p_script);
 	RefPtr get_script() const;
 
@@ -614,14 +614,14 @@ public:
 	StringName tr(const StringName& p_message) const; //translate message (alternative)
 
 	bool _is_queued_for_deletion; // set to true by SceneTree::queue_delete()
-	bool is_queued_for_deletion() const; 
+	bool is_queued_for_deletion() const;
 
 	_FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate=p_enable; }
 	_FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; }
 
 	void clear_internal_resource_paths();
 
-	Object();	
+	Object();
 	virtual ~Object();
 
 };
@@ -649,13 +649,13 @@ class ObjectDB {
 	static HashMap<Object*,ObjectID,ObjectPtrHash> instance_checks;
 
 	static uint32_t instance_counter;
-friend class Object;	
+friend class Object;
 friend void unregister_core_types();
 
 	static void cleanup();
 	static uint32_t add_instance(Object *p_object);
 	static void remove_instance(Object *p_object);
-public:	
+public:
 
 	typedef void (*DebugFunc)(Object *p_obj);
 

+ 6 - 2
scene/resources/default_theme/default_theme.cpp

@@ -556,12 +556,16 @@ void make_default_theme() {
 
 	// GraphNode
 
-	Ref<StyleBoxTexture> graphsb = make_stylebox(graph_node_png,6,24,6,5,16,24,16,5);
-	Ref<StyleBoxTexture> graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,16,24,16,5);
+	Ref<StyleBoxTexture> graphsb = make_stylebox(graph_node_png,6,24,6,5,3,24,16,5);
+	Ref<StyleBoxTexture> graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,3,24,16,5);
+	Ref<StyleBoxTexture> graphsbdefault = make_stylebox(graph_node_default_png,4,4,4,4,6,4,4,4);
+	Ref<StyleBoxTexture> graphsbdeffocus = make_stylebox(graph_node_default_focus_png,4,4,4,4,6,4,4,4);
 	//graphsb->set_expand_margin_size(MARGIN_LEFT,10);
 	//graphsb->set_expand_margin_size(MARGIN_RIGHT,10);
 	t->set_stylebox("frame","GraphNode", graphsb );
 	t->set_stylebox("selectedframe","GraphNode", graphsbselected );
+	t->set_stylebox("defaultframe", "GraphNode", graphsbdefault );
+	t->set_stylebox("defaultfocus", "GraphNode", graphsbdeffocus );
 	t->set_constant("separation","GraphNode", 1 );
 	t->set_icon("port","GraphNode", make_icon( graph_port_png ) );
 	t->set_icon("close","GraphNode", make_icon( graph_node_close_png ) );

BIN
scene/resources/default_theme/graph_node_default.png


BIN
scene/resources/default_theme/graph_node_default_focus.png


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 10 - 0
scene/resources/default_theme/theme_data.h


+ 107 - 43
scene/resources/shader_graph.cpp

@@ -80,12 +80,15 @@ void ShaderGraph::_set_data(const Dictionary &p_data) {
 			ERR_FAIL_COND((conns.size()%3)!=0);
 
 			for(int j=0;j<conns.size();j+=3) {
-
 				SourceSlot ss;
 				int ls=conns[j+0];
-				ss.id=conns[j+1];
-				ss.slot=conns[j+2];
-				n.connections[ls]=ss;
+				if (ls == SLOT_DEFAULT_VALUE) {
+					n.defaults[conns[j+1]]=conns[j+2];
+				} else {
+					ss.id=conns[j+1];
+					ss.slot=conns[j+2];
+					n.connections[ls]=ss;
+				}
 			}
 			shader[t].node_map[n.id]=n;
 
@@ -114,7 +117,7 @@ Dictionary ShaderGraph::_get_data() const {
 			data[idx+4]=E->get().param2;
 
 			Array conns;
-			conns.resize(E->get().connections.size()*3);
+			conns.resize(E->get().connections.size()*3+E->get().defaults.size()*3);
 			int idx2=0;
 			for(Map<int,SourceSlot>::Element*F=E->get().connections.front();F;F=F->next()) {
 
@@ -123,6 +126,14 @@ Dictionary ShaderGraph::_get_data() const {
 				conns[idx2+2]=F->get().slot;
 				idx2+=3;
 			}
+			for(Map<int,Variant>::Element*F=E->get().defaults.front();F;F=F->next()) {
+
+				conns[idx2+0]=SLOT_DEFAULT_VALUE;
+				conns[idx2+1]=F->key();
+				conns[idx2+2]=F->get();
+				idx2+=3;
+			}
+
 			data[idx+5]=conns;
 			idx+=6;
 		}
@@ -164,6 +175,9 @@ void ShaderGraph::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("get_node_list","shader_type"),&ShaderGraph::_get_node_list);
 
+	ObjectTypeDB::bind_method(_MD("default_set_value","shader_type","id","param_id","value"), &ShaderGraph::default_set_value);
+	ObjectTypeDB::bind_method(_MD("default_get_value","shader_type","id","param_id"), &ShaderGraph::default_get_value);
+
 	ObjectTypeDB::bind_method(_MD("scalar_const_node_set_value","shader_type","id","value"),&ShaderGraph::scalar_const_node_set_value);
 	ObjectTypeDB::bind_method(_MD("scalar_const_node_get_value","shader_type","id"),&ShaderGraph::scalar_const_node_set_value);
 
@@ -546,7 +560,7 @@ void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) {
 		case NODE_RGB_INPUT: {node.param1=_find_unique_name("Color");node.param2=Color();} break; // color uniform (assignable in material)
 		case NODE_XFORM_INPUT: {node.param1=_find_unique_name("XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material)
 		case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name("Tex"); } break; // texture input (assignable in material)
-		case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material)			
+		case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material)
 		case NODE_DEFAULT_TEXTURE: {}; break;
 		case NODE_OUTPUT: {} break; // output (shader type dependent)
 		case NODE_COMMENT: {} break; // comment
@@ -692,6 +706,18 @@ void ShaderGraph::get_node_connections(ShaderType p_type,List<Connection> *p_con
 	}
 }
 
+bool ShaderGraph::is_slot_connected(ShaderGraph::ShaderType p_type, int p_dst_id, int slot_id)
+{
+	for(const Map<int,Node>::Element *E=shader[p_type].node_map.front();E;E=E->next()) {
+		for (const Map<int,SourceSlot>::Element *F=E->get().connections.front();F;F=F->next()) {
+
+			if (p_dst_id == E->key() && slot_id==F->key())
+				return true;
+		}
+	}
+	return false;
+}
+
 
 void ShaderGraph::clear(ShaderType p_type) {
 
@@ -1005,6 +1031,33 @@ ShaderGraph::ScalarFunc ShaderGraph::scalar_func_node_get_function(ShaderType p_
 	return ScalarFunc(func);
 }
 
+void ShaderGraph::default_set_value(ShaderGraph::ShaderType p_which, int p_id, int p_param, const Variant &p_value)
+{
+	ERR_FAIL_INDEX(p_which,3);
+	ERR_FAIL_COND(!shader[p_which].node_map.has(p_id));
+	Node& n = shader[p_which].node_map[p_id];
+	if(p_value.get_type()==Variant::NIL)
+		n.defaults.erase(n.defaults.find(p_param));
+	else
+		n.defaults[p_param]=p_value;
+
+	_request_update();
+
+}
+
+Variant ShaderGraph::default_get_value(ShaderGraph::ShaderType p_which, int p_id, int p_param)
+{
+	ERR_FAIL_INDEX_V(p_which,3,Variant());
+	ERR_FAIL_COND_V(!shader[p_which].node_map.has(p_id),Variant());
+	const Node& n = shader[p_which].node_map[p_id];
+
+	if (!n.defaults.has(p_param))
+		return Variant();
+	return n.defaults[p_param];
+}
+
+
+
 void ShaderGraph::vec_func_node_set_function(ShaderType p_type,int p_id,VecFunc p_func){
 
 	ERR_FAIL_INDEX(p_type,3);
@@ -1030,52 +1083,52 @@ ShaderGraph::VecFunc ShaderGraph::vec_func_node_get_function(ShaderType p_type,
 
 void ShaderGraph::color_ramp_node_set_ramp(ShaderType p_type,int p_id,const DVector<Color>& p_colors, const DVector<real_t>& p_offsets){
 
-    ERR_FAIL_INDEX(p_type,3);
-    ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
-    ERR_FAIL_COND(p_colors.size()!=p_offsets.size());
-    Node& n = shader[p_type].node_map[p_id];
-    n.param1=p_colors;
-    n.param2=p_offsets;
-    _request_update();
+	ERR_FAIL_INDEX(p_type,3);
+	ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
+	ERR_FAIL_COND(p_colors.size()!=p_offsets.size());
+	Node& n = shader[p_type].node_map[p_id];
+	n.param1=p_colors;
+	n.param2=p_offsets;
+	_request_update();
 
 }
 
 DVector<Color> ShaderGraph::color_ramp_node_get_colors(ShaderType p_type,int p_id) const{
 
-    ERR_FAIL_INDEX_V(p_type,3,DVector<Color>());
-    ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<Color>());
-    const Node& n = shader[p_type].node_map[p_id];
-    return n.param1;
+	ERR_FAIL_INDEX_V(p_type,3,DVector<Color>());
+	ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<Color>());
+	const Node& n = shader[p_type].node_map[p_id];
+	return n.param1;
 
 
 }
 
 DVector<real_t> ShaderGraph::color_ramp_node_get_offsets(ShaderType p_type,int p_id) const{
 
-    ERR_FAIL_INDEX_V(p_type,3,DVector<real_t>());
-    ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<real_t>());
-    const Node& n = shader[p_type].node_map[p_id];
-    return n.param2;
+	ERR_FAIL_INDEX_V(p_type,3,DVector<real_t>());
+	ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<real_t>());
+	const Node& n = shader[p_type].node_map[p_id];
+	return n.param2;
 
 }
 
 
 void ShaderGraph::curve_map_node_set_points(ShaderType p_type,int p_id,const DVector<Vector2>& p_points) {
 
-    ERR_FAIL_INDEX(p_type,3);
-    ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
-    Node& n = shader[p_type].node_map[p_id];
-    n.param1=p_points;
-    _request_update();
+	ERR_FAIL_INDEX(p_type,3);
+	ERR_FAIL_COND(!shader[p_type].node_map.has(p_id));
+	Node& n = shader[p_type].node_map[p_id];
+	n.param1=p_points;
+	_request_update();
 
 }
 
 DVector<Vector2> ShaderGraph::curve_map_node_get_points(ShaderType p_type,int p_id) const{
 
-    ERR_FAIL_INDEX_V(p_type,3,DVector<Vector2>());
-    ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<Vector2>());
-    const Node& n = shader[p_type].node_map[p_id];
-    return n.param1;
+	ERR_FAIL_INDEX_V(p_type,3,DVector<Vector2>());
+	ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector<Vector2>());
+	const Node& n = shader[p_type].node_map[p_id];
+	return n.param1;
 
 }
 
@@ -1265,6 +1318,12 @@ Variant ShaderGraph::node_get_state(ShaderType p_type,int p_id) const {
 	s["pos"]=n.pos;
 	s["param1"]=n.param1;
 	s["param2"]=n.param2;
+	Array keys;
+	for (Map<int,Variant>::Element *E=n.defaults.front();E;E=E->next()) {
+		keys.append(E->key());
+		s[E->key()]=E->get();
+	}
+	s["default_keys"]=keys;
 	return s;
 
 }
@@ -1277,10 +1336,15 @@ void ShaderGraph::node_set_state(ShaderType p_type,int p_id,const Variant& p_sta
 	ERR_FAIL_COND(!d.has("pos"));
 	ERR_FAIL_COND(!d.has("param1"));
 	ERR_FAIL_COND(!d.has("param2"));
+	ERR_FAIL_COND(!d.has("default_keys"));
+
 	n.pos=d["pos"];
 	n.param1=d["param1"];
 	n.param2=d["param2"];
-
+	Array keys = d["default_keys"];
+	for(int i=0;i<keys.size();i++) {
+		n.defaults[keys[i]]=d[keys[i]];
+	}
 }
 
 ShaderGraph::ShaderGraph(Mode p_mode) : Shader(p_mode) {
@@ -1924,27 +1988,27 @@ void ShaderGraph::_plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector
 	};
 
 	for (i = 0; i < 4; i++)
-	    {
-	      for (j = 0; j < 4; j++)
+		{
+		  for (j = 0; j < 4; j++)
 		{
 		  tmp1[i][j] = (CR_basis[i][0] * geometry[0][j] +
-			      CR_basis[i][1] * geometry[1][j] +
-			      CR_basis[i][2] * geometry[2][j] +
-			      CR_basis[i][3] * geometry[3][j]);
+				  CR_basis[i][1] * geometry[1][j] +
+				  CR_basis[i][2] * geometry[2][j] +
+				  CR_basis[i][3] * geometry[3][j]);
+		}
 		}
-	    }
 	/* compose the above results to get the deltas matrix */
 
 	for (i = 0; i < 4; i++)
-	    {
-	      for (j = 0; j < 4; j++)
+		{
+		  for (j = 0; j < 4; j++)
 		{
 		  deltas[i][j] = (tmp2[i][0] * tmp1[0][j] +
-			      tmp2[i][1] * tmp1[1][j] +
-			      tmp2[i][2] * tmp1[2][j] +
-			      tmp2[i][3] * tmp1[3][j]);
+				  tmp2[i][1] * tmp1[1][j] +
+				  tmp2[i][2] * tmp1[2][j] +
+				  tmp2[i][3] * tmp1[3][j]);
+		}
 		}
-	    }
 
 
 	/* extract the x deltas */

+ 8 - 1
scene/resources/shader_graph.h

@@ -68,7 +68,7 @@ public:
 		NODE_VEC_INTERP, // vec3 interpolation  (with optional curve)
 		NODE_COLOR_RAMP, //take scalar, output vec3
 		NODE_CURVE_MAP, //take scalar, otput scalar
-		NODE_SCALAR_INPUT, // scalar uniform (assignable in material)		
+		NODE_SCALAR_INPUT, // scalar uniform (assignable in material)
 		NODE_VEC_INPUT, // vec3 uniform (assignable in material)
 		NODE_RGB_INPUT, // color uniform (assignable in material)
 		NODE_XFORM_INPUT, // mat4 uniform (assignable in material)
@@ -120,6 +120,7 @@ private:
 
 	String _find_unique_name(const String& p_base);
 
+	enum {SLOT_DEFAULT_VALUE = 0x7FFFFFFF};
 	struct SourceSlot {
 
 		int id;
@@ -135,6 +136,7 @@ private:
 		NodeType type;
 		Variant param1;
 		Variant param2;
+		Map<int, Variant> defaults;
 		int id;
 		mutable int order; // used for sorting
 		int sort_order;
@@ -318,6 +320,9 @@ public:
 		VEC_MAX_FUNC
 	};
 
+	void default_set_value(ShaderType p_which,int p_id,int p_param, const Variant& p_value);
+	Variant default_get_value(ShaderType p_which,int p_id,int p_param);
+
 	void vec_func_node_set_function(ShaderType p_which,int p_id,VecFunc p_func);
 	VecFunc vec_func_node_get_function(ShaderType p_which,int p_id) const;
 
@@ -358,6 +363,8 @@ public:
 
 	void get_node_connections(ShaderType p_which,List<Connection> *p_connections) const;
 
+	bool is_slot_connected(ShaderType p_which,int p_dst_id,int slot_id);
+
 	void clear(ShaderType p_which);
 
 	Variant node_get_state(ShaderType p_type, int p_node) const;

+ 388 - 49
tools/editor/plugins/shader_graph_editor_plugin.cpp

@@ -29,6 +29,7 @@
 #include "shader_graph_editor_plugin.h"
 
 
+#include "scene/gui/check_box.h"
 #include "scene/gui/menu_button.h"
 #include "scene/gui/panel.h"
 #include "spatial_editor_plugin.h"
@@ -840,6 +841,7 @@ void ShaderGraphView::_xform_input_changed(int p_id, Node *p_button){
 	ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
 	ped_popup->set_size(tb->get_size());
 	edited_id=p_id;
+	edited_def=-1;
 	ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_input_node_get_value(type,p_id),PROPERTY_HINT_NONE,"");
 	ped_popup->popup();
 
@@ -850,6 +852,7 @@ void ShaderGraphView::_xform_const_changed(int p_id, Node *p_button){
 	ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
 	ped_popup->set_size(tb->get_size());
 	edited_id=p_id;
+	edited_def=-1;
 	ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_const_node_get_value(type,p_id),PROPERTY_HINT_NONE,"");
 	ped_popup->popup();
 
@@ -879,6 +882,35 @@ void ShaderGraphView::_cube_input_change(int p_id){
 
 void ShaderGraphView::_variant_edited() {
 
+	if (edited_def != -1) {
+
+		Variant v = ped_popup->get_variant();
+		Variant v2 = graph->default_get_value(type,edited_id,edited_def);
+		if (v2.get_type() == Variant::NIL)
+			switch (v.get_type()) {
+			case Variant::VECTOR3:
+				v2=Vector3();
+				break;
+			case Variant::REAL:
+				v2=0.0;
+				break;
+			case Variant::TRANSFORM:
+				v2=Transform();
+				break;
+			case Variant::COLOR:
+				v2=Color();
+				break;
+			}
+		UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+		ur->create_action("Change default value");
+		ur->add_do_method(graph.ptr(),"default_set_value",type,edited_id,edited_def, v);
+		ur->add_undo_method(graph.ptr(),"default_set_value",type,edited_id,edited_def, v2);
+		ur->add_do_method(this,"_update_graph");
+		ur->add_undo_method(this,"_update_graph");
+		ur->commit_action();
+		return;
+	}
+
 	if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_CONST) {
 
 		UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
@@ -1043,6 +1075,7 @@ void ShaderGraphView::_tex_edited(int p_id,Node* p_button) {
 	ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
 	ped_popup->set_size(tb->get_size());
 	edited_id=p_id;
+	edited_def=-1;
 	ped_popup->edit(NULL,"",Variant::OBJECT,graph->texture_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"Texture");
 }
 
@@ -1052,6 +1085,7 @@ void ShaderGraphView::_cube_edited(int p_id,Node* p_button) {
 	ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
 	ped_popup->set_size(tb->get_size());
 	edited_id=p_id;
+	edited_def=-1;
 	ped_popup->edit(NULL,"",Variant::OBJECT,graph->cubemap_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"CubeMap");
 }
 
@@ -1260,6 +1294,97 @@ void ShaderGraphView::_delete_nodes_request()
 
 }
 
+void ShaderGraphView::_default_changed(int p_id, Node *p_button, int p_param, int v_type, String p_hint)
+{
+	ToolButton *tb = p_button->cast_to<ToolButton>();
+	ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height));
+	ped_popup->set_size(tb->get_size());
+	edited_id=p_id;
+	edited_def=p_param;
+	Variant::Type vt = (Variant::Type)v_type;
+	Variant v = graph->default_get_value(type,p_id,edited_def);
+	int h=PROPERTY_HINT_NONE;
+	if (v.get_type() == Variant::NIL)
+		switch (vt) {
+		case Variant::VECTOR3:
+			v=Vector3();
+			break;
+		case Variant::REAL:
+			h=PROPERTY_HINT_RANGE;
+			v=0.0;
+			break;
+		case Variant::TRANSFORM:
+			v=Transform();
+			break;
+		case Variant::COLOR:
+			h=PROPERTY_HINT_COLOR_NO_ALPHA;
+			v=Color();
+			break;
+		}
+
+	ped_popup->edit(NULL,"",vt,v,h,p_hint);
+
+	ped_popup->popup();
+}
+
+ToolButton *ShaderGraphView::make_label(String text, Variant::Type v_type) {
+	ToolButton *l = memnew( ToolButton );
+	l->set_text(text);
+	l->set_text_align(ToolButton::ALIGN_LEFT);
+	l->add_style_override("hover", l->get_stylebox("normal", "ToolButton"));
+	l->add_style_override("pressed", l->get_stylebox("normal", "ToolButton"));
+	l->add_style_override("focus", l->get_stylebox("normal", "ToolButton"));
+	switch (v_type) {
+	case Variant::REAL:
+		l->set_icon(ped_popup->get_icon("Real", "EditorIcons"));
+		break;
+	case Variant::VECTOR3:
+		l->set_icon(ped_popup->get_icon("Vector", "EditorIcons"));
+		break;
+	case Variant::TRANSFORM:
+		l->set_icon(ped_popup->get_icon("Matrix", "EditorIcons"));
+		break;
+	case Variant::COLOR:
+		l->set_icon(ped_popup->get_icon("Color", "EditorIcons"));
+	}
+	return l;
+}
+
+ToolButton *ShaderGraphView::make_editor(String text,GraphNode* gn,int p_id,int param,Variant::Type v_type, String p_hint) {
+	ToolButton *edit = memnew( ToolButton );
+	edit->set_text(text);
+	edit->set_text_align(ToolButton::ALIGN_LEFT);
+	edit->set_flat(false);
+	edit->add_style_override("normal", gn->get_stylebox("defaultframe", "GraphNode"));
+	edit->add_style_override("hover", gn->get_stylebox("defaultframe", "GraphNode"));
+	edit->add_style_override("pressed", gn->get_stylebox("defaultframe", "GraphNode"));
+	edit->add_style_override("focus", gn->get_stylebox("defaultfocus", "GraphNode"));
+	edit->connect("pressed",this,"_default_changed",varray(p_id,edit,param,v_type,p_hint));
+
+	switch (v_type) {
+	case Variant::REAL:
+		edit->set_icon(ped_popup->get_icon("Real", "EditorIcons"));
+		break;
+	case Variant::VECTOR3:
+		edit->set_icon(ped_popup->get_icon("Vector", "EditorIcons"));
+		break;
+	case Variant::TRANSFORM:
+		edit->set_icon(ped_popup->get_icon("Matrix", "EditorIcons"));
+		break;
+	case Variant::COLOR:
+		Image icon_color = Image(15,15,false,Image::FORMAT_RGB);
+		Color c = graph->default_get_value(type,p_id,param);
+		for (int x=1;x<14;x++)
+			for (int y=1;y<14;y++)
+				icon_color.put_pixel(x,y,c);
+		Ref<ImageTexture> t;
+		t.instance();
+		t->create_from_image(icon_color);
+		edit->set_icon(t);
+		break;
+	}
+	return edit;
+}
 
 void ShaderGraphView::_create_node(int p_id) {
 
@@ -1273,6 +1398,9 @@ void ShaderGraphView::_create_node(int p_id) {
 		Color(0,1,1)
 	};
 
+	const String hint_spin = "-65536,65535,0.001";
+	const String hint_slider = "0.0,1.0,0.01,slider";
+
 
 	switch(graph->node_get_type(type,p_id)) {
 
@@ -1377,7 +1505,12 @@ void ShaderGraphView::_create_node(int p_id) {
 		gn->set_title("ScreenTex");
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("UV")));
+		if (!graph->is_slot_connected(type,p_id,0)) {
+			Vector3 v = graph->default_get_value(type, p_id, 0);
+			hbc->add_child(make_editor("UV: " + v,gn,p_id,0,Variant::VECTOR3));
+		} else {
+			hbc->add_child(make_label("UV",Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("RGB")));
 		gn->add_child(hbc);
@@ -1411,11 +1544,21 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("a")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("a",Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("a: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("out")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("b")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("b",Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin));
+		}
 
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
 		gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
@@ -1449,11 +1592,21 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("a")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("a",Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("out")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("b")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("b",Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3));
+		}
 
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
 		gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
@@ -1481,12 +1634,22 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("a")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("a",Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("out")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("b")));
 
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("b",Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin));
+		}
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
 		gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
 
@@ -1519,11 +1682,19 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("a")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("a",Variant::COLOR));
+		} else {
+			hbc->add_child(make_editor(String("a: "),gn,p_id,0,Variant::COLOR));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("out")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("b")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("b",Variant::COLOR));
+		} else {
+			gn->add_child(make_editor(String("b: "),gn,p_id,1,Variant::COLOR));
+		}
 
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
 		gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
@@ -1533,11 +1704,19 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		gn->set_title("XFMult");
 		HBoxContainer *hbc = memnew( HBoxContainer );
-		hbc->add_child( memnew(Label("a")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("a",Variant::TRANSFORM));
+		} else {
+			hbc->add_child(make_editor(String("a: edit..."),gn,p_id,0,Variant::TRANSFORM));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("out")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("b")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("b",Variant::TRANSFORM));
+		} else {
+			gn->add_child(make_editor(String("b: edit..."),gn,p_id,1,Variant::TRANSFORM));
+		}
 
 		gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]);
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],false,0,Color());
@@ -1548,8 +1727,7 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		gn->set_title("XFVecMult");
 
-		Button *button = memnew( Button("RotOnly"));
-		button->set_toggle_mode(true);
+		CheckBox *button = memnew (CheckBox("RotOnly"));
 		button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id));
 		button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id));
 
@@ -1557,13 +1735,22 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("xf")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("xf",Variant::TRANSFORM));
+		} else {
+			hbc->add_child(make_editor(String("xf: edit..."),gn,p_id,0,Variant::TRANSFORM));
+		}
 		hbc->add_spacer();
 		Label *l = memnew(Label("out"));
 		l->set_align(Label::ALIGN_RIGHT);
 		hbc->add_child( l);
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("vec")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("a",Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("a: ")+v,gn,p_id,1,Variant::VECTOR3));
+		}
 
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
 		gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
@@ -1574,17 +1761,25 @@ void ShaderGraphView::_create_node(int p_id) {
 		gn->set_title("XFVecInvMult");
 
 
-		Button *button = memnew( Button("RotOnly"));
-		button->set_toggle_mode(true);
+		CheckBox *button = memnew( CheckBox("RotOnly"));
 		button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id));
 		button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id));
 
 		gn->add_child(button);
 
-		gn->add_child( memnew(Label("vec")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			gn->add_child(make_label("a",Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			gn->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("xf")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			hbc->add_child(make_label("xf", Variant::TRANSFORM));
+		} else {
+			hbc->add_child(make_editor(String("xf: edit..."),gn,p_id,1,Variant::TRANSFORM));
+		}
 		hbc->add_spacer();
 		Label *l = memnew(Label("out"));
 		l->set_align(Label::ALIGN_RIGHT);
@@ -1633,7 +1828,12 @@ void ShaderGraphView::_create_node(int p_id) {
 		gn->add_child(ob);
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
-		hbc->add_child( memnew(Label("in")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("in", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("in: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("out")));
 		gn->add_child(hbc);
@@ -1668,7 +1868,12 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("in")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("in", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("in: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("out")));
 		gn->add_child(hbc);
@@ -1679,7 +1884,12 @@ void ShaderGraphView::_create_node(int p_id) {
 	case ShaderGraph::NODE_VEC_LEN: {
 		gn->set_title("VecLength");
 		HBoxContainer *hbc = memnew( HBoxContainer );
-		hbc->add_child( memnew(Label("in")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("in", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("in: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("len")));
 		gn->add_child(hbc);
@@ -1692,11 +1902,21 @@ void ShaderGraphView::_create_node(int p_id) {
 		gn->set_title("DotProduct");
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("a")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("a", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("dp")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("b")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("b", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3));
+		}
 
 		gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
@@ -1707,7 +1927,12 @@ void ShaderGraphView::_create_node(int p_id) {
 		gn->set_title("Vec2Scalar");
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("vec")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("vec", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("vec: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		Label *l=memnew(Label("x"));
 		l->set_align(Label::ALIGN_RIGHT);
@@ -1732,12 +1957,27 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		gn->set_title("Scalar2Vec");
 		HBoxContainer *hbc = memnew( HBoxContainer );
-		hbc->add_child( memnew(Label("x")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("x", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("x: ")+Variant(v),gn,p_id,0,Variant::REAL));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("vec")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("y")));
-		gn->add_child( memnew(Label("z")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("y", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("y: ")+Variant(v),gn,p_id,1,Variant::REAL));
+		}
+		if (graph->is_slot_connected(type, p_id, 2)) {
+			gn->add_child(make_label("in", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,2);
+			gn->add_child(make_editor(String("in: ")+Variant(v),gn,p_id,2,Variant::REAL));
+		}
 
 		gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
@@ -1749,13 +1989,33 @@ void ShaderGraphView::_create_node(int p_id) {
 		gn->set_title("Vec2XForm");
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("x")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("x", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("x: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("xf")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("y")));
-		gn->add_child( memnew(Label("z")));
-		gn->add_child( memnew(Label("ofs")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("y", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("y: ")+v,gn,p_id,1,Variant::VECTOR3));
+		}
+		if (graph->is_slot_connected(type, p_id, 2)) {
+			gn->add_child(make_label("z", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,2);
+			gn->add_child(make_editor(String("z: ")+v,gn,p_id,2,Variant::VECTOR3));
+		}
+		if (graph->is_slot_connected(type, p_id, 3)) {
+			gn->add_child(make_label("ofs", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,3);
+			gn->add_child(make_editor(String("ofs: ")+v,gn,p_id,3,Variant::VECTOR3));
+		}
 
 		gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]);
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
@@ -1769,7 +2029,11 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("xf")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("fx", Variant::TRANSFORM));
+		} else {
+			hbc->add_child(make_editor(String("fx: edit..."),gn,p_id,0,Variant::TRANSFORM));
+		}
 		hbc->add_spacer();
 		Label *l=memnew(Label("x"));
 		l->set_align(Label::ALIGN_RIGHT);
@@ -1796,12 +2060,27 @@ void ShaderGraphView::_create_node(int p_id) {
 		gn->set_title("ScalarInterp");
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("a")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("a", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("a: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("interp")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("b")));
-		gn->add_child( memnew(Label("c")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("b", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin));
+		}
+		if (graph->is_slot_connected(type, p_id, 2)) {
+			gn->add_child(make_label("c", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,2);
+			gn->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,2,Variant::REAL,hint_slider));
+		}
 
 		gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]);
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color());
@@ -1813,12 +2092,27 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		gn->set_title("VecInterp");
 		HBoxContainer *hbc = memnew( HBoxContainer );
-		hbc->add_child( memnew(Label("a")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("a", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		hbc->add_child( memnew(Label("interp")));
 		gn->add_child(hbc);
-		gn->add_child( memnew(Label("b")));
-		gn->add_child( memnew(Label("c")));
+		if (graph->is_slot_connected(type, p_id, 1)) {
+			gn->add_child(make_label("b", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,1);
+			gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3));
+		}
+		if (graph->is_slot_connected(type, p_id, 2)) {
+			gn->add_child(make_label("c", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,2);
+			gn->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,2,Variant::REAL,hint_slider));
+		}
 
 		gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]);
 		gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color());
@@ -1857,7 +2151,12 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("c")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("c", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_slider));
+		}
 		hbc->add_spacer();
 		Label *l=memnew(Label("rgb"));
 		l->set_align(Label::ALIGN_RIGHT);
@@ -1902,7 +2201,12 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("c")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("c", Variant::REAL));
+		} else {
+			float v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_slider));
+		}
 		hbc->add_spacer();
 		Label *l=memnew(Label("cmap"));
 		l->set_align(Label::ALIGN_RIGHT);
@@ -2016,7 +2320,12 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("UV")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("UV", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		Label *l=memnew(Label("RGB"));
 		l->set_align(Label::ALIGN_RIGHT);
@@ -2047,7 +2356,12 @@ void ShaderGraphView::_create_node(int p_id) {
 
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("UV")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("UV", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		Label *l=memnew(Label("RGB"));
 		l->set_align(Label::ALIGN_RIGHT);
@@ -2067,7 +2381,12 @@ void ShaderGraphView::_create_node(int p_id) {
 		gn->set_title("CanvasItemTex");
 		HBoxContainer *hbc = memnew( HBoxContainer );
 		hbc->add_constant_override("separation",0);
-		hbc->add_child( memnew(Label("UV")));
+		if (graph->is_slot_connected(type, p_id, 0)) {
+			hbc->add_child(make_label("UV", Variant::VECTOR3));
+		} else {
+			Vector3 v = graph->default_get_value(type,p_id,0);
+			hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3));
+		}
 		hbc->add_spacer();
 		Label *l=memnew(Label("RGB"));
 		l->set_align(Label::ALIGN_RIGHT);
@@ -2091,15 +2410,34 @@ void ShaderGraphView::_create_node(int p_id) {
 		List<ShaderGraph::SlotInfo> si;
 		ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si);
 
+		Array colors;
+		colors.push_back("Color");
+		colors.push_back("LightColor");
+		Array reals;
+		reals.push_back("Alpha");
+		reals.push_back("NormapMapDepth");
+		reals.push_back("LightAlpha");
+		reals.push_back("PointSize");
+		Array vectors;
+		vectors.push_back("Normal");
+		vectors.push_back("NormalMap");
+		vectors.push_back("Vertex");
+		vectors.push_back("UV");
+		vectors.push_back("Var1");
+		vectors.push_back("Var2");
+
 		int idx=0;
 		for (List<ShaderGraph::SlotInfo>::Element *E=si.front();E;E=E->next()) {
 			ShaderGraph::SlotInfo& s=E->get();
 			if (s.dir==ShaderGraph::SLOT_OUT) {
-
-				Label *l= memnew( Label );
-				l->set_text(s.name);
-				l->set_align(Label::ALIGN_LEFT);
-				gn->add_child(l);
+				Variant::Type v;
+				if (colors.find(s.name)>=0)
+					v=Variant::COLOR;
+				else if (reals.find(s.name)>=0)
+					v=Variant::REAL;
+				else if (vectors.find(s.name)>=0)
+					v=Variant::VECTOR3;
+				gn->add_child(make_label(s.name, v));
 				gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color());
 				idx++;
 			}
@@ -2256,6 +2594,7 @@ void ShaderGraphView::_bind_methods() {
 	ObjectTypeDB::bind_method("_duplicate_nodes", &ShaderGraphView::_duplicate_nodes);
 	ObjectTypeDB::bind_method("_delete_nodes_request", &ShaderGraphView::_delete_nodes_request);
 
+	ObjectTypeDB::bind_method("_default_changed",&ShaderGraphView::_default_changed);
 	ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed);
 	ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed);
 	ObjectTypeDB::bind_method("_rgb_const_changed",&ShaderGraphView::_rgb_const_changed);

+ 6 - 0
tools/editor/plugins/shader_graph_editor_plugin.h

@@ -129,6 +129,7 @@ class ShaderGraphView : public Node {
 	GraphEdit *graph_edit;
 	Ref<ShaderGraph> graph;
 	int edited_id;
+	int edited_def;
 
 	ShaderGraph::ShaderType type;
 
@@ -136,6 +137,8 @@ class ShaderGraphView : public Node {
 	void _create_node(int p_id);
 
 
+	ToolButton *make_label(String text, Variant::Type v_type = Variant::NIL);
+	ToolButton *make_editor(String text, GraphNode* gn, int p_id, int param, Variant::Type type, String p_hint="");
 
 	void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot);
 	void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot);
@@ -149,6 +152,9 @@ class ShaderGraphView : public Node {
 	void _duplicate_nodes(Array &p_nodes);
 	void _delete_nodes_request();
 
+
+	void _default_changed(int p_id, Node* p_button, int p_param, int v_type, String p_hint);
+
 	void _scalar_const_changed(double p_value,int p_id);
 	void _vec_const_changed(double p_value, int p_id, Array p_arr);
 	void _rgb_const_changed(const Color& p_color, int p_id);

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 247 - 190
tools/editor/property_editor.cpp


+ 24 - 22
tools/editor/property_editor.h

@@ -46,9 +46,9 @@
 */
 
 class CustomPropertyEditor : public Popup {
-	
+
 	OBJ_TYPE( CustomPropertyEditor, Popup );
-	
+
 	enum {
 		MAX_VALUE_EDITORS=12,
 		MAX_ACTION_BUTTONS=5,
@@ -93,7 +93,8 @@ class CustomPropertyEditor : public Popup {
 	TextEdit *text_edit;
 	bool read_only;
 	Button *checks20[20];
-
+	SpinBox *spinbox;
+	HSlider *slider;
 
 	Control *easing_draw;
 
@@ -105,6 +106,7 @@ class CustomPropertyEditor : public Popup {
 	void _file_selected(String p_file);
 	void _scroll_modified(double p_value);
 	void _modified(String p_string);
+	void _range_modified(double p_value);
 	void _focus_enter();
 	void _focus_exit();
 	void _action_pressed(int p_which);
@@ -113,7 +115,7 @@ class CustomPropertyEditor : public Popup {
 	void _color_changed(const Color& p_color);
 	void _draw_easing();
 	void _menu_option(int p_which);
-	
+
 	void _drag_easing(const InputEvent& p_ev);
 
 	void _node_path_selected(NodePath p_path);
@@ -123,23 +125,23 @@ class CustomPropertyEditor : public Popup {
 protected:
 
 	void _notification(int p_what);
-	static void _bind_methods();			
-	
-public:	
+	static void _bind_methods();
+
+public:
 	Variant get_variant() const;
 	String get_name() const;
-	
+
 	void set_read_only(bool p_read_only) { read_only=p_read_only; }
 
 	bool edit(Object* p_owner,const String& p_name,Variant::Type p_type, const Variant& p_variant,int p_hint,String p_hint_text);
-	
+
 	CustomPropertyEditor();
 };
 
 class PropertyEditor : public Control {
-	
+
 	OBJ_TYPE( PropertyEditor, Control );
-	
+
 	Tree *tree;
 	Label *top_label;
 	//Object *object;
@@ -160,27 +162,27 @@ class PropertyEditor : public Control {
 
 	HashMap<String,String> pending;
 	String selected_property;
-	
+
 	CustomPropertyEditor *custom_editor;
-	
+
 	void _resource_edit_request();
 	void _custom_editor_edited();
 	void _custom_editor_request(bool p_arrow);
-	
+
 	void _item_selected();
 	void _item_edited();
 	TreeItem *get_parent_node(String p_path,HashMap<String,TreeItem*>& item_paths,TreeItem *root);
-	
+
 	void set_item_text(TreeItem *p_item, int p_type, const String& p_name, int p_hint=PROPERTY_HINT_NONE, const String& p_hint_text="");
-		
+
 	TreeItem *find_item(TreeItem *p_item,const String& p_name);
-		
-	
+
+
 	virtual void _changed_callback(Object *p_changed,const char * p_what);
 	virtual void _changed_callbacks(Object *p_changed,const String& p_callback);
 
 	void _edit_button(Object *p_item, int p_column, int p_button);
-	
+
 	void _node_removed(Node *p_node);
 	void _edit_set(const String& p_name, const Variant& p_value);
 	void _draw_flags(Object *ti,const Rect2& p_rect);
@@ -191,7 +193,7 @@ class PropertyEditor : public Control {
 
 	UndoRedo *undo_redo;
 protected:
-	
+
 	void _notification(int p_what);
 	static void _bind_methods();
 public:
@@ -217,8 +219,8 @@ public:
 	void set_autoclear(bool p_enable);
 
 	void set_show_categories(bool p_show);
-	
-	PropertyEditor();	
+
+	PropertyEditor();
 	~PropertyEditor();
 
 };

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác