00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 namespace PolyVox
00025 {
00026 template< template<typename> class VolumeType, typename VoxelType>
00027 CubicSurfaceExtractorWithNormals<VolumeType, VoxelType>::CubicSurfaceExtractorWithNormals(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result)
00028 :m_volData(volData)
00029 ,m_sampVolume(volData)
00030 ,m_meshCurrent(result)
00031 ,m_regSizeInVoxels(region)
00032 {
00033 }
00034
00035 template< template<typename> class VolumeType, typename VoxelType>
00036 void CubicSurfaceExtractorWithNormals<VolumeType, VoxelType>::execute()
00037 {
00038 m_meshCurrent->clear();
00039
00040 for(int32_t z = m_regSizeInVoxels.getLowerCorner().getZ(); z < m_regSizeInVoxels.getUpperCorner().getZ(); z++)
00041 {
00042 for(int32_t y = m_regSizeInVoxels.getLowerCorner().getY(); y < m_regSizeInVoxels.getUpperCorner().getY(); y++)
00043 {
00044 for(int32_t x = m_regSizeInVoxels.getLowerCorner().getX(); x < m_regSizeInVoxels.getUpperCorner().getX(); x++)
00045 {
00046
00047 uint32_t regX = x - m_regSizeInVoxels.getLowerCorner().getX();
00048 uint32_t regY = y - m_regSizeInVoxels.getLowerCorner().getY();
00049 uint32_t regZ = z - m_regSizeInVoxels.getLowerCorner().getZ();
00050
00051 int currentVoxel = m_volData->getVoxelAt(x,y,z).getDensity() >= VoxelType::getThreshold();
00052
00053 int plusXVoxel = m_volData->getVoxelAt(x+1,y,z).getDensity() >= VoxelType::getThreshold();
00054 if(currentVoxel > plusXVoxel)
00055 {
00056 uint32_t material = m_volData->getVoxelAt(x,y,z).getMaterial();
00057
00058 uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
00059 uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
00060 uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
00061 uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(1.0f, 0.0f, 0.0f), material));
00062
00063 m_meshCurrent->addTriangleCubic(v0,v2,v1);
00064 m_meshCurrent->addTriangleCubic(v1,v2,v3);
00065 }
00066 if(currentVoxel < plusXVoxel)
00067 {
00068 int material = m_volData->getVoxelAt(x+1,y,z).getMaterial();
00069
00070 uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
00071 uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
00072 uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
00073 uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(-1.0f, 0.0f, 0.0f), material));
00074
00075 m_meshCurrent->addTriangleCubic(v0,v1,v2);
00076 m_meshCurrent->addTriangleCubic(v1,v3,v2);
00077 }
00078
00079 int plusYVoxel = m_volData->getVoxelAt(x,y+1,z).getDensity() >= VoxelType::getThreshold();
00080 if(currentVoxel > plusYVoxel)
00081 {
00082 int material = m_volData->getVoxelAt(x,y,z).getMaterial();
00083
00084 uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
00085 uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
00086 uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
00087 uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 1.0f, 0.0f), material));
00088
00089 m_meshCurrent->addTriangleCubic(v0,v1,v2);
00090 m_meshCurrent->addTriangleCubic(v1,v3,v2);
00091 }
00092 if(currentVoxel < plusYVoxel)
00093 {
00094 int material = m_volData->getVoxelAt(x,y+1,z).getMaterial();
00095
00096 uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
00097 uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
00098 uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ - 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
00099 uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, -1.0f, 0.0f), material));
00100
00101 m_meshCurrent->addTriangleCubic(v0,v2,v1);
00102 m_meshCurrent->addTriangleCubic(v1,v2,v3);
00103 }
00104
00105 int plusZVoxel = m_volData->getVoxelAt(x,y,z+1).getDensity() >= VoxelType::getThreshold();
00106 if(currentVoxel > plusZVoxel)
00107 {
00108 int material = m_volData->getVoxelAt(x,y,z).getMaterial();
00109
00110 uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
00111 uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
00112 uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
00113 uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, 1.0f), material));
00114
00115 m_meshCurrent->addTriangleCubic(v0,v2,v1);
00116 m_meshCurrent->addTriangleCubic(v1,v2,v3);
00117 }
00118 if(currentVoxel < plusZVoxel)
00119 {
00120 int material = m_volData->getVoxelAt(x,y,z+1).getMaterial();
00121
00122 uint32_t v0 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
00123 uint32_t v1 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX - 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
00124 uint32_t v2 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY - 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
00125 uint32_t v3 = m_meshCurrent->addVertex(PositionMaterialNormal(Vector3DFloat(regX + 0.5f, regY + 0.5f, regZ + 0.5f), Vector3DFloat(0.0f, 0.0f, -1.0f), material));
00126
00127 m_meshCurrent->addTriangleCubic(v0,v1,v2);
00128 m_meshCurrent->addTriangleCubic(v1,v3,v2);
00129 }
00130 }
00131 }
00132 }
00133
00134 m_meshCurrent->m_Region = m_regSizeInVoxels;
00135
00136 m_meshCurrent->m_vecLodRecords.clear();
00137 LodRecord lodRecord;
00138 lodRecord.beginIndex = 0;
00139 lodRecord.endIndex = m_meshCurrent->getNoOfIndices();
00140 m_meshCurrent->m_vecLodRecords.push_back(lodRecord);
00141 }
00142 }