Mesh Lod.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /******************************************************************************
  2. 'MeshLod' represents a single level of detail, by containing an array of 'MeshPart's.
  3. /******************************************************************************/
  4. struct MeshLod // Level of Detail, array of Mesh Part's
  5. {
  6. Flt dist2; // squared distance at which this level of detail should be rendered when using 90 deg FOV, negative version means that this LOD should be removed
  7. Mems<MeshPart> parts; // mesh parts
  8. // manage
  9. MeshLod& del ( ); // delete
  10. MeshLod& create( Int num ); // create with 'num' empty MeshParts
  11. MeshLod& create(C MeshLod &src, UInt flag_and=~0); // create from 'src', 'flag_and'=MESH_BASE_FLAG
  12. void copyParams(C MeshLod &src); // copy only parameters without meshes
  13. #if EE_PRIVATE
  14. void zero();
  15. void scaleParams(Flt scale);
  16. MeshLod& include (UInt flag); // include elements specified with 'flag' MESH_BASE_FLAG
  17. #endif
  18. MeshLod& exclude (UInt flag); // exclude elements specified with 'flag' MESH_BASE_FLAG
  19. MeshLod& keepOnly(UInt flag); // keep only elements specified with 'flag' MESH_BASE_FLAG
  20. // get
  21. Bool is ( )C {return parts.elms()>0;} // if has any parts
  22. UInt flag ( )C; // get MESH_BASE_FLAG
  23. UInt memUsage ( )C; // get memory usage
  24. Int vtxs ( )C; // get total number of vertexes
  25. Int edges ( )C; // get total number of edges
  26. Int tris ( )C; // get total number of triangles
  27. Int quads ( )C; // get total number of quads
  28. Int faces ( )C; // get total number of faces , faces =(triangles + quads )
  29. Int trisTotal( )C; // get total number of triangles including quads, trisTotal=(triangles + quads*2)
  30. Bool getBox (Box &box, Bool skip_hidden_parts=true)C; // get box encapsulating the MeshLod, 'skip_hidden_parts'=if MeshParts with MSHP_HIDDEN should not be included in the box, returns false on fail (if no vertexes are present)
  31. 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
  32. Flt dist ( )C; MeshLod& dist(Flt dist); // get/set LOD distance
  33. Bool hasDrawGroup ( Int draw_group_index)C; // check if at least one MeshPart has specified draw group enum index
  34. Bool hasDrawGroupMask(UInt draw_group_mask )C; // check if at least one MeshPart has specified draw group enum mask
  35. // set
  36. #if EE_PRIVATE
  37. MeshLod& setEdgeNormals(Bool flag=false); // recalculate edge 2D normals, 'flag'=if include ETQ_FLAG behavior
  38. MeshLod& setNormals2D (Bool flag=false); // recalculate edge and vertex 2D normals, 'flag'=if include ETQ_FLAG behavior
  39. #endif
  40. MeshLod& setNormals (); // recalculate vertex 3D normals
  41. MeshLod& setTangents (); // recalculate vertex 3D tangents
  42. MeshLod& setBinormals (); // recalculate vertex 3D binormals
  43. MeshLod& setFaceNormals(); // recalculate triangle and quad 3D normals
  44. MeshLod& setAutoTanBin (); // automatically calculate vertex tangents and binormals if needed, if they're not needed then they will be removed
  45. #if EE_PRIVATE
  46. MeshLod& setVtxColorAlphaAsTesselationIntensity(Bool tesselate_edges ); // set vertex color alpha (vtx.color.a) as tesselation intensity, 'tesselate_edges'=if tesselate non continuous edges
  47. MeshLod& setVtxDup2D (UInt flag=0, Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS); // set vertex 2D duplicates (vtx.dup)
  48. #endif
  49. MeshLod& setVtxDup (UInt flag=0, Flt pos_eps=EPS, Flt nrm_cos=EPS_COL_COS); // set vertex 3D duplicates (vtx.dup)
  50. MeshLod& 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')
  51. MeshLod& delBase ( ); // delete all software meshes (MeshBase ) in this mesh
  52. MeshLod& delRender( ); // delete all hardware meshes (MeshRender) in this mesh
  53. #if EE_PRIVATE
  54. MeshLod& setRenderSS( ); // set rendering version of stencil shadow
  55. #endif
  56. MeshLod& setBase (Bool only_if_empty=true ); // set software version, convert 'MeshRender' to 'MeshBase', 'only_if_empty'=perform conversion only if the MeshBase is empty (if set to false then conversion is always performed)
  57. MeshLod& setRender(Bool optimize =true, Int lod_index=0); // set rendering version, convert 'MeshBase' to 'MeshRender', 'optimize'=if optimize the mesh by re-ordering the vertexes/triangles for optimal processing on the GPU, 'lod_index'=index of the LOD in the mesh (used to determine quality of the shader)
  58. MeshLod& setShader( Int lod_index=0); // reset shader, 'lod_index'=index of the LOD in the mesh (used to determine quality of the shader)
  59. MeshLod& material (C MaterialPtr &material, Int lod_index=0); // set material, 'lod_index'=index of the LOD in the mesh (used to determine quality of the shader, if it's <0 then shader will not be reset), 'material' must point to object in constant memory address (mesh will store only the pointer to the material and later use it if needed)
  60. // transform
  61. MeshLod& move ( C Vec &move ); // move
  62. MeshLod& scale (C Vec &scale ); // scale
  63. MeshLod& scaleMove (C Vec &scale, C Vec &move ); // scale and move
  64. MeshLod& scaleMoveBase(C Vec &scale, C Vec &move ); // scale and move (including the 'MeshBase' but without 'MeshRender')
  65. MeshLod& transform (C Matrix3 &matrix ); // transform by matrix
  66. MeshLod& transform (C Matrix &matrix ); // transform by matrix
  67. MeshLod& animate (C MemPtrN<Matrix, 256> &matrixes ); // animate by matrixes
  68. MeshLod& animate (C AnimatedSkeleton &anim_skel); // animate by skeleton
  69. MeshLod& mirrorX ( ); // mirror in X axis
  70. MeshLod& mirrorY ( ); // mirror in Y axis
  71. MeshLod& mirrorZ ( ); // mirror in Z axis
  72. MeshLod& reverse ( ); // reverse faces
  73. #if EE_PRIVATE
  74. MeshLod& rightToLeft ( ); // convert from right hand to left hand coordinate system
  75. #endif
  76. #if EE_PRIVATE
  77. // texturize
  78. MeshLod& texMap( Flt scale=1, Byte tex_index=0); // map texture UV's according to vertex XY position and scale
  79. MeshLod& texMap(C Matrix &matrix , Byte tex_index=0); // map texture UV's according to matrix
  80. MeshLod& texMap(C Plane &plane , Byte tex_index=0); // map texture UV's according to plane
  81. MeshLod& texMap(C Ball &ball , Byte tex_index=0); // map texture UV's according to ball
  82. MeshLod& texMap(C Tube &tube , Byte tex_index=0); // map texture UV's according to tube
  83. #endif
  84. // texture transform
  85. MeshLod& texMove (C Vec2 &move , Byte tex_index=0); // move texture UV's
  86. MeshLod& texScale (C Vec2 &scale, Byte tex_index=0); // scale texture UV's
  87. MeshLod& texRotate( Flt angle, Byte tex_index=0); // rotate texture UV's
  88. // join / split
  89. MeshLod& join (Int i0, Int i1 , Flt weld_pos_eps=EPS); // join i0-th and i1-th parts together, 'weld_pos_eps'=epsilon used for welding vertexes after joining (use <0 to disable welding)
  90. MeshLod& joinAll(Bool test_material, Bool test_draw_group, Bool test_name, UInt test_vtx_flag=0, Flt weld_pos_eps=EPS); // join all parts, 'test_material'=join only those MeshParts which have the same material, 'test_draw_group'=join only those MeshParts which have the same draw group, 'test_name'=join only those MeshParts which have the same name, 'test_vtx_flag'=join only those MeshParts which have same vertex flag, 'weld_pos_eps'=epsilon used for welding vertexes after joining (use <0 to disable welding)
  91. #if EE_PRIVATE
  92. MeshPart* splitVtxs (Int i, C MemPtr<Bool> &vtx_is ); // split i-th part by given 'is' array of vertexes to a new MeshPart, pointer to that MeshPart is returned or null if it wasn't created
  93. MeshPart* splitFaces(Int i, C MemPtr<Bool> &edge_is, C MemPtr<Bool> &tri_is, C MemPtr<Bool> &quad_is); // split i-th part by given 'is' array of faces to a new MeshPart, pointer to that MeshPart is returned or null if it wasn't created
  94. MeshPart* splitBone (Int i, Int bone, C Skeleton *skeleton=null); // split i-th part by bone blend index to a new MeshPart, pointer to that MeshPart is returned or null if it wasn't created
  95. #endif
  96. MeshPart* splitVtxs (Int i, C MemPtr<Int> &vtxs ); // split i-th part by given array of vertexes to a new MeshPart, pointer to that MeshPart is returned or null if it wasn't created
  97. MeshPart* splitFaces(Int i, C MemPtr<Int> &faces ); // split i-th part by given array of faces to a new MeshPart, pointer to that MeshPart is returned or null if it wasn't created, here '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"
  98. MeshPart* splitFaces(Int i, C MemPtr<Int> &edges, C MemPtr<Int> &tris, C MemPtr<Int> &quads); // split i-th part by given array of faces to a new MeshPart, pointer to that MeshPart is returned or null if it wasn't created
  99. // operations
  100. #if EE_PRIVATE
  101. MeshLod& weldEdge (); // weld edges
  102. MeshLod& 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)
  103. #endif
  104. MeshLod& 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)
  105. MeshLod& 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)
  106. MeshLod& tesselate(); // smooth subdivide faces, preserving original vertexes
  107. MeshLod& subdivide(); // smooth subdivide faces, smoothing original vertexes
  108. MeshLod& boneRemap(C MemPtr<Byte, 256> &old_to_new); // remap vertex bone/matrix indexes according to bone 'old_to_new' remap
  109. void setUsedBones(Bool (&bones)[256])C;
  110. void includeUsedBones(Bool (&bones)[256])C;
  111. MeshLod& 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
  112. MeshLod& freeOpenGLESData(); // this method is used only under OpenGL ES (on other platforms it is ignored), the method frees the software copy of the GPU data which increases available memory, however after calling this method the data can no longer be accessed on the CPU (can no longer be locked or saved to file)
  113. // fix
  114. MeshLod& fixTexOffset (Byte tex_index=0); // fix texture offset , this reduces big texture coordinates to small ones increasing texturing quality on low precision video cards
  115. MeshLod& fixTexWrapping(Byte tex_index=0); // fix texture wrapping, fixes texture coordinates created by spherical/tube mapping (this can add new vertexes to the mesh)
  116. // convert
  117. MeshLod& edgeToDepth(Bool tex_align =true ); // edges to depth (extrude 2D edges to 3D faces)
  118. MeshLod& edgeToTri (Bool set_id =false ); // edges to triangles (triangulation)
  119. MeshLod& triToQuad (Flt cos =EPS_COL_COS); // triangles to quads , 'cos'=minimum cosine between 2 triangle normals to weld them into 1 quad (0..1)
  120. MeshLod& 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)
  121. // add / remove
  122. MeshLod& add(C MeshBase &src ); // add MeshBase to self
  123. MeshLod& add(C MeshPart &src ); // add MeshPart to self
  124. MeshLod& add(C MeshLod &src, C Mesh *src_mesh=null, C Mesh *this_mesh=null); // add MeshLod to self, 'src_mesh'=Mesh that 'src' belongs to, 'this_mesh'=Mesh that this belongs to, settings 'src_mesh' and 'this_mesh' is optional, it is used for remapping mesh part variations
  125. // optimize
  126. #if EE_PRIVATE
  127. MeshLod& sortByMaterials (); // sort MeshParts according to their materials
  128. MeshLod& removeDoubleEdges();
  129. MeshLod& removeSingleFaces(Flt fraction ); // remove fraction of single faces (single triangles or quads not linked to any other face), 'fraction'=0..1
  130. MeshLod& 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
  131. #endif
  132. MeshLod& removeDegenerateFaces(Flt eps=EPS);
  133. 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
  134. MeshLod& 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, MeshLod *dest=null, Bool *stop=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), 'stop'=set to 'true' on secondary thread to stop this method, returns dest
  135. MeshLod& 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)
  136. // draw
  137. #if EE_PRIVATE
  138. // helper drawing
  139. void draw2D (C Color &vtx_color, C Color &edge_color, C Color &face_color, Flt vtx_r=0.04f, Flt side_width=0.01f )C; // draw 2D
  140. void drawNormals2D( Flt length , C Color &edge_color, C Color &vtx_color=TRANSPARENT )C; // draw 2D normals
  141. 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
  142. #endif
  143. // default drawing, doesn't use automatic Frustum Culling, this doesn't draw the mesh immediately, instead it adds the mesh to a draw list
  144. void draw(C MatrixM &matrix, C Vec &vel, C Vec &ang_vel=VecZero)C; // add mesh to draw list using 'matrix' matrix, 'vel' velocity and 'ang_vel' angular velocity, this should be called only in RM_PREPARE, when used it will automatically draw meshes in following modes when needed: RM_EARLY_Z RM_SIMPLE RM_SOLID RM_SOLID_M RM_AMBIENT RM_BLEND
  145. void draw(C MatrixM &matrix )C; // add mesh to draw list using 'matrix' matrix and no velocities , this should be called only in RM_PREPARE, when used it will automatically draw meshes in following modes when needed: RM_EARLY_Z RM_SIMPLE RM_SOLID RM_SOLID_M RM_AMBIENT RM_BLEND
  146. void draw(C AnimatedSkeleton &anim_skel )C; // add mesh to draw list using 'anim_skel' matrixes and velocities , this should be called only in RM_PREPARE, when used it will automatically draw meshes in following modes when needed: RM_SIMPLE RM_SOLID RM_SOLID_M RM_AMBIENT RM_BLEND, 'anim_skel' must point to constant memory address (the pointer is stored through which the object can be accessed later during frame rendering)
  147. void draw(C AnimatedSkeleton &anim_skel, C Material &material )C; // add mesh to draw list using 'anim_skel' matrixes and velocities , this should be called only in RM_PREPARE, when used it will automatically draw meshes in following modes when needed: RM_SIMPLE RM_SOLID RM_SOLID_M RM_AMBIENT RM_BLEND, 'anim_skel' must point to constant memory address (the pointer is stored through which the object can be accessed later during frame rendering), 'material'=material used for rendering which overrides the default material, however for performance reasons, the default shader is used, which means that the 'material' should be similar to the default material, and if it's too different then some artifacts can occur
  148. void drawShadow(C MatrixM &matrix )C; // add mesh to shadow draw list using 'matrix' matrix , this should be called only in RM_SHADOW
  149. void drawShadow(C AnimatedSkeleton &anim_skel )C; // add mesh to shadow draw list using 'anim_skel' skeleton, this should be called only in RM_SHADOW, 'anim_skel' must point to constant memory address (the pointer is stored through which the object can be accessed later during frame rendering)
  150. void drawShadow(C AnimatedSkeleton &anim_skel, C Material &material)C; // add mesh to shadow draw list using 'anim_skel' skeleton, this should be called only in RM_SHADOW, 'anim_skel' must point to constant memory address (the pointer is stored through which the object can be accessed later during frame rendering), 'material'=material used for rendering which overrides the default material, however for performance reasons, the default shader is used, which means that the 'material' should be similar to the default material, and if it's too different then some artifacts can occur
  151. // draw blended, this is an alternative to default 'draw' (typically 'draw' draws blended meshes automatically for materials with technique in blend mode), this method however draws the mesh immediately (which allows to set custom shader parameters per draw call), it always uses blend shaders regardless if the material has technique set in blend mode, and provides additional control over material color, this can be called only in RM_BLEND rendering mode, doesn't use automatic Frustum culling
  152. void drawBlend(C Vec4 *color=null)C; // draw with current matrix, 'color'=pointer to optional Material color multiplication
  153. // draw mesh outline, this can be optionally called in RM_OUTLINE in order to outline the mesh, doesn't use automatic Frustum culling
  154. void drawOutline(C Color &color)C; // draw with current matrix
  155. // draw using the "behind" effect, this can be optionally called in RM_BEHIND, doesn't use automatic Frustum culling
  156. void drawBehind(C Color &color_perp, C Color &color_parallel)C; // draw with current matrix, 'color_perp'=color to be used for normals perpendicular to camera, 'color_parallel'=color to be used for normals parallel to camera
  157. #if EE_PRIVATE
  158. // io
  159. Bool save (File &f, CChar *path=null)C; // save, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  160. 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
  161. Bool saveData(File &f, CChar *path=null)C; // save, 'path'=path at which resource is located (this is needed so that the sub-resources can be accessed with relative path), false on fail
  162. Bool loadData(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
  163. Bool loadOld (File &f, CChar *path=null) ;
  164. #endif
  165. void operator*=(C Matrix3 &m) {transform(m);} // transform by matrix
  166. void operator*=(C Matrix &m) {transform(m);} // transform by matrix
  167. MeshLod();
  168. };
  169. /******************************************************************************/
  170. inline Int Elms(C MeshLod &mshl) {return mshl.parts.elms();}
  171. /******************************************************************************/