1 module re.math.transform; 2 3 import re.math; 4 5 struct Transform { 6 private bool _dirty; 7 private Vector3 _position = Vector3(0, 0, 0); 8 private Vector3 _scale = Vector3(1, 1, 1); 9 private float _rotation = 0; 10 private Matrix4 _localToWorldTransform; 11 private Matrix4 _worldToLocalTransform; 12 13 // 2d wrappers 14 15 /// gets 2d position 16 @property Vector2 position2() { 17 auto pos = position; 18 return Vector2(pos.x, pos.y); 19 } 20 21 /// sets 2d position 22 @property Vector2 position2(Vector2 value) { 23 position = Vector3(value.x, value.y, 0); 24 return value; 25 } 26 27 /// gets 2d scale 28 @property Vector2 scale2() { 29 auto scl = scale; 30 return Vector2(scl.x, scl.y); 31 } 32 33 /// sets 2d scale 34 @property Vector2 scale2(Vector2 value) { 35 scale = Vector3(value.x, value.y, 1); 36 return value; 37 } 38 39 // main sub-transforms 40 41 /// gets 3d position 42 @property ref Vector3 position() return { 43 update_transform(); 44 return _position; 45 } 46 47 /// sets 3d position 48 @property Vector3 position(Vector3 value) { 49 _dirty = true; 50 return _position = value; 51 } 52 53 /// gets 3d scale 54 @property Vector3 scale() { 55 update_transform(); 56 return _scale; 57 } 58 59 /// sets 3d scale 60 @property Vector3 scale(Vector3 value) { 61 _dirty = true; 62 return _scale = value; 63 } 64 65 /// gets Z-axis rotation 66 @property float rotation() { 67 update_transform(); 68 return _rotation; 69 } 70 71 /// sets Z-axis rotation 72 @property float rotation(float radians) { 73 _dirty = true; 74 return _rotation = radians; 75 } 76 77 /// gets local-to-world transform 78 @property Matrix4 local_to_world_transform() { 79 update_transform(); 80 return _localToWorldTransform; 81 } 82 83 /// gets world-to-local transform 84 @property Matrix4 world_to_local_transform() { 85 update_transform(); 86 return _worldToLocalTransform; 87 } 88 89 private void update_transform() { 90 if (!_dirty) 91 return; 92 93 // recompute matrices 94 auto translation_mat = raymath.MatrixTranslate(_position.x, _position.y, _position.z); 95 auto rotation_mat = raymath.MatrixRotateZ(_rotation); 96 auto scale_mat = raymath.MatrixScale(_scale.x, _scale.y, _scale.z); 97 98 auto tmp1 = raymath.MatrixMultiply(scale_mat, rotation_mat); 99 auto tmp2 = raymath.MatrixMultiply(tmp1, translation_mat); 100 101 _localToWorldTransform = tmp2; 102 _worldToLocalTransform = raymath.MatrixInvert(_localToWorldTransform); 103 104 _dirty = false; 105 106 } 107 }