Box.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. Extent::Extent(C Box &box) {ext=box.size()*0.5f; pos=box.min+ext;}
  6. Box ::Box (C Rect &rect ) {min.set(rect.min , 0); max.set(rect.max , 0);}
  7. Box ::Box (C Circle &circle ) {min.set(circle.pos-circle.r, 0); max.set(circle.pos+circle.r, 0);}
  8. Box ::Box (C Edge &edge ) {from(edge.p, Elms(edge.p));}
  9. BoxD::BoxD(C EdgeD &edge ) {from(edge.p, Elms(edge.p));}
  10. Box ::Box (C Tri &tri ) {from(tri .p, Elms(tri .p));}
  11. BoxD::BoxD(C TriD &tri ) {from(tri .p, Elms(tri .p));}
  12. Box ::Box (C Quad &quad ) {from(quad.p, Elms(quad.p));}
  13. BoxD::BoxD(C QuadD &quad ) {from(quad.p, Elms(quad.p));}
  14. Box ::Box (C BoxD &box ) {min=box.min; max=box.max;}
  15. BoxD::BoxD(C Box &box ) {min=box.min; max=box.max;}
  16. Box ::Box (C BoxI &box ) {min=box.min; max=box.max;}
  17. Box ::Box (C Extent &ext ) {min=ext.min(); max=ext.max();}
  18. Box ::Box (C Ball &ball ) {set (ball.r, ball.pos);}
  19. BoxD::BoxD(C BallM &ball ) {set (ball.r, ball.pos);}
  20. Box ::Box (C Capsule &capsule) {from(capsule.pointU(), capsule.pointD()); extend (capsule.r);}
  21. Box ::Box (C Tube &tube ) {from(tube .pointU(), tube .pointD()); extendX(CosSin(tube .up.x)*tube.r ).extendY(CosSin(tube .up.y)*tube.r ).extendZ(CosSin(tube .up.z)*tube.r );}
  22. Box ::Box (C Torus &torus ) {T=torus.pos; extendX(CosSin(torus.up.x)*torus.R+torus.r).extendY(CosSin(torus.up.y)*torus.R+torus.r).extendZ(CosSin(torus.up.z)*torus.R+torus.r);}
  23. Box ::Box (C Pyramid &pyramid) {Vec points[5]; pyramid.toCorners(points); from(points, Elms(points));}
  24. Box ::Box (C OBox &obox )
  25. {
  26. Vec size=obox.box.size();
  27. min=max=obox.box.min*obox.matrix;
  28. if(obox.matrix.x.x>0)max.x+=obox.matrix.x.x*size.x;else min.x+=obox.matrix.x.x*size.x;
  29. if(obox.matrix.x.y>0)max.y+=obox.matrix.x.y*size.x;else min.y+=obox.matrix.x.y*size.x;
  30. if(obox.matrix.x.z>0)max.z+=obox.matrix.x.z*size.x;else min.z+=obox.matrix.x.z*size.x;
  31. if(obox.matrix.y.x>0)max.x+=obox.matrix.y.x*size.y;else min.x+=obox.matrix.y.x*size.y;
  32. if(obox.matrix.y.y>0)max.y+=obox.matrix.y.y*size.y;else min.y+=obox.matrix.y.y*size.y;
  33. if(obox.matrix.y.z>0)max.z+=obox.matrix.y.z*size.y;else min.z+=obox.matrix.y.z*size.y;
  34. if(obox.matrix.z.x>0)max.x+=obox.matrix.z.x*size.z;else min.x+=obox.matrix.z.x*size.z;
  35. if(obox.matrix.z.y>0)max.y+=obox.matrix.z.y*size.z;else min.y+=obox.matrix.z.y*size.z;
  36. if(obox.matrix.z.z>0)max.z+=obox.matrix.z.z*size.z;else min.z+=obox.matrix.z.z*size.z;
  37. }
  38. Box::Box(C Cone &cone)
  39. {
  40. T=cone.pos ; // bottom position
  41. Box top=cone.pos+cone.up*cone.h; // top position
  42. Flt csx=CosSin(cone.up.x), csy=CosSin(cone.up.y), csz=CosSin(cone.up.z);
  43. extendX(csx*cone.r_low ).extendY(csy*cone.r_low ).extendZ(csz*cone.r_low );
  44. top.extendX(csx*cone.r_high).extendY(csy*cone.r_high).extendZ(csz*cone.r_high);
  45. T|=top;
  46. }
  47. Box::Box(C Shape &shape)
  48. {
  49. switch(shape.type)
  50. {
  51. default : zero() ; break;
  52. case SHAPE_POINT : T=shape.point ; break;
  53. case SHAPE_EDGE : T=shape.edge ; break;
  54. case SHAPE_RECT : T=shape.rect ; break;
  55. case SHAPE_BOX : T=shape.box ; break;
  56. case SHAPE_OBOX : T=shape.obox ; break;
  57. case SHAPE_CIRCLE : T=shape.circle ; break;
  58. case SHAPE_BALL : T=shape.ball ; break;
  59. case SHAPE_CAPSULE: T=shape.capsule; break;
  60. case SHAPE_TUBE : T=shape.tube ; break;
  61. case SHAPE_TORUS : T=shape.torus ; break;
  62. case SHAPE_CONE : T=shape.cone ; break;
  63. case SHAPE_PYRAMID: T=shape.pyramid; break;
  64. }
  65. }
  66. Box::Box(C MeshBase &mesh ) {from(mesh.vtx.pos(), mesh.vtxs());}
  67. Box::Box(C MeshPart &mesh ) {mesh.getBox(T);}
  68. Box::Box(C Skeleton &skeleton)
  69. {
  70. if(!skeleton.bones.elms())zero();else
  71. {
  72. T=skeleton.bones.last().pos;
  73. REP(skeleton.bones.elms()-1)include(skeleton.bones[i].pos);
  74. }
  75. }
  76. OBox::OBox(C Torus &torus)
  77. {
  78. box .set (Vec(-torus.R-torus.r, -torus.r, -torus.R-torus.r), Vec(torus.R+torus.r, torus.r, torus.R+torus.r));
  79. matrix.setPosUp(torus.pos, torus.up);
  80. }
  81. /******************************************************************************/
  82. Box& Box::operator&=(C Box &b)
  83. {
  84. if(b.min.x>min.x)min.x=b.min.x; if(b.max.x<max.x)max.x=b.max.x;
  85. if(b.min.y>min.y)min.y=b.min.y; if(b.max.y<max.y)max.y=b.max.y;
  86. if(b.min.z>min.z)min.z=b.min.z; if(b.max.z<max.z)max.z=b.max.z;
  87. return T;
  88. }
  89. BoxD& BoxD::operator&=(C BoxD &b)
  90. {
  91. if(b.min.x>min.x)min.x=b.min.x; if(b.max.x<max.x)max.x=b.max.x;
  92. if(b.min.y>min.y)min.y=b.min.y; if(b.max.y<max.y)max.y=b.max.y;
  93. if(b.min.z>min.z)min.z=b.min.z; if(b.max.z<max.z)max.z=b.max.z;
  94. return T;
  95. }
  96. BoxI& BoxI::operator&=(C BoxI &b)
  97. {
  98. if(b.min.x>min.x)min.x=b.min.x; if(b.max.x<max.x)max.x=b.max.x;
  99. if(b.min.y>min.y)min.y=b.min.y; if(b.max.y<max.y)max.y=b.max.y;
  100. if(b.min.z>min.z)min.z=b.min.z; if(b.max.z<max.z)max.z=b.max.z;
  101. return T;
  102. }
  103. OBox& OBox::operator*=(C Flt f) {box*=f; matrix.pos*=f; return T;}
  104. OBox& OBox::operator/=(C Flt f) {box/=f; matrix.pos/=f; return T;}
  105. /******************************************************************************/
  106. OBox& OBox::operator*=(C Vec &v)
  107. {
  108. Flt d=(matrix.x*v).length(); box.min.x*=d; box.max.x*=d;
  109. d=(matrix.y*v).length(); box.min.y*=d; box.max.y*=d;
  110. d=(matrix.z*v).length(); box.min.z*=d; box.max.z*=d;
  111. matrix.pos*=v;
  112. return T;
  113. }
  114. OBox& OBox::operator/=(C Vec &v)
  115. {
  116. Flt d=(matrix.x/v).length(); box.min.x*=d; box.max.x*=d;
  117. d=(matrix.y/v).length(); box.min.y*=d; box.max.y*=d;
  118. d=(matrix.z/v).length(); box.min.z*=d; box.max.z*=d;
  119. matrix.pos/=v;
  120. return T;
  121. }
  122. /******************************************************************************/
  123. Box& Box::operator*=(C Matrix3 &matrix)
  124. {
  125. Vec v[8]; toCorners(v);
  126. Transform(v, matrix, Elms(v));
  127. from (v, Elms(v));
  128. return T;
  129. }
  130. Box& Box::operator*=(C Matrix &matrix)
  131. {
  132. Vec v[8]; toCorners(v);
  133. Transform(v, matrix, Elms(v));
  134. from (v, Elms(v));
  135. return T;
  136. }
  137. Extent& Extent::operator*=(C Matrix3 &matrix)
  138. {
  139. Vec v[8]; toCorners(v);
  140. Transform(v, matrix, Elms(v));
  141. from (v, Elms(v));
  142. return T;
  143. }
  144. Extent& Extent::operator*=(C Matrix &matrix)
  145. {
  146. Vec v[8]; toCorners(v);
  147. Transform(v, matrix, Elms(v));
  148. from (v, Elms(v));
  149. return T;
  150. }
  151. OBox& OBox::mul(C Matrix3 &matrix, Bool normalized)
  152. {
  153. T.matrix*=matrix;
  154. if(!normalized)
  155. {
  156. Flt x=T.matrix.x.normalize(); box.min.x*=x; box.max.x*=x;
  157. Flt y=T.matrix.y.normalize(); box.min.y*=y; box.max.y*=y;
  158. Flt z=T.matrix.z.normalize(); box.min.z*=z; box.max.z*=z;
  159. }
  160. return T;
  161. }
  162. OBox& OBox::mul(C Matrix &matrix, Bool normalized)
  163. {
  164. T.matrix*=matrix;
  165. if(!normalized)
  166. {
  167. Flt x=T.matrix.x.normalize(); box.min.x*=x; box.max.x*=x;
  168. Flt y=T.matrix.y.normalize(); box.min.y*=y; box.max.y*=y;
  169. Flt z=T.matrix.z.normalize(); box.min.z*=z; box.max.z*=z;
  170. }
  171. return T;
  172. }
  173. OBox& OBox::div(C Matrix3 &matrix, Bool normalized)
  174. {
  175. if(normalized)T.matrix.divNormalized(matrix);else
  176. {
  177. T.matrix.div(matrix);
  178. Flt x=T.matrix.x.normalize(); box.min.x*=x; box.max.x*=x;
  179. Flt y=T.matrix.y.normalize(); box.min.y*=y; box.max.y*=y;
  180. Flt z=T.matrix.z.normalize(); box.min.z*=z; box.max.z*=z;
  181. }
  182. return T;
  183. }
  184. OBox& OBox::div(C Matrix &matrix, Bool normalized)
  185. {
  186. if(normalized)T.matrix.divNormalized(matrix);else
  187. {
  188. T.matrix.div(matrix);
  189. Flt x=T.matrix.x.normalize(); box.min.x*=x; box.max.x*=x;
  190. Flt y=T.matrix.y.normalize(); box.min.y*=y; box.max.y*=y;
  191. Flt z=T.matrix.z.normalize(); box.min.z*=z; box.max.z*=z;
  192. }
  193. return T;
  194. }
  195. /******************************************************************************/
  196. Flt Box::area()C
  197. {
  198. Flt w=T.w(),
  199. h=T.h(),
  200. d=T.d();
  201. return 2*(w*h + h*d + w*d);
  202. }
  203. Dbl BoxD::area()C
  204. {
  205. Dbl w=T.w(),
  206. h=T.h(),
  207. d=T.d();
  208. return 2*(w*h + h*d + w*d);
  209. }
  210. /******************************************************************************/
  211. Box & Box ::extendX( Flt e) {min.x-=e; max.x+=e; return T;}
  212. BoxD& BoxD::extendX( Dbl e) {min.x-=e; max.x+=e; return T;}
  213. BoxI& BoxI::extendX( Int e) {min.x-=e; max.x+=e; return T;}
  214. Box & Box ::extendY( Flt e) {min.y-=e; max.y+=e; return T;}
  215. BoxD& BoxD::extendY( Dbl e) {min.y-=e; max.y+=e; return T;}
  216. BoxI& BoxI::extendY( Int e) {min.y-=e; max.y+=e; return T;}
  217. Box & Box ::extendZ( Flt e) {min.z-=e; max.z+=e; return T;}
  218. BoxD& BoxD::extendZ( Dbl e) {min.z-=e; max.z+=e; return T;}
  219. BoxI& BoxI::extendZ( Int e) {min.z-=e; max.z+=e; return T;}
  220. Box & Box ::extend ( Flt e) {min -=e; max +=e; return T;}
  221. BoxD& BoxD::extend ( Dbl e) {min -=e; max +=e; return T;}
  222. BoxI& BoxI::extend ( Int e) {min -=e; max +=e; return T;}
  223. Box & Box ::extend (C Vec &e) {min -=e; max +=e; return T;}
  224. BoxD& BoxD::extend (C VecD &e) {min -=e; max +=e; return T;}
  225. BoxI& BoxI::extend (C VecI &e) {min -=e; max +=e; return T;}
  226. OBox& OBox::extend ( Flt e) {box.extend(e); return T;}
  227. /******************************************************************************/
  228. Box & Box ::includeX(Flt x) {if(x<min.x)min.x=x;else if(x>max.x)max.x=x; return T;}
  229. BoxD& BoxD::includeX(Dbl x) {if(x<min.x)min.x=x;else if(x>max.x)max.x=x; return T;}
  230. BoxI& BoxI::includeX(Int x) {if(x<min.x)min.x=x;else if(x>max.x)max.x=x; return T;}
  231. Box & Box ::includeY(Flt y) {if(y<min.y)min.y=y;else if(y>max.y)max.y=y; return T;}
  232. BoxD& BoxD::includeY(Dbl y) {if(y<min.y)min.y=y;else if(y>max.y)max.y=y; return T;}
  233. BoxI& BoxI::includeY(Int y) {if(y<min.y)min.y=y;else if(y>max.y)max.y=y; return T;}
  234. Box & Box ::includeZ(Flt z) {if(z<min.z)min.z=z;else if(z>max.z)max.z=z; return T;}
  235. BoxD& BoxD::includeZ(Dbl z) {if(z<min.z)min.z=z;else if(z>max.z)max.z=z; return T;}
  236. BoxI& BoxI::includeZ(Int z) {if(z<min.z)min.z=z;else if(z>max.z)max.z=z; return T;}
  237. /******************************************************************************/
  238. Box& Box::include(C Vec &v)
  239. {
  240. Flt x=v.x, y=v.y, z=v.z;
  241. if(x<min.x)min.x=x;else if(x>max.x)max.x=x;
  242. if(y<min.y)min.y=y;else if(y>max.y)max.y=y;
  243. if(z<min.z)min.z=z;else if(z>max.z)max.z=z;
  244. return T;
  245. }
  246. BoxD& BoxD::include(C VecD &v)
  247. {
  248. Dbl x=v.x, y=v.y, z=v.z;
  249. if(x<min.x)min.x=x;else if(x>max.x)max.x=x;
  250. if(y<min.y)min.y=y;else if(y>max.y)max.y=y;
  251. if(z<min.z)min.z=z;else if(z>max.z)max.z=z;
  252. return T;
  253. }
  254. BoxI& BoxI::include(C VecI &v)
  255. {
  256. Int x=v.x, y=v.y, z=v.z;
  257. if(x<min.x)min.x=x;else if(x>max.x)max.x=x;
  258. if(y<min.y)min.y=y;else if(y>max.y)max.y=y;
  259. if(z<min.z)min.z=z;else if(z>max.z)max.z=z;
  260. return T;
  261. }
  262. /******************************************************************************/
  263. Box& Box::include(C Box &b)
  264. {
  265. if(b.min.x<min.x)min.x=b.min.x; if(b.max.x>max.x)max.x=b.max.x;
  266. if(b.min.y<min.y)min.y=b.min.y; if(b.max.y>max.y)max.y=b.max.y;
  267. if(b.min.z<min.z)min.z=b.min.z; if(b.max.z>max.z)max.z=b.max.z;
  268. return T;
  269. }
  270. BoxD& BoxD::include(C BoxD &b)
  271. {
  272. if(b.min.x<min.x)min.x=b.min.x; if(b.max.x>max.x)max.x=b.max.x;
  273. if(b.min.y<min.y)min.y=b.min.y; if(b.max.y>max.y)max.y=b.max.y;
  274. if(b.min.z<min.z)min.z=b.min.z; if(b.max.z>max.z)max.z=b.max.z;
  275. return T;
  276. }
  277. BoxI& BoxI::include(C BoxI &b)
  278. {
  279. if(b.min.x<min.x)min.x=b.min.x; if(b.max.x>max.x)max.x=b.max.x;
  280. if(b.min.y<min.y)min.y=b.min.y; if(b.max.y>max.y)max.y=b.max.y;
  281. if(b.min.z<min.z)min.z=b.min.z; if(b.max.z>max.z)max.z=b.max.z;
  282. return T;
  283. }
  284. Extent& Extent::includeX( Flt x) {T=Box(T).includeX(x); return T;}
  285. Extent& Extent::includeY( Flt y) {T=Box(T).includeY(y); return T;}
  286. Extent& Extent::includeZ( Flt z) {T=Box(T).includeZ(z); return T;}
  287. Extent& Extent::include (C Vec &v) {T=Box(T).include (v); return T;}
  288. Extent& Extent::include (C Box &b) {T=Box(T).include (b); return T;}
  289. /******************************************************************************/
  290. Box& Box::from(C Vec &a, C Vec &b)
  291. {
  292. MinMax(a.x, b.x, min.x, max.x);
  293. MinMax(a.y, b.y, min.y, max.y);
  294. MinMax(a.z, b.z, min.z, max.z);
  295. return T;
  296. }
  297. BoxD& BoxD::from(C VecD &a, C VecD &b)
  298. {
  299. MinMax(a.x, b.x, min.x, max.x);
  300. MinMax(a.y, b.y, min.y, max.y);
  301. MinMax(a.z, b.z, min.z, max.z);
  302. return T;
  303. }
  304. Bool Box::from(C Vec *point, Int points)
  305. {
  306. if(MinMax(point, points, min, max))return true; zero(); return false;
  307. }
  308. Bool BoxD::from(C VecD *point, Int points)
  309. {
  310. if(MinMax(point, points, min, max))return true; zero(); return false;
  311. }
  312. Bool Extent::from(C Vec *point, Int points)
  313. {
  314. Box box; if(MinMax(point, points, box.min, box.max)){T=box; return true;} zero(); return false;
  315. }
  316. Bool Box::from(C Vec *point, Int points, C Matrix &matrix)
  317. {
  318. if(points<=0 || !point){zero(); return false;}
  319. for(min=max=(*point++)*matrix, points--; --points>=0; )
  320. {
  321. Vec v=(*point++)*matrix;
  322. if(v.x<min.x)min.x=v.x;else if(v.x>max.x)max.x=v.x;
  323. if(v.y<min.y)min.y=v.y;else if(v.y>max.y)max.y=v.y;
  324. if(v.z<min.z)min.z=v.z;else if(v.z>max.z)max.z=v.z;
  325. }
  326. return true;
  327. }
  328. void Box::toCorners(Vec (&v)[8])C
  329. {
  330. FREP(8)v[i].set((i&1) ? max.x : min.x,
  331. (i&2) ? max.y : min.y,
  332. (i&4) ? max.z : min.z);
  333. }
  334. void Extent::toCorners(Vec (&v)[8])C
  335. {
  336. FREP(8)v[i].set((i&1) ? pos.x+ext.x : pos.x-ext.x,
  337. (i&2) ? pos.y+ext.y : pos.y-ext.y,
  338. (i&4) ? pos.z+ext.z : pos.z-ext.z);
  339. }
  340. void OBox::toCorners(Vec (&v)[8])C
  341. {
  342. #if 0
  343. box.toCorners(v);
  344. Transform(v, matrix, Elms(v));
  345. #else // optimized
  346. Vec x=matrix.x*box.w(),
  347. y=matrix.y*box.h(),
  348. z=matrix.z*box.d();
  349. v[0|0|0]=box.min; v[0]*=matrix;
  350. v[1|0|0]=v[0]; v[1]+=x; // +x
  351. v[0|2|0]=v[0]; v[2]+=y; // +y
  352. v[0|0|4]=v[0]; v[4]+=z; // +z
  353. v[1|2|0]=v[1]; v[3]+=y; // +x+y
  354. v[1|0|4]=v[1]; v[5]+=z; // +x+z
  355. v[0|2|4]=v[2]; v[6]+=z; // +y+z
  356. v[1|2|4]=v[3]; v[7]+=z; // +x+y+z
  357. #endif
  358. }
  359. Box& Box::mirrorX() {setX(-max.x, -min.x); return T;}
  360. Box& Box::mirrorY() {setY(-max.y, -min.y); return T;}
  361. Box& Box::mirrorZ() {setZ(-max.z, -min.z); return T;}
  362. OBox& OBox::mirrorX() {CHS(matrix.pos.x); CHS(matrix.x.y); CHS(matrix.x.z); CHS(matrix.y.x); CHS(matrix.z.x); CHS(box.min.x); CHS(box.max.x); Swap(box.min.x, box.max.x); return T;}
  363. OBox& OBox::mirrorY() {CHS(matrix.pos.y); CHS(matrix.y.x); CHS(matrix.y.z); CHS(matrix.x.y); CHS(matrix.z.y); CHS(box.min.y); CHS(box.max.y); Swap(box.min.y, box.max.y); return T;}
  364. OBox& OBox::mirrorZ() {CHS(matrix.pos.z); CHS(matrix.z.x); CHS(matrix.z.y); CHS(matrix.x.z); CHS(matrix.y.z); CHS(box.min.z); CHS(box.max.z); Swap(box.min.z, box.max.z); return T;}
  365. /******************************************************************************/
  366. void Box ::rightToLeft() {min.rightToLeft(); max.rightToLeft(); Swap(min.x, max.x); Swap(min.z, max.z);}
  367. void Extent::rightToLeft() {ext.swapYZ(); pos.rightToLeft();}
  368. /******************************************************************************/
  369. // DRAW
  370. /******************************************************************************/
  371. void Box::draw(C Color &color, Bool fill)C
  372. {
  373. VI.color(color);
  374. if(fill)
  375. {
  376. VI.quad(cornerRUF(), cornerLUF(), cornerLDF(), cornerRDF()); // forward
  377. VI.quad(cornerLUB(), cornerRUB(), cornerRDB(), cornerLDB()); // back
  378. VI.quad(cornerRUB(), cornerRUF(), cornerRDF(), cornerRDB()); // right
  379. VI.quad(cornerLUF(), cornerLUB(), cornerLDB(), cornerLDF()); // left
  380. VI.quad(cornerLUF(), cornerRUF(), cornerRUB(), cornerLUB()); // up
  381. VI.quad(cornerLDB(), cornerRDB(), cornerRDF(), cornerLDF()); // down
  382. }else
  383. {
  384. Vec a, b;
  385. a.x=min.x; b.x=max.x; REP(4){a.y=b.y=((i&1) ? min.y : max.y); a.z=b.z=((i&2) ? min.z : max.z); VI.line(a, b);}
  386. a.y=min.y; b.y=max.y; REP(4){a.x=b.x=((i&1) ? min.x : max.x); a.z=b.z=((i&2) ? min.z : max.z); VI.line(a, b);}
  387. a.z=min.z; b.z=max.z; REP(4){a.x=b.x=((i&1) ? min.x : max.x); a.y=b.y=((i&2) ? min.y : max.y); VI.line(a, b);}
  388. }
  389. VI.end();
  390. }
  391. /******************************************************************************/
  392. void OBox::draw(C Color &color, Bool fill)C
  393. {
  394. Vec v[8]; toCorners(v);
  395. VI.color(color);
  396. if(fill)
  397. {
  398. VI.quad(v[1|2|4], v[0|2|4], v[0|0|4], v[1|0|4]); // forward
  399. VI.quad(v[0|2|0], v[1|2|0], v[1|0|0], v[0|0|0]); // back
  400. VI.quad(v[1|2|0], v[1|2|4], v[1|0|4], v[1|0|0]); // right
  401. VI.quad(v[0|2|4], v[0|2|0], v[0|0|0], v[0|0|4]); // left
  402. VI.quad(v[0|2|4], v[1|2|4], v[1|2|0], v[0|2|0]); // up
  403. VI.quad(v[0|0|0], v[1|0|0], v[1|0|4], v[0|0|4]); // down
  404. }else
  405. {
  406. REP(4)VI.line(v[0| i ], v[4| i ]);
  407. REP(4)VI.line(v[0|(i<<1) ], v[1|(i<<1) ]);
  408. REP(4)VI.line(v[0|(i &1)|((i&2)?4:0)], v[2|(i &1)|((i&2)?4:0)]);
  409. }
  410. VI.end();
  411. }
  412. /******************************************************************************/
  413. void Extent::draw(C Color &color, Bool fill)C {Box(T).draw(color, fill);}
  414. /******************************************************************************/
  415. // BOXES
  416. /******************************************************************************/
  417. void Boxes::set(C Box &box, C VecI &cells)
  418. {
  419. T.box =box;
  420. T.cells.x=Max(cells.x, 1);
  421. T.cells.y=Max(cells.y, 1);
  422. T.cells.z=Max(cells.z, 1);
  423. T.size =box.size()/T.cells;
  424. }
  425. void Boxes::set(C Box &box, Int elms)
  426. {
  427. VecI cells;
  428. Vec size=box.size();
  429. Int i0=size.minI(), i1=(i0+1)%3, i2=(i0+2)%3; if(size.c[i2]<size.c[i1])Swap(i1, i2); // 'size' indexes sorted from smallest to biggest
  430. Flt volume=size.mul(),
  431. mul =Cbrt(elms/volume); // = 1/avg_cell_size
  432. Int smallest=cells.c[i0]=Max(1, Round(size.c[i0]*mul)); // set number of cells in the smallest dimension
  433. Flt area=size.c[i1]*size.c[i2]; // calculate area of remaining 2 dimensions (middle and biggest)
  434. mul =Sqrt(elms/(smallest*area)); // = 1/avg_cell_size
  435. Int middle=cells.c[i1]=Max(1, Round(size.c[i1]*mul)); // set number of cells in the middle dimension
  436. cells.c[i2]=Max(1, DivRound(elms, smallest*middle)); // set number of cells in the biggest dimension
  437. set(box, cells);
  438. }
  439. VecI Boxes::coords(C Vec &pos)C
  440. {
  441. VecI O=Trunc((pos-box.min)/size); // use 'Trunc' because it's faster and we're not interested in negative indexes
  442. Clamp(O.x, 0, cells.x-1);
  443. Clamp(O.y, 0, cells.y-1);
  444. Clamp(O.z, 0, cells.z-1);
  445. return O;
  446. }
  447. BoxI Boxes::coords(C Box &box)C
  448. {
  449. return BoxI(coords(box.min),
  450. coords(box.max));
  451. }
  452. Box Boxes::getBox(C VecI &cell)C
  453. {
  454. Box O;
  455. O.min=T.box.min+size*cell;
  456. O.max= O.min+size;
  457. return O;
  458. }
  459. void Boxes::draw(C Color &color)C
  460. {
  461. if(color.a)
  462. {
  463. VI.color(color);
  464. REPD(z, cells.z+1)
  465. {
  466. Flt fz=box.min.z+z*size.z;
  467. REPD(y, cells.y+1)
  468. {
  469. Flt fy=box.min.y+y*size.y;
  470. VI.line(Vec(box.min.x, fy, fz), Vec(box.max.x, fy, fz));
  471. }
  472. REPD(x, cells.x+1)
  473. {
  474. Flt fx=box.min.x+x*size.x;
  475. VI.line(Vec(fx, box.min.y, fz), Vec(fx, box.max.y, fz));
  476. }
  477. }
  478. REPD(y, cells.y+1)
  479. {
  480. Flt fy=box.min.y+y*size.y;
  481. REPD(x, cells.x+1)
  482. {
  483. Flt fx=box.min.x+x*size.x;
  484. VI.line(Vec(fx, fy, box.min.z), Vec(fx, fy, box.max.z));
  485. }
  486. }
  487. VI.end();
  488. }
  489. }
  490. /******************************************************************************/
  491. Box Avg(C Box &a, C Box &b) {return Box(Avg(a.min, b.min), Avg(a.max, b.max));}
  492. /******************************************************************************/
  493. Flt Dist(C Vec &point, C Box &box)
  494. {
  495. #define S box.min
  496. #define L box.max
  497. if(point.x>L.x) // right
  498. {
  499. if(point.y>L.y) // up
  500. {
  501. if(point.z>L.z)return Dist(point, box.cornerRUF()); // ruf corner
  502. if(point.z<S.z)return Dist(point, box.cornerRUB()); // rub corner
  503. return Dist(Vec2(point.x, point.y), Vec2(L.x, L.y)); // ru edge
  504. }
  505. if(point.y<S.y) // down
  506. {
  507. if(point.z>L.z)return Dist(point, box.cornerRDF()); // rdf corner
  508. if(point.z<S.z)return Dist(point, box.cornerRDB()); // rdb corner
  509. return Dist(Vec2(point.x, point.y), Vec2(L.x, S.y)); // rd edge
  510. }
  511. if(point.z>L.z)return Dist(Vec2(point.x, point.z), Vec2(L.x, L.z)); // rf edge
  512. if(point.z<S.z)return Dist(Vec2(point.x, point.z), Vec2(L.x, S.z)); // rb edge
  513. return point.x-L.x; // r side
  514. }
  515. if(point.x<S.x) // left
  516. {
  517. if(point.y>L.y) // up
  518. {
  519. if(point.z>L.z)return Dist(point, box.cornerLUF()); // luf corner
  520. if(point.z<S.z)return Dist(point, box.cornerLUB()); // lub corner
  521. return Dist(Vec2(point.x, point.y), Vec2(S.x, L.y)); // lu edge
  522. }
  523. if(point.y<S.y) // down
  524. {
  525. if(point.z>L.z)return Dist(point, box.cornerLDF()); // ldf corner
  526. if(point.z<S.z)return Dist(point, box.cornerLDB()); // ldb corner
  527. return Dist(Vec2(point.x, point.y), Vec2(S.x, S.y)); // ld edge
  528. }
  529. if(point.z>L.z)return Dist(Vec2(point.x, point.z), Vec2(S.x, L.z)); // lf edge
  530. if(point.z<S.z)return Dist(Vec2(point.x, point.z), Vec2(S.x, S.z)); // lb edge
  531. return S.x-point.x; // l side
  532. }
  533. if(point.y>L.y) // up
  534. {
  535. if(point.z>L.z)return Dist(Vec2(point.y, point.z), Vec2(L.y, L.z)); // uf edge
  536. if(point.z<S.z)return Dist(Vec2(point.y, point.z), Vec2(L.y, S.z)); // ub edge
  537. return point.y-L.y; // u side
  538. }
  539. if(point.y<S.y) // down
  540. {
  541. if(point.z>L.z)return Dist(Vec2(point.y, point.z), Vec2(S.y, L.z)); // df edge
  542. if(point.z<S.z)return Dist(Vec2(point.y, point.z), Vec2(S.y, S.z)); // db edge
  543. return S.y-point.y; // d side
  544. }
  545. if(point.z>L.z)return point.z-L.z; // f side
  546. if(point.z<S.z)return S.z-point.z; // b side
  547. return 0; // inside
  548. #undef S
  549. #undef L
  550. }
  551. /******************************************************************************/
  552. Flt Dist2(C Vec &point, C Box &box)
  553. {
  554. #define S box.min
  555. #define L box.max
  556. if(point.x>L.x) // right
  557. {
  558. if(point.y>L.y) // up
  559. {
  560. if(point.z>L.z)return Dist2(point, box.cornerRUF()); // ruf corner
  561. if(point.z<S.z)return Dist2(point, box.cornerRUB()); // rub corner
  562. return Dist2(Vec2(point.x, point.y), Vec2(L.x, L.y)); // ru edge
  563. }
  564. if(point.y<S.y) // down
  565. {
  566. if(point.z>L.z)return Dist2(point, box.cornerRDF()); // rdf corner
  567. if(point.z<S.z)return Dist2(point, box.cornerRDB()); // rdb corner
  568. return Dist2(Vec2(point.x, point.y), Vec2(L.x, S.y)); // rd edge
  569. }
  570. if(point.z>L.z)return Dist2(Vec2(point.x, point.z), Vec2(L.x, L.z)); // rf edge
  571. if(point.z<S.z)return Dist2(Vec2(point.x, point.z), Vec2(L.x, S.z)); // rb edge
  572. return Sqr(point.x-L.x); // r side
  573. }
  574. if(point.x<S.x) // left
  575. {
  576. if(point.y>L.y) // up
  577. {
  578. if(point.z>L.z)return Dist2(point, box.cornerLUF()); // luf corner
  579. if(point.z<S.z)return Dist2(point, box.cornerLUB()); // lub corner
  580. return Dist2(Vec2(point.x, point.y), Vec2(S.x, L.y)); // lu edge
  581. }
  582. if(point.y<S.y) // down
  583. {
  584. if(point.z>L.z)return Dist2(point, box.cornerLDF()); // ldf corner
  585. if(point.z<S.z)return Dist2(point, box.cornerLDB()); // ldb corner
  586. return Dist2(Vec2(point.x, point.y), Vec2(S.x, S.y)); // ld edge
  587. }
  588. if(point.z>L.z)return Dist2(Vec2(point.x, point.z), Vec2(S.x, L.z)); // lf edge
  589. if(point.z<S.z)return Dist2(Vec2(point.x, point.z), Vec2(S.x, S.z)); // lb edge
  590. return Sqr(S.x-point.x); // l side
  591. }
  592. if(point.y>L.y) // up
  593. {
  594. if(point.z>L.z)return Dist2(Vec2(point.y, point.z), Vec2(L.y, L.z)); // uf edge
  595. if(point.z<S.z)return Dist2(Vec2(point.y, point.z), Vec2(L.y, S.z)); // ub edge
  596. return Sqr(point.y-L.y); // u side
  597. }
  598. if(point.y<S.y) // down
  599. {
  600. if(point.z>L.z)return Dist2(Vec2(point.y, point.z), Vec2(S.y, L.z)); // df edge
  601. if(point.z<S.z)return Dist2(Vec2(point.y, point.z), Vec2(S.y, S.z)); // db edge
  602. return Sqr(S.y-point.y); // d side
  603. }
  604. if(point.z>L.z)return Sqr(point.z-L.z); // f side
  605. if(point.z<S.z)return Sqr(S.z-point.z); // b side
  606. return 0; // inside
  607. #undef S
  608. #undef L
  609. }
  610. /******************************************************************************/
  611. Flt Dist(C Vec &point, C Extent &ext)
  612. {
  613. return Dist(Max(0, Abs(point.x-ext.pos.x)-ext.ext.x),
  614. Max(0, Abs(point.y-ext.pos.y)-ext.ext.y),
  615. Max(0, Abs(point.z-ext.pos.z)-ext.ext.z));
  616. }
  617. Flt Dist2(C Vec &point, C Extent &ext)
  618. {
  619. return Dist2(Max(0, Abs(point.x-ext.pos.x)-ext.ext.x),
  620. Max(0, Abs(point.y-ext.pos.y)-ext.ext.y),
  621. Max(0, Abs(point.z-ext.pos.z)-ext.ext.z));
  622. }
  623. /******************************************************************************/
  624. Flt Dist(C Edge &edge, C Box &box)
  625. {
  626. Edge edge_list[2][3*3*3];
  627. Int edges=0, list_cur=0;
  628. // put edge to the list
  629. edge_list[list_cur][edges++]=edge-box.center();
  630. FREPD(d, 3) // 3 dimensions (x, y, z)
  631. {
  632. Int new_edges=0;
  633. Flt r =(box.max.c[d]-box.min.c[d])*0.5f; // d-dimension radius (d=0 -> width/2, d=1 -> height/2, d=2 -> depth/2)
  634. REP(edges) // try to split all edges by 2 axes: -r, +r
  635. {
  636. Edge &edge=edge_list[list_cur][i];
  637. if(edge.p[0].c[d]>edge.p[1].c[d])edge.reverse(); // sort so they are in "growing" order
  638. Bool left_cut=false, right_cut=false;
  639. Vec left, right;
  640. if(edge.p[0].c[d]<-r) // cut left outside piece
  641. {
  642. if(edge.p[1].c[d]<=-r)edge_list[list_cur^1][new_edges++]=edge;else // fully fits
  643. {
  644. left_cut=true;
  645. Flt f=(-r-edge.p[0].c[d])/(edge.p[1].c[d]-edge.p[0].c[d]);
  646. edge_list[list_cur^1][new_edges++].set(edge.p[0], left=edge.lerp(f));
  647. }
  648. }
  649. if(edge.p[1].c[d]>r) // cut right outside piece
  650. {
  651. if(edge.p[0].c[d]>=r)edge_list[list_cur^1][new_edges++]=edge;else // fully fits
  652. {
  653. right_cut=true;
  654. Flt f=(r-edge.p[0].c[d])/(edge.p[1].c[d]-edge.p[0].c[d]);
  655. edge_list[list_cur^1][new_edges++].set(right=edge.lerp(f), edge.p[1]);
  656. }
  657. }
  658. if(edge.p[0].c[d]<=r && edge.p[1].c[d]>=-r)
  659. edge_list[list_cur^1][new_edges++].set(left_cut ? left : edge.p[0], right_cut ? right : edge.p[1]);
  660. }
  661. // swap lists
  662. list_cur^=1;
  663. edges=new_edges;
  664. // warp
  665. REP(edges)
  666. {
  667. Edge &edge=edge_list[list_cur][i];
  668. ABS(edge.p[0].c[d]); MAX(edge.p[0].c[d]-=r, 0.0f);
  669. ABS(edge.p[1].c[d]); MAX(edge.p[1].c[d]-=r, 0.0f);
  670. }
  671. }
  672. Flt dist=FLT_MAX;
  673. REP(edges)MIN(dist, Dist(VecZero, edge_list[list_cur][i]));
  674. return dist;
  675. }
  676. /******************************************************************************/
  677. Flt Dist(C Box &a, C Box &b)
  678. {
  679. return Dist(Max(0, Abs(a.centerX()-b.centerX())-(a.w()+b.w())*0.5f),
  680. Max(0, Abs(a.centerY()-b.centerY())-(a.h()+b.h())*0.5f),
  681. Max(0, Abs(a.centerZ()-b.centerZ())-(a.d()+b.d())*0.5f));
  682. }
  683. /******************************************************************************/
  684. Flt Dist(C Box &box, C Plane &plane)
  685. {
  686. Vec test((plane.normal.x<=0) ? box.max.x : box.min.x,
  687. (plane.normal.y<=0) ? box.max.y : box.min.y,
  688. (plane.normal.z<=0) ? box.max.z : box.min.z);
  689. return Dist(test, plane);
  690. }
  691. Flt Dist(C OBox &obox, C Plane &plane)
  692. {
  693. Flt n, d=Dist(obox.box.min*obox.matrix, plane);
  694. n=Dot(obox.matrix.x, plane.normal); if(n<0)d+=n*obox.box.w();
  695. n=Dot(obox.matrix.y, plane.normal); if(n<0)d+=n*obox.box.h();
  696. n=Dot(obox.matrix.z, plane.normal); if(n<0)d+=n*obox.box.d();
  697. return d;
  698. }
  699. /******************************************************************************/
  700. Bool Cuts(C Edge &edge, C Box &box)
  701. {
  702. if(Cuts(edge.p[0], box)
  703. || Cuts(edge.p[1], box))return true;
  704. Flt frac;
  705. Vec point=edge.p [0],
  706. move =edge.delta();
  707. if(point.x<box.min.x && edge.p[1].x>=box.min.x){frac=(box.min.x-point.x)/move.x; if( box.includesY(point.y+move.y*frac) && box.includesZ(point.z+move.z*frac))return true;}else
  708. if(point.x>box.max.x && edge.p[1].x<=box.max.x){frac=(box.max.x-point.x)/move.x; if( box.includesY(point.y+move.y*frac) && box.includesZ(point.z+move.z*frac))return true;}
  709. if(point.y<box.min.y && edge.p[1].y>=box.min.y){frac=(box.min.y-point.y)/move.y; if(box.includesX(point.x+move.x*frac) && box.includesZ(point.z+move.z*frac))return true;}else
  710. if(point.y>box.max.y && edge.p[1].y<=box.max.y){frac=(box.max.y-point.y)/move.y; if(box.includesX(point.x+move.x*frac) && box.includesZ(point.z+move.z*frac))return true;}
  711. if(point.z<box.min.z && edge.p[1].z>=box.min.z){frac=(box.min.z-point.z)/move.z; if(box.includesX(point.x+move.x*frac) && box.includesY(point.y+move.y*frac) )return true;}else
  712. if(point.z>box.max.z && edge.p[1].z<=box.max.z){frac=(box.max.z-point.z)/move.z; if(box.includesX(point.x+move.x*frac) && box.includesY(point.y+move.y*frac) )return true;}
  713. return false;
  714. }
  715. /******************************************************************************/
  716. Bool Cuts(C Rect &rect, C Box &box)
  717. {
  718. return rect.min.x<=box.max.x && rect.max.x>=box.min.x
  719. && rect.min.y<=box.max.y && rect.max.y>=box.min.y;
  720. }
  721. Bool Cuts(C Box &a, C Box &b)
  722. {
  723. return a.min.x<=b.max.x && a.max.x>=b.min.x
  724. && a.min.y<=b.max.y && a.max.y>=b.min.y
  725. && a.min.z<=b.max.z && a.max.z>=b.min.z;
  726. }
  727. Bool Cuts(C BoxD &a, C BoxD &b)
  728. {
  729. return a.min.x<=b.max.x && a.max.x>=b.min.x
  730. && a.min.y<=b.max.y && a.max.y>=b.min.y
  731. && a.min.z<=b.max.z && a.max.z>=b.min.z;
  732. }
  733. Bool Cuts(C BoxI &a, C BoxI &b)
  734. {
  735. return a.min.x<=b.max.x && a.max.x>=b.min.x
  736. && a.min.y<=b.max.y && a.max.y>=b.min.y
  737. && a.min.z<=b.max.z && a.max.z>=b.min.z;
  738. }
  739. /******************************************************************************/
  740. Bool Cuts(C Extent &a, C Extent &b)
  741. {
  742. return Abs(a.pos.x-b.pos.x)<=(a.ext.x+b.ext.x)
  743. && Abs(a.pos.y-b.pos.y)<=(a.ext.y+b.ext.y)
  744. && Abs(a.pos.z-b.pos.z)<=(a.ext.z+b.ext.z);
  745. }
  746. /******************************************************************************/
  747. Bool Cuts(C Box &box, C OBox &obox)
  748. {
  749. Vec ae= box.size()*0.5f, // a extents
  750. be=obox.box.size()*0.5f, // b extents
  751. bo=obox.center()-box.center(); // b offset (b center relative to a center)
  752. Matrix3 m=obox.matrix;
  753. m.x.abs();
  754. m.y.abs();
  755. m.z.abs();
  756. if(Abs(bo.x) > ae.x + be.x*m.x.x + be.y*m.y.x + be.z*m.z.x)return false; // a.x axis
  757. if(Abs(bo.y) > ae.y + be.x*m.x.y + be.y*m.y.y + be.z*m.z.y)return false; // a.y axis
  758. if(Abs(bo.z) > ae.z + be.x*m.x.z + be.y*m.y.z + be.z*m.z.z)return false; // a.z axis
  759. if(Abs(bo.x*obox.matrix.x.x + bo.y*obox.matrix.x.y + bo.z*obox.matrix.x.z) > be.x + ae.x*m.x.x + ae.y*m.x.y + ae.z*m.x.z)return false; // b.x axis
  760. if(Abs(bo.x*obox.matrix.y.x + bo.y*obox.matrix.y.y + bo.z*obox.matrix.y.z) > be.y + ae.x*m.y.x + ae.y*m.y.y + ae.z*m.y.z)return false; // b.x axis
  761. if(Abs(bo.x*obox.matrix.z.x + bo.y*obox.matrix.z.y + bo.z*obox.matrix.z.z) > be.z + ae.x*m.z.x + ae.y*m.z.y + ae.z*m.z.z)return false; // b.x axis
  762. if(Abs(bo.z*obox.matrix.x.y - bo.y*obox.matrix.x.z) > ae.y*m.x.z + ae.z*m.x.y + be.y*m.z.x + be.z*m.y.x)return false; // a.x X b.x axis
  763. if(Abs(bo.z*obox.matrix.y.y - bo.y*obox.matrix.y.z) > ae.y*m.y.z + ae.z*m.y.y + be.x*m.z.x + be.z*m.x.x)return false; // a.x X b.y axis
  764. if(Abs(bo.z*obox.matrix.z.y - bo.y*obox.matrix.z.z) > ae.y*m.z.z + ae.z*m.z.y + be.x*m.y.x + be.y*m.x.x)return false; // a.x X b.z axis
  765. if(Abs(bo.x*obox.matrix.x.z - bo.z*obox.matrix.x.x) > ae.x*m.x.z + ae.z*m.x.x + be.y*m.z.y + be.z*m.y.y)return false; // a.y X b.x axis
  766. if(Abs(bo.x*obox.matrix.y.z - bo.z*obox.matrix.y.x) > ae.x*m.y.z + ae.z*m.y.x + be.x*m.z.y + be.z*m.x.y)return false; // a.y X b.y axis
  767. if(Abs(bo.x*obox.matrix.z.z - bo.z*obox.matrix.z.x) > ae.x*m.z.z + ae.z*m.z.x + be.x*m.y.y + be.y*m.x.y)return false; // a.y X b.z axis
  768. if(Abs(bo.y*obox.matrix.x.x - bo.x*obox.matrix.x.y) > ae.x*m.x.y + ae.y*m.x.x + be.y*m.z.z + be.z*m.y.z)return false; // a.z X b.x axis
  769. if(Abs(bo.y*obox.matrix.y.x - bo.x*obox.matrix.y.y) > ae.x*m.y.y + ae.y*m.y.x + be.x*m.z.z + be.z*m.x.z)return false; // a.z X b.y axis
  770. if(Abs(bo.y*obox.matrix.z.x - bo.x*obox.matrix.z.y) > ae.x*m.z.y + ae.y*m.z.x + be.x*m.y.z + be.y*m.x.z)return false; // a.z X b.z axis
  771. return true;
  772. }
  773. /******************************************************************************/
  774. Bool CutsEps(C Box &a, C Box &b)
  775. {
  776. return a.min.x<=b.max.x+EPS && a.max.x>=b.min.x-EPS
  777. && a.min.y<=b.max.y+EPS && a.max.y>=b.min.y-EPS
  778. && a.min.z<=b.max.z+EPS && a.max.z>=b.min.z-EPS;
  779. }
  780. Bool CutsEps(C BoxD &a, C BoxD &b)
  781. {
  782. return a.min.x<=b.max.x+EPSD && a.max.x>=b.min.x-EPSD
  783. && a.min.y<=b.max.y+EPSD && a.max.y>=b.min.y-EPSD
  784. && a.min.z<=b.max.z+EPSD && a.max.z>=b.min.z-EPSD;
  785. }
  786. /******************************************************************************/
  787. Bool Inside(C Box &a, C Box &b)
  788. {
  789. return a.min.x>=b.min.x && a.max.x<=b.max.x
  790. && a.min.y>=b.min.y && a.max.y<=b.max.y
  791. && a.min.z>=b.min.z && a.max.z<=b.max.z;
  792. }
  793. Bool Inside(C BoxD &a, C BoxD &b)
  794. {
  795. return a.min.x>=b.min.x && a.max.x<=b.max.x
  796. && a.min.y>=b.min.y && a.max.y<=b.max.y
  797. && a.min.z>=b.min.z && a.max.z<=b.max.z;
  798. }
  799. Bool Inside(C BoxI &a, C BoxI &b)
  800. {
  801. return a.min.x>=b.min.x && a.max.x<=b.max.x
  802. && a.min.y>=b.min.y && a.max.y<=b.max.y
  803. && a.min.z>=b.min.z && a.max.z<=b.max.z;
  804. }
  805. Bool InsideEps(C Box &a, C Box &b)
  806. {
  807. return a.min.x>=b.min.x-EPS && a.max.x<=b.max.x+EPS
  808. && a.min.y>=b.min.y-EPS && a.max.y<=b.max.y+EPS
  809. && a.min.z>=b.min.z-EPS && a.max.z<=b.max.z+EPS;
  810. }
  811. /******************************************************************************/
  812. Bool SweepPointBox(C Vec &point, C Vec &move, C Box &box, Flt *hit_frac, Vec *hit_normal, Vec *hit_pos)
  813. {
  814. if(Cuts(point, box)){if(hit_frac)*hit_frac=0; if(hit_normal)hit_normal->zero(); if(hit_pos)*hit_pos=point; return true;}
  815. Flt frac;
  816. Vec test;
  817. if(point.x<box.min.x && point.x+move.x>=box.min.x){frac=(box.min.x-point.x)/move.x; test.set(box.min.x, point.y+move.y*frac, point.z+move.z*frac); if( box.includesY(test.y) && box.includesZ(test.z)){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(-1, 0, 0); if(hit_pos)*hit_pos=test; return true;}}else
  818. if(point.x>box.max.x && point.x+move.x<=box.max.x){frac=(box.max.x-point.x)/move.x; test.set(box.max.x, point.y+move.y*frac, point.z+move.z*frac); if( box.includesY(test.y) && box.includesZ(test.z)){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set( 1, 0, 0); if(hit_pos)*hit_pos=test; return true;}}
  819. if(point.y<box.min.y && point.y+move.y>=box.min.y){frac=(box.min.y-point.y)/move.y; test.set(point.x+move.x*frac, box.min.y, point.z+move.z*frac); if(box.includesX(test.x) && box.includesZ(test.z)){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(0, -1, 0); if(hit_pos)*hit_pos=test; return true;}}else
  820. if(point.y>box.max.y && point.y+move.y<=box.max.y){frac=(box.max.y-point.y)/move.y; test.set(point.x+move.x*frac, box.max.y, point.z+move.z*frac); if(box.includesX(test.x) && box.includesZ(test.z)){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(0, 1, 0); if(hit_pos)*hit_pos=test; return true;}}
  821. if(point.z<box.min.z && point.z+move.z>=box.min.z){frac=(box.min.z-point.z)/move.z; test.set(point.x+move.x*frac, point.y+move.y*frac, box.min.z); if(box.includesX(test.x) && box.includesY(test.y) ){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(0, 0, -1); if(hit_pos)*hit_pos=test; return true;}}else
  822. if(point.z>box.max.z && point.z+move.z<=box.max.z){frac=(box.max.z-point.z)/move.z; test.set(point.x+move.x*frac, point.y+move.y*frac, box.max.z); if(box.includesX(test.x) && box.includesY(test.y) ){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(0, 0, 1); if(hit_pos)*hit_pos=test; return true;}}
  823. return false;
  824. }
  825. Bool SweepPointBox(C Vec &point, C Vec &move, C Extent &ext, Flt *hit_frac, Vec *hit_normal, Vec *hit_pos)
  826. {
  827. if(Cuts(point, ext)){if(hit_frac)*hit_frac=0; if(hit_normal)hit_normal->zero(); if(hit_pos)*hit_pos=point; return true;}
  828. Flt frac, border;
  829. Vec test;
  830. border=ext.minX(); if(point.x<border && point.x+move.x>=border){frac=(border-point.x)/move.x; test.set(border, point.y+move.y*frac, point.z+move.z*frac); if( ext.includesY(test.y) && ext.includesZ(test.z)){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(-1, 0, 0); if(hit_pos)*hit_pos=test; return true;}}
  831. else{border=ext.maxX(); if(point.x>border && point.x+move.x<=border){frac=(border-point.x)/move.x; test.set(border, point.y+move.y*frac, point.z+move.z*frac); if( ext.includesY(test.y) && ext.includesZ(test.z)){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set( 1, 0, 0); if(hit_pos)*hit_pos=test; return true;}}}
  832. border=ext.minY(); if(point.y<border && point.y+move.y>=border){frac=(border-point.y)/move.y; test.set(point.x+move.x*frac, border, point.z+move.z*frac); if(ext.includesX(test.x) && ext.includesZ(test.z)){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(0, -1, 0); if(hit_pos)*hit_pos=test; return true;}}
  833. else{border=ext.maxY(); if(point.y>border && point.y+move.y<=border){frac=(border-point.y)/move.y; test.set(point.x+move.x*frac, border, point.z+move.z*frac); if(ext.includesX(test.x) && ext.includesZ(test.z)){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(0, 1, 0); if(hit_pos)*hit_pos=test; return true;}}}
  834. border=ext.minZ(); if(point.z<border && point.z+move.z>=border){frac=(border-point.z)/move.z; test.set(point.x+move.x*frac, point.y+move.y*frac, border); if(ext.includesX(test.x) && ext.includesY(test.y) ){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(0, 0, -1); if(hit_pos)*hit_pos=test; return true;}}
  835. else{border=ext.maxZ(); if(point.z>border && point.z+move.z<=border){frac=(border-point.z)/move.z; test.set(point.x+move.x*frac, point.y+move.y*frac, border); if(ext.includesX(test.x) && ext.includesY(test.y) ){if(hit_frac)*hit_frac=frac; if(hit_normal)hit_normal->set(0, 0, 1); if(hit_pos)*hit_pos=test; return true;}}}
  836. return false;
  837. }
  838. Bool SweepPointBox(C Vec &point, C Vec &move, C OBox &obox, Flt *hit_frac, Vec *hit_normal, Vec *hit_pos)
  839. {
  840. Vec om_point; om_point.fromDivNormalized(point, obox.matrix );
  841. Vec om_move ; om_move .fromDivNormalized(move , obox.matrix.orn());
  842. Flt frac;
  843. if(SweepPointBox(om_point, om_move, obox.box, &frac, hit_normal))
  844. {
  845. if(hit_frac )*hit_frac =frac;
  846. if(hit_pos )*hit_pos =point+move*frac;
  847. if(hit_normal)*hit_normal*=obox.matrix.orn();
  848. return true;
  849. }
  850. return false;
  851. }
  852. /******************************************************************************/
  853. Flt Dist (C Vec &point, C OBox &obox) {return Dist (Vec ().fromDivNormalized(point, obox.matrix), obox.box);}
  854. Flt Dist2(C Vec &point, C OBox &obox) {return Dist2(Vec ().fromDivNormalized(point, obox.matrix), obox.box);}
  855. Bool Cuts (C Vec &point, C OBox &obox) {return Cuts (Vec ().fromDivNormalized(point, obox.matrix), obox.box);}
  856. Flt Dist (C Edge &edge , C OBox &obox) {return Dist (Edge(edge).divNormalized( obox.matrix), obox.box);}
  857. Bool Cuts (C Edge &edge , C OBox &obox) {return Cuts (Edge(edge).divNormalized( obox.matrix), obox.box);}
  858. Bool Cuts (C OBox &a , C OBox &b ) {return Cuts (a.box, OBox(b).div(a.matrix, true));}
  859. /******************************************************************************/
  860. }
  861. /******************************************************************************/