Browse Source

kdtree visualization, click vector calculation

Kajetan Johannes Hammerle 10 months ago
parent
commit
251d0ecac8

+ 95 - 12
client/Game.cpp

@@ -1,4 +1,5 @@
 #include <cmath>
+#include <vector>
 
 #include "client/Game.h"
 #include "client/utils/Utils.h"
@@ -7,9 +8,10 @@
 #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.125f), movedLength(0.0f), mode(Mode::AUTO) {
+Game::Game(const Control& control, const Clock& fps, const Clock& tps, RenderSettings& renderSettings,
+        const WindowSize& size) :
+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;
@@ -33,21 +35,33 @@ pointIndex(0), moveSpeed(0.125f), movedLength(0.0f), mode(Mode::AUTO) {
     }
     updateDistances();
 
-    lines.add(Vector3(0, 0, 0), Vector3(0, 0, 50));
-    lines.add(Vector3(0, 0, 0), Vector3(0, 50, 0));
-    lines.add(Vector3(0, 0, 50), Vector3(0, 50, 0));
-    lines.build();
+    std::vector<KDTree::Triangle> data;
+    //generateSphere(data);
+    generateRandom(data);
+
+    for(KDTree::Triangle& t : data) {
+        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();
+
+    kdTree.build(data);
+    kdTree.fillLines(lines, data);
 }
 
 void Game::tick() {
     lastRotation = rotation;
     lastPos = pos;
-    if(mode == Mode::PLAYER) {
-        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);
 
+    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;
@@ -137,6 +151,26 @@ void Game::tick() {
         }
         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);
+        clickLine.build();
+    }
 }
 
 void Game::renderWorld(float lag, Renderer& renderer) const {
@@ -162,6 +196,7 @@ void Game::renderWorld(float lag, Renderer& renderer) const {
         renderer.update(v, lastRotation.slerp(lag, rotation));
     }
     worldRenderer.render(lag, renderer);
+    treeData.draw();
 }
 
 void Game::renderWorldLines(float lag, Renderer& renderer) const {
@@ -169,6 +204,7 @@ void Game::renderWorldLines(float lag, Renderer& renderer) const {
     renderer.translateTo(0.0f, 0.0f, 0.0f);
     renderer.update();
     lines.draw();
+    clickLine.draw();
 }
 
 void Game::renderTextOverlay(float lag, Renderer& renderer, FontRenderer& fr) const {
@@ -270,3 +306,50 @@ void Game::updateDistances() {
         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 < 7; 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));
+    }
+}

+ 11 - 3
client/Game.h

@@ -13,10 +13,12 @@
 #include "rendering/renderer/WorldRenderer.h"
 #include "common/utils/KDTree.h"
 #include "client/rendering/Lines.h"
+#include "client/rendering/WindowSize.h"
 
 class Game final {
 public:
-    Game(const Control& control, const Clock& fps, const Clock& tps, RenderSettings& renderSettings);
+    Game(const Control& control, const Clock& fps, const Clock& tps, RenderSettings& renderSettings,
+            const WindowSize& size);
 
     void tick();
     void renderWorld(float lag, Renderer& renderer) const;
@@ -32,11 +34,15 @@ private:
     Vector3 pointUntilDistance(float leftDistance, uint index, uint splits) const;
     void getPointsAndTangents(uint index, Vector3& a, Vector3& b, Vector3& tanA, Vector3& tanB) const;
     void updateDistances();
-    
+
+    void generateSphere(std::vector<KDTree::Triangle>& data);
+    void generateRandom(std::vector<KDTree::Triangle>& data);
+
     const Control& control;
     const Clock& fps;
     const Clock& tps;
     RenderSettings& renderSettings;
+    const WindowSize& size;
 
     Vector3 lastPos;
     mutable Vector3 pos;
@@ -62,10 +68,12 @@ private:
     enum Mode {
         AUTO, PLAYER
     };
-    
+
     Mode mode;
     KDTree kdTree;
     Lines lines;
+    Mesh treeData;
+    Lines clickLine;
 };
 
 #endif

+ 1 - 1
client/Main.cpp

@@ -77,7 +77,7 @@ int main() {
     Control control;
     Clock fps;
     Clock tps;
-    static Game game(control, fps, tps, renderSettings);
+    static Game game(control, fps, tps, renderSettings, size);
 
     initCallbacks(window, size, framebuffers, control);
     window.show();

+ 1 - 1
client/input/MouseButtons.cpp

@@ -77,8 +77,8 @@ void MouseButtons::tick() {
     updateLast = true;
     for(MouseButton& k : buttons) {
         k.downTime += k.down;
+        k.downTime *= k.down;
         k.down = k.down && !k.shouldRelease;
-        k.downTime *= !k.shouldRelease;
         k.shouldRelease = false;
     }
 }

+ 7 - 3
client/rendering/Lines.cpp

@@ -2,12 +2,16 @@
 
 Lines::Lines() {
     vertexBuffer.bind();
-    vertexBuffer.setFloatAttribute(0, 3, 0, 3);
+    vertexBuffer.setFloatAttribute(0, 3, 0, 6);
+    vertexBuffer.setFloatAttribute(1, 3, 3, 6);
 }
 
-void Lines::add(const Vector3& a, const Vector3& b) {
+void Lines::add(const Vector3& a, const Vector3& b, int color) {
+    Vector3 c((color & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f, ((color >> 16) & 0xFF) / 255.0f);
     buffer.add(a);
+    buffer.add(c);
     buffer.add(b);
+    buffer.add(c);
 }
 
 void Lines::clear() {
@@ -21,5 +25,5 @@ void Lines::build() {
 
 void Lines::draw() const {
     vertexBuffer.bindArray();
-    vertexBuffer.drawLines(buffer.getLength());
+    vertexBuffer.drawLines(buffer.getLength() / 2);
 }

+ 1 - 1
client/rendering/Lines.h

@@ -9,7 +9,7 @@ class Lines final {
 public:
     Lines();
 
-    void add(const Vector3& a, const Vector3& b);
+    void add(const Vector3& a, const Vector3& b, int color);
 
     void clear();
     void build();

+ 1 - 1
client/rendering/renderer/WorldRenderer.cpp

@@ -22,7 +22,7 @@ void WorldRenderer::render(float lag, Renderer& renderer) const {
     (void) renderer;
     texture.bind(0);
     normalTexture.bind(2);
-    mesh.draw();
+    //mesh.draw();
 }
 
 bool WorldRenderer::isAir(uint x, uint y, uint z) const {

+ 77 - 0
common/utils/KDTree.cpp

@@ -1,4 +1,5 @@
 #include <algorithm>
+#include <iostream>
 
 #include "common/utils/KDTree.h"
 
@@ -125,3 +126,79 @@ void KDTree::build(Node* n, std::vector<KDTree::Triangle>& data) {
     }
 }
 
+void KDTree::fillLines(Lines& lines, const std::vector<KDTree::Triangle>& data) {
+    if(data.size() == 0) {
+        return;
+    }
+    Vector3 min = data[0][0];
+    Vector3 max = data[0][0];
+    for(const Triangle& t : data) {
+        for(const Vector3& v : t.data()) {
+            min.set(std::min(min[0], v[0]), std::min(min[1], v[1]), std::min(min[2], v[2]));
+            max.set(std::max(max[0], v[0]), std::max(max[1], v[1]), std::max(max[2], v[2]));
+        }
+    }
+
+    lines.add(Vector3(min[0], min[1], min[2]), Vector3(max[0], min[1], min[2]), 0xFFFFFF);
+    lines.add(Vector3(min[0], min[1], min[2]), Vector3(min[0], min[1], max[2]), 0xFFFFFF);
+    lines.add(Vector3(max[0], min[1], min[2]), Vector3(max[0], min[1], max[2]), 0xFFFFFF);
+    lines.add(Vector3(min[0], min[1], max[2]), Vector3(max[0], min[1], max[2]), 0xFFFFFF);
+
+    lines.add(Vector3(min[0], min[1], min[2]), Vector3(min[0], max[1], min[2]), 0xFFFFFF);
+    lines.add(Vector3(max[0], min[1], min[2]), Vector3(max[0], max[1], min[2]), 0xFFFFFF);
+    lines.add(Vector3(min[0], min[1], max[2]), Vector3(min[0], max[1], max[2]), 0xFFFFFF);
+    lines.add(Vector3(max[0], min[1], max[2]), Vector3(max[0], max[1], max[2]), 0xFFFFFF);
+
+    lines.add(Vector3(min[0], max[1], min[2]), Vector3(max[0], max[1], min[2]), 0xFFFFFF);
+    lines.add(Vector3(min[0], max[1], min[2]), Vector3(min[0], max[1], max[2]), 0xFFFFFF);
+    lines.add(Vector3(max[0], max[1], min[2]), Vector3(max[0], max[1], max[2]), 0xFFFFFF);
+    lines.add(Vector3(min[0], max[1], max[2]), Vector3(max[0], max[1], max[2]), 0xFFFFFF);
+
+    fillLines(lines, &root, min, max);
+
+    lines.build();
+}
+
+void KDTree::fillLines(Lines& lines, Node* n, const Vector3& min, const Vector3& max) {
+    if(n->lessEqual == nullptr && n->greater == nullptr) {
+        return;
+    }
+    switch(n->splitDim) {
+        case 0:
+            lines.add(Vector3(n->splitValue, min[1], min[2]), Vector3(n->splitValue, max[1], min[2]), 0xFFFFFF);
+            lines.add(Vector3(n->splitValue, max[1], min[2]), Vector3(n->splitValue, max[1], max[2]), 0xFFFFFF);
+            lines.add(Vector3(n->splitValue, max[1], max[2]), Vector3(n->splitValue, min[1], max[2]), 0xFFFFFF);
+            lines.add(Vector3(n->splitValue, min[1], max[2]), Vector3(n->splitValue, min[1], min[2]), 0xFFFFFF);
+            if(n->lessEqual != nullptr) {
+                fillLines(lines, n->lessEqual, min, Vector3(n->splitValue, max[1], max[2]));
+            }
+            if(n->greater != nullptr) {
+                fillLines(lines, n->greater, Vector3(n->splitValue, min[1], min[2]), max);
+            }
+            break;
+        case 1:
+            lines.add(Vector3(min[0], n->splitValue, min[2]), Vector3(max[0], n->splitValue, min[2]), 0xFFFFFF);
+            lines.add(Vector3(min[0], n->splitValue, min[2]), Vector3(min[0], n->splitValue, max[2]), 0xFFFFFF);
+            lines.add(Vector3(max[0], n->splitValue, min[2]), Vector3(max[0], n->splitValue, max[2]), 0xFFFFFF);
+            lines.add(Vector3(min[0], n->splitValue, max[2]), Vector3(max[0], n->splitValue, max[2]), 0xFFFFFF);
+            if(n->lessEqual != nullptr) {
+                fillLines(lines, n->lessEqual, min, Vector3(max[0], n->splitValue, max[2]));
+            }
+            if(n->greater != nullptr) {
+                fillLines(lines, n->greater, Vector3(min[0], n->splitValue, min[2]), max);
+            }
+            break;
+        case 2:
+            lines.add(Vector3(min[0], min[1], n->splitValue), Vector3(min[0], max[1], n->splitValue), 0xFFFFFF);
+            lines.add(Vector3(min[0], max[1], n->splitValue), Vector3(max[0], max[1], n->splitValue), 0xFFFFFF);
+            lines.add(Vector3(max[0], max[1], n->splitValue), Vector3(max[0], min[1], n->splitValue), 0xFFFFFF);
+            lines.add(Vector3(max[0], min[1], n->splitValue), Vector3(min[0], min[1], n->splitValue), 0xFFFFFF);
+            if(n->lessEqual != nullptr) {
+                fillLines(lines, n->lessEqual, min, Vector3(max[0], max[1], n->splitValue));
+            }
+            if(n->greater != nullptr) {
+                fillLines(lines, n->greater, Vector3(min[0], min[1], n->splitValue), max);
+            }
+            break;
+    }
+}

+ 4 - 0
common/utils/KDTree.h

@@ -2,8 +2,10 @@
 #define KDTREE_H
 
 #include <vector>
+
 #include "common/utils/Array.h"
 #include "common/math/Vector.h"
+#include "client/rendering/Lines.h"
 
 struct KDTree final {
 
@@ -39,10 +41,12 @@ public:
     KDTree& operator=(KDTree&& other) = delete;
 
     void build(std::vector<KDTree::Triangle>& data);
+    void fillLines(Lines& lines, const std::vector<KDTree::Triangle>& data);
 private:
     void clean(Node* n);
     float median(std::vector<KDTree::Triangle>& data, int dim) const;
     void build(Node* n, std::vector<KDTree::Triangle>& data);
+    void fillLines(Lines& lines, Node* n, const Vector3& min, const Vector3& max);
 };
 
 #endif

+ 2 - 2
meson.build

@@ -2,11 +2,11 @@ project('cubes plus plus', 'cpp')
 
 # 'common/world/Chunk.cpp', 'common/world/World.cpp', 'common/utils/Face.cpp'
 
-sourcesCommon = ['common/network/Packet.cpp', 'common/block/BlockBuilder.cpp', 'common/block/Block.cpp', 'common/block/BlockRegistry.cpp', 'common/utils/HashedString.cpp', 'common/utils/String.cpp', 'common/utils/SplitString.cpp', 'common/utils/Random.cpp', 'common/world/World.cpp', 'common/math/Vector.cpp', 'common/utils/KDTree.cpp']
+sourcesCommon = ['common/network/Packet.cpp', 'common/block/BlockBuilder.cpp', 'common/block/Block.cpp', 'common/block/BlockRegistry.cpp', 'common/utils/HashedString.cpp', 'common/utils/String.cpp', 'common/utils/SplitString.cpp', 'common/utils/Random.cpp', 'common/world/World.cpp', 'common/math/Vector.cpp']
 
 sourcesServer = ['server/Main.cpp', 'server/network/Server.cpp', 'server/network/Client.cpp', 'server/GameServer.cpp', 'server/commands/ServerCommands.cpp', 'server/commands/CommandManager.cpp', 'server/commands/ConsoleEditor.cpp', 'server/Clock.cpp']
 
-sourcesClient = ['client/Main.cpp', 'client/rendering/WindowSize.cpp', 'client/math/Frustum.cpp', 'client/rendering/Framebuffers.cpp', 'client/rendering/wrapper/GLFWWrapper.cpp', 'client/rendering/wrapper/Window.cpp', 'client/rendering/Engine.cpp', 'client/input/Keys.cpp', 'client/rendering/wrapper/Shader.cpp', 'client/rendering/Shaders.cpp', 'client/utils/Utils.cpp', 'client/rendering/Mesh.cpp', 'client/math/Matrix.cpp', 'client/math/MatrixStack.cpp', 'client/math/Quaternion.cpp', 'client/math/Plane.cpp', 'client/Game.cpp', 'client/input/MouseButtons.cpp', 'client/rendering/FileTexture.cpp', 'client/rendering/FontRenderer.cpp', 'client/rendering/wrapper/Framebuffer.cpp', 'client/rendering/NoiseTexture.cpp', 'client/utils/Clock.cpp', 'client/input/Control.cpp', 'client/rendering/RenderSettings.cpp', 'client/rendering/wrapper/VertexBuffer.cpp', 'client/rendering/wrapper/StreamBuffer.cpp', 'client/rendering/wrapper/Texture.cpp', 'client/utils/PNGReader.cpp', 'client/rendering/wrapper/GLWrapper.cpp', 'client/rendering/Renderer.cpp', 'client/rendering/renderer/WorldRenderer.cpp', 'client/rendering/NormalTexture.cpp', 'client/rendering/Vertex.cpp', 'client/rendering/Triangle.cpp', 'client/rendering/Lines.cpp']
+sourcesClient = ['client/Main.cpp', 'client/rendering/WindowSize.cpp', 'client/math/Frustum.cpp', 'client/rendering/Framebuffers.cpp', 'client/rendering/wrapper/GLFWWrapper.cpp', 'client/rendering/wrapper/Window.cpp', 'client/rendering/Engine.cpp', 'client/input/Keys.cpp', 'client/rendering/wrapper/Shader.cpp', 'client/rendering/Shaders.cpp', 'client/utils/Utils.cpp', 'client/rendering/Mesh.cpp', 'client/math/Matrix.cpp', 'client/math/MatrixStack.cpp', 'client/math/Quaternion.cpp', 'client/math/Plane.cpp', 'client/Game.cpp', 'client/input/MouseButtons.cpp', 'client/rendering/FileTexture.cpp', 'client/rendering/FontRenderer.cpp', 'client/rendering/wrapper/Framebuffer.cpp', 'client/rendering/NoiseTexture.cpp', 'client/utils/Clock.cpp', 'client/input/Control.cpp', 'client/rendering/RenderSettings.cpp', 'client/rendering/wrapper/VertexBuffer.cpp', 'client/rendering/wrapper/StreamBuffer.cpp', 'client/rendering/wrapper/Texture.cpp', 'client/utils/PNGReader.cpp', 'client/rendering/wrapper/GLWrapper.cpp', 'client/rendering/Renderer.cpp', 'client/rendering/renderer/WorldRenderer.cpp', 'client/rendering/NormalTexture.cpp', 'client/rendering/Vertex.cpp', 'client/rendering/Triangle.cpp', 'client/rendering/Lines.cpp', 'common/utils/KDTree.cpp']
 
 sourcesTest = ['tests/Main.cpp', 'common/utils/String.cpp', 'common/utils/SplitString.cpp', 'common/utils/HashedString.cpp', 'common/utils/Random.cpp']
 

+ 2 - 1
resources/shader/lineFragment.fs

@@ -6,10 +6,11 @@ layout (location = 2) out vec4 worldColor;
 layout (location = 3) out float worldShadow;
 
 in vec3 varPosition;
+in vec3 varColor;
 
 void main(void) {
     worldPosition = varPosition;
     worldNormal = vec3(0.0, 0.0, 1.0);
-    worldColor = vec4(1.0, 1.0, 1.0, 1.0);
+    worldColor = vec4(varColor, 1.0);
     worldShadow = 1.0;
 }

+ 3 - 0
resources/shader/lineVertex.vs

@@ -1,15 +1,18 @@
 #version 430
 
 layout (location = 0) in vec3 position;
+layout (location = 1) in vec3 color;
 
 uniform mat4 proj;
 uniform mat4 view;
 uniform mat4 model;
 
 out vec3 varPosition;
+out vec3 varColor;
 
 void main(void) { 
     vec4 worldPos = view * model * vec4(position, 1.0);
     varPosition = worldPos.xyz;
     gl_Position = proj * worldPos;
+    varColor = color;
 }

BIN
resources/textures.png