Turned the Transvoxel mesher into a MarchingCubes mesher. Removed the parts that weren't used.

This commit is contained in:
Relintai 2020-06-12 17:59:04 +02:00
parent aeff73083e
commit a83585bd81
9 changed files with 1257 additions and 0 deletions

4
SCsub
View File

@ -34,6 +34,10 @@ sources = [
"meshers/transvoxel_uv_mesher/voxel_mesher_uv_transvoxel.cpp",
"meshers/transvoxel_uv_mesher/transvoxel_tables.cpp",
"meshers/marching_cubes/marching_cubes_cell_data.cpp",
"meshers/marching_cubes/voxel_mesher_marching_cubes.cpp",
"meshers/marching_cubes/marching_cubes_tables.cpp",
"meshers/blocky/voxel_mesher_blocky.cpp",
"meshers/blocky/voxel_mesher_liquid_blocky.cpp",
"meshers/default/voxel_mesher_default.cpp",

View File

@ -29,6 +29,10 @@ def get_doc_classes():
"TransvoxelCellData",
"VoxelMeshData",
"VoxelMesherUVTransvoxel",
"MarchingCubesCellData",
"VoxelMesherMarchingCubes",
"VoxelMesher",
"EnvironmentData",

View File

@ -0,0 +1,80 @@
/*
Copyright (c) 2019-2020 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "marching_cubes_cell_data.h"
int MarchingCubesCellData::get_vertex_index(int index) const {
return static_cast<int>(vertexIndex[index]);
}
void MarchingCubesCellData::set_vertex_index(int index, int value) {
ERR_FAIL_INDEX(index, 15);
vertexIndex[index] = static_cast<unsigned char>(value);
}
int MarchingCubesCellData::get_vertex_count() const {
return (geometryCounts >> 4);
}
void MarchingCubesCellData::set_vertex_count(int value) {
geometryCounts &= 0xFF0F;
geometryCounts |= value << 4;
}
int MarchingCubesCellData::get_triangle_count() const {
return (geometryCounts & 0x0F);
}
void MarchingCubesCellData::set_triangle_count(int value) {
geometryCounts &= 0xFFF0;
geometryCounts |= value;
}
MarchingCubesCellData::MarchingCubesCellData() {
geometryCounts = 0;
for (int i = 0; i < 15; ++i) {
vertexIndex[i] = 0;
}
}
MarchingCubesCellData::MarchingCubesCellData(const RegularCellData &cell_data) {
geometryCounts = cell_data.geometryCounts;
for (int i = 0; i < 15; ++i) {
vertexIndex[i] = cell_data.vertexIndex[i];
}
}
MarchingCubesCellData::~MarchingCubesCellData() {
}
void MarchingCubesCellData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_vertex_index", "index"), &MarchingCubesCellData::get_vertex_index);
ClassDB::bind_method(D_METHOD("set_vertex_index", "index", "value"), &MarchingCubesCellData::set_vertex_index);
ClassDB::bind_method(D_METHOD("get_vertex_count"), &MarchingCubesCellData::get_vertex_count);
ClassDB::bind_method(D_METHOD("set_vertex_count", "value"), &MarchingCubesCellData::set_vertex_count);
ClassDB::bind_method(D_METHOD("get_triangle_count"), &MarchingCubesCellData::get_triangle_count);
ClassDB::bind_method(D_METHOD("set_triangle_count", "value"), &MarchingCubesCellData::set_triangle_count);
}

View File

@ -0,0 +1,57 @@
/*
Copyright (c) 2019-2020 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef MARCHING_CUBES_CELL_DATA_H
#define MARCHING_CUBES_CELL_DATA_H
#include "core/reference.h"
#include "marching_cubes_tables.h"
using namespace MarchingCubes;
class MarchingCubesCellData : public Reference {
GDCLASS(MarchingCubesCellData, Reference)
public:
int get_vertex_index(int index) const;
void set_vertex_index(int index, int value);
int get_vertex_count() const;
void set_vertex_count(int value);
int get_triangle_count() const;
void set_triangle_count(int value);
MarchingCubesCellData();
MarchingCubesCellData(const MarchingCubes::RegularCellData &cell_data);
~MarchingCubesCellData();
protected:
static void _bind_methods();
private:
long geometryCounts; // High nibble is vertex count, low nibble is triangle count.
unsigned char vertexIndex[15]; // Groups of 3 indexes giving the triangulation.
};
#endif

View File

@ -0,0 +1,380 @@
#include "marching_cubes_tables.h"
//================================================================================
//
// The MarchingCubes Algorithm look-up tables
//
// These tables have been modified, in order to implement uv mapping.
// Also the transition data have been removed.
//
// Copyright 2009 by Eric Lengyel
//
// The following data originates from Eric Lengyel's MarchingCubes Algorithm.
// http://transvoxel.org/
//
// The data in this file may be freely used in implementations of the MarchingCubes
// 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
// MarchingCubes 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 MarchingCubes 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 MarchingCubes {
// 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] = {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0x00, 0x01, 0x01, 0x03, 0x01, 0x03, 0x02, 0x04, 0x01, 0x02, 0x03, 0x04, 0x03, 0x04, 0x04, 0x03, // 0
0x01, 0x03, 0x02, 0x04, 0x02, 0x04, 0x06, 0x0C, 0x02, 0x05, 0x05, 0x0B, 0x05, 0x0A, 0x07, 0x04, // 16
0x01, 0x02, 0x03, 0x04, 0x02, 0x05, 0x05, 0x0A, 0x02, 0x06, 0x04, 0x0C, 0x05, 0x07, 0x0B, 0x04, // 32
0x03, 0x04, 0x04, 0x03, 0x05, 0x0B, 0x07, 0x04, 0x05, 0x07, 0x0A, 0x04, 0x08, 0x0E, 0x0E, 0x03, // 48
0x01, 0x02, 0x02, 0x05, 0x03, 0x04, 0x05, 0x0B, 0x02, 0x06, 0x05, 0x07, 0x04, 0x0C, 0x0A, 0x04, // 64
0x03, 0x04, 0x05, 0x0A, 0x04, 0x03, 0x07, 0x04, 0x05, 0x07, 0x08, 0x0E, 0x0B, 0x04, 0x0E, 0x03, // 80
0x02, 0x06, 0x05, 0x07, 0x05, 0x07, 0x08, 0x0E, 0x06, 0x09, 0x07, 0x0F, 0x07, 0x0F, 0x0E, 0x0D, // 96
0x04, 0x0C, 0x0B, 0x04, 0x0A, 0x04, 0x0E, 0x03, 0x07, 0x0F, 0x0E, 0x0D, 0x0E, 0x0D, 0x02, 0x01, // 112
0x01, 0x02, 0x02, 0x05, 0x02, 0x05, 0x06, 0x07, 0x03, 0x05, 0x04, 0x0A, 0x04, 0x0B, 0x0C, 0x04, // 128
0x02, 0x05, 0x06, 0x07, 0x06, 0x07, 0x09, 0x0F, 0x05, 0x08, 0x07, 0x0E, 0x07, 0x0E, 0x0F, 0x0D, // 144
0x03, 0x05, 0x04, 0x0B, 0x05, 0x08, 0x07, 0x0E, 0x04, 0x07, 0x03, 0x04, 0x0A, 0x0E, 0x04, 0x03, // 160
0x04, 0x0A, 0x0C, 0x04, 0x07, 0x0E, 0x0F, 0x0D, 0x0B, 0x0E, 0x04, 0x03, 0x0E, 0x02, 0x0D, 0x01, // 176
0x03, 0x05, 0x05, 0x08, 0x04, 0x0A, 0x07, 0x0E, 0x04, 0x07, 0x0B, 0x0E, 0x03, 0x04, 0x04, 0x03, // 192
0x04, 0x0B, 0x07, 0x0E, 0x0C, 0x04, 0x0F, 0x0D, 0x0A, 0x0E, 0x0E, 0x02, 0x04, 0x03, 0x0D, 0x01, // 208
0x04, 0x07, 0x0A, 0x0E, 0x0B, 0x0E, 0x0E, 0x02, 0x0C, 0x0F, 0x04, 0x0D, 0x04, 0x0D, 0x03, 0x01, // 224
0x03, 0x04, 0x04, 0x03, 0x04, 0x03, 0x0D, 0x01, 0x04, 0x0D, 0x03, 0x01, 0x03, 0x01, 0x01, 0x00 // 240
};
// 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 } },
{ 0x62, { 0, 1, 2, 4, 5, 3 } }, //{ 0x42, { 0, 1, 2, 0, 2, 3 } }
{ 0x93, { 0, 1, 4, 5, 3, 6, 7, 2, 8 } }, //{ 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 } },
{ 0xC4, { 0, 1, 4, 8, 3, 9, 10, 2, 11, 5, 6, 7 } }, //7 { 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 } },
{ 0xC4, { 0, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3 } }, //A { 0x64, { 0, 4, 5, 0, 1, 4, 1, 3, 4, 1, 2, 3 } },
{ 0xC4, { 0, 5, 4, 6, 8, 7, 9, 11, 10, 1, 3, 2 } }, //B { 0x64, { 0, 5, 4, 0, 4, 1, 1, 4, 3, 1, 3, 2 } },
{ 0xC4, { 0, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3 } }, //C { 0x64, { 0, 4, 5, 0, 3, 4, 0, 1, 3, 1, 2, 3 } },
{ 0xC4, { 0, 1, 2, 6, 7, 3, 8, 9, 4, 10, 11, 5 } }, //D { 0x64, { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5 } },
{ 0xF5, { 0, 1, 2, 7, 8, 3, 9, 10, 4, 11, 12, 5, 13, 14, 6 } }, //E { 0x75, { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6 } },
{ 0xF5, { 0, 4, 5, 9, 3, 10, 11, 1, 12, 13, 2, 14, 6, 7, 8 } } //F { 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][15] = {
{},
{ 0x6201, 0x5102, 0x3304 },
{ 0x6201, 0x2315, 0x4113 },
{ 0x5102, 0x3304, 0x2315, 0x4113, 0x5102, 0x2315 },
{ 0x5102, 0x4223, 0x1326 },
{ 0x3304, 0x6201, 0x4223, 0x1326, 0x3304, 0x4223 },
{ 0x6201, 0x2315, 0x4113, 0x5102, 0x4223, 0x1326 },
{ 0x4223, 0x1326, 0x3304, 0x2315, 0x4113, 0x1326, 0x4113, 0x1326, 0x2315 },
{ 0x4113, 0x8337, 0x4223 },
{ 0x6201, 0x5102, 0x3304, 0x4223, 0x4113, 0x8337 },
{ 0x6201, 0x2315, 0x8337, 0x4223, 0x6201, 0x8337 },
{ 0x5102, 0x3304, 0x2315, 0x8337, 0x4223, 0x3304, 0x4223, 0x3304, 0x8337 },
{ 0x5102, 0x4113, 0x8337, 0x1326, 0x5102, 0x8337 },
{ 0x4113, 0x8337, 0x1326, 0x3304, 0x6201, 0x8337, 0x6201, 0x8337, 0x3304 },
{ 0x6201, 0x2315, 0x8337, 0x1326, 0x5102, 0x2315, 0x5102, 0x2315, 0x1326 },
{ 0x3304, 0x2315, 0x8337, 0x1326, 0x3304, 0x8337 },
//16 3 5 15
{ 0x3304, 0x1146, 0x2245 },
{ 0x6201, 0x5102, 0x1146, 0x2245, 0x6201, 0x1146 },
{ 0x6201, 0x2315, 0x4113, 0x3304, 0x1146, 0x2245 },
{ 0x2315, 0x4113, 0x5102, 0x1146, 0x2245, 0x4113, 0x2245, 0x4113, 0x1146 },
{ 0x5102, 0x4223, 0x1326, 0x3304, 0x1146, 0x2245 },
{ 0x1146, 0x2245, 0x6201, 0x4223, 0x1326, 0x2245, 0x1326, 0x2245, 0x4223 },
{ 0x3304, 0x1146, 0x2245, 0x6201, 0x2315, 0x4113, 0x5102, 0x4223, 0x1326 },
{ 0x4223, 0x1326, 0x1146, 0x2245, 0x2315, 0x4113, 0x4223, 0x2245, 0x2315, 0x4223, 0x1326, 0x2245 },
{ 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, 0x4223, 0x8337, 0x1146, 0x8337, 0x2245, 0x1146 },
{ 0x5102, 0x4113, 0x8337, 0x1326, 0x3304, 0x1146, 0x2245 },
{ 0x4113, 0x8337, 0x1326, 0x1146, 0x2245, 0x6201, 0x4113, 0x8337, 0x2245, 0x8337, 0x1146, 0x2245 },
{ 0x6201, 0x2315, 0x8337, 0x1326, 0x5102, 0x3304, 0x1146, 0x2245, 0x2315, 0x5102, 0x2315, 0x1326 },
{ 0x2245, 0x2315, 0x8337, 0x1326, 0x1146, 0x2315, 0x1146, 0x2315, 0x1326 },
//32 3 10 15
{ 0x2315, 0x2245, 0x8157 },
{ 0x6201, 0x5102, 0x3304, 0x2315, 0x2245, 0x8157 },
{ 0x4113, 0x6201, 0x2245, 0x8157, 0x4113, 0x2245 },
{ 0x2245, 0x8157, 0x4113, 0x5102, 0x3304, 0x8157, 0x3304, 0x8157, 0x5102 },
{ 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, 0x1326, 0x8157, 0x1326, 0x2245, 0x8157 },
{ 0x4223, 0x4113, 0x8337, 0x2315, 0x2245, 0x8157 },
{ 0x6201, 0x5102, 0x3304, 0x4223, 0x4113, 0x8337, 0x2315, 0x2245, 0x8157 },
{ 0x8337, 0x4223, 0x6201, 0x2245, 0x8157, 0x4223, 0x8157, 0x4223, 0x2245 },
{ 0x5102, 0x3304, 0x2245, 0x8157, 0x8337, 0x4223, 0x5102, 0x8157, 0x8337, 0x5102, 0x3304, 0x8157 },
{ 0x5102, 0x4113, 0x8337, 0x1326, 0x2315, 0x2245, 0x8157 },
{ 0x4113, 0x8337, 0x1326, 0x3304, 0x6201, 0x2315, 0x2245, 0x8157, 0x8337, 0x6201, 0x8337, 0x3304 },
{ 0x5102, 0x1326, 0x8337, 0x8157, 0x2245, 0x6201, 0x5102, 0x1326, 0x2245, 0x1326, 0x8157, 0x2245 },
{ 0x8157, 0x8337, 0x1326, 0x3304, 0x2245, 0x8337, 0x2245, 0x8337, 0x3304 },
//48 1 2 7 11
{ 0x2315, 0x3304, 0x1146, 0x8157, 0x2315, 0x1146 },
{ 0x6201, 0x5102, 0x1146, 0x8157, 0x2315, 0x5102, 0x2315, 0x5102, 0x8157 },
{ 0x3304, 0x1146, 0x8157, 0x4113, 0x6201, 0x1146, 0x6201, 0x1146, 0x4113 },
{ 0x4113, 0x5102, 0x1146, 0x8157, 0x4113, 0x1146 },
{ 0x2315, 0x3304, 0x1146, 0x8157, 0x5102, 0x4223, 0x1326 },
{ 0x1326, 0x4223, 0x6201, 0x2315, 0x8157, 0x1146, 0x1326, 0x4223, 0x8157, 0x4223, 0x2315, 0x8157 },
{ 0x3304, 0x1146, 0x8157, 0x4113, 0x6201, 0x5102, 0x4223, 0x1326, 0x1146, 0x6201, 0x1146, 0x4113 },
{ 0x1326, 0x1146, 0x8157, 0x4113, 0x4223, 0x1146, 0x4223, 0x1146, 0x4113 },
{ 0x2315, 0x3304, 0x1146, 0x8157, 0x4223, 0x4113, 0x8337 },
{ 0x6201, 0x5102, 0x1146, 0x8157, 0x2315, 0x4223, 0x4113, 0x8337, 0x5102, 0x2315, 0x5102, 0x8157 },
{ 0x3304, 0x1146, 0x8157, 0x8337, 0x4223, 0x6201, 0x3304, 0x1146, 0x4223, 0x1146, 0x8337, 0x4223 },
{ 0x4223, 0x5102, 0x1146, 0x8157, 0x8337, 0x5102, 0x8337, 0x5102, 0x8157 },
{ 0x2315, 0x3304, 0x1146, 0x8157, 0x5102, 0x4113, 0x8337, 0x1326 },
{ 0x6201, 0x4113, 0x8337, 0x1326, 0x1146, 0x8157, 0x2315, 0x6201, 0x8337, 0x6201, 0x1326, 0x6201, 0x1146, 0x6201, 0x8157 },
{ 0x6201, 0x3304, 0x1146, 0x8157, 0x8337, 0x1326, 0x5102, 0x6201, 0x1146, 0x6201, 0x8157, 0x6201, 0x8337, 0x6201, 0x1326 },
{ 0x1326, 0x1146, 0x8157, 0x8337, 0x1326, 0x8157 },
//64 5 12 15
{ 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, 0x5102, 0x8267 },
{ 0x3304, 0x6201, 0x4223, 0x8267, 0x1146, 0x6201, 0x1146, 0x6201, 0x8267 },
{ 0x5102, 0x4223, 0x8267, 0x1146, 0x6201, 0x2315, 0x4113 },
{ 0x1146, 0x8267, 0x4223, 0x4113, 0x2315, 0x3304, 0x1146, 0x8267, 0x2315, 0x8267, 0x4113, 0x2315 },
{ 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, 0x3304, 0x4223, 0x3304, 0x8337 },
{ 0x8267, 0x1146, 0x5102, 0x4113, 0x8337, 0x1146, 0x8337, 0x1146, 0x4113 },
{ 0x6201, 0x4113, 0x8337, 0x8267, 0x1146, 0x3304, 0x6201, 0x8267, 0x1146, 0x6201, 0x4113, 0x8267 },
{ 0x6201, 0x2315, 0x8337, 0x8267, 0x1146, 0x5102, 0x6201, 0x2315, 0x1146, 0x2315, 0x8267, 0x1146 },
{ 0x1146, 0x3304, 0x2315, 0x8337, 0x8267, 0x3304, 0x8267, 0x3304, 0x8337 },
//80 1 4 7 13
{ 0x3304, 0x1326, 0x8267, 0x2245, 0x3304, 0x8267 },
{ 0x1326, 0x8267, 0x2245, 0x6201, 0x5102, 0x8267, 0x5102, 0x8267, 0x6201 },
{ 0x3304, 0x1326, 0x8267, 0x2245, 0x6201, 0x2315, 0x4113 },
{ 0x1326, 0x8267, 0x2245, 0x2315, 0x4113, 0x5102, 0x1326, 0x8267, 0x4113, 0x8267, 0x2315, 0x4113 },
{ 0x5102, 0x4223, 0x8267, 0x2245, 0x3304, 0x4223, 0x3304, 0x4223, 0x2245 },
{ 0x6201, 0x4223, 0x8267, 0x2245, 0x6201, 0x8267 },
{ 0x5102, 0x4223, 0x8267, 0x2245, 0x3304, 0x6201, 0x2315, 0x4113, 0x4223, 0x3304, 0x4223, 0x2245 },
{ 0x4113, 0x4223, 0x8267, 0x2245, 0x2315, 0x4223, 0x2315, 0x4223, 0x2245 },
{ 0x3304, 0x1326, 0x8267, 0x2245, 0x4223, 0x4113, 0x8337 },
{ 0x1326, 0x8267, 0x2245, 0x6201, 0x5102, 0x4223, 0x4113, 0x8337, 0x8267, 0x5102, 0x8267, 0x6201 },
{ 0x3304, 0x1326, 0x8267, 0x2245, 0x4223, 0x6201, 0x2315, 0x8337 },
{ 0x5102, 0x1326, 0x8267, 0x2245, 0x2315, 0x8337, 0x4223, 0x5102, 0x8267, 0x5102, 0x2245, 0x5102, 0x2315, 0x5102, 0x8337 },
{ 0x3304, 0x2245, 0x8267, 0x8337, 0x4113, 0x5102, 0x3304, 0x2245, 0x4113, 0x2245, 0x8337, 0x4113 },
{ 0x8337, 0x8267, 0x2245, 0x6201, 0x4113, 0x8267, 0x4113, 0x8267, 0x6201 },
{ 0x5102, 0x6201, 0x2315, 0x8337, 0x8267, 0x2245, 0x3304, 0x5102, 0x2315, 0x5102, 0x8337, 0x5102, 0x8267, 0x5102, 0x2245 },
{ 0x2315, 0x8337, 0x8267, 0x2245, 0x2315, 0x8267 },
//96 -
{ 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, 0x8157, 0x3304, 0x8157, 0x5102 },
{ 0x4223, 0x8267, 0x1146, 0x5102, 0x2315, 0x2245, 0x8157 },
{ 0x3304, 0x6201, 0x4223, 0x8267, 0x1146, 0x2315, 0x2245, 0x8157, 0x6201, 0x1146, 0x6201, 0x8267 },
{ 0x4223, 0x8267, 0x1146, 0x5102, 0x6201, 0x2245, 0x8157, 0x4113 },
{ 0x3304, 0x2245, 0x8157, 0x4113, 0x4223, 0x8267, 0x1146, 0x3304, 0x8157, 0x3304, 0x4113, 0x3304, 0x4223, 0x3304, 0x8267 },
{ 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, 0x8157, 0x4223, 0x2245 },
{ 0x4223, 0x5102, 0x3304, 0x2245, 0x8157, 0x8337, 0x1326, 0x8267, 0x1146, 0x4223, 0x8157, 0x4223, 0x2245, 0x5102, 0x2245 },
{ 0x8267, 0x1146, 0x5102, 0x4113, 0x8337, 0x2315, 0x2245, 0x8157, 0x1146, 0x8337, 0x1146, 0x4113 },
{ 0x6201, 0x4113, 0x8337, 0x8267, 0x1146, 0x3304, 0x2315, 0x2245, 0x8157, 0x6201, 0x1146, 0x6201, 0x8267, 0x4113, 0x8267 },
{ 0x8337, 0x8267, 0x1146, 0x5102, 0x6201, 0x2245, 0x8157, 0x8337, 0x1146, 0x8337, 0x5102, 0x8337, 0x6201, 0x8337, 0x2245 },
{ 0x3304, 0x2245, 0x8157, 0x8337, 0x8267, 0x1146, 0x3304, 0x8157, 0x3304, 0x8337, 0x3304, 0x8267 },
//112 0 3 5
{ 0x8157, 0x2315, 0x3304, 0x1326, 0x8267, 0x2315, 0x8267, 0x2315, 0x1326 },
{ 0x8267, 0x8157, 0x2315, 0x6201, 0x5102, 0x1326, 0x8267, 0x6201, 0x5102, 0x8267, 0x8157, 0x6201 },
{ 0x8267, 0x1326, 0x3304, 0x6201, 0x4113, 0x8157, 0x8267, 0x1326, 0x4113, 0x1326, 0x6201, 0x4113 },
{ 0x8267, 0x8157, 0x4113, 0x5102, 0x1326, 0x8157, 0x1326, 0x8157, 0x5102 },
{ 0x5102, 0x4223, 0x8267, 0x8157, 0x2315, 0x3304, 0x5102, 0x4223, 0x2315, 0x4223, 0x8157, 0x2315 },
{ 0x2315, 0x6201, 0x4223, 0x8267, 0x8157, 0x6201, 0x8157, 0x6201, 0x8267 },
{ 0x3304, 0x5102, 0x4223, 0x8267, 0x8157, 0x4113, 0x6201, 0x3304, 0x4223, 0x3304, 0x8267, 0x3304, 0x8157, 0x3304, 0x4113 },
{ 0x4113, 0x4223, 0x8267, 0x8157, 0x4113, 0x8267 },
{ 0x8157, 0x2315, 0x3304, 0x1326, 0x8267, 0x4223, 0x4113, 0x8337, 0x2315, 0x8267, 0x2315, 0x1326 },
{ 0x8157, 0x2315, 0x6201, 0x5102, 0x1326, 0x8267, 0x4223, 0x4113, 0x8337, 0x8157, 0x1326, 0x8157, 0x5102, 0x2315, 0x5102 },
{ 0x8157, 0x8337, 0x4223, 0x6201, 0x3304, 0x1326, 0x8267, 0x8157, 0x4223, 0x8157, 0x6201, 0x8157, 0x3304, 0x8157, 0x1326 },
{ 0x5102, 0x1326, 0x8267, 0x8157, 0x8337, 0x4223, 0x5102, 0x8267, 0x5102, 0x8157, 0x5102, 0x8337 },
{ 0x8267, 0x8157, 0x2315, 0x3304, 0x5102, 0x4113, 0x8337, 0x8267, 0x2315, 0x8267, 0x3304, 0x8267, 0x5102, 0x8267, 0x4113 },
{ 0x6201, 0x4113, 0x8337, 0x8267, 0x8157, 0x2315, 0x6201, 0x8337, 0x6201, 0x8267, 0x6201, 0x8157 },
{ 0x6201, 0x3304, 0x5102, 0x8337, 0x8267, 0x8157 },
{ 0x8337, 0x8267, 0x8157 },
//128 10 12 15
{ 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, 0x1326, 0x4113, 0x1326, 0x2315 },
{ 0x4113, 0x8157, 0x8267, 0x4223, 0x4113, 0x8267 },
{ 0x4223, 0x4113, 0x8157, 0x8267, 0x6201, 0x5102, 0x3304 },
{ 0x8157, 0x8267, 0x4223, 0x6201, 0x2315, 0x8267, 0x2315, 0x8267, 0x6201 },
{ 0x3304, 0x2315, 0x8157, 0x8267, 0x4223, 0x5102, 0x3304, 0x2315, 0x4223, 0x2315, 0x8267, 0x4223 },
{ 0x1326, 0x5102, 0x4113, 0x8157, 0x8267, 0x5102, 0x8267, 0x5102, 0x8157 },
{ 0x8157, 0x4113, 0x6201, 0x3304, 0x1326, 0x8267, 0x8157, 0x4113, 0x1326, 0x4113, 0x3304, 0x1326 },
{ 0x1326, 0x5102, 0x6201, 0x2315, 0x8157, 0x8267, 0x1326, 0x2315, 0x8157, 0x1326, 0x5102, 0x2315 },
{ 0x8267, 0x1326, 0x3304, 0x2315, 0x8157, 0x1326, 0x8157, 0x1326, 0x2315 },
//144 -
{ 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, 0x4113, 0x2245, 0x4113, 0x1146 },
{ 0x5102, 0x4223, 0x1326, 0x3304, 0x1146, 0x2245, 0x8337, 0x8157, 0x8267 },
{ 0x1146, 0x2245, 0x6201, 0x4223, 0x1326, 0x8337, 0x8157, 0x8267, 0x2245, 0x1326, 0x2245, 0x4223 },
{ 0x6201, 0x2315, 0x4113, 0x5102, 0x4223, 0x1326, 0x3304, 0x1146, 0x2245, 0x8337, 0x8157, 0x8267 },
{ 0x4113, 0x4223, 0x1326, 0x1146, 0x2245, 0x2315, 0x8337, 0x8157, 0x8267, 0x4113, 0x2245, 0x4113, 0x1146, 0x4223, 0x1146 },
{ 0x4223, 0x4113, 0x8157, 0x8267, 0x3304, 0x1146, 0x2245 },
{ 0x6201, 0x5102, 0x1146, 0x2245, 0x4223, 0x4113, 0x8157, 0x8267 },
{ 0x8157, 0x8267, 0x4223, 0x6201, 0x2315, 0x3304, 0x1146, 0x2245, 0x8267, 0x2315, 0x8267, 0x6201 },
{ 0x2315, 0x8157, 0x8267, 0x4223, 0x5102, 0x1146, 0x2245, 0x2315, 0x8267, 0x2315, 0x4223, 0x2315, 0x5102, 0x2315, 0x1146 },
{ 0x1326, 0x5102, 0x4113, 0x8157, 0x8267, 0x3304, 0x1146, 0x2245, 0x5102, 0x8267, 0x5102, 0x8157 },
{ 0x1326, 0x1146, 0x2245, 0x6201, 0x4113, 0x8157, 0x8267, 0x1326, 0x2245, 0x1326, 0x6201, 0x1326, 0x4113, 0x1326, 0x8157 },
{ 0x5102, 0x6201, 0x2315, 0x8157, 0x8267, 0x1326, 0x3304, 0x1146, 0x2245, 0x5102, 0x8267, 0x5102, 0x8157, 0x6201, 0x8157 },
{ 0x1326, 0x1146, 0x2245, 0x2315, 0x8157, 0x8267, 0x1326, 0x2245, 0x1326, 0x2315, 0x1326, 0x8157 },
//160 2 8 11 14
{ 0x2315, 0x2245, 0x8267, 0x8337, 0x2315, 0x8267 },
{ 0x2315, 0x2245, 0x8267, 0x8337, 0x6201, 0x5102, 0x3304 },
{ 0x4113, 0x6201, 0x2245, 0x8267, 0x8337, 0x6201, 0x8337, 0x6201, 0x8267 },
{ 0x5102, 0x4113, 0x8337, 0x8267, 0x2245, 0x3304, 0x5102, 0x4113, 0x2245, 0x4113, 0x8267, 0x2245 },
{ 0x2315, 0x2245, 0x8267, 0x8337, 0x5102, 0x4223, 0x1326 },
{ 0x6201, 0x4223, 0x1326, 0x3304, 0x8337, 0x2315, 0x2245, 0x8267 },
{ 0x4113, 0x6201, 0x2245, 0x8267, 0x8337, 0x5102, 0x4223, 0x1326, 0x6201, 0x8337, 0x6201, 0x8267 },
{ 0x4113, 0x4223, 0x1326, 0x3304, 0x2245, 0x8267, 0x8337, 0x4113, 0x1326, 0x4113, 0x3304, 0x4113, 0x2245, 0x4113, 0x8267 },
{ 0x2315, 0x2245, 0x8267, 0x4223, 0x4113, 0x2245, 0x4113, 0x2245, 0x4223 },
{ 0x2315, 0x2245, 0x8267, 0x4223, 0x4113, 0x6201, 0x5102, 0x3304, 0x2245, 0x4113, 0x2245, 0x4223 },
{ 0x6201, 0x2245, 0x8267, 0x4223, 0x6201, 0x8267 },
{ 0x3304, 0x2245, 0x8267, 0x4223, 0x5102, 0x2245, 0x5102, 0x2245, 0x4223 },
{ 0x5102, 0x4113, 0x2315, 0x2245, 0x8267, 0x1326, 0x5102, 0x4113, 0x8267, 0x4113, 0x2245, 0x8267 },
{ 0x4113, 0x2315, 0x2245, 0x8267, 0x1326, 0x3304, 0x6201, 0x4113, 0x2245, 0x4113, 0x8267, 0x4113, 0x1326, 0x4113, 0x3304 },
{ 0x5102, 0x6201, 0x2245, 0x8267, 0x1326, 0x6201, 0x1326, 0x6201, 0x8267 },
{ 0x3304, 0x2245, 0x8267, 0x1326, 0x3304, 0x8267 },
//176 0 3 10
{ 0x8267, 0x8337, 0x2315, 0x3304, 0x1146, 0x8337, 0x1146, 0x8337, 0x3304 },
{ 0x5102, 0x1146, 0x8267, 0x8337, 0x2315, 0x6201, 0x5102, 0x1146, 0x2315, 0x1146, 0x8337, 0x2315 },
{ 0x3304, 0x1146, 0x8267, 0x8337, 0x4113, 0x6201, 0x3304, 0x8337, 0x4113, 0x3304, 0x1146, 0x8337 },
{ 0x8337, 0x4113, 0x5102, 0x1146, 0x8267, 0x4113, 0x8267, 0x4113, 0x1146 },
{ 0x8267, 0x8337, 0x2315, 0x3304, 0x1146, 0x5102, 0x4223, 0x1326, 0x8337, 0x1146, 0x8337, 0x3304 },
{ 0x1146, 0x8267, 0x8337, 0x2315, 0x6201, 0x4223, 0x1326, 0x1146, 0x8337, 0x1146, 0x2315, 0x1146, 0x6201, 0x1146, 0x4223 },
{ 0x8267, 0x8337, 0x4113, 0x6201, 0x3304, 0x1146, 0x5102, 0x4223, 0x1326, 0x8267, 0x3304, 0x8267, 0x6201, 0x8337, 0x6201 },
{ 0x4113, 0x4223, 0x1326, 0x1146, 0x8267, 0x8337, 0x4113, 0x1326, 0x4113, 0x1146, 0x4113, 0x8267 },
{ 0x3304, 0x2315, 0x4113, 0x4223, 0x8267, 0x1146, 0x3304, 0x2315, 0x8267, 0x2315, 0x4223, 0x8267 },
{ 0x2315, 0x6201, 0x5102, 0x1146, 0x8267, 0x4223, 0x4113, 0x2315, 0x5102, 0x2315, 0x1146, 0x2315, 0x8267, 0x2315, 0x4223 },
{ 0x1146, 0x8267, 0x4223, 0x6201, 0x3304, 0x8267, 0x3304, 0x8267, 0x6201 },
{ 0x5102, 0x1146, 0x8267, 0x4223, 0x5102, 0x8267 },
{ 0x8267, 0x1326, 0x5102, 0x4113, 0x2315, 0x3304, 0x1146, 0x8267, 0x5102, 0x8267, 0x4113, 0x8267, 0x2315, 0x8267, 0x3304 },
{ 0x6201, 0x4113, 0x2315, 0x1326, 0x1146, 0x8267 },
{ 0x6201, 0x3304, 0x1146, 0x8267, 0x1326, 0x5102, 0x6201, 0x1146, 0x6201, 0x8267, 0x6201, 0x1326 },
{ 0x1326, 0x1146, 0x8267 },
//192 4 8 13 14
{ 0x1326, 0x8337, 0x8157, 0x1146, 0x1326, 0x8157 },
{ 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, 0x8157, 0x4223, 0x8157, 0x5102 },
{ 0x6201, 0x4223, 0x8337, 0x8157, 0x1146, 0x3304, 0x6201, 0x4223, 0x1146, 0x4223, 0x8157, 0x1146 },
{ 0x8337, 0x8157, 0x1146, 0x5102, 0x4223, 0x6201, 0x2315, 0x4113, 0x8157, 0x4223, 0x8157, 0x5102 },
{ 0x4223, 0x8337, 0x8157, 0x1146, 0x3304, 0x2315, 0x4113, 0x4223, 0x8157, 0x4223, 0x1146, 0x4223, 0x3304, 0x4223, 0x2315 },
{ 0x4223, 0x4113, 0x8157, 0x1146, 0x1326, 0x4113, 0x1326, 0x4113, 0x1146 },
{ 0x4223, 0x4113, 0x8157, 0x1146, 0x1326, 0x6201, 0x5102, 0x3304, 0x4113, 0x1326, 0x4113, 0x1146 },
{ 0x1146, 0x8157, 0x2315, 0x6201, 0x4223, 0x1326, 0x1146, 0x8157, 0x4223, 0x8157, 0x6201, 0x4223 },
{ 0x4223, 0x5102, 0x3304, 0x2315, 0x8157, 0x1146, 0x1326, 0x4223, 0x3304, 0x4223, 0x2315, 0x4223, 0x8157, 0x4223, 0x1146 },
{ 0x4113, 0x8157, 0x1146, 0x5102, 0x4113, 0x1146 },
{ 0x6201, 0x4113, 0x8157, 0x1146, 0x3304, 0x4113, 0x3304, 0x4113, 0x1146 },
{ 0x2315, 0x8157, 0x1146, 0x5102, 0x6201, 0x8157, 0x6201, 0x8157, 0x5102 },
{ 0x2315, 0x8157, 0x1146, 0x3304, 0x2315, 0x1146 },
//208 0 5 12
{ 0x2245, 0x3304, 0x1326, 0x8337, 0x8157, 0x3304, 0x8157, 0x3304, 0x8337 },
{ 0x6201, 0x2245, 0x8157, 0x8337, 0x1326, 0x5102, 0x6201, 0x2245, 0x1326, 0x2245, 0x8337, 0x1326 },
{ 0x2245, 0x3304, 0x1326, 0x8337, 0x8157, 0x6201, 0x2315, 0x4113, 0x3304, 0x8157, 0x3304, 0x8337 },
{ 0x2245, 0x2315, 0x4113, 0x5102, 0x1326, 0x8337, 0x8157, 0x2245, 0x4113, 0x2245, 0x5102, 0x2245, 0x1326, 0x2245, 0x8337 },
{ 0x4223, 0x8337, 0x8157, 0x2245, 0x3304, 0x5102, 0x4223, 0x2245, 0x3304, 0x4223, 0x8337, 0x2245 },
{ 0x8157, 0x2245, 0x6201, 0x4223, 0x8337, 0x2245, 0x8337, 0x2245, 0x4223 },
{ 0x2245, 0x3304, 0x5102, 0x4223, 0x8337, 0x8157, 0x4113, 0x6201, 0x2315, 0x2245, 0x8337, 0x2245, 0x4223, 0x3304, 0x4223 },
{ 0x4223, 0x8337, 0x8157, 0x2245, 0x2315, 0x4113, 0x4223, 0x8157, 0x4223, 0x2245, 0x4223, 0x2315 },
{ 0x4113, 0x8157, 0x2245, 0x3304, 0x1326, 0x4223, 0x4113, 0x8157, 0x1326, 0x8157, 0x3304, 0x1326 },
{ 0x1326, 0x4223, 0x4113, 0x8157, 0x2245, 0x6201, 0x5102, 0x1326, 0x4113, 0x1326, 0x8157, 0x1326, 0x2245, 0x1326, 0x6201 },
{ 0x8157, 0x2245, 0x3304, 0x1326, 0x4223, 0x6201, 0x2315, 0x8157, 0x3304, 0x8157, 0x1326, 0x8157, 0x4223, 0x8157, 0x6201 },
{ 0x5102, 0x1326, 0x4223, 0x2315, 0x8157, 0x2245 },
{ 0x3304, 0x5102, 0x4113, 0x8157, 0x2245, 0x5102, 0x2245, 0x5102, 0x8157 },
{ 0x4113, 0x8157, 0x2245, 0x6201, 0x4113, 0x2245 },
{ 0x5102, 0x6201, 0x2315, 0x8157, 0x2245, 0x3304, 0x5102, 0x2315, 0x5102, 0x8157, 0x5102, 0x2245 },
{ 0x2315, 0x8157, 0x2245 },
//224 0 10 12
{ 0x1146, 0x1326, 0x8337, 0x2315, 0x2245, 0x1326, 0x2245, 0x1326, 0x2315 },
{ 0x1146, 0x1326, 0x8337, 0x2315, 0x2245, 0x6201, 0x5102, 0x3304, 0x1326, 0x2245, 0x1326, 0x2315 },
{ 0x6201, 0x2245, 0x1146, 0x1326, 0x8337, 0x4113, 0x6201, 0x2245, 0x8337, 0x2245, 0x1326, 0x8337 },
{ 0x2245, 0x1146, 0x1326, 0x8337, 0x4113, 0x5102, 0x3304, 0x2245, 0x1326, 0x2245, 0x8337, 0x2245, 0x4113, 0x2245, 0x5102 },
{ 0x5102, 0x1146, 0x2245, 0x2315, 0x8337, 0x4223, 0x5102, 0x1146, 0x8337, 0x1146, 0x2315, 0x8337 },
{ 0x1146, 0x3304, 0x6201, 0x4223, 0x8337, 0x2315, 0x2245, 0x1146, 0x6201, 0x1146, 0x4223, 0x1146, 0x8337, 0x1146, 0x2315 },
{ 0x8337, 0x4113, 0x6201, 0x2245, 0x1146, 0x5102, 0x4223, 0x8337, 0x6201, 0x8337, 0x2245, 0x8337, 0x1146, 0x8337, 0x5102 },
{ 0x4223, 0x8337, 0x4113, 0x3304, 0x2245, 0x1146 },
{ 0x4113, 0x2315, 0x2245, 0x1146, 0x1326, 0x4223, 0x4113, 0x1146, 0x1326, 0x4113, 0x2315, 0x1146 },
{ 0x1146, 0x1326, 0x4223, 0x4113, 0x2315, 0x2245, 0x6201, 0x5102, 0x3304, 0x1146, 0x2315, 0x1146, 0x4113, 0x1326, 0x4113 },
{ 0x1326, 0x4223, 0x6201, 0x2245, 0x1146, 0x4223, 0x1146, 0x4223, 0x2245 },
{ 0x4223, 0x5102, 0x3304, 0x2245, 0x1146, 0x1326, 0x4223, 0x3304, 0x4223, 0x2245, 0x4223, 0x1146 },
{ 0x2245, 0x1146, 0x5102, 0x4113, 0x2315, 0x1146, 0x2315, 0x1146, 0x4113 },
{ 0x4113, 0x2315, 0x2245, 0x1146, 0x3304, 0x6201, 0x4113, 0x2245, 0x4113, 0x1146, 0x4113, 0x3304 },
{ 0x6201, 0x2245, 0x1146, 0x5102, 0x6201, 0x1146 },
{ 0x3304, 0x2245, 0x1146 },
//240 1 2 4 8
{ 0x3304, 0x1326, 0x8337, 0x2315, 0x3304, 0x8337 },
{ 0x5102, 0x1326, 0x8337, 0x2315, 0x6201, 0x1326, 0x6201, 0x1326, 0x2315 },
{ 0x6201, 0x3304, 0x1326, 0x8337, 0x4113, 0x3304, 0x4113, 0x3304, 0x8337 },
{ 0x5102, 0x1326, 0x8337, 0x4113, 0x5102, 0x8337 },
{ 0x4223, 0x8337, 0x2315, 0x3304, 0x5102, 0x8337, 0x5102, 0x8337, 0x3304 },
{ 0x6201, 0x4223, 0x8337, 0x2315, 0x6201, 0x8337 },
{ 0x3304, 0x5102, 0x4223, 0x8337, 0x4113, 0x6201, 0x3304, 0x4223, 0x3304, 0x8337, 0x3304, 0x4113 },
{ 0x4113, 0x4223, 0x8337 },
{ 0x4113, 0x2315, 0x3304, 0x1326, 0x4223, 0x2315, 0x4223, 0x2315, 0x1326 },
{ 0x1326, 0x4223, 0x4113, 0x2315, 0x6201, 0x5102, 0x1326, 0x4113, 0x1326, 0x2315, 0x1326, 0x6201 },
{ 0x3304, 0x1326, 0x4223, 0x6201, 0x3304, 0x4223 },
{ 0x5102, 0x1326, 0x4223 },
{ 0x5102, 0x4113, 0x2315, 0x3304, 0x5102, 0x2315 },
{ 0x6201, 0x4113, 0x2315 },
{ 0x6201, 0x3304, 0x5102 },
{}
//256
};
const Vector3 marching_cube_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 MarchingCubes

View File

@ -0,0 +1,67 @@
//Please note, that these tables were modified to get support for uv-mapping!
//================================================================================
//
// The MarchingCubes Algorithm look-up tables
//
// Copyright 2009 by Eric Lengyel
//
// The following data originates from Eric Lengyel's MarchingCubes Algorithm.
// http://transvoxel.org/
//
// The data in this file may be freely used in implementations of the MarchingCubes
// 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
// MarchingCubes 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 MarchingCubes 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 MARCHING_CUBES_TABLES_H
#define MARCHING_CUBES_TABLES_H
#include "core/math/vector3.h"
namespace MarchingCubes {
// 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);
}
};
extern const unsigned char regularCellClass[256];
extern const RegularCellData regularCellData[16];
extern const unsigned short regularVertexData[256][15];
extern const Vector3 marching_cube_vertices[8];
} // namespace MarchingCubes
#endif

View File

@ -0,0 +1,554 @@
/*
Copyright (c) 2019-2020 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "voxel_mesher_marching_cubes.h"
#include "../../world/default/voxel_chunk_default.h"
#include "../../world/voxel_chunk.h"
#include "core/array.h"
#include "core/dictionary.h"
#include "core/version.h"
#if VERSION_MAJOR < 4
#include "servers/visual_server.h"
#else
#include "servers/rendering_server.h"
typedef class RenderingServer VisualServer;
#endif
int VoxelMesherMarchingCubes::get_texture_scale() const {
return _texture_scale;
}
void VoxelMesherMarchingCubes::set_texture_scale(const int value) {
_texture_scale = value;
}
void VoxelMesherMarchingCubes::get_voxel_type_array(int *arr, Ref<VoxelChunk> chunk, const int x, const int y, const int z, const int size) {
uint8_t *channel_type = chunk->get_channel(VoxelChunkDefault::DEFAULT_CHANNEL_TYPE);
if (channel_type == NULL) {
arr[0] = 0;
arr[1] = 0;
arr[2] = 0;
arr[3] = 0;
arr[4] = 0;
arr[5] = 0;
arr[6] = 0;
arr[7] = 0;
return;
}
arr[0] = channel_type[chunk->get_index(x, y, z)];
arr[1] = channel_type[chunk->get_index(x, y + size, z)];
arr[2] = channel_type[chunk->get_index(x, y, z + size)];
arr[3] = channel_type[chunk->get_index(x, y + size, z + size)];
arr[4] = channel_type[chunk->get_index(x + size, y, z)];
arr[5] = channel_type[chunk->get_index(x + size, y + size, z)];
arr[6] = channel_type[chunk->get_index(x + size, y, z + size)];
arr[7] = channel_type[chunk->get_index(x + size, y + size, z + size)];
}
int VoxelMesherMarchingCubes::get_case_code_from_arr(const int *data) {
int case_code = 0;
if (data[0] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_000;
if (data[1] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_010;
if (data[2] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_001;
if (data[3] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_011;
if (data[4] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_100;
if (data[5] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_110;
if (data[6] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_101;
if (data[7] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_111;
return case_code;
}
int VoxelMesherMarchingCubes::get_case_code(Ref<VoxelChunk> chunk, const int x, const int y, const int z, const int size) {
uint8_t *channel_type = chunk->get_channel(VoxelChunkDefault::DEFAULT_CHANNEL_TYPE);
if (channel_type == NULL) {
return 0;
}
int case_code = 0;
if (channel_type[chunk->get_index(x, y, z)] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_000;
if (channel_type[chunk->get_index(x, y + size, z)] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_010;
if (channel_type[chunk->get_index(x, y, z + size)] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_001;
if (channel_type[chunk->get_index(x, y + size, z + size)] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_011;
if (channel_type[chunk->get_index(x + size, y, z)] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_100;
if (channel_type[chunk->get_index(x + size, y + size, z)] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_110;
if (channel_type[chunk->get_index(x + size, y, z + size)] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_101;
if (channel_type[chunk->get_index(x + size, y + size, z + size)] != 0)
case_code = case_code | VOXEL_ENTRY_MASK_111;
return case_code;
}
int VoxelMesherMarchingCubes::get_voxel_type(Ref<VoxelChunk> chunk, const int x, const int y, const int z, const int size) {
uint8_t *channel_type = chunk->get_channel(VoxelChunkDefault::DEFAULT_CHANNEL_TYPE);
if (channel_type == NULL) {
return 0;
}
int type = 0;
type = channel_type[chunk->get_index(x, y + size, z)];
if (type != 0)
return type;
type = channel_type[chunk->get_index(x, y, z + size)];
if (type != 0)
return type;
type = channel_type[chunk->get_index(x, y + size, z + size)];
if (type != 0)
return type;
type = channel_type[chunk->get_index(x + size, y + size, z + size)];
if (type != 0)
return type;
type = channel_type[chunk->get_index(x, y, z)];
if (type != 0)
return type;
type = channel_type[chunk->get_index(x + size, y + size, z)];
if (type != 0)
return type;
type = channel_type[chunk->get_index(x + size, y, z)];
if (type != 0)
return type;
type = channel_type[chunk->get_index(x + size, y, z + size)];
return type;
}
void VoxelMesherMarchingCubes::_add_chunk(Ref<VoxelChunk> p_chunk) {
Ref<VoxelChunkDefault> chunk = p_chunk;
ERR_FAIL_COND(!chunk.is_valid());
chunk->generate_ao();
int type_arr[8];
int x_size = chunk->get_size_x();
int y_size = chunk->get_size_y();
int z_size = chunk->get_size_z();
int lod_size = get_lod_size();
for (int y = 0; y < y_size; y += lod_size) {
for (int z = 0; z < z_size; z += lod_size) {
for (int x = 0; x < x_size; x += lod_size) {
get_voxel_type_array(type_arr, chunk, x, y, z, lod_size);
int case_code = get_case_code_from_arr(type_arr);
if (case_code == 0 || case_code == 255) {
continue;
}
int regular_cell_class = get_regular_cell_class(case_code);
Ref<MarchingCubesCellData> cell_data = get_regular_cell_data(regular_cell_class);
int index_count = cell_data->get_triangle_count() * 3;
int vertex_count = cell_data->get_vertex_count();
for (int i = 0; i < index_count; ++i) {
int ind = get_vertex_count() + cell_data->get_vertex_index(i);
add_indices(ind);
}
Vector<Vector3> temp_verts;
Dictionary carr;
for (int i = 0; i < 8; ++i) {
int t = type_arr[i];
if (carr.has(t))
carr[t] = static_cast<int>(carr[t]) + 1;
else
carr[t] = 1;
}
int type_id1 = -1;
int type_id1c = -1;
int type_id2 = -1;
int type_id2c = -1;
const Variant *K = NULL;
while ((K = carr.next(K))) {
int k = *K;
if (k == 0)
continue;
int c = carr[k];
if (type_id1c == -1) {
type_id1 = k;
type_id1c = c;
continue;
}
if (c > type_id1c) {
type_id1 = k;
type_id1c = c;
}
}
K = NULL;
while ((K = carr.next(K))) {
int k = *K;
if (k == 0)
continue;
int c = carr[k];
if (type_id2c == -1) {
type_id2 = k;
type_id2c = c;
continue;
}
if (c > type_id2c && k != type_id1) {
type_id2 = k;
type_id2c = c;
}
}
float surface_ratio = 1.0;
if (type_id1 != type_id2) {
if (type_id1c > 0 && type_id2c > 0) {
surface_ratio = 0.5;
} else {
surface_ratio = 0;
}
}
Ref<VoxelSurface> surface1 = _library->get_voxel_surface(type_id1 - 1);
Ref<VoxelSurface> surface2 = _library->get_voxel_surface(type_id2 - 1);
for (int i = 0; i < vertex_count; ++i) {
int fv = get_regular_vertex_data_first_vertex(case_code, i);
int sv = get_regular_vertex_data_second_vertex(case_code, i);
Vector3 offs0 = corner_id_to_vertex(fv) * lod_size;
Vector3 offs1 = corner_id_to_vertex(sv) * lod_size;
int type = chunk->get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunkDefault::DEFAULT_CHANNEL_TYPE);
int fill = 0;
Vector3 vert_pos;
Vector3 vert_dir;
if (type == 0) {
fill = chunk->get_voxel(int(x + offs1.x), int(y + offs1.y), int(z + offs1.z), VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL);
vert_pos = get_regular_vertex_second_position(case_code, i);
vert_dir = get_regular_vertex_first_position(case_code, i);
} else {
fill = chunk->get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunkDefault::DEFAULT_CHANNEL_ISOLEVEL);
vert_pos = get_regular_vertex_first_position(case_code, i);
vert_dir = get_regular_vertex_second_position(case_code, i);
}
vert_dir = vert_dir - vert_pos;
vert_pos += vert_dir * (fill / 256.0);
temp_verts.push_back(vert_pos);
}
PoolVector<Vector3> temp_normals;
temp_normals.resize(temp_verts.size());
for (int i = 0; i < index_count; i += 3) {
int indices[] = {
cell_data->get_vertex_index(i),
cell_data->get_vertex_index(i + 1),
cell_data->get_vertex_index(i + 2)
};
Vector3 vertices[] = {
temp_verts[indices[0]],
temp_verts[indices[1]],
temp_verts[indices[2]],
};
Vector3 i0 = temp_normals[indices[0]];
Vector3 i1 = temp_normals[indices[1]];
Vector3 i2 = temp_normals[indices[2]];
Vector3 v0 = vertices[0];
Vector3 v1 = vertices[1];
Vector3 v2 = vertices[2];
temp_normals.set(indices[0], i0 + (v1 - v0).cross(v0 - v2));
temp_normals.set(indices[1], i1 + (v2 - v1).cross(v1 - v0));
temp_normals.set(indices[2], i2 + (v2 - v1).cross(v2 - v0));
}
for (int i = 0; i < temp_verts.size(); ++i)
temp_normals.set(i, temp_normals[i].normalized());
PoolVector<Vector2> temp_uvs;
temp_uvs.resize(temp_verts.size());
PoolVector<Vector2> temp_uv2s;
temp_uv2s.resize(temp_verts.size());
for (int cvi = 0; cvi < temp_verts.size(); ++cvi) {
Vector3 vertex = temp_verts[cvi];
Vector3 normal = temp_normals[cvi];
Vector3 s;
Vector3 t;
t.x = vertex.z;
t.y = vertex.z;
t.z = vertex.y;
s.x = vertex.y;
s.y = vertex.x;
s.z = vertex.x;
real_t bx = ABS(normal.x);
real_t by = ABS(normal.y);
real_t bz = ABS(normal.z);
if ((bx + 0.0001 > by) && (bx + 0.0001 > bz)) {
Vector2 uv(s.x, t.x);
Rect2 umargin = get_uv_margin();
uv.x *= umargin.size.x;
uv.y *= umargin.size.y;
uv.x += umargin.position.x;
uv.y += umargin.position.y;
temp_uvs.set(cvi, surface1->transform_uv_scaled(VoxelSurface::VOXEL_SIDE_SIDE, uv, x % get_texture_scale(), z % get_texture_scale(), get_texture_scale()));
temp_uv2s.set(cvi, surface2->transform_uv_scaled(VoxelSurface::VOXEL_SIDE_SIDE, uv, x % get_texture_scale(), z % get_texture_scale(), get_texture_scale()));
} else if ((bz + 0.0001 > bx) && (bz + 0.0001 > by)) {
Vector2 uv(s.z, t.z);
Rect2 umargin = get_uv_margin();
uv.x *= umargin.size.x;
uv.y *= umargin.size.y;
uv.x += umargin.position.x;
uv.y += umargin.position.y;
temp_uvs.set(cvi, surface1->transform_uv_scaled(VoxelSurface::VOXEL_SIDE_SIDE, uv, x % get_texture_scale(), z % get_texture_scale(), get_texture_scale()));
temp_uv2s.set(cvi, surface2->transform_uv_scaled(VoxelSurface::VOXEL_SIDE_SIDE, uv, x % get_texture_scale(), z % get_texture_scale(), get_texture_scale()));
} else {
Vector2 uv(s.y, t.y);
Rect2 umargin = get_uv_margin();
uv.x *= umargin.size.x;
uv.y *= umargin.size.y;
uv.x += umargin.position.x;
uv.y += umargin.position.y;
temp_uvs.set(cvi, surface1->transform_uv_scaled(VoxelSurface::VOXEL_SIDE_TOP, uv, x % get_texture_scale(), z % get_texture_scale(), get_texture_scale()));
temp_uv2s.set(cvi, surface2->transform_uv_scaled(VoxelSurface::VOXEL_SIDE_TOP, uv, x % get_texture_scale(), z % get_texture_scale(), get_texture_scale()));
}
}
for (int i = 0; i < temp_verts.size(); ++i) {
Vector3 vert_pos = temp_verts[i];
vert_pos *= float(lod_size);
vert_pos += Vector3(x, y, z);
Vector3 normal = temp_normals[i];
add_color(Color(1.0, 1.0, 1.0, surface_ratio));
vert_pos *= get_voxel_scale();
add_normal(normal);
add_uv(temp_uvs[i]);
add_uv2(temp_uv2s[i]);
add_vertex(vert_pos);
}
}
}
}
remove_doubles_hashed();
}
Vector3 VoxelMesherMarchingCubes::corner_id_to_vertex(int corner_id) const {
ERR_FAIL_COND_V(corner_id < 0 || corner_id > 8, Vector3());
return marching_cube_vertices[corner_id];
}
int VoxelMesherMarchingCubes::get_regular_cell_class(int index) const {
return static_cast<int>(regularCellClass[index]);
}
Ref<MarchingCubesCellData> VoxelMesherMarchingCubes::get_regular_cell_data(int index) const {
return _regular_cell_datas[index];
}
int VoxelMesherMarchingCubes::get_regular_vertex_data(int index1, int index2) const {
//return static_cast<int>(regularVertexData[index1][index2]);
return regularVertexData[index1][index2];
}
//void VoxelMesherMarchingCubes::set_regular_vertex_data(int index1, int index2, int value) {
// ERR_FAIL_INDEX(index1, 256);
// ERR_FAIL_INDEX(index2, 13);
// regularVertexData[index1][index2] = value;
//}
int VoxelMesherMarchingCubes::get_regular_vertex_data_first_vertex(int index1, int index2) const {
int vert1 = regularVertexData[index1][index2] & 0x000F;
return vert1;
}
int VoxelMesherMarchingCubes::get_regular_vertex_data_second_vertex(int index1, int index2) const {
int vert2 = (regularVertexData[index1][index2] & 0x00F0) >> 4;
return vert2;
}
Vector3 VoxelMesherMarchingCubes::get_regular_vertex_first_position(int index1, int index2) const {
int vert = regularVertexData[index1][index2] & 0x000F;
return marching_cube_vertices[vert];
}
Vector3 VoxelMesherMarchingCubes::get_regular_vertex_second_position(int index1, int index2) const {
int vert = (regularVertexData[index1][index2] & 0x00F0) >> 4;
return marching_cube_vertices[vert];
}
Vector3 VoxelMesherMarchingCubes::get_regular_vertex_direction(int index1, int index2) const {
int vert1 = regularVertexData[index1][index2] & 0x000F;
int vert2 = (regularVertexData[index1][index2] & 0x00F0) >> 4;
return marching_cube_vertices[vert2] - marching_cube_vertices[vert1];
}
VoxelMesherMarchingCubes::VoxelMesherMarchingCubes() {
_format = VisualServer::ARRAY_FORMAT_NORMAL | VisualServer::ARRAY_FORMAT_COLOR | VisualServer::ARRAY_FORMAT_TEX_UV | VisualServer::ARRAY_FORMAT_TEX_UV2;
_texture_scale = 4;
for (int i = 0; i < 16; ++i) {
_regular_cell_datas[i] = Ref<MarchingCubesCellData>(memnew(MarchingCubesCellData(regularCellData[i])));
}
}
VoxelMesherMarchingCubes::~VoxelMesherMarchingCubes() {
for (int i = 0; i < 16; ++i) {
_regular_cell_datas[i].unref();
}
}
void VoxelMesherMarchingCubes::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_texture_scale"), &VoxelMesherMarchingCubes::get_texture_scale);
ClassDB::bind_method(D_METHOD("set_texture_scale", "value"), &VoxelMesherMarchingCubes::set_texture_scale);
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_scale"), "set_texture_scale", "get_texture_scale");
ClassDB::bind_method(D_METHOD("_add_chunk", "chunk"), &VoxelMesherMarchingCubes::_add_chunk);
ClassDB::bind_method(D_METHOD("corner_id_to_vertex", "index1"), &VoxelMesherMarchingCubes::corner_id_to_vertex);
ClassDB::bind_method(D_METHOD("get_regular_cell_class", "index"), &VoxelMesherMarchingCubes::get_regular_cell_class);
ClassDB::bind_method(D_METHOD("get_regular_cell_data", "index"), &VoxelMesherMarchingCubes::get_regular_cell_data);
ClassDB::bind_method(D_METHOD("get_regular_vertex_data", "index1", "index2"), &VoxelMesherMarchingCubes::get_regular_vertex_data);
// ClassDB::bind_method(D_METHOD("set_regular_vertex_data", "index1", "index2", "value"), &VoxelMesherMarchingCubes::set_regular_vertex_data);
ClassDB::bind_method(D_METHOD("get_regular_vertex_data_first_vertex", "index1", "index2"), &VoxelMesherMarchingCubes::get_regular_vertex_data_first_vertex);
ClassDB::bind_method(D_METHOD("get_regular_vertex_data_second_vertex", "index1", "index2"), &VoxelMesherMarchingCubes::get_regular_vertex_data_second_vertex);
ClassDB::bind_method(D_METHOD("get_regular_vertex_first_position", "index1", "index2"), &VoxelMesherMarchingCubes::get_regular_vertex_first_position);
ClassDB::bind_method(D_METHOD("get_regular_vertex_second_position", "index1", "index2"), &VoxelMesherMarchingCubes::get_regular_vertex_second_position);
ClassDB::bind_method(D_METHOD("get_regular_vertex_direction", "index1", "index2"), &VoxelMesherMarchingCubes::get_regular_vertex_direction);
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);
}

View File

@ -0,0 +1,105 @@
/*
Copyright (c) 2019-2020 Péter Magyar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef VOXEL_MESHER_MARCHING_CUBES_H
#define VOXEL_MESHER_MARCHING_CUBES_H
#include "../default/voxel_mesher_default.h"
#include "core/reference.h"
#include "marching_cubes_cell_data.h"
#include "marching_cubes_tables.h"
using namespace MarchingCubes;
class VoxelMesherMarchingCubes : public VoxelMesherDefault {
GDCLASS(VoxelMesherMarchingCubes, VoxelMesherDefault)
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,
};
int get_texture_scale() const;
void set_texture_scale(const int value);
//arr should have a size of 8
void get_voxel_type_array(int *arr, Ref<VoxelChunk> chunk, const int x, const int y, const int z, const int size = 1);
int get_case_code_from_arr(const int *data);
int get_case_code(Ref<VoxelChunk> chunk, const int x, const int y, const int z, const int size = 1);
int get_voxel_type(Ref<VoxelChunk> chunk, const int x, const int y, const int z, const int size = 1);
void _add_chunk(Ref<VoxelChunk> p_chunk);
Vector3 corner_id_to_vertex(int corner_id) const;
int get_regular_cell_class(int index) const;
Ref<MarchingCubesCellData> get_regular_cell_data(int index) const;
int get_regular_vertex_data(int index10, int index2) const;
// void set_regular_vertex_data(int index1, int index2, int value);
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_first_position(int index1, int index2) const;
Vector3 get_regular_vertex_second_position(int index1, int index2) const;
Vector3 get_regular_vertex_direction(int index1, int index2) const;
VoxelMesherMarchingCubes();
~VoxelMesherMarchingCubes();
protected:
static void _bind_methods();
Ref<MarchingCubesCellData> _regular_cell_datas[16];
int _texture_scale;
};
VARIANT_ENUM_CAST(VoxelMesherMarchingCubes::VoxelEntryIndices);
VARIANT_ENUM_CAST(VoxelMesherMarchingCubes::VoxelEntryMask);
#endif // VOXEL_MESHER_SMOOTH_H

View File

@ -38,6 +38,9 @@ SOFTWARE.
#include "meshers/transvoxel_uv_mesher/voxel_mesher_uv_transvoxel.h"
#include "meshers/voxel_mesher.h"
#include "meshers/marching_cubes/marching_cubes_cell_data.h"
#include "meshers/marching_cubes/voxel_mesher_marching_cubes.h"
#include "world/block_voxel_structure.h"
#include "world/environment_data.h"
#include "world/voxel_chunk.h"
@ -69,6 +72,9 @@ void register_voxelman_types() {
ClassDB::register_class<VoxelMesherUVTransvoxel>();
ClassDB::register_class<TransvoxelCellData>();
ClassDB::register_class<VoxelMesherMarchingCubes>();
ClassDB::register_class<MarchingCubesCellData>();
ClassDB::register_class<VoxelSurface>();
ClassDB::register_class<VoxelSurfaceSimple>();