Calculate gradients first to reduce number of calculations
Gives about a 2× speedup.
This commit is contained in:
parent
20b8b8fc3d
commit
ac3fb84055
@ -36,6 +36,7 @@ namespace PolyVox
|
||||
template<typename VoxelType>
|
||||
struct EdgeData
|
||||
{
|
||||
EdgeData() : intersects(false) {}
|
||||
Vector3DFloat normal;
|
||||
float fraction; ///<fraction (0.0-1.0) along the edge in the positive direction that the intersection happens
|
||||
bool intersects;
|
||||
@ -161,22 +162,22 @@ namespace PolyVox
|
||||
const auto regionYDimension = region.getDimensionsInVoxels().getY();
|
||||
const auto regionZDimension = region.getDimensionsInVoxels().getZ();
|
||||
|
||||
const auto cellRegionXDimension = regionXDimension+1;
|
||||
const auto cellRegionYDimension = regionYDimension+1;
|
||||
const auto cellRegionZDimension = regionZDimension+1;
|
||||
const auto cellRegionXDimension = regionXDimension+2;
|
||||
const auto cellRegionYDimension = regionYDimension+2;
|
||||
const auto cellRegionZDimension = regionZDimension+2;
|
||||
|
||||
const auto gradientRegionXDimension = regionXDimension+2;
|
||||
const auto gradientRegionYDimension = regionYDimension+2;
|
||||
const auto gradientRegionZDimension = regionZDimension+2;
|
||||
|
||||
std::vector<std::pair<typename VolumeType::VoxelType*, Vector3DFloat>> gradients;
|
||||
std::vector<std::pair<const typename VolumeType::VoxelType, const Vector3DFloat>> gradients;
|
||||
gradients.reserve(gradientRegionXDimension * gradientRegionYDimension * gradientRegionZDimension);
|
||||
|
||||
std::vector<CellData<typename VolumeType::VoxelType>> cells;
|
||||
cells.reserve(cellRegionXDimension * cellRegionYDimension * cellRegionZDimension);
|
||||
|
||||
typename VolumeType::Sampler volSampler{volData};
|
||||
volSampler.setPosition(region.getLowerCorner());
|
||||
volSampler.setPosition(region.getLowerCorner() - Vector3DInt32{1,1,1});
|
||||
volSampler.setWrapMode(WrapMode::Border, -100.0); // -100.0 is well below the threshold
|
||||
|
||||
const float threshold = 0.0f;
|
||||
@ -189,16 +190,17 @@ namespace PolyVox
|
||||
const auto lowerCornerY = region.getLowerCorner().getZ();
|
||||
const auto lowerCornerZ = region.getLowerCorner().getX();
|
||||
|
||||
for(int32_t cellZ = 0; cellZ < cellRegionZDimension; cellZ++)
|
||||
for(int32_t z = 0; z < gradientRegionZDimension; z++)
|
||||
{
|
||||
for(int32_t cellY = 0; cellY < cellRegionYDimension; cellY++)
|
||||
volSampler.setPosition(lowerCornerX-1, lowerCornerY-1, lowerCornerZ+z-1); //Reset x and y and increment z
|
||||
for(int32_t y = 0; y < gradientRegionYDimension; y++)
|
||||
{
|
||||
for(int32_t cellX = 0; cellX < cellRegionXDimension; cellX++)
|
||||
volSampler.setPosition(lowerCornerX-1, lowerCornerY+y-1, lowerCornerZ+z-1); //Reset x and increment y (z remains the same)
|
||||
for(int32_t x = 0; x < gradientRegionXDimension; x++)
|
||||
{
|
||||
//For each cell, calculate the edge intersection points and normals
|
||||
volSampler.setPosition(lowerCornerX+cellX-1, lowerCornerY+cellY-1, lowerCornerZ+cellZ-1);
|
||||
volSampler.movePositiveX(); //Increment x
|
||||
|
||||
const auto& voxel = static_cast<float>(volSampler.getVoxel());
|
||||
const auto& voxel = volSampler.getVoxel();
|
||||
const auto& voxel1px = static_cast<float>(volSampler.peekVoxel1px0py0pz());
|
||||
const auto& voxel1py = static_cast<float>(volSampler.peekVoxel0px1py0pz());
|
||||
const auto& voxel1pz = static_cast<float>(volSampler.peekVoxel0px0py1pz());
|
||||
@ -206,30 +208,61 @@ namespace PolyVox
|
||||
const auto& voxel1nx = static_cast<float>(volSampler.peekVoxel1nx0py0pz());
|
||||
const auto& voxel1ny = static_cast<float>(volSampler.peekVoxel0px1ny0pz());
|
||||
const auto& voxel1nz = static_cast<float>(volSampler.peekVoxel0px0py1nz());
|
||||
const Vector3DFloat g000(voxel1nx - voxel1px, voxel1ny - voxel1py, voxel1nz - voxel1pz);
|
||||
volSampler.movePositiveX();
|
||||
const auto& voxel2px = static_cast<float>(volSampler.peekVoxel1px0py0pz());
|
||||
const auto& voxel1px1ny = static_cast<float>(volSampler.peekVoxel0px1ny0pz());
|
||||
const auto& voxel1px1py = static_cast<float>(volSampler.peekVoxel0px1py0pz());
|
||||
const auto& voxel1px1nz = static_cast<float>(volSampler.peekVoxel0px0py1nz());
|
||||
const auto& voxel1px1pz = static_cast<float>(volSampler.peekVoxel0px0py1pz());
|
||||
const Vector3DFloat g100(voxel - voxel2px, voxel1px1ny - voxel1px1py, voxel1px1nz - voxel1px1pz);
|
||||
volSampler.moveNegativeX();
|
||||
volSampler.movePositiveY();
|
||||
const auto& voxel1nx1py = static_cast<float>(volSampler.peekVoxel1nx0py0pz());
|
||||
const auto& voxel2py = static_cast<float>(volSampler.peekVoxel0px1py0pz());
|
||||
const auto& voxel1py1nz = static_cast<float>(volSampler.peekVoxel0px0py1nz());
|
||||
const auto& voxel1py1pz = static_cast<float>(volSampler.peekVoxel0px0py1pz());
|
||||
const Vector3DFloat g010(voxel1nx1py - voxel1px1py, voxel - voxel2py, voxel1py1nz - voxel1py1pz);
|
||||
volSampler.moveNegativeY();
|
||||
volSampler.movePositiveZ();
|
||||
const auto& voxel1nx1pz = static_cast<float>(volSampler.peekVoxel1nx0py0pz());
|
||||
const auto& voxel1ny1pz = static_cast<float>(volSampler.peekVoxel0px1ny0pz());
|
||||
const auto& voxel2pz = static_cast<float>(volSampler.peekVoxel0px0py1pz());
|
||||
const Vector3DFloat g001(voxel1nx1pz - voxel1px1pz, voxel1ny1pz - voxel1py1pz, voxel - voxel2pz);
|
||||
const Vector3DFloat g(voxel1nx - voxel1px, voxel1ny - voxel1py, voxel1nz - voxel1pz);
|
||||
|
||||
cells.push_back({calculateEdge(voxel, voxel1px, g000, g100, threshold), calculateEdge(voxel, voxel1py, g000, g010, threshold), calculateEdge(voxel, voxel1pz, g000, g001, threshold)});
|
||||
std::pair<const typename VolumeType::VoxelType, Vector3DFloat> data(voxel, g);
|
||||
|
||||
gradients.push_back(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int32_t cellZ = 0; cellZ < cellRegionZDimension; cellZ++)
|
||||
{
|
||||
for(int32_t cellY = 0; cellY < cellRegionYDimension; cellY++)
|
||||
{
|
||||
for(int32_t cellX = 0; cellX < cellRegionXDimension; cellX++)
|
||||
{
|
||||
//For each cell, calculate the edge intersection points and normals
|
||||
const auto& g000 = gradients[convert(cellX, cellY, cellZ, cellRegionXDimension, cellRegionYDimension)];
|
||||
|
||||
//For the last columns/rows, only calculate the interior edge
|
||||
if(cellX < cellRegionXDimension-1 && cellY < cellRegionYDimension-1 && cellZ < cellRegionZDimension-1) //This is the main bulk
|
||||
{
|
||||
const auto& g100 = gradients[convert(cellX+1, cellY, cellZ, cellRegionXDimension, cellRegionYDimension)];
|
||||
const auto& g010 = gradients[convert(cellX, cellY+1, cellZ, cellRegionXDimension, cellRegionYDimension)];
|
||||
const auto& g001 = gradients[convert(cellX, cellY, cellZ+1, cellRegionXDimension, cellRegionYDimension)];
|
||||
cells.push_back({calculateEdge(g000.first, g100.first, g000.second, g100.second, threshold), calculateEdge(g000.first, g010.first, g000.second, g010.second, threshold), calculateEdge(g000.first, g001.first, g000.second, g001.second, threshold)});
|
||||
}
|
||||
else if(cellX == cellRegionXDimension-1 || cellY == cellRegionYDimension-1 || cellZ == cellRegionZDimension-1) //This is the three far edges and the far corner
|
||||
{
|
||||
cells.push_back({}); //Default and empty
|
||||
}
|
||||
else if(cellX == cellRegionXDimension-1) //Far x side
|
||||
{
|
||||
const auto& g100 = gradients[convert(cellX+1, cellY, cellZ, cellRegionXDimension, cellRegionYDimension)];
|
||||
cells.push_back({calculateEdge(g000.first, g100.first, g000.second, g100.second, threshold), EdgeData<typename VolumeType::VoxelType>(), EdgeData<typename VolumeType::VoxelType>()});
|
||||
}
|
||||
else if(cellY == cellRegionYDimension-1) //Far y side
|
||||
{
|
||||
const auto& g010 = gradients[convert(cellX+1, cellY, cellZ, cellRegionXDimension, cellRegionYDimension)];
|
||||
cells.push_back({EdgeData<typename VolumeType::VoxelType>(), calculateEdge(g000.first, g010.first, g000.second, g010.second, threshold), EdgeData<typename VolumeType::VoxelType>()});
|
||||
}
|
||||
else if(cellZ == cellRegionZDimension-1) //Far z side
|
||||
{
|
||||
const auto& g001 = gradients[convert(cellX+1, cellY, cellZ, cellRegionXDimension, cellRegionYDimension)];
|
||||
cells.push_back({EdgeData<typename VolumeType::VoxelType>(), EdgeData<typename VolumeType::VoxelType>(), calculateEdge(g000.first, g001.first, g000.second, g001.second, threshold)});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int32_t cellZ = 0; cellZ < cellRegionZDimension; cellZ++)
|
||||
{
|
||||
for(int32_t cellY = 0; cellY < cellRegionYDimension; cellY++)
|
||||
{
|
||||
for(int32_t cellX = 0; cellX < cellRegionXDimension; cellX++)
|
||||
{
|
||||
if(cellZ >= 1 && cellY >= 1 && cellX >= 1)
|
||||
{
|
||||
//After the first rows and columns are done, start calculating vertex positions
|
||||
|
Loading…
x
Reference in New Issue
Block a user