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