Game.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. #include <cmath>
  2. #include <vector>
  3. #include <fstream>
  4. #include "client/Game.h"
  5. #include "client/utils/Utils.h"
  6. #include "rendering/Renderer.h"
  7. #include "common/utils/String.h"
  8. #include "common/utils/Random.h"
  9. #include "math/Quaternion.h"
  10. #include "rendering/wrapper/GLWrapper.h"
  11. #include "rendering/wrapper/GLFWWrapper.h"
  12. static float readFloat(std::ifstream& in) {
  13. float f;
  14. in >> f;
  15. in.get();
  16. return f;
  17. }
  18. static Vector3 readVector3(std::ifstream& in) {
  19. float x = readFloat(in);
  20. float y = readFloat(in);
  21. float z = readFloat(in);
  22. return Vector3(x, y, z);
  23. }
  24. static Vector2 readVector2(std::ifstream& in) {
  25. float x = readFloat(in);
  26. float y = readFloat(in);
  27. return Vector2(x, y);
  28. }
  29. Game::Game(const Control& control, const Clock& fps, const Clock& tps, RenderSettings& renderSettings,
  30. const WindowSize& size, const char* file) :
  31. control(control), fps(fps), tps(tps), renderSettings(renderSettings), size(size), world(blockRegistry),
  32. worldRenderer(world), pointIndex(0), moveSpeed(0.125f), movedLength(0.0f), mode(Mode::AUTO) {
  33. Random r(0);
  34. float h = World::WORLD_SIZE * 0.6f;
  35. float mid = World::WORLD_SIZE * 0.5f;
  36. float randLength = World::WORLD_SIZE * 0.125f * 0.25f;
  37. pos.set(0, h, 0);
  38. lastPos = pos;
  39. rotation = Quaternion(Vector3(1, 0, 0), -80);
  40. lastRotation = rotation;
  41. Quaternion q;
  42. for(uint i = 0; i < cameraPoints.getCapacity(); i++) {
  43. Vector3 offset(mid, h, mid);
  44. offset += Vector3(r.nextFloat(randLength), r.nextFloat(randLength), r.nextFloat(randLength));
  45. Vector3 v(i * 360.0f / cameraPoints.getCapacity(), 0.0f);
  46. v *= mid * 0.5f;
  47. v += offset;
  48. q.mul(Quaternion(Vector3(r.nextFloat() * 360.0f, r.nextFloat() * -90.0f), -10.0f));
  49. cameraPoints.add({v, q, 0.0f});
  50. }
  51. updateDistances();
  52. std::vector<KDTree::Triangle> data;
  53. (void) readFloat;
  54. (void) file;
  55. std::ifstream in;
  56. in.open(file);
  57. if(in.good()) {
  58. while(true) {
  59. Vector3 a = readVector3(in);
  60. Vector2 ta = readVector2(in);
  61. Vector3 b = readVector3(in);
  62. Vector2 tb = readVector2(in);
  63. Vector3 c = readVector3(in);
  64. Vector2 tc = readVector2(in);
  65. if(in.eof()) {
  66. break;
  67. }
  68. data.push_back(KDTree::Triangle(a, b, c));
  69. treeData.add(Triangle(Vertex(a, ta), Vertex(b, tb), Vertex(c, tc)));
  70. }
  71. }
  72. //generateSphere(data);
  73. //generateRandom(data);
  74. /*for(KDTree::Triangle& t : data) {
  75. treeData.add(Triangle(
  76. Vertex(t[0], Vector2(8.0f / 16.0f, 0.0f)),
  77. Vertex(t[1], Vector2(9.0f / 16.0f, 0.0f)),
  78. Vertex(t[2], Vector2(9.0f / 16.0f, 1.0f / 16.0f))
  79. ));
  80. }*/
  81. treeData.build();
  82. u64 time = GLFWWrapper::getTimeNanos();
  83. kdTree.build(data);
  84. time = GLFWWrapper::getTimeNanos() - time;
  85. std::cout << "KD-Tree-Build-Time: " << time << "ns for " << data.size() << " triangles\n";
  86. kdTree.fillLines(lines);
  87. }
  88. void Game::tick() {
  89. lastRotation = rotation;
  90. lastPos = pos;
  91. Matrix m = rotation.toMatrix();
  92. Vector3 right = m * Vector3(1.0f, 0.0f, 0.0f);
  93. Vector3 up = m * Vector3(0.0f, 1.0f, 0.0f);
  94. Vector3 back = m * Vector3(0.0f, 0.0f, -1.0f);
  95. if(mode == Mode::PLAYER) {
  96. const float speed = 1.0f;
  97. if(control.keys.down.isDown()) {
  98. pos += back * speed;
  99. }
  100. if(control.keys.up.isDown()) {
  101. pos -= back * speed;
  102. }
  103. if(control.keys.left.isDown()) {
  104. pos -= right * speed;
  105. }
  106. if(control.keys.right.isDown()) {
  107. pos += right * speed;
  108. }
  109. if(control.keys.jump.isDown()) {
  110. pos += up * speed;
  111. }
  112. if(control.keys.sneak.isDown()) {
  113. pos -= up * speed;
  114. }
  115. const float rotationSpeed = 5.0f;
  116. if(control.keys.camLeft.isDown()) {
  117. rotation.mul(Quaternion(up, rotationSpeed));
  118. }
  119. if(control.keys.camRight.isDown()) {
  120. rotation.mul(Quaternion(up, -rotationSpeed));
  121. }
  122. if(control.keys.camUp.isDown()) {
  123. rotation.mul(Quaternion(right, rotationSpeed));
  124. }
  125. if(control.keys.camDown.isDown()) {
  126. rotation.mul(Quaternion(right, -rotationSpeed));
  127. }
  128. if(control.keys.test3.getDownTime() == 1) {
  129. cameraPoints.add({pos, rotation, 0.0f});
  130. }
  131. } else if(mode == Mode::AUTO) {
  132. movedLength += moveSpeed;
  133. if(control.keys.camUp.isDown()) {
  134. moveSpeed += 0.0125f;
  135. if(moveSpeed > 1.0f) {
  136. moveSpeed = 1.0f;
  137. }
  138. }
  139. if(control.keys.camDown.isDown()) {
  140. moveSpeed -= 0.0125f;
  141. if(moveSpeed < 0.0f) {
  142. moveSpeed = 0.0f;
  143. }
  144. }
  145. if(control.keys.test3.isDown()) {
  146. mode = Mode::PLAYER;
  147. cameraPoints.clear();
  148. }
  149. }
  150. if(control.keys.test.isDown()) {
  151. mode = Mode::PLAYER;
  152. }
  153. if(control.keys.test2.isDown() && cameraPoints.getLength() >= 3) {
  154. mode = Mode::AUTO;
  155. movedLength = 0.0f;
  156. updateDistances();
  157. }
  158. if(control.keys.test4.getDownTime() == 1) {
  159. renderSettings.shadows = !renderSettings.shadows;
  160. }
  161. if(control.keys.test5.getDownTime() == 1) {
  162. renderSettings.ssao = !renderSettings.ssao;
  163. }
  164. if(control.keys.test6.getDownTime() == 1) {
  165. renderSettings.bump += 0.05f;
  166. if(renderSettings.bump > 1.0f) {
  167. renderSettings.bump = 0.0f;
  168. }
  169. }
  170. if(control.keys.factor.getDownTime() == 1) {
  171. if(renderSettings.factor == 1) {
  172. renderSettings.factor = 2;
  173. } else if(renderSettings.factor == 2) {
  174. renderSettings.factor = 3;
  175. } else {
  176. renderSettings.factor = 1;
  177. }
  178. renderSettings.dirtyFactor = true;
  179. }
  180. if(control.buttons.primary.getDownTime() == 1) {
  181. float hWidth = size.width * 0.5f;
  182. float hHeight = size.height * 0.5f;
  183. float x = (control.buttons.getX() - hWidth) / hWidth;
  184. float y = -(control.buttons.getY() - hHeight) / hHeight;
  185. float aspect = hWidth / hHeight;
  186. float tan = tanf((0.5f * 60.0f) * M_PI / 180.0f);
  187. float q = 1.0f / tan;
  188. Vector3 direction(x / (q / aspect), y / q, 1.0f);
  189. direction.normalize();
  190. direction = m * direction;
  191. clickLine.clear();
  192. clickLine.add(pos, pos + direction * 100.0f, 0xFF00FF);
  193. u64 time = GLFWWrapper::getTimeNanos();
  194. bool check = kdTree.findIntersection(pos, direction);
  195. time = GLFWWrapper::getTimeNanos() - time;
  196. std::cout << "Intersection-Time: " << time << "ns\n";
  197. if(check) {
  198. KDTree::Triangle t = kdTree.getIntersectedTriangle();
  199. clickLine.add(t[0], t[1], 0xFFFF00);
  200. clickLine.add(t[1], t[2], 0xFFFF00);
  201. clickLine.add(t[2], t[0], 0xFFFF00);
  202. Vector3 hit = kdTree.getIntersection();
  203. float diff = 0.2f;
  204. clickLine.add(hit - Vector3(diff, 0.0f, 0.0f), hit + Vector3(diff, 0.0f, 0.0f), 0x00FF00);
  205. clickLine.add(hit - Vector3(0.0f, diff, 0.0f), hit + Vector3(0.0f, diff, 0.0f), 0x00FF00);
  206. clickLine.add(hit - Vector3(0.0f, 0.0f, diff), hit + Vector3(0.0f, 0.0f, diff), 0x00FF00);
  207. }
  208. clickLine.build();
  209. kdTree.fillLines(lines);
  210. }
  211. }
  212. void Game::renderWorld(float lag, Renderer& renderer) const {
  213. if(mode == Mode::AUTO) {
  214. float leftLength = (movedLength - moveSpeed) + moveSpeed * lag;
  215. uint index = 0;
  216. while(leftLength >= cameraPoints[index].distance) {
  217. leftLength -= cameraPoints[index].distance;
  218. index = (index + 1) % cameraPoints.getLength();
  219. }
  220. float t = leftLength / cameraPoints[index].distance;
  221. Vector3 interpolatedPos = pointUntilDistance(leftLength, index, 4000);
  222. uint a = index == 0 ? cameraPoints.getLength() - 1 : index - 1;
  223. uint b = (a + 1) % cameraPoints.getLength();
  224. uint c = (a + 2) % cameraPoints.getLength();
  225. uint d = (a + 3) % cameraPoints.getLength();
  226. renderer.update(interpolatedPos, cameraPoints[b].q.squad(t, cameraPoints[a].q, cameraPoints[c].q, cameraPoints[d].q));
  227. pos = interpolatedPos;
  228. } else if(mode == Mode::PLAYER) {
  229. Vector3 v = lastPos + (pos - lastPos) * lag;
  230. renderer.update(v, lastRotation.slerp(lag, rotation));
  231. }
  232. worldRenderer.render(lag, renderer);
  233. treeData.draw();
  234. }
  235. void Game::renderWorldLines(float lag, Renderer& renderer) const {
  236. (void) lag;
  237. renderer.translateTo(0.0f, 0.0f, 0.0f);
  238. renderer.update();
  239. if(control.keys.kdTree.isDown()) {
  240. GLWrapper::setLineThickness(1.0f);
  241. lines.draw();
  242. }
  243. GLWrapper::setLineThickness(5.0f);
  244. clickLine.draw();
  245. }
  246. void Game::renderTextOverlay(float lag, Renderer& renderer, FontRenderer& fr) const {
  247. (void) lag;
  248. renderer.scale(2.0f).update();
  249. String s;
  250. fr.drawString(10, 10, s.append("FPS: ").append(fps.getUpdatesPerSecond()).append(" TPS: ").append(tps.getUpdatesPerSecond()));
  251. fr.drawString(10, 19, s.clear().append("Speed: ").append(moveSpeed));
  252. Vector3 inter = kdTree.getIntersection();
  253. fr.drawString(10, 29, s.clear().append("Intersection: (").append(inter[0]).append(", ").append(inter[1]).append(", ").append(inter[2]).append(")"));
  254. s.clear();
  255. s += pos;
  256. fr.drawString(10, 38, s);
  257. for(uint i = 0; i < cameraPoints.getLength(); i++) {
  258. s.clear().append(i + 1).append(": ");
  259. s += cameraPoints[i].pos;
  260. fr.drawString(10, i * 9 + 47, s);
  261. }
  262. }
  263. bool Game::isRunning() const {
  264. return true;
  265. }
  266. Vector3 Game::splineTangent(const Vector3& prev, const Vector3& current, const Vector3& next) const {
  267. (void) current;
  268. //Vector3 v(current);
  269. //v.sub(prev).mul(0.5f).addMul(next, 0.5f).addMul(current, -0.5f);
  270. return (next - prev) * 0.5f;
  271. }
  272. Vector3 Game::interpolate(const Vector3& a, const Vector3& b, const Vector3& tanA, const Vector3& tanB, float t) const {
  273. float t2 = t * t;
  274. float t3 = t2 * t;
  275. return a * (2.0f * t3 - 3.0f * t2 + 1.0f) +
  276. b * (-2.0f * t3 + 3.0f * t2) +
  277. tanA * (t3 - 2.0f * t2 + t) +
  278. tanB * (t3 - t2);
  279. }
  280. float Game::distance(uint index, uint splits) const {
  281. Vector3 a;
  282. Vector3 b;
  283. Vector3 tanA;
  284. Vector3 tanB;
  285. getPointsAndTangents(index, a, b, tanA, tanB);
  286. Vector3 currentPos;
  287. Vector3 currentNext = interpolate(a, b, tanA, tanB, 0.0f);
  288. float sum = 0.0f;
  289. for(uint i = 0; i <= splits; i++) {
  290. currentPos = currentNext;
  291. float t = (i + 1.0f) / (splits + 1.0f);
  292. currentNext = interpolate(a, b, tanA, tanB, t);
  293. float l = static_cast<Vector3> (currentPos - currentNext).length();
  294. sum += l;
  295. }
  296. return sum;
  297. }
  298. Vector3 Game::pointUntilDistance(float leftDistance, uint index, uint splits) const {
  299. Vector3 a;
  300. Vector3 b;
  301. Vector3 tanA;
  302. Vector3 tanB;
  303. getPointsAndTangents(index, a, b, tanA, tanB);
  304. Vector3 currentPos;
  305. Vector3 currentNext = interpolate(a, b, tanA, tanB, 0.0f);
  306. float sum = 0.0f;
  307. uint i = 0;
  308. while(leftDistance > sum) {
  309. currentPos = currentNext;
  310. float t = (i + 1.0f) / (splits + 1.0f);
  311. currentNext = interpolate(a, b, tanA, tanB, t);
  312. float l = static_cast<Vector3> (currentPos - currentNext).length();
  313. sum += l;
  314. i++;
  315. }
  316. return currentNext;
  317. }
  318. void Game::getPointsAndTangents(uint index, Vector3& a, Vector3& b, Vector3& tanA, Vector3& tanB) const {
  319. uint prev = index == 0 ? cameraPoints.getLength() - 1 : index - 1;
  320. uint currentA = (prev + 1) % cameraPoints.getLength();
  321. uint currentB = (prev + 2) % cameraPoints.getLength();
  322. uint next = (prev + 3) % cameraPoints.getLength();
  323. a = cameraPoints[currentA].pos;
  324. b = cameraPoints[currentB].pos;
  325. tanA = splineTangent(cameraPoints[prev].pos, a, b);
  326. tanB = splineTangent(a, b, cameraPoints[next].pos);
  327. }
  328. void Game::updateDistances() {
  329. for(uint i = 0; i < cameraPoints.getLength(); i++) {
  330. cameraPoints[i].distance = distance(i, 10000);
  331. }
  332. }
  333. void Game::generateSphere(std::vector<KDTree::Triangle>& data) {
  334. int fieldSize = 8;
  335. int quality = 3;
  336. float radius = 30;
  337. int triangles = fieldSize * quality;
  338. int layers = (2 + fieldSize) * quality;
  339. for(int l = 0; l < layers; l++) {
  340. float high1 = cosf((M_PI * l) / layers);
  341. float high2 = cosf((M_PI * (l + 1)) / layers);
  342. float r1 = sqrtf(1 - high1 * high1) * radius;
  343. float r2 = sqrtf(1 - high2 * high2) * radius;
  344. high1 *= radius;
  345. high2 *= radius;
  346. for(int i = 0; i < triangles; i++) {
  347. float first = 2 * M_PI * i / triangles;
  348. float second = 2 * M_PI * (i + 1) / triangles;
  349. data.push_back(KDTree::Triangle(
  350. Vector3(r2 * cosf(first), high2, r2 * sinf(first)),
  351. Vector3(r1 * cosf(first), high1, r1 * sinf(first)),
  352. Vector3(r1 * cosf(second), high1, r1 * sinf(second))));
  353. data.push_back(KDTree::Triangle(
  354. Vector3(r2 * cosf(first), high2, r2 * sinf(first)),
  355. Vector3(r1 * cosf(second), high1, r1 * sinf(second)),
  356. Vector3(r2 * cosf(second), high2, r2 * sinf(second))));
  357. }
  358. }
  359. }
  360. void Game::generateRandom(std::vector<KDTree::Triangle>& data) {
  361. float radius = 25.0f;
  362. float diff = 5.0f;
  363. Random r(0);
  364. for(int i = 0; i < 10000; i++) {
  365. Vector3 a(r.nextFloat() * radius, r.nextFloat() * radius, r.nextFloat() * radius);
  366. Vector3 b = a + Vector3(r.nextFloat() * diff, r.nextFloat() * diff, r.nextFloat() * diff);
  367. Vector3 c = a + Vector3(r.nextFloat() * diff, r.nextFloat() * diff, r.nextFloat() * diff);
  368. data.push_back(KDTree::Triangle(a, b, c));
  369. }
  370. }