From 8589a298da3a7effebf57d590d6d681bc70a88d1 Mon Sep 17 00:00:00 2001 From: h4570 Date: Thu, 24 Dec 2020 10:33:30 +0100 Subject: [PATCH] added comments, increased performance --- src/engine/include/models/math/vector3.hpp | 99 ++++++-- src/engine/models/math/vector3.cpp | 281 ++++++++------------- 2 files changed, 180 insertions(+), 200 deletions(-) diff --git a/src/engine/include/models/math/vector3.hpp b/src/engine/include/models/math/vector3.hpp index 641f6b1..53939af 100644 --- a/src/engine/include/models/math/vector3.hpp +++ b/src/engine/include/models/math/vector3.hpp @@ -12,6 +12,7 @@ #define _TYRA_VECTOR3_ #include +#include class Math; // Forward definition @@ -20,6 +21,7 @@ class Vector3 { public: + /** This trick will allow use to use vec.x and vex[0] */ union { struct @@ -31,32 +33,91 @@ public: float xyz[3] __attribute__((__aligned__(16))); }; - Vector3(float t_x, float t_y, float t_z); - Vector3(const Vector3 &v); + // ---- + // Constructors/Destructors + // ---- + + /** Create empty vector. */ Vector3(); - ~Vector3(); - Vector3 operator+(Vector3 v); - Vector3 operator-(const Vector3 &v); - Vector3 operator*(Vector3 &v); - Vector3 operator*(const float &t); + /** Create vector with given vector values. */ + Vector3(const Vector3 &t_v) { set(t_v); } + + /** Create vector with given values. */ + Vector3(const float &t_x, const float &t_y, const float &t_z) { set(t_x, t_y, t_z); } + + // ---- + // Operators + // ---- + + Vector3 operator+(const Vector3 &v) const; + Vector3 operator-(const Vector3 &v) const; + /** Also called "cross product" */ + Vector3 operator*(const Vector3 &v) const; + Vector3 operator*(const float &t) const; + Vector3 operator/(const float &t) const; + Vector3 operator-(void) const { return Vector3(-x, -y, -z); } + void operator+=(const Vector3 &t); void operator*=(const float &t); - Vector3 operator/(float t); - Vector3 operator-(void); - static u8 shouldBeBackfaceCulled(const Vector3 *t_cameraPos, const Vector3 *v0, const Vector3 *v1, const Vector3 *v2); - u8 collidesSquare(const Vector3 &t_min, const Vector3 &t_max) const; - u8 isOnSquare(const Vector3 &t_min, const Vector3 &t_max) const; - float length(); - void normalize(); - void setByLerp(const Vector3 &v1, const Vector3 &v2, const float &t_interp, const float &t_scale); - float innerProduct(Vector3 &v); + // ---- + // Functions + // ---- + + /** Set vector values via VU0. */ void set(const Vector3 &v); - void rotate(const Vector3 &v, u8 inversed = false); + + /** Set vector values. */ void set(const float &t_x, const float &t_y, const float &t_z); - void copy(Vector3 &v); + + /** Also called dot3. */ + float innerProduct(const Vector3 &v) const; + + /** Get vector length */ + float length() const; + + /** Normalize vector. */ + void normalize(); + + /** Returns distance between two vectors */ float distanceTo(const Vector3 &v) const; - const void print() const; + + /** + * Checks intersection with given box + * @param t_min Opposite min vertex (ex. near, left, down vertex of bounding box) + * @param t_max Opposite max vertex (ex. far, right, up vertex of bounding box) + */ + u8 collidesBox(const Vector3 &t_min, const Vector3 &t_max) const + { + return ((this->x <= t_max.x && this->x >= t_min.x) && (this->y < t_max.y && this->y >= t_min.y) && (this->z <= t_max.z && this->z >= t_min.z)) ? 1 : 0; + } + + /** + * Checks if this vector is on given box (this->y >= box.y) + * @param t_min Opposite min vertex (ex. near, left, down vertex of bounding box) + * @param t_max Opposite max vertex (ex. far, right, up vertex of bounding box) + */ + u8 isOnBox(const Vector3 &t_min, const Vector3 &t_max) const + { + return ((this->x <= t_max.x && this->x >= t_min.x) && (this->y >= t_max.y) && (this->z <= t_max.z && this->z >= t_min.z)) ? 1 : 0; + } + + /** Check if given triangle should be backface culled. */ + static u8 shouldBeBackfaceCulled(const Vector3 *t_cameraPos, const Vector3 *t_v0, const Vector3 *t_v1, const Vector3 *t_v2); + + /** + * Set by linear interpolation between two vertices (animation). + * @param t_v1 Before vertex + * @param t_v2 After vertex + * @param t_interp State of interpolation + * @param t_scale Scale + */ + void setByLerp(const Vector3 &t_v1, const Vector3 &t_v2, const float &t_interp, const float &t_scale); + + const void print() const + { + printf("Vector3(%f, %f, %f)\n", x, y, z); + } }; #endif diff --git a/src/engine/models/math/vector3.cpp b/src/engine/models/math/vector3.cpp index 7adafd3..57f4303 100644 --- a/src/engine/models/math/vector3.cpp +++ b/src/engine/models/math/vector3.cpp @@ -9,63 +9,24 @@ */ #include "../../include/models/math/vector3.hpp" - #include "../../include/utils/math.hpp" -#include // ---- // Constructors/Destructors // ---- -/** Create by specifying 3 points */ -Vector3::Vector3(float t_x, float t_y, float t_z) -{ - x = t_x; - y = t_y; - z = t_z; -} - -/** Create with another vector values */ -Vector3::Vector3(const Vector3 &another) -{ - x = another.x; - y = another.y; - z = another.z; -} - -void Vector3::setByLerp(const Vector3 &v1, const Vector3 &v2, const float &t_interp, const float &t_scale) -{ - asm volatile( - "lqc2 vf4, 0x0(%1) \n\t" // vf4 = v1 - "lqc2 vf5, 0x0(%2) \n\t" // vf5 = v2 - "mfc1 $8, %3 \n\t" // vf6 = t - "qmtc2 $8, vf6 \n\t" // lerp: - "vsub.xyz vf7, vf5, vf4 \n\t" // vf7 = v2 - v1 - "vmulx.xyz vf8, vf7, vf6 \n\t" // vf8 = vf7 * t - "vadd.xyz vf9, vf8, vf4 \n\t" // vf9 = vf8 + vf4 - "sqc2 vf9, 0x0(%0) \n\t" // v0 = vf9 - : - : "r"(&this->xyz), "r"(&v1.xyz), "r"(&v2.xyz), "f"(t_interp)); - x *= t_scale; - y *= t_scale; - z *= t_scale; -} - -/** Create empty vector */ Vector3::Vector3() { - x = 0; - y = 0; - z = 0; + x = 0.0F; + y = 0.0F; + z = 0.0F; } -Vector3::~Vector3() {} - // ---- -// Methods +// Operators // ---- -Vector3 Vector3::operator+(Vector3 v) +Vector3 Vector3::operator+(const Vector3 &v) const { Vector3 result; asm volatile( // VU0 Macro program @@ -78,7 +39,7 @@ Vector3 Vector3::operator+(Vector3 v) return result; } -Vector3 Vector3::operator-(const Vector3 &v) +Vector3 Vector3::operator-(const Vector3 &v) const { Vector3 result; asm volatile( // VU0 Macro program @@ -91,17 +52,7 @@ Vector3 Vector3::operator-(const Vector3 &v) return result; } -Vector3 Vector3::operator-(void) -{ - Vector3 result; - result.x = -x; - result.y = -y; - result.z = -z; - return result; -} - -/** Also called "cross product" */ -Vector3 Vector3::operator*(Vector3 &v) +Vector3 Vector3::operator*(const Vector3 &v) const { Vector3 res; asm volatile( // VU0 Macro program @@ -119,7 +70,7 @@ Vector3 Vector3::operator*(Vector3 &v) return res; } -Vector3 Vector3::operator*(const float &t) +Vector3 Vector3::operator*(const float &t) const { Vector3 result; asm volatile( @@ -133,6 +84,26 @@ Vector3 Vector3::operator*(const float &t) return result; } +Vector3 Vector3::operator/(const float &t) const +{ + Vector3 result; + result.x = x / t; + result.y = y / t; + result.z = z / t; + return result; +} + +void Vector3::operator+=(const Vector3 &t) +{ + asm volatile( // VU0 Macro program + "lqc2 vf4, 0x0(%0) \n\t" + "lqc2 vf5, 0x0(%1) \n\t" + "vadd.xyz vf4, vf4, vf5 \n\t" + "sqc2 vf4, 0x0(%0) \n\t" + : + : "r"(this->xyz), "r"(t.xyz)); +} + void Vector3::operator*=(const float &t) { asm volatile( @@ -145,54 +116,46 @@ void Vector3::operator*=(const float &t) : "r"(this->xyz), "f"(t)); } -Vector3 Vector3::operator/(float t) +// ---- +// Functions +// ---- + +void Vector3::set(const Vector3 &v) { - Vector3 result; - result.x = x / t; - result.y = y / t; - result.z = z / t; + asm volatile( // VU0 Macro program + "lq $6, 0x0(%1) \n\t" + "sq $6, 0x0(%0) \n\t" + : + : "r"(this->xyz), "r"(v.xyz)); +} + +void Vector3::set(const float &t_x, const float &t_y, const float &t_z) +{ + x = t_x; + y = t_y; + z = t_z; +} + +float Vector3::innerProduct(const Vector3 &v) const +{ + float result; + asm volatile( // VU0 Macro program + "lqc2 vf4, 0x0(%1) \n\t" + "lqc2 vf5, 0x0(%2) \n\t" + "vmul.xyz vf6, vf4, vf5 \n\t" + "vaddy.x vf6, vf6, vf6 \n\t" + "vaddz.x vf6, vf6, vf6 \n\t" + "qmfc2 $2, vf6 \n\t" + "mtc1 $2, %0 \n\t" + : "=f"(result) + : "r"(this->xyz), "r"(v.xyz)); return result; + // return (x * v.x + y * v.y + z * v.z); } -u8 Vector3::shouldBeBackfaceCulled(const Vector3 *t_cameraPos, const Vector3 *v0, const Vector3 *v1, const Vector3 *v2) +float Vector3::length() const { - register float dot; - asm volatile( - "lqc2 vf4, 0x0(%1) \n\t" // vf4 = cameraPos - "lqc2 vf5, 0x0(%2) \n\t" // vf5 = v0 - "lqc2 vf6, 0x0(%3) \n\t" // vf6 = v1 - "lqc2 vf7, 0x0(%4) \n\t" // vf7 = v2 - "vsub.xyz vf8, vf7, vf5 \n\t" // vf8 = vf7(v2) - vf5(v0) - "vsub.xyz vf9, vf6, vf5 \n\t" // vf9 = vf6(v1) - vf5(v0) - "vopmula.xyz ACC, vf8, vf9 \n\t" // vf6 = cross(vf8, vf9) - "vopmsub.xyz vf6, vf9, vf8 \n\t" - "vsub.w vf6, vf6, vf6 \n\t" - "vsub.xyz vf7, vf5, vf4 \n\t" // vf7 = vf5(v0) - vf4(cameraPos) - "vmul.xyz vf5, vf7, vf6 \n\t" // vf5 = dot(vf7, vf6) - "vaddy.x vf5, vf5, vf5 \n\t" - "vaddz.x vf5, vf5, vf5 \n\t" - "qmfc2 $2, vf5 \n\t" // store result on `dot` variable - "mtc1 $2, %0 \n\t" - : "=f"(dot) - : "r"(t_cameraPos->xyz), "r"(v0->xyz), "r"(v1->xyz), "r"(v2->xyz)); - return dot <= 0.0F; -} - -/** Checks intersection with given square */ -u8 Vector3::collidesSquare(const Vector3 &t_min, const Vector3 &t_max) const -{ - return ((this->x <= t_max.x && this->x >= t_min.x) && (this->y < t_max.y && this->y >= t_min.y) && (this->z <= t_max.z && this->z >= t_min.z)) ? 1 : 0; -} - -/** Checks is this vector is on given square */ -u8 Vector3::isOnSquare(const Vector3 &t_min, const Vector3 &t_max) const -{ - return ((this->x <= t_max.x && this->x >= t_min.x) && (this->y >= t_max.y) && (this->z <= t_max.z && this->z >= t_min.z)) ? 1 : 0; -} - -float Vector3::length() -{ - register float result; + float result; asm volatile( // VU0 Macro program "lqc2 vf4, 0x0(%1) \n\t" "vmul.xyz vf5, vf4, vf4 \n\t" @@ -227,85 +190,6 @@ void Vector3::normalize() : "r"(this->xyz)); } -/** Also called dot3 */ -float Vector3::innerProduct(Vector3 &v) -{ - register float result; - asm volatile( // VU0 Macro program - "lqc2 vf4, 0x0(%1) \n\t" - "lqc2 vf5, 0x0(%2) \n\t" - "vmul.xyz vf6, vf4, vf5 \n\t" - "vaddy.x vf6, vf6, vf6 \n\t" - "vaddz.x vf6, vf6, vf6 \n\t" - "qmfc2 $2, vf6 \n\t" - "mtc1 $2, %0 \n\t" - : "=f"(result) - : "r"(this->xyz), "r"(v.xyz)); - return result; - // return (x * v.x + y * v.y + z * v.z); -} - -void Vector3::set(const float &t_x, const float &t_y, const float &t_z) -{ - x = t_x; - y = t_y; - z = t_z; -} - -void Vector3::rotate(const Vector3 &v, u8 inversed) -{ - VECTOR cameraPos = {x, y, z, 0.0F}; - VECTOR rotation; - if (inversed) - { - rotation[0] = -v.x; - rotation[1] = -v.y; - rotation[2] = -v.z; - } - else - { - rotation[0] = v.x; - rotation[1] = v.y; - rotation[2] = v.z; - } - rotation[3] = 0.0F; - - MATRIX rotationMatrix; - matrix_unit(rotationMatrix); - matrix_rotate(rotationMatrix, rotationMatrix, rotation); - VECTOR result; - asm volatile( - "lqc2 vf4, 0x0(%1) \n\t" - "lqc2 vf5, 0x10(%1) \n\t" - "lqc2 vf6, 0x20(%1) \n\t" - "lqc2 vf7, 0x30(%1) \n\t" - "lqc2 vf8, 0x0(%2) \n\t" - "vmulax.xyzw ACC, vf4, vf8 \n\t" - "vmadday.xyzw ACC, vf5, vf8 \n\t" - "vmaddaz.xyzw ACC, vf6, vf8 \n\t" - "vmaddw.xyzw vf9, vf7, vf8 \n\t" - "sqc2 vf9, 0x0(%0) \n\t" - : - : "r"(&result), "r"(&rotationMatrix), "r"(&cameraPos)); - set(Vector3(result[0], result[1], result[2])); -} - -void Vector3::set(const Vector3 &v) -{ - this->x = v.x; - this->y = v.y; - this->z = v.z; -} - -void Vector3::copy(Vector3 &v) -{ - asm volatile( // VU0 Macro program - "lq $6, 0x0(%1) \n\t" - "sq $6, 0x0(%0) \n\t" - : - : "r"(v.xyz), "r"(this->xyz)); -} - float Vector3::distanceTo(const Vector3 &v) const { register float result; @@ -329,7 +213,42 @@ float Vector3::distanceTo(const Vector3 &v) const // (this->z - v.z) * (this->z - v.z)); } -const void Vector3::print() const +u8 Vector3::shouldBeBackfaceCulled(const Vector3 *t_cameraPos, const Vector3 *t_v0, const Vector3 *t_v1, const Vector3 *t_v2) { - printf("Vector3(%f, %f, %f)\n", x, y, z); + register float dot; + asm volatile( + "lqc2 vf4, 0x0(%1) \n\t" // vf4 = cameraPos + "lqc2 vf5, 0x0(%2) \n\t" // vf5 = v0 + "lqc2 vf6, 0x0(%3) \n\t" // vf6 = v1 + "lqc2 vf7, 0x0(%4) \n\t" // vf7 = v2 + "vsub.xyz vf8, vf7, vf5 \n\t" // vf8 = vf7(v2) - vf5(v0) + "vsub.xyz vf9, vf6, vf5 \n\t" // vf9 = vf6(v1) - vf5(v0) + "vopmula.xyz ACC, vf8, vf9 \n\t" // vf6 = cross(vf8, vf9) + "vopmsub.xyz vf6, vf9, vf8 \n\t" + "vsub.w vf6, vf6, vf6 \n\t" + "vsub.xyz vf7, vf5, vf4 \n\t" // vf7 = vf5(v0) - vf4(cameraPos) + "vmul.xyz vf5, vf7, vf6 \n\t" // vf5 = dot(vf7, vf6) + "vaddy.x vf5, vf5, vf5 \n\t" + "vaddz.x vf5, vf5, vf5 \n\t" + "qmfc2 $2, vf5 \n\t" // store result on `dot` variable + "mtc1 $2, %0 \n\t" + : "=f"(dot) + : "r"(t_cameraPos->xyz), "r"(t_v0->xyz), "r"(t_v1->xyz), "r"(t_v2->xyz)); + return dot <= 0.0F; +} + +void Vector3::setByLerp(const Vector3 &t_v1, const Vector3 &t_v2, const float &t_interp, const float &t_scale) +{ + asm volatile( + "lqc2 vf4, 0x0(%1) \n\t" // vf4 = v1 + "lqc2 vf5, 0x0(%2) \n\t" // vf5 = v2 + "mfc1 $8, %3 \n\t" // vf6 = t + "qmtc2 $8, vf6 \n\t" // lerp: + "vsub.xyz vf7, vf5, vf4 \n\t" // vf7 = v2 - v1 + "vmulx.xyz vf8, vf7, vf6 \n\t" // vf8 = vf7 * t + "vadd.xyz vf9, vf8, vf4 \n\t" // vf9 = vf8 + vf4 + "sqc2 vf9, 0x0(%0) \n\t" // v0 = vf9 + : + : "r"(&this->xyz), "r"(&t_v1.xyz), "r"(&t_v2.xyz), "f"(t_interp)); + operator*=(t_scale); }