Game.cpp 7.8 KB

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