1 module hoekjed.dingen.ding; 2 3 import hoekjed; 4 5 struct Houding { 6 Vec!3 _plek = {[0, 0, 0]}; 7 Vec!3 _draai = {[0, 0, 0]}; 8 Vec!3 _grootte = {[1, 1, 1]}; 9 } 10 11 abstract class Ding { 12 protected Wereld _wereld; 13 protected Houding houding; 14 15 protected alias houding this; 16 17 private bool aangepast = true; 18 private bool _ingeschakeld = true; // VERBETER: zoek manier om toe te passen voor elke teken/denk/werkBij stap. 19 20 protected Mat!4 eigenM = Mat!(4).identiteit; 21 protected Mat!4 tekenM = Mat!(4).identiteit; 22 23 Ding ouder; 24 Ding[] kinderen; 25 26 @property Wereld wereld() nothrow { 27 return _wereld; 28 } 29 30 @property Vec!3 plek() nothrow { 31 return _plek; 32 } 33 34 @property Vec!3 draai() nothrow { 35 return _draai; 36 } 37 38 @property Vec!3 grootte() nothrow { 39 return _grootte; 40 } 41 42 @property void plek(Vec!3 waarde) nothrow { 43 _plek = waarde; 44 aangepast = true; 45 } 46 47 @property void draai(Vec!3 waarde) nothrow { 48 _draai = waarde; 49 aangepast = true; 50 } 51 52 @property void grootte(Vec!3 waarde) nothrow { 53 _grootte = waarde; 54 aangepast = true; 55 } 56 57 @property bool ingeschakeld() nothrow { 58 return _ingeschakeld; 59 } 60 61 @property void ingeschakeld(bool waarde) { 62 _ingeschakeld = waarde; 63 wereld.zetIngeschakeld(this, waarde); 64 foreach (Ding kind; kinderen) { 65 kind.ingeschakeld(waarde); 66 } 67 } 68 69 protected abstract void denk(); 70 protected abstract void teken(); 71 72 public static pure Mat!4 krijgEigenM(Houding houding) { 73 Mat!4 eigenM = Mat!(4).identiteit; 74 eigenM[0][0] = houding._grootte.x; 75 eigenM[1][1] = houding._grootte.y; 76 eigenM[2][2] = houding._grootte.z; 77 eigenM = Mat!(4).draaiMz(houding._draai.z).maal(Mat!(4) 78 .draaiMx(houding._draai.x) 79 .maal(Mat!(4).draaiMy(houding._draai.y).maal(eigenM))); 80 // [x, y, z] komen dus overeen met een [theta, psi, rho] stelsel. 81 eigenM[0][3] = houding._plek.x; 82 eigenM[1][3] = houding._plek.y; 83 eigenM[2][3] = houding._plek.z; 84 return eigenM; 85 } 86 87 protected void werkBij(bool ouderAangepast) { 88 if (!ingeschakeld) 89 return; 90 91 assert(!(ouderAangepast && ouder is null)); // Kan ouder niet aanpassen als deze niet bestaat. 92 bool bijgewerkt = aangepast || ouderAangepast; 93 94 if (aangepast) { 95 eigenM = Ding.krijgEigenM(this.houding); 96 aangepast = false; 97 } 98 99 if (bijgewerkt) 100 tekenM = (ouder is null) ? eigenM : ouder.tekenM.maal(eigenM); 101 102 foreach (Ding kind; kinderen) 103 kind.werkBij(bijgewerkt); 104 } 105 106 public void voegKind(Ding kind) { 107 assert(kind !is null); 108 assert(kind.ouder is null); 109 kind.ouder = this; 110 this.kinderen ~= kind; 111 112 if (this._wereld !is null) 113 this._wereld.voegDing(kind); 114 } 115 116 public void verwijderKind(Ding kind) { 117 assert(kind !is null); 118 kinderen.verwijder(kind); 119 kind.ouder = null; 120 if (kind._wereld !is null) 121 kind._wereld.verwijderDing(kind); 122 } 123 124 }