Untitled

mail@pastecode.io avatar
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--;
		}
	}

		
	}
}