From bc9896b69533b2469bc9243624c77747c12aecc5 Mon Sep 17 00:00:00 2001 From: Relintai Date: Fri, 31 May 2019 22:54:31 +0200 Subject: [PATCH] Added in the classes which I want to salvage from my test voxel engine. Some of the classes contain horrible code because I learned godot engine development with these, the will be cleaned up. The Vector3i is from Zylann's godot_voxel module, I'll properly credit him a bit later. --- SCsub | 15 + collections/vector3i.cpp | 1 + collections/vector3i.h | 177 +++++ data/voxel.cpp | 78 ++ data/voxel.h | 50 ++ data/voxel_light.cpp | 16 + data/voxel_light.h | 44 ++ library/voxel_surface.cpp | 100 +++ library/voxel_surface.h | 97 +++ library/voxelman_library.cpp | 155 ++++ library/voxelman_library.h | 76 ++ meshers/transvoxel_tables.cpp | 993 +++++++++++++++++++++++++ meshers/transvoxel_tables.h | 86 +++ meshers/voxel_mesh_data.cpp | 81 ++ meshers/voxel_mesh_data.h | 45 ++ meshers/voxel_mesher.cpp | 379 ++++++++++ meshers/voxel_mesher.h | 102 +++ meshers/voxel_mesher_transvoxel.cpp | 217 ++++++ meshers/voxel_mesher_transvoxel.h | 84 +++ register_types.cpp | 23 +- utility/marching_cubes_voxel_query.cpp | 149 ++++ utility/marching_cubes_voxel_query.h | 75 ++ 22 files changed, 3042 insertions(+), 1 deletion(-) create mode 100644 collections/vector3i.cpp create mode 100644 collections/vector3i.h create mode 100644 data/voxel.cpp create mode 100644 data/voxel.h create mode 100644 data/voxel_light.cpp create mode 100644 data/voxel_light.h create mode 100644 library/voxel_surface.cpp create mode 100644 library/voxel_surface.h create mode 100644 library/voxelman_library.cpp create mode 100644 library/voxelman_library.h create mode 100644 meshers/transvoxel_tables.cpp create mode 100644 meshers/transvoxel_tables.h create mode 100644 meshers/voxel_mesh_data.cpp create mode 100644 meshers/voxel_mesh_data.h create mode 100644 meshers/voxel_mesher.cpp create mode 100644 meshers/voxel_mesher.h create mode 100644 meshers/voxel_mesher_transvoxel.cpp create mode 100644 meshers/voxel_mesher_transvoxel.h create mode 100644 utility/marching_cubes_voxel_query.cpp create mode 100644 utility/marching_cubes_voxel_query.h diff --git a/SCsub b/SCsub index 2f49252..05635be 100644 --- a/SCsub +++ b/SCsub @@ -2,4 +2,19 @@ Import('env') env.add_source_files(env.modules_sources,"register_types.cpp") +env.add_source_files(env.modules_sources,"collections/vector3i.cpp") + +env.add_source_files(env.modules_sources,"library/voxelman_library.cpp") +env.add_source_files(env.modules_sources,"library/voxel_surface.cpp") + +env.add_source_files(env.modules_sources,"data/voxel.cpp") +env.add_source_files(env.modules_sources,"data/voxel_light.cpp") + +env.add_source_files(env.modules_sources,"meshers/voxel_mesher.cpp") +env.add_source_files(env.modules_sources,"meshers/voxel_mesher_transvoxel.cpp") +env.add_source_files(env.modules_sources,"meshers/transvoxel_tables.cpp") + +env.add_source_files(env.modules_sources,"utility/marching_cubes_voxel_query.cpp") + + diff --git a/collections/vector3i.cpp b/collections/vector3i.cpp new file mode 100644 index 0000000..61487bb --- /dev/null +++ b/collections/vector3i.cpp @@ -0,0 +1 @@ +#include "vector3i.h" diff --git a/collections/vector3i.h b/collections/vector3i.h new file mode 100644 index 0000000..5d7b7ae --- /dev/null +++ b/collections/vector3i.h @@ -0,0 +1,177 @@ +#ifndef VOXEL_VECTOR3I_H +#define VOXEL_VECTOR3I_H + +#include +#include + +struct Vector3i { + + union { + struct { + int x; + int y; + int z; + }; + int coords[3]; + }; + + _FORCE_INLINE_ Vector3i() : + x(0), + y(0), + z(0) {} + + _FORCE_INLINE_ Vector3i(int xyz) : + x(xyz), + y(xyz), + z(xyz) {} + + _FORCE_INLINE_ Vector3i(int px, int py, int pz) : + x(px), + y(py), + z(pz) {} + + _FORCE_INLINE_ Vector3i(const Vector3i &other) { + *this = other; + } + + _FORCE_INLINE_ Vector3i(const Vector3 &f) { + x = Math::floor(f.x); + y = Math::floor(f.y); + z = Math::floor(f.z); + } + + _FORCE_INLINE_ Vector3 to_vec3() const { + return Vector3(x, y, z); + } + + _FORCE_INLINE_ int volume() const { + return x * y * z; + } + + _FORCE_INLINE_ int length_sq() const { + return x * x + y * y + z * z; + } + + _FORCE_INLINE_ real_t length() const { + return Math::sqrt((real_t)length_sq()); + } + + _FORCE_INLINE_ int distance_sq(const Vector3i &other) const; + + _FORCE_INLINE_ Vector3i &operator=(const Vector3i &other) { + x = other.x; + y = other.y; + z = other.z; + return *this; + } + + _FORCE_INLINE_ Vector3i &operator=(const Vector3 &other) { + x = (int) other.x; + y = (int) other.y; + z = (int) other.z; + return *this; + } + + _FORCE_INLINE_ void operator+=(const Vector3i &other) { + x += other.x; + y += other.y; + z += other.z; + } + + _FORCE_INLINE_ void operator-=(const Vector3i &other) { + x -= other.x; + y -= other.y; + z -= other.z; + } + + _FORCE_INLINE_ Vector3i operator-() const { + return Vector3i(-x, -y, -z); + } + + _FORCE_INLINE_ int &operator[](unsigned int i) { + return coords[i]; + } + + void clamp_to(const Vector3i min, const Vector3i max) { + if (x < min.x) x = min.x; + if (y < min.y) y = min.y; + if (z < min.z) z = min.z; + + // TODO Not sure it should clamp like that... + if (x >= max.x) x = max.x - 1; + if (y >= max.y) y = max.y - 1; + if (z >= max.z) z = max.z - 1; + } + + _FORCE_INLINE_ bool is_contained_in(const Vector3i &min, const Vector3i &max) { + return x >= min.x && y >= min.y && z >= min.z && x < max.x && y < max.y && z < max.z; + } + + _FORCE_INLINE_ Vector3i wrap(const Vector3i &size) { + return Vector3i( + x % size.x, + y % size.y, + z % size.z); + } + + static void sort_min_max(Vector3i &a, Vector3i &b) { + sort_min_max(a.x, b.x); + sort_min_max(a.y, b.y); + sort_min_max(a.z, b.z); + } + +private: + static _FORCE_INLINE_ void sort_min_max(int &a, int &b) { + if (a > b) { + int temp = a; + a = b; + b = temp; + } + } +}; + +_FORCE_INLINE_ Vector3i operator+(const Vector3i a, const Vector3i &b) { + return Vector3i(a.x + b.x, a.y + b.y, a.z + b.z); +} + +_FORCE_INLINE_ Vector3i operator-(const Vector3i &a, const Vector3i &b) { + return Vector3i(a.x - b.x, a.y - b.y, a.z - b.z); +} + +_FORCE_INLINE_ Vector3i operator*(const Vector3i &a, const Vector3i &b) { + return Vector3i(a.x * b.x, a.y * b.y, a.z * b.z); +} + +_FORCE_INLINE_ Vector3i operator*(const Vector3i &a, int n) { + return Vector3i(a.x * n, a.y * n, a.z * n); +} + +_FORCE_INLINE_ Vector3i operator*(int n, const Vector3i &a) { + return Vector3i(a.x * n, a.y * n, a.z * n); +} + +_FORCE_INLINE_ Vector3i operator/(const Vector3i &a, int n) { + return Vector3i(a.x / n, a.y / n, a.z / n); +} + +_FORCE_INLINE_ bool operator==(const Vector3i &a, const Vector3i &b) { + return a.x == b.x && a.y == b.y && a.z == b.z; +} + +_FORCE_INLINE_ bool operator!=(const Vector3i &a, const Vector3i &b) { + return a.x != b.x || a.y != b.y || a.z != b.z; +} + +_FORCE_INLINE_ int Vector3i::distance_sq(const Vector3i &other) const { + return (other - *this).length_sq(); +} + +struct Vector3iHasher { + static _FORCE_INLINE_ uint32_t hash(const Vector3i &v) { + uint32_t hash = hash_djb2_one_32(v.x); + hash = hash_djb2_one_32(v.y, hash); + return hash_djb2_one_32(v.z, hash); + } +}; + +#endif // VOXEL_VECTOR3I_H diff --git a/data/voxel.cpp b/data/voxel.cpp new file mode 100644 index 0000000..1e7e86b --- /dev/null +++ b/data/voxel.cpp @@ -0,0 +1,78 @@ +#include "voxel.h" + +Ref Voxel::get_surface() { + return _surface; +} + +Vector3i Voxel::get_local_position() const { + return _local_position; +} +void Voxel::set_local_position(Vector3i value) { + _local_position = value; +} + +Vector3 Voxel::get_local_position_bind() const { + return _local_position.to_vec3(); +} +void Voxel::set_local_position_bind(Vector3 value) { + _local_position = value; +} + +char Voxel::get_fill() { + return _fill; +} +void Voxel::set_fill(char fill) { + _fill = fill; +} + +int Voxel::get_fill_bind() { + return (unsigned int) _fill; +} +void Voxel::set_fill_bind(int fill) { + _fill = (char) fill; +} + +float Voxel::get_light() const { + return _light; +} +void Voxel::set_light(float value) { + _light = value; +} + +Voxel::Voxel() { + _light = (float)1; +} + +Voxel::Voxel(Vector3i position, char fill, Ref surface) { + _light = (float)1; + _fill = fill; + + set_surface(surface); + + _local_position = position; +} + +Voxel::~Voxel() { +} + +void Voxel::set_surface(Ref surface) { + _surface = Ref(surface); +} + +void Voxel::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_surface"), &Voxel::get_surface); + ClassDB::bind_method(D_METHOD("set_surface", "Mesher"), &Voxel::set_surface); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "surface", PROPERTY_HINT_RESOURCE_TYPE, "VoxelSurface"), "set_surface", "get_surface"); + + ClassDB::bind_method(D_METHOD("get_fill"), &Voxel::get_fill_bind); + ClassDB::bind_method(D_METHOD("set_fill", "value"), &Voxel::set_fill_bind); + ADD_PROPERTY(PropertyInfo(Variant::INT, "fill"), "set_fill", "get_fill"); + + ClassDB::bind_method(D_METHOD("get_local_position"), &Voxel::get_local_position_bind); + ClassDB::bind_method(D_METHOD("set_local_position", "value"), &Voxel::set_local_position_bind); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "local_position"), "set_fill", "get_local_position"); + + ClassDB::bind_method(D_METHOD("get_light"), &Voxel::get_light); + ClassDB::bind_method(D_METHOD("set_light", "value"), &Voxel::set_light); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "light"), "set_light", "get_light"); +} diff --git a/data/voxel.h b/data/voxel.h new file mode 100644 index 0000000..454ba71 --- /dev/null +++ b/data/voxel.h @@ -0,0 +1,50 @@ +#ifndef VOXEL_H +#define VOXEL_H + +#include "core/reference.h" +#include "../collections/vector3i.h" +#include "core/math/quat.h" +#include "core/resource.h" +#include "core/vector.h" + +#include "../library/voxel_surface.h" + +class VoxelSurface; + +class Voxel : public Reference { + GDCLASS(Voxel, Reference); + +public: + Ref get_surface(); + void set_surface(Ref surface); + + Vector3i get_local_position() const; + void set_local_position(Vector3i value); + + Vector3 get_local_position_bind() const; + void set_local_position_bind(Vector3 value); + + char get_fill(); + void set_fill(char fill); + + int get_fill_bind(); + void set_fill_bind(int fill); + + float get_light() const; + void set_light(float value); + + Voxel(); + Voxel(Vector3i position, char fill, Ref surface); + ~Voxel(); + +protected: + static void _bind_methods(); + +private: + char _fill; + Ref _surface; + Vector3i _local_position; + float _light; +}; + +#endif diff --git a/data/voxel_light.cpp b/data/voxel_light.cpp new file mode 100644 index 0000000..bb325f7 --- /dev/null +++ b/data/voxel_light.cpp @@ -0,0 +1,16 @@ +#include "voxel_light.h" + +VoxelLight::VoxelLight() { +} + +VoxelLight::VoxelLight(Vector3i position, Color color, float strength, Vector3 WorldPosition, Vector3 offset) { + + _world_position = WorldPosition + offset; + _local_position = position; + _offset = offset; + _color = color; + _strength = strength; +} + +VoxelLight::~VoxelLight() { +} diff --git a/data/voxel_light.h b/data/voxel_light.h new file mode 100644 index 0000000..a6a3efe --- /dev/null +++ b/data/voxel_light.h @@ -0,0 +1,44 @@ +#ifndef VOXEL_LIGHT_H +#define VOXEL_LIGHT_H + +#include "core/color.h" +#include "core/reference.h" +#include "core/vector.h" + +#include "../collections/vector3i.h" + +class VoxelLight : public Reference { + GDCLASS(VoxelLight, Reference); + +public: + Vector3i get_local_position() { return _local_position; } + void set_local_position(Vector3i neighbours) { _local_position = neighbours; } + + Vector3 get_world_position() { return _world_position; } + void set_world_position(Vector3 world_position) { _world_position = world_position; } + + Vector3 get_offset() { return _offset; } + void set_offset(Vector3 offset) { _offset = offset; } + + Color get_color() { return _color; } + void set_color(Color color) { _color = color; } + + float get_strength() { return _strength; } + void set_strength(float strength) { _strength = strength; } + + VoxelLight(); + VoxelLight(Vector3i position, Color color, float strength, Vector3 WorldPosition, Vector3 offset); + ~VoxelLight(); + +private: + static void _bind_methods() {} + +private: + Vector3i _local_position; + Vector3 _world_position; + Vector3 _offset; + Color _color; + float _strength; +}; + +#endif diff --git a/library/voxel_surface.cpp b/library/voxel_surface.cpp new file mode 100644 index 0000000..1f35522 --- /dev/null +++ b/library/voxel_surface.cpp @@ -0,0 +1,100 @@ +#include "voxel_surface.h" + + +void VoxelSurface::set_transparent(bool t) { + _is_transparent = t; +} + +void VoxelSurface::set_library(Ref lib) { + _library = (*lib); +} + +Ref VoxelSurface::get_library() { + return Ref(_library); +} + +void VoxelSurface::set_voxel_name(String name) { + _name = name; +} + +VoxelSurface::VoxelSurface() { + _id = -1; + _atlas_texture_id = 0; + _mesh_id = 0; + _prefab_id = 0; + _light = false; + _light_strength = 0; +} + +VoxelSurface::VoxelSurface(int id) { + _id = -1; + _atlas_texture_id = 0; + + _mesh_id = 0; + _prefab_id = 0; + _light = false; + _light_strength = 0; + + _id = id; +} + +VoxelSurface::~VoxelSurface() { +} + +void VoxelSurface::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_id"), &VoxelSurface::get_id); + ClassDB::bind_method(D_METHOD("set_id", "value"), &VoxelSurface::set_id); + ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id"); + + ClassDB::bind_method(D_METHOD("get_voxel_color"), &VoxelSurface::get_voxel_color); + ClassDB::bind_method(D_METHOD("set_voxel_color", "value"), &VoxelSurface::set_voxel_color); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_voxel_color", "get_voxel_color"); + + ClassDB::bind_method(D_METHOD("get_atlas_texture_id"), &VoxelSurface::get_atlas_texture_id); + ClassDB::bind_method(D_METHOD("set_atlas_texture_id", "value"), &VoxelSurface::set_atlas_texture_id); + ADD_PROPERTY(PropertyInfo(Variant::INT, "atlas_texture_id"), "set_atlas_texture_id", "get_atlas_texture_id"); + + ClassDB::bind_method(D_METHOD("get_mesh_id"), &VoxelSurface::get_mesh_id); + ClassDB::bind_method(D_METHOD("set_mesh_id", "value"), &VoxelSurface::set_mesh_id); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mesh_id"), "set_mesh_id", "get_mesh_id"); + + ClassDB::bind_method(D_METHOD("get_mesh_offset"), &VoxelSurface::get_mesh_offset); + ClassDB::bind_method(D_METHOD("set_mesh_offset", "value"), &VoxelSurface::set_mesh_offset); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "mesh_offset"), "set_mesh_offset", "get_mesh_offset"); + + ClassDB::bind_method(D_METHOD("get_prefab_id"), &VoxelSurface::get_prefab_id); + ClassDB::bind_method(D_METHOD("set_prefab_id", "value"), &VoxelSurface::set_prefab_id); + ADD_PROPERTY(PropertyInfo(Variant::INT, "prefab_id"), "set_prefab_id", "get_prefab_id"); + + ClassDB::bind_method(D_METHOD("get_prefab_offset"), &VoxelSurface::get_prefab_offset); + ClassDB::bind_method(D_METHOD("set_prefab_offset", "value"), &VoxelSurface::set_prefab_offset); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "prefab_offset"), "set_prefab_offset", "get_prefab_offset"); + + ClassDB::bind_method(D_METHOD("get_prefab_rotation"), &VoxelSurface::get_prefab_rotation); + ClassDB::bind_method(D_METHOD("set_prefab_rotation", "value"), &VoxelSurface::set_prefab_rotation); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "prefab_rotation"), "set_prefab_rotation", "get_prefab_rotation"); + + ClassDB::bind_method(D_METHOD("get_light"), &VoxelSurface::get_light); + ClassDB::bind_method(D_METHOD("set_light", "value"), &VoxelSurface::set_light); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "has_light"), "set_prefab_id", "get_light"); + + ClassDB::bind_method(D_METHOD("get_light_strength"), &VoxelSurface::get_light_strength); + ClassDB::bind_method(D_METHOD("set_light_strength", "value"), &VoxelSurface::set_light_strength); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "light_strength"), "set_light_strength", "get_light_strength"); + + ClassDB::bind_method(D_METHOD("get_light_color"), &VoxelSurface::get_light_color); + ClassDB::bind_method(D_METHOD("set_light_color", "value"), &VoxelSurface::set_light_color); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color"), "set_light_color", "get_light_color"); + + ClassDB::bind_method(D_METHOD("get_light_offset"), &VoxelSurface::get_light_offset); + ClassDB::bind_method(D_METHOD("set_light_offset", "value"), &VoxelSurface::set_light_offset); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "light_offset"), "set_light_offset", "get_light_offset"); + + ClassDB::bind_method(D_METHOD("set_transparent", "transparent"), &VoxelSurface::set_transparent, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("is_transparent"), &VoxelSurface::is_transparent); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent"), "set_transparent", "is_transparent"); + + ClassDB::bind_method(D_METHOD("set_voxel_name", "name"), &VoxelSurface::set_voxel_name); + ClassDB::bind_method(D_METHOD("get_voxel_name"), &VoxelSurface::get_voxel_name); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "voxel_name"), "set_name", "get_name"); +} diff --git a/library/voxel_surface.h b/library/voxel_surface.h new file mode 100644 index 0000000..26645b1 --- /dev/null +++ b/library/voxel_surface.h @@ -0,0 +1,97 @@ +#ifndef VOXEL_SURFACE_DEFINITION_H +#define VOXEL_SURFACE_DEFINITION_H + +#include "core/color.h" +#include "core/resource.h" +#include "core/vector.h" +#include "scene/resources/material.h" + +#include "voxelman_library.h" + +class VoxelmanLibrary; + +class VoxelSurface : public Resource { + GDCLASS(VoxelSurface, Resource) + +public: + int get_id() { return _id; } + void set_id(int value) { _id = value; } + + Color get_voxel_color() { return _voxel_color; } + void set_voxel_color(Color value) { _voxel_color = value; } + + int get_atlas_texture_id() { return _atlas_texture_id; } + void set_atlas_texture_id(int value) { _atlas_texture_id = value; } + + bool has_face_color() { + return false; + } + + int get_mesh_id() { return _mesh_id; } + void set_mesh_id(int value) { _mesh_id = value; } + + Vector3 get_mesh_offset() { return _mesh_offset; } + void set_mesh_offset(Vector3 value) { _mesh_offset = value; } + + int get_prefab_id() { return _prefab_id; } + void set_prefab_id(int value) { _prefab_id = value; } + + Vector3 get_prefab_offset() { return _prefab_offset; } + void set_prefab_offset(Vector3 value) { _prefab_offset = value; } + + Vector3 get_prefab_rotation() { return _prefab_rotation; } + void set_prefab_rotation(Vector3 value) { _prefab_rotation = value; } + + bool get_light() { return _light; } + void set_light(bool value) { _light = value; } + + float get_light_strength() { return _light_strength; } + void set_light_strength(float value) { _light_strength = value; } + + Color get_light_color() { return _light_color; } + void set_light_color(Color value) { _light_color = value; } + + Vector3 get_light_offset() { return _light_offset; } + void set_light_offset(Vector3 value) { _light_offset = value; } + + void set_transparent(bool t = true); + bool is_transparent() const { return _is_transparent; } + + void set_voxel_name(String name); + String get_voxel_name() const { return _name; } + + void set_library(Ref lib); + Ref get_library(); + + VoxelSurface(); + VoxelSurface(int id); + ~VoxelSurface(); + +protected: + static void _bind_methods(); + +private: + VoxelmanLibrary *_library; + + int _id; + String _name; + Color _voxel_color; + int _atlas_texture_id; + + //These should probably be in a separate data class, which isn't going to be limited to 256 entries. + int _mesh_id; + Vector3 _mesh_offset; + + int _prefab_id; + Vector3 _prefab_offset; + Vector3 _prefab_rotation; + + bool _light; + float _light_strength; + Color _light_color; + Vector3 _light_offset; + + bool _is_transparent; +}; + +#endif diff --git a/library/voxelman_library.cpp b/library/voxelman_library.cpp new file mode 100644 index 0000000..50aef0c --- /dev/null +++ b/library/voxelman_library.cpp @@ -0,0 +1,155 @@ +#include "voxelman_library.h" + +VoxelmanLibrary::VoxelmanLibrary() { + + _atlas_rows = 8; + _atlas_columns = 8; + + _voxel_types_count = 0; + _voxel_types_page = 0; + + _is_textured = true; + + for (int i = 0; i < MAX_VOXEL_TYPES; ++i) { + if (_voxel_types[i] != NULL) { + print_error("set_this"); + _voxel_types[i]->set_library(Ref(this)); + } + } + +} + +VoxelmanLibrary::~VoxelmanLibrary() { +} + +Ref VoxelmanLibrary::get_voxel_surface(int index) const { + ERR_FAIL_INDEX_V(index, _voxel_types_count, Ref(NULL)); + + return _voxel_types[index]; +} + +void VoxelmanLibrary::set_voxel_surface(int index, Ref value) { + ERR_FAIL_COND(index < 0 || index > _voxel_types_count); + ERR_FAIL_COND(value == NULL); + + if (value != NULL) { + + value->set_library(Ref(this)); + + _voxel_types[index] = Ref(value); + } +} + +int VoxelmanLibrary::get_voxel_types_count() { + return _voxel_types_count; +} + +void VoxelmanLibrary::set_voxel_types_count(int value) { + _voxel_types_count = value; +} + +int VoxelmanLibrary::get_voxel_types_page() { + return _voxel_types_page; +} + +void VoxelmanLibrary::set_voxel_types_page(int value) { + if (value < 0 || value > (int)(_voxel_types_count / ITEMS_PER_PAGE)) { + return; + } + + _voxel_types_page = value; +} + +int VoxelmanLibrary::get_voxel_count() const { + int count = 0; + for (int i = 0; i < MAX_VOXEL_TYPES; ++i) { + if (_voxel_types[i].is_valid()) + ++count; + } + return count; +} + +void VoxelmanLibrary::load_default() { +} + +void VoxelmanLibrary::set_atlas_columns(int s) { + ERR_FAIL_COND(s <= 0); + _atlas_columns = s; +} + +void VoxelmanLibrary::set_atlas_rows(int s) { + ERR_FAIL_COND(s <= 0); + _atlas_rows = s; +} + +bool VoxelmanLibrary::get_is_textured() const { + return _is_textured; +} + +void VoxelmanLibrary::set_is_textured(bool value) { + _is_textured = value; +} + +Ref VoxelmanLibrary::create_voxel(int id, String name) { + ERR_FAIL_COND_V(id < 0 || id >= MAX_VOXEL_TYPES, Ref()); + Ref voxel(memnew(VoxelSurface)); + voxel->set_library(Ref(this)); + voxel->set_id(id); + voxel->set_voxel_name(name); + _voxel_types[id] = voxel; + return voxel; +} + +Ref VoxelmanLibrary::_get_voxel_bind(int id) { + ERR_FAIL_COND_V(id < 0 || id >= MAX_VOXEL_TYPES, Ref()); + return _voxel_types[id]; +} + +void VoxelmanLibrary::_validate_property(PropertyInfo &property) const { + + String prop = property.name; + if (prop.begins_with("Voxel_")) { + int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int(); + if (frame >= _voxel_types_count || frame < ITEMS_PER_PAGE * _voxel_types_page || frame > ITEMS_PER_PAGE * (_voxel_types_page + 1)) { + property.usage = 0; + } + } +} + +void VoxelmanLibrary::_bind_methods() { + ClassDB::bind_method(D_METHOD("create_voxel", "id", "name"), &VoxelmanLibrary::create_voxel); + ClassDB::bind_method(D_METHOD("get_voxel", "id"), &VoxelmanLibrary::_get_voxel_bind); + + ClassDB::bind_method(D_METHOD("get_atlas_columns"), &VoxelmanLibrary::get_atlas_columns); + ClassDB::bind_method(D_METHOD("set_atlas_columns", "value"), &VoxelmanLibrary::set_atlas_columns); + ADD_PROPERTY(PropertyInfo(Variant::INT, "atlas_columns"), "set_atlas_columns", "get_atlas_columns"); + + ClassDB::bind_method(D_METHOD("get_atlas_rows"), &VoxelmanLibrary::get_atlas_rows); + ClassDB::bind_method(D_METHOD("set_atlas_rows", "value"), &VoxelmanLibrary::set_atlas_rows); + ADD_PROPERTY(PropertyInfo(Variant::INT, "atlas_rows"), "set_atlas_rows", "get_atlas_rows"); + + ClassDB::bind_method(D_METHOD("get_is_textured"), &VoxelmanLibrary::get_is_textured); + ClassDB::bind_method(D_METHOD("set_is_textured", "value"), &VoxelmanLibrary::set_is_textured); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_textured"), "set_is_textured", "get_is_textured"); + + ClassDB::bind_method(D_METHOD("get_material"), &VoxelmanLibrary::get_material); + ClassDB::bind_method(D_METHOD("set_material", "value"), &VoxelmanLibrary::set_material); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material"); + + ClassDB::bind_method(D_METHOD("get_voxel_types_count"), &VoxelmanLibrary::get_voxel_types_count); + ClassDB::bind_method(D_METHOD("set_voxel_types_count", "value"), &VoxelmanLibrary::set_voxel_types_count); + ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_types_count", PROPERTY_HINT_RANGE, "0," + itos(MAX_VOXEL_TYPES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_voxel_types_count", "get_voxel_types_count"); + + ClassDB::bind_method(D_METHOD("get_voxel_types_page"), &VoxelmanLibrary::get_voxel_types_page); + ClassDB::bind_method(D_METHOD("set_voxel_types_page", "value"), &VoxelmanLibrary::set_voxel_types_page); + ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_types_page", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_voxel_types_page", "get_voxel_types_page"); + + ClassDB::bind_method(D_METHOD("get_voxel_surface", "index"), &VoxelmanLibrary::get_voxel_surface); + ClassDB::bind_method(D_METHOD("set_voxel_surface", "index", "surface"), &VoxelmanLibrary::set_voxel_surface); + + for (int i = 0; i < MAX_VOXEL_TYPES; ++i) { + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "Voxel_" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "VoxelSurface", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_voxel_surface", "get_voxel_surface", i); + } + + BIND_CONSTANT(MAX_VOXEL_TYPES); +} diff --git a/library/voxelman_library.h b/library/voxelman_library.h new file mode 100644 index 0000000..ddf1b9d --- /dev/null +++ b/library/voxelman_library.h @@ -0,0 +1,76 @@ +#ifndef VOXELMAN_LIBRARY_H +#define VOXELMAN_LIBRARY_H + +#include "core/resource.h" +#include "scene/resources/material.h" + +#include "../data/voxel_light.h" +#include "voxel_surface.h" + +class VoxelSurface; +class VoxelMesher; + +class VoxelmanLibrary : public Resource { + GDCLASS(VoxelmanLibrary, Resource) + +public: + + VoxelmanLibrary(); + ~VoxelmanLibrary(); + + int get_atlas_columns() const { return _atlas_columns; } + void set_atlas_columns(int s); + + int get_atlas_rows() const { return _atlas_rows; } + void set_atlas_rows(int s); + + bool get_is_textured() const; + void set_is_textured(bool s); + + Ref get_material() const { return _material; } + void set_material(Ref mat) { _material = mat; } + + Ref create_voxel(int id, String name); + + int get_voxel_count() const; + + void load_default(); + + Ref get_voxel_surface(int index) const; + void set_voxel_surface(int index, Ref value); + + int get_voxel_types_count(); + void set_voxel_types_count(int value); + + int get_voxel_types_page(); + void set_voxel_types_page(int value); + + _FORCE_INLINE_ bool has_voxel(int id) const { return _voxel_types[id].is_valid(); } + _FORCE_INLINE_ const VoxelSurface &get_voxel_const(int id) const { return **_voxel_types[id]; } + _FORCE_INLINE_ Ref get_surface(int id) { return Ref(*_voxel_types[id]); } + +protected: + static void _bind_methods(); + void _validate_property(PropertyInfo &property) const; + + Ref _get_voxel_bind(int id); + +private: + enum { + MAX_VOXEL_TYPES = 256, + ITEMS_PER_PAGE = 10, + }; + + int _voxel_types_count; + int _voxel_types_page; + Ref _voxel_types[MAX_VOXEL_TYPES]; + + Ref _material; + + //atlas + int _atlas_columns; + int _atlas_rows; + bool _is_textured; +}; + +#endif // VOXEL_LIBRARY_H diff --git a/meshers/transvoxel_tables.cpp b/meshers/transvoxel_tables.cpp new file mode 100644 index 0000000..66b649f --- /dev/null +++ b/meshers/transvoxel_tables.cpp @@ -0,0 +1,993 @@ +#include "transvoxel_tables.h" + +//================================================================================ +// +// The Transvoxel Algorithm look-up tables +// +// Copyright 2009 by Eric Lengyel +// +// The following data originates from Eric Lengyel's Transvoxel Algorithm. +// http://transvoxel.org/ +// +// The data in this file may be freely used in implementations of the Transvoxel +// Algorithm. If you do use this data, or any transformation of it, in your own +// projects, commercial or otherwise, please give credit by indicating in your +// source code that the data is part of the author's implementation of the +// Transvoxel Algorithm and that it came from the web address given above. +// (Simply copying and pasting the two lines of the previous paragraph would be +// perfect.) If you distribute a commercial product with source code included, +// then the credit in the source code is required. +// +// If you distribute any kind of product that uses this data, a credit visible to +// the end-user would be appreciated, but it is not required. However, you may +// not claim that the entire implementation of the Transvoxel Algorithm is your +// own if you use the data in this file or any transformation of it. +// +// The format of the data in this file is described in the dissertation "Voxel- +// Based Terrain for Real-Time Virtual Simulations", available at the web page +// given above. References to sections and figures below pertain to that paper. +// +// The contents of this file are protected by copyright and may not be publicly +// reproduced without permission. +// +//================================================================================ + +namespace Transvoxel { + +// The regularCellClass table maps an 8-bit regular Marching Cubes case index to +// an equivalence class index. Even though there are 18 equivalence classes in our +// modified Marching Cubes algorithm, a couple of them use the same exact triangulations, +// just with different vertex locations. We combined those classes for this table so +// that the class index ranges from 0 to 15. + +const unsigned char regularCellClass[256] = { + 0x00, 0x01, 0x01, 0x03, 0x01, 0x03, 0x02, 0x04, 0x01, 0x02, 0x03, 0x04, 0x03, 0x04, 0x04, 0x03, + 0x01, 0x03, 0x02, 0x04, 0x02, 0x04, 0x06, 0x0C, 0x02, 0x05, 0x05, 0x0B, 0x05, 0x0A, 0x07, 0x04, + 0x01, 0x02, 0x03, 0x04, 0x02, 0x05, 0x05, 0x0A, 0x02, 0x06, 0x04, 0x0C, 0x05, 0x07, 0x0B, 0x04, + 0x03, 0x04, 0x04, 0x03, 0x05, 0x0B, 0x07, 0x04, 0x05, 0x07, 0x0A, 0x04, 0x08, 0x0E, 0x0E, 0x03, + 0x01, 0x02, 0x02, 0x05, 0x03, 0x04, 0x05, 0x0B, 0x02, 0x06, 0x05, 0x07, 0x04, 0x0C, 0x0A, 0x04, + 0x03, 0x04, 0x05, 0x0A, 0x04, 0x03, 0x07, 0x04, 0x05, 0x07, 0x08, 0x0E, 0x0B, 0x04, 0x0E, 0x03, + 0x02, 0x06, 0x05, 0x07, 0x05, 0x07, 0x08, 0x0E, 0x06, 0x09, 0x07, 0x0F, 0x07, 0x0F, 0x0E, 0x0D, + 0x04, 0x0C, 0x0B, 0x04, 0x0A, 0x04, 0x0E, 0x03, 0x07, 0x0F, 0x0E, 0x0D, 0x0E, 0x0D, 0x02, 0x01, + 0x01, 0x02, 0x02, 0x05, 0x02, 0x05, 0x06, 0x07, 0x03, 0x05, 0x04, 0x0A, 0x04, 0x0B, 0x0C, 0x04, + 0x02, 0x05, 0x06, 0x07, 0x06, 0x07, 0x09, 0x0F, 0x05, 0x08, 0x07, 0x0E, 0x07, 0x0E, 0x0F, 0x0D, + 0x03, 0x05, 0x04, 0x0B, 0x05, 0x08, 0x07, 0x0E, 0x04, 0x07, 0x03, 0x04, 0x0A, 0x0E, 0x04, 0x03, + 0x04, 0x0A, 0x0C, 0x04, 0x07, 0x0E, 0x0F, 0x0D, 0x0B, 0x0E, 0x04, 0x03, 0x0E, 0x02, 0x0D, 0x01, + 0x03, 0x05, 0x05, 0x08, 0x04, 0x0A, 0x07, 0x0E, 0x04, 0x07, 0x0B, 0x0E, 0x03, 0x04, 0x04, 0x03, + 0x04, 0x0B, 0x07, 0x0E, 0x0C, 0x04, 0x0F, 0x0D, 0x0A, 0x0E, 0x0E, 0x02, 0x04, 0x03, 0x0D, 0x01, + 0x04, 0x07, 0x0A, 0x0E, 0x0B, 0x0E, 0x0E, 0x02, 0x0C, 0x0F, 0x04, 0x0D, 0x04, 0x0D, 0x03, 0x01, + 0x03, 0x04, 0x04, 0x03, 0x04, 0x03, 0x0D, 0x01, 0x04, 0x0D, 0x03, 0x01, 0x03, 0x01, 0x01, 0x00 +}; + +// The regularCellData table holds the triangulation data for all 16 distinct classes to +// which a case can be mapped by the regularCellClass table. + +const RegularCellData regularCellData[16] = { + { 0x00, {} }, + { 0x31, { 0, 1, 2 } }, + { 0x62, { 0, 1, 2, 3, 4, 5 } }, + { 0x42, { 0, 1, 2, 0, 2, 3 } }, + { 0x53, { 0, 1, 4, 1, 3, 4, 1, 2, 3 } }, + { 0x73, { 0, 1, 2, 0, 2, 3, 4, 5, 6 } }, + { 0x93, { 0, 1, 2, 3, 4, 5, 6, 7, 8 } }, + { 0x84, { 0, 1, 4, 1, 3, 4, 1, 2, 3, 5, 6, 7 } }, + { 0x84, { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7 } }, + { 0xC4, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 } }, + { 0x64, { 0, 4, 5, 0, 1, 4, 1, 3, 4, 1, 2, 3 } }, + { 0x64, { 0, 5, 4, 0, 4, 1, 1, 4, 3, 1, 3, 2 } }, + { 0x64, { 0, 4, 5, 0, 3, 4, 0, 1, 3, 1, 2, 3 } }, + { 0x64, { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5 } }, + { 0x75, { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6 } }, + { 0x95, { 0, 4, 5, 0, 3, 4, 0, 1, 3, 1, 2, 3, 6, 7, 8 } } +}; + +// The regularVertexData table gives the vertex locations for every one of the 256 possible +// cases in the modified Marching Cubes algorithm. Each 16-bit value also provides information +// about whether a vertex can be reused from a neighboring cell. See Section 3.3 for details. +// The low byte contains the indexes for the two endpoints of the edge on which the vertex lies, +// as numbered in Figure 3.7. The high byte contains the vertex reuse data shown in Figure 3.8. + +const unsigned short regularVertexData[256][12] = { + {}, + { 0x6201, 0x5102, 0x3304 }, + { 0x6201, 0x2315, 0x4113 }, + { 0x5102, 0x3304, 0x2315, 0x4113 }, + { 0x5102, 0x4223, 0x1326 }, + { 0x3304, 0x6201, 0x4223, 0x1326 }, + { 0x6201, 0x2315, 0x4113, 0x5102, 0x4223, 0x1326 }, + { 0x4223, 0x1326, 0x3304, 0x2315, 0x4113 }, + { 0x4113, 0x8337, 0x4223 }, + { 0x6201, 0x5102, 0x3304, 0x4223, 0x4113, 0x8337 }, + { 0x6201, 0x2315, 0x8337, 0x4223 }, + { 0x5102, 0x3304, 0x2315, 0x8337, 0x4223 }, + { 0x5102, 0x4113, 0x8337, 0x1326 }, + { 0x4113, 0x8337, 0x1326, 0x3304, 0x6201 }, + { 0x6201, 0x2315, 0x8337, 0x1326, 0x5102 }, + { 0x3304, 0x2315, 0x8337, 0x1326 }, + { 0x3304, 0x1146, 0x2245 }, + { 0x6201, 0x5102, 0x1146, 0x2245 }, + { 0x6201, 0x2315, 0x4113, 0x3304, 0x1146, 0x2245 }, + { 0x2315, 0x4113, 0x5102, 0x1146, 0x2245 }, + { 0x5102, 0x4223, 0x1326, 0x3304, 0x1146, 0x2245 }, + { 0x1146, 0x2245, 0x6201, 0x4223, 0x1326 }, + { 0x3304, 0x1146, 0x2245, 0x6201, 0x2315, 0x4113, 0x5102, 0x4223, 0x1326 }, + { 0x4223, 0x1326, 0x1146, 0x2245, 0x2315, 0x4113 }, + { 0x4223, 0x4113, 0x8337, 0x3304, 0x1146, 0x2245 }, + { 0x6201, 0x5102, 0x1146, 0x2245, 0x4223, 0x4113, 0x8337 }, + { 0x4223, 0x6201, 0x2315, 0x8337, 0x3304, 0x1146, 0x2245 }, + { 0x4223, 0x8337, 0x2315, 0x2245, 0x1146, 0x5102 }, + { 0x5102, 0x4113, 0x8337, 0x1326, 0x3304, 0x1146, 0x2245 }, + { 0x4113, 0x8337, 0x1326, 0x1146, 0x2245, 0x6201 }, + { 0x6201, 0x2315, 0x8337, 0x1326, 0x5102, 0x3304, 0x1146, 0x2245 }, + { 0x2245, 0x2315, 0x8337, 0x1326, 0x1146 }, + { 0x2315, 0x2245, 0x8157 }, + { 0x6201, 0x5102, 0x3304, 0x2315, 0x2245, 0x8157 }, + { 0x4113, 0x6201, 0x2245, 0x8157 }, + { 0x2245, 0x8157, 0x4113, 0x5102, 0x3304 }, + { 0x5102, 0x4223, 0x1326, 0x2315, 0x2245, 0x8157 }, + { 0x6201, 0x4223, 0x1326, 0x3304, 0x2315, 0x2245, 0x8157 }, + { 0x6201, 0x2245, 0x8157, 0x4113, 0x5102, 0x4223, 0x1326 }, + { 0x4223, 0x1326, 0x3304, 0x2245, 0x8157, 0x4113 }, + { 0x4223, 0x4113, 0x8337, 0x2315, 0x2245, 0x8157 }, + { 0x6201, 0x5102, 0x3304, 0x4223, 0x4113, 0x8337, 0x2315, 0x2245, 0x8157 }, + { 0x8337, 0x4223, 0x6201, 0x2245, 0x8157 }, + { 0x5102, 0x3304, 0x2245, 0x8157, 0x8337, 0x4223 }, + { 0x5102, 0x4113, 0x8337, 0x1326, 0x2315, 0x2245, 0x8157 }, + { 0x4113, 0x8337, 0x1326, 0x3304, 0x6201, 0x2315, 0x2245, 0x8157 }, + { 0x5102, 0x1326, 0x8337, 0x8157, 0x2245, 0x6201 }, + { 0x8157, 0x8337, 0x1326, 0x3304, 0x2245 }, + { 0x2315, 0x3304, 0x1146, 0x8157 }, + { 0x6201, 0x5102, 0x1146, 0x8157, 0x2315 }, + { 0x3304, 0x1146, 0x8157, 0x4113, 0x6201 }, + { 0x4113, 0x5102, 0x1146, 0x8157 }, + { 0x2315, 0x3304, 0x1146, 0x8157, 0x5102, 0x4223, 0x1326 }, + { 0x1326, 0x4223, 0x6201, 0x2315, 0x8157, 0x1146 }, + { 0x3304, 0x1146, 0x8157, 0x4113, 0x6201, 0x5102, 0x4223, 0x1326 }, + { 0x1326, 0x1146, 0x8157, 0x4113, 0x4223 }, + { 0x2315, 0x3304, 0x1146, 0x8157, 0x4223, 0x4113, 0x8337 }, + { 0x6201, 0x5102, 0x1146, 0x8157, 0x2315, 0x4223, 0x4113, 0x8337 }, + { 0x3304, 0x1146, 0x8157, 0x8337, 0x4223, 0x6201 }, + { 0x4223, 0x5102, 0x1146, 0x8157, 0x8337 }, + { 0x2315, 0x3304, 0x1146, 0x8157, 0x5102, 0x4113, 0x8337, 0x1326 }, + { 0x6201, 0x4113, 0x8337, 0x1326, 0x1146, 0x8157, 0x2315 }, + { 0x6201, 0x3304, 0x1146, 0x8157, 0x8337, 0x1326, 0x5102 }, + { 0x1326, 0x1146, 0x8157, 0x8337 }, + { 0x1326, 0x8267, 0x1146 }, + { 0x6201, 0x5102, 0x3304, 0x1326, 0x8267, 0x1146 }, + { 0x6201, 0x2315, 0x4113, 0x1326, 0x8267, 0x1146 }, + { 0x5102, 0x3304, 0x2315, 0x4113, 0x1326, 0x8267, 0x1146 }, + { 0x5102, 0x4223, 0x8267, 0x1146 }, + { 0x3304, 0x6201, 0x4223, 0x8267, 0x1146 }, + { 0x5102, 0x4223, 0x8267, 0x1146, 0x6201, 0x2315, 0x4113 }, + { 0x1146, 0x8267, 0x4223, 0x4113, 0x2315, 0x3304 }, + { 0x4113, 0x8337, 0x4223, 0x1326, 0x8267, 0x1146 }, + { 0x6201, 0x5102, 0x3304, 0x4223, 0x4113, 0x8337, 0x1326, 0x8267, 0x1146 }, + { 0x6201, 0x2315, 0x8337, 0x4223, 0x1326, 0x8267, 0x1146 }, + { 0x5102, 0x3304, 0x2315, 0x8337, 0x4223, 0x1326, 0x8267, 0x1146 }, + { 0x8267, 0x1146, 0x5102, 0x4113, 0x8337 }, + { 0x6201, 0x4113, 0x8337, 0x8267, 0x1146, 0x3304 }, + { 0x6201, 0x2315, 0x8337, 0x8267, 0x1146, 0x5102 }, + { 0x1146, 0x3304, 0x2315, 0x8337, 0x8267 }, + { 0x3304, 0x1326, 0x8267, 0x2245 }, + { 0x1326, 0x8267, 0x2245, 0x6201, 0x5102 }, + { 0x3304, 0x1326, 0x8267, 0x2245, 0x6201, 0x2315, 0x4113 }, + { 0x1326, 0x8267, 0x2245, 0x2315, 0x4113, 0x5102 }, + { 0x5102, 0x4223, 0x8267, 0x2245, 0x3304 }, + { 0x6201, 0x4223, 0x8267, 0x2245 }, + { 0x5102, 0x4223, 0x8267, 0x2245, 0x3304, 0x6201, 0x2315, 0x4113 }, + { 0x4113, 0x4223, 0x8267, 0x2245, 0x2315 }, + { 0x3304, 0x1326, 0x8267, 0x2245, 0x4223, 0x4113, 0x8337 }, + { 0x1326, 0x8267, 0x2245, 0x6201, 0x5102, 0x4223, 0x4113, 0x8337 }, + { 0x3304, 0x1326, 0x8267, 0x2245, 0x4223, 0x6201, 0x2315, 0x8337 }, + { 0x5102, 0x1326, 0x8267, 0x2245, 0x2315, 0x8337, 0x4223 }, + { 0x3304, 0x2245, 0x8267, 0x8337, 0x4113, 0x5102 }, + { 0x8337, 0x8267, 0x2245, 0x6201, 0x4113 }, + { 0x5102, 0x6201, 0x2315, 0x8337, 0x8267, 0x2245, 0x3304 }, + { 0x2315, 0x8337, 0x8267, 0x2245 }, + { 0x2315, 0x2245, 0x8157, 0x1326, 0x8267, 0x1146 }, + { 0x6201, 0x5102, 0x3304, 0x2315, 0x2245, 0x8157, 0x1326, 0x8267, 0x1146 }, + { 0x6201, 0x2245, 0x8157, 0x4113, 0x1326, 0x8267, 0x1146 }, + { 0x2245, 0x8157, 0x4113, 0x5102, 0x3304, 0x1326, 0x8267, 0x1146 }, + { 0x4223, 0x8267, 0x1146, 0x5102, 0x2315, 0x2245, 0x8157 }, + { 0x3304, 0x6201, 0x4223, 0x8267, 0x1146, 0x2315, 0x2245, 0x8157 }, + { 0x4223, 0x8267, 0x1146, 0x5102, 0x6201, 0x2245, 0x8157, 0x4113 }, + { 0x3304, 0x2245, 0x8157, 0x4113, 0x4223, 0x8267, 0x1146 }, + { 0x4223, 0x4113, 0x8337, 0x2315, 0x2245, 0x8157, 0x1326, 0x8267, 0x1146 }, + { 0x6201, 0x5102, 0x3304, 0x4223, 0x4113, 0x8337, 0x2315, 0x2245, 0x8157, 0x1326, 0x8267, 0x1146 }, + { 0x8337, 0x4223, 0x6201, 0x2245, 0x8157, 0x1326, 0x8267, 0x1146 }, + { 0x4223, 0x5102, 0x3304, 0x2245, 0x8157, 0x8337, 0x1326, 0x8267, 0x1146 }, + { 0x8267, 0x1146, 0x5102, 0x4113, 0x8337, 0x2315, 0x2245, 0x8157 }, + { 0x6201, 0x4113, 0x8337, 0x8267, 0x1146, 0x3304, 0x2315, 0x2245, 0x8157 }, + { 0x8337, 0x8267, 0x1146, 0x5102, 0x6201, 0x2245, 0x8157 }, + { 0x3304, 0x2245, 0x8157, 0x8337, 0x8267, 0x1146 }, + { 0x8157, 0x2315, 0x3304, 0x1326, 0x8267 }, + { 0x8267, 0x8157, 0x2315, 0x6201, 0x5102, 0x1326 }, + { 0x8267, 0x1326, 0x3304, 0x6201, 0x4113, 0x8157 }, + { 0x8267, 0x8157, 0x4113, 0x5102, 0x1326 }, + { 0x5102, 0x4223, 0x8267, 0x8157, 0x2315, 0x3304 }, + { 0x2315, 0x6201, 0x4223, 0x8267, 0x8157 }, + { 0x3304, 0x5102, 0x4223, 0x8267, 0x8157, 0x4113, 0x6201 }, + { 0x4113, 0x4223, 0x8267, 0x8157 }, + { 0x8157, 0x2315, 0x3304, 0x1326, 0x8267, 0x4223, 0x4113, 0x8337 }, + { 0x8157, 0x2315, 0x6201, 0x5102, 0x1326, 0x8267, 0x4223, 0x4113, 0x8337 }, + { 0x8157, 0x8337, 0x4223, 0x6201, 0x3304, 0x1326, 0x8267 }, + { 0x5102, 0x1326, 0x8267, 0x8157, 0x8337, 0x4223 }, + { 0x8267, 0x8157, 0x2315, 0x3304, 0x5102, 0x4113, 0x8337 }, + { 0x6201, 0x4113, 0x8337, 0x8267, 0x8157, 0x2315 }, + { 0x6201, 0x3304, 0x5102, 0x8337, 0x8267, 0x8157 }, + { 0x8337, 0x8267, 0x8157 }, + { 0x8337, 0x8157, 0x8267 }, + { 0x6201, 0x5102, 0x3304, 0x8337, 0x8157, 0x8267 }, + { 0x6201, 0x2315, 0x4113, 0x8337, 0x8157, 0x8267 }, + { 0x5102, 0x3304, 0x2315, 0x4113, 0x8337, 0x8157, 0x8267 }, + { 0x5102, 0x4223, 0x1326, 0x8337, 0x8157, 0x8267 }, + { 0x6201, 0x4223, 0x1326, 0x3304, 0x8337, 0x8157, 0x8267 }, + { 0x6201, 0x2315, 0x4113, 0x5102, 0x4223, 0x1326, 0x8337, 0x8157, 0x8267 }, + { 0x4223, 0x1326, 0x3304, 0x2315, 0x4113, 0x8337, 0x8157, 0x8267 }, + { 0x4113, 0x8157, 0x8267, 0x4223 }, + { 0x4223, 0x4113, 0x8157, 0x8267, 0x6201, 0x5102, 0x3304 }, + { 0x8157, 0x8267, 0x4223, 0x6201, 0x2315 }, + { 0x3304, 0x2315, 0x8157, 0x8267, 0x4223, 0x5102 }, + { 0x1326, 0x5102, 0x4113, 0x8157, 0x8267 }, + { 0x8157, 0x4113, 0x6201, 0x3304, 0x1326, 0x8267 }, + { 0x1326, 0x5102, 0x6201, 0x2315, 0x8157, 0x8267 }, + { 0x8267, 0x1326, 0x3304, 0x2315, 0x8157 }, + { 0x3304, 0x1146, 0x2245, 0x8337, 0x8157, 0x8267 }, + { 0x6201, 0x5102, 0x1146, 0x2245, 0x8337, 0x8157, 0x8267 }, + { 0x6201, 0x2315, 0x4113, 0x3304, 0x1146, 0x2245, 0x8337, 0x8157, 0x8267 }, + { 0x2315, 0x4113, 0x5102, 0x1146, 0x2245, 0x8337, 0x8157, 0x8267 }, + { 0x5102, 0x4223, 0x1326, 0x3304, 0x1146, 0x2245, 0x8337, 0x8157, 0x8267 }, + { 0x1146, 0x2245, 0x6201, 0x4223, 0x1326, 0x8337, 0x8157, 0x8267 }, + { 0x6201, 0x2315, 0x4113, 0x5102, 0x4223, 0x1326, 0x3304, 0x1146, 0x2245, 0x8337, 0x8157, 0x8267 }, + { 0x4113, 0x4223, 0x1326, 0x1146, 0x2245, 0x2315, 0x8337, 0x8157, 0x8267 }, + { 0x4223, 0x4113, 0x8157, 0x8267, 0x3304, 0x1146, 0x2245 }, + { 0x6201, 0x5102, 0x1146, 0x2245, 0x4223, 0x4113, 0x8157, 0x8267 }, + { 0x8157, 0x8267, 0x4223, 0x6201, 0x2315, 0x3304, 0x1146, 0x2245 }, + { 0x2315, 0x8157, 0x8267, 0x4223, 0x5102, 0x1146, 0x2245 }, + { 0x1326, 0x5102, 0x4113, 0x8157, 0x8267, 0x3304, 0x1146, 0x2245 }, + { 0x1326, 0x1146, 0x2245, 0x6201, 0x4113, 0x8157, 0x8267 }, + { 0x5102, 0x6201, 0x2315, 0x8157, 0x8267, 0x1326, 0x3304, 0x1146, 0x2245 }, + { 0x1326, 0x1146, 0x2245, 0x2315, 0x8157, 0x8267 }, + { 0x2315, 0x2245, 0x8267, 0x8337 }, + { 0x2315, 0x2245, 0x8267, 0x8337, 0x6201, 0x5102, 0x3304 }, + { 0x4113, 0x6201, 0x2245, 0x8267, 0x8337 }, + { 0x5102, 0x4113, 0x8337, 0x8267, 0x2245, 0x3304 }, + { 0x2315, 0x2245, 0x8267, 0x8337, 0x5102, 0x4223, 0x1326 }, + { 0x6201, 0x4223, 0x1326, 0x3304, 0x8337, 0x2315, 0x2245, 0x8267 }, + { 0x4113, 0x6201, 0x2245, 0x8267, 0x8337, 0x5102, 0x4223, 0x1326 }, + { 0x4113, 0x4223, 0x1326, 0x3304, 0x2245, 0x8267, 0x8337 }, + { 0x2315, 0x2245, 0x8267, 0x4223, 0x4113 }, + { 0x2315, 0x2245, 0x8267, 0x4223, 0x4113, 0x6201, 0x5102, 0x3304 }, + { 0x6201, 0x2245, 0x8267, 0x4223 }, + { 0x3304, 0x2245, 0x8267, 0x4223, 0x5102 }, + { 0x5102, 0x4113, 0x2315, 0x2245, 0x8267, 0x1326 }, + { 0x4113, 0x2315, 0x2245, 0x8267, 0x1326, 0x3304, 0x6201 }, + { 0x5102, 0x6201, 0x2245, 0x8267, 0x1326 }, + { 0x3304, 0x2245, 0x8267, 0x1326 }, + { 0x8267, 0x8337, 0x2315, 0x3304, 0x1146 }, + { 0x5102, 0x1146, 0x8267, 0x8337, 0x2315, 0x6201 }, + { 0x3304, 0x1146, 0x8267, 0x8337, 0x4113, 0x6201 }, + { 0x8337, 0x4113, 0x5102, 0x1146, 0x8267 }, + { 0x8267, 0x8337, 0x2315, 0x3304, 0x1146, 0x5102, 0x4223, 0x1326 }, + { 0x1146, 0x8267, 0x8337, 0x2315, 0x6201, 0x4223, 0x1326 }, + { 0x8267, 0x8337, 0x4113, 0x6201, 0x3304, 0x1146, 0x5102, 0x4223, 0x1326 }, + { 0x4113, 0x4223, 0x1326, 0x1146, 0x8267, 0x8337 }, + { 0x3304, 0x2315, 0x4113, 0x4223, 0x8267, 0x1146 }, + { 0x2315, 0x6201, 0x5102, 0x1146, 0x8267, 0x4223, 0x4113 }, + { 0x1146, 0x8267, 0x4223, 0x6201, 0x3304 }, + { 0x5102, 0x1146, 0x8267, 0x4223 }, + { 0x8267, 0x1326, 0x5102, 0x4113, 0x2315, 0x3304, 0x1146 }, + { 0x6201, 0x4113, 0x2315, 0x1326, 0x1146, 0x8267 }, + { 0x6201, 0x3304, 0x1146, 0x8267, 0x1326, 0x5102 }, + { 0x1326, 0x1146, 0x8267 }, + { 0x1326, 0x8337, 0x8157, 0x1146 }, + { 0x8337, 0x8157, 0x1146, 0x1326, 0x6201, 0x5102, 0x3304 }, + { 0x8337, 0x8157, 0x1146, 0x1326, 0x6201, 0x2315, 0x4113 }, + { 0x4113, 0x5102, 0x3304, 0x2315, 0x1326, 0x8337, 0x8157, 0x1146 }, + { 0x8337, 0x8157, 0x1146, 0x5102, 0x4223 }, + { 0x6201, 0x4223, 0x8337, 0x8157, 0x1146, 0x3304 }, + { 0x8337, 0x8157, 0x1146, 0x5102, 0x4223, 0x6201, 0x2315, 0x4113 }, + { 0x4223, 0x8337, 0x8157, 0x1146, 0x3304, 0x2315, 0x4113 }, + { 0x4223, 0x4113, 0x8157, 0x1146, 0x1326 }, + { 0x4223, 0x4113, 0x8157, 0x1146, 0x1326, 0x6201, 0x5102, 0x3304 }, + { 0x1146, 0x8157, 0x2315, 0x6201, 0x4223, 0x1326 }, + { 0x4223, 0x5102, 0x3304, 0x2315, 0x8157, 0x1146, 0x1326 }, + { 0x4113, 0x8157, 0x1146, 0x5102 }, + { 0x6201, 0x4113, 0x8157, 0x1146, 0x3304 }, + { 0x2315, 0x8157, 0x1146, 0x5102, 0x6201 }, + { 0x2315, 0x8157, 0x1146, 0x3304 }, + { 0x2245, 0x3304, 0x1326, 0x8337, 0x8157 }, + { 0x6201, 0x2245, 0x8157, 0x8337, 0x1326, 0x5102 }, + { 0x2245, 0x3304, 0x1326, 0x8337, 0x8157, 0x6201, 0x2315, 0x4113 }, + { 0x2245, 0x2315, 0x4113, 0x5102, 0x1326, 0x8337, 0x8157 }, + { 0x4223, 0x8337, 0x8157, 0x2245, 0x3304, 0x5102 }, + { 0x8157, 0x2245, 0x6201, 0x4223, 0x8337 }, + { 0x2245, 0x3304, 0x5102, 0x4223, 0x8337, 0x8157, 0x4113, 0x6201, 0x2315 }, + { 0x4223, 0x8337, 0x8157, 0x2245, 0x2315, 0x4113 }, + { 0x4113, 0x8157, 0x2245, 0x3304, 0x1326, 0x4223 }, + { 0x1326, 0x4223, 0x4113, 0x8157, 0x2245, 0x6201, 0x5102 }, + { 0x8157, 0x2245, 0x3304, 0x1326, 0x4223, 0x6201, 0x2315 }, + { 0x5102, 0x1326, 0x4223, 0x2315, 0x8157, 0x2245 }, + { 0x3304, 0x5102, 0x4113, 0x8157, 0x2245 }, + { 0x4113, 0x8157, 0x2245, 0x6201 }, + { 0x5102, 0x6201, 0x2315, 0x8157, 0x2245, 0x3304 }, + { 0x2315, 0x8157, 0x2245 }, + { 0x1146, 0x1326, 0x8337, 0x2315, 0x2245 }, + { 0x1146, 0x1326, 0x8337, 0x2315, 0x2245, 0x6201, 0x5102, 0x3304 }, + { 0x6201, 0x2245, 0x1146, 0x1326, 0x8337, 0x4113 }, + { 0x2245, 0x1146, 0x1326, 0x8337, 0x4113, 0x5102, 0x3304 }, + { 0x5102, 0x1146, 0x2245, 0x2315, 0x8337, 0x4223 }, + { 0x1146, 0x3304, 0x6201, 0x4223, 0x8337, 0x2315, 0x2245 }, + { 0x8337, 0x4113, 0x6201, 0x2245, 0x1146, 0x5102, 0x4223 }, + { 0x4223, 0x8337, 0x4113, 0x3304, 0x2245, 0x1146 }, + { 0x4113, 0x2315, 0x2245, 0x1146, 0x1326, 0x4223 }, + { 0x1146, 0x1326, 0x4223, 0x4113, 0x2315, 0x2245, 0x6201, 0x5102, 0x3304 }, + { 0x1326, 0x4223, 0x6201, 0x2245, 0x1146 }, + { 0x4223, 0x5102, 0x3304, 0x2245, 0x1146, 0x1326 }, + { 0x2245, 0x1146, 0x5102, 0x4113, 0x2315 }, + { 0x4113, 0x2315, 0x2245, 0x1146, 0x3304, 0x6201 }, + { 0x6201, 0x2245, 0x1146, 0x5102 }, + { 0x3304, 0x2245, 0x1146 }, + { 0x3304, 0x1326, 0x8337, 0x2315 }, + { 0x5102, 0x1326, 0x8337, 0x2315, 0x6201 }, + { 0x6201, 0x3304, 0x1326, 0x8337, 0x4113 }, + { 0x5102, 0x1326, 0x8337, 0x4113 }, + { 0x4223, 0x8337, 0x2315, 0x3304, 0x5102 }, + { 0x6201, 0x4223, 0x8337, 0x2315 }, + { 0x3304, 0x5102, 0x4223, 0x8337, 0x4113, 0x6201 }, + { 0x4113, 0x4223, 0x8337 }, + { 0x4113, 0x2315, 0x3304, 0x1326, 0x4223 }, + { 0x1326, 0x4223, 0x4113, 0x2315, 0x6201, 0x5102 }, + { 0x3304, 0x1326, 0x4223, 0x6201 }, + { 0x5102, 0x1326, 0x4223 }, + { 0x5102, 0x4113, 0x2315, 0x3304 }, + { 0x6201, 0x4113, 0x2315 }, + { 0x6201, 0x3304, 0x5102 }, + {} +}; + +// The transitionCellClass table maps a 9-bit transition cell case index to an equivalence +// class index. Even though there are 73 equivalence classes in the Transvoxel Algorithm, +// several of them use the same exact triangulations, just with different vertex locations. +// We combined those classes for this table so that the class index ranges from 0 to 55. +// The high bit is set in the cases for which the inverse state of the voxel data maps to +// the equivalence class, meaning that the winding order of each triangle should be reversed. + +const unsigned char transitionCellClass[512] = { + 0x00, 0x01, 0x02, 0x84, 0x01, 0x05, 0x04, 0x04, 0x02, 0x87, 0x09, 0x8C, 0x84, 0x0B, 0x05, 0x05, + 0x01, 0x08, 0x07, 0x8D, 0x05, 0x0F, 0x8B, 0x0B, 0x04, 0x0D, 0x0C, 0x1C, 0x04, 0x8B, 0x85, 0x85, + 0x02, 0x07, 0x09, 0x8C, 0x87, 0x10, 0x0C, 0x0C, 0x09, 0x12, 0x15, 0x9A, 0x8C, 0x19, 0x90, 0x10, + 0x84, 0x8D, 0x8C, 0x9C, 0x0B, 0x9D, 0x0F, 0x0F, 0x05, 0x1B, 0x10, 0xAC, 0x05, 0x0F, 0x8B, 0x0B, + 0x01, 0x05, 0x87, 0x0B, 0x08, 0x0F, 0x0D, 0x8B, 0x07, 0x10, 0x12, 0x19, 0x8D, 0x9D, 0x1B, 0x0F, + 0x05, 0x0F, 0x10, 0x9D, 0x0F, 0x1E, 0x1D, 0xA1, 0x8B, 0x1D, 0x99, 0x32, 0x0B, 0xA1, 0x8F, 0x94, + 0x04, 0x8B, 0x0C, 0x0F, 0x0D, 0x1D, 0x1C, 0x8F, 0x0C, 0x99, 0x1A, 0x31, 0x1C, 0x32, 0x2C, 0xA7, + 0x04, 0x0B, 0x0C, 0x0F, 0x8B, 0xA1, 0x8F, 0x96, 0x85, 0x8F, 0x90, 0x27, 0x85, 0x94, 0x8B, 0x8A, + 0x02, 0x04, 0x09, 0x05, 0x07, 0x8B, 0x0C, 0x85, 0x09, 0x0C, 0x15, 0x90, 0x8C, 0x0F, 0x10, 0x8B, + 0x87, 0x0D, 0x12, 0x1B, 0x10, 0x1D, 0x99, 0x8F, 0x0C, 0x1C, 0x1A, 0x2C, 0x0C, 0x8F, 0x90, 0x8B, + 0x09, 0x0C, 0x15, 0x10, 0x12, 0x99, 0x1A, 0x90, 0x15, 0x1A, 0x23, 0x30, 0x9A, 0x31, 0x30, 0x19, + 0x8C, 0x1C, 0x9A, 0xAC, 0x19, 0x32, 0x31, 0x27, 0x90, 0x2C, 0x30, 0x29, 0x10, 0xA7, 0x19, 0x24, + 0x84, 0x04, 0x8C, 0x05, 0x8D, 0x0B, 0x1C, 0x85, 0x8C, 0x0C, 0x9A, 0x10, 0x9C, 0x0F, 0xAC, 0x0B, + 0x0B, 0x8B, 0x19, 0x0F, 0x9D, 0xA1, 0x32, 0x94, 0x0F, 0x8F, 0x31, 0xA7, 0x0F, 0x96, 0x27, 0x8A, + 0x05, 0x85, 0x90, 0x8B, 0x1B, 0x8F, 0x2C, 0x8B, 0x10, 0x90, 0x30, 0x19, 0xAC, 0x27, 0x29, 0x24, + 0x05, 0x85, 0x10, 0x0B, 0x0F, 0x94, 0xA7, 0x8A, 0x8B, 0x8B, 0x19, 0x24, 0x0B, 0x8A, 0x24, 0x83, + 0x03, 0x06, 0x0A, 0x8B, 0x06, 0x0E, 0x0B, 0x0B, 0x0A, 0x91, 0x14, 0x8F, 0x8B, 0x17, 0x05, 0x85, + 0x06, 0x13, 0x11, 0x98, 0x0E, 0x1F, 0x97, 0x2B, 0x0B, 0x18, 0x0F, 0x36, 0x0B, 0xAB, 0x05, 0x85, + 0x0A, 0x11, 0x16, 0x8F, 0x91, 0x20, 0x0F, 0x8F, 0x14, 0x22, 0x21, 0x1D, 0x8F, 0x2D, 0x0B, 0x8B, + 0x8B, 0x98, 0x8F, 0xB7, 0x17, 0xAE, 0x8C, 0x0C, 0x05, 0x2F, 0x8B, 0xB5, 0x85, 0xA6, 0x84, 0x04, + 0x06, 0x0E, 0x91, 0x17, 0x13, 0x1F, 0x18, 0xAB, 0x11, 0x20, 0x22, 0x2D, 0x98, 0xAE, 0x2F, 0xA6, + 0x0E, 0x1F, 0x20, 0xAE, 0x1F, 0x33, 0x2E, 0x2A, 0x97, 0x2E, 0xAD, 0x28, 0x2B, 0x2A, 0x26, 0x25, + 0x0B, 0x97, 0x0F, 0x8C, 0x18, 0x2E, 0x37, 0x8C, 0x0F, 0xAD, 0x9D, 0x90, 0x36, 0x28, 0x35, 0x07, + 0x0B, 0x2B, 0x8F, 0x0C, 0xAB, 0x2A, 0x8C, 0x89, 0x05, 0x26, 0x0B, 0x87, 0x85, 0x25, 0x84, 0x82, + 0x0A, 0x0B, 0x14, 0x05, 0x11, 0x97, 0x0F, 0x05, 0x16, 0x0F, 0x21, 0x0B, 0x8F, 0x8C, 0x8B, 0x84, + 0x91, 0x18, 0x22, 0x2F, 0x20, 0x2E, 0xAD, 0x26, 0x0F, 0x37, 0x9D, 0x35, 0x8F, 0x8C, 0x0B, 0x84, + 0x14, 0x0F, 0x21, 0x8B, 0x22, 0xAD, 0x9D, 0x0B, 0x21, 0x9D, 0x9E, 0x8F, 0x1D, 0x90, 0x8F, 0x85, + 0x8F, 0x36, 0x1D, 0xB5, 0x2D, 0x28, 0x90, 0x87, 0x0B, 0x35, 0x8F, 0x34, 0x8B, 0x07, 0x85, 0x81, + 0x8B, 0x0B, 0x8F, 0x85, 0x98, 0x2B, 0x36, 0x85, 0x8F, 0x8F, 0x1D, 0x8B, 0xB7, 0x0C, 0xB5, 0x04, + 0x17, 0xAB, 0x2D, 0xA6, 0xAE, 0x2A, 0x28, 0x25, 0x8C, 0x8C, 0x90, 0x07, 0x0C, 0x89, 0x87, 0x82, + 0x05, 0x05, 0x0B, 0x84, 0x2F, 0x26, 0x35, 0x84, 0x8B, 0x0B, 0x8F, 0x85, 0xB5, 0x87, 0x34, 0x81, + 0x85, 0x85, 0x8B, 0x04, 0xA6, 0x25, 0x07, 0x82, 0x84, 0x84, 0x85, 0x81, 0x04, 0x82, 0x81, 0x80 +}; + +// The transitionCellData table holds the triangulation data for all 56 distinct classes to +// which a case can be mapped by the transitionCellClass table. The class index should be ANDed +// with 0x7F before using it to look up triangulation data in this table. + +const TransitionCellData transitionCellData[56] = { + { 0x00, {} }, + { 0x42, { 0, 1, 3, 1, 2, 3 } }, + { 0x31, { 0, 1, 2 } }, + { 0x42, { 0, 1, 2, 0, 2, 3 } }, + { 0x53, { 0, 1, 4, 1, 3, 4, 1, 2, 3 } }, + { 0x64, { 0, 1, 5, 1, 2, 5, 2, 4, 5, 2, 3, 4 } }, + { 0x84, { 0, 1, 3, 1, 2, 3, 4, 5, 6, 4, 6, 7 } }, + { 0x73, { 0, 1, 3, 1, 2, 3, 4, 5, 6 } }, + { 0x84, { 0, 1, 3, 1, 2, 3, 4, 5, 7, 5, 6, 7 } }, + { 0x62, { 0, 1, 2, 3, 4, 5 } }, + { 0x53, { 0, 1, 3, 0, 3, 4, 1, 2, 3 } }, + { 0x75, { 0, 1, 6, 1, 2, 6, 2, 5, 6, 2, 3, 5, 3, 4, 5 } }, + { 0x84, { 0, 1, 4, 1, 3, 4, 1, 2, 3, 5, 6, 7 } }, + { 0x95, { 0, 1, 4, 1, 3, 4, 1, 2, 3, 5, 6, 8, 6, 7, 8 } }, + { 0xA6, { 0, 1, 5, 1, 2, 5, 2, 4, 5, 2, 3, 4, 6, 7, 8, 6, 8, 9 } }, + { 0x86, { 0, 1, 7, 1, 2, 7, 2, 3, 7, 3, 6, 7, 3, 4, 6, 4, 5, 6 } }, + { 0x95, { 0, 1, 5, 1, 2, 5, 2, 4, 5, 2, 3, 4, 6, 7, 8 } }, + { 0x95, { 0, 1, 3, 1, 2, 3, 4, 5, 7, 4, 7, 8, 5, 6, 7 } }, + { 0xA4, { 0, 1, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9 } }, + { 0xC6, { 0, 1, 3, 1, 2, 3, 4, 5, 7, 5, 6, 7, 8, 9, 10, 8, 10, 11 } }, + { 0x64, { 0, 1, 3, 1, 2, 3, 0, 3, 4, 0, 4, 5 } }, + { 0x93, { 0, 1, 2, 3, 4, 5, 6, 7, 8 } }, + { 0x64, { 0, 1, 4, 0, 4, 5, 1, 3, 4, 1, 2, 3 } }, + { 0x97, { 0, 1, 8, 1, 7, 8, 1, 2, 7, 2, 3, 7, 3, 4, 7, 4, 5, 7, 5, 6, 7 } }, + { 0xB7, { 0, 1, 6, 1, 2, 6, 2, 5, 6, 2, 3, 5, 3, 4, 5, 7, 8, 10, 8, 9, 10 } }, + { 0xA6, { 0, 1, 6, 1, 2, 6, 2, 5, 6, 2, 3, 5, 3, 4, 5, 7, 8, 9 } }, + { 0xB5, { 0, 1, 4, 1, 3, 4, 1, 2, 3, 5, 6, 7, 8, 9, 10 } }, + { 0xA6, { 0, 1, 5, 1, 2, 5, 2, 4, 5, 2, 3, 4, 6, 7, 9, 7, 8, 9 } }, + { 0xA6, { 0, 1, 4, 1, 3, 4, 1, 2, 3, 5, 6, 9, 6, 8, 9, 6, 7, 8 } }, + { 0x97, { 0, 1, 8, 1, 2, 8, 2, 3, 8, 3, 7, 8, 3, 4, 7, 4, 5, 7, 5, 6, 7 } }, + { 0x86, { 0, 1, 7, 1, 6, 7, 1, 2, 6, 2, 5, 6, 2, 4, 5, 2, 3, 4 } }, + { 0xC8, { 0, 1, 7, 1, 2, 7, 2, 3, 7, 3, 6, 7, 3, 4, 6, 4, 5, 6, 8, 9, 10, 8, 10, 11 } }, + { 0xB7, { 0, 1, 5, 1, 2, 5, 2, 4, 5, 2, 3, 4, 6, 9, 10, 6, 7, 9, 7, 8, 9 } }, + { 0x75, { 0, 1, 6, 1, 3, 6, 1, 2, 3, 3, 4, 6, 4, 5, 6 } }, + { 0xA6, { 0, 1, 3, 1, 2, 3, 4, 5, 9, 5, 8, 9, 5, 6, 8, 6, 7, 8 } }, + { 0xC4, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 } }, + { 0x86, { 1, 2, 4, 2, 3, 4, 0, 1, 7, 1, 4, 7, 4, 6, 7, 4, 5, 6 } }, + { 0x64, { 0, 4, 5, 0, 1, 4, 1, 3, 4, 1, 2, 3 } }, + { 0x86, { 0, 1, 4, 1, 3, 4, 1, 2, 3, 0, 4, 7, 4, 6, 7, 4, 5, 6 } }, + { 0x97, { 1, 2, 3, 1, 3, 4, 1, 4, 5, 0, 1, 8, 1, 5, 8, 5, 7, 8, 5, 6, 7 } }, + { 0xA6, { 0, 1, 3, 1, 2, 3, 4, 5, 9, 5, 8, 9, 5, 6, 8, 6, 7, 8 } }, + { 0xC8, { 0, 1, 5, 1, 2, 5, 2, 4, 5, 2, 3, 4, 6, 7, 11, 7, 10, 11, 7, 8, 10, 8, 9, 10 } }, + { 0x97, { 0, 1, 8, 1, 2, 8, 2, 7, 8, 2, 3, 7, 3, 6, 7, 3, 4, 6, 4, 5, 6 } }, + { 0x97, { 0, 1, 4, 1, 3, 4, 1, 2, 3, 0, 4, 8, 4, 7, 8, 4, 5, 7, 5, 6, 7 } }, + { 0xB7, { 0, 1, 5, 1, 2, 5, 2, 4, 5, 2, 3, 4, 6, 7, 10, 7, 9, 10, 7, 8, 9 } }, + { 0xA8, { 0, 1, 9, 1, 2, 9, 2, 8, 9, 2, 3, 8, 3, 7, 8, 3, 4, 7, 4, 6, 7, 4, 5, 6 } }, + { 0xB9, { 0, 1, 7, 1, 6, 7, 1, 2, 6, 2, 5, 6, 2, 3, 5, 3, 4, 5, 0, 7, 10, 7, 9, 10, 7, 8, 9 } }, + { 0xA6, { 0, 1, 5, 1, 4, 5, 1, 2, 4, 2, 3, 4, 6, 7, 9, 7, 8, 9 } }, + { 0xC6, { 0, 1, 5, 1, 2, 5, 2, 4, 5, 2, 3, 4, 6, 7, 8, 9, 10, 11 } }, + { 0xB7, { 0, 1, 7, 1, 2, 7, 2, 3, 7, 3, 6, 7, 3, 4, 6, 4, 5, 6, 8, 9, 10 } }, + { 0xA8, { 1, 2, 3, 1, 3, 4, 1, 4, 6, 4, 5, 6, 0, 1, 9, 1, 6, 9, 6, 8, 9, 6, 7, 8 } }, + { 0xCC, { 0, 1, 9, 1, 8, 9, 1, 2, 8, 2, 11, 8, 2, 3, 11, 3, 4, 11, 4, 5, 11, 5, 10, 11, 5, 6, 10, 6, 9, 10, 6, 7, 9, 7, 0, 9 } }, + { 0x86, { 0, 1, 2, 0, 2, 3, 0, 6, 7, 0, 3, 6, 1, 4, 5, 1, 5, 2 } }, + { 0x97, { 0, 1, 4, 1, 3, 4, 1, 2, 3, 2, 5, 6, 2, 6, 3, 0, 7, 8, 0, 4, 7 } }, + { 0xA8, { 0, 1, 5, 1, 4, 5, 1, 2, 4, 2, 3, 4, 3, 6, 7, 3, 7, 4, 0, 8, 9, 0, 5, 8 } }, + { 0xA8, { 0, 1, 5, 1, 4, 5, 1, 2, 4, 2, 3, 4, 2, 6, 3, 3, 6, 7, 0, 8, 9, 0, 5, 8 } } +}; + +// The transitionCornerData table contains the transition cell corner reuse data +// shown in Figure 4.18. + +const unsigned char transitionCornerData[13] = { + 0x30, 0x21, 0x20, 0x12, 0x40, 0x82, 0x10, 0x81, 0x80, 0x37, 0x27, 0x17, 0x87 +}; + +// The transitionVertexData table gives the vertex locations for every one of the 512 possible +// cases in the Tranvoxel Algorithm. Each 16-bit value also provides information about whether +// a vertex can be reused from a neighboring cell. See Section 4.5 for details. The low byte +// contains the indexes for the two endpoints of the edge on which the vertex lies, as numbered +// in Figure 4.16. The high byte contains the vertex reuse data shown in Figure 4.17. + +const unsigned short transitionVertexData[512][12] = { + {}, + { 0x2301, 0x1503, 0x199B, 0x289A }, + { 0x2301, 0x2412, 0x4514 }, + { 0x1503, 0x4514, 0x2412, 0x289A, 0x199B }, + { 0x8525, 0x2412, 0x289A, 0x89AC }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC }, + { 0x8525, 0x4514, 0x1503, 0x199B, 0x89AC }, + { 0x8525, 0x8658, 0x4445 }, + { 0x1503, 0x2301, 0x289A, 0x199B, 0x8658, 0x8525, 0x4445 }, + { 0x8525, 0x8658, 0x4445, 0x2301, 0x2412, 0x4514 }, + { 0x1503, 0x4514, 0x2412, 0x289A, 0x199B, 0x8658, 0x8525, 0x4445 }, + { 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC }, + { 0x8658, 0x4445, 0x4514, 0x2301, 0x289A, 0x89AC }, + { 0x8658, 0x4445, 0x4514, 0x1503, 0x199B, 0x89AC }, + { 0x8478, 0x8658, 0x89AC, 0x88BC }, + { 0x2301, 0x1503, 0x199B, 0x289A, 0x8478, 0x8658, 0x89AC, 0x88BC }, + { 0x8478, 0x8658, 0x89AC, 0x88BC, 0x2301, 0x2412, 0x4514 }, + { 0x1503, 0x4514, 0x2412, 0x289A, 0x199B, 0x8658, 0x8478, 0x88BC, 0x89AC }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x88BC }, + { 0x2301, 0x4514, 0x8525, 0x8658, 0x8478, 0x88BC, 0x289A }, + { 0x8478, 0x8658, 0x8525, 0x4514, 0x1503, 0x199B, 0x88BC }, + { 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC }, + { 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x1503, 0x199B, 0x289A }, + { 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x2412, 0x4514 }, + { 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2412, 0x4514, 0x1503, 0x199B, 0x289A }, + { 0x8478, 0x4445, 0x2412, 0x289A, 0x88BC }, + { 0x1503, 0x2301, 0x2412, 0x4445, 0x8478, 0x88BC, 0x199B }, + { 0x2301, 0x4514, 0x4445, 0x8478, 0x88BC, 0x289A }, + { 0x1503, 0x4514, 0x4445, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x8367, 0x4647 }, + { 0x2301, 0x1503, 0x199B, 0x289A, 0x8478, 0x8367, 0x4647 }, + { 0x2301, 0x2412, 0x4514, 0x8478, 0x8367, 0x4647 }, + { 0x1503, 0x4514, 0x2412, 0x289A, 0x199B, 0x8367, 0x8478, 0x4647 }, + { 0x2412, 0x8525, 0x89AC, 0x289A, 0x8367, 0x8478, 0x4647 }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x8525, 0x4514, 0x1503, 0x199B, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x8478, 0x8367, 0x4647, 0x8525, 0x8658, 0x4445 }, + { 0x2301, 0x1503, 0x199B, 0x289A, 0x8478, 0x8367, 0x4647, 0x8525, 0x8658, 0x4445 }, + { 0x8478, 0x8367, 0x4647, 0x8525, 0x8658, 0x4445, 0x2301, 0x2412, 0x4514 }, + { 0x1503, 0x4514, 0x2412, 0x289A, 0x199B, 0x8658, 0x8525, 0x4445, 0x8367, 0x8478, 0x4647 }, + { 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A, 0x8367, 0x8478, 0x4647 }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x2301, 0x4514, 0x4445, 0x8658, 0x89AC, 0x289A, 0x8367, 0x8478, 0x4647 }, + { 0x8658, 0x4445, 0x4514, 0x1503, 0x199B, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC }, + { 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC, 0x1503, 0x2301, 0x289A, 0x199B }, + { 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC, 0x2412, 0x2301, 0x4514 }, + { 0x1503, 0x4514, 0x2412, 0x289A, 0x199B, 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC }, + { 0x1503, 0x2301, 0x2412, 0x8525, 0x8658, 0x4647, 0x8367, 0x88BC, 0x199B }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x4514, 0x2301, 0x289A, 0x88BC }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x4514, 0x1503, 0x199B, 0x88BC }, + { 0x8367, 0x4647, 0x4445, 0x8525, 0x89AC, 0x88BC }, + { 0x8367, 0x4647, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x1503, 0x199B, 0x289A }, + { 0x8367, 0x4647, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x2412, 0x4514 }, + { 0x8525, 0x4445, 0x4647, 0x8367, 0x88BC, 0x89AC, 0x1503, 0x4514, 0x2412, 0x289A, 0x199B }, + { 0x8367, 0x4647, 0x4445, 0x2412, 0x289A, 0x88BC }, + { 0x8367, 0x4647, 0x4445, 0x2412, 0x2301, 0x1503, 0x199B, 0x88BC }, + { 0x2301, 0x4514, 0x4445, 0x4647, 0x8367, 0x88BC, 0x289A }, + { 0x8367, 0x4647, 0x4445, 0x4514, 0x1503, 0x199B, 0x88BC }, + { 0x1636, 0x8367, 0x88BC, 0x199B }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A }, + { 0x8367, 0x1636, 0x199B, 0x88BC, 0x2412, 0x2301, 0x4514 }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A }, + { 0x8525, 0x2412, 0x289A, 0x89AC, 0x1636, 0x8367, 0x88BC, 0x199B }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x89AC }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1636, 0x8367, 0x88BC, 0x199B }, + { 0x8367, 0x1636, 0x1503, 0x4514, 0x8525, 0x89AC, 0x88BC }, + { 0x1636, 0x8367, 0x88BC, 0x199B, 0x8525, 0x8658, 0x4445 }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x1636, 0x8367, 0x88BC, 0x199B, 0x8525, 0x8658, 0x4445, 0x2301, 0x2412, 0x4514 }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A, 0x8367, 0x1636, 0x199B, 0x88BC }, + { 0x8367, 0x1636, 0x1503, 0x2301, 0x2412, 0x4445, 0x8658, 0x89AC, 0x88BC }, + { 0x8658, 0x4445, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1636, 0x8367, 0x88BC, 0x199B }, + { 0x8658, 0x4445, 0x4514, 0x1503, 0x1636, 0x8367, 0x88BC, 0x89AC }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x289A }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x8658, 0x8478, 0x8367, 0x1636, 0x1503, 0x4514, 0x2412, 0x289A, 0x89AC }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x199B }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x1503 }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x4514, 0x2301, 0x289A, 0x199B }, + { 0x1503, 0x4514, 0x8525, 0x8658, 0x8478, 0x8367, 0x1636 }, + { 0x8525, 0x4445, 0x8478, 0x8367, 0x1636, 0x199B, 0x89AC }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x8478, 0x4445, 0x8525, 0x89AC, 0x289A }, + { 0x8525, 0x4445, 0x8478, 0x8367, 0x1636, 0x199B, 0x89AC, 0x2412, 0x2301, 0x4514 }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x8367, 0x8478, 0x4445, 0x8525, 0x89AC, 0x289A }, + { 0x1636, 0x8367, 0x8478, 0x4445, 0x2412, 0x289A, 0x199B }, + { 0x2412, 0x4445, 0x8478, 0x8367, 0x1636, 0x1503, 0x2301 }, + { 0x2301, 0x4514, 0x4445, 0x8478, 0x8367, 0x1636, 0x199B, 0x289A }, + { 0x8367, 0x1636, 0x1503, 0x4514, 0x4445, 0x8478 }, + { 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4647, 0x1636, 0x1503, 0x2301, 0x289A, 0x88BC }, + { 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x4647, 0x8478, 0x88BC, 0x289A }, + { 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B, 0x8525, 0x2412, 0x289A, 0x89AC }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x1636, 0x4647, 0x8478, 0x88BC, 0x89AC }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4647, 0x1636, 0x1503, 0x4514, 0x8525, 0x89AC, 0x88BC }, + { 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B, 0x8525, 0x8658, 0x4445 }, + { 0x8478, 0x4647, 0x1636, 0x1503, 0x2301, 0x289A, 0x88BC, 0x8658, 0x8525, 0x4445 }, + { 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B, 0x8525, 0x8658, 0x4445, 0x2301, 0x2412, 0x4514 }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x4647, 0x8478, 0x88BC, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B, 0x8658, 0x4445, 0x2412, 0x289A, 0x89AC }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x1503, 0x1636, 0x4647, 0x8478, 0x88BC, 0x89AC }, + { 0x8658, 0x4445, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4647, 0x1636, 0x1503, 0x4514, 0x4445, 0x8658, 0x89AC, 0x88BC }, + { 0x1636, 0x4647, 0x8658, 0x89AC, 0x199B }, + { 0x2301, 0x1503, 0x1636, 0x4647, 0x8658, 0x89AC, 0x289A }, + { 0x1636, 0x4647, 0x8658, 0x89AC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x4647, 0x8658, 0x89AC, 0x289A }, + { 0x2412, 0x8525, 0x8658, 0x4647, 0x1636, 0x199B, 0x289A }, + { 0x8658, 0x4647, 0x1636, 0x1503, 0x2301, 0x2412, 0x8525 }, + { 0x2301, 0x4514, 0x8525, 0x8658, 0x4647, 0x1636, 0x199B, 0x289A }, + { 0x1503, 0x4514, 0x8525, 0x8658, 0x4647, 0x1636 }, + { 0x8525, 0x4445, 0x4647, 0x1636, 0x199B, 0x89AC }, + { 0x8525, 0x4445, 0x4647, 0x1636, 0x1503, 0x2301, 0x289A, 0x89AC }, + { 0x8525, 0x4445, 0x4647, 0x1636, 0x199B, 0x89AC, 0x2412, 0x2301, 0x4514 }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x4647, 0x4445, 0x8525, 0x89AC, 0x289A }, + { 0x2412, 0x4445, 0x4647, 0x1636, 0x199B, 0x289A }, + { 0x1503, 0x2301, 0x2412, 0x4445, 0x4647, 0x1636 }, + { 0x2301, 0x4514, 0x4445, 0x4647, 0x1636, 0x199B, 0x289A }, + { 0x1503, 0x4514, 0x4445, 0x4647, 0x1636 }, + { 0x1636, 0x1503, 0x4334 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A }, + { 0x2301, 0x2412, 0x4514, 0x1636, 0x1503, 0x4334 }, + { 0x2412, 0x4514, 0x4334, 0x1636, 0x199B, 0x289A }, + { 0x8525, 0x2412, 0x289A, 0x89AC, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x2301, 0x2412, 0x8525, 0x89AC, 0x199B }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x8525, 0x89AC, 0x199B }, + { 0x1636, 0x1503, 0x4334, 0x8525, 0x8658, 0x4445 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x8525, 0x8658, 0x4445, 0x2301, 0x2412, 0x4514, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x2412, 0x289A, 0x199B, 0x8658, 0x8525, 0x4445 }, + { 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A, 0x1503, 0x1636, 0x4334 }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x4334, 0x1636, 0x199B, 0x89AC }, + { 0x8658, 0x4445, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x4445, 0x8658, 0x89AC, 0x199B }, + { 0x8658, 0x8478, 0x88BC, 0x89AC, 0x1503, 0x1636, 0x4334 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A, 0x8478, 0x8658, 0x89AC, 0x88BC }, + { 0x8478, 0x8658, 0x89AC, 0x88BC, 0x2301, 0x2412, 0x4514, 0x1636, 0x1503, 0x4334 }, + { 0x2412, 0x4514, 0x4334, 0x1636, 0x199B, 0x289A, 0x8478, 0x8658, 0x89AC, 0x88BC }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x4334, 0x1636, 0x199B, 0x88BC }, + { 0x2301, 0x4514, 0x8525, 0x8658, 0x8478, 0x88BC, 0x289A, 0x1503, 0x1636, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x8525, 0x8658, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A, 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC }, + { 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x2412, 0x4514, 0x1636, 0x1503, 0x4334 }, + { 0x2412, 0x4514, 0x4334, 0x1636, 0x199B, 0x289A, 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC }, + { 0x8478, 0x4445, 0x2412, 0x289A, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x2301, 0x2412, 0x4445, 0x8478, 0x88BC, 0x199B }, + { 0x2301, 0x4514, 0x4445, 0x8478, 0x88BC, 0x289A, 0x1503, 0x1636, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x4445, 0x8478, 0x88BC, 0x199B }, + { 0x1636, 0x1503, 0x4334, 0x8478, 0x8367, 0x4647 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A, 0x8478, 0x8367, 0x4647 }, + { 0x2301, 0x2412, 0x4514, 0x1636, 0x1503, 0x4334, 0x8478, 0x8367, 0x4647 }, + { 0x2412, 0x4514, 0x4334, 0x1636, 0x199B, 0x289A, 0x8478, 0x8367, 0x4647 }, + { 0x8525, 0x2412, 0x289A, 0x89AC, 0x1636, 0x1503, 0x4334, 0x8478, 0x8367, 0x4647 }, + { 0x1636, 0x4334, 0x2301, 0x2412, 0x8525, 0x89AC, 0x199B, 0x8367, 0x8478, 0x4647 }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1636, 0x1503, 0x4334, 0x8478, 0x8367, 0x4647 }, + { 0x1636, 0x4334, 0x4514, 0x8525, 0x89AC, 0x199B, 0x8367, 0x8478, 0x4647 }, + { 0x1636, 0x1503, 0x4334, 0x8478, 0x8367, 0x4647, 0x8525, 0x8658, 0x4445 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A, 0x8478, 0x8367, 0x4647, 0x8525, 0x8658, 0x4445 }, + { 0x2301, 0x2412, 0x4514, 0x1636, 0x1503, 0x4334, 0x8478, 0x8367, 0x4647, 0x8525, 0x8658, 0x4445 }, + { 0x2412, 0x4514, 0x4334, 0x1636, 0x199B, 0x289A, 0x8478, 0x8367, 0x4647, 0x8525, 0x8658, 0x4445 }, + { 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A, 0x8367, 0x8478, 0x4647, 0x1503, 0x1636, 0x4334 }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x4334, 0x1636, 0x199B, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x8658, 0x4445, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1636, 0x1503, 0x4334, 0x8478, 0x8367, 0x4647 }, + { 0x8658, 0x4445, 0x4514, 0x4334, 0x1636, 0x199B, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC, 0x1503, 0x1636, 0x4334 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A, 0x8367, 0x4647, 0x8658, 0x89AC, 0x88BC }, + { 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC, 0x1503, 0x1636, 0x4334, 0x2412, 0x2301, 0x4514 }, + { 0x1636, 0x4334, 0x4514, 0x2412, 0x289A, 0x199B, 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x2412, 0x2301, 0x4334, 0x1636, 0x199B, 0x88BC }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x4514, 0x2301, 0x289A, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x4514, 0x4334, 0x1636, 0x199B, 0x88BC }, + { 0x8525, 0x4445, 0x4647, 0x8367, 0x88BC, 0x89AC, 0x1503, 0x1636, 0x4334 }, + { 0x8367, 0x4647, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x4334, 0x1636, 0x199B, 0x289A }, + { 0x8367, 0x4647, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x2412, 0x4514, 0x1636, 0x1503, 0x4334 }, + { 0x8367, 0x4647, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x2412, 0x4514, 0x4334, 0x1636, 0x199B, 0x289A }, + { 0x8367, 0x4647, 0x4445, 0x2412, 0x289A, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x2301, 0x2412, 0x4445, 0x4647, 0x8367, 0x88BC, 0x199B }, + { 0x8367, 0x4647, 0x4445, 0x4514, 0x2301, 0x289A, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x8367, 0x4647, 0x4445, 0x4514, 0x4334, 0x1636, 0x199B, 0x88BC }, + { 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC }, + { 0x2301, 0x4334, 0x8367, 0x88BC, 0x289A }, + { 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC, 0x2412, 0x2301, 0x4514 }, + { 0x2412, 0x4514, 0x4334, 0x8367, 0x88BC, 0x289A }, + { 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC, 0x2412, 0x8525, 0x89AC, 0x289A }, + { 0x8525, 0x2412, 0x2301, 0x4334, 0x8367, 0x88BC, 0x89AC }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1503, 0x4334, 0x8367, 0x88BC, 0x199B }, + { 0x8367, 0x4334, 0x4514, 0x8525, 0x89AC, 0x88BC }, + { 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC, 0x8658, 0x8525, 0x4445 }, + { 0x2301, 0x4334, 0x8367, 0x88BC, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC, 0x2412, 0x2301, 0x4514, 0x8658, 0x8525, 0x4445 }, + { 0x2412, 0x4514, 0x4334, 0x8367, 0x88BC, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A, 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x4334, 0x8367, 0x88BC, 0x89AC }, + { 0x2301, 0x4514, 0x4445, 0x8658, 0x89AC, 0x289A, 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC }, + { 0x8658, 0x4445, 0x4514, 0x4334, 0x8367, 0x88BC, 0x89AC }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B }, + { 0x8658, 0x8478, 0x8367, 0x4334, 0x2301, 0x289A, 0x89AC }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x2412, 0x4514, 0x4334, 0x8367, 0x8478, 0x8658, 0x89AC, 0x289A }, + { 0x2412, 0x8525, 0x8658, 0x8478, 0x8367, 0x4334, 0x1503, 0x199B, 0x289A }, + { 0x8367, 0x4334, 0x2301, 0x2412, 0x8525, 0x8658, 0x8478 }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x8658, 0x8525, 0x4514, 0x2301, 0x289A, 0x199B }, + { 0x8658, 0x8478, 0x8367, 0x4334, 0x4514, 0x8525 }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x4445, 0x8525, 0x89AC, 0x199B }, + { 0x8525, 0x4445, 0x8478, 0x8367, 0x4334, 0x2301, 0x289A, 0x89AC }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x4445, 0x8525, 0x89AC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x8525, 0x4445, 0x8478, 0x8367, 0x4334, 0x4514, 0x2412, 0x289A, 0x89AC }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x4445, 0x2412, 0x289A, 0x199B }, + { 0x8367, 0x4334, 0x2301, 0x2412, 0x4445, 0x8478 }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x4445, 0x4514, 0x2301, 0x289A, 0x199B }, + { 0x8367, 0x4334, 0x4514, 0x4445, 0x8478 }, + { 0x1503, 0x4334, 0x4647, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4647, 0x4334, 0x2301, 0x289A, 0x88BC }, + { 0x8478, 0x4647, 0x4334, 0x1503, 0x199B, 0x88BC, 0x2412, 0x2301, 0x4514 }, + { 0x8478, 0x4647, 0x4334, 0x4514, 0x2412, 0x289A, 0x88BC }, + { 0x1503, 0x4334, 0x4647, 0x8478, 0x88BC, 0x199B, 0x8525, 0x2412, 0x289A, 0x89AC }, + { 0x8478, 0x4647, 0x4334, 0x2301, 0x2412, 0x8525, 0x89AC, 0x88BC }, + { 0x1503, 0x4334, 0x4647, 0x8478, 0x88BC, 0x199B, 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC }, + { 0x8478, 0x4647, 0x4334, 0x4514, 0x8525, 0x89AC, 0x88BC }, + { 0x1503, 0x4334, 0x4647, 0x8478, 0x88BC, 0x199B, 0x8525, 0x8658, 0x4445 }, + { 0x8478, 0x4647, 0x4334, 0x2301, 0x289A, 0x88BC, 0x8658, 0x8525, 0x4445 }, + { 0x1503, 0x4334, 0x4647, 0x8478, 0x88BC, 0x199B, 0x8525, 0x8658, 0x4445, 0x2301, 0x2412, 0x4514 }, + { 0x2412, 0x4514, 0x4334, 0x4647, 0x8478, 0x88BC, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x8478, 0x4647, 0x4334, 0x1503, 0x199B, 0x88BC, 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x4334, 0x4647, 0x8478, 0x88BC, 0x89AC }, + { 0x8658, 0x4445, 0x4514, 0x2301, 0x289A, 0x89AC, 0x1503, 0x4334, 0x4647, 0x8478, 0x88BC, 0x199B }, + { 0x8658, 0x4445, 0x4514, 0x4334, 0x4647, 0x8478, 0x88BC, 0x89AC }, + { 0x1503, 0x4334, 0x4647, 0x8658, 0x89AC, 0x199B }, + { 0x8658, 0x4647, 0x4334, 0x2301, 0x289A, 0x89AC }, + { 0x1503, 0x4334, 0x4647, 0x8658, 0x89AC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x2412, 0x4514, 0x4334, 0x4647, 0x8658, 0x89AC, 0x289A }, + { 0x1503, 0x4334, 0x4647, 0x8658, 0x8525, 0x2412, 0x289A, 0x199B }, + { 0x2412, 0x8525, 0x8658, 0x4647, 0x4334, 0x2301 }, + { 0x2301, 0x4514, 0x8525, 0x8658, 0x4647, 0x4334, 0x1503, 0x199B, 0x289A }, + { 0x8658, 0x4647, 0x4334, 0x4514, 0x8525 }, + { 0x8525, 0x4445, 0x4647, 0x4334, 0x1503, 0x199B, 0x89AC }, + { 0x8525, 0x4445, 0x4647, 0x4334, 0x2301, 0x289A, 0x89AC }, + { 0x1503, 0x4334, 0x4647, 0x4445, 0x8525, 0x89AC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x2412, 0x4514, 0x4334, 0x4647, 0x4445, 0x8525, 0x89AC, 0x289A }, + { 0x1503, 0x4334, 0x4647, 0x4445, 0x2412, 0x289A, 0x199B }, + { 0x2412, 0x4445, 0x4647, 0x4334, 0x2301 }, + { 0x1503, 0x4334, 0x4647, 0x4445, 0x4514, 0x2301, 0x289A, 0x199B }, + { 0x4514, 0x4445, 0x4647, 0x4334 }, + { 0x4514, 0x4445, 0x4647, 0x4334 }, + { 0x2301, 0x1503, 0x199B, 0x289A, 0x4334, 0x4514, 0x4445, 0x4647 }, + { 0x2412, 0x4445, 0x4647, 0x4334, 0x2301 }, + { 0x1503, 0x4334, 0x4647, 0x4445, 0x2412, 0x289A, 0x199B }, + { 0x8525, 0x2412, 0x289A, 0x89AC, 0x4514, 0x4445, 0x4647, 0x4334 }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC, 0x4514, 0x4445, 0x4647, 0x4334 }, + { 0x8525, 0x4445, 0x4647, 0x4334, 0x2301, 0x289A, 0x89AC }, + { 0x8525, 0x4445, 0x4647, 0x4334, 0x1503, 0x199B, 0x89AC }, + { 0x8658, 0x4647, 0x4334, 0x4514, 0x8525 }, + { 0x1503, 0x2301, 0x289A, 0x199B, 0x8525, 0x4514, 0x4334, 0x4647, 0x8658 }, + { 0x2412, 0x8525, 0x8658, 0x4647, 0x4334, 0x2301 }, + { 0x1503, 0x4334, 0x4647, 0x8658, 0x8525, 0x2412, 0x289A, 0x199B }, + { 0x2412, 0x4514, 0x4334, 0x4647, 0x8658, 0x89AC, 0x289A }, + { 0x8658, 0x4647, 0x4334, 0x4514, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC }, + { 0x8658, 0x4647, 0x4334, 0x2301, 0x289A, 0x89AC }, + { 0x1503, 0x4334, 0x4647, 0x8658, 0x89AC, 0x199B }, + { 0x8478, 0x8658, 0x89AC, 0x88BC, 0x4445, 0x4647, 0x4334, 0x4514 }, + { 0x2301, 0x1503, 0x199B, 0x289A, 0x8478, 0x8658, 0x89AC, 0x88BC, 0x4334, 0x4514, 0x4445, 0x4647 }, + { 0x8478, 0x8658, 0x89AC, 0x88BC, 0x2412, 0x4445, 0x4647, 0x4334, 0x2301 }, + { 0x1503, 0x4334, 0x4647, 0x4445, 0x2412, 0x289A, 0x199B, 0x8658, 0x8478, 0x88BC, 0x89AC }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC, 0x4445, 0x4647, 0x4334, 0x4514 }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x88BC, 0x4514, 0x4445, 0x4647, 0x4334 }, + { 0x2301, 0x4334, 0x4647, 0x4445, 0x8525, 0x8658, 0x8478, 0x88BC, 0x289A }, + { 0x8478, 0x8658, 0x8525, 0x4445, 0x4647, 0x4334, 0x1503, 0x199B, 0x88BC }, + { 0x8478, 0x4647, 0x4334, 0x4514, 0x8525, 0x89AC, 0x88BC }, + { 0x8478, 0x4647, 0x4334, 0x4514, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x1503, 0x199B, 0x289A }, + { 0x8478, 0x4647, 0x4334, 0x2301, 0x2412, 0x8525, 0x89AC, 0x88BC }, + { 0x8478, 0x4647, 0x4334, 0x1503, 0x2412, 0x8525, 0x199B, 0x289A, 0x89AC, 0x88BC }, + { 0x8478, 0x4647, 0x4334, 0x4514, 0x2412, 0x289A, 0x88BC }, + { 0x1503, 0x2301, 0x2412, 0x4514, 0x4334, 0x4647, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4647, 0x4334, 0x2301, 0x289A, 0x88BC }, + { 0x1503, 0x4334, 0x4647, 0x8478, 0x88BC, 0x199B }, + { 0x8367, 0x4334, 0x4514, 0x4445, 0x8478 }, + { 0x2301, 0x1503, 0x199B, 0x289A, 0x8367, 0x4334, 0x4514, 0x4445, 0x8478 }, + { 0x8367, 0x4334, 0x2301, 0x2412, 0x4445, 0x8478 }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x4445, 0x2412, 0x289A, 0x199B }, + { 0x2412, 0x8525, 0x89AC, 0x289A, 0x8478, 0x4445, 0x4514, 0x4334, 0x8367 }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC, 0x8367, 0x4334, 0x4514, 0x4445, 0x8478 }, + { 0x8525, 0x4445, 0x8478, 0x8367, 0x4334, 0x2301, 0x289A, 0x89AC }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x4445, 0x8525, 0x89AC, 0x199B }, + { 0x8658, 0x8478, 0x8367, 0x4334, 0x4514, 0x8525 }, + { 0x2301, 0x1503, 0x199B, 0x289A, 0x8367, 0x4334, 0x4514, 0x8525, 0x8658, 0x8478 }, + { 0x8367, 0x4334, 0x2301, 0x2412, 0x8525, 0x8658, 0x8478 }, + { 0x2412, 0x8525, 0x8658, 0x8478, 0x8367, 0x4334, 0x1503, 0x199B, 0x289A }, + { 0x2412, 0x4514, 0x4334, 0x8367, 0x8478, 0x8658, 0x89AC, 0x289A }, + { 0x8658, 0x8478, 0x8367, 0x4334, 0x4514, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC }, + { 0x8658, 0x8478, 0x8367, 0x4334, 0x2301, 0x289A, 0x89AC }, + { 0x1503, 0x4334, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B }, + { 0x8658, 0x4445, 0x4514, 0x4334, 0x8367, 0x88BC, 0x89AC }, + { 0x8658, 0x4445, 0x4514, 0x4334, 0x8367, 0x88BC, 0x89AC, 0x1503, 0x2301, 0x289A, 0x199B }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x4334, 0x8367, 0x88BC, 0x89AC }, + { 0x8658, 0x4445, 0x2412, 0x1503, 0x4334, 0x8367, 0x289A, 0x199B, 0x88BC, 0x89AC }, + { 0x8367, 0x4334, 0x4514, 0x4445, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC }, + { 0x1503, 0x2301, 0x2412, 0x8525, 0x8658, 0x4445, 0x4514, 0x4334, 0x8367, 0x88BC, 0x199B }, + { 0x2301, 0x4334, 0x8367, 0x88BC, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC, 0x8658, 0x8525, 0x4445 }, + { 0x8367, 0x4334, 0x4514, 0x8525, 0x89AC, 0x88BC }, + { 0x8367, 0x4334, 0x4514, 0x8525, 0x89AC, 0x88BC, 0x2301, 0x1503, 0x199B, 0x289A }, + { 0x8525, 0x2412, 0x2301, 0x4334, 0x8367, 0x88BC, 0x89AC }, + { 0x1503, 0x4334, 0x8367, 0x8525, 0x2412, 0x88BC, 0x89AC, 0x289A, 0x199B }, + { 0x2412, 0x4514, 0x4334, 0x8367, 0x88BC, 0x289A }, + { 0x1503, 0x2301, 0x2412, 0x4514, 0x4334, 0x8367, 0x88BC, 0x199B }, + { 0x2301, 0x4334, 0x8367, 0x88BC, 0x289A }, + { 0x8367, 0x4334, 0x1503, 0x199B, 0x88BC }, + { 0x1636, 0x8367, 0x88BC, 0x199B, 0x4647, 0x4334, 0x4514, 0x4445 }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A, 0x4334, 0x4514, 0x4445, 0x4647 }, + { 0x8367, 0x1636, 0x199B, 0x88BC, 0x2301, 0x4334, 0x4647, 0x4445, 0x2412 }, + { 0x2412, 0x4445, 0x4647, 0x4334, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A }, + { 0x8525, 0x2412, 0x289A, 0x89AC, 0x1636, 0x8367, 0x88BC, 0x199B, 0x4514, 0x4445, 0x4647, 0x4334 }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x89AC, 0x4334, 0x4514, 0x4445, 0x4647 }, + { 0x8525, 0x4445, 0x4647, 0x4334, 0x2301, 0x289A, 0x89AC, 0x1636, 0x8367, 0x88BC, 0x199B }, + { 0x8367, 0x1636, 0x1503, 0x4334, 0x4647, 0x4445, 0x8525, 0x89AC, 0x88BC }, + { 0x1636, 0x8367, 0x88BC, 0x199B, 0x8658, 0x4647, 0x4334, 0x4514, 0x8525 }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A, 0x8658, 0x4647, 0x4334, 0x4514, 0x8525 }, + { 0x1636, 0x8367, 0x88BC, 0x199B, 0x8658, 0x4647, 0x4334, 0x2301, 0x2412, 0x8525 }, + { 0x2412, 0x8525, 0x8658, 0x4647, 0x4334, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A }, + { 0x2412, 0x4514, 0x4334, 0x4647, 0x8658, 0x89AC, 0x289A, 0x8367, 0x1636, 0x199B, 0x88BC }, + { 0x8367, 0x1636, 0x1503, 0x2301, 0x2412, 0x4514, 0x4334, 0x4647, 0x8658, 0x89AC, 0x88BC }, + { 0x8658, 0x4647, 0x4334, 0x2301, 0x289A, 0x89AC, 0x1636, 0x8367, 0x88BC, 0x199B }, + { 0x8367, 0x1636, 0x1503, 0x4334, 0x4647, 0x8658, 0x89AC, 0x88BC }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B, 0x4647, 0x4334, 0x4514, 0x4445 }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x289A, 0x4647, 0x4334, 0x4514, 0x4445 }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B, 0x2412, 0x4445, 0x4647, 0x4334, 0x2301 }, + { 0x8658, 0x8478, 0x8367, 0x1636, 0x1503, 0x4334, 0x4647, 0x4445, 0x2412, 0x289A, 0x89AC }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x199B, 0x4445, 0x4647, 0x4334, 0x4514 }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x2412, 0x4334, 0x4514, 0x4445, 0x4647 }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x4445, 0x4647, 0x4334, 0x2301, 0x289A, 0x199B }, + { 0x1503, 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x4445, 0x4647, 0x4334 }, + { 0x8525, 0x4514, 0x4334, 0x4647, 0x8478, 0x8367, 0x1636, 0x199B, 0x89AC }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x8478, 0x4647, 0x4334, 0x4514, 0x8525, 0x89AC, 0x289A }, + { 0x8525, 0x2412, 0x2301, 0x4334, 0x4647, 0x8478, 0x8367, 0x1636, 0x199B, 0x89AC }, + { 0x2412, 0x8525, 0x89AC, 0x289A, 0x1503, 0x1636, 0x8367, 0x8478, 0x4647, 0x4334 }, + { 0x1636, 0x8367, 0x8478, 0x4647, 0x4334, 0x4514, 0x2412, 0x289A, 0x199B }, + { 0x2412, 0x2301, 0x1503, 0x1636, 0x8367, 0x8478, 0x4647, 0x4334, 0x4514 }, + { 0x1636, 0x8367, 0x8478, 0x4647, 0x4334, 0x2301, 0x289A, 0x199B }, + { 0x1636, 0x8367, 0x8478, 0x4647, 0x4334, 0x1503 }, + { 0x1636, 0x4334, 0x4514, 0x4445, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4445, 0x4514, 0x4334, 0x1636, 0x1503, 0x2301, 0x289A, 0x88BC }, + { 0x1636, 0x4334, 0x2301, 0x2412, 0x4445, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4445, 0x2412, 0x289A, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x4445, 0x8478, 0x88BC, 0x199B, 0x8525, 0x2412, 0x289A, 0x89AC }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x1636, 0x4334, 0x4514, 0x4445, 0x8478, 0x88BC, 0x89AC }, + { 0x1636, 0x4334, 0x2301, 0x8525, 0x4445, 0x8478, 0x289A, 0x89AC, 0x88BC, 0x199B }, + { 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x8525, 0x8658, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x8658, 0x8525, 0x4514, 0x4334, 0x1636, 0x1503, 0x2301, 0x289A, 0x88BC }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x4334, 0x1636, 0x199B, 0x88BC }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC, 0x1636, 0x1503, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x2412, 0x8658, 0x8478, 0x289A, 0x89AC, 0x88BC, 0x199B }, + { 0x8658, 0x8478, 0x88BC, 0x89AC, 0x2412, 0x2301, 0x1503, 0x1636, 0x4334, 0x4514 }, + { 0x1636, 0x4334, 0x2301, 0x8658, 0x8478, 0x289A, 0x89AC, 0x88BC, 0x199B }, + { 0x8658, 0x8478, 0x88BC, 0x89AC, 0x1503, 0x1636, 0x4334 }, + { 0x1636, 0x4334, 0x4514, 0x4445, 0x8658, 0x89AC, 0x199B }, + { 0x2301, 0x1503, 0x1636, 0x4334, 0x4514, 0x4445, 0x8658, 0x89AC, 0x289A }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x4334, 0x1636, 0x199B, 0x89AC }, + { 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A, 0x1503, 0x1636, 0x4334 }, + { 0x2412, 0x8525, 0x8658, 0x4445, 0x4514, 0x4334, 0x1636, 0x199B, 0x289A }, + { 0x8658, 0x8525, 0x2412, 0x2301, 0x1503, 0x1636, 0x4334, 0x4514, 0x4445 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x1636, 0x1503, 0x4334, 0x8525, 0x8658, 0x4445 }, + { 0x1636, 0x4334, 0x4514, 0x8525, 0x89AC, 0x199B }, + { 0x2301, 0x1503, 0x1636, 0x4334, 0x4514, 0x8525, 0x89AC, 0x289A }, + { 0x1636, 0x4334, 0x2301, 0x2412, 0x8525, 0x89AC, 0x199B }, + { 0x8525, 0x2412, 0x289A, 0x89AC, 0x1636, 0x1503, 0x4334 }, + { 0x2412, 0x4514, 0x4334, 0x1636, 0x199B, 0x289A }, + { 0x2301, 0x1503, 0x1636, 0x4334, 0x4514, 0x2412 }, + { 0x2301, 0x4334, 0x1636, 0x199B, 0x289A }, + { 0x1636, 0x1503, 0x4334 }, + { 0x1503, 0x4514, 0x4445, 0x4647, 0x1636 }, + { 0x2301, 0x4514, 0x4445, 0x4647, 0x1636, 0x199B, 0x289A }, + { 0x1503, 0x2301, 0x2412, 0x4445, 0x4647, 0x1636 }, + { 0x2412, 0x4445, 0x4647, 0x1636, 0x199B, 0x289A }, + { 0x8525, 0x2412, 0x289A, 0x89AC, 0x1503, 0x4514, 0x4445, 0x4647, 0x1636 }, + { 0x1636, 0x4647, 0x4445, 0x4514, 0x2301, 0x2412, 0x8525, 0x89AC, 0x199B }, + { 0x8525, 0x4445, 0x4647, 0x1636, 0x1503, 0x2301, 0x289A, 0x89AC }, + { 0x8525, 0x4445, 0x4647, 0x1636, 0x199B, 0x89AC }, + { 0x1503, 0x4514, 0x8525, 0x8658, 0x4647, 0x1636 }, + { 0x2301, 0x4514, 0x8525, 0x8658, 0x4647, 0x1636, 0x199B, 0x289A }, + { 0x8658, 0x4647, 0x1636, 0x1503, 0x2301, 0x2412, 0x8525 }, + { 0x2412, 0x8525, 0x8658, 0x4647, 0x1636, 0x199B, 0x289A }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x4647, 0x8658, 0x89AC, 0x289A }, + { 0x1636, 0x4647, 0x8658, 0x89AC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x2301, 0x1503, 0x1636, 0x4647, 0x8658, 0x89AC, 0x289A }, + { 0x1636, 0x4647, 0x8658, 0x89AC, 0x199B }, + { 0x8658, 0x8478, 0x88BC, 0x89AC, 0x1636, 0x4647, 0x4445, 0x4514, 0x1503 }, + { 0x2301, 0x4514, 0x4445, 0x4647, 0x1636, 0x199B, 0x289A, 0x8478, 0x8658, 0x89AC, 0x88BC }, + { 0x8478, 0x8658, 0x89AC, 0x88BC, 0x2412, 0x4445, 0x4647, 0x1636, 0x1503, 0x2301 }, + { 0x2412, 0x4445, 0x4647, 0x1636, 0x199B, 0x289A, 0x8478, 0x8658, 0x89AC, 0x88BC }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC, 0x1503, 0x4514, 0x4445, 0x4647, 0x1636 }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x4514, 0x4445, 0x4647, 0x1636, 0x199B, 0x88BC }, + { 0x2301, 0x1503, 0x1636, 0x4647, 0x4445, 0x8525, 0x8658, 0x8478, 0x88BC, 0x289A }, + { 0x8478, 0x8658, 0x8525, 0x4445, 0x4647, 0x1636, 0x199B, 0x88BC }, + { 0x8478, 0x4647, 0x1636, 0x1503, 0x4514, 0x8525, 0x89AC, 0x88BC }, + { 0x2301, 0x4514, 0x8525, 0x8478, 0x4647, 0x1636, 0x89AC, 0x88BC, 0x199B, 0x289A }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x1636, 0x4647, 0x8478, 0x88BC, 0x89AC }, + { 0x8478, 0x4647, 0x1636, 0x2412, 0x8525, 0x199B, 0x289A, 0x89AC, 0x88BC }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x4647, 0x8478, 0x88BC, 0x289A }, + { 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x8478, 0x4647, 0x1636, 0x1503, 0x2301, 0x289A, 0x88BC }, + { 0x1636, 0x4647, 0x8478, 0x88BC, 0x199B }, + { 0x8367, 0x1636, 0x1503, 0x4514, 0x4445, 0x8478 }, + { 0x2301, 0x4514, 0x4445, 0x8478, 0x8367, 0x1636, 0x199B, 0x289A }, + { 0x2412, 0x4445, 0x8478, 0x8367, 0x1636, 0x1503, 0x2301 }, + { 0x1636, 0x8367, 0x8478, 0x4445, 0x2412, 0x289A, 0x199B }, + { 0x8525, 0x2412, 0x289A, 0x89AC, 0x1503, 0x4514, 0x4445, 0x8478, 0x8367, 0x1636 }, + { 0x1636, 0x8367, 0x8478, 0x4445, 0x4514, 0x2301, 0x2412, 0x8525, 0x89AC, 0x199B }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x8478, 0x4445, 0x8525, 0x89AC, 0x289A }, + { 0x8525, 0x4445, 0x8478, 0x8367, 0x1636, 0x199B, 0x89AC }, + { 0x1503, 0x4514, 0x8525, 0x8658, 0x8478, 0x8367, 0x1636 }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x4514, 0x2301, 0x289A, 0x199B }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x1503 }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x199B }, + { 0x8658, 0x8478, 0x8367, 0x1636, 0x1503, 0x4514, 0x2412, 0x289A, 0x89AC }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B, 0x2301, 0x2412, 0x4514 }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x289A }, + { 0x1636, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B }, + { 0x8658, 0x4445, 0x4514, 0x1503, 0x1636, 0x8367, 0x88BC, 0x89AC }, + { 0x2301, 0x4514, 0x4445, 0x8658, 0x8367, 0x1636, 0x89AC, 0x88BC, 0x199B, 0x289A }, + { 0x8367, 0x1636, 0x1503, 0x2301, 0x2412, 0x4445, 0x8658, 0x89AC, 0x88BC }, + { 0x8658, 0x4445, 0x2412, 0x1636, 0x8367, 0x289A, 0x199B, 0x88BC, 0x89AC }, + { 0x8367, 0x1636, 0x1503, 0x4514, 0x4445, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC }, + { 0x8367, 0x1636, 0x199B, 0x88BC, 0x8658, 0x8525, 0x2412, 0x2301, 0x4514, 0x4445 }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A, 0x8525, 0x8658, 0x4445 }, + { 0x1636, 0x8367, 0x88BC, 0x199B, 0x8525, 0x8658, 0x4445 }, + { 0x8367, 0x1636, 0x1503, 0x4514, 0x8525, 0x89AC, 0x88BC }, + { 0x2301, 0x4514, 0x8525, 0x8367, 0x1636, 0x89AC, 0x88BC, 0x199B, 0x289A }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x89AC }, + { 0x2412, 0x8525, 0x8367, 0x1636, 0x89AC, 0x88BC, 0x199B, 0x289A }, + { 0x2412, 0x4514, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A }, + { 0x8367, 0x1636, 0x199B, 0x88BC, 0x2412, 0x2301, 0x4514 }, + { 0x2301, 0x1503, 0x1636, 0x8367, 0x88BC, 0x289A }, + { 0x1636, 0x8367, 0x88BC, 0x199B }, + { 0x8367, 0x4647, 0x4445, 0x4514, 0x1503, 0x199B, 0x88BC }, + { 0x2301, 0x4514, 0x4445, 0x4647, 0x8367, 0x88BC, 0x289A }, + { 0x8367, 0x4647, 0x4445, 0x2412, 0x2301, 0x1503, 0x199B, 0x88BC }, + { 0x8367, 0x4647, 0x4445, 0x2412, 0x289A, 0x88BC }, + { 0x8367, 0x4647, 0x4445, 0x4514, 0x1503, 0x199B, 0x88BC, 0x2412, 0x8525, 0x89AC, 0x289A }, + { 0x8525, 0x2412, 0x2301, 0x4514, 0x4445, 0x4647, 0x8367, 0x88BC, 0x89AC }, + { 0x8525, 0x4445, 0x4647, 0x8367, 0x1503, 0x2301, 0x88BC, 0x199B, 0x289A, 0x89AC }, + { 0x8367, 0x4647, 0x4445, 0x8525, 0x89AC, 0x88BC }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x4514, 0x1503, 0x199B, 0x88BC }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x4514, 0x2301, 0x289A, 0x88BC }, + { 0x1503, 0x2301, 0x2412, 0x8525, 0x8658, 0x4647, 0x8367, 0x88BC, 0x199B }, + { 0x8367, 0x4647, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC }, + { 0x2412, 0x4514, 0x1503, 0x8367, 0x4647, 0x8658, 0x199B, 0x88BC, 0x89AC, 0x289A }, + { 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC, 0x2412, 0x2301, 0x4514 }, + { 0x8367, 0x4647, 0x8658, 0x2301, 0x1503, 0x89AC, 0x289A, 0x199B, 0x88BC }, + { 0x8658, 0x4647, 0x8367, 0x88BC, 0x89AC }, + { 0x1503, 0x4514, 0x4445, 0x4647, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B }, + { 0x8658, 0x8478, 0x8367, 0x4647, 0x4445, 0x4514, 0x2301, 0x289A, 0x89AC }, + { 0x1503, 0x2301, 0x2412, 0x4445, 0x4647, 0x8367, 0x8478, 0x8658, 0x89AC, 0x199B }, + { 0x8658, 0x8478, 0x8367, 0x4647, 0x4445, 0x2412, 0x289A, 0x89AC }, + { 0x2412, 0x8525, 0x8658, 0x8478, 0x8367, 0x4647, 0x4445, 0x4514, 0x1503, 0x199B, 0x289A }, + { 0x8367, 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x4514, 0x4445, 0x4647 }, + { 0x1503, 0x2301, 0x289A, 0x199B, 0x8367, 0x8478, 0x8658, 0x8525, 0x4445, 0x4647 }, + { 0x8478, 0x8658, 0x8525, 0x4445, 0x4647, 0x8367 }, + { 0x8525, 0x4514, 0x1503, 0x199B, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC, 0x8478, 0x8367, 0x4647 }, + { 0x2412, 0x8525, 0x89AC, 0x289A, 0x8367, 0x8478, 0x4647 }, + { 0x1503, 0x4514, 0x2412, 0x289A, 0x199B, 0x8367, 0x8478, 0x4647 }, + { 0x2301, 0x2412, 0x4514, 0x8478, 0x8367, 0x4647 }, + { 0x2301, 0x1503, 0x199B, 0x289A, 0x8478, 0x8367, 0x4647 }, + { 0x8478, 0x8367, 0x4647 }, + { 0x1503, 0x4514, 0x4445, 0x8478, 0x88BC, 0x199B }, + { 0x2301, 0x4514, 0x4445, 0x8478, 0x88BC, 0x289A }, + { 0x1503, 0x2301, 0x2412, 0x4445, 0x8478, 0x88BC, 0x199B }, + { 0x8478, 0x4445, 0x2412, 0x289A, 0x88BC }, + { 0x1503, 0x4514, 0x4445, 0x8478, 0x88BC, 0x199B, 0x8525, 0x2412, 0x289A, 0x89AC }, + { 0x8525, 0x2412, 0x2301, 0x4514, 0x4445, 0x8478, 0x88BC, 0x89AC }, + { 0x8525, 0x4445, 0x8478, 0x1503, 0x2301, 0x88BC, 0x199B, 0x289A, 0x89AC }, + { 0x8478, 0x4445, 0x8525, 0x89AC, 0x88BC }, + { 0x8478, 0x8658, 0x8525, 0x4514, 0x1503, 0x199B, 0x88BC }, + { 0x2301, 0x4514, 0x8525, 0x8658, 0x8478, 0x88BC, 0x289A }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x88BC }, + { 0x8478, 0x8658, 0x8525, 0x2412, 0x289A, 0x88BC }, + { 0x2412, 0x4514, 0x1503, 0x8478, 0x8658, 0x199B, 0x88BC, 0x89AC, 0x289A }, + { 0x8478, 0x8658, 0x89AC, 0x88BC, 0x2301, 0x2412, 0x4514 }, + { 0x1503, 0x2301, 0x8658, 0x8478, 0x289A, 0x89AC, 0x88BC, 0x199B }, + { 0x8478, 0x8658, 0x89AC, 0x88BC }, + { 0x8658, 0x4445, 0x4514, 0x1503, 0x199B, 0x89AC }, + { 0x8658, 0x4445, 0x4514, 0x2301, 0x289A, 0x89AC }, + { 0x8658, 0x4445, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC }, + { 0x2412, 0x4445, 0x8658, 0x89AC, 0x289A }, + { 0x2412, 0x8525, 0x8658, 0x4445, 0x4514, 0x1503, 0x199B, 0x289A }, + { 0x8525, 0x2412, 0x2301, 0x4514, 0x4445, 0x8658 }, + { 0x1503, 0x2301, 0x289A, 0x199B, 0x8658, 0x8525, 0x4445 }, + { 0x8525, 0x8658, 0x4445 }, + { 0x8525, 0x4514, 0x1503, 0x199B, 0x89AC }, + { 0x8525, 0x4514, 0x2301, 0x289A, 0x89AC }, + { 0x8525, 0x2412, 0x2301, 0x1503, 0x199B, 0x89AC }, + { 0x8525, 0x2412, 0x289A, 0x89AC }, + { 0x1503, 0x4514, 0x2412, 0x289A, 0x199B }, + { 0x2301, 0x2412, 0x4514 }, + { 0x2301, 0x1503, 0x199B, 0x289A }, + {} +}; + +const Vector3 transvoxel_vertices[8] = { + Vector3(0, 0, 0), + Vector3(1, 0, 0), + Vector3(0, 0, 1), + Vector3(1, 0, 1), + Vector3(0, 1, 0), + Vector3(1, 1, 0), + Vector3(0, 1, 1), + Vector3(1, 1, 1) +}; + +} // namespace Transvoxel diff --git a/meshers/transvoxel_tables.h b/meshers/transvoxel_tables.h new file mode 100644 index 0000000..b58fc61 --- /dev/null +++ b/meshers/transvoxel_tables.h @@ -0,0 +1,86 @@ +//================================================================================ +// +// The Transvoxel Algorithm look-up tables +// +// Copyright 2009 by Eric Lengyel +// +// The following data originates from Eric Lengyel's Transvoxel Algorithm. +// http://transvoxel.org/ +// +// The data in this file may be freely used in implementations of the Transvoxel +// Algorithm. If you do use this data, or any transformation of it, in your own +// projects, commercial or otherwise, please give credit by indicating in your +// source code that the data is part of the author's implementation of the +// Transvoxel Algorithm and that it came from the web address given above. +// (Simply copying and pasting the two lines of the previous paragraph would be +// perfect.) If you distribute a commercial product with source code included, +// then the credit in the source code is required. +// +// If you distribute any kind of product that uses this data, a credit visible to +// the end-user would be appreciated, but it is not required. However, you may +// not claim that the entire implementation of the Transvoxel Algorithm is your +// own if you use the data in this file or any transformation of it. +// +// The format of the data in this file is described in the dissertation "Voxel- +// Based Terrain for Real-Time Virtual Simulations", available at the web page +// given above. References to sections and figures below pertain to that paper. +// +// The contents of this file are protected by copyright and may not be publicly +// reproduced without permission. +// +//================================================================================ + +#ifndef TRANSVOXEL_TABLES_H +#define TRANSVOXEL_TABLES_H + +#include "core/math/vector3.h" + +namespace Transvoxel { + +// The RegularCellData structure holds information about the triangulation +// used for a single equivalence class in the modified Marching Cubes algorithm, +// described in Section 3.2. + +struct RegularCellData { + unsigned char geometryCounts; // High nibble is vertex count, low nibble is triangle count. + unsigned char vertexIndex[15]; // Groups of 3 indexes giving the triangulation. + + long GetVertexCount(void) const { + return (geometryCounts >> 4); + } + + long GetTriangleCount(void) const { + return (geometryCounts & 0x0F); + } +}; + +// The TransitionCellData structure holds information about the triangulation +// used for a single equivalence class in the Transvoxel Algorithm transition cell, +// described in Section 4.3. + +struct TransitionCellData { + long geometryCounts; // High nibble is vertex count, low nibble is triangle count. + unsigned char vertexIndex[36]; // Groups of 3 indexes giving the triangulation. + + long GetVertexCount(void) const { + return (geometryCounts >> 4); + } + + long GetTriangleCount(void) const { + return (geometryCounts & 0x0F); + } +}; + +extern const unsigned char regularCellClass[256]; +extern const RegularCellData regularCellData[16]; +extern const unsigned short regularVertexData[256][12]; +extern const unsigned char transitionCellClass[512]; +extern const TransitionCellData transitionCellData[56]; +extern const unsigned char transitionCornerData[13]; +extern const unsigned short transitionVertexData[512][12]; + +extern const Vector3 transvoxel_vertices[8]; + +} // namespace Transvoxel + +#endif diff --git a/meshers/voxel_mesh_data.cpp b/meshers/voxel_mesh_data.cpp new file mode 100644 index 0000000..0cef6bb --- /dev/null +++ b/meshers/voxel_mesh_data.cpp @@ -0,0 +1,81 @@ +#include "voxel_mesh_data.h" + +Ref VoxelMeshData::get_material() { + return _material; +} + +void VoxelMeshData::set_material(Ref material) { + _material = material; +} + +Ref VoxelMeshData::create_mesh() { + _surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES); + _surface_tool->set_material(_material); + + int len = _vertices->size(); + + for (int i = 0; i < len; ++i) { + _surface_tool->add_normal(_normals->get(i)); + //_surface_tool->add_color(_colors->get(i)); + //_surface_tool->add_uv(_uvs->get(i)); + + _surface_tool->add_vertex(_vertices->get(i)); + } + + for (int i = 0; i < _indices->size(); ++i) { + _surface_tool->add_index(_indices->get(i)); + } + + Ref m = _surface_tool->commit(); + + return m; +} + +void VoxelMeshData::add_vertices_from(Vector &vertices) { + _vertices->append_array(vertices); +} + +void VoxelMeshData::add_normals_from(Vector &normals) { + _normals->append_array(normals); +} + +void VoxelMeshData::add_indices_from(Vector &indices) { + _indices->append_array(indices); +} + +void VoxelMeshData::add_vertex(Vector3 vertex) { + _vertices->push_back(vertex); +} + +void VoxelMeshData::add_normal(Vector3 normal) { + _normals->push_back(normal); +} + +void VoxelMeshData::add_index(int iundex) { + _indices->push_back(iundex); +} + +void VoxelMeshData::clear() { + _vertices->clear(); + _normals->clear(); + _indices->clear(); +} + +VoxelMeshData::VoxelMeshData() { + _vertices = memnew(Vector()); + _normals = memnew(Vector()); + _indices = memnew(Vector()); + + _surface_tool.instance(); +} + +VoxelMeshData::~VoxelMeshData() { + memdelete(_vertices); + memdelete(_normals); + memdelete(_indices); + + _surface_tool.unref(); +} + +void VoxelMeshData::_bind_methods() { +} diff --git a/meshers/voxel_mesh_data.h b/meshers/voxel_mesh_data.h new file mode 100644 index 0000000..cbe64b0 --- /dev/null +++ b/meshers/voxel_mesh_data.h @@ -0,0 +1,45 @@ +#ifndef VOXEL_MESH_DATA_H +#define VOXEL_MESH_DATA_H + +#include "core/reference.h" +#include "core/vector.h" +#include "scene/resources/mesh.h" +#include "scene/resources/surface_tool.h" +#include "scene/resources/material.h" + +class VoxelMeshData : public Reference { + GDCLASS(VoxelMeshData, Reference) + +public: + Ref get_material(); + void set_material(Ref material); + + Ref create_mesh(); + + void add_vertex(Vector3 vertex); + void add_normal(Vector3 normal); + void add_index(int iundex); + + void add_vertices_from(Vector &vertices); + void add_normals_from(Vector &normals); + void add_indices_from(Vector &indices); + + void clear(); + + VoxelMeshData(); + ~VoxelMeshData(); + +protected: + static void _bind_methods(); + +private: + Ref _material; + + Vector *_vertices; + Vector *_normals; + Vector *_indices; + + Ref _surface_tool; +}; + +#endif diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp new file mode 100644 index 0000000..5a0b2f1 --- /dev/null +++ b/meshers/voxel_mesher.cpp @@ -0,0 +1,379 @@ +#include "voxel_mesher.h" + +VoxelMesher::VoxelMesher(Ref library) { + _library = library; + + _vertices = memnew(Vector()); + _normals = memnew(Vector()); + _colors = memnew(Vector()); + _uvs = memnew(Vector()); + _indices = memnew(Vector()); + _bones = memnew(Vector()); + + _debug_voxel_face = false; + size = (float)1; + vertexOffset = Vector3((float)0.5, (float)0.5, (float)0.5); + + _surface_tool = memnew(SurfaceTool()); +} + +VoxelMesher::VoxelMesher() { + _vertices = memnew(Vector()); + _normals = memnew(Vector()); + _colors = memnew(Vector()); + _uvs = memnew(Vector()); + _indices = memnew(Vector()); + _bones = memnew(Vector()); + + _debug_voxel_face = false; + size = (float)1; + vertexOffset = Vector3((float)0.5, (float)0.5, (float)0.5); + + _surface_tool = memnew(SurfaceTool()); +} + +VoxelMesher::~VoxelMesher() { + memdelete(_vertices); + memdelete(_normals); + memdelete(_colors); + memdelete(_uvs); + memdelete(_indices); + memdelete(_bones); + memdelete(_surface_tool); +} + +Ref VoxelMesher::build_mesh() { + _surface_tool->begin(Mesh::PRIMITIVE_TRIANGLES); + _surface_tool->set_material(_library->get_material()); + + int len = _vertices->size(); + + for (int i = 0; i < len; ++i) { + if (_normals->size() > 0) { + _surface_tool->add_normal(_normals->get(i)); + } + + if (_colors->size() > 0) { + _surface_tool->add_color(_colors->get(i)); + } + + if (_uvs->size() > 0) { + _surface_tool->add_uv(_uvs->get(i)); + } + + _surface_tool->add_vertex(_vertices->get(i)); + } + + for (int i = 0; i < _indices->size(); ++i) { + _surface_tool->add_index(_indices->get(i)); + } + + _surface_tool->generate_normals(); + + Ref m = _surface_tool->commit(); + + return m; +} + +void VoxelMesher::reset() { + _vertices->clear(); + _normals->clear(); + _colors->clear(); + _uvs->clear(); + _indices->clear(); + _bones->clear(); +} + +void VoxelMesher::create_mesh_for_marching_cubes_query(Ref query) { + ERR_FAIL_COND(!query.is_valid()); + ERR_FAIL_COND(!has_method("_create_mesh_for_marching_cubes_query")); + + call("_create_mesh_for_marching_cubes_query", query); +} + +/* +void VoxelMesher::add_voxels(Hash3DMap > *voxels) { + ERR_FAIL_COND(!has_method("_add_voxels")); + + Array arr; + + const int *k = NULL; + while (k = voxels->next(k)) { + Ref v = voxels->get(*k); + + arr.append(v); + } + + call("_add_voxels", arr); +}*/ + +void VoxelMesher::add_voxel(Ref voxels) { + ERR_FAIL_COND(!has_method("_add_voxel")); + + call("_add_voxel", voxels); +} + +void VoxelMesher::create_trimesh_shape(Ref shape) const { + if (_vertices->size() == 0) + return; + + PoolVector face_points; + + if (_indices->size() == 0) { + + //face_points.resize(_vertices->size()); + + int len = (_vertices->size() / 4); + + for (int i = 0; i < len; ++i) { + + face_points.push_back(_vertices->get(i * 4)); + face_points.push_back(_vertices->get((i * 4) + 2)); + face_points.push_back(_vertices->get((i * 4) + 1)); + + face_points.push_back(_vertices->get(i * 4)); + face_points.push_back(_vertices->get((i * 4) + 3)); + face_points.push_back(_vertices->get((i * 4) + 2)); + } + + shape->set_faces(face_points); + + return; + } + + face_points.resize(_indices->size()); + for (int i = 0; i < face_points.size(); i++) { + face_points.set(i, _vertices->get(_indices->get(i))); + } + + shape->set_faces(face_points); +} + +void VoxelMesher::bake_lights(MeshInstance *node, Vector > *lights) { + + Color darkColor(0, 0, 0, 1); + + for (int v = 0; v < _vertices->size(); ++v) { + + Vector3 vet = _vertices->get(v); + Vector3 vertex = node->to_global(vet); + + //grab normal + Vector3 normal = _normals->get(v); + + Vector3 v_lightDiffuse; + + //calculate the lights value + for (int i = 0; i < lights->size(); ++i) { + Ref light = lights->get(i); + + Vector3 lightDir = light->get_world_position() - vertex; + + float dist2 = lightDir.dot(lightDir); + //inverse sqrt + lightDir *= (1.0 / sqrt(dist2)); + + float NdotL = normal.dot(lightDir); + + if (NdotL > 1.0) { + NdotL = 1.0; + } else if (NdotL < 0.0) { + NdotL = 0.0; + } + + Color cc = light->get_color(); + Vector3 cv(cc.r, cc.g, cc.b); + + Vector3 value = cv * (NdotL / (1.0 + dist2)); + + value *= light->get_strength(); + v_lightDiffuse += value; + + /* + float dist2 = Mathf.Clamp(Vector3.Distance(transformedLights[i], vertices), 0f, 15f); + dist2 /= 35f; + + Vector3 value = Vector3.one; + value *= ((float) lights[i].Strength) / 255f; + value *= (1 - dist2); + v_lightDiffuse += value;*/ + } + + Color f = _colors->get(v); + //Color f = darkColor; + + Vector3 cv2(f.r, f.g, f.b); + cv2 += v_lightDiffuse; + + if (cv2.x > 1) + cv2.x = 1; + + if (cv2.y > 1) + cv2.y = 1; + + if (cv2.y > 1) + cv2.y = 1; + + // cv2.x = Mathf.Clamp(cv2.x, 0f, 1f); + //cv2.y = Mathf.Clamp(cv2.y, 0f, 1f); + // cv2.z = Mathf.Clamp(cv2.z, 0f, 1f); + + f.r = cv2.x; + f.g = cv2.y; + f.b = cv2.z; + + //f.r = v_lightDiffuse.x; + //f.g = v_lightDiffuse.y; + //f.b = v_lightDiffuse.z; + + _colors->set(v, f); + } + + // for (int i = 0; i < _colors->size(); ++i) { + // print_error(_colors->get(i)); + // } +} + +Vector *VoxelMesher::get_vertices() { + return _vertices; +} + +int VoxelMesher::get_vertex_count() { + return _vertices->size(); +} + +void VoxelMesher::add_vertex(Vector3 vertex) { + _vertices->push_back(vertex); +} + +Vector3 VoxelMesher::get_vertex(int idx) { + return _vertices->get(idx); +} + +void VoxelMesher::remove_vertex(int idx) { + _vertices->remove(idx); +} + +Vector *VoxelMesher::get_normals() { + return _normals; +} + +int VoxelMesher::get_normal_count() { + return _normals->size(); +} + +void VoxelMesher::add_normal(Vector3 normal) { + _normals->push_back(normal); +} + +Vector3 VoxelMesher::get_normal(int idx) { + return _normals->get(idx); +} + +void VoxelMesher::remove_normal(int idx) { + _normals->remove(idx); +} + +Vector *VoxelMesher::get_colors() { + return _colors; +} + +int VoxelMesher::get_color_count() { + return _colors->size(); +} + +void VoxelMesher::add_color(Color color) { + _colors->push_back(color); +} + +Color VoxelMesher::get_color(int idx) { + return _colors->get(idx); +} + +void VoxelMesher::remove_color(int idx) { + _colors->remove(idx); +} + +Vector *VoxelMesher::get_uvs() { + return _uvs; +} + +int VoxelMesher::get_uv_count() { + return _uvs->size(); +} + +void VoxelMesher::add_uv(Vector2 uv) { + _uvs->push_back(uv); +} + +Vector2 VoxelMesher::get_uv(int idx) { + return _uvs->get(idx); +} + +void VoxelMesher::remove_uv(int idx) { + _uvs->remove(idx); +} + + +Vector *VoxelMesher::get_indices() { + return _indices; +} + +int VoxelMesher::get_indices_count() { + return _indices->size(); +} + +void VoxelMesher::add_indices(int index) { + _indices->push_back(index); +} + +int VoxelMesher::get_indice(int idx) { + return _indices->get(idx); +} + +void VoxelMesher::remove_indices(int idx) { + _indices->remove(idx); +} + + +void VoxelMesher::_bind_methods() { + //BIND_VMETHOD(MethodInfo("_build_mesh", PropertyInfo(Variant::BOOL, "recal", PROPERTY_HINT_RESOURCE_TYPE, "SpellCastInfo"))); + BIND_VMETHOD(MethodInfo("_add_voxels", PropertyInfo(Variant::ARRAY, "voxels"))); + BIND_VMETHOD(MethodInfo("_add_voxel", PropertyInfo(Variant::OBJECT, "voxel", PROPERTY_HINT_RESOURCE_TYPE, "Voxel"))); + BIND_VMETHOD(MethodInfo("_create_mesh_for_marching_cubes_query", PropertyInfo(Variant::OBJECT, "query", PROPERTY_HINT_RESOURCE_TYPE, "MarchingCubesVoxelQuery"))); + + 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"); + + ClassDB::bind_method(D_METHOD("get_vertex_count"), &VoxelMesher::get_vertex_count); + ClassDB::bind_method(D_METHOD("get_vertex", "idx"), &VoxelMesher::get_vertex); + ClassDB::bind_method(D_METHOD("remove_vertex", "idx"), &VoxelMesher::remove_vertex); + ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &VoxelMesher::add_vertex); + + ClassDB::bind_method(D_METHOD("get_normal_count"), &VoxelMesher::get_normal_count); + ClassDB::bind_method(D_METHOD("get_normal", "idx"), &VoxelMesher::get_normal); + ClassDB::bind_method(D_METHOD("remove_normal", "idx"), &VoxelMesher::remove_normal); + ClassDB::bind_method(D_METHOD("add_normal", "normal"), &VoxelMesher::add_normal); + + ClassDB::bind_method(D_METHOD("get_color_count"), &VoxelMesher::get_color_count); + ClassDB::bind_method(D_METHOD("get_color", "idx"), &VoxelMesher::get_color); + ClassDB::bind_method(D_METHOD("remove_color", "idx"), &VoxelMesher::remove_color); + ClassDB::bind_method(D_METHOD("add_color", "color"), &VoxelMesher::add_color); + + ClassDB::bind_method(D_METHOD("get_uv_count"), &VoxelMesher::get_uv_count); + ClassDB::bind_method(D_METHOD("get_uv", "idx"), &VoxelMesher::get_uv); + ClassDB::bind_method(D_METHOD("remove_uv", "idx"), &VoxelMesher::remove_uv); + ClassDB::bind_method(D_METHOD("add_uv", "vertex"), &VoxelMesher::add_uv); + + ClassDB::bind_method(D_METHOD("get_indices_count"), &VoxelMesher::get_indices_count); + ClassDB::bind_method(D_METHOD("get_indice", "idx"), &VoxelMesher::get_indice); + ClassDB::bind_method(D_METHOD("remove_indices", "idx"), &VoxelMesher::remove_indices); + ClassDB::bind_method(D_METHOD("add_indices", "indice"), &VoxelMesher::add_indices); + + ClassDB::bind_method(D_METHOD("reset"), &VoxelMesher::reset); + + //ClassDB::bind_method(D_METHOD("calculate_vertex_ambient_occlusion", "meshinstance_path", "radius", "intensity", "sampleCount"), &VoxelMesher::calculate_vertex_ambient_occlusion_path); + + ClassDB::bind_method(D_METHOD("build_mesh"), &VoxelMesher::build_mesh); +} diff --git a/meshers/voxel_mesher.h b/meshers/voxel_mesher.h new file mode 100644 index 0000000..585482b --- /dev/null +++ b/meshers/voxel_mesher.h @@ -0,0 +1,102 @@ +#ifndef VOXEL_TOOLS_H +#define VOXEL_TOOLS_H + +#include "core/reference.h" +#include "core/color.h" +#include "core/math/vector2.h" +#include "core/math/vector3.h" +#include "core/vector.h" +#include "scene/3d/mesh_instance.h" +#include "scene/resources/material.h" +#include "scene/resources/mesh.h" +#include "scene/resources/surface_tool.h" +#include "scene/3d/immediate_geometry.h" +#include "scene/3d/spatial.h" +#include "scene/main/node.h" +#include "scene/resources/concave_polygon_shape.h" + +#include "../library/voxelman_library.h" +#include "../collections/vector3i.h" +#include "../data/voxel.h" +#include "../library/voxelman_library.h" +#include "../utility/marching_cubes_voxel_query.h" + +const double PI_2 = 3.141592653589793238463 / 2; +const double PI = 3.141592653589793238463; + +class VoxelmanLibrary; +class Voxel; + +class VoxelMesher : public Reference { + GDCLASS(VoxelMesher, Reference); + +public: + Ref get_library() { return _library; } + void set_library(Ref library) { _library = library; } + + void reset(); + + //void add_voxels(Hash3DMap > *voxels); + void add_voxel(Ref voxels); + void create_mesh_for_marching_cubes_query(Ref query); + + void create_trimesh_shape(Ref shape) const; + void bake_lights(MeshInstance *node, Vector > *lights); + + Ref build_mesh(); + + Vector *get_vertices(); + int get_vertex_count(); + Vector3 get_vertex(int idx); + void remove_vertex(int idx); + void add_vertex(Vector3 vertex); + + Vector *get_normals(); + int get_normal_count(); + Vector3 get_normal(int idx); + void remove_normal(int idx); + void add_normal(Vector3 normal); + + Vector *get_colors(); + int get_color_count(); + Color get_color(int idx); + void remove_color(int idx); + void add_color(Color color); + + Vector *get_uvs(); + int get_uv_count(); + Vector2 get_uv(int idx); + void remove_uv(int idx); + void add_uv(Vector2 vector); + + Vector *get_indices(); + int get_indices_count(); + int get_indice(int idx); + void remove_indices(int idx); + void add_indices(int index); + + VoxelMesher(Ref library); + VoxelMesher(); + ~VoxelMesher(); + +protected: + static void _bind_methods(); + +private: + Vector *_vertices; + Vector *_normals; + Vector *_colors; + Vector *_uvs; + Vector *_indices; + Vector *_bones; + + Ref _library; + + float size; + Vector3 vertexOffset; + bool _debug_voxel_face; + + SurfaceTool *_surface_tool; +}; + +#endif diff --git a/meshers/voxel_mesher_transvoxel.cpp b/meshers/voxel_mesher_transvoxel.cpp new file mode 100644 index 0000000..f44102a --- /dev/null +++ b/meshers/voxel_mesher_transvoxel.cpp @@ -0,0 +1,217 @@ +#include "voxel_mesher_transvoxel.h" + +int TransvoxelRegularCellData::get_vertex_index(int index) const { + return static_cast(_cell_data.vertexIndex[index]); +} + +int TransvoxelRegularCellData::get_vertex_count() const { + return _cell_data.GetVertexCount(); +} + +int TransvoxelRegularCellData::get_triangle_count() const { + return _cell_data.GetTriangleCount(); +} + +TransvoxelRegularCellData::TransvoxelRegularCellData() { +} + +TransvoxelRegularCellData::TransvoxelRegularCellData(RegularCellData cell_data) { + _cell_data = cell_data; +} + +TransvoxelRegularCellData::~TransvoxelRegularCellData() { +} + +void TransvoxelRegularCellData::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_vertex_index", "index"), &TransvoxelRegularCellData::get_vertex_index); + ClassDB::bind_method(D_METHOD("get_vertex_count"), &TransvoxelRegularCellData::get_vertex_count); + ClassDB::bind_method(D_METHOD("get_triangle_count"), &TransvoxelRegularCellData::get_triangle_count); +} + + +int TransvoxelTransitionCellData::get_vertex_index(int index) const { + return static_cast(_cell_data.vertexIndex[index]); +} + +int TransvoxelTransitionCellData::get_vertex_count() const { + return _cell_data.GetVertexCount(); +} + +int TransvoxelTransitionCellData::get_triangle_count() const { + return _cell_data.GetTriangleCount(); +} + +TransvoxelTransitionCellData::TransvoxelTransitionCellData() { +} + +TransvoxelTransitionCellData::TransvoxelTransitionCellData(TransitionCellData cell_data) { + _cell_data = cell_data; +} + +TransvoxelTransitionCellData::~TransvoxelTransitionCellData() { +} + +void TransvoxelTransitionCellData::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_vertex_index", "index"), &TransvoxelTransitionCellData::get_vertex_index); + ClassDB::bind_method(D_METHOD("get_vertex_count"), &TransvoxelTransitionCellData::get_vertex_count); + ClassDB::bind_method(D_METHOD("get_triangle_count"), &TransvoxelTransitionCellData::get_triangle_count); +} + + + + +int VoxelMesherTransvoxel::get_regular_cell_class(int index) const { + return static_cast(regularCellClass[index]); +} + +Ref VoxelMesherTransvoxel::get_regular_cell_data(int index) const { + return _regular_cell_datas[index]; +} + +int VoxelMesherTransvoxel::get_regular_vertex_data(int index1, int index2) const { + //return static_cast(regularVertexData[index1][index2]); + return regularVertexData[index1][index2]; +} + +int VoxelMesherTransvoxel::get_regular_vertex_data_first_vertex(int index1, int index2) const { + int vert1 = regularVertexData[index1][index2] & 0x000F; + int vert2 = (regularVertexData[index1][index2] & 0x00F0) >> 4; + + //The paper says, that the smaller vertex index should be considered first + if (vert2 < vert1) { + return vert2; + } + + return vert1; +} + +int VoxelMesherTransvoxel::get_regular_vertex_data_second_vertex(int index1, int index2) const { + int vert1 = regularVertexData[index1][index2] & 0x000F; + int vert2 = (regularVertexData[index1][index2] & 0x00F0) >> 4; + + //The paper says, that the smaller vertex index should be considered first + if (vert2 > vert1) { + return vert2; + } + + return vert1; +} + +Vector3 VoxelMesherTransvoxel::get_regular_vertex_start_position(int index1, int index2) const { + int vert1 = regularVertexData[index1][index2] & 0x000F; + int vert2 = (regularVertexData[index1][index2] & 0x00F0) >> 4; + + //The paper says, that the smaller vertex index should be considered first + if (vert2 < vert1) { + return transvoxel_vertices[vert2]; + } + + return transvoxel_vertices[vert1]; +} + +Vector3 VoxelMesherTransvoxel::get_regular_vertex_direction(int index1, int index2) const { + int vert1 = regularVertexData[index1][index2] & 0x000F; + int vert2 = (regularVertexData[index1][index2] & 0x00F0) >> 4; + + //The paper says, that the smaller vertex index should be considered first + if (vert2 < vert1) { + int t = vert2; + vert2 = vert1; + vert1 = t; + } + + return transvoxel_vertices[vert2] - transvoxel_vertices[vert1]; +} + +int VoxelMesherTransvoxel::get_transition_cell_class(int index) const { + return static_cast(transitionCellClass[index]); +} + +Ref VoxelMesherTransvoxel::get_transition_cell_data(int index) const { + return _transition_cell_data[index]; +} + +int VoxelMesherTransvoxel::get_transition_corner_data(int index) const { + return static_cast(transitionCornerData[index]); +} + +int VoxelMesherTransvoxel::get_transition_vertex_data(int index1, int index2) const { + return static_cast(transitionVertexData[index1][index2]); +} + +int VoxelMesherTransvoxel::get_transition_vertex_data_first_vertex(int index1, int index2) const { + unsigned short val = transitionVertexData[index1][index2]; + + unsigned short vert = val & 0x000F; + + return static_cast(vert); +} + +int VoxelMesherTransvoxel::get_transition_vertex_data_second_vertex(int index1, int index2) const { + unsigned short val = transitionVertexData[index1][index2]; + + unsigned short vert = (val & 0x00F0) >> 4; + + return static_cast(vert); +} + +Vector3 VoxelMesherTransvoxel::get_transition_vertex_start_position(int index1, int index2) const { + int vert1 = regularVertexData[index1][index2] & 0x000F; + int vert2 = (regularVertexData[index1][index2] & 0x00F0) >> 4; + + //The paper says, that the smaller vertex index should be considered first + if (vert2 < vert1) { + return transvoxel_vertices[vert2]; + } + + return transvoxel_vertices[vert1]; +} + +Vector3 VoxelMesherTransvoxel::get_transition_vertex_direction(int index1, int index2) const { + int vert1 = regularVertexData[index1][index2] & 0x000F; + int vert2 = (regularVertexData[index1][index2] & 0x00F0) >> 4; + + //The paper says, that the smaller vertex index should be considered first + if (vert2 < vert1) { + int t = vert2; + vert2 = vert1; + vert1 = t; + } + + return transvoxel_vertices[vert2] - transvoxel_vertices[vert1]; +} + + +VoxelMesherTransvoxel::VoxelMesherTransvoxel() { + for (int i = 0; i < 16; ++i) { + _regular_cell_datas[i] = Ref(memnew(TransvoxelRegularCellData(regularCellData[i]))); + } + + for (int i = 0; i < 56; ++i) { + _transition_cell_data[i] = Ref(memnew(TransvoxelTransitionCellData(transitionCellData[i]))); + } + +} + +VoxelMesherTransvoxel::~VoxelMesherTransvoxel() { + +} + +void VoxelMesherTransvoxel::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_regular_cell_class", "index"), &VoxelMesherTransvoxel::get_regular_cell_class); + ClassDB::bind_method(D_METHOD("get_regular_cell_data", "index"), &VoxelMesherTransvoxel::get_regular_cell_data); + ClassDB::bind_method(D_METHOD("get_regular_vertex_data", "index1", "index2"), &VoxelMesherTransvoxel::get_regular_vertex_data); + ClassDB::bind_method(D_METHOD("get_regular_vertex_data_first_vertex", "index1", "index2"), &VoxelMesherTransvoxel::get_regular_vertex_data_first_vertex); + ClassDB::bind_method(D_METHOD("get_regular_vertex_data_second_vertex", "index1", "index2"), &VoxelMesherTransvoxel::get_regular_vertex_data_second_vertex); + ClassDB::bind_method(D_METHOD("get_regular_vertex_start_position", "index1", "index2"), &VoxelMesherTransvoxel::get_regular_vertex_start_position); + ClassDB::bind_method(D_METHOD("get_regular_vertex_direction", "index1", "index2"), &VoxelMesherTransvoxel::get_regular_vertex_direction); + + ClassDB::bind_method(D_METHOD("get_transition_cell_class", "index"), &VoxelMesherTransvoxel::get_transition_cell_class); + ClassDB::bind_method(D_METHOD("get_transition_cell_data", "index"), &VoxelMesherTransvoxel::get_transition_cell_data); + ClassDB::bind_method(D_METHOD("get_transition_corner_data", "index"), &VoxelMesherTransvoxel::get_transition_corner_data); + ClassDB::bind_method(D_METHOD("get_transition_vertex_data", "index1", "index2"), &VoxelMesherTransvoxel::get_transition_vertex_data); + ClassDB::bind_method(D_METHOD("get_transition_vertex_data_first_vertex", "index1", "index2"), &VoxelMesherTransvoxel::get_transition_vertex_data_first_vertex); + ClassDB::bind_method(D_METHOD("get_transition_vertex_data_second_vertex", "index1", "index2"), &VoxelMesherTransvoxel::get_transition_vertex_data_second_vertex); + ClassDB::bind_method(D_METHOD("get_transition_vertex_start_position", "index1", "index2"), &VoxelMesherTransvoxel::get_transition_vertex_start_position); + ClassDB::bind_method(D_METHOD("get_transition_vertex_direction", "index1", "index2"), &VoxelMesherTransvoxel::get_transition_vertex_direction); +} diff --git a/meshers/voxel_mesher_transvoxel.h b/meshers/voxel_mesher_transvoxel.h new file mode 100644 index 0000000..177364b --- /dev/null +++ b/meshers/voxel_mesher_transvoxel.h @@ -0,0 +1,84 @@ +#ifndef VOXEL_MESHER_TRANSVOXEL_H +#define VOXEL_MESHER_TRANSVOXEL_H + +#include "core/reference.h" +#include "voxel_mesher.h" + +#include "transvoxel_tables.h" + +using namespace Transvoxel; + +class TransvoxelRegularCellData : public Reference { + GDCLASS(TransvoxelRegularCellData, Reference) + +public: + int get_vertex_index(int index) const; + int get_vertex_count() const; + int get_triangle_count() const; + + TransvoxelRegularCellData(); + TransvoxelRegularCellData(RegularCellData cell_data); + ~TransvoxelRegularCellData(); + +protected: + static void _bind_methods(); + +private: + RegularCellData _cell_data; +}; + +class TransvoxelTransitionCellData : public Reference { + GDCLASS(TransvoxelTransitionCellData, Reference) + +public: + int get_vertex_index(int index) const; + int get_vertex_count() const; + int get_triangle_count() const; + + TransvoxelTransitionCellData(); + TransvoxelTransitionCellData(TransitionCellData cell_data); + ~TransvoxelTransitionCellData(); + +protected: + static void _bind_methods(); + +private: + TransitionCellData _cell_data; +}; + + + +class VoxelMesherTransvoxel : public VoxelMesher { + GDCLASS(VoxelMesherTransvoxel, VoxelMesher) + +public: + int get_regular_cell_class(int index) const; + + Ref get_regular_cell_data(int index) const; + int get_regular_vertex_data(int index10, int index2) const; + int get_regular_vertex_data_first_vertex(int index1, int index2) const; + int get_regular_vertex_data_second_vertex(int index1, int index2) const; + Vector3 get_regular_vertex_start_position(int index1, int index2) const; + Vector3 get_regular_vertex_direction(int index1, int index2) const; + + + int get_transition_cell_class(int index) const; + + Ref get_transition_cell_data(int index) const; + int get_transition_corner_data(int index) const; + int get_transition_vertex_data(int index1, int index2) const; + int get_transition_vertex_data_first_vertex(int index1, int index2) const; + int get_transition_vertex_data_second_vertex(int index1, int index2) const; + Vector3 get_transition_vertex_start_position(int index1, int index2) const; + Vector3 get_transition_vertex_direction(int index1, int index2) const; + + VoxelMesherTransvoxel(); + ~VoxelMesherTransvoxel(); + +protected: + static void _bind_methods(); + Ref _regular_cell_datas[16]; + Ref _transition_cell_data[56]; +}; + +#endif // VOXEL_MESHER_SMOOTH_H diff --git a/register_types.cpp b/register_types.cpp index 2fcab1a..645fda2 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -1,7 +1,28 @@ #include "register_types.h" -void register_voxelman_types() { +#include "library/voxel_surface.h" +#include "library/voxelman_library.h" +#include "data/voxel.h" +#include "data/voxel_light.h" +#include "meshers/voxel_mesher.h" +#include "meshers/voxel_mesher_transvoxel.h" + +#include "utility/marching_cubes_voxel_query.h" + +void register_voxelman_types() { + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + + ClassDB::register_class(); + ClassDB::register_class(); + + ClassDB::register_class(); + ClassDB::register_class(); + + ClassDB::register_class(); } void unregister_voxelman_types() { diff --git a/utility/marching_cubes_voxel_query.cpp b/utility/marching_cubes_voxel_query.cpp new file mode 100644 index 0000000..92865cd --- /dev/null +++ b/utility/marching_cubes_voxel_query.cpp @@ -0,0 +1,149 @@ +#include "marching_cubes_voxel_query.h" + +const String MarchingCubesVoxelQuery::BINDING_STRING_VOXEL_ENTRY_INDICES = "Index_000, Index_100, Index_010, Index_110, Index_001, Index_101, Index_011, Index_111"; +const String MarchingCubesVoxelQuery::BINDING_STRING_VOXEL_ENTRY_MASK = "Index_000, Index_100, Index_010, Index_110, Index_001, Index_101, Index_011, Index_111"; + +Ref MarchingCubesVoxelQuery::get_entry(int index) { + return _voxels[index]; +} +void MarchingCubesVoxelQuery::set_entry(int index, Ref voxel) { + _voxels[index] = voxel; +} + +int MarchingCubesVoxelQuery::get_size() { + return _size; +} +void MarchingCubesVoxelQuery::set_size(int size) { + _size = size; +} + +Vector3i MarchingCubesVoxelQuery::get_position() { + return _position; +} +void MarchingCubesVoxelQuery::set_position(Vector3i position) { + _position = position; +} + +Vector3 MarchingCubesVoxelQuery::get_position_bind() { + return _position.to_vec3(); +} +void MarchingCubesVoxelQuery::set_position_bind(Vector3 position) { + _position = position; +} + +int MarchingCubesVoxelQuery::get_case_code() { + return _case_code; +} + +void MarchingCubesVoxelQuery::update_case_code() { + int entry_mask = 0; + + if (_voxels[VOXEL_ENTRY_INDEX_000].is_valid()) { + entry_mask = entry_mask | VOXEL_ENTRY_MASK_000; + } + + if (_voxels[VOXEL_ENTRY_INDEX_100].is_valid()) { + entry_mask = entry_mask | VOXEL_ENTRY_MASK_100; + } + + if (_voxels[VOXEL_ENTRY_INDEX_010].is_valid()) { + entry_mask = entry_mask | VOXEL_ENTRY_MASK_010; + } + + if (_voxels[VOXEL_ENTRY_INDEX_110].is_valid()) { + entry_mask = entry_mask | VOXEL_ENTRY_MASK_110; + } + + if (_voxels[VOXEL_ENTRY_INDEX_001].is_valid()) { + entry_mask = entry_mask | VOXEL_ENTRY_MASK_001; + } + + if (_voxels[VOXEL_ENTRY_INDEX_101].is_valid()) { + entry_mask = entry_mask | VOXEL_ENTRY_MASK_101; + } + + if (_voxels[VOXEL_ENTRY_INDEX_011].is_valid()) { + entry_mask = entry_mask | VOXEL_ENTRY_MASK_011; + } + + if (_voxels[VOXEL_ENTRY_INDEX_111].is_valid()) { + entry_mask = entry_mask | VOXEL_ENTRY_MASK_111; + } + + _case_code = entry_mask; +} + +bool MarchingCubesVoxelQuery::is_triangulation_trivial() { + int corner = 0; + + if (_voxels[VOXEL_ENTRY_INDEX_111].is_valid()) { + corner = 0xFF; + } + + if ((_case_code ^ corner) != 0) { + // Cell has a nontrivial triangulation. + return false; + } + + return true; +} + +void MarchingCubesVoxelQuery::set_entries(Ref voxel000, Ref voxel100, Ref voxel010, Ref voxel110, Ref voxel001, + Ref voxel101, Ref voxel011, Ref voxel111) { + _voxels[VOXEL_ENTRY_INDEX_000] = voxel000; + _voxels[VOXEL_ENTRY_INDEX_100] = voxel100; + _voxels[VOXEL_ENTRY_INDEX_010] = voxel010; + _voxels[VOXEL_ENTRY_INDEX_110] = voxel110; + _voxels[VOXEL_ENTRY_INDEX_001] = voxel001; + _voxels[VOXEL_ENTRY_INDEX_101] = voxel101; + _voxels[VOXEL_ENTRY_INDEX_011] = voxel011; + _voxels[VOXEL_ENTRY_INDEX_111] = voxel111; + + update_case_code(); +} + +MarchingCubesVoxelQuery::MarchingCubesVoxelQuery() { + _size = 1; +} + +MarchingCubesVoxelQuery::~MarchingCubesVoxelQuery() { + +} + +void MarchingCubesVoxelQuery::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_entry", "index"), &MarchingCubesVoxelQuery::get_entry); + ClassDB::bind_method(D_METHOD("set_entry", "index", "voxel"), &MarchingCubesVoxelQuery::set_entry); + + ClassDB::bind_method(D_METHOD("get_size"), &MarchingCubesVoxelQuery::get_size); + ClassDB::bind_method(D_METHOD("set_size", "size"), &MarchingCubesVoxelQuery::set_size); + ADD_PROPERTY(PropertyInfo(Variant::INT, "size"), "set_size", "get_size"); + + ClassDB::bind_method(D_METHOD("get_position"), &MarchingCubesVoxelQuery::get_position_bind); + ClassDB::bind_method(D_METHOD("set_position", "spositionize"), &MarchingCubesVoxelQuery::set_position_bind); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "set_position", "get_position"); + + ClassDB::bind_method(D_METHOD("get_case_code"), &MarchingCubesVoxelQuery::get_case_code); + ClassDB::bind_method(D_METHOD("update_case_code"), &MarchingCubesVoxelQuery::update_case_code); + ClassDB::bind_method(D_METHOD("is_triangulation_trivial"), &MarchingCubesVoxelQuery::is_triangulation_trivial); + + BIND_ENUM_CONSTANT(VOXEL_ENTRY_INDEX_000); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_INDEX_100); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_INDEX_010); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_INDEX_110); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_INDEX_001); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_INDEX_101); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_INDEX_011); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_INDEX_111); + + BIND_ENUM_CONSTANT(VOXEL_ENTRIES_SIZE); + + BIND_ENUM_CONSTANT(VOXEL_ENTRY_MASK_000); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_MASK_100); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_MASK_010); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_MASK_110); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_MASK_001); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_MASK_101); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_MASK_011); + BIND_ENUM_CONSTANT(VOXEL_ENTRY_MASK_111); + +} diff --git a/utility/marching_cubes_voxel_query.h b/utility/marching_cubes_voxel_query.h new file mode 100644 index 0000000..5118b77 --- /dev/null +++ b/utility/marching_cubes_voxel_query.h @@ -0,0 +1,75 @@ +#ifndef MARCHING_CUBES_VOXEL_QUERY_H +#define MARCHING_CUBES_VOXEL_QUERY_H + +#include "core/reference.h" + +#include "../data/voxel.h" + +class MarchingCubesVoxelQuery : public Reference { + GDCLASS(MarchingCubesVoxelQuery, Reference); + +public: + static const String BINDING_STRING_VOXEL_ENTRY_INDICES; + static const String BINDING_STRING_VOXEL_ENTRY_MASK; + + enum VoxelEntryIndices { + VOXEL_ENTRY_INDEX_000 = 0, + VOXEL_ENTRY_INDEX_100 = 1, + VOXEL_ENTRY_INDEX_001 = 2, + VOXEL_ENTRY_INDEX_101 = 3, + + VOXEL_ENTRY_INDEX_010 = 4, + VOXEL_ENTRY_INDEX_110 = 5, + VOXEL_ENTRY_INDEX_011 = 6, + VOXEL_ENTRY_INDEX_111 = 7, + + VOXEL_ENTRIES_SIZE = 8, + }; + + enum VoxelEntryMask { + VOXEL_ENTRY_MASK_000 = 1 << 0, + VOXEL_ENTRY_MASK_100 = 1 << 1, + VOXEL_ENTRY_MASK_001 = 1 << 2, + VOXEL_ENTRY_MASK_101 = 1 << 3, + + VOXEL_ENTRY_MASK_010 = 1 << 4, + VOXEL_ENTRY_MASK_110 = 1 << 5, + VOXEL_ENTRY_MASK_011 = 1 << 6, + VOXEL_ENTRY_MASK_111 = 1 << 7, + }; + + Ref get_entry(int index); + void set_entry(int index, Ref voxel); + + int get_size(); + void set_size(int size); + + Vector3i get_position(); + void set_position(Vector3i position); + + Vector3 get_position_bind(); + void set_position_bind(Vector3 position); + + int get_case_code(); + void update_case_code(); + bool is_triangulation_trivial(); + + void set_entries(Ref voxel000, Ref voxel100, Ref voxel010, Ref voxel110, Ref voxel001, Ref voxel101, Ref voxel011, Ref voxel111); + + MarchingCubesVoxelQuery(); + ~MarchingCubesVoxelQuery(); + +protected: + static void _bind_methods(); + +private: + int _case_code; + int _size; + Vector3i _position; + Ref _voxels[VOXEL_ENTRIES_SIZE]; +}; + +VARIANT_ENUM_CAST(MarchingCubesVoxelQuery::VoxelEntryIndices); +VARIANT_ENUM_CAST(MarchingCubesVoxelQuery::VoxelEntryMask); + +#endif