Rework the vertex light 3d module to actually be 3d.

This commit is contained in:
Relintai 2024-03-27 16:02:08 +01:00
parent b2b13bfb80
commit c0805afa6c
9 changed files with 201 additions and 174 deletions

View File

@ -33,7 +33,7 @@
#include "core/config/engine.h"
#include "scene/resources/world_2d.h"
#include "scene/resources/world_3d.h"
bool VertexLight3D::get_is_enabled() {
return _enabled;
@ -44,10 +44,10 @@ void VertexLight3D::set_enabled(const bool p_enabled) {
_update_light_visibility();
}
Vector2i VertexLight3D::get_range() {
real_t VertexLight3D::get_range() {
return _range;
}
void VertexLight3D::set_range(const Vector2i &p_range) {
void VertexLight3D::set_range(const real_t p_range) {
_range = p_range;
VertexLights3DServer::get_singleton()->light_set_range(_vertex_light, _range);
@ -80,24 +80,6 @@ void VertexLight3D::set_mode(const VertexLight3D::VertexLight3DMode 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;
}
@ -111,12 +93,10 @@ VertexLight3D::VertexLight3D() {
_vertex_light = RID_PRIME(VertexLights3DServer::get_singleton()->light_create());
_enabled = true;
_range = Vector2i(32, 32);
_range = 5;
_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);
@ -129,9 +109,9 @@ VertexLight3D::~VertexLight3D() {
void VertexLight3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
Ref<World2D> world = get_world_2d();
Ref<World3D> world = get_world_3d();
ERR_FAIL_COND(!world.is_valid());
RID map = world->get_vertex_lights_2d_map();
RID map = world->get_vertex_lights_3d_map();
VertexLights3DServer::get_singleton()->light_set_map(_vertex_light, map);
VertexLights3DServer::get_singleton()->light_set_position(_vertex_light, get_global_transform().get_origin());
@ -167,7 +147,7 @@ void VertexLight3D::_bind_methods() {
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");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "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);
@ -182,14 +162,6 @@ void VertexLight3D::_bind_methods() {
//,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");

View File

@ -32,7 +32,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "scene/main/node_2d.h"
#include "scene/main/spatial.h"
#include "core/containers/hash_map.h"
#include "core/containers/vector.h"
@ -41,8 +41,8 @@
#include "vertex_lights_3d_server.h"
class VertexLight3D : public Node2D {
GDCLASS(VertexLight3D, Node2D);
class VertexLight3D : public Spatial {
GDCLASS(VertexLight3D, Spatial);
public:
enum VertexLight3DMode {
@ -55,8 +55,8 @@ public:
bool get_is_enabled();
void set_enabled(const bool p_enabled);
Vector2i get_range();
void set_range(const Vector2i &p_range);
real_t get_range();
void set_range(const real_t p_range);
real_t get_attenuation();
void set_attenuation(const real_t p_attenuation);
@ -67,12 +67,6 @@ public:
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);
@ -89,12 +83,10 @@ protected:
RID _vertex_light;
bool _enabled;
Vector2i _range;
real_t _range;
real_t _attenuation;
Color _color;
VertexLight3DMode _mode;
Vector2i _z_range;
Vector2i _layer_range;
int _item_cull_mask;
};

View File

@ -33,7 +33,7 @@
#include "core/config/engine.h"
#include "scene/resources/world_2d.h"
#include "scene/resources/world_3d.h"
#include "vertex_lights_3d_server.h"
@ -78,9 +78,9 @@ void VertexLight3DEnvironment::_update_light_visibility() {
return;
}
Ref<World2D> world = get_world_2d();
Ref<World3D> world = get_world_3d();
ERR_FAIL_COND(!world.is_valid());
RID map = world->get_vertex_lights_2d_map();
RID map = world->get_vertex_lights_3d_map();
VertexLights3DServer::get_singleton()->map_set_base_color(map, _color);
}

View File

@ -32,15 +32,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "scene/main/node_2d.h"
#include "scene/main/spatial.h"
#include "core/containers/hash_map.h"
#include "core/containers/vector.h"
#include "core/math/color.h"
#include "core/math/vector2i.h"
class VertexLight3DEnvironment : public Node2D {
GDCLASS(VertexLight3DEnvironment, Node2D);
class VertexLight3DEnvironment : public Spatial {
GDCLASS(VertexLight3DEnvironment, Spatial);
public:
bool get_is_enabled();

View File

@ -39,17 +39,17 @@ void VertexLights3DServer::VertexLightQuadrant3D::get_lights(List<VertexLightDat
}
}
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 VertexLights3DServer::VertexLightQuadrant3D::sample_light_value(const Color &p_current_color, const Vector3 &p_position, const int p_item_cull_mask) {
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) {
if (l->range == 0) {
continue;
}
@ -57,19 +57,13 @@ Color VertexLights3DServer::VertexLightQuadrant3D::sample_light(const Color &p_c
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);
Vector3 light_to_pos = p_position - l->position;
Vector3 light_to_pos_normal_space = light_to_pos;
light_to_pos_normal_space.x /= l->range;
light_to_pos_normal_space.y /= l->range;
light_to_pos_normal_space.z /= l->range;
real_t ltpnsl = light_to_pos_normal_space.length();
@ -77,7 +71,7 @@ Color VertexLights3DServer::VertexLightQuadrant3D::sample_light(const Color &p_c
if (ltpnsl >= 1) {
continue;
}
real_t attenuation = pow(1.0 - ltpnsl, l->attenuation);
Color ac = l->color * attenuation;
@ -93,10 +87,64 @@ Color VertexLights3DServer::VertexLightQuadrant3D::sample_light(const Color &p_c
c = c.blend(ac);
} break;
}
c = c.clamp();
}
return c;
}
Color VertexLights3DServer::VertexLightQuadrant3D::sample_light(const Color &p_current_color, const Vector3 &p_position, const Vector3 &p_normal, const int p_item_cull_mask) {
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 == 0) {
continue;
}
if ((l->item_cull_mask & p_item_cull_mask) == 0) {
continue;
}
Vector3 light_to_pos = p_position - l->position;
Vector3 light_to_pos_normal_space = light_to_pos;
light_to_pos_normal_space.x /= l->range;
light_to_pos_normal_space.y /= l->range;
light_to_pos_normal_space.z /= l->range;
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;
}
@ -106,7 +154,7 @@ void VertexLights3DServer::VertexLightMap3D::recreate_quadrants() {
List<VertexLightData3D *> lights;
get_lights(&lights);
for (HashMap<Vector2i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
for (HashMap<Vector3i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
memdelete(E->value());
}
@ -119,7 +167,7 @@ void VertexLights3DServer::VertexLightMap3D::recreate_quadrants() {
}
void VertexLights3DServer::VertexLightMap3D::get_lights(List<VertexLightData3D *> *p_lights) {
for (HashMap<Vector2i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
for (HashMap<Vector3i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
E->value()->get_lights(p_lights);
}
}
@ -150,8 +198,8 @@ void VertexLights3DServer::VertexLightMap3D::remove_light(VertexLightData3D *p_l
}
}
VertexLights3DServer::VertexLightQuadrant3D *VertexLights3DServer::VertexLightMap3D::get_quadrant_for_position(const Vector2 &p_position) {
Vector2i quadrant_position = to_quadrant_position(p_position);
VertexLights3DServer::VertexLightQuadrant3D *VertexLights3DServer::VertexLightMap3D::get_quadrant_for_position(const Vector3 &p_position) {
Vector3i quadrant_position = to_quadrant_position(p_position);
if (!quadrants.has(quadrant_position)) {
VertexLightQuadrant3D *quadrant = memnew(VertexLightQuadrant3D);
@ -163,7 +211,7 @@ VertexLights3DServer::VertexLightQuadrant3D *VertexLights3DServer::VertexLightMa
return quadrants[quadrant_position];
}
void VertexLights3DServer::VertexLightMap3D::set_light_position(VertexLightData3D *p_light, const Vector2 &p_position) {
void VertexLights3DServer::VertexLightMap3D::set_light_position(VertexLightData3D *p_light, const Vector3 &p_position) {
remove_light(p_light);
p_light->position = p_position;
add_light(p_light);
@ -173,7 +221,7 @@ void VertexLights3DServer::VertexLightMap3D::clear() {
List<VertexLightData3D *> lights;
get_lights(&lights);
for (HashMap<Vector2i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
for (HashMap<Vector3i, VertexLightQuadrant3D *>::Element *E = quadrants.front(); E; E = E->next) {
memdelete(E->value());
}
@ -187,19 +235,43 @@ void VertexLights3DServer::VertexLightMap3D::clear() {
}
}
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 VertexLights3DServer::VertexLightMap3D::sample_light_value(const Vector3 &p_position, const int p_item_cull_mask) {
Color c = base_color;
Vector2i quadrant_position = to_quadrant_position(p_position);
Vector3i 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);
for (int z = quadrant_position.z - 1; z <= quadrant_position.z + 1; ++z) {
Vector3i qp = Vector3i(x, y, z);
if (quadrants.has(qp)) {
VertexLightQuadrant3D *q = quadrants[qp];
c = q->sample_light(c, p_position, p_item_cull_mask, p_layer, p_z_index);
if (quadrants.has(qp)) {
VertexLightQuadrant3D *q = quadrants[qp];
c = q->sample_light_value(c, p_position, p_item_cull_mask);
}
}
}
}
return c;
}
Color VertexLights3DServer::VertexLightMap3D::sample_light(const Vector3 &p_position, const Vector3 &p_normal, const int p_item_cull_mask) {
Color c = base_color;
Vector3i 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) {
for (int z = quadrant_position.z - 1; z <= quadrant_position.z + 1; ++z) {
Vector3i qp = Vector3i(x, y, z);
if (quadrants.has(qp)) {
VertexLightQuadrant3D *q = quadrants[qp];
c = q->sample_light(c, p_position, p_normal, p_item_cull_mask);
}
}
}
}

View File

@ -36,10 +36,10 @@
#include "scene/main/scene_tree.h"
// Defaults
Vector2i VertexLights3DServer::get_default_quadrant_size() const {
Vector3i VertexLights3DServer::get_default_quadrant_size() const {
return _default_quadrant_size;
}
void VertexLights3DServer::set_default_quadrant_size(const Vector2i &p_size) {
void VertexLights3DServer::set_default_quadrant_size(const Vector3i &p_size) {
_default_quadrant_size = p_size;
}
@ -52,13 +52,13 @@ RID VertexLights3DServer::map_create() {
return rid;
}
Vector2i VertexLights3DServer::map_get_quadrant_size(RID p_map) const {
Vector3i VertexLights3DServer::map_get_quadrant_size(RID p_map) const {
const VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == NULL, Vector2i());
ERR_FAIL_COND_V(map == NULL, Vector3i());
return map->quadrant_size;
}
void VertexLights3DServer::map_set_quadrant_size(RID p_map, const Vector2i &p_size) {
void VertexLights3DServer::map_set_quadrant_size(RID p_map, const Vector3i &p_size) {
VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND(map == NULL);
@ -165,13 +165,13 @@ void VertexLights3DServer::light_set_enabled(RID p_light, const bool p_enabled)
_light_enabled_changed(light);
}
Vector2 VertexLights3DServer::light_get_position(RID p_light) {
Vector3 VertexLights3DServer::light_get_position(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, Vector2());
ERR_FAIL_COND_V(light == NULL, Vector3());
return light->position;
}
void VertexLights3DServer::light_set_position(RID p_light, const Vector2 &p_position) {
void VertexLights3DServer::light_set_position(RID p_light, const Vector3 &p_position) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
@ -187,13 +187,13 @@ void VertexLights3DServer::light_set_position(RID p_light, const Vector2 &p_posi
_light_changed(light);
}
Vector2i VertexLights3DServer::light_get_range(RID p_light) {
real_t VertexLights3DServer::light_get_range(RID p_light) {
const VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(light == NULL, Vector2i());
ERR_FAIL_COND_V(light == NULL, 0);
return light->range;
}
void VertexLights3DServer::light_set_range(RID p_light, const Vector2i &p_range) {
void VertexLights3DServer::light_set_range(RID p_light, const real_t p_range) {
VertexLightData3D *light = light_owner.getornull(p_light);
ERR_FAIL_COND(light == NULL);
@ -247,36 +247,6 @@ void VertexLights3DServer::light_set_mode(RID p_light, const VertexLights3DServe
_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);
@ -294,11 +264,18 @@ void VertexLights3DServer::light_set_item_cull_mask(RID p_light, const int p_ite
// 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) {
Color VertexLights3DServer::sample_light_value(RID p_map, const Vector3 &p_position, const int p_item_cull_mask) {
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);
return map->sample_light_value(p_position, p_item_cull_mask);
}
Color VertexLights3DServer::sample_light(RID p_map, const Vector3 &p_position, const Vector3 &p_normal, const int p_item_cull_mask) {
VertexLightMap3D *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == NULL, Color());
return map->sample_light(p_position, p_normal, p_item_cull_mask);
}
// Rest
@ -368,7 +345,7 @@ VertexLights3DServer::VertexLights3DServer() {
_self = this;
GLOBAL_DEF("vertex_lights_3d/default_quadrant_size", Vector2i(256, 256));
GLOBAL_DEF("vertex_lights_3d/default_quadrant_size", Vector3i(32, 32, 32));
_default_quadrant_size = GLOBAL_GET("vertex_lights_3d/default_quadrant_size");
_map_changed_name = "map_changed";
@ -421,18 +398,13 @@ void VertexLights3DServer::_bind_methods() {
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));
ClassDB::bind_method(D_METHOD("sample_light_value", "map", "position", "item_cull_mask"), &VertexLights3DServer::sample_light_value, DEFVAL(1));
ClassDB::bind_method(D_METHOD("sample_light", "map", "position", "normal", "item_cull_mask"), &VertexLights3DServer::sample_light, DEFVAL(1));
// Rest, DEFVAL(0)

View File

@ -40,7 +40,7 @@
#include "core/containers/rid.h"
#include "core/containers/vector.h"
#include "core/math/color.h"
#include "core/math/vector2i.h"
#include "core/math/vector3i.h"
class VertexLights3DServer : public Object {
GDCLASS(VertexLights3DServer, Object);
@ -55,15 +55,15 @@ public:
// Defaults
Vector2i get_default_quadrant_size() const;
void set_default_quadrant_size(const Vector2i &p_size);
Vector3i get_default_quadrant_size() const;
void set_default_quadrant_size(const Vector3i &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);
Vector3i map_get_quadrant_size(RID p_map) const;
void map_set_quadrant_size(RID p_map, const Vector3i &p_size);
Color map_get_base_color(RID p_map) const;
void map_set_base_color(RID p_map, const Color &p_base_color);
@ -82,11 +82,11 @@ public:
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);
Vector3 light_get_position(RID p_light);
void light_set_position(RID p_light, const Vector3 &p_position);
Vector2i light_get_range(RID p_light);
void light_set_range(RID p_light, const Vector2i &p_range);
real_t light_get_range(RID p_light);
void light_set_range(RID p_light, const real_t p_range);
real_t light_get_attenuation(RID p_light);
void light_set_attenuation(RID p_light, const real_t p_attenuation);
@ -97,18 +97,13 @@ public:
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);
Color sample_light_value(RID p_map, const Vector3 &p_position, const int p_item_cull_mask = 1);
Color sample_light(RID p_map, const Vector3 &p_position, const Vector3 &p_normal, const int p_item_cull_mask = 1);
// Rest
@ -137,13 +132,11 @@ protected:
class VertexLightData3D : public RID_Data {
public:
bool enabled;
Vector2 position;
Vector2i range;
Vector3 position;
real_t range;
real_t attenuation;
Color color;
VertexLights3DServer::VertexLight3DMode mode;
Vector2i z_range;
Vector2i layer_range;
int item_cull_mask;
VertexLightMap3D *map;
@ -156,26 +149,25 @@ protected:
quadrant = NULL;
enabled = true;
range = Vector2i(32, 32);
range = 5;
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;
Vector3i 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);
Color sample_light_value(const Color &p_current_color, const Vector3 &p_position, const int p_item_cull_mask);
Color sample_light(const Color &p_current_color, const Vector3 &p_position, const Vector3 &p_normal, const int p_item_cull_mask);
VertexLightQuadrant3D() {
map = NULL;
@ -184,8 +176,8 @@ protected:
class VertexLightMap3D : public RID_Data {
public:
HashMap<Vector2i, VertexLightQuadrant3D *> quadrants;
Vector2i quadrant_size;
HashMap<Vector3i, VertexLightQuadrant3D *> quadrants;
Vector3i quadrant_size;
Color base_color;
RID self;
@ -197,20 +189,21 @@ protected:
void add_light(VertexLightData3D *p_light);
void remove_light(VertexLightData3D *p_light);
VertexLightQuadrant3D *get_quadrant_for_position(const Vector2 &p_position);
VertexLightQuadrant3D *get_quadrant_for_position(const Vector3 &p_position);
void set_light_position(VertexLightData3D *p_light, const Vector2 &p_position);
void set_light_position(VertexLightData3D *p_light, const Vector3 &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);
Color sample_light_value(const Vector3 &p_position, const int p_item_cull_mask);
Color sample_light(const Vector3 &p_position, const Vector3 &p_normal, const int p_item_cull_mask);
_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_ Vector3i to_quadrant_position(const Vector3 &p_position) {
return Vector3i(p_position.x / quadrant_size.x, p_position.y / quadrant_size.y, p_position.z / quadrant_size.z);
}
_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_ Vector3 to_position(const Vector3i &p_quadrant_position) {
return Vector3(p_quadrant_position.x * quadrant_size.x, p_quadrant_position.y * quadrant_size.y, p_quadrant_position.z * quadrant_size.z);
}
};
@ -235,7 +228,7 @@ protected:
mutable RID_Owner<VertexLightMap3D> map_owner;
mutable RID_Owner<VertexLightData3D> light_owner;
Vector2i _default_quadrant_size;
Vector3i _default_quadrant_size;
// Maybe an api could be adde that's per quadrant
mutable HashSet<RID> _changed_maps;

View File

@ -39,6 +39,12 @@
#include "scene/main/scene_string_names.h"
#include "servers/navigation_server.h"
#include "modules/modules_enabled.gen.h"
#ifdef MODULE_VERTEX_LIGHTS_3D_ENABLED
#include "modules/vertex_lights_3d/vertex_lights_3d_server.h"
#endif
struct SpatialIndexer {
Octree<VisibilityNotifier> octree;
@ -267,6 +273,10 @@ RID World3D::get_navigation_map() const {
return navigation_map;
}
RID World3D::get_vertex_lights_3d_map() {
return vertex_lights_3d_map;
}
void World3D::set_environment(const Ref<Environment3D> &p_environment) {
if (environment == p_environment) {
return;
@ -333,23 +343,31 @@ void World3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space);
ClassDB::bind_method(D_METHOD("get_scenario"), &World3D::get_scenario);
ClassDB::bind_method(D_METHOD("get_navigation_map"), &World3D::get_navigation_map);
ClassDB::bind_method(D_METHOD("get_vertex_lights_3d_map"), &World3D::get_vertex_lights_3d_map);
ClassDB::bind_method(D_METHOD("set_environment", "env"), &World3D::set_environment);
ClassDB::bind_method(D_METHOD("get_environment"), &World3D::get_environment);
ClassDB::bind_method(D_METHOD("set_fallback_environment", "env"), &World3D::set_fallback_environment);
ClassDB::bind_method(D_METHOD("get_fallback_environment"), &World3D::get_fallback_environment);
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World3D::get_direct_space_state);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment3D"), "set_environment", "get_environment");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment3D"), "set_fallback_environment", "get_fallback_environment");
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
ADD_PROPERTY(PropertyInfo(Variant::RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario");
ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState", 0), "", "get_direct_space_state");
ADD_PROPERTY(PropertyInfo(Variant::RID, "vertex_lights_3d_map", PROPERTY_HINT_NONE, "", 0), "", "get_vertex_lights_3d_map");
}
World3D::World3D() {
space = RID_PRIME(PhysicsServer::get_singleton()->space_create());
scenario = RID_PRIME(RenderingServer::get_singleton()->scenario_create());
#ifdef MODULE_VERTEX_LIGHTS_3D_ENABLED
vertex_lights_3d_map = RID_PRIME(VertexLights3DServer::get_singleton()->map_create());
#endif
PhysicsServer::get_singleton()->space_set_active(space, true);
PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/3d/default_gravity", 9.8));
PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/3d/default_gravity_vector", Vector3(0, -1, 0)));
@ -380,6 +398,10 @@ World3D::~World3D() {
RenderingServer::get_singleton()->free(scenario);
NavigationServer::get_singleton()->free(navigation_map);
#ifdef MODULE_VERTEX_LIGHTS_3D_ENABLED
VertexLights3DServer::get_singleton()->free(vertex_lights_3d_map);
#endif
#ifndef _3D_DISABLED
memdelete(indexer);
#endif

View File

@ -49,6 +49,7 @@ private:
RID space;
RID scenario;
RID navigation_map;
RID vertex_lights_3d_map;
SpatialIndexer *indexer;
Ref<Environment3D> environment;
Ref<Environment3D> fallback_environment;
@ -74,6 +75,9 @@ public:
RID get_space() const;
RID get_scenario() const;
RID get_navigation_map() const;
// TODO Maybe World should have a callback on creation?
RID get_vertex_lights_3d_map();
void set_environment(const Ref<Environment3D> &p_environment);
Ref<Environment3D> get_environment() const;