mirror of
https://github.com/Relintai/voxelman.git
synced 2024-11-12 10:15:12 +01:00
Fixed the voxel mesher, and converted it to c++. Also small bugfixes, and binding improvements. ALso moved a few export variables from GDscript to bindings.
This commit is contained in:
parent
e4e38c0bde
commit
469773a9fd
@ -18,6 +18,15 @@ const unsigned int VoxelCubePoints::visibility_check_table[6] = {
|
||||
VOXEL_NEIGHBOUR_BOTTOM //VOXEL_FACE_BOTTOM 5
|
||||
};
|
||||
|
||||
const int VoxelCubePoints::face_light_direction_table[6][3] = {
|
||||
{ 0, 0, -1 }, //VOXEL_FACE_FRONT 0
|
||||
{ -1, 0, 0 }, //VOXEL_FACE_RIGHT 1
|
||||
{ 0, 0, 1 }, //VOXEL_FACE_BACK 2
|
||||
{ 1, 0, 0 }, //VOXEL_FACE_LEFT 3
|
||||
{ 0, -1, 0 }, //VOXEL_FACE_TOP 4
|
||||
{ 0, 1, 0 } //VOXEL_FACE_BOTTOM 5
|
||||
};
|
||||
|
||||
const float VoxelCubePoints::point_direction_table[8][3] = {
|
||||
{ -0.5, -0.5, -0.5 }, //P000
|
||||
{ 0.5, -0.5, -0.5 }, //P100
|
||||
@ -615,6 +624,12 @@ Color VoxelCubePoints::get_face_point_color_mixed(int face, int index) {
|
||||
return _point_colors[indx] - Color(ao_value, ao_value, ao_value);
|
||||
}
|
||||
|
||||
Vector3 VoxelCubePoints::get_face_light_direction(int face) {
|
||||
ERR_FAIL_INDEX_V(face, VOXEL_FACE_COUNT, Vector3());
|
||||
|
||||
return Vector3(face_light_direction_table[face][0], face_light_direction_table[face][1], face_light_direction_table[face][2]);
|
||||
}
|
||||
|
||||
Vector3 VoxelCubePoints::get_point(int index) {
|
||||
ERR_FAIL_INDEX_V(index, POINT_COUNT, Vector3());
|
||||
|
||||
@ -787,6 +802,8 @@ void VoxelCubePoints::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_face_point_light_color", "face", "index"), &VoxelCubePoints::get_face_point_light_color);
|
||||
ClassDB::bind_method(D_METHOD("get_face_point_color_mixed", "face", "index"), &VoxelCubePoints::get_face_point_color_mixed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_face_light_direction", "face"), &VoxelCubePoints::get_face_light_direction);
|
||||
|
||||
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);
|
||||
|
@ -113,13 +113,15 @@ public:
|
||||
int get_point_type(int index);
|
||||
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);
|
||||
Color get_face_point_ao_color(int face, int index);
|
||||
Color get_face_point_light_color(int face, int index);
|
||||
Color get_face_point_color_mixed(int face, int index);
|
||||
|
||||
Vector3 get_face_light_direction(int face);
|
||||
|
||||
Vector3 get_point(int index);
|
||||
Vector3 get_top_left_point(int face);
|
||||
Vector3 get_top_right_point(int face);
|
||||
@ -137,6 +139,7 @@ protected:
|
||||
|
||||
static const unsigned int index_table[6][4];
|
||||
static const unsigned int visibility_check_table[6];
|
||||
static const int face_light_direction_table[6][3];
|
||||
static const float point_direction_table[8][3];
|
||||
static const unsigned int point_direction_neighbour_table[8][3];
|
||||
static const float uv_direction_table[8][4][2];
|
||||
|
@ -1,10 +1,102 @@
|
||||
#include "voxel_mesher_cubic.h"
|
||||
|
||||
float VoxelMesherCubic::get_ao_strength() const {
|
||||
return _ao_strength;
|
||||
}
|
||||
void VoxelMesherCubic::set_ao_strength(float value) {
|
||||
_ao_strength = value;
|
||||
}
|
||||
|
||||
void VoxelMesherCubic::_add_buffer(Ref<VoxelBuffer> buffer) {
|
||||
buffer->generate_ao();
|
||||
|
||||
Vector3i bfs = buffer->get_size();
|
||||
int x_size = bfs.x - 1;
|
||||
int y_size = bfs.y - 1;
|
||||
int z_size = bfs.z - 1;
|
||||
|
||||
float lod_size = get_lod_size();
|
||||
float voxel_size = get_lod_size();
|
||||
float voxel_scale = get_voxel_scale();
|
||||
|
||||
Ref<VoxelCubePoints> cube_points;
|
||||
cube_points.instance();
|
||||
|
||||
float tile_uv_size = 1 / 4.0;
|
||||
Color base_light(0.4, 0.4, 0.4);
|
||||
|
||||
for (int y = lod_size; y < y_size - lod_size; y += lod_size) {
|
||||
for (int z = lod_size; z < z_size - lod_size; z += lod_size) {
|
||||
for (int x = lod_size; x < x_size - lod_size; x += lod_size) {
|
||||
|
||||
cube_points->setup(buffer, x, y, z, lod_size);
|
||||
|
||||
if (!cube_points->has_points())
|
||||
continue;
|
||||
|
||||
for (int face = 0; face < VoxelCubePoints::VOXEL_FACE_COUNT; ++face) {
|
||||
if (!cube_points->is_face_visible(face))
|
||||
continue;
|
||||
|
||||
add_indices(get_vertex_count() + 2);
|
||||
add_indices(get_vertex_count() + 1);
|
||||
add_indices(get_vertex_count() + 0);
|
||||
add_indices(get_vertex_count() + 3);
|
||||
add_indices(get_vertex_count() + 2);
|
||||
add_indices(get_vertex_count() + 0);
|
||||
|
||||
Vector3 vertices[4] = {
|
||||
cube_points->get_point_for_face(face, 0),
|
||||
cube_points->get_point_for_face(face, 1),
|
||||
cube_points->get_point_for_face(face, 2),
|
||||
cube_points->get_point_for_face(face, 3)
|
||||
};
|
||||
|
||||
Vector3 normals[4] = {
|
||||
(vertices[3] - vertices[0]).cross(vertices[1] - vertices[0]),
|
||||
(vertices[0] - vertices[1]).cross(vertices[2] - vertices[1]),
|
||||
(vertices[1] - vertices[2]).cross(vertices[3] - vertices[2]),
|
||||
(vertices[2] - vertices[3]).cross(vertices[0] - vertices[3])
|
||||
};
|
||||
|
||||
Vector3 face_light_direction = cube_points->get_face_light_direction(face);
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Color light = cube_points->get_face_point_light_color(face, i);
|
||||
light += base_light;
|
||||
|
||||
float NdotL = CLAMP(normals[i].dot(face_light_direction), 0, 1.0);
|
||||
|
||||
light *= NdotL;
|
||||
|
||||
light -= cube_points->get_face_point_ao_color(face, i) * _ao_strength;
|
||||
add_color(light);
|
||||
|
||||
light.r = CLAMP(light.r, 0, 1.0);
|
||||
light.g = CLAMP(light.g, 0, 1.0);
|
||||
light.b = CLAMP(light.b, 0, 1.0);
|
||||
|
||||
add_uv((cube_points->get_point_uv_direction(face, i) + Vector2(0.5, 0.5)) * Vector2(tile_uv_size, tile_uv_size));
|
||||
|
||||
add_vertex((vertices[i] * voxel_size + Vector3(x, y, z)) * voxel_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VoxelMesherCubic::VoxelMesherCubic() {
|
||||
_ao_strength = 0.25;
|
||||
}
|
||||
|
||||
VoxelMesherCubic::~VoxelMesherCubic() {
|
||||
}
|
||||
|
||||
void VoxelMesherCubic::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_add_buffer", "buffer"), &VoxelMesherCubic::_add_buffer);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_ao_strength"), &VoxelMesherCubic::get_ao_strength);
|
||||
ClassDB::bind_method(D_METHOD("set_ao_strength", "value"), &VoxelMesherCubic::set_ao_strength);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ao_strength"), "set_ao_strength", "get_ao_strength");
|
||||
}
|
||||
|
@ -1,18 +1,31 @@
|
||||
#ifndef VOXEL_MESHER_CUBIC_H
|
||||
#define VOXEL_MESHER_CUBIC_H
|
||||
|
||||
#include "core/color.h"
|
||||
#include "core/math/vector3.h"
|
||||
#include "core/math/vector2.h"
|
||||
|
||||
#include "../voxel_mesher.h"
|
||||
|
||||
#include "voxel_cube_points.h"
|
||||
|
||||
class VoxelMesherCubic : public VoxelMesher {
|
||||
GDCLASS(VoxelMesherCubic, VoxelMesher);
|
||||
|
||||
public:
|
||||
float get_ao_strength() const;
|
||||
void set_ao_strength(float value);
|
||||
|
||||
void _add_buffer(Ref<VoxelBuffer> buffer);
|
||||
|
||||
VoxelMesherCubic();
|
||||
~VoxelMesherCubic();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
float _ao_strength;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -3,19 +3,18 @@
|
||||
VoxelMesher::VoxelMesher(Ref<VoxelmanLibrary> library) {
|
||||
_library = library;
|
||||
|
||||
_debug_voxel_face = false;
|
||||
size = (float)1;
|
||||
vertexOffset = Vector3((float)0.5, (float)0.5, (float)0.5);
|
||||
_voxel_scale = 1;
|
||||
_lod_size = 1;
|
||||
|
||||
_surface_tool = memnew(SurfaceTool());
|
||||
_surface_tool.instance();
|
||||
}
|
||||
|
||||
VoxelMesher::VoxelMesher() {
|
||||
_debug_voxel_face = false;
|
||||
size = (float)1;
|
||||
vertexOffset = Vector3((float)0.5, (float)0.5, (float)0.5);
|
||||
|
||||
_surface_tool = memnew(SurfaceTool());
|
||||
_voxel_scale = 1;
|
||||
_lod_size = 1;
|
||||
|
||||
_surface_tool.instance();
|
||||
}
|
||||
|
||||
VoxelMesher::~VoxelMesher() {
|
||||
@ -26,7 +25,7 @@ VoxelMesher::~VoxelMesher() {
|
||||
_indices.clear();
|
||||
_bones.clear();
|
||||
|
||||
memdelete(_surface_tool);
|
||||
_surface_tool.unref();
|
||||
|
||||
if (_library.is_valid()) {
|
||||
_library.unref();
|
||||
@ -59,7 +58,9 @@ Ref<ArrayMesh> VoxelMesher::build_mesh() {
|
||||
_surface_tool->add_index(_indices.get(i));
|
||||
}
|
||||
|
||||
_surface_tool->generate_normals();
|
||||
if (_normals.size() == 0) {
|
||||
_surface_tool->generate_normals();
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> m = _surface_tool->commit();
|
||||
|
||||
@ -81,6 +82,20 @@ void VoxelMesher::add_buffer(Ref<VoxelBuffer> voxels) {
|
||||
call("_add_buffer", voxels);
|
||||
}
|
||||
|
||||
float VoxelMesher::get_voxel_scale() const {
|
||||
return _voxel_scale;
|
||||
}
|
||||
void VoxelMesher::set_voxel_scale(const float voxel_scale) {
|
||||
_voxel_scale = voxel_scale;
|
||||
}
|
||||
|
||||
int VoxelMesher::get_lod_size() const {
|
||||
return _lod_size;
|
||||
}
|
||||
void VoxelMesher::set_lod_size(const int lod_size) {
|
||||
_lod_size = lod_size;
|
||||
}
|
||||
|
||||
void VoxelMesher::create_trimesh_shape(Ref<ConcavePolygonShape> shape) const {
|
||||
if (_vertices.size() == 0)
|
||||
return;
|
||||
@ -89,8 +104,6 @@ void VoxelMesher::create_trimesh_shape(Ref<ConcavePolygonShape> shape) const {
|
||||
|
||||
if (_indices.size() == 0) {
|
||||
|
||||
//face_points.resize(_vertices.size());
|
||||
|
||||
int len = (_vertices.size() / 4);
|
||||
|
||||
for (int i = 0; i < len; ++i) {
|
||||
@ -310,6 +323,14 @@ void VoxelMesher::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_buffer", "buffer"), &VoxelMesher::add_buffer);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_voxel_scale"), &VoxelMesher::get_voxel_scale);
|
||||
ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &VoxelMesher::set_voxel_scale);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_lod_size"), &VoxelMesher::get_lod_size);
|
||||
ClassDB::bind_method(D_METHOD("set_lod_size", "value"), &VoxelMesher::set_lod_size);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_size"), "set_lod_size", "get_lod_size");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_library"), &VoxelMesher::get_library);
|
||||
ClassDB::bind_method(D_METHOD("set_library", "value"), &VoxelMesher::set_library);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "library"), "set_library", "get_library");
|
||||
|
@ -36,6 +36,12 @@ public:
|
||||
|
||||
void add_buffer(Ref<VoxelBuffer> voxels);
|
||||
|
||||
float get_voxel_scale() const;
|
||||
void set_voxel_scale(const float voxel_scale);
|
||||
|
||||
int get_lod_size() const;
|
||||
void set_lod_size(const int lod_size);
|
||||
|
||||
void create_trimesh_shape(Ref<ConcavePolygonShape> shape) const;
|
||||
void bake_lights(MeshInstance *node, Vector<Ref<VoxelLight> > &lights);
|
||||
|
||||
@ -87,11 +93,10 @@ protected:
|
||||
|
||||
Ref<VoxelmanLibrary> _library;
|
||||
|
||||
float size;
|
||||
Vector3 vertexOffset;
|
||||
bool _debug_voxel_face;
|
||||
float _voxel_scale;
|
||||
int _lod_size;
|
||||
|
||||
SurfaceTool *_surface_tool;
|
||||
Ref<SurfaceTool> _surface_tool;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -323,9 +323,9 @@ void VoxelBuffer::add_light(int local_x, int local_y, int local_z, int size, Col
|
||||
int size_z = _size.z;
|
||||
|
||||
float sizef = static_cast<float>(size);
|
||||
float rf = (color.r / sizef);
|
||||
float gf = (color.g / sizef);
|
||||
float bf = (color.b / sizef);
|
||||
//float rf = (color.r / sizef);
|
||||
//float gf = (color.g / sizef);
|
||||
//float bf = (color.b / sizef);
|
||||
|
||||
for (int y = local_y - size; y <= local_y + size; ++y) {
|
||||
if (y < 0 || y > size_y)
|
||||
@ -339,11 +339,19 @@ void VoxelBuffer::add_light(int local_x, int local_y, int local_z, int size, Col
|
||||
if (x < 0 || x > size_x)
|
||||
continue;
|
||||
|
||||
float len = (Math::sqrt((real_t)x * x + y * y + z * z)) / sizef;
|
||||
int lx = x - local_x;
|
||||
int ly = y - local_y;
|
||||
int lz = z - local_z;
|
||||
|
||||
int r = rf * len * 255.0;
|
||||
int g = gf * len * 255.0;
|
||||
int b = bf * len * 255.0;
|
||||
float str = size - (((float)lx * lx + ly * ly + lz * lz));
|
||||
str /= size;
|
||||
|
||||
if (str < 0)
|
||||
continue;
|
||||
|
||||
int r = color.r * str * 255.0;
|
||||
int g = color.g * str * 255.0;
|
||||
int b = color.b * str * 255.0;
|
||||
|
||||
r += get_voxel(x, y, z, CHANNEL_LIGHT_COLOR_R);
|
||||
g += get_voxel(x, y, z, CHANNEL_LIGHT_COLOR_G);
|
||||
|
@ -74,11 +74,26 @@ void VoxelChunk::set_library(Ref<VoxelmanLibrary> value) {
|
||||
_library = value;
|
||||
}
|
||||
|
||||
int VoxelChunk::get_lod_size() const {
|
||||
return _lod_size;
|
||||
}
|
||||
void VoxelChunk::set_lod_size(const int lod_size) {
|
||||
_lod_size = lod_size;
|
||||
|
||||
if (_mesher.is_valid()) {
|
||||
_mesher->set_lod_size(_lod_size);
|
||||
}
|
||||
}
|
||||
|
||||
float VoxelChunk::get_voxel_scale() const {
|
||||
return _voxel_scale;
|
||||
}
|
||||
void VoxelChunk::set_voxel_scale(float value) {
|
||||
_voxel_scale = value;
|
||||
|
||||
if (_mesher.is_valid()) {
|
||||
_mesher->set_voxel_scale(_voxel_scale);
|
||||
}
|
||||
}
|
||||
|
||||
Ref<VoxelMesher> VoxelChunk::get_mesher() const {
|
||||
@ -131,6 +146,9 @@ void VoxelChunk::build() {
|
||||
call("_create_mesher");
|
||||
|
||||
ERR_FAIL_COND(!_mesher.is_valid());
|
||||
|
||||
_mesher->set_lod_size(get_lod_size());
|
||||
_mesher->set_voxel_scale(get_voxel_scale());
|
||||
}
|
||||
|
||||
_mesher->set_library(_library);
|
||||
@ -159,7 +177,7 @@ void VoxelChunk::build() {
|
||||
}
|
||||
|
||||
void VoxelChunk::_create_mesher() {
|
||||
_mesher = Ref<VoxelMesher>(memnew(VoxelMesher()));
|
||||
_mesher = Ref<VoxelMesher>(memnew(VoxelMesherCubic()));
|
||||
}
|
||||
|
||||
void VoxelChunk::finalize_mesh() {
|
||||
@ -421,6 +439,10 @@ void VoxelChunk::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_library", "value"), &VoxelChunk::set_library);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanLibrary"), "set_library", "get_library");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_lod_size"), &VoxelChunk::get_lod_size);
|
||||
ClassDB::bind_method(D_METHOD("set_lod_size", "value"), &VoxelChunk::set_lod_size);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_size"), "set_lod_size", "get_lod_size");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_voxel_scale"), &VoxelChunk::get_voxel_scale);
|
||||
ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &VoxelChunk::set_voxel_scale);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../data/voxel_light.h"
|
||||
|
||||
#include "../meshers/voxel_mesher.h"
|
||||
#include "../meshers/cubic_mesher/voxel_mesher_cubic.h"
|
||||
|
||||
#include "../library/voxel_surface.h"
|
||||
#include "../library/voxelman_library.h"
|
||||
@ -51,6 +52,9 @@ public:
|
||||
Ref<VoxelmanLibrary> get_library();
|
||||
void set_library(Ref<VoxelmanLibrary> value);
|
||||
|
||||
int get_lod_size() const;
|
||||
void set_lod_size(int lod_size);
|
||||
|
||||
float get_voxel_scale() const;
|
||||
void set_voxel_scale(float value);
|
||||
|
||||
@ -97,7 +101,7 @@ public:
|
||||
StaticBody *create_trimesh_collision_node();
|
||||
|
||||
VoxelChunk();
|
||||
virtual ~VoxelChunk();
|
||||
~VoxelChunk();
|
||||
|
||||
void draw_debug_voxels(int max, Color color = Color(1, 1, 1));
|
||||
void draw_debug_voxel_lights();
|
||||
@ -114,6 +118,8 @@ protected:
|
||||
|
||||
Ref<VoxelBuffer> _buffer;
|
||||
Vector<Ref<VoxelLight> > _voxel_lights;
|
||||
|
||||
int _lod_size;
|
||||
float _voxel_scale;
|
||||
|
||||
NodePath _library_path;
|
||||
|
Loading…
Reference in New Issue
Block a user