Game.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #include <cmath>
  2. #include "client/Game.h"
  3. #include "client/utils/Utils.h"
  4. #include "rendering/Renderer.h"
  5. #include "common/utils/String.h"
  6. #include "common/utils/Random.h"
  7. #include "math/Quaternion.h"
  8. Game::Game(const Control& control, const Clock& fps, const Clock& tps, RenderSettings& renderSettings) :
  9. control(control), fps(fps), tps(tps), renderSettings(renderSettings), world(blockRegistry), worldRenderer(world),
  10. pointIndex(0), moveSpeed(0.125f), movedLength(0.0f), mode(Mode::AUTO) {
  11. Random r(0);
  12. float h = World::WORLD_SIZE * 0.6f;
  13. float mid = World::WORLD_SIZE * 0.5f;
  14. float randLength = World::WORLD_SIZE * 0.125f * 0.25f;
  15. pos.set(0, h, 0);
  16. lastPos = pos;
  17. rotation = Quaternion(Vector3(1, 0, 0), -80);
  18. lastRotation = rotation;
  19. Quaternion q;
  20. for(uint i = 0; i < cameraPoints.getCapacity(); i++) {
  21. Vector3 offset(mid, h, mid);
  22. offset += Vector3(r.nextFloat(randLength), r.nextFloat(randLength), r.nextFloat(randLength));
  23. Vector3 v(i * 360.0f / cameraPoints.getCapacity(), 0.0f);
  24. v *= mid * 0.5f;
  25. v += offset;
  26. q.mul(Quaternion(Vector3(r.nextFloat() * 360.0f, r.nextFloat() * -90.0f), -10.0f));
  27. cameraPoints.add({v, q, 0.0f});
  28. }
  29. updateDistances();
  30. }
  31. void Game::tick() {
  32. lastRotation = rotation;
  33. lastPos = pos;
  34. if(mode == Mode::PLAYER) {
  35. Matrix m = rotation.toMatrix();
  36. Vector3 right = m * Vector3(1.0f, 0.0f, 0.0f);
  37. Vector3 up = m * Vector3(0.0f, 1.0f, 0.0f);
  38. Vector3 back = m * Vector3(0.0f, 0.0f, -1.0f);
  39. const float speed = 1.0f;
  40. if(control.keys.down.isDown()) {
  41. pos += back * speed;
  42. }
  43. if(control.keys.up.isDown()) {
  44. pos -= back * speed;
  45. }
  46. if(control.keys.left.isDown()) {
  47. pos -= right * speed;
  48. }
  49. if(control.keys.right.isDown()) {
  50. pos += right * speed;
  51. }
  52. if(control.keys.jump.isDown()) {
  53. pos += up * speed;
  54. }
  55. if(control.keys.sneak.isDown()) {
  56. pos -= up * speed;
  57. }
  58. const float rotationSpeed = 5.0f;
  59. if(control.keys.camLeft.isDown()) {
  60. rotation.mul(Quaternion(up, rotationSpeed));
  61. }
  62. if(control.keys.camRight.isDown()) {
  63. rotation.mul(Quaternion(up, -rotationSpeed));
  64. }
  65. if(control.keys.camUp.isDown()) {
  66. rotation.mul(Quaternion(right, rotationSpeed));
  67. }
  68. if(control.keys.camDown.isDown()) {
  69. rotation.mul(Quaternion(right, -rotationSpeed));
  70. }
  71. if(control.keys.test3.getDownTime() == 1) {
  72. cameraPoints.add({pos, rotation, 0.0f});
  73. }
  74. } else if(mode == Mode::AUTO) {
  75. movedLength += moveSpeed;
  76. if(control.keys.camUp.isDown()) {
  77. moveSpeed += 0.0125f;
  78. if(moveSpeed > 1.0f) {
  79. moveSpeed = 1.0f;
  80. }
  81. }
  82. if(control.keys.camDown.isDown()) {
  83. moveSpeed -= 0.0125f;
  84. if(moveSpeed < 0.0f) {
  85. moveSpeed = 0.0f;
  86. }
  87. }
  88. if(control.keys.test3.isDown()) {
  89. mode = Mode::PLAYER;
  90. cameraPoints.clear();
  91. }
  92. }
  93. if(control.keys.test.isDown()) {
  94. mode = Mode::PLAYER;
  95. }
  96. if(control.keys.test2.isDown() && cameraPoints.getLength() >= 3) {
  97. mode = Mode::AUTO;
  98. movedLength = 0.0f;
  99. updateDistances();
  100. }
  101. if(control.keys.test4.getDownTime() == 1) {
  102. renderSettings.shadows = !renderSettings.shadows;
  103. }
  104. if(control.keys.test5.getDownTime() == 1) {
  105. renderSettings.ssao = !renderSettings.ssao;
  106. }
  107. if(control.keys.test6.getDownTime() == 1) {
  108. renderSettings.bump += 0.05f;
  109. if(renderSettings.bump > 1.0f) {
  110. renderSettings.bump = 0.0f;
  111. }
  112. }
  113. if(control.keys.factor.getDownTime() == 1) {
  114. if(renderSettings.factor == 1) {
  115. renderSettings.factor = 2;
  116. } else if(renderSettings.factor == 2) {
  117. renderSettings.factor = 3;
  118. } else {
  119. renderSettings.factor = 1;
  120. }
  121. renderSettings.dirtyFactor = true;
  122. }
  123. }
  124. void Game::renderWorld(float lag, Renderer& renderer) const {
  125. if(mode == Mode::AUTO) {
  126. float leftLength = (movedLength - moveSpeed) + moveSpeed * lag;
  127. uint index = 0;
  128. while(leftLength >= cameraPoints[index].distance) {
  129. leftLength -= cameraPoints[index].distance;
  130. index = (index + 1) % cameraPoints.getLength();
  131. }
  132. float t = leftLength / cameraPoints[index].distance;
  133. Vector3 interpolatedPos = pointUntilDistance(leftLength, index, 4000);
  134. uint a = index == 0 ? cameraPoints.getLength() - 1 : index - 1;
  135. uint b = (a + 1) % cameraPoints.getLength();
  136. uint c = (a + 2) % cameraPoints.getLength();
  137. uint d = (a + 3) % cameraPoints.getLength();
  138. renderer.update(interpolatedPos, cameraPoints[b].q.squad(t, cameraPoints[a].q, cameraPoints[c].q, cameraPoints[d].q));
  139. pos = interpolatedPos;
  140. } else if(mode == Mode::PLAYER) {
  141. Vector3 v = lastPos + (pos - lastPos) * lag;
  142. renderer.update(v, lastRotation.slerp(lag, rotation));
  143. }
  144. worldRenderer.render(lag, renderer);
  145. }
  146. void Game::renderTextOverlay(float lag, Renderer& renderer, FontRenderer& fr) const {
  147. (void) lag;
  148. renderer.scale(2.0f).update();
  149. String s;
  150. fr.drawString(10, 10, s.append("FPS: ").append(fps.getUpdatesPerSecond()).append(" TPS: ").append(tps.getUpdatesPerSecond()));
  151. fr.drawString(10, 19, s.clear().append("Speed: ").append(moveSpeed));
  152. s.clear();
  153. s += pos;
  154. fr.drawString(10, 28, s);
  155. for(uint i = 0; i < cameraPoints.getLength(); i++) {
  156. s.clear().append(i + 1).append(": ");
  157. s += cameraPoints[i].pos;
  158. fr.drawString(10, i * 9 + 37, s);
  159. }
  160. }
  161. bool Game::isRunning() const {
  162. return true;
  163. }
  164. Vector3 Game::splineTangent(const Vector3& prev, const Vector3& current, const Vector3& next) const {
  165. (void) current;
  166. //Vector3 v(current);
  167. //v.sub(prev).mul(0.5f).addMul(next, 0.5f).addMul(current, -0.5f);
  168. return (next - prev) * 0.5f;
  169. }
  170. Vector3 Game::interpolate(const Vector3& a, const Vector3& b, const Vector3& tanA, const Vector3& tanB, float t) const {
  171. float t2 = t * t;
  172. float t3 = t2 * t;
  173. return a * (2.0f * t3 - 3.0f * t2 + 1.0f) +
  174. b * (-2.0f * t3 + 3.0f * t2) +
  175. tanA * (t3 - 2.0f * t2 + t) +
  176. tanB * (t3 - t2);
  177. }
  178. float Game::distance(uint index, uint splits) const {
  179. Vector3 a;
  180. Vector3 b;
  181. Vector3 tanA;
  182. Vector3 tanB;
  183. getPointsAndTangents(index, a, b, tanA, tanB);
  184. Vector3 currentPos;
  185. Vector3 currentNext = interpolate(a, b, tanA, tanB, 0.0f);
  186. float sum = 0.0f;
  187. for(uint i = 0; i <= splits; i++) {
  188. currentPos = currentNext;
  189. float t = (i + 1.0f) / (splits + 1.0f);
  190. currentNext = interpolate(a, b, tanA, tanB, t);
  191. float l = static_cast<Vector3> (currentPos - currentNext).length();
  192. sum += l;
  193. }
  194. return sum;
  195. }
  196. Vector3 Game::pointUntilDistance(float leftDistance, uint index, uint splits) const {
  197. Vector3 a;
  198. Vector3 b;
  199. Vector3 tanA;
  200. Vector3 tanB;
  201. getPointsAndTangents(index, a, b, tanA, tanB);
  202. Vector3 currentPos;
  203. Vector3 currentNext = interpolate(a, b, tanA, tanB, 0.0f);
  204. float sum = 0.0f;
  205. uint i = 0;
  206. while(leftDistance > sum) {
  207. currentPos = currentNext;
  208. float t = (i + 1.0f) / (splits + 1.0f);
  209. currentNext = interpolate(a, b, tanA, tanB, t);
  210. float l = static_cast<Vector3> (currentPos - currentNext).length();
  211. sum += l;
  212. i++;
  213. }
  214. return currentNext;
  215. }
  216. void Game::getPointsAndTangents(uint index, Vector3& a, Vector3& b, Vector3& tanA, Vector3& tanB) const {
  217. uint prev = index == 0 ? cameraPoints.getLength() - 1 : index - 1;
  218. uint currentA = (prev + 1) % cameraPoints.getLength();
  219. uint currentB = (prev + 2) % cameraPoints.getLength();
  220. uint next = (prev + 3) % cameraPoints.getLength();
  221. a = cameraPoints[currentA].pos;
  222. b = cameraPoints[currentB].pos;
  223. tanA = splineTangent(cameraPoints[prev].pos, a, b);
  224. tanB = splineTangent(a, b, cameraPoints[next].pos);
  225. }
  226. void Game::updateDistances() {
  227. for(uint i = 0; i < cameraPoints.getLength(); i++) {
  228. cameraPoints[i].distance = distance(i, 10000);
  229. }
  230. }