mirror of
https://github.com/Relintai/godot_voxel.git
synced 2024-11-19 02:47:18 +01:00
Added marching cubes polygonization, almost works but sometimes holes appear
This commit is contained in:
parent
a12435266f
commit
d74201c93f
350
dmc/marching_cubes_tables.h
Normal file
350
dmc/marching_cubes_tables.h
Normal file
@ -0,0 +1,350 @@
|
||||
#ifndef MARCHING_CUBES_TABLES_H
|
||||
#define MARCHING_CUBES_TABLES_H
|
||||
|
||||
namespace MarchingCubes {
|
||||
|
||||
// Marching Cubes tables from the public domain code found on http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
|
||||
// in http://paulbourke.net/geometry/polygonise/marchingsource.cpp
|
||||
// Thanks!
|
||||
|
||||
// Edges table
|
||||
int mc_edges[256] = {
|
||||
0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
||||
0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
|
||||
0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
|
||||
0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
|
||||
0x460, 0x569, 0x663, 0x76a, 0x066, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
|
||||
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
|
||||
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
|
||||
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc, 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
|
||||
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
|
||||
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x055, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
|
||||
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
|
||||
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
|
||||
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
|
||||
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
|
||||
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
|
||||
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000
|
||||
};
|
||||
|
||||
// Triangulation lookup table
|
||||
int mc_triangles[256][16] = {
|
||||
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
|
||||
{ 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 },
|
||||
{ 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 },
|
||||
{ 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
|
||||
{ 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 },
|
||||
{ 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 },
|
||||
{ 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
|
||||
{ 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 },
|
||||
{ 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 },
|
||||
{ 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
|
||||
{ 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 },
|
||||
{ 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 },
|
||||
{ 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 },
|
||||
{ 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 },
|
||||
{ 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 },
|
||||
{ 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 },
|
||||
{ 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
|
||||
{ 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 },
|
||||
{ 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
|
||||
{ 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 },
|
||||
{ 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 },
|
||||
{ 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 },
|
||||
{ 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 },
|
||||
{ 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 },
|
||||
{ 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
|
||||
{ 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 },
|
||||
{ 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 },
|
||||
{ 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 },
|
||||
{ 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
|
||||
{ 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 },
|
||||
{ 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 },
|
||||
{ 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
|
||||
{ 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 },
|
||||
{ 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 },
|
||||
{ 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 },
|
||||
{ 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 },
|
||||
{ 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 },
|
||||
{ 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
|
||||
{ 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 },
|
||||
{ 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
|
||||
{ 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 },
|
||||
{ 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 },
|
||||
{ 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 },
|
||||
{ 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 },
|
||||
{ 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 },
|
||||
{ 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 },
|
||||
{ 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 },
|
||||
{ 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 },
|
||||
{ 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 },
|
||||
{ 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 },
|
||||
{ 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 },
|
||||
{ 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 },
|
||||
{ 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 },
|
||||
{ 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 },
|
||||
{ 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 },
|
||||
{ 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 },
|
||||
{ 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 },
|
||||
{ 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 },
|
||||
{ 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 },
|
||||
{ 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 },
|
||||
{ 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 },
|
||||
{ 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 },
|
||||
{ 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 },
|
||||
{ 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 },
|
||||
{ 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 },
|
||||
{ 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 },
|
||||
{ 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 },
|
||||
{ 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 },
|
||||
{ 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 },
|
||||
{ 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 },
|
||||
{ 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 },
|
||||
{ 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 },
|
||||
{ 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 },
|
||||
{ 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 },
|
||||
{ 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 },
|
||||
{ 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 },
|
||||
{ 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 },
|
||||
{ 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 },
|
||||
{ 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 },
|
||||
{ 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 },
|
||||
{ 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 },
|
||||
{ 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 },
|
||||
{ 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 },
|
||||
{ 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 },
|
||||
{ 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 },
|
||||
{ 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 },
|
||||
{ 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 },
|
||||
{ 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 },
|
||||
{ 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 },
|
||||
{ 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 },
|
||||
{ 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 },
|
||||
{ 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 },
|
||||
{ 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 },
|
||||
{ 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 },
|
||||
{ 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 },
|
||||
{ 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 },
|
||||
{ 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 },
|
||||
{ 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 },
|
||||
{ 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 },
|
||||
{ 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 },
|
||||
{ 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 },
|
||||
{ 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 },
|
||||
{ 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 },
|
||||
{ 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 },
|
||||
{ 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }
|
||||
};
|
||||
|
||||
// Throw in the corners inside of the volume and get a 4 bit array which edges are cutting it.
|
||||
// Edge indices to check then (Edge between 0 and 4 cut == msEdges[x] & 4).
|
||||
//
|
||||
// 0---1---1
|
||||
// | |
|
||||
// 4 2
|
||||
// | |
|
||||
// 3---3---2
|
||||
//
|
||||
int ms_edges[16] = {
|
||||
0x0, // 0000 Nothing intersects
|
||||
0x9, // 0001 0
|
||||
0x3, // 0010 1
|
||||
0xA, // 0011 0 1
|
||||
0x6, // 0100 2
|
||||
0xF, // 0101 0 2
|
||||
0x5, // 0110 1 2
|
||||
0xC, // 0111 0 1 2
|
||||
0xC, // 1000 3
|
||||
0x5, // 1001 0 3
|
||||
0xF, // 1010 1 3
|
||||
0x6, // 1011 0 1 3
|
||||
0xA, // 1100 2 3
|
||||
0x3, // 1101 0 2 3
|
||||
0x9, // 1110 1 2 3
|
||||
0x0 // 1111 0 1 2 3
|
||||
};
|
||||
|
||||
// To get a triangulation with up to 5 triangles based on the corners inside. Alternative
|
||||
// ambigous cases added at the end. Indices of the counterclockwise formed triangles:
|
||||
//
|
||||
// 0---1---2
|
||||
// | |
|
||||
// 7 3
|
||||
// | |
|
||||
// 6---5---4
|
||||
//
|
||||
int ms_triangles[18][13] = {
|
||||
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nothing intersects
|
||||
{ 7, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 0
|
||||
{ 3, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 1
|
||||
{ 7, 2, 0, 7, 3, 2, -1, -1, -1, -1, -1, -1, -1 }, // 0 1
|
||||
{ 5, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 2
|
||||
{ 7, 1, 0, 3, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, // 0 2
|
||||
{ 1, 4, 2, 1, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, // 1 2
|
||||
{ 0, 7, 5, 0, 5, 4, 0, 4, 2, -1, -1, -1, -1 }, // 0 1 2
|
||||
{ 7, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // 3
|
||||
{ 0, 5, 1, 0, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, // 0 3
|
||||
{ 1, 3, 2, 7, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, // 1 3
|
||||
{ 3, 6, 5, 3, 0, 6, 3, 2, 0, -1, -1, -1, -1 }, // 0 1 3
|
||||
{ 7, 6, 4, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1 }, // 2 3
|
||||
{ 3, 1, 0, 3, 0, 6, 3, 6, 4, -1, -1, -1, -1 }, // 0 2 3
|
||||
{ 2, 1, 7, 2, 7, 6, 2, 6, 4, -1, -1, -1, -1 }, // 1 2 3
|
||||
{ 6, 2, 0, 6, 4, 2, -1, -1, -1, -1, -1, -1, -1 }, // 0 1 2 3
|
||||
{ 1, 0, 7, 1, 7, 5, 1, 5, 4, 1, 4, 3, -1 }, // 0 2 alternative
|
||||
{ 1, 3, 2, 1, 5, 3, 1, 6, 5, 1, 7, 6, -1 } // 1 3 alternative
|
||||
};
|
||||
|
||||
} // namespace MarchingCubes
|
||||
|
||||
#endif // MARCHING_CUBES_TABLES_H
|
@ -1,5 +1,8 @@
|
||||
#include "voxel_mesher_dmc.h"
|
||||
#include "../cube_tables.h"
|
||||
#include "../utility.h"
|
||||
#include "marching_cubes_tables.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
// Algorithm taken from https://www.volume-gfx.com/volume-rendering/dual-marching-cubes/
|
||||
@ -14,13 +17,14 @@ enum Channels {
|
||||
};
|
||||
|
||||
const int CHUNK_SIZE = 16;
|
||||
const float ISO_LEVEL = 0.0;
|
||||
|
||||
struct HermiteValue {
|
||||
float value; // Signed "distance" to surface
|
||||
Vector3 gradient; // "Normal" of the volume
|
||||
|
||||
HermiteValue() :
|
||||
value(0) {
|
||||
value(1.0) {
|
||||
}
|
||||
};
|
||||
|
||||
@ -102,21 +106,48 @@ void split(OctreeNode *node) {
|
||||
}
|
||||
}
|
||||
|
||||
inline float interpolate(float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, Vector3 position) {
|
||||
// Trilinear interpolation between corner values of a cube.
|
||||
// Cube points respect the same position as in the ASCII schema.
|
||||
template <typename T>
|
||||
inline T interpolate(const T v0, const T v1, const T v2, const T v3, const T v4, const T v5, const T v6, const T v7, Vector3 position) {
|
||||
|
||||
float one_min_x = 1.f - position.x;
|
||||
float one_min_y = 1.f - position.y;
|
||||
float one_min_z = 1.f - position.z;
|
||||
float one_min_x_one_min_y = one_min_x * one_min_y;
|
||||
float x_one_min_y = position.x * one_min_y;
|
||||
const float one_min_x = 1.f - position.x;
|
||||
const float one_min_y = 1.f - position.y;
|
||||
const float one_min_z = 1.f - position.z;
|
||||
const float one_min_x_one_min_y = one_min_x * one_min_y;
|
||||
const float x_one_min_y = position.x * one_min_y;
|
||||
|
||||
float res = one_min_z * (v0 * one_min_x_one_min_y + v1 * x_one_min_y + v4 * one_min_x * position.y);
|
||||
T res = one_min_z * (v0 * one_min_x_one_min_y + v1 * x_one_min_y + v4 * one_min_x * position.y);
|
||||
res += position.z * (v3 * one_min_x_one_min_y + v2 * x_one_min_y + v7 * one_min_x * position.y);
|
||||
res += position.x * position.y * (v5 * one_min_z + v6 * position.z);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
inline Vector3 interpolate(const Vector3 &v0, const Vector3 &v1, const HermiteValue &val0, const HermiteValue &val1, Vector3 &out_normal) {
|
||||
|
||||
if (Math::abs(val0.value - ISO_LEVEL) <= FLT_EPSILON) {
|
||||
out_normal = val0.gradient;
|
||||
return v0;
|
||||
}
|
||||
|
||||
if (Math::abs(val1.value - ISO_LEVEL) <= FLT_EPSILON) {
|
||||
out_normal = val1.gradient;
|
||||
return v1;
|
||||
}
|
||||
|
||||
if (Math::abs(val1.value - val0.value) <= FLT_EPSILON) {
|
||||
out_normal = val0.gradient;
|
||||
return v0;
|
||||
}
|
||||
|
||||
float mu = (ISO_LEVEL - val0.value) / (val1.value - val0.value);
|
||||
out_normal = val0.gradient + mu * (val1.gradient - val0.gradient);
|
||||
out_normal.normalize();
|
||||
|
||||
return v0 + mu * (v1 - v0);
|
||||
}
|
||||
|
||||
inline HermiteValue get_hermite_value(const VoxelBuffer &voxels, int x, int y, int z) {
|
||||
HermiteValue v;
|
||||
v.value = voxels.get_voxel_iso(x, y, z, CHANNEL_VALUE);
|
||||
@ -127,6 +158,35 @@ inline HermiteValue get_hermite_value(const VoxelBuffer &voxels, int x, int y, i
|
||||
return v;
|
||||
}
|
||||
|
||||
inline HermiteValue get_interpolated_hermite_value(const VoxelBuffer &voxels, Vector3 pos) {
|
||||
|
||||
int x0 = static_cast<int>(pos.x);
|
||||
int y0 = static_cast<int>(pos.y);
|
||||
int z0 = static_cast<int>(pos.z);
|
||||
|
||||
int x1 = static_cast<int>(Math::ceil(pos.x));
|
||||
int y1 = static_cast<int>(Math::ceil(pos.y));
|
||||
int z1 = static_cast<int>(Math::ceil(pos.z));
|
||||
|
||||
HermiteValue v0 = get_hermite_value(voxels, x0, y0, z0);
|
||||
HermiteValue v1 = get_hermite_value(voxels, x1, y0, z0);
|
||||
HermiteValue v2 = get_hermite_value(voxels, x1, y0, z1);
|
||||
HermiteValue v3 = get_hermite_value(voxels, x0, y0, z1);
|
||||
|
||||
HermiteValue v4 = get_hermite_value(voxels, x0, y1, z0);
|
||||
HermiteValue v5 = get_hermite_value(voxels, x1, y1, z0);
|
||||
HermiteValue v6 = get_hermite_value(voxels, x1, y1, z1);
|
||||
HermiteValue v7 = get_hermite_value(voxels, x0, y1, z1);
|
||||
|
||||
Vector3 rpos = pos - Vector3(x0, y0, z0);
|
||||
|
||||
HermiteValue v;
|
||||
v.value = interpolate(v0.value, v1.value, v2.value, v3.value, v4.value, v5.value, v6.value, v7.value, rpos);
|
||||
v.gradient = interpolate(v0.gradient, v1.gradient, v2.gradient, v3.gradient, v4.gradient, v5.gradient, v6.gradient, v7.gradient, rpos);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
bool can_split(OctreeNode *node, const VoxelBuffer &voxels, float geometric_error) {
|
||||
|
||||
if (node->size == 1) {
|
||||
@ -262,24 +322,19 @@ Ref<ArrayMesh> generate_debug_octree_mesh(OctreeNode *root) {
|
||||
|
||||
struct GetMaxDepth {
|
||||
int max_depth;
|
||||
void operator()(OctreeNode *node, int depth) {
|
||||
void operator()(OctreeNode *_, int depth) {
|
||||
if (depth > max_depth) {
|
||||
max_depth = depth;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
GetMaxDepth get_max_depth;
|
||||
foreach_node(root, get_max_depth);
|
||||
|
||||
struct Arrays {
|
||||
PoolVector3Array positions;
|
||||
PoolColorArray colors;
|
||||
PoolIntArray indices;
|
||||
};
|
||||
|
||||
Arrays arrays;
|
||||
|
||||
struct AddCube {
|
||||
Arrays *arrays;
|
||||
int max_depth;
|
||||
@ -306,6 +361,10 @@ Ref<ArrayMesh> generate_debug_octree_mesh(OctreeNode *root) {
|
||||
}
|
||||
};
|
||||
|
||||
GetMaxDepth get_max_depth;
|
||||
foreach_node(root, get_max_depth);
|
||||
|
||||
Arrays arrays;
|
||||
AddCube add_cube;
|
||||
add_cube.arrays = &arrays;
|
||||
add_cube.max_depth = get_max_depth.max_depth;
|
||||
@ -343,6 +402,10 @@ inline bool is_surface_near(OctreeNode *node) {
|
||||
struct DualCell {
|
||||
Vector3 corners[8];
|
||||
HermiteValue values[8];
|
||||
bool has_values;
|
||||
|
||||
DualCell() :
|
||||
has_values(false) {}
|
||||
|
||||
inline void set_corner(int i, Vector3 vertex, HermiteValue value) {
|
||||
CRASH_COND(i < 0 || i >= 8);
|
||||
@ -836,6 +899,7 @@ void vert_proc(DualGrid &grid, OctreeNode *n0, OctreeNode *n1, OctreeNode *n2, O
|
||||
cell.set_corner(5, get_center(n5), n5->center_value);
|
||||
cell.set_corner(6, get_center(n6), n6->center_value);
|
||||
cell.set_corner(7, get_center(n7), n7->center_value);
|
||||
cell.has_values = true;
|
||||
grid.cells.push_back(cell);
|
||||
|
||||
create_border_cells(grid, n0, n1, n2, n3, n4, n5, n6, n7);
|
||||
@ -1053,7 +1117,176 @@ void node_proc(DualGrid &grid, OctreeNode *node) {
|
||||
vert_proc(grid, children[0], children[1], children[2], children[3], children[4], children[5], children[6], children[7]);
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> polygonize(const VoxelBuffer &voxels, float geometric_error) {
|
||||
class MeshBuilder {
|
||||
public:
|
||||
void add_vertex(Vector3 position, Vector3 normal) {
|
||||
|
||||
int i = 0;
|
||||
|
||||
if (_position_to_index.find(position) != _position_to_index.end()) {
|
||||
|
||||
i = _position_to_index[position];
|
||||
|
||||
} else {
|
||||
|
||||
i = _positions.size();
|
||||
_position_to_index[position] = i;
|
||||
|
||||
_positions.push_back(position);
|
||||
_normals.push_back(normal);
|
||||
}
|
||||
|
||||
_indices.push_back(i);
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> commit(bool wireframe) {
|
||||
|
||||
if (_positions.size() == 0) {
|
||||
return Ref<ArrayMesh>();
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(_indices.size() % 3 != 0, Ref<ArrayMesh>());
|
||||
|
||||
if (wireframe) {
|
||||
|
||||
// Debug purpose, no effort to be fast here
|
||||
std::vector<int> wireframe_indices;
|
||||
|
||||
for (int i = 0; i < _indices.size(); i += 3) {
|
||||
|
||||
wireframe_indices.push_back(_indices[i]);
|
||||
wireframe_indices.push_back(_indices[i + 1]);
|
||||
|
||||
wireframe_indices.push_back(_indices[i + 1]);
|
||||
wireframe_indices.push_back(_indices[i + 2]);
|
||||
|
||||
wireframe_indices.push_back(_indices[i + 2]);
|
||||
wireframe_indices.push_back(_indices[i]);
|
||||
}
|
||||
|
||||
_indices = wireframe_indices;
|
||||
}
|
||||
|
||||
PoolVector3Array positions;
|
||||
PoolVector3Array normals;
|
||||
PoolIntArray indices;
|
||||
|
||||
raw_copy_to(positions, _positions);
|
||||
raw_copy_to(normals, _normals);
|
||||
raw_copy_to(indices, _indices);
|
||||
|
||||
Array surface;
|
||||
surface.resize(Mesh::ARRAY_MAX);
|
||||
surface[Mesh::ARRAY_VERTEX] = positions;
|
||||
surface[Mesh::ARRAY_NORMAL] = normals;
|
||||
surface[Mesh::ARRAY_INDEX] = indices;
|
||||
|
||||
Ref<ArrayMesh> mesh;
|
||||
mesh.instance();
|
||||
mesh->add_surface_from_arrays(wireframe ? Mesh::PRIMITIVE_LINES : Mesh::PRIMITIVE_TRIANGLES, surface);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Vector3> _positions;
|
||||
std::vector<Vector3> _normals;
|
||||
std::vector<int> _indices;
|
||||
std::map<Vector3, int> _position_to_index;
|
||||
};
|
||||
|
||||
Ref<ArrayMesh> polygonize_dual_grid(const DualGrid &grid, const VoxelBuffer &voxels, bool wireframe) {
|
||||
|
||||
MeshBuilder mesh_builder;
|
||||
|
||||
for (int dci = 0; dci < grid.cells.size(); ++dci) {
|
||||
|
||||
const DualCell &cell = grid.cells[dci];
|
||||
const Vector3 *corners = cell.corners;
|
||||
|
||||
// Polygonize using regular marching cubes
|
||||
unsigned char case_index = 0;
|
||||
HermiteValue values[8];
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (cell.has_values) {
|
||||
values[i] = cell.values[i];
|
||||
} else {
|
||||
values[i] = get_interpolated_hermite_value(voxels, corners[i]);
|
||||
}
|
||||
if (values[i].value >= ISO_LEVEL) {
|
||||
case_index |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
int edge = MarchingCubes::mc_edges[case_index];
|
||||
|
||||
if (!edge) {
|
||||
// Nothing intersects
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the intersection vertices
|
||||
Vector3 intersection_points[12];
|
||||
Vector3 intersection_normals[12];
|
||||
if (edge & 1) {
|
||||
intersection_points[0] = interpolate(corners[0], corners[1], values[0], values[1], intersection_normals[0]);
|
||||
}
|
||||
if (edge & 2) {
|
||||
intersection_points[1] = interpolate(corners[1], corners[2], values[1], values[2], intersection_normals[1]);
|
||||
}
|
||||
if (edge & 4) {
|
||||
intersection_points[2] = interpolate(corners[2], corners[3], values[2], values[3], intersection_normals[2]);
|
||||
}
|
||||
if (edge & 8) {
|
||||
intersection_points[3] = interpolate(corners[3], corners[0], values[3], values[0], intersection_normals[3]);
|
||||
}
|
||||
if (edge & 16) {
|
||||
intersection_points[4] = interpolate(corners[4], corners[5], values[4], values[5], intersection_normals[4]);
|
||||
}
|
||||
if (edge & 32) {
|
||||
intersection_points[5] = interpolate(corners[5], corners[6], values[5], values[6], intersection_normals[5]);
|
||||
}
|
||||
if (edge & 64) {
|
||||
intersection_points[6] = interpolate(corners[6], corners[7], values[6], values[7], intersection_normals[6]);
|
||||
}
|
||||
if (edge & 128) {
|
||||
intersection_points[7] = interpolate(corners[7], corners[4], values[7], values[4], intersection_normals[7]);
|
||||
}
|
||||
if (edge & 256) {
|
||||
intersection_points[8] = interpolate(corners[0], corners[4], values[0], values[4], intersection_normals[8]);
|
||||
}
|
||||
if (edge & 512) {
|
||||
intersection_points[9] = interpolate(corners[1], corners[5], values[1], values[5], intersection_normals[9]);
|
||||
}
|
||||
if (edge & 1024) {
|
||||
intersection_points[10] = interpolate(corners[2], corners[6], values[2], values[6], intersection_normals[10]);
|
||||
}
|
||||
if (edge & 2048) {
|
||||
intersection_points[11] = interpolate(corners[3], corners[7], values[3], values[7], intersection_normals[11]);
|
||||
}
|
||||
|
||||
// Create the triangles according to the table.
|
||||
for (int i = 0; MarchingCubes::mc_triangles[case_index][i] != -1; i += 3) {
|
||||
|
||||
mesh_builder.add_vertex(
|
||||
intersection_points[MarchingCubes::mc_triangles[case_index][i]],
|
||||
intersection_normals[MarchingCubes::mc_triangles[case_index][i]]);
|
||||
|
||||
mesh_builder.add_vertex(
|
||||
intersection_points[MarchingCubes::mc_triangles[case_index][i + 1]],
|
||||
intersection_normals[MarchingCubes::mc_triangles[case_index][i + 1]]);
|
||||
|
||||
mesh_builder.add_vertex(
|
||||
intersection_points[MarchingCubes::mc_triangles[case_index][i + 2]],
|
||||
intersection_normals[MarchingCubes::mc_triangles[case_index][i + 2]]);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh_builder.commit(wireframe);
|
||||
}
|
||||
|
||||
Ref<ArrayMesh> polygonize(const VoxelBuffer &voxels, float geometric_error, VoxelMesherDMC::Mode mode) {
|
||||
|
||||
int padding = 1;
|
||||
int chunk_size = CHUNK_SIZE;
|
||||
@ -1067,22 +1300,35 @@ Ref<ArrayMesh> polygonize(const VoxelBuffer &voxels, float geometric_error) {
|
||||
root.origin = Vector3i();
|
||||
root.size = chunk_size;
|
||||
generate_octree_top_down(&root, voxels, geometric_error);
|
||||
//return generate_debug_octree_mesh(&root);
|
||||
|
||||
if (mode == VoxelMesherDMC::MODE_DEBUG_OCTREE) {
|
||||
return generate_debug_octree_mesh(&root);
|
||||
}
|
||||
|
||||
DualGrid grid;
|
||||
node_proc(grid, &root);
|
||||
return generate_debug_dual_grid_mesh(grid);
|
||||
// TODO Handle non-subdivided octree
|
||||
if (mode == VoxelMesherDMC::MODE_DEBUG_DUAL_GRID) {
|
||||
return generate_debug_dual_grid_mesh(grid);
|
||||
}
|
||||
|
||||
// TODO
|
||||
return polygonize_dual_grid(grid, voxels, mode == VoxelMesherDMC::MODE_WIREFRAME);
|
||||
// TODO Marching squares skirts
|
||||
}
|
||||
|
||||
} // namespace dmc
|
||||
|
||||
Ref<ArrayMesh> VoxelMesherDMC::build_mesh(Ref<VoxelBuffer> voxels, real_t geometric_error) {
|
||||
Ref<ArrayMesh> VoxelMesherDMC::build_mesh(Ref<VoxelBuffer> voxels, real_t geometric_error, Mode mode) {
|
||||
ERR_FAIL_COND_V(voxels.is_null(), Ref<ArrayMesh>());
|
||||
return dmc::polygonize(**voxels, geometric_error);
|
||||
return dmc::polygonize(**voxels, geometric_error, mode);
|
||||
}
|
||||
|
||||
void VoxelMesherDMC::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("build_mesh", "voxel_buffer", "geometric_error"), &VoxelMesherDMC::build_mesh);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("build_mesh", "voxel_buffer", "geometric_error", "mode"), &VoxelMesherDMC::build_mesh, DEFVAL(MODE_NORMAL));
|
||||
|
||||
BIND_ENUM_CONSTANT(MODE_NORMAL);
|
||||
BIND_ENUM_CONSTANT(MODE_WIREFRAME);
|
||||
BIND_ENUM_CONSTANT(MODE_DEBUG_OCTREE);
|
||||
BIND_ENUM_CONSTANT(MODE_DEBUG_DUAL_GRID);
|
||||
}
|
||||
|
@ -12,10 +12,19 @@ Ref<ArrayMesh> polygonize(const VoxelBuffer &voxels, float geometric_error);
|
||||
class VoxelMesherDMC : public Reference {
|
||||
GDCLASS(VoxelMesherDMC, Reference)
|
||||
public:
|
||||
Ref<ArrayMesh> build_mesh(Ref<VoxelBuffer> voxels, real_t geometric_error);
|
||||
enum Mode {
|
||||
MODE_NORMAL,
|
||||
MODE_WIREFRAME,
|
||||
MODE_DEBUG_OCTREE,
|
||||
MODE_DEBUG_DUAL_GRID
|
||||
};
|
||||
|
||||
Ref<ArrayMesh> build_mesh(Ref<VoxelBuffer> voxels, real_t geometric_error, Mode mode);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(VoxelMesherDMC::Mode)
|
||||
|
||||
#endif // VOXEL_MESHER_DMC_H
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "vector3i.h"
|
||||
#include <core/ustring.h>
|
||||
#include <core/vector.h>
|
||||
#include <vector>
|
||||
|
||||
// Takes elements starting from a given position and moves them at the beginning,
|
||||
// then shrink the array to fit them. Other elements are discarded.
|
||||
@ -44,4 +45,11 @@ inline String ptr2s(const void *p) {
|
||||
return String::num_uint64((uint64_t)p, 16);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void raw_copy_to(PoolVector<T> &to, const std::vector<T> &from) {
|
||||
to.resize(from.size());
|
||||
typename PoolVector<T>::Write w = to.write();
|
||||
memcpy(w.ptr(), from.data(), from.size() * sizeof(T));
|
||||
}
|
||||
|
||||
#endif // HEADER_VOXEL_UTILITY_H
|
||||
|
Loading…
Reference in New Issue
Block a user