platform_math.c (18978B)
1 ////////////////////////////////////////////////////////////////// 2 // platform_math.c 3 4 // range 5 6 RV_GLOBAL s64 rv_range_diff(rv_range range) 7 { 8 return range.max - range.min; 9 } 10 11 ////////////////////////////////////////////////////////////////// 12 // vector math 13 14 15 // vec2 16 RV_GLOBAL rv_vec2 rv_vec2_neg(rv_vec2 v) { 17 return rv_vec2_scale(v, -1); 18 } 19 RV_GLOBAL rv_vec2 rv_vec2_norm(rv_vec2 v) { 20 f32 len = rv_vec2_len(v); 21 return rv_vec2_scale(v, len != 0.f ? 1.0f / rv_vec2_len(v) : 1.f); 22 } 23 RV_GLOBAL rv_vec2 rv_vec2_scale(rv_vec2 v, f32 s) 24 { 25 return rv_v2(v.x * s, v.y * s); 26 } 27 RV_GLOBAL rv_vec2 rv_vec2_add(rv_vec2 a, rv_vec2 b) 28 { 29 return rv_v2(a.x + b.x, a.y + b.y); 30 } 31 RV_GLOBAL rv_vec2 rv_vec2_sub(rv_vec2 a, rv_vec2 b) 32 { 33 return rv_v2(a.x - b.x, a.y - b.y); 34 } 35 RV_GLOBAL rv_vec2 rv_vec2_mul(rv_vec2 a, rv_vec2 b) 36 { 37 return rv_v2(a.x * b.x, a.y * b.y); 38 } 39 RV_GLOBAL rv_vec2 rv_vec2_div(rv_vec2 a, rv_vec2 b) 40 { 41 return rv_v2(a.x / b.x, a.y / b.y); 42 } 43 RV_GLOBAL rv_vec2 rv_vec2_project_onto(rv_vec2 a, rv_vec2 b) 44 { 45 f32 dot = rv_vec2_dot(a, b); 46 f32 len = rv_vec2_dot(b, b); 47 48 // Orthogonal, so return b 49 if (len == 0.f) return b; 50 51 return rv_vec2_scale(b, dot / len); 52 } 53 54 RV_GLOBAL f32 rv_vec2_len(rv_vec2 v) 55 { 56 return (f32)sqrtf(rv_vec2_dot(v, v)); 57 } 58 RV_GLOBAL f32 rv_vec2_dist(rv_vec2 a, rv_vec2 b) 59 { 60 f32 dx = (a.x - b.x); 61 f32 dy = (a.y - b.y); 62 return (float)(sqrtf(dx * dx + dy * dy)); 63 } 64 RV_GLOBAL f32 rv_vec2_cross(rv_vec2 a, rv_vec2 b) 65 { 66 return a.x * b.y - a.y * b.x; 67 } 68 RV_GLOBAL f32 rv_vec2_angle(rv_vec2 a, rv_vec2 b) 69 { 70 return (float)acos(rv_vec2_dot(a, b) / (rv_vec2_len(a) * rv_vec2_len(b))); 71 } 72 RV_GLOBAL f32 rv_vec2_dot(rv_vec2 a, rv_vec2 b) 73 { 74 return (f32)(a.x * b.x + a.y * b.y); 75 } 76 77 RV_GLOBAL bool32 rv_vec2_nan(rv_vec2 v) 78 { 79 if (v.x != v.x || v.y != v.y) return true; 80 return false; 81 } 82 RV_GLOBAL bool32 rv_vec2_eq(rv_vec2 a, rv_vec2 b) 83 { 84 return (a.x == b.x && a.y == b.y); 85 } 86 87 88 // vec3 89 RV_GLOBAL rv_vec3 rv_vec3_neg(rv_vec3 v) 90 { 91 return rv_vec3_scale(v, -1.f); 92 } 93 RV_GLOBAL rv_vec3 rv_vec3_scale(rv_vec3 v, f32 s) 94 { 95 return rv_v3(v.x * s, v.y * s, v.z * s); 96 } 97 RV_GLOBAL rv_vec3 rv_vec3_norm(rv_vec3 v) 98 { 99 f32 len = rv_vec3_len(v); 100 return len == 0.f ? v : rv_vec3_scale(v, 1.f / len); 101 } 102 RV_GLOBAL rv_vec3 rv_vec3_add(rv_vec3 a, rv_vec3 b) 103 { 104 return rv_v3(a.x + b.x, a.y + b.y, a.z + b.z); 105 } 106 RV_GLOBAL rv_vec3 rv_vec3_sub(rv_vec3 a, rv_vec3 b) 107 { 108 return rv_v3(a.x - b.x, a.y - b.y, a.z - b.z); 109 } 110 RV_GLOBAL rv_vec3 rv_vec3_mul(rv_vec3 a, rv_vec3 b) 111 { 112 return rv_v3(a.x * b.x, a.y * b.y, a.z * b.z); 113 } 114 RV_GLOBAL rv_vec3 rv_vec3_div(rv_vec3 a, rv_vec3 b) 115 { 116 return rv_v3(a.x / b.x, a.y / b.y, a.z / b.z); 117 } 118 RV_GLOBAL rv_vec3 rv_vec3_project_onto(rv_vec3 a, rv_vec3 b) 119 { 120 f32 dot = rv_vec3_dot(a, b); 121 f32 len = rv_vec3_dot(b, b); 122 123 // Orthogonal, so return b 124 if (len == 0.f) return b; 125 126 return rv_vec3_scale(b, dot / len); 127 } 128 RV_GLOBAL rv_vec3 rv_vec3_cross(rv_vec3 a, rv_vec3 b) 129 { 130 return rv_v3 131 ( 132 a.y * b.z - a.z * b.y, 133 a.z * b.x - a.x * b.z, 134 a.x * b.y - a.y * b.x 135 ); 136 } 137 138 RV_GLOBAL f32 rv_vec3_len(rv_vec3 v) 139 { 140 return (f32)sqrt(rv_vec3_dot(v, v)); 141 } 142 RV_GLOBAL f32 rv_vec3_dist(rv_vec3 a, rv_vec3 b) 143 { 144 f32 dx = (a.x - b.x); 145 f32 dy = (a.y - b.y); 146 f32 dz = (a.z - b.z); 147 return sqrtf(dx * dx + dy * dy + dz * dz); 148 } 149 RV_GLOBAL f32 rv_vec3_dot(rv_vec3 a, rv_vec3 b) 150 { 151 return (f32)((a.x * b.x) + (a.y * b.y) + a.z * b.z); 152 } 153 154 RV_GLOBAL bool32 rv_vec3_nan(rv_vec3 v) 155 { 156 if (v.x != v.x || v.y != v.y || v.z != v.z) return true; 157 return false; 158 } 159 RV_GLOBAL bool32 rv_vec3_eq(rv_vec3 a, rv_vec3 b) 160 { 161 return (a.x == b.x && a.y == b.y && a.z == b.z); 162 } 163 RV_GLOBAL bool32 rv_vec3_same_dir(rv_vec3 a, rv_vec3 b) 164 { 165 return (rv_vec3_dot(a, b) > 0.f); 166 } 167 168 // vec4 169 RV_GLOBAL rv_vec4 rv_vec4_neg(rv_vec4 v) 170 { 171 return rv_vec4_scale(v, -1); 172 } 173 RV_GLOBAL rv_vec4 rv_vec4_scale(rv_vec4 v, f32 s) 174 { 175 return rv_v4(v.x * s, v.y * s, v.z * s, v.w * s); 176 } 177 RV_GLOBAL rv_vec4 rv_vec4_norm(rv_vec4 v) 178 { 179 return rv_vec4_scale(v, 1.0f / rv_vec4_len(v)); 180 } 181 RV_GLOBAL rv_vec4 rv_vec4_add(rv_vec4 a, rv_vec4 b) 182 { 183 return rv_v4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); 184 } 185 RV_GLOBAL rv_vec4 rv_vec4_sub(rv_vec4 a, rv_vec4 b) 186 { 187 return rv_v4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); 188 } 189 RV_GLOBAL rv_vec4 rv_vec4_mul(rv_vec4 a, rv_vec4 b) 190 { 191 return rv_v4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); 192 } 193 RV_GLOBAL rv_vec4 rv_vec4_div(rv_vec4 a, rv_vec4 b) 194 { 195 return rv_v4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); 196 } 197 RV_GLOBAL rv_vec4 rv_vec4_project_onto(rv_vec4 a, rv_vec4 b) 198 { 199 f32 dot = rv_vec4_dot(a, b); 200 f32 len = rv_vec4_dot(b, b); 201 202 // Orthogonal, so return b 203 if (len == 0.f) return b; 204 205 return rv_vec4_scale(b, dot / len); 206 } 207 RV_GLOBAL rv_vec4 rv_vec4_from_color(rv_color_t c) 208 { 209 return rv_v4((float)c.r / 255.0f, (float)c.g / 255.0f, (float)c.b / 255.0f, (float)c.a / 255.0f); 210 } 211 212 RV_GLOBAL f32 rv_vec4_len(rv_vec4 v) 213 { 214 return (f32)sqrtf(rv_vec4_dot(v, v)); 215 } 216 RV_GLOBAL f32 rv_vec4_dist(rv_vec4 a, rv_vec4 b) 217 { 218 f32 dx = (a.x - b.x); 219 f32 dy = (a.y - b.y); 220 f32 dz = (a.z - b.z); 221 f32 dw = (a.w - b.w); 222 return (float)(sqrtf(dx * dx + dy * dy + dz * dz + dw * dw)); 223 } 224 RV_GLOBAL f32 rv_vec4_dot(rv_vec4 a, rv_vec4 b) 225 { 226 return (f32)(a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w); 227 } 228 229 RV_GLOBAL bool32 rv_vec4_nan(rv_vec4 v) 230 { 231 if (v.x != v.x || v.y != v.y || v.z != v.z || v.w != v.w) return true; 232 return false; 233 } 234 RV_GLOBAL bool32 rv_vec4_eq(rv_vec4 a, rv_vec4 b) 235 { 236 return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w); 237 } 238 239 240 ////////////////////////////////////////////////////////////////// 241 // matrix math 242 243 244 RV_GLOBAL rv_mat4 rv_mat4_translatev(rv_vec3 v) 245 { 246 rv_mat4 m_res = rv_mat4_identity(); 247 248 m_res.elements[0 + 4 * 3] = v.x; 249 m_res.elements[1 + 4 * 3] = v.y; 250 m_res.elements[2 + 4 * 3] = v.z; 251 252 return m_res; 253 } 254 RV_GLOBAL rv_mat4 rv_mat4_rotatev(f32 angle, rv_vec3 axis) 255 { 256 rv_mat4 m_res = rv_mat4_identity(); 257 258 float a = angle; 259 float c = (float)cos(a); 260 float s = (float)sin(a); 261 262 rv_vec3 naxis = rv_vec3_norm(axis); 263 float x = naxis.x; 264 float y = naxis.y; 265 float z = naxis.z; 266 267 //First column 268 m_res.elements[0 + 0 * 4] = x * x * (1 - c) + c; 269 m_res.elements[1 + 0 * 4] = x * y * (1 - c) + z * s; 270 m_res.elements[2 + 0 * 4] = x * z * (1 - c) - y * s; 271 272 //Second column 273 m_res.elements[0 + 1 * 4] = x * y * (1 - c) - z * s; 274 m_res.elements[1 + 1 * 4] = y * y * (1 - c) + c; 275 m_res.elements[2 + 1 * 4] = y * z * (1 - c) + x * s; 276 277 //Third column 278 m_res.elements[0 + 2 * 4] = x * z * (1 - c) + y * s; 279 m_res.elements[1 + 2 * 4] = y * z * (1 - c) - x * s; 280 m_res.elements[2 + 2 * 4] = z * z * (1 - c) + c; 281 282 return m_res; 283 } 284 RV_GLOBAL rv_mat4 rv_mat4_scalev(rv_vec3 v) 285 { 286 rv_mat4 m_res = rv_mat4_identity(); 287 m_res.elements[0 + 0 * 4] = v.x; 288 m_res.elements[1 + 1 * 4] = v.y; 289 m_res.elements[2 + 2 * 4] = v.z; 290 return m_res; 291 } 292 RV_GLOBAL rv_mat4 rv_mat4_transpose(rv_mat4 m) 293 { 294 rv_mat4 t = rv_mat4_identity(); 295 296 // First row 297 t.elements[0 * 4 + 0] = m.elements[0 * 4 + 0]; 298 t.elements[1 * 4 + 0] = m.elements[0 * 4 + 1]; 299 t.elements[2 * 4 + 0] = m.elements[0 * 4 + 2]; 300 t.elements[3 * 4 + 0] = m.elements[0 * 4 + 3]; 301 302 // Second row 303 t.elements[0 * 4 + 1] = m.elements[1 * 4 + 0]; 304 t.elements[1 * 4 + 1] = m.elements[1 * 4 + 1]; 305 t.elements[2 * 4 + 1] = m.elements[1 * 4 + 2]; 306 t.elements[3 * 4 + 1] = m.elements[1 * 4 + 3]; 307 308 // Third row 309 t.elements[0 * 4 + 2] = m.elements[2 * 4 + 0]; 310 t.elements[1 * 4 + 2] = m.elements[2 * 4 + 1]; 311 t.elements[2 * 4 + 2] = m.elements[2 * 4 + 2]; 312 t.elements[3 * 4 + 2] = m.elements[2 * 4 + 3]; 313 314 // Fourth row 315 t.elements[0 * 4 + 3] = m.elements[3 * 4 + 0]; 316 t.elements[1 * 4 + 3] = m.elements[3 * 4 + 1]; 317 t.elements[2 * 4 + 3] = m.elements[3 * 4 + 2]; 318 t.elements[3 * 4 + 3] = m.elements[3 * 4 + 3]; 319 320 return t; 321 } 322 RV_GLOBAL rv_mat4 rv_mat4_inverse(rv_mat4 m) 323 { 324 rv_mat4 res = rv_mat4_identity(); 325 326 f32 temp[16]; 327 328 temp[0] = m.elements[5] * m.elements[10] * m.elements[15] - 329 m.elements[5] * m.elements[11] * m.elements[14] - 330 m.elements[9] * m.elements[6] * m.elements[15] + 331 m.elements[9] * m.elements[7] * m.elements[14] + 332 m.elements[13] * m.elements[6] * m.elements[11] - 333 m.elements[13] * m.elements[7] * m.elements[10]; 334 335 temp[4] = -m.elements[4] * m.elements[10] * m.elements[15] + 336 m.elements[4] * m.elements[11] * m.elements[14] + 337 m.elements[8] * m.elements[6] * m.elements[15] - 338 m.elements[8] * m.elements[7] * m.elements[14] - 339 m.elements[12] * m.elements[6] * m.elements[11] + 340 m.elements[12] * m.elements[7] * m.elements[10]; 341 342 temp[8] = m.elements[4] * m.elements[9] * m.elements[15] - 343 m.elements[4] * m.elements[11] * m.elements[13] - 344 m.elements[8] * m.elements[5] * m.elements[15] + 345 m.elements[8] * m.elements[7] * m.elements[13] + 346 m.elements[12] * m.elements[5] * m.elements[11] - 347 m.elements[12] * m.elements[7] * m.elements[9]; 348 349 temp[12] = -m.elements[4] * m.elements[9] * m.elements[14] + 350 m.elements[4] * m.elements[10] * m.elements[13] + 351 m.elements[8] * m.elements[5] * m.elements[14] - 352 m.elements[8] * m.elements[6] * m.elements[13] - 353 m.elements[12] * m.elements[5] * m.elements[10] + 354 m.elements[12] * m.elements[6] * m.elements[9]; 355 356 temp[1] = -m.elements[1] * m.elements[10] * m.elements[15] + 357 m.elements[1] * m.elements[11] * m.elements[14] + 358 m.elements[9] * m.elements[2] * m.elements[15] - 359 m.elements[9] * m.elements[3] * m.elements[14] - 360 m.elements[13] * m.elements[2] * m.elements[11] + 361 m.elements[13] * m.elements[3] * m.elements[10]; 362 363 temp[5] = m.elements[0] * m.elements[10] * m.elements[15] - 364 m.elements[0] * m.elements[11] * m.elements[14] - 365 m.elements[8] * m.elements[2] * m.elements[15] + 366 m.elements[8] * m.elements[3] * m.elements[14] + 367 m.elements[12] * m.elements[2] * m.elements[11] - 368 m.elements[12] * m.elements[3] * m.elements[10]; 369 370 temp[9] = -m.elements[0] * m.elements[9] * m.elements[15] + 371 m.elements[0] * m.elements[11] * m.elements[13] + 372 m.elements[8] * m.elements[1] * m.elements[15] - 373 m.elements[8] * m.elements[3] * m.elements[13] - 374 m.elements[12] * m.elements[1] * m.elements[11] + 375 m.elements[12] * m.elements[3] * m.elements[9]; 376 377 temp[13] = m.elements[0] * m.elements[9] * m.elements[14] - 378 m.elements[0] * m.elements[10] * m.elements[13] - 379 m.elements[8] * m.elements[1] * m.elements[14] + 380 m.elements[8] * m.elements[2] * m.elements[13] + 381 m.elements[12] * m.elements[1] * m.elements[10] - 382 m.elements[12] * m.elements[2] * m.elements[9]; 383 384 temp[2] = m.elements[1] * m.elements[6] * m.elements[15] - 385 m.elements[1] * m.elements[7] * m.elements[14] - 386 m.elements[5] * m.elements[2] * m.elements[15] + 387 m.elements[5] * m.elements[3] * m.elements[14] + 388 m.elements[13] * m.elements[2] * m.elements[7] - 389 m.elements[13] * m.elements[3] * m.elements[6]; 390 391 temp[6] = -m.elements[0] * m.elements[6] * m.elements[15] + 392 m.elements[0] * m.elements[7] * m.elements[14] + 393 m.elements[4] * m.elements[2] * m.elements[15] - 394 m.elements[4] * m.elements[3] * m.elements[14] - 395 m.elements[12] * m.elements[2] * m.elements[7] + 396 m.elements[12] * m.elements[3] * m.elements[6]; 397 398 temp[10] = m.elements[0] * m.elements[5] * m.elements[15] - 399 m.elements[0] * m.elements[7] * m.elements[13] - 400 m.elements[4] * m.elements[1] * m.elements[15] + 401 m.elements[4] * m.elements[3] * m.elements[13] + 402 m.elements[12] * m.elements[1] * m.elements[7] - 403 m.elements[12] * m.elements[3] * m.elements[5]; 404 405 temp[14] = -m.elements[0] * m.elements[5] * m.elements[14] + 406 m.elements[0] * m.elements[6] * m.elements[13] + 407 m.elements[4] * m.elements[1] * m.elements[14] - 408 m.elements[4] * m.elements[2] * m.elements[13] - 409 m.elements[12] * m.elements[1] * m.elements[6] + 410 m.elements[12] * m.elements[2] * m.elements[5]; 411 412 temp[3] = -m.elements[1] * m.elements[6] * m.elements[11] + 413 m.elements[1] * m.elements[7] * m.elements[10] + 414 m.elements[5] * m.elements[2] * m.elements[11] - 415 m.elements[5] * m.elements[3] * m.elements[10] - 416 m.elements[9] * m.elements[2] * m.elements[7] + 417 m.elements[9] * m.elements[3] * m.elements[6]; 418 419 temp[7] = m.elements[0] * m.elements[6] * m.elements[11] - 420 m.elements[0] * m.elements[7] * m.elements[10] - 421 m.elements[4] * m.elements[2] * m.elements[11] + 422 m.elements[4] * m.elements[3] * m.elements[10] + 423 m.elements[8] * m.elements[2] * m.elements[7] - 424 m.elements[8] * m.elements[3] * m.elements[6]; 425 426 temp[11] = -m.elements[0] * m.elements[5] * m.elements[11] + 427 m.elements[0] * m.elements[7] * m.elements[9] + 428 m.elements[4] * m.elements[1] * m.elements[11] - 429 m.elements[4] * m.elements[3] * m.elements[9] - 430 m.elements[8] * m.elements[1] * m.elements[7] + 431 m.elements[8] * m.elements[3] * m.elements[5]; 432 433 temp[15] = m.elements[0] * m.elements[5] * m.elements[10] - 434 m.elements[0] * m.elements[6] * m.elements[9] - 435 m.elements[4] * m.elements[1] * m.elements[10] + 436 m.elements[4] * m.elements[2] * m.elements[9] + 437 m.elements[8] * m.elements[1] * m.elements[6] - 438 m.elements[8] * m.elements[2] * m.elements[5]; 439 440 float determinant = m.elements[0] * temp[0] + m.elements[1] * temp[4] + m.elements[2] * temp[8] + m.elements[3] * temp[12]; 441 determinant = 1.0f / determinant; 442 443 for (int i = 0; i < 4 * 4; i++) 444 res.elements[i] = (float)(temp[i] * (float)determinant); 445 446 return res; 447 } 448 RV_GLOBAL rv_mat4 rv_mat4_look_at(rv_vec3 position, rv_vec3 target, rv_vec3 up) 449 { 450 rv_vec3 f = rv_vec3_norm(rv_vec3_sub(target, position)); 451 rv_vec3 s = rv_vec3_norm(rv_vec3_cross(f, up)); 452 rv_vec3 u = rv_vec3_cross(s, f); 453 454 rv_mat4 m_res = rv_mat4_identity(); 455 m_res.elements[0 * 4 + 0] = s.x; 456 m_res.elements[1 * 4 + 0] = s.y; 457 m_res.elements[2 * 4 + 0] = s.z; 458 459 m_res.elements[0 * 4 + 1] = u.x; 460 m_res.elements[1 * 4 + 1] = u.y; 461 m_res.elements[2 * 4 + 1] = u.z; 462 463 m_res.elements[0 * 4 + 2] = -f.x; 464 m_res.elements[1 * 4 + 2] = -f.y; 465 m_res.elements[2 * 4 + 2] = -f.z; 466 467 m_res.elements[3 * 4 + 0] = -rv_vec3_dot(s, position);; 468 m_res.elements[3 * 4 + 1] = -rv_vec3_dot(u, position); 469 m_res.elements[3 * 4 + 2] = rv_vec3_dot(f, position); 470 471 return m_res; 472 } 473 474 RV_GLOBAL rv_mat4 rv_mat4_mul(rv_mat4 m0, rv_mat4 m1) 475 { 476 rv_mat4 m_res = {0}; 477 for (u32 y = 0; y < 4; ++y) { 478 for (u32 x = 0; x < 4; ++x) { 479 f32 sum = 0.0f; 480 for (u32 e = 0; e < 4; ++e) { 481 sum += m0.elements[x + e * 4] * m1.elements[e + y * 4]; 482 } 483 m_res.elements[x + y * 4] = sum; 484 } 485 } 486 487 return m_res; 488 } 489 RV_GLOBAL rv_mat4 rv_mat4_mul_list_(rv_mat4* m_list, s64 m_list_len) 490 { 491 va_list ap; 492 rv_mat4 m = rv_mat4_identity(); 493 for (uint32_t i = 0; i < m_list_len; ++i) { 494 m = rv_mat4_mul(m, m_list[i]); 495 } 496 return m; 497 } 498 RV_GLOBAL rv_vec4 rv_mat4_mul_vec4(rv_mat4 m, rv_vec4 v) 499 { 500 return rv_v4 501 ( 502 m.elements[0 + 4 * 0] * v.x + m.elements[0 + 4 * 1] * v.y + m.elements[0 + 4 * 2] * v.z + m.elements[0 + 4 * 3] * v.w, 503 m.elements[1 + 4 * 0] * v.x + m.elements[1 + 4 * 1] * v.y + m.elements[1 + 4 * 2] * v.z + m.elements[1 + 4 * 3] * v.w, 504 m.elements[2 + 4 * 0] * v.x + m.elements[2 + 4 * 1] * v.y + m.elements[2 + 4 * 2] * v.z + m.elements[2 + 4 * 3] * v.w, 505 m.elements[3 + 4 * 0] * v.x + m.elements[3 + 4 * 1] * v.y + m.elements[3 + 4 * 2] * v.z + m.elements[3 + 4 * 3] * v.w 506 ); 507 } 508 RV_GLOBAL rv_vec3 rv_mat4_mul_vec3(rv_mat4 m, rv_vec3 v) 509 { 510 return rv_mat4_mul_vec4(m, rv_v4(.xyz = v, .w = 1.f)).xyz; 511 } 512 513 RV_GLOBAL rv_mat4 rv_mat4_ortho_norm(rv_mat4 m) 514 { 515 m.v.right = rv_vec4_norm(m.v.right); 516 m.v.up = rv_vec4_norm(m.v.up); 517 m.v.dir = rv_vec4_norm(m.v.dir); 518 return m; 519 } 520 RV_GLOBAL rv_mat4 rv_mat4_ortho(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f) 521 { 522 rv_mat4 m_res = rv_mat4_identity(); 523 524 // Main diagonal 525 m_res.elements[0 + 0 * 4] = 2.0f / (r - l); 526 m_res.elements[1 + 1 * 4] = 2.0f / (t - b); 527 m_res.elements[2 + 2 * 4] = -2.0f / (f - n); 528 529 // Last column 530 m_res.elements[0 + 3 * 4] = -(r + l) / (r - l); 531 m_res.elements[1 + 3 * 4] = -(t + b) / (t - b); 532 m_res.elements[2 + 3 * 4] = -(f + n) / (f - n); 533 534 return m_res; 535 } 536 RV_GLOBAL rv_mat4 rv_mat4_perspective(f32 fov, f32 asp_ratio, f32 n, f32 f) 537 { 538 // Zero matrix 539 rv_mat4 m_res = {0}; 540 541 f32 q = 1.0f / (float)tan(rv_deg2rad(0.5f * fov)); 542 f32 a = q / asp_ratio; 543 f32 b = (n + f) / (n - f); 544 f32 c = (2.0f * n * f) / (n - f); 545 546 m_res.elements[0 + 0 * 4] = a; 547 m_res.elements[1 + 1 * 4] = q; 548 m_res.elements[2 + 2 * 4] = b; 549 m_res.elements[2 + 3 * 4] = c; 550 m_res.elements[3 + 2 * 4] = -1.0f; 551 552 return m_res; 553 } 554 555 RV_GLOBAL void rv_mat4_decompose(const rv_mat4* m, rv_vec3* translation, rv_vec3* rotation, rv_vec3* scale) 556 { 557 rv_mat4 mat = *m; 558 559 scale->xyz[0] = rv_vec4_len(mat.v.right); 560 scale->xyz[1] = rv_vec4_len(mat.v.up); 561 scale->xyz[2] = rv_vec4_len(mat.v.dir); 562 563 mat = rv_mat4_ortho_norm(mat); 564 565 rotation->xyz[0] = rv_rad2deg(atan2f(mat.m[1][2], mat.m[2][2])); 566 rotation->xyz[1] = rv_rad2deg(atan2f(-mat.m[0][2], sqrtf(mat.m[1][2] * mat.m[1][2] + 567 mat.m[2][2] * mat.m[2][2]))); 568 rotation->xyz[2] = rv_rad2deg(atan2f(mat.m[0][1], mat.m[0][0])); 569 570 translation->xyz[0] = mat.v.position.x; 571 translation->xyz[1] = mat.v.position.y; 572 translation->xyz[2] = mat.v.position.z; 573 } 574 RV_GLOBAL rv_mat4 rv_mat4_recompose(rv_vec3 translation, rv_vec3 rotation, rv_vec3 scale) 575 { 576 rv_mat4 mat = rv_mat4_identity(); 577 578 rv_vec3 direction_unary[3] = { 579 RV_XAXIS, 580 RV_YAXIS, 581 RV_ZAXIS 582 }; 583 584 rv_mat4 rot[3] = {rv_mat4_identity(), rv_mat4_identity(), rv_mat4_identity()}; 585 for (uint32_t i = 0; i < 3; ++i) { 586 rot[i] = rv_mat4_rotatev(rv_deg2rad(rotation.xyz[i]), direction_unary[i]); 587 } 588 589 mat = rv_mat4_mul_list(rot[2], rot[1], rot[0]); 590 591 float valid_scale[3] = {0}; 592 for (uint32_t i = 0; i < 3; ++i) { 593 valid_scale[i] = fabsf(scale.xyz[i]) < RV_EPSILON ? 0.001f : scale.xyz[i]; 594 } 595 596 mat.v.right = rv_vec4_scale(mat.v.right, valid_scale[0]); 597 mat.v.up = rv_vec4_scale(mat.v.up, valid_scale[1]); 598 mat.v.dir = rv_vec4_scale(mat.v.dir, valid_scale[2]); 599 mat.v.position = rv_v4(translation.xyz[0], translation.xyz[1], translation.xyz[2], 1.f); 600 601 return mat; 602 }