|
@@ -1,71 +1,116 @@
|
|
|
|
+#include <cmath>
|
|
|
|
+
|
|
#include "client/Game.h"
|
|
#include "client/Game.h"
|
|
#include "client/utils/Utils.h"
|
|
#include "client/utils/Utils.h"
|
|
#include "rendering/Renderer.h"
|
|
#include "rendering/Renderer.h"
|
|
#include "common/utils/String.h"
|
|
#include "common/utils/String.h"
|
|
|
|
+#include "common/utils/Random.h"
|
|
|
|
|
|
Game::Game(const Control& control, const Camera& camera, Ray& ray, const Clock& fps, const Clock& tps,
|
|
Game::Game(const Control& control, const Camera& camera, Ray& ray, const Clock& fps, const Clock& tps,
|
|
RenderSettings& renderSettings) :
|
|
RenderSettings& renderSettings) :
|
|
-control(control), camera(camera), ray(ray), fps(fps), tps(tps), renderSettings(renderSettings), lengthAngle(20.0f),
|
|
+control(control), camera(camera), ray(ray), fps(fps), tps(tps), renderSettings(renderSettings), lengthAngle(240.0f),
|
|
-widthAngle(35.0f), world(blockRegistry), worldRenderer(world) {
|
|
+widthAngle(20.0f), world(blockRegistry), worldRenderer(world), pointIndex(0), moveSpeed(0.25f), movedLength(0.0f),
|
|
- pos.set(0, 10, 0);
|
|
+mode(Mode::AUTO) {
|
|
-}
|
|
+ Random r(0);
|
|
|
|
+ float h = World::WORLD_SIZE * 0.75f;
|
|
|
|
+ float mid = World::WORLD_SIZE * 0.5f;
|
|
|
|
+ float randLength = World::WORLD_SIZE * 0.125f;
|
|
|
|
+ pos.set(0, h, 0);
|
|
|
|
|
|
-void Game::tick() {
|
|
+ for(uint i = 0; i < cameraPoints.getCapacity(); i++) {
|
|
- const float speed = 0.25f;
|
|
+ Vector offset(mid, h, mid);
|
|
- if(control.keys.down.isDown()) {
|
|
+ offset.add(Vector(r.nextFloat(randLength), r.nextFloat(randLength), r.nextFloat(randLength)));
|
|
- pos.addMul(camera.getFlatBack(), speed);
|
|
+ Vector v;
|
|
- }
|
|
+ v.setAngles(i * 360.0f / cameraPoints.getCapacity(), 0.0f).mul(mid * 0.5f).add(offset);
|
|
- if(control.keys.up.isDown()) {
|
|
+ cameraPoints.add( {v, 0.0f});
|
|
- pos.addMul(camera.getFlatBack(), -speed);
|
|
|
|
- }
|
|
|
|
- if(control.keys.left.isDown()) {
|
|
|
|
- pos.addMul(camera.getFlatRight(), -speed);
|
|
|
|
}
|
|
}
|
|
- if(control.keys.right.isDown()) {
|
|
+ for(uint i = 0; i < cameraPoints.getLength(); i++) {
|
|
- pos.addMul(camera.getFlatRight(), speed);
|
|
+ cameraPoints[i].distance = distance(i, 20);
|
|
- }
|
|
|
|
- if(control.keys.jump.isDown()) {
|
|
|
|
- pos.addMul(camera.getFlatUp(), speed);
|
|
|
|
- }
|
|
|
|
- if(control.keys.sneak.isDown()) {
|
|
|
|
- pos.addMul(camera.getFlatUp(), -speed);
|
|
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- const float rotation = 5.0f;
|
|
+void Game::tick() {
|
|
- if(control.keys.camLeft.isDown()) {
|
|
+ if(mode == Mode::PLAYER) {
|
|
- lengthAngle += rotation;
|
|
+ const float speed = 0.25f;
|
|
- }
|
|
+ if(control.keys.down.isDown()) {
|
|
- if(control.keys.camRight.isDown()) {
|
|
+ pos.addMul(camera.getFlatBack(), speed);
|
|
- lengthAngle -= rotation;
|
|
+ }
|
|
- }
|
|
+ if(control.keys.up.isDown()) {
|
|
- if(control.keys.camUp.isDown() && widthAngle - rotation > -90.0f) {
|
|
+ pos.addMul(camera.getFlatBack(), -speed);
|
|
- widthAngle -= rotation;
|
|
+ }
|
|
- }
|
|
+ if(control.keys.left.isDown()) {
|
|
- if(control.keys.camDown.isDown() && widthAngle + rotation < 90.0f) {
|
|
+ pos.addMul(camera.getFlatRight(), -speed);
|
|
- widthAngle += rotation;
|
|
+ }
|
|
- }
|
|
+ if(control.keys.right.isDown()) {
|
|
|
|
+ pos.addMul(camera.getFlatRight(), speed);
|
|
|
|
+ }
|
|
|
|
+ if(control.keys.jump.isDown()) {
|
|
|
|
+ pos.addMul(camera.getFlatUp(), speed);
|
|
|
|
+ }
|
|
|
|
+ if(control.keys.sneak.isDown()) {
|
|
|
|
+ pos.addMul(camera.getFlatUp(), -speed);
|
|
|
|
+ }
|
|
|
|
|
|
- ray.store();
|
|
+ const float rotation = 5.0f;
|
|
- ray.set(pos, lengthAngle, widthAngle);
|
|
+ if(control.keys.camLeft.isDown()) {
|
|
|
|
+ lengthAngle += rotation;
|
|
|
|
+ }
|
|
|
|
+ if(control.keys.camRight.isDown()) {
|
|
|
|
+ lengthAngle -= rotation;
|
|
|
|
+ }
|
|
|
|
+ if(control.keys.camUp.isDown() && widthAngle - rotation > -90.0f) {
|
|
|
|
+ widthAngle -= rotation;
|
|
|
|
+ }
|
|
|
|
+ if(control.keys.camDown.isDown() && widthAngle + rotation < 90.0f) {
|
|
|
|
+ widthAngle += rotation;
|
|
|
|
+ }
|
|
|
|
|
|
- if(control.keys.test5.getDownTime() == 1) {
|
|
+ ray.store();
|
|
- renderSettings.ssao = !renderSettings.ssao;
|
|
+ ray.set(pos, lengthAngle, widthAngle);
|
|
|
|
+ } else if(mode == Mode::AUTO) {
|
|
|
|
+ movedLength += moveSpeed;
|
|
}
|
|
}
|
|
-
|
|
+
|
|
- renderSettings.testRadius /= 0.95f;
|
|
+ if(control.keys.test.getDownTime() == 1) {
|
|
|
|
+ mode = Mode::PLAYER;
|
|
}
|
|
}
|
|
- if(control.keys.test2.isDown()) {
|
|
+ if(control.keys.test2.getDownTime() == 1) {
|
|
- renderSettings.testRadius *= 0.95f;
|
|
+ mode = Mode::AUTO;
|
|
}
|
|
}
|
|
- if(control.keys.test3.isDown()) {
|
|
+ if(control.keys.test5.getDownTime() == 1) {
|
|
- renderSettings.testBias /= 0.95f;
|
|
+ renderSettings.ssao = !renderSettings.ssao;
|
|
}
|
|
}
|
|
- if(control.keys.test4.isDown()) {
|
|
|
|
- renderSettings.testBias *= 0.95f;
|
|
|
|
- }*/
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void Game::renderWorld(float lag, Renderer& renderer) const {
|
|
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();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ uint prev = index;
|
|
|
|
+ float t = leftLength / cameraPoints[index].distance;
|
|
|
|
+ if(prev == 0) {
|
|
|
|
+ prev = cameraPoints.getLength() - 1;
|
|
|
|
+ } else {
|
|
|
|
+ prev = (prev - 1) % cameraPoints.getLength();
|
|
|
|
+ }
|
|
|
|
+ uint currentA = (prev + 1) % cameraPoints.getLength();
|
|
|
|
+ uint currentB = (prev + 2) % cameraPoints.getLength();
|
|
|
|
+ uint next = (prev + 3) % cameraPoints.getLength();
|
|
|
|
+
|
|
|
|
+ Vector tangentA = splineTangent(cameraPoints[prev].pos, cameraPoints[currentA].pos, cameraPoints[currentB].pos);
|
|
|
|
+ Vector tangentB = splineTangent(cameraPoints[currentA].pos, cameraPoints[currentB].pos, cameraPoints[next].pos);
|
|
|
|
+
|
|
|
|
+ Vector interpolatedPos = interpolate(cameraPoints[currentA].pos, cameraPoints[currentB].pos, tangentA, tangentB, t);
|
|
|
|
+
|
|
|
|
+ pos.set(interpolatedPos);
|
|
|
|
+ ray.set(interpolatedPos, lengthAngle, widthAngle);
|
|
|
|
+ ray.store();
|
|
|
|
+ }
|
|
worldRenderer.render(lag, renderer);
|
|
worldRenderer.render(lag, renderer);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -74,18 +119,55 @@ void Game::renderTextOverlay(float lag, Renderer& renderer, FontRenderer& fr) co
|
|
renderer.scale(1.0f).update();
|
|
renderer.scale(1.0f).update();
|
|
|
|
|
|
String s;
|
|
String s;
|
|
- s.append("FPS: ").append(fps.getUpdatesPerSecond());
|
|
+ fr.drawString(10, 10, s.append("FPS: ").append(fps.getUpdatesPerSecond()));
|
|
- fr.drawString(10, 10, s);
|
|
+ fr.drawString(10, 19, s.clear().append("TPS: ").append(tps.getUpdatesPerSecond()));
|
|
- s.clear().append("TPS: ").append(tps.getUpdatesPerSecond());
|
|
+ s.clear();
|
|
- fr.drawString(10, 20, s);
|
|
+ pos.toString(s);
|
|
- s.clear().append("Bias: ").append("%.6f", renderSettings.testBias);
|
|
+ fr.drawString(10, 28, s);
|
|
- fr.drawString(10, 30, s);
|
|
+ for(uint i = 0; i < cameraPoints.getLength(); i++) {
|
|
- s.clear().append("Radius: ").append("%.6f", renderSettings.testRadius);
|
|
+ s.clear().append(i + 1).append(": ");
|
|
- fr.drawString(10, 40, s);
|
|
+ cameraPoints[i].pos.toString(s);
|
|
- s.clear().append("Shadows: ").append(renderSettings.shadows);
|
|
+ fr.drawString(10, i * 9 + 37, s);
|
|
- fr.drawString(10, 50, s);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
bool Game::isRunning() const {
|
|
bool Game::isRunning() const {
|
|
return true;
|
|
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 {
|
|
|
|
+ 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();
|
|
|
|
+
|
|
|
|
+ Vector tangentA = splineTangent(cameraPoints[prev].pos, cameraPoints[currentA].pos, cameraPoints[currentB].pos);
|
|
|
|
+ Vector tangentB = splineTangent(cameraPoints[currentA].pos, cameraPoints[currentB].pos, cameraPoints[next].pos);
|
|
|
|
+
|
|
|
|
+ Vector currentPos;
|
|
|
|
+ Vector currentNext = interpolate(cameraPoints[currentA].pos, cameraPoints[currentB].pos, tangentA, tangentB, 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(cameraPoints[currentA].pos, cameraPoints[currentB].pos, tangentA, tangentB, t);
|
|
|
|
+ sum += currentPos.sub(currentNext).length();
|
|
|
|
+ }
|
|
|
|
+ return sum;
|
|
|
|
+}
|