diff --git a/particles/foo2.prtc b/particles/foo2.prtc new file mode 100644 index 0000000..3846c35 --- /dev/null +++ b/particles/foo2.prtc @@ -0,0 +1,9 @@ +Center Delay +count velocity x y theta_i theta_f color start end decayrate +=================================================== +s +18000 65 0.5 0.5 0 360 cyan 1 0 0 +18000 65 0.5 0.5 0 360 magenta 2.075 0 0 +18000 65 0.5 0.5 0 360 yellow 4.931 0 0 +5000 65 0.78127 0.5 -45 45 white 4.931 10 2 +5000 65 0.21873 0.5 135 225 white 4.931 10 2 diff --git a/particles/load.prtc b/particles/load.prtc index c712cc2..699375f 100644 --- a/particles/load.prtc +++ b/particles/load.prtc @@ -2,6 +2,6 @@ Center Delay count velocity x y theta_i theta_f color start end decayrate =================================================== s -20000 70 0.4 0.5 0 360 cyan 0 0 0 -20000 70 0.5 0.5 0 360 yellow 0 0 0 -20000 70 0.6 0.5 0 360 magenta 0 0 0 +20000 68 0.5 0.5 0 360 cyan 1 0 0 +20000 68 0.5 0.5 0 360 magenta 2.075 0 0 +20000 68 0.5 0.5 0 360 yellow 4.931 0 0 diff --git a/particles/standard.prtc b/particles/standard.prtc new file mode 100644 index 0000000..c712cc2 --- /dev/null +++ b/particles/standard.prtc @@ -0,0 +1,7 @@ +Center Delay +count velocity x y theta_i theta_f color start end decayrate +=================================================== +s +20000 70 0.4 0.5 0 360 cyan 0 0 0 +20000 70 0.5 0.5 0 360 yellow 0 0 0 +20000 70 0.6 0.5 0 360 magenta 0 0 0 diff --git a/rooms/load.room b/rooms/load.room index ac3b37e..076273e 100644 --- a/rooms/load.room +++ b/rooms/load.room @@ -1,9 +1,9 @@ -Square (relative) -x y (remember to dupe first entry for final entry) -================================================== +Big Diamond (relative) +x y +================== r -0.275 0.1 -0.725 0.1 -0.725 0.9 -0.275 0.9 -0.275 0.1 +0.5 0.0 +0.78125 0.5 +0.5 1.0 +0.21875 0.5 +0.5 0.0 diff --git a/shaders/blur2.fs b/shaders/blur2.fs index 984fa61..8983ab0 100644 --- a/shaders/blur2.fs +++ b/shaders/blur2.fs @@ -21,7 +21,7 @@ void main() vec4 color = texture(texture0, fragTexCoord) * weight[0]; - for (int i = 1; i < 4; i++) { + for (int i = 1; i < 5; i++) { vec2 offset = texel * float(i); color += texture(texture0, fragTexCoord + offset) * weight[i]; color += texture(texture0, fragTexCoord - offset) * weight[i]; diff --git a/src/main.cpp b/src/main.cpp index 0b27730..58c2d39 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,8 +16,9 @@ int main(int argc, char* argv[]) { const int screenWidth = 1920; const int screenHeight = 1080; int rotFrame = 0; - float angle = 0.05; - float d_interval_pct = 0.00001; + float rotSpeed = -0.1f; + float rotAngle = 0.0f; + float d_interval_pct = 0.00001f; bool rotate = false; bool drawLines = true; bool drawFPS = false; @@ -67,6 +68,8 @@ int main(int argc, char* argv[]) { int resXY = blurShader.GetLocation("resolution"); int dirXY = blurShader.GetLocation("direction"); + int angleGL = rotShader.GetLocation("angle"); + int resRotGL = rotShader.GetLocation("resolution"); float resolution[2] = { float(screenWidth), float(screenHeight)}; blurShader.SetValue(resXY, resolution, RL_SHADER_UNIFORM_VEC2); noBlur.SetValue(resXY, resolution, RL_SHADER_UNIFORM_VEC2); @@ -77,14 +80,21 @@ int main(int argc, char* argv[]) { if (IsKeyPressed(KEY_R)) rotate = !rotate; if (IsKeyPressed(KEY_L)) drawLines = !drawLines; if (IsKeyPressed(KEY_F)) drawFPS = !drawFPS; - if (IsKeyPressed(KEY_D)) angle *= -1; + if (IsKeyPressed(KEY_D)) rotSpeed *= -1; if (IsKeyPressed(KEY_B)) useShader = !useShader; if (IsKeyPressed(KEY_SPACE)) paused = !paused; if (IsKeyPressed(KEY_T)) sim.reverseInterval(); if (!paused) { sim.updateFields(window.GetTime()); if (rotate) { - rotFrame++; + if (rotSpeed > 0) { + rotFrame++; + } else if (rotSpeed < 0 ) { + rotFrame--; + } + + rotAngle += rotSpeed * window.GetFrameTime(); + rotAngle = std::fmod(rotAngle, 2.0f * PI); } } //for(const auto& item : sim.getCorners()) lines.push_back({item[0], item[1]}); @@ -121,12 +131,15 @@ int main(int argc, char* argv[]) { blur.EndMode(); blurShader.SetValue(dirXY, dirV, SHADER_UNIFORM_VEC2); - } + } + + rotShader.SetValue(angleGL, &rotAngle, SHADER_UNIFORM_FLOAT); + rotShader.SetValue(resRotGL, resolution, SHADER_UNIFORM_VEC2); while(window.Drawing()) { window.ClearBackground(BLACK); - //rot.BeginMode(); + rot.BeginMode(); ClearBackground(BLACK); if (useShader) { blurShader.BeginMode(); @@ -137,7 +150,10 @@ int main(int argc, char* argv[]) { DrawTextureRec(renderTarget.texture, {0, 0, resolution[0], -resolution[1]}, {0,0}, WHITE); //noBlur.EndMode(); } - //rotShader.BeginMode(); + rot.EndMode(); + rotShader.BeginMode(); + DrawTextureRec(rot.texture, {0, 0, resolution[0], -resolution[1]}, {0,0}, WHITE); + rotShader.EndMode(); if(drawFPS) window.DrawFPS(10,10); } diff --git a/src/polypartiCL.hpp b/src/polypartiCL.hpp index 1742f91..be11645 100644 --- a/src/polypartiCL.hpp +++ b/src/polypartiCL.hpp @@ -87,4 +87,4 @@ namespace Polyparti { class Beam : public ParticleField { }; -}; +}; \ No newline at end of file diff --git a/tmp/polypartiCL.cpp b/tmp/polypartiCL.cpp new file mode 100644 index 0000000..eaf2ca9 --- /dev/null +++ b/tmp/polypartiCL.cpp @@ -0,0 +1,563 @@ +//use floats, not doubles, for 32-bit iGPUs + +#include "polypartiCL.hpp" +#include +#include +#include +#include +#include +#include + +using namespace sycl; + +struct Polyparti::ParticleField::ColCode { + std::vector positions, velocities; + float t, lifeTime = 0, startTime = 0; + int count, decay = 0, originCounter = 0; + int color[4]; + //float decay = 1.0f; + bool dies = false, dead = false; + + // allocate only one queue so we don't reinitialize every step of the calculation + static queue& q_shared() { + static queue q{gpu_selector_v, property::queue::in_order()}; + return q; + } + + void checkCollisions(std::vector verticies) { + queue& q = q_shared(); + int len_points = positions.size(); + + //Pointers to malloc on GPU VRAM for calculations. malloc_shared pointers are entry/exit + //point for data in CPU RAM + float *v_ptr = malloc_shared(2 * len_points, q); + float *d_ptr = malloc_shared(2 * len_points, q); + float *c_ptr = malloc_shared(2 * len_points, q); + float *ray_ptr = malloc_device(2 * len_points, q); + float *det_ptr = malloc_device(len_points, q); + float *bestA_ptr = malloc_device(2 * len_points, q); + float *bestSlope_ptr = malloc_device(2 * len_points, q); + float *r_ptr = malloc_device(len_points, q); + float *s_ptr = malloc_device(len_points, q); + float *rPref_ptr = malloc_device(len_points, q); + float *sPref_ptr = malloc_device(len_points, q); + float *nml_ptr = malloc_device(len_points * 2, q); + float *dot_ptr = malloc_device(len_points, q); + + float *t_ptr = malloc_shared(1, q); + std::vector sPrefInit(len_points, float(1000000.0f)); + + XYVector A, B, borderSlope; + + //Copy arrays from CPU RAM to shared pointer with GPU VRAM & CPU RAM + //SYCL can only handle one memcpy per kernel + + q.submit([&](handler& h) {h.memcpy(c_ptr, &positions[0], len_points * 2 * sizeof(float)); }); + q.wait(); + + q.submit([&](handler& h) {h.memcpy(v_ptr, &velocities[0], len_points * 2 * sizeof(float));}); + q.wait(); + + q.submit([&](handler& h) {h.memcpy(sPref_ptr, &sPrefInit[0], len_points * sizeof(float)); }); + q.wait(); + + q.submit([&](handler& h) { h.memcpy(t_ptr, &t, sizeof(float)); }); + q.wait(); + + + //Calculate expected location of each particle after imminent time step, and vectorize the + //difference from the current position. We will use Cramer's Rule with the + //vectorized boundary, also , to check intersection + + q.submit([&](handler& h) { + h.parallel_for(len_points * 2, [=](id<1> i) { + d_ptr[i] = v_ptr[i] * *t_ptr + c_ptr[i]; + ray_ptr[i] = d_ptr[i] - c_ptr[i]; + }); + }); + q.wait(); + + //Iterate over each room boundary in terms of their endpoints. Note that iterative and + //parallel computing concepts can work in tandem, with the next kernel executed + //sychronously within the for loop + + for (int i = 1; i < verticies.size(); i++) { + A = verticies[i-1], B = verticies[i]; + borderSlope[0] = B[0] - A[0]; + borderSlope[1] = B[1] - A[1]; + + q.submit([&](handler& h) { + h.parallel_for(len_points, [=](id<1> i) { + //Calculate determinant of 2x2 matrix of both vectors + det_ptr[i] = borderSlope[0] * ray_ptr[(i*2) + 1] - borderSlope[1] * ray_ptr[(i*2)]; + if (fabs(det_ptr[i]) > float(1e-5) * hypot(borderSlope[0], borderSlope[1]) * hypot(ray_ptr[i*2], ray_ptr[(i*2) + 1])) { + // + r_ptr[i] = ((c_ptr[i*2] - A[0]) * ray_ptr[(i*2)+1] - (c_ptr[(2*i)+1] - A[1]) * ray_ptr[i*2]) / det_ptr[i]; + s_ptr[i] = ((c_ptr[i*2] - A[0]) * borderSlope[1] - (c_ptr[(i*2) + 1] - A[1]) * borderSlope[0]) / det_ptr[i]; + } else { + r_ptr[i] = float(-1.0f); + s_ptr[i] = float(-1.0f); + } + }); + }); + q.wait(); + + q.submit([&](handler& h) { + h.parallel_for(len_points, [=](id<1> i) { + if (r_ptr[i] >= float(0.0) && r_ptr[i] <= float(1.0) + && s_ptr[i] >= float(0.0) && s_ptr[i] <= float(1.0)) { + if (s_ptr[i] < sPref_ptr[i]) { + sPref_ptr[i] = s_ptr[i]; + rPref_ptr[i] = r_ptr[i]; + bestA_ptr[i*2] = A[0]; + bestA_ptr[(i*2) + 1] = A[1]; + bestSlope_ptr[i*2] = borderSlope[0]; + bestSlope_ptr[(i*2) + 1] = borderSlope[1]; + } + } + }); + }); + q.wait(); + } + q.submit([&](handler& h) { + h.parallel_for(len_points, [=](id<1> i) { + if (sPref_ptr[i] < float(1000000.0f)) { + nml_ptr[(i*2)] = (-1 * bestSlope_ptr[(i*2) + 1]) / hypot(bestSlope_ptr[i*2], bestSlope_ptr[(i*2) + 1]); + nml_ptr[(i*2) + 1] = bestSlope_ptr[i*2] / hypot(bestSlope_ptr[i*2], bestSlope_ptr[(i*2) + 1]); + + dot_ptr[i] = (nml_ptr[i*2] * v_ptr[i*2]) + (nml_ptr[(i*2) + 1] * v_ptr[(i*2) + 1]); + + if (dot_ptr[i] > 0) { + nml_ptr[i*2] = nml_ptr[i*2] * -1; + nml_ptr[(i*2) + 1] = nml_ptr[(i*2) + 1] * -1; + dot_ptr[i] *= -1; + } + + v_ptr[i*2] -= 2 * dot_ptr[i] * nml_ptr[i*2]; + v_ptr[(i*2) + 1] -= 2 * dot_ptr[i] * nml_ptr[(i*2) + 1]; + + c_ptr[i*2] = bestA_ptr[i*2] + (rPref_ptr[i] * bestSlope_ptr[i*2]); + c_ptr[(i*2) + 1] = bestA_ptr[(i*2) + 1] + (rPref_ptr[i] * bestSlope_ptr[(i*2) + 1]); + + c_ptr[i*2] -= nml_ptr[i*2] * 1e-4f; + c_ptr[(i*2) + 1] -= nml_ptr[(i*2) + 1] * 1e-4f; + } + }); + }); + q.wait(); + + //Get the computed data back into pointers we can use + q.submit([&](handler& h) {h.memcpy(&positions[0], c_ptr, len_points * 2 * sizeof(float));}); + q.submit([&](handler& h) {h.memcpy(&velocities[0], v_ptr, len_points * 2 * sizeof(float));}); + q.wait(); + + free(c_ptr, q); + free(d_ptr, q); + free(v_ptr, q); + free(ray_ptr, q); + free(det_ptr, q); + free(bestA_ptr, q); + free(bestSlope_ptr, q); + free(r_ptr, q); + free(s_ptr, q); + free(rPref_ptr, q); + free(sPref_ptr, q); + free(nml_ptr, q); + free(dot_ptr, q); + free(t_ptr,q); + + } + void moveParticles() { + queue& q = q_shared(); + int len = positions.size(); + float *v_ptr = malloc_shared(2 * len, q); + float *p_ptr = malloc_shared(2 * len, q); + float *t_ptr = malloc_shared(1, q); + + q.submit([&](handler& h) { + h.memcpy(p_ptr, &positions[0], len * 2 * sizeof(float)); + }); + q.wait(); + q.submit([&](handler& h) { h.memcpy(v_ptr, &velocities[0], len * 2 * sizeof(float)); } ); + q.wait(); + + q.submit([&](handler& h) { h.memcpy(t_ptr, &t, sizeof(float)); } ); + q.wait(); + + q.submit([&](handler& h) { h.parallel_for(len * 2, [=](id<1> i) { + p_ptr[i] += v_ptr[i] * *t_ptr; + }); }); + q.wait(); + + q.submit([&](handler& h) { h.memcpy(&positions[0], p_ptr, len * 2 * sizeof(float)); }); + q.wait(); + + q.submit([&](handler& h) { h.memcpy(&velocities[0], v_ptr, len * 2 * sizeof(float)); }); + q.wait(); + + free(p_ptr, q); + free(v_ptr, q); + free(t_ptr, q); + } + +}; + +Polyparti::ParticleField::ParticleField() : colcode(std::make_unique()) { } +Polyparti::ParticleField::~ParticleField() = default; +Polyparti::ParticleField::ParticleField(const ParticleField& other) + : colcode(std::make_unique(*other.colcode)) {} +Polyparti::ParticleField::ParticleField(ParticleField&&) noexcept = default; +Polyparti::ParticleField& Polyparti::ParticleField::operator=(ParticleField&& other) noexcept = default; +Polyparti::ParticleField& Polyparti::ParticleField::operator=(const ParticleField& other) { + if (this != &other) { *colcode = *other.colcode; } + return *this; +} + +void Polyparti::ParticleField::addParticle(float x, float y, float vx, float vy) { + colcode->positions.push_back({x, y}); + colcode->velocities.push_back({vx, vy}); + colcode->count++; +} + +void Polyparti::ParticleField::deleteParticle(int index) { + colcode->positions.erase(colcode->positions.begin() + index); + colcode->velocities.erase(colcode->velocities.begin() + index); + colcode->count--; +} + +void Polyparti::ParticleField::updateField(std::vector verticies, double time) { + if(colcode->t > 0) { + ++colcode->originCounter; + } else if (colcode->t < 0) { + --colcode->originCounter; + } + if (colcode->dies) { + if (time >= colcode->lifeTime) { + colcode->color[3] -= colcode->decay; + } + if (colcode->color[3] <= 0) { + colcode->dead = true; + } + } + + if(colcode->originCounter >= 0) { + colcode->checkCollisions(verticies); + colcode->moveParticles(); + } +} + +const std::vector& Polyparti::ParticleField::getPositions() const { + return colcode->positions; +} + +const std::vector& Polyparti::ParticleField::getVelocities() const { + return colcode->velocities; +} +int Polyparti::ParticleField::getSize() { + return colcode->positions.size(); +} + +void Polyparti::ParticleField::setColor(std::string newColor) { + colcode->color[3] = 255; + if (newColor == "red" ) { + colcode->color[0] = 255; + colcode->color[1] = 0; + colcode->color[2] = 0; + } else if (newColor == "orange") { + colcode->color[0] = 255; + colcode->color[1] = 127; + colcode->color[2] = 0; + } else if (newColor == "yellow") { + colcode->color[0] = 255; + colcode->color[1] = 255; + colcode->color[2] = 0; + } else if (newColor == "green") { + colcode->color[0] = 0; + colcode->color[1] = 255; + colcode->color[2] = 0; + } else if (newColor == "blue") { + colcode->color[0] = 0; + colcode->color[1] = 0; + colcode->color[2] = 255; + } else if (newColor == "indigo") { + colcode->color[0] = 31; + colcode->color[1] = 0; + colcode->color[2] = 127; + } else if (newColor == "violet") { + colcode->color[0] = 127; + colcode->color[1] = 0; + colcode->color[2] = 127; + } else if (newColor == "cyan") { + colcode->color[0] = 0; + colcode->color[1] = 255; + colcode->color[2] = 255; + } else if (newColor == "darkgreen") { + colcode->color[0] = 0; + colcode->color[1] = 127; + colcode->color[2] = 0; + } else if (newColor == "magenta") { + colcode->color[0] = 255; + colcode->color[1] = 0; + colcode->color[2] = 255; + } else { + colcode->color[0] = 255; + colcode->color[1] = 255; + colcode->color[2] = 255; + } +} + +int* Polyparti::ParticleField::getColor() { + return colcode->color; +} + +int Polyparti::ParticleField::getCount() { + return colcode->count; +} + +void Polyparti::ParticleField::setInterval(const float interval) { + colcode->t = interval; +} + +void Polyparti::ParticleField::setDecay(const float t, const float d) { + if (t != 0) { + colcode->dies = true; + colcode->lifeTime = t; + colcode->decay = static_cast(fabs(d)); + } +} + +bool Polyparti::ParticleField::isDead() { + return colcode->dead; +} + +bool Polyparti::ParticleField::willDie() { + return colcode->dies; +} +struct Polyparti::Room::ImplRoom { + std::vector corners; + XYVector midpoint; +// std::vector field; +}; +Polyparti::Room::Room() : implRoom(std::make_unique()) {} + +Polyparti::Room::Room(int w, int h) : Room() { screenWidth = w; screenHeight = h;} + +Polyparti::Room::Room(int w, int h, int fps) : Room() { + screenWidth = w; + screenHeight = h; + interval = 1.0f/fps; +} +Polyparti::Room::~Room() = default; +Polyparti::Room::Room(const Room& other) + : implRoom(std::make_unique(*other.implRoom)), + info(other.info), + field(other.field), + x_min(other.x_min), + x_max(other.x_max), + y_min(other.y_min), + y_max(other.y_max){} +Polyparti::Room::Room(Room&& other) noexcept = default; +Polyparti::Room& Polyparti::Room::operator=(const Room& other) { + if (this != &other) { + *implRoom = *other.implRoom; + info = other.info; + field = other.field; + x_min = other.x_min; + x_max = other.x_max; + y_min = other.y_min; + y_max = other.y_max; + } + return *this; +} + +Polyparti::Room& Polyparti::Room::operator=(Room&& other) noexcept = default; + + +void Polyparti::Room::addCorner(float x, float y) { implRoom->corners.push_back({x,y}); } + +void Polyparti::Room::checkCorners() { + if (implRoom->corners.front() != implRoom->corners.back()) { implRoom->corners.push_back(implRoom->corners.front()); } +} + +std::vector Polyparti::Room::getCorners() { + return implRoom->corners; +} +void Polyparti::Room::loadRoom(std::string name) { + std::ifstream roomfile; + std::string roomName, temp; + bool relative = false; + float a, b, tot_x = 0, tot_y = 0; + int n = 0; + char check; + roomfile.open(name); + if (roomfile.is_open()) { + getline(roomfile, roomName); + getline(roomfile, temp); + getline(roomfile, temp); + check = roomfile.get(); + this->name = roomName; + } + else { std::cout << "error" << std::endl;} + + x_min = screenHeight; + y_min = screenWidth; + + if (check == 'r') { relative = true; } + + if (roomfile.is_open()) { + while (roomfile >> a >> b) { + if (relative) { a *= screenWidth; b *= screenHeight; } + addCorner(a,b); + tot_x += a; + tot_y += b; + n++; + + if ( a > x_max) {x_max = a;} + if ( a < x_min) {x_min = a;} + if ( b > y_max) {y_max = b;} + if ( b < y_min) {y_min = b;} + } + } else { + std::cout << "error: rooms/load.room not found" << '\n'; + } + checkCorners(); + roomfile.close(); + + implRoom->midpoint[0] = tot_x / n; + implRoom->midpoint[1] = tot_y / n; +} + +void Polyparti::Room::loadParticles(std::string name) { + fieldInfo newEntry; + std::ifstream partfile(name); + bool relativeScreen = false; + bool relativeRoom = false; + int count; + float velocity, x, y, deg_start, deg_end, start, life, decay; + std::string color, partName, temp; + + getline(partfile, partName); + getline(partfile, temp); + getline(partfile, temp); + + char check = partfile.get(); + if (check =='s') { relativeScreen = true;} + else if (check == 'r') { relativeRoom = true; } + + if (partfile.is_open()) { + while (partfile >> count >> velocity >> x >> y >> deg_start >> deg_end >> color >> start + >> life >> decay) { + if (relativeScreen) { + x *= screenWidth; + y *= screenHeight; + } else if (relativeRoom) { + x = implRoom->midpoint[0] + (x * (x_max - x_min) / 2); + y = implRoom->midpoint[1] + (y * (y_max - y_min) / 2); + } + newEntry.count = count; + newEntry.velocity = velocity; + newEntry.x = x; + newEntry.y = y; + newEntry.deg_start = deg_start; + newEntry.deg_end = deg_end; + newEntry.color = color; + newEntry.start = start; + newEntry.life = life; + newEntry.decayRate = decay; + + if (start == 0) { this->info.push_back(newEntry); } + else { + ++moreCount; + this->later.push_back(newEntry); + } + } + + //sort later fields by descending order so they can be popped_back + std::sort(later.begin(), later.end(), + [] (const fieldInfo& a, const fieldInfo& b) { return a.start > b.start; }); + } + else { + std::cout << "error: particles/load.prtc not found" << '\n'; + } + +} +void Polyparti::Room::initField(Polyparti::Room::fieldInfo info) { + ParticleField newField; + double rad = 4 * std::acos(0.0); + int passCount; + bool finalPass = false; + info.deg_start = (info.deg_start / 360) * rad; + info.deg_end = (info.deg_end/360) * rad; + + newField.setColor(info.color); + newField.setInterval(interval); + newField.setDecay(info.life, info.decayRate); + + for (int i = 0; i < passCount; i++) { + double angle = (float(i) / passCount) * (info.deg_end - info.deg_start); + newField.addParticle(info.x, info.y, info.velocity * (std::cos(angle + info.deg_start)), info.velocity * -(std::sin(angle + info.deg_start))); + } + + field.push_back(std::move(newField)); +} + +void Polyparti::Room::rotateRoom(float degrees) { + float rad = (degrees / 360) * 4 * std::acos(0.0); + + for (auto& point : implRoom->corners) { + float temp = point[0]; + point[0] = ((temp - implRoom->midpoint[0]) * std::cos(rad) - (point[1] - (implRoom->midpoint[1])) * std::sin(rad)); + point[1] = ((temp - implRoom->midpoint[0]) * std::sin(rad) + (point[1] - (implRoom->midpoint[1])) * std::cos(rad)); + point[0] += implRoom->midpoint[0]; + point[1] += implRoom->midpoint[1]; + } + } + +void Polyparti::Room::addFields() { + for (auto& i: info) initField(i); + + /*for (auto& f: field) { + if (!f.willDie()) { + + } + }*/ + +} + +void Polyparti::Room::updateFields(double time) { + while (moreCount && later.back().start <= time) { + initField(later.back()); + later.pop_back(); + --moreCount; + } + for (auto& f : field) { + f.updateField(implRoom->corners, time); + } + field.erase(std::remove_if(field.begin(), field.end(), [](auto& f) { return f.isDead();}), field.end()); +} + + + +Polyparti::ParticleField& Polyparti::Room::getField(int index) { return field.at(index); } + +void Polyparti::Room::adjustInterval(const float diff) { + //float diff = 1.0 + pct; + interval += diff; + for (auto &f : field) { + f.setInterval(diff); + } +} + +void Polyparti::Room::reverseInterval() { + interval = -interval; + for (auto &f : field) { + f.setInterval(interval); + } +} +int Polyparti::Room::getFieldCount() { + return field.size(); +} + +std::string Polyparti::Room::getName() { + return this->name; +}