Box.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. /******************************************************************************
  2. Use 'Box' to handle box shapes, Flt type
  3. Use 'BoxD' to handle box shapes, Dbl type
  4. Use 'BoxI' to handle box shapes, Int type
  5. Use 'OBox' to handle oriented box shapes, Flt type (oriented box is a box which can be rotated)
  6. /******************************************************************************/
  7. struct Box // Box Shape
  8. {
  9. Vec min, max;
  10. Box& zero( ) {min.zero(); max.zero(); return T;}
  11. Box& set (C Vec &min, C Vec &max ) {T.min=min; T.max=max; return T;}
  12. Box& set (Flt min_x, Flt min_y, Flt min_z, Flt max_x, Flt max_y, Flt max_z) {min.set(min_x , min_y , min_z ); max.set(max_x , max_y , max_z ); return T;}
  13. Box& set (Flt r, C Vec &pos=VecZero ) {min.set(pos.x-r , pos.y-r , pos.z-r ); max.set(pos.x+r , pos.y+r , pos.z+r ); return T;}
  14. Box& set (Flt w, Flt h, Flt d, C Vec &pos=VecZero ) {min.set(pos.x-w*0.5f, pos.y-h*0.5f, pos.z-d*0.5f); max.set(pos.x+w*0.5f, pos.y+h*0.5f, pos.z+d*0.5f); return T;}
  15. Box& setR(Flt w, Flt h, Flt d, C Vec &pos=VecZero ) {min.set(pos.x-w , pos.y-h*0.5f, pos.z-d*0.5f); max.set(pos.x , pos.y+h*0.5f, pos.z+d*0.5f); return T;} // set right
  16. Box& setL(Flt w, Flt h, Flt d, C Vec &pos=VecZero ) {min.set(pos.x , pos.y-h*0.5f, pos.z-d*0.5f); max.set(pos.x+w , pos.y+h*0.5f, pos.z+d*0.5f); return T;} // set left
  17. Box& setU(Flt w, Flt h, Flt d, C Vec &pos=VecZero ) {min.set(pos.x-w*0.5f, pos.y-h , pos.z-d*0.5f); max.set(pos.x+w*0.5f, pos.y , pos.z+d*0.5f); return T;} // set up
  18. Box& setD(Flt w, Flt h, Flt d, C Vec &pos=VecZero ) {min.set(pos.x-w*0.5f, pos.y , pos.z-d*0.5f); max.set(pos.x+w*0.5f, pos.y+h , pos.z+d*0.5f); return T;} // set down
  19. Box& setF(Flt w, Flt h, Flt d, C Vec &pos=VecZero ) {min.set(pos.x-w*0.5f, pos.y-h*0.5f, pos.z-d ); max.set(pos.x+w*0.5f, pos.y+h*0.5f, pos.z ); return T;} // set forward
  20. Box& setB(Flt w, Flt h, Flt d, C Vec &pos=VecZero ) {min.set(pos.x-w*0.5f, pos.y-h*0.5f, pos.z ); max.set(pos.x+w*0.5f, pos.y+h*0.5f, pos.z+d ); return T;} // set back
  21. Box& operator+=(C Vec &v) {min+=v ; max+=v ; return T;}
  22. Box& operator-=(C Vec &v) {min-=v ; max-=v ; return T;}
  23. Box& operator+=(C Box &b) {min+=b.min; max+=b.max; return T;}
  24. Box& operator-=(C Box &b) {min-=b.min; max-=b.max; return T;}
  25. Box& operator*=( Flt f) {min*=f ; max*=f ; return T;}
  26. Box& operator/=( Flt f) {min/=f ; max/=f ; return T;}
  27. Box& operator*=(C Vec &v) {min*=v ; max*=v ; return T;}
  28. Box& operator/=(C Vec &v) {min/=v ; max/=v ; return T;}
  29. Box& operator*=(C Matrix3 &m); // transform by matrix
  30. Box& operator*=(C Matrix &m); // transform by matrix
  31. Box& operator|=(C Vec &v) {return include(v);}
  32. Box& operator|=(C Box &b) {return include(b);}
  33. Box& operator&=(C Box &b); // intersect
  34. friend Box operator+ (C Box &box, C Vec &v) {return Box(box)+=v;}
  35. friend Box operator- (C Box &box, C Vec &v) {return Box(box)-=v;}
  36. friend Box operator* (C Box &box, Flt f) {return Box(box)*=f;}
  37. friend Box operator/ (C Box &box, Flt f) {return Box(box)/=f;}
  38. friend Box operator* (C Box &box, C Vec &v) {return Box(box)*=v;}
  39. friend Box operator/ (C Box &box, C Vec &v) {return Box(box)/=v;}
  40. friend Box operator* (C Box &box, C Matrix3 &m) {return Box(box)*=m;}
  41. friend Box operator* (C Box &box, C Matrix &m) {return Box(box)*=m;}
  42. friend Box operator| (C Box &a , C Vec &v) {return Box(a )|=v;} // union
  43. friend Box operator| (C Box &a , C Box &b) {return Box(a )|=b;} // union
  44. friend Box operator& (C Box &a , C Box &b) {return Box(a )&=b;} // intersection
  45. // get
  46. Flt w ()C {return max.x-min.x;} // get width
  47. Flt h ()C {return max.y-min.y;} // get height
  48. Flt d ()C {return max.z-min.z;} // get depth
  49. Vec size ()C {return max -min ;} // get size
  50. Flt centerX ()C {return Avg(min.x, max.x);} // get center X
  51. Flt centerY ()C {return Avg(min.y, max.y);} // get center Y
  52. Flt centerZ ()C {return Avg(min.z, max.z);} // get center Z
  53. Vec center ()C {return Vec(centerX(), centerY(), centerZ());} // get center
  54. Vec cornerLDB()C {return Vec( min.x , min.y , min.z );} // get left down back corner
  55. Vec cornerLDF()C {return Vec( min.x , min.y , max.z );} // get left down front corner
  56. Vec cornerLUB()C {return Vec( min.x , max.y , min.z );} // get left up back corner
  57. Vec cornerLUF()C {return Vec( min.x , max.y , max.z );} // get left up front corner
  58. Vec cornerRDB()C {return Vec( max.x , min.y , min.z );} // get right down back corner
  59. Vec cornerRDF()C {return Vec( max.x , min.y , max.z );} // get right down front corner
  60. Vec cornerRUB()C {return Vec( max.x , max.y , min.z );} // get right up back corner
  61. Vec cornerRUF()C {return Vec( max.x , max.y , max.z );} // get right up front corner
  62. Vec left ()C {return Vec( min.x , centerY(), centerZ());} // get left point
  63. Vec right ()C {return Vec( max.x , centerY(), centerZ());} // get right point
  64. Vec down ()C {return Vec(centerX(), min.y , centerZ());} // get down point
  65. Vec up ()C {return Vec(centerX(), max.y , centerZ());} // get up point
  66. Vec back ()C {return Vec(centerX(), centerY(), min.z );} // get back point
  67. Vec forward ()C {return Vec(centerX(), centerY(), max.z );} // get forward point
  68. Flt area ()C; // get surface area
  69. Flt volume ()C {return w()*h()*d() ;} // get volume
  70. Bool validX ()C {return min.x<=max.x;} // if has valid X's
  71. Bool validY ()C {return min.y<=max.y;} // if has valid Y's
  72. Bool validZ ()C {return min.z<=max.z;} // if has valid Z's
  73. Bool valid ()C {return validX() && validY() && validZ();} // if is valid
  74. Rect xz ()C {return Rect(min.x, min.z, max.x, max.z);} // get rectangle in XZ plane
  75. Bool includesX( Flt x)C {return x>=min.x && x<=max.x ;} // if box includes 'x'
  76. Bool includesY( Flt y)C {return y>=min.y && y<=max.y ;} // if box includes 'y'
  77. Bool includesZ( Flt z)C {return z>=min.z && z<=max.z ;} // if box includes 'z'
  78. Bool includes (C Vec &v)C {return includesX(v.x) && includesY(v.y) && includesZ(v.z);} // if box includes vector
  79. Flt lerpX(Flt s )C {return Lerp(min.x, max.x, s) ;} // lerp between min.x and max.x
  80. Flt lerpY(Flt s )C {return Lerp(min.y, max.y, s) ;} // lerp between min.y and max.y
  81. Flt lerpZ(Flt s )C {return Lerp(min.z, max.z, s) ;} // lerp between min.z and max.z
  82. Vec lerp (Flt x, Flt y, Flt z)C {return Vec(lerpX(x), lerpY(y), lerpZ(z));} // lerp inside box
  83. Str asText()C {return S+"Min: "+min+", Max: "+max;} // get text description
  84. // set
  85. Box& setX(Flt x ) {T.min.x=x ; T.max.x=x ; return T;}
  86. Box& setY(Flt y ) {T.min.y=y ; T.max.y=y ; return T;}
  87. Box& setZ(Flt z ) {T.min.z=z ; T.max.z=z ; return T;}
  88. Box& setX(Flt min, Flt max) {T.min.x=min; T.max.x=max; return T;}
  89. Box& setY(Flt min, Flt max) {T.min.y=min; T.max.y=max; return T;}
  90. Box& setZ(Flt min, Flt max) {T.min.z=min; T.max.z=max; return T;}
  91. // operations
  92. Box& extendX ( Flt e); // extend X's by 'e'
  93. Box& extendY ( Flt e); // extend Y's by 'e'
  94. Box& extendZ ( Flt e); // extend Z's by 'e'
  95. Box& extend ( Flt e); // extend by float
  96. Box& extend (C Vec &e); // extend by vector
  97. Box& includeX ( Flt x); // extend box to include 'x'
  98. Box& includeY ( Flt y); // extend box to include 'y'
  99. Box& includeZ ( Flt z); // extend box to include 'z'
  100. Box& include (C Vec &v); // extend box to include vector
  101. Box& include (C Box &b); // extend box to include box
  102. Box& from (C Vec &a , C Vec &b ); // set box from 2 points
  103. Bool from (C Vec *point, Int points ); // set box from an array of points , false on fail (if there are no points)
  104. Bool from (C Vec *point, Int points, C Matrix &matrix); // set box from an array of points transformed by 'matrix', false on fail (if there are no points)
  105. void toCorners( Vec (&v)[8])C; // convert to 8 corner points
  106. Box& mirrorX(); // mirror in X axis
  107. Box& mirrorY(); // mirror in Y axis
  108. Box& mirrorZ(); // mirror in Z axis
  109. #if EE_PRIVATE
  110. void rightToLeft(); // convert from right hand to left hand coordinate system
  111. #endif
  112. // draw
  113. void draw(C Color &color=WHITE, Bool fill=false)C; // this relies on active object matrix which can be set using 'SetMatrix' function
  114. Box() {}
  115. Box(C Vec &vec ) {min=max=vec ;}
  116. Box(C Vec &min, C Vec &max ) {set(min, max );}
  117. Box( Flt min_x, Flt min_y, Flt min_z, Flt max_x, Flt max_y, Flt max_z) {set(min_x, min_y, min_z, max_x, max_y, max_z);}
  118. Box( Flt r, C Vec &pos=VecZero ) {set(r, pos );}
  119. Box( Flt w, Flt h, Flt d, C Vec &pos=VecZero ) {set(w, h, d, pos );}
  120. Box(C Rect &rect );
  121. Box(C Circle &circle );
  122. Box(C Edge &edge );
  123. Box(C Tri &tri );
  124. Box(C Quad &quad );
  125. Box(C BoxD &box );
  126. Box(C BoxI &box );
  127. Box(C OBox &obox );
  128. Box(C Extent &ext );
  129. Box(C Ball &ball );
  130. Box(C Capsule &capsule );
  131. Box(C Tube &tube );
  132. Box(C Torus &torus );
  133. Box(C Cone &cone );
  134. Box(C Pyramid &pyramid );
  135. Box(C Shape &shape );
  136. Box(C MeshBase &mesh );
  137. Box(C MeshPart &mesh );
  138. Box(C Skeleton &skeleton);
  139. };
  140. /******************************************************************************/
  141. // box with helper constructor
  142. struct Box_R : Box { Box_R(Flt w, Flt h, Flt d, C Vec &pos=VecZero) {setR(w, h, d, pos);} }; // right
  143. struct Box_L : Box { Box_L(Flt w, Flt h, Flt d, C Vec &pos=VecZero) {setL(w, h, d, pos);} }; // left
  144. struct Box_U : Box { Box_U(Flt w, Flt h, Flt d, C Vec &pos=VecZero) {setU(w, h, d, pos);} }; // up
  145. struct Box_D : Box { Box_D(Flt w, Flt h, Flt d, C Vec &pos=VecZero) {setD(w, h, d, pos);} }; // down
  146. struct Box_F : Box { Box_F(Flt w, Flt h, Flt d, C Vec &pos=VecZero) {setF(w, h, d, pos);} }; // forward
  147. struct Box_B : Box { Box_B(Flt w, Flt h, Flt d, C Vec &pos=VecZero) {setB(w, h, d, pos);} }; // back
  148. /******************************************************************************/
  149. struct BoxD // Box Shape (double precision)
  150. {
  151. VecD min, max;
  152. BoxD& zero( ) {min.zero(); max.zero(); return T;}
  153. BoxD& set (C VecD &min, C VecD &max ) {T.min=min; T.max=max; return T;}
  154. BoxD& set (Dbl min_x, Dbl min_y, Dbl min_z, Dbl max_x, Dbl max_y, Dbl max_z) {min.set(min_x , min_y , min_z ); max.set(max_x , max_y , max_z ); return T;}
  155. BoxD& set (Dbl r, C VecD &pos=0 ) {min.set(pos.x-r , pos.y-r , pos.z-r ); max.set(pos.x+r , pos.y+r , pos.z+r ); return T;}
  156. BoxD& set (Dbl w, Dbl h, Dbl d, C VecD &pos=0 ) {min.set(pos.x-w*0.5, pos.y-h*0.5, pos.z-d*0.5); max.set(pos.x+w*0.5, pos.y+h*0.5, pos.z+d*0.5); return T;}
  157. BoxD& operator|=(C VecD &v) {return include(v);}
  158. BoxD& operator|=(C BoxD &b) {return include(b);}
  159. BoxD& operator&=(C BoxD &b); // intersect
  160. friend BoxD operator| (C BoxD &a, C VecD &v) {return BoxD(a)|=v;} // union
  161. friend BoxD operator| (C BoxD &a, C BoxD &b) {return BoxD(a)|=b;} // union
  162. friend BoxD operator& (C BoxD &a, C BoxD &b) {return BoxD(a)&=b;} // intersection
  163. // get
  164. Dbl w ()C {return max.x-min.x;} // get width
  165. Dbl h ()C {return max.y-min.y;} // get height
  166. Dbl d ()C {return max.z-min.z;} // get depth
  167. VecD size ()C {return max -min ;} // get size
  168. Dbl centerX()C {return Avg(min.x, max.x);} // get center X
  169. Dbl centerY()C {return Avg(min.y, max.y);} // get center Y
  170. Dbl centerZ()C {return Avg(min.z, max.z);} // get center Z
  171. VecD center ()C {return VecD(centerX(), centerY(), centerZ());} // get center
  172. Dbl area ()C; // get surface area
  173. Dbl volume ()C {return w()*h()*d();} // get volume
  174. Bool validX ()C {return min.x<=max.x;} // if has valid X's
  175. Bool validY ()C {return min.y<=max.y;} // if has valid Y's
  176. Bool validZ ()C {return min.z<=max.z;} // if has valid Z's
  177. Bool valid ()C {return validX() && validY() && validZ();} // if is valid
  178. RectD xz ()C {return RectD(min.x, min.z, max.x, max.z);} // get rectangle in XZ plane
  179. Bool includesX( Dbl x)C {return x>=min.x && x<=max.x ;} // if box includes 'x'
  180. Bool includesY( Dbl y)C {return y>=min.y && y<=max.y ;} // if box includes 'y'
  181. Bool includesZ( Dbl z)C {return z>=min.z && z<=max.z ;} // if box includes 'z'
  182. Bool includes (C VecD &v)C {return includesX(v.x) && includesY(v.y) && includesZ(v.z);} // if box includes vector
  183. // operations
  184. BoxD& extendX ( Dbl e); // extend X's by 'e'
  185. BoxD& extendY ( Dbl e); // extend Y's by 'e'
  186. BoxD& extendZ ( Dbl e); // extend Z's by 'e'
  187. BoxD& extend ( Dbl e); // extend by float
  188. BoxD& extend (C VecD &e); // extend by vector
  189. BoxD& includeX( Dbl x); // extend box to include 'x'
  190. BoxD& includeY( Dbl y); // extend box to include 'y'
  191. BoxD& includeZ( Dbl z); // extend box to include 'z'
  192. BoxD& include (C VecD &v); // extend box to include vector
  193. BoxD& include (C BoxD &b); // extend box to include box
  194. BoxD& from (C VecD &a, C VecD &b); // set box from 2 points
  195. Bool from (C VecD *v, Int n); // set box from 'n' 'v' points, false on fail
  196. BoxD() {}
  197. BoxD(C VecD &vec ) {min=max=vec ;}
  198. BoxD(C VecD &min, C VecD &max ) {set(min, max );}
  199. BoxD( Dbl min_x, Dbl min_y, Dbl min_z, Dbl max_x, Dbl max_y, Dbl max_z) {set(min_x, min_y, min_z, max_x, max_y, max_z);}
  200. BoxD( Dbl r, C VecD &pos=0 ) {set(r, pos );}
  201. BoxD( Dbl w, Dbl h, Dbl d, C VecD &pos=0 ) {set(w, h, d, pos );}
  202. BoxD(C EdgeD &edge);
  203. BoxD(C TriD &tri );
  204. BoxD(C QuadD &quad);
  205. BoxD(C Box &box );
  206. BoxD(C BallM &ball);
  207. };
  208. /******************************************************************************/
  209. struct BoxI // Box Shape (integer)
  210. {
  211. VecI min, max;
  212. BoxI& zero( ) {min.zero(); max.zero(); return T;}
  213. BoxI& set (C VecI &min, C VecI &max ) {T.min=min; T.max=max; return T;}
  214. BoxI& set (Int min_x, Int min_y, Int min_z, Int max_x, Int max_y, Int max_z) {min.set(min_x, min_y, min_z); max.set(max_x, max_y, max_z); return T;}
  215. BoxI& operator|=(C VecI &v) {return include(v);}
  216. BoxI& operator|=(C BoxI &b) {return include(b);}
  217. BoxI& operator&=(C BoxI &b); // intersect
  218. friend BoxI operator| (C BoxI &a, C VecI &v) {return BoxI(a)|=v;} // union
  219. friend BoxI operator| (C BoxI &a, C BoxI &b) {return BoxI(a)|=b;} // union
  220. friend BoxI operator& (C BoxI &a, C BoxI &b) {return BoxI(a)&=b;} // intersection
  221. // get
  222. Int w ()C {return max.x-min.x;} // get width
  223. Int h ()C {return max.y-min.y;} // get height
  224. Int d ()C {return max.z-min.z;} // get depth
  225. VecI size ()C {return max -min ;} // get size
  226. Int volume ()C {return w() * h() * d() ;} // get volume
  227. Long volumeL()C {return Long(w())*Long(h())*Long(d());} // get volume (64-bit Long precision)
  228. RectI xz ()C {return RectI(min.x, min.z, max.x, max.z);} // get rectangle in XZ plane
  229. Bool includesX( Int x)C {return x>=min.x && x<=max.x ;} // if box includes 'x'
  230. Bool includesY( Int y)C {return y>=min.y && y<=max.y ;} // if box includes 'y'
  231. Bool includesZ( Int z)C {return z>=min.z && z<=max.z ;} // if box includes 'z'
  232. Bool includes (C VecI &v)C {return includesX(v.x) && includesY(v.y) && includesZ(v.z);} // if box includes vector
  233. Int centerXI()C {return AvgI(min.x, max.x);} // get center X (Int)
  234. Flt centerXF()C {return AvgF(min.x, max.x);} // get center X (Flt)
  235. Int centerYI()C {return AvgI(min.y, max.y);} // get center Y (Int)
  236. Flt centerYF()C {return AvgF(min.y, max.y);} // get center Y (Flt)
  237. Int centerZI()C {return AvgI(min.z, max.z);} // get center Z (Int)
  238. Flt centerZF()C {return AvgF(min.z, max.z);} // get center Z (Flt)
  239. VecI centerI ()C {return VecI(centerXI(), centerYI(), centerZI());} // get center (VecI)
  240. Vec centerF ()C {return Vec (centerXF(), centerYF(), centerZF());} // get center (Vec )
  241. Str asText()C {return S+"Min: "+min+", Max: "+max;} // get text description
  242. // set
  243. BoxI& setX(Int x ) {T.min.x=x ; T.max.x=x ; return T;}
  244. BoxI& setY(Int y ) {T.min.y=y ; T.max.y=y ; return T;}
  245. BoxI& setZ(Int z ) {T.min.z=z ; T.max.z=z ; return T;}
  246. BoxI& setX(Int min, Int max) {T.min.x=min; T.max.x=max; return T;}
  247. BoxI& setY(Int min, Int max) {T.min.y=min; T.max.y=max; return T;}
  248. BoxI& setZ(Int min, Int max) {T.min.z=min; T.max.z=max; return T;}
  249. // operations
  250. BoxI& extendX ( Int e); // extend X
  251. BoxI& extendY ( Int e); // extend Y
  252. BoxI& extendZ ( Int e); // extend Z
  253. BoxI& extend ( Int e); // extend by float
  254. BoxI& extend (C VecI &e); // extend by vector
  255. BoxI& includeX( Int x); // extend box to include 'x'
  256. BoxI& includeY( Int y); // extend box to include 'y'
  257. BoxI& includeZ( Int z); // extend box to include 'z'
  258. BoxI& include (C VecI &v); // extend box to include vector
  259. BoxI& include (C BoxI &b); // extend box to include box
  260. BoxI() {}
  261. BoxI(C VecI &vec ) {min=max=vec ;}
  262. BoxI(C VecI &min, C VecI &max ) {set(min, max );}
  263. BoxI(Int min_x, Int min_y, Int min_z, Int max_x, Int max_y, Int max_z) {set(min_x, min_y, min_z, max_x, max_y, max_z);}
  264. };
  265. /******************************************************************************/
  266. struct OBox // Oriented Box (Box with matrix transformation, can be rotated)
  267. {
  268. Box box ;
  269. Matrix matrix; // must be normalized
  270. OBox& operator+=(C Vec &v) {matrix.pos+=v; return T;}
  271. OBox& operator-=(C Vec &v) {matrix.pos-=v; return T;}
  272. OBox& operator*=( Flt f);
  273. OBox& operator/=( Flt f);
  274. OBox& operator*=(C Vec &v);
  275. OBox& operator/=(C Vec &v);
  276. OBox& operator*=(C Matrix3 &m) {return mul(m);}
  277. OBox& operator/=(C Matrix3 &m) {return div(m);}
  278. OBox& operator*=(C Matrix &m) {return mul(m);}
  279. OBox& operator/=(C Matrix &m) {return div(m);}
  280. friend OBox operator+ (C OBox &obox, C Vec &v) {return OBox(obox)+=v;}
  281. friend OBox operator- (C OBox &obox, C Vec &v) {return OBox(obox)-=v;}
  282. friend OBox operator* (C OBox &obox, Flt f) {return OBox(obox)*=f;}
  283. friend OBox operator/ (C OBox &obox, Flt f) {return OBox(obox)/=f;}
  284. friend OBox operator* (C OBox &obox, C Vec &v) {return OBox(obox)*=v;}
  285. friend OBox operator/ (C OBox &obox, C Vec &v) {return OBox(obox)/=v;}
  286. friend OBox operator* (C OBox &obox, C Matrix3 &m) {return OBox(obox)*=m;}
  287. friend OBox operator/ (C OBox &obox, C Matrix3 &m) {return OBox(obox)/=m;}
  288. friend OBox operator* (C OBox &obox, C Matrix &m) {return OBox(obox)*=m;}
  289. friend OBox operator/ (C OBox &obox, C Matrix &m) {return OBox(obox)/=m;}
  290. // get / set
  291. Vec center()C {return box.center()*matrix;} // get center
  292. Flt area ()C {return box.area () ;} // get surface area
  293. Flt volume()C {return box.volume() ;} // get volume
  294. Str asText()C {return box.asText();} // get text description
  295. // operations
  296. OBox& extend( Flt e ); // extend
  297. OBox& mul (C Matrix3 &matrix, Bool normalized=false); // transform by 'matrix', if you know that the matrix is normalized then set 'normalized=true' for more performance
  298. OBox& mul (C Matrix &matrix, Bool normalized=false); // transform by 'matrix', if you know that the matrix is normalized then set 'normalized=true' for more performance
  299. OBox& div (C Matrix3 &matrix, Bool normalized=false); // transform by 'matrix', if you know that the matrix is normalized then set 'normalized=true' for more performance
  300. OBox& div (C Matrix &matrix, Bool normalized=false); // transform by 'matrix', if you know that the matrix is normalized then set 'normalized=true' for more performance
  301. void toCorners(Vec (&v)[8])C; // convert to 8 corner points
  302. OBox& mirrorX(); // mirror in X axis
  303. OBox& mirrorY(); // mirror in Y axis
  304. OBox& mirrorZ(); // mirror in Z axis
  305. // draw
  306. void draw(C Color &color=WHITE, Bool fill=false)C; // this relies on active object matrix which can be set using 'SetMatrix' function
  307. OBox() {}
  308. OBox(C Box &box, C Matrix &matrix=MatrixIdentity) {T.box=box; T.matrix=matrix;} // 'matrix' must be normalized
  309. OBox(C Torus &torus);
  310. };
  311. /******************************************************************************/
  312. struct Extent // similar to 'Box' however it operates on center position and extents in each axis
  313. {
  314. Vec ext; // extents in each axis
  315. union
  316. {
  317. Vec pos ; // center position
  318. Vec center; // center position
  319. };
  320. Extent& zero( ) {ext.zero(); pos.zero(); return T;}
  321. Extent& set (C Vec &ext, C Vec &pos=VecZero) {T.ext=ext; T.pos=pos; return T;}
  322. Extent& operator+=(C Vec &v) { pos+=v ; return T;}
  323. Extent& operator-=(C Vec &v) { pos-=v ; return T;}
  324. Extent& operator+=(C Extent &e) {ext+=e.ext; pos+=e.pos; return T;}
  325. Extent& operator-=(C Extent &e) {ext-=e.ext; pos-=e.pos; return T;}
  326. Extent& operator*=( Flt f) {ext*=f ; pos*=f ; return T;}
  327. Extent& operator/=( Flt f) {ext/=f ; pos/=f ; return T;}
  328. Extent& operator*=(C Vec &v) {ext*=v ; pos*=v ; return T;}
  329. Extent& operator/=(C Vec &v) {ext/=v ; pos/=v ; return T;}
  330. Extent& operator*=(C Matrix3 &m); // transform by matrix
  331. Extent& operator*=(C Matrix &m); // transform by matrix
  332. Extent& operator|=(C Vec &v) {return include(v);}
  333. Extent& operator|=(C Box &b) {return include(b);}
  334. friend Extent operator+ (C Extent &ext, C Vec &v) {return Extent(ext)+=v;}
  335. friend Extent operator- (C Extent &ext, C Vec &v) {return Extent(ext)-=v;}
  336. friend Extent operator* (C Extent &ext, Flt f) {return Extent(ext)*=f;}
  337. friend Extent operator/ (C Extent &ext, Flt f) {return Extent(ext)/=f;}
  338. friend Extent operator* (C Extent &ext, C Vec &v) {return Extent(ext)*=v;}
  339. friend Extent operator/ (C Extent &ext, C Vec &v) {return Extent(ext)/=v;}
  340. friend Extent operator* (C Extent &ext, C Matrix3 &m) {return Extent(ext)*=m;}
  341. friend Extent operator* (C Extent &ext, C Matrix &m) {return Extent(ext)*=m;}
  342. // get
  343. Flt minX()C {return pos.x-ext.x;} // get minimum position X
  344. Flt minY()C {return pos.y-ext.y;} // get minimum position Y
  345. Flt minZ()C {return pos.z-ext.z;} // get minimum position Z
  346. Flt maxX()C {return pos.x+ext.x;} // get maximum position X
  347. Flt maxY()C {return pos.y+ext.y;} // get maximum position Y
  348. Flt maxZ()C {return pos.z+ext.z;} // get maximum position Z
  349. Vec min ()C {return pos -ext ;} // get minimum position
  350. Vec max ()C {return pos +ext ;} // get maximum position
  351. Vec left ()C {return Vec( minX(), center.y , center.z );} // get left point
  352. Vec right ()C {return Vec( maxX(), center.y , center.z );} // get right point
  353. Vec down ()C {return Vec(center.x , minY(), center.z );} // get down point
  354. Vec up ()C {return Vec(center.x , maxY(), center.z );} // get up point
  355. Vec back ()C {return Vec(center.x , center.y , minZ());} // get back point
  356. Vec forward()C {return Vec(center.x , center.y , maxZ());} // get forward point
  357. Flt w()C {return ext.x*2;} // get width
  358. Flt h()C {return ext.y*2;} // get height
  359. Flt d()C {return ext.z*2;} // get depth
  360. Vec size()C {return ext*2;} // get size
  361. Flt volume()C {return ext.mul()*8;} // get volume "w()*h()*d()"
  362. Rect rectXZ()C {return Rect(minX(), minZ(), maxX(), maxZ());} // get rectangle in XZ plane
  363. Bool includesX( Flt x)C {return Abs(x-pos.x)<=ext.x ;} // if extent includes 'x'
  364. Bool includesY( Flt y)C {return Abs(y-pos.y)<=ext.y ;} // if extent includes 'y'
  365. Bool includesZ( Flt z)C {return Abs(z-pos.z)<=ext.z ;} // if extent includes 'z'
  366. Bool includes (C Vec &v)C {return includesX(v.x) && includesY(v.y) && includesZ(v.z);} // if extent includes vector
  367. Str asText()C {return S+"Pos: "+pos+", Ext: "+ext;} // get text description
  368. // operations
  369. Extent& extendX( Flt e) {ext.x+=e; return T;} // extend X by 'e'
  370. Extent& extendY( Flt e) {ext.y+=e; return T;} // extend Y by 'e'
  371. Extent& extendZ( Flt e) {ext.z+=e; return T;} // extend Z by 'e'
  372. Extent& extend ( Flt e) {ext +=e; return T;} // extend by float
  373. Extent& extend (C Vec &e) {ext +=e; return T;} // extend by vector
  374. Extent& includeX( Flt x); // extend to include 'x'
  375. Extent& includeY( Flt y); // extend to include 'y'
  376. Extent& includeZ( Flt z); // extend to include 'z'
  377. Extent& include (C Vec &v); // extend to include vector
  378. Extent& include (C Box &b); // extend to include box
  379. Bool from (C Vec *point, Int points) ; // set from an array of points, false on fail (if there are no points)
  380. void toCorners(Vec (&v)[8] )C; // convert to 8 corner points
  381. Extent& mirrorX() {CHS(pos.x); return T;} // mirror in X axis
  382. Extent& mirrorY() {CHS(pos.y); return T;} // mirror in Y axis
  383. Extent& mirrorZ() {CHS(pos.z); return T;} // mirror in Z axis
  384. #if EE_PRIVATE
  385. void rightToLeft(); // convert from right hand to left hand coordinate system
  386. #endif
  387. // draw
  388. void draw(C Color &color=WHITE, Bool fill=false)C; // this relies on active object matrix which can be set using 'SetMatrix' function
  389. Extent() {}
  390. Extent( Flt ext, C Vec &pos=VecZero) {set(ext, pos);}
  391. Extent(C Vec &ext, C Vec &pos=VecZero) {set(ext, pos);}
  392. Extent(C Box &box);
  393. };
  394. /******************************************************************************/
  395. struct Boxes // Boxes, allows space partitioning divided into "cells.x * cells.y * cells.z" cells (sub-boxes)
  396. {
  397. VecI cells; // number of cells in each dimension
  398. Vec size ; // size of a single cell
  399. Box box ; // box covering all cells
  400. // set
  401. void set(C Box &box, C VecI &cells); // set partitioning according to 'box' space divided into "cells.x * cells.y * cells.z" cells
  402. void set(C Box &box, Int elms ); // set partitioning according to 'box' space divided into approximately "elms" cells, 'cells' will be calculated automatically
  403. // get
  404. VecI coords(C Vec &pos )C; // get cell coordinates of 'pos' world position, coordinates are automatically clamped to 0..cells-1 range
  405. BoxI coords(C Box &box )C; // get cell coordinates of 'box' world box , coordinates are automatically clamped to 0..cells-1 range
  406. Box getBox(C VecI &cell)C; // get world box from 'cell' coordinates
  407. Int index (C VecI &pos )C {return pos.x + cells.x*(pos.y + cells.y*pos.z);} // get cell index of cell position
  408. Int index (C Vec &pos )C {return index(coords(pos)); } // get cell index of world position
  409. Int num ( )C {return cells.x*cells.y*cells.z; } // get total number of cells
  410. // draw
  411. void draw(C Color &color=WHITE)C; // this relies on active object matrix which can be set using 'SetMatrix' function
  412. Boxes() {}
  413. Boxes(C Box &box, C VecI &cells) {set(box, cells);}
  414. Boxes(C Box &box, Int elms ) {set(box, elms );}
  415. };
  416. /******************************************************************************/
  417. inline BoxI Round(C Box &b) {return BoxI(Round(b.min.x), Round(b.min.y), Round(b.min.z), Round(b.max.x), Round(b.max.y), Round(b.max.z));}
  418. Box Avg(C Box &a, C Box &b);
  419. // distance
  420. Flt Dist (C Vec &point, C Box &box ); // distance between point and a box
  421. Flt Dist (C Vec &point, C OBox &obox ); // distance between point and a box
  422. Flt Dist (C Vec &point, C Extent &ext ); // distance between point and an extent
  423. Flt Dist2(C Vec &point, C Box &box ); // squared distance between point and a box
  424. Flt Dist2(C Vec &point, C OBox &obox ); // squared distance between point and a box
  425. Flt Dist2(C Vec &point, C Extent &ext ); // squared distance between point and an extent
  426. Flt Dist (C Edge &edge , C Box &box ); // distance between edge and a box
  427. Flt Dist (C Edge &edge , C OBox &obox ); // distance between edge and a box
  428. Flt Dist (C Box &a , C Box &b ); // distance between box and a box
  429. Flt Dist (C Box &box , C Plane &plane); // distance between box and a plane
  430. Flt Dist (C OBox &obox , C Plane &plane); // distance between box and a plane
  431. // if cuts
  432. inline Bool Cuts(C Vec &point, C Box &box ) {return box.includes(point);} // if point cuts a box
  433. inline Bool Cuts(C VecD &point, C BoxD &box ) {return box.includes(point);} // if point cuts a box
  434. inline Bool Cuts(C VecI &point, C BoxI &box ) {return box.includes(point);} // if point cuts a box
  435. inline Bool Cuts(C Vec &point, C Extent &ext ) {return ext.includes(point);} // if point cuts an extent
  436. Bool Cuts(C Vec &point, C OBox &obox); // if point cuts a box
  437. Bool Cuts(C Edge &edge , C Box &box ); // if edge cuts a box
  438. Bool Cuts(C Edge &edge , C OBox &obox); // if edge cuts a box
  439. Bool Cuts(C Rect &rect , C Box &box ); // if rectangle cuts a rectangle (from box)
  440. Bool Cuts(C Box &a , C Box &b ); // if box cuts a box
  441. Bool Cuts(C Box &box , C OBox &obox); // if box cuts a box
  442. Bool Cuts(C OBox &a , C OBox &b ); // if box cuts a box
  443. Bool Cuts(C BoxD &a , C BoxD &b ); // if box cuts a box
  444. Bool Cuts(C BoxI &a , C BoxI &b ); // if box cuts a box
  445. Bool Cuts(C Extent &a , C Extent &b ); // if extent cuts an extent
  446. Bool CutsEps(C Box &a, C Box &b); // if box cuts a box, epsilon=EPS
  447. Bool CutsEps(C BoxD &a, C BoxD &b); // if box cuts a box, epsilon=EPSD
  448. Bool Inside (C Box &a, C Box &b); // if 'a' is fully inside 'b'
  449. Bool Inside (C BoxD &a, C BoxD &b); // if 'a' is fully inside 'b'
  450. Bool Inside (C BoxI &a, C BoxI &b); // if 'a' is fully inside 'b'
  451. Bool InsideEps(C Box &a, C Box &b); // if 'a' is fully inside 'b', with EPS epsilon tolerance
  452. // sweep
  453. Bool SweepPointBox(C Vec &point, C Vec &move, C Box &box , Flt *hit_frac=null, Vec *hit_normal=null, Vec *hit_pos=null); // if moving point cuts through a static box
  454. Bool SweepPointBox(C Vec &point, C Vec &move, C OBox &obox, Flt *hit_frac=null, Vec *hit_normal=null, Vec *hit_pos=null); // if moving point cuts through a static oriented box
  455. Bool SweepPointBox(C Vec &point, C Vec &move, C Extent &ext , Flt *hit_frac=null, Vec *hit_normal=null, Vec *hit_pos=null); // if moving point cuts through a static extent
  456. /******************************************************************************/