Mesh Base.h 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /******************************************************************************
  2. 'MeshBase' is the most low level software mesh.
  3. It contains vertexes, edges, triangles and quads.
  4. /******************************************************************************/
  5. enum VTX_FLAGS // flags of a single vertex 'MeshVtxs::flag'
  6. {
  7. VTX_FLAG_CLOTH=0x1, // when converting MeshBase to ClothMesh then use the vertex in physical cloth creation
  8. };
  9. enum ETQ_FLAG // Edge-Triangle-Quad Flag
  10. {
  11. ETQ_L =0x01, // has solid left side
  12. ETQ_R =0x02, // has solid right side
  13. ETQ_NO_PHYS=0x04, // no physical body will be created from this face
  14. ETQ_LR=ETQ_L|ETQ_R,
  15. };
  16. enum MESH_BASE_FLAG // Mesh Base Flag
  17. {
  18. VTX_POS =1<< 0, // vertex position
  19. VTX_NRM =1<< 1, // vertex normal
  20. VTX_TAN =1<< 2, // vertex tangent
  21. VTX_BIN =1<< 3, // vertex binormal
  22. VTX_HLP =1<<28, // vertex helper
  23. VTX_TEX0 =1<< 4, // vertex texture UV 0
  24. VTX_TEX1 =1<< 5, // vertex texture UV 1
  25. VTX_TEX2 =1<<31, // vertex texture UV 2
  26. VTX_COLOR =1<<29, // vertex color
  27. VTX_MATERIAL=1<<27, // vertex material blend
  28. VTX_MATRIX =1<< 6, // vertex matrix index
  29. VTX_BLEND =1<< 7, // vertex matrix blend
  30. VTX_SIZE =1<< 8, // vertex size
  31. VTX_FLAG =1<<30, // vertex flag
  32. VTX_DUP =1<< 9, // vertex duplicate
  33. EDGE_IND =1<<10, // edge vertex index
  34. EDGE_ADJ_FACE=1<<11, // edge adjacent face
  35. EDGE_NRM =1<<12, // edge normal
  36. EDGE_FLAG =1<<13, // edge flag
  37. EDGE_ID =1<<14, // edge id
  38. TRI_IND =1<<15, // triangle vertex index
  39. TRI_ADJ_FACE=1<<16, // triangle adjacent face
  40. TRI_ADJ_EDGE=1<<17, // triangle adjacent edge
  41. TRI_NRM =1<<18, // triangle normal
  42. TRI_FLAG =1<<19, // triangle flag
  43. TRI_ID =1<<20, // triangle id
  44. QUAD_IND =1<<21, // quad vertex index
  45. QUAD_ADJ_FACE=1<<22, // quad adjacent face
  46. QUAD_ADJ_EDGE=1<<23, // quad adjacent edge
  47. QUAD_NRM =1<<24, // quad normal
  48. QUAD_FLAG =1<<25, // quad flag
  49. QUAD_ID =1<<26, // quad id
  50. VTX_TEX_ALL =VTX_TEX0 |VTX_TEX1|VTX_TEX2,
  51. VTX_TAN_BIN =VTX_TAN |VTX_BIN ,
  52. VTX_NRM_TAN_BIN=VTX_NRM |VTX_TAN_BIN ,
  53. VTX_SKIN =VTX_MATRIX|VTX_BLEND ,
  54. FACE_IND =TRI_IND |QUAD_IND ,
  55. FACE_ADJ_FACE=TRI_ADJ_FACE|QUAD_ADJ_FACE,
  56. FACE_ADJ_EDGE=TRI_ADJ_EDGE|QUAD_ADJ_EDGE,
  57. FACE_NRM =TRI_NRM |QUAD_NRM ,
  58. FACE_FLAG =TRI_FLAG |QUAD_FLAG ,
  59. FACE_ID =TRI_ID |QUAD_ID ,
  60. VTX_ALL= VTX_POS|VTX_NRM_TAN_BIN|VTX_HLP|VTX_TEX_ALL|VTX_COLOR|VTX_MATERIAL|VTX_MATRIX|VTX_BLEND|VTX_SIZE|VTX_DUP|VTX_FLAG,
  61. EDGE_ALL=EDGE_IND|EDGE_ADJ_FACE| EDGE_NRM|EDGE_FLAG|EDGE_ID,
  62. TRI_ALL= TRI_IND| TRI_ADJ_FACE| TRI_ADJ_EDGE| TRI_NRM| TRI_FLAG| TRI_ID,
  63. QUAD_ALL=QUAD_IND|QUAD_ADJ_FACE|QUAD_ADJ_EDGE|QUAD_NRM|QUAD_FLAG|QUAD_ID,
  64. FACE_ALL=FACE_IND|FACE_ADJ_FACE|FACE_ADJ_EDGE|FACE_NRM|FACE_FLAG|FACE_ID,
  65. ADJ_ALL=EDGE_ADJ_FACE|TRI_ADJ_FACE|TRI_ADJ_EDGE|QUAD_ADJ_FACE|QUAD_ADJ_EDGE,
  66. NRM_ALL= VTX_NRM |EDGE_NRM |TRI_NRM |QUAD_NRM ,
  67. FLAG_ALL= VTX_FLAG|EDGE_FLAG|TRI_FLAG|QUAD_FLAG,
  68. ID_ALL= EDGE_ID |TRI_ID |QUAD_ID ,
  69. #if EE_PRIVATE
  70. VTX_MSHR=VTX_POS|VTX_NRM_TAN_BIN|VTX_HLP|VTX_TEX_ALL|VTX_COLOR|VTX_MATERIAL|VTX_MATRIX|VTX_BLEND|VTX_SIZE, // vertex values which can be stored in MeshRender
  71. #endif
  72. };
  73. enum MESH_SIMPLIFY : Byte
  74. {
  75. SIMPLIFY_QUADRIC, // vertex distances are calculated based on quadric matrixes
  76. SIMPLIFY_PLANES , // vertex distances are calculated based on planes (requires more memory)
  77. };
  78. enum MESH_AO_FUNC : Byte
  79. {
  80. MAF_FULL , // 0
  81. MAF_QUARTIC , // Sqr(Sqr(x))
  82. MAF_SQUARE , // Sqr(x)
  83. MAF_LINEAR , // x
  84. MAF_LINEAR_REV, // 2-2/(x+1)
  85. MAF_SQUARE_REV, // 1-Sqr(1-x)
  86. };
  87. /******************************************************************************/
  88. void SetSkin(C MemPtrN<IndexWeight, 256> &skin, VecB4 &matrix, VecB4 &blend, C Skeleton *skeleton); // set 'matrix' and 'blend' skinning values from 'skin' and 'skeleton' (optional)
  89. /******************************************************************************/
  90. #if EE_PRIVATE
  91. struct VtxDup
  92. {
  93. Vec pos;
  94. Int dup;
  95. };
  96. struct VtxDupNrm : VtxDup
  97. {
  98. Vec nrm;
  99. };
  100. Int SetVtxDup(MemPtr<VtxDup > vtxs, C Box &box, Flt pos_eps=EPS ); // returns the number of unique positions
  101. Int SetVtxDup(MemPtr<VtxDupNrm> vtxs, C Box &box, Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS); // returns the number of unique positions
  102. /******************************************************************************/
  103. UInt EtqFlagSwap(UInt flag); // swap sides of ETQ_FLAG
  104. SIDE_TYPE GetSide(C VecI2 &edge, C VecI &tri );
  105. SIDE_TYPE GetSide(C VecI2 &edge, C VecI4 &quad);
  106. #endif
  107. /******************************************************************************/
  108. struct VtxFull // Vertex containing all possible data
  109. {
  110. Vec pos, nrm, tan, bin, hlp;
  111. Vec2 tex0, tex1, tex2;
  112. Color color;
  113. VecB4 material, matrix, blend;
  114. Flt size;
  115. void reset(); // reset vertex values, this sets all members to zero, except 'color' which is set to WHITE
  116. VtxFull& from(C MeshBase &mshb, Int i) ; // set VtxFull from i-th vertex in 'mshb'
  117. void to ( MeshBase &mshb, Int i)C; // set i-th 'mshb' vertex from VtxFull
  118. VtxFull& avg(C VtxFull &a, C VtxFull &b); // set as average from vertexes, T=Avg(a, b)
  119. VtxFull& lerp(C VtxFull &a, C VtxFull &b, Flt step ); // set as linear interpolation from vertexes, T=Lerp(a, b, step)
  120. VtxFull& lerp(C VtxFull &a, C VtxFull &b, C VtxFull &c, C Vec &blend); // set as linear interpolation from vertexes, T=a*blend.x + b*blend.y + c*blend.z
  121. VtxFull& mul(C Matrix &matrix, C Matrix3 &matrix3); // transform vertex by matrixes ('pos hlp' by 'matrix', and 'nrm tan bin' by 'matrix3')
  122. };
  123. /******************************************************************************/
  124. struct MeshVtxs // Mesh Vertexes
  125. {
  126. Int elms ()C {return _elms ;} // get number of vertexes
  127. Vec * pos () {return _pos ;} Vec & pos (Int i) {RANGE_ASSERT(i, _elms); return _pos [i];} // get i-th vertex position
  128. C Vec * pos ()C {return _pos ;} C Vec & pos (Int i)C {RANGE_ASSERT(i, _elms); return _pos [i];} // get i-th vertex position
  129. Vec * nrm () {return _nrm ;} Vec & nrm (Int i) {RANGE_ASSERT(i, _elms); return _nrm [i];} // get i-th vertex normal
  130. C Vec * nrm ()C {return _nrm ;} C Vec & nrm (Int i)C {RANGE_ASSERT(i, _elms); return _nrm [i];} // get i-th vertex normal
  131. Vec * tan () {return _tan ;} Vec & tan (Int i) {RANGE_ASSERT(i, _elms); return _tan [i];} // get i-th vertex tangent
  132. C Vec * tan ()C {return _tan ;} C Vec & tan (Int i)C {RANGE_ASSERT(i, _elms); return _tan [i];} // get i-th vertex tangent
  133. Vec * bin () {return _bin ;} Vec & bin (Int i) {RANGE_ASSERT(i, _elms); return _bin [i];} // get i-th vertex binormal
  134. C Vec * bin ()C {return _bin ;} C Vec & bin (Int i)C {RANGE_ASSERT(i, _elms); return _bin [i];} // get i-th vertex binormal
  135. Vec * hlp () {return _hlp ;} Vec & hlp (Int i) {RANGE_ASSERT(i, _elms); return _hlp [i];} // get i-th vertex helper
  136. C Vec * hlp ()C {return _hlp ;} C Vec & hlp (Int i)C {RANGE_ASSERT(i, _elms); return _hlp [i];} // get i-th vertex helper
  137. Vec2 * tex0 () {return _tex0 ;} Vec2 & tex0 (Int i) {RANGE_ASSERT(i, _elms); return _tex0 [i];} // get i-th vertex texture UV 0
  138. C Vec2 * tex0 ()C {return _tex0 ;} C Vec2 & tex0 (Int i)C {RANGE_ASSERT(i, _elms); return _tex0 [i];} // get i-th vertex texture UV 0
  139. Vec2 * tex1 () {return _tex1 ;} Vec2 & tex1 (Int i) {RANGE_ASSERT(i, _elms); return _tex1 [i];} // get i-th vertex texture UV 1
  140. C Vec2 * tex1 ()C {return _tex1 ;} C Vec2 & tex1 (Int i)C {RANGE_ASSERT(i, _elms); return _tex1 [i];} // get i-th vertex texture UV 1
  141. Vec2 * tex2 () {return _tex2 ;} Vec2 & tex2 (Int i) {RANGE_ASSERT(i, _elms); return _tex2 [i];} // get i-th vertex texture UV 2
  142. C Vec2 * tex2 ()C {return _tex2 ;} C Vec2 & tex2 (Int i)C {RANGE_ASSERT(i, _elms); return _tex2 [i];} // get i-th vertex texture UV 2
  143. Color* color () {return _color ;} Color& color (Int i) {RANGE_ASSERT(i, _elms); return _color [i];} // get i-th vertex color
  144. C Color* color ()C {return _color ;} C Color& color (Int i)C {RANGE_ASSERT(i, _elms); return _color [i];} // get i-th vertex color
  145. VecB4* material() {return _material;} VecB4& material(Int i) {RANGE_ASSERT(i, _elms); return _material[i];} // get i-th vertex material blend
  146. C VecB4* material()C {return _material;} C VecB4& material(Int i)C {RANGE_ASSERT(i, _elms); return _material[i];} // get i-th vertex material blend
  147. VecB4* matrix () {return _matrix ;} VecB4& matrix (Int i) {RANGE_ASSERT(i, _elms); return _matrix [i];} // get i-th vertex bone/matrix index , index maps to a specific bone of a skeleton, where 0=skeleton root bone, 1=skeleton bone #0, 2=skeleton bone #1, 3=skeleton bone #2, and so on, this can be summarized in the following : bone = (index ? skeleton.bone[index-1] : skeleton.root), only xyz components are used which point to 3 bones, w is unused and should be set to 0
  148. C VecB4* matrix ()C {return _matrix ;} C VecB4& matrix (Int i)C {RANGE_ASSERT(i, _elms); return _matrix [i];} // get i-th vertex bone/matrix index , index maps to a specific bone of a skeleton, where 0=skeleton root bone, 1=skeleton bone #0, 2=skeleton bone #1, 3=skeleton bone #2, and so on, this can be summarized in the following : bone = (index ? skeleton.bone[index-1] : skeleton.root), only xyz components are used which point to 3 bones, w is unused and should be set to 0
  149. VecB4* blend () {return _blend ;} VecB4& blend (Int i) {RANGE_ASSERT(i, _elms); return _blend [i];} // get i-th vertex bone/matrix weight, weight factor between corresponding matrix.xyzw bones, only xyz components are used, their sum must be equal to 255 !! w is unused and should be set to 0
  150. C VecB4* blend ()C {return _blend ;} C VecB4& blend (Int i)C {RANGE_ASSERT(i, _elms); return _blend [i];} // get i-th vertex bone/matrix weight, weight factor between corresponding matrix.xyzw bones, only xyz components are used, their sum must be equal to 255 !! w is unused and should be set to 0
  151. Flt * size () {return _size ;} Flt & size (Int i) {RANGE_ASSERT(i, _elms); return _size [i];} // get i-th vertex size
  152. C Flt * size ()C {return _size ;} C Flt & size (Int i)C {RANGE_ASSERT(i, _elms); return _size [i];} // get i-th vertex size
  153. Byte * flag () {return _flag ;} Byte & flag (Int i) {RANGE_ASSERT(i, _elms); return _flag [i];} // get i-th vertex VTX_FLAGS
  154. C Byte * flag ()C {return _flag ;} C Byte & flag (Int i)C {RANGE_ASSERT(i, _elms); return _flag [i];} // get i-th vertex VTX_FLAGS
  155. Int * dup () {return _dup ;} Int & dup (Int i) {RANGE_ASSERT(i, _elms); return _dup [i];} // get i-th vertex duplicate, index of identical vertex
  156. C Int * dup ()C {return _dup ;} C Int & dup (Int i)C {RANGE_ASSERT(i, _elms); return _dup [i];} // get i-th vertex duplicate, index of identical vertex
  157. MeshVtxs() {}
  158. #if !EE_PRIVATE
  159. private:
  160. #endif
  161. Int _elms; Vec *_pos, *_nrm, *_tan, *_bin, *_hlp; Vec2 *_tex0, *_tex1, *_tex2; Color *_color; VecB4 *_material, *_matrix, *_blend; Flt *_size; Byte *_flag; Int *_dup;
  162. NO_COPY_CONSTRUCTOR(MeshVtxs);
  163. };
  164. /******************************************************************************/
  165. struct MeshEdges // Mesh Edges
  166. {
  167. Int elms ()C {return _elms ;} // get number of edges
  168. VecI2* ind () {return _ind ;} VecI2& ind (Int i) {RANGE_ASSERT(i, _elms); return _ind [i];} // get i-th edge vertex indexes
  169. C VecI2* ind ()C {return _ind ;} C VecI2& ind (Int i)C {RANGE_ASSERT(i, _elms); return _ind [i];} // get i-th edge vertex indexes
  170. VecI2* adjFace() {return _adj_face;} VecI2& adjFace(Int i) {RANGE_ASSERT(i, _elms); return _adj_face[i];} // get i-th edge adjacent faces, index to faces adjacent to the edge encoded in following way : if(adj_face==-1) -> no face, else if(adj_face&SIGN_BIT)adj_quad_index=adj_face^SIGN_BIT, else adj_tri_index=adj_face
  171. C VecI2* adjFace()C {return _adj_face;} C VecI2& adjFace(Int i)C {RANGE_ASSERT(i, _elms); return _adj_face[i];} // get i-th edge adjacent faces, index to faces adjacent to the edge encoded in following way : if(adj_face==-1) -> no face, else if(adj_face&SIGN_BIT)adj_quad_index=adj_face^SIGN_BIT, else adj_tri_index=adj_face
  172. Vec * nrm () {return _nrm ;} Vec & nrm (Int i) {RANGE_ASSERT(i, _elms); return _nrm [i];} // get i-th edge normal
  173. C Vec * nrm ()C {return _nrm ;} C Vec & nrm (Int i)C {RANGE_ASSERT(i, _elms); return _nrm [i];} // get i-th edge normal
  174. Byte * flag () {return _flag ;} Byte & flag (Int i) {RANGE_ASSERT(i, _elms); return _flag [i];} // get i-th edge flag
  175. C Byte * flag ()C {return _flag ;} C Byte & flag (Int i)C {RANGE_ASSERT(i, _elms); return _flag [i];} // get i-th edge flag
  176. Int * id () {return _id ;} Int & id (Int i) {RANGE_ASSERT(i, _elms); return _id [i];} // get i-th edge id
  177. C Int * id ()C {return _id ;} C Int & id (Int i)C {RANGE_ASSERT(i, _elms); return _id [i];} // get i-th edge id
  178. MeshEdges() {}
  179. #if !EE_PRIVATE
  180. private:
  181. #endif
  182. Int _elms; VecI2 *_ind, *_adj_face; Vec *_nrm; Byte *_flag; Int *_id;
  183. NO_COPY_CONSTRUCTOR(MeshEdges);
  184. };
  185. /******************************************************************************/
  186. struct MeshTris // Mesh Triangles
  187. {
  188. Int elms ()C {return _elms ;} // get number of triangles
  189. VecI* ind () {return _ind ;} VecI& ind (Int i) {RANGE_ASSERT(i, _elms); return _ind [i];} // get i-th triangle vertex indexes
  190. C VecI* ind ()C {return _ind ;} C VecI& ind (Int i)C {RANGE_ASSERT(i, _elms); return _ind [i];} // get i-th triangle vertex indexes
  191. VecI* adjFace() {return _adj_face;} VecI& adjFace(Int i) {RANGE_ASSERT(i, _elms); return _adj_face[i];} // get i-th triangle adjacent faces, index to faces adjacent to the triangle encoded in following way : if(adj_face==-1) -> no face, else if(adj_face&SIGN_BIT)adj_quad_index=adj_face^SIGN_BIT, else adj_tri_index=adj_face
  192. C VecI* adjFace()C {return _adj_face;} C VecI& adjFace(Int i)C {RANGE_ASSERT(i, _elms); return _adj_face[i];} // get i-th triangle adjacent faces, index to faces adjacent to the triangle encoded in following way : if(adj_face==-1) -> no face, else if(adj_face&SIGN_BIT)adj_quad_index=adj_face^SIGN_BIT, else adj_tri_index=adj_face
  193. VecI* adjEdge() {return _adj_edge;} VecI& adjEdge(Int i) {RANGE_ASSERT(i, _elms); return _adj_edge[i];} // get i-th triangle adjacent edges, index to edges adjacent to the triangle encoded in following way : if(adj_edge==-1) -> no edge, else adj_edge_index=adj_edge
  194. C VecI* adjEdge()C {return _adj_edge;} C VecI& adjEdge(Int i)C {RANGE_ASSERT(i, _elms); return _adj_edge[i];} // get i-th triangle adjacent edges, index to edges adjacent to the triangle encoded in following way : if(adj_edge==-1) -> no edge, else adj_edge_index=adj_edge
  195. Vec * nrm () {return _nrm ;} Vec & nrm (Int i) {RANGE_ASSERT(i, _elms); return _nrm [i];} // get i-th triangle normal
  196. C Vec * nrm ()C {return _nrm ;} C Vec & nrm (Int i)C {RANGE_ASSERT(i, _elms); return _nrm [i];} // get i-th triangle normal
  197. Byte* flag () {return _flag ;} Byte& flag (Int i) {RANGE_ASSERT(i, _elms); return _flag [i];} // get i-th triangle flag
  198. C Byte* flag ()C {return _flag ;} C Byte& flag (Int i)C {RANGE_ASSERT(i, _elms); return _flag [i];} // get i-th triangle flag
  199. Int * id () {return _id ;} Int & id (Int i) {RANGE_ASSERT(i, _elms); return _id [i];} // get i-th triangle id
  200. C Int * id ()C {return _id ;} C Int & id (Int i)C {RANGE_ASSERT(i, _elms); return _id [i];} // get i-th triangle id
  201. MeshTris() {}
  202. #if !EE_PRIVATE
  203. private:
  204. #endif
  205. Int _elms; VecI *_ind, *_adj_face, *_adj_edge; Vec *_nrm; Byte *_flag; Int *_id;
  206. NO_COPY_CONSTRUCTOR(MeshTris);
  207. };
  208. /******************************************************************************/
  209. struct MeshQuads // Mesh Quads
  210. {
  211. Int elms ()C {return _elms ;} // get number of quads
  212. VecI4* ind () {return _ind ;} VecI4& ind (Int i) {RANGE_ASSERT(i, _elms); return _ind [i];} // get i-th quad vertex indexes
  213. C VecI4* ind ()C {return _ind ;} C VecI4& ind (Int i)C {RANGE_ASSERT(i, _elms); return _ind [i];} // get i-th quad vertex indexes
  214. VecI4* adjFace() {return _adj_face;} VecI4& adjFace(Int i) {RANGE_ASSERT(i, _elms); return _adj_face[i];} // get i-th quad adjacent faces, index to faces adjacent to the quad encoded in following way : if(adj_face==-1) -> no face, else if(adj_face&SIGN_BIT)adj_quad_index=adj_face^SIGN_BIT, else adj_tri_index=adj_face
  215. C VecI4* adjFace()C {return _adj_face;} C VecI4& adjFace(Int i)C {RANGE_ASSERT(i, _elms); return _adj_face[i];} // get i-th quad adjacent faces, index to faces adjacent to the quad encoded in following way : if(adj_face==-1) -> no face, else if(adj_face&SIGN_BIT)adj_quad_index=adj_face^SIGN_BIT, else adj_tri_index=adj_face
  216. VecI4* adjEdge() {return _adj_edge;} VecI4& adjEdge(Int i) {RANGE_ASSERT(i, _elms); return _adj_edge[i];} // get i-th quad adjacent edges, index to edges adjacent to the quad encoded in following way : if(adj_edge==-1) -> no edge, else adj_edge_index=adj_edge
  217. C VecI4* adjEdge()C {return _adj_edge;} C VecI4& adjEdge(Int i)C {RANGE_ASSERT(i, _elms); return _adj_edge[i];} // get i-th quad adjacent edges, index to edges adjacent to the quad encoded in following way : if(adj_edge==-1) -> no edge, else adj_edge_index=adj_edge
  218. Vec * nrm () {return _nrm ;} Vec & nrm (Int i) {RANGE_ASSERT(i, _elms); return _nrm [i];} // get i-th quad normal
  219. C Vec * nrm ()C {return _nrm ;} C Vec & nrm (Int i)C {RANGE_ASSERT(i, _elms); return _nrm [i];} // get i-th quad normal
  220. Byte * flag () {return _flag ;} Byte & flag (Int i) {RANGE_ASSERT(i, _elms); return _flag [i];} // get i-th quad flag
  221. C Byte * flag ()C {return _flag ;} C Byte & flag (Int i)C {RANGE_ASSERT(i, _elms); return _flag [i];} // get i-th quad flag
  222. Int * id () {return _id ;} Int & id (Int i) {RANGE_ASSERT(i, _elms); return _id [i];} // get i-th quad id
  223. C Int * id ()C {return _id ;} C Int & id (Int i)C {RANGE_ASSERT(i, _elms); return _id [i];} // get i-th quad id
  224. MeshQuads() {}
  225. #if !EE_PRIVATE
  226. private:
  227. #endif
  228. Int _elms; VecI4 *_ind, *_adj_face, *_adj_edge; Vec *_nrm; Byte *_flag; Int *_id;
  229. NO_COPY_CONSTRUCTOR(MeshQuads);
  230. };
  231. /******************************************************************************/
  232. struct MeshBase // Mesh Base (the most low level software mesh, contains : Vertexes + Edges + Triangles + Quads)
  233. {
  234. MeshVtxs vtx ; // vertexes
  235. MeshEdges edge; // edges
  236. MeshTris tri ; // triangles
  237. MeshQuads quad; // quads
  238. // manage
  239. MeshBase& del ( ); // delete manually
  240. MeshBase& create ( Int vtxs, Int edges, Int tris, Int quads, UInt flag=0 ); // create, 'vtxs'=number of vertexes, 'edges'=number of edges, 'tris'=number of triangles, 'quads'=number of quads, 'flag'=MESH_BASE_FLAG (here VTX_POS, EDGE_IND, TRI_IND, QUAD_IND are always created automatically so you don't have to specify them manually)
  241. MeshBase& create (C MeshBase &src , UInt flag_and=~0 ); // create from 'src' , 'flag_and'=MESH_BASE_FLAG
  242. MeshBase& create (C MeshRender &src , UInt flag_and=~0 ); // create from 'src' , 'flag_and'=MESH_BASE_FLAG
  243. MeshBase& create (C MeshPart &src , UInt flag_and=~0 ); // create from 'src' , 'flag_and'=MESH_BASE_FLAG
  244. MeshBase& create (C MeshLod &src , UInt flag_and=~0 , Bool set_face_id_from_part_index=false ); // create from 'src' , 'flag_and'=MESH_BASE_FLAG, 'set_face_id_from_part_index'=if set face 'id' members to the index of the original MeshPart that they were created from
  245. MeshBase& create (C MeshBase *src , Int elms, UInt flag_and=~0 , Bool set_face_id_from_part_index=false ); // create from 'src' array, 'flag_and'=MESH_BASE_FLAG, 'set_face_id_from_part_index'=if set face 'id' members to the index of the original MeshPart that they were created from
  246. MeshBase& create (C PhysPart &src ); // create from 'src'
  247. MeshBase& createPhys(C MeshLod &src , UInt flag_and=VTX_POS|FACE_IND, Bool set_face_id_from_part_index=false, Bool skip_hidden_parts=false); // create from 'src' , 'flag_and'=MESH_BASE_FLAG, 'set_face_id_from_part_index'=if set face 'id' members to the index of the original MeshPart that they were created from, this method ignores parts with MSHP_NO_PHYS_BODY flag and does not include them in the final mesh, 'skip_hidden_parts'=if ignore MeshPart's with MSHP_HIDDEN flag
  248. #if EE_PRIVATE
  249. MeshBase& create (C MeshBase *src[], Int elms, UInt flag_and=~0 , Bool set_face_id_from_part_index=false ); // create from 'src' array, 'flag_and'=MESH_BASE_FLAG, 'set_face_id_from_part_index'=if set face 'id' members to the index of the original MeshPart that they were created from
  250. Bool createVtx (C VtxBuf &vb, UInt flag, UInt storage, MeshRender::BoneSplit *bone_split, Int bone_splits, UInt flag_and=~0) ; // create vertexes from vertex buffer
  251. Bool createInd (C IndBuf &ib ) ; // create indexed from index buffer
  252. MeshBase& copyFace (MeshBase &dest, C MemPtr<Bool> &edge_is, C MemPtr<Bool> &tri_is, C MemPtr<Bool> &quad_is, UInt flag_and=~0)C; // copy only selected elements , 'flag_and'=MESH_BASE_FLAG, 'edge_is tri_is quad_is' must point to an array of Bool's of size equal to number of eddges, triangles and quads respectively, i-th element will be copied only if "_is[i]==true", if the "is" parameter is set to null, then no elemenets are copied, !! method returns 'dest' !!
  253. void copyId (MeshBase &dest, Int id, UInt flag_and=~0)C; // copy only elements with matching id , 'flag_and'=MESH_BASE_FLAG, the 'id' parameter is compared to 'id' member of each edge, triangle and quad from the mesh, if any element matches the comparison, then it is copied into destination mesh
  254. void copyId (MeshLod &dest, UInt flag_and=~0)C; // copy according to id's (each id to separate MeshPart), 'flag_and'=MESH_BASE_FLAG, this method tests 'id' member of each edge, triangle and quad, and stores the element in different Mesh Parts depending on the 'id' value, elements of "id==0" go to 0-th MeshPart, elements of "id==1" go to 1-st MeshPart, ...
  255. void copyId (Mesh &dest, UInt flag_and=~0)C; // copy according to id's (each id to separate MeshPart), 'flag_and'=MESH_BASE_FLAG, this method tests 'id' member of each edge, triangle and quad, and stores the element in different Mesh Parts depending on the 'id' value, elements of "id==0" go to 0-th MeshPart, elements of "id==1" go to 1-st MeshPart, ...
  256. void copyVtxs (C MeshBase &src); void copyVtxs (C MeshBase &src, C MemPtr<Bool> &is);
  257. void copyEdges(C MeshBase &src); void copyEdges(C MeshBase &src, C MemPtr<Bool> &is);
  258. void copyTris (C MeshBase &src); void copyTris (C MeshBase &src, C MemPtr<Bool> &is);
  259. void copyQuads(C MeshBase &src); void copyQuads(C MeshBase &src, C MemPtr<Bool> &is);
  260. #if PHYSX
  261. Bool create(PxConvexMesh &convex);
  262. Bool create(PxTriangleMesh &mesh );
  263. #else
  264. Bool create(btConvexHullShape &convex);
  265. Bool create(btBvhTriangleMeshShape &mesh );
  266. #endif
  267. #endif
  268. MeshBase& include (UInt flag); // include elements specified with 'flag' MESH_BASE_FLAG
  269. MeshBase& exclude (UInt flag); // exclude elements specified with 'flag' MESH_BASE_FLAG
  270. MeshBase& keepOnly(UInt flag); // keep only elements specified with 'flag' MESH_BASE_FLAG
  271. // create
  272. MeshBase& createPlane ( Int x=2, Int y=2, UInt flag=0 ); // create mesh as 3D plane from (0,0,0) to (1,1,0) vertex positions using quads, 'x, y'=vertex resolution, 'flag'=VTX_FLAG
  273. MeshBase& create (C Box &box , UInt flag=0, Int resolution=-1 ); // create mesh as 3D box , 'flag'=VTX_FLAG
  274. MeshBase& create (C OBox &obox , UInt flag=0, Int resolution=-1 ); // create mesh as 3D oriented box , 'flag'=VTX_FLAG
  275. MeshBase& create (C Ball &ball , UInt flag=0, Int resolution=-1 ); // create mesh as 3D ball in cube mode and UV mapping, 'flag'=VTX_FLAG
  276. MeshBase& create2 (C Ball &ball , UInt flag=0, Int resolution=-1, Int resolution2=-1); // create mesh as 3D ball in spherical mode and UV mapping, 'flag'=VTX_FLAG
  277. MeshBase& createIco (C Ball &ball , UInt flag=0, Int resolution=-1 ); // create mesh as 3D ball in icosphere mode and UV mapping, 'flag'=VTX_FLAG
  278. MeshBase& create (C Capsule &capsule, UInt flag=0, Int resolution=-1, Int resolution2=-1); // create mesh as 3D capsule , 'flag'=VTX_FLAG
  279. MeshBase& create (C Tube &tube , UInt flag=0, Int resolution=-1 ); // create mesh as 3D tube , 'flag'=VTX_FLAG
  280. MeshBase& create (C Cone &cone , UInt flag=0, Int resolution=-1 ); // create mesh as 3D cone , 'flag'=VTX_FLAG
  281. MeshBase& create (C Torus &torus , UInt flag=0, Int resolution=-1, Int resolution2=-1); // create mesh as 3D torus , 'flag'=VTX_FLAG
  282. MeshBase& create (C Shape &shape , UInt flag=0, Int resolution=-1, Int resolution2=-1); // create mesh as 3D shape , 'flag'=VTX_FLAG
  283. MeshBase& createConvex(C Vec *point , Int points, Int max_points=-1 ); // create mesh as 3D convex mesh created from 'point' array of 'points' elements, you can optionally limit the maximum number of generated points to 'max_points' by setting it to a value different than -1
  284. #if EE_PRIVATE
  285. MeshBase& createGrid ( Int x=2, Int y=2, Bool fast=false ); // create mesh as 2D grid from (0,0) to (1,1) vertex positions using edges, 'x, y'=vertex resolution
  286. MeshBase& createFast (C Box &box ); // create mesh as 3D box (fast version - only vertex position and quad indexes are set)
  287. MeshBase& createBox (C Matrix &matrix , UInt flag=0 , Int resolution=-1); // create mesh as 3D box , 'flag'=VTX_FLAG
  288. MeshBase& createHalf (C Ball &ball , UInt flag=0 , Int resolution=-1); // create mesh as 3D ball's upper half, 'flag'=VTX_FLAG
  289. MeshBase& createIcoHalf (C Ball &ball , UInt flag=0 , Int resolution=-1); // create mesh as 3D ball's upper half, 'flag'=VTX_FLAG
  290. MeshBase& createFast (C Tube &tube , Int resolution=-1); // create mesh as 3D tube (fast)
  291. MeshBase& createEdge (C Rect &rect , Bool solid=false ); // create mesh as 2D edged-rectangle
  292. MeshBase& createEdge (C Circle &circle , Bool solid=false, Int resolution=-1); // create mesh as 2D edged-circle
  293. MeshBase& createEdgeStar( Flt r1, Flt r2 , Bool solid=false, Int resolution=-1); // create mesh as 2D edged-star, 'r1,r2'=star radius
  294. #endif
  295. // get
  296. Bool is ()C {return vtx.elms() || edge.elms() || tri.elms() || quad.elms() ;} // if has any data
  297. Int vtxs ()C {return vtx.elms() ;} // get number of vertexes
  298. Int edges ()C {return edge.elms() ;} // get number of edges
  299. Int tris ()C {return tri.elms() ;} // get number of triangles
  300. Int quads ()C {return quad.elms() ;} // get number of quads
  301. Int faces ()C {return tri.elms() + quad.elms() ;} // get number of faces
  302. Int trisTotal()C {return tri.elms() + quad.elms()*2;} // get number of triangles including quads (each quad can be represented by 2 triangles)
  303. UInt flag ( )C; // get MESH_BASE_FLAG
  304. UInt memUsage ( )C; // get memory usage
  305. Bool getBox (Box &box )C; // get box encapsulating the mesh, this method iterates through all vertexes, false on fail (if no vertexes are present)
  306. Bool getBox (Box &box , C Matrix &mesh_matrix)C; // get box encapsulating the mesh, this method iterates through all vertexes, 'mesh_matrix'=matrix affecting vertex positions, false on fail (if no vertexes are present)
  307. Bool getBall (Ball &ball )C; // get ball encapsulating the mesh, this method iterates through all vertexes, false on fail (if no vertexes are present)
  308. Bool getRect (Rect &rect )C; // get 2D rectangle encapsulating the mesh on XY plane, false on fail (if no vertexes are present)
  309. Bool getRectXZ (Rect &rect )C; // get 2D rectangle encapsulating the mesh on XZ plane, false on fail (if no vertexes are present)
  310. Flt area (Vec *center=null )C; // get surface area of all mesh faces, 'center'=if specified then it will be calculated as the average surface center
  311. Flt convexVolume( )C; // calculate volume of this mesh assuming that it's convex
  312. Int maxId ( )C; // get maximum value of ID in edges/faces, -1 if doesn't have any
  313. Bool hasId (Int id )C; // if any of the edges/faces have their id set to 'id'
  314. // set
  315. #if EE_PRIVATE
  316. MeshBase& setEdgeNormals(Bool flag=false ); // recalculate edge 2D normals, 'flag'=if include ETQ_FLAG behavior in normal calculation
  317. MeshBase& setNormals2D (Bool flag=false ); // recalculate edge and vertex 2D normals, 'flag'=if include ETQ_FLAG behavior in normal calculation
  318. MeshBase& setVtxDupEx (UInt flag=0, Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS, Bool smooth_groups_in_vtx_material=false);
  319. #endif
  320. MeshBase& setNormals ( ); // recalculate vertex 3D normals
  321. MeshBase& setTangents ( ); // recalculate vertex 3D tangents
  322. MeshBase& setBinormals ( ); // recalculate vertex 3D binormals
  323. MeshBase& setFaceNormals( ); // recalculate triangle and quad 3D normals
  324. MeshBase& setAutoTanBin ( ); // automatically calculate vertex tangents and binormals if needed, if binormals are not needed then they will be removed
  325. MeshBase& setVtxDup2D (UInt flag=0, Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS); // set vertex 2D duplicates (vtx.dup)
  326. MeshBase& setVtxDup (UInt flag=0, Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS); // set vertex 3D duplicates (vtx.dup)
  327. MeshBase& setAdjacencies(Bool faces=true, Bool edges=false ); // set adjacencies, 'faces'=if set face adjacencies ('tri.adjFace', 'quad.adjFace'), 'edges'=if set edges ('edge') and edge adjacencies ('tri.adjEdge', 'quad.adjEdge', 'edge.adjFace')
  328. // transform
  329. MeshBase& move ( C Vec &move ); // move mesh
  330. MeshBase& scale (C Vec &scale ); // scale mesh
  331. MeshBase& scaleMove(C Vec &scale, C Vec &move ); // scale and move mesh
  332. MeshBase& setSize (C Box &box ); // scale and move mesh to fit box
  333. MeshBase& transform(C Matrix3 &matrix ); // transform by matrix
  334. MeshBase& transform(C Matrix &matrix ); // transform by matrix
  335. MeshBase& animate (C MemPtrN<Matrix, 256> &matrixes ); // animate by matrixes
  336. MeshBase& animate (C AnimatedSkeleton &anim_skel); // animate by skeleton
  337. MeshBase& mirrorX ( ); // mirror in X axis
  338. MeshBase& mirrorY ( ); // mirror in Y axis
  339. MeshBase& mirrorZ ( ); // mirror in Z axis
  340. MeshBase& reverse ( ); // reverse all faces
  341. MeshBase& reverse ( Int face ); // reverse selected face , here the 'face' index can point to both triangles and quads, if face is a triangle then "face=triangle_index", if face is a quad then "face=quad_index^SIGN_BIT"
  342. MeshBase& reverse (C MemPtr<Int> &faces ); // reverse selected faces, here the 'faces' index can point to both triangles and quads, if face is a triangle then "face=triangle_index", if face is a quad then "face=quad_index^SIGN_BIT"
  343. #if EE_PRIVATE
  344. MeshBase& rightToLeft( ); // convert from right hand to left hand coordinate system
  345. #endif
  346. // texture transform
  347. MeshBase& texMove (C Vec2 &move , Byte tex_index=0); // move texture UV's
  348. MeshBase& texScale (C Vec2 &scale, Byte tex_index=0); // scale texture UV's
  349. MeshBase& texRotate( Flt angle, Byte tex_index=0); // rotate texture UV's
  350. // texturize
  351. MeshBase& texMap ( Flt scale=1, Byte tex_index=0); // map texture UV's according to vertex XY position and scale
  352. MeshBase& texMapXZ( Flt scale=1, Byte tex_index=0); // map texture UV's according to vertex XZ position and scale
  353. MeshBase& texMap (C Matrix &matrix , Byte tex_index=0); // map texture UV's according to matrix
  354. MeshBase& texMap (C Plane &plane , Byte tex_index=0); // map texture UV's according to plane
  355. MeshBase& texMap (C Ball &ball , Byte tex_index=0); // map texture UV's according to ball
  356. MeshBase& texMap (C Tube &tube , Byte tex_index=0); // map texture UV's according to tube
  357. // operations
  358. #if EE_PRIVATE
  359. MeshBase& weldEdge (); // weld edges
  360. MeshBase& weldVtx2D (UInt flag=0, Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS, Flt remove_degenerate_faces_eps=EPS); // weld 2D vertexes , this function will weld vertexes together if they share the same position (ignoring Z), 'flag'=if selected elements aren't equal then don't weld (MESH_BASE_FLAG), 'remove_degenerate_faces_eps'=epsilon used for removing degenerate faces which may occur after welding vertexes (use <0 to disable removal)
  361. #endif
  362. MeshBase& weldVtx (UInt flag=0, Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS, Flt remove_degenerate_faces_eps=EPS); // weld 3D vertexes , this function will weld vertexes together if they share the same position, 'flag'=if selected elements aren't equal then don't weld (MESH_BASE_FLAG), 'remove_degenerate_faces_eps'=epsilon used for removing degenerate faces which may occur after welding vertexes (use <0 to disable removal)
  363. MeshBase& weldVtxValues(UInt flag , Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS, Flt remove_degenerate_faces_eps=EPS); // weld vertex values, this function will weld values of vertexes which share the same position, 'flag'= elements to weld (MESH_BASE_FLAG), 'remove_degenerate_faces_eps'=epsilon used for removing degenerate faces which may occur after welding vertexes (use <0 to disable removal)
  364. MeshBase& tesselate (); // smooth subdivide faces, preserving original vertexes
  365. MeshBase& subdivide (); // smooth subdivide faces, smoothing original vertexes
  366. MeshBase& subdivideEdge(Bool freeze_z=false, C MemPtr<Bool> &is=null); // smooth subdivide edges, 'is'=only selected edges
  367. MeshBase& boneRemap(C MemPtr<Byte, 256> &old_to_new); // remap vertex bone/matrix indexes according to bone 'old_to_new' remap
  368. void setUsedBones(Bool (&bones)[256])C;
  369. void includeUsedBones(Bool (&bones)[256])C;
  370. MeshBase& explodeVtxs(); // separate vertexes so that each edge/face has its own unique vertexes
  371. MeshBase& setVtxAO(Flt strength, Flt bias, Flt max, Flt ray_length, Flt pos_eps=EPS, Int rays=1024, MESH_AO_FUNC func=MAF_FULL, Threads *threads=null); // calculate per-vertex ambient occlusion in vertex colors, 'strength'=0..1 AO strength, 'bias'=0..1, 'max'=AO limit 0..1, 'ray_length'=max ray distance to test, 'rays'=number of rays to use for AO calculation, 'func'=falloff function
  372. #if EE_PRIVATE
  373. void splitVtxs (MeshBase &dest, C MemPtr<Bool> & vtx_is, UInt flag_and=~0); // split by moving selected vertexes to 'dest' leaving the rest only, copy only elements included in 'flag_and' MESH_BASE_FLAG
  374. void splitFaces(MeshBase &dest, C MemPtr<Bool> &edge_is, C MemPtr<Bool> &tri_is, C MemPtr<Bool> &quad_is, UInt flag_and=~0); // split by moving selected faces to 'dest' leaving the rest only, copy only elements included in 'flag_and' MESH_BASE_FLAG
  375. void copyVtx (Int i, MeshBase &dest, Int dest_i )C; // copy i-th vertex to 'dest' dest_i-th vertex
  376. MeshBase& splitEdges(Flt length=1 , Bool *is=null) ; // split edges, 'length'=maximum length of edge, 'is'=only selected edges
  377. MeshBase& splitEdges(Flt length, Flt d , Bool *is=null) ; // split edges, 'length'=minimum length of edge to part, 'd'=length of added edges on left & right side, 'is'=only selected edges
  378. // join / split
  379. void split (MemPtr<MeshBaseIndex> meshes, C Boxes &boxes, UInt flag_and=~0)C; // split to container of meshes by boxes , copy only elements included in 'flag_and' MESH_BASE_FLAG
  380. void split (MemPtr<MeshBaseIndex> meshes, C VecI &cells, UInt flag_and=~0)C; // split to container of meshes by number of splits , copy only elements included in 'flag_and' MESH_BASE_FLAG
  381. void splitBone(MeshBase &dest, Int bone , UInt flag_and=~0) ; // split by moving elements influenced by 'bone' to 'dest' leaving the rest only, copy only elements included in 'flag_and' MESH_BASE_FLAG
  382. #endif
  383. // fix
  384. MeshBase& fixTexOffset (Byte tex_index=0); // fix texture offset , this reduces big texture coordinates to small ones increasing texturing quality on low precision video cards
  385. MeshBase& fixTexWrapping(Byte tex_index=0); // fix texture wrapping, fixes texture coordinates created by spherical/tube mapping (this can add new vertexes to the mesh)
  386. // link
  387. #if EE_PRIVATE
  388. void linkVtxVtxOnFace(Index &vtx_vtx )C; // link vertexes with neighbor vertexes on faces
  389. void linkVtxVtxOnEdge(Index &vtx_vtx , Bool sort=true )C; // link vertexes with neighbor vertexes on edges, 'sort'=if sort vertexes in angle order
  390. void linkVtxEdge (Index &vtx_edge, Bool sort=true )C; // link vertexes with edges, 'sort'=if sort edges in angle order
  391. void linkVtxFace (Index &vtx_face )C; // link vertexes with faces
  392. void linkFaceFace (Index &face_face )C; // link faces with faces, first are listed triangles followed by quads
  393. void linkEdgeFace ( ) ; // link edges with faces
  394. void linkRectEdge (Index &rect_edge, C Rects &rects)C; // link rectangles with edges
  395. #endif
  396. void getVtxNeighbors (Int vtx , MemPtr<Int> vtxs )C; // get 'vtxs' neighbors of 'vtx' (including itself), this will return an array of vertexes that are connected to each other
  397. void getFaceNeighbors(Int face, MemPtr<Int> faces)C; // get 'faces' neighbors of 'face' (including itself), this will return an array of faces that are connected to each other, here the 'face' and 'faces' indexes can point to both triangles and quads, if face is a triangle then "face=triangle_index", if face is a quad then "face=quad_index^SIGN_BIT"
  398. // convert
  399. #if EE_PRIVATE
  400. MeshBase& edgeToPoly (MemPtr<Poly> polys ); // edges to polys
  401. #endif
  402. MeshBase& edgeToDepth(Bool tex_align=true ); // edges to depth (extrude 2D edges to 3D faces)
  403. MeshBase& edgeToTri (Bool set_id =false ); // edges to triangles (triangulation)
  404. MeshBase& triToQuad (Flt cos =EPS_COL_COS); // triangles to quads , 'cos'=minimum cosine between 2 triangle normals to weld them into 1 quad (0..1)
  405. MeshBase& quadToTri (Flt cos =2 ); // quads to triangles, 'cos'=minimum cosine between 2 quad triangle normals to leave them as 1 quad (0..1, value >1 converts all quads into triangles)
  406. MeshBase& quadToTri (C MemPtr<Int> &quads ); // quads to triangles, 'quads'=indexes of quads to convert
  407. enum TEX_MODE
  408. {
  409. TEX_NONE , // don't create texture coordinates
  410. TEX_KEEP , // keep existing texture coordinates
  411. TEX_UNIFORM, // set uniform texture coordinates in range 0..1
  412. TEX_SCALED , // set scaled texture coordinates (X coords are scaled by vertex size, Y coords are scaled by distances between vertexes)
  413. };
  414. MeshBase& inflateEdges(TEX_MODE x_tex_coords=TEX_SCALED, TEX_MODE y_tex_coords=TEX_SCALED, Bool to_edges=false); // inflate mesh edges, 'x_tex_coords'=mode for settings X texture coordinates, 'y_tex_coords'=mode for settings Y texture coordinates, 'to_edges'=if inflate into edges (if false then faces will be created), this function operates on XY plane
  415. #if EE_PRIVATE
  416. // csg
  417. MeshBase& cut2D ( ); // cut 2D mesh by self !! beta !!
  418. MeshBase& cut2D (C MeshBase &mshb ); // cut 2D mesh by mshb !! beta !!
  419. MeshBase& grid2D(C Vec2 &scale=Vec2(1), C Vec2 &offset=Vec2(0)); // cut 2D mesh by grid !! beta !!
  420. MeshBase& csg2D (C MeshBase &mshb , UInt sel ); // csg 2D, sel=SEL_FLAG !! beta !!
  421. #endif
  422. // add / remove
  423. MeshBase& addVtx (C Vec &pos ); // add empty vertex at 'pos' position
  424. MeshBase& addEdge(C VecI2 &ind ); // add edge by giving vertex indexes
  425. MeshBase& addTri (C VecI &ind ); // add triangle by giving vertex indexes
  426. MeshBase& addQuad(C VecI4 &ind ); // add quad by giving vertex indexes
  427. MeshBase& add (C MeshBase &src, UInt flag_and=~0); // add MeshBase
  428. MeshBase& add (C MeshRender &src, UInt flag_and=~0); // add MeshRender
  429. MeshBase& add (C MeshPart &src, UInt flag_and=~0); // add MeshPart
  430. #if EE_PRIVATE
  431. MeshBase& keepVtxs (C MemPtr<Bool> &is); // keep only vertexes which "is[i]==true"
  432. MeshBase& keepEdges(C MemPtr<Bool> &is); // keep only edges which "is[i]==true"
  433. MeshBase& keepTris (C MemPtr<Bool> &is); // keep only triangles which "is[i]==true"
  434. MeshBase& keepQuads(C MemPtr<Bool> &is); // keep only quads which "is[i]==true"
  435. #endif
  436. MeshBase& removeVtx (Int vtx );
  437. MeshBase& removeEdge(Int edge);
  438. MeshBase& removeTri (Int tri );
  439. MeshBase& removeQuad(Int quad);
  440. MeshBase& removeFace(Int face); // remove face, here the 'face' index can point to both triangles and quads, if face is a triangle then "face=triangle_index", if face is a quad then "face=quad_index^SIGN_BIT"
  441. MeshBase& removeVtxs (C MemPtr<Int> &vtxs ); // remove selected vertexes
  442. MeshBase& removeEdges(C MemPtr<Int> &edges, Bool remove_unused_vtxs=true); // remove selected edges
  443. MeshBase& removeTris (C MemPtr<Int> &tris , Bool remove_unused_vtxs=true); // remove selected triangles
  444. MeshBase& removeQuads(C MemPtr<Int> &quads, Bool remove_unused_vtxs=true); // remove selected quads
  445. MeshBase& removeFaces(C MemPtr<Int> &faces, Bool remove_unused_vtxs=true); // remove selected faces, here the 'faces' indexes can point to both triangles and quads, if face is a triangle then "face=triangle_index", if face is a quad then "face=quad_index^SIGN_BIT"
  446. MeshBase& removeDoubleSideFaces(Bool remove_unused_vtxs=true);
  447. MeshBase& mergeFaces(Int a, Int b); // this method will merge 2 faces together, but only if they share exactly 2 vertexes
  448. // optimize
  449. #if EE_PRIVATE
  450. MeshBase& removeSingleFaces (Flt fraction ); // remove fraction (0..1) of single faces (single triangles or quads not linked to any other face)
  451. MeshBase& removeDoubleEdges ();
  452. MeshBase& weldInlineEdges (Flt cos_edge=EPS_COL_COS, Flt cos_vtx=-1, Bool z_test=true); // weld inline edge vertexes, 'cos_edge'=minimum cosine between edge normals, 'cos_vtx'=minimum cosine between vertex normals, 'z_test'=if perform tests for inline 'z' vertex component
  453. #endif
  454. MeshBase& optimizeCache (Bool faces=true, Bool vertexes=true); // this method will re-order elements for best rendering performance, 'faces'=if re-order faces, 'vertexes'=if re-order vertexes
  455. MeshBase& removeDegenerateFaces(Flt eps=EPS);
  456. Bool removeUnusedVtxs (Bool include_edge_references=true); // remove vertexes which aren't used by any face or edge, if 'include_edge_references' is set to false then only face references are tested (without the edges), returns true if any vertex was removed
  457. MeshBase& simplify(Flt intensity, Flt max_distance=1.0f, Flt max_uv=1.0f, Flt max_color=0.02f, Flt max_material=0.02f, Flt max_skin=1, Flt max_normal=PI, Bool keep_border=false, MESH_SIMPLIFY mode=SIMPLIFY_QUADRIC, Flt pos_eps=EPS, MeshBase *dest=null); // simplify mesh by removing vertexes/faces, 'intensity'=how much to simplify (0..1, 0=no simplification, 1=full simplification), 'max_distance'=max distance between elements to merge them (0..Inf), 'max_uv'=max allowed vertex texture UV deviations (0..1), 'max_color'=max allowed vertex color deviations (0..1), 'max_material'=max allowed vertex material deviations (0..1), 'max_skin'=max allowed vertex skin deviations (0..1), 'max_normal'=max allowed vertex normal angle deviations (0..PI), 'keep_border'=if always keep border edges (edges that have faces only on one side), 'pos_eps'=vertex position epsilon, 'dest'=destination MeshBase (if set to null then the mesh will simplify itself), returns dest
  458. MeshBase& weldCoplanarFaces(Flt cos_face=EPS_COL_COS, Flt cos_vtx=-1, Bool safe=true, Flt max_face_length=-1); // weld coplanar faces, 'cos_face'=minimum cosine between face normals, 'cos_vtx'=minimum cosine between vertex normals, 'safe'=if process only faces without neighbors, 'max_face_length'=max allowed face length (-1=no limit)
  459. // draw
  460. #if EE_PRIVATE
  461. void draw2D (C Color &vtx_color, C Color &edge_color, C Color &face_color, Flt vtx_r=0.04f, Flt side_width=0.1f )C; // draw 2D
  462. void drawNormals2D( Flt length , C Color &edge_color, C Color &vtx_color=TRANSPARENT )C; // draw 2D normals
  463. void drawNormals ( Flt length , C Color &face_color, C Color &vtx_color=TRANSPARENT, C Color &tangent_color=TRANSPARENT, C Color &binormal_color=TRANSPARENT)C; // draw 3D normals
  464. #endif
  465. void drawAuto(C Material *material)C; // draw 3D, doesn't use automatic Frustum culling, optionally call this outside Render or inside Render function in any desired RENDER_MODE
  466. // io
  467. void operator=(C Str &name) ; // load, Exit on fail
  468. Bool save (C Str &name)C; // save, false on fail
  469. Bool load (C Str &name) ; // load, false on fail
  470. Bool save ( File &f )C; // save, false on fail
  471. Bool load ( File &f, CChar *path=null) ; // load, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  472. #if EE_PRIVATE
  473. Bool saveData(File &f)C; // save, false on fail
  474. Bool loadData(File &f) ; // load, false on fail
  475. Bool saveTxt (FileText &f)C; // save text, false on fail
  476. Bool loadTxt (FileText &f) ; // load text, false on fail
  477. Bool saveTxt (C Str &name)C; // save text, false on fail
  478. Bool loadTxt (C Str &name) ; // load text, false on fail
  479. #endif
  480. MeshBase& operator*=(C Matrix3 &m ) {return transform(m );} // transform by matrix
  481. MeshBase& operator*=(C Matrix &m ) {return transform(m );} // transform by matrix
  482. MeshBase& operator+=(C MeshBase &src) {return add (src);} // add 'src'
  483. MeshBase& operator+=(C MeshRender &src) {return add (src);} // add 'src'
  484. MeshBase& operator+=(C MeshPart &src) {return add (src);} // add 'src'
  485. MeshBase& operator =(C MeshBase &src) {return create (src);} // create from 'src'
  486. ~MeshBase() {del ( );}
  487. MeshBase() {Zero(T);}
  488. explicit MeshBase( Int vtxs, Int edges, Int tris, Int quads, UInt flag=0);
  489. explicit MeshBase(C MeshBase &src , UInt flag_and=~0 );
  490. explicit MeshBase(C MeshRender &src , UInt flag_and=~0 );
  491. explicit MeshBase(C MeshPart &src , UInt flag_and=~0 );
  492. explicit MeshBase(C MeshLod &src , UInt flag_and=~0 );
  493. explicit MeshBase(C PhysPart &src );
  494. };
  495. /******************************************************************************/
  496. #if EE_PRIVATE
  497. struct MeshBaseIndex : MeshBase
  498. {
  499. Int index;
  500. };
  501. #endif
  502. /******************************************************************************/
  503. inline Int Elms(C MeshVtxs &vtx ) {return vtx .elms();}
  504. inline Int Elms(C MeshEdges &edge) {return edge.elms();}
  505. inline Int Elms(C MeshTris &tri ) {return tri .elms();}
  506. inline Int Elms(C MeshQuads &quad) {return quad.elms();}
  507. /******************************************************************************/