From 2b8b1d7c4632e5a8b11b5dd6d974ec94ce211289 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Sun, 2 Jun 2019 15:09:02 -0700 Subject: [PATCH] added MultiMeshInstance2D node for using MultiMesh in 2D --- doc/classes/MultiMeshInstance2D.xml | 27 +++++ drivers/gles2/rasterizer_canvas_gles2.cpp | 2 + drivers/gles2/shaders/canvas.glsl | 5 + drivers/gles3/shaders/canvas.glsl | 5 + editor/icons/icon_multi_mesh_instance_2d.svg | 4 + scene/2d/multimesh_instance_2d.cpp | 111 +++++++++++++++++++ scene/2d/multimesh_instance_2d.h | 65 +++++++++++ scene/register_scene_types.cpp | 12 +- 8 files changed, 226 insertions(+), 5 deletions(-) create mode 100644 doc/classes/MultiMeshInstance2D.xml create mode 100644 editor/icons/icon_multi_mesh_instance_2d.svg create mode 100644 scene/2d/multimesh_instance_2d.cpp create mode 100644 scene/2d/multimesh_instance_2d.h diff --git a/doc/classes/MultiMeshInstance2D.xml b/doc/classes/MultiMeshInstance2D.xml new file mode 100644 index 00000000000..0bf243ee247 --- /dev/null +++ b/doc/classes/MultiMeshInstance2D.xml @@ -0,0 +1,27 @@ + + + + Node that instances a [MultiMesh] in 2D. + + + [MultiMeshInstance2D] is a specialized node to instance a [MultiMesh] resource in 2D. + Usage is the same as [MultiMeshInstance]. + + + + + + + + The [MultiMesh] that will be drawn by the [MultiMeshInstance2D]. + + + The normal map that will be used if using the default [CanvasItemMaterial]. + + + The [Texture] that will be used if using the default [CanvasItemMaterial]. Can be accessed as [code]TEXTURE[/code] in CanvasItem shader. + + + + + diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index ee722e9d6c8..b82186162d4 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -1081,6 +1081,8 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur } else { glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 3, buffer + color_ofs); } + } else { + glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, 1.0, 1.0, 1.0, 1.0); } if (multi_mesh->custom_data_floats) { diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 7dce784f523..0818942b0a6 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -112,7 +112,12 @@ void main() { #ifdef USE_INSTANCING mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0))); color *= instance_color; + +#ifdef USE_INSTANCE_CUSTOM vec4 instance_custom = instance_custom_data; +#else + vec4 instance_custom = vec4(0.0); +#endif #else mat4 extra_matrix_instance = extra_matrix; diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 0d1e7ee4a1d..a46b31c92e5 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -117,7 +117,12 @@ void main() { #ifdef USE_INSTANCING mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0))); color *= instance_color; + +#ifdef USE_INSTANCE_CUSTOM vec4 instance_custom = instance_custom_data; +#else + vec4 instance_custom = vec4(0.0); +#endif #else mat4 extra_matrix_instance = extra_matrix; diff --git a/editor/icons/icon_multi_mesh_instance_2d.svg b/editor/icons/icon_multi_mesh_instance_2d.svg new file mode 100644 index 00000000000..07202ac6596 --- /dev/null +++ b/editor/icons/icon_multi_mesh_instance_2d.svg @@ -0,0 +1,4 @@ + + + + diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp new file mode 100644 index 00000000000..ca753021634 --- /dev/null +++ b/scene/2d/multimesh_instance_2d.cpp @@ -0,0 +1,111 @@ +/*************************************************************************/ +/* multimesh_instance_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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 "multimesh_instance_2d.h" + +void MultiMeshInstance2D::_notification(int p_what) { + + if (p_what == NOTIFICATION_DRAW) { + if (multimesh.is_valid()) { + draw_multimesh(multimesh, texture, normal_map); + } + } +} + +void MultiMeshInstance2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_multimesh", "multimesh"), &MultiMeshInstance2D::set_multimesh); + ClassDB::bind_method(D_METHOD("get_multimesh"), &MultiMeshInstance2D::get_multimesh); + + ClassDB::bind_method(D_METHOD("set_texture", "texture"), &MultiMeshInstance2D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &MultiMeshInstance2D::get_texture); + + ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &MultiMeshInstance2D::set_normal_map); + ClassDB::bind_method(D_METHOD("get_normal_map"), &MultiMeshInstance2D::get_normal_map); + + ADD_SIGNAL(MethodInfo("texture_changed")); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multimesh", PROPERTY_HINT_RESOURCE_TYPE, "MultiMesh"), "set_multimesh", "get_multimesh"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); +} + +void MultiMeshInstance2D::set_multimesh(const Ref &p_multimesh) { + + multimesh = p_multimesh; + update(); +} + +Ref MultiMeshInstance2D::get_multimesh() const { + + return multimesh; +} + +void MultiMeshInstance2D::set_texture(const Ref &p_texture) { + + if (p_texture == texture) + return; + texture = p_texture; + update(); + emit_signal("texture_changed"); + _change_notify("texture"); +} + +Ref MultiMeshInstance2D::get_texture() const { + + return texture; +} + +void MultiMeshInstance2D::set_normal_map(const Ref &p_texture) { + + normal_map = p_texture; + update(); +} + +Ref MultiMeshInstance2D::get_normal_map() const { + + return normal_map; +} + +Rect2 MultiMeshInstance2D::_edit_get_rect() const { + + if (multimesh.is_valid()) { + AABB aabb = multimesh->get_aabb(); + return Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); + } + + return Node2D::_edit_get_rect(); +} + +MultiMeshInstance2D::MultiMeshInstance2D() { +} + +MultiMeshInstance2D::~MultiMeshInstance2D() { +} diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h new file mode 100644 index 00000000000..37954971835 --- /dev/null +++ b/scene/2d/multimesh_instance_2d.h @@ -0,0 +1,65 @@ +/*************************************************************************/ +/* multimesh_instance_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef MULTIMESH_INSTANCE_2D_H +#define MULTIMESH_INSTANCE_2D_H + +#include "scene/2d/node_2d.h" +#include "scene/resources/multimesh.h" + +class MultiMeshInstance2D : public Node2D { + GDCLASS(MultiMeshInstance2D, Node2D); + + Ref multimesh; + + Ref texture; + Ref normal_map; + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + void set_multimesh(const Ref &p_multimesh); + Ref get_multimesh() const; + + void set_texture(const Ref &p_texture); + Ref get_texture() const; + + void set_normal_map(const Ref &p_texture); + Ref get_normal_map() const; + + virtual Rect2 _edit_get_rect() const; + + MultiMeshInstance2D(); + ~MultiMeshInstance2D(); +}; + +#endif // MULTIMESH_INSTANCE_2D_H diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 8e6e8e2a53a..5e4cf9c2ee7 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -48,6 +48,7 @@ #include "scene/2d/light_occluder_2d.h" #include "scene/2d/line_2d.h" #include "scene/2d/mesh_instance_2d.h" +#include "scene/2d/multimesh_instance_2d.h" #include "scene/2d/navigation_2d.h" #include "scene/2d/parallax_background.h" #include "scene/2d/parallax_layer.h" @@ -543,6 +544,7 @@ void register_scene_types() { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_virtual_class(); ClassDB::register_virtual_class(); ClassDB::register_class(); @@ -587,9 +589,13 @@ void register_scene_types() { SceneTree::add_idle_callback(ParticlesMaterial::flush_changes); ParticlesMaterial::init_shaders(); -#ifndef _3D_DISABLED ClassDB::register_virtual_class(); ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + +#ifndef _3D_DISABLED ClassDB::register_virtual_class(); ClassDB::register_class(); ClassDB::register_class(); @@ -603,7 +609,6 @@ void register_scene_types() { SceneTree::add_idle_callback(SpatialMaterial::flush_changes); SpatialMaterial::init_shaders(); - ClassDB::register_class(); ClassDB::register_class(); OS::get_singleton()->yield(); //may take time to init @@ -619,9 +624,6 @@ void register_scene_types() { ClassDB::register_class(); ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - OS::get_singleton()->yield(); //may take time to init ClassDB::register_class();