/*************************************************************************/ /* mm_node_universal_property.cpp */ /*************************************************************************/ /* This file is part of: */ /* PANDEMONIUM ENGINE */ /* https://github.com/Relintai/pandemonium_engine */ /*************************************************************************/ /* Copyright (c) 2022-present Péter Magyar. */ /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "mm_node_universal_property.h" #include "mm_node.h" int MMNodeUniversalProperty::get_default_type() const { return default_type; } void MMNodeUniversalProperty::set_default_type(const int val) { default_type = val; } int MMNodeUniversalProperty::get_default_int() const { return default_int; } void MMNodeUniversalProperty::set_default_int(const int val) { default_int = val; } float MMNodeUniversalProperty::get_default_float() const { return default_float; } void MMNodeUniversalProperty::set_default_float(const float val) { default_float = val; } Vector2 MMNodeUniversalProperty::get_default_vector2() const { return default_vector2; } void MMNodeUniversalProperty::set_default_vector2(const Vector2 &val) { default_vector2 = val; } Vector3 MMNodeUniversalProperty::get_default_vector3() const { return default_vector3; } void MMNodeUniversalProperty::set_default_vector3(const Vector3 &val) { default_vector3 = val; } Color MMNodeUniversalProperty::get_default_color() const { return default_color; } void MMNodeUniversalProperty::set_default_color(const Color &val) { default_color = val; } Ref MMNodeUniversalProperty::get_default_image() { return default_image; } void MMNodeUniversalProperty::set_default_image(const Ref &val) { default_image = val; } bool MMNodeUniversalProperty::get_get_value_from_owner() const { return get_value_from_owner; } void MMNodeUniversalProperty::set_get_value_from_owner(const bool val) { get_value_from_owner = val; } bool MMNodeUniversalProperty::get_force_override() const { return force_override; } void MMNodeUniversalProperty::set_force_override(const bool val) { force_override = val; } Ref MMNodeUniversalProperty::get_override_image() { return override_image; } void MMNodeUniversalProperty::set_override_image(const Ref &val) { override_image = val; } int MMNodeUniversalProperty::get_input_slot_type() const { return input_slot_type; } void MMNodeUniversalProperty::set_input_slot_type(const int val) { input_slot_type = val; } int MMNodeUniversalProperty::get_output_slot_type() const { return output_slot_type; } void MMNodeUniversalProperty::set_output_slot_type(const int val) { output_slot_type = val; } String MMNodeUniversalProperty::get_slot_name() const { return slot_name; } void MMNodeUniversalProperty::set_slot_name(const String &val) { slot_name = val; } float MMNodeUniversalProperty::get_value_step() const { return value_step; } void MMNodeUniversalProperty::set_value_step(const float val) { value_step = val; } Vector2 MMNodeUniversalProperty::get_value_range() const { return value_range; } void MMNodeUniversalProperty::set_value_range(const Vector2 &val) { value_range = val; } Ref MMNodeUniversalProperty::get_input_property() { return input_property; } void MMNodeUniversalProperty::set_input_property(const Ref &val) { if (input_property == val) { return; } if (input_property.is_valid()) { input_property->disconnect("changed", this, "on_input_property_changed"); } input_property = val; if (input_property.is_valid()) { input_property->connect("changed", this, "on_input_property_changed"); } emit_changed(); } // Because in UndiRedo if you pass null as the only argument it will look; // for a method with no arguments; void MMNodeUniversalProperty::unset_input_property() { set_input_property(Ref()); } void MMNodeUniversalProperty::on_input_property_changed() { emit_changed(); } Ref MMNodeUniversalProperty::get_owner() { return owner; } void MMNodeUniversalProperty::set_owner(const Ref &val) { owner = val; } Variant MMNodeUniversalProperty::get_value(const Vector2 &uv, const bool skip_owner_val) { if (get_value_from_owner && !skip_owner_val) { return get_owner_value(uv); } if (!input_property.is_valid()) { return get_default_value(uv); } if (default_type == input_property->default_type) { return input_property->get_value(uv); } if (default_type == DEFAULT_TYPE_INT) { return to_int(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_FLOAT) { return to_float(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_VECTOR2) { return to_vector2(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_VECTOR3) { return to_vector3(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_COLOR) { return to_color(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_IMAGE) { return to_color(input_property->get_value(uv)); } return input_property->get_value(uv); } Variant MMNodeUniversalProperty::get_owner_value(const Vector2 &uv) { if (default_type == DEFAULT_TYPE_INT) { return to_int(owner->get_property_value(uv)); } else if (default_type == DEFAULT_TYPE_FLOAT) { return to_float(owner->get_property_value(uv)); } else if (default_type == DEFAULT_TYPE_VECTOR2) { return to_vector2(owner->get_property_value(uv)); } else if (default_type == DEFAULT_TYPE_VECTOR3) { return to_vector3(owner->get_property_value(uv)); } else if (default_type == DEFAULT_TYPE_COLOR) { return to_color(owner->get_property_value(uv)); } else if (default_type == DEFAULT_TYPE_IMAGE) { return to_color(owner->get_property_value(uv)); } return Variant(); } Variant MMNodeUniversalProperty::get_value_or_zero(const Vector2 &uv, const bool skip_owner_val) { if (get_value_from_owner && !skip_owner_val) { return get_owner_value(uv); } if (!input_property.is_valid()) { return get_zero_value(); } if (default_type == input_property->default_type) { return input_property->get_value(uv); } if (default_type == DEFAULT_TYPE_INT) { return to_int(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_FLOAT) { return to_float(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_VECTOR2) { return to_vector2(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_VECTOR3) { return to_vector3(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_COLOR) { return to_color(input_property->get_value(uv)); } else if (default_type == DEFAULT_TYPE_IMAGE) { return to_color(input_property->get_value(uv)); } return input_property->get_value(uv); } Vector2 MMNodeUniversalProperty::get_value_sdf3d(const Vector3 &uv3, const bool skip_owner_val) { if (get_value_from_owner && !skip_owner_val) { return owner->get_property_value_sdf3d(uv3); } if (!input_property.is_valid()) { return default_vector2; } return input_property->get_value_sdf3d(uv3); } int MMNodeUniversalProperty::to_int(const Variant &val) { if (val.get_type() == Variant::INT) { return val; } if (val.get_type() == Variant::REAL) { return int(val); } if (val.get_type() == Variant::VECTOR2) { Vector2 v = val; return int(v.x); } if (val.get_type() == Variant::VECTOR3) { Vector3 v = val; return int(v.x); } if (val.get_type() == Variant::COLOR) { Color v = val; return int(v.r); } return 0; } float MMNodeUniversalProperty::to_float(const Variant &val) { if (val.get_type() == Variant::REAL) { return val; } if (val.get_type() == Variant::INT) { return float(val); } if (val.get_type() == Variant::VECTOR2) { Vector2 v = val; return float(v.x); } if (val.get_type() == Variant::VECTOR3) { Vector3 v = val; return float(v.x); } if (val.get_type() == Variant::COLOR) { Color v = val; return float(v.r); } return 0.0; } Vector2 MMNodeUniversalProperty::to_vector2(const Variant &val) { if (val.get_type() == Variant::VECTOR2) { return val; } if (val.get_type() == Variant::INT) { return Vector2(val, val); } if (val.get_type() == Variant::REAL) { return Vector2(val, val); } if (val.get_type() == Variant::VECTOR3) { Vector3 v = val; return Vector2(v.x, v.y); } if (val.get_type() == Variant::COLOR) { Color v = val; return Vector2(v.r, v.g); } return Vector2(); } Vector3 MMNodeUniversalProperty::to_vector3(const Variant &val) { if (val.get_type() == Variant::VECTOR3) { return val; } if (val.get_type() == Variant::INT) { return Vector3(val, val, val); } if (val.get_type() == Variant::REAL) { return Vector3(val, val, val); } if (val.get_type() == Variant::VECTOR2) { Vector2 v = val; return Vector3(v.x, v.y, 0); } if (val.get_type() == Variant::COLOR) { Color v = val; return Vector3(v.r, v.g, v.b); } return Vector3(); } Color MMNodeUniversalProperty::to_color(const Variant &val) { if (val.get_type() == Variant::COLOR) { return val; } if (val.get_type() == Variant::INT) { return Color(val, val, val, 1); } if (val.get_type() == Variant::REAL) { return Color(val, val, val, 1); } if (val.get_type() == Variant::VECTOR2) { Vector2 v = val; return Color(v.x, v.y, 0, 1); } if (val.get_type() == Variant::VECTOR3) { Vector3 v = val; return Color(v.x, v.y, v.z, 1); } return Color(); } void MMNodeUniversalProperty::set_value(const Variant &val) { if (default_type == DEFAULT_TYPE_IMAGE) { override_image = val; emit_changed(); return; } set_default_value(val); } Variant MMNodeUniversalProperty::get_zero_value() { if (default_type == DEFAULT_TYPE_INT) { return 0; } else if (default_type == DEFAULT_TYPE_FLOAT) { return 0.0; } else if (default_type == DEFAULT_TYPE_VECTOR2) { return Vector2(); } else if (default_type == DEFAULT_TYPE_VECTOR3) { return Vector3(); } else if (default_type == DEFAULT_TYPE_COLOR) { return Color(); } else if (default_type == DEFAULT_TYPE_IMAGE) { return Color(); } return Variant(); } Variant MMNodeUniversalProperty::get_default_value(const Vector2 &uv) { if (default_type == DEFAULT_TYPE_INT) { return default_int; } else if (default_type == DEFAULT_TYPE_FLOAT) { return default_float; } else if (default_type == DEFAULT_TYPE_VECTOR2) { return default_vector2; } else if (default_type == DEFAULT_TYPE_VECTOR3) { return default_vector3; } else if (default_type == DEFAULT_TYPE_COLOR) { return default_color; } else if (default_type == DEFAULT_TYPE_IMAGE) { Ref image = default_image; if (override_image.is_valid()) { image = override_image; } if (!image.is_valid()) { return default_color; } image->lock(); int x = uv.x * image->get_width(); int y = uv.y * image->get_height(); x = CLAMP(x, 0, image->get_width() - 1); y = CLAMP(y, 0, image->get_width() - 1); Color c = image->get_pixel(x, y); image->unlock(); return c; } return Variant(); } Variant MMNodeUniversalProperty::get_default_value_const(const Vector2 &uv) const { if (default_type == DEFAULT_TYPE_INT) { return default_int; } else if (default_type == DEFAULT_TYPE_FLOAT) { return default_float; } else if (default_type == DEFAULT_TYPE_VECTOR2) { return default_vector2; } else if (default_type == DEFAULT_TYPE_VECTOR3) { return default_vector3; } else if (default_type == DEFAULT_TYPE_COLOR) { return default_color; } else if (default_type == DEFAULT_TYPE_IMAGE) { Ref image = default_image; if (override_image.is_valid()) { image = override_image; } if (!image.is_valid()) { return default_color; } image->lock(); int x = uv.x * image->get_width(); int y = uv.y * image->get_height(); x = CLAMP(x, 0, image->get_width() - 1); y = CLAMP(y, 0, image->get_width() - 1); Color c = image->get_pixel(x, y); image->unlock(); return c; } return Variant(); } void MMNodeUniversalProperty::set_default_value(const Variant &val) { if (default_type == DEFAULT_TYPE_INT) { default_int = val; } else if (default_type == DEFAULT_TYPE_FLOAT) { default_float = val; } else if (default_type == DEFAULT_TYPE_VECTOR2) { default_vector2 = val; } else if (default_type == DEFAULT_TYPE_VECTOR3) { default_vector3 = val; } else if (default_type == DEFAULT_TYPE_COLOR) { default_color = val; } else if (default_type == DEFAULT_TYPE_IMAGE) { default_image = val; } emit_changed(); } Ref MMNodeUniversalProperty::get_active_image() { if (!force_override && input_property.is_valid()) { return input_property->get_active_image(); } if (override_image.is_valid()) { return override_image; } return default_image; } void MMNodeUniversalProperty::do_emit_changed() { emit_changed(); } MMNodeUniversalProperty::MMNodeUniversalProperty() { default_type = DEFAULT_TYPE_INT; default_int = 0; default_float = 0; get_value_from_owner = false; force_override = false; input_slot_type = SLOT_TYPE_NONE; output_slot_type = SLOT_TYPE_NONE; value_step = 0.1; value_range = Vector2(-1000, 1000); } MMNodeUniversalProperty::~MMNodeUniversalProperty() { } void MMNodeUniversalProperty::_notification(int p_what) { if (p_what == NOTIFICATION_POSTINITIALIZE) { if (input_property.is_valid()) { input_property->connect("changed", this, "on_input_property_changed"); } } } void MMNodeUniversalProperty::_bind_methods() { ClassDB::bind_method(D_METHOD("get_default_type"), &MMNodeUniversalProperty::get_default_type); ClassDB::bind_method(D_METHOD("set_default_type", "value"), &MMNodeUniversalProperty::set_default_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "default_type"), "set_default_type", "get_default_type"); ClassDB::bind_method(D_METHOD("get_default_int"), &MMNodeUniversalProperty::get_default_int); ClassDB::bind_method(D_METHOD("set_default_int", "value"), &MMNodeUniversalProperty::set_default_int); ADD_PROPERTY(PropertyInfo(Variant::INT, "default_int"), "set_default_int", "get_default_int"); ClassDB::bind_method(D_METHOD("get_default_float"), &MMNodeUniversalProperty::get_default_float); ClassDB::bind_method(D_METHOD("set_default_float", "value"), &MMNodeUniversalProperty::set_default_float); ADD_PROPERTY(PropertyInfo(Variant::REAL, "default_float"), "set_default_float", "get_default_float"); ClassDB::bind_method(D_METHOD("get_default_vector2"), &MMNodeUniversalProperty::get_default_vector2); ClassDB::bind_method(D_METHOD("set_default_vector2", "value"), &MMNodeUniversalProperty::set_default_vector2); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "default_vector2"), "set_default_vector2", "get_default_vector2"); ClassDB::bind_method(D_METHOD("get_default_vector3"), &MMNodeUniversalProperty::get_default_vector3); ClassDB::bind_method(D_METHOD("set_default_vector3", "value"), &MMNodeUniversalProperty::set_default_vector3); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "default_vector3"), "set_default_vector3", "get_default_vector3"); ClassDB::bind_method(D_METHOD("get_default_color"), &MMNodeUniversalProperty::get_default_color); ClassDB::bind_method(D_METHOD("set_default_color", "value"), &MMNodeUniversalProperty::set_default_color); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_color"), "set_default_color", "get_default_color"); ClassDB::bind_method(D_METHOD("get_default_image"), &MMNodeUniversalProperty::get_default_image); ClassDB::bind_method(D_METHOD("set_default_image", "value"), &MMNodeUniversalProperty::set_default_image); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "default_image", PROPERTY_HINT_RESOURCE_TYPE, "Image"), "set_default_image", "get_default_image"); ClassDB::bind_method(D_METHOD("get_get_value_from_owner"), &MMNodeUniversalProperty::get_get_value_from_owner); ClassDB::bind_method(D_METHOD("set_get_value_from_owner", "value"), &MMNodeUniversalProperty::set_get_value_from_owner); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "get_value_from_owner"), "set_get_value_from_owner", "get_get_value_from_owner"); ClassDB::bind_method(D_METHOD("get_force_override"), &MMNodeUniversalProperty::get_force_override); ClassDB::bind_method(D_METHOD("set_force_override", "value"), &MMNodeUniversalProperty::set_force_override); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_override"), "set_force_override", "get_force_override"); ClassDB::bind_method(D_METHOD("get_override_image"), &MMNodeUniversalProperty::get_override_image); ClassDB::bind_method(D_METHOD("set_override_image", "value"), &MMNodeUniversalProperty::set_override_image); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "override_image", PROPERTY_HINT_RESOURCE_TYPE, "Image", 0), "set_override_image", "get_override_image"); ClassDB::bind_method(D_METHOD("get_input_slot_type"), &MMNodeUniversalProperty::get_input_slot_type); ClassDB::bind_method(D_METHOD("set_input_slot_type", "value"), &MMNodeUniversalProperty::set_input_slot_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "input_slot_type"), "set_input_slot_type", "get_input_slot_type"); ClassDB::bind_method(D_METHOD("get_output_slot_type"), &MMNodeUniversalProperty::get_output_slot_type); ClassDB::bind_method(D_METHOD("set_output_slot_type", "value"), &MMNodeUniversalProperty::set_output_slot_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "output_slot_type"), "set_output_slot_type", "get_output_slot_type"); ClassDB::bind_method(D_METHOD("get_slot_name"), &MMNodeUniversalProperty::get_slot_name); ClassDB::bind_method(D_METHOD("set_slot_name", "value"), &MMNodeUniversalProperty::set_slot_name); ADD_PROPERTY(PropertyInfo(Variant::STRING, "slot_name"), "set_slot_name", "get_slot_name"); ClassDB::bind_method(D_METHOD("get_value_step"), &MMNodeUniversalProperty::get_value_step); ClassDB::bind_method(D_METHOD("set_value_step", "value"), &MMNodeUniversalProperty::set_value_step); ADD_PROPERTY(PropertyInfo(Variant::REAL, "value_step"), "set_value_step", "get_value_step"); ClassDB::bind_method(D_METHOD("get_value_range"), &MMNodeUniversalProperty::get_value_range); ClassDB::bind_method(D_METHOD("set_value_range", "value"), &MMNodeUniversalProperty::set_value_range); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "value_range"), "set_value_range", "get_value_range"); ClassDB::bind_method(D_METHOD("get_input_property"), &MMNodeUniversalProperty::get_input_property); ClassDB::bind_method(D_METHOD("set_input_property", "value"), &MMNodeUniversalProperty::set_input_property); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "input_property", PROPERTY_HINT_RESOURCE_TYPE, "MMNodeUniversalProperty"), "set_input_property", "get_input_property"); ClassDB::bind_method(D_METHOD("unset_input_property"), &MMNodeUniversalProperty::unset_input_property); ClassDB::bind_method(D_METHOD("on_input_property_changed"), &MMNodeUniversalProperty::on_input_property_changed); ClassDB::bind_method(D_METHOD("get_owner"), &MMNodeUniversalProperty::get_owner); ClassDB::bind_method(D_METHOD("set_owner", "value"), &MMNodeUniversalProperty::set_owner); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "MMNode", 0), "set_owner", "get_owner"); ClassDB::bind_method(D_METHOD("get_value", "uv", "skip_owner_val"), &MMNodeUniversalProperty::get_value, false); ClassDB::bind_method(D_METHOD("get_owner_value", "uv"), &MMNodeUniversalProperty::get_owner_value); ClassDB::bind_method(D_METHOD("get_value_or_zero", "uv", "skip_owner_val"), &MMNodeUniversalProperty::get_value_or_zero, false); ClassDB::bind_method(D_METHOD("get_value_sdf3d", "uv3", "skip_owner_val"), &MMNodeUniversalProperty::get_value_sdf3d, false); ClassDB::bind_method(D_METHOD("to_int", "val"), &MMNodeUniversalProperty::to_int); ClassDB::bind_method(D_METHOD("to_float", "val"), &MMNodeUniversalProperty::to_float); ClassDB::bind_method(D_METHOD("to_vector2", "val"), &MMNodeUniversalProperty::to_vector2); ClassDB::bind_method(D_METHOD("to_vector3", "val"), &MMNodeUniversalProperty::to_vector3); ClassDB::bind_method(D_METHOD("to_color", "val"), &MMNodeUniversalProperty::to_color); ClassDB::bind_method(D_METHOD("set_value", "val"), &MMNodeUniversalProperty::set_value); ClassDB::bind_method(D_METHOD("get_zero_value"), &MMNodeUniversalProperty::get_zero_value); ClassDB::bind_method(D_METHOD("get_default_value", "uv"), &MMNodeUniversalProperty::get_default_value, Vector2()); ClassDB::bind_method(D_METHOD("set_default_value", "val"), &MMNodeUniversalProperty::set_default_value); ClassDB::bind_method(D_METHOD("get_active_image"), &MMNodeUniversalProperty::get_active_image); ClassDB::bind_method(D_METHOD("do_emit_changed"), &MMNodeUniversalProperty::do_emit_changed); BIND_ENUM_CONSTANT(SLOT_TYPE_NONE); BIND_ENUM_CONSTANT(SLOT_TYPE_IMAGE); BIND_ENUM_CONSTANT(SLOT_TYPE_INT); BIND_ENUM_CONSTANT(SLOT_TYPE_FLOAT); BIND_ENUM_CONSTANT(SLOT_TYPE_VECTOR2); BIND_ENUM_CONSTANT(SLOT_TYPE_VECTOR3); BIND_ENUM_CONSTANT(SLOT_TYPE_COLOR); BIND_ENUM_CONSTANT(SLOT_TYPE_UNIVERSAL); BIND_ENUM_CONSTANT(DEFAULT_TYPE_INT); BIND_ENUM_CONSTANT(DEFAULT_TYPE_FLOAT); BIND_ENUM_CONSTANT(DEFAULT_TYPE_VECTOR2); BIND_ENUM_CONSTANT(DEFAULT_TYPE_VECTOR3); BIND_ENUM_CONSTANT(DEFAULT_TYPE_COLOR); BIND_ENUM_CONSTANT(DEFAULT_TYPE_IMAGE); }