geometry.cpp 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. /*************************************************************************/
  2. /* geometry.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "geometry.h"
  30. #include "print_string.h"
  31. void Geometry::MeshData::optimize_vertices() {
  32. Map<int,int> vtx_remap;
  33. for(int i=0;i<faces.size();i++) {
  34. for(int j=0;j<faces[i].indices.size();j++) {
  35. int idx = faces[i].indices[j];
  36. if (!vtx_remap.has(idx)) {
  37. int ni = vtx_remap.size();
  38. vtx_remap[idx]=ni;
  39. }
  40. faces[i].indices[j]=vtx_remap[idx];
  41. }
  42. }
  43. for(int i=0;i<edges.size();i++) {
  44. int a = edges[i].a;
  45. int b = edges[i].b;
  46. if (!vtx_remap.has(a)) {
  47. int ni = vtx_remap.size();
  48. vtx_remap[a]=ni;
  49. }
  50. if (!vtx_remap.has(b)) {
  51. int ni = vtx_remap.size();
  52. vtx_remap[b]=ni;
  53. }
  54. edges[i].a=vtx_remap[a];
  55. edges[i].b=vtx_remap[b];
  56. }
  57. Vector<Vector3> new_vertices;
  58. new_vertices.resize(vtx_remap.size());
  59. for(int i=0;i<vertices.size();i++) {
  60. if (vtx_remap.has(i))
  61. new_vertices[vtx_remap[i]]=vertices[i];
  62. }
  63. vertices=new_vertices;
  64. }
  65. Vector< Vector<Vector2> > (*Geometry::_decompose_func)(const Vector<Vector2>& p_polygon)=NULL;
  66. struct _FaceClassify {
  67. struct _Link {
  68. int face;
  69. int edge;
  70. void clear() { face=-1; edge=-1; }
  71. _Link() { face=-1; edge=-1; }
  72. };
  73. bool valid;
  74. int group;
  75. _Link links[3];
  76. Face3 face;
  77. _FaceClassify() {
  78. group=-1;
  79. valid=false;
  80. };
  81. };
  82. static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) {
  83. /* connect faces, error will occur if an edge is shared between more than 2 faces */
  84. /* clear connections */
  85. bool error=false;
  86. for (int i=0;i<len;i++) {
  87. for (int j=0;j<3;j++) {
  88. p_faces[i].links[j].clear();
  89. }
  90. }
  91. for (int i=0;i<len;i++) {
  92. if (p_faces[i].group!=p_group)
  93. continue;
  94. for (int j=i+1;j<len;j++) {
  95. if (p_faces[j].group!=p_group)
  96. continue;
  97. for (int k=0;k<3;k++) {
  98. Vector3 vi1=p_faces[i].face.vertex[k];
  99. Vector3 vi2=p_faces[i].face.vertex[(k+1)%3];
  100. for (int l=0;l<3;l++) {
  101. Vector3 vj2=p_faces[j].face.vertex[l];
  102. Vector3 vj1=p_faces[j].face.vertex[(l+1)%3];
  103. if (vi1.distance_to(vj1)<0.00001 &&
  104. vi2.distance_to(vj2)<0.00001
  105. ) {
  106. if (p_faces[i].links[k].face!=-1) {
  107. ERR_PRINT("already linked\n");
  108. error=true;
  109. break;
  110. }
  111. if (p_faces[j].links[l].face!=-1) {
  112. ERR_PRINT("already linked\n");
  113. error=true;
  114. break;
  115. }
  116. p_faces[i].links[k].face=j;
  117. p_faces[i].links[k].edge=l;
  118. p_faces[j].links[l].face=i;
  119. p_faces[j].links[l].edge=k;
  120. }
  121. }
  122. if (error)
  123. break;
  124. }
  125. if (error)
  126. break;
  127. }
  128. if (error)
  129. break;
  130. }
  131. for (int i=0;i<len;i++) {
  132. p_faces[i].valid=true;
  133. for (int j=0;j<3;j++) {
  134. if (p_faces[i].links[j].face==-1)
  135. p_faces[i].valid=false;
  136. }
  137. /*printf("face %i is valid: %i, group %i. connected to %i:%i,%i:%i,%i:%i\n",i,p_faces[i].valid,p_faces[i].group,
  138. p_faces[i].links[0].face,
  139. p_faces[i].links[0].edge,
  140. p_faces[i].links[1].face,
  141. p_faces[i].links[1].edge,
  142. p_faces[i].links[2].face,
  143. p_faces[i].links[2].edge);*/
  144. }
  145. return error;
  146. }
  147. static bool _group_face(_FaceClassify *p_faces, int len, int p_index,int p_group) {
  148. if (p_faces[p_index].group>=0)
  149. return false;
  150. p_faces[p_index].group=p_group;
  151. for (int i=0;i<3;i++) {
  152. ERR_FAIL_INDEX_V(p_faces[p_index].links[i].face,len,true);
  153. _group_face(p_faces,len,p_faces[p_index].links[i].face,p_group);
  154. }
  155. return true;
  156. }
  157. DVector< DVector< Face3 > > Geometry::separate_objects( DVector< Face3 > p_array ) {
  158. DVector< DVector< Face3 > > objects;
  159. int len = p_array.size();
  160. DVector<Face3>::Read r=p_array.read();
  161. const Face3* arrayptr = r.ptr();
  162. DVector< _FaceClassify> fc;
  163. fc.resize( len );
  164. DVector< _FaceClassify >::Write fcw=fc.write();
  165. _FaceClassify * _fcptr = fcw.ptr();
  166. for (int i=0;i<len;i++) {
  167. _fcptr[i].face=arrayptr[i];
  168. }
  169. bool error=_connect_faces(_fcptr,len,-1);
  170. if (error) {
  171. ERR_FAIL_COND_V(error, DVector< DVector< Face3 > >() ); // invalid geometry
  172. }
  173. /* group connected faces in separate objects */
  174. int group=0;
  175. for (int i=0;i<len;i++) {
  176. if (!_fcptr[i].valid)
  177. continue;
  178. if (_group_face(_fcptr,len,i,group)) {
  179. group++;
  180. }
  181. }
  182. /* group connected faces in separate objects */
  183. for (int i=0;i<len;i++) {
  184. _fcptr[i].face=arrayptr[i];
  185. }
  186. if (group>=0) {
  187. objects.resize(group);
  188. DVector< DVector<Face3> >::Write obw=objects.write();
  189. DVector< Face3 > *group_faces = obw.ptr();
  190. for (int i=0;i<len;i++) {
  191. if (!_fcptr[i].valid)
  192. continue;
  193. if (_fcptr[i].group>=0 && _fcptr[i].group<group) {
  194. group_faces[_fcptr[i].group].push_back( _fcptr[i].face );
  195. }
  196. }
  197. }
  198. return objects;
  199. }
  200. /*** GEOMETRY WRAPPER ***/
  201. enum _CellFlags {
  202. _CELL_SOLID=1,
  203. _CELL_EXTERIOR=2,
  204. _CELL_STEP_MASK=0x1C,
  205. _CELL_STEP_NONE=0<<2,
  206. _CELL_STEP_Y_POS=1<<2,
  207. _CELL_STEP_Y_NEG=2<<2,
  208. _CELL_STEP_X_POS=3<<2,
  209. _CELL_STEP_X_NEG=4<<2,
  210. _CELL_STEP_Z_POS=5<<2,
  211. _CELL_STEP_Z_NEG=6<<2,
  212. _CELL_STEP_DONE=7<<2,
  213. _CELL_PREV_MASK=0xE0,
  214. _CELL_PREV_NONE=0<<5,
  215. _CELL_PREV_Y_POS=1<<5,
  216. _CELL_PREV_Y_NEG=2<<5,
  217. _CELL_PREV_X_POS=3<<5,
  218. _CELL_PREV_X_NEG=4<<5,
  219. _CELL_PREV_Z_POS=5<<5,
  220. _CELL_PREV_Z_NEG=6<<5,
  221. _CELL_PREV_FIRST=7<<5,
  222. };
  223. static inline void _plot_face(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,const Vector3& voxelsize,const Face3& p_face) {
  224. AABB aabb( Vector3(x,y,z),Vector3(len_x,len_y,len_z));
  225. aabb.pos=aabb.pos*voxelsize;
  226. aabb.size=aabb.size*voxelsize;
  227. if (!p_face.intersects_aabb(aabb))
  228. return;
  229. if (len_x==1 && len_y==1 && len_z==1) {
  230. p_cell_status[x][y][z]=_CELL_SOLID;
  231. return;
  232. }
  233. int div_x=len_x>1?2:1;
  234. int div_y=len_y>1?2:1;
  235. int div_z=len_z>1?2:1;
  236. #define _SPLIT(m_i,m_div,m_v,m_len_v,m_new_v,m_new_len_v)\
  237. if (m_div==1) {\
  238. m_new_v=m_v;\
  239. m_new_len_v=1; \
  240. } else if (m_i==0) {\
  241. m_new_v=m_v;\
  242. m_new_len_v=m_len_v/2;\
  243. } else {\
  244. m_new_v=m_v+m_len_v/2;\
  245. m_new_len_v=m_len_v-m_len_v/2; \
  246. }
  247. int new_x;
  248. int new_len_x;
  249. int new_y;
  250. int new_len_y;
  251. int new_z;
  252. int new_len_z;
  253. for (int i=0;i<div_x;i++) {
  254. _SPLIT(i,div_x,x,len_x,new_x,new_len_x);
  255. for (int j=0;j<div_y;j++) {
  256. _SPLIT(j,div_y,y,len_y,new_y,new_len_y);
  257. for (int k=0;k<div_z;k++) {
  258. _SPLIT(k,div_z,z,len_z,new_z,new_len_z);
  259. _plot_face(p_cell_status,new_x,new_y,new_z,new_len_x,new_len_y,new_len_z,voxelsize,p_face);
  260. }
  261. }
  262. }
  263. }
  264. static inline void _mark_outside(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z) {
  265. if (p_cell_status[x][y][z]&3)
  266. return; // nothing to do, already used and/or visited
  267. p_cell_status[x][y][z]=_CELL_PREV_FIRST;
  268. while(true) {
  269. uint8_t &c = p_cell_status[x][y][z];
  270. //printf("at %i,%i,%i\n",x,y,z);
  271. if ( (c&_CELL_STEP_MASK)==_CELL_STEP_NONE) {
  272. /* Haven't been in here, mark as outside */
  273. p_cell_status[x][y][z]|=_CELL_EXTERIOR;
  274. //printf("not marked as anything, marking exterior\n");
  275. }
  276. //printf("cell step is %i\n",(c&_CELL_STEP_MASK));
  277. if ( (c&_CELL_STEP_MASK)!=_CELL_STEP_DONE) {
  278. /* if not done, increase step */
  279. c+=1<<2;
  280. //printf("incrementing cell step\n");
  281. }
  282. if ( (c&_CELL_STEP_MASK)==_CELL_STEP_DONE) {
  283. /* Go back */
  284. //printf("done, going back a cell\n");
  285. switch(c&_CELL_PREV_MASK) {
  286. case _CELL_PREV_FIRST: {
  287. //printf("at end, finished marking\n");
  288. return;
  289. } break;
  290. case _CELL_PREV_Y_POS: {
  291. y++;
  292. ERR_FAIL_COND(y>=len_y);
  293. } break;
  294. case _CELL_PREV_Y_NEG: {
  295. y--;
  296. ERR_FAIL_COND(y<0);
  297. } break;
  298. case _CELL_PREV_X_POS: {
  299. x++;
  300. ERR_FAIL_COND(x>=len_x);
  301. } break;
  302. case _CELL_PREV_X_NEG: {
  303. x--;
  304. ERR_FAIL_COND(x<0);
  305. } break;
  306. case _CELL_PREV_Z_POS: {
  307. z++;
  308. ERR_FAIL_COND(z>=len_z);
  309. } break;
  310. case _CELL_PREV_Z_NEG: {
  311. z--;
  312. ERR_FAIL_COND(z<0);
  313. } break;
  314. default: {
  315. ERR_FAIL();
  316. }
  317. }
  318. continue;
  319. }
  320. //printf("attempting new cell!\n");
  321. int next_x=x,next_y=y,next_z=z;
  322. uint8_t prev=0;
  323. switch(c&_CELL_STEP_MASK) {
  324. case _CELL_STEP_Y_POS: {
  325. next_y++;
  326. prev=_CELL_PREV_Y_NEG;
  327. } break;
  328. case _CELL_STEP_Y_NEG: {
  329. next_y--;
  330. prev=_CELL_PREV_Y_POS;
  331. } break;
  332. case _CELL_STEP_X_POS: {
  333. next_x++;
  334. prev=_CELL_PREV_X_NEG;
  335. } break;
  336. case _CELL_STEP_X_NEG: {
  337. next_x--;
  338. prev=_CELL_PREV_X_POS;
  339. } break;
  340. case _CELL_STEP_Z_POS: {
  341. next_z++;
  342. prev=_CELL_PREV_Z_NEG;
  343. } break;
  344. case _CELL_STEP_Z_NEG: {
  345. next_z--;
  346. prev=_CELL_PREV_Z_POS;
  347. } break;
  348. default: ERR_FAIL();
  349. }
  350. //printf("testing if new cell will be ok...!\n");
  351. if (next_x<0 || next_x>=len_x)
  352. continue;
  353. if (next_y<0 || next_y>=len_y)
  354. continue;
  355. if (next_z<0 || next_z>=len_z)
  356. continue;
  357. //printf("testing if new cell is traversable\n");
  358. if (p_cell_status[next_x][next_y][next_z]&3)
  359. continue;
  360. //printf("move to it\n");
  361. x=next_x;
  362. y=next_y;
  363. z=next_z;
  364. p_cell_status[x][y][z]|=prev;
  365. }
  366. }
  367. static inline void _build_faces(uint8_t*** p_cell_status,int x,int y,int z,int len_x,int len_y,int len_z,DVector<Face3>& p_faces) {
  368. ERR_FAIL_INDEX(x,len_x);
  369. ERR_FAIL_INDEX(y,len_y);
  370. ERR_FAIL_INDEX(z,len_z);
  371. if (p_cell_status[x][y][z]&_CELL_EXTERIOR)
  372. return;
  373. /* static const Vector3 vertices[8]={
  374. Vector3(0,0,0),
  375. Vector3(0,0,1),
  376. Vector3(0,1,0),
  377. Vector3(0,1,1),
  378. Vector3(1,0,0),
  379. Vector3(1,0,1),
  380. Vector3(1,1,0),
  381. Vector3(1,1,1),
  382. };
  383. */
  384. #define vert(m_idx) Vector3( (m_idx&4)>>2, (m_idx&2)>>1, m_idx&1 )
  385. static const uint8_t indices[6][4]={
  386. {7,6,4,5},
  387. {7,3,2,6},
  388. {7,5,1,3},
  389. {0,2,3,1},
  390. {0,1,5,4},
  391. {0,4,6,2},
  392. };
  393. /*
  394. {0,1,2,3},
  395. {0,1,4,5},
  396. {0,2,4,6},
  397. {4,5,6,7},
  398. {2,3,7,6},
  399. {1,3,5,7},
  400. {0,2,3,1},
  401. {0,1,5,4},
  402. {0,4,6,2},
  403. {7,6,4,5},
  404. {7,3,2,6},
  405. {7,5,1,3},
  406. */
  407. for (int i=0;i<6;i++) {
  408. Vector3 face_points[4];
  409. int disp_x=x+((i%3)==0?((i<3)?1:-1):0);
  410. int disp_y=y+(((i-1)%3)==0?((i<3)?1:-1):0);
  411. int disp_z=z+(((i-2)%3)==0?((i<3)?1:-1):0);
  412. bool plot=false;
  413. if (disp_x<0 || disp_x>=len_x)
  414. plot=true;
  415. if (disp_y<0 || disp_y>=len_y)
  416. plot=true;
  417. if (disp_z<0 || disp_z>=len_z)
  418. plot=true;
  419. if (!plot && (p_cell_status[disp_x][disp_y][disp_z]&_CELL_EXTERIOR))
  420. plot=true;
  421. if (!plot)
  422. continue;
  423. for (int j=0;j<4;j++)
  424. face_points[j]=vert( indices[i][j] ) + Vector3(x,y,z);
  425. p_faces.push_back(
  426. Face3(
  427. face_points[0],
  428. face_points[1],
  429. face_points[2]
  430. )
  431. );
  432. p_faces.push_back(
  433. Face3(
  434. face_points[2],
  435. face_points[3],
  436. face_points[0]
  437. )
  438. );
  439. }
  440. }
  441. DVector< Face3 > Geometry::wrap_geometry( DVector< Face3 > p_array,float *p_error ) {
  442. #define _MIN_SIZE 1.0
  443. #define _MAX_LENGTH 20
  444. int face_count=p_array.size();
  445. DVector<Face3>::Read facesr=p_array.read();
  446. const Face3 *faces = facesr.ptr();
  447. AABB global_aabb;
  448. for(int i=0;i<face_count;i++) {
  449. if (i==0) {
  450. global_aabb=faces[i].get_aabb();
  451. } else {
  452. global_aabb.merge_with( faces[i].get_aabb() );
  453. }
  454. }
  455. global_aabb.grow_by(0.01); // avoid numerical error
  456. // determine amount of cells in grid axis
  457. int div_x,div_y,div_z;
  458. if (global_aabb.size.x/_MIN_SIZE<_MAX_LENGTH)
  459. div_x=(int)(global_aabb.size.x/_MIN_SIZE)+1;
  460. else
  461. div_x=_MAX_LENGTH;
  462. if (global_aabb.size.y/_MIN_SIZE<_MAX_LENGTH)
  463. div_y=(int)(global_aabb.size.y/_MIN_SIZE)+1;
  464. else
  465. div_y=_MAX_LENGTH;
  466. if (global_aabb.size.z/_MIN_SIZE<_MAX_LENGTH)
  467. div_z=(int)(global_aabb.size.z/_MIN_SIZE)+1;
  468. else
  469. div_z=_MAX_LENGTH;
  470. Vector3 voxelsize=global_aabb.size;
  471. voxelsize.x/=div_x;
  472. voxelsize.y/=div_y;
  473. voxelsize.z/=div_z;
  474. // create and initialize cells to zero
  475. print_line("Wrapper: Initializing Cells");
  476. uint8_t ***cell_status=memnew_arr(uint8_t**,div_x);
  477. for(int i=0;i<div_x;i++) {
  478. cell_status[i]=memnew_arr(uint8_t*,div_y);
  479. for(int j=0;j<div_y;j++) {
  480. cell_status[i][j]=memnew_arr(uint8_t,div_z);
  481. for(int k=0;k<div_z;k++) {
  482. cell_status[i][j][k]=0;
  483. }
  484. }
  485. }
  486. // plot faces into cells
  487. print_line("Wrapper (1/6): Plotting Faces");
  488. for (int i=0;i<face_count;i++) {
  489. Face3 f=faces[i];
  490. for (int j=0;j<3;j++) {
  491. f.vertex[j]-=global_aabb.pos;
  492. }
  493. _plot_face(cell_status,0,0,0,div_x,div_y,div_z,voxelsize,f);
  494. }
  495. // determine which cells connect to the outside by traversing the outside and recursively flood-fill marking
  496. print_line("Wrapper (2/6) Flood Filling");
  497. for (int i=0;i<div_x;i++) {
  498. for (int j=0;j<div_y;j++) {
  499. _mark_outside(cell_status,i,j,0,div_x,div_y,div_z);
  500. _mark_outside(cell_status,i,j,div_z-1,div_x,div_y,div_z);
  501. }
  502. }
  503. for (int i=0;i<div_z;i++) {
  504. for (int j=0;j<div_y;j++) {
  505. _mark_outside(cell_status,0,j,i,div_x,div_y,div_z);
  506. _mark_outside(cell_status,div_x-1,j,i,div_x,div_y,div_z);
  507. }
  508. }
  509. for (int i=0;i<div_x;i++) {
  510. for (int j=0;j<div_z;j++) {
  511. _mark_outside(cell_status,i,0,j,div_x,div_y,div_z);
  512. _mark_outside(cell_status,i,div_y-1,j,div_x,div_y,div_z);
  513. }
  514. }
  515. // build faces for the inside-outside cell divisors
  516. print_line("Wrapper (3/6): Building Faces");
  517. DVector<Face3> wrapped_faces;
  518. for (int i=0;i<div_x;i++) {
  519. for (int j=0;j<div_y;j++) {
  520. for (int k=0;k<div_z;k++) {
  521. _build_faces(cell_status,i,j,k,div_x,div_y,div_z,wrapped_faces);
  522. }
  523. }
  524. }
  525. print_line("Wrapper (4/6): Transforming Back Vertices");
  526. // transform face vertices to global coords
  527. int wrapped_faces_count=wrapped_faces.size();
  528. DVector<Face3>::Write wrapped_facesw=wrapped_faces.write();
  529. Face3* wrapped_faces_ptr=wrapped_facesw.ptr();
  530. for(int i=0;i<wrapped_faces_count;i++) {
  531. for(int j=0;j<3;j++) {
  532. Vector3& v = wrapped_faces_ptr[i].vertex[j];
  533. v=v*voxelsize;
  534. v+=global_aabb.pos;
  535. }
  536. }
  537. // clean up grid
  538. print_line("Wrapper (5/6): Grid Cleanup");
  539. for(int i=0;i<div_x;i++) {
  540. for(int j=0;j<div_y;j++) {
  541. memdelete_arr( cell_status[i][j] );
  542. }
  543. memdelete_arr( cell_status[i] );
  544. }
  545. memdelete_arr(cell_status);
  546. if (p_error)
  547. *p_error=voxelsize.length();
  548. print_line("Wrapper (6/6): Finished.");
  549. return wrapped_faces;
  550. }
  551. Geometry::MeshData Geometry::build_convex_mesh(const DVector<Plane> &p_planes) {
  552. MeshData mesh;
  553. #define SUBPLANE_SIZE 1024.0
  554. float subplane_size = 1024.0; // should compute this from the actual plane
  555. for (int i=0;i<p_planes.size();i++) {
  556. Plane p =p_planes[i];
  557. Vector3 ref=Vector3(0.0,1.0,0.0);
  558. if (ABS(p.normal.dot(ref))>0.95)
  559. ref=Vector3(0.0,0.0,1.0); // change axis
  560. Vector3 right = p.normal.cross(ref).normalized();
  561. Vector3 up = p.normal.cross( right ).normalized();
  562. Vector< Vector3 > vertices;
  563. Vector3 center = p.get_any_point();
  564. // make a quad clockwise
  565. vertices.push_back( center - up * subplane_size + right * subplane_size );
  566. vertices.push_back( center - up * subplane_size - right * subplane_size );
  567. vertices.push_back( center + up * subplane_size - right * subplane_size );
  568. vertices.push_back( center + up * subplane_size + right * subplane_size );
  569. for (int j=0;j<p_planes.size();j++) {
  570. if (j==i)
  571. continue;
  572. Vector< Vector3 > new_vertices;
  573. Plane clip=p_planes[j];
  574. if (clip.normal.dot(p.normal)>0.95)
  575. continue;
  576. if (vertices.size()<3)
  577. break;
  578. for(int k=0;k<vertices.size();k++) {
  579. int k_n=(k+1)%vertices.size();
  580. Vector3 edge0_A=vertices[k];
  581. Vector3 edge1_A=vertices[k_n];
  582. real_t dist0 = clip.distance_to(edge0_A);
  583. real_t dist1 = clip.distance_to(edge1_A);
  584. if ( dist0 <= 0 ) { // behind plane
  585. new_vertices.push_back(vertices[k]);
  586. }
  587. // check for different sides and non coplanar
  588. if ( (dist0*dist1) < 0) {
  589. // calculate intersection
  590. Vector3 rel = edge1_A - edge0_A;
  591. real_t den=clip.normal.dot( rel );
  592. if (Math::abs(den)<CMP_EPSILON)
  593. continue; // point too short
  594. real_t dist=-(clip.normal.dot( edge0_A )-clip.d)/den;
  595. Vector3 inters = edge0_A+rel*dist;
  596. new_vertices.push_back(inters);
  597. }
  598. }
  599. vertices=new_vertices;
  600. }
  601. if (vertices.size()<3)
  602. continue;
  603. //result is a clockwise face
  604. MeshData::Face face;
  605. // add face indices
  606. for (int j=0;j<vertices.size();j++) {
  607. int idx=-1;
  608. for (int k=0;k<mesh.vertices.size();k++) {
  609. if (mesh.vertices[k].distance_to(vertices[j])<0.001) {
  610. idx=k;
  611. break;
  612. }
  613. }
  614. if (idx==-1) {
  615. idx=mesh.vertices.size();
  616. mesh.vertices.push_back(vertices[j]);
  617. }
  618. face.indices.push_back(idx);
  619. }
  620. face.plane=p;
  621. mesh.faces.push_back(face);
  622. //add edge
  623. for(int j=0;j<face.indices.size();j++) {
  624. int a=face.indices[j];
  625. int b=face.indices[(j+1)%face.indices.size()];
  626. bool found=false;
  627. for(int k=0;k<mesh.edges.size();k++) {
  628. if (mesh.edges[k].a==a && mesh.edges[k].b==b) {
  629. found=true;
  630. break;
  631. }
  632. if (mesh.edges[k].b==a && mesh.edges[k].a==b) {
  633. found=true;
  634. break;
  635. }
  636. }
  637. if (found)
  638. continue;
  639. MeshData::Edge edge;
  640. edge.a=a;
  641. edge.b=b;
  642. mesh.edges.push_back(edge);
  643. }
  644. }
  645. return mesh;
  646. }
  647. DVector<Plane> Geometry::build_box_planes(const Vector3& p_extents) {
  648. DVector<Plane> planes;
  649. planes.push_back( Plane( Vector3(1,0,0), p_extents.x ) );
  650. planes.push_back( Plane( Vector3(-1,0,0), p_extents.x ) );
  651. planes.push_back( Plane( Vector3(0,1,0), p_extents.y ) );
  652. planes.push_back( Plane( Vector3(0,-1,0), p_extents.y ) );
  653. planes.push_back( Plane( Vector3(0,0,1), p_extents.z ) );
  654. planes.push_back( Plane( Vector3(0,0,-1), p_extents.z ) );
  655. return planes;
  656. }
  657. DVector<Plane> Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
  658. DVector<Plane> planes;
  659. for (int i=0;i<p_sides;i++) {
  660. Vector3 normal;
  661. normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
  662. normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
  663. planes.push_back( Plane( normal, p_radius ) );
  664. }
  665. Vector3 axis;
  666. axis[p_axis]=1.0;
  667. planes.push_back( Plane( axis, p_height*0.5 ) );
  668. planes.push_back( Plane( -axis, p_height*0.5 ) );
  669. return planes;
  670. }
  671. DVector<Plane> Geometry::build_sphere_planes(float p_radius, int p_lats,int p_lons, Vector3::Axis p_axis) {
  672. DVector<Plane> planes;
  673. Vector3 axis;
  674. axis[p_axis]=1.0;
  675. Vector3 axis_neg;
  676. axis_neg[(p_axis+1)%3]=1.0;
  677. axis_neg[(p_axis+2)%3]=1.0;
  678. axis_neg[p_axis]=-1.0;
  679. for (int i=0;i<p_lons;i++) {
  680. Vector3 normal;
  681. normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_lons);
  682. normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_lons);
  683. planes.push_back( Plane( normal, p_radius ) );
  684. for (int j=1;j<=p_lats;j++) {
  685. //todo this is stupid, fix
  686. Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized();
  687. Vector3 pos = angle*p_radius;
  688. planes.push_back( Plane( pos, angle ) );
  689. planes.push_back( Plane( pos * axis_neg, angle * axis_neg) );
  690. }
  691. }
  692. return planes;
  693. }
  694. DVector<Plane> Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
  695. DVector<Plane> planes;
  696. Vector3 axis;
  697. axis[p_axis]=1.0;
  698. Vector3 axis_neg;
  699. axis_neg[(p_axis+1)%3]=1.0;
  700. axis_neg[(p_axis+2)%3]=1.0;
  701. axis_neg[p_axis]=-1.0;
  702. for (int i=0;i<p_sides;i++) {
  703. Vector3 normal;
  704. normal[(p_axis+1)%3]=Math::cos(i*(2.0*Math_PI)/p_sides);
  705. normal[(p_axis+2)%3]=Math::sin(i*(2.0*Math_PI)/p_sides);
  706. planes.push_back( Plane( normal, p_radius ) );
  707. for (int j=1;j<=p_lats;j++) {
  708. Vector3 angle = normal.linear_interpolate(axis,j/(float)p_lats).normalized();
  709. Vector3 pos = axis*p_height*0.5 + angle*p_radius;
  710. planes.push_back( Plane( pos, angle ) );
  711. planes.push_back( Plane( pos * axis_neg, angle * axis_neg) );
  712. }
  713. }
  714. return planes;
  715. }