Mesh Group.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. MeshGroup& MeshGroup::include (UInt flag) {REPAO(meshes).include (flag); return T;}
  6. MeshGroup& MeshGroup::exclude (UInt flag) {REPAO(meshes).exclude (flag); return T;}
  7. MeshGroup& MeshGroup::keepOnly(UInt flag) {REPAO(meshes).keepOnly(flag); return T;}
  8. /******************************************************************************/
  9. void MeshGroup::zero () {ext.zero();}
  10. MeshGroup::MeshGroup() {zero();}
  11. MeshGroup& MeshGroup::delBase () {REPAO(meshes).delBase (); return T;}
  12. MeshGroup& MeshGroup::delRender() {REPAO(meshes).delRender(); return T;}
  13. MeshGroup& MeshGroup::del ()
  14. {
  15. meshes.del();
  16. zero(); return T;
  17. }
  18. /******************************************************************************/
  19. MeshGroup& MeshGroup::create(C Mesh &src, C Boxes &boxes)
  20. {
  21. struct MeshPartEx : MeshPart
  22. {
  23. Int lod_index, box_index;
  24. };
  25. Memt<MeshPartEx> mesh_parts;
  26. Memt<MeshBaseIndex> mesh_splits;
  27. MemtN<Int, 256> box_parts;
  28. // split 'src'
  29. FREPD(l, src.lods()) // add in order
  30. {
  31. C MeshLod &lod=src.lod(l); FREPAD(p, lod) // add in order
  32. {
  33. C MeshPart &part=lod.parts[p]; part.base.split(mesh_splits, boxes); FREPAD(s, mesh_splits) // add in order
  34. {
  35. MeshBaseIndex &mesh_split=mesh_splits[s];
  36. MeshPartEx &mesh_part =mesh_parts.New();
  37. Swap(mesh_part.base, SCAST(MeshBase, mesh_split));
  38. mesh_part.copyParams(part, true);
  39. mesh_part.lod_index=l;
  40. box_parts(mesh_part.box_index=mesh_split.index)=1; // set that this box part has some data
  41. }
  42. }
  43. }
  44. // check which box_parts have anything
  45. Int bps=0; FREPA(box_parts) // process in order
  46. {
  47. Int &box_part=box_parts[i]; if(box_part)box_part=bps++; // if box part is valid, then set its target index as current number of bps, and inc that by 1
  48. }
  49. // create mesh group
  50. MeshGroup temp, &dest=(T.meshes.contains(&src) ? temp : T); // if this contains 'src' then operate on 'temp' first
  51. dest.meshes.setNum(bps); REPAD(s, dest.meshes)
  52. {
  53. Mesh &mesh=dest.meshes[s].setLods(src.lods()); mesh.copyParams(src); // create split meshes to always have the same amount of LOD's
  54. REPD(l, mesh.lods()) // process all LOD's in this split mesh
  55. {
  56. MeshLod &lod=mesh.lod(l); lod.copyParams(src.lod(l));
  57. Int parts=0; // how many parts in this LOD
  58. REPA(mesh_parts)
  59. {
  60. MeshPartEx &mesh_part=mesh_parts[i]; if(mesh_part.lod_index==l && box_parts[mesh_part.box_index]==s)parts++; // if mesh_part should be assigned to this lod
  61. }
  62. lod.parts.setNum(parts); // always set LOD parts in case we're operating on MeshGroup that already had some data, and this will clear it
  63. if(parts)
  64. {
  65. parts=0;
  66. FREPA(mesh_parts) // add in order
  67. {
  68. MeshPartEx &mesh_part=mesh_parts[i]; if(mesh_part.lod_index==l && box_parts[mesh_part.box_index]==s)Swap(SCAST(MeshPart, mesh_part), lod.parts[parts++]);
  69. }
  70. }
  71. }
  72. }
  73. if(&dest==&temp)Swap(temp, T);
  74. setBox(true); return T;
  75. }
  76. MeshGroup& MeshGroup::create(C Mesh &src, C VecI &cells ) {return create(src, Boxes(src.ext, cells));}
  77. MeshGroup& MeshGroup::create(C MeshGroup &src, UInt flag_and)
  78. {
  79. if(this==&src)keepOnly(flag_and);else
  80. {
  81. meshes.setNum(src.meshes.elms()); FREPA(T)meshes[i].create(src.meshes[i], flag_and);
  82. copyParams(src);
  83. }
  84. return T;
  85. }
  86. void MeshGroup::copyParams(C MeshGroup &src)
  87. {
  88. if(this!=&src)
  89. {
  90. ext=src.ext;
  91. }
  92. }
  93. /******************************************************************************/
  94. // GET
  95. /******************************************************************************/
  96. UInt MeshGroup::flag ()C {UInt flag=0; REPA(T)flag|=meshes[i].flag (); return flag;}
  97. Int MeshGroup::vtxs ()C {Int n =0; REPA(T)n +=meshes[i].vtxs (); return n ;}
  98. Int MeshGroup::edges ()C {Int n =0; REPA(T)n +=meshes[i].edges (); return n ;}
  99. Int MeshGroup::tris ()C {Int n =0; REPA(T)n +=meshes[i].tris (); return n ;}
  100. Int MeshGroup::quads ()C {Int n =0; REPA(T)n +=meshes[i].quads (); return n ;}
  101. Int MeshGroup::faces ()C {Int n =0; REPA(T)n +=meshes[i].faces (); return n ;}
  102. Int MeshGroup::trisTotal()C {Int n =0; REPA(T)n +=meshes[i].trisTotal(); return n ;}
  103. /******************************************************************************/
  104. // JOIN
  105. /******************************************************************************/
  106. MeshGroup& MeshGroup::join(Int i0, Int i1)
  107. {
  108. if(i0!=i1 && InRange(i0, T) && InRange(i1, T))
  109. {
  110. if(i1<i0)Swap(i0, i1);
  111. meshes[i0]+=meshes[i1];
  112. meshes.remove(i1, true);
  113. }
  114. return T;
  115. }
  116. MeshGroup& MeshGroup::joinAll(Bool test_material, Bool test_draw_group, Bool test_name, UInt test_vtx_flag, Flt weld_pos_eps) {REPAO(meshes).joinAll(test_material, test_draw_group, test_name, test_vtx_flag, weld_pos_eps); return T;}
  117. /******************************************************************************/
  118. // TEXTURIZE
  119. /******************************************************************************/
  120. MeshGroup& MeshGroup::texMap ( Flt scale , Byte tex_index) {REPAO(meshes).texMap (scale , tex_index); return T;}
  121. MeshGroup& MeshGroup::texMap (C Matrix &matrix, Byte tex_index) {REPAO(meshes).texMap (matrix, tex_index); return T;}
  122. MeshGroup& MeshGroup::texMap (C Plane &plane , Byte tex_index) {REPAO(meshes).texMap (plane , tex_index); return T;}
  123. MeshGroup& MeshGroup::texMap (C Ball &ball , Byte tex_index) {REPAO(meshes).texMap (ball , tex_index); return T;}
  124. MeshGroup& MeshGroup::texMap (C Tube &tube , Byte tex_index) {REPAO(meshes).texMap (tube , tex_index); return T;}
  125. MeshGroup& MeshGroup::texMove (C Vec2 &move , Byte tex_index) {REPAO(meshes).texMove (move , tex_index); return T;}
  126. MeshGroup& MeshGroup::texScale (C Vec2 &scale , Byte tex_index) {REPAO(meshes).texScale (scale , tex_index); return T;}
  127. MeshGroup& MeshGroup::texRotate( Flt angle , Byte tex_index) {REPAO(meshes).texRotate(angle , tex_index); return T;}
  128. /******************************************************************************/
  129. // TRANSFORM
  130. /******************************************************************************/
  131. MeshGroup& MeshGroup::move ( C Vec &move) { ext+=move; REPAO(meshes).move ( move); return T;}
  132. MeshGroup& MeshGroup::scale (C Vec &scale ) {ext*=scale; REPAO(meshes).scale (scale ); return T;}
  133. MeshGroup& MeshGroup::scaleMove(C Vec &scale, C Vec &move) {ext*=scale; ext+=move; REPAO(meshes).scaleMove(scale, move); return T;}
  134. /******************************************************************************/
  135. // SET
  136. /******************************************************************************/
  137. MeshGroup& MeshGroup::setFaceNormals( ) {REPAO(meshes).setFaceNormals( ); return T;}
  138. MeshGroup& MeshGroup::setNormals ( ) {REPAO(meshes).setNormals ( ); return T;}
  139. MeshGroup& MeshGroup::setVtxDup (UInt flag, Flt pos_eps, Flt nrm_cos) {REPAO(meshes).setVtxDup (flag, pos_eps, nrm_cos); return T;}
  140. MeshGroup& MeshGroup::setRender ( ) {REPAO(meshes).setRender ( ); return T;}
  141. MeshGroup& MeshGroup::setShader ( ) {REPAO(meshes).setShader ( ); return T;}
  142. MeshGroup& MeshGroup::material (C MaterialPtr &material ) {REPAO(meshes).material (material ); return T;}
  143. Bool MeshGroup::setBox (Bool set_mesh_boxes )
  144. {
  145. if(set_mesh_boxes)REPAO(meshes).setBox();
  146. Bool found=false; Box box; REPA(T)
  147. {
  148. C Mesh &mesh=T.meshes[i]; if(mesh.vtxs()){if(found)box|=mesh.ext;else{found=true; box=mesh.ext;}}
  149. }
  150. if(found)T.ext=box;else T.ext.zero(); return found;
  151. }
  152. /******************************************************************************/
  153. // OPERATIONS
  154. /******************************************************************************/
  155. MeshGroup& MeshGroup::weldVtx2D (UInt flag, Flt pos_eps, Flt nrm_cos, Flt remove_degenerate_faces_eps) {REPAO(meshes).weldVtx2D(flag, pos_eps, nrm_cos, remove_degenerate_faces_eps); return T;}
  156. MeshGroup& MeshGroup::weldVtx (UInt flag, Flt pos_eps, Flt nrm_cos, Flt remove_degenerate_faces_eps) {REPAO(meshes).weldVtx (flag, pos_eps, nrm_cos, remove_degenerate_faces_eps); return T;}
  157. MeshGroup& MeshGroup::weldVtxValues(UInt flag, Flt pos_eps, Flt nrm_cos, Flt remove_degenerate_faces_eps)
  158. {
  159. struct VtxDupIndex : VtxDupNrm
  160. {
  161. VecI index;
  162. Int count;
  163. };
  164. flag&=T.flag();
  165. // create vertex array
  166. Int vtx_num=0; REPAD(m, T){Mesh &mesh=T.meshes[m]; REPAD(p, mesh.parts)vtx_num+=mesh.parts[p].base.vtxs();} // do not use T.vtxs() as it includes MeshRender
  167. Memc<VtxDupIndex> vtxs; vtxs.setNum(vtx_num); vtx_num=0;
  168. REPAD(m, T)
  169. {
  170. Mesh &mesh=T.meshes[m];
  171. REPAD(p, mesh.parts)
  172. {
  173. MeshBase &mshb=mesh.parts[p].base;
  174. C Vec *nrm =mshb.vtx.nrm();
  175. REPA(mshb.vtx)
  176. {
  177. VtxDupIndex &vtx=vtxs[vtx_num++];
  178. vtx.pos =mshb.vtx.pos(i);
  179. vtx.nrm =(nrm ? nrm[i] : VecZero);
  180. vtx.index.set(i, p, m);
  181. vtx.count=0;
  182. }
  183. }
  184. }
  185. // get vtx dup
  186. SetVtxDup(SCAST(Memc<VtxDupNrm>, vtxs), ext, pos_eps, nrm_cos);
  187. // weld
  188. REPA(vtxs)
  189. {
  190. VtxDupIndex &vn=vtxs[i]; vtxs[vn.dup].count++; if(vn.dup!=i)
  191. {
  192. VtxDupIndex &vd=vtxs[vn.dup];
  193. if(flag&VTX_POS )meshes[vn.index.z].parts[vn.index.y].base.vtx.pos (vn.index.x) =meshes[vd.index.z].parts[vd.index.y].base.vtx.pos (vd.index.x);
  194. if(flag&VTX_NRM )meshes[vd.index.z].parts[vd.index.y].base.vtx.nrm (vd.index.x)+=meshes[vn.index.z].parts[vn.index.y].base.vtx.nrm (vn.index.x);
  195. if(flag&VTX_TAN )meshes[vd.index.z].parts[vd.index.y].base.vtx.tan (vd.index.x)+=meshes[vn.index.z].parts[vn.index.y].base.vtx.tan (vn.index.x);
  196. if(flag&VTX_BIN )meshes[vd.index.z].parts[vd.index.y].base.vtx.bin (vd.index.x)+=meshes[vn.index.z].parts[vn.index.y].base.vtx.bin (vn.index.x);
  197. if(flag&VTX_HLP )meshes[vd.index.z].parts[vd.index.y].base.vtx.hlp (vd.index.x)+=meshes[vn.index.z].parts[vn.index.y].base.vtx.hlp (vn.index.x);
  198. if(flag&VTX_TEX0)meshes[vd.index.z].parts[vd.index.y].base.vtx.tex0(vd.index.x)+=meshes[vn.index.z].parts[vn.index.y].base.vtx.tex0(vn.index.x);
  199. if(flag&VTX_TEX1)meshes[vd.index.z].parts[vd.index.y].base.vtx.tex1(vd.index.x)+=meshes[vn.index.z].parts[vn.index.y].base.vtx.tex1(vn.index.x);
  200. if(flag&VTX_TEX2)meshes[vd.index.z].parts[vd.index.y].base.vtx.tex2(vd.index.x)+=meshes[vn.index.z].parts[vn.index.y].base.vtx.tex2(vn.index.x);
  201. }
  202. }
  203. if(flag&VTX_NRM ){REPA(vtxs){VtxDupIndex &vn=vtxs[i]; if(vn.dup==i)meshes[vn.index.z].parts[vn.index.y].base.vtx.nrm (vn.index.x).normalize();} REPA(vtxs){VtxDupIndex &vn=vtxs[i], &vd=vtxs[vn.dup]; meshes[vn.index.z].parts[vn.index.y].base.vtx.nrm (vn.index.x)=meshes[vd.index.z].parts[vd.index.y].base.vtx.nrm (vd.index.x);}}
  204. if(flag&VTX_TAN ){REPA(vtxs){VtxDupIndex &vn=vtxs[i]; if(vn.dup==i)meshes[vn.index.z].parts[vn.index.y].base.vtx.tan (vn.index.x).normalize();} REPA(vtxs){VtxDupIndex &vn=vtxs[i], &vd=vtxs[vn.dup]; meshes[vn.index.z].parts[vn.index.y].base.vtx.tan (vn.index.x)=meshes[vd.index.z].parts[vd.index.y].base.vtx.tan (vd.index.x);}}
  205. if(flag&VTX_BIN ){REPA(vtxs){VtxDupIndex &vn=vtxs[i]; if(vn.dup==i)meshes[vn.index.z].parts[vn.index.y].base.vtx.bin (vn.index.x).normalize();} REPA(vtxs){VtxDupIndex &vn=vtxs[i], &vd=vtxs[vn.dup]; meshes[vn.index.z].parts[vn.index.y].base.vtx.bin (vn.index.x)=meshes[vd.index.z].parts[vd.index.y].base.vtx.bin (vd.index.x);}}
  206. if(flag&VTX_HLP ){REPA(vtxs){VtxDupIndex &vn=vtxs[i]; if(vn.dup==i)meshes[vn.index.z].parts[vn.index.y].base.vtx.hlp (vn.index.x)/=vn.count ;} REPA(vtxs){VtxDupIndex &vn=vtxs[i], &vd=vtxs[vn.dup]; meshes[vn.index.z].parts[vn.index.y].base.vtx.hlp (vn.index.x)=meshes[vd.index.z].parts[vd.index.y].base.vtx.hlp (vd.index.x);}}
  207. if(flag&VTX_TEX0){REPA(vtxs){VtxDupIndex &vn=vtxs[i]; if(vn.dup==i)meshes[vn.index.z].parts[vn.index.y].base.vtx.tex0(vn.index.x)/=vn.count ;} REPA(vtxs){VtxDupIndex &vn=vtxs[i], &vd=vtxs[vn.dup]; meshes[vn.index.z].parts[vn.index.y].base.vtx.tex0(vn.index.x)=meshes[vd.index.z].parts[vd.index.y].base.vtx.tex0(vd.index.x);}}
  208. if(flag&VTX_TEX1){REPA(vtxs){VtxDupIndex &vn=vtxs[i]; if(vn.dup==i)meshes[vn.index.z].parts[vn.index.y].base.vtx.tex1(vn.index.x)/=vn.count ;} REPA(vtxs){VtxDupIndex &vn=vtxs[i], &vd=vtxs[vn.dup]; meshes[vn.index.z].parts[vn.index.y].base.vtx.tex1(vn.index.x)=meshes[vd.index.z].parts[vd.index.y].base.vtx.tex1(vd.index.x);}}
  209. if(flag&VTX_TEX2){REPA(vtxs){VtxDupIndex &vn=vtxs[i]; if(vn.dup==i)meshes[vn.index.z].parts[vn.index.y].base.vtx.tex2(vn.index.x)/=vn.count ;} REPA(vtxs){VtxDupIndex &vn=vtxs[i], &vd=vtxs[vn.dup]; meshes[vn.index.z].parts[vn.index.y].base.vtx.tex2(vn.index.x)=meshes[vd.index.z].parts[vd.index.y].base.vtx.tex2(vd.index.x);}}
  210. // remove degenerate faces
  211. if(flag&VTX_POS && remove_degenerate_faces_eps>=0)removeDegenerateFaces(remove_degenerate_faces_eps);
  212. return T;
  213. }
  214. MeshGroup& MeshGroup::freeOpenGLESData() {REPAO(meshes).freeOpenGLESData(); return T;}
  215. /******************************************************************************/
  216. // CONVERT
  217. /******************************************************************************/
  218. MeshGroup& MeshGroup::triToQuad(Flt cos) {REPAO(meshes).triToQuad(cos); return T;}
  219. MeshGroup& MeshGroup::quadToTri(Flt cos) {REPAO(meshes).quadToTri(cos); return T;}
  220. /******************************************************************************/
  221. // FIX
  222. /******************************************************************************/
  223. MeshGroup& MeshGroup::fixTexWrapping(Byte tex_index) {REPAO(meshes).fixTexWrapping(tex_index); return T;}
  224. MeshGroup& MeshGroup::fixTexOffset (Byte tex_index) {REPAO(meshes).fixTexOffset (tex_index); return T;}
  225. /******************************************************************************/
  226. // ADD/REMOVE
  227. /******************************************************************************/
  228. MeshGroup& MeshGroup::remove(Int i, Bool set_box)
  229. {
  230. if(InRange(i, T))
  231. {
  232. meshes.remove(i, true);
  233. if(set_box)setBox(false);
  234. }
  235. return T;
  236. }
  237. /******************************************************************************/
  238. // OPTIMIZE
  239. /******************************************************************************/
  240. MeshGroup& MeshGroup::removeDegenerateFaces(Flt eps ) {REPAO(meshes).removeDegenerateFaces(eps ); return T;}
  241. MeshGroup& MeshGroup::weldCoplanarFaces (Flt cos_face, Flt cos_vtx, Bool safe, Flt max_face_length) {REPAO(meshes).weldCoplanarFaces (cos_face, cos_vtx, safe, max_face_length); return T;}
  242. MeshGroup& MeshGroup::sortByMaterials ( ) {REPAO(meshes).sortByMaterials ( ); return T;}
  243. MeshGroup& MeshGroup::simplify(Flt intensity, Flt max_distance, Flt max_uv, Flt max_color, Flt max_material, Flt max_skin, Flt max_normal, Bool keep_border, MESH_SIMPLIFY mode, Flt pos_eps, MeshGroup *dest, Bool *stop)
  244. {
  245. if(!dest)dest=this;
  246. if( dest!=this)
  247. {
  248. dest->copyParams(T);
  249. dest->meshes.setNum(meshes.elms());
  250. }
  251. REPAO(meshes).simplify(intensity, max_distance, max_uv, max_color, max_material, max_skin, max_normal, keep_border, mode, pos_eps, &dest->meshes[i], stop);
  252. return *dest;
  253. }
  254. /******************************************************************************/
  255. // DRAW
  256. /******************************************************************************/
  257. void MeshGroup::draw(C MatrixM &matrix)C
  258. {
  259. switch(meshes.elms())
  260. {
  261. case 0 : return; // if no meshes then return
  262. case 1 : break ; // if only one mesh then continue but skip MeshGroup.ext frustum checking because it won't be needed (it's equal to meshes[0].ext which is checked later)
  263. default: if(!Frustum(ext, matrix))return; // if more than one meshes then check the MeshGroup.ext
  264. }
  265. FREPA(meshes)
  266. {
  267. C Mesh &mesh=meshes[i]; if(Frustum(mesh, matrix))mesh.draw(matrix);
  268. }
  269. }
  270. void MeshGroup::drawShadow(C MatrixM &matrix)C
  271. {
  272. switch(meshes.elms())
  273. {
  274. case 0 : return; // if no meshes then return
  275. case 1 : break ; // if only one mesh then continue but skip MeshGroup.ext frustum checking because it won't be needed (it's equal to meshes[0].ext which is checked later)
  276. default: if(!Frustum(ext, matrix))return; // if more than one meshes then check the MeshGroup.ext
  277. }
  278. FREPA(meshes)
  279. {
  280. C Mesh &mesh=meshes[i]; if(Frustum(mesh, matrix))mesh.drawShadow(matrix);
  281. }
  282. }
  283. /******************************************************************************/
  284. }
  285. /******************************************************************************/