Mshb Operations.cpp 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. // WELD
  6. /******************************************************************************/
  7. static void Weld(MeshBase &mshb, UInt flag, Flt pos_eps, Flt nrm_cos, Flt remove_degenerate_faces_eps, Bool flat)
  8. {
  9. if(pos_eps>=0)
  10. {
  11. if(flat)mshb.setVtxDup2D(flag, pos_eps, nrm_cos);
  12. else mshb.setVtxDup (flag, pos_eps, nrm_cos);
  13. Int *vtx_dup=mshb.vtx .dup();
  14. VecI2 *edg_ind=mshb.edge.ind();
  15. VecI *tri_ind=mshb.tri .ind();
  16. VecI4 *qud_ind=mshb.quad.ind();
  17. Memt<Bool> is;
  18. // vtx is
  19. is.setNum(mshb.vtxs()); REPAO(is)=(vtx_dup[i]==i);
  20. Int vtxs=CountIs(is);
  21. if( vtxs==mshb.vtxs())
  22. {
  23. mshb.exclude(VTX_DUP|ADJ_ALL);
  24. }else
  25. {
  26. Memt<Int> vtx_remap; SetRemap(vtx_remap, is, mshb.vtxs());
  27. REPA(vtx_remap)if(!is[i])vtx_remap[i]=vtx_remap[vtx_dup[i]];
  28. mshb.exclude(VTX_DUP|ADJ_ALL);
  29. MeshBase temp(vtxs, 0, 0, 0, mshb.flag());
  30. // vtx
  31. {
  32. temp.copyVtxs(mshb, is);
  33. }
  34. // quad
  35. Memb<VecI4> quad_tri;
  36. {
  37. is.setNum(mshb.quads());
  38. FREPA(mshb.quad)
  39. {
  40. VecI4 f=qud_ind[i], r=f; r.remapAll(vtx_remap);
  41. if(!(is[i]=r.allDifferent()))
  42. {
  43. if(r.c[0]!=r.c[1] && r.c[1]!=r.c[3] && r.c[0]!=r.c[3])quad_tri.New().set(f.c[0], f.c[1], f.c[3], i);else // 013
  44. if(r.c[0]!=r.c[1] && r.c[1]!=r.c[2] && r.c[0]!=r.c[2])quad_tri.New().set(f.c[0], f.c[1], f.c[2], i);else // 012
  45. if(r.c[1]!=r.c[2] && r.c[2]!=r.c[3] && r.c[1]!=r.c[3])quad_tri.New().set(f.c[1], f.c[2], f.c[3], i);else // 123
  46. if(r.c[2]!=r.c[3] && r.c[3]!=r.c[0] && r.c[2]!=r.c[0])quad_tri.New().set(f.c[2], f.c[3], f.c[0], i); // 230
  47. }
  48. }
  49. temp.quad._elms=CountIs(is); temp.include(QUAD_ALL&mshb.flag());
  50. temp.copyQuads(mshb, is);
  51. IndRemap(vtx_remap, temp.quad.ind(), temp.quads());
  52. }
  53. // tri
  54. {
  55. is.setNum(mshb.tris()); FREPA(mshb.tri){VecI f=tri_ind[i]; f.remapAll(vtx_remap); is[i]=f.allDifferent();}
  56. Int tris=CountIs(is);
  57. UInt flag=mshb.flag(), f=(flag&TRI_ALL);
  58. if(quad_tri.elms())
  59. {
  60. f|=TRI_IND;
  61. if(flag&QUAD_NRM )f|=TRI_NRM;
  62. if(flag&QUAD_FLAG)f|=TRI_FLAG;
  63. if(flag&QUAD_ID )f|=TRI_ID;
  64. }
  65. temp.tri._elms=tris+quad_tri.elms(); temp.include(f);
  66. temp.copyTris(mshb, is);
  67. if(temp.tri.nrm () && !mshb.tri.nrm ())ZeroN(temp.tri.nrm (), tris);
  68. if(temp.tri.flag() && !mshb.tri.flag())ZeroN(temp.tri.flag(), tris);
  69. if(temp.tri.id () && !mshb.tri.id ())ZeroN(temp.tri.id (), tris);
  70. REPA(quad_tri)
  71. {
  72. VecI4 &v=quad_tri[i];
  73. temp.tri.ind (tris+i)=v.xyz;
  74. if(temp.tri.nrm ())temp.tri.nrm (tris+i)=(mshb.quad.nrm () ? mshb.quad.nrm (v.w) : 0);
  75. if(temp.tri.flag())temp.tri.flag(tris+i)=(mshb.quad.flag() ? mshb.quad.flag(v.w) : 0);
  76. if(temp.tri.id ())temp.tri.id (tris+i)=(mshb.quad.id () ? mshb.quad.id (v.w) : -1);
  77. }
  78. IndRemap(vtx_remap, temp.tri.ind(), temp.tris());
  79. }
  80. // edge
  81. {
  82. is.setNum(mshb.edges()); FREPA(mshb.edge){Int *p=edg_ind[i].c; is[i]=(vtx_remap[p[0]]!=vtx_remap[p[1]]);}
  83. temp.edge._elms=CountIs(is); temp.include(EDGE_ALL&mshb.flag());
  84. temp.copyEdges(mshb, is);
  85. IndRemap(vtx_remap, temp.edge.ind(), temp.edges());
  86. }
  87. // remove degenerate faces
  88. if(remove_degenerate_faces_eps>=0)temp.removeDegenerateFaces(remove_degenerate_faces_eps);
  89. // finish
  90. Swap(mshb, temp);
  91. }
  92. }
  93. }
  94. MeshBase& MeshBase::weldVtx2D(UInt flag, Flt pos_eps, Flt nrm_cos, Flt remove_degenerate_faces_eps) {Weld(T, flag, pos_eps, nrm_cos, remove_degenerate_faces_eps, true ); return T;}
  95. MeshBase& MeshBase::weldVtx (UInt flag, Flt pos_eps, Flt nrm_cos, Flt remove_degenerate_faces_eps) {Weld(T, flag, pos_eps, nrm_cos, remove_degenerate_faces_eps, false); return T;}
  96. /******************************************************************************/
  97. MeshBase& MeshBase::weldVtxValues(UInt flag, Flt pos_eps, Flt nrm_cos, Flt remove_degenerate_faces_eps)
  98. {
  99. flag&=T.flag();
  100. if(flag&(VTX_POS|VTX_NRM_TAN_BIN|VTX_HLP|VTX_TEX_ALL|VTX_COLOR|VTX_MATERIAL|VTX_SKIN|VTX_SIZE))
  101. {
  102. setVtxDup(0, pos_eps, nrm_cos);
  103. Memt<Int > num ; num .setNumZero(vtxs());
  104. Memt<VecI4> color; if(flag&VTX_COLOR)color.setNumZero(vtxs());
  105. // sum all values in duplicates
  106. REPA(vtx)
  107. {
  108. Int d=vtx.dup(i); num[d]++; if(d!=i)
  109. {
  110. if(flag&VTX_POS )vtx.pos (i) =vtx.pos (d);
  111. if(flag&VTX_MATERIAL)vtx.material(i) =vtx.material(d); // !! sum must be equal to 255 !!
  112. if(flag&VTX_MATRIX )vtx.matrix (i) =vtx.matrix (d);
  113. if(flag&VTX_BLEND )vtx.blend (i) =vtx.blend (d); // !! sum must be equal to 255 !!
  114. if(flag&VTX_NRM )vtx.nrm (d)+=vtx.nrm (i);
  115. if(flag&VTX_TAN )vtx.tan (d)+=vtx.tan (i);
  116. if(flag&VTX_BIN )vtx.bin (d)+=vtx.bin (i);
  117. if(flag&VTX_HLP )vtx.hlp (d)+=vtx.hlp (i);
  118. if(flag&VTX_TEX0 )vtx.tex0 (d)+=vtx.tex0 (i);
  119. if(flag&VTX_TEX1 )vtx.tex1 (d)+=vtx.tex1 (i);
  120. if(flag&VTX_TEX2 )vtx.tex2 (d)+=vtx.tex2 (i);
  121. if(flag&VTX_SIZE )vtx.size (d)+=vtx.size (i);
  122. }
  123. if(flag&VTX_COLOR)color[d]+=vtx.color(i).v4;
  124. }
  125. // first calculate the average values, then set those values
  126. if(flag&VTX_NRM ){REPA(vtx)if(vtx.dup(i)==i)vtx.nrm (i).normalize(); REPA(vtx)vtx.nrm (i)=vtx.nrm (vtx.dup(i));}
  127. if(flag&VTX_TAN ){REPA(vtx)if(vtx.dup(i)==i)vtx.tan (i).normalize(); REPA(vtx)vtx.tan (i)=vtx.tan (vtx.dup(i));}
  128. if(flag&VTX_BIN ){REPA(vtx)if(vtx.dup(i)==i)vtx.bin (i).normalize(); REPA(vtx)vtx.bin (i)=vtx.bin (vtx.dup(i));}
  129. if(flag&VTX_HLP ){REPA(vtx)if(vtx.dup(i)==i)vtx.hlp (i)/= num[i]; REPA(vtx)vtx.hlp (i)=vtx.hlp (vtx.dup(i));}
  130. if(flag&VTX_TEX0 ){REPA(vtx)if(vtx.dup(i)==i)vtx.tex0(i)/= num[i]; REPA(vtx)vtx.tex0(i)=vtx.tex0(vtx.dup(i));}
  131. if(flag&VTX_TEX1 ){REPA(vtx)if(vtx.dup(i)==i)vtx.tex1(i)/= num[i]; REPA(vtx)vtx.tex1(i)=vtx.tex1(vtx.dup(i));}
  132. if(flag&VTX_TEX2 ){REPA(vtx)if(vtx.dup(i)==i)vtx.tex2(i)/= num[i]; REPA(vtx)vtx.tex2(i)=vtx.tex2(vtx.dup(i));}
  133. if(flag&VTX_SIZE ){REPA(vtx)if(vtx.dup(i)==i)vtx.size(i)/= num[i]; REPA(vtx)vtx.size(i)=vtx.size(vtx.dup(i));}
  134. if(flag&VTX_COLOR){REPA(vtx)if(vtx.dup(i)==i)
  135. {
  136. VecI4 &c=color[i];
  137. Int n=num [i];
  138. vtx.color(i).set(DivRound(c.x, n), DivRound(c.y, n), DivRound(c.z, n), DivRound(c.w, n));
  139. }
  140. REPA(vtx)vtx.color(i)=vtx.color(vtx.dup(i));
  141. }
  142. if((flag&VTX_POS) && remove_degenerate_faces_eps>=0)removeDegenerateFaces(remove_degenerate_faces_eps);
  143. }
  144. return T;
  145. }
  146. /******************************************************************************/
  147. void MeshBase::copyVtx(Int i, MeshBase &dest, Int dest_i)C
  148. {
  149. if(InRange(i, vtx) && InRange(dest_i, dest.vtx))
  150. {
  151. if(dest.vtx.pos ())dest.vtx.pos (dest_i)=(vtx.pos () ? vtx.pos (i) : 0);
  152. if(dest.vtx.nrm ())dest.vtx.nrm (dest_i)=(vtx.nrm () ? vtx.nrm (i) : 0);
  153. if(dest.vtx.tan ())dest.vtx.tan (dest_i)=(vtx.tan () ? vtx.tan (i) : 0);
  154. if(dest.vtx.bin ())dest.vtx.bin (dest_i)=(vtx.bin () ? vtx.bin (i) : 0);
  155. if(dest.vtx.hlp ())dest.vtx.hlp (dest_i)=(vtx.hlp () ? vtx.hlp (i) : 0);
  156. if(dest.vtx.tex0 ())dest.vtx.tex0 (dest_i)=(vtx.tex0 () ? vtx.tex0 (i) : 0);
  157. if(dest.vtx.tex1 ())dest.vtx.tex1 (dest_i)=(vtx.tex1 () ? vtx.tex1 (i) : 0);
  158. if(dest.vtx.tex2 ())dest.vtx.tex2 (dest_i)=(vtx.tex2 () ? vtx.tex2 (i) : 0);
  159. if(dest.vtx.matrix ())dest.vtx.matrix (dest_i)=(vtx.matrix () ? vtx.matrix (i) : 0);
  160. if(dest.vtx.blend ())dest.vtx.blend (dest_i)=(vtx.blend () ? vtx.blend (i) : VecB4(255, 0, 0, 0)); // !! sum must be equal to 255 !!
  161. if(dest.vtx.size ())dest.vtx.size (dest_i)=(vtx.size () ? vtx.size (i) : 0);
  162. if(dest.vtx.material())dest.vtx.material(dest_i)=(vtx.material() ? vtx.material(i) : 0);
  163. if(dest.vtx.color ())dest.vtx.color (dest_i)=(vtx.color () ? vtx.color (i) : TRANSPARENT);
  164. if(dest.vtx.flag ())dest.vtx.flag (dest_i)=(vtx.flag () ? vtx.flag (i) : 0);
  165. if(dest.vtx.dup ())dest.vtx.dup (dest_i)=(vtx.dup () ? vtx.dup (i) : dest_i);
  166. }
  167. }
  168. /******************************************************************************/
  169. struct WeldEdge
  170. {
  171. Int id;
  172. UInt flag;
  173. VecI2 ind;
  174. Vec nrm;
  175. };
  176. static Int CompareWeldEdge(C WeldEdge &e0, C WeldEdge &e1)
  177. {
  178. if(e0.ind.c[0]<e1.ind.c[0])return -1;
  179. if(e0.ind.c[0]>e1.ind.c[0])return +1;
  180. if(e0.ind.c[1]<e1.ind.c[1])return -1;
  181. if(e0.ind.c[1]>e1.ind.c[1])return +1;
  182. return 0;
  183. }
  184. MeshBase& MeshBase::weldEdge()
  185. {
  186. if(edge.ind())
  187. {
  188. // copy edges
  189. Memt<Bool> edge_is; edge_is.setNum(edges()); SetMem(edge_is.data(), 1, edge_is.elms());
  190. Memt<WeldEdge> w_edge ; w_edge .setNum(edges());
  191. FREPA(edge)
  192. {
  193. w_edge[i].ind =edge.ind (i);
  194. if(edge.id ())w_edge[i].id =edge.id (i);
  195. if(edge.nrm ())w_edge[i].nrm =edge.nrm (i);
  196. if(edge.flag())w_edge[i].flag=edge.flag(i);
  197. if(w_edge[i].ind.c[0]>w_edge[i].ind.c[1])
  198. {
  199. w_edge[i].ind.reverse();
  200. //w_edge[i].id .reverse();
  201. if(!edge.flag())w_edge[i].nrm.chs ();
  202. w_edge[i].flag=EtqFlagSwap(w_edge[i].flag);
  203. }
  204. }
  205. // check for duplicate edges
  206. w_edge.sort(CompareWeldEdge);
  207. FREPA(edge)if(edge_is[i])
  208. {
  209. Int ind0=w_edge[i].ind.c[0];
  210. for(Int j=i+1; j<edges(); j++)if(edge_is[j])
  211. {
  212. if(w_edge[j].ind.c[0]!=ind0)break;
  213. if(w_edge[j].ind.c[1]==w_edge[i].ind.c[1])
  214. {
  215. w_edge [i].nrm +=w_edge[j].nrm;
  216. w_edge [i].flag|=w_edge[j].flag;
  217. //w_edge [i].id OP w_edge[j].id;
  218. edge_is[j]=0;
  219. }
  220. }
  221. }
  222. // create
  223. Int edges =CountIs(edge_is);
  224. if( edges!=T.edges())
  225. {
  226. Bool nrm = (edge.nrm ()!=null),
  227. flag= (edge.flag()!=null),
  228. id = (edge.id ()!=null);
  229. Int num =T.edges();
  230. exclude(EDGE_ALL|FACE_ADJ_EDGE); edge._elms=edges;
  231. include(EDGE_IND| (nrm ? EDGE_NRM : 0) | (flag ? EDGE_FLAG : 0) | (id ? EDGE_ID : 0));
  232. edges=0; FREP(num)if(edge_is[i])edge.ind (edges++)= w_edge[i].ind;
  233. edges=0; if(nrm )FREP(num)if(edge_is[i])edge.nrm (edges++)=!w_edge[i].nrm;
  234. edges=0; if(flag)FREP(num)if(edge_is[i])edge.flag(edges++)= w_edge[i].flag;
  235. edges=0; if(id )FREP(num)if(edge_is[i])edge.id (edges++)= w_edge[i].id;
  236. }
  237. }
  238. return T;
  239. }
  240. /******************************************************************************/
  241. MeshBase& MeshBase::explodeVtxs()
  242. {
  243. MeshBase temp(edges()*2 + tris()*3 + quads()*4, edges(), tris(), quads(), flag()&~VTX_DUP);
  244. Int v=0;
  245. temp.copyEdges(T); FREPA(temp.edge){VecI2 &edge=temp.edge.ind(i); FREPA(edge){copyVtx(edge.c[i], temp, v); edge.c[i]=v++;}}
  246. temp.copyTris (T); FREPA(temp.tri ){VecI &tri =temp.tri .ind(i); FREPA(tri ){copyVtx(tri .c[i], temp, v); tri .c[i]=v++;}}
  247. temp.copyQuads(T); FREPA(temp.quad){VecI4 &quad=temp.quad.ind(i); FREPA(quad){copyVtx(quad.c[i], temp, v); quad.c[i]=v++;}}
  248. Swap(temp, T);
  249. return T;
  250. }
  251. /******************************************************************************/
  252. // TESSELATE
  253. /******************************************************************************/
  254. static INLINE Flt Crease(C Vec &n) {Flt l=n.length2(); return l ? 1/Sqrt(l) : 0;} // this function will make the formula work as if 'n' is normalized and then final value scaled by original length, scale is performed to avoid cases where both normal vectors are similar and its cross product has very small length (direction could be incorrect due to precision issues)
  255. struct TriHull
  256. {
  257. Vec P0, P1, P2, B210, B120, B021, B012, B102, B201, B111,
  258. N0, N1, N2, N110, N011, N101;
  259. #if 0 // unoptimized original version
  260. void set01()
  261. {
  262. B210=(2*P0 + P1 - Dot(P1-P0, N0)*N0)/3;
  263. B120=(2*P1 + P0 - Dot(P0-P1, N1)*N1)/3;
  264. }
  265. void set12()
  266. {
  267. B021=(2*P1 + P2 - Dot(P2-P1, N1)*N1)/3;
  268. B012=(2*P2 + P1 - Dot(P1-P2, N2)*N2)/3;
  269. }
  270. void set20()
  271. {
  272. B102=(2*P2 + P0 - Dot(P0-P2, N2)*N2)/3;
  273. B201=(2*P0 + P2 - Dot(P2-P0, N0)*N0)/3;
  274. }
  275. void set01(C Vec &NA, C Vec &NB)
  276. {
  277. Vec N=CrossN(N0, NA); B210=P0+(Dot(P1-P0, N)*Crease(N)/3)*N;
  278. N=CrossN(N1, NB); B120=P1+(Dot(P0-P1, N)*Crease(N)/3)*N;
  279. }
  280. void set12(C Vec &NA, C Vec &NB)
  281. {
  282. Vec N=CrossN(N1, NA); B021=P1+(Dot(P2-P1, N)*Crease(N)/3)*N;
  283. N=CrossN(N2, NB); B012=P2+(Dot(P1-P2, N)*Crease(N)/3)*N;
  284. }
  285. void set20(C Vec &NA, C Vec &NB)
  286. {
  287. Vec N=CrossN(N2, NA); B102=P2+(Dot(P0-P2, N)*Crease(N)/3)*N;
  288. N=CrossN(N0, NB); B201=P0+(Dot(P2-P0, N)*Crease(N)/3)*N;
  289. }
  290. void finalize()
  291. {
  292. Vec E=(B210+B120+B021+B012+B102+B201)/6,
  293. V=(P0+P1+P2)/3;
  294. B111=E+(E-V)/2;
  295. Flt V01=2 * Dot(P1-P0, N0+N1) / Dot(P1-P0, P1-P0); N110=N0 + N1 - V01*(P1-P0); N110.normalize();
  296. Flt V12=2 * Dot(P2-P1, N1+N2) / Dot(P2-P1, P2-P1); N011=N1 + N2 - V12*(P2-P1); N011.normalize();
  297. Flt V20=2 * Dot(P0-P2, N2+N0) / Dot(P0-P2, P0-P2); N101=N2 + N0 - V20*(P0-P2); N101.normalize();
  298. }
  299. void set(Vec &pos, Vec &nrm, Flt U, Flt V)
  300. {
  301. Flt W=1-U-V,
  302. UU=Sqr(U), VV=Sqr(V), WW=Sqr(W),
  303. UU3=UU*3,
  304. VV3=VV*3,
  305. WW3=WW*3;
  306. pos=P0 * (WW * W)
  307. + P1 * (UU * U)
  308. + P2 * (VV * V)
  309. + B210 * (WW3 * U)
  310. + B120 * (W * UU3)
  311. + B201 * (WW3 * V)
  312. + B021 * (UU3 * V)
  313. + B102 * (W * VV3)
  314. + B012 * (U * VV3)
  315. + B111 * (6 * W * U * V);
  316. nrm=N0 * WW
  317. + N1 * UU
  318. + N2 * VV
  319. + N110 * (W * U)
  320. + N011 * (U * V)
  321. + N101 * (W * V);
  322. nrm.normalize();
  323. }
  324. #else // optimized, where all B* are 3x bigger, except 'B111' which is 6x bigger
  325. void set01()
  326. {
  327. B210=2*P0 + P1 - Dot(P1-P0, N0)*N0;
  328. B120=2*P1 + P0 - Dot(P0-P1, N1)*N1;
  329. }
  330. void set12()
  331. {
  332. B021=2*P1 + P2 - Dot(P2-P1, N1)*N1;
  333. B012=2*P2 + P1 - Dot(P1-P2, N2)*N2;
  334. }
  335. void set20()
  336. {
  337. B102=2*P2 + P0 - Dot(P0-P2, N2)*N2;
  338. B201=2*P0 + P2 - Dot(P2-P0, N0)*N0;
  339. }
  340. void set01(C Vec &NA, C Vec &NB)
  341. {
  342. Vec N=Cross(N0, NA); B210=P0*3+(Dot(P1-P0, N)*Crease(N))*N;
  343. N=Cross(N1, NB); B120=P1*3+(Dot(P0-P1, N)*Crease(N))*N;
  344. }
  345. void set12(C Vec &NA, C Vec &NB)
  346. {
  347. Vec N=Cross(N1, NA); B021=P1*3+(Dot(P2-P1, N)*Crease(N))*N;
  348. N=Cross(N2, NB); B012=P2*3+(Dot(P1-P2, N)*Crease(N))*N;
  349. }
  350. void set20(C Vec &NA, C Vec &NB)
  351. {
  352. Vec N=Cross(N2, NA); B102=P2*3+(Dot(P0-P2, N)*Crease(N))*N;
  353. N=Cross(N0, NB); B201=P0*3+(Dot(P2-P0, N)*Crease(N))*N;
  354. }
  355. void finalize()
  356. {
  357. Vec E=B210+B120+B021+B012+B102+B201,
  358. V=P0+P1+P2;
  359. B111=E*0.5f-V;
  360. Flt V01=2 * Dot(P1-P0, N0+N1) / Dot(P1-P0, P1-P0); N110=N0 + N1 - V01*(P1-P0); N110.normalize();
  361. Flt V12=2 * Dot(P2-P1, N1+N2) / Dot(P2-P1, P2-P1); N011=N1 + N2 - V12*(P2-P1); N011.normalize();
  362. Flt V20=2 * Dot(P0-P2, N2+N0) / Dot(P0-P2, P0-P2); N101=N2 + N0 - V20*(P0-P2); N101.normalize();
  363. }
  364. void set(Vec &pos, Vec &nrm, Flt U, Flt V)
  365. {
  366. Flt W=1-U-V,
  367. UU=Sqr(U), VV=Sqr(V), WW=Sqr(W);
  368. pos=P0 * (WW * W)
  369. + P1 * (UU * U)
  370. + P2 * (VV * V)
  371. + B210 * (WW * U)
  372. + B120 * (W * UU)
  373. + B201 * (WW * V)
  374. + B021 * (UU * V)
  375. + B102 * (W * VV)
  376. + B012 * (U * VV)
  377. + B111 * (W * U * V);
  378. nrm=N0 * WW
  379. + N1 * UU
  380. + N2 * VV
  381. + N110 * (W * U)
  382. + N011 * (U * V)
  383. + N101 * (W * V);
  384. nrm.normalize();
  385. }
  386. #endif
  387. };
  388. struct QuadHull
  389. {
  390. Vec P0, P1, P2, P3, B01, B10, B12, B21, B23, B32, B30, B03, B02, B13, B20, B31,
  391. N0, N1, N2, N3, N01, N12, N23, N30, N0123;
  392. void set01()
  393. {
  394. B01=(2*P0 + P1 - Dot(P1 - P0, N0)*N0)/3;
  395. B10=(2*P1 + P0 - Dot(P0 - P1, N1)*N1)/3;
  396. }
  397. void set12()
  398. {
  399. B12=(2*P1 + P2 - Dot(P2 - P1, N1)*N1)/3;
  400. B21=(2*P2 + P1 - Dot(P1 - P2, N2)*N2)/3;
  401. }
  402. void set23()
  403. {
  404. B23=(2*P2 + P3 - Dot(P3 - P2, N2)*N2)/3;
  405. B32=(2*P3 + P2 - Dot(P2 - P3, N3)*N3)/3;
  406. }
  407. void set30()
  408. {
  409. B30=(2*P3 + P0 - Dot(P0 - P3, N3)*N3)/3;
  410. B03=(2*P0 + P3 - Dot(P3 - P0, N0)*N0)/3;
  411. }
  412. void set01(C Vec &NA, C Vec &NB)
  413. {
  414. Vec N=Cross(N0, NA); B01=P0+(Dot(P1-P0, N)*Crease(N)/3)*N;
  415. N=Cross(N1, NB); B10=P1+(Dot(P0-P1, N)*Crease(N)/3)*N;
  416. }
  417. void set12(C Vec &NA, C Vec &NB)
  418. {
  419. Vec N=Cross(N1, NA); B12=P1+(Dot(P2-P1, N)*Crease(N)/3)*N;
  420. N=Cross(N2, NB); B21=P2+(Dot(P1-P2, N)*Crease(N)/3)*N;
  421. }
  422. void set23(C Vec &NA, C Vec &NB)
  423. {
  424. Vec N=Cross(N2, NA); B23=P2+(Dot(P3-P2, N)*Crease(N)/3)*N;
  425. N=Cross(N3, NB); B32=P3+(Dot(P2-P3, N)*Crease(N)/3)*N;
  426. }
  427. void set30(C Vec &NA, C Vec &NB)
  428. {
  429. Vec N=Cross(N3, NA); B30=P3+(Dot(P0-P3, N)*Crease(N)/3)*N;
  430. N=Cross(N0, NB); B03=P0+(Dot(P3-P0, N)*Crease(N)/3)*N;
  431. }
  432. void finalize()
  433. {
  434. Vec Q=B01+B10+B12+B21+B23+B32+B30+B03;
  435. Vec E0=(2*(B01+B03+Q) - (B21+B23))/18, V0=(4*P0 + 2*(P3+P1) + P2)/9; B02=E0+(E0-V0)/2;
  436. Vec E1=(2*(B12+B10+Q) - (B32+B30))/18, V1=(4*P1 + 2*(P0+P2) + P3)/9; B13=E1+(E1-V1)/2;
  437. Vec E2=(2*(B23+B21+Q) - (B03+B01))/18, V2=(4*P2 + 2*(P1+P3) + P0)/9; B20=E2+(E2-V2)/2;
  438. Vec E3=(2*(B30+B32+Q) - (B10+B12))/18, V3=(4*P3 + 2*(P2+P0) + P1)/9; B31=E3+(E3-V3)/2;
  439. Flt V01=2*(Dot(P1-P0, N0+N1) / Dot(P1-P0, P1-P0)); N01=N0 + N1 - V01*(P1-P0); N01.normalize();
  440. Flt V12=2*(Dot(P2-P1, N1+N2) / Dot(P2-P1, P2-P1)); N12=N1 + N2 - V12*(P2-P1); N12.normalize();
  441. Flt V23=2*(Dot(P3-P2, N2+N3) / Dot(P3-P2, P3-P2)); N23=N2 + N3 - V23*(P3-P2); N23.normalize();
  442. Flt V30=2*(Dot(P0-P3, N3+N0) / Dot(P0-P3, P0-P3)); N30=N3 + N0 - V30*(P0-P3); N30.normalize();
  443. N0123=2*(N01+N12+N23+N30) + (N0+N1+N2+N3); N0123.normalize();
  444. }
  445. void set(Vec &pos, Vec &nrm, Flt U, Flt V)
  446. {
  447. Flt BU0=(1-U) * (1-U) * (1-U),
  448. BU1=3 * U * (1-U) * (1-U),
  449. BU2=3 * U * U * (1-U),
  450. BU3=U * U * U,
  451. BV0=(1-V) * (1-V) * (1-V),
  452. BV1=3 * V * (1-V) * (1-V),
  453. BV2=3 * V * V * (1-V),
  454. BV3=V * V * V;
  455. pos=BV0*(BU0*P0 + BU1*B01 + BU2*B10 + BU3*P1)
  456. + BV1*(BU0*B03 + BU1*B02 + BU2*B13 + BU3*B12)
  457. + BV2*(BU0*B30 + BU1*B31 + BU2*B20 + BU3*B21)
  458. + BV3*(BU0*P3 + BU1*B32 + BU2*B23 + BU3*P2);
  459. Flt NU0=(1-U) * (1-U),
  460. NU1=2 * U * (1-U),
  461. NU2=U * U,
  462. NV0=(1-V) * (1-V),
  463. NV1=2 * V * (1-V),
  464. NV2=V * V;
  465. nrm=NV0*(NU0*N0 + NU1*N01 + NU2*N1)
  466. + NV1*(NU0*N30 + NU1*N0123 + NU2*N12)
  467. + NV2*(NU0*N3 + NU1*N23 + NU2*N2);
  468. nrm.normalize();
  469. }
  470. };
  471. static Bool SameNrm(C MeshBase &mesh, Int face, Int v0, Int v1, C Vec &test_n0, C Vec &test_n1, Vec &out_n0, Vec &out_n1) // check if the neighboring 'face' face has the same vtx normals for 'v0,v1' vertexes
  472. {
  473. if(face==-1)return true; // compare to -1 and not >=0 because it can have SIGN_BIT, if there's no adjacent face, then return true so we can use default version
  474. Int face_vtxs;
  475. VecI4 face_ind;
  476. if(face&SIGN_BIT) // quad
  477. {
  478. face_vtxs=4;
  479. face_ind =mesh.quad.ind(face^SIGN_BIT);
  480. }else
  481. {
  482. face_vtxs =3;
  483. face_ind.xyz=mesh.tri.ind(face);
  484. }
  485. REP(face_vtxs) // find the same edge
  486. {
  487. Int test_v1=face_ind.c[i]; if((mesh.vtx.dup() ? mesh.vtx.dup(test_v1) : test_v1)==v1) // first check for v1, because we're checking the neighbor, so it should have vertexes in rotated order
  488. {
  489. Int test_v0=face_ind.c[(i+1)%face_vtxs]; if((mesh.vtx.dup() ? mesh.vtx.dup(test_v0) : test_v0)==v0) // now check for v0
  490. {
  491. out_n0=mesh.vtx.nrm(test_v0);
  492. out_n1=mesh.vtx.nrm(test_v1);
  493. return Dot(test_n0, out_n0)>=EPS_COL_COS && Dot(test_n1, out_n1)>=EPS_COL_COS; // check if both normals are the same
  494. }
  495. break;
  496. }
  497. }
  498. return true;
  499. }
  500. MeshBase& MeshBase::tesselate()
  501. {
  502. if(vtx.pos())
  503. {
  504. setVtxDup().setAdjacencies(true);
  505. // vtxs are created in following order [original_vtxs, tri edges, quad edges & centers]
  506. Int vtxs=T.vtxs (),
  507. tris=T.tris (),
  508. quads=T.quads();
  509. MeshBase temp; temp.create(vtxs + tris*3 + quads*5, 0, tris*4, quads*4, flag()&~(VTX_DUP|EDGE_ALL|ADJ_ALL|FACE_NRM));
  510. MemtN<IndexWeight, 256> skin;
  511. Int * vtx_dup= vtx.dup ();
  512. Vec * pos_src=temp.vtx.pos (),
  513. * pos_dst=temp.vtx.pos (),
  514. * nrm_src=temp.vtx.nrm (),
  515. * nrm_dst=temp.vtx.nrm (),
  516. * tan_src=temp.vtx.tan (),
  517. * tan_dst=temp.vtx.tan (),
  518. * bin_src=temp.vtx.bin (),
  519. * bin_dst=temp.vtx.bin (),
  520. * hlp_src=temp.vtx.hlp (),
  521. * hlp_dst=temp.vtx.hlp ();
  522. Vec2 *tex0_src=temp.vtx.tex0(),
  523. *tex0_dst=temp.vtx.tex0(),
  524. *tex1_src=temp.vtx.tex1(),
  525. *tex1_dst=temp.vtx.tex1(),
  526. *tex2_src=temp.vtx.tex2(),
  527. *tex2_dst=temp.vtx.tex2();
  528. VecB4 * mt_src=temp.vtx.matrix (),
  529. * mt_dst=temp.vtx.matrix ();
  530. VecB4 *bln_src=temp.vtx.blend (),
  531. *bln_dst=temp.vtx.blend ();
  532. Flt *siz_src=temp.vtx.size (),
  533. *siz_dst=temp.vtx.size ();
  534. VecB4 *mtl_src=temp.vtx.material(),
  535. *mtl_dst=temp.vtx.material();
  536. Color *col_src=temp.vtx.color (),
  537. *col_dst=temp.vtx.color ();
  538. Byte *flg_src=temp.vtx.flag (),
  539. *flg_dst=temp.vtx.flag ();
  540. VecI *tri_src = tri .ind (),
  541. *tri_dst =temp.tri .ind (),
  542. *tri_adjf = tri .adjFace();
  543. Byte *tri_fl_src= tri .flag (),
  544. *tri_fl_dst=temp.tri .flag ();
  545. Int *tri_id_src= tri .id (),
  546. *tri_id_dst=temp.tri .id ();
  547. VecI4 *qud_src = quad.ind (),
  548. *qud_dst =temp.quad.ind (),
  549. *qud_adjf = quad.adjFace();
  550. Byte *qud_fl_src= quad.flag (),
  551. *qud_fl_dst=temp.quad.flag ();
  552. Int *qud_id_src= quad.id (),
  553. *qud_id_dst=temp.quad.id ();
  554. // original vtxs
  555. if( pos_dst){CopyN( pos_dst, vtx.pos (), vtxs); pos_dst+=vtxs;}
  556. if( nrm_dst){CopyN( nrm_dst, vtx.nrm (), vtxs); nrm_dst+=vtxs;}
  557. if( tan_dst){CopyN( tan_dst, vtx.tan (), vtxs); tan_dst+=vtxs;}
  558. if( bin_dst){CopyN( bin_dst, vtx.bin (), vtxs); bin_dst+=vtxs;}
  559. if( hlp_dst){CopyN( hlp_dst, vtx.hlp (), vtxs); hlp_dst+=vtxs;}
  560. if(tex0_dst){CopyN(tex0_dst, vtx.tex0 (), vtxs); tex0_dst+=vtxs;}
  561. if(tex1_dst){CopyN(tex1_dst, vtx.tex1 (), vtxs); tex1_dst+=vtxs;}
  562. if(tex2_dst){CopyN(tex2_dst, vtx.tex2 (), vtxs); tex2_dst+=vtxs;}
  563. if( mt_dst){CopyN( mt_dst, vtx.matrix (), vtxs); mt_dst+=vtxs;}
  564. if( bln_dst){CopyN( bln_dst, vtx.blend (), vtxs); bln_dst+=vtxs;}
  565. if( siz_dst){CopyN( siz_dst, vtx.size (), vtxs); siz_dst+=vtxs;}
  566. if( mtl_dst){CopyN( mtl_dst, vtx.material(), vtxs); mtl_dst+=vtxs;}
  567. if( col_dst){CopyN( col_dst, vtx.color (), vtxs); col_dst+=vtxs;}
  568. if( flg_dst){CopyN( flg_dst, vtx.flag (), vtxs); flg_dst+=vtxs;}
  569. // set faces
  570. FREP(tris)
  571. {
  572. VecI ind=tri_src[i];
  573. tri_dst[0].set(ind.x , vtxs+0, vtxs+2);
  574. tri_dst[1].set(vtxs+0, ind.y , vtxs+1);
  575. tri_dst[2].set(vtxs+0, vtxs+1, vtxs+2);
  576. tri_dst[3].set(vtxs+1, ind.z , vtxs+2);
  577. tri_dst+=4;
  578. if(tri_fl_dst)
  579. {
  580. tri_fl_dst[0]=tri_fl_dst[1]=tri_fl_dst[2]=tri_fl_dst[3]=*tri_fl_src++;
  581. tri_fl_dst+=4;
  582. }
  583. if(tri_id_dst)
  584. {
  585. tri_id_dst[0]=tri_id_dst[1]=tri_id_dst[2]=tri_id_dst[3]=*tri_id_src++;
  586. tri_id_dst+=4;
  587. }
  588. if(nrm_src)
  589. {
  590. TriHull hull;
  591. hull.P0=pos_src[ind.x];
  592. hull.P1=pos_src[ind.y];
  593. hull.P2=pos_src[ind.z];
  594. hull.N0=nrm_src[ind.x];
  595. hull.N1=nrm_src[ind.y];
  596. hull.N2=nrm_src[ind.z];
  597. VecI af=tri_adjf[i], ind_dup=ind; ind_dup.remap(vtx_dup); Vec NA, NB;
  598. if(SameNrm(T, af.x, ind_dup.x, ind_dup.y, hull.N0, hull.N1, NA, NB))hull.set01();else hull.set01(NA, NB);
  599. if(SameNrm(T, af.y, ind_dup.y, ind_dup.z, hull.N1, hull.N2, NA, NB))hull.set12();else hull.set12(NA, NB);
  600. if(SameNrm(T, af.z, ind_dup.z, ind_dup.x, hull.N2, hull.N0, NA, NB))hull.set20();else hull.set20(NA, NB);
  601. hull.finalize();
  602. hull.set(pos_dst[0], nrm_dst[0], 0.5f, 0);
  603. hull.set(pos_dst[1], nrm_dst[1], 0.5f, 0.5f);
  604. hull.set(pos_dst[2], nrm_dst[2], 0, 0.5f);
  605. pos_dst+=3;
  606. nrm_dst+=3;
  607. }else
  608. {
  609. Vec P0=pos_src[ind.x], P1=pos_src[ind.y], P2=pos_src[ind.z];
  610. pos_dst[0]=Avg(P0, P1);
  611. pos_dst[1]=Avg(P1, P2);
  612. pos_dst[2]=Avg(P2, P0);
  613. pos_dst+=3;
  614. }
  615. if(tan_dst)
  616. {
  617. Vec t0=tan_src[ind.x], t1=tan_src[ind.y], t2=tan_src[ind.z];
  618. tan_dst[0]=!(t0+t1);
  619. tan_dst[1]=!(t1+t2);
  620. tan_dst[2]=!(t2+t0);
  621. tan_dst+=3;
  622. }
  623. if(bin_dst)
  624. {
  625. Vec b0=bin_src[ind.x], b1=bin_src[ind.y], b2=bin_src[ind.z];
  626. bin_dst[0]=!(b0+b1);
  627. bin_dst[1]=!(b1+b2);
  628. bin_dst[2]=!(b2+b0);
  629. bin_dst+=3;
  630. }
  631. if(hlp_dst)
  632. {
  633. Vec h0=hlp_src[ind.x], h1=hlp_src[ind.y], h2=hlp_src[ind.z];
  634. hlp_dst[0]=Avg(h0, h1);
  635. hlp_dst[1]=Avg(h1, h2);
  636. hlp_dst[2]=Avg(h2, h0);
  637. hlp_dst+=3;
  638. }
  639. if(tex0_dst)
  640. {
  641. Vec2 t0=tex0_src[ind.x], t1=tex0_src[ind.y], t2=tex0_src[ind.z];
  642. tex0_dst[0]=Avg(t0, t1);
  643. tex0_dst[1]=Avg(t1, t2);
  644. tex0_dst[2]=Avg(t2, t0);
  645. tex0_dst+=3;
  646. }
  647. if(tex1_dst)
  648. {
  649. Vec2 t0=tex1_src[ind.x], t1=tex1_src[ind.y], t2=tex1_src[ind.z];
  650. tex1_dst[0]=Avg(t0, t1);
  651. tex1_dst[1]=Avg(t1, t2);
  652. tex1_dst[2]=Avg(t2, t0);
  653. tex1_dst+=3;
  654. }
  655. if(tex2_dst)
  656. {
  657. Vec2 t0=tex2_src[ind.x], t1=tex2_src[ind.y], t2=tex2_src[ind.z];
  658. tex2_dst[0]=Avg(t0, t1);
  659. tex2_dst[1]=Avg(t1, t2);
  660. tex2_dst[2]=Avg(t2, t0);
  661. tex2_dst+=3;
  662. }
  663. if(siz_dst)
  664. {
  665. Flt s0=siz_src[ind.x], s1=siz_src[ind.y], s2=siz_src[ind.z];
  666. siz_dst[0]=Avg(s0, s1);
  667. siz_dst[1]=Avg(s1, s2);
  668. siz_dst[2]=Avg(s2, s0);
  669. siz_dst+=3;
  670. }
  671. if(mtl_dst)
  672. {
  673. VecB4 m0=mtl_src[ind.x], m1=mtl_src[ind.y], m2=mtl_src[ind.z];
  674. mtl_dst[0]=AvgI(m0, m1);
  675. mtl_dst[1]=AvgI(m1, m2);
  676. mtl_dst[2]=AvgI(m2, m0);
  677. mtl_dst+=3;
  678. }
  679. if(col_dst)
  680. {
  681. Color c0=col_src[ind.x], c1=col_src[ind.y], c2=col_src[ind.z];
  682. col_dst[0]=Avg(c0, c1);
  683. col_dst[1]=Avg(c1, c2);
  684. col_dst[2]=Avg(c2, c0);
  685. col_dst+=3;
  686. }
  687. if(flg_dst)
  688. {
  689. Byte f0=flg_src[ind.x], f1=flg_src[ind.y], f2=flg_src[ind.z];
  690. flg_dst[0]=(f0|f1);
  691. flg_dst[1]=(f1|f2);
  692. flg_dst[2]=(f2|f0);
  693. flg_dst+=3;
  694. }
  695. if(mt_dst && bln_dst)
  696. {
  697. VecB4 m0= mt_src[ind.x], m1= mt_src[ind.y], m2= mt_src[ind.z];
  698. VecB4 b0=bln_src[ind.x], b1=bln_src[ind.y], b2=bln_src[ind.z];
  699. REP(4)skin.New().set(m0.c[i], b0.c[i]);
  700. REP(4)skin.New().set(m1.c[i], b1.c[i]);
  701. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  702. REP(4)skin.New().set(m1.c[i], b1.c[i]);
  703. REP(4)skin.New().set(m2.c[i], b2.c[i]);
  704. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  705. REP(4)skin.New().set(m2.c[i], b2.c[i]);
  706. REP(4)skin.New().set(m0.c[i], b0.c[i]);
  707. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  708. }else
  709. {
  710. if(mt_dst)
  711. {
  712. mt_dst[0]=mt_src[ind.x]; // just copy from first point, because we need correct data and blending with sum of 255
  713. mt_dst[1]=mt_src[ind.y];
  714. mt_dst[2]=mt_src[ind.z];
  715. mt_dst+=3;
  716. }
  717. if(bln_dst)
  718. {
  719. bln_dst[0]=bln_src[ind.x]; // just copy from first point, because we need correct data and blending with sum of 255
  720. bln_dst[1]=bln_src[ind.y];
  721. bln_dst[2]=bln_src[ind.z];
  722. bln_dst+=3;
  723. }
  724. }
  725. vtxs+=3;
  726. }
  727. FREP(quads)
  728. {
  729. VecI4 ind=qud_src[i];
  730. qud_dst[0].set(ind.x, vtxs+0, vtxs+4, vtxs+3);
  731. qud_dst[1].set(vtxs+0, ind.y, vtxs+1, vtxs+4);
  732. qud_dst[2].set(vtxs+3, vtxs+4, vtxs+2, ind.w);
  733. qud_dst[3].set(vtxs+4, vtxs+1, ind.z, vtxs+2);
  734. qud_dst+=4;
  735. if(qud_fl_dst)
  736. {
  737. qud_fl_dst[0]=qud_fl_dst[1]=qud_fl_dst[2]=qud_fl_dst[3]=*qud_fl_src++;
  738. qud_fl_dst+=4;
  739. }
  740. if(qud_id_dst)
  741. {
  742. qud_id_dst[0]=qud_id_dst[1]=qud_id_dst[2]=qud_id_dst[3]=*qud_id_src++;
  743. qud_id_dst+=4;
  744. }
  745. if(nrm_src)
  746. {
  747. QuadHull hull;
  748. hull.P0=pos_src[ind.x];
  749. hull.P1=pos_src[ind.y];
  750. hull.P2=pos_src[ind.z];
  751. hull.P3=pos_src[ind.w];
  752. hull.N0=nrm_src[ind.x];
  753. hull.N1=nrm_src[ind.y];
  754. hull.N2=nrm_src[ind.z];
  755. hull.N3=nrm_src[ind.w];
  756. VecI4 af=qud_adjf[i], ind_dup=ind; ind_dup.remap(vtx_dup); Vec NA, NB;
  757. if(SameNrm(T, af.x, ind_dup.x, ind_dup.y, hull.N0, hull.N1, NA, NB))hull.set01();else hull.set01(NA, NB);
  758. if(SameNrm(T, af.y, ind_dup.y, ind_dup.z, hull.N1, hull.N2, NA, NB))hull.set12();else hull.set12(NA, NB);
  759. if(SameNrm(T, af.z, ind_dup.z, ind_dup.w, hull.N2, hull.N3, NA, NB))hull.set23();else hull.set23(NA, NB);
  760. if(SameNrm(T, af.w, ind_dup.w, ind_dup.x, hull.N3, hull.N0, NA, NB))hull.set30();else hull.set30(NA, NB);
  761. hull.finalize();
  762. hull.set(pos_dst[0], nrm_dst[0], 0.5f, 0);
  763. hull.set(pos_dst[1], nrm_dst[1], 1, 0.5f);
  764. hull.set(pos_dst[2], nrm_dst[2], 0.5f, 1);
  765. hull.set(pos_dst[3], nrm_dst[3], 0, 0.5f);
  766. hull.set(pos_dst[4], nrm_dst[4], 0.5f, 0.5f);
  767. pos_dst+=5;
  768. nrm_dst+=5;
  769. }else
  770. {
  771. Vec P0=pos_src[ind.x], P1=pos_src[ind.y], P2=pos_src[ind.z], P3=pos_src[ind.w];
  772. pos_dst[0]=Avg(P0, P1);
  773. pos_dst[1]=Avg(P1, P2);
  774. pos_dst[2]=Avg(P2, P3);
  775. pos_dst[3]=Avg(P3, P0);
  776. pos_dst[4]=Avg(P0, P1, P2, P3);
  777. pos_dst+=5;
  778. }
  779. if(tan_dst)
  780. {
  781. Vec t0=tan_src[ind.x], t1=tan_src[ind.y], t2=tan_src[ind.z], t3=tan_src[ind.w];
  782. tan_dst[0]=!(t0+t1);
  783. tan_dst[1]=!(t1+t2);
  784. tan_dst[2]=!(t2+t3);
  785. tan_dst[3]=!(t3+t0);
  786. tan_dst[4]=!(t0+t1+t2+t3);
  787. tan_dst+=5;
  788. }
  789. if(bin_dst)
  790. {
  791. Vec b0=bin_src[ind.x], b1=bin_src[ind.y], b2=bin_src[ind.z], b3=bin_src[ind.w];
  792. bin_dst[0]=!(b0+b1);
  793. bin_dst[1]=!(b1+b2);
  794. bin_dst[2]=!(b2+b3);
  795. bin_dst[3]=!(b3+b0);
  796. bin_dst[4]=!(b0+b1+b2+b3);
  797. bin_dst+=5;
  798. }
  799. if(hlp_dst)
  800. {
  801. Vec h0=hlp_src[ind.x], h1=hlp_src[ind.y], h2=hlp_src[ind.z], h3=hlp_src[ind.w];
  802. hlp_dst[0]=Avg(h0, h1);
  803. hlp_dst[1]=Avg(h1, h2);
  804. hlp_dst[2]=Avg(h2, h3);
  805. hlp_dst[3]=Avg(h3, h0);
  806. hlp_dst[4]=Avg(h0, h1, h2, h3);
  807. hlp_dst+=5;
  808. }
  809. if(tex0_dst)
  810. {
  811. Vec2 t0=tex0_src[ind.x], t1=tex0_src[ind.y], t2=tex0_src[ind.z], t3=tex0_src[ind.w];
  812. tex0_dst[0]=Avg(t0, t1);
  813. tex0_dst[1]=Avg(t1, t2);
  814. tex0_dst[2]=Avg(t2, t3);
  815. tex0_dst[3]=Avg(t3, t0);
  816. tex0_dst[4]=Avg(t0, t1, t2, t3);
  817. tex0_dst+=5;
  818. }
  819. if(tex1_dst)
  820. {
  821. Vec2 t0=tex1_src[ind.x], t1=tex1_src[ind.y], t2=tex1_src[ind.z], t3=tex1_src[ind.w];
  822. tex1_dst[0]=Avg(t0, t1);
  823. tex1_dst[1]=Avg(t1, t2);
  824. tex1_dst[2]=Avg(t2, t3);
  825. tex1_dst[3]=Avg(t3, t0);
  826. tex1_dst[4]=Avg(t0, t1, t2, t3);
  827. tex1_dst+=5;
  828. }
  829. if(tex2_dst)
  830. {
  831. Vec2 t0=tex2_src[ind.x], t1=tex2_src[ind.y], t2=tex2_src[ind.z], t3=tex2_src[ind.w];
  832. tex2_dst[0]=Avg(t0, t1);
  833. tex2_dst[1]=Avg(t1, t2);
  834. tex2_dst[2]=Avg(t2, t3);
  835. tex2_dst[3]=Avg(t3, t0);
  836. tex2_dst[4]=Avg(t0, t1, t2, t3);
  837. tex2_dst+=5;
  838. }
  839. if(siz_dst)
  840. {
  841. Flt s0=siz_src[ind.x], s1=siz_src[ind.y], s2=siz_src[ind.z], s3=siz_src[ind.w];
  842. siz_dst[0]=Avg(s0, s1);
  843. siz_dst[1]=Avg(s1, s2);
  844. siz_dst[2]=Avg(s2, s3);
  845. siz_dst[3]=Avg(s3, s0);
  846. siz_dst[4]=Avg(s0, s1, s2, s3);
  847. siz_dst+=5;
  848. }
  849. if(mtl_dst)
  850. {
  851. VecB4 m0=mtl_src[ind.x], m1=mtl_src[ind.y], m2=mtl_src[ind.z], m3=mtl_src[ind.w];
  852. mtl_dst[0]=AvgI(m0, m1);
  853. mtl_dst[1]=AvgI(m1, m2);
  854. mtl_dst[2]=AvgI(m2, m3);
  855. mtl_dst[3]=AvgI(m3, m0);
  856. mtl_dst[4]=AvgI(m0, m1, m2, m3);
  857. mtl_dst+=5;
  858. }
  859. if(col_dst)
  860. {
  861. Color c0=col_src[ind.x], c1=col_src[ind.y], c2=col_src[ind.z], c3=col_src[ind.w];
  862. col_dst[0]=Avg(c0, c1);
  863. col_dst[1]=Avg(c1, c2);
  864. col_dst[2]=Avg(c2, c3);
  865. col_dst[3]=Avg(c3, c0);
  866. col_dst[4]=Avg(c0, c1, c2, c3);
  867. col_dst+=5;
  868. }
  869. if(flg_dst)
  870. {
  871. Byte f0=flg_src[ind.x], f1=flg_src[ind.y], f2=flg_src[ind.z], f3=flg_src[ind.w];
  872. flg_dst[0]=(f0|f1);
  873. flg_dst[1]=(f1|f2);
  874. flg_dst[2]=(f2|f3);
  875. flg_dst[3]=(f3|f0);
  876. flg_dst[4]=(f0|f1|f2|f3);
  877. flg_dst+=5;
  878. }
  879. if(mt_dst && bln_dst)
  880. {
  881. VecB4 m0= mt_src[ind.x], m1= mt_src[ind.y], m2= mt_src[ind.z], m3= mt_src[ind.w];
  882. VecB4 b0=bln_src[ind.x], b1=bln_src[ind.y], b2=bln_src[ind.z], b3=bln_src[ind.w];
  883. REP(4)skin.New().set(m0.c[i], b0.c[i]);
  884. REP(4)skin.New().set(m1.c[i], b1.c[i]);
  885. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  886. REP(4)skin.New().set(m1.c[i], b1.c[i]);
  887. REP(4)skin.New().set(m2.c[i], b2.c[i]);
  888. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  889. REP(4)skin.New().set(m2.c[i], b2.c[i]);
  890. REP(4)skin.New().set(m3.c[i], b3.c[i]);
  891. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  892. REP(4)skin.New().set(m3.c[i], b3.c[i]);
  893. REP(4)skin.New().set(m0.c[i], b0.c[i]);
  894. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  895. REP(4)skin.New().set(m0.c[i], b0.c[i]);
  896. REP(4)skin.New().set(m1.c[i], b1.c[i]);
  897. REP(4)skin.New().set(m2.c[i], b2.c[i]);
  898. REP(4)skin.New().set(m3.c[i], b3.c[i]);
  899. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  900. }else
  901. {
  902. if(mt_dst)
  903. {
  904. mt_dst[0]=mt_src[ind.x]; // just copy from first point, because we need correct data and blending with sum of 255
  905. mt_dst[1]=mt_src[ind.y];
  906. mt_dst[2]=mt_src[ind.z];
  907. mt_dst[3]=mt_src[ind.w];
  908. mt_dst[4]=mt_src[ind.x];
  909. mt_dst+=5;
  910. }
  911. if(bln_dst)
  912. {
  913. bln_dst[0]=bln_src[ind.x]; // just copy from first point, because we need correct data and blending with sum of 255
  914. bln_dst[1]=bln_src[ind.y];
  915. bln_dst[2]=bln_src[ind.z];
  916. bln_dst[3]=bln_src[ind.w];
  917. bln_dst[4]=bln_src[ind.x];
  918. bln_dst+=5;
  919. }
  920. }
  921. vtxs+=5;
  922. }
  923. temp.weldVtx(VTX_ALL, EPSD, EPS_COL_COS, -1); // use small epsilon in case mesh is scaled down
  924. Swap(temp, T);
  925. }
  926. return T;
  927. }
  928. /******************************************************************************/
  929. // SUBDIVIDE
  930. /******************************************************************************/
  931. MeshBase& MeshBase::subdivide()
  932. {
  933. const Bool tri_as_quad=false;
  934. // tri_as_quad:false -> vtxs are created in following order [original_vtxs, quads_center, edges_center]
  935. // tri_as_quad:true -> vtxs are created in following order [original_vtxs, tris_center, quads_center, edges_center]
  936. setAdjacencies(true, true);
  937. Int *dup_vtx =null;
  938. Int *dup_edge_edg=null;
  939. Bool *dup_edge_add=null;
  940. VecI2 *dup_edge_adj=null;
  941. if(vtx.dup())
  942. {
  943. dup_vtx =vtx .dup (); vtx ._dup =null;
  944. dup_edge_adj =edge.adjFace(); edge._adj_face=null;
  945. VecI *dup_tri_adj_edg=tri .adjEdge(); tri ._adj_edge=null;
  946. VecI4 *dup_qud_adj_edg=quad.adjEdge(); quad._adj_edge=null;
  947. AllocZero (dup_edge_add, edges());
  948. exclude (VTX_DUP|EDGE_ALL|ADJ_ALL);
  949. setAdjacencies(true, true);
  950. Alloc (dup_edge_edg, edges());
  951. REPA(edge)
  952. {
  953. Int *ef=edge.adjFace(i).c;
  954. REPD(f, 2)
  955. {
  956. Int face =ef[f];
  957. if( face!=-1) // compare to -1 and not >=0 because it can have SIGN_BIT
  958. {
  959. if(face&SIGN_BIT){Int *fe=quad.adjEdge(face^SIGN_BIT).c; REPD(e, 4)if(fe[e]==i){dup_edge_edg[i]=dup_qud_adj_edg[face^SIGN_BIT].c[e]; goto found;}}
  960. else {Int *fe=tri .adjEdge(face ).c; REPD(e, 3)if(fe[e]==i){dup_edge_edg[i]=dup_tri_adj_edg[face ].c[e]; goto found;}}
  961. }
  962. }
  963. dup_edge_edg[i]=i;
  964. found:;
  965. }
  966. Free(dup_tri_adj_edg);
  967. Free(dup_qud_adj_edg);
  968. }
  969. Int *p, p0, p1, p2, p3,
  970. vtxs=T.vtxs (),
  971. edges=T.edges(),
  972. tris=T.tris (),
  973. quads=T.quads(),
  974. tri_vtx_offset=vtxs,
  975. quad_vtx_offset= tri_vtx_offset+(tri_as_quad ? tris : 0),
  976. edge_vtx_offset=quad_vtx_offset+quads;
  977. MeshBase temp(vtxs + (tri_as_quad ? tris : 0)+quads + edges, 0, tri_as_quad ? 0 : tris*4, (tri_as_quad ? tris*3 : 0)+quads*4, (VTX_NRM_TAN_BIN|VTX_HLP|VTX_TEX0|VTX_TEX1|VTX_TEX2|VTX_MATRIX|VTX_BLEND|VTX_SIZE|VTX_MATERIAL|VTX_COLOR|VTX_FLAG)&flag());
  978. MemtN<IndexWeight, 256> skin;
  979. Vec * pos_src=temp.vtx.pos (),
  980. * pos_dst=temp.vtx.pos (),
  981. * nrm_src=temp.vtx.nrm (),
  982. * nrm_dst=temp.vtx.nrm (),
  983. * tan_src=temp.vtx.tan (),
  984. * tan_dst=temp.vtx.tan (),
  985. * bin_src=temp.vtx.bin (),
  986. * bin_dst=temp.vtx.bin (),
  987. * hlp_src=temp.vtx.hlp (),
  988. * hlp_dst=temp.vtx.hlp ();
  989. Vec2 *tex0_src=temp.vtx.tex0(),
  990. *tex0_dst=temp.vtx.tex0(),
  991. *tex1_src=temp.vtx.tex1(),
  992. *tex1_dst=temp.vtx.tex1(),
  993. *tex2_src=temp.vtx.tex2(),
  994. *tex2_dst=temp.vtx.tex2();
  995. VecB4 * mt_src=temp.vtx.matrix (),
  996. * mt_dst=temp.vtx.matrix ();
  997. VecB4 *bln_src=temp.vtx.blend (),
  998. *bln_dst=temp.vtx.blend ();
  999. Flt *siz_src=temp.vtx.size (),
  1000. *siz_dst=temp.vtx.size ();
  1001. VecB4 *mtl_src=temp.vtx.material(),
  1002. *mtl_dst=temp.vtx.material();
  1003. Color *col_src=temp.vtx.color (),
  1004. *col_dst=temp.vtx.color ();
  1005. Byte *flg_src=temp.vtx.flag (),
  1006. *flg_dst=temp.vtx.flag ();
  1007. VecI2 *edg_src= edge.ind (),
  1008. *edg_adj= edge.adjFace();
  1009. VecI *tri_src= tri .ind (),
  1010. *tri_dst=temp.tri .ind ();
  1011. VecI4 *qud_src= quad.ind (),
  1012. *qud_dst=temp.quad.ind ();
  1013. // original vtxs
  1014. if( pos_dst){CopyN( pos_dst, vtx.pos (), vtxs); pos_dst+=vtxs;}
  1015. if( nrm_dst){CopyN( nrm_dst, vtx.nrm (), vtxs); nrm_dst+=vtxs;}
  1016. if( tan_dst){CopyN( tan_dst, vtx.tan (), vtxs); tan_dst+=vtxs;}
  1017. if( bin_dst){CopyN( bin_dst, vtx.bin (), vtxs); bin_dst+=vtxs;}
  1018. if( hlp_dst){CopyN( hlp_dst, vtx.hlp (), vtxs); hlp_dst+=vtxs;}
  1019. if(tex0_dst){CopyN(tex0_dst, vtx.tex0 (), vtxs); tex0_dst+=vtxs;}
  1020. if(tex1_dst){CopyN(tex1_dst, vtx.tex1 (), vtxs); tex1_dst+=vtxs;}
  1021. if(tex2_dst){CopyN(tex2_dst, vtx.tex2 (), vtxs); tex2_dst+=vtxs;}
  1022. if( mt_dst){CopyN( mt_dst, vtx.matrix (), vtxs); mt_dst+=vtxs;}
  1023. if( bln_dst){CopyN( bln_dst, vtx.blend (), vtxs); bln_dst+=vtxs;}
  1024. if( siz_dst){CopyN( siz_dst, vtx.size (), vtxs); siz_dst+=vtxs;}
  1025. if( mtl_dst){CopyN( mtl_dst, vtx.material(), vtxs); mtl_dst+=vtxs;}
  1026. if( col_dst){CopyN( col_dst, vtx.color (), vtxs); col_dst+=vtxs;}
  1027. if( flg_dst){CopyN( flg_dst, vtx.flag (), vtxs); flg_dst+=vtxs;}
  1028. // reposition original points
  1029. Int *vtx_edg_num =AllocZero<Int>(vtxs),
  1030. *vtx_edg_num_b=AllocZero<Int>(vtxs), // border
  1031. *vtx_fac_num =AllocZero<Int>(vtxs);
  1032. Vec *vtx_edg_avg =AllocZero<Vec>(vtxs),
  1033. *vtx_edg_avg_b=AllocZero<Vec>(vtxs), // border
  1034. *vtx_fac_avg =AllocZero<Vec>(vtxs),
  1035. * tri_center=(tri_as_quad ? pos_src+ tri_vtx_offset : Alloc<Vec>(tris)), // if we're storing tris as quads then we store their center in the dest mesh, and we can access those centers from there, otherwise allocate an array
  1036. *quad_center= pos_src+quad_vtx_offset;
  1037. // face points
  1038. if(tri_as_quad)FREP(tris)
  1039. {
  1040. p=tri_src[i].c; p0=p[0]; p1=p[1]; p2=p[2];
  1041. if( pos_dst)* pos_dst++=Avg ( pos_src[p0], pos_src[p1], pos_src[p2]);
  1042. if( nrm_dst)* nrm_dst++= !( nrm_src[p0]+ nrm_src[p1]+ nrm_src[p2]);
  1043. if( tan_dst)* tan_dst++= !( tan_src[p0]+ tan_src[p1]+ tan_src[p2]);
  1044. if( bin_dst)* bin_dst++= !( bin_src[p0]+ bin_src[p1]+ bin_src[p2]);
  1045. if( hlp_dst)* hlp_dst++=Avg ( hlp_src[p0], hlp_src[p1], hlp_src[p2]);
  1046. if(tex0_dst)*tex0_dst++=Avg (tex0_src[p0],tex0_src[p1],tex0_src[p2]);
  1047. if(tex1_dst)*tex1_dst++=Avg (tex1_src[p0],tex1_src[p1],tex1_src[p2]);
  1048. if(tex2_dst)*tex2_dst++=Avg (tex2_src[p0],tex2_src[p1],tex2_src[p2]);
  1049. if( siz_dst)* siz_dst++=Avg ( siz_src[p0], siz_src[p1], siz_src[p2]);
  1050. if( mtl_dst)* mtl_dst++=AvgI( mtl_src[p0], mtl_src[p1], mtl_src[p2]);
  1051. if( col_dst)* col_dst++=Avg ( col_src[p0], col_src[p1], col_src[p2]);
  1052. if( flg_dst)* flg_dst++= ( flg_src[p0]| flg_src[p1]| flg_src[p2]);
  1053. if( mt_dst && bln_dst)
  1054. {
  1055. REP(3){Int point=p[i]; REP(4)skin.New().set(mt_src[point].c[i], bln_src[point].c[i]);}
  1056. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  1057. }else
  1058. {
  1059. if( mt_dst)* mt_dst++= mt_src[p0]; // just copy from first point, because we need correct data and blending with sum of 255
  1060. if(bln_dst)*bln_dst++=bln_src[p0]; // just copy from first point, because we need correct data and blending with sum of 255
  1061. }
  1062. }else FREP(tris)
  1063. {
  1064. p=tri_src[i].c; p0=p[0]; p1=p[1]; p2=p[2];
  1065. tri_center[i]=Avg(pos_src[p0], pos_src[p1], pos_src[p2]);
  1066. }
  1067. FREP(quads)
  1068. {
  1069. p=qud_src[i].c; p0=p[0]; p1=p[1]; p2=p[2]; p3=p[3];
  1070. if( pos_dst)* pos_dst++=Avg ( pos_src[p0], pos_src[p1], pos_src[p2], pos_src[p3]);
  1071. if( nrm_dst)* nrm_dst++= !( nrm_src[p0]+ nrm_src[p1]+ nrm_src[p2]+ nrm_src[p3]);
  1072. if( tan_dst)* tan_dst++= !( tan_src[p0]+ tan_src[p1]+ tan_src[p2]+ tan_src[p3]);
  1073. if( bin_dst)* bin_dst++= !( bin_src[p0]+ bin_src[p1]+ bin_src[p2]+ bin_src[p3]);
  1074. if( hlp_dst)* hlp_dst++=Avg ( hlp_src[p0], hlp_src[p1], hlp_src[p2], hlp_src[p3]);
  1075. if(tex0_dst)*tex0_dst++=Avg (tex0_src[p0],tex0_src[p1],tex0_src[p2],tex0_src[p3]);
  1076. if(tex1_dst)*tex1_dst++=Avg (tex1_src[p0],tex1_src[p1],tex1_src[p2],tex1_src[p3]);
  1077. if(tex2_dst)*tex2_dst++=Avg (tex2_src[p0],tex2_src[p1],tex2_src[p2],tex2_src[p3]);
  1078. if( siz_dst)* siz_dst++=Avg ( siz_src[p0], siz_src[p1], siz_src[p2], siz_src[p3]);
  1079. if( mtl_dst)* mtl_dst++=AvgI( mtl_src[p0], mtl_src[p1], mtl_src[p2], mtl_src[p3]);
  1080. if( col_dst)* col_dst++=Avg ( col_src[p0], col_src[p1], col_src[p2], col_src[p3]);
  1081. if( flg_dst)* flg_dst++= ( flg_src[p0]| flg_src[p1]| flg_src[p2]| flg_src[p3]);
  1082. if( mt_dst && bln_dst)
  1083. {
  1084. REP(4){Int point=p[i]; REP(4)skin.New().set(mt_src[point].c[i], bln_src[point].c[i]);}
  1085. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  1086. }else
  1087. {
  1088. if( mt_dst)* mt_dst++= mt_src[p0]; // just copy from first point, because we need correct data and blending with sum of 255
  1089. if(bln_dst)*bln_dst++=bln_src[p0]; // just copy from first point, because we need correct data and blending with sum of 255
  1090. }
  1091. }
  1092. // edge points
  1093. FREP(edges)
  1094. {
  1095. p=edg_src[i].c; p0=p[0]; p1=p[1];
  1096. if( pos_dst) pos_dst[i]=Avg ( pos_src[p0], pos_src[p1]);
  1097. if( nrm_dst) nrm_dst[i]= !( nrm_src[p0]+ nrm_src[p1]);
  1098. if( tan_dst) tan_dst[i]= !( tan_src[p0]+ tan_src[p1]);
  1099. if( bin_dst) bin_dst[i]= !( bin_src[p0]+ bin_src[p1]);
  1100. if( hlp_dst) hlp_dst[i]=Avg ( hlp_src[p0], hlp_src[p1]);
  1101. if(tex0_dst)tex0_dst[i]=Avg (tex0_src[p0],tex0_src[p1]);
  1102. if(tex1_dst)tex1_dst[i]=Avg (tex1_src[p0],tex1_src[p1]);
  1103. if(tex2_dst)tex2_dst[i]=Avg (tex2_src[p0],tex2_src[p1]);
  1104. if( siz_dst) siz_dst[i]=Avg ( siz_src[p0], siz_src[p1]);
  1105. if( mtl_dst) mtl_dst[i]=AvgI( mtl_src[p0], mtl_src[p1]);
  1106. if( col_dst) col_dst[i]=Avg ( col_src[p0], col_src[p1]);
  1107. if( flg_dst) flg_dst[i]= ( flg_src[p0]| flg_src[p1]);
  1108. if( mt_dst && bln_dst)
  1109. {
  1110. REP(2){Int point=p[i]; REP(4)skin.New().set(mt_src[point].c[i], bln_src[point].c[i]);}
  1111. SetSkin(skin, *mt_dst++, *bln_dst++, null); skin.clear();
  1112. }else
  1113. {
  1114. if( mt_dst)* mt_dst++= mt_src[p0]; // just copy from first point, because we need correct data and blending with sum of 255
  1115. if(bln_dst)*bln_dst++=bln_src[p0]; // just copy from first point, because we need correct data and blending with sum of 255
  1116. }
  1117. p=(dup_vtx ? dup_edge_adj[dup_edge_edg[i]] : edg_adj[i]).c; p0=p[0]; p1=p[1];
  1118. // edge point average (must be based on edge mid-points, before adjusting it by face centers)
  1119. if(dup_vtx){Bool &add=dup_edge_add[dup_edge_edg[i]]; if(add)goto skip_edge;else add=true;}
  1120. {
  1121. VecI2 f=edg_src[i]; f.remap(dup_vtx);
  1122. Vec &v=pos_dst[i];
  1123. if(p0!=-1 && p1!=-1) // have both faces, compare to -1 and not >=0 because it can have SIGN_BIT
  1124. {
  1125. vtx_edg_avg[f.c[0]]+=v;
  1126. vtx_edg_avg[f.c[1]]+=v;
  1127. vtx_edg_num[f.c[0]]++;
  1128. vtx_edg_num[f.c[1]]++;
  1129. }else
  1130. {
  1131. vtx_edg_avg_b[f.c[0]]+=v;
  1132. vtx_edg_avg_b[f.c[1]]+=v;
  1133. vtx_edg_num_b[f.c[0]]++;
  1134. vtx_edg_num_b[f.c[1]]++;
  1135. }
  1136. }
  1137. skip_edge:;
  1138. // adjust point by adj_facs center
  1139. if(p0!=-1 && p1!=-1) // have both faces, compare to -1 and not >=0 because it can have SIGN_BIT
  1140. {
  1141. Vec fp=Avg((p0&SIGN_BIT) ? quad_center[p0^SIGN_BIT] : tri_center[p0],
  1142. (p1&SIGN_BIT) ? quad_center[p1^SIGN_BIT] : tri_center[p1]);
  1143. pos_dst[i]=Avg(pos_dst[i], fp); // make edge point to be average of edge points and nearby face centers
  1144. }
  1145. }
  1146. // reposition original points
  1147. {
  1148. // face point average
  1149. FREP(tris)
  1150. {
  1151. VecI f=tri_src [i]; f.remap(dup_vtx);
  1152. Vec &v=tri_center[i];
  1153. vtx_fac_avg[f.c[0]]+=v;
  1154. vtx_fac_avg[f.c[1]]+=v;
  1155. vtx_fac_avg[f.c[2]]+=v;
  1156. vtx_fac_num[f.c[0]]++;
  1157. vtx_fac_num[f.c[1]]++;
  1158. vtx_fac_num[f.c[2]]++;
  1159. }
  1160. FREP(quads)
  1161. {
  1162. VecI4 f= qud_src [i]; f.remap(dup_vtx);
  1163. Vec &v=quad_center[i];
  1164. vtx_fac_avg[f.c[0]]+=v;
  1165. vtx_fac_avg[f.c[1]]+=v;
  1166. vtx_fac_avg[f.c[2]]+=v;
  1167. vtx_fac_avg[f.c[3]]+=v;
  1168. vtx_fac_num[f.c[0]]++;
  1169. vtx_fac_num[f.c[1]]++;
  1170. vtx_fac_num[f.c[2]]++;
  1171. vtx_fac_num[f.c[3]]++;
  1172. }
  1173. FREP(vtxs)
  1174. {
  1175. Int n=vtx_edg_num [i];
  1176. if(n && vtx_fac_num [i]==n)pos_src[i]=((vtx_fac_avg[i] + 2*vtx_edg_avg[i])/n + (n-3)*pos_src[i])/n;else
  1177. if( n=vtx_edg_num_b[i] )pos_src[i]=Avg(vtx_edg_avg_b[i]/n, pos_src[i]);
  1178. }
  1179. }
  1180. if(!tri_as_quad)Free(tri_center);
  1181. Free(vtx_fac_avg );
  1182. Free(vtx_edg_avg_b);
  1183. Free(vtx_edg_avg );
  1184. Free(vtx_fac_num );
  1185. Free(vtx_edg_num_b);
  1186. Free(vtx_edg_num );
  1187. // create faces
  1188. VecI *tri_adj_edg=tri.adjEdge(); FREP(tris)
  1189. {
  1190. p=tri_src[i].c;
  1191. if(tri_as_quad)
  1192. {
  1193. qud_dst[0].set(p[0], edge_vtx_offset+tri_adj_edg[i].c[0],
  1194. tri_vtx_offset+i,
  1195. edge_vtx_offset+tri_adj_edg[i].c[2]);
  1196. qud_dst[1].set(p[1], edge_vtx_offset+tri_adj_edg[i].c[1],
  1197. tri_vtx_offset+i,
  1198. edge_vtx_offset+tri_adj_edg[i].c[0]);
  1199. qud_dst[2].set(p[2], edge_vtx_offset+tri_adj_edg[i].c[2],
  1200. tri_vtx_offset+i,
  1201. edge_vtx_offset+tri_adj_edg[i].c[1]);
  1202. qud_dst+=3;
  1203. }else
  1204. {
  1205. tri_dst[0].set(p[0], edge_vtx_offset+tri_adj_edg[i].c[0],
  1206. edge_vtx_offset+tri_adj_edg[i].c[2]);
  1207. tri_dst[1].set(p[1], edge_vtx_offset+tri_adj_edg[i].c[1],
  1208. edge_vtx_offset+tri_adj_edg[i].c[0]);
  1209. tri_dst[2].set(p[2], edge_vtx_offset+tri_adj_edg[i].c[2],
  1210. edge_vtx_offset+tri_adj_edg[i].c[1]);
  1211. tri_dst[3].set( edge_vtx_offset+tri_adj_edg[i].c[0],
  1212. edge_vtx_offset+tri_adj_edg[i].c[1],
  1213. edge_vtx_offset+tri_adj_edg[i].c[2]);
  1214. tri_dst+=4;
  1215. }
  1216. }
  1217. VecI4 *qud_adj_edg=quad.adjEdge(); FREP(quads)
  1218. {
  1219. p=qud_src[i].c;
  1220. qud_dst[0].set(p[0], edge_vtx_offset+qud_adj_edg[i].c[0],
  1221. quad_vtx_offset+i,
  1222. edge_vtx_offset+qud_adj_edg[i].c[3]);
  1223. qud_dst[1].set(p[1], edge_vtx_offset+qud_adj_edg[i].c[1],
  1224. quad_vtx_offset+i,
  1225. edge_vtx_offset+qud_adj_edg[i].c[0]);
  1226. qud_dst[2].set(p[2], edge_vtx_offset+qud_adj_edg[i].c[2],
  1227. quad_vtx_offset+i,
  1228. edge_vtx_offset+qud_adj_edg[i].c[1]);
  1229. qud_dst[3].set(p[3], edge_vtx_offset+qud_adj_edg[i].c[3],
  1230. quad_vtx_offset+i,
  1231. edge_vtx_offset+qud_adj_edg[i].c[2]);
  1232. qud_dst+=4;
  1233. }
  1234. if(dup_vtx)
  1235. {
  1236. REP(vtxs)pos_src[i]=pos_src[dup_vtx[i]];
  1237. Free(dup_vtx );
  1238. Free(dup_edge_edg);
  1239. Free(dup_edge_add);
  1240. Free(dup_edge_adj);
  1241. temp.setVtxDup();
  1242. }
  1243. Swap(T, temp); return T;
  1244. }
  1245. /******************************************************************************/
  1246. MeshBase& MeshBase::subdivideEdge(Bool freeze_z, C MemPtr<Bool> &is)
  1247. {
  1248. Int *p, p0, p1;
  1249. Int vtxs =T.vtxs (),
  1250. edges=T.edges(),
  1251. num =(is ? CountIs(is) : edges);
  1252. MeshBase temp(vtxs+num, edges+num, 0, 0, (VTX_NRM_TAN_BIN|VTX_HLP|VTX_TEX0|VTX_TEX1|VTX_TEX2|VTX_MATRIX|VTX_BLEND|VTX_SIZE|VTX_MATERIAL|VTX_COLOR|VTX_FLAG|EDGE_FLAG|EDGE_ID)&flag());
  1253. MemtN<IndexWeight, 256> skin;
  1254. // original points
  1255. CopyN(temp.vtx.nrm (), vtx.nrm (), vtxs);
  1256. CopyN(temp.vtx.tan (), vtx.tan (), vtxs);
  1257. CopyN(temp.vtx.bin (), vtx.bin (), vtxs);
  1258. CopyN(temp.vtx.hlp (), vtx.hlp (), vtxs);
  1259. CopyN(temp.vtx.tex0 (), vtx.tex0 (), vtxs);
  1260. CopyN(temp.vtx.tex1 (), vtx.tex1 (), vtxs);
  1261. CopyN(temp.vtx.tex2 (), vtx.tex2 (), vtxs);
  1262. CopyN(temp.vtx.matrix (), vtx.matrix (), vtxs);
  1263. CopyN(temp.vtx.blend (), vtx.blend (), vtxs);
  1264. CopyN(temp.vtx.size (), vtx.size (), vtxs);
  1265. CopyN(temp.vtx.material(), vtx.material(), vtxs);
  1266. CopyN(temp.vtx.color (), vtx.color (), vtxs);
  1267. CopyN(temp.vtx.flag (), vtx.flag (), vtxs);
  1268. CopyN(temp.edge.ind (), edge.ind (), edges);
  1269. CopyN(temp.edge.flag(), edge.flag(), edges);
  1270. CopyN(temp.edge.id (), edge.id (), edges);
  1271. Int j=0; FREP(edges)if(!is || ElmIs(is, i))
  1272. {
  1273. p=edge.ind(i).c; p0=p[0]; p1=p[1];
  1274. // edge points
  1275. temp.vtx.pos (vtxs+j)=Avg (vtx.pos (p0),vtx.pos (p1));
  1276. if(temp.vtx.nrm ())temp.vtx.nrm (vtxs+j)= !(vtx.nrm (p0)+vtx.nrm (p1));
  1277. if(temp.vtx.tan ())temp.vtx.tan (vtxs+j)= !(vtx.tan (p0)+vtx.tan (p1));
  1278. if(temp.vtx.bin ())temp.vtx.bin (vtxs+j)= !(vtx.bin (p0)+vtx.bin (p1));
  1279. if(temp.vtx.hlp ())temp.vtx.hlp (vtxs+j)=Avg (vtx.hlp (p0),vtx.hlp (p1));
  1280. if(temp.vtx.tex0 ())temp.vtx.tex0 (vtxs+j)=Avg (vtx.tex0 (p0),vtx.tex0 (p1));
  1281. if(temp.vtx.tex1 ())temp.vtx.tex1 (vtxs+j)=Avg (vtx.tex1 (p0),vtx.tex1 (p1));
  1282. if(temp.vtx.tex2 ())temp.vtx.tex2 (vtxs+j)=Avg (vtx.tex2 (p0),vtx.tex2 (p1));
  1283. if(temp.vtx.size ())temp.vtx.size (vtxs+j)=Avg (vtx.size (p0),vtx.size (p1));
  1284. if(temp.vtx.material())temp.vtx.material(vtxs+j)=AvgI(vtx.material(p0),vtx.material(p1));
  1285. if(temp.vtx.color ())temp.vtx.color (vtxs+j)=Avg (vtx.color (p0),vtx.color (p1));
  1286. if(temp.vtx.flag ())temp.vtx.flag (vtxs+j)= (vtx.flag (p0)|vtx.flag (p1));
  1287. if(temp.vtx.matrix () && temp.vtx.blend())
  1288. {
  1289. REP(2){Int point=p[i]; REP(4)skin.New().set(vtx.matrix(point).c[i], vtx.blend(point).c[i]);}
  1290. SetSkin(skin, temp.vtx.matrix(vtxs+j), temp.vtx.blend(vtxs+j), null); skin.clear();
  1291. }else
  1292. {
  1293. if(temp.vtx.matrix())temp.vtx.matrix(vtxs+j)=vtx.matrix(p0); // just copy from first point, because we need correct data and blending with sum of 255
  1294. if(temp.vtx.blend ())temp.vtx.blend (vtxs+j)=vtx.blend (p0); // just copy from first point, because we need correct data and blending with sum of 255
  1295. }
  1296. // edges
  1297. temp.edge.ind (i ).set(p0, vtxs+j );
  1298. temp.edge.ind (edges+j).set( vtxs+j, p1);
  1299. if(temp.edge.flag())temp.edge.flag(edges+j)=edge.flag(i);
  1300. if(temp.edge.id ())temp.edge.id (edges+j)=edge.id (i);
  1301. j++;
  1302. }
  1303. // move original points
  1304. Memt<Int> vtx_num_mem; Int *vtx_num=vtx_num_mem.setNumZero(vtxs).data();
  1305. Bool *vtx_freeze=(freeze_z ? AllocZero<Bool>(vtxs) : null);
  1306. ZeroN(temp.vtx.pos(), vtxs);
  1307. j=0; FREP(edges)if(!is || ElmIs(is, i))
  1308. {
  1309. p=edge.ind(i).c; p0=p[0]; p1=p[1];
  1310. if(edge.flag() && (edge.flag(i)&ETQ_LR)==ETQ_LR)
  1311. {
  1312. if(freeze_z)
  1313. {
  1314. vtx_freeze[p0]=true;
  1315. vtx_freeze[p1]=true;
  1316. }
  1317. }else
  1318. {
  1319. vtx_num[p0]++; temp.vtx.pos(p0)+=temp.vtx.pos(vtxs+j);
  1320. vtx_num[p1]++; temp.vtx.pos(p1)+=temp.vtx.pos(vtxs+j);
  1321. }
  1322. j++;
  1323. }
  1324. FREP(vtxs)
  1325. {
  1326. if(vtx_num[i]>=2)
  1327. {
  1328. temp.vtx.pos(i) =Avg(vtx.pos(i), temp.vtx.pos(i)/vtx_num[i]);
  1329. if(freeze_z && vtx_freeze[i])temp.vtx.pos(i).z= vtx.pos(i).z;
  1330. }else
  1331. {
  1332. temp.vtx.pos(i)=vtx.pos(i);
  1333. }
  1334. }
  1335. // free
  1336. Free(vtx_freeze);
  1337. Swap(T, temp); return T;
  1338. }
  1339. /******************************************************************************/
  1340. //
  1341. /******************************************************************************/
  1342. struct SplitEdge
  1343. {
  1344. VecI2 ind;
  1345. Int id;
  1346. UInt flag;
  1347. };
  1348. MeshBase& MeshBase::splitEdges(Flt length, Bool *is)
  1349. {
  1350. Memb<VtxFull > mvtx (128);
  1351. Memb<SplitEdge> medge(128);
  1352. {
  1353. // copy original vtx
  1354. FREPA(vtx)mvtx.New().from(T, i);
  1355. // create edges
  1356. FREPA(edge)
  1357. {
  1358. Int *p =edge.ind(i).c, p0=p[0], p1=p[1];
  1359. VtxFull &v0 =mvtx[p0],
  1360. &v1 =mvtx[p1];
  1361. Int next=p1, prev;
  1362. if(!is || is[i])
  1363. {
  1364. Flt l=Dist(v0.pos.xy, v1.pos.xy);
  1365. Int c=Round(l/length);
  1366. REPD(j, c-1)
  1367. {
  1368. prev=mvtx.elms(); mvtx.New().lerp(v0, v1, Flt(j+1)/c);
  1369. SplitEdge &e=medge.New();
  1370. e.ind.set(prev, next);
  1371. if(edge.id ())e.id =edge.id (i);
  1372. if(edge.flag())e.flag=edge.flag(i);
  1373. next=prev;
  1374. }
  1375. }
  1376. prev=p0;
  1377. SplitEdge &e=medge.New();
  1378. e.ind.set(prev, next);
  1379. if(edge.id ())e.id =edge.id (i);
  1380. if(edge.flag())e.flag=edge.flag(i);
  1381. }
  1382. }
  1383. // create mshb
  1384. {
  1385. UInt f=((VTX_ALL|EDGE_ID|EDGE_FLAG)&flag());
  1386. create(mvtx.elms(), medge.elms(), 0, 0, f);
  1387. REPA(vtx )mvtx[i].to(T, i);
  1388. REPA(edge)
  1389. {
  1390. SplitEdge &e=medge[i];
  1391. edge.ind (i)=e.ind ;
  1392. if(edge.id ())edge.id (i)=e.id ;
  1393. if(edge.flag())edge.flag(i)=e.flag;
  1394. }
  1395. }
  1396. return T;
  1397. }
  1398. MeshBase& MeshBase::splitEdges(Flt length, Flt d, Bool *is)
  1399. {
  1400. Memb<VtxFull > mvtx (128);
  1401. Memb<SplitEdge> medge(128);
  1402. {
  1403. // copy original vtx
  1404. FREPA(vtx)mvtx.New().from(T, i);
  1405. // create edges
  1406. d=Min(d, length/3);
  1407. FREPA(edge)
  1408. {
  1409. Int *p =edge.ind(i).c, p0=p[0], p1=p[1];
  1410. VtxFull &v0 =mvtx[p0],
  1411. &v1 =mvtx[p1];
  1412. Int next=p1, prev;
  1413. if(!is || is[i])
  1414. {
  1415. Flt l=Dist(v0.pos.xy, v1.pos.xy);
  1416. if(l>=length)
  1417. {
  1418. // first edge
  1419. {
  1420. prev=mvtx.elms(); mvtx.New().lerp(v0, v1, 1-d/l);
  1421. SplitEdge &e=medge.New();
  1422. e.ind.set(prev, next);
  1423. if(edge.id ())e.id =edge.id (i);
  1424. if(edge.flag())e.flag=edge.flag(i);
  1425. next=prev;
  1426. }
  1427. // second edge
  1428. {
  1429. prev=mvtx.elms(); mvtx.New().lerp(v0, v1, d/l);
  1430. SplitEdge &e=medge.New();
  1431. e.ind.set(prev, next);
  1432. if(edge.id ())e.id =edge.id (i);
  1433. if(edge.flag())e.flag=edge.flag(i);
  1434. next=prev;
  1435. }
  1436. }
  1437. }
  1438. prev=p0;
  1439. SplitEdge &e=medge.New();
  1440. e.ind.set(prev, next);
  1441. if(edge.id ())e.id =edge.id (i);
  1442. if(edge.flag())e.flag=edge.flag(i);
  1443. }
  1444. }
  1445. // create mshb
  1446. {
  1447. UInt f=((VTX_ALL|EDGE_ID|EDGE_FLAG)&flag());
  1448. create(mvtx.elms(), medge.elms(), 0, 0, f);
  1449. REPA(vtx )mvtx[i].to(T, i);
  1450. REPA(edge)
  1451. {
  1452. SplitEdge &e=medge[i];
  1453. edge.ind (i)=e.ind ;
  1454. if(edge.id ())edge.id (i)=e.id ;
  1455. if(edge.flag())edge.flag(i)=e.flag;
  1456. }
  1457. }
  1458. return T;
  1459. }
  1460. /******************************************************************************/
  1461. // EXTRUDE
  1462. /******************************************************************************
  1463. MeshBase& extrEdge (Flt length, Bool keep_src=false ); // extrude edges !! beta !!
  1464. MeshBase& extr (Flt length ); // extrude
  1465. /******************************************************************************
  1466. static void MSHBCreate(MeshBase &dest, MeshBase &src, Poly &poly)
  1467. {
  1468. dest.create(poly.vtx.elms(), poly.vtx.elms(), 0, 0, (src.flag()&VTX_ALL)|EDGE_FLAG);
  1469. Int j=0;
  1470. MFREP(poly.vtx)
  1471. {
  1472. PVTX &vtx=poly.vtx[i];
  1473. VtxSet(dest, src, j, vtx.ind);
  1474. dest.edge.ind [j].set(j, (j+1)%dest.vtx.num);
  1475. dest.edge.flag[j]=ETQ_R;
  1476. j++;
  1477. }
  1478. dest.setNormal2();
  1479. }
  1480. /******************************************************************************
  1481. static void MSHBCreate(MeshBase &dest, MeshBase &src, Poly &poly, Flt length, Bool inf)
  1482. {
  1483. MeshBase temp;
  1484. // create extruded temp
  1485. {
  1486. Memb<VtxFull> vtxs(poly.vtx.elms());
  1487. Vec *nrm=src.vtx.nrm;
  1488. poly.setAngle();
  1489. MFREP(poly.vtx)
  1490. {
  1491. PVTX &pvtx =poly.vtx[i];
  1492. Int ind =pvtx.ind;
  1493. Flt angle=pvtx.angle;
  1494. //if(angle>=0 && angle<=PI)
  1495. {
  1496. VtxFull &v=Zero(vtxs.New());
  1497. VtxSet(v, src, ind);
  1498. //v.pos+=nrm[ind]*length/Sin(angle/2);
  1499. v.pos+=nrm[ind]*length/Max(0.25f, Sin(angle/2));
  1500. }/*else
  1501. {
  1502. VtxFull &v=Zero(vtxs.New());
  1503. VtxSet(v, src, ind);
  1504. v.pos+=nrm[ind]*length;
  1505. }*
  1506. }
  1507. temp.create(vtxs.elms(), vtxs.elms(), 0, 0, (src.flag()&VTX_ALL)|EDGE_FLAG);
  1508. FREPA(vtxs)
  1509. {
  1510. VtxSet(temp, vtxs[i], i);
  1511. temp.edge.ind [i].set(i, (i+1)%temp.vtx.num);
  1512. temp.edge.flag[i]=ETQ_R;
  1513. }
  1514. }
  1515. // get non-infinite parts
  1516. {
  1517. temp.cut2D(); temp.weldVtx(0, 0.001f);
  1518. Meml<Poly> polys; temp.edgToPoly(polys);
  1519. MeshBase *mshb=AllocN(MeshBase, polys.elms()); Int mshbs=0;
  1520. MFREP(polys)
  1521. {
  1522. Poly &poly=polys[i];
  1523. if(poly.inf()==inf)MSHBCreate(mshb[mshbs++], temp, poly);
  1524. }
  1525. dest.create(mshb, mshbs); REP(mshbs)mshb[i].del(); Free(mshb);
  1526. }
  1527. }
  1528. /******************************************************************************
  1529. MeshBase& MeshBase::extrEdge(Flt length, Bool keep_src)
  1530. {
  1531. MeshBase *mshb;
  1532. Int mshbs;
  1533. // extrude
  1534. {
  1535. setNormal2(true);
  1536. Meml<Poly> polys; edgToPoly(polys);
  1537. AllocZero(mshb, polys.elms()+1); mshbs=0;
  1538. MFREP(polys)
  1539. {
  1540. Poly &poly=polys[i];
  1541. MSHBCreate(mshb[mshbs], T, poly, length, poly.inf());
  1542. if(mshb[mshbs].is2())mshbs++;
  1543. }
  1544. }
  1545. // solid up
  1546. /*{
  1547. REP(mshbs)
  1548. {
  1549. MeshBase &m=mshb[i];
  1550. Byte *flag=m.edge.flag; REP(m.edge.num)(*flag++)|=ETQ_LR;
  1551. }
  1552. }*
  1553. // create
  1554. if(mshbs)
  1555. {
  1556. if(keep_src)copy(mshb[mshbs++]); del();
  1557. create(mshb, mshbs); REP(mshbs)mshb[i].del();
  1558. }
  1559. Free(mshb);
  1560. return T;
  1561. }
  1562. /******************************************************************************
  1563. MeshBase& MeshBase::extr(Flt length)
  1564. {
  1565. if(!vtx .nrm )setNormals ();
  1566. if(!edge.adj_face)setAdjacencies();
  1567. Int edges=0; REPA(edge)if(edge.adj_face[i].x==-1 || edge.adj_face[i].y==-1)edges++; // compare to -1 and not <0 because it can have SIGN_BIT
  1568. MeshBase temp(vtx.num*2, 0, tri.num*2, quad.num*2+edges, flag()&(VTX_NRM|VTX_TEX0));
  1569. if(temp.vtx.nrm)
  1570. {
  1571. CopyN(temp.vtx.nrm , vtx.nrm, vtx.num);
  1572. CopyN(temp.vtx.nrm+vtx.num, vtx.nrm, vtx.num);
  1573. Chs (temp.vtx.nrm+vtx.num, vtx.num);
  1574. }
  1575. CopyN(temp.vtx .pos , vtx .pos , vtx .num);
  1576. CopyN(temp.vtx .tex0 , vtx .tex0, vtx .num);
  1577. CopyN(temp.vtx .tex0+vtx.num, vtx .tex0, vtx .num);
  1578. CopyN(temp.tri .ind , tri .ind , tri .num);
  1579. CopyN(temp.quad.ind , quad.ind , quad.num);
  1580. {
  1581. Vec *dest=temp.vtx.pos+vtx.num;
  1582. REPA(vtx)
  1583. {
  1584. dest[i]=vtx.pos[i]-vtx.nrm[i]*length;
  1585. }
  1586. }
  1587. {
  1588. VecI *dest=temp.tri.ind+tri.num;
  1589. REPA(tri)
  1590. {
  1591. dest[i]=tri.ind[i]+vtx.num;
  1592. dest[i].reverse();
  1593. }
  1594. }
  1595. {
  1596. VecI4 *dest=temp.quad.ind+quad.num;
  1597. REPA(quad)
  1598. {
  1599. dest[i]=quad.ind[i]+vtx.num;
  1600. dest[i].reverse();
  1601. }
  1602. dest+=quad.num;
  1603. REPA(edge)
  1604. if(edge.adj_face[i].x==-1) // compare to -1 and not <0 because it can have SIGN_BIT
  1605. {
  1606. (dest++)->set(edge.ind[i].x, edge.ind[i].y, edge.ind[i].y+vtx.num, edge.ind[i].x+vtx.num);
  1607. }else
  1608. if(edge.adj_face[i].y==-1) // compare to -1 and not <0 because it can have SIGN_BIT
  1609. {
  1610. (dest++)->set(edge.ind[i].y, edge.ind[i].x, edge.ind[i].x+vtx.num, edge.ind[i].y+vtx.num);
  1611. }
  1612. }
  1613. Swap(T, temp); return T;
  1614. }
  1615. /******************************************************************************/
  1616. MeshBase& MeshBase::boneRemap(C MemPtr<Byte, 256> &old_to_new)
  1617. {
  1618. if(VecB4 *matrix=vtx.matrix())REP(vtxs())
  1619. {
  1620. VecB4 &m=matrix[i]; REPA(m.c)
  1621. {
  1622. Byte &b=m.c[i];
  1623. #if VIRTUAL_ROOT_BONE
  1624. if(b)
  1625. {
  1626. if(InRange(b-1, old_to_new))
  1627. {
  1628. b=old_to_new[b-1];
  1629. if(b==0xFF)b=0;else b++;
  1630. }else
  1631. {
  1632. b=0;
  1633. }
  1634. }
  1635. #else
  1636. if(InRange(b, old_to_new))
  1637. {
  1638. b=old_to_new[b];
  1639. if(b==0xFF)b=0;
  1640. }else
  1641. {
  1642. b=0;
  1643. }
  1644. #endif
  1645. }
  1646. }
  1647. return T;
  1648. }
  1649. void MeshBase:: setUsedBones(Bool (&bones)[256])C {Zero(bones); includeUsedBones(bones);}
  1650. void MeshBase::includeUsedBones(Bool (&bones)[256])C
  1651. {
  1652. if(C VecB4 *matrix=vtx.matrix())
  1653. {
  1654. C VecB4 *blend=vtx.blend(); // this is optional
  1655. REP(vtxs())
  1656. {
  1657. VecB4 m=matrix[i], b; if(blend)b=blend[i];
  1658. REPA(m.c)
  1659. {
  1660. Byte bone=m.c[i];
  1661. #if VIRTUAL_ROOT_BONE
  1662. if(bone)
  1663. {
  1664. bone--;
  1665. if(blend ? b.c[i] : true)bones[bone]=true;
  1666. }
  1667. #else
  1668. if(blend ? b.c[i] : true)bones[bone]=true;
  1669. #endif
  1670. }
  1671. }
  1672. }
  1673. }
  1674. /******************************************************************************/
  1675. }
  1676. /******************************************************************************/