From 82a892cededa92521cc22e595ad0a7067f132a9e Mon Sep 17 00:00:00 2001 From: kearwood Date: Mon, 8 Aug 2022 00:20:45 -0700 Subject: [PATCH] Added editorconfig file for VS C++ code style formatting. Applied C++ auto formatting. --- .editorconfig | 136 +++++++++ include/aabb.h | 60 ++-- include/hitinfo.h | 31 +- include/matrix2.h | 74 ++--- include/matrix2x3.h | 82 +++--- include/matrix4.h | 105 +++---- include/quaternion.h | 86 +++--- include/scalar.h | 4 +- include/triangle3.h | 47 ++-- include/vector2.h | 68 ++--- include/vector2i.h | 64 +++-- include/vector3.h | 102 +++---- include/vector4.h | 78 +++--- src/aabb.cpp | 447 ++++++++++++++--------------- src/hitinfo.cpp | 50 ++-- src/matrix2.cpp | 234 ++++++++-------- src/matrix2x3.cpp | 276 +++++++++--------- src/matrix4.cpp | 655 ++++++++++++++++++++++--------------------- src/quaternion.cpp | 618 +++++++++++++++++++++------------------- src/scalar.cpp | 4 +- src/triangle3.cpp | 498 ++++++++++++++++---------------- src/vector2.cpp | 301 +++++++++++--------- src/vector2i.cpp | 297 +++++++++++--------- src/vector3.cpp | 599 +++++++++++++++++++++------------------ src/vector4.cpp | 440 ++++++++++++++++------------- 25 files changed, 2876 insertions(+), 2480 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b4829f5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,136 @@ +# Visual Studio generated .editorconfig file with C++ settings. +root = true + +[*.{c++,cc,cpp,cppm,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}] + +# Visual C++ Code Style settings + +cpp_generate_documentation_comments = xml + +# Visual C++ Formatting settings + +cpp_indent_braces = false +cpp_indent_multi_line_relative_to = innermost_parenthesis +cpp_indent_within_parentheses = indent +cpp_indent_preserve_within_parentheses = true +cpp_indent_case_contents = true +cpp_indent_case_labels = false +cpp_indent_case_contents_when_block = false +cpp_indent_lambda_braces_when_parameter = true +cpp_indent_goto_labels = one_left +cpp_indent_preprocessor = leftmost_column +cpp_indent_access_specifiers = false +cpp_indent_namespace_contents = false +cpp_indent_preserve_comments = false +cpp_new_line_before_open_brace_namespace = ignore +cpp_new_line_before_open_brace_type = ignore +cpp_new_line_before_open_brace_function = ignore +cpp_new_line_before_open_brace_block = false +cpp_new_line_before_open_brace_lambda = ignore +cpp_new_line_scope_braces_on_separate_lines = false +cpp_new_line_close_brace_same_line_empty_type = false +cpp_new_line_close_brace_same_line_empty_function = false +cpp_new_line_before_catch = true +cpp_new_line_before_else = true +cpp_new_line_before_while_in_do_while = false +cpp_space_before_function_open_parenthesis = remove +cpp_space_within_parameter_list_parentheses = false +cpp_space_between_empty_parameter_list_parentheses = false +cpp_space_after_keywords_in_control_flow_statements = true +cpp_space_within_control_flow_statement_parentheses = false +cpp_space_before_lambda_open_parenthesis = false +cpp_space_within_cast_parentheses = false +cpp_space_after_cast_close_parenthesis = false +cpp_space_within_expression_parentheses = false +cpp_space_before_block_open_brace = true +cpp_space_between_empty_braces = false +cpp_space_before_initializer_list_open_brace = false +cpp_space_within_initializer_list_braces = true +cpp_space_preserve_in_initializer_list = true +cpp_space_before_open_square_bracket = false +cpp_space_within_square_brackets = false +cpp_space_before_empty_square_brackets = false +cpp_space_between_empty_square_brackets = false +cpp_space_group_square_brackets = true +cpp_space_within_lambda_brackets = false +cpp_space_between_empty_lambda_brackets = false +cpp_space_before_comma = false +cpp_space_after_comma = true +cpp_space_remove_around_member_operators = true +cpp_space_before_inheritance_colon = true +cpp_space_before_constructor_colon = true +cpp_space_remove_before_semicolon = true +cpp_space_after_semicolon = true +cpp_space_remove_around_unary_operator = true +cpp_space_around_binary_operator = insert +cpp_space_around_assignment_operator = insert +cpp_space_pointer_reference_alignment = left +cpp_space_around_ternary_operator = insert +cpp_wrap_preserve_blocks = one_liners + +[*.{c++,cc,cpp,cppm,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}] + +# Visual C++ Code Style settings + +cpp_generate_documentation_comments = xml + +# Visual C++ Formatting settings + +cpp_indent_braces = false +cpp_indent_multi_line_relative_to = outermost_parenthesis +cpp_indent_within_parentheses = indent +cpp_indent_preserve_within_parentheses = true +cpp_indent_case_contents = true +cpp_indent_case_labels = false +cpp_indent_case_contents_when_block = false +cpp_indent_lambda_braces_when_parameter = true +cpp_indent_goto_labels = one_left +cpp_indent_preprocessor = leftmost_column +cpp_indent_access_specifiers = false +cpp_indent_namespace_contents = false +cpp_indent_preserve_comments = false +cpp_new_line_before_open_brace_namespace = same_line +cpp_new_line_before_open_brace_type = new_line +cpp_new_line_before_open_brace_function = new_line +cpp_new_line_before_open_brace_block = same_line +cpp_new_line_before_open_brace_lambda = same_line +cpp_new_line_scope_braces_on_separate_lines = true +cpp_new_line_close_brace_same_line_empty_type = false +cpp_new_line_close_brace_same_line_empty_function = false +cpp_new_line_before_catch = false +cpp_new_line_before_else = false +cpp_new_line_before_while_in_do_while = false +cpp_space_before_function_open_parenthesis = remove +cpp_space_within_parameter_list_parentheses = false +cpp_space_between_empty_parameter_list_parentheses = false +cpp_space_after_keywords_in_control_flow_statements = true +cpp_space_within_control_flow_statement_parentheses = false +cpp_space_before_lambda_open_parenthesis = false +cpp_space_within_cast_parentheses = false +cpp_space_after_cast_close_parenthesis = false +cpp_space_within_expression_parentheses = false +cpp_space_before_block_open_brace = true +cpp_space_between_empty_braces = false +cpp_space_before_initializer_list_open_brace = false +cpp_space_within_initializer_list_braces = true +cpp_space_preserve_in_initializer_list = true +cpp_space_before_open_square_bracket = false +cpp_space_within_square_brackets = false +cpp_space_before_empty_square_brackets = false +cpp_space_between_empty_square_brackets = false +cpp_space_group_square_brackets = true +cpp_space_within_lambda_brackets = false +cpp_space_between_empty_lambda_brackets = false +cpp_space_before_comma = false +cpp_space_after_comma = true +cpp_space_remove_around_member_operators = true +cpp_space_before_inheritance_colon = true +cpp_space_before_constructor_colon = true +cpp_space_remove_before_semicolon = true +cpp_space_after_semicolon = true +cpp_space_remove_around_unary_operator = true +cpp_space_around_binary_operator = insert +cpp_space_around_assignment_operator = insert +cpp_space_pointer_reference_alignment = left +cpp_space_around_ternary_operator = insert +cpp_wrap_preserve_blocks = never diff --git a/include/aabb.h b/include/aabb.h index cd2e1e6..ebaa688 100644 --- a/include/aabb.h +++ b/include/aabb.h @@ -43,61 +43,63 @@ namespace kraken { class Matrix4; -class AABB { +class AABB +{ public: Vector3 min; Vector3 max; - void init(const Vector3 &minPoint, const Vector3 &maxPoint); - void init(const Vector3 &corner1, const Vector3 &corner2, const Matrix4 &modelMatrix); + void init(const Vector3& minPoint, const Vector3& maxPoint); + void init(const Vector3& corner1, const Vector3& corner2, const Matrix4& modelMatrix); void init(); - static AABB Create(const Vector3 &minPoint, const Vector3 &maxPoint); - static AABB Create(const Vector3 &corner1, const Vector3 &corner2, const Matrix4 &modelMatrix); + static AABB Create(const Vector3& minPoint, const Vector3& maxPoint); + static AABB Create(const Vector3& corner1, const Vector3& corner2, const Matrix4& modelMatrix); static AABB Create(); - void scale(const Vector3 &s); + void scale(const Vector3& s); void scale(float s); - + Vector3 center() const; Vector3 size() const; float volume() const; bool intersects(const AABB& b) const; - bool contains(const AABB &b) const; - bool contains(const Vector3 &v) const; - - bool intersectsLine(const Vector3 &v1, const Vector3 &v2) const; - bool intersectsRay(const Vector3 &v1, const Vector3 &dir) const; - bool intersectsSphere(const Vector3 ¢er, float radius) const; - void encapsulate(const AABB & b); - + bool contains(const AABB& b) const; + bool contains(const Vector3& v) const; + + bool intersectsLine(const Vector3& v1, const Vector3& v2) const; + bool intersectsRay(const Vector3& v1, const Vector3& dir) const; + bool intersectsSphere(const Vector3& center, float radius) const; + void encapsulate(const AABB& b); + bool operator ==(const AABB& b) const; bool operator !=(const AABB& b) const; - + // Comparison operators are implemented to allow insertion into sorted containers such as std::set bool operator >(const AABB& b) const; bool operator <(const AABB& b) const; - + static AABB Infinite(); static AABB Zero(); - + float longest_radius() const; - Vector3 nearestPoint(const Vector3 & v) const; + Vector3 nearestPoint(const Vector3& v) const; }; static_assert(std::is_pod::value, "kraken::AABB must be a POD type."); } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::AABB &s) const - { - size_t h1 = hash()(s.min); - size_t h2 = hash()(s.max); - return h1 ^ ( h2 << 1 ); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::AABB& s) const + { + size_t h1 = hash()(s.min); + size_t h2 = hash()(s.max); + return h1 ^ (h2 << 1); + } +}; } // namespace std diff --git a/include/hitinfo.h b/include/hitinfo.h index 7a62072..4222d78 100644 --- a/include/hitinfo.h +++ b/include/hitinfo.h @@ -38,26 +38,27 @@ class KRNode; namespace kraken { -class HitInfo { +class HitInfo +{ public: - HitInfo(); - HitInfo(const Vector3 &position, const Vector3 &normal, const float distance); - HitInfo(const Vector3 &position, const Vector3 &normal, const float distance, KRNode *node); - ~HitInfo(); + HitInfo(); + HitInfo(const Vector3& position, const Vector3& normal, const float distance); + HitInfo(const Vector3& position, const Vector3& normal, const float distance, KRNode* node); + ~HitInfo(); - Vector3 getPosition() const; - Vector3 getNormal() const; - float getDistance() const; - KRNode *getNode() const; - bool didHit() const; + Vector3 getPosition() const; + Vector3 getNormal() const; + float getDistance() const; + KRNode* getNode() const; + bool didHit() const; - HitInfo& operator =(const HitInfo& b); + HitInfo& operator =(const HitInfo& b); private: - KRNode *m_node; - Vector3 m_position; - Vector3 m_normal; - float m_distance; + KRNode* m_node; + Vector3 m_position; + Vector3 m_normal; + float m_distance; }; } // namespace kraken diff --git a/include/matrix2.h b/include/matrix2.h index f7fd513..4d7da2b 100644 --- a/include/matrix2.h +++ b/include/matrix2.h @@ -36,54 +36,57 @@ namespace kraken { -class Matrix2 { +class Matrix2 +{ public: - union { - struct { + union + { + struct + { Vector2 axis_x, axis_y; }; // Matrix components, in column-major order float c[4]; }; - + // Default initializer - Creates an identity matrix void init(); - - void init(float *pMat); - - void init(const Vector2 &new_axis_x, const Vector2 &new_axis_y); - void init(const Matrix2 &m); - + void init(float* pMat); + + void init(const Vector2& new_axis_x, const Vector2& new_axis_y); + + void init(const Matrix2& m); + // Overload comparison operator - bool operator==(const Matrix2 &m) const; - + bool operator==(const Matrix2& m) const; + // Overload compound multiply operator - Matrix2& operator*=(const Matrix2 &m); - + Matrix2& operator*=(const Matrix2& m); + float& operator[](unsigned i); float operator[](unsigned i) const; - + // Overload multiply operator //Matrix4& operator*(const Matrix4 &m); - Matrix2 operator*(const Matrix2 &m) const; - - float *getPointer(); - + Matrix2 operator*(const Matrix2& m) const; + + float* getPointer(); + void scale(float x, float y); - void scale(const Vector2 &v); + void scale(const Vector2& v); void scale(float s); void rotate(float angle); bool invert(); void transpose(); - - static Matrix2 Invert(const Matrix2 &m); - static Matrix2 Transpose(const Matrix2 &m); - static Vector2 Dot(const Matrix2 &m, const Vector2 &v); + + static Matrix2 Invert(const Matrix2& m); + static Matrix2 Transpose(const Matrix2& m); + static Vector2 Dot(const Matrix2& m, const Vector2& v); static Matrix2 Rotation(float); - static Matrix2 Scaling(const Vector2 &v); + static Matrix2 Scaling(const Vector2& v); static Matrix2 Identity(); }; static_assert(std::is_pod::value, "kraken::Matrix2 must be a POD type."); @@ -91,16 +94,17 @@ static_assert(std::is_pod::value, "kraken::Matrix2 must be a POD type." } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Matrix2 &s) const - { - size_t h1 = hash()(s.axis_x); - size_t h2 = hash()(s.axis_y); - return h1 ^ (h2 << 1); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Matrix2& s) const + { + size_t h1 = hash()(s.axis_x); + size_t h2 = hash()(s.axis_y); + return h1 ^ (h2 << 1); + } +}; } // namespace std #endif // KRAKEN_MATRIX2_H diff --git a/include/matrix2x3.h b/include/matrix2x3.h index 56da618..0293840 100644 --- a/include/matrix2x3.h +++ b/include/matrix2x3.h @@ -37,55 +37,58 @@ namespace kraken { -class Matrix2x3 { +class Matrix2x3 +{ public: - union { - struct { + union + { + struct + { Vector2 axis_x, axis_y, transform; }; // Matrix components, in column-major order float c[6]; }; - + // Default initializer - Creates an identity matrix void init(); - - void init(float *pMat); - - void init(const Vector2 &new_axis_x, const Vector2 &new_axis_y, const Vector2 &new_transform); - void init(const Matrix2x3 &m); - + void init(float* pMat); + + void init(const Vector2& new_axis_x, const Vector2& new_axis_y, const Vector2& new_transform); + + void init(const Matrix2x3& m); + // Overload comparison operator - bool operator==(const Matrix2x3 &m) const; - + bool operator==(const Matrix2x3& m) const; + // Overload compound multiply operator - Matrix2x3& operator*=(const Matrix2x3 &m); - + Matrix2x3& operator*=(const Matrix2x3& m); + float& operator[](unsigned i); float operator[](unsigned i) const; - + // Overload multiply operator - Matrix2x3 operator*(const Matrix2x3 &m) const; - - float *getPointer(); - + Matrix2x3 operator*(const Matrix2x3& m) const; + + float* getPointer(); + void translate(float x, float y); - void translate(const Vector2 &v); + void translate(const Vector2& v); void scale(float x, float y); - void scale(const Vector2 &v); + void scale(const Vector2& v); void scale(float s); void rotate(float angle); bool invert(); - - static Vector2 DotNoTranslate(const Matrix2x3 &m, const Vector2 &v); // Dot product without including translation; useful for transforming normals and tangents - static Matrix2x3 Invert(const Matrix2x3 &m); - static Vector2 Dot(const Matrix2x3 &m, const Vector2 &v); - - static Matrix2x3 Translation(const Vector2 &v); + + static Vector2 DotNoTranslate(const Matrix2x3& m, const Vector2& v); // Dot product without including translation; useful for transforming normals and tangents + static Matrix2x3 Invert(const Matrix2x3& m); + static Vector2 Dot(const Matrix2x3& m, const Vector2& v); + + static Matrix2x3 Translation(const Vector2& v); static Matrix2x3 Rotation(float angle); - static Matrix2x3 Scaling(const Vector2 &v); + static Matrix2x3 Scaling(const Vector2& v); static Matrix2x3 Identity(); }; static_assert(std::is_pod::value, "kraken::Matrix2x3 must be a POD type."); @@ -93,17 +96,18 @@ static_assert(std::is_pod::value, "kraken::Matrix2x3 must be a POD ty } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Matrix2x3 &s) const - { - size_t h1 = hash()(s.axis_x); - size_t h2 = hash()(s.axis_y); - size_t h3 = hash()(s.transform); - return h1 ^ (h2 << 1) ^ (h3 << 2); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Matrix2x3& s) const + { + size_t h1 = hash()(s.axis_x); + size_t h2 = hash()(s.axis_y); + size_t h3 = hash()(s.transform); + return h1 ^ (h2 << 1) ^ (h3 << 2); + } +}; } // namespace std #endif // KRAKEN_MATRIX2X3_H diff --git a/include/matrix4.h b/include/matrix4.h index ffb4d01..ec694d7 100644 --- a/include/matrix4.h +++ b/include/matrix4.h @@ -38,7 +38,8 @@ namespace kraken { -enum class AXIS { +enum class AXIS +{ X_AXIS, Y_AXIS, Z_AXIS @@ -46,68 +47,71 @@ enum class AXIS { class Quaternion; -class Matrix4 { +class Matrix4 +{ public: - union { - struct { + union + { + struct + { Vector4 axis_x, axis_y, axis_z, transform; }; // Matrix components, in column-major order float c[16]; }; - + // Default initializer - Creates an identity matrix void init(); - - void init(float *pMat); - void init(const Vector3 &new_axis_x, const Vector3 &new_axis_y, const Vector3 &new_axis_z, const Vector3 &new_transform); - void init(const Matrix4 &m); - static Matrix4 Create(float *pMat); - static Matrix4 Create(const Vector3 &new_axis_x, const Vector3 &new_axis_y, const Vector3 &new_axis_z, const Vector3 &new_transform); - + void init(float* pMat); + void init(const Vector3& new_axis_x, const Vector3& new_axis_y, const Vector3& new_axis_z, const Vector3& new_transform); + void init(const Matrix4& m); + + static Matrix4 Create(float* pMat); + static Matrix4 Create(const Vector3& new_axis_x, const Vector3& new_axis_y, const Vector3& new_axis_z, const Vector3& new_transform); + // Overload comparison operator - bool operator==(const Matrix4 &m) const; - + bool operator==(const Matrix4& m) const; + // Overload compound multiply operator - Matrix4& operator*=(const Matrix4 &m); - + Matrix4& operator*=(const Matrix4& m); + float& operator[](unsigned i); float operator[](unsigned i) const; - + // Overload multiply operator //Matrix4& operator*(const Matrix4 &m); - Matrix4 operator*(const Matrix4 &m) const; - - float *getPointer(); - + Matrix4 operator*(const Matrix4& m) const; + + float* getPointer(); + void perspective(float fov, float aspect, float nearz, float farz); void ortho(float left, float right, float top, float bottom, float nearz, float farz); void translate(float x, float y, float z); - void translate(const Vector3 &v); + void translate(const Vector3& v); void scale(float x, float y, float z); - void scale(const Vector3 &v); + void scale(const Vector3& v); void scale(float s); void rotate(float angle, AXIS axis); - void rotate(const Quaternion &q); + void rotate(const Quaternion& q); void bias(); bool invert(); void transpose(); - - static Vector3 DotNoTranslate(const Matrix4 &m, const Vector3 &v); // Dot product without including translation; useful for transforming normals and tangents - static Matrix4 Invert(const Matrix4 &m); - static Matrix4 Transpose(const Matrix4 &m); - static Vector3 Dot(const Matrix4 &m, const Vector3 &v); - static Vector4 Dot4(const Matrix4 &m, const Vector4 &v); - static float DotW(const Matrix4 &m, const Vector3 &v); - static Vector3 DotWDiv(const Matrix4 &m, const Vector3 &v); - - static Matrix4 LookAt(const Vector3 &cameraPos, const Vector3 &lookAtPos, const Vector3 &upDirection); - - static Matrix4 Translation(const Vector3 &v); - static Matrix4 Rotation(const Vector3 &v); - static Matrix4 Scaling(const Vector3 &v); + + static Vector3 DotNoTranslate(const Matrix4& m, const Vector3& v); // Dot product without including translation; useful for transforming normals and tangents + static Matrix4 Invert(const Matrix4& m); + static Matrix4 Transpose(const Matrix4& m); + static Vector3 Dot(const Matrix4& m, const Vector3& v); + static Vector4 Dot4(const Matrix4& m, const Vector4& v); + static float DotW(const Matrix4& m, const Vector3& v); + static Vector3 DotWDiv(const Matrix4& m, const Vector3& v); + + static Matrix4 LookAt(const Vector3& cameraPos, const Vector3& lookAtPos, const Vector3& upDirection); + + static Matrix4 Translation(const Vector3& v); + static Matrix4 Rotation(const Vector3& v); + static Matrix4 Scaling(const Vector3& v); static Matrix4 Identity(); }; static_assert(std::is_pod::value, "kraken::Matrix4 must be a POD type."); @@ -115,18 +119,19 @@ static_assert(std::is_pod::value, "kraken::Matrix4 must be a POD type." } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Matrix4 &s) const - { - size_t h1 = hash()(s.axis_x); - size_t h2 = hash()(s.axis_y); - size_t h3 = hash()(s.axis_z); - size_t h4 = hash()(s.transform); - return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Matrix4& s) const + { + size_t h1 = hash()(s.axis_x); + size_t h2 = hash()(s.axis_y); + size_t h3 = hash()(s.axis_z); + size_t h4 = hash()(s.transform); + return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3); + } +}; } // namespace std #endif // KRAKEN_MATRIX4_H diff --git a/include/quaternion.h b/include/quaternion.h index fa49170..f655c4a 100644 --- a/include/quaternion.h +++ b/include/quaternion.h @@ -36,10 +36,13 @@ namespace kraken { -class Quaternion { +class Quaternion +{ public: - union { - struct { + union + { + struct + { float w, x, y, z; }; float c[4]; @@ -48,71 +51,72 @@ public: void init(); void init(float w, float x, float y, float z); void init(const Quaternion& p); - void init(const Vector3 &euler); - void init(const Vector3 &from_vector, const Vector3 &to_vector); + void init(const Vector3& euler); + void init(const Vector3& from_vector, const Vector3& to_vector); static Quaternion Create(); static Quaternion Create(float w, float x, float y, float z); static Quaternion Create(const Quaternion& p); - static Quaternion Create(const Vector3 &euler); - static Quaternion Create(const Vector3 &from_vector, const Vector3 &to_vector); - - Quaternion operator +(const Quaternion &v) const; - Quaternion operator -(const Quaternion &v) const; + static Quaternion Create(const Vector3& euler); + static Quaternion Create(const Vector3& from_vector, const Vector3& to_vector); + + Quaternion operator +(const Quaternion& v) const; + Quaternion operator -(const Quaternion& v) const; Quaternion operator +() const; Quaternion operator -() const; - - Quaternion operator *(const Quaternion &v); + + Quaternion operator *(const Quaternion& v); Quaternion operator *(float num) const; Quaternion operator /(float num) const; - + Quaternion& operator +=(const Quaternion& v); Quaternion& operator -=(const Quaternion& v); Quaternion& operator *=(const Quaternion& v); Quaternion& operator *=(const float& v); Quaternion& operator /=(const float& v); - friend bool operator ==(Quaternion &v1, Quaternion &v2); - friend bool operator !=(Quaternion &v1, Quaternion &v2); + friend bool operator ==(Quaternion& v1, Quaternion& v2); + friend bool operator !=(Quaternion& v1, Quaternion& v2); float& operator [](unsigned i); float operator [](unsigned i) const; - - void setEulerXYZ(const Vector3 &euler); - void setEulerZYX(const Vector3 &euler); + + void setEulerXYZ(const Vector3& euler); + void setEulerZYX(const Vector3& euler); Vector3 eulerXYZ() const; Matrix4 rotationMatrix() const; - + void normalize(); - static Quaternion Normalize(const Quaternion &v1); - + static Quaternion Normalize(const Quaternion& v1); + void conjugate(); - static Quaternion Conjugate(const Quaternion &v1); + static Quaternion Conjugate(const Quaternion& v1); void invert(); - static Quaternion Invert(const Quaternion &v1); - - static Quaternion FromAngleAxis(const Vector3 &axis, float angle); - static Quaternion FromRotationMatrix(const Matrix4 &m); - static Quaternion Lerp(const Quaternion &a, const Quaternion &b, float t); - static Quaternion Slerp(const Quaternion &a, const Quaternion &b, float t); - static float Dot(const Quaternion &v1, const Quaternion &v2); + static Quaternion Invert(const Quaternion& v1); + + static Quaternion FromAngleAxis(const Vector3& axis, float angle); + static Quaternion FromRotationMatrix(const Matrix4& m); + static Quaternion Lerp(const Quaternion& a, const Quaternion& b, float t); + static Quaternion Slerp(const Quaternion& a, const Quaternion& b, float t); + static float Dot(const Quaternion& v1, const Quaternion& v2); }; static_assert(std::is_pod::value, "kraken::Quaternion must be a POD type."); } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Quaternion &s) const - { - size_t h1 = hash()(s.c[0]); - size_t h2 = hash()(s.c[1]); - size_t h3 = hash()(s.c[2]); - size_t h4 = hash()(s.c[3]); - return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Quaternion& s) const + { + size_t h1 = hash()(s.c[0]); + size_t h2 = hash()(s.c[1]); + size_t h3 = hash()(s.c[2]); + size_t h4 = hash()(s.c[3]); + return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3); + } +}; } // namespace std #endif // KRAKEN_QUATERNION_H diff --git a/include/scalar.h b/include/scalar.h index ee3c758..d103169 100644 --- a/include/scalar.h +++ b/include/scalar.h @@ -34,8 +34,8 @@ namespace kraken { - float SmoothStep(float a, float b, float t); - float Lerp(float a, float b, float t); +float SmoothStep(float a, float b, float t); +float Lerp(float a, float b, float t); }; // namespace kraken diff --git a/include/triangle3.h b/include/triangle3.h index 35368a6..b35adc7 100644 --- a/include/triangle3.h +++ b/include/triangle3.h @@ -41,40 +41,41 @@ class Triangle3 public: Vector3 vert[3]; - void init(const Triangle3 &tri); - void init(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3); - static Triangle3 Create(const Triangle3 &tri); - static Triangle3 Create(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3); - + void init(const Triangle3& tri); + void init(const Vector3& v1, const Vector3& v2, const Vector3& v3); + static Triangle3 Create(const Triangle3& tri); + static Triangle3 Create(const Vector3& v1, const Vector3& v2, const Vector3& v3); + Vector3 calculateNormal() const; - + bool operator ==(const Triangle3& b) const; bool operator !=(const Triangle3& b) const; Vector3& operator[](unsigned int i); Vector3 operator[](unsigned int i) const; - - bool rayCast(const Vector3 &start, const Vector3 &dir, Vector3 &hit_point) const; - bool sphereCast(const Vector3 &start, const Vector3 &dir, float radius, Vector3 &hit_point, float &hit_distance) const; - - bool containsPoint(const Vector3 &p) const; - Vector3 closestPointOnTriangle(const Vector3 &p) const; + + bool rayCast(const Vector3& start, const Vector3& dir, Vector3& hit_point) const; + bool sphereCast(const Vector3& start, const Vector3& dir, float radius, Vector3& hit_point, float& hit_distance) const; + + bool containsPoint(const Vector3& p) const; + Vector3 closestPointOnTriangle(const Vector3& p) const; }; static_assert(std::is_pod::value, "kraken::Triangle3 must be a POD type."); } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Triangle3 &s) const - { - size_t h1 = hash()(s.vert[0]); - size_t h2 = hash()(s.vert[1]); - size_t h3 = hash()(s.vert[2]); - return h1 ^ (h2 << 1) ^ (h3 << 2); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Triangle3& s) const + { + size_t h1 = hash()(s.vert[0]); + size_t h2 = hash()(s.vert[1]); + size_t h3 = hash()(s.vert[2]); + return h1 ^ (h2 << 1) ^ (h3 << 2); + } +}; } // namespace std #endif // KRAKEN_TRIANGLE3_H diff --git a/include/vector2.h b/include/vector2.h index bfe842e..3940801 100644 --- a/include/vector2.h +++ b/include/vector2.h @@ -38,65 +38,68 @@ namespace kraken { -class Vector2 { - +class Vector2 +{ + public: - union { - struct { + union + { + struct + { float x, y; }; float c[2]; }; - + void init(); void init(float X, float Y); void init(float v); - void init(float *v); - void init(const Vector2 &v); + void init(float* v); + void init(const Vector2& v); static Vector2 Create(); static Vector2 Create(float X, float Y); static Vector2 Create(float v); - static Vector2 Create(float *v); - static Vector2 Create(const Vector2 &v); + static Vector2 Create(float* v); + static Vector2 Create(const Vector2& v); // Vector2 swizzle getters Vector2 yx() const; - + // Vector2 swizzle setters - void yx(const Vector2 &v); - + void yx(const Vector2& v); + Vector2 operator +(const Vector2& b) const; Vector2 operator -(const Vector2& b) const; Vector2 operator +() const; Vector2 operator -() const; Vector2 operator *(const float v) const; Vector2 operator /(const float v) const; - + Vector2& operator +=(const Vector2& b); Vector2& operator -=(const Vector2& b); Vector2& operator *=(const float v); Vector2& operator /=(const float v); - + // Comparison operators are implemented to allow insertion into sorted containers such as std::set bool operator >(const Vector2& b) const; bool operator <(const Vector2& b) const; - + bool operator ==(const Vector2& b) const; bool operator !=(const Vector2& b) const; - + float& operator[](unsigned i); float operator[](unsigned i) const; - + float sqrMagnitude() const; float magnitude() const; void normalize(); - static Vector2 Normalize(const Vector2 &v); + static Vector2 Normalize(const Vector2& v); - static float Cross(const Vector2 &v1, const Vector2 &v2); - static float Dot(const Vector2 &v1, const Vector2 &v2); - static Vector2 Min(const Vector2 &v1, const Vector2 &v2); - static Vector2 Max(const Vector2 &v1, const Vector2 &v2); + static float Cross(const Vector2& v1, const Vector2& v2); + static float Dot(const Vector2& v1, const Vector2& v2); + static Vector2 Min(const Vector2& v1, const Vector2& v2); + static Vector2 Max(const Vector2& v1, const Vector2& v2); static Vector2 Min(); static Vector2 Max(); static Vector2 Zero(); @@ -107,16 +110,17 @@ static_assert(std::is_pod::value, "kraken::Vector2 must be a POD type." } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Vector2 &s) const - { - size_t h1 = hash()(s.x); - size_t h2 = hash()(s.y); - return h1 ^ (h2 << 1); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Vector2& s) const + { + size_t h1 = hash()(s.x); + size_t h2 = hash()(s.y); + return h1 ^ (h2 << 1); + } +}; } // namespace std #endif // KRAKEN_VECTOR2_H diff --git a/include/vector2i.h b/include/vector2i.h index 6893b45..9034876 100644 --- a/include/vector2i.h +++ b/include/vector2i.h @@ -37,11 +37,14 @@ namespace kraken { -class Vector2i { +class Vector2i +{ public: - union { - struct { + union + { + struct + { int x, y; }; int c[2]; @@ -50,52 +53,52 @@ public: void init(); void init(int X, int Y); void init(int v); - void init(int *v); - void init(const Vector2i &v); + void init(int* v); + void init(const Vector2i& v); static Vector2i Create(); static Vector2i Create(int X, int Y); static Vector2i Create(int v); - static Vector2i Create(int *v); - static Vector2i Create(const Vector2i &v); + static Vector2i Create(int* v); + static Vector2i Create(const Vector2i& v); // Vector2 swizzle getters Vector2i yx() const; - + // Vector2 swizzle setters - void yx(const Vector2i &v); - + void yx(const Vector2i& v); + Vector2i operator +(const Vector2i& b) const; Vector2i operator -(const Vector2i& b) const; Vector2i operator +() const; Vector2i operator -() const; Vector2i operator *(const int v) const; Vector2i operator /(const int v) const; - + Vector2i& operator +=(const Vector2i& b); Vector2i& operator -=(const Vector2i& b); Vector2i& operator *=(const int v); Vector2i& operator /=(const int v); - + // Comparison operators are implemented to allow insertion into sorted containers such as std::set bool operator >(const Vector2i& b) const; bool operator <(const Vector2i& b) const; - + bool operator ==(const Vector2i& b) const; bool operator !=(const Vector2i& b) const; - + int& operator[](unsigned i); int operator[](unsigned i) const; - + int sqrMagnitude() const; int magnitude() const; void normalize(); - static Vector2i Normalize(const Vector2i &v); + static Vector2i Normalize(const Vector2i& v); - static int Cross(const Vector2i &v1, const Vector2i &v2); - static int Dot(const Vector2i &v1, const Vector2i &v2); - static Vector2i Min(const Vector2i &v1, const Vector2i &v2); - static Vector2i Max(const Vector2i &v1, const Vector2i &v2); + static int Cross(const Vector2i& v1, const Vector2i& v2); + static int Dot(const Vector2i& v1, const Vector2i& v2); + static Vector2i Min(const Vector2i& v1, const Vector2i& v2); + static Vector2i Max(const Vector2i& v1, const Vector2i& v2); static Vector2i Min(); static Vector2i Max(); @@ -107,14 +110,15 @@ static_assert(std::is_pod::value, "kraken::Vector2i must be a POD type } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Vector2i &s) const - { - size_t h1 = hash()(s.x); - size_t h2 = hash()(s.y); - return h1 ^ (h2 << 1); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Vector2i& s) const + { + size_t h1 = hash()(s.x); + size_t h2 = hash()(s.y); + return h1 ^ (h2 << 1); + } +}; } // namespace std diff --git a/include/vector3.h b/include/vector3.h index 8c1c052..01c35af 100644 --- a/include/vector3.h +++ b/include/vector3.h @@ -38,32 +38,35 @@ namespace kraken { -class Vector3 { +class Vector3 +{ public: - union { - struct { + union + { + struct + { float x, y, z; }; float c[3]; }; - + void init(); void init(float X, float Y, float Z); void init(float v); - void init(float *v); - void init(double *v); - void init(const Vector3 &v); - void init(const Vector4 &v); + void init(float* v); + void init(double* v); + void init(const Vector3& v); + void init(const Vector4& v); static Vector3 Create(); static Vector3 Create(float X, float Y, float Z); static Vector3 Create(float v); - static Vector3 Create(float *v); - static Vector3 Create(double *v); - static Vector3 Create(const Vector3 &v); - static Vector3 Create(const Vector4 &v); + static Vector3 Create(float* v); + static Vector3 Create(double* v); + static Vector3 Create(const Vector3& v); + static Vector3 Create(const Vector4& v); + - // Vector2 swizzle getters Vector2 xx() const; Vector2 xy() const; @@ -74,15 +77,15 @@ public: Vector2 zx() const; Vector2 zy() const; Vector2 zz() const; - + // Vector2 swizzle setters - void xy(const Vector2 &v); - void xz(const Vector2 &v); - void yx(const Vector2 &v); - void yz(const Vector2 &v); - void zx(const Vector2 &v); - void zy(const Vector2 &v); - + void xy(const Vector2& v); + void xz(const Vector2& v); + void yx(const Vector2& v); + void yz(const Vector2& v); + void zx(const Vector2& v); + void zy(const Vector2& v); + Vector3& operator =(const Vector4& b); Vector3 operator +(const Vector3& b) const; Vector3 operator -(const Vector3& b) const; @@ -90,33 +93,33 @@ public: Vector3 operator -() const; Vector3 operator *(const float v) const; Vector3 operator /(const float v) const; - + Vector3& operator +=(const Vector3& b); Vector3& operator -=(const Vector3& b); Vector3& operator *=(const float v); Vector3& operator /=(const float v); - + bool operator ==(const Vector3& b) const; bool operator !=(const Vector3& b) const; - + // Comparison operators are implemented to allow insertion into sorted containers such as std::set bool operator >(const Vector3& b) const; bool operator <(const Vector3& b) const; - + float& operator[](unsigned i); float operator[](unsigned i) const; - + float sqrMagnitude() const; // calculate the square of the magnitude (useful for comparison of magnitudes without the cost of a sqrt() function) float magnitude() const; - - void scale(const Vector3 &v); + + void scale(const Vector3& v); void normalize(); - static Vector3 Normalize(const Vector3 &v); - - static Vector3 Cross(const Vector3 &v1, const Vector3 &v2); - static float Dot(const Vector3 &v1, const Vector3 &v2); - static Vector3 Min(const Vector3 &v1, const Vector3 &v2); - static Vector3 Max(const Vector3 &v1, const Vector3 &v2); + static Vector3 Normalize(const Vector3& v); + + static Vector3 Cross(const Vector3& v1, const Vector3& v2); + static float Dot(const Vector3& v1, const Vector3& v2); + static Vector3 Min(const Vector3& v1, const Vector3& v2); + static Vector3 Max(const Vector3& v1, const Vector3& v2); static Vector3 Min(); static Vector3 Max(); @@ -128,25 +131,26 @@ public: static Vector3 Down(); static Vector3 Left(); static Vector3 Right(); - static Vector3 Scale(const Vector3 &v1, const Vector3 &v2); - static Vector3 Lerp(const Vector3 &v1, const Vector3 &v2, float d); - static Vector3 Slerp(const Vector3 &v1, const Vector3 &v2, float d); - static void OrthoNormalize(Vector3 &normal, Vector3 &tangent); // Gram-Schmidt Orthonormalization + static Vector3 Scale(const Vector3& v1, const Vector3& v2); + static Vector3 Lerp(const Vector3& v1, const Vector3& v2, float d); + static Vector3 Slerp(const Vector3& v1, const Vector3& v2, float d); + static void OrthoNormalize(Vector3& normal, Vector3& tangent); // Gram-Schmidt Orthonormalization }; static_assert(std::is_pod::value, "kraken::Vector3 must be a POD type."); } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Vector3 &s) const - { - size_t h1 = hash()(s.x); - size_t h2 = hash()(s.y); - size_t h3 = hash()(s.z); - return h1 ^ (h2 << 1) ^ (h3 << 2); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Vector3& s) const + { + size_t h1 = hash()(s.x); + size_t h2 = hash()(s.y); + size_t h3 = hash()(s.z); + return h1 ^ (h2 << 1) ^ (h3 << 2); + } +}; } // namespace std diff --git a/include/vector4.h b/include/vector4.h index 03d773c..601e6d2 100644 --- a/include/vector4.h +++ b/include/vector4.h @@ -37,11 +37,14 @@ namespace kraken { class Vector3; -class Vector4 { - +class Vector4 +{ + public: - union { - struct { + union + { + struct + { float x, y, z, w; }; float c[4]; @@ -50,47 +53,47 @@ public: void init(); void init(float X, float Y, float Z, float W); void init(float v); - void init(float *v); - void init(const Vector4 &v); - void init(const Vector3 &v, float W); + void init(float* v); + void init(const Vector4& v); + void init(const Vector3& v, float W); static Vector4 Create(); static Vector4 Create(float X, float Y, float Z, float W); static Vector4 Create(float v); - static Vector4 Create(float *v); - static Vector4 Create(const Vector4 &v); - static Vector4 Create(const Vector3 &v, float W); - + static Vector4 Create(float* v); + static Vector4 Create(const Vector4& v); + static Vector4 Create(const Vector3& v, float W); + Vector4 operator +(const Vector4& b) const; Vector4 operator -(const Vector4& b) const; Vector4 operator +() const; Vector4 operator -() const; Vector4 operator *(const float v) const; Vector4 operator /(const float v) const; - + Vector4& operator +=(const Vector4& b); Vector4& operator -=(const Vector4& b); Vector4& operator *=(const float v); Vector4& operator /=(const float v); - + bool operator ==(const Vector4& b) const; bool operator !=(const Vector4& b) const; - + // Comparison operators are implemented to allow insertion into sorted containers such as std::set bool operator >(const Vector4& b) const; bool operator <(const Vector4& b) const; - + float& operator[](unsigned i); float operator[](unsigned i) const; - + float sqrMagnitude() const; // calculate the square of the magnitude (useful for comparison of magnitudes without the cost of a sqrt() function) float magnitude() const; - + void normalize(); - static Vector4 Normalize(const Vector4 &v); - - static float Dot(const Vector4 &v1, const Vector4 &v2); - static Vector4 Min(const Vector4 &v1, const Vector4 &v2); - static Vector4 Max(const Vector4 &v1, const Vector4 &v2); + static Vector4 Normalize(const Vector4& v); + + static float Dot(const Vector4& v1, const Vector4& v2); + static Vector4 Min(const Vector4& v1, const Vector4& v2); + static Vector4 Max(const Vector4& v1, const Vector4& v2); static Vector4 Min(); static Vector4 Max(); @@ -102,25 +105,26 @@ public: static Vector4 Down(); static Vector4 Left(); static Vector4 Right(); - static Vector4 Lerp(const Vector4 &v1, const Vector4 &v2, float d); - static Vector4 Slerp(const Vector4 &v1, const Vector4 &v2, float d); - static void OrthoNormalize(Vector4 &normal, Vector4 &tangent); // Gram-Schmidt Orthonormalization + static Vector4 Lerp(const Vector4& v1, const Vector4& v2, float d); + static Vector4 Slerp(const Vector4& v1, const Vector4& v2, float d); + static void OrthoNormalize(Vector4& normal, Vector4& tangent); // Gram-Schmidt Orthonormalization }; static_assert(std::is_pod::value, "kraken::Vector4 must be a POD type."); } // namespace kraken namespace std { - template<> - struct hash { - public: - size_t operator()(const kraken::Vector4 &s) const - { - size_t h1 = hash()(s.x); - size_t h2 = hash()(s.y); - size_t h3 = hash()(s.z); - size_t h4 = hash()(s.w); - return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3); - } - }; +template<> +struct hash +{ +public: + size_t operator()(const kraken::Vector4& s) const + { + size_t h1 = hash()(s.x); + size_t h2 = hash()(s.y); + size_t h3 = hash()(s.z); + size_t h4 = hash()(s.w); + return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3); + } +}; } // namespace std diff --git a/src/aabb.cpp b/src/aabb.cpp index e3a960f..7d86254 100644 --- a/src/aabb.cpp +++ b/src/aabb.cpp @@ -37,210 +37,210 @@ namespace kraken { void AABB::init() { - min = Vector3::Min(); - max = Vector3::Max(); + min = Vector3::Min(); + max = Vector3::Max(); } AABB AABB::Create() { - AABB r; - r.init(); - return r; + AABB r; + r.init(); + return r; } -void AABB::init(const Vector3 &minPoint, const Vector3 &maxPoint) +void AABB::init(const Vector3& minPoint, const Vector3& maxPoint) { - min = minPoint; - max = maxPoint; + min = minPoint; + max = maxPoint; } -AABB AABB::Create(const Vector3 &minPoint, const Vector3 &maxPoint) +AABB AABB::Create(const Vector3& minPoint, const Vector3& maxPoint) { - AABB r; - r.init(minPoint, maxPoint); - return r; + AABB r; + r.init(minPoint, maxPoint); + return r; } -void AABB::init(const Vector3 &corner1, const Vector3 &corner2, const Matrix4 &modelMatrix) +void AABB::init(const Vector3& corner1, const Vector3& corner2, const Matrix4& modelMatrix) { - for(int iCorner=0; iCorner<8; iCorner++) { - Vector3 sourceCornerVertex = Matrix4::DotWDiv(modelMatrix, Vector3::Create( - (iCorner & 1) == 0 ? corner1.x : corner2.x, - (iCorner & 2) == 0 ? corner1.y : corner2.y, - (iCorner & 4) == 0 ? corner1.z : corner2.z)); - - - if(iCorner == 0) { - min = sourceCornerVertex; - max = sourceCornerVertex; - } else { - if(sourceCornerVertex.x < min.x) min.x = sourceCornerVertex.x; - if(sourceCornerVertex.y < min.y) min.y = sourceCornerVertex.y; - if(sourceCornerVertex.z < min.z) min.z = sourceCornerVertex.z; - if(sourceCornerVertex.x > max.x) max.x = sourceCornerVertex.x; - if(sourceCornerVertex.y > max.y) max.y = sourceCornerVertex.y; - if(sourceCornerVertex.z > max.z) max.z = sourceCornerVertex.z; - } + for (int iCorner = 0; iCorner < 8; iCorner++) { + Vector3 sourceCornerVertex = Matrix4::DotWDiv(modelMatrix, Vector3::Create( + (iCorner & 1) == 0 ? corner1.x : corner2.x, + (iCorner & 2) == 0 ? corner1.y : corner2.y, + (iCorner & 4) == 0 ? corner1.z : corner2.z)); + + + if (iCorner == 0) { + min = sourceCornerVertex; + max = sourceCornerVertex; + } else { + if (sourceCornerVertex.x < min.x) min.x = sourceCornerVertex.x; + if (sourceCornerVertex.y < min.y) min.y = sourceCornerVertex.y; + if (sourceCornerVertex.z < min.z) min.z = sourceCornerVertex.z; + if (sourceCornerVertex.x > max.x) max.x = sourceCornerVertex.x; + if (sourceCornerVertex.y > max.y) max.y = sourceCornerVertex.y; + if (sourceCornerVertex.z > max.z) max.z = sourceCornerVertex.z; } + } } -AABB AABB::Create(const Vector3 &corner1, const Vector3 &corner2, const Matrix4 &modelMatrix) +AABB AABB::Create(const Vector3& corner1, const Vector3& corner2, const Matrix4& modelMatrix) { - AABB r; - r.init(corner1, corner2, modelMatrix); - return r; + AABB r; + r.init(corner1, corner2, modelMatrix); + return r; } bool AABB::operator ==(const AABB& b) const { - return min == b.min && max == b.max; + return min == b.min && max == b.max; } bool AABB::operator !=(const AABB& b) const { - return min != b.min || max != b.max; + return min != b.min || max != b.max; } Vector3 AABB::center() const { - return (min + max) * 0.5f; + return (min + max) * 0.5f; } Vector3 AABB::size() const { - return max - min; + return max - min; } float AABB::volume() const { - Vector3 s = size(); - return s.x * s.y * s.z; + Vector3 s = size(); + return s.x * s.y * s.z; } -void AABB::scale(const Vector3 &s) +void AABB::scale(const Vector3& s) { - Vector3 prev_center = center(); - Vector3 prev_size = size(); - Vector3 new_scale = Vector3::Create(prev_size.x * s.x, - prev_size.y * s.y, - prev_size.z * s.z) * 0.5f; - min = prev_center - new_scale; - max = prev_center + new_scale; + Vector3 prev_center = center(); + Vector3 prev_size = size(); + Vector3 new_scale = Vector3::Create(prev_size.x * s.x, + prev_size.y * s.y, + prev_size.z * s.z) * 0.5f; + min = prev_center - new_scale; + max = prev_center + new_scale; } void AABB::scale(float s) { - scale(Vector3::Create(s)); + scale(Vector3::Create(s)); } bool AABB::operator >(const AABB& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(min > b.min) { - return true; - } else if(min < b.min) { - return false; - } else if(max > b.max) { - return true; - } else { - return false; - } + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (min > b.min) { + return true; + } else if (min < b.min) { + return false; + } else if (max > b.max) { + return true; + } else { + return false; + } } bool AABB::operator <(const AABB& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - - if(min < b.min) { - return true; - } else if(min > b.min) { - return false; - } else if(max < b.max) { - return true; - } else { - return false; - } + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + + if (min < b.min) { + return true; + } else if (min > b.min) { + return false; + } else if (max < b.max) { + return true; + } else { + return false; + } } bool AABB::intersects(const AABB& b) const { - // Return true if the two volumes intersect - return min.x <= b.max.x && min.y <= b.max.y && min.z <= b.max.z && max.x >= b.min.x && max.y >= b.min.y && max.z >= b.min.z; + // Return true if the two volumes intersect + return min.x <= b.max.x && min.y <= b.max.y && min.z <= b.max.z && max.x >= b.min.x && max.y >= b.min.y && max.z >= b.min.z; } -bool AABB::contains(const AABB &b) const +bool AABB::contains(const AABB& b) const { - // Return true if the passed KRAABB is entirely contained within this KRAABB - return b.min.x >= min.x && b.min.y >= min.y && b.min.z >= min.z && b.max.x <= max.x && b.max.y <= max.y && b.max.z <= max.z; + // Return true if the passed KRAABB is entirely contained within this KRAABB + return b.min.x >= min.x && b.min.y >= min.y && b.min.z >= min.z && b.max.x <= max.x && b.max.y <= max.y && b.max.z <= max.z; } -bool AABB::contains(const Vector3 &v) const +bool AABB::contains(const Vector3& v) const { - return v.x >= min.x && v.x <= max.x && v.y >= min.y && v.y <= max.y && v.z >= min.z && v.z <= max.z; + return v.x >= min.x && v.x <= max.x && v.y >= min.y && v.y <= max.y && v.z >= min.z && v.z <= max.z; } AABB AABB::Infinite() { - return AABB::Create(Vector3::Min(), Vector3::Max()); + return AABB::Create(Vector3::Min(), Vector3::Max()); } AABB AABB::Zero() { - return AABB::Create(Vector3::Zero(), Vector3::Zero()); + return AABB::Create(Vector3::Zero(), Vector3::Zero()); } float AABB::longest_radius() const { - float radius1 = (center() - min).magnitude(); - float radius2 = (max - center()).magnitude(); - return radius1 > radius2 ? radius1 : radius2; + float radius1 = (center() - min).magnitude(); + float radius2 = (max - center()).magnitude(); + return radius1 > radius2 ? radius1 : radius2; } -bool AABB::intersectsLine(const Vector3 &v1, const Vector3 &v2) const +bool AABB::intersectsLine(const Vector3& v1, const Vector3& v2) const { - Vector3 dir = Vector3::Normalize(v2 - v1); - float length = (v2 - v1).magnitude(); - - // EZ cases: if the ray starts inside the box, or ends inside - // the box, then it definitely hits the box. - // I'm using this code for ray tracing with an octree, - // so I needed rays that start and end within an - // octree node to COUNT as hits. - // You could modify this test to (ray starts inside and ends outside) - // to qualify as a hit if you wanted to NOT count totally internal rays - if( contains( v1 ) || contains( v2 ) ) - return true ; - - // the algorithm says, find 3 t's, - Vector3 t ; - - // LARGEST t is the only one we need to test if it's on the face. - for(int i = 0 ; i < 3 ; i++) { - if( dir[i] > 0 ) { // CULL BACK FACE - t[i] = ( min[i] - v1[i] ) / dir[i]; - } else { - t[i] = ( max[i] - v1[i] ) / dir[i]; - } + Vector3 dir = Vector3::Normalize(v2 - v1); + float length = (v2 - v1).magnitude(); + + // EZ cases: if the ray starts inside the box, or ends inside + // the box, then it definitely hits the box. + // I'm using this code for ray tracing with an octree, + // so I needed rays that start and end within an + // octree node to COUNT as hits. + // You could modify this test to (ray starts inside and ends outside) + // to qualify as a hit if you wanted to NOT count totally internal rays + if (contains(v1) || contains(v2)) + return true; + + // the algorithm says, find 3 t's, + Vector3 t; + + // LARGEST t is the only one we need to test if it's on the face. + for (int i = 0; i < 3; i++) { + if (dir[i] > 0) { // CULL BACK FACE + t[i] = (min[i] - v1[i]) / dir[i]; + } else { + t[i] = (max[i] - v1[i]) / dir[i]; } - - int mi = 0; - if(t[1] > t[mi]) mi = 1; - if(t[2] > t[mi]) mi = 2; - if(t[mi] >= 0 && t[mi] <= length) { - Vector3 pt = v1 + dir * t[mi]; - - // check it's in the box in other 2 dimensions - int o1 = ( mi + 1 ) % 3 ; // i=0: o1=1, o2=2, i=1: o1=2,o2=0 etc. - int o2 = ( mi + 2 ) % 3 ; - - return pt[o1] >= min[o1] && pt[o1] <= max[o1] && pt[o2] >= min[o2] && pt[o2] <= max[o2]; - } - - return false ; // the ray did not hit the box. + } + + int mi = 0; + if (t[1] > t[mi]) mi = 1; + if (t[2] > t[mi]) mi = 2; + if (t[mi] >= 0 && t[mi] <= length) { + Vector3 pt = v1 + dir * t[mi]; + + // check it's in the box in other 2 dimensions + int o1 = (mi + 1) % 3; // i=0: o1=1, o2=2, i=1: o1=2,o2=0 etc. + int o2 = (mi + 2) % 3; + + return pt[o1] >= min[o1] && pt[o1] <= max[o1] && pt[o2] >= min[o2] && pt[o2] <= max[o2]; + } + + return false; // the ray did not hit the box. } -bool AABB::intersectsRay(const Vector3 &v1, const Vector3 &dir) const +bool AABB::intersectsRay(const Vector3& v1, const Vector3& dir) const { /* Fast Ray-Box Intersection @@ -248,12 +248,13 @@ bool AABB::intersectsRay(const Vector3 &v1, const Vector3 &dir) const from "Graphics Gems", Academic Press, 1990 */ - // FINDME, TODO - Perhaps there is a more efficient algorithm, as we don't actually need the exact coordinate of the intersection + // FINDME, TODO - Perhaps there is a more efficient algorithm, as we don't actually need the exact coordinate of the intersection - enum { - RIGHT = 0, - LEFT = 1, - MIDDLE = 2 + enum + { + RIGHT = 0, + LEFT = 1, + MIDDLE = 2 } quadrant[3]; bool inside = true; @@ -261,113 +262,113 @@ bool AABB::intersectsRay(const Vector3 &v1, const Vector3 &dir) const maxT.init(); Vector3 coord; coord.init(); - float candidatePlane[3]; + float candidatePlane[3]; // Find candidate planes; this loop can be avoided if rays cast all from the eye(assume perpsective view) - for (int i=0; i<3; i++) - if(v1.c[i] < min.c[i]) { - quadrant[i] = LEFT; - candidatePlane[i] = min.c[i]; - inside = false; - } else if(v1.c[i] > max.c[i]) { - quadrant[i] = RIGHT; - candidatePlane[i] = max.c[i]; - inside = false; - } else { - quadrant[i] = MIDDLE; - } - - /* Ray v1 inside bounding box */ - if (inside) { - coord = v1; - return true; - } + for (int i = 0; i < 3; i++) + if (v1.c[i] < min.c[i]) { + quadrant[i] = LEFT; + candidatePlane[i] = min.c[i]; + inside = false; + } else if (v1.c[i] > max.c[i]) { + quadrant[i] = RIGHT; + candidatePlane[i] = max.c[i]; + inside = false; + } else { + quadrant[i] = MIDDLE; + } - /* Calculate T distances to candidate planes */ - for (int i = 0; i < 3; i++) { - if (quadrant[i] != MIDDLE && dir[i] != 0.0f) { - maxT.c[i] = (candidatePlane[i]-v1.c[i]) / dir[i]; - } else { - maxT.c[i] = -1.0f; + /* Ray v1 inside bounding box */ + if (inside) { + coord = v1; + return true; } - } - - /* Get largest of the maxT's for final choice of intersection */ - int whichPlane = 0; - for (int i = 1; i < 3; i++) { - if (maxT.c[whichPlane] < maxT.c[i]) { - whichPlane = i; - } - } - - /* Check final candidate actually inside box */ - if (maxT.c[whichPlane] < 0.0f) { - return false; - } - for (int i = 0; i < 3; i++) { - if (whichPlane != i) { - coord[i] = v1.c[i] + maxT.c[whichPlane] *dir[i]; - if (coord[i] < min.c[i] || coord[i] > max.c[i]) { - return false; + + /* Calculate T distances to candidate planes */ + for (int i = 0; i < 3; i++) { + if (quadrant[i] != MIDDLE && dir[i] != 0.0f) { + maxT.c[i] = (candidatePlane[i] - v1.c[i]) / dir[i]; + } else { + maxT.c[i] = -1.0f; } - } else { - assert(quadrant[i] != MIDDLE); // This should not be possible - coord[i] = candidatePlane[i]; - } + } + + /* Get largest of the maxT's for final choice of intersection */ + int whichPlane = 0; + for (int i = 1; i < 3; i++) { + if (maxT.c[whichPlane] < maxT.c[i]) { + whichPlane = i; + } + } + + /* Check final candidate actually inside box */ + if (maxT.c[whichPlane] < 0.0f) { + return false; + } + for (int i = 0; i < 3; i++) { + if (whichPlane != i) { + coord[i] = v1.c[i] + maxT.c[whichPlane] * dir[i]; + if (coord[i] < min.c[i] || coord[i] > max.c[i]) { + return false; + } + } else { + assert(quadrant[i] != MIDDLE); // This should not be possible + coord[i] = candidatePlane[i]; + } + } + return true; /* ray hits box */ +} + +bool AABB::intersectsSphere(const Vector3& center, float radius) const +{ + // Arvo's Algorithm + + float squaredDistance = 0; + + // process X + if (center.x < min.x) { + float diff = center.x - min.x; + squaredDistance += diff * diff; + } else if (center.x > max.x) { + float diff = center.x - max.x; + squaredDistance += diff * diff; } - return true; /* ray hits box */ + + // process Y + if (center.y < min.y) { + float diff = center.y - min.y; + squaredDistance += diff * diff; + } else if (center.y > max.y) { + float diff = center.y - max.y; + squaredDistance += diff * diff; + } + + // process Z + if (center.z < min.z) { + float diff = center.z - min.z; + squaredDistance += diff * diff; + } else if (center.z > max.z) { + float diff = center.z - max.z; + squaredDistance += diff * diff; + } + + return squaredDistance <= radius; } -bool AABB::intersectsSphere(const Vector3 ¢er, float radius) const +void AABB::encapsulate(const AABB& b) { - // Arvo's Algorithm - - float squaredDistance = 0; - - // process X - if (center.x < min.x) { - float diff = center.x - min.x; - squaredDistance += diff * diff; - } else if (center.x > max.x) { - float diff = center.x - max.x; - squaredDistance += diff * diff; - } - - // process Y - if (center.y < min.y) { - float diff = center.y - min.y; - squaredDistance += diff * diff; - } else if (center.y > max.y) { - float diff = center.y - max.y; - squaredDistance += diff * diff; - } - - // process Z - if (center.z < min.z) { - float diff = center.z - min.z; - squaredDistance += diff * diff; - } else if (center.z > max.z) { - float diff = center.z - max.z; - squaredDistance += diff * diff; - } - - return squaredDistance <= radius; + if (b.min.x < min.x) min.x = b.min.x; + if (b.min.y < min.y) min.y = b.min.y; + if (b.min.z < min.z) min.z = b.min.z; + + if (b.max.x > max.x) max.x = b.max.x; + if (b.max.y > max.y) max.y = b.max.y; + if (b.max.z > max.z) max.z = b.max.z; } -void AABB::encapsulate(const AABB & b) +Vector3 AABB::nearestPoint(const Vector3& v) const { - if(b.min.x < min.x) min.x = b.min.x; - if(b.min.y < min.y) min.y = b.min.y; - if(b.min.z < min.z) min.z = b.min.z; - - if(b.max.x > max.x) max.x = b.max.x; - if(b.max.y > max.y) max.y = b.max.y; - if(b.max.z > max.z) max.z = b.max.z; -} - -Vector3 AABB::nearestPoint(const Vector3 & v) const -{ - return Vector3::Create(KRCLAMP(v.x, min.x, max.x), KRCLAMP(v.y, min.y, max.y), KRCLAMP(v.z, min.z, max.z)); + return Vector3::Create(KRCLAMP(v.x, min.x, max.x), KRCLAMP(v.y, min.y, max.y), KRCLAMP(v.z, min.z, max.z)); } } // namespace kraken diff --git a/src/hitinfo.cpp b/src/hitinfo.cpp index 23fb8cb..6170db2 100644 --- a/src/hitinfo.cpp +++ b/src/hitinfo.cpp @@ -35,26 +35,26 @@ namespace kraken { HitInfo::HitInfo() { - m_position = Vector3::Zero(); - m_normal = Vector3::Zero(); - m_distance = 0.0f; - m_node = NULL; + m_position = Vector3::Zero(); + m_normal = Vector3::Zero(); + m_distance = 0.0f; + m_node = NULL; } -HitInfo::HitInfo(const Vector3 &position, const Vector3 &normal, const float distance, KRNode *node) +HitInfo::HitInfo(const Vector3& position, const Vector3& normal, const float distance, KRNode* node) { - m_position = position; - m_normal = normal; - m_distance = distance; - m_node = node; + m_position = position; + m_normal = normal; + m_distance = distance; + m_node = node; } -HitInfo::HitInfo(const Vector3 &position, const Vector3 &normal, const float distance) +HitInfo::HitInfo(const Vector3& position, const Vector3& normal, const float distance) { - m_position = position; - m_normal = normal; - m_distance = distance; - m_node = NULL; + m_position = position; + m_normal = normal; + m_distance = distance; + m_node = NULL; } HitInfo::~HitInfo() @@ -64,36 +64,36 @@ HitInfo::~HitInfo() bool HitInfo::didHit() const { - return m_normal != Vector3::Zero(); + return m_normal != Vector3::Zero(); } Vector3 HitInfo::getPosition() const { - return m_position; + return m_position; } Vector3 HitInfo::getNormal() const { - return m_normal; + return m_normal; } float HitInfo::getDistance() const { - return m_distance; + return m_distance; } -KRNode *HitInfo::getNode() const +KRNode* HitInfo::getNode() const { - return m_node; + return m_node; } HitInfo& HitInfo::operator =(const HitInfo& b) { - m_position = b.m_position; - m_normal = b.m_normal; - m_distance = b.m_distance; - m_node = b.m_node; - return *this; + m_position = b.m_position; + m_normal = b.m_normal; + m_distance = b.m_distance; + m_node = b.m_node; + return *this; } } // namespace kraken diff --git a/src/matrix2.cpp b/src/matrix2.cpp index 94e4087..1197720 100644 --- a/src/matrix2.cpp +++ b/src/matrix2.cpp @@ -35,171 +35,185 @@ namespace kraken { -void Matrix2::init() { - // Default constructor - Initialize with an identity matrix - static const float IDENTITY_MATRIX[] = { - 1.0, 0.0, - 0.0, 1.0 - }; - memcpy(c, IDENTITY_MATRIX, sizeof(float) * 4); - -} - -void Matrix2::init(float *pMat) { - memcpy(c, pMat, sizeof(float) * 4); -} - -void Matrix2::init(const Vector2 &new_axis_x, const Vector2 &new_axis_y) +void Matrix2::init() { - c[0] = new_axis_x.x; c[1] = new_axis_x.y; - c[2] = new_axis_y.x; c[3] = new_axis_y.y; + // Default constructor - Initialize with an identity matrix + static const float IDENTITY_MATRIX[] = { + 1.0, 0.0, + 0.0, 1.0 + }; + memcpy(c, IDENTITY_MATRIX, sizeof(float) * 4); + } -void Matrix2::init(const Matrix2 &m) { - memcpy(c, m.c, sizeof(float) * 4); +void Matrix2::init(float* pMat) +{ + memcpy(c, pMat, sizeof(float) * 4); } -float *Matrix2::getPointer() { - return c; +void Matrix2::init(const Vector2& new_axis_x, const Vector2& new_axis_y) +{ + c[0] = new_axis_x.x; c[1] = new_axis_x.y; + c[2] = new_axis_y.x; c[3] = new_axis_y.y; } -float& Matrix2::operator[](unsigned i) { - return c[i]; +void Matrix2::init(const Matrix2& m) +{ + memcpy(c, m.c, sizeof(float) * 4); } -float Matrix2::operator[](unsigned i) const { - return c[i]; +float* Matrix2::getPointer() +{ + return c; +} + +float& Matrix2::operator[](unsigned i) +{ + return c[i]; +} + +float Matrix2::operator[](unsigned i) const +{ + return c[i]; } // Overload comparison operator -bool Matrix2::operator==(const Matrix2 &m) const { - return memcmp(c, m.c, sizeof(float) * 4) == 0; +bool Matrix2::operator==(const Matrix2& m) const +{ + return memcmp(c, m.c, sizeof(float) * 4) == 0; } // Overload compound multiply operator -Matrix2& Matrix2::operator*=(const Matrix2 &m) { - float temp[4]; - - int x,y; - - for (x=0; x < 2; x++) - { - for(y=0; y < 2; y++) - { - temp[y + (x*2)] = (c[x*2] * m.c[y]) + - (c[x*2+1] * m.c[y+2]); - } +Matrix2& Matrix2::operator*=(const Matrix2& m) +{ + float temp[4]; + + int x, y; + + for (x = 0; x < 2; x++) { + for (y = 0; y < 2; y++) { + temp[y + (x * 2)] = (c[x * 2] * m.c[y]) + + (c[x * 2 + 1] * m.c[y + 2]); } - - memcpy(c, temp, sizeof(float) * 4); - return *this; + } + + memcpy(c, temp, sizeof(float) * 4); + return *this; } // Overload multiply operator -Matrix2 Matrix2::operator*(const Matrix2 &m) const { - Matrix2 ret = *this; - ret *= m; - return ret; +Matrix2 Matrix2::operator*(const Matrix2& m) const +{ + Matrix2 ret = *this; + ret *= m; + return ret; } /* Rotate a matrix by an angle on a X, Y, or Z axis */ -void Matrix2::rotate(float angle) { - - Matrix2 newMatrix; // Create new identity matrix - newMatrix.init(); - newMatrix.c[0] = cosf(angle); - newMatrix.c[1] = -sinf(angle); - newMatrix.c[2] = -newMatrix.c[1]; - newMatrix.c[3] = newMatrix.c[0]; - - *this *= newMatrix; +void Matrix2::rotate(float angle) +{ + + Matrix2 newMatrix; // Create new identity matrix + newMatrix.init(); + newMatrix.c[0] = cosf(angle); + newMatrix.c[1] = -sinf(angle); + newMatrix.c[2] = -newMatrix.c[1]; + newMatrix.c[3] = newMatrix.c[0]; + + *this *= newMatrix; } /* Scale matrix by separate x, y, and z amounts */ -void Matrix2::scale(float x, float y) { - Matrix2 newMatrix; // Create new identity matrix - newMatrix.init(); - - newMatrix.c[0] = x; - newMatrix.c[3] = y; - - *this *= newMatrix; +void Matrix2::scale(float x, float y) +{ + Matrix2 newMatrix; // Create new identity matrix + newMatrix.init(); + + newMatrix.c[0] = x; + newMatrix.c[3] = y; + + *this *= newMatrix; } -void Matrix2::scale(const Vector2 &v) { - scale(v.x, v.y); +void Matrix2::scale(const Vector2& v) +{ + scale(v.x, v.y); } /* Scale all dimensions equally */ -void Matrix2::scale(float s) { - scale(s,s); +void Matrix2::scale(float s) +{ + scale(s, s); } /* Replace matrix with its inverse */ -bool Matrix2::invert() { - float det = c[0] * c[3] - c[1] * c[2]; - if (det == 0) { - return false; - } - float invdet = 1.0f / det; - float tmp = c[0]; - c[0] = c[3] * invdet; - c[1] = -c[1] * invdet; - c[2] = -c[2] * invdet; - c[3] = tmp * invdet; - - return true; +bool Matrix2::invert() +{ + float det = c[0] * c[3] - c[1] * c[2]; + if (det == 0) { + return false; + } + float invdet = 1.0f / det; + float tmp = c[0]; + c[0] = c[3] * invdet; + c[1] = -c[1] * invdet; + c[2] = -c[2] * invdet; + c[3] = tmp * invdet; + + return true; } -void Matrix2::transpose() { - float tmp = c[1]; - c[1] = c[2]; - c[2] = tmp; +void Matrix2::transpose() +{ + float tmp = c[1]; + c[1] = c[2]; + c[2] = tmp; } /* Dot Product, returning Vector2 */ -Vector2 Matrix2::Dot(const Matrix2 &m, const Vector2 &v) { - return Vector2::Create( - v.c[0] * m.c[0] + v.c[1] * m.c[2], - v.c[0] * m.c[1] + v.c[1] * m.c[3] - ); +Vector2 Matrix2::Dot(const Matrix2& m, const Vector2& v) +{ + return Vector2::Create( + v.c[0] * m.c[0] + v.c[1] * m.c[2], + v.c[0] * m.c[1] + v.c[1] * m.c[3] + ); } -Matrix2 Matrix2::Invert(const Matrix2 &m) +Matrix2 Matrix2::Invert(const Matrix2& m) { - Matrix2 matInvert = m; - matInvert.invert(); - return matInvert; + Matrix2 matInvert = m; + matInvert.invert(); + return matInvert; } -Matrix2 Matrix2::Transpose(const Matrix2 &m) +Matrix2 Matrix2::Transpose(const Matrix2& m) { - Matrix2 matTranspose = m; - matTranspose.transpose(); - return matTranspose; + Matrix2 matTranspose = m; + matTranspose.transpose(); + return matTranspose; } Matrix2 Matrix2::Rotation(float angle) { - Matrix2 m; - m.init(); - m.rotate(angle); - return m; + Matrix2 m; + m.init(); + m.rotate(angle); + return m; } -Matrix2 Matrix2::Scaling(const Vector2 &v) +Matrix2 Matrix2::Scaling(const Vector2& v) { - Matrix2 m; - m.init(); - m.scale(v); - return m; + Matrix2 m; + m.init(); + m.scale(v); + return m; } Matrix2 Matrix2::Identity() { - Matrix2 m; - m.init(); - return m; + Matrix2 m; + m.init(); + return m; } } // namespace kraken diff --git a/src/matrix2x3.cpp b/src/matrix2x3.cpp index 54c48a0..0b05401 100644 --- a/src/matrix2x3.cpp +++ b/src/matrix2x3.cpp @@ -35,198 +35,214 @@ namespace kraken { -void Matrix2x3::init() { - // Default constructor - Initialize with an identity matrix - static const float IDENTITY_MATRIX[] = { - 1.0, 0.0, - 0.0, 1.0, - 0.0, 0.0 - }; - memcpy(c, IDENTITY_MATRIX, sizeof(float) * 6); - -} - -void Matrix2x3::init(float *pMat) { - memcpy(c, pMat, sizeof(float) * 6); -} - -void Matrix2x3::init(const Vector2 &new_axis_x, const Vector2 &new_axis_y, const Vector2 &new_transform) +void Matrix2x3::init() { - c[0] = new_axis_x.x; c[1] = new_axis_x.y; - c[2] = new_axis_y.x; c[3] = new_axis_y.y; - c[4] = new_transform.x; c[5] = new_transform.y; + // Default constructor - Initialize with an identity matrix + static const float IDENTITY_MATRIX[] = { + 1.0, 0.0, + 0.0, 1.0, + 0.0, 0.0 + }; + memcpy(c, IDENTITY_MATRIX, sizeof(float) * 6); + } -void Matrix2x3::init(const Matrix2x3 &m) { - memcpy(c, m.c, sizeof(float) * 6); +void Matrix2x3::init(float* pMat) +{ + memcpy(c, pMat, sizeof(float) * 6); } -float *Matrix2x3::getPointer() { - return c; +void Matrix2x3::init(const Vector2& new_axis_x, const Vector2& new_axis_y, const Vector2& new_transform) +{ + c[0] = new_axis_x.x; c[1] = new_axis_x.y; + c[2] = new_axis_y.x; c[3] = new_axis_y.y; + c[4] = new_transform.x; c[5] = new_transform.y; } -float& Matrix2x3::operator[](unsigned i) { - return c[i]; +void Matrix2x3::init(const Matrix2x3& m) +{ + memcpy(c, m.c, sizeof(float) * 6); } -float Matrix2x3::operator[](unsigned i) const { - return c[i]; +float* Matrix2x3::getPointer() +{ + return c; +} + +float& Matrix2x3::operator[](unsigned i) +{ + return c[i]; +} + +float Matrix2x3::operator[](unsigned i) const +{ + return c[i]; } // Overload comparison operator -bool Matrix2x3::operator==(const Matrix2x3 &m) const { - return memcmp(c, m.c, sizeof(float) * 6) == 0; +bool Matrix2x3::operator==(const Matrix2x3& m) const +{ + return memcmp(c, m.c, sizeof(float) * 6) == 0; } // Overload compound multiply operator -Matrix2x3& Matrix2x3::operator*=(const Matrix2x3 &m) { - float temp[6]; -/* - temp[0] = c[0] * m[0] + c[2] * m[1]; - temp[1] = c[1] * m[0] + c[3] * m[1]; - temp[2] = c[0] * m[2] + c[2] * m[3]; - temp[3] = c[1] * m[2] + c[3] * m[3]; - temp[4] = c[0] * m[4] + c[2] * m[5] + c[4]; - temp[5] = c[1] * m[4] + c[3] * m[5] + c[5]; -*/ - temp[0] = m[0] * c[0] + m[2] * c[1]; - temp[1] = m[1] * c[0] + m[3] * c[1]; - temp[2] = m[0] * c[2] + m[2] * c[3]; - temp[3] = m[1] * c[2] + m[3] * c[3]; - temp[4] = m[0] * c[4] + m[2] * c[5] + m[4]; - temp[5] = m[1] * c[4] + m[3] * c[5] + m[5]; +Matrix2x3& Matrix2x3::operator*=(const Matrix2x3& m) +{ + float temp[6]; + /* + temp[0] = c[0] * m[0] + c[2] * m[1]; + temp[1] = c[1] * m[0] + c[3] * m[1]; + temp[2] = c[0] * m[2] + c[2] * m[3]; + temp[3] = c[1] * m[2] + c[3] * m[3]; + temp[4] = c[0] * m[4] + c[2] * m[5] + c[4]; + temp[5] = c[1] * m[4] + c[3] * m[5] + c[5]; + */ + temp[0] = m[0] * c[0] + m[2] * c[1]; + temp[1] = m[1] * c[0] + m[3] * c[1]; + temp[2] = m[0] * c[2] + m[2] * c[3]; + temp[3] = m[1] * c[2] + m[3] * c[3]; + temp[4] = m[0] * c[4] + m[2] * c[5] + m[4]; + temp[5] = m[1] * c[4] + m[3] * c[5] + m[5]; - memcpy(c, temp, sizeof(float) * 6); - return *this; + memcpy(c, temp, sizeof(float) * 6); + return *this; } // Overload multiply operator -Matrix2x3 Matrix2x3::operator*(const Matrix2x3 &m) const { - Matrix2x3 ret = *this; - ret *= m; - return ret; +Matrix2x3 Matrix2x3::operator*(const Matrix2x3& m) const +{ + Matrix2x3 ret = *this; + ret *= m; + return ret; } /* Perform translation operations on a matrix */ -void Matrix2x3::translate(float x, float y) { - Matrix2x3 newMatrix; // Create new identity matrix - newMatrix.init(); - - newMatrix.transform.x = x; - newMatrix.transform.y = y; - - *this *= newMatrix; +void Matrix2x3::translate(float x, float y) +{ + Matrix2x3 newMatrix; // Create new identity matrix + newMatrix.init(); + + newMatrix.transform.x = x; + newMatrix.transform.y = y; + + *this *= newMatrix; } -void Matrix2x3::translate(const Vector2 &v) +void Matrix2x3::translate(const Vector2& v) { - translate(v.x, v.y); + translate(v.x, v.y); } /* Rotate a matrix by an angle on a X, Y, or Z axis */ -void Matrix2x3::rotate(float angle) { - Matrix2x3 newMatrix; - newMatrix.init(); - newMatrix.c[0] = cosf(angle); - newMatrix.c[1] = -sinf(angle); - newMatrix.c[2] = -newMatrix.c[1]; - newMatrix.c[3] = newMatrix.c[0]; - - *this *= newMatrix; +void Matrix2x3::rotate(float angle) +{ + Matrix2x3 newMatrix; + newMatrix.init(); + newMatrix.c[0] = cosf(angle); + newMatrix.c[1] = -sinf(angle); + newMatrix.c[2] = -newMatrix.c[1]; + newMatrix.c[3] = newMatrix.c[0]; + + *this *= newMatrix; } /* Scale matrix by separate x, y, and z amounts */ -void Matrix2x3::scale(float x, float y) { - Matrix2x3 newMatrix; // Create new identity matrix - newMatrix.init(); - - newMatrix.c[0] = x; - newMatrix.c[3] = y; - - *this *= newMatrix; +void Matrix2x3::scale(float x, float y) +{ + Matrix2x3 newMatrix; // Create new identity matrix + newMatrix.init(); + + newMatrix.c[0] = x; + newMatrix.c[3] = y; + + *this *= newMatrix; } -void Matrix2x3::scale(const Vector2 &v) { - scale(v.x, v.y); +void Matrix2x3::scale(const Vector2& v) +{ + scale(v.x, v.y); } /* Scale all dimensions equally */ -void Matrix2x3::scale(float s) { - scale(s,s); +void Matrix2x3::scale(float s) +{ + scale(s, s); } /* Replace matrix with its inverse */ -bool Matrix2x3::invert() { - float det = c[0] * c[3] - c[1] * c[2]; - if (det == 0) { - return false; - } - float invdet = 1.0f / det; - float tmp[6]; - tmp[0] = c[3] * invdet; - tmp[1] = -c[1] * invdet; - tmp[2] = -c[2] * invdet; - tmp[3] = c[0] * invdet; - tmp[4] = (c[2] * c[5] - c[3] * c[4]) * invdet; - tmp[5] = (c[1] * c[4] - c[0] * c[5]) * invdet; - memcpy(c, tmp, sizeof(float) * 6); - - return true; +bool Matrix2x3::invert() +{ + float det = c[0] * c[3] - c[1] * c[2]; + if (det == 0) { + return false; + } + float invdet = 1.0f / det; + float tmp[6]; + tmp[0] = c[3] * invdet; + tmp[1] = -c[1] * invdet; + tmp[2] = -c[2] * invdet; + tmp[3] = c[0] * invdet; + tmp[4] = (c[2] * c[5] - c[3] * c[4]) * invdet; + tmp[5] = (c[1] * c[4] - c[0] * c[5]) * invdet; + memcpy(c, tmp, sizeof(float) * 6); + + return true; } /* Dot Product, returning Vector2 */ -Vector2 Matrix2x3::Dot(const Matrix2x3 &m, const Vector2 &v) { - return Vector2::Create( - v.c[0] * m.c[0] + v.c[1] * m.c[2] + m.c[4], - v.c[0] * m.c[1] + v.c[1] * m.c[3] + m.c[5] - ); +Vector2 Matrix2x3::Dot(const Matrix2x3& m, const Vector2& v) +{ + return Vector2::Create( + v.c[0] * m.c[0] + v.c[1] * m.c[2] + m.c[4], + v.c[0] * m.c[1] + v.c[1] * m.c[3] + m.c[5] + ); } // Dot product without including translation; useful for transforming normals and tangents -Vector2 Matrix2x3::DotNoTranslate(const Matrix2x3 &m, const Vector2 &v) +Vector2 Matrix2x3::DotNoTranslate(const Matrix2x3& m, const Vector2& v) { - return Vector2::Create( - v.c[0] * m.c[0] + v.c[1] * m.c[2], - v.c[0] * m.c[1] + v.c[1] * m.c[3] - ); + return Vector2::Create( + v.c[0] * m.c[0] + v.c[1] * m.c[2], + v.c[0] * m.c[1] + v.c[1] * m.c[3] + ); } -Matrix2x3 Matrix2x3::Invert(const Matrix2x3 &m) +Matrix2x3 Matrix2x3::Invert(const Matrix2x3& m) { - Matrix2x3 matInvert = m; - matInvert.invert(); - return matInvert; + Matrix2x3 matInvert = m; + matInvert.invert(); + return matInvert; } -Matrix2x3 Matrix2x3::Translation(const Vector2 &v) +Matrix2x3 Matrix2x3::Translation(const Vector2& v) { - Matrix2x3 m; - m.init(); - m.transform.x = v.x; - m.transform.y = v.y; - return m; + Matrix2x3 m; + m.init(); + m.transform.x = v.x; + m.transform.y = v.y; + return m; } Matrix2x3 Matrix2x3::Rotation(float angle) { - Matrix2x3 m; - m.init(); - m.rotate(angle); - return m; + Matrix2x3 m; + m.init(); + m.rotate(angle); + return m; } -Matrix2x3 Matrix2x3::Scaling(const Vector2 &v) +Matrix2x3 Matrix2x3::Scaling(const Vector2& v) { - Matrix2x3 m; - m.init(); - m.scale(v); - return m; + Matrix2x3 m; + m.init(); + m.scale(v); + return m; } Matrix2x3 Matrix2x3::Identity() { - Matrix2x3 m; - m.init(); - return m; + Matrix2x3 m; + m.init(); + return m; } } // namespace kraken diff --git a/src/matrix4.cpp b/src/matrix4.cpp index 1f17560..8a5a365 100644 --- a/src/matrix4.cpp +++ b/src/matrix4.cpp @@ -35,432 +35,453 @@ namespace kraken { -void Matrix4::init() { - // Default constructor - Initialize with an identity matrix - static const float IDENTITY_MATRIX[] = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }; - memcpy(c, IDENTITY_MATRIX, sizeof(float) * 16); - -} - -void Matrix4::init(float *pMat) { - memcpy(c, pMat, sizeof(float) * 16); -} - -void Matrix4::init(const Vector3 &new_axis_x, const Vector3 &new_axis_y, const Vector3 &new_axis_z, const Vector3 &new_transform) +void Matrix4::init() { - c[0] = new_axis_x.x; c[1] = new_axis_x.y; c[2] = new_axis_x.z; c[3] = 0.0f; - c[4] = new_axis_y.x; c[5] = new_axis_y.y; c[6] = new_axis_y.z; c[7] = 0.0f; - c[8] = new_axis_z.x; c[9] = new_axis_z.y; c[10] = new_axis_z.z; c[11] = 0.0f; - c[12] = new_transform.x; c[13] = new_transform.y; c[14] = new_transform.z; c[15] = 1.0f; + // Default constructor - Initialize with an identity matrix + static const float IDENTITY_MATRIX[] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + memcpy(c, IDENTITY_MATRIX, sizeof(float) * 16); + } -void Matrix4::init(const Matrix4 &m) { - memcpy(c, m.c, sizeof(float) * 16); +void Matrix4::init(float* pMat) +{ + memcpy(c, pMat, sizeof(float) * 16); } -Matrix4 Matrix4::Create(float *pMat) +void Matrix4::init(const Vector3& new_axis_x, const Vector3& new_axis_y, const Vector3& new_axis_z, const Vector3& new_transform) +{ + c[0] = new_axis_x.x; c[1] = new_axis_x.y; c[2] = new_axis_x.z; c[3] = 0.0f; + c[4] = new_axis_y.x; c[5] = new_axis_y.y; c[6] = new_axis_y.z; c[7] = 0.0f; + c[8] = new_axis_z.x; c[9] = new_axis_z.y; c[10] = new_axis_z.z; c[11] = 0.0f; + c[12] = new_transform.x; c[13] = new_transform.y; c[14] = new_transform.z; c[15] = 1.0f; +} + +void Matrix4::init(const Matrix4& m) +{ + memcpy(c, m.c, sizeof(float) * 16); +} + +Matrix4 Matrix4::Create(float* pMat) { Matrix4 r; r.init(pMat); return r; } -Matrix4 Matrix4::Create(const Vector3 &new_axis_x, const Vector3 &new_axis_y, const Vector3 &new_axis_z, const Vector3 &new_transform) +Matrix4 Matrix4::Create(const Vector3& new_axis_x, const Vector3& new_axis_y, const Vector3& new_axis_z, const Vector3& new_transform) { Matrix4 r; r.init(new_axis_x, new_axis_y, new_axis_z, new_transform); return r; } -float *Matrix4::getPointer() { - return c; +float* Matrix4::getPointer() +{ + return c; } -float& Matrix4::operator[](unsigned i) { - return c[i]; +float& Matrix4::operator[](unsigned i) +{ + return c[i]; } -float Matrix4::operator[](unsigned i) const { - return c[i]; +float Matrix4::operator[](unsigned i) const +{ + return c[i]; } // Overload comparison operator -bool Matrix4::operator==(const Matrix4 &m) const { - return memcmp(c, m.c, sizeof(float) * 16) == 0; +bool Matrix4::operator==(const Matrix4& m) const +{ + return memcmp(c, m.c, sizeof(float) * 16) == 0; } // Overload compound multiply operator -Matrix4& Matrix4::operator*=(const Matrix4 &m) { - float temp[16]; - - int x,y; - - for (x=0; x < 4; x++) - { - for(y=0; y < 4; y++) - { - temp[y + (x*4)] = (c[x*4] * m.c[y]) + - (c[(x*4)+1] * m.c[y+4]) + - (c[(x*4)+2] * m.c[y+8]) + - (c[(x*4)+3] * m.c[y+12]); - } +Matrix4& Matrix4::operator*=(const Matrix4& m) +{ + float temp[16]; + + int x, y; + + for (x = 0; x < 4; x++) { + for (y = 0; y < 4; y++) { + temp[y + (x * 4)] = (c[x * 4] * m.c[y]) + + (c[(x * 4) + 1] * m.c[y + 4]) + + (c[(x * 4) + 2] * m.c[y + 8]) + + (c[(x * 4) + 3] * m.c[y + 12]); } - - memcpy(c, temp, sizeof(float) << 4); - return *this; + } + + memcpy(c, temp, sizeof(float) << 4); + return *this; } // Overload multiply operator -Matrix4 Matrix4::operator*(const Matrix4 &m) const { - Matrix4 ret = *this; - ret *= m; - return ret; +Matrix4 Matrix4::operator*(const Matrix4& m) const +{ + Matrix4 ret = *this; + ret *= m; + return ret; } /* Generate a perspective view matrix using a field of view angle fov, * window aspect ratio, near and far clipping planes */ -void Matrix4::perspective(float fov, float aspect, float nearz, float farz) { - - memset(c, 0, sizeof(float) * 16); - - float range= tanf(fov * 0.5f) * nearz; - c[0] = (2 * nearz) / ((range * aspect) - (-range * aspect)); - c[5] = (2 * nearz) / (2 * range); - c[10] = -(farz + nearz) / (farz - nearz); - c[11] = -1; - c[14] = -(2 * farz * nearz) / (farz - nearz); - /* - float range= atan(fov / 20.0f) * nearz; - float r = range * aspect; - float t = range * 1.0; - - c[0] = nearz / r; - c[5] = nearz / t; - c[10] = -(farz + nearz) / (farz - nearz); - c[11] = -(2.0 * farz * nearz) / (farz - nearz); - c[14] = -1.0; - */ +void Matrix4::perspective(float fov, float aspect, float nearz, float farz) +{ + + memset(c, 0, sizeof(float) * 16); + + float range = tanf(fov * 0.5f) * nearz; + c[0] = (2 * nearz) / ((range * aspect) - (-range * aspect)); + c[5] = (2 * nearz) / (2 * range); + c[10] = -(farz + nearz) / (farz - nearz); + c[11] = -1; + c[14] = -(2 * farz * nearz) / (farz - nearz); + /* + float range= atan(fov / 20.0f) * nearz; + float r = range * aspect; + float t = range * 1.0; + + c[0] = nearz / r; + c[5] = nearz / t; + c[10] = -(farz + nearz) / (farz - nearz); + c[11] = -(2.0 * farz * nearz) / (farz - nearz); + c[14] = -1.0; + */ } /* Perform translation operations on a matrix */ -void Matrix4::translate(float x, float y, float z) { - Matrix4 newMatrix; // Create new identity matrix - newMatrix.init(); - - newMatrix.c[12] = x; - newMatrix.c[13] = y; - newMatrix.c[14] = z; - - *this *= newMatrix; +void Matrix4::translate(float x, float y, float z) +{ + Matrix4 newMatrix; // Create new identity matrix + newMatrix.init(); + + newMatrix.c[12] = x; + newMatrix.c[13] = y; + newMatrix.c[14] = z; + + *this *= newMatrix; } -void Matrix4::translate(const Vector3 &v) +void Matrix4::translate(const Vector3& v) { - translate(v.x, v.y, v.z); + translate(v.x, v.y, v.z); } /* Rotate a matrix by an angle on a X, Y, or Z axis */ -void Matrix4::rotate(float angle, AXIS axis) { - const int cos1[3] = { 5, 0, 0 }; // cos(angle) - const int cos2[3] = { 10, 10, 5 }; // cos(angle) - const int sin1[3] = { 9, 2, 4 }; // -sin(angle) - const int sin2[3] = { 6, 8, 1 }; // sin(angle) - - /* - X_AXIS: - - 1, 0, 0, 0 - 0, cos(angle), -sin(angle), 0 - 0, sin(angle), cos(angle), 0 - 0, 0, 0, 1 - - Y_AXIS: - - cos(angle), 0, -sin(angle), 0 - 0, 1, 0, 0 - sin(angle), 0, cos(angle), 0 - 0, 0, 0, 1 - - Z_AXIS: - - cos(angle), -sin(angle), 0, 0 - sin(angle), cos(angle), 0, 0 - 0, 0, 1, 0 - 0, 0, 0, 1 - - */ - - Matrix4 newMatrix; // Create new identity matrix - newMatrix.init(); - - uint8_t index = static_cast(axis); - newMatrix.c[cos1[index]] = cosf(angle); - newMatrix.c[sin1[index]] = -sinf(angle); - newMatrix.c[sin2[index]] = -newMatrix.c[sin1[index]]; - newMatrix.c[cos2[index]] = newMatrix.c[cos1[index]]; - - *this *= newMatrix; +void Matrix4::rotate(float angle, AXIS axis) +{ + const int cos1[3] = { 5, 0, 0 }; // cos(angle) + const int cos2[3] = { 10, 10, 5 }; // cos(angle) + const int sin1[3] = { 9, 2, 4 }; // -sin(angle) + const int sin2[3] = { 6, 8, 1 }; // sin(angle) + + /* + X_AXIS: + + 1, 0, 0, 0 + 0, cos(angle), -sin(angle), 0 + 0, sin(angle), cos(angle), 0 + 0, 0, 0, 1 + + Y_AXIS: + + cos(angle), 0, -sin(angle), 0 + 0, 1, 0, 0 + sin(angle), 0, cos(angle), 0 + 0, 0, 0, 1 + + Z_AXIS: + + cos(angle), -sin(angle), 0, 0 + sin(angle), cos(angle), 0, 0 + 0, 0, 1, 0 + 0, 0, 0, 1 + + */ + + Matrix4 newMatrix; // Create new identity matrix + newMatrix.init(); + + uint8_t index = static_cast(axis); + newMatrix.c[cos1[index]] = cosf(angle); + newMatrix.c[sin1[index]] = -sinf(angle); + newMatrix.c[sin2[index]] = -newMatrix.c[sin1[index]]; + newMatrix.c[cos2[index]] = newMatrix.c[cos1[index]]; + + *this *= newMatrix; } -void Matrix4::rotate(const Quaternion &q) +void Matrix4::rotate(const Quaternion& q) { - *this *= q.rotationMatrix(); + *this *= q.rotationMatrix(); } /* Scale matrix by separate x, y, and z amounts */ -void Matrix4::scale(float x, float y, float z) { - Matrix4 newMatrix; // Create new identity matrix - newMatrix.init(); - - newMatrix.c[0] = x; - newMatrix.c[5] = y; - newMatrix.c[10] = z; - - *this *= newMatrix; +void Matrix4::scale(float x, float y, float z) +{ + Matrix4 newMatrix; // Create new identity matrix + newMatrix.init(); + + newMatrix.c[0] = x; + newMatrix.c[5] = y; + newMatrix.c[10] = z; + + *this *= newMatrix; } -void Matrix4::scale(const Vector3 &v) { - scale(v.x, v.y, v.z); +void Matrix4::scale(const Vector3& v) +{ + scale(v.x, v.y, v.z); } /* Scale all dimensions equally */ -void Matrix4::scale(float s) { - scale(s,s,s); +void Matrix4::scale(float s) +{ + scale(s, s, s); } - // Initialize with a bias matrix -void Matrix4::bias() { - static const float BIAS_MATRIX[] = { - 0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 0.5, 0.0, - 0.5, 0.5, 0.5, 1.0 - }; - memcpy(c, BIAS_MATRIX, sizeof(float) * 16); +// Initialize with a bias matrix +void Matrix4::bias() +{ + static const float BIAS_MATRIX[] = { + 0.5, 0.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 0.0, + 0.0, 0.0, 0.5, 0.0, + 0.5, 0.5, 0.5, 1.0 + }; + memcpy(c, BIAS_MATRIX, sizeof(float) * 16); } /* Generate an orthographic view matrix */ -void Matrix4::ortho(float left, float right, float top, float bottom, float nearz, float farz) { - memset(c, 0, sizeof(float) * 16); - c[0] = 2.0f / (right - left); - c[5] = 2.0f / (bottom - top); - c[10] = -1.0f / (farz - nearz); - c[11] = -nearz / (farz - nearz); - c[15] = 1.0f; +void Matrix4::ortho(float left, float right, float top, float bottom, float nearz, float farz) +{ + memset(c, 0, sizeof(float) * 16); + c[0] = 2.0f / (right - left); + c[5] = 2.0f / (bottom - top); + c[10] = -1.0f / (farz - nearz); + c[11] = -nearz / (farz - nearz); + c[15] = 1.0f; } /* Replace matrix with its inverse */ -bool Matrix4::invert() { - // Based on gluInvertMatrix implementation - - float inv[16], det; - int i; - - inv[0] = c[5]*c[10]*c[15] - c[5]*c[11]*c[14] - c[9]*c[6]*c[15] - + c[9]*c[7]*c[14] + c[13]*c[6]*c[11] - c[13]*c[7]*c[10]; - inv[4] = -c[4]*c[10]*c[15] + c[4]*c[11]*c[14] + c[8]*c[6]*c[15] - - c[8]*c[7]*c[14] - c[12]*c[6]*c[11] + c[12]*c[7]*c[10]; - inv[8] = c[4]*c[9]*c[15] - c[4]*c[11]*c[13] - c[8]*c[5]*c[15] - + c[8]*c[7]*c[13] + c[12]*c[5]*c[11] - c[12]*c[7]*c[9]; - inv[12] = -c[4]*c[9]*c[14] + c[4]*c[10]*c[13] + c[8]*c[5]*c[14] - - c[8]*c[6]*c[13] - c[12]*c[5]*c[10] + c[12]*c[6]*c[9]; - inv[1] = -c[1]*c[10]*c[15] + c[1]*c[11]*c[14] + c[9]*c[2]*c[15] - - c[9]*c[3]*c[14] - c[13]*c[2]*c[11] + c[13]*c[3]*c[10]; - inv[5] = c[0]*c[10]*c[15] - c[0]*c[11]*c[14] - c[8]*c[2]*c[15] - + c[8]*c[3]*c[14] + c[12]*c[2]*c[11] - c[12]*c[3]*c[10]; - inv[9] = -c[0]*c[9]*c[15] + c[0]*c[11]*c[13] + c[8]*c[1]*c[15] - - c[8]*c[3]*c[13] - c[12]*c[1]*c[11] + c[12]*c[3]*c[9]; - inv[13] = c[0]*c[9]*c[14] - c[0]*c[10]*c[13] - c[8]*c[1]*c[14] - + c[8]*c[2]*c[13] + c[12]*c[1]*c[10] - c[12]*c[2]*c[9]; - inv[2] = c[1]*c[6]*c[15] - c[1]*c[7]*c[14] - c[5]*c[2]*c[15] - + c[5]*c[3]*c[14] + c[13]*c[2]*c[7] - c[13]*c[3]*c[6]; - inv[6] = -c[0]*c[6]*c[15] + c[0]*c[7]*c[14] + c[4]*c[2]*c[15] - - c[4]*c[3]*c[14] - c[12]*c[2]*c[7] + c[12]*c[3]*c[6]; - inv[10] = c[0]*c[5]*c[15] - c[0]*c[7]*c[13] - c[4]*c[1]*c[15] - + c[4]*c[3]*c[13] + c[12]*c[1]*c[7] - c[12]*c[3]*c[5]; - inv[14] = -c[0]*c[5]*c[14] + c[0]*c[6]*c[13] + c[4]*c[1]*c[14] - - c[4]*c[2]*c[13] - c[12]*c[1]*c[6] + c[12]*c[2]*c[5]; - inv[3] = -c[1]*c[6]*c[11] + c[1]*c[7]*c[10] + c[5]*c[2]*c[11] - - c[5]*c[3]*c[10] - c[9]*c[2]*c[7] + c[9]*c[3]*c[6]; - inv[7] = c[0]*c[6]*c[11] - c[0]*c[7]*c[10] - c[4]*c[2]*c[11] - + c[4]*c[3]*c[10] + c[8]*c[2]*c[7] - c[8]*c[3]*c[6]; - inv[11] = -c[0]*c[5]*c[11] + c[0]*c[7]*c[9] + c[4]*c[1]*c[11] - - c[4]*c[3]*c[9] - c[8]*c[1]*c[7] + c[8]*c[3]*c[5]; - inv[15] = c[0]*c[5]*c[10] - c[0]*c[6]*c[9] - c[4]*c[1]*c[10] - + c[4]*c[2]*c[9] + c[8]*c[1]*c[6] - c[8]*c[2]*c[5]; - - det = c[0]*inv[0] + c[1]*inv[4] + c[2]*inv[8] + c[3]*inv[12]; - - if (det == 0) { - return false; - } - - det = 1.0f / det; - - for (i = 0; i < 16; i++) { - c[i] = inv[i] * det; - } - - return true; +bool Matrix4::invert() +{ + // Based on gluInvertMatrix implementation + + float inv[16], det; + int i; + + inv[0] = c[5] * c[10] * c[15] - c[5] * c[11] * c[14] - c[9] * c[6] * c[15] + + c[9] * c[7] * c[14] + c[13] * c[6] * c[11] - c[13] * c[7] * c[10]; + inv[4] = -c[4] * c[10] * c[15] + c[4] * c[11] * c[14] + c[8] * c[6] * c[15] + - c[8] * c[7] * c[14] - c[12] * c[6] * c[11] + c[12] * c[7] * c[10]; + inv[8] = c[4] * c[9] * c[15] - c[4] * c[11] * c[13] - c[8] * c[5] * c[15] + + c[8] * c[7] * c[13] + c[12] * c[5] * c[11] - c[12] * c[7] * c[9]; + inv[12] = -c[4] * c[9] * c[14] + c[4] * c[10] * c[13] + c[8] * c[5] * c[14] + - c[8] * c[6] * c[13] - c[12] * c[5] * c[10] + c[12] * c[6] * c[9]; + inv[1] = -c[1] * c[10] * c[15] + c[1] * c[11] * c[14] + c[9] * c[2] * c[15] + - c[9] * c[3] * c[14] - c[13] * c[2] * c[11] + c[13] * c[3] * c[10]; + inv[5] = c[0] * c[10] * c[15] - c[0] * c[11] * c[14] - c[8] * c[2] * c[15] + + c[8] * c[3] * c[14] + c[12] * c[2] * c[11] - c[12] * c[3] * c[10]; + inv[9] = -c[0] * c[9] * c[15] + c[0] * c[11] * c[13] + c[8] * c[1] * c[15] + - c[8] * c[3] * c[13] - c[12] * c[1] * c[11] + c[12] * c[3] * c[9]; + inv[13] = c[0] * c[9] * c[14] - c[0] * c[10] * c[13] - c[8] * c[1] * c[14] + + c[8] * c[2] * c[13] + c[12] * c[1] * c[10] - c[12] * c[2] * c[9]; + inv[2] = c[1] * c[6] * c[15] - c[1] * c[7] * c[14] - c[5] * c[2] * c[15] + + c[5] * c[3] * c[14] + c[13] * c[2] * c[7] - c[13] * c[3] * c[6]; + inv[6] = -c[0] * c[6] * c[15] + c[0] * c[7] * c[14] + c[4] * c[2] * c[15] + - c[4] * c[3] * c[14] - c[12] * c[2] * c[7] + c[12] * c[3] * c[6]; + inv[10] = c[0] * c[5] * c[15] - c[0] * c[7] * c[13] - c[4] * c[1] * c[15] + + c[4] * c[3] * c[13] + c[12] * c[1] * c[7] - c[12] * c[3] * c[5]; + inv[14] = -c[0] * c[5] * c[14] + c[0] * c[6] * c[13] + c[4] * c[1] * c[14] + - c[4] * c[2] * c[13] - c[12] * c[1] * c[6] + c[12] * c[2] * c[5]; + inv[3] = -c[1] * c[6] * c[11] + c[1] * c[7] * c[10] + c[5] * c[2] * c[11] + - c[5] * c[3] * c[10] - c[9] * c[2] * c[7] + c[9] * c[3] * c[6]; + inv[7] = c[0] * c[6] * c[11] - c[0] * c[7] * c[10] - c[4] * c[2] * c[11] + + c[4] * c[3] * c[10] + c[8] * c[2] * c[7] - c[8] * c[3] * c[6]; + inv[11] = -c[0] * c[5] * c[11] + c[0] * c[7] * c[9] + c[4] * c[1] * c[11] + - c[4] * c[3] * c[9] - c[8] * c[1] * c[7] + c[8] * c[3] * c[5]; + inv[15] = c[0] * c[5] * c[10] - c[0] * c[6] * c[9] - c[4] * c[1] * c[10] + + c[4] * c[2] * c[9] + c[8] * c[1] * c[6] - c[8] * c[2] * c[5]; + + det = c[0] * inv[0] + c[1] * inv[4] + c[2] * inv[8] + c[3] * inv[12]; + + if (det == 0) { + return false; + } + + det = 1.0f / det; + + for (i = 0; i < 16; i++) { + c[i] = inv[i] * det; + } + + return true; } -void Matrix4::transpose() { - float trans[16]; - for(int x=0; x<4; x++) { - for(int y=0; y<4; y++) { - trans[x + y * 4] = c[y + x * 4]; - } +void Matrix4::transpose() +{ + float trans[16]; + for (int x = 0; x < 4; x++) { + for (int y = 0; y < 4; y++) { + trans[x + y * 4] = c[y + x * 4]; } - memcpy(c, trans, sizeof(float) * 16); + } + memcpy(c, trans, sizeof(float) * 16); } /* Dot Product, returning Vector3 */ -Vector3 Matrix4::Dot(const Matrix4 &m, const Vector3 &v) { - return Vector3::Create( - v.c[0] * m.c[0] + v.c[1] * m.c[4] + v.c[2] * m.c[8] + m.c[12], - v.c[0] * m.c[1] + v.c[1] * m.c[5] + v.c[2] * m.c[9] + m.c[13], - v.c[0] * m.c[2] + v.c[1] * m.c[6] + v.c[2] * m.c[10] + m.c[14] - ); +Vector3 Matrix4::Dot(const Matrix4& m, const Vector3& v) +{ + return Vector3::Create( + v.c[0] * m.c[0] + v.c[1] * m.c[4] + v.c[2] * m.c[8] + m.c[12], + v.c[0] * m.c[1] + v.c[1] * m.c[5] + v.c[2] * m.c[9] + m.c[13], + v.c[0] * m.c[2] + v.c[1] * m.c[6] + v.c[2] * m.c[10] + m.c[14] + ); } -Vector4 Matrix4::Dot4(const Matrix4 &m, const Vector4 &v) { +Vector4 Matrix4::Dot4(const Matrix4& m, const Vector4& v) +{ #ifdef KRAKEN_USE_ARM_NEON - Vector4 d; - d.init(); - asm volatile ( - "vld1.32 {d0, d1}, [%1] \n\t" //Q0 = v - "vld1.32 {d18, d19}, [%0]! \n\t" //Q1 = m - "vld1.32 {d20, d21}, [%0]! \n\t" //Q2 = m+4 - "vld1.32 {d22, d23}, [%0]! \n\t" //Q3 = m+8 - "vld1.32 {d24, d25}, [%0]! \n\t" //Q4 = m+12 - - "vmul.f32 q13, q9, d0[0] \n\t" //Q5 = Q1*Q0[0] - "vmla.f32 q13, q10, d0[1] \n\t" //Q5 += Q1*Q0[1] - "vmla.f32 q13, q11, d1[0] \n\t" //Q5 += Q2*Q0[2] - "vmla.f32 q13, q12, d1[1] \n\t" //Q5 += Q3*Q0[3] - - "vst1.32 {d26, d27}, [%2] \n\t" //Q4 = m+12 - : /* no output registers */ - : "r"(m.c), "r"(v.c), "r"(d.c) - : "q0", "q9", "q10","q11", "q12", "q13", "memory" - ); - return d; -#else - return Vector4::Create( - v.c[0] * m.c[0] + v.c[1] * m.c[4] + v.c[2] * m.c[8] + m.c[12], - v.c[0] * m.c[1] + v.c[1] * m.c[5] + v.c[2] * m.c[9] + m.c[13], - v.c[0] * m.c[2] + v.c[1] * m.c[6] + v.c[2] * m.c[10] + m.c[14], - v.c[0] * m.c[3] + v.c[1] * m.c[7] + v.c[2] * m.c[11] + m.c[15] + Vector4 d; + d.init(); + asm volatile ( + "vld1.32 {d0, d1}, [%1] \n\t" //Q0 = v + "vld1.32 {d18, d19}, [%0]! \n\t" //Q1 = m + "vld1.32 {d20, d21}, [%0]! \n\t" //Q2 = m+4 + "vld1.32 {d22, d23}, [%0]! \n\t" //Q3 = m+8 + "vld1.32 {d24, d25}, [%0]! \n\t" //Q4 = m+12 + + "vmul.f32 q13, q9, d0[0] \n\t" //Q5 = Q1*Q0[0] + "vmla.f32 q13, q10, d0[1] \n\t" //Q5 += Q1*Q0[1] + "vmla.f32 q13, q11, d1[0] \n\t" //Q5 += Q2*Q0[2] + "vmla.f32 q13, q12, d1[1] \n\t" //Q5 += Q3*Q0[3] + + "vst1.32 {d26, d27}, [%2] \n\t" //Q4 = m+12 + : /* no output registers */ + : "r"(m.c), "r"(v.c), "r"(d.c) + : "q0", "q9", "q10", "q11", "q12", "q13", "memory" ); + return d; +#else + return Vector4::Create( + v.c[0] * m.c[0] + v.c[1] * m.c[4] + v.c[2] * m.c[8] + m.c[12], + v.c[0] * m.c[1] + v.c[1] * m.c[5] + v.c[2] * m.c[9] + m.c[13], + v.c[0] * m.c[2] + v.c[1] * m.c[6] + v.c[2] * m.c[10] + m.c[14], + v.c[0] * m.c[3] + v.c[1] * m.c[7] + v.c[2] * m.c[11] + m.c[15] + ); #endif } // Dot product without including translation; useful for transforming normals and tangents -Vector3 Matrix4::DotNoTranslate(const Matrix4 &m, const Vector3 &v) +Vector3 Matrix4::DotNoTranslate(const Matrix4& m, const Vector3& v) { - return Vector3::Create( - v.x * m.c[0] + v.y * m.c[4] + v.z * m.c[8], - v.x * m.c[1] + v.y * m.c[5] + v.z * m.c[9], - v.x * m.c[2] + v.y * m.c[6] + v.z * m.c[10] - ); + return Vector3::Create( + v.x * m.c[0] + v.y * m.c[4] + v.z * m.c[8], + v.x * m.c[1] + v.y * m.c[5] + v.z * m.c[9], + v.x * m.c[2] + v.y * m.c[6] + v.z * m.c[10] + ); } /* Dot Product, returning w component as if it were a Vector4 (This will be deprecated once Vector4 is implemented instead*/ -float Matrix4::DotW(const Matrix4 &m, const Vector3 &v) { - return v.x * m.c[0*4 + 3] + v.y * m.c[1*4 + 3] + v.z * m.c[2*4 + 3] + m.c[3*4 + 3]; +float Matrix4::DotW(const Matrix4& m, const Vector3& v) +{ + return v.x * m.c[0 * 4 + 3] + v.y * m.c[1 * 4 + 3] + v.z * m.c[2 * 4 + 3] + m.c[3 * 4 + 3]; } /* Dot Product followed by W-divide */ -Vector3 Matrix4::DotWDiv(const Matrix4 &m, const Vector3 &v) { - Vector4 r = Dot4(m, Vector4::Create(v, 1.0f)); - return Vector3::Create(r) / r.w; +Vector3 Matrix4::DotWDiv(const Matrix4& m, const Vector3& v) +{ + Vector4 r = Dot4(m, Vector4::Create(v, 1.0f)); + return Vector3::Create(r) / r.w; } -Matrix4 Matrix4::LookAt(const Vector3 &cameraPos, const Vector3 &lookAtPos, const Vector3 &upDirection) +Matrix4 Matrix4::LookAt(const Vector3& cameraPos, const Vector3& lookAtPos, const Vector3& upDirection) { - Matrix4 matLookat; - matLookat.init(); - Vector3 lookat_z_axis = lookAtPos - cameraPos; - lookat_z_axis.normalize(); - Vector3 lookat_x_axis = Vector3::Cross(upDirection, lookat_z_axis); - lookat_x_axis.normalize(); - Vector3 lookat_y_axis = Vector3::Cross(lookat_z_axis, lookat_x_axis); - - matLookat.getPointer()[0] = lookat_x_axis.x; - matLookat.getPointer()[1] = lookat_y_axis.x; - matLookat.getPointer()[2] = lookat_z_axis.x; - - matLookat.getPointer()[4] = lookat_x_axis.y; - matLookat.getPointer()[5] = lookat_y_axis.y; - matLookat.getPointer()[6] = lookat_z_axis.y; - - matLookat.getPointer()[8] = lookat_x_axis.z; - matLookat.getPointer()[9] = lookat_y_axis.z; - matLookat.getPointer()[10] = lookat_z_axis.z; - - matLookat.getPointer()[12] = -Vector3::Dot(lookat_x_axis, cameraPos); - matLookat.getPointer()[13] = -Vector3::Dot(lookat_y_axis, cameraPos); - matLookat.getPointer()[14] = -Vector3::Dot(lookat_z_axis, cameraPos); - - return matLookat; + Matrix4 matLookat; + matLookat.init(); + Vector3 lookat_z_axis = lookAtPos - cameraPos; + lookat_z_axis.normalize(); + Vector3 lookat_x_axis = Vector3::Cross(upDirection, lookat_z_axis); + lookat_x_axis.normalize(); + Vector3 lookat_y_axis = Vector3::Cross(lookat_z_axis, lookat_x_axis); + + matLookat.getPointer()[0] = lookat_x_axis.x; + matLookat.getPointer()[1] = lookat_y_axis.x; + matLookat.getPointer()[2] = lookat_z_axis.x; + + matLookat.getPointer()[4] = lookat_x_axis.y; + matLookat.getPointer()[5] = lookat_y_axis.y; + matLookat.getPointer()[6] = lookat_z_axis.y; + + matLookat.getPointer()[8] = lookat_x_axis.z; + matLookat.getPointer()[9] = lookat_y_axis.z; + matLookat.getPointer()[10] = lookat_z_axis.z; + + matLookat.getPointer()[12] = -Vector3::Dot(lookat_x_axis, cameraPos); + matLookat.getPointer()[13] = -Vector3::Dot(lookat_y_axis, cameraPos); + matLookat.getPointer()[14] = -Vector3::Dot(lookat_z_axis, cameraPos); + + return matLookat; } -Matrix4 Matrix4::Invert(const Matrix4 &m) +Matrix4 Matrix4::Invert(const Matrix4& m) { - Matrix4 matInvert = m; - matInvert.invert(); - return matInvert; + Matrix4 matInvert = m; + matInvert.invert(); + return matInvert; } -Matrix4 Matrix4::Transpose(const Matrix4 &m) +Matrix4 Matrix4::Transpose(const Matrix4& m) { - Matrix4 matTranspose = m; - matTranspose.transpose(); - return matTranspose; + Matrix4 matTranspose = m; + matTranspose.transpose(); + return matTranspose; } -Matrix4 Matrix4::Translation(const Vector3 &v) +Matrix4 Matrix4::Translation(const Vector3& v) { - Matrix4 m; - m.init(); - m[12] = v.x; - m[13] = v.y; - m[14] = v.z; -// m.translate(v); - return m; + Matrix4 m; + m.init(); + m[12] = v.x; + m[13] = v.y; + m[14] = v.z; + // m.translate(v); + return m; } -Matrix4 Matrix4::Rotation(const Vector3 &v) +Matrix4 Matrix4::Rotation(const Vector3& v) { - Matrix4 m; - m.init(); - m.rotate(v.x, AXIS::X_AXIS); - m.rotate(v.y, AXIS::Y_AXIS); - m.rotate(v.z, AXIS::Z_AXIS); - return m; + Matrix4 m; + m.init(); + m.rotate(v.x, AXIS::X_AXIS); + m.rotate(v.y, AXIS::Y_AXIS); + m.rotate(v.z, AXIS::Z_AXIS); + return m; } -Matrix4 Matrix4::Scaling(const Vector3 &v) +Matrix4 Matrix4::Scaling(const Vector3& v) { - Matrix4 m; - m.init(); - m.scale(v); - return m; + Matrix4 m; + m.init(); + m.scale(v); + return m; } Matrix4 Matrix4::Identity() { - Matrix4 m; - m.init(); - return m; + Matrix4 m; + m.init(); + return m; } } // namespace kraken diff --git a/src/quaternion.cpp b/src/quaternion.cpp index 25eda71..e0cda44 100644 --- a/src/quaternion.cpp +++ b/src/quaternion.cpp @@ -35,323 +35,353 @@ namespace kraken { -void Quaternion::init() { - c[0] = 1.0; - c[1] = 0.0; - c[2] = 0.0; - c[3] = 0.0; +void Quaternion::init() +{ + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + c[3] = 0.0; } Quaternion Quaternion::Create() { - Quaternion r; - r.init(); - return r; + Quaternion r; + r.init(); + return r; } -void Quaternion::init(float w, float x, float y, float z) { - c[0] = w; - c[1] = x; - c[2] = y; - c[3] = z; +void Quaternion::init(float w, float x, float y, float z) +{ + c[0] = w; + c[1] = x; + c[2] = y; + c[3] = z; } Quaternion Quaternion::Create(float w, float x, float y, float z) { - Quaternion r; - r.init(w, x, y, z); - return r; + Quaternion r; + r.init(w, x, y, z); + return r; } -void Quaternion::init(const Quaternion& p) { - c[0] = p[0]; - c[1] = p[1]; - c[2] = p[2]; - c[3] = p[3]; +void Quaternion::init(const Quaternion& p) +{ + c[0] = p[0]; + c[1] = p[1]; + c[2] = p[2]; + c[3] = p[3]; } Quaternion Quaternion::Create(const Quaternion& p) { - Quaternion r; - r.init(p); - return r; + Quaternion r; + r.init(p); + return r; } -void Quaternion::init(const Vector3 &euler) { - setEulerZYX(euler); -} - -Quaternion Quaternion::Create(const Vector3 &euler) +void Quaternion::init(const Vector3& euler) { - Quaternion r; - r.init(euler); - return r; + setEulerZYX(euler); } -void Quaternion::init(const Vector3 &from_vector, const Vector3 &to_vector) { - - Vector3 a = Vector3::Cross(from_vector, to_vector); - c[0] = a[0]; - c[1] = a[1]; - c[2] = a[2]; - c[3] = sqrtf(from_vector.sqrMagnitude() * to_vector.sqrMagnitude()) + Vector3::Dot(from_vector, to_vector); - normalize(); -} - -Quaternion Quaternion::Create(const Vector3 &from_vector, const Vector3 &to_vector) +Quaternion Quaternion::Create(const Vector3& euler) { - Quaternion r; - r.init(from_vector, to_vector); - return r; + Quaternion r; + r.init(euler); + return r; } -void Quaternion::setEulerXYZ(const Vector3 &euler) +void Quaternion::init(const Vector3& from_vector, const Vector3& to_vector) { - *this = Quaternion::FromAngleAxis(Vector3::Create(1.0f, 0.0f, 0.0f), euler.x) - * Quaternion::FromAngleAxis(Vector3::Create(0.0f, 1.0f, 0.0f), euler.y) - * Quaternion::FromAngleAxis(Vector3::Create(0.0f, 0.0f, 1.0f), euler.z); + + Vector3 a = Vector3::Cross(from_vector, to_vector); + c[0] = a[0]; + c[1] = a[1]; + c[2] = a[2]; + c[3] = sqrtf(from_vector.sqrMagnitude() * to_vector.sqrMagnitude()) + Vector3::Dot(from_vector, to_vector); + normalize(); } -void Quaternion::setEulerZYX(const Vector3 &euler) { - // ZYX Order! - float c1 = cosf(euler[0] * 0.5f); - float c2 = cosf(euler[1] * 0.5f); - float c3 = cosf(euler[2] * 0.5f); - float s1 = sinf(euler[0] * 0.5f); - float s2 = sinf(euler[1] * 0.5f); - float s3 = sinf(euler[2] * 0.5f); - - c[0] = c1 * c2 * c3 + s1 * s2 * s3; - c[1] = s1 * c2 * c3 - c1 * s2 * s3; - c[2] = c1 * s2 * c3 + s1 * c2 * s3; - c[3] = c1 * c2 * s3 - s1 * s2 * c3; +Quaternion Quaternion::Create(const Vector3& from_vector, const Vector3& to_vector) +{ + Quaternion r; + r.init(from_vector, to_vector); + return r; } -float Quaternion::operator [](unsigned i) const { - return c[i]; +void Quaternion::setEulerXYZ(const Vector3& euler) +{ + *this = Quaternion::FromAngleAxis(Vector3::Create(1.0f, 0.0f, 0.0f), euler.x) + * Quaternion::FromAngleAxis(Vector3::Create(0.0f, 1.0f, 0.0f), euler.y) + * Quaternion::FromAngleAxis(Vector3::Create(0.0f, 0.0f, 1.0f), euler.z); } -float &Quaternion::operator [](unsigned i) { - return c[i]; +void Quaternion::setEulerZYX(const Vector3& euler) +{ + // ZYX Order! + float c1 = cosf(euler[0] * 0.5f); + float c2 = cosf(euler[1] * 0.5f); + float c3 = cosf(euler[2] * 0.5f); + float s1 = sinf(euler[0] * 0.5f); + float s2 = sinf(euler[1] * 0.5f); + float s3 = sinf(euler[2] * 0.5f); + + c[0] = c1 * c2 * c3 + s1 * s2 * s3; + c[1] = s1 * c2 * c3 - c1 * s2 * s3; + c[2] = c1 * s2 * c3 + s1 * c2 * s3; + c[3] = c1 * c2 * s3 - s1 * s2 * c3; } -Vector3 Quaternion::eulerXYZ() const { - float a2 = 2 * (c[0] * c[2] - c[1] * c[3]); - if(a2 <= -0.99999) { - return Vector3::Create( - 2.0f * atan2f(c[1], c[0]), - -PI * 0.5f, - 0 - ); - } else if(a2 >= 0.99999) { - return Vector3::Create( - 2.0f * atan2f(c[1], c[0]), - PI * 0.5f, - 0 - ); - } else { - return Vector3::Create( - atan2f(2 * (c[0] * c[1] + c[2] * c[3]), (1 - 2 * (c[1] * c[1] + c[2] * c[2]))), - asinf(a2), - atan2f(2 * (c[0] * c[3] + c[1] * c[2]), (1 - 2 * (c[2] * c[2] + c[3] * c[3]))) - ); - } - - +float Quaternion::operator [](unsigned i) const +{ + return c[i]; } -bool operator ==(Quaternion &v1, Quaternion &v2) { - return - v1[0] == v2[0] - && v1[1] == v2[1] - && v1[2] == v2[2] - && v1[3] == v2[3]; +float& Quaternion::operator [](unsigned i) +{ + return c[i]; } -bool operator !=(Quaternion &v1, Quaternion &v2) { - return - v1[0] != v2[0] - || v1[1] != v2[1] - || v1[2] != v2[2] - || v1[3] != v2[3]; -} - -Quaternion Quaternion::operator *(const Quaternion &v) { - float t0 = (c[3]-c[2])*(v[2]-v[3]); - float t1 = (c[0]+c[1])*(v[0]+v[1]); - float t2 = (c[0]-c[1])*(v[2]+v[3]); - float t3 = (c[3]+c[2])*(v[0]-v[1]); - float t4 = (c[3]-c[1])*(v[1]-v[2]); - float t5 = (c[3]+c[1])*(v[1]+v[2]); - float t6 = (c[0]+c[2])*(v[0]-v[3]); - float t7 = (c[0]-c[2])*(v[0]+v[3]); - float t8 = t5+t6+t7; - float t9 = (t4+t8)/2; - - return Quaternion::Create( - t0+t9-t5, - t1+t9-t8, - t2+t9-t7, - t3+t9-t6 +Vector3 Quaternion::eulerXYZ() const +{ + float a2 = 2 * (c[0] * c[2] - c[1] * c[3]); + if (a2 <= -0.99999) { + return Vector3::Create( + 2.0f * atan2f(c[1], c[0]), + -PI * 0.5f, + 0 ); -} - -Quaternion Quaternion::operator *(float v) const { - return Quaternion::Create(c[0] * v, c[1] * v, c[2] * v, c[3] * v); -} - -Quaternion Quaternion::operator /(float num) const { - float inv_num = 1.0f / num; - return Quaternion::Create(c[0] * inv_num, c[1] * inv_num, c[2] * inv_num, c[3] * inv_num); -} - -Quaternion Quaternion::operator +(const Quaternion &v) const { - return Quaternion::Create(c[0] + v[0], c[1] + v[1], c[2] + v[2], c[3] + v[3]); -} - -Quaternion Quaternion::operator -(const Quaternion &v) const { - return Quaternion::Create(c[0] - v[0], c[1] - v[1], c[2] - v[2], c[3] - v[3]); -} - -Quaternion& Quaternion::operator +=(const Quaternion& v) { - c[0] += v[0]; - c[1] += v[1]; - c[2] += v[2]; - c[3] += v[3]; - return *this; -} - -Quaternion& Quaternion::operator -=(const Quaternion& v) { - c[0] -= v[0]; - c[1] -= v[1]; - c[2] -= v[2]; - c[3] -= v[3]; - return *this; -} - -Quaternion& Quaternion::operator *=(const Quaternion& v) { - float t0 = (c[3]-c[2])*(v[2]-v[3]); - float t1 = (c[0]+c[1])*(v[0]+v[1]); - float t2 = (c[0]-c[1])*(v[2]+v[3]); - float t3 = (c[3]+c[2])*(v[0]-v[1]); - float t4 = (c[3]-c[1])*(v[1]-v[2]); - float t5 = (c[3]+c[1])*(v[1]+v[2]); - float t6 = (c[0]+c[2])*(v[0]-v[3]); - float t7 = (c[0]-c[2])*(v[0]+v[3]); - float t8 = t5+t6+t7; - float t9 = (t4+t8)/2; - - c[0] = t0+t9-t5; - c[1] = t1+t9-t8; - c[2] = t2+t9-t7; - c[3] = t3+t9-t6; - - return *this; -} - -Quaternion& Quaternion::operator *=(const float& v) { - c[0] *= v; - c[1] *= v; - c[2] *= v; - c[3] *= v; - return *this; -} - -Quaternion& Quaternion::operator /=(const float& v) { - float inv_v = 1.0f / v; - c[0] *= inv_v; - c[1] *= inv_v; - c[2] *= inv_v; - c[3] *= inv_v; - return *this; -} - -Quaternion Quaternion::operator +() const { - return *this; -} - -Quaternion Quaternion::operator -() const { - return Quaternion::Create(-c[0], -c[1], -c[2], -c[3]); -} - -Quaternion Quaternion::Normalize(const Quaternion &v1) { - float inv_magnitude = 1.0f / sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] + v1[3] * v1[3]); - return Quaternion::Create( - v1[0] * inv_magnitude, - v1[1] * inv_magnitude, - v1[2] * inv_magnitude, - v1[3] * inv_magnitude + } else if (a2 >= 0.99999) { + return Vector3::Create( + 2.0f * atan2f(c[1], c[0]), + PI * 0.5f, + 0 ); + } else { + return Vector3::Create( + atan2f(2 * (c[0] * c[1] + c[2] * c[3]), (1 - 2 * (c[1] * c[1] + c[2] * c[2]))), + asinf(a2), + atan2f(2 * (c[0] * c[3] + c[1] * c[2]), (1 - 2 * (c[2] * c[2] + c[3] * c[3]))) + ); + } + + } -void Quaternion::normalize() { - float inv_magnitude = 1.0f / sqrtf(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]); - c[0] *= inv_magnitude; - c[1] *= inv_magnitude; - c[2] *= inv_magnitude; - c[3] *= inv_magnitude; +bool operator ==(Quaternion& v1, Quaternion& v2) +{ + return + v1[0] == v2[0] + && v1[1] == v2[1] + && v1[2] == v2[2] + && v1[3] == v2[3]; } -Quaternion Quaternion::Conjugate(const Quaternion &v1) { - return Quaternion::Create(v1[0], -v1[1], -v1[2], -v1[3]); +bool operator !=(Quaternion& v1, Quaternion& v2) +{ + return + v1[0] != v2[0] + || v1[1] != v2[1] + || v1[2] != v2[2] + || v1[3] != v2[3]; } -void Quaternion::conjugate() { - c[1] = -c[1]; - c[2] = -c[2]; - c[3] = -c[3]; +Quaternion Quaternion::operator *(const Quaternion& v) +{ + float t0 = (c[3] - c[2]) * (v[2] - v[3]); + float t1 = (c[0] + c[1]) * (v[0] + v[1]); + float t2 = (c[0] - c[1]) * (v[2] + v[3]); + float t3 = (c[3] + c[2]) * (v[0] - v[1]); + float t4 = (c[3] - c[1]) * (v[1] - v[2]); + float t5 = (c[3] + c[1]) * (v[1] + v[2]); + float t6 = (c[0] + c[2]) * (v[0] - v[3]); + float t7 = (c[0] - c[2]) * (v[0] + v[3]); + float t8 = t5 + t6 + t7; + float t9 = (t4 + t8) / 2; + + return Quaternion::Create( + t0 + t9 - t5, + t1 + t9 - t8, + t2 + t9 - t7, + t3 + t9 - t6 + ); } -void Quaternion::invert() { +Quaternion Quaternion::operator *(float v) const +{ + return Quaternion::Create(c[0] * v, c[1] * v, c[2] * v, c[3] * v); +} + +Quaternion Quaternion::operator /(float num) const +{ + float inv_num = 1.0f / num; + return Quaternion::Create(c[0] * inv_num, c[1] * inv_num, c[2] * inv_num, c[3] * inv_num); +} + +Quaternion Quaternion::operator +(const Quaternion& v) const +{ + return Quaternion::Create(c[0] + v[0], c[1] + v[1], c[2] + v[2], c[3] + v[3]); +} + +Quaternion Quaternion::operator -(const Quaternion& v) const +{ + return Quaternion::Create(c[0] - v[0], c[1] - v[1], c[2] - v[2], c[3] - v[3]); +} + +Quaternion& Quaternion::operator +=(const Quaternion& v) +{ + c[0] += v[0]; + c[1] += v[1]; + c[2] += v[2]; + c[3] += v[3]; + return *this; +} + +Quaternion& Quaternion::operator -=(const Quaternion& v) +{ + c[0] -= v[0]; + c[1] -= v[1]; + c[2] -= v[2]; + c[3] -= v[3]; + return *this; +} + +Quaternion& Quaternion::operator *=(const Quaternion& v) +{ + float t0 = (c[3] - c[2]) * (v[2] - v[3]); + float t1 = (c[0] + c[1]) * (v[0] + v[1]); + float t2 = (c[0] - c[1]) * (v[2] + v[3]); + float t3 = (c[3] + c[2]) * (v[0] - v[1]); + float t4 = (c[3] - c[1]) * (v[1] - v[2]); + float t5 = (c[3] + c[1]) * (v[1] + v[2]); + float t6 = (c[0] + c[2]) * (v[0] - v[3]); + float t7 = (c[0] - c[2]) * (v[0] + v[3]); + float t8 = t5 + t6 + t7; + float t9 = (t4 + t8) / 2; + + c[0] = t0 + t9 - t5; + c[1] = t1 + t9 - t8; + c[2] = t2 + t9 - t7; + c[3] = t3 + t9 - t6; + + return *this; +} + +Quaternion& Quaternion::operator *=(const float& v) +{ + c[0] *= v; + c[1] *= v; + c[2] *= v; + c[3] *= v; + return *this; +} + +Quaternion& Quaternion::operator /=(const float& v) +{ + float inv_v = 1.0f / v; + c[0] *= inv_v; + c[1] *= inv_v; + c[2] *= inv_v; + c[3] *= inv_v; + return *this; +} + +Quaternion Quaternion::operator +() const +{ + return *this; +} + +Quaternion Quaternion::operator -() const +{ + return Quaternion::Create(-c[0], -c[1], -c[2], -c[3]); +} + +Quaternion Quaternion::Normalize(const Quaternion& v1) +{ + float inv_magnitude = 1.0f / sqrtf(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] + v1[3] * v1[3]); + return Quaternion::Create( + v1[0] * inv_magnitude, + v1[1] * inv_magnitude, + v1[2] * inv_magnitude, + v1[3] * inv_magnitude + ); +} + +void Quaternion::normalize() +{ + float inv_magnitude = 1.0f / sqrtf(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]); + c[0] *= inv_magnitude; + c[1] *= inv_magnitude; + c[2] *= inv_magnitude; + c[3] *= inv_magnitude; +} + +Quaternion Quaternion::Conjugate(const Quaternion& v1) +{ + return Quaternion::Create(v1[0], -v1[1], -v1[2], -v1[3]); +} + +void Quaternion::conjugate() +{ + c[1] = -c[1]; + c[2] = -c[2]; + c[3] = -c[3]; +} + +void Quaternion::invert() +{ conjugate(); normalize(); } -Quaternion Quaternion::Invert(const Quaternion &v1) { +Quaternion Quaternion::Invert(const Quaternion& v1) +{ return Normalize(Conjugate(v1)); } -Matrix4 Quaternion::rotationMatrix() const { - Matrix4 matRotate; - matRotate.init(); - - /* - Vector3 euler = eulerXYZ(); - - matRotate.rotate(euler.x, X_AXIS); - matRotate.rotate(euler.y, Y_AXIS); - matRotate.rotate(euler.z, Z_AXIS); - */ - - // FINDME - Determine why the more optimal routine commented below wasn't working - - - matRotate.c[0] = 1.0f - 2.0f * (c[2] * c[2] + c[3] * c[3]); - matRotate.c[1] = 2.0f * (c[1] * c[2] - c[0] * c[3]); - matRotate.c[2] = 2.0f * (c[0] * c[2] + c[1] * c[3]); - - matRotate.c[4] = 2.0f * (c[1] * c[2] + c[0] * c[3]); - matRotate.c[5] = 1.0f - 2.0f * (c[1] * c[1] + c[3] * c[3]); - matRotate.c[6] = 2.0f * (c[2] * c[3] - c[0] * c[1]); - - matRotate.c[8] = 2.0f * (c[1] * c[3] - c[0] * c[2]); - matRotate.c[9] = 2.0f * (c[0] * c[1] + c[2] * c[3]); - matRotate.c[10] = 1.0f - 2.0f * (c[1] * c[1] + c[2] * c[2]); - - return matRotate; +Matrix4 Quaternion::rotationMatrix() const +{ + Matrix4 matRotate; + matRotate.init(); + + /* + Vector3 euler = eulerXYZ(); + + matRotate.rotate(euler.x, X_AXIS); + matRotate.rotate(euler.y, Y_AXIS); + matRotate.rotate(euler.z, Z_AXIS); + */ + + // FINDME - Determine why the more optimal routine commented below wasn't working + + + matRotate.c[0] = 1.0f - 2.0f * (c[2] * c[2] + c[3] * c[3]); + matRotate.c[1] = 2.0f * (c[1] * c[2] - c[0] * c[3]); + matRotate.c[2] = 2.0f * (c[0] * c[2] + c[1] * c[3]); + + matRotate.c[4] = 2.0f * (c[1] * c[2] + c[0] * c[3]); + matRotate.c[5] = 1.0f - 2.0f * (c[1] * c[1] + c[3] * c[3]); + matRotate.c[6] = 2.0f * (c[2] * c[3] - c[0] * c[1]); + + matRotate.c[8] = 2.0f * (c[1] * c[3] - c[0] * c[2]); + matRotate.c[9] = 2.0f * (c[0] * c[1] + c[2] * c[3]); + matRotate.c[10] = 1.0f - 2.0f * (c[1] * c[1] + c[2] * c[2]); + + return matRotate; } -Quaternion Quaternion::FromAngleAxis(const Vector3 &axis, float angle) +Quaternion Quaternion::FromAngleAxis(const Vector3& axis, float angle) { - float ha = angle * 0.5f; - float sha = sinf(ha); - return Quaternion::Create(cosf(ha), axis.x * sha, axis.y * sha, axis.z * sha); + float ha = angle * 0.5f; + float sha = sinf(ha); + return Quaternion::Create(cosf(ha), axis.x * sha, axis.y * sha, axis.z * sha); } -Quaternion Quaternion::FromRotationMatrix(const Matrix4 &m) +Quaternion Quaternion::FromRotationMatrix(const Matrix4& m) { -// see http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + // see http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm const float trace = m[0] + m[5] + m[10]; float w, x, y, z; if (trace > 0.0) { @@ -379,53 +409,53 @@ Quaternion Quaternion::FromRotationMatrix(const Matrix4 &m) y = (m[6] + m[9]) / s; z = 0.25f * s; } - return Quaternion::Create(w, x, y, z); + return Quaternion::Create(w, x, y, z); } -float Quaternion::Dot(const Quaternion &v1, const Quaternion &v2) +float Quaternion::Dot(const Quaternion& v1, const Quaternion& v2) { - return v1.c[0] * v2.c[0] + v1.c[1] * v2.c[1] + v1.c[2] * v2.c[2] + v1.c[3] * v2.c[3]; + return v1.c[0] * v2.c[0] + v1.c[1] * v2.c[1] + v1.c[2] * v2.c[2] + v1.c[3] * v2.c[3]; } -Quaternion Quaternion::Lerp(const Quaternion &a, const Quaternion &b, float t) +Quaternion Quaternion::Lerp(const Quaternion& a, const Quaternion& b, float t) { - if (t <= 0.0f) { - return a; - } else if (t >= 1.0f) { - return b; - } - - return a * (1.0f - t) + b * t; + if (t <= 0.0f) { + return a; + } else if (t >= 1.0f) { + return b; + } + + return a * (1.0f - t) + b * t; } -Quaternion Quaternion::Slerp(const Quaternion &a, const Quaternion &b, float t) +Quaternion Quaternion::Slerp(const Quaternion& a, const Quaternion& b, float t) { - if (t <= 0.0f) { - return a; - } - - if (t >= 1.0f) { - return b; - } - - float coshalftheta = Dot(a, b); - Quaternion c = a; - - // Angle is greater than 180. We can negate the angle/quat to get the - // shorter rotation to reach the same destination. - if ( coshalftheta < 0.0f ) { - coshalftheta = -coshalftheta; - c = -c; - } - - if ( coshalftheta > (1.0f - std::numeric_limits::epsilon())) { - // Angle is tiny - save some computation by lerping instead. - return Lerp(c, b, t); - } - - float halftheta = acosf(coshalftheta); - - return (c * sinf((1.0f - t) * halftheta) + b * sinf(t * halftheta)) / sinf(halftheta); + if (t <= 0.0f) { + return a; + } + + if (t >= 1.0f) { + return b; + } + + float coshalftheta = Dot(a, b); + Quaternion c = a; + + // Angle is greater than 180. We can negate the angle/quat to get the + // shorter rotation to reach the same destination. + if (coshalftheta < 0.0f) { + coshalftheta = -coshalftheta; + c = -c; + } + + if (coshalftheta > (1.0f - std::numeric_limits::epsilon())) { + // Angle is tiny - save some computation by lerping instead. + return Lerp(c, b, t); + } + + float halftheta = acosf(coshalftheta); + + return (c * sinf((1.0f - t) * halftheta) + b * sinf(t * halftheta)) / sinf(halftheta); } } // namespace kraken diff --git a/src/scalar.cpp b/src/scalar.cpp index 90cf1cc..c75f3bd 100644 --- a/src/scalar.cpp +++ b/src/scalar.cpp @@ -35,8 +35,8 @@ namespace kraken { float SmoothStep(float a, float b, float t) { - float d = (3.0f * t * t - 2.0f * t * t * t); - return a * (1.0f - d) + b * d; + float d = (3.0f * t * t - 2.0f * t * t * t); + return a * (1.0f - d) + b * d; } float Lerp(float a, float b, float t) diff --git a/src/triangle3.cpp b/src/triangle3.cpp index 235f9ab..554a750 100644 --- a/src/triangle3.cpp +++ b/src/triangle3.cpp @@ -34,92 +34,92 @@ using namespace kraken; namespace { - bool _intersectSphere(const Vector3 &start, const Vector3 &dir, const Vector3 &sphere_center, float sphere_radius, float &distance) - { - // dir must be normalized +bool _intersectSphere(const Vector3& start, const Vector3& dir, const Vector3& sphere_center, float sphere_radius, float& distance) +{ + // dir must be normalized - // From: http://archive.gamedev.net/archive/reference/articles/article1026.html + // From: http://archive.gamedev.net/archive/reference/articles/article1026.html - // TODO - Move to another class? - Vector3 Q = sphere_center - start; - float c = Q.magnitude(); - float v = Vector3::Dot(Q, dir); - float d = sphere_radius * sphere_radius - (c * c - v * v); + // TODO - Move to another class? + Vector3 Q = sphere_center - start; + float c = Q.magnitude(); + float v = Vector3::Dot(Q, dir); + float d = sphere_radius * sphere_radius - (c * c - v * v); - if (d < 0.0) { - // No intersection - return false; - } - - // Return the distance to the [first] intersecting point - - distance = v - sqrtf(d); - if (distance < 0.0f) { - return false; - } - return true; - - } - - bool _sameSide(const Vector3 &p1, const Vector3 &p2, const Vector3 &a, const Vector3 &b) - { - // TODO - Move to Vector3 class? - // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle - - Vector3 cp1 = Vector3::Cross(b - a, p1 - a); - Vector3 cp2 = Vector3::Cross(b - a, p2 - a); - if (Vector3::Dot(cp1, cp2) >= 0) return true; + if (d < 0.0) { + // No intersection return false; } - Vector3 _closestPointOnLine(const Vector3 &a, const Vector3 &b, const Vector3 &p) - { - // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle + // Return the distance to the [first] intersecting point - // Determine t (the length of the vector from ‘a’ to ‘p’) - - Vector3 c = p - a; - Vector3 V = Vector3::Normalize(b - a); - float d = (a - b).magnitude(); - float t = Vector3::Dot(V, c); - - // Check to see if ‘t’ is beyond the extents of the line segment - - if (t < 0) return a; - if (t > d) return b; - - // Return the point between ‘a’ and ‘b’ - - return a + V * t; + distance = v - sqrtf(d); + if (distance < 0.0f) { + return false; } + return true; + +} + +bool _sameSide(const Vector3& p1, const Vector3& p2, const Vector3& a, const Vector3& b) +{ + // TODO - Move to Vector3 class? + // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle + + Vector3 cp1 = Vector3::Cross(b - a, p1 - a); + Vector3 cp2 = Vector3::Cross(b - a, p2 - a); + if (Vector3::Dot(cp1, cp2) >= 0) return true; + return false; +} + +Vector3 _closestPointOnLine(const Vector3& a, const Vector3& b, const Vector3& p) +{ + // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle + + // Determine t (the length of the vector from ‘a’ to ‘p’) + + Vector3 c = p - a; + Vector3 V = Vector3::Normalize(b - a); + float d = (a - b).magnitude(); + float t = Vector3::Dot(V, c); + + // Check to see if ‘t’ is beyond the extents of the line segment + + if (t < 0) return a; + if (t > d) return b; + + // Return the point between ‘a’ and ‘b’ + + return a + V * t; +} } // anonymous namespace namespace kraken { -void Triangle3::init(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3) +void Triangle3::init(const Vector3& v1, const Vector3& v2, const Vector3& v3) { - vert[0] = v1; - vert[1] = v2; - vert[2] = v3; + vert[0] = v1; + vert[1] = v2; + vert[2] = v3; } -void Triangle3::init(const Triangle3 &tri) +void Triangle3::init(const Triangle3& tri) { - vert[0] = tri[0]; - vert[1] = tri[1]; - vert[2] = tri[2]; + vert[0] = tri[0]; + vert[1] = tri[1]; + vert[2] = tri[2]; } -Triangle3 Triangle3::Create(const Triangle3 &tri) +Triangle3 Triangle3::Create(const Triangle3& tri) { Triangle3 r; r.init(tri); return r; } -Triangle3 Triangle3::Create(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3) +Triangle3 Triangle3::Create(const Vector3& v1, const Vector3& v2, const Vector3& v3) { Triangle3 r; r.init(v1, v2, v3); @@ -128,226 +128,226 @@ Triangle3 Triangle3::Create(const Vector3 &v1, const Vector3 &v2, const Vector3 bool Triangle3::operator ==(const Triangle3& b) const { - return vert[0] == b[0] && vert[1] == b[1] && vert[2] == b[2]; + return vert[0] == b[0] && vert[1] == b[1] && vert[2] == b[2]; } bool Triangle3::operator !=(const Triangle3& b) const { - return vert[0] != b[0] || vert[1] != b[1] || vert[2] != b[2]; + return vert[0] != b[0] || vert[1] != b[1] || vert[2] != b[2]; } Vector3& Triangle3::operator[](unsigned int i) { - return vert[i]; + return vert[i]; } Vector3 Triangle3::operator[](unsigned int i) const { - return vert[i]; + return vert[i]; } -bool Triangle3::rayCast(const Vector3 &start, const Vector3 &dir, Vector3 &hit_point) const +bool Triangle3::rayCast(const Vector3& start, const Vector3& dir, Vector3& hit_point) const { - // algorithm based on Dan Sunday's implementation at http://geomalgorithms.com/a06-_intersect-2.html - const float SMALL_NUM = 0.00000001f; // anything that avoids division overflow - Vector3 u, v, n; // triangle vectors - Vector3 w0, w; // ray vectors - float r, a, b; // params to calc ray-plane intersect - - // get triangle edge vectors and plane normal - u = vert[1] - vert[0]; - v = vert[2] - vert[0]; - n = Vector3::Cross(u, v); // cross product - if (n == Vector3::Zero()) // triangle is degenerate - return false; // do not deal with this case - - w0 = start - vert[0]; - a = -Vector3::Dot(n, w0); - b = Vector3::Dot(n,dir); - if (fabs(b) < SMALL_NUM) { // ray is parallel to triangle plane - if (a == 0) - return false; // ray lies in triangle plane - else { - return false; // ray disjoint from plane - } - } - - // get intersect point of ray with triangle plane - r = a / b; - if (r < 0.0f) // ray goes away from triangle - return false; // => no intersect - // for a segment, also test if (r > 1.0) => no intersect - - - Vector3 plane_hit_point = start + dir * r; // intersect point of ray and plane - - // is plane_hit_point inside triangle? - float uu, uv, vv, wu, wv, D; - uu = Vector3::Dot(u,u); - uv = Vector3::Dot(u,v); - vv = Vector3::Dot(v,v); - w = plane_hit_point - vert[0]; - wu = Vector3::Dot(w,u); - wv = Vector3::Dot(w,v); - D = uv * uv - uu * vv; - - // get and test parametric coords - float s, t; - s = (uv * wv - vv * wu) / D; - if (s < 0.0f || s > 1.0f) // plane_hit_point is outside triangle - return false; - t = (uv * wu - uu * wv) / D; - if (t < 0.0f || (s + t) > 1.0f) // plane_hit_point is outside triangle - return false; + // algorithm based on Dan Sunday's implementation at http://geomalgorithms.com/a06-_intersect-2.html + const float SMALL_NUM = 0.00000001f; // anything that avoids division overflow + Vector3 u, v, n; // triangle vectors + Vector3 w0, w; // ray vectors + float r, a, b; // params to calc ray-plane intersect - // plane_hit_point is inside the triangle - hit_point = plane_hit_point; - return true; + // get triangle edge vectors and plane normal + u = vert[1] - vert[0]; + v = vert[2] - vert[0]; + n = Vector3::Cross(u, v); // cross product + if (n == Vector3::Zero()) // triangle is degenerate + return false; // do not deal with this case + + w0 = start - vert[0]; + a = -Vector3::Dot(n, w0); + b = Vector3::Dot(n, dir); + if (fabs(b) < SMALL_NUM) { // ray is parallel to triangle plane + if (a == 0) + return false; // ray lies in triangle plane + else { + return false; // ray disjoint from plane + } + } + + // get intersect point of ray with triangle plane + r = a / b; + if (r < 0.0f) // ray goes away from triangle + return false; // => no intersect +// for a segment, also test if (r > 1.0) => no intersect + + + Vector3 plane_hit_point = start + dir * r; // intersect point of ray and plane + + // is plane_hit_point inside triangle? + float uu, uv, vv, wu, wv, D; + uu = Vector3::Dot(u, u); + uv = Vector3::Dot(u, v); + vv = Vector3::Dot(v, v); + w = plane_hit_point - vert[0]; + wu = Vector3::Dot(w, u); + wv = Vector3::Dot(w, v); + D = uv * uv - uu * vv; + + // get and test parametric coords + float s, t; + s = (uv * wv - vv * wu) / D; + if (s < 0.0f || s > 1.0f) // plane_hit_point is outside triangle + return false; + t = (uv * wu - uu * wv) / D; + if (t < 0.0f || (s + t) > 1.0f) // plane_hit_point is outside triangle + return false; + + // plane_hit_point is inside the triangle + hit_point = plane_hit_point; + return true; } Vector3 Triangle3::calculateNormal() const { - Vector3 v1 = vert[1] - vert[0]; - Vector3 v2 = vert[2] - vert[0]; - - return Vector3::Normalize(Vector3::Cross(v1, v2)); + Vector3 v1 = vert[1] - vert[0]; + Vector3 v2 = vert[2] - vert[0]; + + return Vector3::Normalize(Vector3::Cross(v1, v2)); } -Vector3 Triangle3::closestPointOnTriangle(const Vector3 &p) const +Vector3 Triangle3::closestPointOnTriangle(const Vector3& p) const { - Vector3 a = vert[0]; - Vector3 b = vert[1]; - Vector3 c = vert[2]; - - Vector3 Rab = _closestPointOnLine(a, b, p); - Vector3 Rbc = _closestPointOnLine(b, c, p); - Vector3 Rca = _closestPointOnLine(c, a, p); - - // return closest [Rab, Rbc, Rca] to p; - float sd_Rab = (p - Rab).sqrMagnitude(); - float sd_Rbc = (p - Rbc).sqrMagnitude(); - float sd_Rca = (p - Rca).sqrMagnitude(); - - if(sd_Rab < sd_Rbc && sd_Rab < sd_Rca) { - return Rab; - } else if(sd_Rbc < sd_Rab && sd_Rbc < sd_Rca) { - return Rbc; - } else { - return Rca; - } + Vector3 a = vert[0]; + Vector3 b = vert[1]; + Vector3 c = vert[2]; + + Vector3 Rab = _closestPointOnLine(a, b, p); + Vector3 Rbc = _closestPointOnLine(b, c, p); + Vector3 Rca = _closestPointOnLine(c, a, p); + + // return closest [Rab, Rbc, Rca] to p; + float sd_Rab = (p - Rab).sqrMagnitude(); + float sd_Rbc = (p - Rbc).sqrMagnitude(); + float sd_Rca = (p - Rca).sqrMagnitude(); + + if (sd_Rab < sd_Rbc && sd_Rab < sd_Rca) { + return Rab; + } else if (sd_Rbc < sd_Rab && sd_Rbc < sd_Rca) { + return Rbc; + } else { + return Rca; + } } -bool Triangle3::sphereCast(const Vector3 &start, const Vector3 &dir, float radius, Vector3 &hit_point, float &hit_distance) const +bool Triangle3::sphereCast(const Vector3& start, const Vector3& dir, float radius, Vector3& hit_point, float& hit_distance) const { - // Dir must be normalized - const float SMALL_NUM = 0.001f; // anything that avoids division overflow - - Vector3 tri_normal = calculateNormal(); - - float d = Vector3::Dot(tri_normal, vert[0]); - float e = Vector3::Dot(tri_normal, start) - radius; - float cotangent_distance = e - d; - - Vector3 plane_intersect; - float plane_intersect_distance; - - float denom = Vector3::Dot(tri_normal, dir); - - if(denom > -SMALL_NUM) { - return false; // dir is co-planar with the triangle or going in the direction of the normal; no intersection - } + // Dir must be normalized + const float SMALL_NUM = 0.001f; // anything that avoids division overflow - // Detect an embedded plane, caused by a sphere that is already intersecting the plane. - if(cotangent_distance <= 0 && cotangent_distance >= -radius * 2.0f) { - // Embedded plane - Sphere is already intersecting the plane. - // Use the point closest to the origin of the sphere as the intersection - plane_intersect = start - tri_normal * (cotangent_distance + radius); - plane_intersect_distance = 0.0f; - } else { - // Sphere is not intersecting the plane - // Determine the first point hit by the swept sphere on the triangle's plane - - plane_intersect_distance = -(cotangent_distance / denom); - plane_intersect = start + dir * plane_intersect_distance - tri_normal * radius; - } - - if(plane_intersect_distance < 0.0f) { - return false; - } - - if(containsPoint(plane_intersect)) { - // Triangle contains point - hit_point = plane_intersect; - hit_distance = plane_intersect_distance; - return true; - } else { - // Triangle does not contain point, cast ray back to sphere from closest point on triangle edge or vertice - Vector3 closest_point = closestPointOnTriangle(plane_intersect); - float reverse_hit_distance; - if(_intersectSphere(closest_point, -dir, start, radius, reverse_hit_distance)) { - // Reverse cast hit sphere - hit_distance = reverse_hit_distance; - hit_point = closest_point; - return true; - } else { - // Reverse cast did not hit sphere - return false; - } - } -} + Vector3 tri_normal = calculateNormal(); + float d = Vector3::Dot(tri_normal, vert[0]); + float e = Vector3::Dot(tri_normal, start) - radius; + float cotangent_distance = e - d; -bool Triangle3::containsPoint(const Vector3 &p) const -{ - /* - // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle - - const float SMALL_NUM = 0.00000001f; // anything that avoids division overflow - // Vector3 A = vert[0], B = vert[1], C = vert[2]; - if (_sameSide(p, vert[0], vert[1], vert[2]) && _sameSide(p, vert[1], vert[0], vert[2]) && _sameSide(p, vert[2], vert[0], vert[1])) { - Vector3 vc1 = Vector3::Cross(vert[0] - vert[1], vert[0] - vert[2]); - if(fabs(Vector3::Dot(vert[0] - p, vc1)) <= SMALL_NUM) { - return true; - } - } - + Vector3 plane_intersect; + float plane_intersect_distance; + + float denom = Vector3::Dot(tri_normal, dir); + + if (denom > -SMALL_NUM) { + return false; // dir is co-planar with the triangle or going in the direction of the normal; no intersection + } + + // Detect an embedded plane, caused by a sphere that is already intersecting the plane. + if (cotangent_distance <= 0 && cotangent_distance >= -radius * 2.0f) { + // Embedded plane - Sphere is already intersecting the plane. + // Use the point closest to the origin of the sphere as the intersection + plane_intersect = start - tri_normal * (cotangent_distance + radius); + plane_intersect_distance = 0.0f; + } else { + // Sphere is not intersecting the plane + // Determine the first point hit by the swept sphere on the triangle's plane + + plane_intersect_distance = -(cotangent_distance / denom); + plane_intersect = start + dir * plane_intersect_distance - tri_normal * radius; + } + + if (plane_intersect_distance < 0.0f) { return false; - */ - - // From: http://blogs.msdn.com/b/rezanour/archive/2011/08/07/barycentric-coordinates-and-point-in-triangle-tests.aspx - - Vector3 A = vert[0]; - Vector3 B = vert[1]; - Vector3 C = vert[2]; - Vector3 P = p; - - // Prepare our barycentric variables - Vector3 u = B - A; - Vector3 v = C - A; - Vector3 w = P - A; - - Vector3 vCrossW = Vector3::Cross(v, w); - Vector3 vCrossU = Vector3::Cross(v, u); - - // Test sign of r - if (Vector3::Dot(vCrossW, vCrossU) < 0) - return false; - - Vector3 uCrossW = Vector3::Cross(u, w); - Vector3 uCrossV = Vector3::Cross(u, v); - - // Test sign of t - if (Vector3::Dot(uCrossW, uCrossV) < 0) - return false; - - // At this point, we know that r and t and both > 0. - // Therefore, as long as their sum is <= 1, each must be less <= 1 - float denom = uCrossV.magnitude(); - float r = vCrossW.magnitude() / denom; - float t = uCrossW.magnitude() / denom; - - return (r + t <= 1); + } + + if (containsPoint(plane_intersect)) { + // Triangle contains point + hit_point = plane_intersect; + hit_distance = plane_intersect_distance; + return true; + } else { + // Triangle does not contain point, cast ray back to sphere from closest point on triangle edge or vertice + Vector3 closest_point = closestPointOnTriangle(plane_intersect); + float reverse_hit_distance; + if (_intersectSphere(closest_point, -dir, start, radius, reverse_hit_distance)) { + // Reverse cast hit sphere + hit_distance = reverse_hit_distance; + hit_point = closest_point; + return true; + } else { + // Reverse cast did not hit sphere + return false; + } + } +} + + +bool Triangle3::containsPoint(const Vector3& p) const +{ + /* + // From: http://stackoverflow.com/questions/995445/determine-if-a-3d-point-is-within-a-triangle + + const float SMALL_NUM = 0.00000001f; // anything that avoids division overflow + // Vector3 A = vert[0], B = vert[1], C = vert[2]; + if (_sameSide(p, vert[0], vert[1], vert[2]) && _sameSide(p, vert[1], vert[0], vert[2]) && _sameSide(p, vert[2], vert[0], vert[1])) { + Vector3 vc1 = Vector3::Cross(vert[0] - vert[1], vert[0] - vert[2]); + if(fabs(Vector3::Dot(vert[0] - p, vc1)) <= SMALL_NUM) { + return true; + } + } + + return false; + */ + + // From: http://blogs.msdn.com/b/rezanour/archive/2011/08/07/barycentric-coordinates-and-point-in-triangle-tests.aspx + + Vector3 A = vert[0]; + Vector3 B = vert[1]; + Vector3 C = vert[2]; + Vector3 P = p; + + // Prepare our barycentric variables + Vector3 u = B - A; + Vector3 v = C - A; + Vector3 w = P - A; + + Vector3 vCrossW = Vector3::Cross(v, w); + Vector3 vCrossU = Vector3::Cross(v, u); + + // Test sign of r + if (Vector3::Dot(vCrossW, vCrossU) < 0) + return false; + + Vector3 uCrossW = Vector3::Cross(u, w); + Vector3 uCrossV = Vector3::Cross(u, v); + + // Test sign of t + if (Vector3::Dot(uCrossW, uCrossV) < 0) + return false; + + // At this point, we know that r and t and both > 0. + // Therefore, as long as their sum is <= 1, each must be less <= 1 + float denom = uCrossV.magnitude(); + float r = vCrossW.magnitude() / denom; + float t = uCrossW.magnitude() / denom; + + return (r + t <= 1); } } // namespace kraken diff --git a/src/vector2.cpp b/src/vector2.cpp index 635a925..237a0df 100644 --- a/src/vector2.cpp +++ b/src/vector2.cpp @@ -34,237 +34,268 @@ namespace kraken { -void Vector2::init() { - x = 0.0; - y = 0.0; +void Vector2::init() +{ + x = 0.0; + y = 0.0; } Vector2 Vector2::Create() { - Vector2 r; - r.init(); - return r; + Vector2 r; + r.init(); + return r; } -void Vector2::init(float X, float Y) { - x = X; - y = Y; +void Vector2::init(float X, float Y) +{ + x = X; + y = Y; } Vector2 Vector2::Create(float X, float Y) { - Vector2 r; - r.init(X,Y); - return r; + Vector2 r; + r.init(X, Y); + return r; } -void Vector2::init(float v) { - x = v; - y = v; +void Vector2::init(float v) +{ + x = v; + y = v; } Vector2 Vector2::Create(float v) { - Vector2 r; - r.init(v); - return r; + Vector2 r; + r.init(v); + return r; } -void Vector2::init(float *v) { - x = v[0]; - y = v[1]; -} - -Vector2 Vector2::Create(float *v) +void Vector2::init(float* v) { - Vector2 r; - r.init(v); - return r; + x = v[0]; + y = v[1]; } -void Vector2::init(const Vector2 &v) { - x = v.x; - y = v.y; -} - -Vector2 Vector2::Create(const Vector2 &v) +Vector2 Vector2::Create(float* v) { - Vector2 r; - r.init(v); - return r; + Vector2 r; + r.init(v); + return r; +} + +void Vector2::init(const Vector2& v) +{ + x = v.x; + y = v.y; +} + +Vector2 Vector2::Create(const Vector2& v) +{ + Vector2 r; + r.init(v); + return r; } // Vector2 swizzle getters Vector2 Vector2::yx() const { - return Vector2::Create(y,x); + return Vector2::Create(y, x); } // Vector2 swizzle setters -void Vector2::yx(const Vector2 &v) +void Vector2::yx(const Vector2& v) { - y = v.x; - x = v.y; + y = v.x; + x = v.y; } -Vector2 Vector2::Min() { - return Vector2::Create(-std::numeric_limits::max()); +Vector2 Vector2::Min() +{ + return Vector2::Create(-std::numeric_limits::max()); } -Vector2 Vector2::Max() { - return Vector2::Create(std::numeric_limits::max()); +Vector2 Vector2::Max() +{ + return Vector2::Create(std::numeric_limits::max()); } -Vector2 Vector2::Zero() { - return Vector2::Create(0.0f); +Vector2 Vector2::Zero() +{ + return Vector2::Create(0.0f); } -Vector2 Vector2::One() { - return Vector2::Create(1.0f); +Vector2 Vector2::One() +{ + return Vector2::Create(1.0f); } -Vector2 Vector2::operator +(const Vector2& b) const { - return Vector2::Create(x + b.x, y + b.y); +Vector2 Vector2::operator +(const Vector2& b) const +{ + return Vector2::Create(x + b.x, y + b.y); } -Vector2 Vector2::operator -(const Vector2& b) const { - return Vector2::Create(x - b.x, y - b.y); +Vector2 Vector2::operator -(const Vector2& b) const +{ + return Vector2::Create(x - b.x, y - b.y); } -Vector2 Vector2::operator +() const { - return *this; +Vector2 Vector2::operator +() const +{ + return *this; } -Vector2 Vector2::operator -() const { - return Vector2::Create(-x, -y); +Vector2 Vector2::operator -() const +{ + return Vector2::Create(-x, -y); } -Vector2 Vector2::operator *(const float v) const { - return Vector2::Create(x * v, y * v); +Vector2 Vector2::operator *(const float v) const +{ + return Vector2::Create(x * v, y * v); } -Vector2 Vector2::operator /(const float v) const { - float inv_v = 1.0f / v; - return Vector2::Create(x * inv_v, y * inv_v); +Vector2 Vector2::operator /(const float v) const +{ + float inv_v = 1.0f / v; + return Vector2::Create(x * inv_v, y * inv_v); } -Vector2& Vector2::operator +=(const Vector2& b) { - x += b.x; - y += b.y; - return *this; +Vector2& Vector2::operator +=(const Vector2& b) +{ + x += b.x; + y += b.y; + return *this; } -Vector2& Vector2::operator -=(const Vector2& b) { - x -= b.x; - y -= b.y; - return *this; +Vector2& Vector2::operator -=(const Vector2& b) +{ + x -= b.x; + y -= b.y; + return *this; } -Vector2& Vector2::operator *=(const float v) { - x *= v; - y *= v; - return *this; +Vector2& Vector2::operator *=(const float v) +{ + x *= v; + y *= v; + return *this; } -Vector2& Vector2::operator /=(const float v) { - float inv_v = 1.0f / v; - x *= inv_v; - y *= inv_v; - return *this; +Vector2& Vector2::operator /=(const float v) +{ + float inv_v = 1.0f / v; + x *= inv_v; + y *= inv_v; + return *this; } -bool Vector2::operator ==(const Vector2& b) const { - return x == b.x && y == b.y; +bool Vector2::operator ==(const Vector2& b) const +{ + return x == b.x && y == b.y; } -bool Vector2::operator !=(const Vector2& b) const { - return x != b.x || y != b.y; +bool Vector2::operator !=(const Vector2& b) const +{ + return x != b.x || y != b.y; } bool Vector2::operator >(const Vector2& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(x > b.x) { - return true; - } else if(x < b.x) { - return false; - } else if(y > b.y) { - return true; - } else { - return false; - } + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (x > b.x) { + return true; + } else if (x < b.x) { + return false; + } else if (y > b.y) { + return true; + } else { + return false; + } } bool Vector2::operator <(const Vector2& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(x < b.x) { - return true; - } else if(x > b.x) { - return false; - } else if(y < b.y) { - return true; - } else { - return false; - } + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (x < b.x) { + return true; + } else if (x > b.x) { + return false; + } else if (y < b.y) { + return true; + } else { + return false; + } } -float& Vector2::operator[] (unsigned i) { - switch(i) { - case 0: - return x; - case 1: - default: - return y; - } +float& Vector2::operator[] (unsigned i) +{ + switch (i) { + case 0: + return x; + case 1: + default: + return y; + } } -float Vector2::operator[](unsigned i) const { - switch(i) { - case 0: - return x; - case 1: - default: - return y; - } +float Vector2::operator[](unsigned i) const +{ + switch (i) { + case 0: + return x; + case 1: + default: + return y; + } } -void Vector2::normalize() { - float inv_magnitude = 1.0f / sqrtf(x * x + y * y); - x *= inv_magnitude; - y *= inv_magnitude; +void Vector2::normalize() +{ + float inv_magnitude = 1.0f / sqrtf(x * x + y * y); + x *= inv_magnitude; + y *= inv_magnitude; } -float Vector2::sqrMagnitude() const { - return x * x + y * y; +float Vector2::sqrMagnitude() const +{ + return x * x + y * y; } -float Vector2::magnitude() const { - return sqrtf(x * x + y * y); +float Vector2::magnitude() const +{ + return sqrtf(x * x + y * y); } -Vector2 Vector2::Normalize(const Vector2 &v) { - float inv_magnitude = 1.0f / sqrtf(v.x * v.x + v.y * v.y); - return Vector2::Create(v.x * inv_magnitude, v.y * inv_magnitude); +Vector2 Vector2::Normalize(const Vector2& v) +{ + float inv_magnitude = 1.0f / sqrtf(v.x * v.x + v.y * v.y); + return Vector2::Create(v.x * inv_magnitude, v.y * inv_magnitude); } -float Vector2::Cross(const Vector2 &v1, const Vector2 &v2) { - return v1.x * v2.y - v1.y * v2.x; +float Vector2::Cross(const Vector2& v1, const Vector2& v2) +{ + return v1.x * v2.y - v1.y * v2.x; } -float Vector2::Dot(const Vector2 &v1, const Vector2 &v2) { - return v1.x * v2.x + v1.y * v2.y; +float Vector2::Dot(const Vector2& v1, const Vector2& v2) +{ + return v1.x * v2.x + v1.y * v2.y; } -Vector2 Vector2::Min(const Vector2 &v1, const Vector2 &v2) { +Vector2 Vector2::Min(const Vector2& v1, const Vector2& v2) +{ return Vector2::Create(KRMIN(v1.x, v2.x), KRMIN(v1.y, v2.y)); } -Vector2 Vector2::Max(const Vector2 &v1, const Vector2 &v2) { +Vector2 Vector2::Max(const Vector2& v1, const Vector2& v2) +{ return Vector2::Create(KRMAX(v1.x, v2.x), KRMAX(v1.y, v2.y)); } diff --git a/src/vector2i.cpp b/src/vector2i.cpp index 7bde9cd..71a5e84 100644 --- a/src/vector2i.cpp +++ b/src/vector2i.cpp @@ -34,231 +34,262 @@ namespace kraken { -void Vector2i::init() { - x = 0; - y = 0; +void Vector2i::init() +{ + x = 0; + y = 0; } Vector2i Vector2i::Create() { - Vector2i r; - r.init(); - return r; + Vector2i r; + r.init(); + return r; } -void Vector2i::init(int X, int Y) { - x = X; - y = Y; +void Vector2i::init(int X, int Y) +{ + x = X; + y = Y; } Vector2i Vector2i::Create(int X, int Y) { - Vector2i r; - r.init(X,Y); - return r; + Vector2i r; + r.init(X, Y); + return r; } -void Vector2i::init(int v) { - x = v; - y = v; +void Vector2i::init(int v) +{ + x = v; + y = v; } Vector2i Vector2i::Create(int v) { - Vector2i r; - r.init(v); - return r; + Vector2i r; + r.init(v); + return r; } -void Vector2i::init(int *v) { - x = v[0]; - y = v[1]; -} - -Vector2i Vector2i::Create(int *v) +void Vector2i::init(int* v) { - Vector2i r; - r.init(v); - return r; + x = v[0]; + y = v[1]; } -void Vector2i::init(const Vector2i &v) { - x = v.x; - y = v.y; -} - -Vector2i Vector2i::Create(const Vector2i &v) +Vector2i Vector2i::Create(int* v) { - Vector2i r; - r.init(v); - return r; + Vector2i r; + r.init(v); + return r; +} + +void Vector2i::init(const Vector2i& v) +{ + x = v.x; + y = v.y; +} + +Vector2i Vector2i::Create(const Vector2i& v) +{ + Vector2i r; + r.init(v); + return r; } // Vector2 swizzle getters Vector2i Vector2i::yx() const { - return Vector2i::Create(y,x); + return Vector2i::Create(y, x); } // Vector2 swizzle setters -void Vector2i::yx(const Vector2i &v) +void Vector2i::yx(const Vector2i& v) { - y = v.x; - x = v.y; + y = v.x; + x = v.y; } -Vector2i Vector2i::Min() { - return Vector2i::Create(-std::numeric_limits::max()); +Vector2i Vector2i::Min() +{ + return Vector2i::Create(-std::numeric_limits::max()); } -Vector2i Vector2i::Max() { - return Vector2i::Create(std::numeric_limits::max()); +Vector2i Vector2i::Max() +{ + return Vector2i::Create(std::numeric_limits::max()); } -Vector2i Vector2i::Zero() { - return Vector2i::Create(0); +Vector2i Vector2i::Zero() +{ + return Vector2i::Create(0); } -Vector2i Vector2i::One() { - return Vector2i::Create(1); +Vector2i Vector2i::One() +{ + return Vector2i::Create(1); } -Vector2i Vector2i::operator +(const Vector2i& b) const { - return Vector2i::Create(x + b.x, y + b.y); +Vector2i Vector2i::operator +(const Vector2i& b) const +{ + return Vector2i::Create(x + b.x, y + b.y); } -Vector2i Vector2i::operator -(const Vector2i& b) const { - return Vector2i::Create(x - b.x, y - b.y); +Vector2i Vector2i::operator -(const Vector2i& b) const +{ + return Vector2i::Create(x - b.x, y - b.y); } -Vector2i Vector2i::operator +() const { - return *this; +Vector2i Vector2i::operator +() const +{ + return *this; } -Vector2i Vector2i::operator -() const { - return Vector2i::Create(-x, -y); +Vector2i Vector2i::operator -() const +{ + return Vector2i::Create(-x, -y); } -Vector2i Vector2i::operator *(const int v) const { - return Vector2i::Create(x * v, y * v); +Vector2i Vector2i::operator *(const int v) const +{ + return Vector2i::Create(x * v, y * v); } -Vector2i Vector2i::operator /(const int v) const { - return Vector2i::Create(x / v, y / v); +Vector2i Vector2i::operator /(const int v) const +{ + return Vector2i::Create(x / v, y / v); } -Vector2i& Vector2i::operator +=(const Vector2i& b) { - x += b.x; - y += b.y; - return *this; +Vector2i& Vector2i::operator +=(const Vector2i& b) +{ + x += b.x; + y += b.y; + return *this; } -Vector2i& Vector2i::operator -=(const Vector2i& b) { - x -= b.x; - y -= b.y; - return *this; +Vector2i& Vector2i::operator -=(const Vector2i& b) +{ + x -= b.x; + y -= b.y; + return *this; } -Vector2i& Vector2i::operator *=(const int v) { - x *= v; - y *= v; - return *this; +Vector2i& Vector2i::operator *=(const int v) +{ + x *= v; + y *= v; + return *this; } -Vector2i& Vector2i::operator /=(const int v) { - x /= v; - y /= v; - return *this; +Vector2i& Vector2i::operator /=(const int v) +{ + x /= v; + y /= v; + return *this; } -bool Vector2i::operator ==(const Vector2i& b) const { - return x == b.x && y == b.y; +bool Vector2i::operator ==(const Vector2i& b) const +{ + return x == b.x && y == b.y; } -bool Vector2i::operator !=(const Vector2i& b) const { - return x != b.x || y != b.y; +bool Vector2i::operator !=(const Vector2i& b) const +{ + return x != b.x || y != b.y; } bool Vector2i::operator >(const Vector2i& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(x > b.x) { - return true; - } else if(x < b.x) { - return false; - } else if(y > b.y) { - return true; - } else { - return false; - } + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (x > b.x) { + return true; + } else if (x < b.x) { + return false; + } else if (y > b.y) { + return true; + } else { + return false; + } } bool Vector2i::operator <(const Vector2i& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(x < b.x) { - return true; - } else if(x > b.x) { - return false; - } else if(y < b.y) { - return true; - } else { - return false; - } + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (x < b.x) { + return true; + } else if (x > b.x) { + return false; + } else if (y < b.y) { + return true; + } else { + return false; + } } -int& Vector2i::operator[] (unsigned i) { - switch(i) { - case 0: - return x; - case 1: - default: - return y; - } +int& Vector2i::operator[] (unsigned i) +{ + switch (i) { + case 0: + return x; + case 1: + default: + return y; + } } -int Vector2i::operator[](unsigned i) const { - switch(i) { - case 0: - return x; - case 1: - default: - return y; - } +int Vector2i::operator[](unsigned i) const +{ + switch (i) { + case 0: + return x; + case 1: + default: + return y; + } } -void Vector2i::normalize() { - int m = magnitude(); - x /= m; - y /= m; +void Vector2i::normalize() +{ + int m = magnitude(); + x /= m; + y /= m; } -int Vector2i::sqrMagnitude() const { - return x * x + y * y; +int Vector2i::sqrMagnitude() const +{ + return x * x + y * y; } -int Vector2i::magnitude() const { - return static_cast(sqrtf((float)x * (float)x + (float)y * (float)y)); +int Vector2i::magnitude() const +{ + return static_cast(sqrtf((float)x * (float)x + (float)y * (float)y)); } -Vector2i Vector2i::Normalize(const Vector2i &v) { - int m = v.magnitude(); - return Vector2i::Create(v.x / m, v.y / m); +Vector2i Vector2i::Normalize(const Vector2i& v) +{ + int m = v.magnitude(); + return Vector2i::Create(v.x / m, v.y / m); } -int Vector2i::Cross(const Vector2i &v1, const Vector2i &v2) { - return v1.x * v2.y - v1.y * v2.x; +int Vector2i::Cross(const Vector2i& v1, const Vector2i& v2) +{ + return v1.x * v2.y - v1.y * v2.x; } -int Vector2i::Dot(const Vector2i &v1, const Vector2i &v2) { - return v1.x * v2.x + v1.y * v2.y; +int Vector2i::Dot(const Vector2i& v1, const Vector2i& v2) +{ + return v1.x * v2.x + v1.y * v2.y; } -Vector2i Vector2i::Min(const Vector2i &v1, const Vector2i &v2) { +Vector2i Vector2i::Min(const Vector2i& v1, const Vector2i& v2) +{ return Vector2i::Create(KRMIN(v1.x, v2.x), KRMIN(v1.y, v2.y)); } -Vector2i Vector2i::Max(const Vector2i &v1, const Vector2i &v2) { +Vector2i Vector2i::Max(const Vector2i& v1, const Vector2i& v2) +{ return Vector2i::Create(KRMAX(v1.x, v2.x), KRMAX(v1.y, v2.y)); } diff --git a/src/vector3.cpp b/src/vector3.cpp index 2be52cf..35ead73 100644 --- a/src/vector3.cpp +++ b/src/vector3.cpp @@ -37,428 +37,469 @@ namespace kraken { //default constructor void Vector3::init() { - x = 0.0f; - y = 0.0f; - z = 0.0f; + x = 0.0f; + y = 0.0f; + z = 0.0f; } Vector3 Vector3::Create() { - Vector3 r; - r.init(); - return r; + Vector3 r; + r.init(); + return r; } -void Vector3::init(const Vector3 &v) { - x = v.x; - y = v.y; - z = v.z; -} - -Vector3 Vector3::Create(const Vector3 &v) +void Vector3::init(const Vector3& v) { - Vector3 r; - r.init(v); - return r; + x = v.x; + y = v.y; + z = v.z; } -void Vector3::init(const Vector4 &v) { - x = v.x; - y = v.y; - z = v.z; -} - -Vector3 Vector3::Create(const Vector4 &v) +Vector3 Vector3::Create(const Vector3& v) { - Vector3 r; - r.init(v); - return r; + Vector3 r; + r.init(v); + return r; } -void Vector3::init(float *v) { - x = v[0]; - y = v[1]; - z = v[2]; -} - -Vector3 Vector3::Create(float *v) +void Vector3::init(const Vector4& v) { - Vector3 r; - r.init(v); - return r; + x = v.x; + y = v.y; + z = v.z; } - -void Vector3::init(double *v) { - x = (float)v[0]; - y = (float)v[1]; - z = (float)v[2]; -} - -Vector3 Vector3::Create(double *v) +Vector3 Vector3::Create(const Vector4& v) { - Vector3 r; - r.init(v); - return r; + Vector3 r; + r.init(v); + return r; +} + +void Vector3::init(float* v) +{ + x = v[0]; + y = v[1]; + z = v[2]; +} + +Vector3 Vector3::Create(float* v) +{ + Vector3 r; + r.init(v); + return r; } -void Vector3::init(float v) { - x = v; - y = v; - z = v; +void Vector3::init(double* v) +{ + x = (float)v[0]; + y = (float)v[1]; + z = (float)v[2]; +} + +Vector3 Vector3::Create(double* v) +{ + Vector3 r; + r.init(v); + return r; +} + + +void Vector3::init(float v) +{ + x = v; + y = v; + z = v; } Vector3 Vector3::Create(float v) { - Vector3 r; - r.init(v); - return r; + Vector3 r; + r.init(v); + return r; } void Vector3::init(float X, float Y, float Z) { - x = X; - y = Y; - z = Z; + x = X; + y = Y; + z = Z; } Vector3 Vector3::Create(float X, float Y, float Z) { - Vector3 r; - r.init(X,Y,Z); - return r; + Vector3 r; + r.init(X, Y, Z); + return r; } Vector2 Vector3::xx() const { - return Vector2::Create(x,x); + return Vector2::Create(x, x); } Vector2 Vector3::xy() const { - return Vector2::Create(x,y); + return Vector2::Create(x, y); } Vector2 Vector3::xz() const { - return Vector2::Create(x,z); + return Vector2::Create(x, z); } Vector2 Vector3::yx() const { - return Vector2::Create(y,x); + return Vector2::Create(y, x); } Vector2 Vector3::yy() const { - return Vector2::Create(y,y); + return Vector2::Create(y, y); } Vector2 Vector3::yz() const { - return Vector2::Create(y,z); + return Vector2::Create(y, z); } Vector2 Vector3::zx() const { - return Vector2::Create(z,x); + return Vector2::Create(z, x); } Vector2 Vector3::zy() const { - return Vector2::Create(z,y); + return Vector2::Create(z, y); } Vector2 Vector3::zz() const { - return Vector2::Create(z,z); + return Vector2::Create(z, z); } -void Vector3::xy(const Vector2 &v) +void Vector3::xy(const Vector2& v) { - x = v.x; - y = v.y; + x = v.x; + y = v.y; } -void Vector3::xz(const Vector2 &v) +void Vector3::xz(const Vector2& v) { - x = v.x; - z = v.y; + x = v.x; + z = v.y; } -void Vector3::yx(const Vector2 &v) +void Vector3::yx(const Vector2& v) { - y = v.x; - x = v.y; + y = v.x; + x = v.y; } -void Vector3::yz(const Vector2 &v) +void Vector3::yz(const Vector2& v) { - y = v.x; - z = v.y; + y = v.x; + z = v.y; } -void Vector3::zx(const Vector2 &v) +void Vector3::zx(const Vector2& v) { - z = v.x; - x = v.y; + z = v.x; + x = v.y; } -void Vector3::zy(const Vector2 &v) +void Vector3::zy(const Vector2& v) { - z = v.x; - y = v.y; + z = v.x; + y = v.y; } -Vector3 Vector3::Min() { - return Vector3::Create(-std::numeric_limits::max()); -} - -Vector3 Vector3::Max() { - return Vector3::Create(std::numeric_limits::max()); -} - -Vector3 Vector3::Zero() { - return Vector3::Create(); -} - -Vector3 Vector3::One() { - return Vector3::Create(1.0f, 1.0f, 1.0f); -} - -Vector3 Vector3::Forward() { - return Vector3::Create(0.0f, 0.0f, 1.0f); -} - -Vector3 Vector3::Backward() { - return Vector3::Create(0.0f, 0.0f, -1.0f); -} - -Vector3 Vector3::Up() { - return Vector3::Create(0.0f, 1.0f, 0.0f); -} - -Vector3 Vector3::Down() { - return Vector3::Create(0.0f, -1.0f, 0.0f); -} - -Vector3 Vector3::Left() { - return Vector3::Create(-1.0f, 0.0f, 0.0f); -} - -Vector3 Vector3::Right() { - return Vector3::Create(1.0f, 0.0f, 0.0f); -} - - -void Vector3::scale(const Vector3 &v) +Vector3 Vector3::Min() { - x *= v.x; - y *= v.y; - z *= v.z; + return Vector3::Create(-std::numeric_limits::max()); } -Vector3 Vector3::Scale(const Vector3 &v1, const Vector3 &v2) +Vector3 Vector3::Max() { - return Vector3::Create(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); + return Vector3::Create(std::numeric_limits::max()); } -Vector3 Vector3::Lerp(const Vector3 &v1, const Vector3 &v2, float d) { - return v1 + (v2 - v1) * d; +Vector3 Vector3::Zero() +{ + return Vector3::Create(); } -Vector3 Vector3::Slerp(const Vector3 &v1, const Vector3 &v2, float d) { - // From: http://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/ - // Dot product - the cosine of the angle between 2 vectors. - float dot = Vector3::Dot(v1, v2); - // Clamp it to be in the range of Acos() - if(dot < -1.0f) dot = -1.0f; - if(dot > 1.0f) dot = 1.0f; - // Acos(dot) returns the angle between start and end, - // And multiplying that by percent returns the angle between - // start and the final result. - float theta = acosf(dot)*d; - Vector3 RelativeVec = v2 - v1*dot; - RelativeVec.normalize(); // Orthonormal basis - // The final result. - return ((v1*cosf(theta)) + (RelativeVec*sinf(theta))); +Vector3 Vector3::One() +{ + return Vector3::Create(1.0f, 1.0f, 1.0f); } -void Vector3::OrthoNormalize(Vector3 &normal, Vector3 &tangent) { - // Gram-Schmidt Orthonormalization - normal.normalize(); - Vector3 proj = normal * Dot(tangent, normal); - tangent = tangent - proj; - tangent.normalize(); +Vector3 Vector3::Forward() +{ + return Vector3::Create(0.0f, 0.0f, 1.0f); } -Vector3& Vector3::operator =(const Vector4 &b) { - x = b.x; - y = b.y; - z = b.z; - return *this; +Vector3 Vector3::Backward() +{ + return Vector3::Create(0.0f, 0.0f, -1.0f); } -Vector3 Vector3::operator +(const Vector3& b) const { - return Vector3::Create(x + b.x, y + b.y, z + b.z); -} -Vector3 Vector3::operator -(const Vector3& b) const { - return Vector3::Create(x - b.x, y - b.y, z - b.z); -} -Vector3 Vector3::operator +() const { - return *this; -} -Vector3 Vector3::operator -() const { - return Vector3::Create(-x, -y, -z); +Vector3 Vector3::Up() +{ + return Vector3::Create(0.0f, 1.0f, 0.0f); } -Vector3 Vector3::operator *(const float v) const { - return Vector3::Create(x * v, y * v, z * v); +Vector3 Vector3::Down() +{ + return Vector3::Create(0.0f, -1.0f, 0.0f); } -Vector3 Vector3::operator /(const float v) const { - float inv_v = 1.0f / v; - return Vector3::Create(x * inv_v, y * inv_v, z * inv_v); +Vector3 Vector3::Left() +{ + return Vector3::Create(-1.0f, 0.0f, 0.0f); } -Vector3& Vector3::operator +=(const Vector3& b) { - x += b.x; - y += b.y; - z += b.z; - - return *this; +Vector3 Vector3::Right() +{ + return Vector3::Create(1.0f, 0.0f, 0.0f); } -Vector3& Vector3::operator -=(const Vector3& b) { - x -= b.x; - y -= b.y; - z -= b.z; - - return *this; + +void Vector3::scale(const Vector3& v) +{ + x *= v.x; + y *= v.y; + z *= v.z; } -Vector3& Vector3::operator *=(const float v) { - x *= v; - y *= v; - z *= v; - - return *this; +Vector3 Vector3::Scale(const Vector3& v1, const Vector3& v2) +{ + return Vector3::Create(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); } -Vector3& Vector3::operator /=(const float v) { - float inv_v = 1.0f / v; - x *= inv_v; - y *= inv_v; - z *= inv_v; - - return *this; +Vector3 Vector3::Lerp(const Vector3& v1, const Vector3& v2, float d) +{ + return v1 + (v2 - v1) * d; } -bool Vector3::operator ==(const Vector3& b) const { - return x == b.x && y == b.y && z == b.z; - -} -bool Vector3::operator !=(const Vector3& b) const { - return x != b.x || y != b.y || z != b.z; +Vector3 Vector3::Slerp(const Vector3& v1, const Vector3& v2, float d) +{ + // From: http://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/ + // Dot product - the cosine of the angle between 2 vectors. + float dot = Vector3::Dot(v1, v2); + // Clamp it to be in the range of Acos() + if (dot < -1.0f) dot = -1.0f; + if (dot > 1.0f) dot = 1.0f; + // Acos(dot) returns the angle between start and end, + // And multiplying that by percent returns the angle between + // start and the final result. + float theta = acosf(dot) * d; + Vector3 RelativeVec = v2 - v1 * dot; + RelativeVec.normalize(); // Orthonormal basis + // The final result. + return ((v1 * cosf(theta)) + (RelativeVec * sinf(theta))); } -float& Vector3::operator[](unsigned i) { - switch(i) { - case 0: - return x; - case 1: - return y; - default: - case 2: - return z; - } +void Vector3::OrthoNormalize(Vector3& normal, Vector3& tangent) +{ + // Gram-Schmidt Orthonormalization + normal.normalize(); + Vector3 proj = normal * Dot(tangent, normal); + tangent = tangent - proj; + tangent.normalize(); } -float Vector3::operator[](unsigned i) const { - switch(i) { - case 0: - return x; - case 1: - return y; - case 2: - default: - return z; - } +Vector3& Vector3::operator =(const Vector4& b) +{ + x = b.x; + y = b.y; + z = b.z; + return *this; } -float Vector3::sqrMagnitude() const { - // calculate the square of the magnitude (useful for comparison of magnitudes without the cost of a sqrt() function) - return x * x + y * y + z * z; +Vector3 Vector3::operator +(const Vector3& b) const +{ + return Vector3::Create(x + b.x, y + b.y, z + b.z); +} +Vector3 Vector3::operator -(const Vector3& b) const +{ + return Vector3::Create(x - b.x, y - b.y, z - b.z); +} +Vector3 Vector3::operator +() const +{ + return *this; +} +Vector3 Vector3::operator -() const +{ + return Vector3::Create(-x, -y, -z); } -float Vector3::magnitude() const { - return sqrtf(x * x + y * y + z * z); +Vector3 Vector3::operator *(const float v) const +{ + return Vector3::Create(x * v, y * v, z * v); } -void Vector3::normalize() { - float inv_magnitude = 1.0f / sqrtf(x * x + y * y + z * z); - x *= inv_magnitude; - y *= inv_magnitude; - z *= inv_magnitude; -} -Vector3 Vector3::Normalize(const Vector3 &v) { - float inv_magnitude = 1.0f / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); - return Vector3::Create(v.x * inv_magnitude, v.y * inv_magnitude, v.z * inv_magnitude); +Vector3 Vector3::operator /(const float v) const +{ + float inv_v = 1.0f / v; + return Vector3::Create(x * inv_v, y * inv_v, z * inv_v); } -Vector3 Vector3::Cross(const Vector3 &v1, const Vector3 &v2) { - return Vector3::Create(v1.y * v2.z - v1.z * v2.y, - v1.z * v2.x - v1.x * v2.z, - v1.x * v2.y - v1.y * v2.x); +Vector3& Vector3::operator +=(const Vector3& b) +{ + x += b.x; + y += b.y; + z += b.z; + + return *this; } -float Vector3::Dot(const Vector3 &v1, const Vector3 &v2) { - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; +Vector3& Vector3::operator -=(const Vector3& b) +{ + x -= b.x; + y -= b.y; + z -= b.z; + + return *this; } -Vector3 Vector3::Min(const Vector3 &v1, const Vector3 &v2) { +Vector3& Vector3::operator *=(const float v) +{ + x *= v; + y *= v; + z *= v; + + return *this; +} + +Vector3& Vector3::operator /=(const float v) +{ + float inv_v = 1.0f / v; + x *= inv_v; + y *= inv_v; + z *= inv_v; + + return *this; +} + +bool Vector3::operator ==(const Vector3& b) const +{ + return x == b.x && y == b.y && z == b.z; + +} +bool Vector3::operator !=(const Vector3& b) const +{ + return x != b.x || y != b.y || z != b.z; +} + +float& Vector3::operator[](unsigned i) +{ + switch (i) { + case 0: + return x; + case 1: + return y; + default: + case 2: + return z; + } +} + +float Vector3::operator[](unsigned i) const +{ + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + default: + return z; + } +} + +float Vector3::sqrMagnitude() const +{ + // calculate the square of the magnitude (useful for comparison of magnitudes without the cost of a sqrt() function) + return x * x + y * y + z * z; +} + +float Vector3::magnitude() const +{ + return sqrtf(x * x + y * y + z * z); +} + +void Vector3::normalize() +{ + float inv_magnitude = 1.0f / sqrtf(x * x + y * y + z * z); + x *= inv_magnitude; + y *= inv_magnitude; + z *= inv_magnitude; +} +Vector3 Vector3::Normalize(const Vector3& v) +{ + float inv_magnitude = 1.0f / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); + return Vector3::Create(v.x * inv_magnitude, v.y * inv_magnitude, v.z * inv_magnitude); +} + +Vector3 Vector3::Cross(const Vector3& v1, const Vector3& v2) +{ + return Vector3::Create(v1.y * v2.z - v1.z * v2.y, + v1.z * v2.x - v1.x * v2.z, + v1.x * v2.y - v1.y * v2.x); +} + +float Vector3::Dot(const Vector3& v1, const Vector3& v2) +{ + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; +} + +Vector3 Vector3::Min(const Vector3& v1, const Vector3& v2) +{ return Vector3::Create(KRMIN(v1.x, v2.x), KRMIN(v1.y, v2.y), KRMIN(v1.z, v2.z)); } -Vector3 Vector3::Max(const Vector3 &v1, const Vector3 &v2) { +Vector3 Vector3::Max(const Vector3& v1, const Vector3& v2) +{ return Vector3::Create(KRMAX(v1.x, v2.x), KRMAX(v1.y, v2.y), KRMAX(v1.z, v2.z)); } bool Vector3::operator >(const Vector3& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(x > b.x) { - return true; - } else if(x < b.x) { - return false; - } else if(y > b.y) { - return true; - } else if(y < b.y) { - return false; - } else if(z > b.z) { - return true; - } else { - return false; - } + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (x > b.x) { + return true; + } else if (x < b.x) { + return false; + } else if (y > b.y) { + return true; + } else if (y < b.y) { + return false; + } else if (z > b.z) { + return true; + } else { + return false; + } } bool Vector3::operator <(const Vector3& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(x < b.x) { - return true; - } else if(x > b.x) { - return false; - } else if(y < b.y) { - return true; - } else if(y > b.y) { - return false; - } else if(z < b.z) { - return true; - } else { - return false; - } + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (x < b.x) { + return true; + } else if (x > b.x) { + return false; + } else if (y < b.y) { + return true; + } else if (y > b.y) { + return false; + } else if (z < b.z) { + return true; + } else { + return false; + } } } // namespace kraken diff --git a/src/vector4.cpp b/src/vector4.cpp index e49795a..e753b24 100644 --- a/src/vector4.cpp +++ b/src/vector4.cpp @@ -37,308 +37,346 @@ namespace kraken { //default constructor void Vector4::init() { - x = 0.0f; - y = 0.0f; - z = 0.0f; - w = 0.0f; + x = 0.0f; + y = 0.0f; + z = 0.0f; + w = 0.0f; } Vector4 Vector4::Create() { - Vector4 r; - r.init(); - return r; + Vector4 r; + r.init(); + return r; } -void Vector4::init(const Vector4 &v) { - x = v.x; - y = v.y; - z = v.z; - w = v.w; -} - -Vector4 Vector4::Create(const Vector4 &v) +void Vector4::init(const Vector4& v) { - Vector4 r; - r.init(v); - return r; + x = v.x; + y = v.y; + z = v.z; + w = v.w; } -void Vector4::init(const Vector3 &v, float W) { - x = v.x; - y = v.y; - z = v.z; - w = W; -} - -Vector4 Vector4::Create(const Vector3 &v, float W) +Vector4 Vector4::Create(const Vector4& v) { - Vector4 r; - r.init(v, W); - return r; + Vector4 r; + r.init(v); + return r; } -void Vector4::init(float *v) { - x = v[0]; - y = v[1]; - z = v[2]; - w = v[3]; -} - -Vector4 Vector4::Create(float *v) +void Vector4::init(const Vector3& v, float W) { - Vector4 r; - r.init(v); - return r; + x = v.x; + y = v.y; + z = v.z; + w = W; } -void Vector4::init(float v) { - x = v; - y = v; - z = v; - w = v; +Vector4 Vector4::Create(const Vector3& v, float W) +{ + Vector4 r; + r.init(v, W); + return r; +} + +void Vector4::init(float* v) +{ + x = v[0]; + y = v[1]; + z = v[2]; + w = v[3]; +} + +Vector4 Vector4::Create(float* v) +{ + Vector4 r; + r.init(v); + return r; +} + +void Vector4::init(float v) +{ + x = v; + y = v; + z = v; + w = v; } Vector4 Vector4::Create(float v) { - Vector4 r; - r.init(v); - return r; + Vector4 r; + r.init(v); + return r; } void Vector4::init(float X, float Y, float Z, float W) { - x = X; - y = Y; - z = Z; - w = W; + x = X; + y = Y; + z = Z; + w = W; } Vector4 Vector4::Create(float X, float Y, float Z, float W) { - Vector4 r; - r.init(X, Y, Z, W); - return r; + Vector4 r; + r.init(X, Y, Z, W); + return r; } -Vector4 Vector4::Min() { - return Vector4::Create(-std::numeric_limits::max()); +Vector4 Vector4::Min() +{ + return Vector4::Create(-std::numeric_limits::max()); } -Vector4 Vector4::Max() { - return Vector4::Create(std::numeric_limits::max()); +Vector4 Vector4::Max() +{ + return Vector4::Create(std::numeric_limits::max()); } -Vector4 Vector4::Zero() { - return Vector4::Create(); +Vector4 Vector4::Zero() +{ + return Vector4::Create(); } -Vector4 Vector4::One() { - return Vector4::Create(1.0f, 1.0f, 1.0f, 1.0f); +Vector4 Vector4::One() +{ + return Vector4::Create(1.0f, 1.0f, 1.0f, 1.0f); } -Vector4 Vector4::Forward() { - return Vector4::Create(0.0f, 0.0f, 1.0f, 1.0f); +Vector4 Vector4::Forward() +{ + return Vector4::Create(0.0f, 0.0f, 1.0f, 1.0f); } -Vector4 Vector4::Backward() { - return Vector4::Create(0.0f, 0.0f, -1.0f, 1.0f); +Vector4 Vector4::Backward() +{ + return Vector4::Create(0.0f, 0.0f, -1.0f, 1.0f); } -Vector4 Vector4::Up() { - return Vector4::Create(0.0f, 1.0f, 0.0f, 1.0f); +Vector4 Vector4::Up() +{ + return Vector4::Create(0.0f, 1.0f, 0.0f, 1.0f); } -Vector4 Vector4::Down() { - return Vector4::Create(0.0f, -1.0f, 0.0f, 1.0f); +Vector4 Vector4::Down() +{ + return Vector4::Create(0.0f, -1.0f, 0.0f, 1.0f); } -Vector4 Vector4::Left() { - return Vector4::Create(-1.0f, 0.0f, 0.0f, 1.0f); +Vector4 Vector4::Left() +{ + return Vector4::Create(-1.0f, 0.0f, 0.0f, 1.0f); } -Vector4 Vector4::Right() { - return Vector4::Create(1.0f, 0.0f, 0.0f, 1.0f); +Vector4 Vector4::Right() +{ + return Vector4::Create(1.0f, 0.0f, 0.0f, 1.0f); } -Vector4 Vector4::Lerp(const Vector4 &v1, const Vector4 &v2, float d) { - return v1 + (v2 - v1) * d; +Vector4 Vector4::Lerp(const Vector4& v1, const Vector4& v2, float d) +{ + return v1 + (v2 - v1) * d; } -Vector4 Vector4::Slerp(const Vector4 &v1, const Vector4 &v2, float d) { - // From: http://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/ - // Dot product - the cosine of the angle between 2 vectors. - float dot = Vector4::Dot(v1, v2); - // Clamp it to be in the range of Acos() - if(dot < -1.0f) dot = -1.0f; - if(dot > 1.0f) dot = 1.0f; - // Acos(dot) returns the angle between start and end, - // And multiplying that by percent returns the angle between - // start and the final result. - float theta = acosf(dot)*d; - Vector4 RelativeVec = v2 - v1*dot; - RelativeVec.normalize(); // Orthonormal basis - // The final result. - return ((v1*cosf(theta)) + (RelativeVec*sinf(theta))); +Vector4 Vector4::Slerp(const Vector4& v1, const Vector4& v2, float d) +{ + // From: http://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/ + // Dot product - the cosine of the angle between 2 vectors. + float dot = Vector4::Dot(v1, v2); + // Clamp it to be in the range of Acos() + if (dot < -1.0f) dot = -1.0f; + if (dot > 1.0f) dot = 1.0f; + // Acos(dot) returns the angle between start and end, + // And multiplying that by percent returns the angle between + // start and the final result. + float theta = acosf(dot) * d; + Vector4 RelativeVec = v2 - v1 * dot; + RelativeVec.normalize(); // Orthonormal basis + // The final result. + return ((v1 * cosf(theta)) + (RelativeVec * sinf(theta))); } -void Vector4::OrthoNormalize(Vector4 &normal, Vector4 &tangent) { - // Gram-Schmidt Orthonormalization - normal.normalize(); - Vector4 proj = normal * Dot(tangent, normal); - tangent = tangent - proj; - tangent.normalize(); +void Vector4::OrthoNormalize(Vector4& normal, Vector4& tangent) +{ + // Gram-Schmidt Orthonormalization + normal.normalize(); + Vector4 proj = normal * Dot(tangent, normal); + tangent = tangent - proj; + tangent.normalize(); } -Vector4 Vector4::operator +(const Vector4& b) const { - return Vector4::Create(x + b.x, y + b.y, z + b.z, w + b.w); +Vector4 Vector4::operator +(const Vector4& b) const +{ + return Vector4::Create(x + b.x, y + b.y, z + b.z, w + b.w); } -Vector4 Vector4::operator -(const Vector4& b) const { - return Vector4::Create(x - b.x, y - b.y, z - b.z, w - b.w); +Vector4 Vector4::operator -(const Vector4& b) const +{ + return Vector4::Create(x - b.x, y - b.y, z - b.z, w - b.w); } -Vector4 Vector4::operator +() const { - return *this; +Vector4 Vector4::operator +() const +{ + return *this; } -Vector4 Vector4::operator -() const { - return Vector4::Create(-x, -y, -z, -w); +Vector4 Vector4::operator -() const +{ + return Vector4::Create(-x, -y, -z, -w); } -Vector4 Vector4::operator *(const float v) const { - return Vector4::Create(x * v, y * v, z * v, w * v); +Vector4 Vector4::operator *(const float v) const +{ + return Vector4::Create(x * v, y * v, z * v, w * v); } -Vector4 Vector4::operator /(const float v) const { - return Vector4::Create(x / v, y / v, z / v, w/ v); +Vector4 Vector4::operator /(const float v) const +{ + return Vector4::Create(x / v, y / v, z / v, w / v); } -Vector4& Vector4::operator +=(const Vector4& b) { - x += b.x; - y += b.y; - z += b.z; - w += b.w; - - return *this; +Vector4& Vector4::operator +=(const Vector4& b) +{ + x += b.x; + y += b.y; + z += b.z; + w += b.w; + + return *this; } -Vector4& Vector4::operator -=(const Vector4& b) { - x -= b.x; - y -= b.y; - z -= b.z; - w -= b.w; - - return *this; +Vector4& Vector4::operator -=(const Vector4& b) +{ + x -= b.x; + y -= b.y; + z -= b.z; + w -= b.w; + + return *this; } -Vector4& Vector4::operator *=(const float v) { - x *= v; - y *= v; - z *= v; - w *= v; - - return *this; +Vector4& Vector4::operator *=(const float v) +{ + x *= v; + y *= v; + z *= v; + w *= v; + + return *this; } -Vector4& Vector4::operator /=(const float v) { - float inv_v = 1.0f / v; - x *= inv_v; - y *= inv_v; - z *= inv_v; - w *= inv_v; - - return *this; +Vector4& Vector4::operator /=(const float v) +{ + float inv_v = 1.0f / v; + x *= inv_v; + y *= inv_v; + z *= inv_v; + w *= inv_v; + + return *this; } -bool Vector4::operator ==(const Vector4& b) const { - return x == b.x && y == b.y && z == b.z && w == b.w; - +bool Vector4::operator ==(const Vector4& b) const +{ + return x == b.x && y == b.y && z == b.z && w == b.w; + } -bool Vector4::operator !=(const Vector4& b) const { - return x != b.x || y != b.y || z != b.z || w != b.w; +bool Vector4::operator !=(const Vector4& b) const +{ + return x != b.x || y != b.y || z != b.z || w != b.w; } -float& Vector4::operator[](unsigned i) { - switch(i) { - case 0: - return x; - case 1: - return y; - case 2: - return z; - default: - case 3: - return w; - } +float& Vector4::operator[](unsigned i) +{ + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + case 3: + return w; + } } -float Vector4::operator[](unsigned i) const { - switch(i) { - case 0: - return x; - case 1: - return y; - case 2: - return z; - default: - case 3: - return w; - } +float Vector4::operator[](unsigned i) const +{ + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + case 3: + return w; + } } -float Vector4::sqrMagnitude() const { - // calculate the square of the magnitude (useful for comparison of magnitudes without the cost of a sqrt() function) - return x * x + y * y + z * z + w * w; +float Vector4::sqrMagnitude() const +{ + // calculate the square of the magnitude (useful for comparison of magnitudes without the cost of a sqrt() function) + return x * x + y * y + z * z + w * w; } -float Vector4::magnitude() const { - return sqrtf(x * x + y * y + z * z + w * w); +float Vector4::magnitude() const +{ + return sqrtf(x * x + y * y + z * z + w * w); } -void Vector4::normalize() { - float inv_magnitude = 1.0f / sqrtf(x * x + y * y + z * z + w * w); - x *= inv_magnitude; - y *= inv_magnitude; - z *= inv_magnitude; - w *= inv_magnitude; +void Vector4::normalize() +{ + float inv_magnitude = 1.0f / sqrtf(x * x + y * y + z * z + w * w); + x *= inv_magnitude; + y *= inv_magnitude; + z *= inv_magnitude; + w *= inv_magnitude; } -Vector4 Vector4::Normalize(const Vector4 &v) { - float inv_magnitude = 1.0f / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); - return Vector4::Create(v.x * inv_magnitude, - v.y * inv_magnitude, - v.z * inv_magnitude, - v.w * inv_magnitude); +Vector4 Vector4::Normalize(const Vector4& v) +{ + float inv_magnitude = 1.0f / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); + return Vector4::Create(v.x * inv_magnitude, + v.y * inv_magnitude, + v.z * inv_magnitude, + v.w * inv_magnitude); } -float Vector4::Dot(const Vector4 &v1, const Vector4 &v2) { - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; +float Vector4::Dot(const Vector4& v1, const Vector4& v2) +{ + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; } -Vector4 Vector4::Min(const Vector4 &v1, const Vector4 &v2) { +Vector4 Vector4::Min(const Vector4& v1, const Vector4& v2) +{ return Vector4::Create(KRMIN(v1.x, v2.x), KRMIN(v1.y, v2.y), KRMIN(v1.z, v2.z), KRMIN(v1.w, v2.w)); } -Vector4 Vector4::Max(const Vector4 &v1, const Vector4 &v2) { +Vector4 Vector4::Max(const Vector4& v1, const Vector4& v2) +{ return Vector4::Create(KRMAX(v1.x, v2.x), KRMAX(v1.y, v2.y), KRMAX(v1.z, v2.z), KRMAX(v1.w, v2.w)); } bool Vector4::operator >(const Vector4& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(x != b.x) return x > b.x; - if(y != b.y) return y > b.y; - if(z != b.z) return z > b.z; - if(w != b.w) return w > b.w; - return false; + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (x != b.x) return x > b.x; + if (y != b.y) return y > b.y; + if (z != b.z) return z > b.z; + if (w != b.w) return w > b.w; + return false; } bool Vector4::operator <(const Vector4& b) const { - // Comparison operators are implemented to allow insertion into sorted containers such as std::set - if(x != b.x) return x < b.x; - if(y != b.y) return y < b.y; - if(z != b.z) return z < b.z; - if(w != b.w) return w < b.w; - return false; + // Comparison operators are implemented to allow insertion into sorted containers such as std::set + if (x != b.x) return x < b.x; + if (y != b.y) return y < b.y; + if (z != b.z) return z < b.z; + if (w != b.w) return w < b.w; + return false; } } // namespace kraken