1 /* 2 Copyright © 2020, Luna Nielsen 3 Distributed under the 2-Clause BSD License, see LICENSE file. 4 5 Authors: Luna Nielsen 6 */ 7 module engine.math.transform; 8 import gl3n.linalg; 9 10 /** 11 A 3D transform 12 */ 13 class Transform { 14 private: 15 Transform parent; 16 17 // Generated matrix 18 mat4 g_matrix() { 19 return mat4.translation(position) * rotation.to_matrix!(4, 4) * mat4.scaling(scale.x, scale.y, scale.z); 20 } 21 22 // Generated matrix 23 mat4 g_matrix_ns() { 24 return mat4.translation(position) * rotation.to_matrix!(4, 4); 25 } 26 27 public: 28 29 /** 30 Create a new 3D transform 31 */ 32 this(Transform parent = null) { 33 this(vec3(0, 0, 0), vec3(1, 1, 1), quat.identity, parent); 34 } 35 36 /** 37 Create a new 3D transform 38 */ 39 this(vec3 position, Transform parent = null) { 40 this(position, vec3(1, 1, 1), quat.identity, parent); 41 } 42 43 /** 44 Create a new 3D transform 45 */ 46 this(vec3 position, vec3 scale, Transform parent = null) { 47 this(position, scale, quat.identity, parent); 48 } 49 50 /** 51 Create a new 3D transform 52 */ 53 this(vec3 position, vec3 scale, quat rotation, Transform parent = null) { 54 this.parent = parent; 55 this.position = position; 56 this.scale = scale; 57 this.rotation = rotation; 58 } 59 60 /** 61 Position of transform 62 */ 63 vec3 position; 64 65 /** 66 Origin of transform 67 */ 68 vec3 origin; 69 70 /** 71 Scale of transform 72 */ 73 vec3 scale; 74 75 /** 76 Rotation of transform 77 */ 78 quat rotation; 79 80 /** 81 Changes the transform's parent 82 */ 83 void changeParent(Transform parent) { 84 this.parent = parent; 85 } 86 87 /** 88 Gets the calculated matrix for this transform 89 */ 90 mat4 matrix() { 91 if (parent is null) return g_matrix; 92 return g_matrix*parent.matrix; 93 } 94 95 /** 96 Gets the calculated matrix for this transform without any scaling applied 97 */ 98 mat4 matrixUnscaled() { 99 if (parent is null) return g_matrix_ns; 100 return g_matrix_ns*parent.matrixUnscaled; 101 } 102 } 103 104 /** 105 A 2D transform 106 */ 107 class Transform2D { 108 private: 109 Transform2D parent; 110 111 // Generated matrix 112 mat4 g_matrix() { 113 return 114 mat4.zrotation(rotation) * 115 mat4.scaling(scale.x, scale.y, 1) * 116 mat4.translation(position.x, position.y, 0) * 117 mat4.translation(origin.x, origin.y, 0); 118 } 119 120 public: 121 122 /** 123 Create a new 2D transform 124 */ 125 this(Transform2D parent = null) { 126 this(vec2(0, 0), vec2(0, 0), vec2(1, 1), 0, parent); 127 } 128 129 /** 130 Create a new 2D transform 131 */ 132 this(vec2 position, vec2 origin = vec2(0, 0), vec2 scale = vec2(1, 1), float rotation = 0, Transform2D parent = null) { 133 this.position = position; 134 this.origin = origin; 135 this.scale = scale; 136 this.rotation = rotation; 137 this.parent = parent; 138 } 139 140 /** 141 Position of transform 142 */ 143 vec2 position; 144 145 /** 146 Position of the transform origin 147 */ 148 vec2 origin; 149 150 /** 151 Scale of transform 152 */ 153 vec2 scale; 154 155 /** 156 Rotation of transform 157 */ 158 float rotation; 159 160 /** 161 Changes the transform's parent 162 */ 163 void changeParent(Transform2D parent) { 164 this.parent = parent; 165 } 166 167 /** 168 Gets the calculated matrix for this transform 169 */ 170 mat4 matrix() { 171 if (parent is null) return g_matrix; 172 return g_matrix*parent.matrix; 173 } 174 }