1 /** 2 Transforms 3 4 Copyright: 5 Copyright © 2020-2026, Inochi2D Project 6 7 License: 8 $(LINK2 https://github.com/Inochi2D/inochi2d/blob/main/LICENSE, BSD 2-clause License) 9 10 Authors: 11 Luna Nielsen 12 */ 13 module inochi2d.core.math.transform; 14 import inochi2d.core.math; 15 import inochi2d.core; 16 import inochi2d.common; 17 import numath; 18 19 /** 20 A transform 21 */ 22 struct Transform { 23 public: 24 @nogc: 25 26 /** 27 The translation of the transform 28 */ 29 vec3 translation = vec3(0, 0, 0); 30 31 /** 32 The rotation of the transform 33 */ 34 vec3 rotation = vec3(0, 0, 0); 35 36 /** 37 The scale of the transform 38 */ 39 vec2 scale = vec2(1, 1); 40 41 /** 42 Returns the result of 2 transforms multiplied together 43 */ 44 Transform opBinary(string op : "+")(Transform other) @nogc { 45 Transform tnew; 46 tnew.translation = this.translation + other.translation; 47 tnew.rotation = this.rotation + other.rotation; 48 tnew.scale = this.scale * other.scale; 49 return tnew; 50 } 51 52 /** 53 Calculates the basis matrix for this transform. 54 */ 55 Basis matrix() { 56 return Basis( 57 mat4.translation(this.translation) * 58 mat4.zRotation(this.rotation.z) * mat4.yRotation( 59 this.rotation.y) * mat4.xRotation(this.rotation.x) * 60 mat4.scaling(this.scale.x, this.scale.y, 1) 61 ); 62 } 63 64 /** 65 Clears the vector 66 */ 67 void clear() { 68 translation = vec3(0); 69 rotation = vec3(0); 70 scale = vec2(1, 1); 71 } 72 73 /** 74 Serializes the transform. 75 */ 76 void onSerialize(ref DataNode object) { 77 object["trans"] = translation.data.serialize(); 78 object["rot"] = rotation.data.serialize(); 79 object["scale"] = scale.data.serialize(); 80 } 81 82 /** 83 Deserializes a transform from JSON. 84 */ 85 void onDeserialize(ref DataNode object, ref ModelState state) { 86 object.tryGetRef(state, translation.data, "trans", [0, 0, 0]); 87 object.tryGetRef(state, rotation.data, "rot", [0, 0, 0]); 88 object.tryGetRef(state, scale.data, "scale", [1, 1]); 89 } 90 } 91 92 /** 93 A 4x4 basis matrix. 94 */ 95 struct Basis { 96 public: 97 @nogc: 98 99 /** 100 The underlying matrix of the basis 101 */ 102 mat4 matrix = mat4.identity; 103 alias matrix this; 104 105 /** 106 The translation of the basis. 107 */ 108 @property vec3 translation() pure => vec3(matrix.matrix[0][3], matrix.matrix[1][3], matrix.matrix[2][3]); 109 110 /** 111 The scale of the basis 112 */ 113 @property vec2 scale() pure => vec2( 114 vec3(matrix.matrix[0][0], matrix.matrix[1][0], matrix.matrix[2][0]).length(), 115 vec3(matrix.matrix[0][1], matrix.matrix[1][1], matrix.matrix[2][1]).length() 116 ); 117 }