Mshb Create.cpp 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. MeshBase& MeshBase::createPlane(Int x, Int y, UInt flag)
  6. {
  7. MAX(x, 2);
  8. MAX(y, 2);
  9. create(x*y, 0, 0, (x-1)*(y-1), flag&(VTX_NRM_TAN_BIN|VTX_TEX0));
  10. // face
  11. if(VecI4 *quad=T.quad.ind())
  12. FREPD(sy, y-1)
  13. FREPD(sx, x-1)
  14. {
  15. Int p=sx+sy*x;
  16. (quad++)->set(p+x, p+1+x, p+1, p);
  17. }
  18. // vtx
  19. if(Vec *pos=vtx.pos())FREPD(sy, y)
  20. {
  21. Flt fy=sy/Flt(y-1);
  22. FREPD(sx, x)(pos++)->set(sx/Flt(x-1), fy, 0);
  23. }
  24. if(Vec *nrm=vtx.nrm())REPA(vtx)(nrm++)->set(0, 0, -1);
  25. if(Vec *tan=vtx.tan())REPA(vtx)(tan++)->set(1, 0, 0);
  26. if(Vec *bin=vtx.bin())REPA(vtx)(bin++)->set(0, -1, 0);
  27. if(vtx.tex0())texMap();
  28. return T;
  29. }
  30. MeshBase& MeshBase::createGrid(Int x, Int y, Bool fast)
  31. {
  32. MAX(x, 2);
  33. MAX(y, 2);
  34. if(fast)create(x*2+(y-2)*2, x+y , 0, 0);
  35. else create(x*y , y*(x-1)+x*(y-1), 0, 0);
  36. // vtx
  37. Vec *pos=vtx.pos();
  38. if(fast)
  39. {
  40. FREPD(sx, x) (pos++)->set( sx/Flt(x-1), 1, 0);
  41. FREPD(sx, x) (pos++)->set( sx/Flt(x-1), 0, 0);
  42. for(Int sy=1; sy<y-1; sy++)(pos++)->set(0, sy/Flt(y-1), 0 );
  43. for(Int sy=1; sy<y-1; sy++)(pos++)->set(1, sy/Flt(y-1), 0 );
  44. }else
  45. FREPD(sy, y)
  46. {
  47. Flt fy=sy/Flt(y-1);
  48. FREPD(sx, x)(pos++)->set(sx/Flt(x-1), fy, 0);
  49. }
  50. // edge
  51. VecI2 *edge=T.edge.ind();
  52. if(fast)
  53. {
  54. FREPD(sx, x )(edge++)->set( sx, sx+x);
  55. (edge++)->set( x, x+x-1);
  56. FREPD(sy, y-2)(edge++)->set(x+x+sy, x+x+sy+y-2);
  57. (edge++)->set( 0, x-1);
  58. }else
  59. {
  60. FREPD(sy, y)FREPD(sx, x-1)(edge++)->set(sx+sy*x, sx+1+(sy )*x);
  61. FREPD(sx, x)FREPD(sy, y-1)(edge++)->set(sx+sy*x, sx +(sy+1)*x);
  62. }
  63. return T;
  64. }
  65. /******************************************************************************/
  66. MeshBase& MeshBase::createFast(C Box &box)
  67. {
  68. create(8, 0, 0, 6);
  69. // vtx
  70. FREP(8)vtx.pos(i).set(( i &1) ? box.max.x : box.min.x,
  71. ((i>>1)&1) ? box.max.y : box.min.y,
  72. ((i>>2)&1) ? box.max.z : box.min.z);
  73. // face
  74. // x
  75. quad.ind(0).set(1|2|0, 1|2|4, 1|0|4, 1|0|0);
  76. quad.ind(1).set(0|0|0, 0|0|4, 0|2|4, 0|2|0);
  77. // y
  78. quad.ind(2).set(2|4|0, 2|4|1, 2|0|1, 2|0|0);
  79. quad.ind(3).set(0|0|0, 0|0|1, 0|4|1, 0|4|0);
  80. // z
  81. quad.ind(4).set(4|1|2, 4|0|2, 4|0|0, 4|1|0);
  82. quad.ind(5).set(0|1|0, 0|0|0, 0|0|2, 0|1|2);
  83. return T;
  84. }
  85. MeshBase& MeshBase::createBox(C Matrix &matrix, UInt flag, Int resolution)
  86. {
  87. Matrix m; MeshBase mesh[6]; REPA(mesh)
  88. {
  89. m.setOrient(DIR_ENUM(i));
  90. m.anchor(0.5f);
  91. m*=matrix;
  92. mesh[i].createPlane(resolution, resolution, flag).transform(m);
  93. }
  94. create(mesh, Elms(mesh));
  95. if(!(flag&(VTX_TAN_BIN|VTX_TEX0)))weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  96. return T;
  97. }
  98. MeshBase& MeshBase::create(C Box & box, UInt flag, Int resolution) {return createBox(Matrix( box.size(), box.min) , flag, resolution);}
  99. MeshBase& MeshBase::create(C OBox &obox, UInt flag, Int resolution) {return createBox(Matrix(obox.box.size(), obox.box.min)*obox.matrix, flag, resolution);}
  100. /******************************************************************************/
  101. MeshBase& MeshBase::create(C Ball &ball, UInt flag, Int resolution)
  102. {
  103. if(resolution<0)resolution=7;else MAX(resolution, 2); // default size else min size
  104. Int face_vtxs=resolution*resolution;
  105. create(face_vtxs*6, 0, 0, (resolution-1)*(resolution-1)*6, flag&VTX_TEX0);
  106. Vec *pos = vtx .pos ();
  107. Vec2 *tex = vtx .tex0();
  108. VecI4 *quad=T.quad.ind ();
  109. // vtx
  110. FREPD(y, resolution)
  111. {
  112. Flt fy=y/Flt(resolution-1), sy=-Tan(fy*PI_2-PI_4);
  113. FREPD(x, resolution)
  114. {
  115. Flt fx=x/Flt(resolution-1), sx=-Tan(fx*PI_2-PI_4);
  116. pos[face_vtxs*0].set( sx, sy, 1 );
  117. pos[face_vtxs*1].set( 1 , sy, -sx);
  118. pos[face_vtxs*2].set(-sx, sy, -1 );
  119. pos[face_vtxs*3].set(-1 , sy, sx);
  120. pos[face_vtxs*4].set(-sx, 1, sy);
  121. pos[face_vtxs*5].set(-sx, -1, -sy);
  122. pos++;
  123. if(tex)
  124. {
  125. tex[face_vtxs*0].set(fx, fy);
  126. tex[face_vtxs*1].set(fx, fy);
  127. tex[face_vtxs*2].set(fx, fy);
  128. tex[face_vtxs*3].set(fx, fy);
  129. tex[face_vtxs*4].set(fx, fy);
  130. tex[face_vtxs*5].set(fx, fy);
  131. tex++;
  132. }
  133. }
  134. }
  135. // face
  136. FREPD(f, 6)
  137. FREPD(y, resolution-1)
  138. FREPD(x, resolution-1)
  139. {
  140. Int p=x + y*resolution + f*face_vtxs;
  141. (quad++)->set(p, p+1, p+1+resolution, p+resolution);
  142. }
  143. if(!(flag&VTX_TEX0))weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  144. Normalize(vtx.pos(), vtxs());
  145. if(flag&VTX_NRM)
  146. {
  147. include(VTX_NRM);
  148. CopyN (vtx.nrm(), vtx.pos(), vtxs());
  149. }
  150. transform(Matrix(ball.r, ball.pos));
  151. if(flag&VTX_TAN)setTangents ();
  152. if(flag&VTX_BIN)setBinormals();
  153. return T;
  154. }
  155. MeshBase& MeshBase::createHalf(C Ball &ball, UInt flag, Int resolution)
  156. {
  157. if(resolution<0)resolution=7;else MAX(resolution, 2); // default size else min size
  158. #if 1 // floor
  159. Int res_half=Max((resolution+1)/2, 2),
  160. #else // ceil
  161. Int res_half=resolution/2+1,
  162. #endif
  163. face_vtxs=resolution*resolution,
  164. half_vtxs=resolution*res_half;
  165. create(half_vtxs*4 + face_vtxs, 0, 0, (resolution-1)*(res_half-1)*4 + (resolution-1)*(resolution-1), flag&VTX_TEX0);
  166. Vec *pos = vtx .pos ();
  167. Vec2 *tex = vtx .tex0();
  168. VecI4 *quad=T.quad.ind ();
  169. // vtx
  170. FREPD(y, res_half)
  171. {
  172. Flt fy=y/Flt((res_half-1)*2), sy=-Tan(fy*PI_2-PI_4);
  173. FREPD(x, resolution)
  174. {
  175. Flt fx=x/Flt(resolution-1), sx=-Tan(fx*PI_2-PI_4);
  176. pos[half_vtxs*0].set( sx, sy, 1 );
  177. pos[half_vtxs*1].set( 1 , sy, -sx);
  178. pos[half_vtxs*2].set(-sx, sy, -1 );
  179. pos[half_vtxs*3].set(-1 , sy, sx);
  180. pos++;
  181. if(tex)
  182. {
  183. tex[half_vtxs*0].set(fx, fy);
  184. tex[half_vtxs*1].set(fx, fy);
  185. tex[half_vtxs*2].set(fx, fy);
  186. tex[half_vtxs*3].set(fx, fy);
  187. tex++;
  188. }
  189. }
  190. }
  191. pos+=resolution*res_half*3;
  192. if(tex)tex+=resolution*res_half*3;
  193. FREPD(y, resolution)
  194. {
  195. Flt fy=y/Flt(resolution-1), sy=-Tan(fy*PI_2-PI_4);
  196. FREPD(x, resolution)
  197. {
  198. Flt fx=x/Flt(resolution-1), sx=-Tan(fx*PI_2-PI_4);
  199. (pos++)->set(-sx, 1, sy);
  200. if(tex)(tex++)->set( fx, fy);
  201. }
  202. }
  203. // face
  204. FREPD(f, 4)
  205. FREPD(y, res_half -1)
  206. FREPD(x, resolution-1)
  207. {
  208. Int p=x + y*resolution + f*half_vtxs;
  209. (quad++)->set(p, p+1, p+1+resolution, p+resolution);
  210. }
  211. FREPD(y, resolution-1)
  212. FREPD(x, resolution-1)
  213. {
  214. Int p=x + y*resolution + 4*half_vtxs;
  215. (quad++)->set(p, p+1, p+1+resolution, p+resolution);
  216. }
  217. if(!(flag&VTX_TEX0))weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  218. Normalize(vtx.pos(), vtxs());
  219. if(flag&VTX_NRM)
  220. {
  221. include(VTX_NRM);
  222. CopyN (vtx.nrm(), vtx.pos(), vtxs());
  223. }
  224. transform(Matrix(ball.r, ball.pos));
  225. if(flag&VTX_TAN)setTangents ();
  226. if(flag&VTX_BIN)setBinormals();
  227. return T;
  228. }
  229. /******************************************************************************/
  230. MeshBase& MeshBase::create2(C Ball &ball, UInt flag, Int resolution, Int resolution2)
  231. {
  232. if(resolution <0)resolution =24;else MAX(resolution , 3); // default size else min size
  233. if(resolution2<0)resolution2=13;else MAX(resolution2, 3); // default size else min size
  234. create((resolution+1)*resolution2, 0, resolution*2, resolution*(resolution2-3), flag&VTX_TEX0);
  235. // vertexes
  236. REPD(y, resolution2)
  237. {
  238. Flt cy, sy; CosSin(cy, sy, y/Flt(resolution2-1)*PI-PI_2);
  239. REPD(x, resolution+1)
  240. {
  241. Flt cx, sx; CosSin(cx, sx, x/Flt(resolution)*PI2);
  242. vtx.pos (x+y*(resolution+1)).set(cx*cy, sy, sx*cy);
  243. if(vtx.tex0())vtx.tex0(x+y*(resolution+1)).set(x/Flt(resolution), y/Flt(resolution2-1));
  244. }
  245. }
  246. // triangles
  247. REPD(x, resolution)
  248. {
  249. Int i=x+ 0 *(resolution+1); tri.ind(x ).set(i+resolution+1, i+resolution+1+1, i);
  250. i=x+(resolution2-2)*(resolution+1); tri.ind(x+resolution).set(i+resolution+1, i+1 , i);
  251. }
  252. // quads
  253. REPD(y, resolution2-3)
  254. REPD(x, resolution)
  255. {
  256. Int i=x+(y+1)*(resolution+1); quad.ind(x+y*resolution).set(i+resolution+1, i+resolution+1+1, i+1, i);
  257. }
  258. if(!(flag&VTX_TEX0))weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  259. Normalize(vtx.pos(), vtxs());
  260. if(flag&VTX_NRM)
  261. {
  262. include(VTX_NRM);
  263. CopyN (vtx.nrm(), vtx.pos(), vtxs());
  264. }
  265. transform(Matrix(ball.r, ball.pos));
  266. if(flag&VTX_TAN)setTangents ();
  267. if(flag&VTX_BIN)setBinormals();
  268. return T;
  269. }
  270. /******************************************************************************/
  271. //VecD2 p((1+Sqrt(5.0))/2, 1); p.normalize();
  272. #define X 0.85065080835203999f // p.x
  273. #define Y 0.52573111211913359f // p.y
  274. static const Vec IcoVtxs[]=
  275. {
  276. Vec( Y, 0,-X), Vec(-Y, 0,-X), Vec( Y, 0, X), Vec(-Y, 0, X),
  277. Vec( 0,-X,-Y), Vec( 0,-X, Y), Vec( 0, X,-Y), Vec( 0, X, Y),
  278. Vec(-X,-Y, 0), Vec( X,-Y, 0), Vec(-X, Y, 0), Vec( X, Y, 0),
  279. };
  280. static const VecI IcoTris[]=
  281. {
  282. VecI(0, 4, 1), VecI(0,9, 4), VecI(9, 5,4), VecI( 4,5,8), VecI(4,8, 1),
  283. VecI(8,10, 1), VecI(8,3,10), VecI(5, 3,8), VecI( 5,2,3), VecI(2,7, 3),
  284. VecI(7,10, 3), VecI(7,6,10), VecI(7,11,6), VecI(11,0,6), VecI(0,1, 6),
  285. VecI(6, 1,10), VecI(9,0,11), VecI(9,11,2), VecI( 9,2,5), VecI(7,2,11),
  286. };
  287. #undef X
  288. #undef Y
  289. MeshBase& MeshBase::createIco(C Ball &ball, UInt flag, Int resolution)
  290. {
  291. if(resolution< 0)resolution=3; // default
  292. if(resolution<=0) // simple
  293. {
  294. create(Elms(IcoVtxs), 0, Elms(IcoTris), 0);
  295. CopyN(vtx.pos(), IcoVtxs, vtxs());
  296. CopyN(tri.ind(), IcoTris, tris());
  297. }else // subdivision
  298. {
  299. resolution++;
  300. const Int vtxs=(resolution+1)*(resolution+2)/2, tris=resolution*resolution, sides=Elms(IcoTris);
  301. create(vtxs*sides, 0, tris*sides, 0);
  302. Int vtx_offset=0;
  303. Vec *p=vtx.pos();
  304. VecI *t=tri.ind();
  305. REP(sides)
  306. {
  307. C VecI &tri_ind=IcoTris[i];
  308. C Vec &v0 =IcoVtxs[tri_ind.x],
  309. &v1 =IcoVtxs[tri_ind.y],
  310. &v2 =IcoVtxs[tri_ind.z];
  311. Vec v01 =(v1-v0)/resolution,
  312. v02 =(v2-v0)/resolution,
  313. vy =v0;
  314. for(Int y=0; y<=resolution; y++)
  315. {
  316. Vec vx=vy;
  317. Int xs=resolution-y;
  318. for(Int x=0; x<=xs; x++)
  319. {
  320. *p++=vx;
  321. vx+=v01;
  322. if(y!=resolution && x!=xs)
  323. {
  324. (t++)->set(vtx_offset , vtx_offset+1, vtx_offset+xs+1);
  325. if(x+1<xs)(t++)->set(vtx_offset+xs+1, vtx_offset+1, vtx_offset+xs+2);
  326. }
  327. vtx_offset++;
  328. }
  329. vy+=v02;
  330. }
  331. }
  332. weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  333. Normalize(vtx.pos(), T.vtxs());
  334. }
  335. if(flag&VTX_NRM)
  336. {
  337. include(VTX_NRM);
  338. CopyN (vtx.nrm(), vtx.pos(), T.vtxs());
  339. }
  340. transform(Matrix(ball.r, ball.pos));
  341. if(flag&VTX_TAN)setTangents ();
  342. if(flag&VTX_BIN)setBinormals();
  343. return T;
  344. }
  345. /******************************************************************************/
  346. MeshBase& MeshBase::createIcoHalf(C Ball &ball, UInt flag, Int resolution)
  347. {
  348. createIco(Ball(1), 0, resolution);
  349. Memt<Bool> is; is.setNumZero(vtxs());
  350. REPA(tri)
  351. {
  352. C VecI &t=tri.ind(i);
  353. if(vtx.pos(t.x).y>EPS
  354. || vtx.pos(t.y).y>EPS
  355. || vtx.pos(t.z).y>EPS)is[t.x]=is[t.y]=is[t.z]=true;
  356. }
  357. keepVtxs(is);
  358. REPA(vtx){Vec &p=vtx.pos(i); if(p.y<0){p.y=0; p.normalize();}}
  359. if(flag&VTX_NRM)
  360. {
  361. include(VTX_NRM);
  362. CopyN (vtx.nrm(), vtx.pos(), T.vtxs());
  363. }
  364. transform(Matrix(ball.r, ball.pos));
  365. if(flag&VTX_TAN)setTangents ();
  366. if(flag&VTX_BIN)setBinormals();
  367. return T;
  368. }
  369. /******************************************************************************/
  370. MeshBase& MeshBase::create(C Capsule &capsule, UInt flag, Int resolution, Int resolution2)
  371. {
  372. if(resolution <0)resolution =12;else MAX(resolution , 3);
  373. if(resolution2<0)resolution2= 5;else MAX(resolution2, 2);
  374. Flt r=Min(capsule.r, capsule.h*0.5f);
  375. create((resolution+1)*(resolution2-1)*2+2, 0, resolution*2, resolution+(resolution2-2)*resolution*2, flag&VTX_TEX0);
  376. REPD(y, resolution2-1)
  377. {
  378. Flt cy, sy; CosSin(cy, sy, y/Flt(resolution2-1)*PI_2);
  379. REPD(x, resolution+1)
  380. {
  381. Flt cx, sx; CosSin(cx, sx, x/Flt(resolution)*PI2);
  382. Int i0=x+ y *(resolution+1),
  383. i1=x+(y+resolution2-1)*(resolution+1);
  384. vtx.pos(i0).set(cy*cx*r, capsule.h*0.5f-r+sy*r, cy*sx*r);
  385. CHS((vtx.pos(i1)=vtx.pos(i0)).y);
  386. if(vtx.tex0())
  387. {
  388. vtx.tex0(i0).set(x/Flt(resolution), (y/Flt(resolution2-1)*r + capsule.h*0.5f-r)/(capsule.h*0.5f)*0.5f+0.5f);
  389. vtx.tex0(i1).set(vtx.tex0(i0).x, 1-vtx.tex0(i0).y);
  390. }
  391. }
  392. }
  393. vtx.pos(vtxs()-2).set(0, capsule.h*0.5f, 0);
  394. vtx.pos(vtxs()-1).set(0, -capsule.h*0.5f, 0);
  395. if(vtx.tex0())
  396. {
  397. vtx.tex0(vtxs()-2).set(0.5f, 1);
  398. vtx.tex0(vtxs()-1).set(0.5f, 0);
  399. }
  400. REP(resolution)
  401. {
  402. Int lo=(resolution2-1)*(resolution+1),
  403. o =lo-(resolution+1);
  404. tri .ind(i ).set(o+ i+1, o+ i, vtxs()-2);
  405. tri .ind(i+resolution).set(o+lo+i, o+lo+i+1, vtxs()-1);
  406. quad.ind(i ).set(lo+i+1, lo+i, i, i+1);
  407. REPD(y, resolution2-2)
  408. {
  409. o=y*(resolution+1);
  410. quad.ind(resolution+resolution* y +i).set(o+i+1, o+i, o+(resolution+1)+i, o+(resolution+1)+i+1); o+=lo;
  411. quad.ind(resolution+resolution*(y+resolution2-2)+i).set(o+(resolution+1)+i+1, o+(resolution+1)+i, o+i, o+i+1);
  412. }
  413. }
  414. if(!(flag&VTX_TEX0))weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  415. transform(Matrix().setPosUp(capsule.pos, capsule.up));
  416. if(flag&VTX_NRM)setVtxDup ().setNormals().exclude(VTX_DUP);
  417. if(flag&VTX_TAN)setTangents ();
  418. if(flag&VTX_BIN)setBinormals();
  419. return T;
  420. }
  421. /******************************************************************************/
  422. MeshBase& MeshBase::createFast(C Tube &tube, Int resolution)
  423. {
  424. if(resolution<0)resolution=12;else MAX(resolution, 3);
  425. Flt h_2=tube.h/2;
  426. create(resolution*2, 0, (resolution-2)*2+resolution*2, 0);
  427. VecI *tri=T.tri.ind();
  428. REP(resolution)
  429. {
  430. Flt c, s; CosSin(c, s, i*PI2/resolution);
  431. vtx.pos( i).set(c*tube.r, h_2, s*tube.r);
  432. vtx.pos(resolution+i).set(c*tube.r, -h_2, s*tube.r);
  433. (tri++)->set(i, (i+1)%resolution, resolution+i);
  434. (tri++)->set((i+1)%resolution, (i+1)%resolution+resolution, resolution+i);
  435. }
  436. REP(resolution-2)
  437. {
  438. tri[ i].set( 0, i+2, i+1);
  439. tri[resolution-2+i].set(resolution, resolution+i+1, resolution+i+2);
  440. }
  441. transform(Matrix().setPosUp(tube.pos, tube.up));
  442. return T;
  443. }
  444. MeshBase& MeshBase::create(C Tube &tube, UInt flag, Int resolution)
  445. {
  446. if(resolution<0)resolution=12;else MAX(resolution, 3);
  447. Int offset,
  448. resolution1=resolution+1;
  449. Flt h_2=tube.h/2;
  450. create(resolution*2 + resolution1*2, 0, (resolution-2)*2, resolution, flag&(VTX_NRM_TAN_BIN|VTX_TEX0));
  451. VecI *tri =T.tri .ind();
  452. VecI4 *quad=T.quad.ind();
  453. // vtxs
  454. REP(resolution)
  455. {
  456. Flt c, s; CosSin(c, s, i*PI2/resolution);
  457. vtx.pos( i).set(c*tube.r, h_2, s*tube.r);
  458. vtx.pos(resolution+i).set(c*tube.r, -h_2, s*tube.r);
  459. if(vtx.nrm())
  460. {
  461. vtx.nrm( i).set(0, 1, 0);
  462. vtx.nrm(resolution+i).set(0, -1, 0);
  463. }
  464. if(vtx.tan())
  465. {
  466. vtx.tan( i).set(1, 0, 0);
  467. vtx.tan(resolution+i).set(1, 0, 0);
  468. }
  469. if(vtx.bin())
  470. {
  471. vtx.bin( i).set(0, 0, -1);
  472. vtx.bin(resolution+i).set(0, 0, 1);
  473. }
  474. if(vtx.tex0())
  475. {
  476. vtx.tex0( i).set(c*0.5f+0.5f, -s*0.5f+0.5f);
  477. vtx.tex0(resolution+i).set(c*0.5f+0.5f, s*0.5f+0.5f);
  478. }
  479. }
  480. offset=resolution*2; REP(resolution1)
  481. {
  482. Flt c, s; CosSin(c, s, i*PI2/resolution);
  483. vtx.pos(offset+ i).set(c*tube.r, h_2, s*tube.r);
  484. vtx.pos(offset+resolution1+i).set(c*tube.r, -h_2, s*tube.r);
  485. if(vtx.nrm())
  486. {
  487. vtx.nrm(offset+ i).set(c, 0, s);
  488. vtx.nrm(offset+resolution1+i).set(c, 0, s);
  489. }
  490. if(vtx.tan())
  491. {
  492. vtx.tan(offset+ i).set(-s, 0, c);
  493. vtx.tan(offset+resolution1+i).set(-s, 0, c);
  494. }
  495. if(vtx.bin())
  496. {
  497. vtx.bin(offset+ i).set(0, -1, 0);
  498. vtx.bin(offset+resolution1+i).set(0, -1, 0);
  499. }
  500. if(vtx.tex0())
  501. {
  502. vtx.tex0(offset+ i).set(Flt(i)/resolution, 0);
  503. vtx.tex0(offset+resolution1+i).set(Flt(i)/resolution, 1);
  504. }
  505. }
  506. // tris
  507. REP(resolution-2)
  508. {
  509. tri[ i].set( 0, i+2, i+1);
  510. tri[resolution-2+i].set(resolution, resolution+i+1, resolution+i+2);
  511. }
  512. // quads
  513. REP(resolution)(quad++)->set(offset+i, offset+i+1, offset+resolution1+i+1, offset+resolution1+i); // sides
  514. if(!(flag&VTX_TEX0))weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  515. transform(Matrix().setPosUp(tube.pos, tube.up));
  516. return T;
  517. }
  518. /******************************************************************************/
  519. MeshBase& MeshBase::create(C Cone &cone, UInt flag, Int resolution)
  520. {
  521. if( resolution<0)resolution=12;else MAX(resolution, 3);
  522. Int resolution1 =resolution+1,
  523. offset;
  524. if(cone.r_low >EPS
  525. && cone.r_high>EPS)
  526. {
  527. offset=resolution*2;
  528. create(resolution*2+resolution1*2, 0, (resolution-2)*2, resolution, flag&(VTX_NRM_TAN_BIN|VTX_TEX0));
  529. VecI *tri =T.tri .ind();
  530. VecI4 *quad=T.quad.ind();
  531. // vtxs
  532. REP(resolution)
  533. {
  534. Flt c, s; CosSin(c, s, i*PI2/resolution);
  535. vtx.pos( i).set(c*cone.r_high, cone.h, s*cone.r_high);
  536. vtx.pos(resolution+i).set(c*cone.r_low , 0, s*cone.r_low );
  537. if(vtx.nrm())
  538. {
  539. vtx.nrm( i).set(0, 1, 0);
  540. vtx.nrm(resolution+i).set(0, -1, 0);
  541. }
  542. if(vtx.tan())
  543. {
  544. vtx.tan( i).set(1, 0, 0);
  545. vtx.tan(resolution+i).set(1, 0, 0);
  546. }
  547. if(vtx.bin())
  548. {
  549. vtx.bin( i).set(0, 0, -1);
  550. vtx.bin(resolution+i).set(0, 0, 1);
  551. }
  552. if(vtx.tex0())
  553. {
  554. vtx.tex0( i).set(c, 1-s);
  555. vtx.tex0(resolution+i).set(c, s);
  556. }
  557. }
  558. Vec2 N(cone.r_high-cone.r_low, cone.h); N=PerpN(N);
  559. REP(resolution1)
  560. {
  561. Flt c, s; CosSin(c, s, i*PI2/resolution);
  562. vtx.pos(offset+ i).set(c*cone.r_high, cone.h, s*cone.r_high);
  563. vtx.pos(offset+resolution1+i).set(c*cone.r_low , 0, s*cone.r_low );
  564. if(vtx.nrm())
  565. {
  566. vtx.nrm(offset+ i).set(N.x*c, N.y, N.x*s);
  567. vtx.nrm(offset+resolution1+i).set(N.x*c, N.y, N.x*s);
  568. }
  569. if(vtx.tan())
  570. {
  571. vtx.tan(offset+ i).set(-s,0,c);
  572. vtx.tan(offset+resolution1+i).set(-s,0,c);
  573. }
  574. if(vtx.bin())
  575. {
  576. vtx.bin(offset+ i).set(N.y*c, -N.x, N.y*s);
  577. vtx.bin(offset+resolution1+i).set(N.y*c, -N.x, N.y*s);
  578. }
  579. if(vtx.tex0())
  580. {
  581. vtx.tex0(offset+ i).set(Flt(i)/resolution, 0);
  582. vtx.tex0(offset+resolution1+i).set(Flt(i)/resolution, 1);
  583. }
  584. }
  585. // tris
  586. REP(resolution-2)
  587. {
  588. tri[ i].set( 0, i+2, i+1);
  589. tri[resolution-2+i].set(resolution, resolution+i+1, resolution+i+2);
  590. }
  591. // quads
  592. REP(resolution)(quad++)->set(offset+i, offset+i+1, offset+resolution1+i+1, offset+resolution1+i); // sides
  593. transform(Matrix().setPosUp(cone.pos, cone.up));
  594. }else
  595. if(cone.r_low>EPS)
  596. {
  597. offset=resolution;
  598. create(resolution+resolution1*2, 0, resolution-2+resolution, 0, flag&(VTX_NRM_TAN_BIN|VTX_TEX0));
  599. VecI *tri=T.tri.ind();
  600. // vtxs
  601. REP(resolution)
  602. {
  603. Flt c, s; CosSin(c, s, i*PI2/resolution);
  604. vtx.pos (i).set(c*cone.r_low, 0, s*cone.r_low);
  605. if(vtx.nrm ())vtx.nrm (i).set(0, -1, 0);
  606. if(vtx.tan ())vtx.tan (i).set(1, 0, 0);
  607. if(vtx.bin ())vtx.bin (i).set(0, 0, 1);
  608. if(vtx.tex0())vtx.tex0(i).set(c, s );
  609. }
  610. Vec2 N(cone.r_high-cone.r_low, cone.h); N=PerpN(N);
  611. REP(resolution1)
  612. {
  613. Flt c, s; CosSin(c, s, i*PI2/resolution);
  614. vtx.pos(offset+ i).set(c*cone.r_high, cone.h, s*cone.r_high);
  615. vtx.pos(offset+resolution1+i).set(c*cone.r_low , 0, s*cone.r_low );
  616. if(vtx.nrm())
  617. {
  618. vtx.nrm(offset+ i).set( 0, 1, 0);
  619. vtx.nrm(offset+resolution1+i).set(N.x*c, N.y, N.x*s);
  620. }
  621. if(vtx.tan())
  622. {
  623. vtx.tan(offset+ i).set(-s, 0, c);
  624. vtx.tan(offset+resolution1+i).set(-s, 0, c);
  625. }
  626. if(vtx.bin())
  627. {
  628. vtx.bin(offset+ i).set(N.y*c, -N.x, N.y*s);
  629. vtx.bin(offset+resolution1+i).set(N.y*c, -N.x, N.y*s);
  630. }
  631. if(vtx.tex0())
  632. {
  633. vtx.tex0(offset+ i).set( 0.5f, 0);
  634. vtx.tex0(offset+resolution1+i).set(Flt(i)/resolution, 1);
  635. }
  636. }
  637. // bottom
  638. REP(resolution-2)(tri++)->set(0, i+1, i+2);
  639. // sides
  640. REP(resolution)(tri++)->set(offset+i, offset+resolution1+i+1, offset+resolution1+i);
  641. transform(Matrix().setPosUp(cone.pos, cone.up));
  642. }else
  643. if(cone.r_high>EPS)
  644. {
  645. offset=resolution;
  646. create(resolution+resolution1*2, 0, resolution-2+resolution, 0, flag&(VTX_NRM_TAN_BIN|VTX_TEX0));
  647. VecI *tri=T.tri.ind();
  648. // vtxs
  649. REP(resolution)
  650. {
  651. Flt c, s; CosSin(c, s, i*PI2/resolution);
  652. vtx.pos (i).set(c*cone.r_high, cone.h, s*cone.r_high);
  653. if(vtx.nrm ())vtx.nrm (i).set(0, 1, 0);
  654. if(vtx.tan ())vtx.tan (i).set(1, 0, 0);
  655. if(vtx.bin ())vtx.bin (i).set(0, 0, -1);
  656. if(vtx.tex0())vtx.tex0(i).set(c, 1-s );
  657. }
  658. Vec2 N(cone.r_high-cone.r_low, cone.h); N=PerpN(N);
  659. REP(resolution1)
  660. {
  661. Flt c, s; CosSin(c, s, i*PI2/resolution);
  662. vtx.pos(offset+ i).set(c*cone.r_high, cone.h, s*cone.r_high);
  663. vtx.pos(offset+resolution1+i).set(c*cone.r_low , 0, s*cone.r_low );
  664. if(vtx.nrm())
  665. {
  666. vtx.nrm(offset+ i).set(N.x*c, N.y, N.x*s);
  667. vtx.nrm(offset+resolution1+i).set( 0, -1, 0);
  668. }
  669. if(vtx.tan())
  670. {
  671. vtx.tan(offset+ i).set(-s, 0, c);
  672. vtx.tan(offset+resolution1+i).set(-s, 0, c);
  673. }
  674. if(vtx.bin())
  675. {
  676. vtx.bin(offset+ i).set(N.y*c, -N.x, N.y*s);
  677. vtx.bin(offset+resolution1+i).set(N.y*c, -N.x, N.y*s);
  678. }
  679. if(vtx.tex0())
  680. {
  681. vtx.tex0(offset+ i).set(Flt(i)/resolution, 0);
  682. vtx.tex0(offset+resolution1+i).set( 0.5f, 1);
  683. }
  684. }
  685. // bottom
  686. REP(resolution-2)(tri++)->set(0, i+2, i+1);
  687. // sides
  688. REP(resolution)(tri++)->set(offset+i, offset+i+1, offset+resolution1+i);
  689. transform(Matrix().setPosUp(cone.pos, cone.up));
  690. }else
  691. {
  692. del();
  693. }
  694. if(!(flag&VTX_TEX0))weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  695. return T;
  696. }
  697. /******************************************************************************/
  698. MeshBase& MeshBase::create(C Torus &torus, UInt flag, Int resolution, Int resolution2)
  699. {
  700. if(resolution <0)resolution =12;else MAX(resolution , 3);
  701. if(resolution2<0)resolution2=12;else MAX(resolution2, 3);
  702. create((resolution+1)*(resolution2+1), 0, 0, resolution*resolution2, flag&(VTX_NRM_TAN_BIN|VTX_TEX0));
  703. VecI4 *quad=T.quad.ind();
  704. Matrix3 m; m.setUp(torus.up);
  705. // vtxs
  706. REP(resolution+1)
  707. {
  708. Vec2 cs; CosSin(cs.x, cs.y, i*PI2/resolution);
  709. Vec d=cs.x*m.x + cs.y*m.z;
  710. REPD(i2, resolution2+1)
  711. {
  712. Vec2 cs2; CosSin(cs2.x, cs2.y, i2*PI2/resolution2);
  713. Vec d2=cs2.x*d + cs2.y*m.y;
  714. Int j=i*(resolution2+1)+i2;
  715. vtx.pos (j)=torus.pos + d*torus.R + d2*torus.r;
  716. if(vtx.nrm ())vtx.nrm (j)=d2;
  717. if(vtx.tan ())vtx.tan (j)=cs.y*m.x - cs.x*m.z;
  718. if(vtx.bin ())vtx.bin (j)=cs2.x*m.y - cs2.y*d;
  719. if(vtx.tex0())vtx.tex0(j).set((1-Flt(i)/resolution)*4, Flt(i2)/resolution2);
  720. }
  721. }
  722. // quads
  723. REPD(i , resolution )
  724. REPD(i2, resolution2)(quad++)->set( i *(resolution2+1) + i2 , i *(resolution2+1) + i2+1,
  725. (i+1)*(resolution2+1) + i2+1, (i+1)*(resolution2+1) + i2 );
  726. if(!(flag&VTX_TEX0))weldVtx(VTX_ALL, EPS, EPS_COL_COS, -1);
  727. return T;
  728. }
  729. /******************************************************************************/
  730. MeshBase& MeshBase::createEdge(C Rect &rect, Bool solid)
  731. {
  732. create(4, 4, 0, 0, solid ? EDGE_FLAG : 0);
  733. vtx .pos(0).set(rect.min.x, rect.max.y, 0);
  734. vtx .pos(1).set(rect.max.x, rect.max.y, 0);
  735. vtx .pos(2).set(rect.max.x, rect.min.y, 0);
  736. vtx .pos(3).set(rect.min.x, rect.min.y, 0);
  737. edge.ind(0).set(0, 1);
  738. edge.ind(1).set(1, 2);
  739. edge.ind(2).set(2, 3);
  740. edge.ind(3).set(3, 0);
  741. if(edge.flag())edge.flag(0)=edge.flag(1)=edge.flag(2)=edge.flag(3)=ETQ_R;
  742. return T;
  743. }
  744. /******************************************************************************/
  745. MeshBase& MeshBase::create(C Shape &shape, UInt flag, Int resolution, Int resolution2)
  746. {
  747. switch(shape.type)
  748. {
  749. case SHAPE_BOX : return create(shape.box , flag, resolution);
  750. case SHAPE_OBOX : return create(shape.obox , flag, resolution);
  751. case SHAPE_BALL : return create(shape.ball , flag, resolution);
  752. case SHAPE_CAPSULE: return create(shape.capsule, flag, resolution, resolution2);
  753. case SHAPE_TUBE : return create(shape.tube , flag, resolution);
  754. case SHAPE_CONE : return create(shape.cone , flag, resolution);
  755. case SHAPE_TORUS : return create(shape.torus , flag, resolution, resolution2);
  756. default : return del();
  757. }
  758. }
  759. /******************************************************************************/
  760. MeshBase& MeshBase::createEdge(C Circle &circle, Bool solid, Int resolution)
  761. {
  762. if(resolution<0)resolution=24;else MAX(resolution, 3);
  763. create(resolution, resolution, 0, 0, solid ? EDGE_FLAG : 0);
  764. FREP(resolution)
  765. {
  766. Vec2 v; CosSin(v.x, v.y, i*-PI2/resolution);
  767. vtx .pos (i).set(circle.pos+v*circle.r, 0);
  768. edge.ind (i).set(i, (i+1)%resolution);
  769. if(edge.flag())edge.flag(i)=ETQ_R;
  770. }
  771. return T;
  772. }
  773. /******************************************************************************/
  774. MeshBase& MeshBase::createEdgeStar(Flt r1, Flt r2, Bool solid, Int resolution)
  775. {
  776. MAX(resolution, 3); resolution*=2;
  777. create(resolution, resolution, 0, 0, solid ? EDGE_FLAG : 0);
  778. FREP(resolution)
  779. {
  780. Flt x, y; CosSin(x, y, PI_2-i*PI2/resolution);
  781. if(i&1) vtx .pos (i).set(x*r1, y*r1, 0);
  782. else vtx .pos (i).set(x*r2, y*r2, 0);
  783. edge.ind (i).set(i, (i+1)%resolution);
  784. if(edge.flag())edge.flag(i)=ETQ_R;
  785. }
  786. return T;
  787. }
  788. /******************************************************************************/
  789. // CONVEX
  790. /******************************************************************************/
  791. struct Face
  792. {
  793. VecI tri ;
  794. Plane plane;
  795. };
  796. struct Convex
  797. {
  798. Memb<Vec > pos ;
  799. Memb<Face> face;
  800. void newFace(Int p0, Int p1, Int p2)
  801. {
  802. Face &f=face.New();
  803. f.tri .set(p0, p1, p2);
  804. f.plane.set(pos[p0], GetNormal(pos[p0], pos[p1], pos[p2]));
  805. }
  806. Bool cutsEps(Vec &pos)
  807. {
  808. if(face.elms())
  809. {
  810. REPA(face)if(Dist(pos, face[i].plane)>EPS)return false;
  811. return true;
  812. }
  813. return false;
  814. }
  815. Flt distPlanar(Vec &pos)
  816. {
  817. Flt d=0; REPA(face)MAX(d, Dist(pos, face[i].plane));
  818. return d;
  819. }
  820. void include(C Vec &pos)
  821. {
  822. Int pos_index=-1;
  823. Memc<VecI2> edge;
  824. REPA(face) // order is important
  825. {
  826. Face &f=face[i];
  827. Flt d=Dist(pos, f.plane);
  828. if( d>EPS) // face requires removing
  829. {
  830. if(pos_index<0){pos_index=T.pos.elms(); T.pos.add(pos);} // add point to container
  831. VecI2 test;
  832. Int t;
  833. test.set(f.tri.c[0], f.tri.c[1]); t=edge.find(test); if(t>=0)edge.remove(t);else{test.reverse(); edge.add(test);}
  834. test.set(f.tri.c[1], f.tri.c[2]); t=edge.find(test); if(t>=0)edge.remove(t);else{test.reverse(); edge.add(test);}
  835. test.set(f.tri.c[2], f.tri.c[0]); t=edge.find(test); if(t>=0)edge.remove(t);else{test.reverse(); edge.add(test);}
  836. face.remove(i);
  837. }
  838. }
  839. // add faces
  840. REPA(edge)newFace(pos_index, edge[i].y, edge[i].x);
  841. }
  842. };
  843. MeshBase& MeshBase::createConvex(C Vec *point, Int points, Int max_points)
  844. {
  845. MeshBase temp; // use 'temp' in case the 'point' comes from 'this'
  846. if(points>=4)
  847. {
  848. Int bound[8]={-1,-1,-1,-1, -1,-1,-1,-1};
  849. Flt dist [8];
  850. // get center
  851. Vec center=0; REP(points)center+=point[i]; center/=points;
  852. // get boundaries
  853. REP(points)
  854. {
  855. Flt d;
  856. Int o=0;
  857. Vec D=point[i]-center;
  858. d= D.x+D.y+D.z; if(bound[o]<0 || d>dist[o]){bound[o]=i; dist[o]=d;} o++;
  859. d= D.x+D.y-D.z; if(bound[o]<0 || d>dist[o]){bound[o]=i; dist[o]=d;} o++;
  860. d= D.x-D.y+D.z; if(bound[o]<0 || d>dist[o]){bound[o]=i; dist[o]=d;} o++;
  861. d= D.x-D.y-D.z; if(bound[o]<0 || d>dist[o]){bound[o]=i; dist[o]=d;} o++;
  862. d=-D.x+D.y+D.z; if(bound[o]<0 || d>dist[o]){bound[o]=i; dist[o]=d;} o++;
  863. d=-D.x+D.y-D.z; if(bound[o]<0 || d>dist[o]){bound[o]=i; dist[o]=d;} o++;
  864. d=-D.x-D.y+D.z; if(bound[o]<0 || d>dist[o]){bound[o]=i; dist[o]=d;} o++;
  865. d=-D.x-D.y-D.z; if(bound[o]<0 || d>dist[o]){bound[o]=i; dist[o]=d;} o++;
  866. }
  867. // move indexes left and remove duplicates
  868. Int bounds=0;
  869. {
  870. Int bound_new[Elms(bound)];
  871. FREPA(bound) // preserve order
  872. {
  873. Int b=bound[i]; if(b>=0)
  874. {
  875. REP(bounds)if(bound_new[i]==b)goto skip;
  876. bound_new[bounds++]=b;
  877. skip:;
  878. }
  879. }
  880. Swap(bound_new, bound);
  881. }
  882. Convex convex;
  883. /*TODO: optimize this?
  884. if(bounds==8) special case of box
  885. {
  886. }else*/
  887. if(bounds>=4)
  888. {
  889. // take 3 first
  890. VecI trii(bound[0], bound[1], bound[2]);
  891. Tri tri (point[trii.x], point[trii.y], point[trii.z]);
  892. // from the rest take the most distant
  893. Int disti=-1;
  894. Flt dist;
  895. for(Int i=3; i<bounds; i++)
  896. {
  897. Flt d=DistPointPlane(point[bound[i]], tri);
  898. if(disti<0 || Abs(d)>Abs(dist)){disti=i; dist=d;}
  899. }
  900. if(dist<=EPS) // if found point is coplanar to the triangle
  901. REP(points) // find a point that is most distant from the triangle plane
  902. {
  903. Flt d=DistPointPlane(point[i], tri);
  904. if(Abs(d)>Abs(dist)){bound[disti]=i; dist=d;}
  905. }
  906. // adjust
  907. if(dist>0)trii.reverse();
  908. Swap(bound[disti], bound[3]);
  909. // build convex from the 4 points
  910. convex.pos.New()=point[trii.x];
  911. convex.pos.New()=point[trii.y];
  912. convex.pos.New()=point[trii.z];
  913. convex.pos.New()=point[bound[3]];
  914. convex.newFace(0, 1, 2);
  915. convex.newFace(1, 0, 3);
  916. convex.newFace(2, 1, 3);
  917. convex.newFace(0, 2, 3);
  918. for(Int i=4; i<bounds; i++)convex.include(point[bound[i]]);
  919. }
  920. if(convex.pos.elms())
  921. {
  922. Memc<Vec> left; REP(points)
  923. {
  924. REPD(b, bounds)if(bound[b]==i)goto already_added;
  925. left.add(point[i]);
  926. already_added:;
  927. }
  928. if(max_points<=0) // insert all
  929. {
  930. REPA(left)if(convex.cutsEps(left[i]))left.remove(i); // early out
  931. REPA(left) convex.include(left[i]);
  932. }
  933. else // limit the vtx number
  934. {
  935. for(; left.elms() && convex.pos.elms()<max_points; )
  936. {
  937. // find the most distant
  938. Int disti=-1;
  939. Flt dist;
  940. for(Int i=0; i<Elms(left); ) // order is important
  941. {
  942. Flt d=convex.distPlanar(left[i]);
  943. if( d>EPS) // potentially to be added
  944. {
  945. if(disti<0 || d>dist){disti=i; dist=d;}
  946. i++;
  947. }
  948. else // it's too close so it can be thrown out
  949. {
  950. left.remove(i);
  951. }
  952. }
  953. if(disti<0)break;
  954. convex.include(left[disti]);
  955. left .remove ( disti );
  956. }
  957. }
  958. temp.create(convex.pos.elms(), 0, convex.face.elms(), 0);
  959. REPA(temp.vtx)temp.vtx.pos(i)=convex.pos [i];
  960. REPA(temp.tri)temp.tri.ind(i)=convex.face[i].tri;
  961. }
  962. }
  963. Swap(T, temp);
  964. return T;
  965. }
  966. /******************************************************************************
  967. MeshBase& createBlade( Int resolution=2, Flt width=0.06f, Flt angle=1.0f, Bool center=false, Flt normal_x_add=2, Flt normal_y_add=3); // create mesh as grass blade, 'resolution'=resolution, 'width'=blade width, 'angle'=blade bend angle, 'center'=if create center vertexes, 'normal_x_add normal_y_add' offsets to vertex normal
  968. MeshBase& createGrass(Int num, C Shape &shape=Shape(Circle(1)), Flt pitch=0.3f, Int resolution=2, Flt width=0.06f, Flt angle=1.0f, Bool center=false, Flt normal_x_add=2, Flt normal_y_add=3); // create mesh as grass , 'num'=number of blades, 'shape'=grass positions, 'pitch'=max angle of blade pitch, 'resolution'=resolution, 'width'=blade width, 'angle'=blade bend angle, 'center'=if create center vertexes, 'normal_x_add normal_y_add' offsets to vertex normal
  969. MeshBase& createRock (Int resolution=3, Int subdivisions=2 ); // create mesh as rock
  970. enum MESH_TREE_FLAG // Mesh Tree Creation Flags
  971. {
  972. MESH_TREE_LEAF_FLAT =0x1, // leafs will be created flat instead of geometrical
  973. MESH_TREE_LEAF_CENTER=0x2, // leafs will be created at center of the branch (valid only with MESH_TREE_LEAF_FLAT flag)
  974. };
  975. Mesh& createTree(MaterialPtr bark_material, Memb<MaterialPtr> &leaf_materials, UInt tree_flag=0, Flt leaf_scale=1, Flt leaf_intensity=1); // create a random tree mesh, 'tree_flag'=MESH_TREE_FLAG
  976. /******************************************************************************/
  977. // GRASS
  978. /******************************************************************************
  979. MeshBase& MeshBase::createBlade(Int resolution, Flt width, Flt angle, Bool center, Flt nrm_x_add, Flt nrm_y_add)
  980. {
  981. if(center)create(1 + (resolution+1)*3 + 1,0,4,resolution*2,VTX_TEX0);
  982. else create(1 + (resolution+1)*2 + 1,0,2,resolution ,VTX_TEX0);
  983. Vec *pos =T.vtx .pos ();
  984. Vec2 *tex =T.vtx .tex0();
  985. VecI *tri =T.tri .ind ();
  986. VecI4 *quad=T.quad.ind ();
  987. // vtxs
  988. (pos++)->zero();
  989. (tex++)->set (0.5f,1.0f);
  990. for(Int i=0; i<=resolution; i++)
  991. {
  992. Flt s=(i+1)/Flt(resolution+2),
  993. w=Sin(s*PI)*width,
  994. y= Sin(s*angle),
  995. z=1-Cos(s*angle);
  996. if(center)
  997. {
  998. (pos++)->set(-w,y-z*w,z+(1-y)*w); (tex++)->set(0 ,1-s);
  999. (pos++)->set( 0,y ,z ); (tex++)->set(0.5f,1-s);
  1000. (pos++)->set( w,y-z*w,z+(1-y)*w); (tex++)->set(1 ,1-s);
  1001. }else
  1002. {
  1003. (pos++)->set(-w,y,z); (tex++)->set(0,1-s);
  1004. (pos++)->set( w,y,z); (tex++)->set(1,1-s);
  1005. }
  1006. }
  1007. pos->set(0,Sin(angle),1-Cos(angle));
  1008. tex->set(0.5f,0.0f);
  1009. // tris
  1010. if(center)
  1011. {
  1012. tri[0].set(0,1,2);
  1013. tri[1].set(0,2,3); Int a=vtxs()-1, b=a-1, c=a-2, d=a-3;
  1014. tri[2].set(a,b,c);
  1015. tri[3].set(a,c,d);
  1016. }else
  1017. {
  1018. tri[0].set(0,1,2); Int a=vtxs()-1, b=a-1, c=a-2;
  1019. tri[1].set(a,b,c);
  1020. }
  1021. // quads
  1022. FREP(resolution)
  1023. {
  1024. if(center)
  1025. {
  1026. Int i3=i*3;
  1027. (quad++)->set(1+i3 , 1+i3+3 , 1+i3+3+1, 1+i3+1);
  1028. (quad++)->set(1+i3+1, 1+i3+3+1, 1+i3+3+2, 1+i3+2);
  1029. }else
  1030. {
  1031. Int i2=i*2;
  1032. (quad++)->set(1+i2, 1+i2+2, 1+i2+2+1, 1+i2+1);
  1033. }
  1034. }
  1035. // nrm
  1036. setNormals();
  1037. if(nrm_x_add || nrm_y_add)
  1038. {
  1039. Vec *pos=T.vtx.pos();
  1040. Vec *nrm=T.vtx.nrm();
  1041. REPA(vtx)
  1042. {
  1043. nrm[i].x+=nrm_x_add*Sign(pos[i].x);
  1044. nrm[i].y+=nrm_y_add;
  1045. nrm[i].normalize();
  1046. }
  1047. }
  1048. return T;
  1049. }
  1050. MeshBase& MeshBase::createGrass(Int num, C Shape &shape, Flt pitch, Int resolution, Flt width, Flt angle, Bool center, Flt nrm_x_add, Flt nrm_y_add)
  1051. {
  1052. MeshBase *mshb; AllocZero(mshb,num);
  1053. REP(num)
  1054. {
  1055. Vec offset=Random(shape);
  1056. if(ShapeType2D(shape.type))Swap(offset.y,offset.z);
  1057. else offset.y=0;
  1058. mshb[i].createBlade(resolution, Random.f(0.9f,1.1f)*width, Random.f(0.9f,1.1f)*angle,center,nrm_x_add,nrm_y_add).transform(Matrix().setRotateXY(Random.f(-pitch,pitch), Random.f(PI2)).move(offset));
  1059. }
  1060. create(mshb,num);
  1061. REP(num)mshb[i].del(); Free(mshb);
  1062. return T;
  1063. }
  1064. /******************************************************************************/
  1065. // ROCK
  1066. /******************************************************************************
  1067. MeshBase& MeshBase::createRock(Int resolution, Int subdivisions)
  1068. {
  1069. create(Ball(0.5),VTX_TEX0,resolution).quadToTri();
  1070. // vtxs
  1071. setVtxDup();
  1072. Vec *pos=vtx.pos();
  1073. Int *dup=vtx.dup();
  1074. REPA(vtx)if(dup[i]==i)pos[i]+=Random(Ball(0.15f));
  1075. REPA(vtx)pos[i]=pos[dup[i]];
  1076. // scale
  1077. Flt f=0.6f,t=1/f;
  1078. scale(Vec(Random.f(f,t), Random.f(f,t), Random.f(f,t)));
  1079. // smooth
  1080. REP(subdivisions)subdivide().setVtxDup();
  1081. // finish
  1082. setTangents();
  1083. return T;
  1084. }
  1085. /******************************************************************************/
  1086. // TREE
  1087. /******************************************************************************/
  1088. #define RES 7
  1089. #define STEP 2
  1090. /******************************************************************************
  1091. struct Branch
  1092. {
  1093. Vec pos[RES+1];
  1094. Flt r [RES+1];
  1095. Flt length;
  1096. Int num,parent;
  1097. Flt step(Flt frac, Vec &pos, Vec &dir)
  1098. {
  1099. Flt length=0;
  1100. FREP(num)
  1101. {
  1102. Vec &p0=T.pos[i],
  1103. &p1=T.pos[i+1],
  1104. d =p1-p0;
  1105. Flt l =d.normalize()/T.length;
  1106. if(frac>=length && frac<=length+l)
  1107. {
  1108. frac=(frac-length)/l;
  1109. dir=d;
  1110. pos=Lerp(p0 ,p1 ,frac);
  1111. return Lerp(r[i],r[i+1],frac);
  1112. }
  1113. length+=l;
  1114. }
  1115. pos=T.pos[0];
  1116. return 0;
  1117. }
  1118. };
  1119. struct Leaf
  1120. {
  1121. Matrix m;
  1122. };
  1123. /******************************************************************************
  1124. static void BranchAdd(Memb<Branch> &branch, C Vec &pos, C Vec &dir, Flt r, Flt length, Int parent, Int step)
  1125. {
  1126. Int num=Mid(Round((length/20)*2*RES),1,RES),
  1127. cur=branch.elms();
  1128. Branch &b=branch.New();
  1129. b.length =length;
  1130. b.parent =parent;
  1131. b.num =num;
  1132. Vec p=pos,
  1133. d=dir;
  1134. FREP(num)
  1135. {
  1136. b.pos[i]=p;
  1137. b.r [i]=r;
  1138. p+=d*length/num;
  1139. d =Random.dir(d,step ? 0.5f : 0.15f);
  1140. r*=Random.f(0.75f,0.85f);
  1141. }
  1142. b.pos[num]=p;
  1143. b.r [num]=0;
  1144. if(step<=STEP)REPD(c,Round(Random.f(0.2f,1.1f)*length))
  1145. {
  1146. Vec pos,dir;
  1147. Flt f=Random.f(0.3f,0.95f);
  1148. Flt r=b.step(f,pos,dir);
  1149. BranchAdd(branch, pos, Random.dir(dir,0.5f,1.2f), Random.f(0.75f,0.85f)*r, Random.f(0.8f,1.2f)*(1-f)*length,cur,step+1);
  1150. }
  1151. }
  1152. static void BranchCreate(Memb<Branch> &branch)
  1153. {
  1154. BranchAdd(branch, Vec(0, 0, 0), Vec(0, 1, 0), Random.f(0.25f, 0.5f), Random.f(15, 20), -1, 0);
  1155. }
  1156. static void BranchDraw(Memb<Branch> &branch)
  1157. {
  1158. REPA(branch)
  1159. {
  1160. Branch &b=branch[i];
  1161. Int r=Max(3,Round(Sqrt(b.r[0])*16));
  1162. REP(b.num)
  1163. {
  1164. Vec &p0=b.pos[i ],
  1165. &p1=b.pos[i+1];
  1166. Cone(b.r[i],b.r[i+1],Dist(p0,p1),p0,!(p1-p0)).draw(WHITE,false,r);
  1167. }
  1168. }
  1169. }
  1170. static void CreateMesh(MeshBase &mshb, Branch &b, MeshBase *inside)
  1171. {
  1172. if(!b.num)mshb.del();else
  1173. {
  1174. Int r =Max(3,Round(Sqrt(b.r[0])*16)),
  1175. r1=r+1;
  1176. mshb.create(r1*b.num+1,0,r,r*(b.num-1), VTX_NRM|VTX_TEX0);
  1177. Vec *pos =mshb.vtx .pos ();
  1178. Vec *nrm =mshb.vtx .nrm ();
  1179. Vec2 *tex =mshb.vtx .tex0();
  1180. VecI *tri =mshb.tri .ind ();
  1181. VecI4 *quad=mshb.quad.ind ();
  1182. Matrix matrix=MatrixIdentity;
  1183. Int v=0;
  1184. Flt t=Random.f();
  1185. FREP(b.num)
  1186. {
  1187. Vec dir =b.pos[i+1]-b.pos[i]; Flt length=dir.normalize();
  1188. matrix.orn()*=Matrix3().setRotation(matrix.y, dir);
  1189. matrix.pos =b.pos[i];
  1190. REPD(j,r1)
  1191. {
  1192. Flt c, s; CosSin(c, s, j*PI2/r);
  1193. pos[v+j].set(c*b.r[i],0,s*b.r[i]);
  1194. nrm[v+j].set(c ,0,s );
  1195. tex[v+j].set(Flt(j)/r,t);
  1196. }
  1197. Transform(pos+v,matrix ,r1);
  1198. Transform(nrm+v,matrix.orn(),r1); Normalize(nrm+v,r1);
  1199. if(i==b.num-1)
  1200. {
  1201. Int last=mshb.vtxs()-1;
  1202. REPD(j,r)(tri++)->set(last,v+j+1,v+j);
  1203. }else
  1204. {
  1205. REPD(j,r)(quad++)->set(v+r1+j,v+r1+j+1,v+j+1,v+j);
  1206. }
  1207. if(inside && i==2)
  1208. {
  1209. inside->create(r,0,r-2,0, VTX_TEX0);
  1210. REPD(j,r)
  1211. {
  1212. Flt c, s; CosSin(c, s, j*PI2/r);
  1213. inside->vtx.pos (j)=pos[v+j];
  1214. inside->vtx.tex0(j).set(c*0.3f+0.5f,s*-0.3f+0.5f);
  1215. }
  1216. REPD(j,r-2)inside->tri.ind(j).set(0,j+2,j+1);
  1217. }
  1218. t-=length;
  1219. v+=r1;
  1220. }
  1221. pos[v]=b.pos[b.num];
  1222. nrm[v]=matrix.y;
  1223. tex[v].set(0.5f,t);
  1224. mshb.texScale(Vec2(1,(b.parent==-1) ? 0.35f : 0.1f/b.r[0]))
  1225. .texMove (Random.vec2());
  1226. }
  1227. }
  1228. static void LeafCreate(Memb<Leaf> &leaf, Memb<Branch> &branch, UInt tree_flag, Flt leaf_scale, Flt leaf_intensity)
  1229. {
  1230. FREPA(branch)
  1231. {
  1232. Branch &b=branch[i];
  1233. REPD(j,b.num)
  1234. {
  1235. Flt r=Avg(b.r[j],b.r[j+1]);
  1236. if( r<=0.1f)
  1237. {
  1238. Vec &p0 =b.pos[j],
  1239. &p1 =b.pos[j+1],
  1240. dir =p1-p0;
  1241. Flt length=dir.normalize();
  1242. REPD(cn,Round(Random.f(0.75f,1.25f)*10*length*leaf_intensity))
  1243. {
  1244. Leaf &l=leaf.New();
  1245. Matrix &m=l.m;
  1246. m.setRotateX(Random.f(DegToRad(45),(tree_flag&MESH_TREE_LEAF_FLAT) ? DegToRad(180) : DegToRad(90)))
  1247. . rotateY(Random.f(PI2))
  1248. . scale (Random.f(0.75f,1.3f)*((tree_flag&MESH_TREE_LEAF_FLAT) ? 0.4f : 0.5f)*leaf_scale);
  1249. Flt c, s; CosSin(c, s, Random.f(PI2));
  1250. Flt f=Random.f();
  1251. Vec y=PerpN ( dir),
  1252. x=CrossN (y,dir);
  1253. r=Lerp (b.r[j],b.r[j+1],f);
  1254. m+=p0
  1255. +dir*(f*length)
  1256. +x *(r* c)
  1257. +y *(r* s);
  1258. }
  1259. }
  1260. }
  1261. }
  1262. }
  1263. static void CreateMesh(MeshBase &mshb,Leaf &leaf,UInt tree_flag)
  1264. {
  1265. if(tree_flag&MESH_TREE_LEAF_FLAT)
  1266. {
  1267. mshb.createPlane(2,2,VTX_TEX0|VTX_NRM).move(Vec(-0.5,0,0));
  1268. REPA(mshb.vtx)
  1269. {
  1270. mshb.vtx.nrm(i).x+=Sign(mshb.vtx.pos(i).x);
  1271. mshb.vtx.nrm(i) +=Random.vec(-0.2f,0.2f);
  1272. mshb.vtx.nrm(i).normalize();
  1273. }
  1274. if(tree_flag&MESH_TREE_LEAF_CENTER)mshb.move(Vec(0,-0.5,0));
  1275. }else
  1276. {
  1277. mshb.createBlade(1,0.2f,1.5f,false,1,0);
  1278. }
  1279. mshb*=leaf.m;
  1280. mshb.include(VTX_HLP); REPA(mshb.vtx)mshb.vtx.hlp(i)=leaf.m.pos; // set helper positions to leaf start
  1281. }
  1282. static Mesh& setTree(Mesh &mesh, MaterialPtr bark_material, Memb<MaterialPtr> &leaf_materials, Memb<Branch> &branch, UInt tree_flag, Flt leaf_scale, Flt leaf_intensity)
  1283. {
  1284. Bool inside=false;
  1285. Memc<MeshPart> p;
  1286. // inside
  1287. if(inside)
  1288. {
  1289. MeshPart &part=p.New(); // create 0-th MeshPart for 'inside'
  1290. part.flag=MSHP_NO_PHYS_BODY;
  1291. }
  1292. // branches
  1293. REPA(branch)
  1294. {
  1295. MeshPart &part=p.New();
  1296. part.material(bark_material);
  1297. CreateMesh(part.base,branch[i],(!inside || i) ? null : &p(0).base);
  1298. }
  1299. // leafs
  1300. if(leaf_materials.elms())
  1301. {
  1302. Memb<Leaf> leaf; LeafCreate(leaf,branch,tree_flag,leaf_scale,leaf_intensity);
  1303. REPA(leaf)
  1304. {
  1305. MeshPart &part=p.New();
  1306. CreateMesh(part.base,leaf[i],tree_flag);
  1307. part.material(leaf_materials[i%leaf_materials.elms()]);
  1308. part.flag=MSHP_NO_PHYS_BODY;
  1309. }
  1310. }
  1311. // finish
  1312. {
  1313. mesh.create (p.elms() ); FREPA(mesh)Swap(mesh.part(i),p[i]);
  1314. mesh.joinAll(true, true, false, 0);
  1315. mesh.setTangents()
  1316. .setBox ();
  1317. }
  1318. return mesh;
  1319. }
  1320. Mesh& Mesh::createTree(MaterialPtr bark_material, Memb<MaterialPtr> &leaf_materials, UInt tree_flag, Flt leaf_scale, Flt leaf_intensity)
  1321. {
  1322. Memb<Branch> branch;
  1323. BranchCreate(branch);
  1324. setTree(T,bark_material,leaf_materials,branch,tree_flag,leaf_scale,leaf_intensity);
  1325. return T;
  1326. }
  1327. /******************************************************************************/
  1328. }
  1329. /******************************************************************************/