33 template<
typename VolumeType,
typename IsQuadNeeded>
34 const uint32_t CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::MaxVerticesPerPosition = 8;
36 template<
typename VolumeType,
typename IsQuadNeeded>
39 ,m_regSizeInVoxels(region)
40 ,m_meshCurrent(result)
41 ,m_bMergeQuads(bMergeQuads)
42 ,m_eWrapMode(eWrapMode)
43 ,m_tBorderValue(tBorderValue)
45 m_funcIsQuadNeededCallback = isQuadNeeded;
48 template<
typename VolumeType,
typename IsQuadNeeded>
51 m_meshCurrent->clear();
53 uint32_t uArrayWidth = m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2;
54 uint32_t uArrayHeight = m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2;
56 uint32_t arraySize[3]= {uArrayWidth, uArrayHeight, MaxVerticesPerPosition};
57 m_previousSliceVertices.resize(arraySize);
58 m_currentSliceVertices.resize(arraySize);
59 memset(m_previousSliceVertices.getRawData(), 0xff, m_previousSliceVertices.getNoOfElements() *
sizeof(IndexAndMaterial));
60 memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() *
sizeof(IndexAndMaterial));
62 m_vecQuads[NegativeX].resize(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2);
63 m_vecQuads[PositiveX].resize(m_regSizeInVoxels.getUpperX() - m_regSizeInVoxels.getLowerX() + 2);
65 m_vecQuads[NegativeY].resize(m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2);
66 m_vecQuads[PositiveY].resize(m_regSizeInVoxels.getUpperY() - m_regSizeInVoxels.getLowerY() + 2);
68 m_vecQuads[NegativeZ].resize(m_regSizeInVoxels.getUpperZ() - m_regSizeInVoxels.getLowerZ() + 2);
69 m_vecQuads[PositiveZ].resize(m_regSizeInVoxels.getUpperZ() - m_regSizeInVoxels.getLowerZ() + 2);
71 typename VolumeType::Sampler volumeSampler(m_volData);
72 volumeSampler.setWrapMode(m_eWrapMode, m_tBorderValue);
74 for(
int32_t z = m_regSizeInVoxels.getLowerZ(); z <= m_regSizeInVoxels.getUpperZ(); z++)
76 uint32_t regZ = z - m_regSizeInVoxels.getLowerZ();
78 for(
int32_t y = m_regSizeInVoxels.getLowerY(); y <= m_regSizeInVoxels.getUpperY(); y++)
80 uint32_t regY = y - m_regSizeInVoxels.getLowerY();
82 volumeSampler.setPosition(m_regSizeInVoxels.getLowerX(),y,z);
84 for(
int32_t x = m_regSizeInVoxels.getLowerX(); x <= m_regSizeInVoxels.getUpperX(); x++)
86 uint32_t regX = x - m_regSizeInVoxels.getLowerX();
89 typename VolumeType::VoxelType currentVoxel = volumeSampler.getVoxel();
90 typename VolumeType::VoxelType negXVoxel = volumeSampler.peekVoxel1nx0py0pz();
91 typename VolumeType::VoxelType negYVoxel = volumeSampler.peekVoxel0px1ny0pz();
92 typename VolumeType::VoxelType negZVoxel = volumeSampler.peekVoxel0px0py1nz();
95 if(m_funcIsQuadNeededCallback(currentVoxel, negXVoxel, material))
97 uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices);
98 uint32_t v1 = addVertex(regX , regY , regZ + 1, material, m_currentSliceVertices);
99 uint32_t v2 = addVertex(regX , regY + 1, regZ + 1, material, m_currentSliceVertices);
100 uint32_t v3 = addVertex(regX , regY + 1, regZ , material, m_previousSliceVertices);
102 m_vecQuads[NegativeX][regX].push_back(Quad(v0, v1, v2, v3));
105 if(m_funcIsQuadNeededCallback(negXVoxel, currentVoxel, material))
107 uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices);
108 uint32_t v1 = addVertex(regX , regY , regZ + 1, material, m_currentSliceVertices);
109 uint32_t v2 = addVertex(regX , regY + 1, regZ + 1, material, m_currentSliceVertices);
110 uint32_t v3 = addVertex(regX , regY + 1, regZ , material, m_previousSliceVertices);
112 m_vecQuads[PositiveX][regX].push_back(Quad(v0, v3, v2, v1));
116 if(m_funcIsQuadNeededCallback(currentVoxel, negYVoxel, material))
118 uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices);
119 uint32_t v1 = addVertex(regX + 1, regY , regZ , material, m_previousSliceVertices);
120 uint32_t v2 = addVertex(regX + 1, regY , regZ + 1, material, m_currentSliceVertices);
121 uint32_t v3 = addVertex(regX , regY , regZ + 1, material, m_currentSliceVertices);
123 m_vecQuads[NegativeY][regY].push_back(Quad(v0, v1, v2, v3));
126 if(m_funcIsQuadNeededCallback(negYVoxel, currentVoxel, material))
128 uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices);
129 uint32_t v1 = addVertex(regX + 1, regY , regZ , material, m_previousSliceVertices);
130 uint32_t v2 = addVertex(regX + 1, regY , regZ + 1, material, m_currentSliceVertices);
131 uint32_t v3 = addVertex(regX , regY , regZ + 1, material, m_currentSliceVertices);
133 m_vecQuads[PositiveY][regY].push_back(Quad(v0, v3, v2, v1));
137 if(m_funcIsQuadNeededCallback(currentVoxel, negZVoxel, material))
139 uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices);
140 uint32_t v1 = addVertex(regX , regY + 1, regZ , material, m_previousSliceVertices);
141 uint32_t v2 = addVertex(regX + 1, regY + 1, regZ , material, m_previousSliceVertices);
142 uint32_t v3 = addVertex(regX + 1, regY , regZ , material, m_previousSliceVertices);
144 m_vecQuads[NegativeZ][regZ].push_back(Quad(v0, v1, v2, v3));
147 if(m_funcIsQuadNeededCallback(negZVoxel, currentVoxel, material))
149 uint32_t v0 = addVertex(regX , regY , regZ , material, m_previousSliceVertices);
150 uint32_t v1 = addVertex(regX , regY + 1, regZ , material, m_previousSliceVertices);
151 uint32_t v2 = addVertex(regX + 1, regY + 1, regZ , material, m_previousSliceVertices);
152 uint32_t v3 = addVertex(regX + 1, regY , regZ , material, m_previousSliceVertices);
154 m_vecQuads[PositiveZ][regZ].push_back(Quad(v0, v3, v2, v1));
157 volumeSampler.movePositiveX();
161 m_previousSliceVertices.swap(m_currentSliceVertices);
162 memset(m_currentSliceVertices.getRawData(), 0xff, m_currentSliceVertices.getNoOfElements() *
sizeof(IndexAndMaterial));
165 for(
uint32_t uFace = 0; uFace < NoOfFaces; uFace++)
167 std::vector< std::list<Quad> >& vecListQuads = m_vecQuads[uFace];
169 for(
uint32_t slice = 0; slice < vecListQuads.size(); slice++)
171 std::list<Quad>& listQuads = vecListQuads[slice];
177 while(performQuadMerging(listQuads)){}
180 typename std::list<Quad>::iterator iterEnd = listQuads.end();
181 for(
typename std::list<Quad>::iterator quadIter = listQuads.begin(); quadIter != iterEnd; quadIter++)
183 Quad& quad = *quadIter;
184 m_meshCurrent->addTriangleCubic(quad.vertices[0], quad.vertices[1],quad.vertices[2]);
185 m_meshCurrent->addTriangleCubic(quad.vertices[0], quad.vertices[2],quad.vertices[3]);
190 m_meshCurrent->m_Region = m_regSizeInVoxels;
191 m_meshCurrent->removeUnusedVertices();
193 m_meshCurrent->m_vecLodRecords.clear();
196 lodRecord.
endIndex = m_meshCurrent->getNoOfIndices();
197 m_meshCurrent->m_vecLodRecords.push_back(lodRecord);
200 template<
typename VolumeType,
typename IsQuadNeeded>
203 for(
uint32_t ct = 0; ct < MaxVerticesPerPosition; ct++)
205 IndexAndMaterial& rEntry = existingVertices[uX][uY][ct];
207 if(rEntry.iIndex == -1)
210 rEntry.iIndex = m_meshCurrent->addVertex(
PositionMaterial(
Vector3DFloat(static_cast<float>(uX) - 0.5f, static_cast<float>(uY) - 0.5f, static_cast<float>(uZ) - 0.5f), uMaterialIn));
211 rEntry.uMaterial = uMaterialIn;
213 return rEntry.iIndex;
217 if(rEntry.uMaterial == static_cast<int32_t>(uMaterialIn))
219 return rEntry.iIndex;
229 template<
typename VolumeType,
typename IsQuadNeeded>
230 bool CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::performQuadMerging(std::list<Quad>& quads)
232 bool bDidMerge =
false;
233 for(
typename std::list<Quad>::iterator outerIter = quads.begin(); outerIter != quads.end(); outerIter++)
235 typename std::list<Quad>::iterator innerIter = outerIter;
237 while(innerIter != quads.end())
239 Quad& q1 = *outerIter;
240 Quad& q2 = *innerIter;
242 bool result = mergeQuads(q1,q2);
247 innerIter = quads.erase(innerIter);
259 template<
typename VolumeType,
typename IsQuadNeeded>
260 bool CubicSurfaceExtractor<VolumeType, IsQuadNeeded>::mergeQuads(Quad& q1, Quad& q2)
264 if(std::abs(m_meshCurrent->getVertices()[q1.vertices[0]].getMaterial() - m_meshCurrent->getVertices()[q2.vertices[0]].getMaterial()) < 0.001)
269 if((q1.vertices[0] == q2.vertices[1]) && ((q1.vertices[3] == q2.vertices[2])))
271 q1.vertices[0] = q2.vertices[0];
272 q1.vertices[3] = q2.vertices[3];
275 else if((q1.vertices[3] == q2.vertices[0]) && ((q1.vertices[2] == q2.vertices[1])))
277 q1.vertices[3] = q2.vertices[3];
278 q1.vertices[2] = q2.vertices[2];
281 else if((q1.vertices[1] == q2.vertices[0]) && ((q1.vertices[2] == q2.vertices[3])))
283 q1.vertices[1] = q2.vertices[1];
284 q1.vertices[2] = q2.vertices[2];
287 else if((q1.vertices[0] == q2.vertices[3]) && ((q1.vertices[1] == q2.vertices[2])))
289 q1.vertices[0] = q2.vertices[0];
290 q1.vertices[1] = q2.vertices[1];