Copy the vertex lights 2d module over to the 3d version.

This commit is contained in:
Relintai 2024-03-27 12:26:20 +01:00
parent 0ee99269a6
commit b2b13bfb80
16 changed files with 1858 additions and 179 deletions

View File

@ -5,4 +5,7 @@ Import('env')
module_env = env.Clone()
module_env.add_source_files(env.modules_sources,"register_types.cpp")
module_env.add_source_files(env.modules_sources,"vertex_light_data_3d.cpp")
module_env.add_source_files(env.modules_sources,"vertex_lights_3d_server.cpp")
module_env.add_source_files(env.modules_sources,"vertex_light_data.cpp")
module_env.add_source_files(env.modules_sources,"vertex_light_3d.cpp")
module_env.add_source_files(env.modules_sources,"vertex_light_3d_environment.cpp")

View File

@ -1,7 +1,7 @@
def can_build(env, platform):
return False
return True
def configure(env):
@ -10,7 +10,9 @@ def configure(env):
def get_doc_classes():
return [
"VertexLightData3D",
"VertexLights3DServer",
"VertexLight3D",
"VertexLight3DEnvironment",
]
def get_doc_path():

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VertexLight3D" inherits="Node3D" version="4.3">
<brief_description>
A [Node3D] that manages a light in [VertexLights3DServer].
</brief_description>
<description>
A [Node3D] that manages a light in [VertexLights3DServer].
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="attenuation" type="float" setter="set_attenuation" getter="get_attenuation" default="1.0">
The light's attenuation.
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 1, 1, 1, 1 )">
The light's color.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="get_is_enabled" default="true">
WHether this light is enabled or not.
</member>
<member name="item_cull_mask" type="int" setter="set_item_cull_mask" getter="get_item_cull_mask" default="1">
The light's item cull mask.
</member>
<member name="layer_range" type="Vector2i" setter="set_layer_range" getter="get_layer_range" default="Vector2i( -512, 512 )">
The light's layer range.
</member>
<member name="mode" type="int" setter="set_mode" getter="get_mode" enum="VertexLight3D.VertexLight3DMode" default="0">
The light's mode.
</member>
<member name="range" type="Vector2i" setter="set_range" getter="get_range" default="Vector2i( 32, 32 )">
The light's range.
</member>
<member name="z_range" type="Vector2i" setter="set_z_range" getter="get_z_range" default="Vector2i( -1024, 1024 )">
The light's z range.
</member>
</members>
<constants>
<constant name="VERTEX_LIGHT_3D_MODE_ADD" value="0" enum="VertexLight3DMode">
The light's color gets added to the resulting colors.
</constant>
<constant name="VERTEX_LIGHT_3D_MODE_SUB" value="1" enum="VertexLight3DMode">
The light's color gets substracted to the resulting colors.
</constant>
<constant name="VERTEX_LIGHT_3D_MODE_MIX" value="2" enum="VertexLight3DMode">
The light's color gets blended with the resulting colors.
</constant>
</constants>
</class>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VertexLight3DEnvironment" inherits="Node3D" version="4.3">
<brief_description>
A [Node3D] that manages a map's base color in [VertexLights3DServer].
</brief_description>
<description>
A [Node3D] that manages a map's base color in [VertexLights3DServer].
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 0, 0, 0, 1 )">
The base color.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="get_is_enabled" default="true">
Whether this [VertexLight3DEnvironment] is actively managing the base color or not.
</member>
</members>
<constants>
</constants>
</class>

View File

@ -0,0 +1,280 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VertexLights3DServer" inherits="Object" version="4.3">
<brief_description>
A server that provides a way to store static lights that can be used to bake lighting information into mesh vertex data, or [CanvasItem]'s color modulation.
</brief_description>
<description>
A server that provides a way to store static lights that can be used to bake lighting information into mesh vertex data, or [CanvasItem]'s color modulation.
With this class extremely complex light information can be stored and used with no additional cost on the GPU side.
After adding lights, you can use [member sample_light] to sample lighting at a specified point in the map's space, then use the resulting [Color] to either further modifty the modulate property of [CanvasItem]s, or you can render meshes using this color in you custom _draw methods.
The drawback of this method is that it's more expensive change lights.
Note that you can use the normal 3D lighting system on top of this if you need dynamic lights (like [Light3D]). That system is better suited for that purpose.
Currently this class stores lights inside quadrants. Their optimal size should be a bit more than the radius of the biggest light you want to have.
</description>
<tutorials>
</tutorials>
<methods>
<method name="flush_notifications">
<return type="void" />
<description>
Flushes map changed notifications. This will get called automatically.
</description>
</method>
<method name="free">
<return type="void" />
<argument index="0" name="rid" type="RID" />
<description>
Frees an allocated resource.
</description>
</method>
<method name="get_default_quadrant_size" qualifiers="const">
<return type="Vector2i" />
<description>
Get the default internal quadrant size.
</description>
</method>
<method name="light_create">
<return type="RID" />
<description>
Create a light.
</description>
</method>
<method name="light_get_attenuation">
<return type="float" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's attenuation property.
</description>
</method>
<method name="light_get_color">
<return type="Color" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's color property.
</description>
</method>
<method name="light_get_is_enabled">
<return type="bool" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's enabled property.
</description>
</method>
<method name="light_get_item_cull_mask">
<return type="int" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's item cull mask property.
</description>
</method>
<method name="light_get_layer_range">
<return type="Vector2i" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's layer range property.
</description>
</method>
<method name="light_get_map">
<return type="RID" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's map.
</description>
</method>
<method name="light_get_mode">
<return type="int" enum="VertexLights3DServer.VertexLight3DMode" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's mix mode.
</description>
</method>
<method name="light_get_position">
<return type="Vector2" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's position.
</description>
</method>
<method name="light_get_range">
<return type="Vector2i" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's range.
</description>
</method>
<method name="light_get_z_range">
<return type="Vector2i" />
<argument index="0" name="light" type="RID" />
<description>
Get a light's z range property.
</description>
</method>
<method name="light_set_attenuation">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="attenuation" type="float" />
<description>
Set a light's attenuation property.
</description>
</method>
<method name="light_set_color">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="color" type="Color" />
<description>
Set a light's color property.
</description>
</method>
<method name="light_set_enabled">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="enabled" type="bool" />
<description>
Set a light's enabled property.
</description>
</method>
<method name="light_set_item_cull_mask">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="item_cull_mask" type="int" />
<description>
Set a light's item cull mask property.
</description>
</method>
<method name="light_set_layer_range">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="layer_range" type="Vector2i" />
<description>
Set a light's layer range property.
</description>
</method>
<method name="light_set_map">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="map" type="RID" />
<description>
Set a light's map.
</description>
</method>
<method name="light_set_mode">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="mode" type="int" enum="VertexLights3DServer.VertexLight3DMode" />
<description>
Set a light's mix mode.
</description>
</method>
<method name="light_set_position">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="position" type="Vector2" />
<description>
Set a light's position.
</description>
</method>
<method name="light_set_range">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="range" type="Vector2i" />
<description>
Set a light's range.
</description>
</method>
<method name="light_set_z_range">
<return type="void" />
<argument index="0" name="light" type="RID" />
<argument index="1" name="z_range" type="Vector2i" />
<description>
Set a light's z range property.
</description>
</method>
<method name="map_clear">
<return type="void" />
<argument index="0" name="map" type="RID" />
<description>
Clears a map of all lights.
</description>
</method>
<method name="map_create">
<return type="RID" />
<description>
Creates a map.
</description>
</method>
<method name="map_get_base_color" qualifiers="const">
<return type="Color" />
<argument index="0" name="map" type="RID" />
<description>
Returns the base color of a map.
</description>
</method>
<method name="map_get_lights" qualifiers="const">
<return type="Array" />
<argument index="0" name="map" type="RID" />
<description>
Returns all lights in a map.
</description>
</method>
<method name="map_get_quadrant_size" qualifiers="const">
<return type="Vector2i" />
<argument index="0" name="map" type="RID" />
<description>
Returns a map's quadrant size.
</description>
</method>
<method name="map_set_base_color">
<return type="void" />
<argument index="0" name="map" type="RID" />
<argument index="1" name="base_color" type="Color" />
<description>
Sets the base color of a map.
</description>
</method>
<method name="map_set_quadrant_size">
<return type="void" />
<argument index="0" name="map" type="RID" />
<argument index="1" name="size" type="Vector2i" />
<description>
Sets a map's quadrant size.
</description>
</method>
<method name="sample_light">
<return type="Color" />
<argument index="0" name="map" type="RID" />
<argument index="1" name="position" type="Vector2" />
<argument index="2" name="item_cull_mask" type="int" default="1" />
<argument index="3" name="layer" type="int" default="0" />
<argument index="4" name="z_index" type="int" default="0" />
<description>
Sample the lighing information at a specific position.
</description>
</method>
<method name="set_default_quadrant_size">
<return type="void" />
<argument index="0" name="size" type="Vector2i" />
<description>
Set the default internal quadrant size.
</description>
</method>
</methods>
<signals>
<signal name="map_changed">
<argument index="0" name="map" type="RID" />
<description>
Emitted after a map changed (only once per frame).
</description>
</signal>
</signals>
<constants>
<constant name="VERTEX_LIGHT_3D_MODE_ADD" value="0" enum="VertexLight3DMode">
The light's color gets added to the resulting colors.
</constant>
<constant name="VERTEX_LIGHT_3D_MODE_SUB" value="1" enum="VertexLight3DMode">
The light's color gets substracted to the resulting colors.
</constant>
<constant name="VERTEX_LIGHT_3D_MODE_MIX" value="2" enum="VertexLight3DMode">
The light's color gets blended with the resulting colors.
</constant>
</constants>
</class>

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="16"
viewBox="0 0 16 16"
width="16"
version="1.1"
id="svg1"
sodipodi:docname="icon_vertex_light_3d.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="47.25"
inkscape:cx="7.005291"
inkscape:cy="8.5714286"
inkscape:window-width="1920"
inkscape:window-height="1052"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3-4.5801 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3zm-1 11v1h2v-1z"
fill="#a5b7f3"
fill-opacity=".98824"
id="path1" />
<g
fill="#ffd684"
id="g3"
transform="rotate(-70.720541,7.7659337,5.574093)">
<ellipse
cx="3.7237"
cy="3.0267999"
rx="2.0114"
ry="1.9956"
id="ellipse1" />
<ellipse
cx="11.717"
cy="6.1733999"
rx="2.0114"
ry="1.9956"
id="ellipse2" />
<ellipse
cx="6.5219002"
cy="12.477"
rx="2.0114"
ry="1.9956"
id="ellipse3" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="16"
viewBox="0 0 16 16"
width="16"
version="1.1"
id="svg4"
sodipodi:docname="icon_vertex_light_3d_environment.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs4" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="53"
inkscape:cx="8"
inkscape:cy="8"
inkscape:window-width="1920"
inkscape:window-height="1052"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<g
fill="none"
stroke="#e0e0e0"
id="g4"
style="stroke:#a5b7f3;stroke-opacity:0.98823529">
<circle
cx="8"
cy="8"
r="6"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
id="circle1"
style="stroke:#a5b7f3;stroke-opacity:0.98823529" />
<g
stroke-width="1.5"
transform="translate(0 -1036.4)"
id="g3"
style="stroke:#a5b7f3;stroke-opacity:0.98823529">
<path
d="m2 1044.4c4.5932 1.582 8.3985 1.0627 12 0"
id="path1"
style="stroke:#a5b7f3;stroke-opacity:0.98823529" />
<path
d="m8 1038.4c-3 4-3 8 0 12"
id="path2"
style="stroke:#a5b7f3;stroke-opacity:0.98823529" />
<path
d="m8 1038.4c3 4 3 8 0 12"
id="path3"
style="stroke:#a5b7f3;stroke-opacity:0.98823529" />
</g>
</g>
<g
fill="#ffd684"
id="g3-3"
transform="rotate(-72.939283,7.7951298,5.6881068)">
<ellipse
cx="3.7237"
cy="3.0267999"
rx="2.0114"
ry="1.9956"
id="ellipse1" />
<ellipse
cx="11.717"
cy="6.1733999"
rx="2.0114"
ry="1.9956"
id="ellipse2" />
<ellipse
cx="6.5219002"
cy="12.477"
rx="2.0114"
ry="1.9956"
id="ellipse3" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -31,13 +31,31 @@
#include "register_types.h"
#include "vertex_light_data_3d.h"
#include "core/config/engine.h"
#include "vertex_light_3d.h"
#include "vertex_light_3d_environment.h"
#include "vertex_lights_3d_server.h"
VertexLights3DServer *vertex_lights_3d_server = NULL;
void register_vertex_lights_3d_types(ModuleRegistrationLevel p_level) {
if (p_level == MODULE_REGISTRATION_LEVEL_SCENE) {
ClassDB::register_class<VertexLightData3D>();
if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) {
vertex_lights_3d_server = memnew(VertexLights3DServer);
ClassDB::register_class<VertexLights3DServer>();
Engine::get_singleton()->add_singleton(Engine::Singleton("VertexLights3DServer", VertexLights3DServer::get_singleton()));
} else if (p_level == MODULE_REGISTRATION_LEVEL_SCENE) {
ClassDB::register_class<VertexLight3D>();
ClassDB::register_class<VertexLight3DEnvironment>();
} else if (p_level == MODULE_REGISTRATION_LEVEL_FINALIZE) {
vertex_lights_3d_server->init();
}
}
void unregister_vertex_lights_3d_types(ModuleRegistrationLevel p_level) {
if (p_level == MODULE_REGISTRATION_LEVEL_SINGLETON) {
if (vertex_lights_3d_server) {
memdelete(vertex_lights_3d_server);
}
}
}

View File

@ -0,0 +1,200 @@
/*************************************************************************/
/* vertex_light_3d.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 "vertex_light_3d.h"
#include "core/config/engine.h"
#include "scene/resources/world_2d.h"
bool VertexLight3D::get_is_enabled() {
return _enabled;
}
void VertexLight3D::set_enabled(const bool p_enabled) {
_enabled = p_enabled;
_update_light_visibility();
}
Vector2i VertexLight3D::get_range() {
return _range;
}
void VertexLight3D::set_range(const Vector2i &p_range) {
_range = p_range;
VertexLights3DServer::get_singleton()->light_set_range(_vertex_light, _range);
}
real_t VertexLight3D::get_attenuation() {
return _attenuation;
}
void VertexLight3D::set_attenuation(const real_t p_attenuation) {
_attenuation = p_attenuation;
VertexLights3DServer::get_singleton()->light_set_attenuation(_vertex_light, _attenuation);
}
Color VertexLight3D::get_color() {
return _color;
}
void VertexLight3D::set_color(const Color &p_color) {
_color = p_color;
VertexLights3DServer::get_singleton()->light_set_color(_vertex_light, _color);
}
VertexLight3D::VertexLight3DMode VertexLight3D::get_mode() {
return _mode;
}
void VertexLight3D::set_mode(const VertexLight3D::VertexLight3DMode p_mode) {
_mode = p_mode;
VertexLights3DServer::get_singleton()->light_set_mode(_vertex_light, (VertexLights3DServer::VertexLight3DMode)_mode);
}
Vector2i VertexLight3D::get_z_range() {
return _z_range;
}
void VertexLight3D::set_z_range(const Vector2i &p_z_range) {
_z_range = p_z_range;
VertexLights3DServer::get_singleton()->light_set_z_range(_vertex_light, _z_range);
}
Vector2i VertexLight3D::get_layer_range() {
return _layer_range;
}
void VertexLight3D::set_layer_range(const Vector2i &p_layer_range) {
_layer_range = p_layer_range;
VertexLights3DServer::get_singleton()->light_set_layer_range(_vertex_light, _layer_range);
}
int VertexLight3D::get_item_cull_mask() {
return _item_cull_mask;
}
void VertexLight3D::set_item_cull_mask(const int p_item_cull_mask) {
_item_cull_mask = p_item_cull_mask;
VertexLights3DServer::get_singleton()->light_set_item_cull_mask(_vertex_light, _item_cull_mask);
}
VertexLight3D::VertexLight3D() {
_vertex_light = RID_PRIME(VertexLights3DServer::get_singleton()->light_create());
_enabled = true;
_range = Vector2i(32, 32);
_attenuation = 1;
_color = Color(1, 1, 1, 1);
_item_cull_mask = 1;
_z_range = Vector2i(-1024, 1024);
_layer_range = Vector2i(-512, 512);
_mode = VERTEX_LIGHT_3D_MODE_ADD;
set_notify_transform(true);
}
VertexLight3D::~VertexLight3D() {
VertexLights3DServer::get_singleton()->free(_vertex_light);
}
void VertexLight3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
Ref<World2D> world = get_world_2d();
ERR_FAIL_COND(!world.is_valid());
RID map = world->get_vertex_lights_2d_map();
VertexLights3DServer::get_singleton()->light_set_map(_vertex_light, map);
VertexLights3DServer::get_singleton()->light_set_position(_vertex_light, get_global_transform().get_origin());
_update_light_visibility();
} break;
case NOTIFICATION_EXIT_TREE: {
VertexLights3DServer::get_singleton()->light_set_map(_vertex_light, RID());
_update_light_visibility();
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
VertexLights3DServer::get_singleton()->light_set_position(_vertex_light, get_global_transform().get_origin());
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
_update_light_visibility();
} break;
}
}
void VertexLight3D::_update_light_visibility() {
if (!is_inside_tree()) {
return;
}
VertexLights3DServer::get_singleton()->light_set_enabled(_vertex_light, _enabled && is_visible_in_tree());
}
void VertexLight3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_is_enabled"), &VertexLight3D::get_is_enabled);
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &VertexLight3D::set_enabled);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "get_is_enabled");
ClassDB::bind_method(D_METHOD("get_range"), &VertexLight3D::get_range);
ClassDB::bind_method(D_METHOD("set_range", "range"), &VertexLight3D::set_range);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "range"), "set_range", "get_range");
ClassDB::bind_method(D_METHOD("get_attenuation"), &VertexLight3D::get_attenuation);
ClassDB::bind_method(D_METHOD("set_attenuation", "attenuation"), &VertexLight3D::set_attenuation);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_attenuation", "get_attenuation");
ClassDB::bind_method(D_METHOD("get_color"), &VertexLight3D::get_color);
ClassDB::bind_method(D_METHOD("set_color", "color"), &VertexLight3D::set_color);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ClassDB::bind_method(D_METHOD("get_mode"), &VertexLight3D::get_mode);
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VertexLight3D::set_mode);
//,Mask
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix"), "set_mode", "get_mode");
ClassDB::bind_method(D_METHOD("get_z_range"), &VertexLight3D::get_z_range);
ClassDB::bind_method(D_METHOD("set_z_range", "z_range"), &VertexLight3D::set_z_range);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "z_range", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range", "get_z_range");
ClassDB::bind_method(D_METHOD("get_layer_range"), &VertexLight3D::get_layer_range);
ClassDB::bind_method(D_METHOD("set_layer_range", "layer_range"), &VertexLight3D::set_layer_range);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "layer_range", PROPERTY_HINT_RANGE, "-512,512,1"), "set_layer_range", "get_layer_range");
ClassDB::bind_method(D_METHOD("get_item_cull_mask"), &VertexLight3D::get_item_cull_mask);
ClassDB::bind_method(D_METHOD("set_item_cull_mask", "item_cull_mask"), &VertexLight3D::set_item_cull_mask);
ADD_PROPERTY(PropertyInfo(Variant::INT, "item_cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_item_cull_mask", "get_item_cull_mask");
BIND_ENUM_CONSTANT(VERTEX_LIGHT_3D_MODE_ADD);
BIND_ENUM_CONSTANT(VERTEX_LIGHT_3D_MODE_SUB);
BIND_ENUM_CONSTANT(VERTEX_LIGHT_3D_MODE_MIX);
}

View File

@ -0,0 +1,103 @@
#ifndef VERTEX_LIGHT_3D_H
#define VERTEX_LIGHT_3D_H
/*************************************************************************/
/* vertex_3d.h */
/*************************************************************************/
/* 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 "scene/main/node_2d.h"
#include "core/containers/hash_map.h"
#include "core/containers/vector.h"
#include "core/math/color.h"
#include "core/math/vector2i.h"
#include "vertex_lights_3d_server.h"
class VertexLight3D : public Node2D {
GDCLASS(VertexLight3D, Node2D);
public:
enum VertexLight3DMode {
VERTEX_LIGHT_3D_MODE_ADD = VertexLights3DServer::VERTEX_LIGHT_3D_MODE_ADD,
VERTEX_LIGHT_3D_MODE_SUB = VertexLights3DServer::VERTEX_LIGHT_3D_MODE_SUB,
VERTEX_LIGHT_3D_MODE_MIX = VertexLights3DServer::VERTEX_LIGHT_3D_MODE_MIX,
//VERTEX_LIGHT_3D_MODE_MASK = VertexLights3DServer::VERTEX_LIGHT_3D_MODE_MASK
};
bool get_is_enabled();
void set_enabled(const bool p_enabled);
Vector2i get_range();
void set_range(const Vector2i &p_range);
real_t get_attenuation();
void set_attenuation(const real_t p_attenuation);
Color get_color();
void set_color(const Color &p_color);
VertexLight3D::VertexLight3DMode get_mode();
void set_mode(const VertexLight3D::VertexLight3DMode p_mode);
Vector2i get_z_range();
void set_z_range(const Vector2i &p_z_range);
Vector2i get_layer_range();
void set_layer_range(const Vector2i &p_layer_range);
int get_item_cull_mask();
void set_item_cull_mask(const int p_item_cull_mask);
VertexLight3D();
~VertexLight3D();
protected:
void _notification(int p_what);
void _update_light_visibility();
static void _bind_methods();
RID _vertex_light;
bool _enabled;
Vector2i _range;
real_t _attenuation;
Color _color;
VertexLight3DMode _mode;
Vector2i _z_range;
Vector2i _layer_range;
int _item_cull_mask;
};
VARIANT_ENUM_CAST(VertexLight3D::VertexLight3DMode);
#endif

View File

@ -0,0 +1,96 @@
/*************************************************************************/
/* vertex_light_3d.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 "vertex_light_3d_environment.h"
#include "core/config/engine.h"
#include "scene/resources/world_2d.h"
#include "vertex_lights_3d_server.h"
bool VertexLight3DEnvironment::get_is_enabled() {
return _enabled;
}
void VertexLight3DEnvironment::set_enabled(const bool p_enabled) {
_enabled = p_enabled;
_update_light_visibility();
}
Color VertexLight3DEnvironment::get_color() {
return _color;
}
void VertexLight3DEnvironment::set_color(const Color &p_color) {
_color = p_color;
_update_light_visibility();
}
VertexLight3DEnvironment::VertexLight3DEnvironment() {
_enabled = true;
}
VertexLight3DEnvironment::~VertexLight3DEnvironment() {
}
void VertexLight3DEnvironment::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
_update_light_visibility();
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
_update_light_visibility();
} break;
}
}
void VertexLight3DEnvironment::_update_light_visibility() {
if (!is_inside_tree() || !_enabled || !is_visible_in_tree()) {
return;
}
Ref<World2D> world = get_world_2d();
ERR_FAIL_COND(!world.is_valid());
RID map = world->get_vertex_lights_2d_map();
VertexLights3DServer::get_singleton()->map_set_base_color(map, _color);
}
void VertexLight3DEnvironment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_is_enabled"), &VertexLight3DEnvironment::get_is_enabled);
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &VertexLight3DEnvironment::set_enabled);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "get_is_enabled");
ClassDB::bind_method(D_METHOD("get_color"), &VertexLight3DEnvironment::get_color);
ClassDB::bind_method(D_METHOD("set_color", "color"), &VertexLight3DEnvironment::set_color);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
}

View File

@ -1,8 +1,8 @@
#ifndef VERTEX_LIGHT_DATA_3D_H
#define VERTEX_LIGHT_DATA_3D_H
#ifndef VERTEX_LIGHT_3D_ENVIRONMENT_H
#define VERTEX_LIGHT_3D_ENVIRONMENT_H
/*************************************************************************/
/* vertex_light_data_3d.h.h */
/* vertex_3d.h */
/*************************************************************************/
/* This file is part of: */
/* PANDEMONIUM ENGINE */
@ -32,55 +32,35 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "scene/main/node_2d.h"
#include "core/containers/hash_map.h"
#include "core/containers/vector.h"
#include "core/math/color.h"
#include "core/object/reference.h"
#include "core/math/transform.h"
#include "core/math/vector2i.h"
class VertexLightData3D : public Reference {
GDCLASS(VertexLightData3D, Reference);
class VertexLight3DEnvironment : public Node2D {
GDCLASS(VertexLight3DEnvironment, Node2D);
public:
Transform get_transform() const;
void set_transform(const Transform &p_transform);
bool get_is_enabled();
void set_enabled(const bool p_enabled);
real_t get_range() const;
void set_range(const real_t value);
Color get_color();
void set_color(const Color &p_color);
real_t get_attenuation() const;
void set_attenuation(const real_t value);
VertexLight3DEnvironment();
~VertexLight3DEnvironment();
Color get_color() const;
void set_color(const Color value);
protected:
void _notification(int p_what);
real_t get_energy() const;
void set_energy(const real_t value);
void _update_light_visibility();
real_t get_indirect_energy() const;
void set_indirect_energy(const real_t value);
bool get_negative() const;
void set_negative(const bool value);
real_t get_specular() const;
void set_specular(const real_t value);
VertexLightData3D();
~VertexLightData3D();
private:
static void _bind_methods();
private:
Transform _transform;
real_t _range;
real_t _attenuation;
bool _enabled;
Color _color;
real_t _energy;
real_t _indirect_energy;
bool _negative;
real_t _specular;
};
#endif

View File

@ -0,0 +1,208 @@
/*************************************************************************/
/* vertex_light_data.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 "vertex_lights_3d_server.h"
//VertexLightQuadrant3D
void VertexLights3DServer::VertexLightQuadrant3D::get_lights(List<VertexLightData3D *> *p_lights) {
for (uint32_t i = 0; i < lights.size(); ++i) {
p_lights->push_back(lights[i]);
}
}
Color VertexLights3DServer::VertexLightQuadrant3D::sample_light(const Color &p_current_color, const Vector2 &p_position, const int p_item_cull_mask, const int p_layer, const int p_z_index) {
Color c = p_current_color;
for (uint32_t i = 0; i < lights.size(); ++i) {
VertexLightData3D *l = lights[i];
if (!l->enabled) {
continue;
}
if (l->range.x == 0 || l->range.y == 0) {
continue;
}
if ((l->item_cull_mask & p_item_cull_mask) == 0) {
continue;
}
if (p_layer < l->layer_range.x || p_layer > l->layer_range.y) {
continue;
}
if (p_z_index < l->z_range.x || p_z_index > l->z_range.y) {
continue;
}
Vector2 light_to_pos = p_position - l->position;
Vector2 light_to_pos_normal_space = light_to_pos;
light_to_pos_normal_space.x /= static_cast<real_t>(l->range.x);
light_to_pos_normal_space.y /= static_cast<real_t>(l->range.y);
real_t ltpnsl = light_to_pos_normal_space.length();
// Position is outside the light's range.
if (ltpnsl >= 1) {
continue;
}
real_t attenuation = pow(1.0 - ltpnsl, l->attenuation);
Color ac = l->color * attenuation;
switch (l->mode) {
case VertexLights3DServer::VERTEX_LIGHT_3D_MODE_ADD: {
c += ac;
} break;
case VertexLights3DServer::VERTEX_LIGHT_3D_MODE_SUB: {
c -= ac;
} break;
case VertexLights3DServer::VERTEX_LIGHT_3D_MODE_MIX: {
c = c.blend(ac);
} break;
}
c = c.clamp();
}
return c;
}
//VertexLightMap3D
void VertexLights3DServer::VertexLightMap3D::recreate_quadrants() {
List<VertexLightData3D *> lights;
get_lights(&lights);
for (HashMap<Vector2i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
memdelete(E->value());
}
quadrants.clear();
for (List<VertexLightData3D *>::Element *E = lights.front(); E; E = E->next()) {
VertexLightData3D *l = E->get();
add_light(l);
}
}
void VertexLights3DServer::VertexLightMap3D::get_lights(List<VertexLightData3D *> *p_lights) {
for (HashMap<Vector2i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
E->value()->get_lights(p_lights);
}
}
void VertexLights3DServer::VertexLightMap3D::add_light(VertexLightData3D *p_light) {
VertexLightQuadrant3D *quadrant = get_quadrant_for_position(p_light->position);
p_light->map = this;
p_light->quadrant = quadrant;
quadrant->lights.push_back(p_light);
}
void VertexLights3DServer::VertexLightMap3D::remove_light(VertexLightData3D *p_light) {
p_light->map = NULL;
VertexLightQuadrant3D *quadrant = p_light->quadrant;
// Quadrant wan not updated properly somewhere!
ERR_FAIL_NULL(quadrant);
quadrant->lights.erase(p_light);
p_light->quadrant = NULL;
if (quadrant->lights.size() == 0) {
quadrants.erase(quadrant->position);
memdelete(quadrant);
}
}
VertexLights3DServer::VertexLightQuadrant3D *VertexLights3DServer::VertexLightMap3D::get_quadrant_for_position(const Vector2 &p_position) {
Vector2i quadrant_position = to_quadrant_position(p_position);
if (!quadrants.has(quadrant_position)) {
VertexLightQuadrant3D *quadrant = memnew(VertexLightQuadrant3D);
quadrant->position = quadrant_position;
quadrants[quadrant_position] = quadrant;
return quadrant;
}
return quadrants[quadrant_position];
}
void VertexLights3DServer::VertexLightMap3D::set_light_position(VertexLightData3D *p_light, const Vector2 &p_position) {
remove_light(p_light);
p_light->position = p_position;
add_light(p_light);
}
void VertexLights3DServer::VertexLightMap3D::clear() {
List<VertexLightData3D *> lights;
get_lights(&lights);
for (HashMap<Vector2i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
memdelete(E->value());
}
quadrants.clear();
for (List<VertexLightData3D *>::Element *E = lights.front(); E; E = E->next()) {
VertexLightData3D *l = E->get();
l->map = NULL;
l->quadrant = NULL;
}
}
Color VertexLights3DServer::VertexLightMap3D::sample_light(const Vector2 &p_position, const int p_item_cull_mask, const int p_layer, const int p_z_index) {
Color c = base_color;
Vector2i quadrant_position = to_quadrant_position(p_position);
for (int x = quadrant_position.x - 1; x <= quadrant_position.x + 1; ++x) {
for (int y = quadrant_position.y - 1; y <= quadrant_position.y + 1; ++y) {
Vector2i qp = Vector2i(x, y);
if (quadrants.has(qp)) {
VertexLightQuadrant3D *q = quadrants[qp];
c = q->sample_light(c, p_position, p_item_cull_mask, p_layer, p_z_index);
}
}
}
return c;
}

View File

@ -1,134 +0,0 @@
/*************************************************************************/
/* vertex_light_data_3d.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 "vertex_light_data_3d.h"
Transform VertexLightData3D::get_transform() const {
return _transform;
}
void VertexLightData3D::set_transform(const Transform &p_transform) {
_transform = p_transform;
}
real_t VertexLightData3D::get_range() const {
return _range;
}
void VertexLightData3D::set_range(const real_t value) {
_range = value;
}
real_t VertexLightData3D::get_attenuation() const {
return _attenuation;
}
void VertexLightData3D::set_attenuation(const real_t value) {
_attenuation = value;
}
Color VertexLightData3D::get_color() const {
return _color;
}
void VertexLightData3D::set_color(const Color value) {
_color = value;
}
real_t VertexLightData3D::get_energy() const {
return _energy;
}
void VertexLightData3D::set_energy(const real_t value) {
_energy = value;
}
real_t VertexLightData3D::get_indirect_energy() const {
return _indirect_energy;
}
void VertexLightData3D::set_indirect_energy(const real_t value) {
_indirect_energy = value;
}
bool VertexLightData3D::get_negative() const {
return _negative;
}
void VertexLightData3D::set_negative(const bool value) {
_negative = value;
}
real_t VertexLightData3D::get_specular() const {
return _specular;
}
void VertexLightData3D::set_specular(const real_t value) {
_specular = value;
}
VertexLightData3D::VertexLightData3D() {
_range = 0;
_attenuation = 0;
_energy = 0;
_indirect_energy = 0;
_negative = false;
_specular = 0;
}
VertexLightData3D::~VertexLightData3D() {
}
void VertexLightData3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_transform"), &VertexLightData3D::get_transform);
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &VertexLightData3D::set_transform);
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform");
ClassDB::bind_method(D_METHOD("get_range"), &VertexLightData3D::get_range);
ClassDB::bind_method(D_METHOD("set_range", "value"), &VertexLightData3D::set_range);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "light_range"), "set_range", "get_range");
ClassDB::bind_method(D_METHOD("get_attenuation"), &VertexLightData3D::get_attenuation);
ClassDB::bind_method(D_METHOD("set_attenuation", "value"), &VertexLightData3D::set_attenuation);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "light_attenuation"), "set_attenuation", "get_attenuation");
ClassDB::bind_method(D_METHOD("get_color"), &VertexLightData3D::get_color);
ClassDB::bind_method(D_METHOD("set_color", "value"), &VertexLightData3D::set_color);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color"), "set_color", "get_color");
ClassDB::bind_method(D_METHOD("get_energy"), &VertexLightData3D::get_energy);
ClassDB::bind_method(D_METHOD("set_energy", "value"), &VertexLightData3D::set_energy);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "light_energy"), "set_energy", "get_energy");
ClassDB::bind_method(D_METHOD("get_indirect_energy"), &VertexLightData3D::get_indirect_energy);
ClassDB::bind_method(D_METHOD("set_indirect_energy", "value"), &VertexLightData3D::set_indirect_energy);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "light_indirect_energy"), "set_indirect_energy", "get_indirect_energy");
ClassDB::bind_method(D_METHOD("get_negative"), &VertexLightData3D::get_negative);
ClassDB::bind_method(D_METHOD("set_negative", "value"), &VertexLightData3D::set_negative);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "get_negative");
ClassDB::bind_method(D_METHOD("get_specular"), &VertexLightData3D::get_specular);
ClassDB::bind_method(D_METHOD("set_specular", "value"), &VertexLightData3D::set_specular);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "light_specular"), "set_specular", "get_specular");
}

View File

@ -0,0 +1,449 @@
/*************************************************************************/
/* vertex_lights_3d.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 "vertex_lights_3d_server.h"
#include "core/config/project_settings.h"
#include "scene/main/scene_tree.h"
// Defaults
Vector2i VertexLights3DServer::get_default_quadrant_size() const {
return _default_quadrant_size;
}
void VertexLights3DServer::set_default_quadrant_size(const Vector2i &p_size) {
_default_quadrant_size = p_size;
}
// Maps
RID VertexLights3DServer::map_create() {
VertexLightMap3D *map = memnew(VertexLightMap3D);
RID rid = map_owner.make_rid(map);
map->self = rid;
map->quadrant_size = _default_quadrant_size;
return rid;
}
Vector2i VertexLights3DServer::map_get_quadrant_size(RID p_map) const {
const VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == NULL, Vector2i());
return map->quadrant_size;
}
void VertexLights3DServer::map_set_quadrant_size(RID p_map, const Vector2i &p_size) {
VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND(map == NULL);
map->quadrant_size = p_size;
map->recreate_quadrants();
_map_changed(map);
}
Color VertexLights3DServer::map_get_base_color(RID p_map) const {
const VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == NULL, Color());
return map->base_color;
}
void VertexLights3DServer::map_set_base_color(RID p_map, const Color &p_base_color) {
VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND(map == NULL);
map->base_color = p_base_color;
_map_changed(map);
}
Array VertexLights3DServer::map_get_lights(RID p_map) const {
VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == NULL, Array());
List<VertexLightData3D *> lights;
map->get_lights(&lights);
Array arr;
arr.resize(lights.size());
int i = 0;
for (List<VertexLightData3D *>::Element *E = lights.front(); E; E = E->next()) {
arr[i++] = E->get()->self;
}
return arr;
}
void VertexLights3DServer::map_clear(RID p_map) {
VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND(map == NULL);
map->clear();
_map_changed(map);
}
// Lights
RID VertexLights3DServer::light_create() {
VertexLightData3D *light = memnew(VertexLightData3D);
RID rid = light_owner.make_rid(light);
light->self = rid;
return rid;
}
RID VertexLights3DServer::light_get_map(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, RID());
if (!light->map) {
return RID();
}
return light->map->self;
}
void VertexLights3DServer::light_set_map(RID p_light, RID p_map) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
VertexLightMap3D *map = map_owner.getornull(p_map);
if (light->map) {
_light_changed(light);
light->map->remove_light(light);
}
if (map) {
map->add_light(light);
_light_changed(light);
}
}
bool VertexLights3DServer::light_get_is_enabled(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, false);
return light->enabled;
}
void VertexLights3DServer::light_set_enabled(RID p_light, const bool p_enabled) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
if (light->enabled == p_enabled) {
return;
}
light->enabled = p_enabled;
_light_enabled_changed(light);
}
Vector2 VertexLights3DServer::light_get_position(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, Vector2());
return light->position;
}
void VertexLights3DServer::light_set_position(RID p_light, const Vector2 &p_position) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
if (light->map) {
// This ensure the light gets moved to the proper quadrant
light->map->set_light_position(light, p_position);
_light_changed(light);
return;
}
light->position = p_position;
_light_changed(light);
}
Vector2i VertexLights3DServer::light_get_range(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, Vector2i());
return light->range;
}
void VertexLights3DServer::light_set_range(RID p_light, const Vector2i &p_range) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
light->range = p_range;
_light_changed(light);
}
real_t VertexLights3DServer::light_get_attenuation(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, 0);
return light->attenuation;
}
void VertexLights3DServer::light_set_attenuation(RID p_light, const real_t p_attenuation) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
light->attenuation = p_attenuation;
_light_changed(light);
}
Color VertexLights3DServer::light_get_color(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, Color());
return light->color;
}
void VertexLights3DServer::light_set_color(RID p_light, const Color &p_color) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
light->color = p_color;
_light_changed(light);
}
VertexLights3DServer::VertexLight3DMode VertexLights3DServer::light_get_mode(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, VertexLights3DServer::VERTEX_LIGHT_3D_MODE_ADD);
return light->mode;
}
void VertexLights3DServer::light_set_mode(RID p_light, const VertexLights3DServer::VertexLight3DMode p_mode) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
light->mode = p_mode;
_light_changed(light);
}
Vector2i VertexLights3DServer::light_get_z_range(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, Vector2i());
return light->z_range;
}
void VertexLights3DServer::light_set_z_range(RID p_light, const Vector2i &p_z_range) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
light->z_range = p_z_range;
_light_changed(light);
}
Vector2i VertexLights3DServer::light_get_layer_range(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, Vector2i());
return light->layer_range;
}
void VertexLights3DServer::light_set_layer_range(RID p_light, const Vector2i &p_layer_range) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
light->layer_range = p_layer_range;
_light_changed(light);
}
int VertexLights3DServer::light_get_item_cull_mask(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, 0);
return light->item_cull_mask;
}
void VertexLights3DServer::light_set_item_cull_mask(RID p_light, const int p_item_cull_mask) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
light->item_cull_mask = p_item_cull_mask;
_light_changed(light);
}
// Sampling
Color VertexLights3DServer::sample_light(RID p_map, const Vector2 &p_position, const int p_item_cull_mask, const int p_layer, const int p_z_index) {
VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == NULL, Color());
return map->sample_light(p_position, p_item_cull_mask, p_layer, p_z_index);
}
// Rest
void VertexLights3DServer::free(RID p_rid) {
if (!p_rid.is_valid()) {
ERR_FAIL_MSG("Invalid RID.");
return;
}
if (map_owner.owns(p_rid)) {
VertexLightMap3D *map = map_owner.get(p_rid);
map->clear();
map->self = RID();
map_owner.free(p_rid);
memdelete(map);
} else if (light_owner.owns(p_rid)) {
VertexLightData3D *light = light_owner.get(p_rid);
if (light->map) {
_light_changed(light);
light->map->remove_light(light);
}
light->self = RID();
light_owner.free(p_rid);
memdelete(light);
} else {
ERR_FAIL_MSG("Invalid RID.");
}
}
void VertexLights3DServer::init() {
call_deferred("_register_update");
}
void VertexLights3DServer::register_update() {
if (SceneTree::get_singleton()) {
if (!SceneTree::get_singleton()->is_connected("idle_frame", this, "flush_notifications")) {
SceneTree::get_singleton()->connect("idle_frame", this, "flush_notifications");
}
}
}
void VertexLights3DServer::unregister_update() {
if (SceneTree::get_singleton()) {
if (SceneTree::get_singleton()->is_connected("idle_frame", this, "flush_notifications")) {
SceneTree::get_singleton()->disconnect("idle_frame", this, "flush_notifications");
}
}
}
void VertexLights3DServer::flush_notifications() {
for (HashSet<RID>::Iterator iter = _changed_maps.begin(); iter; ++iter) {
emit_signal(_map_changed_name, iter.key());
}
_changed_maps.clear();
}
VertexLights3DServer::VertexLights3DServer() {
ERR_FAIL_COND(_self);
_self = this;
GLOBAL_DEF("vertex_lights_3d/default_quadrant_size", Vector2i(256, 256));
_default_quadrant_size = GLOBAL_GET("vertex_lights_3d/default_quadrant_size");
_map_changed_name = "map_changed";
}
VertexLights3DServer::~VertexLights3DServer() {
_self = NULL;
}
void VertexLights3DServer::_bind_methods() {
ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map")));
ClassDB::bind_method(D_METHOD("get_default_quadrant_size"), &VertexLights3DServer::get_default_quadrant_size);
ClassDB::bind_method(D_METHOD("set_default_quadrant_size", "size"), &VertexLights3DServer::set_default_quadrant_size);
ClassDB::bind_method(D_METHOD("map_create"), &VertexLights3DServer::map_create);
ClassDB::bind_method(D_METHOD("map_get_quadrant_size", "map"), &VertexLights3DServer::map_get_quadrant_size);
ClassDB::bind_method(D_METHOD("map_set_quadrant_size", "map", "size"), &VertexLights3DServer::map_set_quadrant_size);
ClassDB::bind_method(D_METHOD("map_get_base_color", "map"), &VertexLights3DServer::map_get_base_color);
ClassDB::bind_method(D_METHOD("map_set_base_color", "map", "base_color"), &VertexLights3DServer::map_set_base_color);
ClassDB::bind_method(D_METHOD("map_get_lights", "map"), &VertexLights3DServer::map_get_lights);
ClassDB::bind_method(D_METHOD("map_clear", "map"), &VertexLights3DServer::map_clear);
// Lights
ClassDB::bind_method(D_METHOD("light_create"), &VertexLights3DServer::light_create);
ClassDB::bind_method(D_METHOD("light_get_map", "light"), &VertexLights3DServer::light_get_map);
ClassDB::bind_method(D_METHOD("light_set_map", "light", "map"), &VertexLights3DServer::light_set_map);
ClassDB::bind_method(D_METHOD("light_get_is_enabled", "light"), &VertexLights3DServer::light_get_is_enabled);
ClassDB::bind_method(D_METHOD("light_set_enabled", "light", "enabled"), &VertexLights3DServer::light_set_enabled);
ClassDB::bind_method(D_METHOD("light_get_position", "light"), &VertexLights3DServer::light_get_position);
ClassDB::bind_method(D_METHOD("light_set_position", "light", "position"), &VertexLights3DServer::light_set_position);
ClassDB::bind_method(D_METHOD("light_get_range", "light"), &VertexLights3DServer::light_get_range);
ClassDB::bind_method(D_METHOD("light_set_range", "light", "range"), &VertexLights3DServer::light_set_range);
ClassDB::bind_method(D_METHOD("light_get_attenuation", "light"), &VertexLights3DServer::light_get_attenuation);
ClassDB::bind_method(D_METHOD("light_set_attenuation", "light", "attenuation"), &VertexLights3DServer::light_set_attenuation);
ClassDB::bind_method(D_METHOD("light_get_color", "light"), &VertexLights3DServer::light_get_color);
ClassDB::bind_method(D_METHOD("light_set_color", "light", "color"), &VertexLights3DServer::light_set_color);
ClassDB::bind_method(D_METHOD("light_get_mode", "light"), &VertexLights3DServer::light_get_mode);
ClassDB::bind_method(D_METHOD("light_set_mode", "light", "mode"), &VertexLights3DServer::light_set_mode);
ClassDB::bind_method(D_METHOD("light_get_z_range", "light"), &VertexLights3DServer::light_get_z_range);
ClassDB::bind_method(D_METHOD("light_set_z_range", "light", "z_range"), &VertexLights3DServer::light_set_z_range);
ClassDB::bind_method(D_METHOD("light_get_layer_range", "light"), &VertexLights3DServer::light_get_layer_range);
ClassDB::bind_method(D_METHOD("light_set_layer_range", "light", "layer_range"), &VertexLights3DServer::light_set_layer_range);
ClassDB::bind_method(D_METHOD("light_get_item_cull_mask", "light"), &VertexLights3DServer::light_get_item_cull_mask);
ClassDB::bind_method(D_METHOD("light_set_item_cull_mask", "light", "item_cull_mask"), &VertexLights3DServer::light_set_item_cull_mask);
// Sampling
ClassDB::bind_method(D_METHOD("sample_light", "map", "position", "item_cull_mask", "layer", "z_index"), &VertexLights3DServer::sample_light, DEFVAL(1), DEFVAL(0), DEFVAL(0));
// Rest, DEFVAL(0)
ClassDB::bind_method(D_METHOD("free", "rid"), &VertexLights3DServer::free);
ClassDB::bind_method(D_METHOD("_register_update"), &VertexLights3DServer::register_update);
ClassDB::bind_method(D_METHOD("flush_notifications"), &VertexLights3DServer::flush_notifications);
BIND_ENUM_CONSTANT(VERTEX_LIGHT_3D_MODE_ADD);
BIND_ENUM_CONSTANT(VERTEX_LIGHT_3D_MODE_SUB);
BIND_ENUM_CONSTANT(VERTEX_LIGHT_3D_MODE_MIX);
}
VertexLights3DServer *VertexLights3DServer::_self = NULL;

View File

@ -0,0 +1,249 @@
#ifndef VERTEX_LIGHT_3D_SERVER_H
#define VERTEX_LIGHT_3D_SERVER_H
/*************************************************************************/
/* vertex_lights_3d.h */
/*************************************************************************/
/* 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 "core/object/object.h"
#include "core/containers/hash_map.h"
#include "core/containers/hash_set.h"
#include "core/containers/list.h"
#include "core/containers/rid.h"
#include "core/containers/vector.h"
#include "core/math/color.h"
#include "core/math/vector2i.h"
class VertexLights3DServer : public Object {
GDCLASS(VertexLights3DServer, Object);
public:
enum VertexLight3DMode {
VERTEX_LIGHT_3D_MODE_ADD = 0,
VERTEX_LIGHT_3D_MODE_SUB,
VERTEX_LIGHT_3D_MODE_MIX,
//VERTEX_LIGHT_3D_MODE_MASK
};
// Defaults
Vector2i get_default_quadrant_size() const;
void set_default_quadrant_size(const Vector2i &p_size);
// Maps
RID map_create();
Vector2i map_get_quadrant_size(RID p_map) const;
void map_set_quadrant_size(RID p_map, const Vector2i &p_size);
Color map_get_base_color(RID p_map) const;
void map_set_base_color(RID p_map, const Color &p_base_color);
Array map_get_lights(RID p_map) const;
void map_clear(RID p_map);
// Lights
RID light_create();
RID light_get_map(RID p_light);
void light_set_map(RID p_light, RID p_map);
bool light_get_is_enabled(RID p_light);
void light_set_enabled(RID p_light, const bool p_enabled);
Vector2 light_get_position(RID p_light);
void light_set_position(RID p_light, const Vector2 &p_position);
Vector2i light_get_range(RID p_light);
void light_set_range(RID p_light, const Vector2i &p_range);
real_t light_get_attenuation(RID p_light);
void light_set_attenuation(RID p_light, const real_t p_attenuation);
Color light_get_color(RID p_light);
void light_set_color(RID p_light, const Color &p_color);
VertexLights3DServer::VertexLight3DMode light_get_mode(RID p_light);
void light_set_mode(RID p_light, const VertexLights3DServer::VertexLight3DMode p_mode);
Vector2i light_get_z_range(RID p_light);
void light_set_z_range(RID p_light, const Vector2i &p_z_range);
Vector2i light_get_layer_range(RID p_light);
void light_set_layer_range(RID p_light, const Vector2i &p_layer_range);
int light_get_item_cull_mask(RID p_light);
void light_set_item_cull_mask(RID p_light, const int p_item_cull_mask);
// Sampling
Color sample_light(RID p_map, const Vector2 &p_position, const int p_item_cull_mask = 1, const int p_layer = 0, const int p_z_index = 0);
// Rest
void free(RID p_rid);
void init();
void flush_notifications();
_FORCE_INLINE_ static VertexLights3DServer *get_singleton() {
return _self;
}
VertexLights3DServer();
~VertexLights3DServer();
protected:
void register_update();
void unregister_update();
static void _bind_methods();
class VertexLightMap3D;
class VertexLightQuadrant3D;
class VertexLightData3D;
class VertexLightData3D : public RID_Data {
public:
bool enabled;
Vector2 position;
Vector2i range;
real_t attenuation;
Color color;
VertexLights3DServer::VertexLight3DMode mode;
Vector2i z_range;
Vector2i layer_range;
int item_cull_mask;
VertexLightMap3D *map;
VertexLightQuadrant3D *quadrant;
RID self;
VertexLightData3D() {
map = NULL;
quadrant = NULL;
enabled = true;
range = Vector2i(32, 32);
attenuation = 1;
color = Color(1, 1, 1, 1);
item_cull_mask = 1;
z_range = Vector2i(-1024, 1024);
layer_range = Vector2i(-512, 512);
mode = VertexLights3DServer::VERTEX_LIGHT_3D_MODE_ADD;
}
};
class VertexLightQuadrant3D {
public:
Vector2i position;
LocalVector<VertexLightData3D *> lights;
VertexLightMap3D *map;
void get_lights(List<VertexLightData3D *> *p_lights);
Color sample_light(const Color &p_current_color, const Vector2 &p_local_position, const int p_item_cull_mask, const int p_layer, const int p_z_index);
VertexLightQuadrant3D() {
map = NULL;
}
};
class VertexLightMap3D : public RID_Data {
public:
HashMap<Vector2i, VertexLightQuadrant3D *> quadrants;
Vector2i quadrant_size;
Color base_color;
RID self;
void recreate_quadrants();
void get_lights(List<VertexLightData3D *> *p_lights);
void add_light(VertexLightData3D *p_light);
void remove_light(VertexLightData3D *p_light);
VertexLightQuadrant3D *get_quadrant_for_position(const Vector2 &p_position);
void set_light_position(VertexLightData3D *p_light, const Vector2 &p_position);
void clear();
Color sample_light(const Vector2 &p_position, const int p_item_cull_mask = 1, const int p_layer = 0, const int p_z_index = 0);
_FORCE_INLINE_ Vector2i to_quadrant_position(const Vector2 &p_position) {
return Vector2i(p_position.x / quadrant_size.x, p_position.y / quadrant_size.y);
}
_FORCE_INLINE_ Vector2 to_position(const Vector2i &p_quadrant_position) {
return Vector2(p_quadrant_position.x * quadrant_size.x, p_quadrant_position.y * quadrant_size.y);
}
};
_FORCE_INLINE_ void _light_changed(const VertexLightData3D *p_light) const {
if (p_light && p_light->enabled && p_light->map) {
_changed_maps.insert(p_light->map->self);
}
}
_FORCE_INLINE_ void _light_enabled_changed(const VertexLightData3D *p_light) const {
if (p_light && p_light->map) {
_changed_maps.insert(p_light->map->self);
}
}
_FORCE_INLINE_ void _map_changed(const VertexLightMap3D *p_map) const {
if (p_map) {
_changed_maps.insert(p_map->self);
}
}
mutable RID_Owner<VertexLightMap3D> map_owner;
mutable RID_Owner<VertexLightData3D> light_owner;
Vector2i _default_quadrant_size;
// Maybe an api could be adde that's per quadrant
mutable HashSet<RID> _changed_maps;
StringName _map_changed_name;
static VertexLights3DServer *_self;
};
VARIANT_ENUM_CAST(VertexLights3DServer::VertexLight3DMode);
#endif