|
@@ -3,433 +3,75 @@
|
|
|
#include <fstream>
|
|
|
|
|
|
#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"
|
|
|
+#include "gaming-core/math/Quaternion.h"
|
|
|
+#include "gaming-core/utils/Utils.h"
|
|
|
#include "rendering/wrapper/GLWrapper.h"
|
|
|
#include "rendering/wrapper/GLFWWrapper.h"
|
|
|
|
|
|
-static float readFloat(std::ifstream& in) {
|
|
|
- float f;
|
|
|
- in >> f;
|
|
|
- in.get();
|
|
|
- return f;
|
|
|
-}
|
|
|
-
|
|
|
-static Vector3 readVector3(std::ifstream& in) {
|
|
|
- float x = readFloat(in);
|
|
|
- float y = readFloat(in);
|
|
|
- float z = readFloat(in);
|
|
|
- return Vector3(x, y, z);
|
|
|
-}
|
|
|
-
|
|
|
-static Vector2 readVector2(std::ifstream& in) {
|
|
|
- float x = readFloat(in);
|
|
|
- float y = readFloat(in);
|
|
|
- return Vector2(x, y);
|
|
|
-}
|
|
|
-
|
|
|
-Game::Game(const Control& control, const Clock& fps, const Clock& tps, RenderSettings& renderSettings,
|
|
|
- const WindowSize& size, const char* file) :
|
|
|
-control(control), fps(fps), tps(tps), renderSettings(renderSettings), size(size), world(blockRegistry),
|
|
|
-worldRenderer(world), pointIndex(0), moveSpeed(0.125f), 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.25f;
|
|
|
- pos.set(0, h, 0);
|
|
|
- lastPos = pos;
|
|
|
-
|
|
|
- rotation = Quaternion(Vector3(1, 0, 0), -80);
|
|
|
- lastRotation = rotation;
|
|
|
-
|
|
|
- Quaternion q;
|
|
|
- for(uint i = 0; i < cameraPoints.getCapacity(); i++) {
|
|
|
- Vector3 offset(mid, h, mid);
|
|
|
- offset += Vector3(r.nextFloat(randLength), r.nextFloat(randLength), r.nextFloat(randLength));
|
|
|
- Vector3 v(i * 360.0f / cameraPoints.getCapacity(), 0.0f);
|
|
|
- v *= mid * 0.5f;
|
|
|
- v += offset;
|
|
|
-
|
|
|
- q.mul(Quaternion(Vector3(r.nextFloat() * 360.0f, r.nextFloat() * -90.0f), -10.0f));
|
|
|
- cameraPoints.add({v, q, 0.0f});
|
|
|
- }
|
|
|
- updateDistances();
|
|
|
-
|
|
|
- std::vector<KDTree::Triangle> data;
|
|
|
-
|
|
|
- (void) readFloat;
|
|
|
- (void) file;
|
|
|
-
|
|
|
- std::ifstream in;
|
|
|
- in.open(file);
|
|
|
- if(in.good()) {
|
|
|
- while(true) {
|
|
|
- Vector3 a = readVector3(in);
|
|
|
- Vector2 ta = readVector2(in);
|
|
|
-
|
|
|
- Vector3 b = readVector3(in);
|
|
|
- Vector2 tb = readVector2(in);
|
|
|
-
|
|
|
- Vector3 c = readVector3(in);
|
|
|
- Vector2 tc = readVector2(in);
|
|
|
-
|
|
|
- if(in.eof()) {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- data.push_back(KDTree::Triangle(a, b, c));
|
|
|
- treeData.add(Triangle(Vertex(a, ta), Vertex(b, tb), Vertex(c, tc)));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- treeData.add(Triangle(
|
|
|
- Vertex(t[0], Vector2(8.0f / 16.0f, 0.0f)),
|
|
|
- Vertex(t[1], Vector2(9.0f / 16.0f, 0.0f)),
|
|
|
- Vertex(t[2], Vector2(9.0f / 16.0f, 1.0f / 16.0f))
|
|
|
- ));
|
|
|
- }*/
|
|
|
- treeData.build();
|
|
|
-
|
|
|
- u64 time = GLFWWrapper::getTimeNanos();
|
|
|
- kdTree.build(data);
|
|
|
- time = GLFWWrapper::getTimeNanos() - time;
|
|
|
- std::cout << "KD-Tree-Build-Time: " << time << "ns for " << data.size() << " triangles\n";
|
|
|
- kdTree.fillLines(lines);
|
|
|
+Game::Game(const Control& control, const Clock& fps, const Clock& tps, RenderSettings& settings, const Size& size) :
|
|
|
+control(control), fps(fps), tps(tps), renderSettings(settings), size(size), world(blockRegistry), worldRenderer(world) {
|
|
|
+ pos = Vector3(16.0f, 24.0f, 0.0f);
|
|
|
}
|
|
|
|
|
|
void Game::tick() {
|
|
|
lastRotation = rotation;
|
|
|
lastPos = pos;
|
|
|
|
|
|
- Matrix m = rotation.toMatrix();
|
|
|
- Vector3 right = m * Vector3(1.0f, 0.0f, 0.0f);
|
|
|
- Vector3 up = m * Vector3(0.0f, 1.0f, 0.0f);
|
|
|
- Vector3 back = m * Vector3(0.0f, 0.0f, -1.0f);
|
|
|
-
|
|
|
- if(mode == Mode::PLAYER) {
|
|
|
- const float speed = 1.0f;
|
|
|
- if(control.keys.down.isDown()) {
|
|
|
- pos += back * speed;
|
|
|
- }
|
|
|
- if(control.keys.up.isDown()) {
|
|
|
- pos -= back * speed;
|
|
|
- }
|
|
|
- if(control.keys.left.isDown()) {
|
|
|
- pos -= right * speed;
|
|
|
- }
|
|
|
- if(control.keys.right.isDown()) {
|
|
|
- pos += right * speed;
|
|
|
- }
|
|
|
- if(control.keys.jump.isDown()) {
|
|
|
- pos += up * speed;
|
|
|
- }
|
|
|
- if(control.keys.sneak.isDown()) {
|
|
|
- pos -= 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));
|
|
|
- }
|
|
|
+ Vector3 right = rotation * Vector3(1.0f, 0.0f, 0.0f);
|
|
|
+ Vector3 up = rotation * Vector3(0.0f, 1.0f, 0.0f);
|
|
|
+ Vector3 back = rotation * Vector3(0.0f, 0.0f, -1.0f);
|
|
|
|
|
|
- if(control.keys.test3.getDownTime() == 1) {
|
|
|
- cameraPoints.add({pos, rotation, 0.0f});
|
|
|
- }
|
|
|
- } else if(mode == Mode::AUTO) {
|
|
|
- movedLength += moveSpeed;
|
|
|
-
|
|
|
- if(control.keys.camUp.isDown()) {
|
|
|
- moveSpeed += 0.0125f;
|
|
|
- if(moveSpeed > 1.0f) {
|
|
|
- moveSpeed = 1.0f;
|
|
|
- }
|
|
|
- }
|
|
|
- if(control.keys.camDown.isDown()) {
|
|
|
- moveSpeed -= 0.0125f;
|
|
|
- if(moveSpeed < 0.0f) {
|
|
|
- moveSpeed = 0.0f;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(control.keys.test3.isDown()) {
|
|
|
- mode = Mode::PLAYER;
|
|
|
- cameraPoints.clear();
|
|
|
- }
|
|
|
+ const float speed = 1.0f;
|
|
|
+ if(control.keys.down.isDown()) {
|
|
|
+ pos += back * speed;
|
|
|
}
|
|
|
-
|
|
|
- if(control.keys.test.isDown()) {
|
|
|
- mode = Mode::PLAYER;
|
|
|
+ if(control.keys.up.isDown()) {
|
|
|
+ pos -= back * speed;
|
|
|
}
|
|
|
- if(control.keys.test2.isDown() && cameraPoints.getLength() >= 3) {
|
|
|
- mode = Mode::AUTO;
|
|
|
- movedLength = 0.0f;
|
|
|
- updateDistances();
|
|
|
+ if(control.keys.left.isDown()) {
|
|
|
+ pos -= right * speed;
|
|
|
}
|
|
|
- if(control.keys.test4.getDownTime() == 1) {
|
|
|
- renderSettings.shadows = !renderSettings.shadows;
|
|
|
+ if(control.keys.right.isDown()) {
|
|
|
+ pos += right * speed;
|
|
|
}
|
|
|
- if(control.keys.test5.getDownTime() == 1) {
|
|
|
- renderSettings.ssao = !renderSettings.ssao;
|
|
|
+ if(control.keys.jump.isDown()) {
|
|
|
+ pos += up * speed;
|
|
|
}
|
|
|
- if(control.keys.test6.getDownTime() == 1) {
|
|
|
- renderSettings.bump += 0.05f;
|
|
|
- if(renderSettings.bump > 1.0f) {
|
|
|
- renderSettings.bump = 0.0f;
|
|
|
- }
|
|
|
+ if(control.keys.sneak.isDown()) {
|
|
|
+ pos -= up * speed;
|
|
|
}
|
|
|
- if(control.keys.factor.getDownTime() == 1) {
|
|
|
- if(renderSettings.factor == 1) {
|
|
|
- renderSettings.factor = 2;
|
|
|
- } else if(renderSettings.factor == 2) {
|
|
|
- renderSettings.factor = 3;
|
|
|
- } else {
|
|
|
- renderSettings.factor = 1;
|
|
|
- }
|
|
|
- renderSettings.dirtyFactor = true;
|
|
|
- }
|
|
|
-
|
|
|
- if(control.buttons.primary.getDownTime() == 1) {
|
|
|
- float hWidth = size.width * 0.5f;
|
|
|
- float hHeight = size.height * 0.5f;
|
|
|
-
|
|
|
- float x = (control.buttons.getX() - hWidth) / hWidth;
|
|
|
- float y = -(control.buttons.getY() - hHeight) / hHeight;
|
|
|
-
|
|
|
- float aspect = hWidth / hHeight;
|
|
|
- float tan = tanf((0.5f * 60.0f) * M_PI / 180.0f);
|
|
|
- float q = 1.0f / tan;
|
|
|
-
|
|
|
- Vector3 direction(x / (q / aspect), y / q, 1.0f);
|
|
|
- direction.normalize();
|
|
|
- direction = m * direction;
|
|
|
|
|
|
- clickLine.clear();
|
|
|
- clickLine.add(pos, pos + direction * 100.0f, 0xFF00FF);
|
|
|
-
|
|
|
- u64 time = GLFWWrapper::getTimeNanos();
|
|
|
- bool check = kdTree.findIntersection(pos, direction);
|
|
|
- time = GLFWWrapper::getTimeNanos() - time;
|
|
|
- std::cout << "Intersection-Time: " << time << "ns\n";
|
|
|
- if(check) {
|
|
|
- KDTree::Triangle t = kdTree.getIntersectedTriangle();
|
|
|
-
|
|
|
- clickLine.add(t[0], t[1], 0xFFFF00);
|
|
|
- clickLine.add(t[1], t[2], 0xFFFF00);
|
|
|
- clickLine.add(t[2], t[0], 0xFFFF00);
|
|
|
-
|
|
|
- Vector3 hit = kdTree.getIntersection();
|
|
|
- float diff = 0.2f;
|
|
|
-
|
|
|
- clickLine.add(hit - Vector3(diff, 0.0f, 0.0f), hit + Vector3(diff, 0.0f, 0.0f), 0x00FF00);
|
|
|
- clickLine.add(hit - Vector3(0.0f, diff, 0.0f), hit + Vector3(0.0f, diff, 0.0f), 0x00FF00);
|
|
|
- clickLine.add(hit - Vector3(0.0f, 0.0f, diff), hit + Vector3(0.0f, 0.0f, diff), 0x00FF00);
|
|
|
- }
|
|
|
-
|
|
|
- clickLine.build();
|
|
|
-
|
|
|
- kdTree.fillLines(lines);
|
|
|
+ const float rotationSpeed = 5.0f;
|
|
|
+ if(control.keys.camLeft.isDown()) {
|
|
|
+ rotation = Quaternion(up, -rotationSpeed) * rotation;
|
|
|
+ }
|
|
|
+ if(control.keys.camRight.isDown()) {
|
|
|
+ rotation = Quaternion(up, rotationSpeed) * rotation;
|
|
|
+ }
|
|
|
+ if(control.keys.camUp.isDown()) {
|
|
|
+ rotation = Quaternion(right, -rotationSpeed) * rotation;
|
|
|
+ }
|
|
|
+ if(control.keys.camDown.isDown()) {
|
|
|
+ rotation = Quaternion(right, rotationSpeed) * rotation;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
- Vector3 interpolatedPos = pointUntilDistance(leftLength, index, 4000);
|
|
|
-
|
|
|
- uint a = index == 0 ? cameraPoints.getLength() - 1 : index - 1;
|
|
|
- uint b = (a + 1) % cameraPoints.getLength();
|
|
|
- uint c = (a + 2) % cameraPoints.getLength();
|
|
|
- uint d = (a + 3) % cameraPoints.getLength();
|
|
|
-
|
|
|
- renderer.update(interpolatedPos, cameraPoints[b].q.squad(t, cameraPoints[a].q, cameraPoints[c].q, cameraPoints[d].q));
|
|
|
- pos = interpolatedPos;
|
|
|
- } else if(mode == Mode::PLAYER) {
|
|
|
- Vector3 v = lastPos + (pos - lastPos) * lag;
|
|
|
- renderer.update(v, lastRotation.slerp(lag, rotation));
|
|
|
- }
|
|
|
+ renderer.update(Utils::interpolate(lastPos, pos, lag), lastRotation.lerp(lag, rotation));
|
|
|
worldRenderer.render(lag, renderer);
|
|
|
- treeData.draw();
|
|
|
-}
|
|
|
-
|
|
|
-void Game::renderWorldLines(float lag, Renderer& renderer) const {
|
|
|
- (void) lag;
|
|
|
- renderer.translateTo(0.0f, 0.0f, 0.0f);
|
|
|
- renderer.update();
|
|
|
- if(control.keys.kdTree.isDown()) {
|
|
|
- GLWrapper::setLineThickness(1.0f);
|
|
|
- lines.draw();
|
|
|
- }
|
|
|
- GLWrapper::setLineThickness(5.0f);
|
|
|
- clickLine.draw();
|
|
|
}
|
|
|
|
|
|
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(" TPS: ").append(tps.getUpdatesPerSecond()));
|
|
|
- fr.drawString(10, 19, s.clear().append("Speed: ").append(moveSpeed));
|
|
|
- Vector3 inter = kdTree.getIntersection();
|
|
|
- fr.drawString(10, 29, s.clear().append("Intersection: (").append(inter[0]).append(", ").append(inter[1]).append(", ").append(inter[2]).append(")"));
|
|
|
- s.clear();
|
|
|
- s += pos;
|
|
|
- fr.drawString(10, 38, s);
|
|
|
- for(uint i = 0; i < cameraPoints.getLength(); i++) {
|
|
|
- s.clear().append(i + 1).append(": ");
|
|
|
- s += cameraPoints[i].pos;
|
|
|
- fr.drawString(10, i * 9 + 47, s);
|
|
|
- }
|
|
|
+ StringBuffer<100> s;
|
|
|
+ s.append("FPS: ").append(fps.getUpdatesPerSecond()).append(" TPS: ").append(tps.getUpdatesPerSecond());
|
|
|
+ fr.drawString(10, 10, s);
|
|
|
}
|
|
|
|
|
|
bool Game::isRunning() const {
|
|
|
return true;
|
|
|
-}
|
|
|
-
|
|
|
-Vector3 Game::splineTangent(const Vector3& prev, const Vector3& current, const Vector3& next) const {
|
|
|
- (void) current;
|
|
|
-
|
|
|
-
|
|
|
- return (next - prev) * 0.5f;
|
|
|
-}
|
|
|
-
|
|
|
-Vector3 Game::interpolate(const Vector3& a, const Vector3& b, const Vector3& tanA, const Vector3& tanB, float t) const {
|
|
|
- float t2 = t * t;
|
|
|
- float t3 = t2 * t;
|
|
|
- return a * (2.0f * t3 - 3.0f * t2 + 1.0f) +
|
|
|
- b * (-2.0f * t3 + 3.0f * t2) +
|
|
|
- tanA * (t3 - 2.0f * t2 + t) +
|
|
|
- tanB * (t3 - t2);
|
|
|
-}
|
|
|
-
|
|
|
-float Game::distance(uint index, uint splits) const {
|
|
|
- Vector3 a;
|
|
|
- Vector3 b;
|
|
|
- Vector3 tanA;
|
|
|
- Vector3 tanB;
|
|
|
- getPointsAndTangents(index, a, b, tanA, tanB);
|
|
|
-
|
|
|
- Vector3 currentPos;
|
|
|
- Vector3 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 = static_cast<Vector3> (currentPos - currentNext).length();
|
|
|
- sum += l;
|
|
|
- }
|
|
|
- return sum;
|
|
|
-}
|
|
|
-
|
|
|
-Vector3 Game::pointUntilDistance(float leftDistance, uint index, uint splits) const {
|
|
|
- Vector3 a;
|
|
|
- Vector3 b;
|
|
|
- Vector3 tanA;
|
|
|
- Vector3 tanB;
|
|
|
- getPointsAndTangents(index, a, b, tanA, tanB);
|
|
|
-
|
|
|
- Vector3 currentPos;
|
|
|
- Vector3 currentNext = interpolate(a, b, tanA, tanB, 0.0f);
|
|
|
-
|
|
|
- float sum = 0.0f;
|
|
|
- uint i = 0;
|
|
|
- while(leftDistance > sum) {
|
|
|
- currentPos = currentNext;
|
|
|
- float t = (i + 1.0f) / (splits + 1.0f);
|
|
|
- currentNext = interpolate(a, b, tanA, tanB, t);
|
|
|
- float l = static_cast<Vector3> (currentPos - currentNext).length();
|
|
|
- sum += l;
|
|
|
- i++;
|
|
|
- }
|
|
|
- return currentNext;
|
|
|
-}
|
|
|
-
|
|
|
-void Game::getPointsAndTangents(uint index, Vector3& a, Vector3& b, Vector3& tanA, Vector3& 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 = cameraPoints[currentA].pos;
|
|
|
- b = cameraPoints[currentB].pos;
|
|
|
-
|
|
|
- tanA = splineTangent(cameraPoints[prev].pos, a, b);
|
|
|
- tanB = splineTangent(a, b, cameraPoints[next].pos);
|
|
|
-}
|
|
|
-
|
|
|
-void Game::updateDistances() {
|
|
|
- for(uint i = 0; i < cameraPoints.getLength(); i++) {
|
|
|
- cameraPoints[i].distance = distance(i, 10000);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void Game::generateSphere(std::vector<KDTree::Triangle>& data) {
|
|
|
- int fieldSize = 8;
|
|
|
- int quality = 3;
|
|
|
- float radius = 30;
|
|
|
-
|
|
|
- int triangles = fieldSize * quality;
|
|
|
- int layers = (2 + fieldSize) * quality;
|
|
|
-
|
|
|
- for(int l = 0; l < layers; l++) {
|
|
|
- float high1 = cosf((M_PI * l) / layers);
|
|
|
- float high2 = cosf((M_PI * (l + 1)) / layers);
|
|
|
-
|
|
|
- float r1 = sqrtf(1 - high1 * high1) * radius;
|
|
|
- float r2 = sqrtf(1 - high2 * high2) * radius;
|
|
|
-
|
|
|
- high1 *= radius;
|
|
|
- high2 *= radius;
|
|
|
-
|
|
|
- for(int i = 0; i < triangles; i++) {
|
|
|
- float first = 2 * M_PI * i / triangles;
|
|
|
- float second = 2 * M_PI * (i + 1) / triangles;
|
|
|
-
|
|
|
- data.push_back(KDTree::Triangle(
|
|
|
- Vector3(r2 * cosf(first), high2, r2 * sinf(first)),
|
|
|
- Vector3(r1 * cosf(first), high1, r1 * sinf(first)),
|
|
|
- Vector3(r1 * cosf(second), high1, r1 * sinf(second))));
|
|
|
-
|
|
|
- data.push_back(KDTree::Triangle(
|
|
|
- Vector3(r2 * cosf(first), high2, r2 * sinf(first)),
|
|
|
- Vector3(r1 * cosf(second), high1, r1 * sinf(second)),
|
|
|
- Vector3(r2 * cosf(second), high2, r2 * sinf(second))));
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void Game::generateRandom(std::vector<KDTree::Triangle>& data) {
|
|
|
- float radius = 25.0f;
|
|
|
- float diff = 5.0f;
|
|
|
- Random r(0);
|
|
|
- for(int i = 0; i < 10000; i++) {
|
|
|
- Vector3 a(r.nextFloat() * radius, r.nextFloat() * radius, r.nextFloat() * radius);
|
|
|
- Vector3 b = a + Vector3(r.nextFloat() * diff, r.nextFloat() * diff, r.nextFloat() * diff);
|
|
|
- Vector3 c = a + Vector3(r.nextFloat() * diff, r.nextFloat() * diff, r.nextFloat() * diff);
|
|
|
- data.push_back(KDTree::Triangle(a, b, c));
|
|
|
- }
|
|
|
}
|