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>
|
template<typename VoxelType>
|
||||||
struct EdgeData
|
struct EdgeData
|
||||||
{
|
{
|
||||||
|
EdgeData() : intersects(false) {}
|
||||||
Vector3DFloat normal;
|
Vector3DFloat normal;
|
||||||
float fraction; ///<fraction (0.0-1.0) along the edge in the positive direction that the intersection happens
|
float fraction; ///<fraction (0.0-1.0) along the edge in the positive direction that the intersection happens
|
||||||
bool intersects;
|
bool intersects;
|
||||||
@ -161,22 +162,22 @@ namespace PolyVox
|
|||||||
const auto regionYDimension = region.getDimensionsInVoxels().getY();
|
const auto regionYDimension = region.getDimensionsInVoxels().getY();
|
||||||
const auto regionZDimension = region.getDimensionsInVoxels().getZ();
|
const auto regionZDimension = region.getDimensionsInVoxels().getZ();
|
||||||
|
|
||||||
const auto cellRegionXDimension = regionXDimension+1;
|
const auto cellRegionXDimension = regionXDimension+2;
|
||||||
const auto cellRegionYDimension = regionYDimension+1;
|
const auto cellRegionYDimension = regionYDimension+2;
|
||||||
const auto cellRegionZDimension = regionZDimension+1;
|
const auto cellRegionZDimension = regionZDimension+2;
|
||||||
|
|
||||||
const auto gradientRegionXDimension = regionXDimension+2;
|
const auto gradientRegionXDimension = regionXDimension+2;
|
||||||
const auto gradientRegionYDimension = regionYDimension+2;
|
const auto gradientRegionYDimension = regionYDimension+2;
|
||||||
const auto gradientRegionZDimension = regionZDimension+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);
|
gradients.reserve(gradientRegionXDimension * gradientRegionYDimension * gradientRegionZDimension);
|
||||||
|
|
||||||
std::vector<CellData<typename VolumeType::VoxelType>> cells;
|
std::vector<CellData<typename VolumeType::VoxelType>> cells;
|
||||||
cells.reserve(cellRegionXDimension * cellRegionYDimension * cellRegionZDimension);
|
cells.reserve(cellRegionXDimension * cellRegionYDimension * cellRegionZDimension);
|
||||||
|
|
||||||
typename VolumeType::Sampler volSampler{volData};
|
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
|
volSampler.setWrapMode(WrapMode::Border, -100.0); // -100.0 is well below the threshold
|
||||||
|
|
||||||
const float threshold = 0.0f;
|
const float threshold = 0.0f;
|
||||||
@ -189,16 +190,17 @@ namespace PolyVox
|
|||||||
const auto lowerCornerY = region.getLowerCorner().getZ();
|
const auto lowerCornerY = region.getLowerCorner().getZ();
|
||||||
const auto lowerCornerZ = region.getLowerCorner().getX();
|
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.movePositiveX(); //Increment x
|
||||||
volSampler.setPosition(lowerCornerX+cellX-1, lowerCornerY+cellY-1, lowerCornerZ+cellZ-1);
|
|
||||||
|
|
||||||
const auto& voxel = static_cast<float>(volSampler.getVoxel());
|
const auto& voxel = volSampler.getVoxel();
|
||||||
const auto& voxel1px = static_cast<float>(volSampler.peekVoxel1px0py0pz());
|
const auto& voxel1px = static_cast<float>(volSampler.peekVoxel1px0py0pz());
|
||||||
const auto& voxel1py = static_cast<float>(volSampler.peekVoxel0px1py0pz());
|
const auto& voxel1py = static_cast<float>(volSampler.peekVoxel0px1py0pz());
|
||||||
const auto& voxel1pz = static_cast<float>(volSampler.peekVoxel0px0py1pz());
|
const auto& voxel1pz = static_cast<float>(volSampler.peekVoxel0px0py1pz());
|
||||||
@ -206,30 +208,61 @@ namespace PolyVox
|
|||||||
const auto& voxel1nx = static_cast<float>(volSampler.peekVoxel1nx0py0pz());
|
const auto& voxel1nx = static_cast<float>(volSampler.peekVoxel1nx0py0pz());
|
||||||
const auto& voxel1ny = static_cast<float>(volSampler.peekVoxel0px1ny0pz());
|
const auto& voxel1ny = static_cast<float>(volSampler.peekVoxel0px1ny0pz());
|
||||||
const auto& voxel1nz = static_cast<float>(volSampler.peekVoxel0px0py1nz());
|
const auto& voxel1nz = static_cast<float>(volSampler.peekVoxel0px0py1nz());
|
||||||
const Vector3DFloat g000(voxel1nx - voxel1px, voxel1ny - voxel1py, voxel1nz - voxel1pz);
|
const Vector3DFloat g(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);
|
|
||||||
|
|
||||||
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)
|
if(cellZ >= 1 && cellY >= 1 && cellX >= 1)
|
||||||
{
|
{
|
||||||
//After the first rows and columns are done, start calculating vertex positions
|
//After the first rows and columns are done, start calculating vertex positions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user