mirror of
https://github.com/Relintai/voxelman.git
synced 2024-11-12 10:15:12 +01:00
Implemented Ao generation, and started working on light support.
This commit is contained in:
parent
370702cc1e
commit
7f0a832677
@ -1,16 +1,82 @@
|
||||
#include "voxel_light.h"
|
||||
|
||||
VoxelLight::VoxelLight() {
|
||||
int VoxelLight::get_chunk_position_x() {
|
||||
return _chunk_position.x;
|
||||
}
|
||||
int VoxelLight::get_chunk_position_y() {
|
||||
return _chunk_position.y;
|
||||
}
|
||||
int VoxelLight::get_chunk_position_z() {
|
||||
return _chunk_position.z;
|
||||
}
|
||||
Vector3i VoxelLight::get_chunk_position() {
|
||||
return _chunk_position;
|
||||
}
|
||||
void VoxelLight::set_chunk_position(int x, int y, int z) {
|
||||
_chunk_position.x = x;
|
||||
_chunk_position.y = y;
|
||||
_chunk_position.z = z;
|
||||
}
|
||||
|
||||
VoxelLight::VoxelLight(Vector3i position, Color color, float strength, Vector3 WorldPosition, Vector3 offset) {
|
||||
int VoxelLight::get_world_position_x() {
|
||||
return _world_position.x;
|
||||
}
|
||||
int VoxelLight::get_world_position_y() {
|
||||
return _world_position.y;
|
||||
}
|
||||
int VoxelLight::get_world_position_z() {
|
||||
return _world_position.z;
|
||||
}
|
||||
Vector3i VoxelLight::get_world_position() {
|
||||
return _world_position;
|
||||
|
||||
_world_position = WorldPosition + offset;
|
||||
_local_position = position;
|
||||
_offset = offset;
|
||||
_color = color;
|
||||
_strength = strength;
|
||||
}
|
||||
void VoxelLight::set_world_position(int x, int y, int z) {
|
||||
_world_position.x = x;
|
||||
_world_position.y = y;
|
||||
_world_position.z = z;
|
||||
}
|
||||
|
||||
Color VoxelLight::get_color() {
|
||||
return _color;
|
||||
|
||||
}
|
||||
void VoxelLight::set_color(Color color) {
|
||||
_color = color;
|
||||
|
||||
}
|
||||
|
||||
float VoxelLight::get_size() {
|
||||
return _size;
|
||||
|
||||
}
|
||||
void VoxelLight::set_size(float size) {
|
||||
_size = size;
|
||||
}
|
||||
|
||||
VoxelLight::VoxelLight() {
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
VoxelLight::~VoxelLight() {
|
||||
}
|
||||
|
||||
void VoxelLight::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_chunk_position_x"), &VoxelLight::get_chunk_position_x);
|
||||
ClassDB::bind_method(D_METHOD("get_chunk_position_y"), &VoxelLight::get_chunk_position_y);
|
||||
ClassDB::bind_method(D_METHOD("get_chunk_position_z"), &VoxelLight::get_chunk_position_z);
|
||||
ClassDB::bind_method(D_METHOD("set_chunk_position", "x", "y", "z"), &VoxelLight::set_chunk_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_world_position_x"), &VoxelLight::get_world_position_x);
|
||||
ClassDB::bind_method(D_METHOD("get_world_position_y"), &VoxelLight::get_world_position_y);
|
||||
ClassDB::bind_method(D_METHOD("get_world_position_z"), &VoxelLight::get_world_position_z);
|
||||
ClassDB::bind_method(D_METHOD("set_world_position", "x", "y", "z"), &VoxelLight::set_world_position);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_color"), &VoxelLight::get_color);
|
||||
ClassDB::bind_method(D_METHOD("set_color"), &VoxelLight::set_color);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_size"), &VoxelLight::get_size);
|
||||
ClassDB::bind_method(D_METHOD("set_size"), &VoxelLight::set_size);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "size"), "set_size", "get_size");
|
||||
}
|
||||
|
@ -11,34 +11,35 @@ class VoxelLight : public Reference {
|
||||
GDCLASS(VoxelLight, Reference);
|
||||
|
||||
public:
|
||||
Vector3i get_local_position() { return _local_position; }
|
||||
void set_local_position(Vector3i neighbours) { _local_position = neighbours; }
|
||||
int get_chunk_position_x();
|
||||
int get_chunk_position_y();
|
||||
int get_chunk_position_z();
|
||||
Vector3i get_chunk_position();
|
||||
void set_chunk_position(int x, int y, int z);
|
||||
|
||||
Vector3 get_world_position() { return _world_position; }
|
||||
void set_world_position(Vector3 world_position) { _world_position = world_position; }
|
||||
int get_world_position_x();
|
||||
int get_world_position_y();
|
||||
int get_world_position_z();
|
||||
Vector3i get_world_position();
|
||||
void set_world_position(int x, int y, int z);
|
||||
|
||||
Vector3 get_offset() { return _offset; }
|
||||
void set_offset(Vector3 offset) { _offset = offset; }
|
||||
Color get_color();
|
||||
void set_color(Color color);
|
||||
|
||||
Color get_color() { return _color; }
|
||||
void set_color(Color color) { _color = color; }
|
||||
|
||||
float get_strength() { return _strength; }
|
||||
void set_strength(float strength) { _strength = strength; }
|
||||
float get_size();
|
||||
void set_size(float strength);
|
||||
|
||||
VoxelLight();
|
||||
VoxelLight(Vector3i position, Color color, float strength, Vector3 WorldPosition, Vector3 offset);
|
||||
~VoxelLight();
|
||||
|
||||
private:
|
||||
static void _bind_methods() {}
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
Vector3i _local_position;
|
||||
Vector3 _world_position;
|
||||
Vector3 _offset;
|
||||
Vector3i _chunk_position;
|
||||
Vector3i _world_position;
|
||||
Color _color;
|
||||
float _strength;
|
||||
int _size;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -428,6 +428,15 @@ void VoxelCubePoints::setup(const Ref<VoxelBuffer> buffer, int x, int y, int z,
|
||||
_point_fills[P101] = buffer->get_voxel(x + size, y, z + size, VoxelBuffer::CHANNEL_ISOLEVEL);
|
||||
_point_fills[P111] = buffer->get_voxel(x + size, y + size, z + size, VoxelBuffer::CHANNEL_ISOLEVEL);
|
||||
|
||||
_point_aos[P000] = buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_AO);
|
||||
_point_aos[P100] = buffer->get_voxel(x + size, y, z, VoxelBuffer::CHANNEL_AO);
|
||||
_point_aos[P010] = buffer->get_voxel(x, y + size, z, VoxelBuffer::CHANNEL_AO);
|
||||
_point_aos[P001] = buffer->get_voxel(x, y, z + size, VoxelBuffer::CHANNEL_AO);
|
||||
_point_aos[P110] = buffer->get_voxel(x + size, y + size, z, VoxelBuffer::CHANNEL_AO);
|
||||
_point_aos[P011] = buffer->get_voxel(x, y + size, z + size, VoxelBuffer::CHANNEL_AO);
|
||||
_point_aos[P101] = buffer->get_voxel(x + size, y, z + size, VoxelBuffer::CHANNEL_AO);
|
||||
_point_aos[P111] = buffer->get_voxel(x + size, y + size, z + size, VoxelBuffer::CHANNEL_AO);
|
||||
|
||||
refresh_neighbours(buffer);
|
||||
|
||||
refresh_points();
|
||||
@ -564,6 +573,18 @@ int VoxelCubePoints::get_point_neighbours(int index) {
|
||||
return _point_neighbours[index];
|
||||
}
|
||||
|
||||
int VoxelCubePoints::get_point_ao(int index) {
|
||||
ERR_FAIL_INDEX_V(index, POINT_COUNT, 0);
|
||||
|
||||
return _point_aos[index];
|
||||
}
|
||||
|
||||
int VoxelCubePoints::get_face_point_ao(int face, int index) {
|
||||
int indx = get_point_index(face, index);
|
||||
|
||||
return _point_aos[indx];
|
||||
}
|
||||
|
||||
Vector3 VoxelCubePoints::get_point(int index) {
|
||||
ERR_FAIL_INDEX_V(index, POINT_COUNT, Vector3());
|
||||
|
||||
@ -730,6 +751,9 @@ void VoxelCubePoints::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_point_fill", "index"), &VoxelCubePoints::get_point_fill);
|
||||
ClassDB::bind_method(D_METHOD("get_point_neighbours", "index"), &VoxelCubePoints::get_point_neighbours);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_point_ao", "index"), &VoxelCubePoints::get_point_ao);
|
||||
ClassDB::bind_method(D_METHOD("get_face_point_ao", "face", "index"), &VoxelCubePoints::get_face_point_ao);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_point", "index"), &VoxelCubePoints::get_point);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_top_left_point", "face"), &VoxelCubePoints::get_top_left_point);
|
||||
|
@ -114,6 +114,9 @@ public:
|
||||
int get_point_fill(int index);
|
||||
int get_point_neighbours(int index);
|
||||
|
||||
int get_point_ao(int index);
|
||||
int get_face_point_ao(int face, int index);
|
||||
|
||||
Vector3 get_point(int index);
|
||||
Vector3 get_top_left_point(int face);
|
||||
Vector3 get_top_right_point(int face);
|
||||
@ -140,6 +143,7 @@ private:
|
||||
|
||||
uint8_t _point_types[POINT_COUNT];
|
||||
uint8_t _point_fills[POINT_COUNT];
|
||||
uint8_t _point_aos[POINT_COUNT];
|
||||
unsigned int _point_neighbours[POINT_COUNT];
|
||||
|
||||
int _size;
|
||||
|
@ -284,6 +284,60 @@ uint8_t *VoxelBuffer::get_channel_raw(unsigned int channel_index) const {
|
||||
return channel.data;
|
||||
}
|
||||
|
||||
void VoxelBuffer::generate_ao() {
|
||||
unsigned int size_x = _size.x;
|
||||
unsigned int size_y = _size.y;
|
||||
unsigned int size_z = _size.z;
|
||||
|
||||
ERR_FAIL_COND(size_x == 0 || size_y == 0 || size_z == 0);
|
||||
|
||||
for (unsigned int y = 1; y < size_y - 1; ++y) {
|
||||
for (unsigned int z = 1; z < size_z - 1; ++z) {
|
||||
for (unsigned int x = 1; x < size_x - 1; ++x) {
|
||||
int current = get_voxel(x, y, z, CHANNEL_ISOLEVEL);
|
||||
|
||||
int sum = get_voxel(x + 1, y, z, CHANNEL_ISOLEVEL);
|
||||
sum += get_voxel(x - 1, y, z, CHANNEL_ISOLEVEL);
|
||||
sum += get_voxel(x, y + 1, z, CHANNEL_ISOLEVEL);
|
||||
sum += get_voxel(x, y - 1, z, CHANNEL_ISOLEVEL);
|
||||
sum += get_voxel(x, y, z + 1, CHANNEL_ISOLEVEL);
|
||||
sum += get_voxel(x, y, z - 1, CHANNEL_ISOLEVEL);
|
||||
|
||||
sum /= 6;
|
||||
|
||||
sum -= current;
|
||||
|
||||
if (sum < 0)
|
||||
sum = 0;
|
||||
|
||||
set_voxel(sum, x, y, z, CHANNEL_AO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelBuffer::add_light(int local_x, int local_y, int local_z, int size, Color color){
|
||||
VoxelBufferLight l;
|
||||
|
||||
l.x = local_x;
|
||||
l.y = local_y;
|
||||
l.z = local_z;
|
||||
l.color = color;
|
||||
l.size = size;
|
||||
|
||||
_lights.push_back(l);
|
||||
}
|
||||
void VoxelBuffer::remove_light(int local_x, int local_y, int local_z) {
|
||||
for (int i = 0; i < _lights.size(); ++i) {
|
||||
VoxelBufferLight l = _lights.get(i);
|
||||
|
||||
if (l.x == local_x && l.y == local_y && l-z == local_z) {
|
||||
_lights.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelBuffer::create_channel(int i, Vector3i size, uint8_t defval) {
|
||||
create_channel_noinit(i, size);
|
||||
memset(_channels[i].data, defval, get_volume() * sizeof(uint8_t));
|
||||
@ -327,6 +381,11 @@ void VoxelBuffer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("is_uniform", "channel"), &VoxelBuffer::is_uniform);
|
||||
ClassDB::bind_method(D_METHOD("optimize"), &VoxelBuffer::compress_uniform_channels);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("generate_ao"), &VoxelBuffer::generate_ao);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_light", "local_x", "local_y", "local_z", "size", "color"), &VoxelBuffer::add_light);
|
||||
ClassDB::bind_method(D_METHOD("remove_light", "local_x", "local_y", "local_z"), &VoxelBuffer::remove_light);
|
||||
|
||||
BIND_ENUM_CONSTANT(CHANNEL_TYPE);
|
||||
BIND_ENUM_CONSTANT(CHANNEL_ISOLEVEL);
|
||||
BIND_ENUM_CONSTANT(CHANNEL_LIGHT_COLOR_R);
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
CHANNEL_LIGHT_COLOR_R,
|
||||
CHANNEL_LIGHT_COLOR_G,
|
||||
CHANNEL_LIGHT_COLOR_B,
|
||||
CHANNEL_AO,
|
||||
CHANNEL_DATA1,
|
||||
CHANNEL_DATA2,
|
||||
// Arbitrary value, 8 should be enough. Tweak for your needs.
|
||||
@ -122,6 +123,10 @@ public:
|
||||
|
||||
uint8_t *get_channel_raw(unsigned int channel_index) const;
|
||||
|
||||
void generate_ao();
|
||||
void add_light(int local_x, int local_y, int local_z, int size, Color color);
|
||||
void remove_light(int local_x, int local_y, int local_z);
|
||||
|
||||
private:
|
||||
void create_channel_noinit(int i, Vector3i size);
|
||||
void create_channel(int i, Vector3i size, uint8_t defval);
|
||||
@ -142,6 +147,14 @@ protected:
|
||||
_FORCE_INLINE_ void _fill_area_binding(int defval, Vector3 min, Vector3 max, unsigned int channel_index) { fill_area(defval, Vector3i(min), Vector3i(max), channel_index); }
|
||||
_FORCE_INLINE_ void _set_voxel_f_binding(real_t value, int x, int y, int z, unsigned int channel) { set_voxel_f(value, x, y, z, channel); }
|
||||
|
||||
struct VoxelBufferLight {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
Color _color;
|
||||
int _size;
|
||||
};
|
||||
|
||||
private:
|
||||
struct Channel {
|
||||
// Allocated when the channel is populated.
|
||||
@ -162,6 +175,8 @@ private:
|
||||
|
||||
// How many voxels are there in the three directions. All populated channels have the same size.
|
||||
Vector3i _size;
|
||||
|
||||
Vector<VoxelBufferLight> _lights;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(VoxelBuffer::ChannelId)
|
||||
|
Loading…
Reference in New Issue
Block a user