1 module Engine.Transform; 2 3 import Engine.Core; 4 import Engine.Component; 5 import std.stdio; 6 7 8 9 class Transform : Component { 10 11 @property ref vec3 Position() { 12 updateInvert = true; 13 updatePos = true; 14 return position; 15 }; 16 17 @property ref vec3 Scale()() { 18 updateInvert = true; 19 updateScale = true; 20 return scale; 21 }; 22 23 24 @property ref vec3 Rotation()() { 25 updateInvert = true; 26 updateRot = true; 27 return rotation; 28 }; 29 30 vec3 position = vec3(0,0,0); 31 vec3 rotation = vec3(0,0,0); 32 vec3 scale = vec3(1,1,1); 33 34 package mat4 matrix; 35 package mat4 translateMatrix; 36 package mat4 scaleMatrix; 37 package mat4 rotateMatrix; 38 package mat4 invertMatrix; 39 package bool updateInvert = true; 40 41 42 package bool updatePos = true; 43 package bool updateRot = true; 44 package bool updateScale = true; 45 46 this() { 47 48 } 49 50 override void OnComponentAdd() { 51 entity.transform_ = this; 52 } 53 54 mat4 Matrix()() { 55 bool recalculate = false; 56 if (updateRot) { 57 rotateMatrix = mat4.identity.rotatex(rotation.x).rotatey(rotation.y).rotatez(rotation.z); 58 recalculate = true; 59 updateRot = false; 60 } 61 if (updateScale) { 62 scaleMatrix = mat4.identity.scale(scale.x, scale.y, scale.z); 63 recalculate = true; 64 updateScale = false; 65 } 66 if (updatePos) { 67 translateMatrix = mat4.identity.translation(position.x, position.y, position.z); 68 recalculate = true; 69 updatePos = false; 70 } 71 if (recalculate) { 72 matrix = translateMatrix*rotateMatrix*scaleMatrix; 73 updateInvert = true; 74 } 75 return matrix; 76 } 77 78 mat4 InvertedMatrix()() { 79 if (updateInvert) { 80 invertMatrix = Matrix().inverse; 81 } 82 updateInvert = false; 83 return invertMatrix; 84 } 85 86 mat4 Matrix2() { 87 auto r = mat4.identity.rotatex(rotation.x).rotatey(rotation.y).rotatez(rotation.z); 88 auto s = mat4.identity.scale(scale.x, scale.y, scale.z); 89 auto t = mat4.identity.translation(position.x, position.y, position.z); 90 return t*r*s; 91 } 92 93 94 } 95 96 unittest { 97 import std.random; 98 import std.datetime; 99 100 Random gen; 101 gen.seed(0); 102 103 auto transforms = new Transform[100]; 104 for(int i=0;i<transforms.length;i++) { 105 transforms[i] = new Transform(); 106 } 107 108 auto time = benchmark!({ 109 for(int i=0;i<transforms.length;i++) { 110 auto t = transforms[i]; 111 auto r = uniform(0, 100, gen) >= 50; 112 if (r) { 113 114 t.Position.x++; 115 t.updatePos = true; 116 } 117 t.Matrix(); 118 } 119 })(1000); 120 121 writeln(time[0].hnsecs); 122 123 }