rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

realX.h (7768B)


      1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr)
      2  *
      3  * The RSys library is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published
      5  * by the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * The RSys library is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 /*
     17  * Internal header used to generate funcs on REAL_TYPE__ vector of X dimensions
     18  */
     19 #include "math.h"
     20 #include <math.h>
     21 
     22 #ifdef COMPILER_GCC
     23   #pragma GCC push_options
     24   #pragma GCC optimize("unroll-loops")
     25 #endif
     26 
     27 #if REALX_DIMENSION__ <= 4
     28 static FINLINE REAL_TYPE__*
     29 REALX_CTOR__
     30   (REAL_TYPE__* dst
     31   ,const REAL_TYPE__ x
     32   ,const REAL_TYPE__ y
     33 #if REALX_DIMENSION__ > 2
     34   ,const REAL_TYPE__ z
     35 #endif
     36 #if REALX_DIMENSION__ > 3
     37   ,const REAL_TYPE__ w
     38 #endif
     39   )
     40 {
     41   ASSERT(dst);
     42   dst[0] = x;
     43   dst[1] = y;
     44 #if REALX_DIMENSION__ > 2
     45   dst[2] = z;
     46 #endif
     47 #if REALX_DIMENSION__ > 3
     48   dst[3] = w;
     49 #endif
     50   return dst;
     51 }
     52 #endif
     53 
     54 static FINLINE REAL_TYPE__*
     55 REALX_CAST__(REAL_TYPE__* dst, const REAL_TYPE_COMPATIBLE__* src)
     56 {
     57   int i;
     58   ASSERT(dst && src);
     59   FOR_EACH(i, 0, REALX_DIMENSION__)
     60     dst[i] = (REAL_TYPE__)src[i];
     61   return dst;
     62 }
     63 
     64 static FINLINE REAL_TYPE__*
     65 REALX_FUNC__(splat)(REAL_TYPE__* dst, const REAL_TYPE__ val)
     66 {
     67   int i;
     68   ASSERT(dst);
     69   FOR_EACH(i, 0, REALX_DIMENSION__)
     70     dst[i] = val;
     71   return dst;
     72 }
     73 
     74 static FINLINE REAL_TYPE__*
     75 REALX_FUNC__(set__)(REAL_TYPE__* dst, const REAL_TYPE__* src)
     76 {
     77   int i;
     78   ASSERT(dst && src);
     79   ASSERT(!MEM_AREA_OVERLAP(dst, SIZEOF_REALX__, src, SIZEOF_REALX__));
     80   FOR_EACH(i, 0, REALX_DIMENSION__)
     81     dst[i] = src[i];
     82   return dst;
     83 }
     84 
     85 static FINLINE REAL_TYPE__*
     86 REALX_FUNC__(set)(REAL_TYPE__* dst, const REAL_TYPE__* src)
     87 {
     88   ASSERT(dst && src);
     89   if(!MEM_AREA_OVERLAP(dst, SIZEOF_REALX__, src, SIZEOF_REALX__)) {
     90     return REALX_FUNC__(set__)(dst, src);
     91   } else {
     92     REAL_TYPE__ tmp[REALX_DIMENSION__];
     93     return REALX_FUNC__(set__)(dst, REALX_FUNC__(set__)(tmp, src));
     94   }
     95 }
     96 
     97 static FINLINE REAL_TYPE__
     98 REALX_FUNC__(dot)(const REAL_TYPE__* a, const REAL_TYPE__* b)
     99 {
    100   REAL_TYPE__ dot = 0;
    101   int i;
    102   ASSERT(a && b);
    103   FOR_EACH(i, 0, REALX_DIMENSION__)
    104     dot += a[i] * b[i];
    105   return dot;
    106 }
    107 
    108 static FINLINE REAL_TYPE__
    109 REALX_FUNC__(len)(const REAL_TYPE__* a)
    110 {
    111   ASSERT(a);
    112   return (REAL_TYPE__)sqrt((double)REALX_FUNC__(dot)(a, a));
    113 }
    114 
    115 static FINLINE REAL_TYPE__
    116 REALX_FUNC__(normalize)(REAL_TYPE__* dst, const REAL_TYPE__* a)
    117 {
    118   REAL_TYPE__ tmp[REALX_DIMENSION__];
    119   REAL_TYPE__ len, rcp_len;
    120   int i;
    121   ASSERT(dst && a);
    122 
    123   len = REALX_FUNC__(len)(a);
    124   if(len == 0)
    125     return len;
    126 
    127   rcp_len = 1.0f / len;
    128   FOR_EACH(i, 0, REALX_DIMENSION__)
    129     tmp[i] = a[i] * rcp_len;
    130   REALX_FUNC__(set__)(dst, tmp);
    131   return len;
    132 }
    133 
    134 static FINLINE int
    135 REALX_FUNC__(is_normalized)(const REAL_TYPE__* a)
    136 {
    137   return REAL_EQ_EPS__(REALX_FUNC__(len)(a), (REAL_TYPE__)1.0, REAL_EPSILON__);
    138 }
    139 
    140 static FINLINE REAL_TYPE__*
    141 REALX_FUNC__(add)
    142   (REAL_TYPE__* dst,
    143    const REAL_TYPE__* a,
    144    const REAL_TYPE__* b)
    145 {
    146   REAL_TYPE__ tmp[REALX_DIMENSION__];
    147   int i;
    148   ASSERT(dst && a && b);
    149   FOR_EACH(i, 0, REALX_DIMENSION__)
    150     tmp[i] = a[i] + b[i];
    151   return REALX_FUNC__(set__)(dst, tmp);
    152 }
    153 
    154 static FINLINE REAL_TYPE__*
    155 REALX_REAL_FUNC__(add)
    156   (REAL_TYPE__* dst,
    157    const REAL_TYPE__* a,
    158    const REAL_TYPE__ f)
    159 {
    160   REAL_TYPE__ tmp[REALX_DIMENSION__];
    161   int i;
    162   ASSERT(dst && a);
    163   FOR_EACH(i, 0, REALX_DIMENSION__)
    164     tmp[i] = a[i] + f;
    165   return REALX_FUNC__(set__)(dst, tmp);
    166 }
    167 
    168 static FINLINE REAL_TYPE__*
    169 REALX_FUNC__(sub)
    170   (REAL_TYPE__* dst,
    171    const REAL_TYPE__* a,
    172    const REAL_TYPE__* b)
    173 {
    174   REAL_TYPE__ tmp[REALX_DIMENSION__];
    175   int i;
    176   ASSERT(dst && a && b);
    177   FOR_EACH(i, 0, REALX_DIMENSION__)
    178     tmp[i] = a[i] - b[i];
    179   return REALX_FUNC__(set__)(dst, tmp);
    180 }
    181 
    182 static FINLINE REAL_TYPE__*
    183 REALX_REAL_FUNC__(sub)
    184   (REAL_TYPE__* dst,
    185    const REAL_TYPE__* a,
    186    const REAL_TYPE__ f)
    187 {
    188   REAL_TYPE__ tmp[REALX_DIMENSION__];
    189   int i;
    190   ASSERT(dst && a);
    191   FOR_EACH(i, 0, REALX_DIMENSION__)
    192     tmp[i] = a[i] - f;
    193   return REALX_FUNC__(set__)(dst, tmp);
    194 }
    195 
    196 static FINLINE REAL_TYPE__*
    197 REALX_FUNC__(mul)
    198   (REAL_TYPE__* dst,
    199    const REAL_TYPE__* a,
    200    const REAL_TYPE__* b)
    201 {
    202   REAL_TYPE__ tmp[REALX_DIMENSION__];
    203   int i;
    204   ASSERT(dst && a && b);
    205   FOR_EACH(i, 0, REALX_DIMENSION__)
    206     tmp[i] = a[i] * b[i];
    207   return REALX_FUNC__(set__)(dst, tmp);
    208 }
    209 
    210 static FINLINE REAL_TYPE__*
    211 REALX_REAL_FUNC__(mul)
    212   (REAL_TYPE__* dst,
    213    const REAL_TYPE__* a,
    214    const REAL_TYPE__ f)
    215 {
    216   REAL_TYPE__ tmp[REALX_DIMENSION__];
    217   int i;
    218   ASSERT(dst && a);
    219   FOR_EACH(i, 0, REALX_DIMENSION__)
    220     tmp[i] = a[i] * f;
    221   return REALX_FUNC__(set__)(dst, tmp);
    222 }
    223 
    224 static FINLINE REAL_TYPE__*
    225 REALX_FUNC__(div)
    226   (REAL_TYPE__* dst,
    227    const REAL_TYPE__* a,
    228    const REAL_TYPE__* b)
    229 {
    230   REAL_TYPE__ tmp[REALX_DIMENSION__];
    231   int i;
    232   ASSERT(dst && a && b);
    233   FOR_EACH(i, 0, REALX_DIMENSION__)
    234     tmp[i] = a[i] / b[i];
    235   return REALX_FUNC__(set__)(dst, tmp);
    236 }
    237 
    238 static FINLINE REAL_TYPE__*
    239 REALX_REAL_FUNC__(div)
    240   (REAL_TYPE__* dst,
    241    const REAL_TYPE__* a,
    242    const REAL_TYPE__ f)
    243 {
    244   REAL_TYPE__ tmp[REALX_DIMENSION__];
    245   int i;
    246   ASSERT(dst && a);
    247   FOR_EACH(i, 0, REALX_DIMENSION__)
    248     tmp[i] = a[i] / f;
    249   return REALX_FUNC__(set__)(dst, tmp);
    250 }
    251 
    252 static FINLINE REAL_TYPE__*
    253 REALX_FUNC__(minus)(REAL_TYPE__* dst, const REAL_TYPE__* a)
    254 {
    255   REAL_TYPE__ tmp[REALX_DIMENSION__];
    256   int i;
    257   ASSERT(dst && a);
    258   FOR_EACH(i, 0, REALX_DIMENSION__)
    259     tmp[i] = -a[i];
    260   return REALX_FUNC__(set__)(dst, tmp);
    261 }
    262 
    263 static FINLINE REAL_TYPE__
    264 REALX_FUNC__(sum)(const REAL_TYPE__* a)
    265 {
    266   REAL_TYPE__ f = 0;
    267   int i = 0;
    268   ASSERT(a);
    269   do {
    270     f += a[i];
    271     ++i;
    272   } while(i < REALX_DIMENSION__);
    273   return f;
    274 }
    275 
    276 static FINLINE REAL_TYPE__*
    277 REALX_FUNC__(lerp)
    278   (REAL_TYPE__* dst,
    279    const REAL_TYPE__* from,
    280    const REAL_TYPE__* to,
    281    const REAL_TYPE__ t)
    282 {
    283   ASSERT(dst && from && to);
    284   if(t <= 0.f) {
    285     REALX_FUNC__(set)(dst, from);
    286   } else if(t >= 1) {
    287     REALX_FUNC__(set)(dst, to);
    288   } else {
    289     REAL_TYPE__ tmp[REALX_DIMENSION__];
    290     int i;
    291     FOR_EACH(i, 0, REALX_DIMENSION__)
    292       tmp[i] = from[i] + t * (to[i] - from[i]);
    293     REALX_FUNC__(set__)(dst, tmp);
    294   }
    295   return dst;
    296 }
    297 
    298 static FINLINE int
    299 REALX_FUNC__(eq)(const REAL_TYPE__* a, const REAL_TYPE__* b)
    300 {
    301   int i = 0;
    302   int is_eq = 1;
    303   ASSERT(a && b);
    304   do {
    305     is_eq = a[i] == b[i];
    306     ++i;
    307   } while(i < REALX_DIMENSION__  && is_eq);
    308   return is_eq;
    309 }
    310 
    311 static FINLINE int
    312 REALX_FUNC__(eq_eps)
    313   (const REAL_TYPE__* a,
    314    const REAL_TYPE__* b,
    315    const REAL_TYPE__ eps)
    316 {
    317   int i = 0;
    318   int is_eq = 1;
    319   ASSERT(a && b);
    320   do {
    321     is_eq = REAL_EQ_EPS__(a[i], b[i], eps);
    322     ++i;
    323   } while(i < REALX_DIMENSION__ && is_eq);
    324   return is_eq;
    325 }
    326 
    327 static FINLINE REAL_TYPE__*
    328 REALX_FUNC__(max)
    329   (REAL_TYPE__* dst,
    330    const REAL_TYPE__* a,
    331    const REAL_TYPE__* b)
    332 {
    333   REAL_TYPE__ tmp[REALX_DIMENSION__];
    334   int i;
    335   ASSERT(dst && a && b);
    336   FOR_EACH(i, 0, REALX_DIMENSION__)
    337     tmp[i] = a[i] > b[i] ? a[i] : b[i];
    338   return REALX_FUNC__(set__)(dst, tmp);
    339 }
    340 
    341 static FINLINE REAL_TYPE__*
    342 REALX_FUNC__(min)
    343   (REAL_TYPE__* dst,
    344    const REAL_TYPE__* a,
    345    const REAL_TYPE__* b)
    346 {
    347   REAL_TYPE__ tmp[REALX_DIMENSION__];
    348   int i;
    349   ASSERT(dst && a && b);
    350   FOR_EACH(i, 0, REALX_DIMENSION__)
    351     tmp[i] = a[i] < b[i] ? a[i] : b[i];
    352   return REALX_FUNC__(set__)(dst, tmp);
    353 }
    354 
    355 #ifdef COMPILER_GCC
    356   #pragma GCC pop_options
    357 #endif