Browse Source

Add Color.from_hsv()

Bernhard Liebl 7 years ago
parent
commit
be55171231
4 changed files with 88 additions and 7 deletions
  1. 49 0
      core/color.cpp
  2. 1 0
      core/color.h
  3. 2 0
      core/variant_call.cpp
  4. 36 7
      modules/gdscript/gdscript_parser.cpp

+ 49 - 0
core/color.cpp

@@ -400,6 +400,55 @@ String Color::to_html(bool p_alpha) const {
 	return txt;
 	return txt;
 }
 }
 
 
+Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) {
+
+	const float h_ = p_h / 60.0f;
+	const float c = p_v * p_s;
+	const float x = c * (1.0f - Math::abs(Math::fmod(h_, 2.0f) - 1.0f));
+	float r, g, b;
+
+	switch ((int)h_) {
+		case 0: {
+			r = c;
+			g = x;
+			b = 0;
+		} break;
+		case 1: {
+			r = x;
+			g = c;
+			b = 0;
+		} break;
+		case 2: {
+			r = 0;
+			g = c;
+			b = x;
+		} break;
+		case 3: {
+			r = 0;
+			g = x;
+			b = c;
+		} break;
+		case 4: {
+			r = x;
+			g = 0;
+			b = c;
+		} break;
+		case 5: {
+			r = c;
+			g = 0;
+			b = x;
+		} break;
+		default: {
+			r = 0;
+			g = 0;
+			b = 0;
+		} break;
+	}
+
+	const float m = p_v - c;
+	return Color(m + r, m + g, m + b, p_a);
+}
+
 float Color::gray() const {
 float Color::gray() const {
 
 
 	return (r + g + b) / 3.0;
 	return (r + g + b) / 3.0;

+ 1 - 0
core/color.h

@@ -190,6 +190,7 @@ struct Color {
 	static bool html_is_valid(const String &p_color);
 	static bool html_is_valid(const String &p_color);
 	static Color named(const String &p_name);
 	static Color named(const String &p_name);
 	String to_html(bool p_alpha = true) const;
 	String to_html(bool p_alpha = true) const;
+	Color from_hsv(float p_h, float p_s, float p_v, float p_a);
 
 
 	_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
 	_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
 	operator String() const;
 	operator String() const;

+ 2 - 0
core/variant_call.cpp

@@ -443,6 +443,7 @@ struct _VariantCall {
 	VCALL_LOCALMEM1R(Color, lightened);
 	VCALL_LOCALMEM1R(Color, lightened);
 	VCALL_LOCALMEM1R(Color, darkened);
 	VCALL_LOCALMEM1R(Color, darkened);
 	VCALL_LOCALMEM1R(Color, to_html);
 	VCALL_LOCALMEM1R(Color, to_html);
+	VCALL_LOCALMEM4R(Color, from_hsv);
 
 
 	VCALL_LOCALMEM0R(RID, get_id);
 	VCALL_LOCALMEM0R(RID, get_id);
 
 
@@ -1589,6 +1590,7 @@ void register_variant_methods() {
 	ADDFUNC1R(COLOR, COLOR, Color, lightened, REAL, "amount", varray());
 	ADDFUNC1R(COLOR, COLOR, Color, lightened, REAL, "amount", varray());
 	ADDFUNC1R(COLOR, COLOR, Color, darkened, REAL, "amount", varray());
 	ADDFUNC1R(COLOR, COLOR, Color, darkened, REAL, "amount", varray());
 	ADDFUNC1R(COLOR, STRING, Color, to_html, BOOL, "with_alpha", varray(true));
 	ADDFUNC1R(COLOR, STRING, Color, to_html, BOOL, "with_alpha", varray(true));
+	ADDFUNC4R(COLOR, COLOR, Color, from_hsv, REAL, "h", REAL, "s", REAL, "v", REAL, "a", varray(1.0));
 
 
 	ADDFUNC0R(_RID, INT, RID, get_id, varray());
 	ADDFUNC0R(_RID, INT, RID, get_id, varray());
 
 

+ 36 - 7
modules/gdscript/gdscript_parser.cpp

@@ -578,18 +578,47 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
 
 
 			if (identifier == StringName()) {
 			if (identifier == StringName()) {
 
 
-				_set_error("Built-in type constant expected after '.'");
+				_set_error("Built-in type constant or static function expected after '.'");
 				return NULL;
 				return NULL;
 			}
 			}
 			if (!Variant::has_numeric_constant(bi_type, identifier)) {
 			if (!Variant::has_numeric_constant(bi_type, identifier)) {
 
 
-				_set_error("Static constant  '" + identifier.operator String() + "' not present in built-in type " + Variant::get_type_name(bi_type) + ".");
-				return NULL;
-			}
+				if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN &&
+						Variant::is_method_const(bi_type, identifier) &&
+						Variant::get_method_return_type(bi_type, identifier) == bi_type) {
+
+					tokenizer->advance();
+
+					OperatorNode *construct = alloc_node<OperatorNode>();
+					construct->op = OperatorNode::OP_CALL;
+
+					TypeNode *tn = alloc_node<TypeNode>();
+					tn->vtype = bi_type;
+					construct->arguments.push_back(tn);
+
+					OperatorNode *op = alloc_node<OperatorNode>();
+					op->op = OperatorNode::OP_CALL;
+					op->arguments.push_back(construct);
+
+					IdentifierNode *id = alloc_node<IdentifierNode>();
+					id->name = identifier;
+					op->arguments.push_back(id);
+
+					if (!_parse_arguments(op, op->arguments, p_static, true))
+						return NULL;
+
+					expr = op;
+				} else {
 
 
-			ConstantNode *cn = alloc_node<ConstantNode>();
-			cn->value = Variant::get_numeric_constant_value(bi_type, identifier);
-			expr = cn;
+					_set_error("Static constant  '" + identifier.operator String() + "' not present in built-in type " + Variant::get_type_name(bi_type) + ".");
+					return NULL;
+				}
+			} else {
+
+				ConstantNode *cn = alloc_node<ConstantNode>();
+				cn->value = Variant::get_numeric_constant_value(bi_type, identifier);
+				expr = cn;
+			}
 
 
 		} else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_OPEN && tokenizer->is_token_literal()) {
 		} else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_OPEN && tokenizer->is_token_literal()) {
 			// We check with is_token_literal, as this allows us to use match/sync/etc. as a name
 			// We check with is_token_literal, as this allows us to use match/sync/etc. as a name