LCOV - code coverage report
Current view: top level - core/geom - SPVec4.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 32 34 94.1 %
Date: 2024-05-12 00:16:13 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /**
       2             : Copyright 2013 BlackBerry Inc.
       3             : Copyright (c) 2014-2015 Chukong Technologies
       4             : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
       5             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       6             : 
       7             : Licensed under the Apache License, Version 2.0 (the "License");
       8             : you may not use this file except in compliance with the License.
       9             : You may obtain a copy of the License at
      10             : 
      11             : http://www.apache.org/licenses/LICENSE-2.0
      12             : 
      13             : Unless required by applicable law or agreed to in writing, software
      14             : distributed under the License is distributed on an "AS IS" BASIS,
      15             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      16             : See the License for the specific language governing permissions and
      17             : limitations under the License.
      18             : 
      19             : Original file from GamePlay3D: http://gameplay3d.org
      20             : 
      21             : This file was modified to fit the cocos2d-x project
      22             : This file was modified for stappler project
      23             : */
      24             : 
      25             : #ifndef STAPPLER_GEOM_SPVEC4_H
      26             : #define STAPPLER_GEOM_SPVEC4_H
      27             : 
      28             : #include "SPSIMD.h"
      29             : #include "SPVec2.h"
      30             : #include "SPVec3.h"
      31             : 
      32             : namespace STAPPLER_VERSIONIZED stappler::geom {
      33             : 
      34             : class Mat4;
      35             : 
      36             : class alignas(16) Vec4 {
      37             : public:
      38             :         static constexpr size_t Dimansions = 2;
      39             : 
      40             :         static const Vec4 ZERO;
      41             :         static const Vec4 ONE;
      42             :         static const Vec4 UNIT_X;
      43             :         static const Vec4 UNIT_Y;
      44             :         static const Vec4 UNIT_Z;
      45             :         static const Vec4 UNIT_W;
      46             : 
      47             :         static void add(const Vec4& v1, const Vec4& v2, Vec4* dst) {
      48             :                 simd::add(&v1.x, &v2.x, &dst->x);
      49             :         }
      50             : 
      51             :         static void subtract(const Vec4& v1, const Vec4& v2, Vec4* dst) {
      52             :                 simd::sub(&v1.x, &v2.x, &dst->x);
      53             :         }
      54             : 
      55    30692772 :         static void scale(const Vec4& v1, const Vec4& v2, Vec4* dst) {
      56    30692772 :                 simd::multiply(&v1.x, &v2.x, &dst->x);
      57    30692772 :         }
      58             : 
      59             :         static void unscale(const Vec4& v1, const Vec4& v2, Vec4* dst) {
      60             :                 simd::divide(&v1.x, &v2.x, &dst->x);
      61             :         }
      62             : 
      63          50 :         static float dot(const Vec4& v1, const Vec4& v2) {
      64          50 :                 return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w);
      65             :         }
      66             : 
      67             :         static float angle(const Vec4& v1, const Vec4& v2);
      68             : 
      69             :         static void clamp(const Vec4& v, const Vec4& min, const Vec4& max, Vec4* dst);
      70             : 
      71             :         template <typename Functor>
      72             :         static constexpr std::bitset<4> bitop(const Vec4& v, const Functor &f) {
      73             :                 std::bitset<4> ret;
      74             :                 ret.set(0, f(v.x));
      75             :                 ret.set(1, f(v.y));
      76             :                 ret.set(2, f(v.z));
      77             :                 ret.set(3, f(v.w));
      78             :                 return ret;
      79             :         }
      80             : 
      81             :         template <typename Functor>
      82             :         static constexpr std::bitset<4> bitop(const Vec4& v1, const Vec4& v2, const Functor &f) {
      83             :                 std::bitset<4> ret;
      84             :                 ret.set(0, f(v1.x, v2.x));
      85             :                 ret.set(1, f(v1.y, v2.y));
      86             :                 ret.set(2, f(v1.z, v2.z));
      87             :                 ret.set(3, f(v1.w, v2.w));
      88             :                 return ret;
      89             :         }
      90             : 
      91             :         static constexpr Vec4 fill(float v) {
      92             :                 return Vec4(v, v, v, v);
      93             :         }
      94             : 
      95             :         float x;
      96             :         float y;
      97             :         float z;
      98             :         float w;
      99             : 
     100    42001193 :         constexpr Vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
     101    70121005 :         constexpr Vec4(float xx, float yy, float zz, float ww) : x(xx), y(yy), z(zz), w(ww) { }
     102      736692 :         constexpr Vec4(const Vec2 &origin, float zz, float ww) : x(origin.x), y(origin.y), z(zz), w(ww) { }
     103          20 :         constexpr Vec4(const Vec3 &origin, float ww) : x(origin.x), y(origin.y), z(origin.z), w(ww) { }
     104        2419 :         constexpr Vec4(const Vec2 &origin, const Vec2 &extra) : x(origin.x), y(origin.y), z(extra.x), w(extra.y) { }
     105             : 
     106             :         constexpr Vec4(const Vec4 &p1, const Vec4 &p2) : x(p2.x - p1.x), y(p2.y - p1.y), z(p2.z - p1.z), w(p2.w - p1.w) { }
     107             :         constexpr Vec4(const Vec4 &copy) = default;
     108             : 
     109             :         template <typename Functor>
     110          50 :         constexpr Vec4(const Vec4 &v, const Functor &f) : x(f(v.x)), y(f(v.y)), z(f(v.z)), w(f(v.w)) { }
     111             : 
     112             :         template <typename Functor>
     113             :         constexpr Vec4(const Vec4 &v1, const Vec4 &v2, const Functor &f) : x(f(v1.x, v2.x)), y(f(v1.y, v2.y)), z(f(v1.z, v2.z)), w(f(v1.w, v2.w)) { }
     114             : 
     115             :         constexpr bool isValid() const { return !std::isnan(x) && !std::isnan(y) && !std::isnan(z) && !std::isnan(w); }
     116             : 
     117             :         constexpr Vec2 xy() const {
     118             :                 return Vec2(x, y);
     119             :         }
     120             : 
     121             :         constexpr Vec3 xyz() const {
     122             :                 return Vec3(x, y, z);
     123             :         }
     124             : 
     125             :         void add(const float &v) {
     126             :                 simd::add(&this->x, v, &this->x);
     127             :         }
     128             : 
     129          50 :         void add(const Vec4 &v) {
     130          50 :                 simd::add(&this->x, &v.x, &this->x);
     131          50 :         }
     132             : 
     133             :         void subtract(const float &v) {
     134             :                 simd::sub(&this->x, v, &this->x);
     135             :         }
     136             : 
     137             :         void subtract(const Vec4 &v) {
     138             :                 simd::sub(&this->x, &v.x, &this->x);
     139             :         }
     140             : 
     141             :         void scale(const float &v) {
     142             :                 simd::multiply(&this->x, v, &this->x);
     143             :         }
     144             : 
     145             :         void scale(const Vec4 &v) {
     146             :                 simd::multiply(&this->x, &v.x, &this->x);
     147             :         }
     148             : 
     149             :         void unscale(const float &v) {
     150             :                 simd::divide(&this->x, v, &this->x);
     151             :         }
     152             : 
     153             :         void unscale(const Vec4 &v) {
     154             :                 simd::divide(&this->x, &v.x, &this->x);
     155             :         }
     156             : 
     157             :         void clamp(const Vec4& min, const Vec4& max);
     158             : 
     159             :         constexpr float distanceSquared(const Vec4& v) const {
     160             :                 const float dx = v.x - x;
     161             :                 const float dy = v.y - y;
     162             :                 const float dz = v.z - z;
     163             :                 const float dw = v.w - w;
     164             : 
     165             :                 return (dx * dx + dy * dy + dz * dz + dw * dw);
     166             :         }
     167             : 
     168             :         constexpr float lengthSquared() const {
     169             :                 return (x * x + y * y + z * z + w * w);
     170             :         }
     171             : 
     172             :         constexpr float distance(const Vec4& v) const { return std::sqrt(distanceSquared(v)); }
     173             : 
     174             :         constexpr float length() const { return std::sqrt(lengthSquared()); }
     175             : 
     176             :         constexpr bool isWithinDistance(const Vec4& v, float val) const {
     177             :                 return distanceSquared(v) < val * val;
     178             :         }
     179             : 
     180             :         constexpr float dot(const Vec4& v) const { return (x * v.x + y * v.y + z * v.z + w * v.w); }
     181             : 
     182             :         constexpr void negate() { x = -x; y = -y; z = -z; w = -w; }
     183             : 
     184             :         constexpr Vec4 & normalize();
     185             : 
     186             :         Vec4 getNormalized() const;
     187             : 
     188             :         constexpr bool fuzzyEquals(const Vec4& b, float var = NumericLimits<float>::epsilon()) const {
     189             :                 return (x - var <= b.x && b.x <= x + var) && (y - var <= b.y && b.y <= y + var)
     190             :                                  && (z - var <= b.z && b.z <= z + var) && (w - var <= b.w && b.w <= w + var);
     191             :         }
     192             : 
     193             :         Vec4& operator+=(const float &v) {
     194             :                 add(v);
     195             :                 return *this;
     196             :         }
     197             : 
     198          25 :         Vec4& operator+=(const Vec4& v) {
     199          25 :                 add(v);
     200          25 :                 return *this;
     201             :         }
     202             : 
     203             :         Vec4& operator-=(const float &v) {
     204             :                 subtract(v);
     205             :                 return *this;
     206             :         }
     207             : 
     208             :         Vec4& operator-=(const Vec4& v) {
     209             :                 subtract(v);
     210             :                 return *this;
     211             :         }
     212             : 
     213             :         Vec4& operator*=(const float &v) {
     214             :                 scale(v);
     215             :                 return *this;
     216             :         }
     217             : 
     218             :         Vec4& operator*=(const Vec4 &s) {
     219             :                 scale(s);
     220             :                 return *this;
     221             :         }
     222             : 
     223             :         Vec4& operator/=(const float &v) {
     224             :                 unscale(v);
     225             :                 return *this;
     226             :         }
     227             : 
     228             :         Vec4& operator/=(const Vec4 &s) {
     229             :                 unscale(s);
     230             :                 return *this;
     231             :         }
     232             : 
     233             :         SP_THREE_WAY_COMPARISON_FRIEND_CONSTEXPR(Vec4)
     234             : };
     235             : 
     236          25 : constexpr inline Vec4 &Vec4::normalize() {
     237          25 :         float n = x * x + y * y + z * z + w * w;
     238             :         // Already normalized.
     239          25 :         if (n == 1.0f) {
     240           0 :                 return *this;
     241             :         }
     242             : 
     243          25 :         n = sqrt(n);
     244             :         // Too close to zero.
     245          25 :         if (n < math::MATH_TOLERANCE) {
     246           0 :                 return *this;
     247             :         }
     248             : 
     249          25 :         n = 1.0f / n;
     250          25 :         x *= n;
     251          25 :         y *= n;
     252          25 :         z *= n;
     253          25 :         w *= n;
     254             : 
     255          25 :         return *this;
     256             : }
     257             : 
     258             : #ifndef __LCC__
     259             : 
     260             : constexpr const Vec4 Vec4::ZERO = Vec4(0.0f, 0.0f, 0.0f, 0.0f);
     261             : constexpr const Vec4 Vec4::ONE = Vec4(1.0f, 1.0f, 1.0f, 1.0f);
     262             : constexpr const Vec4 Vec4::UNIT_X = Vec4(1.0f, 0.0f, 0.0f, 0.0f);
     263             : constexpr const Vec4 Vec4::UNIT_Y = Vec4(0.0f, 1.0f, 0.0f, 0.0f);
     264             : constexpr const Vec4 Vec4::UNIT_Z = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
     265             : constexpr const Vec4 Vec4::UNIT_W = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
     266             : 
     267             : #endif
     268             : 
     269             : inline const Vec4 operator+(const Vec4 &l, const Vec4 &r) {
     270             :         Vec4 result;
     271             :         Vec4::add(l, r, &result);
     272             :         return result;
     273             : }
     274             : 
     275             : inline const Vec4 operator+(const Vec4 &l, const float &r) {
     276             :         Vec4 result(l);
     277             :         result.add(r);
     278             :         return result;
     279             : }
     280             : 
     281             : inline const Vec4 operator+(const float &l, const Vec4 &r) {
     282             :         Vec4 result(r);
     283             :         result.add(l);
     284             :         return result;
     285             : }
     286             : 
     287             : inline const Vec4 operator-(const Vec4 &l, const Vec4 &r) {
     288             :         Vec4 result;
     289             :         Vec4::subtract(l, r, &result);
     290             :         return result;
     291             : }
     292             : 
     293             : inline const Vec4 operator-(const Vec4 &l, const float &r) {
     294             :         Vec4 result(l);
     295             :         result.subtract(r);
     296             :         return result;
     297             : }
     298             : 
     299    30693134 : inline const Vec4 operator*(const Vec4 &l, const Vec4 &r) {
     300    30693134 :         Vec4 result;
     301    30693134 :         Vec4::scale(l, r, &result);
     302    30693278 :         return result;
     303             : }
     304             : 
     305             : inline const Vec4 operator*(const Vec4 &l, const float &r) {
     306             :         Vec4 result(l);
     307             :         result.scale(r);
     308             :         return result;
     309             : }
     310             : 
     311             : inline const Vec4 operator*(const float &l, const Vec4 &r) {
     312             :         Vec4 result(r);
     313             :         result.scale(l);
     314             :         return result;
     315             : }
     316             : 
     317             : inline const Vec4 operator/(const Vec4 &l, const Vec4 &r) {
     318             :         Vec4 result;
     319             :         Vec4::unscale(l, r, &result);
     320             :         return result;
     321             : }
     322             : 
     323             : inline const Vec4 operator/(const Vec4 &l, const float &r) {
     324             :         Vec4 result(l);
     325             :         result.unscale(r);
     326             :         return result;
     327             : }
     328             : 
     329             : constexpr Vec4 operator-(const Vec4& v) {
     330             :         Vec4 result(v);
     331             :         result.negate();
     332             :         return result;
     333             : }
     334             : 
     335             : inline std::basic_ostream<char> &
     336             : operator << (std::basic_ostream<char> & os, const Vec4 & vec) {
     337             :         os << "(x: " << vec.x << "; y: " << vec.y << "; z: " << vec.z << "; w: " << vec.w << ")";
     338             :         return os;
     339             : }
     340             : 
     341             : }
     342             : 
     343             : #endif /* STAPPLER_GEOM_SPVEC4_H */

Generated by: LCOV version 1.14