Browse Source

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

Mariano Javier Suligoy 10 years ago
parent
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


File diff suppressed because it is too large
+ 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);

File diff suppressed because it is too large
+ 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();
 
 };

Some files were not shown because too many files changed in this diff