| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- /* r3d_mesh_data.odin -- R3D Mesh Data Module.
- *
- * Copyright (c) 2025-2026 Le Juez Victor
- *
- * This software is provided 'as-is', without any express or implied warranty.
- * For conditions of distribution and use, see accompanying LICENSE file.
- */
- package r3d
- import rl "vendor:raylib"
- when ODIN_OS == .Windows {
- foreign import lib {
- "windows/libr3d.a",
- "system:raylib",
- "system:assimp",
- }
- } else when ODIN_OS == .Linux {
- foreign import lib {
- "linux/libr3d.a",
- "system:raylib",
- "system:assimp",
- }
- } else when ODIN_OS == .Darwin {
- foreign import lib {
- "darwin/libr3d.a",
- "system:raylib",
- "system:assimp",
- }
- }
- /**
- * @brief Represents a vertex and all its attributes for a mesh.
- */
- Vertex :: struct {
- position: rl.Vector3, /**< The 3D position of the vertex in object space. */
- texcoord: rl.Vector2, /**< The 2D texture coordinates (UV) for mapping textures. */
- normal: rl.Vector3, /**< The normal vector used for lighting calculations. */
- color: rl.Color, /**< Vertex color, in RGBA32. */
- tangent: rl.Vector4, /**< The tangent vector, used in normal mapping (often with a handedness in w). */
- boneIds: [4]i32, /**< Indices of up to 4 bones that influence this vertex (for skinning). */
- weights: [4]f32, /**< Corresponding bone weights (should sum to 1.0). Defines the influence of each bone. */
- }
- /**
- * @brief Represents a mesh stored in CPU memory.
- *
- * R3D_MeshData is the CPU-side container of a mesh. It stores vertex and index data,
- * and provides utility functions to generate, transform, and process geometry before
- * uploading it to the GPU as an R3D_Mesh.
- *
- * Think of it as a toolbox for procedural or dynamic mesh generation on the CPU.
- */
- MeshData :: struct {
- vertices: [^]Vertex, ///< Pointer to vertex data in CPU memory.
- indices: [^]u32, ///< Pointer to index data in CPU memory.
- vertexCount: i32, ///< Number of vertices.
- indexCount: i32, ///< Number of indices.
- }
- @(default_calling_convention="c", link_prefix="R3D_")
- foreign lib {
- /**
- * @brief Creates an empty mesh data container.
- *
- * Allocates memory for vertex and index buffers. All allocated buffers
- * are zero-initialized.
- *
- * @param vertexCount Number of vertices to allocate. Must be non-zero.
- * @param indexCount Number of indices to allocate. May be zero.
- * If zero, no index buffer is allocated.
- *
- * @return A new R3D_MeshData instance with allocated memory.
- */
- CreateMeshData :: proc(vertexCount: i32, indexCount: i32) -> MeshData ---
- /**
- * @brief Releases memory used by a mesh data container.
- * @param meshData R3D_MeshData to destroy.
- */
- UnloadMeshData :: proc(meshData: MeshData) ---
- /**
- * @brief Check if mesh data is valid.
- *
- * Returns true if the mesh data contains at least one vertex buffer
- * with a positive number of vertices.
- *
- * @param meshData Mesh data to check.
- * @return true if valid, false otherwise.
- */
- IsMeshDataValid :: proc(meshData: MeshData) -> bool ---
- /**
- * @brief Generate a quad mesh with specified dimensions, resolution, and orientation.
- *
- * Creates a flat rectangular quad mesh with customizable facing direction.
- * The mesh can be subdivided for higher resolution or displacement mapping.
- * The quad is centered at the origin and oriented according to the frontDir parameter,
- * which defines both the face direction and the surface normal.
- *
- * @param width Width of the quad along its local X axis.
- * @param length Length of the quad along its local Z axis.
- * @param resX Number of subdivisions along the width.
- * @param resZ Number of subdivisions along the length.
- * @param frontDir Direction vector defining the quad's front face and normal.
- * This vector will be normalized internally.
- *
- * @return Generated quad mesh structure with proper normals, tangents, and UVs.
- */
- GenMeshDataQuad :: proc(width: f32, length: f32, resX: i32, resZ: i32, frontDir: rl.Vector3) -> MeshData ---
- /**
- * @brief Generate a plane mesh with specified dimensions and resolution.
- *
- * Creates a flat plane mesh in the XZ plane, centered at the origin.
- * The mesh can be subdivided for higher resolution or displacement mapping.
- *
- * @param width Width of the plane along the X axis.
- * @param length Length of the plane along the Z axis.
- * @param resX Number of subdivisions along the X axis.
- * @param resZ Number of subdivisions along the Z axis.
- *
- * @return Generated plane mesh structure.
- */
- GenMeshDataPlane :: proc(width: f32, length: f32, resX: i32, resZ: i32) -> MeshData ---
- /**
- * @brief Generate a polygon mesh with specified number of sides.
- *
- * Creates a regular polygon mesh centered at the origin in the XY plane.
- * The polygon is generated with vertices evenly distributed around a circle.
- *
- * @param sides Number of sides for the polygon (minimum 3).
- * @param radius Radius of the circumscribed circle.
- * @param frontDir Direction vector defining the polygon's front face and normal.
- * This vector will be normalized internally.
- *
- * @return Generated polygon mesh structure.
- */
- GenMeshDataPoly :: proc(sides: i32, radius: f32, frontDir: rl.Vector3) -> MeshData ---
- /**
- * @brief Generate a cube mesh with specified dimensions.
- *
- * Creates a cube mesh centered at the origin with the specified width, height, and length.
- * Each face consists of two triangles with proper normals and texture coordinates.
- *
- * @param width Width of the cube along the X axis.
- * @param height Height of the cube along the Y axis.
- * @param length Length of the cube along the Z axis.
- *
- * @return Generated cube mesh structure.
- */
- GenMeshDataCube :: proc(width: f32, height: f32, length: f32) -> MeshData ---
- /**
- * @brief Generate a subdivided cube mesh with specified dimensions.
- *
- * Extension of R3D_GenMeshDataCube() allowing per-axis subdivision.
- * Each face can be tessellated along the X, Y, and Z axes according
- * to the provided resolutions.
- *
- * @param width Width of the cube along the X axis.
- * @param height Height of the cube along the Y axis.
- * @param length Length of the cube along the Z axis.
- * @param resX Number of subdivisions along the X axis.
- * @param resY Number of subdivisions along the Y axis.
- * @param resZ Number of subdivisions along the Z axis.
- *
- * @return Generated cube mesh structure.
- */
- GenMeshDataCubeEx :: proc(width: f32, height: f32, length: f32, resX: i32, resY: i32, resZ: i32) -> MeshData ---
- /**
- * @brief Generate a slope mesh by cutting a cube with a plane.
- *
- * Creates a slope mesh by slicing a cube with a plane that passes through the origin.
- * The plane is defined by its normal vector, and the portion of the cube on the side
- * opposite to the normal direction is kept. This allows creating ramps, wedges, and
- * angled surfaces with arbitrary orientations.
- *
- * @param width Width of the base cube along the X axis.
- * @param height Height of the base cube along the Y axis.
- * @param length Length of the base cube along the Z axis.
- * @param slopeNormal Normal vector of the cutting plane. The mesh keeps the portion
- * of the cube in the direction opposite to this normal.
- * Example: {-1, 0, 0} creates a ramp rising towards +X.
- * {0, 1, 0} creates a wedge with the slope facing up.
- * {-1.0, 1.0, 0} creates a 45° diagonal slope.
- *
- * @return Generated slope mesh structure.
- *
- * @note The normal vector will be automatically normalized internally.
- * @note The cutting plane always passes through the center of the cube (origin).
- */
- GenMeshDataSlope :: proc(width: f32, height: f32, length: f32, slopeNormal: rl.Vector3) -> MeshData ---
- /**
- * @brief Generate a sphere mesh with specified parameters.
- *
- * Creates a UV sphere mesh centered at the origin using latitude-longitude subdivision.
- * Higher ring and slice counts produce smoother spheres but with more vertices.
- *
- * @param radius Radius of the sphere.
- * @param rings Number of horizontal rings (latitude divisions).
- * @param slices Number of vertical slices (longitude divisions).
- *
- * @return Generated sphere mesh structure.
- */
- GenMeshDataSphere :: proc(radius: f32, rings: i32, slices: i32) -> MeshData ---
- /**
- * @brief Generate a hemisphere mesh with specified parameters.
- *
- * Creates a half-sphere mesh (dome) centered at the origin, extending upward in the Y axis.
- * Uses the same UV sphere generation technique as R3D_GenMeshSphere but only the upper half.
- *
- * @param radius Radius of the hemisphere.
- * @param rings Number of horizontal rings (latitude divisions).
- * @param slices Number of vertical slices (longitude divisions).
- *
- * @return Generated hemisphere mesh structure.
- */
- GenMeshDataHemiSphere :: proc(radius: f32, rings: i32, slices: i32) -> MeshData ---
- /**
- * @brief Generate a cylinder mesh with specified parameters.
- *
- * Creates a mesh centered at the origin, extending along the Y axis.
- * The mesh includes top and bottom caps and smooth side surfaces.
- * A cone is produced when bottomRadius and topRadius differ.
- *
- * @param bottomRadius Radius of the bottom cap.
- * @param topRadius Radius of the top cap.
- * @param height Height of the shape along the Y axis.
- * @param slices Number of radial subdivisions around the shape.
- *
- * @return Generated mesh structure.
- */
- GenMeshDataCylinder :: proc(bottomRadius: f32, topRadius: f32, height: f32, slices: i32) -> MeshData ---
- /**
- * @brief Generate a capsule mesh with specified parameters.
- *
- * Creates a capsule mesh centered at the origin, extending along the Y axis.
- * The capsule consists of a cylindrical body with hemispherical caps on both ends.
- * The total height of the capsule is height + 2 * radius.
- *
- * @param radius Radius of the capsule (both cylindrical body and hemispherical caps).
- * @param height Height of the cylindrical portion along the Y axis.
- * @param rings Total number of latitudinal subdivisions for both hemispheres combined.
- * @param slices Number of radial subdivisions around the shape.
- *
- * @return Generated mesh structure.
- */
- GenMeshDataCapsule :: proc(radius: f32, height: f32, rings: i32, slices: i32) -> MeshData ---
- /**
- * @brief Generate a torus mesh with specified parameters.
- *
- * Creates a torus (donut shape) mesh centered at the origin in the XZ plane.
- * The torus is defined by a major radius (distance from center to tube center)
- * and a minor radius (tube thickness).
- *
- * @param radius Major radius of the torus (distance from center to tube center).
- * @param size Minor radius of the torus (tube thickness/radius).
- * @param radSeg Number of segments around the major radius.
- * @param sides Number of sides around the tube cross-section.
- *
- * @return Generated torus mesh structure.
- */
- GenMeshDataTorus :: proc(radius: f32, size: f32, radSeg: i32, sides: i32) -> MeshData ---
- /**
- * @brief Generate a trefoil knot mesh with specified parameters.
- *
- * Creates a trefoil knot mesh, which is a mathematical knot shape.
- * Similar to a torus but with a twisted, knotted topology.
- *
- * @param radius Major radius of the knot.
- * @param size Minor radius (tube thickness) of the knot.
- * @param radSeg Number of segments around the major radius.
- * @param sides Number of sides around the tube cross-section.
- *
- * @return Generated trefoil knot mesh structure.
- */
- GenMeshDataKnot :: proc(radius: f32, size: f32, radSeg: i32, sides: i32) -> MeshData ---
- /**
- * @brief Generate a terrain mesh from a heightmap image.
- *
- * Creates a terrain mesh by interpreting the brightness values of a heightmap image
- * as height values. The resulting mesh represents a 3D terrain surface.
- *
- * @param heightmap rl.Image containing height data (grayscale values represent elevation).
- * @param size 3D vector defining the terrain dimensions (width, max height, depth).
- *
- * @return Generated heightmap terrain mesh structure.
- */
- GenMeshDataHeightmap :: proc(heightmap: rl.Image, size: rl.Vector3) -> MeshData ---
- /**
- * @brief Generate a voxel-style mesh from a cubicmap image.
- *
- * Creates a mesh composed of cubes based on a cubicmap image, where each pixel
- * represents the presence or absence of a cube at that position. Useful for
- * creating voxel-based or block-based geometry.
- *
- * @param cubicmap rl.Image where pixel values determine cube placement.
- * @param cubeSize 3D vector defining the size of each individual cube.
- *
- * @return Generated cubicmap mesh structure.
- */
- GenMeshDataCubicmap :: proc(cubicmap: rl.Image, cubeSize: rl.Vector3) -> MeshData ---
- /**
- * @brief Creates a deep copy of an existing mesh data container.
- * @param meshData Source mesh data to duplicate.
- * @return A new R3D_MeshData containing a copy of the source data.
- */
- DuplicateMeshData :: proc(meshData: MeshData) -> MeshData ---
- /**
- * @brief Merges two mesh data containers into a single one.
- * @param a First mesh data.
- * @param b Second mesh data.
- * @return A new R3D_MeshData containing the merged geometry.
- */
- MergeMeshData :: proc(a: MeshData, b: MeshData) -> MeshData ---
- /**
- * @brief Translates all vertices by a given offset.
- * @param meshData Mesh data to modify.
- * @param translation Offset to apply to all vertex positions.
- */
- TranslateMeshData :: proc(meshData: ^MeshData, translation: rl.Vector3) ---
- /**
- * @brief Rotates all vertices using a quaternion.
- * @param meshData Mesh data to modify.
- * @param rotation rl.Quaternion representing the rotation.
- */
- RotateMeshData :: proc(meshData: ^MeshData, rotation: rl.Quaternion) ---
- /**
- * @brief Scales all vertices by given factors.
- * @param meshData Mesh data to modify.
- * @param scale Scaling factors for each axis.
- */
- ScaleMeshData :: proc(meshData: ^MeshData, scale: rl.Vector3) ---
- /**
- * @brief Generates planar UV coordinates.
- * @param meshData Mesh data to modify.
- * @param uvScale Scaling factors for UV coordinates.
- * @param axis Axis along which to project the planar mapping.
- */
- GenMeshDataUVsPlanar :: proc(meshData: ^MeshData, uvScale: rl.Vector2, axis: rl.Vector3) ---
- /**
- * @brief Generates spherical UV coordinates.
- * @param meshData Mesh data to modify.
- */
- GenMeshDataUVsSpherical :: proc(meshData: ^MeshData) ---
- /**
- * @brief Generates cylindrical UV coordinates.
- * @param meshData Mesh data to modify.
- */
- GenMeshDataUVsCylindrical :: proc(meshData: ^MeshData) ---
- /**
- * @brief Computes vertex normals from triangle geometry.
- * @param meshData Mesh data to modify.
- */
- GenMeshDataNormals :: proc(meshData: ^MeshData) ---
- /**
- * @brief Computes vertex tangents based on existing normals and UVs.
- * @param meshData Mesh data to modify.
- */
- GenMeshDataTangents :: proc(meshData: ^MeshData) ---
- /**
- * @brief Calculates the axis-aligned bounding box of the mesh.
- * @param meshData Mesh data to analyze.
- * @return The computed bounding box.
- */
- CalculateMeshDataBoundingBox :: proc(meshData: MeshData) -> rl.BoundingBox ---
- }
|