/*************************************************************************/ /* mm_node.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.h" #include "../editor/mm_graph_node.h" #include "core/object/object.h" #include "mm_material.h" #include "mm_node_universal_property.h" #include "scene/main/node.h" Vector2 MMNode::get_graph_position() { return graph_position; } void MMNode::set_graph_position(const Vector2 &pos) { graph_position = pos; emit_changed(); } Vector MMNode::get_input_properties() { Vector r; for (int i = 0; i < input_properties.size(); i++) { r.push_back(input_properties[i].get_ref_ptr()); } return r; } void MMNode::set_input_properties(const Vector &val) { input_properties.clear(); for (int i = 0; i < val.size(); i++) { Ref e = Ref(val[i]); input_properties.push_back(e); } } Vector MMNode::get_output_properties() { Vector r; for (int i = 0; i < output_properties.size(); i++) { r.push_back(output_properties[i].get_ref_ptr()); } return r; } void MMNode::set_output_properties(const Vector &val) { output_properties.clear(); for (int i = 0; i < val.size(); i++) { Ref e = Ref(val[i]); output_properties.push_back(e); } } bool MMNode::get_properties_initialized() const { return properties_initialized; } void MMNode::set_properties_initialized(const bool val) { properties_initialized = val; } bool MMNode::get_dirty() const { return dirty; } void MMNode::set_dirty(const bool val) { bool changed = val != dirty; dirty = val; if (changed) { emit_changed(); } } bool MMNode::render(const Ref &material) { if (!dirty) { return false; } for (int i = 0; i < input_properties.size(); ++i) { Ref p = input_properties[i]; if (!p.is_valid()) { continue; } if (p->get_input_property().is_valid() && p->get_input_property()->get_owner()->get_dirty()) { return false; } } call("_render", material); dirty = false; return true; } void MMNode::_render(const Ref &material) { } Ref MMNode::render_image(const Ref &material) { return call("_render_image", material); } Ref MMNode::_render_image(const Ref &material) { Ref image; image.instance(); image->create(material->image_size.x, material->image_size.y, false, Image::FORMAT_RGBA8); image->lock(); float w = image->get_width(); float h = image->get_height(); float pseed = Math::randf() + Math::rand(); for (int x = 0; x < image->get_width(); ++x) { //x in range(image.get_width()) for (int y = 0; y < image->get_height(); ++y) { //y in range(image.get_height()) Vector2 v = Vector2(x / w, y / h); Color col = get_value_for(v, pseed); image->set_pixel(x, y, col); } } image->unlock(); return image; } Color MMNode::get_value_for(const Vector2 &uv, const int pseed) { return call("_get_value_for", uv, pseed); } Color MMNode::_get_value_for(const Vector2 &uv, const int pseed) { return Color(); } void MMNode::init_properties() { if (!properties_initialized) { properties_initialized = true; call("_init_properties"); } } void MMNode::_init_properties() { } void MMNode::register_methods(Node *mm_graph_node) { init_properties(); call("_register_methods", mm_graph_node); } void MMNode::_register_methods_bind(Node *mm_graph_node) { MMGraphNode *gn = Object::cast_to(mm_graph_node); ERR_FAIL_COND(!gn); _register_methods(gn); } void MMNode::_register_methods(MMGraphNode *mm_graph_node) { } void MMNode::register_input_property(const Ref &p_prop) { Ref prop = p_prop; prop->set_owner(this); if (!prop->is_connected("changed", this, "on_input_property_changed")) { prop->connect("changed", this, "on_input_property_changed"); } input_properties.erase(prop); input_properties.push_back(prop); } void MMNode::unregister_input_property(const Ref &p_prop) { Ref prop = p_prop; if (prop->get_owner() == this) { prop->set_owner(nullptr); } if (prop->is_connected("changed", this, "on_input_property_changed")) { prop->disconnect("changed", this, "on_input_property_changed"); } input_properties.erase(prop); } void MMNode::register_output_property(const Ref &p_prop) { Ref prop = p_prop; prop->set_owner(this); output_properties.erase(prop); output_properties.push_back(prop); } void MMNode::unregister_output_property(const Ref &p_prop) { Ref prop = p_prop; if (prop->get_owner() == this) { prop->set_owner(nullptr); } output_properties.erase(prop); } void MMNode::on_input_property_changed() { set_dirty(true); emit_changed(); } Variant MMNode::get_property_value(const Vector2 &uv) { return call("_get_property_value", uv); } Variant MMNode::_get_property_value(const Vector2 &uv) { return Variant(); } Vector2 MMNode::get_property_value_sdf3d(const Vector3 &uv3) { return call("_get_property_value_sdf3d", uv3); } Vector2 MMNode::_get_property_value_sdf3d(const Vector3 &uv3) { return Vector2(); } MMNode::MMNode() { properties_initialized = false; dirty = true; } MMNode::~MMNode() { } void MMNode::_bind_methods() { ClassDB::bind_method(D_METHOD("get_graph_position"), &MMNode::get_graph_position); ClassDB::bind_method(D_METHOD("set_graph_position", "value"), &MMNode::set_graph_position); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_position"), "set_graph_position", "get_graph_position"); ClassDB::bind_method(D_METHOD("get_input_properties"), &MMNode::get_input_properties); ClassDB::bind_method(D_METHOD("set_input_properties", "value"), &MMNode::set_input_properties); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "input_properties", PROPERTY_HINT_NONE, "23/20:MMNodeUniversalProperty", PROPERTY_USAGE_EDITOR, "MMNodeUniversalProperty"), "set_input_properties", "get_input_properties"); ClassDB::bind_method(D_METHOD("get_output_properties"), &MMNode::get_output_properties); ClassDB::bind_method(D_METHOD("set_output_properties", "value"), &MMNode::set_output_properties); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "output_properties", PROPERTY_HINT_NONE, "23/20:MMNodeUniversalProperty", PROPERTY_USAGE_EDITOR, "MMNodeUniversalProperty"), "set_output_properties", "get_output_properties"); ClassDB::bind_method(D_METHOD("get_properties_initialized"), &MMNode::get_properties_initialized); ClassDB::bind_method(D_METHOD("set_properties_initialized", "value"), &MMNode::set_properties_initialized); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "properties_initialized", PROPERTY_HINT_NONE, "", 0), "set_properties_initialized", "get_properties_initialized"); ClassDB::bind_method(D_METHOD("get_dirty"), &MMNode::get_dirty); ClassDB::bind_method(D_METHOD("set_dirty", "value"), &MMNode::set_dirty); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dirty", PROPERTY_HINT_NONE, "", 0), "set_dirty", "get_dirty"); BIND_VMETHOD(MethodInfo("_render", PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "MMMaterial"))); ClassDB::bind_method(D_METHOD("render", "material"), &MMNode::render); ClassDB::bind_method(D_METHOD("_render", "material"), &MMNode::_render); BIND_VMETHOD(MethodInfo("_render_image", PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "MMMaterial"))); ClassDB::bind_method(D_METHOD("render_image", "material"), &MMNode::render_image); ClassDB::bind_method(D_METHOD("_render_image", "material"), &MMNode::_render_image); BIND_VMETHOD(MethodInfo("_get_value_for", PropertyInfo(Variant::VECTOR2, "uv"), PropertyInfo(Variant::INT, "pseed"))); ClassDB::bind_method(D_METHOD("get_value_for", "uv", "pseed"), &MMNode::get_value_for); ClassDB::bind_method(D_METHOD("_get_value_for", "uv", "pseed"), &MMNode::_get_value_for); BIND_VMETHOD(MethodInfo("_init_properties")); ClassDB::bind_method(D_METHOD("init_properties"), &MMNode::init_properties); ClassDB::bind_method(D_METHOD("_init_properties"), &MMNode::_init_properties); BIND_VMETHOD(MethodInfo("_register_methods", PropertyInfo(Variant::OBJECT, "mm_graph_node"))); ClassDB::bind_method(D_METHOD("register_methods", "mm_graph_node"), &MMNode::register_methods); ClassDB::bind_method(D_METHOD("_register_methods", "mm_graph_node"), &MMNode::_register_methods_bind); ClassDB::bind_method(D_METHOD("register_input_property", "prop"), &MMNode::register_input_property); ClassDB::bind_method(D_METHOD("unregister_input_property", "prop"), &MMNode::unregister_input_property); ClassDB::bind_method(D_METHOD("register_output_property", "prop"), &MMNode::register_output_property); ClassDB::bind_method(D_METHOD("unregister_output_property", "prop"), &MMNode::unregister_output_property); ClassDB::bind_method(D_METHOD("on_input_property_changed"), &MMNode::on_input_property_changed); BIND_VMETHOD(MethodInfo("_get_property_value", PropertyInfo(Variant::VECTOR2, "uv"))); ClassDB::bind_method(D_METHOD("get_property_value", "uv"), &MMNode::get_property_value); ClassDB::bind_method(D_METHOD("_get_property_value", "uv"), &MMNode::_get_property_value); BIND_VMETHOD(MethodInfo("_get_property_value_sdf3d", PropertyInfo(Variant::VECTOR3, "uv3"))); ClassDB::bind_method(D_METHOD("get_property_value_sdf3d", "uv3"), &MMNode::get_property_value_sdf3d); ClassDB::bind_method(D_METHOD("_get_property_value_sdf3d", "uv3"), &MMNode::_get_property_value_sdf3d); }