Huge optimization
This commit is contained in:
parent
1dd7d845d9
commit
98c3f97eea
2 changed files with 46 additions and 15 deletions
|
@ -11,9 +11,25 @@ void WorleyNoise::generateNoise()
|
||||||
|
|
||||||
// Generate random points
|
// Generate random points
|
||||||
points.clear();
|
points.clear();
|
||||||
for (int i = 0; i < numberOfPoints * 3; i++)
|
points.reserve(pow(numberOfPoints, 3));
|
||||||
|
for (int x = 0; x < numberOfPoints; x++)
|
||||||
{
|
{
|
||||||
points.emplace_back(getRandomPoint());
|
for (int y = 0; y < numberOfPoints; y++)
|
||||||
|
{
|
||||||
|
for (int z = 0; z < numberOfPoints; z++)
|
||||||
|
{
|
||||||
|
Vector3d point = getRandomPoint();
|
||||||
|
|
||||||
|
// Scale and translate into subcell
|
||||||
|
point /= (float) numberOfPoints;
|
||||||
|
|
||||||
|
Vector3d offset = Vector3d(x, y, z);
|
||||||
|
offset /= (float) numberOfPoints;
|
||||||
|
point += offset;
|
||||||
|
|
||||||
|
points[x + y * numberOfPoints + z * numberOfPoints * numberOfPoints] = point;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate getNoise map
|
// Generate getNoise map
|
||||||
|
@ -28,7 +44,7 @@ void WorleyNoise::generateNoise()
|
||||||
{
|
{
|
||||||
Vector3d point = Vector3d(x, y, z);
|
Vector3d point = Vector3d(x, y, z);
|
||||||
point /= (float) size;
|
point /= (float) size;
|
||||||
setNoise(x, y, z, repeatableDistanceToClosestPoint(point));
|
setNoise(x, y, z, distanceToClosestPoint(point));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +66,7 @@ void WorleyNoise::generateNoise()
|
||||||
<< duration.count() << " seconds" << std::endl;
|
<< duration.count() << " seconds" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
WorleyNoise::WorleyNoise(int size, int numberOfPoints) : numberOfPoints(pow(numberOfPoints, 3)), Noise(size)
|
WorleyNoise::WorleyNoise(int size, int numberOfPoints) : numberOfPoints(numberOfPoints), Noise(size)
|
||||||
{
|
{
|
||||||
// Init random
|
// Init random
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
|
@ -67,8 +83,11 @@ Vector3d WorleyNoise::getRandomPoint()
|
||||||
|
|
||||||
float WorleyNoise::distanceToClosestPoint(Vector3d point)
|
float WorleyNoise::distanceToClosestPoint(Vector3d point)
|
||||||
{
|
{
|
||||||
|
std::vector<Vector3d> closePoints = getSubcellPoints(point);
|
||||||
|
|
||||||
|
// Iterate over all subcells
|
||||||
float minDistance = INFINITY;
|
float minDistance = INFINITY;
|
||||||
for (Vector3d p: points)
|
for (Vector3d p: closePoints)
|
||||||
{
|
{
|
||||||
float distance = length(p - point);
|
float distance = length(p - point);
|
||||||
if (distance < minDistance)
|
if (distance < minDistance)
|
||||||
|
@ -79,22 +98,34 @@ float WorleyNoise::distanceToClosestPoint(Vector3d point)
|
||||||
return minDistance;
|
return minDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
float WorleyNoise::repeatableDistanceToClosestPoint(Vector3d point)
|
std::vector<Vector3d> WorleyNoise::getSubcellPoints(Vector3d point)
|
||||||
{
|
{
|
||||||
std::set<float> distances;
|
std::vector<Vector3d> closePoints;
|
||||||
|
|
||||||
// Move point around to get distance to closest point in all 27 cells
|
point.x = std::floor(point.x * numberOfPoints);
|
||||||
|
point.y = std::floor(point.y * numberOfPoints);
|
||||||
|
point.z = std::floor(point.z * numberOfPoints);
|
||||||
|
|
||||||
|
// Iterate over all subcells
|
||||||
for (int x = -1; x <= 1; x++)
|
for (int x = -1; x <= 1; x++)
|
||||||
{
|
{
|
||||||
for (int y = -1; y <= 1; y++)
|
for (int y = -1; y <= 1; y++)
|
||||||
{
|
{
|
||||||
for (int z = -1; z <= 1; z++)
|
for (int z = -1; z <= 1; z++)
|
||||||
{
|
{
|
||||||
Vector3d offsetPoint = point + Vector3d(x, y, z);
|
Vector3d offset = Vector3d(x, y, z);
|
||||||
distances.insert(distanceToClosestPoint(offsetPoint));
|
Vector3d subcell = point + offset;
|
||||||
|
|
||||||
|
// Wrap around
|
||||||
|
subcell.x = std::fmod(subcell.x + numberOfPoints, numberOfPoints);
|
||||||
|
subcell.y = std::fmod(subcell.y + numberOfPoints, numberOfPoints);
|
||||||
|
subcell.z = std::fmod(subcell.z + numberOfPoints, numberOfPoints);
|
||||||
|
|
||||||
|
// Get points in subcell
|
||||||
|
int index = subcell.x + subcell.y * numberOfPoints + subcell.z * numberOfPoints * numberOfPoints;
|
||||||
|
closePoints.push_back(points[index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return closePoints;
|
||||||
return *std::min_element(distances.begin(), distances.end());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int numberOfPoints;
|
int numberOfPoints;
|
||||||
std::vector<Vector3d> points; // Points in 3D space in [0, 1]
|
std::vector<Vector3d> points; // 3D-Array, each cell represents a subcell. There are numberOfPoints^3 subcells.
|
||||||
|
|
||||||
std::uniform_real_distribution<float> distribution;
|
std::uniform_real_distribution<float> distribution;
|
||||||
std::mt19937 generator;
|
std::mt19937 generator;
|
||||||
|
@ -23,9 +23,9 @@ protected:
|
||||||
|
|
||||||
float distanceToClosestPoint(Vector3d point);
|
float distanceToClosestPoint(Vector3d point);
|
||||||
|
|
||||||
float repeatableDistanceToClosestPoint(Vector3d point);
|
|
||||||
|
|
||||||
void generateNoise();
|
void generateNoise();
|
||||||
|
|
||||||
|
std::vector<Vector3d> getSubcellPoints(Vector3d point);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue