meh.
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::mutex m;
|
std::mutex m;
|
||||||
std::atomic<bool> isGenerating{false};
|
std::atomic<int> isGenerating{0};
|
||||||
std::future<void> generationFuture;
|
std::future<void> generationFuture;
|
||||||
|
|
||||||
std::mutex previewMutex;
|
std::mutex previewMutex;
|
||||||
@@ -245,10 +245,11 @@ bool exportavi(std::vector<frame> frames, AnimationConfig config) {
|
|||||||
|
|
||||||
void mainLogic(const AnimationConfig& config, Shared& state, int gradnoise) {
|
void mainLogic(const AnimationConfig& config, Shared& state, int gradnoise) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
if (isGenerating) return; //apparently sometimes this function is called twice. dont know how, but this might resolve that.
|
if (isGenerating != 0) return; //apparently sometimes this function is called twice. dont know how, but this might resolve that.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Grid2 grid;
|
Grid2 grid;
|
||||||
|
isGenerating = 1;
|
||||||
if (gradnoise == 0) {
|
if (gradnoise == 0) {
|
||||||
grid = setup(config);
|
grid = setup(config);
|
||||||
} else if (gradnoise == 1) {
|
} else if (gradnoise == 1) {
|
||||||
@@ -267,24 +268,25 @@ void mainLogic(const AnimationConfig& config, Shared& state, int gradnoise) {
|
|||||||
std::cout << "generated grid" << std::endl;
|
std::cout << "generated grid" << std::endl;
|
||||||
Preview(grid);
|
Preview(grid);
|
||||||
std::cout << "generated preview" << std::endl;
|
std::cout << "generated preview" << std::endl;
|
||||||
|
grid = grid.backfillGrid();
|
||||||
frame tempData = grid.getTempAsFrame(Vec2(0,0), Vec2(config.height,config.width), Vec2(256,256));
|
frame tempData = grid.getTempAsFrame(Vec2(0,0), Vec2(config.height,config.width), Vec2(256,256));
|
||||||
std::cout << "Temp frame looks like: " << tempData << std::endl;
|
std::cout << "Temp frame looks like: " << tempData << std::endl;
|
||||||
bool success = BMPWriter::saveBMP("output/temperature.bmp", tempData);
|
bool success = BMPWriter::saveBMP("output/temperature.bmp", tempData);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
std::cout << "yo! this failed in Preview" << std::endl;
|
std::cout << "yo! this failed in Preview" << std::endl;
|
||||||
}
|
}
|
||||||
isGenerating = true;
|
isGenerating = 2;
|
||||||
std::vector<frame> frames;
|
std::vector<frame> frames;
|
||||||
|
|
||||||
for (int i = 0; i < config.totalFrames; ++i){
|
for (int i = 0; i < config.totalFrames; ++i){
|
||||||
// Check if we should stop the generation
|
// Check if we should stop the generation
|
||||||
if (!isGenerating) {
|
if (isGenerating == 0) {
|
||||||
std::cout << "Generation cancelled at frame " << i << std::endl;
|
std::cout << "Generation cancelled at frame " << i << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//expandPixel(grid,config,seeds);
|
//expandPixel(grid,config,seeds);
|
||||||
grid.diffuseTemperatures(1.0, 1.0, 1.0);
|
//grid.diffuseTemperatures(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(state.mutex);
|
std::lock_guard<std::mutex> lock(state.mutex);
|
||||||
state.grid = grid;
|
state.grid = grid;
|
||||||
@@ -308,13 +310,13 @@ void mainLogic(const AnimationConfig& config, Shared& state, int gradnoise) {
|
|||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "errored at: " << e.what() << std::endl;
|
std::cerr << "errored at: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
isGenerating = false;
|
isGenerating = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to cancel ongoing generation
|
// Function to cancel ongoing generation
|
||||||
void cancelGeneration() {
|
void cancelGeneration() {
|
||||||
if (isGenerating) {
|
if (isGenerating) {
|
||||||
isGenerating = false;
|
isGenerating = 0;
|
||||||
// Wait for the thread to finish (with timeout to avoid hanging)
|
// Wait for the thread to finish (with timeout to avoid hanging)
|
||||||
if (generationFuture.valid()) {
|
if (generationFuture.valid()) {
|
||||||
auto status = generationFuture.wait_for(std::chrono::milliseconds(100));
|
auto status = generationFuture.wait_for(std::chrono::milliseconds(100));
|
||||||
@@ -437,7 +439,7 @@ int main() {
|
|||||||
ImGui::RadioButton("Gradient", &gradnoise, 0);
|
ImGui::RadioButton("Gradient", &gradnoise, 0);
|
||||||
ImGui::RadioButton("Perlin Noise", &gradnoise, 1);
|
ImGui::RadioButton("Perlin Noise", &gradnoise, 1);
|
||||||
|
|
||||||
if (isGenerating) {
|
if (isGenerating != 0) {
|
||||||
ImGui::BeginDisabled();
|
ImGui::BeginDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,7 +448,7 @@ int main() {
|
|||||||
mainlogicthread = std::async(std::launch::async, mainLogic, config, std::ref(state), gradnoise);
|
mainlogicthread = std::async(std::launch::async, mainLogic, config, std::ref(state), gradnoise);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isGenerating && textu != 0) {
|
if (isGenerating == 2 && textu != 0) {
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
@@ -475,7 +477,7 @@ int main() {
|
|||||||
ImGui::Text("Generating preview...");
|
ImGui::Text("Generating preview...");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (isGenerating) {
|
} else if (isGenerating == 2) {
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
@@ -509,6 +511,20 @@ int main() {
|
|||||||
ImGui::Text("Generating preview...");
|
ImGui::Text("Generating preview...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (isGenerating != 0) {
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
ImGui::Text(previewText.c_str());
|
||||||
|
|
||||||
|
if (textu != 0) {
|
||||||
|
ImVec2 imageSize = ImVec2(config.width * 0.5f, config.height * 0.5f);
|
||||||
|
ImVec2 uv_min = ImVec2(0.0f, 0.0f);
|
||||||
|
ImVec2 uv_max = ImVec2(1.0f, 1.0f);
|
||||||
|
ImGui::Image((void*)(intptr_t)textu, imageSize, uv_min, uv_max);
|
||||||
|
} else {
|
||||||
|
ImGui::Text("Generating preview...");
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ImGui::Text("No preview available");
|
ImGui::Text("No preview available");
|
||||||
ImGui::Text("Start generation to see live preview");
|
ImGui::Text("Start generation to see live preview");
|
||||||
|
|||||||
1025
util/grid/grid2.hpp
1025
util/grid/grid2.hpp
File diff suppressed because it is too large
Load Diff
@@ -16,10 +16,10 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto closest = others.begin();
|
auto closest = others.begin();
|
||||||
double minDistance = position.distance(closest->first);
|
float minDistance = position.distance(closest->first);
|
||||||
|
|
||||||
for (auto it = std::next(others.begin()); it != others.end(); ++it) {
|
for (auto it = std::next(others.begin()); it != others.end(); ++it) {
|
||||||
double distance = position.distance(it->first);
|
float distance = position.distance(it->first);
|
||||||
if (distance < minDistance) {
|
if (distance < minDistance) {
|
||||||
minDistance = distance;
|
minDistance = distance;
|
||||||
closest = it;
|
closest = it;
|
||||||
@@ -31,19 +31,24 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
double temp;
|
float temp;
|
||||||
|
float conductivity = 0.5;
|
||||||
|
float specific_heat = 900.0;
|
||||||
|
float diffusivity = 2000.0;
|
||||||
|
|
||||||
Temp(float temp) : temp(temp) {
|
Temp(float temp) : temp(temp) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Temp(const Vec2& testPos, const std::unordered_map<Vec2, Temp>& others) {
|
Temp(const Vec2& testPos, const std::unordered_map<Vec2, Temp>& others) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
double power = 2.0;
|
float power = 2.0;
|
||||||
double num = 0.0;
|
float num = 0.0;
|
||||||
double den = 0.0;
|
float den = 0.0;
|
||||||
|
|
||||||
for (const auto& [point, tempObj] : others) {
|
for (const auto& [point, tempObj] : others) {
|
||||||
double dist = testPos.distance(point);
|
float dist = testPos.distance(point);
|
||||||
double weight = 1.0 / std::pow(dist, power);
|
float weight = 1.0 / std::pow(dist, power);
|
||||||
num += weight * tempObj.temp;
|
num += weight * tempObj.temp;
|
||||||
den += weight;
|
den += weight;
|
||||||
}
|
}
|
||||||
@@ -54,15 +59,15 @@ public:
|
|||||||
this->temp = num / den;
|
this->temp = num / den;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double calTempIDW(const Vec2& testPos, std::unordered_map<Vec2, Temp> others) {
|
static float calTempIDW(const Vec2& testPos, std::unordered_map<Vec2, Temp> others) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
double power = 2.0;
|
float power = 2.0;
|
||||||
double num = 0.0;
|
float num = 0.0;
|
||||||
double den = 0.0;
|
float den = 0.0;
|
||||||
for (const auto& [point, temp] : others) {
|
for (const auto& [point, temp] : others) {
|
||||||
double dist = testPos.distance(point);
|
float dist = testPos.distance(point);
|
||||||
|
|
||||||
double weight = 1.0 / std::pow(dist, power);
|
float weight = 1.0 / std::pow(dist, power);
|
||||||
num += weight * temp.temp;
|
num += weight * temp.temp;
|
||||||
den += weight;
|
den += weight;
|
||||||
}
|
}
|
||||||
@@ -73,18 +78,18 @@ public:
|
|||||||
return num / den;
|
return num / den;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float calGrad(const Vec2& testPos, std::unordered_map<Vec2, Temp> others) {
|
static float calGrad(const Vec2& testPos, std::unordered_map<Vec2, Temp>& others) {
|
||||||
std::vector<std::pair<Vec2, double>> nearbyPoints;
|
std::vector<std::pair<Vec2, float>> nearbyPoints;
|
||||||
for (const auto& [point, temp] : others) {
|
for (const auto& [point, temp] : others) {
|
||||||
if (point.distance(testPos) <= 25) {
|
if (point.distance(testPos) <= 25) {
|
||||||
nearbyPoints.emplace_back(point, temp.temp);
|
nearbyPoints.emplace_back(point, temp.temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double sumX, sumY, sumT, sumX2, sumY2, sumXY, sumXT, sumYT = 0;
|
float sumX, sumY, sumT, sumX2, sumY2, sumXY, sumXT, sumYT = 0;
|
||||||
int n = nearbyPoints.size();
|
int n = nearbyPoints.size();
|
||||||
for (const auto& [point, temp] : nearbyPoints) {
|
for (const auto& [point, temp] : nearbyPoints) {
|
||||||
double x = point.x - testPos.x;
|
float x = point.x - testPos.x;
|
||||||
double y = point.y - testPos.y;
|
float y = point.y - testPos.y;
|
||||||
|
|
||||||
sumX += x;
|
sumX += x;
|
||||||
sumY += y;
|
sumY += y;
|
||||||
@@ -96,14 +101,14 @@ public:
|
|||||||
sumYT += y * temp;
|
sumYT += y * temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
double det = sumX2 * sumY2 - sumXY * sumXY;
|
float det = sumX2 * sumY2 - sumXY * sumXY;
|
||||||
|
|
||||||
if (std::abs(det) < 1e-10) {
|
if (std::abs(det) < 1e-10) {
|
||||||
Vec2 calpoint = Vec2(0, 0); // Singular matrix, cannot solve
|
Vec2 calpoint = Vec2(0, 0); // Singular matrix, cannot solve
|
||||||
}
|
}
|
||||||
|
|
||||||
double a = (sumXT * sumY2 - sumYT * sumXY) / det;
|
float a = (sumXT * sumY2 - sumYT * sumXY) / det;
|
||||||
double b = (sumX2 * sumYT - sumXY * sumXT) / det;
|
float b = (sumX2 * sumYT - sumXY * sumXT) / det;
|
||||||
|
|
||||||
Vec2 calpoint = Vec2(a, b); // ∇T = (∂T/∂x, ∂T/∂y)
|
Vec2 calpoint = Vec2(a, b); // ∇T = (∂T/∂x, ∂T/∂y)
|
||||||
|
|
||||||
@@ -115,73 +120,6 @@ public:
|
|||||||
return estimatedTemp;
|
return estimatedTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double diffuseHeat(const Vec2& position, const std::unordered_map<Vec2, Temp>& neighbors,
|
|
||||||
double currentTemp, double thermalDiffusivity, double timeStep, double gridSpacing = 1.0) {
|
|
||||||
TIME_FUNCTION;
|
|
||||||
|
|
||||||
double laplacian = 0.0;
|
|
||||||
int validNeighbors = 0;
|
|
||||||
|
|
||||||
for (const auto& [neighborPos, neighborTemp] : neighbors) {
|
|
||||||
double distance = position.distance(neighborPos);
|
|
||||||
|
|
||||||
if (std::abs(distance - gridSpacing) < 0.1 * gridSpacing) {
|
|
||||||
laplacian += (neighborTemp.temp - currentTemp);
|
|
||||||
validNeighbors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validNeighbors > 0) {
|
|
||||||
laplacian /= (validNeighbors * gridSpacing * gridSpacing);
|
|
||||||
|
|
||||||
double tempChange = thermalDiffusivity * timeStep * laplacian;
|
|
||||||
return currentTemp + tempChange;
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentTemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static double diffuseHeatWeighted(const Vec2& position, const std::unordered_map<Vec2, Temp>& neighbors,
|
|
||||||
double currentTemp, double thermalDiffusivity, double timeStep) {
|
|
||||||
TIME_FUNCTION;
|
|
||||||
|
|
||||||
if (neighbors.empty()) {
|
|
||||||
return currentTemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
double weightedSum = 0.0;
|
|
||||||
double totalWeight = 0.0;
|
|
||||||
|
|
||||||
for (const auto& [neighborPos, neighborTemp] : neighbors) {
|
|
||||||
double distance = position.distance(neighborPos);
|
|
||||||
|
|
||||||
if (distance < 1e-10) continue;
|
|
||||||
|
|
||||||
double weight = 1.0 / (distance * distance);
|
|
||||||
weightedSum += weight * neighborTemp.temp;
|
|
||||||
totalWeight += weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalWeight < 1e-10) {
|
|
||||||
return currentTemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
double averageNeighborTemp = weightedSum / totalWeight;
|
|
||||||
|
|
||||||
double diffusionRate = thermalDiffusivity * timeStep;
|
|
||||||
|
|
||||||
diffusionRate = std::min(diffusionRate, 1.0);
|
|
||||||
|
|
||||||
return currentTemp + diffusionRate * (averageNeighborTemp - currentTemp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void diffuse(const std::unordered_map<Vec2, Temp>& neighbors,
|
|
||||||
double thermalDiffusivity,
|
|
||||||
double timeStep,
|
|
||||||
double gridSpacing = 1.0) {
|
|
||||||
this->temp = diffuseHeatWeighted(Vec2(0, 0), neighbors, this->temp,
|
|
||||||
thermalDiffusivity, timeStep);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user