mirror of
https://github.com/Relintai/voxelman.git
synced 2025-01-12 15:01:09 +01:00
Turned the Transvoxel mesher into a MarchingCubes mesher. Removed the parts that weren't used.
This commit is contained in:
parent
aeff73083e
commit
a83585bd81
4
SCsub
4
SCsub
@ -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",
|
||||
|
@ -29,6 +29,10 @@ def get_doc_classes():
|
||||
"TransvoxelCellData",
|
||||
"VoxelMeshData",
|
||||
"VoxelMesherUVTransvoxel",
|
||||
|
||||
"MarchingCubesCellData",
|
||||
"VoxelMesherMarchingCubes",
|
||||
|
||||
"VoxelMesher",
|
||||
|
||||
"EnvironmentData",
|
||||
|
80
meshers/marching_cubes/marching_cubes_cell_data.cpp
Normal file
80
meshers/marching_cubes/marching_cubes_cell_data.cpp
Normal 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);
|
||||
}
|
57
meshers/marching_cubes/marching_cubes_cell_data.h
Normal file
57
meshers/marching_cubes/marching_cubes_cell_data.h
Normal 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
|
380
meshers/marching_cubes/marching_cubes_tables.cpp
Normal file
380
meshers/marching_cubes/marching_cubes_tables.cpp
Normal 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
|
67
meshers/marching_cubes/marching_cubes_tables.h
Normal file
67
meshers/marching_cubes/marching_cubes_tables.h
Normal 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
|
554
meshers/marching_cubes/voxel_mesher_marching_cubes.cpp
Normal file
554
meshers/marching_cubes/voxel_mesher_marching_cubes.cpp
Normal 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);
|
||||
}
|
105
meshers/marching_cubes/voxel_mesher_marching_cubes.h
Normal file
105
meshers/marching_cubes/voxel_mesher_marching_cubes.h
Normal 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
|
@ -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>();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user