123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- #include <cmath>
- #include "client/Game.h"
- #include "client/utils/Utils.h"
- #include "rendering/Renderer.h"
- #include "common/utils/String.h"
- #include "common/utils/Random.h"
- #include "math/Quaternion.h"
- Game::Game(const Control& control, const Clock& fps, const Clock& tps, RenderSettings& renderSettings) :
- control(control), fps(fps), tps(tps), renderSettings(renderSettings), world(blockRegistry), worldRenderer(world),
- pointIndex(0), moveSpeed(0.25f), movedLength(0.0f), mode(Mode::AUTO) {
- Random r(0);
- float h = World::WORLD_SIZE * 0.6f;
- float mid = World::WORLD_SIZE * 0.5f;
- float randLength = World::WORLD_SIZE * 0.125f * 0.5f;
- pos.set(0, h, 0);
- lastPos.set(pos);
- rotation = Quaternion(Vector(1, 0, 0), -80);
- lastRotation = rotation;
- Quaternion q(0.0f, 0.0f, 0.0f, 1.0f);
- for(uint i = 0; i < cameraPoints.getCapacity(); i++) {
- Vector offset(mid, h, mid);
- offset.add(Vector(r.nextFloat(randLength), r.nextFloat(randLength), r.nextFloat(randLength)));
- Vector v;
- v.setAngles(i * 360.0f / cameraPoints.getCapacity(), 0.0f).mul(mid * 0.5f).add(offset);
- q.mul(Quaternion(Vector(r.nextFloat() * 360.0f, r.nextFloat() * -90.0f), -5.0f));
- cameraPoints.add({v, q, 0.0f});
- }
- for(uint i = 0; i < cameraPoints.getLength(); i++) {
- cameraPoints[i].distance = distance(i, 20);
- }
-
- Quaternion testQ = Quaternion(0, 0, 0, 1);
- Quaternion rotTest = Quaternion(Vector(1, 0, 0), 5.0f);
-
- testQ.mul(rotTest);
-
- std::cout << "TEST: " << testQ.xyz.getX() << " " << testQ.xyz.getY() << " " << testQ.xyz.getZ() << " " << testQ.w << "\n";
-
- }
- void Game::tick() {
- lastRotation = rotation;
- lastPos = pos;
- if(mode == Mode::PLAYER) {
- Vector right(1.0f, 0.0f, 0.0f);
- Vector up(0.0f, 1.0f, 0.0f);
- Vector back(0.0f, 0.0f, -1.0f);
- Matrix m = rotation.toMatrix();
- right.mul(m);
- up.mul(m);
- back.mul(m);
- const float speed = 1.0f;
- if(control.keys.down.isDown()) {
- pos.addMul(back, speed);
- }
- if(control.keys.up.isDown()) {
- pos.addMul(back, -speed);
- }
- if(control.keys.left.isDown()) {
- pos.addMul(right, -speed);
- }
- if(control.keys.right.isDown()) {
- pos.addMul(right, speed);
- }
- if(control.keys.jump.isDown()) {
- pos.addMul(up, speed);
- }
- if(control.keys.sneak.isDown()) {
- pos.addMul(up, -speed);
- }
- const float rotationSpeed = 5.0f;
- if(control.keys.camLeft.isDown()) {
- rotation.mul(Quaternion(up, rotationSpeed));
- }
- if(control.keys.camRight.isDown()) {
- rotation.mul(Quaternion(up, -rotationSpeed));
- }
- if(control.keys.camUp.isDown()) {
- rotation.mul(Quaternion(right, rotationSpeed));
- }
- if(control.keys.camDown.isDown()) {
- rotation.mul(Quaternion(right, -rotationSpeed));
- }
- } else if(mode == Mode::AUTO) {
- movedLength += moveSpeed;
- }
- if(control.keys.test.isDown()) {
- mode = Mode::PLAYER;
- }
- if(control.keys.test2.isDown()) {
- mode = Mode::AUTO;
- }
- if(control.keys.test4.getDownTime() == 1) {
- renderSettings.shadows = !renderSettings.shadows;
- }
- if(control.keys.test5.getDownTime() == 1) {
- renderSettings.ssao = !renderSettings.ssao;
- }
- }
- void Game::renderWorld(float lag, Renderer& renderer) const {
- if(mode == Mode::AUTO) {
- float leftLength = (movedLength - moveSpeed) + moveSpeed * lag;
- uint index = 0;
- while(leftLength >= cameraPoints[index].distance) {
- leftLength -= cameraPoints[index].distance;
- index = (index + 1) % cameraPoints.getLength();
- }
- float t = leftLength / cameraPoints[index].distance;
- Vector a;
- Vector b;
- Vector tanA;
- Vector tanB;
- getPointsAndTangents(index, a, b, tanA, tanB);
- Vector interpolatedPos = interpolate(a, b, tanA, tanB, t);
- renderer.update(interpolatedPos, cameraPoints[index].q.slerp(t, cameraPoints[(index + 1) % cameraPoints.getLength()].q));
- pos = interpolatedPos;
- } else if(mode == Mode::PLAYER) {
- Vector v(lastPos);
- v.addMul(pos, lag).addMul(lastPos, -lag);
- renderer.update(v, lastRotation.slerp(lag, rotation));
- }
- worldRenderer.render(lag, renderer);
- }
- void Game::renderTextOverlay(float lag, Renderer& renderer, FontRenderer& fr) const {
- (void) lag;
- renderer.scale(2.0f).update();
- String s;
- fr.drawString(10, 10, s.append("FPS: ").append(fps.getUpdatesPerSecond())
- .append(" ").append("%0.8f", renderSettings.testBias).append(" ").append("%0.8f", renderSettings.testRadius));
- fr.drawString(10, 19, s.clear().append("TPS: ").append(tps.getUpdatesPerSecond()));
- s.clear();
- pos.toString(s);
- fr.drawString(10, 28, s);
- for(uint i = 0; i < cameraPoints.getLength(); i++) {
- s.clear().append(i + 1).append(": ");
- cameraPoints[i].pos.toString(s);
- fr.drawString(10, i * 9 + 37, s);
- }
- }
- bool Game::isRunning() const {
- return true;
- }
- Vector Game::splineTangent(const Vector& prev, const Vector& current, const Vector& next) const {
- Vector v(current);
- v.sub(prev).mul(0.5f).addMul(next, 0.5f).addMul(current, -0.5f);
- return v;
- }
- Vector Game::interpolate(const Vector& a, const Vector& b, const Vector& tanA, const Vector& tanB, float t) const {
- float t2 = t * t;
- float t3 = t2 * t;
- Vector v;
- v.addMul(a, 2.0f * t3 - 3.0f * t2 + 1.0f).addMul(b, -2.0f * t3 + 3.0f * t2)
- .addMul(tanA, t3 - 2.0f * t2 + t).addMul(tanB, t3 - t2);
- return v;
- }
- float Game::distance(uint index, uint splits) const {
- Vector a;
- Vector b;
- Vector tanA;
- Vector tanB;
- getPointsAndTangents(index, a, b, tanA, tanB);
- Vector currentPos;
- Vector currentNext = interpolate(a, b, tanA, tanB, 0.0f);
- float sum = 0.0f;
- for(uint i = 0; i <= splits; i++) {
- currentPos = currentNext;
- float t = (i + 1.0f) / (splits + 1.0f);
- currentNext = interpolate(a, b, tanA, tanB, t);
- float l = currentPos.sub(currentNext).length();
- sum += l;
- }
- return sum;
- }
- void Game::getPointsAndTangents(uint index, Vector& a, Vector& b, Vector& tanA, Vector& tanB) const {
- uint prev = index == 0 ? cameraPoints.getLength() - 1 : index - 1;
- uint currentA = (prev + 1) % cameraPoints.getLength();
- uint currentB = (prev + 2) % cameraPoints.getLength();
- uint next = (prev + 3) % cameraPoints.getLength();
- a.set(cameraPoints[currentA].pos);
- b.set(cameraPoints[currentB].pos);
- tanA = splineTangent(cameraPoints[prev].pos, a, b);
- tanB = splineTangent(a, b, cameraPoints[next].pos);
- }
|