rewrite of grid2 done. dropped a lot of repeated code. removed sizes that I wasnt using.

This commit is contained in:
Yggdrasil75
2025-11-28 09:01:24 -05:00
parent 7083e60767
commit a06c869428
2 changed files with 126 additions and 434 deletions

View File

@@ -58,8 +58,8 @@ Grid2 setup(AnimationConfig config) {
std::vector<Vec2> pos; std::vector<Vec2> pos;
std::vector<Vec4> colors; std::vector<Vec4> colors;
std::vector<float> sizes; std::vector<float> sizes;
for (int y = 0; y < config.height; ++y) { for (int y = 0; y < config.height - 1; ++y) {
for (int x = 0; x < config.width; ++x) { for (int x = 0; x < config.width - 1; ++x) {
float gradient = (x + y) / float(config.width + config.height - 2); float gradient = (x + y) / float(config.width + config.height - 2);
pos.push_back(Vec2(x,y)); pos.push_back(Vec2(x,y));
colors.push_back(Vec4(gradient, gradient, gradient, 1.0f)); colors.push_back(Vec4(gradient, gradient, gradient, 1.0f));
@@ -253,7 +253,7 @@ void mainLogic(const AnimationConfig& config, Shared& state, int gradnoise) {
if (gradnoise == 0) { if (gradnoise == 0) {
grid = setup(config); grid = setup(config);
} else if (gradnoise == 1) { } else if (gradnoise == 1) {
grid = grid.noiseGenGridTemps(0,0,config.height, config.width, 0.01, 1.0, false, config.noisemod); grid = grid.noiseGenGridTemps(0,0,config.height-1, config.width-1, 0.01, 1.0, false, config.noisemod);
} }
grid.setDefault(Vec4(0,0,0,0)); grid.setDefault(Vec4(0,0,0,0));
{ {

View File

@@ -203,7 +203,7 @@ public:
GenericPixel(size_t id, Vec4 color, Vec2 pos) : id(id), color(color), pos(pos) {}; GenericPixel(size_t id, Vec4 color, Vec2 pos) : id(id), color(color), pos(pos) {};
//getters //getters
Vec4 getColor() { Vec4 getColor() const {
return color; return color;
} }
@@ -226,7 +226,7 @@ class Grid2 {
protected: protected:
//all positions //all positions
reverselookupassistant Positions; reverselookupassistant Positions;
std::unordered_map<size_t /*id*/, GenericPixel> Pixels; std::unordered_map<size_t, GenericPixel> Pixels;
std::vector<size_t> unassignedIDs; std::vector<size_t> unassignedIDs;
@@ -239,7 +239,6 @@ protected:
//TODO: spatial map //TODO: spatial map
SpatialGrid spatialGrid; SpatialGrid spatialGrid;
//float spatialCellSize = 2.0f;
float spatialCellSize = neighborRadius * 1.5f; float spatialCellSize = neighborRadius * 1.5f;
// Default background color for empty spaces // Default background color for empty spaces
@@ -252,7 +251,6 @@ protected:
std::unordered_map<size_t, WaterParticle> water; std::unordered_map<size_t, WaterParticle> water;
std::unordered_map<size_t, Temp> tempMap; std::unordered_map<size_t, Temp> tempMap;
bool updatingView = false;
public: public:
bool usable = false; bool usable = false;
@@ -264,7 +262,6 @@ public:
<< " max: " << maxChance << " gen colors: " << color << std::endl; << " max: " << maxChance << " gen colors: " << color << std::endl;
std::vector<Vec2> poses; std::vector<Vec2> poses;
std::vector<Vec4> colors; std::vector<Vec4> colors;
std::vector<float> sizes;
for (int x = minx; x < maxx; x++) { for (int x = minx; x < maxx; x++) {
for (int y = miny; y < maxy; y++) { for (int y = miny; y < maxy; y++) {
float nx = (x+noisemod)/(maxx+EPSILON)/0.1; float nx = (x+noisemod)/(maxx+EPSILON)/0.1;
@@ -282,18 +279,16 @@ public:
Vec4 newc = Vec4(red,green,blue,1.0); Vec4 newc = Vec4(red,green,blue,1.0);
colors.push_back(newc); colors.push_back(newc);
poses.push_back(Vec2(x,y)); poses.push_back(Vec2(x,y));
sizes.push_back(1.0f);
} else { } else {
Vec4 newc = Vec4(alpha,alpha,alpha,1.0); Vec4 newc = Vec4(alpha,alpha,alpha,1.0);
colors.push_back(newc); colors.push_back(newc);
poses.push_back(Vec2(x,y)); poses.push_back(Vec2(x,y));
sizes.push_back(1.0f);
} }
} }
} }
} }
std::cout << "noise generated" << std::endl; std::cout << "noise generated" << std::endl;
bulkAddObjects(poses,colors,sizes); bulkAddObjects(poses,colors);
return *this; return *this;
} }
@@ -458,15 +453,13 @@ public:
return results; return results;
} }
//get color from id
Vec4 getColor(size_t id) { Vec4 getColor(size_t id) {
return Colors.at(id); return Pixels.at(id).getColor();
} }
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(getPositionID(id), getTemps()); Temp temp = Temp(getPositionID(id), getTemps());
//double dtemp = Temp::calTempIDW(getPositionID(id), getTemps());
tempMap.emplace(id, temp); tempMap.emplace(id, temp);
} }
else { else {
@@ -474,6 +467,19 @@ public:
} }
return tempMap.at(id).temp; return tempMap.at(id).temp;
} }
double getTemp(Vec2 pos) {
size_t posid;
if (Positions.contains(pos)) {
posid = Positions.at(pos);
}
if (tempMap.find(posid) != tempMap.end()) {
return Temp(getPositionID(posid), getTemps()).temp;
}
else {
return tempMap.at(posid).temp;
}
}
std::unordered_map<Vec2, Temp> getTemps() { std::unordered_map<Vec2, Temp> getTemps() {
std::unordered_map<Vec2, Temp> out; std::unordered_map<Vec2, Temp> out;
@@ -519,20 +525,18 @@ public:
maxCorner.y = std::max(maxCorner.y, pos.y); maxCorner.y = std::max(maxCorner.y, pos.y);
} }
// Add a small margin to avoid edge cases
float margin = 1.0f;
minCorner.x -= margin;
minCorner.y -= margin;
maxCorner.x += margin;
maxCorner.y += margin;
} }
frame getGridRegionAsFrame(const Vec2& minCorner, const Vec2& maxCorner, frame getGridRegionAsFrame(const Vec2& minCorner, const Vec2& maxCorner,
Vec2& res, frame::colormap outChannels = frame::colormap::RGB) const { Vec2& res, frame::colormap outChannels = frame::colormap::RGB) const {
TIME_FUNCTION; TIME_FUNCTION;
// Calculate dimensions
size_t width = static_cast<int>(maxCorner.x - minCorner.x); size_t width = static_cast<int>(maxCorner.x - minCorner.x);
size_t height = static_cast<int>(maxCorner.y - minCorner.y); size_t height = static_cast<int>(maxCorner.y - minCorner.y);
size_t outputWidth = static_cast<int>(res.x);
size_t outputHeight = static_cast<int>(res.y);
float widthScale = outputWidth / width;
float heightScale = outputHeight / height;
frame outframe = frame(); frame outframe = frame();
outframe.colorFormat = outChannels; outframe.colorFormat = outChannels;
@@ -540,385 +544,135 @@ public:
width = height = 0; width = height = 0;
return outframe; return outframe;
} }
std::cout << "Rendering region: " << minCorner << " to " << maxCorner
<< " at resolution: " << res << std::endl;
std::cout << "Scale factors: " << widthScale << " x " << heightScale << std::endl;
std::vector<Vec4> colorBuffer(width * height, Vec4(0,0,0,0)); std::unordered_map<Vec2,Vec4> colorBuffer;
colorBuffer.reserve(outputHeight*outputWidth);
std::unordered_map<Vec2,Vec4> colorTempBuffer;
colorTempBuffer.reserve(outputHeight * outputWidth);
std::unordered_map<Vec2,int> countBuffer;
countBuffer.reserve(outputHeight * outputWidth);
std::cout << "built buffers" << std::endl;
for (const auto& [id, pos] : Positions) { for (const auto& [id, pos] : Positions) {
if (maxCorner.x > pos.x > minCorner.x && maxCorner.y pos.y > mincorner.y) { if (pos.x >= minCorner.x && pos.x <= maxCorner.x &&
pos.y >= minCorner.y && pos.y <= maxCorner.y) {
float relx = pos.x - minCorner.x;
float rely = pos.y - minCorner.y;
int pixx = static_cast<int>(relx * widthScale);
int pixy = static_cast<int>(rely * heightScale);
Vec2 pix = Vec2(pixx,pixy);
colorTempBuffer[pix] += Pixels.at(id).getColor();
countBuffer[pix]++;
//std::cout << "pixel at " << pix << " is: " << Pixels.at(id).getColor();
} }
}
// Calculate pixel coordinates std::cout << std::endl << "built initial buffer" << std::endl;
int pixelXm = static_cast<int>(pos.x/2 - minCorner.x);
int pixelXM = static_cast<int>(pos.x/2 - minCorner.x); for (size_t y = 0; y < outputHeight; ++y) {
int pixelYm = static_cast<int>(pos.y/2 - minCorner.y); for (size_t x = 0; x < outputWidth; ++x) {
int pixelYM = static_cast<int>(pos.y/2 - minCorner.y); if (countBuffer[Vec2(x,y)] > 0) colorBuffer[Vec2(x,y)] = colorTempBuffer[Vec2(x,y)] / static_cast<float>(countBuffer[Vec2(x,y)]) * 255;
else colorBuffer[Vec2(x,y)] = defaultBackgroundColor;
pixelXm = std::max(0, pixelXm); }
pixelXM = std::min(width - 1, pixelXM); }
pixelYm = std::max(0, pixelYm); std::cout << "blended second buffer" << std::endl;
pixelYM = std::min(height - 1, pixelYM);
switch (outChannels) {
// Ensure within bounds case frame::colormap::RGBA: {
if (pixelXM >= minCorner.x && pixelXm < width && pixelYM >= minCorner.y && pixelYm < height) { std::vector<uint8_t> colorBuffer2(outputWidth*outputHeight*4, 0);
const Vec4& color = Colors.at(id); std::cout << "outputting RGBA: " << std::endl;
float srcAlpha = color.a; for (const auto& [v2,getColor] : colorBuffer) {
float invSrcAlpha = 1.0f - srcAlpha; size_t index = (v2.y * outputWidth + v2.x) * 4;
for (int py = pixelYm; py <= pixelYM; ++py){ // std::cout << "index: " << index << std::endl;
for (int px = pixelXm; px <= pixelXM; ++px){ colorBuffer2[index+0] = getColor.r;
int index = (py * width + px); colorBuffer2[index+1] = getColor.g;
Vec4 dest = colorBuffer[index]; colorBuffer2[index+2] = getColor.b;
colorBuffer2[index+3] = getColor.a;
// Alpha blending: new_color = src * src_alpha + dest * (1 - src_alpha)
dest.r = color.r * srcAlpha + dest.r * invSrcAlpha;
dest.g = color.g * srcAlpha + dest.g * invSrcAlpha;
dest.b = color.b * srcAlpha + dest.b * invSrcAlpha;
dest.a = srcAlpha + dest.a * invSrcAlpha;
colorBuffer[index] = dest;
}
} }
frame result = frame(res.x,res.y, frame::colormap::RGBA);
result.setData(colorBuffer2);
std::cout << "returning result" << std::endl;
return result;
break;
} }
} case frame::colormap::BGR: {
std::vector<uint8_t> colorBuffer2(outputWidth*outputHeight*3, 0);
// Convert to RGB bytes std::cout << "outputting BGR: " << std::endl;
rgbData.resize(colorBuffer.size() * 3); for (const auto& [v2,getColor] : colorBuffer) {
for (int i = 0; i < colorBuffer.size(); ++i) { size_t index = (v2.y * outputWidth + v2.x) * 3;
Vec4& color = colorBuffer[i]; // std::cout << "index: " << index << std::endl;
int rgbIndex = i * 3; colorBuffer2[index+2] = getColor.r;
float alpha = color.a; colorBuffer2[index+1] = getColor.g;
colorBuffer2[index+0] = getColor.b;
if (alpha < 1.0) { //colorBuffer2[index+3] = getColor.a;
float invalpha = 1.0 - alpha;
color.r = defaultBackgroundColor.r * alpha + color.r * invalpha;
color.g = defaultBackgroundColor.g * alpha + color.g * invalpha;
color.b = defaultBackgroundColor.b * alpha + color.b * invalpha;
}
// Convert from [0,1] to [0,255] and store as RGB
rgbData[rgbIndex + 0] = static_cast<unsigned char>(color.r * 255);
rgbData[rgbIndex + 1] = static_cast<unsigned char>(color.g * 255);
rgbData[rgbIndex + 2] = static_cast<unsigned char>(color.b * 255);
}
}
void getGridRegionAsRGB(const Vec2& minCorner, const Vec2& maxCorner,
int& width, int& height, std::vector<uint8_t>& rgbData) const {
TIME_FUNCTION;
// Calculate dimensions
width = static_cast<int>(maxCorner.x - minCorner.x);
height = static_cast<int>(maxCorner.y - minCorner.y);
if (width <= 0 || height <= 0) {
width = height = 0;
rgbData.clear();
rgbData.shrink_to_fit();
return;
}
// Initialize RGB data with default background color
std::vector<Vec4> rgbaBuffer(width * height, Vec4(0,0,0,0));
// For each position in the grid, find the corresponding pixel
for (const auto& [id, pos] : Positions) {
size_t size = Sizes.at(id);
// Calculate pixel coordinates
int pixelXm = static_cast<int>(pos.x - size/2 - minCorner.x);
int pixelXM = static_cast<int>(pos.x + size/2 - minCorner.x);
int pixelYm = static_cast<int>(pos.y - size/2 - minCorner.y);
int pixelYM = static_cast<int>(pos.y + size/2 - minCorner.y);
pixelXm = std::max(0, pixelXm);
pixelXM = std::min(width - 1, pixelXM);
pixelYm = std::max(0, pixelYm);
pixelYM = std::min(height - 1, pixelYM);
// Ensure within bounds
if (pixelXM >= minCorner.x && pixelXm < width && pixelYM >= minCorner.y && pixelYm < height) {
const Vec4& color = Colors.at(id);
float srcAlpha = color.a;
float invSrcAlpha = 1.0f - srcAlpha;
for (int py = pixelYm; py <= pixelYM; ++py){
for (int px = pixelXm; px <= pixelXM; ++px){
int index = (py * width + px);
Vec4 dest = rgbaBuffer[index];
// Alpha blending: new_color = src * src_alpha + dest * (1 - src_alpha)
dest.r = color.r * srcAlpha + dest.r * invSrcAlpha;
dest.g = color.g * srcAlpha + dest.g * invSrcAlpha;
dest.b = color.b * srcAlpha + dest.b * invSrcAlpha;
dest.a = srcAlpha + dest.a * invSrcAlpha;
rgbaBuffer[index] = dest;
}
} }
frame result = frame(res.x,res.y, frame::colormap::BGR);
result.setData(colorBuffer2);
std::cout << "returning result" << std::endl;
return result;
break;
} }
} case frame::colormap::RGB:
default: {
// Convert to RGB bytes std::vector<uint8_t> colorBuffer2(outputWidth*outputHeight*3, 0);
rgbData.resize(rgbaBuffer.size() * 3); std::cout << "outputting RGB: " << std::endl;
for (int i = 0; i < rgbaBuffer.size(); ++i) { for (const auto& [v2,getColor] : colorBuffer) {
Vec4& color = rgbaBuffer[i]; size_t index = (v2.y * outputWidth + v2.x) * 3;
int rgbIndex = i * 3; // std::cout << "index: " << index << std::endl;
float alpha = color.a; colorBuffer2[index+0] = getColor.r;
colorBuffer2[index+1] = getColor.g;
if (alpha < 1.0) { colorBuffer2[index+2] = getColor.b;
float invalpha = 1.0 - alpha; //colorBuffer2[index+3] = getColor.a;
color.r = defaultBackgroundColor.r * alpha + color.r * invalpha;
color.g = defaultBackgroundColor.g * alpha + color.g * invalpha;
color.b = defaultBackgroundColor.b * alpha + color.b * invalpha;
}
// Convert from [0,1] to [0,255] and store as RGB
rgbData[rgbIndex + 0] = static_cast<unsigned char>(color.r * 255);
rgbData[rgbIndex + 1] = static_cast<unsigned char>(color.g * 255);
rgbData[rgbIndex + 2] = static_cast<unsigned char>(color.b * 255);
}
}
// Get region as BGR
void getGridRegionAsBGR(const Vec2& minCorner, const Vec2& maxCorner,
int& width, int& height, std::vector<uint8_t>& bgrData) const {
TIME_FUNCTION;
// Calculate dimensions
width = static_cast<int>(maxCorner.x - minCorner.x);
height = static_cast<int>(maxCorner.y - minCorner.y);
if (width <= 0 || height <= 0) {
width = height = 0;
bgrData.clear();
bgrData.shrink_to_fit();
return;
}
// Initialize RGB data with default background color
std::vector<Vec4> rgbaBuffer(width * height, defaultBackgroundColor);
// For each position in the grid, find the corresponding pixel
for (const auto& [id, pos] : Positions) {
size_t size = Sizes.at(id);
// Calculate pixel coordinates
int pixelXm = static_cast<int>(pos.x - size/2 - minCorner.x);
int pixelXM = static_cast<int>(pos.x + size/2 - minCorner.x);
int pixelYm = static_cast<int>(pos.y - size/2 - minCorner.y);
int pixelYM = static_cast<int>(pos.y + size/2 - minCorner.y);
pixelXm = std::max(0, pixelXm);
pixelXM = std::min(width - 1, pixelXM);
pixelYm = std::max(0, pixelYm);
pixelYM = std::min(height - 1, pixelYM);
// Ensure within bounds
if (pixelXM >= minCorner.x && pixelXm < width && pixelYM >= minCorner.y && pixelYm < height) {
const Vec4& color = Colors.at(id);
float srcAlpha = color.a;
float invSrcAlpha = 1.0f - srcAlpha;
for (int py = pixelYm; py <= pixelYM; ++py){
for (int px = pixelXm; px <= pixelXM; ++px){
int index = (py * width + px);
Vec4 dest = rgbaBuffer[index];
// Alpha blending: new_color = src * src_alpha + dest * (1 - src_alpha)
dest.r = color.r * srcAlpha + dest.r * invSrcAlpha;
dest.g = color.g * srcAlpha + dest.g * invSrcAlpha;
dest.b = color.b * srcAlpha + dest.b * invSrcAlpha;
dest.a = srcAlpha + dest.a * invSrcAlpha;
rgbaBuffer[index] = dest;
}
} }
frame result = frame(res.x,res.y, frame::colormap::RGB);
result.setData(colorBuffer2);
std::cout << "returning result" << std::endl;
return result;
break;
} }
} }
// Convert to BGR bytes
bgrData.resize(rgbaBuffer.size() * 3);
for (int i = 0; i < rgbaBuffer.size(); ++i) {
const Vec4& color = rgbaBuffer[i];
int bgrIndex = i * 3;
// Convert from [0,1] to [0,255] and store as BGR
bgrData[bgrIndex + 2] = static_cast<unsigned char>(color.r * 255);
bgrData[bgrIndex + 1] = static_cast<unsigned char>(color.g * 255);
bgrData[bgrIndex + 0] = static_cast<unsigned char>(color.b * 255);
}
} }
void getGridRegionAsRGBA(const Vec2& minCorner, const Vec2& maxCorner, frame getGridAsFrame(frame::colormap outchannel = frame::colormap::RGB) {
int& width, int& height, std::vector<uint8_t>& rgbaData) const { Vec2 min;
TIME_FUNCTION; Vec2 max;
// Calculate dimensions getBoundingBox(min,max);
width = static_cast<int>(maxCorner.x - minCorner.x); Vec2 res = (max + 1) - min;
height = static_cast<int>(maxCorner.y - minCorner.y); std::cout << "getting grid as frame with the following: " << min << max << res << std::endl;
return getGridRegionAsFrame(min, max, res, outchannel);
if (width <= 0 || height <= 0) {
width = height = 0;
rgbaData.clear();
rgbaData.shrink_to_fit();
return;
}
// Initialize RGBA data with default background color
std::vector<Vec4> rgbaBuffer(width * height, defaultBackgroundColor);
// For each position in the grid, find the corresponding pixel
for (const auto& [id, pos] : Positions) {
size_t size = Sizes.at(id);
// Calculate pixel coordinates
int pixelXm = static_cast<int>(pos.x - size/2 - minCorner.x);
int pixelXM = static_cast<int>(pos.x + size/2 - minCorner.x);
int pixelYm = static_cast<int>(pos.y - size/2 - minCorner.y);
int pixelYM = static_cast<int>(pos.y + size/2 - minCorner.y);
pixelXm = std::max(0, pixelXm);
pixelXM = std::min(width - 1, pixelXM);
pixelYm = std::max(0, pixelYm);
pixelYM = std::min(height - 1, pixelYM);
// Ensure within bounds
if (pixelXM >= minCorner.x && pixelXm < width && pixelYM >= minCorner.y && pixelYm < height) {
const Vec4& color = Colors.at(id);
float srcAlpha = color.a;
float invSrcAlpha = 1.0f - srcAlpha;
for (int py = pixelYm; py <= pixelYM; ++py){
for (int px = pixelXm; px <= pixelXM; ++px){
int index = (py * width + px);
Vec4 dest = rgbaBuffer[index];
// Alpha blending: new_color = src * src_alpha + dest * (1 - src_alpha)
dest.r = color.r * srcAlpha + dest.r * invSrcAlpha;
dest.g = color.g * srcAlpha + dest.g * invSrcAlpha;
dest.b = color.b * srcAlpha + dest.b * invSrcAlpha;
dest.a = srcAlpha + dest.a * invSrcAlpha;
rgbaBuffer[index] = dest;
}
}
}
}
// Convert to RGBA bytes
rgbaData.resize(rgbaBuffer.size() * 4);
for (int i = 0; i < rgbaBuffer.size(); ++i) {
const Vec4& color = rgbaBuffer[i];
int rgbaIndex = i * 4;
// Convert from [0,1] to [0,255] and store as RGBA
rgbaData[rgbaIndex + 0] = static_cast<unsigned char>(color.r * 255);
rgbaData[rgbaIndex + 1] = static_cast<unsigned char>(color.g * 255);
rgbaData[rgbaIndex + 2] = static_cast<unsigned char>(color.b * 255);
rgbaData[rgbaIndex + 3] = static_cast<unsigned char>(color.a * 255);
}
}
//get full as rgb/bgr
void getGridAsRGB(int& width, int& height, std::vector<uint8_t>& rgbData) {
Vec2 minCorner, maxCorner;
getBoundingBox(minCorner, maxCorner);
getGridRegionAsRGB(minCorner, maxCorner, width, height, rgbData);
}
void getGridAsBGR(int& width, int& height, std::vector<uint8_t>& bgrData) {
Vec2 minCorner, maxCorner;
getBoundingBox(minCorner, maxCorner);
getGridRegionAsBGR(minCorner, maxCorner, width, height, bgrData);
}
//frame stuff
frame getGridRegionAsFrameRGB(const Vec2& minCorner, const Vec2& maxCorner) const {
TIME_FUNCTION;
int width, height;
std::vector<uint8_t> rgbData;
getGridRegionAsRGB(minCorner, maxCorner, width, height, rgbData);
frame resultFrame(width, height, frame::colormap::RGB);
resultFrame.setData(rgbData);
return resultFrame;
}
frame getGridRegionAsFrameRGBA(const Vec2& minCorner, const Vec2& maxCorner) const {
TIME_FUNCTION;
int width, height;
std::vector<uint8_t> rgbaData;
getGridRegionAsRGBA(minCorner, maxCorner, width, height, rgbaData);
frame resultFrame(width, height, frame::colormap::RGBA);
resultFrame.setData(rgbaData);
return resultFrame;
}
// Get region as frame (BGR format)
frame getGridRegionAsFrameBGR(const Vec2& minCorner, const Vec2& maxCorner) const {
TIME_FUNCTION;
int width, height;
std::vector<uint8_t> bgrData;
getGridRegionAsBGR(minCorner, maxCorner, width, height, bgrData);
frame resultFrame(width, height, frame::colormap::BGR);
resultFrame.setData(bgrData);
return resultFrame;
}
// Get entire grid as frame with specified format
frame getGridAsFrame(frame::colormap format = frame::colormap::RGB) const {
TIME_FUNCTION;
Vec2 minCorner, maxCorner;
getBoundingBox(minCorner, maxCorner);
frame Frame;
switch (format) {
case frame::colormap::RGB:
Frame = std::move(getGridRegionAsFrameRGB(minCorner, maxCorner));
break;
case frame::colormap::RGBA:
Frame = std::move(getGridRegionAsFrameRGBA(minCorner, maxCorner));
break;
case frame::colormap::BGR:
Frame = std::move(getGridRegionAsFrameBGR(minCorner, maxCorner));
break;
default:
Frame = std::move(getGridRegionAsFrameRGB(minCorner, maxCorner));
break;
}
return Frame;
} }
frame getTempAsFrame(Vec2 minCorner, Vec2 maxCorner, Vec2 res, frame::colormap outcolor = frame::colormap::RGB) { frame getTempAsFrame(Vec2 minCorner, Vec2 maxCorner, Vec2 res, frame::colormap outcolor = frame::colormap::RGB) {
TIME_FUNCTION; TIME_FUNCTION;
if (updatingView) return frame();
updatingView = true;
int pcount = 0; int pcount = 0;
// std::cout << "getTempAsFrame() started" << pcount++ << std::endl;
size_t sheight = maxCorner.x - minCorner.x; size_t sheight = maxCorner.x - minCorner.x;
size_t swidth = maxCorner.y - minCorner.y; size_t swidth = maxCorner.y - minCorner.y;
// std::cout << "getTempAsFrame() started" << pcount++ << std::endl;
int width = static_cast<int>(res.x); int width = static_cast<int>(res.x);
int height = static_cast<int>(res.y); int height = static_cast<int>(res.y);
// std::cout << "getTempAsFrame() started" << pcount++ << std::endl;
std::unordered_map<Vec2, double> tempBuffer; std::unordered_map<Vec2, double> tempBuffer;
tempBuffer.reserve(res.x * res.y); tempBuffer.reserve(res.x * res.y);
// 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 xdiff = (maxCorner.x - minCorner.x);
float ydiff = (maxCorner.y - minCorner.y); float ydiff = (maxCorner.y - minCorner.y);
// 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(minCorner.x + (x * xdiff / res.x),minCorner.y + (y * ydiff / res.y)); Vec2 cposin = Vec2(minCorner.x + (x * xdiff / res.x),minCorner.y + (y * ydiff / res.y));
// std::cout << "getTempAsFrame() started" << pcount++ << std::endl;
double ctemp = getTemp(cposin); double ctemp = getTemp(cposin);
tempBuffer[Vec2(x,y)] = ctemp; tempBuffer[Vec2(x,y)] = ctemp;
// std::cout << "getTempAsFrame() started" << pcount++ << std::endl;
if (ctemp > maxTemp) maxTemp = ctemp; if (ctemp > maxTemp) maxTemp = ctemp;
else if (ctemp < minTemp) minTemp = ctemp; else if (ctemp < minTemp) minTemp = ctemp;
} }
} }
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;
switch (outcolor) { switch (outcolor) {
case frame::colormap::RGBA: { case frame::colormap::RGBA: {
std::vector<uint8_t> rgbaBuffer(width*height*4, 0); std::vector<uint8_t> rgbaBuffer(width*height*4, 0);
@@ -930,10 +684,8 @@ public:
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;
frame result = frame(res.x,res.y, frame::colormap::RGBA); frame result = frame(res.x,res.y, frame::colormap::RGBA);
result.setData(rgbaBuffer); result.setData(rgbaBuffer);
updatingView = false;
return result; return result;
break; break;
} }
@@ -945,12 +697,9 @@ public:
rgbaBuffer[index+2] = atemp; rgbaBuffer[index+2] = atemp;
rgbaBuffer[index+1] = atemp; rgbaBuffer[index+1] = atemp;
rgbaBuffer[index+0] = atemp; rgbaBuffer[index+0] = atemp;
//rgbaBuffer[index+3] = 255;
} }
// std::cout << "rgba buffer is " << rgbaBuffer.size() << std::endl;
frame result = frame(res.x,res.y, frame::colormap::BGR); frame result = frame(res.x,res.y, frame::colormap::BGR);
result.setData(rgbaBuffer); result.setData(rgbaBuffer);
updatingView = false;
return result; return result;
break; break;
} }
@@ -963,78 +712,36 @@ public:
rgbaBuffer[index+0] = atemp; rgbaBuffer[index+0] = atemp;
rgbaBuffer[index+1] = atemp; rgbaBuffer[index+1] = atemp;
rgbaBuffer[index+2] = atemp; rgbaBuffer[index+2] = atemp;
//rgbaBuffer[index+3] = 255;
} }
// std::cout << "rgba buffer is " << rgbaBuffer.size() << std::endl;
frame result = frame(res.x,res.y, frame::colormap::RGB); frame result = frame(res.x,res.y, frame::colormap::RGB);
result.setData(rgbaBuffer); result.setData(rgbaBuffer);
updatingView = false;
return result; return result;
break; break;
} }
} }
} }
//remove object (should remove the id, the color, the position, and the size)
size_t removeID(size_t id) { size_t removeID(size_t id) {
Vec2 oldPosition = Positions.at(id); Vec2 oldPosition = Positions.at(id);
Positions.remove(id); Positions.remove(id);
Colors.erase(id); Pixels.erase(id);
Sizes.erase(id);
unassignedIDs.push_back(id); unassignedIDs.push_back(id);
spatialGrid.remove(id, oldPosition); spatialGrid.remove(id, oldPosition);
// updateNeighborForID(id);
return id; return id;
} }
size_t removeID(Vec2 pos) {
size_t id = getPositionVec(pos);
Positions.remove(id);
Colors.erase(id);
Sizes.erase(id);
unassignedIDs.push_back(id);
spatialGrid.remove(id, pos);
// updateNeighborForID(id);
return id;
}
//bulk update positions //bulk update positions
void bulkUpdatePositions(const std::unordered_map<size_t, Vec2>& newPositions) { void bulkUpdatePositions(const std::unordered_map<size_t, Vec2>& newPositions) {
TIME_FUNCTION; TIME_FUNCTION;
//#pragma omp parallel for
for (const auto& [id, newPos] : newPositions) { for (const auto& [id, newPos] : newPositions) {
Vec2 oldPosition = Positions.at(id); Vec2 oldPosition = Positions.at(id);
Positions.at(id).move(newPos); Positions.at(id).move(newPos);
Pixels.at(id).move(newPos);
spatialGrid.update(id, oldPosition, newPos); spatialGrid.update(id, oldPosition, newPos);
} }
// updateNeighborMap();
} }
// Bulk update colors std::vector<size_t> bulkAddObjects(const std::vector<Vec2> poses, std::vector<Vec4> colors) {
void bulkUpdateColors(const std::unordered_map<size_t, Vec4>& newColors) {
TIME_FUNCTION;
//#pragma omp parallel for
for (const auto& [id, newColor] : newColors) {
auto it = Colors.find(id);
if (it != Colors.end()) {
it->second = newColor;
}
}
}
// Bulk update sizes
void bulkUpdateSizes(const std::unordered_map<size_t, float>& newSizes) {
TIME_FUNCTION;
//#pragma omp parallel for
for (const auto& [id, newSize] : newSizes) {
auto it = Sizes.find(id);
if (it != Sizes.end()) {
it->second = newSize;
}
}
}
std::vector<size_t> bulkAddObjects(const std::vector<Vec2> poses, std::vector<Vec4> colors, std::vector<float>& sizes) {
TIME_FUNCTION; TIME_FUNCTION;
std::vector<size_t> ids; std::vector<size_t> ids;
ids.reserve(poses.size()); ids.reserve(poses.size());
@@ -1042,28 +749,25 @@ public:
// Reserve space in maps to avoid rehashing // Reserve space in maps to avoid rehashing
if (Positions.bucket_count() < Positions.size() + poses.size()) { if (Positions.bucket_count() < Positions.size() + poses.size()) {
Positions.reserve(Positions.size() + poses.size()); Positions.reserve(Positions.size() + poses.size());
Colors.reserve(Colors.size() + colors.size()); Pixels.reserve(Positions.size() + poses.size());
Sizes.reserve(Sizes.size() + sizes.size());
} }
// Batch insertion // Batch insertion
std::vector<size_t> newids; std::vector<size_t> newids;
for (size_t i = 0; i < poses.size(); ++i) { for (size_t i = 0; i < poses.size(); ++i) {
size_t id = Positions.set(poses[i]); size_t id = Positions.set(poses[i]);
Colors[id] = colors[i]; Pixels.emplace(id, GenericPixel(id, colors[i], poses[i]));
Sizes[id] = sizes[i];
spatialGrid.insert(id,poses[i]); spatialGrid.insert(id,poses[i]);
newids.push_back(id); newids.push_back(id);
} }
shrinkIfNeeded(); shrinkIfNeeded();
// updateNeighborMap();
usable = true; usable = true;
return newids; return newids;
} }
std::vector<size_t> bulkAddObjects(const std::vector<Vec2> poses, std::vector<Vec4> colors, std::vector<float>& sizes, std::vector<float>& temps) { std::vector<size_t> bulkAddObjects(const std::vector<Vec2> poses, std::vector<Vec4> colors, std::vector<float>& temps) {
TIME_FUNCTION; TIME_FUNCTION;
std::vector<size_t> ids; std::vector<size_t> ids;
ids.reserve(poses.size()); ids.reserve(poses.size());
@@ -1071,8 +775,7 @@ public:
// Reserve space in maps to avoid rehashing // Reserve space in maps to avoid rehashing
if (Positions.bucket_count() < Positions.size() + poses.size()) { if (Positions.bucket_count() < Positions.size() + poses.size()) {
Positions.reserve(Positions.size() + poses.size()); Positions.reserve(Positions.size() + poses.size());
Colors.reserve(Colors.size() + colors.size()); Pixels.reserve(Positions.size() + poses.size());
Sizes.reserve(Sizes.size() + sizes.size());
tempMap.reserve(tempMap.size() + temps.size()); tempMap.reserve(tempMap.size() + temps.size());
} }
@@ -1080,8 +783,7 @@ public:
std::vector<size_t> newids; std::vector<size_t> newids;
for (size_t i = 0; i < poses.size(); ++i) { for (size_t i = 0; i < poses.size(); ++i) {
size_t id = Positions.set(poses[i]); size_t id = Positions.set(poses[i]);
Colors[id] = colors[i]; Pixels.emplace(id, GenericPixel(id, colors[i], poses[i]));
Sizes[id] = sizes[i];
Temp temptemp = Temp(temps[i]); Temp temptemp = Temp(temps[i]);
tempMap.insert({id, temptemp}); tempMap.insert({id, temptemp});
spatialGrid.insert(id,poses[i]); spatialGrid.insert(id,poses[i]);
@@ -1101,14 +803,9 @@ public:
//clear //clear
void clear() { void clear() {
Positions.clear(); Positions.clear();
Colors.clear(); Pixels.clear();
Sizes.clear();
spatialGrid.clear(); spatialGrid.clear();
//neighborMap.clear(); Pixels.rehash(0);
Colors.rehash(0);
Sizes.rehash(0);
// neighborMap.rehash(0);
// 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);
} }
@@ -1168,7 +865,6 @@ public:
<< " max: " << maxChance << " gen colors: " << color << std::endl; << " max: " << maxChance << " gen colors: " << color << std::endl;
std::vector<Vec2> poses; std::vector<Vec2> poses;
std::vector<Vec4> colors; std::vector<Vec4> colors;
std::vector<float> sizes;
std::vector<float> temps; std::vector<float> temps;
int callnumber = 0; int callnumber = 0;
for (int x = minx; x < maxx; x++) { for (int x = minx; x < maxx; x++) {
@@ -1186,21 +882,19 @@ public:
Vec4 newc = Vec4(red,green,blue,1.0); Vec4 newc = Vec4(red,green,blue,1.0);
colors.push_back(newc); colors.push_back(newc);
poses.push_back(Vec2(x,y)); poses.push_back(Vec2(x,y));
sizes.push_back(1.0f);
temps.push_back(temp * 100); temps.push_back(temp * 100);
//std::cout << "temp: " << temp << std::endl; //std::cout << "temp: " << temp << std::endl;
} else { } else {
Vec4 newc = Vec4(alpha,alpha,alpha,1.0); Vec4 newc = Vec4(alpha,alpha,alpha,1.0);
colors.push_back(newc); colors.push_back(newc);
poses.push_back(Vec2(x,y)); poses.push_back(Vec2(x,y));
sizes.push_back(1.0f);
temps.push_back(temp * 100); temps.push_back(temp * 100);
} }
} }
} }
} }
std::cout << "noise generated" << std::endl; std::cout << "noise generated" << std::endl;
bulkAddObjects(poses, colors, sizes, temps); bulkAddObjects(poses, colors, temps);
return *this; return *this;
} }
@@ -1228,7 +922,6 @@ public:
getBoundingBox(Min, Max); getBoundingBox(Min, Max);
std::vector<Vec2> newPos; std::vector<Vec2> newPos;
std::vector<Vec4> newColors; std::vector<Vec4> newColors;
std::vector<float> newSizes;
for (size_t x = Min.x; x < Max.x; x++) { for (size_t x = Min.x; x < Max.x; x++) {
for (size_t y = Min.y; y < Max.y; x++) { for (size_t y = Min.y; y < Max.y; x++) {
Vec2 pos = Vec2(x,y); Vec2 pos = Vec2(x,y);
@@ -1237,10 +930,9 @@ public:
float size = 0.1; float size = 0.1;
newPos.push_back(pos); newPos.push_back(pos);
newColors.push_back(color); newColors.push_back(color);
newSizes.push_back(size);
} }
} }
bulkAddObjects(newPos, newColors, newSizes); bulkAddObjects(newPos, newColors);
gradTemps(); gradTemps();
return *this; return *this;
} }