r3d_mesh.odin 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /* r3d_mesh.odin -- R3D Mesh Module.
  2. *
  3. * Copyright (c) 2025-2026 Le Juez Victor
  4. *
  5. * This software is provided 'as-is', without any express or implied warranty.
  6. * For conditions of distribution and use, see accompanying LICENSE file.
  7. */
  8. package r3d
  9. import rl "vendor:raylib"
  10. when ODIN_OS == .Windows {
  11. foreign import lib {
  12. "windows/libr3d.a",
  13. "system:raylib",
  14. "system:assimp",
  15. }
  16. } else when ODIN_OS == .Linux {
  17. foreign import lib {
  18. "linux/libr3d.a",
  19. "system:raylib",
  20. "system:assimp",
  21. }
  22. } else when ODIN_OS == .Darwin {
  23. foreign import lib {
  24. "darwin/libr3d.a",
  25. "system:raylib",
  26. "system:assimp",
  27. }
  28. }
  29. /**
  30. * @brief Hint on how a mesh will be used.
  31. */
  32. MeshUsage :: enum u32 {
  33. STATIC_MESH = 0, ///< Will never be updated.
  34. DYNAMIC_MESH = 1, ///< Will be updated occasionally.
  35. STREAMED_MESH = 2, ///< Will be update on each frame.
  36. }
  37. /**
  38. * @brief Defines the geometric primitive type.
  39. */
  40. PrimitiveType :: enum u32 {
  41. POINTS = 0, ///< Each vertex represents a single point.
  42. LINES = 1, ///< Each pair of vertices forms an independent line segment.
  43. LINE_STRIP = 2, ///< Connected series of line segments sharing vertices.
  44. LINE_LOOP = 3, ///< Closed loop of connected line segments.
  45. TRIANGLES = 4, ///< Each set of three vertices forms an independent triangle.
  46. TRIANGLE_STRIP = 5, ///< Connected strip of triangles sharing vertices.
  47. TRIANGLE_FAN = 6, ///< Fan of triangles sharing the first vertex.
  48. }
  49. /**
  50. * @brief Shadow casting modes for objects.
  51. *
  52. * Controls how an object interacts with the shadow mapping system.
  53. * These modes determine whether the object contributes to shadows,
  54. * and if so, whether it is also rendered in the main pass.
  55. */
  56. ShadowCastMode :: enum u32 {
  57. ON_AUTO = 0, ///< The object casts shadows; the faces used are determined by the material's culling mode.
  58. ON_DOUBLE_SIDED = 1, ///< The object casts shadows with both front and back faces, ignoring face culling.
  59. ON_FRONT_SIDE = 2, ///< The object casts shadows with only front faces, culling back faces.
  60. ON_BACK_SIDE = 3, ///< The object casts shadows with only back faces, culling front faces.
  61. ONLY_AUTO = 4, ///< The object only casts shadows; the faces used are determined by the material's culling mode.
  62. ONLY_DOUBLE_SIDED = 5, ///< The object only casts shadows with both front and back faces, ignoring face culling.
  63. ONLY_FRONT_SIDE = 6, ///< The object only casts shadows with only front faces, culling back faces.
  64. ONLY_BACK_SIDE = 7, ///< The object only casts shadows with only back faces, culling front faces.
  65. DISABLED = 8, ///< The object does not cast shadows at all.
  66. }
  67. /**
  68. * @brief Represents a 3D mesh.
  69. *
  70. * Stores vertex and index data, shadow casting settings, bounding box, and layer information.
  71. * Can represent a static or skinned mesh.
  72. */
  73. Mesh :: struct {
  74. vao, vbo, ebo: u32, ///< OpenGL objects handles.
  75. vertexCount, indexCount: i32, ///< Number of vertices and indices currently in use.
  76. allocVertexCount, allocIndexCount: i32, ///< Number of vertices and indices allocated in GPU buffers.
  77. shadowCastMode: ShadowCastMode, ///< Shadow casting mode for the mesh.
  78. primitiveType: PrimitiveType, ///< Type of primitive that constitutes the vertices.
  79. usage: MeshUsage, ///< Hint about the usage of the mesh, retained in case of update if there is a reallocation.
  80. layerMask: Layer, ///< Bitfield indicating the rendering layer(s) of this mesh.
  81. aabb: rl.BoundingBox, ///< Axis-Aligned Bounding Box in local space.
  82. }
  83. @(default_calling_convention="c", link_prefix="R3D_")
  84. foreign lib {
  85. /**
  86. * @brief Creates a 3D mesh from CPU-side mesh data.
  87. * @param type Primitive type used to interpret vertex data.
  88. * @param data R3D_MeshData containing vertices and indices (cannot be NULL).
  89. * @param aabb Optional pointer to a bounding box. If NULL, it will be computed automatically.
  90. * @param usage Hint on how the mesh will be used.
  91. * @return Created R3D_Mesh.
  92. * @note The function copies all vertex and index data into GPU buffers.
  93. */
  94. LoadMesh :: proc(type: PrimitiveType, data: MeshData, aabb: ^rl.BoundingBox, usage: MeshUsage) -> Mesh ---
  95. /**
  96. * @brief Destroys a 3D mesh and frees its resources.
  97. * @param mesh R3D_Mesh to destroy.
  98. */
  99. UnloadMesh :: proc(mesh: Mesh) ---
  100. /**
  101. * @brief Check if a mesh is valid for rendering.
  102. *
  103. * Returns true if the mesh has a valid VAO and VBO.
  104. *
  105. * @param mesh The mesh to check.
  106. * @return true if valid, false otherwise.
  107. */
  108. IsMeshValid :: proc(mesh: Mesh) -> bool ---
  109. /**
  110. * @brief Generate a quad mesh with orientation.
  111. * @param width Width along local X axis.
  112. * @param length Length along local Z axis.
  113. * @param resX Subdivisions along width.
  114. * @param resZ Subdivisions along length.
  115. * @param frontDir Direction vector for the quad's front face.
  116. * @return Mesh ready for rendering.
  117. * @see R3D_GenMeshDataQuad
  118. */
  119. GenMeshQuad :: proc(width: f32, length: f32, resX: i32, resZ: i32, frontDir: rl.Vector3) -> Mesh ---
  120. /**
  121. * @brief Generate a plane mesh.
  122. * @param width Width along X axis.
  123. * @param length Length along Z axis.
  124. * @param resX Subdivisions along X axis.
  125. * @param resZ Subdivisions along Z axis.
  126. * @return Mesh ready for rendering.
  127. * @see R3D_GenMeshDataPlane
  128. */
  129. GenMeshPlane :: proc(width: f32, length: f32, resX: i32, resZ: i32) -> Mesh ---
  130. /**
  131. * @brief Generate a polygon mesh.
  132. * @param sides Number of sides (min 3).
  133. * @param radius Radius of the polygon.
  134. * @param frontDir Direction vector for the polygon's front face.
  135. * @return Mesh ready for rendering.
  136. * @see R3D_GenMeshDataPoly
  137. */
  138. GenMeshPoly :: proc(sides: i32, radius: f32, frontDir: rl.Vector3) -> Mesh ---
  139. /**
  140. * @brief Generate a cube mesh.
  141. * @param width Width along X axis.
  142. * @param height Height along Y axis.
  143. * @param length Length along Z axis.
  144. * @return Mesh ready for rendering.
  145. * @see R3D_GenMeshDataCube
  146. */
  147. GenMeshCube :: proc(width: f32, height: f32, length: f32) -> Mesh ---
  148. /**
  149. * @brief Generate a subdivided cube mesh.
  150. * @param width Width along X axis.
  151. * @param height Height along Y axis.
  152. * @param length Length along Z axis.
  153. * @param resX Subdivisions along X axis.
  154. * @param resY Subdivisions along Y axis.
  155. * @param resZ Subdivisions along Z axis.
  156. * @return Mesh ready for rendering.
  157. * @see R3D_GenMeshDataCubeEx
  158. */
  159. GenMeshCubeEx :: proc(width: f32, height: f32, length: f32, resX: i32, resY: i32, resZ: i32) -> Mesh ---
  160. /**
  161. * @brief Generate a slope mesh.
  162. * @param width Width along X axis.
  163. * @param height Height along Y axis.
  164. * @param length Length along Z axis.
  165. * @param slopeNormal Direction of the slope.
  166. * @return Mesh ready for rendering.
  167. * @see R3D_GenMeshDataSlope
  168. */
  169. GenMeshSlope :: proc(width: f32, height: f32, length: f32, slopeNormal: rl.Vector3) -> Mesh ---
  170. /**
  171. * @brief Generate a sphere mesh.
  172. * @param radius Sphere radius.
  173. * @param rings Number of latitude divisions.
  174. * @param slices Number of longitude divisions.
  175. * @return Mesh ready for rendering.
  176. * @see R3D_GenMeshDataSphere
  177. */
  178. GenMeshSphere :: proc(radius: f32, rings: i32, slices: i32) -> Mesh ---
  179. /**
  180. * @brief Generate a hemisphere mesh.
  181. * @param radius Hemisphere radius.
  182. * @param rings Number of latitude divisions.
  183. * @param slices Number of longitude divisions.
  184. * @return Mesh ready for rendering.
  185. * @see R3D_GenMeshDataHemiSphere
  186. */
  187. GenMeshHemiSphere :: proc(radius: f32, rings: i32, slices: i32) -> Mesh ---
  188. /**
  189. * @brief Generate a cylinder mesh.
  190. * @param bottomRadius Bottom radius.
  191. * @param topRadius Top radius.
  192. * @param height Height along Y axis.
  193. * @param slices Radial subdivisions.
  194. * @return Mesh ready for rendering.
  195. * @see R3D_GenMeshDataCylinder
  196. */
  197. GenMeshCylinder :: proc(bottomRadius: f32, topRadius: f32, height: f32, slices: i32) -> Mesh ---
  198. /**
  199. * @brief Generate a capsule mesh.
  200. * @param radius Capsule radius.
  201. * @param height Height along Y axis.
  202. * @param rings Number of latitude divisions.
  203. * @param slices Number of longitude divisions.
  204. * @return Mesh ready for rendering.
  205. * @see R3D_GenMeshDataCapsule
  206. */
  207. GenMeshCapsule :: proc(radius: f32, height: f32, rings: i32, slices: i32) -> Mesh ---
  208. /**
  209. * @brief Generate a torus mesh.
  210. * @param radius Major radius (center to tube).
  211. * @param size Minor radius (tube thickness).
  212. * @param radSeg Segments around major radius.
  213. * @param sides Sides around tube cross-section.
  214. * @return Mesh ready for rendering.
  215. * @see R3D_GenMeshDataTorus
  216. */
  217. GenMeshTorus :: proc(radius: f32, size: f32, radSeg: i32, sides: i32) -> Mesh ---
  218. /**
  219. * @brief Generate a trefoil knot mesh.
  220. * @param radius Major radius.
  221. * @param size Minor radius.
  222. * @param radSeg Segments around major radius.
  223. * @param sides Sides around tube cross-section.
  224. * @return Mesh ready for rendering.
  225. * @see R3D_GenMeshDataKnot
  226. */
  227. GenMeshKnot :: proc(radius: f32, size: f32, radSeg: i32, sides: i32) -> Mesh ---
  228. /**
  229. * @brief Generate a heightmap terrain mesh.
  230. * @param heightmap Heightmap image.
  231. * @param size 3D dimensions of terrain.
  232. * @return Mesh ready for rendering.
  233. * @see R3D_GenMeshDataHeightmap
  234. */
  235. GenMeshHeightmap :: proc(heightmap: rl.Image, size: rl.Vector3) -> Mesh ---
  236. /**
  237. * @brief Generate a cubicmap voxel mesh.
  238. * @param cubicmap Cubicmap image.
  239. * @param cubeSize Size of each cube.
  240. * @return Mesh ready for rendering.
  241. * @see R3D_GenMeshDataCubicmap
  242. */
  243. GenMeshCubicmap :: proc(cubicmap: rl.Image, cubeSize: rl.Vector3) -> Mesh ---
  244. /**
  245. * @brief Upload a mesh data on the GPU.
  246. *
  247. * This function uploads a mesh's vertex and optional index data to the GPU.
  248. *
  249. * If `aabb` is provided, it will be used as the mesh's bounding box; if null,
  250. * the bounding box is automatically recalculated from the vertex data.
  251. *
  252. * @param mesh Pointer to the mesh structure to update.
  253. * @param data Mesh data (vertices and indices) to upload.
  254. * @param aabb Optional bounding box; if null, it is recalculated automatically.
  255. * @return Returns true if the update is successful, false otherwise.
  256. */
  257. UpdateMesh :: proc(mesh: ^Mesh, data: MeshData, aabb: ^rl.BoundingBox) -> bool ---
  258. }