pushing to work.

This commit is contained in:
yggdrasil75
2025-11-25 05:36:01 -05:00
parent 72c318a320
commit 872cf3db1a
3 changed files with 226 additions and 129 deletions

View File

@@ -85,25 +85,25 @@ void Preview(Grid2& grid) {
} }
void livePreview(Grid2& grid) { void livePreview(Grid2& grid) {
// std::lock_guard<std::mutex> lock(previewMutex); std::lock_guard<std::mutex> lock(previewMutex);
// //currentPreviewFrame = grid.getGridAsFrame(frame::colormap::RGBA); currentPreviewFrame = grid.getGridAsFrame(frame::colormap::RGBA);
// Vec2 min; // Vec2 min;
// Vec2 max; // Vec2 max;
// grid.getBoundingBox(min, max); // grid.getBoundingBox(min, max);
// currentPreviewFrame = grid.getTempAsFrame(min,max, Vec2(1024,1024)); //currentPreviewFrame = grid.getTempAsFrame(min,max, Vec2(1024,1024));
// glGenTextures(1, &textu); glGenTextures(1, &textu);
// glBindTexture(GL_TEXTURE_2D, textu); glBindTexture(GL_TEXTURE_2D, textu);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
// glBindTexture(GL_TEXTURE_2D, textu); glBindTexture(GL_TEXTURE_2D, textu);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, currentPreviewFrame.getWidth(), currentPreviewFrame.getHeight(), glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, currentPreviewFrame.getWidth(), currentPreviewFrame.getHeight(),
// 0, GL_RGBA, GL_UNSIGNED_BYTE, currentPreviewFrame.getData().data()); 0, GL_RGBA, GL_UNSIGNED_BYTE, currentPreviewFrame.getData().data());
// updatePreview = true; updatePreview = true;
} }
std::vector<std::tuple<size_t, Vec2, Vec4>> pickSeeds(Grid2 grid, AnimationConfig config) { std::vector<std::tuple<size_t, Vec2, Vec4>> pickSeeds(Grid2 grid, AnimationConfig config) {
@@ -134,7 +134,7 @@ void pickTempSeeds(Grid2& grid, AnimationConfig config) {
std::uniform_int_distribution<> yDist(0, config.height - 1); std::uniform_int_distribution<> yDist(0, config.height - 1);
std::uniform_real_distribution<> temp(0.0f, 100.0f); std::uniform_real_distribution<> temp(0.0f, 100.0f);
for (int i = 0; i < config.numSeeds; ++i){ for (int i = 0; i < config.numSeeds * 100; ++i){
grid.setTemp(Vec2(xDist(gen),yDist(gen)).floor(), temp(gen)); grid.setTemp(Vec2(xDist(gen),yDist(gen)).floor(), temp(gen));
} }
} }
@@ -276,33 +276,33 @@ void mainLogic(const AnimationConfig& config, Shared& state, int gradnoise) {
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) {
// 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);
// std::lock_guard<std::mutex> lock(state.mutex); std::lock_guard<std::mutex> lock(state.mutex);
// state.grid = grid; state.grid = grid;
// state.hasNewFrame = true; state.hasNewFrame = true;
// state.currentFrame = i; state.currentFrame = i;
// // Print compression info for this frame // Print compression info for this frame
// if (i % 10 == 0 ) { if (i % 10 == 0 ) {
// frame bgrframe; frame bgrframe;
// std::cout << "Processing frame " << i + 1 << "/" << config.totalFrames << std::endl; std::cout << "Processing frame " << i + 1 << "/" << config.totalFrames << std::endl;
// bgrframe = grid.getGridAsFrame(frame::colormap::BGR); bgrframe = grid.getGridAsFrame(frame::colormap::BGR);
// frames.push_back(bgrframe); frames.push_back(bgrframe);
// //bgrframe.decompress(); //bgrframe.decompress();
// //BMPWriter::saveBMP(std::format("output/grayscalesource.{}.bmp", i), bgrframe); //BMPWriter::saveBMP(std::format("output/grayscalesource.{}.bmp", i), bgrframe);
// bgrframe.compressFrameLZ78(); bgrframe.compressFrameLZ78();
// //bgrframe.printCompressionStats(); //bgrframe.printCompressionStats();
// } }
// } }
// exportavi(frames,config); exportavi(frames,config);
} }
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;

View File

@@ -202,7 +202,7 @@ protected:
Vec2 gridMax; Vec2 gridMax;
//neighbor map //neighbor map
std::unordered_map<size_t, std::vector<size_t>> neighborMap; //std::unordered_map<size_t, std::vector<size_t>> neighborMap;
float neighborRadius = 1.0f; float neighborRadius = 1.0f;
//TODO: spatial map //TODO: spatial map
@@ -416,7 +416,7 @@ public:
// Add to spatial grid // Add to spatial grid
spatialGrid.insert(id, pos); spatialGrid.insert(id, pos);
updateNeighborForID(id); // updateNeighborForID(id);
return id; return id;
} }
@@ -425,7 +425,7 @@ public:
Vec2 oldPosition = Positions.at(id); Vec2 oldPosition = Positions.at(id);
spatialGrid.update(id, oldPosition, newPosition); spatialGrid.update(id, oldPosition, newPosition);
Positions.at(id).move(newPosition); Positions.at(id).move(newPosition);
updateNeighborForID(id); // updateNeighborForID(id);
} }
void setPosition(size_t id, float x, float y) { void setPosition(size_t id, float x, float y) {
@@ -434,7 +434,7 @@ public:
spatialGrid.update(id, oldPos, newPos); spatialGrid.update(id, oldPos, newPos);
Positions.at(id).move(newPos); Positions.at(id).move(newPos);
updateNeighborForID(id); // updateNeighborForID(id);
} }
//set color by id (by pos same as get color) //set color by id (by pos same as get color)
@@ -489,7 +489,7 @@ public:
Sizes.erase(id); Sizes.erase(id);
unassignedIDs.push_back(id); unassignedIDs.push_back(id);
spatialGrid.remove(id, oldPosition); spatialGrid.remove(id, oldPosition);
updateNeighborForID(id); // updateNeighborForID(id);
return id; return id;
} }
@@ -500,7 +500,7 @@ public:
Sizes.erase(id); Sizes.erase(id);
unassignedIDs.push_back(id); unassignedIDs.push_back(id);
spatialGrid.remove(id, pos); spatialGrid.remove(id, pos);
updateNeighborForID(id); // updateNeighborForID(id);
return id; return id;
} }
@@ -513,7 +513,7 @@ public:
Positions.at(id).move(newPos); Positions.at(id).move(newPos);
spatialGrid.update(id, oldPosition, newPos); spatialGrid.update(id, oldPosition, newPos);
} }
updateNeighborMap(); // updateNeighborMap();
} }
// Bulk update colors // Bulk update colors
@@ -567,7 +567,7 @@ public:
} }
shrinkIfNeeded(); shrinkIfNeeded();
updateNeighborMap(); // updateNeighborMap();
return getAllIDs(); // Or generate ID range return getAllIDs(); // Or generate ID range
} }
@@ -594,7 +594,38 @@ public:
} }
shrinkIfNeeded(); shrinkIfNeeded();
updateNeighborMap(); // updateNeighborMap();
usable = true;
return newids;
}
std::vector<size_t> bulkAddObjects(const std::vector<Vec2> poses, std::vector<Vec4> colors, std::vector<float>& sizes, std::vector<float>& temps) {
TIME_FUNCTION;
std::vector<size_t> ids;
ids.reserve(poses.size());
// Reserve space in maps to avoid rehashing
if (Positions.bucket_count() < Positions.size() + poses.size()) {
Positions.reserve(Positions.size() + poses.size());
Colors.reserve(Colors.size() + colors.size());
Sizes.reserve(Sizes.size() + sizes.size());
tempMap.reserve(tempMap.size() + temps.size());
}
// Batch insertion
std::vector<size_t> newids;
for (size_t i = 0; i < poses.size(); ++i) {
size_t id = Positions.set(poses[i]);
Colors[id] = colors[i];
Sizes[id] = sizes[i];
tempMap.emplace(id, Temp(temps[i]));
spatialGrid.insert(id,poses[i]);
newids.push_back(id);
}
shrinkIfNeeded();
// updateNeighborMap();
usable = true; usable = true;
return newids; return newids;
@@ -900,36 +931,9 @@ public:
Frame = std::move(getGridRegionAsFrameRGB(minCorner, maxCorner)); Frame = std::move(getGridRegionAsFrameRGB(minCorner, maxCorner));
break; break;
} }
//Frame.compressFrameDiff();
//Frame.compressFrameRLE();
//Frame.compressFrameLZ78();
return Frame; return Frame;
} }
// Get compressed frame with specified compression
frame getGridAsCompressedFrame(frame::colormap format = frame::colormap::RGB,
frame::compresstype compression = frame::compresstype::RLE) {
TIME_FUNCTION;
frame gridFrame = getGridAsFrame(format);
if (gridFrame.getData().empty()) {
return gridFrame;
}
switch (compression) {
case frame::compresstype::RLE:
return gridFrame.compressFrameRLE();
case frame::compresstype::DIFF:
return gridFrame.compressFrameDiff();
case frame::compresstype::DIFFRLE:
return gridFrame.compressFrameDiffRLE();
case frame::compresstype::HUFFMAN:
return gridFrame.compressFrameHuffman();
case frame::compresstype::RAW:
default:
return gridFrame;
}
}
//get bounding box //get bounding box
void getBoundingBox(Vec2& minCorner, Vec2& maxCorner) const { void getBoundingBox(Vec2& minCorner, Vec2& maxCorner) const {
@@ -968,10 +972,10 @@ public:
Colors.clear(); Colors.clear();
Sizes.clear(); Sizes.clear();
spatialGrid.clear(); spatialGrid.clear();
neighborMap.clear(); //neighborMap.clear();
Colors.rehash(0); Colors.rehash(0);
Sizes.rehash(0); Sizes.rehash(0);
neighborMap.rehash(0); // neighborMap.rehash(0);
// Reset to default background color // Reset to default background color
defaultBackgroundColor = Vec4(0.0f, 0.0f, 0.0f, 0.0f); defaultBackgroundColor = Vec4(0.0f, 0.0f, 0.0f, 0.0f);
} }
@@ -989,63 +993,82 @@ public:
} }
} }
void updateNeighborMap() { // void updateNeighborMap() {
//std::cout << "updateNeighborMap()" << std::endl; // //std::cout << "updateNeighborMap()" << std::endl;
TIME_FUNCTION; // TIME_FUNCTION;
neighborMap.clear(); // neighborMap.clear();
optimizeSpatialGrid(); // optimizeSpatialGrid();
// For each object, find nearby neighbors // // For each object, find nearby neighbors
float radiusSq = neighborRadius * neighborRadius; // float radiusSq = neighborRadius * neighborRadius;
#pragma omp parallel for // #pragma omp parallel for
for (const auto& [id1, pos1] : Positions) { // for (const auto& [id1, pos1] : Positions) {
std::vector<size_t> neighbors; // std::vector<size_t> neighbors;
//std::vector<size_t> candidate_ids = spatialGrid.queryRange(pos1, neighborRadius); // //std::vector<size_t> candidate_ids = spatialGrid.queryRange(pos1, neighborRadius);
std::unordered_set<size_t> candidate_idset = spatialGrid.find(pos1); // std::unordered_set<size_t> candidate_idset = spatialGrid.find(pos1);
std::vector<size_t> candidate_ids; // std::vector<size_t> candidate_ids;
candidate_ids.reserve(candidate_idset.size()); // candidate_ids.reserve(candidate_idset.size());
for (auto it = candidate_idset.begin(); it != candidate_idset.end();) { // for (auto it = candidate_idset.begin(); it != candidate_idset.end();) {
candidate_ids.push_back(std::move(candidate_idset.extract(it++).value())); // candidate_ids.push_back(std::move(candidate_idset.extract(it++).value()));
} // }
for (size_t id2 : candidate_ids) { // for (size_t id2 : candidate_ids) {
if (id1 != id2) { // && Positions.at(id1).distanceSquared(Positions.at(id2)) <= radiusSq) { // if (id1 != id2) { // && Positions.at(id1).distanceSquared(Positions.at(id2)) <= radiusSq) {
neighbors.push_back(id2); // neighbors.push_back(id2);
} // }
} // }
#pragma omp critical // #pragma omp critical
neighborMap[id1] = std::move(neighbors); // neighborMap[id1] = std::move(neighbors);
} // }
} // }
// Update neighbor map for a single object // Update neighbor map for a single object
void updateNeighborForID(size_t id) { // void updateNeighborForID(size_t id) {
TIME_FUNCTION; // TIME_FUNCTION;
Vec2 pos_it = Positions.at(id); // Vec2 pos_it = Positions.at(id);
// std::vector<size_t> neighbors;
// float radiusSq = neighborRadius * neighborRadius;
// for (const auto& [id2, pos2] : Positions) {
// if (id != id2 && pos_it.distanceSquared(pos2) <= radiusSq) {
// neighbors.push_back(id2);
// }
// }
// neighborMap[id] = std::move(neighbors);
// }
// // Get neighbors for an ID
// const std::vector<size_t>& getNeighbors(size_t id) const {
// static const std::vector<size_t> empty;
// auto it = neighborMap.find(id);
// return it != neighborMap.end() ? it->second : empty;
// }
std::vector<size_t> getNeighbors(size_t id) const {
Vec2 pos = Positions.at(id);
std::vector<size_t> candidates = spatialGrid.queryRange(pos, neighborRadius);
// Filter out self and apply exact distance check
std::vector<size_t> neighbors; std::vector<size_t> neighbors;
float radiusSq = neighborRadius * neighborRadius; float radiusSq = neighborRadius * neighborRadius;
for (const auto& [id2, pos2] : Positions) { for (size_t candidateId : candidates) {
if (id != id2 && pos_it.distanceSquared(pos2) <= radiusSq) { if (candidateId != id &&
neighbors.push_back(id2); pos.distanceSquared(Positions.at(candidateId)) <= radiusSq) {
neighbors.push_back(candidateId);
} }
} }
neighborMap[id] = std::move(neighbors);
}
// Get neighbors for an ID return neighbors;
const std::vector<size_t>& getNeighbors(size_t id) const {
static const std::vector<size_t> empty;
auto it = neighborMap.find(id);
return it != neighborMap.end() ? it->second : empty;
} }
// Set neighbor search radius // Set neighbor search radius
void setNeighborRadius(float radius) { void setNeighborRadius(float radius) {
neighborRadius = radius; neighborRadius = radius;
updateNeighborMap(); // Recompute all neighbors // updateNeighborMap(); // Recompute all neighbors
optimizeSpatialGrid();
} }
@@ -1057,14 +1080,56 @@ public:
void setTemp(size_t id, double temp) { void setTemp(size_t id, double temp) {
Temp tval = Temp(temp); Temp tval = Temp(temp);
tempMap[id] = tval; tempMap.emplace(id, tval);
}
Grid2 noiseGenGridTemps(size_t minx,size_t miny, size_t maxx, size_t maxy, float minChance = 0.1f
, float maxChance = 1.0f, bool color = true, int noisemod = 42) {
TIME_FUNCTION;
std::cout << "generating a noise grid with the following: (" << minx << ", " << miny
<< ") by (" << maxx << ", " << maxy << ") " << "chance: " << minChance
<< " max: " << maxChance << " gen colors: " << color << std::endl;
std::vector<Vec2> poses;
std::vector<Vec4> colors;
std::vector<float> sizes;
for (int x = minx; x < maxx; x++) {
for (int y = miny; y < maxy; y++) {
float nx = (x+noisemod)/(maxx+EPSILON)/0.1;
float ny = (y+noisemod)/(maxy+EPSILON)/0.1;
Vec2 pos = Vec2(nx,ny);
float alpha = noisegen.permute(pos);
if (alpha > minChance && alpha < maxChance) {
if (color) {
float red = noisegen.permute(Vec2(nx*0.3,ny*0.3));
float green = noisegen.permute(Vec2(nx*0.6,ny*.06));
float blue = noisegen.permute(Vec2(nx*0.9,ny*0.9));
std::uniform_real_distribution<> temp(0.0f, 100.0f);
Vec4 newc = Vec4(red,green,blue,1.0);
colors.push_back(newc);
poses.push_back(Vec2(x,y));
sizes.push_back(1.0f);
} else {
Vec4 newc = Vec4(alpha,alpha,alpha,1.0);
colors.push_back(newc);
poses.push_back(pos);
sizes.push_back(1.0f);
}
}
}
}
std::cout << "noise generated" << std::endl;
bulkAddObjects(poses,colors,sizes);
return *this;
} }
double getTemp(size_t id) { double getTemp(size_t id) {
if (tempMap.find(id) != tempMap.end()) { if (tempMap.find(id) != tempMap.end()) {
Temp temp; Temp temp = Temp(getPositionID(id), getTemps());
double dtemp = temp.calTempIDW(getPositionID(id), getTemps()); //double dtemp = Temp::calTempIDW(getPositionID(id), getTemps());
setTemp(id, dtemp); tempMap.emplace(id, temp);
}
else {
std::cout << "found a temp: " << tempMap.at(id).temp << std::endl;
} }
return tempMap.at(id).temp; return tempMap.at(id).temp;
} }
@@ -1072,7 +1137,18 @@ public:
std::unordered_map<Vec2, Temp> getTemps() { std::unordered_map<Vec2, Temp> getTemps() {
std::unordered_map<Vec2, Temp> out; std::unordered_map<Vec2, Temp> out;
for (const auto& [id, temp] : tempMap) { for (const auto& [id, temp] : tempMap) {
out[getPositionID(id)] = temp; out.emplace(getPositionID(id), temp);
}
return out;
}
std::unordered_map<Vec2, Temp> getTemps(size_t id) {
std::unordered_map<Vec2, Temp> out;
std::vector<size_t> tval = spatialGrid.queryRange(Positions.at(id), 10);
for (size_t tempid : tval) {
Vec2 pos = Positions.at(tempid);
Temp temp = tempMap.at(tempid);
out.insert({pos, temp});
} }
return out; return out;
} }
@@ -1080,8 +1156,7 @@ public:
double getTemp(const Vec2 pos) { double getTemp(const Vec2 pos) {
size_t id = getOrCreatePositionVec(pos, 0.0f, true); size_t id = getOrCreatePositionVec(pos, 0.0f, true);
if (tempMap.find(id) == tempMap.end()) { if (tempMap.find(id) == tempMap.end()) {
Temp temp; double dtemp = Temp::calTempIDW(pos, getTemps(id));
double dtemp = temp.calTempIDW(pos, getTemps());
setTemp(id, dtemp); setTemp(id, dtemp);
return dtemp; return dtemp;
} }
@@ -1106,11 +1181,13 @@ public:
// std::cout << "getTempAsFrame() started" << pcount++ << std::endl; // std::cout << "getTempAsFrame() started" << pcount++ << std::endl;
double maxTemp = 0.0; double maxTemp = 0.0;
double minTemp = 0.0; double minTemp = 0.0;
float xdiff = (maxCorner.x - minCorner.x);
float ydiff = (maxCorner.y - minCorner.y);
// std::cout << "getTempAsFrame() started" << pcount++ << std::endl; // std::cout << "getTempAsFrame() started" << pcount++ << std::endl;
for (int x = 0; x < res.x; x++) { for (int x = 0; x < res.x; x++) {
for (int y = 0; y < res.y; y++) { for (int y = 0; y < res.y; y++) {
Vec2 cposout = Vec2(x,y); Vec2 cposout = Vec2(x,y);
Vec2 cposin = Vec2(x/sheight, y/swidth); Vec2 cposin = Vec2(minCorner.x + (x * xdiff / res.x),minCorner.y + (y * ydiff / res.y));
// std::cout << "getTempAsFrame() started" << pcount++ << std::endl; // std::cout << "getTempAsFrame() started" << pcount++ << std::endl;
double ctemp = getTemp(cposin); double ctemp = getTemp(cposin);
@@ -1123,17 +1200,17 @@ public:
std::cout << "max temp: " << maxTemp << " min temp: " << minTemp << std::endl; std::cout << "max temp: " << maxTemp << " min temp: " << minTemp << std::endl;
// std::cout << "getTempAsFrame() middle" << std::endl; // std::cout << "getTempAsFrame() middle" << std::endl;
std::vector<uint8_t> rgbaBuffer(width*height*4, 0); std::vector<uint8_t> rgbaBuffer(width*height*3, 0);
for (const auto& [v2, temp] : tempBuffer) { for (const auto& [v2, temp] : tempBuffer) {
size_t index = (v2.y * width + v2.y) * 4; size_t index = (v2.y * width + v2.x) * 3;
uint8_t atemp = static_cast<unsigned char>((((temp-minTemp) * 100) / (maxTemp-minTemp)) * 255); uint8_t atemp = static_cast<unsigned char>((((temp-minTemp)) / (maxTemp-minTemp)) * 255);
rgbaBuffer[index] = atemp; rgbaBuffer[index] = atemp;
rgbaBuffer[index+1] = atemp; rgbaBuffer[index+1] = atemp;
rgbaBuffer[index+2] = atemp; rgbaBuffer[index+2] = atemp;
rgbaBuffer[index+3] = 255; //rgbaBuffer[index+3] = 255;
} }
std::cout << "rgba buffer is " << rgbaBuffer.size() << std::endl; std::cout << "rgba buffer is " << rgbaBuffer.size() << std::endl;
frame result = frame(res.x,res.y, frame::colormap::RGBA); frame result = frame(res.x,res.y, frame::colormap::RGB);
result.setData(rgbaBuffer); result.setData(rgbaBuffer);
updatingView = false; updatingView = false;
return result; return result;

View File

@@ -13,6 +13,26 @@ protected:
public: public:
double temp; double temp;
Temp(float temp) : temp(temp) {};
Temp(const Vec2& testPos, const std::unordered_map<Vec2, Temp>& others) {
TIME_FUNCTION;
double power = 2.0;
double num = 0.0;
double den = 0.0;
for (const auto& [point, tempObj] : others) {
double dist = testPos.distance(point);
double weight = 1.0 / std::pow(dist, power);
num += weight * tempObj.temp;
den += weight;
}
if (den < 1e-10 && den > -1e-10) {
den = 1e-10;
}
this->temp = num / den;
}
static double calTempIDW(const Vec2& testPos, std::unordered_map<Vec2, Temp> others) { static double calTempIDW(const Vec2& testPos, std::unordered_map<Vec2, Temp> others) {
TIME_FUNCTION; TIME_FUNCTION;