1use std::{mem::size_of, convert::TryInto, ops};
2
3use field_offset::FieldOffset;
4
5use crate::db_internal::{mat4_loadSIMD, mat4_storeSIMD, mat4_mulSIMD, mat4_transformSIMD};
6
7#[repr(C)]
8#[derive(Clone, Copy, Debug, Default)]
9pub struct Vector2 {
10 pub x: f32,
11 pub y: f32,
12}
13
14impl Vector2 {
15 pub const fn new(x: f32, y: f32) -> Vector2 {
16 return Vector2 { x: x, y: y };
17 }
18
19 pub const fn zero() -> Vector2 {
20 return Vector2 { x: 0.0, y: 0.0 };
21 }
22
23 pub const fn unit_x() -> Vector2 {
24 return Vector2 { x: 1.0, y: 0.0 };
25 }
26
27 pub const fn unit_y() -> Vector2 {
28 return Vector2 { x: 0.0, y: 1.0 };
29 }
30
31 pub fn distance_sq(lhs: &Vector2, rhs: &Vector2) -> f32 {
33 let dx = lhs.x - rhs.x;
34 let dy = lhs.y - rhs.y;
35 return (dx * dx) + (dy * dy);
36 }
37
38 pub fn distance(lhs: &Vector2, rhs: &Vector2) -> f32 {
40 let dx = lhs.x - rhs.x;
41 let dy = lhs.y - rhs.y;
42 return ((dx * dx) + (dy * dy)).sqrt();
43 }
44
45 pub fn length_sq(self) -> f32 {
47 return (self.x * self.x) + (self.y * self.y);
48 }
49
50 pub fn length(self) -> f32 {
52 return ((self.x * self.x) + (self.y * self.y)).sqrt();
53 }
54
55 pub fn normalize(&mut self) {
57 let mag = 1.0 / (self.x * self.x + self.y * self.y).sqrt();
58 self.x *= mag;
59 self.y *= mag;
60 }
61
62 pub fn normalized(&self) -> Vector2 {
64 let mag = 1.0 / (self.x * self.x + self.y * self.y).sqrt();
65 return Vector2 { x: self.x * mag, y: self.y * mag };
66 }
67
68 pub fn dot(lhs: &Vector2, rhs: &Vector2) -> f32 {
70 return (lhs.x * rhs.x) + (lhs.y * rhs.y);
71 }
72}
73
74impl ops::Add<Vector2> for Vector2 {
75 type Output = Vector2;
76
77 fn add(self, rhs: Vector2) -> Vector2 {
78 return Vector2 { x: self.x + rhs.x, y: self.y + rhs.y };
79 }
80}
81
82impl ops::Sub<Vector2> for Vector2 {
83 type Output = Vector2;
84
85 fn sub(self, rhs: Vector2) -> Vector2 {
86 return Vector2 { x: self.x - rhs.x, y: self.y - rhs.y };
87 }
88}
89
90impl ops::Mul<Vector2> for Vector2 {
91 type Output = Vector2;
92
93 fn mul(self, rhs: Vector2) -> Vector2 {
94 return Vector2 { x: self.x * rhs.x, y: self.y * rhs.y };
95 }
96}
97
98impl ops::Mul<f32> for Vector2 {
99 type Output = Vector2;
100
101 fn mul(self, rhs: f32) -> Vector2 {
102 return Vector2 { x: self.x * rhs, y: self.y * rhs };
103 }
104}
105
106impl ops::Mul<Vector2> for f32 {
107 type Output = Vector2;
108
109 fn mul(self, rhs: Vector2) -> Vector2 {
110 return Vector2 { x: self * rhs.x, y: self * rhs.y };
111 }
112}
113
114impl ops::Div<Vector2> for Vector2 {
115 type Output = Vector2;
116
117 fn div(self, rhs: Vector2) -> Vector2 {
118 return Vector2 { x: self.x / rhs.x, y: self.y / rhs.y };
119 }
120}
121
122impl ops::Div<f32> for Vector2 {
123 type Output = Vector2;
124
125 fn div(self, rhs: f32) -> Vector2 {
126 return Vector2 { x: self.x / rhs, y: self.y / rhs };
127 }
128}
129
130impl ops::Div<Vector2> for f32 {
131 type Output = Vector2;
132
133 fn div(self, rhs: Vector2) -> Vector2 {
134 return Vector2 { x: self / rhs.x, y: self / rhs.y };
135 }
136}
137
138#[repr(C)]
139#[derive(Clone, Copy, Debug, Default)]
140pub struct Vector3 {
141 pub x: f32,
142 pub y: f32,
143 pub z: f32,
144}
145
146impl Vector3 {
147 pub const fn new(x: f32, y: f32, z: f32) -> Vector3 {
148 return Vector3 { x: x, y: y, z: z };
149 }
150
151 pub const fn zero() -> Vector3 {
152 return Vector3 { x: 0.0, y: 0.0, z: 0.0 };
153 }
154
155 pub const fn unit_x() -> Vector3 {
156 return Vector3 { x: 1.0, y: 0.0, z: 0.0 };
157 }
158
159 pub const fn unit_y() -> Vector3 {
160 return Vector3 { x: 0.0, y: 1.0, z: 0.0 };
161 }
162
163 pub const fn unit_z() -> Vector3 {
164 return Vector3 { x: 0.0, y: 0.0, z: 1.0 };
165 }
166
167 pub fn distance_sq(lhs: &Vector3, rhs: &Vector3) -> f32 {
169 let dx = lhs.x - rhs.x;
170 let dy = lhs.y - rhs.y;
171 let dz = lhs.z - rhs.z;
172 return (dx * dx) + (dy * dy) + (dz * dz);
173 }
174
175 pub fn distance(lhs: &Vector3, rhs: &Vector3) -> f32 {
177 let dx = lhs.x - rhs.x;
178 let dy = lhs.y - rhs.y;
179 let dz = lhs.z - rhs.z;
180 return ((dx * dx) + (dy * dy) + (dz * dz)).sqrt();
181 }
182
183 pub fn length_sq(self) -> f32 {
185 return (self.x * self.x) + (self.y * self.y) + (self.z * self.z);
186 }
187
188 pub fn length(self) -> f32 {
190 return ((self.x * self.x) + (self.y * self.y) + (self.z * self.z)).sqrt();
191 }
192
193 pub fn normalize(&mut self) {
195 let mag = 1.0 / (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
196 self.x *= mag;
197 self.y *= mag;
198 self.z *= mag;
199 }
200
201 pub fn normalized(&self) -> Vector3 {
203 let mag = 1.0 / (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
204 return Vector3 { x: self.x * mag, y: self.y * mag, z: self.z * mag };
205 }
206
207 pub fn dot(lhs: &Vector3, rhs: &Vector3) -> f32 {
209 return (lhs.x * rhs.x) + (lhs.y * rhs.y) + (lhs.z * rhs.z);
210 }
211
212 pub fn cross(lhs: &Vector3, rhs: &Vector3) -> Vector3 {
214 return Vector3 {
215 x: lhs.y * rhs.z - lhs.z * rhs.y,
216 y: -(lhs.x * rhs.z - lhs.z * rhs.x),
217 z: lhs.x * rhs.y - lhs.y * rhs.x
218 };
219 }
220}
221
222impl ops::Add<Vector3> for Vector3 {
223 type Output = Vector3;
224
225 fn add(self, rhs: Vector3) -> Vector3 {
226 return Vector3 { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z };
227 }
228}
229
230impl ops::Sub<Vector3> for Vector3 {
231 type Output = Vector3;
232
233 fn sub(self, rhs: Vector3) -> Vector3 {
234 return Vector3 { x: self.x - rhs.x, y: self.y - rhs.y, z: self.z - rhs.z };
235 }
236}
237
238impl ops::Mul<Vector3> for Vector3 {
239 type Output = Vector3;
240
241 fn mul(self, rhs: Vector3) -> Vector3 {
242 return Vector3 { x: self.x * rhs.x, y: self.y * rhs.y, z: self.z * rhs.z };
243 }
244}
245
246impl ops::Mul<f32> for Vector3 {
247 type Output = Vector3;
248
249 fn mul(self, rhs: f32) -> Vector3 {
250 return Vector3 { x: self.x * rhs, y: self.y * rhs, z: self.z * rhs };
251 }
252}
253
254impl ops::Mul<Vector3> for f32 {
255 type Output = Vector3;
256
257 fn mul(self, rhs: Vector3) -> Vector3 {
258 return Vector3 { x: self * rhs.x, y: self * rhs.y, z: self * rhs.z };
259 }
260}
261
262impl ops::Div<Vector3> for Vector3 {
263 type Output = Vector3;
264
265 fn div(self, rhs: Vector3) -> Vector3 {
266 return Vector3 { x: self.x / rhs.x, y: self.y / rhs.y, z: self.z / rhs.z };
267 }
268}
269
270impl ops::Div<f32> for Vector3 {
271 type Output = Vector3;
272
273 fn div(self, rhs: f32) -> Vector3 {
274 return Vector3 { x: self.x / rhs, y: self.y / rhs, z: self.z / rhs };
275 }
276}
277
278impl ops::Div<Vector3> for f32 {
279 type Output = Vector3;
280
281 fn div(self, rhs: Vector3) -> Vector3 {
282 return Vector3 { x: self / rhs.x, y: self / rhs.y, z: self / rhs.z };
283 }
284}
285
286#[repr(C)]
287#[derive(Clone, Copy, Debug, Default)]
288pub struct Vector4 {
289 pub x: f32,
290 pub y: f32,
291 pub z: f32,
292 pub w: f32,
293}
294
295impl Vector4 {
296 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Vector4 {
297 return Vector4 { x: x, y: y, z: z, w: w };
298 }
299
300 pub const fn zero() -> Vector4 {
301 return Vector4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
302 }
303
304 pub const fn unit_x() -> Vector4 {
305 return Vector4 { x: 1.0, y: 0.0, z: 0.0, w: 0.0 };
306 }
307
308 pub const fn unit_y() -> Vector4 {
309 return Vector4 { x: 0.0, y: 1.0, z: 0.0, w: 0.0 };
310 }
311
312 pub const fn unit_z() -> Vector4 {
313 return Vector4 { x: 0.0, y: 0.0, z: 1.0, w: 0.0 };
314 }
315
316 pub const fn unit_w() -> Vector4 {
317 return Vector4 { x: 0.0, y: 0.0, z: 0.0, w: 1.0 };
318 }
319
320 pub fn distance_sq(lhs: &Vector4, rhs: &Vector4) -> f32 {
322 let dx = lhs.x - rhs.x;
323 let dy = lhs.y - rhs.y;
324 let dz = lhs.z - rhs.z;
325 let dw = lhs.w - rhs.w;
326 return (dx * dx) + (dy * dy) + (dz * dz) + (dw * dw);
327 }
328
329 pub fn distance(lhs: &Vector4, rhs: &Vector4) -> f32 {
331 let dx = lhs.x - rhs.x;
332 let dy = lhs.y - rhs.y;
333 let dz = lhs.z - rhs.z;
334 let dw = lhs.w - rhs.w;
335 return ((dx * dx) + (dy * dy) + (dz * dz) + (dw * dw)).sqrt();
336 }
337
338 pub fn length_sq(self) -> f32 {
340 return (self.x * self.x) + (self.y * self.y) + (self.z * self.z) + (self.w * self.w);
341 }
342
343 pub fn length(self) -> f32 {
345 return ((self.x * self.x) + (self.y * self.y) + (self.z * self.z) + (self.w * self.w)).sqrt();
346 }
347
348 pub fn normalize(&mut self) {
350 let mag = 1.0 / (self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt();
351 self.x *= mag;
352 self.y *= mag;
353 self.z *= mag;
354 self.w *= mag;
355 }
356
357 pub fn normalized(&self) -> Vector4 {
359 let mag = 1.0 / (self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt();
360 return Vector4 { x: self.x * mag, y: self.y * mag, z: self.z * mag, w: self.w * mag };
361 }
362
363 pub fn dot(lhs: &Vector4, rhs: &Vector4) -> f32 {
365 return (lhs.x * rhs.x) + (lhs.y * rhs.y) + (lhs.z * rhs.z) + (lhs.w * rhs.w);
366 }
367}
368
369impl ops::Add<Vector4> for Vector4 {
370 type Output = Vector4;
371
372 fn add(self, rhs: Vector4) -> Vector4 {
373 return Vector4 { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z, w: self.w + rhs.w };
374 }
375}
376
377impl ops::Sub<Vector4> for Vector4 {
378 type Output = Vector4;
379
380 fn sub(self, rhs: Vector4) -> Vector4 {
381 return Vector4 { x: self.x - rhs.x, y: self.y - rhs.y, z: self.z - rhs.z, w: self.w - rhs.w };
382 }
383}
384
385impl ops::Mul<Vector4> for Vector4 {
386 type Output = Vector4;
387
388 fn mul(self, rhs: Vector4) -> Vector4 {
389 return Vector4 { x: self.x * rhs.x, y: self.y * rhs.y, z: self.z * rhs.z, w: self.w * rhs.w };
390 }
391}
392
393impl ops::Mul<f32> for Vector4 {
394 type Output = Vector4;
395
396 fn mul(self, rhs: f32) -> Vector4 {
397 return Vector4 { x: self.x * rhs, y: self.y * rhs, z: self.z * rhs, w: self.w * rhs };
398 }
399}
400
401impl ops::Mul<Vector4> for f32 {
402 type Output = Vector4;
403
404 fn mul(self, rhs: Vector4) -> Vector4 {
405 return Vector4 { x: self * rhs.x, y: self * rhs.y, z: self * rhs.z, w: self * rhs.w };
406 }
407}
408
409impl ops::Div<Vector4> for Vector4 {
410 type Output = Vector4;
411
412 fn div(self, rhs: Vector4) -> Vector4 {
413 return Vector4 { x: self.x / rhs.x, y: self.y / rhs.y, z: self.z / rhs.z, w: self.w / rhs.w };
414 }
415}
416
417impl ops::Div<f32> for Vector4 {
418 type Output = Vector4;
419
420 fn div(self, rhs: f32) -> Vector4 {
421 return Vector4 { x: self.x / rhs, y: self.y / rhs, z: self.z / rhs, w: self.w / rhs };
422 }
423}
424
425impl ops::Div<Vector4> for f32 {
426 type Output = Vector4;
427
428 fn div(self, rhs: Vector4) -> Vector4 {
429 return Vector4 { x: self / rhs.x, y: self / rhs.y, z: self / rhs.z, w: self / rhs.w };
430 }
431}
432
433#[repr(C)]
434#[derive(Clone, Copy, Debug)]
435pub struct Quaternion {
436 pub x: f32,
437 pub y: f32,
438 pub z: f32,
439 pub w: f32,
440}
441
442impl Quaternion {
443 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Quaternion {
444 return Quaternion { x: x, y: y, z: z, w: w };
445 }
446
447 pub const fn identity() -> Quaternion {
448 return Quaternion { x: 0.0, y: 0.0, z: 0.0, w: 1.0 };
449 }
450
451 pub fn from_euler(euler_angles: Vector3) -> Quaternion {
453 let cx = (euler_angles.x * 0.5).cos();
454 let sx = (euler_angles.x * 0.5).sin();
455 let cy = (euler_angles.y * 0.5).cos();
456 let sy = (euler_angles.y * 0.5).sin();
457 let cz = (euler_angles.z * 0.5).cos();
458 let sz = (euler_angles.z * 0.5).sin();
459
460 return Quaternion {
461 x: sx * cy * cz - cx * sy * sz,
462 y: cx * sy * cz + sx * cy * sz,
463 z: cx * cy * sz - sx * sy * cz,
464 w: cx * cy * cz + sx * sy * sz,
465 };
466 }
467
468 pub fn normalize(&mut self) {
470 let mag = 1.0 / (self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt();
471 self.x *= mag;
472 self.y *= mag;
473 self.z *= mag;
474 self.w *= mag;
475 }
476
477 pub fn normalized(&self) -> Quaternion {
479 let mag = 1.0 / (self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt();
480 return Quaternion { x: self.x * mag, y: self.y * mag, z: self.z * mag, w: self.w * mag };
481 }
482
483 pub fn invert(&mut self) {
485 let n = 1.0 / (self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w);
486 self.x *= -n;
487 self.y *= -n;
488 self.z *= -n;
489 self.w *= n;
490 }
491}
492
493impl ops::Mul<Quaternion> for Quaternion {
494 type Output = Quaternion;
495
496 fn mul(self, rhs: Quaternion) -> Quaternion {
497 let x = self.x * rhs.w + self.y * rhs.z - self.z * rhs.y + self.w * rhs.x;
498 let y = -self.x * rhs.z + self.y * rhs.w + self.z * rhs.x + self.w * rhs.y;
499 let z = self.x * rhs.y - self.y * rhs.x + self.z * rhs.w + self.w * rhs.z;
500 let w = -self.x * rhs.x - self.y * rhs.y - self.z * rhs.z + self.w * rhs.w;
501 return Quaternion { x: x, y: y, z: z, w: w };
502 }
503}
504
505impl ops::Mul<Vector3> for Quaternion {
506 type Output = Vector3;
507
508 fn mul(self, rhs: Vector3) -> Vector3 {
509 let x = 2.0 * (self.y * rhs.z - self.z * rhs.y);
510 let y = 2.0 * (self.z * rhs.x - self.x * rhs.z);
511 let z = 2.0 * (self.x * rhs.y - self.y * rhs.x);
512
513 let rx = rhs.x + x * self.w + (self.y * z - self.z * y);
514 let ry = rhs.y + y * self.w + (self.z * x - self.x * z);
515 let rz = rhs.z + z * self.w + (self.x * y - self.y * x);
516
517 return Vector3 { x: rx, y: ry, z: rz };
518 }
519}
520
521#[repr(C)]
522#[derive(Clone, Copy, Debug)]
523pub struct Matrix4x4 {
524 pub m: [[f32;4];4],
525}
526
527impl Matrix4x4 {
528 pub const fn identity() -> Matrix4x4 {
529 return Matrix4x4 { m: [
530 [1.0, 0.0, 0.0, 0.0],
531 [0.0, 1.0, 0.0, 0.0],
532 [0.0, 0.0, 1.0, 0.0],
533 [0.0, 0.0, 0.0, 1.0],
534 ] };
535 }
536
537 pub fn get_row(self: &Matrix4x4, index: usize) -> Vector4 {
539 Vector4::new(self.m[0][index], self.m[1][index], self.m[2][index], self.m[3][index])
540 }
541
542 pub fn get_column(self: &Matrix4x4, index: usize) -> Vector4 {
544 Vector4::new(self.m[index][0], self.m[index][1], self.m[index][2], self.m[index][3])
545 }
546
547 pub fn transpose(self: &mut Matrix4x4) {
549 let c0 = self.m[0];
550 let c1 = self.m[1];
551 let c2 = self.m[2];
552 let c3 = self.m[3];
553
554 self.m[0] = [c0[0], c1[0], c2[0], c3[0]];
555 self.m[1] = [c0[1], c1[1], c2[1], c3[1]];
556 self.m[2] = [c0[2], c1[2], c2[2], c3[2]];
557 self.m[3] = [c0[3], c1[3], c2[3], c3[3]];
558 }
559
560 pub fn transposed(self: &Matrix4x4) -> Matrix4x4 {
562 let mut ret = *self;
563 ret.transpose();
564
565 return ret;
566 }
567
568 pub fn translation(translation: Vector3) -> Matrix4x4 {
570 return Matrix4x4 { m: [
571 [1.0, 0.0, 0.0, 0.0],
572 [0.0, 1.0, 0.0, 0.0],
573 [0.0, 0.0, 1.0, 0.0],
574 [translation.x, translation.y, translation.z, 1.0],
575 ] };
576 }
577
578 pub fn scale(scale: Vector3) -> Matrix4x4 {
580 return Matrix4x4 { m: [
581 [scale.x, 0.0, 0.0, 0.0],
582 [0.0, scale.y, 0.0, 0.0],
583 [0.0, 0.0, scale.z, 0.0],
584 [0.0, 0.0, 0.0, 1.0],
585 ] };
586 }
587
588 pub fn rotation(rotation: Quaternion) -> Matrix4x4 {
590 let num9 = rotation.x * rotation.x;
591 let num8 = rotation.y * rotation.y;
592 let num7 = rotation.z * rotation.z;
593 let num6 = rotation.x * rotation.y;
594 let num5 = rotation.z * rotation.w;
595 let num4 = rotation.z * rotation.x;
596 let num3 = rotation.y * rotation.w;
597 let num2 = rotation.y * rotation.z;
598 let num = rotation.x * rotation.w;
599
600 let mut result = Matrix4x4::identity();
601 result.m[0][0] = 1.0 - (2.0 * (num8 + num7));
602 result.m[0][1] = 2.0 * (num6 + num5);
603 result.m[0][2] = 2.0 * (num4 - num3);
604 result.m[0][3] = 0.0;
605 result.m[1][0] = 2.0 * (num6 - num5);
606 result.m[1][1] = 1.0 - (2.0 * (num7 + num9));
607 result.m[1][2] = 2.0 * (num2 + num);
608 result.m[1][3] = 0.0;
609 result.m[2][0] = 2.0 * (num4 + num3);
610 result.m[2][1] = 2.0 * (num2 - num);
611 result.m[2][2] = 1.0 - (2.0 * (num8 + num9));
612 result.m[2][3] = 0.0;
613 result.m[3][0] = 0.0;
614 result.m[3][1] = 0.0;
615 result.m[3][2] = 0.0;
616 result.m[3][3] = 1.0;
617
618 return result;
619 }
620
621 pub fn projection_ortho(left: f32, right: f32, top: f32, bottom: f32, near: f32, far: f32) -> Matrix4x4 {
623 let scale_x = 2.0 / (right - left);
624 let scale_y = 2.0 / (top - bottom);
625 let scale_z = 1.0 / (near - far);
626
627 let mut mat = Matrix4x4::identity();
628
629 mat.m[0][0] = scale_x;
630 mat.m[1][1] = scale_y;
631 mat.m[2][2] = scale_z;
632
633 mat.m[3][0] = (left + right) / (left - right);
634 mat.m[3][1] = (top + bottom) / (bottom - top);
635 mat.m[3][2] = near / (near - far);
636
637 return mat;
638 }
639
640 pub fn projection_ortho_aspect(aspect_ratio: f32, scale: f32, near: f32, far: f32) -> Matrix4x4 {
642 let extent_x = scale * aspect_ratio * 0.5;
643 let extent_y = scale * 0.5;
644
645 return Matrix4x4::projection_ortho(-extent_x, extent_x, extent_y, -extent_y, near, far);
646 }
647
648 pub fn projection_perspective(aspect_ratio: f32, field_of_view: f32, near: f32, far: f32) -> Matrix4x4 {
650 let top = (field_of_view * 0.5).tan() * near;
651 let bottom = -top;
652 let right = top * aspect_ratio;
653 let left = -right;
654
655 let height = top - bottom;
656 let width = right - left;
657
658 let two_n = 2.0 * near;
659
660 let mut mat = Matrix4x4 {m: [
661 [ 0.0, 0.0, 0.0, 0.0 ],
662 [ 0.0, 0.0, 0.0, 0.0 ],
663 [ 0.0, 0.0, 0.0, 0.0 ],
664 [ 0.0, 0.0, 0.0, 0.0 ],
665 ]};
666
667 mat.m[0][0] = two_n / width;
668 mat.m[1][1] = two_n / height;
669 mat.m[2][2] = far / (near - far);
670 mat.m[2][3] = -1.0;
671 mat.m[3][2] = (near * far) /
672 (near - far);
673
674 return mat;
675 }
676
677 #[deprecated(since = "0.1.16", note = "Dreambox v2.x now directly supports compiling with SIMD intrinsics")]
679 #[allow(deprecated)]
680 pub fn load_identity_simd() {
681 let m = Matrix4x4::identity();
682 Matrix4x4::load_simd(&m);
683 }
684
685 #[deprecated(since = "0.1.16", note = "Dreambox v2.x now directly supports compiling with WASM SIMD intrinsics")]
687 pub fn load_simd(matrix: &Matrix4x4) {
688 unsafe { mat4_loadSIMD(matrix) };
689 }
690
691 #[deprecated(since = "0.1.16", note = "Dreambox v2.x now directly supports compiling with WASM SIMD intrinsics")]
693 pub fn store_simd(matrix: &mut Matrix4x4) {
694 unsafe { mat4_storeSIMD(matrix) };
695 }
696
697 #[deprecated(since = "0.1.16", note = "Dreambox v2.x now directly supports compiling with WASM SIMD intrinsics")]
699 pub fn mul_simd(matrix: &Matrix4x4) {
700 unsafe { mat4_mulSIMD(matrix) };
701 }
702
703 #[deprecated(since = "0.1.16", note = "Dreambox v2.x now directly supports compiling with WASM SIMD intrinsics")]
705 pub fn transform_vector_simd(data: &mut [Vector4]) {
706 unsafe {
707 let ptr = data.as_mut_ptr();
708 let stride = size_of::<Vector4>();
709 mat4_transformSIMD(ptr, ptr, data.len().try_into().unwrap(), stride.try_into().unwrap());
710 }
711 }
712
713 #[deprecated(since = "0.1.16", note = "Dreambox v2.x now directly supports compiling with WASM SIMD intrinsics")]
715 pub fn transform_vertex_simd<T>(data: &mut [T], field: FieldOffset<T,Vector4>) {
716 unsafe {
717 let fieldref = field.apply_ptr_mut(data.as_mut_ptr());
718 let stride = size_of::<T>();
719 mat4_transformSIMD(fieldref, fieldref, data.len().try_into().unwrap(), stride.try_into().unwrap());
720 }
721 }
722}
723
724impl ops::Mul<Vector4> for Matrix4x4 {
725 type Output = Vector4;
726
727 fn mul(self, rhs: Vector4) -> Vector4 {
728 let x = (rhs.x * self.m[0][0]) + (rhs.y * self.m[1][0]) + (rhs.z * self.m[2][0]) + (rhs.w * self.m[3][0]);
729 let y = (rhs.x * self.m[0][1]) + (rhs.y * self.m[1][1]) + (rhs.z * self.m[2][1]) + (rhs.w * self.m[3][1]);
730 let z = (rhs.x * self.m[0][2]) + (rhs.y * self.m[1][2]) + (rhs.z * self.m[2][2]) + (rhs.w * self.m[3][2]);
731 let w = (rhs.x * self.m[0][3]) + (rhs.y * self.m[1][3]) + (rhs.z * self.m[2][3]) + (rhs.w * self.m[3][3]);
732
733 return Vector4 { x, y, z, w };
734 }
735}
736
737impl ops::Mul<f32> for Matrix4x4 {
738 type Output = Matrix4x4;
739
740 fn mul(self, rhs: f32) -> Matrix4x4 {
741 let m00 = self.m[0][0] * rhs;
742 let m10 = self.m[1][0] * rhs;
743 let m20 = self.m[2][0] * rhs;
744 let m30 = self.m[3][0] * rhs;
745
746 let m01 = self.m[0][1] * rhs;
747 let m11 = self.m[1][1] * rhs;
748 let m21 = self.m[2][1] * rhs;
749 let m31 = self.m[3][1] * rhs;
750
751 let m02 = self.m[0][2] * rhs;
752 let m12 = self.m[1][2] * rhs;
753 let m22 = self.m[2][2] * rhs;
754 let m32 = self.m[3][2] * rhs;
755
756 let m03 = self.m[0][3] * rhs;
757 let m13 = self.m[1][3] * rhs;
758 let m23 = self.m[2][3] * rhs;
759 let m33 = self.m[3][3] * rhs;
760
761 return Matrix4x4 { m: [
762 [m00, m10, m20, m30],
763 [m01, m11, m21, m31],
764 [m02, m12, m22, m32],
765 [m03, m13, m23, m33],
766 ] };
767 }
768}
769
770impl ops::Mul<Matrix4x4> for Matrix4x4 {
771 type Output = Matrix4x4;
772
773 fn mul(self, rhs: Matrix4x4) -> Matrix4x4 {
774 let m00 = (self.m[0][0] * rhs.m[0][0]) + (self.m[0][1] * rhs.m[1][0]) + (self.m[0][2] * rhs.m[2][0]) + (self.m[0][3] * rhs.m[3][0]);
775 let m10 = (self.m[0][0] * rhs.m[0][1]) + (self.m[0][1] * rhs.m[1][1]) + (self.m[0][2] * rhs.m[2][1]) + (self.m[0][3] * rhs.m[3][1]);
776 let m20 = (self.m[0][0] * rhs.m[0][2]) + (self.m[0][1] * rhs.m[1][2]) + (self.m[0][2] * rhs.m[2][2]) + (self.m[0][3] * rhs.m[3][2]);
777 let m30 = (self.m[0][0] * rhs.m[0][3]) + (self.m[0][1] * rhs.m[1][3]) + (self.m[0][2] * rhs.m[2][3]) + (self.m[0][3] * rhs.m[3][3]);
778
779 let m01 = (self.m[1][0] * rhs.m[0][0]) + (self.m[1][1] * rhs.m[1][0]) + (self.m[1][2] * rhs.m[2][0]) + (self.m[1][3] * rhs.m[3][0]);
780 let m11 = (self.m[1][0] * rhs.m[0][1]) + (self.m[1][1] * rhs.m[1][1]) + (self.m[1][2] * rhs.m[2][1]) + (self.m[1][3] * rhs.m[3][1]);
781 let m21 = (self.m[1][0] * rhs.m[0][2]) + (self.m[1][1] * rhs.m[1][2]) + (self.m[1][2] * rhs.m[2][2]) + (self.m[1][3] * rhs.m[3][2]);
782 let m31 = (self.m[1][0] * rhs.m[0][3]) + (self.m[1][1] * rhs.m[1][3]) + (self.m[1][2] * rhs.m[2][3]) + (self.m[1][3] * rhs.m[3][3]);
783
784 let m02 = (self.m[2][0] * rhs.m[0][0]) + (self.m[2][1] * rhs.m[1][0]) + (self.m[2][2] * rhs.m[2][0]) + (self.m[2][3] * rhs.m[3][0]);
785 let m12 = (self.m[2][0] * rhs.m[0][1]) + (self.m[2][1] * rhs.m[1][1]) + (self.m[2][2] * rhs.m[2][1]) + (self.m[2][3] * rhs.m[3][1]);
786 let m22 = (self.m[2][0] * rhs.m[0][2]) + (self.m[2][1] * rhs.m[1][2]) + (self.m[2][2] * rhs.m[2][2]) + (self.m[2][3] * rhs.m[3][2]);
787 let m32 = (self.m[2][0] * rhs.m[0][3]) + (self.m[2][1] * rhs.m[1][3]) + (self.m[2][2] * rhs.m[2][3]) + (self.m[2][3] * rhs.m[3][3]);
788
789 let m03 = (self.m[3][0] * rhs.m[0][0]) + (self.m[3][1] * rhs.m[1][0]) + (self.m[3][2] * rhs.m[2][0]) + (self.m[3][3] * rhs.m[3][0]);
790 let m13 = (self.m[3][0] * rhs.m[0][1]) + (self.m[3][1] * rhs.m[1][1]) + (self.m[3][2] * rhs.m[2][1]) + (self.m[3][3] * rhs.m[3][1]);
791 let m23 = (self.m[3][0] * rhs.m[0][2]) + (self.m[3][1] * rhs.m[1][2]) + (self.m[3][2] * rhs.m[2][2]) + (self.m[3][3] * rhs.m[3][2]);
792 let m33 = (self.m[3][0] * rhs.m[0][3]) + (self.m[3][1] * rhs.m[1][3]) + (self.m[3][2] * rhs.m[2][3]) + (self.m[3][3] * rhs.m[3][3]);
793
794 return Matrix4x4 { m: [
795 [m00, m10, m20, m30],
796 [m01, m11, m21, m31],
797 [m02, m12, m22, m32],
798 [m03, m13, m23, m33],
799 ] };
800 }
801}
802
803impl ops::Add<Matrix4x4> for Matrix4x4 {
804 type Output = Matrix4x4;
805
806 fn add(self, rhs: Matrix4x4) -> Matrix4x4 {
807 let m00 = self.m[0][0] + rhs.m[0][0];
808 let m10 = self.m[1][0] + rhs.m[1][0];
809 let m20 = self.m[2][0] + rhs.m[2][0];
810 let m30 = self.m[3][0] + rhs.m[3][0];
811
812 let m01 = self.m[0][1] + rhs.m[0][1];
813 let m11 = self.m[1][1] + rhs.m[1][1];
814 let m21 = self.m[2][1] + rhs.m[2][1];
815 let m31 = self.m[3][1] + rhs.m[3][1];
816
817 let m02 = self.m[0][2] + rhs.m[0][2];
818 let m12 = self.m[1][2] + rhs.m[1][2];
819 let m22 = self.m[2][2] + rhs.m[2][2];
820 let m32 = self.m[3][2] + rhs.m[3][2];
821
822 let m03 = self.m[0][3] + rhs.m[0][3];
823 let m13 = self.m[1][3] + rhs.m[1][3];
824 let m23 = self.m[2][3] + rhs.m[2][3];
825 let m33 = self.m[3][3] + rhs.m[3][3];
826
827 return Matrix4x4 { m: [
828 [m00, m10, m20, m30],
829 [m01, m11, m21, m31],
830 [m02, m12, m22, m32],
831 [m03, m13, m23, m33],
832 ] };
833 }
834}
835
836impl ops::Sub<Matrix4x4> for Matrix4x4 {
837 type Output = Matrix4x4;
838
839 fn sub(self, rhs: Matrix4x4) -> Matrix4x4 {
840 let m00 = self.m[0][0] - rhs.m[0][0];
841 let m10 = self.m[1][0] - rhs.m[1][0];
842 let m20 = self.m[2][0] - rhs.m[2][0];
843 let m30 = self.m[3][0] - rhs.m[3][0];
844
845 let m01 = self.m[0][1] - rhs.m[0][1];
846 let m11 = self.m[1][1] - rhs.m[1][1];
847 let m21 = self.m[2][1] - rhs.m[2][1];
848 let m31 = self.m[3][1] - rhs.m[3][1];
849
850 let m02 = self.m[0][2] - rhs.m[0][2];
851 let m12 = self.m[1][2] - rhs.m[1][2];
852 let m22 = self.m[2][2] - rhs.m[2][2];
853 let m32 = self.m[3][2] - rhs.m[3][2];
854
855 let m03 = self.m[0][3] - rhs.m[0][3];
856 let m13 = self.m[1][3] - rhs.m[1][3];
857 let m23 = self.m[2][3] - rhs.m[2][3];
858 let m33 = self.m[3][3] - rhs.m[3][3];
859
860 return Matrix4x4 { m: [
861 [m00, m10, m20, m30],
862 [m01, m11, m21, m31],
863 [m02, m12, m22, m32],
864 [m03, m13, m23, m33],
865 ] };
866 }
867}