Browse Source

tests physics and collision detection

Kajetan Johannes Hammerle 3 years ago
parent
commit
b24a0e590a
5 changed files with 93 additions and 29 deletions
  1. 42 28
      client/Game.cpp
  2. 2 0
      client/Game.h
  3. 7 1
      common/entities/Player.h
  4. 34 0
      common/world/World.cpp
  5. 8 0
      common/world/World.h

+ 42 - 28
client/Game.cpp

@@ -11,6 +11,7 @@ BlockRegistry Game::blockRegistry;
 World Game::world{blockRegistry};
 static WorldRenderer worldRenderer{Game::world};
 Controller Game::controller;
+Player Game::player;
 
 typedef void (*State)();
 static State tickState;
@@ -19,11 +20,6 @@ static State renderState;
 static BaseGUI baseGUI;
 static StartGUI startGUI;
 
-static Vector3 lastPos;
-static Vector3 pos;
-static Quaternion lastRotation;
-static Quaternion rotation;
-
 static void tickConnectedState() {
     GameClient::consumeEvents();
 }
@@ -58,60 +54,78 @@ bool Game::init() {
     tickState = tickConnectState;
     renderState = renderConnectState;
 
-    pos = Vector3(0.0f, 30.0f, 0.0f);
-    rotation = Quaternion(Vector3(1.0f, 0.0f, 0.0f), 30) * rotation;
-    rotation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), 30) * rotation;
+    player.position = Vector3(0.0f, 30.0f, 0.0f);
+    player.lastLengthAngle = 0.0f;
+    player.lengthAngle = 0.0f;
+    player.lastWidthAngle = 0.0f;
+    player.widthAngle = 0.0f;
+    world.addPlayer(&player);
     return false;
 }
 
 void Game::tick() {
     tickState();
+    world.preTick();
 
-    lastRotation = rotation;
-    lastPos = pos;
+    Quaternion q(Vector3(0.0f, 1.0f, 0.0f), player.lengthAngle);
+    q *= Quaternion(Vector3(1.0f, 0.0f, 0.0f), player.widthAngle);
 
-    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);
+    Vector3 up(0.0f, 1.0f, 0.0f);
+    Vector3 back = q * Vector3(0.0f, 0.0f, -1.0f);
+    // back.setAngles(player.widthAngle, player.lengthAngle);
+    // back[1] = 0.0f;
+    // back.normalize();
+    Vector3 right = back.cross(up);
 
-    const float speed = 2.0f;
+    const float speed = 0.25f;
     if(controller.down.isDown()) {
-        pos += back * speed;
+        player.acceleration += back * speed;
     }
     if(controller.up.isDown()) {
-        pos -= back * speed;
+        player.acceleration -= back * speed;
     }
     if(controller.left.isDown()) {
-        pos -= right * speed;
+        player.acceleration -= right * speed;
     }
     if(controller.right.isDown()) {
-        pos += right * speed;
+        player.acceleration += right * speed;
     }
     if(controller.jump.isDown()) {
-        pos += up * speed;
+        player.acceleration += up * speed;
     }
     if(controller.sneak.isDown()) {
-        pos -= up * speed;
+        player.acceleration -= up * speed;
     }
 
     const float rotationSpeed = 5.0f;
     if(controller.camLeft.isDown()) {
-        rotation = Quaternion(up, -rotationSpeed) * rotation;
+        player.lengthAngle -= rotationSpeed;
     }
     if(controller.camRight.isDown()) {
-        rotation = Quaternion(up, rotationSpeed) * rotation;
+        player.lengthAngle += rotationSpeed;
     }
-    if(controller.camUp.isDown()) {
-        rotation = Quaternion(right, -rotationSpeed) * rotation;
+    if(controller.camUp.isDown() &&
+       player.widthAngle - rotationSpeed > -90.0f) {
+        player.widthAngle -= rotationSpeed;
     }
-    if(controller.camDown.isDown()) {
-        rotation = Quaternion(right, rotationSpeed) * rotation;
+    if(controller.camDown.isDown() &&
+       player.widthAngle + rotationSpeed < 90.0f) {
+        player.widthAngle += rotationSpeed;
     }
+
+    world.tick();
 }
 
 void Game::renderWorld() {
-    Engine::matrix.update(Utils::interpolate(lastPos, pos, Engine::lag),
-                          lastRotation.lerp(Engine::lag, rotation));
+    Quaternion q(Vector3(0.0f, 1.0f, 0.0f),
+                 Utils::interpolate(player.lastLengthAngle, player.lengthAngle,
+                                    Engine::lag));
+    q *= Quaternion(Vector3(1.0f, 0.0f, 0.0f),
+                    Utils::interpolate(player.lastWidthAngle, player.widthAngle,
+                                       Engine::lag));
+    Engine::matrix.update(
+        Utils::interpolate(player.lastPosition, player.position, Engine::lag),
+        q);
     worldRenderer.render();
 }
 

+ 2 - 0
client/Game.h

@@ -3,12 +3,14 @@
 
 #include "client/input/Controller.h"
 #include "common/block/BlockRegistry.h"
+#include "common/entities/Player.h"
 #include "common/world/World.h"
 
 namespace Game {
     extern BlockRegistry blockRegistry;
     extern World world;
     extern Controller controller;
+    extern Player player;
 
     bool init();
 

+ 7 - 1
common/entities/Player.h

@@ -1,11 +1,17 @@
 #ifndef PLAYER_H
 #define PLAYER_H
 
-#include "math/Vector.h"
+#include "math/Quaternion.h"
 
 struct Player {
     Vector3 lastPosition;
     Vector3 position;
+    float lastLengthAngle;
+    float lengthAngle;
+    float lastWidthAngle;
+    float widthAngle;
+    Vector3 velocity;
+    Vector3 acceleration;
 };
 
 #endif

+ 34 - 0
common/world/World.cpp

@@ -20,4 +20,38 @@ int World::getSize() const {
 
 int World::getHeight() const {
     return blocks.getHeight();
+}
+
+void World::addPlayer(Player* p) {
+    players.add(p);
+}
+
+void World::preTick() {
+    for(Player* p : players) {
+        p->lastPosition = p->position;
+        p->lastLengthAngle = p->lengthAngle;
+        p->lastWidthAngle = p->widthAngle;
+        p->acceleration = Vector3(0.0f, -0.5f, 0.0f);
+    }
+}
+
+void World::tick() {
+    for(Player* p : players) {
+        p->acceleration +=
+            Vector3(-p->velocity[0] * 0.7f, 0.0f, -p->velocity[2] * 0.7f);
+        p->velocity += p->acceleration;
+        p->position += p->velocity;
+
+        int x = p->position[0];
+        int y = p->position[1];
+        int z = p->position[2];
+        while(getBlock(x, y, z).getId() != 0 ||
+              getBlock(x - 1, y, z).getId() != 0 ||
+              getBlock(x + 1, y, z).getId() != 0 ||
+              getBlock(x, y, z - 1).getId() != 0 ||
+              getBlock(x, y, z + 1).getId() != 0) {
+            y++;
+        }
+        p->position[1] = y + 1.0f;
+    }
 }

+ 8 - 0
common/world/World.h

@@ -2,11 +2,14 @@
 #define WORLD_H
 
 #include "common/block/BlockRegistry.h"
+#include "common/entities/Player.h"
 #include "common/world/BlockStorage.h"
+#include "utils/List.h"
 
 class World final {
     const BlockRegistry& blockRegistry;
     BlockStorage blocks;
+    List<Player*> players;
 
 public:
     mutable bool dirty;
@@ -18,6 +21,11 @@ public:
 
     int getSize() const;
     int getHeight() const;
+
+    void addPlayer(Player* p);
+
+    void preTick();
+    void tick();
 };
 
 #endif