Browse Source

quaternions for camera points

Kajetan Johannes Hammerle 3 years ago
parent
commit
ad8be1d9ca
7 changed files with 36 additions and 19 deletions
  1. 20 9
      client/Game.cpp
  2. 1 0
      client/Game.h
  3. 8 8
      client/Main.cpp
  4. 1 1
      client/math/Quaternion.cpp
  5. 1 1
      client/math/Quaternion.h
  6. 4 0
      client/math/Vector.cpp
  7. 1 0
      client/math/Vector.h

+ 20 - 9
client/Game.cpp

@@ -11,25 +11,36 @@ Game::Game(const Control& control, const Clock& fps, const Clock& tps, RenderSet
 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.75f;
+    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);
-        cameraPoints.add( {v, 0.0f});
+
+        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() {
@@ -39,7 +50,7 @@ void Game::tick() {
         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);
@@ -64,7 +75,7 @@ void Game::tick() {
         if(control.keys.sneak.isDown()) {
             pos.addMul(up, -speed);
         }
-        
+
         const float rotationSpeed = 5.0f;
         if(control.keys.camLeft.isDown()) {
             rotation.mul(Quaternion(up, rotationSpeed));
@@ -112,9 +123,9 @@ void Game::renderWorld(float lag, Renderer& renderer) const {
         Vector tanA;
         Vector tanB;
         getPointsAndTangents(index, a, b, tanA, tanB);
-        
+
         Vector interpolatedPos = interpolate(a, b, tanA, tanB, t);
-        renderer.update(interpolatedPos, Quaternion(Vector(1.0f, 0.0f, 0.0f), -30.0f));
+        renderer.update(interpolatedPos, cameraPoints[index].q.slerp(t, cameraPoints[(index + 1) % cameraPoints.getLength()].q));
         pos = interpolatedPos;
     } else if(mode == Mode::PLAYER) {
         Vector v(lastPos);
@@ -187,10 +198,10 @@ void Game::getPointsAndTangents(uint index, Vector& a, Vector& b, Vector& tanA,
     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);
 }

+ 1 - 0
client/Game.h

@@ -45,6 +45,7 @@ private:
 
     struct Point {
         Vector pos;
+        Quaternion q;
         float distance;
     };
 

+ 8 - 8
client/Main.cpp

@@ -53,38 +53,38 @@ int main() {
     if(GLFWWrapper::hasError()) {
         return 0;
     }
-    
+
     WindowSize size(1024, 620);
     Window window(size, "Test");
     if(window.hasError() || initGLEW()) {
         return 0;
     }
-    
+
     Shaders shaders;
     if(shaders.hasError()) {
         return 0;
     }
-    
+
     Framebuffers framebuffers(size);
     if(framebuffers.hasError()) {
         return 0;
     }
-    
+
     RenderSettings renderSettings;
     Engine engine(shaders, framebuffers, size, renderSettings);
-    
+
     Control control;
     Clock fps;
     Clock tps;
     static Game game(control, fps, tps, renderSettings);
-    
+
     initCallbacks(window, size, framebuffers, control);
     window.show();
-    
+
     const u64 nanosPerTick = 50000000;
     u64 lag = 0;
     while(!window.shouldClose() && game.isRunning()) {
-        engine.renderTick((float) lag / nanosPerTick, game);
+        engine.renderTick(static_cast<float> (lag) / nanosPerTick, game);
         window.swapBuffers();
         lag += fps.update();
         while(lag >= nanosPerTick) {

+ 1 - 1
client/math/Quaternion.cpp

@@ -23,7 +23,7 @@ Quaternion Quaternion::lerp(float f, const Quaternion& other) const {
 
 Quaternion Quaternion::slerp(float f, const Quaternion& other) const {
     float angle = xyz.dot(other.xyz) + w * other.w;
-    if(angle > 1.0f) {
+    if(angle >= 1.0f) {
         return *this;
     } else if(angle < -1.0f) {
         angle = -1.0f;

+ 1 - 1
client/math/Quaternion.h

@@ -16,7 +16,7 @@ public:
     Matrix toMatrix() const;
     void mul(const Quaternion& other);
 
-private:
+//private:
     Quaternion interpolate(float a, float b, const Quaternion& other) const;
     
     Vector xyz;

+ 4 - 0
client/math/Vector.cpp

@@ -8,6 +8,10 @@ Vector::Vector() : x(0), y(0), z(0) {
 Vector::Vector(float ix, float iy, float iz) : x(ix), y(iy), z(iz) {
 }
 
+Vector::Vector(float lengthAngle, float widthAngle) {
+    setAngles(lengthAngle, widthAngle);
+}
+
 float Vector::getX() const {
     return x;
 }

+ 1 - 0
client/math/Vector.h

@@ -8,6 +8,7 @@ class Vector final {
 public:
     Vector();
     Vector(float ix, float iy, float iz);
+    Vector(float lengthAngle, float widthAngle);
 
     float getX() const;
     float getY() const;