Untitled
unknown
plain_text
a year ago
6.8 kB
2
Indexable
Never
#include <thread> #include <mutex> #include <atomic> #include <vector> #include "./nvToolsExt.h" #include "test.h" #include <random> #include <queue> #include <unordered_set> #include <cstdint> #include <future> // Just some hints on implementation // You could remove all of them struct PointStruct { std::atomic<float> _ax; std::atomic<float> _ay; bool _flag; PointStruct() :_ax(0), _ay(0), _flag(false) {} PointStruct(const std::atomic<float>& ax, const std::atomic<float>& ay, const bool flag) { _ax = ax.load(); _ay = ay.load(); _flag = flag; } PointStruct(const PointStruct& other) { _ax = other._ax.load(); _ay = other._ay.load(); _flag = other._flag; } PointStruct& operator=(const PointStruct& other) { _ax.store(other._ax.load()); _ay.store(other._ay.load()); _flag = other._flag; } }; static std::atomic_int globalTime; static std::atomic_bool workerMustExit = false; static std::atomic_bool counterMustExit = false; static std::thread workerThread; static std::thread counterThread; std::vector<PointStruct> points(130880, {0,0,false}); std::vector<std::vector<float>> velocities(130880, { 0.0,0.0}); std::vector<std::vector<float>> alphaC(130880, { 0.0,0.0 }); std::vector<std::vector<int>> intData(64, { 0,0,0, false}); std::vector<float> V0(130880, 0.0); static int startPointCount = 0; //std::mutex mtx; bool hitOnce = false; bool flag = false; const float g = 0.5; int RandomGenerator( int num) { std::random_device rd; // a seed source for the random number engine std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd() std::uniform_int_distribution<> distrib(1, num); return distrib(gen); } void alpha() { for (int i = 0; i < alphaC.size(); ++i) { alphaC[i][0] = RandomGenerator(100) * 0.01; alphaC[i][1] = pow(1 - (alphaC[i][0] * alphaC[i][0]),0.5); } /*for (int i = alphaC.size() / 2; i < alphaC.size(); ++i) { alphaC[i][0] = RandomGenerator(100) * (-0.01); alphaC[i][1] = pow(1 - (alphaC[i][0] * alphaC[i][0]), 0.5); }*/ } void velo(int time) { float delta; int j; for (int i = 0; i < velocities.size(); ++i) { j = i / 64; if (points[i]._flag && j<64) { delta = (time - intData[j][2]) * 0.01; velocities[i][0] = V0[i] * alphaC[i][1]; velocities[i][1] = V0[i] * alphaC[i][0] - g * delta; } } } void position(int time) { //std::lock_guard<std::mutex> lock(mtx); //float time = delta * 0.001; float delta; int j; for (int i = 0; i < velocities.size(); ++i) { j = i / 64; if (points[i]._flag && j < 64) { delta = (time - intData[j][2]) * 0.01; points[i]._ax = intData[j][0] + velocities[i][0] * delta; points[i]._ay = intData[j][1] + (V0[i] * 0.7 * delta - (g * delta * delta) / 2); if (points[i]._ax > 1025 || points[i]._ay > 765) points[i]._flag = false; } } } // some code //видимо тут лежит логика на обновление картинки void WorkerThread(void) { while (!workerMustExit) { nvtxRangePush(__FUNCTION__); static int lastTime = 0; const int time = globalTime.load(); const int delta = time - lastTime; lastTime = time; if (delta > 0 && flag) { //int t = time - t0; /*velo(t); position(t);*/ test::render(); } static const int MIN_UPDATE_PERIOD_MS = 10; if (delta < MIN_UPDATE_PERIOD_MS) std::this_thread::sleep_for(std::chrono::milliseconds(MIN_UPDATE_PERIOD_MS - delta)); nvtxRangePop(); } } //инициализация нашего класса void test::init(void) { // some code std::random_device rd; // a seed source for the random number engine std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd() std::uniform_int_distribution<> distrib(1, 20); for (int i = 0; i < V0.size(); ++i) { V0[i] = RandomGenerator(5)* RandomGenerator(10); } alpha(); workerThread = std::thread(WorkerThread); // some code } //тут завершаем работу void test::term(void) { // some code workerMustExit = true; counterMustExit = true; // some code workerThread.join(); counterThread.join(); // some code } //рендерим картинку, ну то есть говорим что пока рисовать void test::render(void) { // some code if (flag) { for (int i = 0; i < points.size(); ++i) { if (points[i]._flag) { platform::drawPoint(points[i]._ax, points[i]._ay, 1, 1, 1, 1); } } } // platform::drawPoint(testPair.first, testPair.second, 1, 1, 1, 1); // some code } // void test::update(int dt) { // some code // Atomically replaces the current value with the result of arithmetic addition of the value and arg globalTime.fetch_add(dt); // some code } //тут реагируем на клик void test::on_click(int x, int y) { if (!flag) { //counterThread.detach(); intData[startPointCount][0] = x; intData[startPointCount][1] = 765 - y; intData[startPointCount][2] = globalTime.load(); intData[startPointCount][3] = true; /*startX = x; startY = y; t0 = globalTime.load();*/ //points.assign(64, { (float)intData[startPointCount][0],(float)intData[startPointCount][1],true }); for (int i = 0; i < 64; ++i) { points[i]._ax = intData[startPointCount][0]; points[i]._ay = intData[startPointCount][1]; points[i]._flag = true; } //testPair = { (float)x,(float)y }; counterThread = std::thread(PointsThread); flag = true; } } int GenerateValidPosition( int range) { int i = 0; do { i = RandomGenerator(range); } while (!points[i]._flag); return i; } void AssignNewPoints(std::vector<std::vector<int>> intData, int range) { for (int i = range; i < range + 64; ++i) { points[i]._ax = intData[startPointCount][0]; points[i]._ay = intData[startPointCount][1]; //points[i][2] = intData[startPointCount][2]; points[i]._flag = true; } } void test::PointsThread(void) { while (!counterMustExit) { static int lastTime = 0; const int time = globalTime.load(); const int delta = time - lastTime; lastTime = time; if (delta > 0 && flag) { //int t = time - t0; velo(time); position(time); } if (!hitOnce && time-intData[startPointCount][2] > 1500 ) { hitOnce = true; int destroyOrBlow = GenerateValidPosition(63); while (destroyOrBlow > 0) { int range = startPointCount + 64; startPointCount++; int position = GenerateValidPosition(range); if (destroyOrBlow % 2) { intData[startPointCount][0] = points[position]._ax; intData[startPointCount][1] = points[position]._ay; intData[startPointCount][2] = globalTime.load(); intData[startPointCount][3] = true; AssignNewPoints(intData, range); } else points[destroyOrBlow]._flag = false; destroyOrBlow--; } } } }