-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVoxelChunk.h
111 lines (97 loc) · 4.72 KB
/
VoxelChunk.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#pragma once
#include "VoxelData.h"
#include "VoxelChunkTransitionSurfaceDesc.h"
#include <vector>
#include "VoxelConstants.h"
#include <glm/glm.hpp>
#include "qef.h"
#include "SamplerFunction.h"
#define EDGE_SCALE 255
using namespace glm;
using namespace svd;
class VoxelChunk{
public:
private:
VoxelData* _data;
// tables required in the vertex generation.
int indexMap[VoxelConstants::UsableRange * VoxelConstants::UsableRange * VoxelConstants::UsableRange];
// this can be optimized to use only 3 * 3 * VoxelConstants::UsableRange ^ 2 chars.
char edgeMap[VoxelConstants::UsableRange * VoxelConstants::UsableRange * VoxelConstants::UsableRange * 3];
// dim x dim x number of surfaces x number of edges.
char surfaceEdgeMap[VoxelConstants::UsableRange * VoxelConstants::UsableRange * 3 * 2];
// surfaceId is the index of the surface; edgeNum is the index of the axis/edge.
inline int calcSurfaceEdgeMapIndex(int x, int y, int surfaceId, int edgeNum){
return ((x + y * VoxelConstants::UsableRange) * 3 + surfaceId) * 2 + edgeNum;
}
VoxelChunkTransitionSurfaceDesc edgeDescs[6];
// mesh data, may move these to a different class in the future
std::vector<vec3> tempVertices;
std::vector<unsigned int> tempIndices;
std::vector<vec3> tempNormals;
inline int calcDataIndex(int x, int y, int z){
return x + y * VoxelConstants::DataRange + z * VoxelConstants::DataRange * VoxelConstants::DataRange;
}
inline int calcUsableIndex(int x, int y, int z){
return x + y * VoxelConstants::UsableRange + z * VoxelConstants::UsableRange * VoxelConstants::UsableRange;
}
inline VoxelData* read(const int x, const int y, const int z){
int idx = calcDataIndex(x, y, z);
return &_data[idx];
}
inline int readVertexIndex(const int x, const int y, const int z){
return indexMap[calcUsableIndex(x, y, z)];
}
inline void solverAddX(unsigned char baseMat, const VoxelData* _vdat, QefSolver& solver, int& intersectionCount, vec3& accumNormal, float _x, float _y, float _z){
if (_vdat->material != baseMat){
solver.add(
Vec3(_x + ((float)_vdat->intersections[0]) / EDGE_SCALE, _y, _z),
Vec3(_vdat->normal[0].x, _vdat->normal[0].y, _vdat->normal[0].z));
intersectionCount++;
accumNormal += _vdat->normal[0];
}
}
inline void solverAddY(unsigned char baseMat, const VoxelData* _vdat, QefSolver& solver, int& intersectionCount, vec3& accumNormal, float _x, float _y, float _z){
if (_vdat->material != baseMat){
solver.add(
Vec3(_x, _y + ((float)_vdat->intersections[1]) / EDGE_SCALE, _z),
Vec3(_vdat->normal[1].x, _vdat->normal[1].y, _vdat->normal[1].z));
intersectionCount++;
accumNormal += _vdat->normal[1];
}
}
inline void solverAddZ(unsigned char baseMat, const VoxelData* _vdat, QefSolver& solver, int& intersectionCount, vec3& accumNormal, float _x, float _y, float _z){
if (_vdat->material != baseMat){
solver.add(
Vec3(_x, _y, _z + ((float)_vdat->intersections[2]) / EDGE_SCALE),
Vec3(_vdat->normal[2].x, _vdat->normal[2].y, _vdat->normal[2].z));
intersectionCount++;
accumNormal += _vdat->normal[2];
}
}
// helper functions for createEdgeDesc2D
void duplicateIndicesAndEdgeFlags(const vec3& vertTranslate, VoxelChunk* adjChunk, int loc0, int loc1, VoxelChunkTransitionSurfaceDesc* edgeDesc, int facing);
void copyIndicesAndEdgeFlags(const vec3& vertTranslate, VoxelChunk* adjChunk, int loc0, int loc1, VoxelChunkTransitionSurfaceDesc* edgeDesc, int facing);
void generateEdgeMapOnMaxSurface(int surfaceId);
// helper functions for createEdgeDesc1D
int readIndex_X(int c, int maxDim);
int readIndex_Y(int c, int maxDim);
int readIndex_Z(int c, int maxDim);
void _1DPhase_MinusOne(const vec3& vertTranslate, VoxelChunk* baseChunk, int loc0, VoxelChunkTransitionSurfaceDesc* edgeDesc, int type);
void _1DPhase_Zero(const vec3& vertTranslate, VoxelChunk* baseChunk, VoxelChunkTransitionSurfaceDesc* edgeDesc, int type);
void _1DPhase_PlusOne(const vec3& vertTranslate, VoxelChunk* baseChunk, int loc0, VoxelChunkTransitionSurfaceDesc* edgeDesc, int type);
public:
VoxelChunk(void);
~VoxelChunk();
void performSDF(SamplerFunction* sf);
void createDataArray(void);
void generateVertices(void);
void generateIndices(void);
inline const std::vector<vec3>& getVertices(void){ return tempVertices; };
inline const std::vector<unsigned int>& getIndices(void){ return tempIndices; };
inline const std::vector<vec3>& getNormals(void){ return tempNormals; };
void writeRaw(int x, int y, int z, const VoxelData& vData);
// experimental
void customSDF(int x, int y, int z, int w, SamplerFunction* sampler);
void createEdgeDesc1D(const int lodDiff, const int loc0, VoxelChunk* adjChunk, const int facing);
void createEdgeDesc2D(const int lodDiff, const int loc0, const int loc1, VoxelChunk* baseChunk, const int facing);
};