geometry.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. /*************************************************************************/
  2. /* geometry.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 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. PoolVector< PoolVector< Face3 > > Geometry::separate_objects( PoolVector< Face3 > p_array ) {
  158. PoolVector< PoolVector< Face3 > > objects;
  159. int len = p_array.size();
  160. PoolVector<Face3>::Read r=p_array.read();
  161. const Face3* arrayptr = r.ptr();
  162. PoolVector< _FaceClassify> fc;
  163. fc.resize( len );
  164. PoolVector< _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, PoolVector< PoolVector< 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. PoolVector< PoolVector<Face3> >::Write obw=objects.write();
  189. PoolVector< 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. Rect3 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,PoolVector<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. PoolVector< Face3 > Geometry::wrap_geometry( PoolVector< Face3 > p_array,real_t *p_error ) {
  442. #define _MIN_SIZE 1.0
  443. #define _MAX_LENGTH 20
  444. int face_count=p_array.size();
  445. PoolVector<Face3>::Read facesr=p_array.read();
  446. const Face3 *faces = facesr.ptr();
  447. Rect3 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. PoolVector<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. PoolVector<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 PoolVector<Plane> &p_planes) {
  552. MeshData mesh;
  553. #define SUBPLANE_SIZE 1024.0
  554. real_t 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. PoolVector<Plane> Geometry::build_box_planes(const Vector3& p_extents) {
  648. PoolVector<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. PoolVector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) {
  658. PoolVector<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. PoolVector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats,int p_lons, Vector3::Axis p_axis) {
  672. PoolVector<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/(real_t)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. PoolVector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
  695. PoolVector<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/(real_t)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. }
  716. struct _AtlasWorkRect {
  717. Size2i s;
  718. Point2i p;
  719. int idx;
  720. _FORCE_INLINE_ bool operator<(const _AtlasWorkRect& p_r) const { return s.width > p_r.s.width; };
  721. };
  722. struct _AtlasWorkRectResult {
  723. Vector<_AtlasWorkRect> result;
  724. int max_w;
  725. int max_h;
  726. };
  727. void Geometry::make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size) {
  728. //super simple, almost brute force scanline stacking fitter
  729. //it's pretty basic for now, but it tries to make sure that the aspect ratio of the
  730. //resulting atlas is somehow square. This is necesary because video cards have limits
  731. //on texture size (usually 2048 or 4096), so the more square a texture, the more chances
  732. //it will work in every hardware.
  733. // for example, it will prioritize a 1024x1024 atlas (works everywhere) instead of a
  734. // 256x8192 atlas (won't work anywhere).
  735. ERR_FAIL_COND(p_rects.size()==0);
  736. Vector<_AtlasWorkRect> wrects;
  737. wrects.resize(p_rects.size());
  738. for(int i=0;i<p_rects.size();i++) {
  739. wrects[i].s=p_rects[i];
  740. wrects[i].idx=i;
  741. }
  742. wrects.sort();
  743. int widest = wrects[0].s.width;
  744. Vector<_AtlasWorkRectResult> results;
  745. for(int i=0;i<=12;i++) {
  746. int w = 1<<i;
  747. int max_h=0;
  748. int max_w=0;
  749. if ( w < widest )
  750. continue;
  751. Vector<int> hmax;
  752. hmax.resize(w);
  753. for(int j=0;j<w;j++)
  754. hmax[j]=0;
  755. //place them
  756. int ofs=0;
  757. int limit_h=0;
  758. for(int j=0;j<wrects.size();j++) {
  759. if (ofs+wrects[j].s.width > w) {
  760. ofs=0;
  761. }
  762. int from_y=0;
  763. for(int k=0;k<wrects[j].s.width;k++) {
  764. if (hmax[ofs+k] > from_y)
  765. from_y=hmax[ofs+k];
  766. }
  767. wrects[j].p.x=ofs;
  768. wrects[j].p.y=from_y;
  769. int end_h = from_y+wrects[j].s.height;
  770. int end_w = ofs+wrects[j].s.width;
  771. if (ofs==0)
  772. limit_h=end_h;
  773. for(int k=0;k<wrects[j].s.width;k++) {
  774. hmax[ofs+k]=end_h;
  775. }
  776. if (end_h > max_h)
  777. max_h=end_h;
  778. if (end_w > max_w)
  779. max_w=end_w;
  780. if (ofs==0 || end_h>limit_h ) //while h limit not reched, keep stacking
  781. ofs+=wrects[j].s.width;
  782. }
  783. _AtlasWorkRectResult result;
  784. result.result=wrects;
  785. result.max_h=max_h;
  786. result.max_w=max_w;
  787. results.push_back(result);
  788. }
  789. //find the result with the best aspect ratio
  790. int best=-1;
  791. real_t best_aspect=1e20;
  792. for(int i=0;i<results.size();i++) {
  793. real_t h = nearest_power_of_2(results[i].max_h);
  794. real_t w = nearest_power_of_2(results[i].max_w);
  795. real_t aspect = h>w ? h/w : w/h;
  796. if (aspect < best_aspect) {
  797. best=i;
  798. best_aspect=aspect;
  799. }
  800. }
  801. r_result.resize(p_rects.size());
  802. for(int i=0;i<p_rects.size();i++) {
  803. r_result[ results[best].result[i].idx ]=results[best].result[i].p;
  804. }
  805. r_size=Size2(results[best].max_w,results[best].max_h );
  806. }