Browse Source

basic quaternions

Kajetan Johannes Hammerle 3 years ago
parent
commit
73fb1146cc
5 changed files with 90 additions and 8 deletions
  1. 2 3
      client/Game.cpp
  2. 57 0
      client/math/Quaternion.cpp
  3. 26 0
      client/math/Quaternion.h
  4. 4 4
      client/math/Vector.cpp
  5. 1 1
      meson.build

+ 2 - 3
client/Game.cpp

@@ -1,10 +1,9 @@
-#include <cmath>
-
 #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"
 
 Game::Game(const Control& control, const Camera& camera, Ray& ray, const Clock& fps, const Clock& tps,
         RenderSettings& renderSettings) :
@@ -90,7 +89,7 @@ void Game::renderWorld(float lag, Renderer& renderer) const {
             leftLength -= cameraPoints[index].distance;
             index = (index + 1) % cameraPoints.getLength();
         }
-
+        
         uint prev = index;
         float t = leftLength / cameraPoints[index].distance;
         if(prev == 0) {

+ 57 - 0
client/math/Quaternion.cpp

@@ -0,0 +1,57 @@
+#include <cmath>
+
+#include "client/math/Quaternion.h"
+
+Quaternion::Quaternion(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {
+}
+
+Quaternion::Quaternion(Vector unitAxis, float angle) {
+    float sin;
+    sincosf(angle * (M_PI / 360.0f), &sin, &w);
+    x = unitAxis.getX() * sin;
+    y = unitAxis.getY() * sin;
+    z = unitAxis.getZ() * sin;
+}
+
+Quaternion Quaternion::lerp(float f, const Quaternion& other) const {
+    Quaternion q = interpolate(1 - f, f, other);
+    q.normalize();
+    return q;
+}
+
+Quaternion Quaternion::slerp(float f, const Quaternion& other) const {
+    float arccos = acosf(x * other.x + y * other.y + z * other.z + w * other.w);
+    float sin = 1.0f / sinf(arccos);
+    return interpolate(sinf((1 - f) * arccos) * sin, sinf(f * arccos) * sin, other);
+}
+
+Quaternion Quaternion::interpolate(float a, float b, const Quaternion& other) const {
+    return Quaternion(x * a + other.x * b, y * a + other.y * b, z * a + other.z * b, w * a + other.w * b);
+}
+
+void Quaternion::normalize() {
+    float f = 1.0f / sqrtf(x * x + y * y + z * z + w * w);
+    x *= f;
+    y *= f;
+    z *= f;
+    w *= f;
+}
+
+Matrix Quaternion::toMatrix() const {
+    float x2 = 2 * x * x;
+    float y2 = 2 * y * y;
+    float z2 = 2 * z * z; 
+    
+    float xy = 2 * x * y;
+    float xz = 2 * x * z;
+    float xw = 2 * x * w;
+    float zw = 2 * z * w;
+    float yz = 2 * y * z;
+    float yw = 2 * y * w;
+
+    Matrix m;
+    m.set(0, 1 - y2 - z2).set(1, xy - zw).set(2, xz + yw);
+    m.set(4, xy + zw).set(5, 1 - x2 - z2).set(6, yz - xw);
+    m.set(8, xz - yw).set(9, yz + xw).set(10, 1 - x2 - y2);
+    return m;
+}

+ 26 - 0
client/math/Quaternion.h

@@ -0,0 +1,26 @@
+#ifndef QUATERNION_H
+#define QUATERNION_H
+
+#include "client/math/Vector.h"
+#include "client/math/Matrix.h"
+
+class Quaternion {
+public:
+    Quaternion(float x, float y, float z, float w);
+    Quaternion(Vector unitAxis, float angle);
+    
+    Quaternion lerp(float f, const Quaternion& other) const;
+    Quaternion slerp(float f, const Quaternion& other) const;
+    void normalize();
+    Matrix toMatrix() const;
+
+private:
+    Quaternion interpolate(float a, float b, const Quaternion& other) const;
+    
+    float x;
+    float y;
+    float z;
+    float w;
+};
+
+#endif

+ 4 - 4
client/math/Vector.cpp

@@ -61,8 +61,8 @@ Vector& Vector::setMul(const Vector& v, float f) {
 }
 
 Vector& Vector::setAngles(float lengthAngle, float widthAngle) {
-    lengthAngle = lengthAngle * M_PI / 180.0f;
-    widthAngle = widthAngle * M_PI / 180.0f;
+    lengthAngle = lengthAngle * (M_PI / 180.0f);
+    widthAngle = widthAngle * (M_PI / 180.0f);
     x = cosf(widthAngle) * sinf(lengthAngle);
     y = sinf(widthAngle);
     z = cosf(widthAngle) * cosf(lengthAngle);
@@ -117,7 +117,7 @@ Vector& Vector::cross(const Vector& v) {
 }
 
 Vector& Vector::normalize() {
-    float f = 1.0f / sqrtf(squareLength());
+    float f = 1.0f / length();
     x *= f;
     y *= f;
     z *= f;
@@ -129,7 +129,7 @@ float Vector::squareLength() const {
 }
 
 float Vector::length() const {
-    return sqrt(squareLength());
+    return sqrtf(squareLength());
 }
 
 float Vector::dot(const Vector& v) const {

+ 1 - 1
meson.build

@@ -6,7 +6,7 @@ sourcesCommon = ['common/block/BlockBuilder.cpp', 'common/block/Block.cpp', 'com
 
 sourcesServer = ['server/Main.cpp', 'server/network/Server.cpp', 'server/GameServer.cpp', 'server/commands/ServerCommands.cpp', 'server/commands/CommandManager.cpp', 'server/network/Socket.cpp', 'server/commands/CommandEditor.cpp', 'server/Clock.cpp']
 
-sourcesClient = ['client/Main.cpp', 'client/rendering/WindowSize.cpp', 'client/math/Frustum.cpp', 'client/math/Ray.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/Vector.cpp', 'client/math/Camera.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']
+sourcesClient = ['client/Main.cpp', 'client/rendering/WindowSize.cpp', 'client/math/Frustum.cpp', 'client/math/Ray.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/Vector.cpp', 'client/math/Quaternion.cpp', 'client/math/Camera.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']
 
 sourcesTest = ['tests/Main.cpp', 'common/utils/String.cpp', 'common/utils/SplitString.cpp', 'client/math/Matrix.cpp', 'client/math/Vector.cpp', 'common/utils/HashedString.cpp', 'common/utils/Random.cpp']