From eb7dc4fd0af953fa7baa1d0b0d446861b58f3726 Mon Sep 17 00:00:00 2001 From: Maximilian Hunt Date: Mon, 17 Apr 2023 17:14:30 +0100 Subject: [PATCH] Implement the rest of the geometric mesh generation functions --- api.txt | 14 ++--- src/3d.h | 120 +++++++++++++++++++++++++++++++++++++++++-- test/test_mesh.janet | 46 ++++++++++++----- 3 files changed, 157 insertions(+), 23 deletions(-) diff --git a/api.txt b/api.txt index 0a4f778..37681c9 100644 --- a/api.txt +++ b/api.txt @@ -335,14 +335,14 @@ [ ] bool IsModelAnimationValid(Model model, ModelAnimation anim) // Mesh generation functions -[ ] Mesh GenMeshPoly(int sides, float radius) -[ ] Mesh GenMeshPlane(float width, float length, int resX, int resZ) +[x] Mesh GenMeshPoly(int sides, float radius) +[x] Mesh GenMeshPlane(float width, float length, int resX, int resZ) [x] Mesh GenMeshCube(float width, float height, float length) -[ ] Mesh GenMeshSphere(float radius, int rings, int slices) -[ ] Mesh GenMeshHemiSphere(float radius, int rings, int slices) -[ ] Mesh GenMeshCylinder(float radius, float height, int slices) -[ ] Mesh GenMeshTorus(float radius, float size, int radSeg, int sides) -[ ] Mesh GenMeshKnot(float radius, float size, int radSeg, int sides) +[x] Mesh GenMeshSphere(float radius, int rings, int slices) +[x] Mesh GenMeshHemiSphere(float radius, int rings, int slices) +[x] Mesh GenMeshCylinder(float radius, float height, int slices) +[x] Mesh GenMeshTorus(float radius, float size, int radSeg, int sides) +[x] Mesh GenMeshKnot(float radius, float size, int radSeg, int sides) [ ] Mesh GenMeshHeightmap(Image heightmap, Vector3 size) [ ] Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize) diff --git a/src/3d.h b/src/3d.h index a182555..34de555 100644 --- a/src/3d.h +++ b/src/3d.h @@ -159,16 +159,98 @@ static Janet cfun_DrawMesh(int32_t argc, Janet *argv) { return janet_wrap_nil(); } +static Janet cfun_GenMeshPoly(int32_t argc, Janet *argv) { + janet_fixarity(argc, 2); + int sides = janet_getinteger(argv, 0); + float radius = (float) janet_getnumber(argv, 1); + Mesh *polyMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); + *polyMesh = GenMeshPoly(sides, radius); + return janet_wrap_abstract(polyMesh); +} + +static Janet cfun_GenMeshPlane(int32_t argc, Janet *argv) { + janet_fixarity(argc, 4); + float width = (float) janet_getnumber(argv, 0); + float length = (float) janet_getnumber(argv, 1); + int resX = janet_getinteger(argv, 2); + int resY = janet_getinteger(argv, 3); + Mesh *planeMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); + *planeMesh = GenMeshPlane(width, length, resX, resY); + return janet_wrap_abstract(planeMesh); +} + static Janet cfun_GenMeshCube(int32_t argc, Janet *argv) { janet_fixarity(argc, 3); - float width = janet_getnumber(argv, 0); - float height = janet_getnumber(argv, 1); - float length = janet_getnumber(argv, 2); + float width = (float) janet_getnumber(argv, 0); + float height = (float) janet_getnumber(argv, 1); + float length = (float) janet_getnumber(argv, 2); Mesh *cubeMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); *cubeMesh = GenMeshCube(width, height, length); return janet_wrap_abstract(cubeMesh); } +static Janet cfun_GenMeshSphere(int32_t argc, Janet *argv) { + janet_fixarity(argc, 3); + float radius = (float) janet_getnumber(argv, 0); + int rings = janet_getinteger(argv, 1); + int slices = janet_getinteger(argv, 2); + Mesh *sphereMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); + *sphereMesh = GenMeshSphere(radius, rings, slices); + return janet_wrap_abstract(sphereMesh); +} + +static Janet cfun_GenMeshHemiSphere(int32_t argc, Janet *argv) { + janet_fixarity(argc, 3); + float radius = (float) janet_getnumber(argv, 0); + int rings = janet_getinteger(argv, 1); + int slices = janet_getinteger(argv, 2); + Mesh *sphereMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); + *sphereMesh = GenMeshHemiSphere(radius, rings, slices); + return janet_wrap_abstract(sphereMesh); +} + +static Janet cfun_GenMeshCylinder(int32_t argc, Janet *argv) { + janet_fixarity(argc, 3); + float radius = (float) janet_getnumber(argv, 0); + float height = (float) janet_getnumber(argv, 1); + int slices = janet_getinteger(argv, 2); + Mesh *cylinderMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); + *cylinderMesh = GenMeshCylinder(radius, height, slices); + return janet_wrap_abstract(cylinderMesh); +} + +static Janet cfun_GenMeshCone(int32_t argc, Janet *argv) { + janet_fixarity(argc, 3); + float radius = (float) janet_getnumber(argv, 0); + float height = (float) janet_getnumber(argv, 1); + int slices = janet_getinteger(argv, 2); + Mesh *coneMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); + *coneMesh = GenMeshCone(radius, height, slices); + return janet_wrap_abstract(coneMesh); +} + +static Janet cfun_GenMeshTorus(int32_t argc, Janet *argv) { + janet_fixarity(argc, 4); + float radius = (float) janet_getnumber(argv, 0); + float size = (float) janet_getnumber(argv, 1); + int radSeg = janet_getinteger(argv, 2); + int sides = janet_getinteger(argv, 3); + Mesh *torusMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); + *torusMesh = GenMeshTorus(radius, size, radSeg, sides); + return janet_wrap_abstract(torusMesh); +} + +static Janet cfun_GenMeshKnot(int32_t argc, Janet *argv) { + janet_fixarity(argc, 4); + float radius = (float) janet_getnumber(argv, 0); + float size = (float) janet_getnumber(argv, 1); + int radSeg = janet_getinteger(argv, 2); + int sides = janet_getinteger(argv, 3); + Mesh *knotMesh = janet_abstract(&AT_Mesh, sizeof(Mesh)); + *knotMesh = GenMeshKnot(radius, size, radSeg, sides); + return janet_wrap_abstract(knotMesh); +} + static Janet cfun_LoadMaterialDefault(int32_t argc, Janet *argv) { janet_fixarity(argc, 0); Material *defaultMaterial = janet_abstract(&AT_Material, sizeof(Material)); @@ -245,9 +327,41 @@ static JanetReg threed_cfuns[] = { "(load-material-default)\n\n" "Load and return the default material" }, + {"gen-mesh-poly", cfun_GenMeshPoly, + "(gen-mesh-poly sides radius)\n\n" + "Generate a polygonal mesh with given number of sides and radius" + }, + {"gen-mesh-plane", cfun_GenMeshPlane, + "(gen-mesh-plane width length res-x res-y)\n\n" + "Generate a plane mesh with given dimensions and subdivisions" + }, {"gen-mesh-cube", cfun_GenMeshCube, "(gen-mesh-cube width height length)\n\n" "Generate a cube mesh with given dimensions" }, + {"gen-mesh-sphere", cfun_GenMeshSphere, + "(gen-mesh-sphere radius rings slices)\n\n" + "Generate a sphere mesh with given dimensions" + }, + {"gen-mesh-hemisphere", cfun_GenMeshHemiSphere, + "(gen-mesh-hemisphere radius rings slices)\n\n" + "Generate a hemisphere mesh with given dimensions (no bottom cap)" + }, + {"gen-mesh-cylinder", cfun_GenMeshCylinder, + "(gen-mesh-cylinder radius height slices)\n\n" + "Generate a cylinder mesh with given dimensions" + }, + {"gen-mesh-cone", cfun_GenMeshCone, + "(gen-mesh-cone radius height slices)\n\n" + "Generate a cone mesh with given dimensions" + }, + {"gen-mesh-torus", cfun_GenMeshTorus, + "(gen-mesh-torus radius size rad-seg sides)\n\n" + "Generate a torus mesh with given dimensions" + }, + {"gen-mesh-knot", cfun_GenMeshKnot, + "(gen-mesh-knot radius size rad-seg sides)\n\n" + "Generate a trefoil knot mesh with given dimensions" + }, {NULL, NULL, NULL} }; diff --git a/test/test_mesh.janet b/test/test_mesh.janet index 73bdf37..8cd059b 100644 --- a/test/test_mesh.janet +++ b/test/test_mesh.janet @@ -6,26 +6,46 @@ (init-window 800 600 "Mesh Stuff") (set-target-fps 60) -(def camera (camera-3d :target [0 0 0] - :up [0 0 1] - :position [5 5 7] - :type :perspective - :fovy 60)) +(def meshes [(gen-mesh-poly 5 0.5) + (gen-mesh-plane 1 1 10 10) + (gen-mesh-cube 1 1 1) + (gen-mesh-sphere 0.5 10 10) + (gen-mesh-hemisphere 0.5 10 10) + (gen-mesh-cylinder 0.5 1 10) + (gen-mesh-cone 0.5 1 10) + (gen-mesh-torus 0.25 1 10 10) + (gen-mesh-knot 0.25 1 100 100)]) -(def mesh (gen-mesh-cube 2 2 2)) (def material (load-material-default)) -(def transform [1 0 0 0 - 0 1 0 0 - 0 0 1 0 - 0 0 0 1]) + +(defn camera + [t] + (def center (- (length meshes) 0.5)) + (camera-3d :target [center 0 0] + :up [0 1 0] + :position [(+ center (* 5 (math/cos t))) 7 (* 5 (math/sin t))] + :type :perspective + :fovy 60)) + +(defn make-transform + [x] + [1 0 0 (* 2 x) + 0 1 0 0 + 0 0 1 0 + 0 0 0 1]) + +(var t 0) (while (not (window-should-close)) + (+= t (/ 1 60)) (begin-drawing) - (clear-background [0 0 0]) - (begin-mode-3d camera) - (draw-mesh mesh material transform) + (begin-mode-3d (camera t)) + + (for i 0 (length meshes) + (draw-mesh (meshes i) material (make-transform i))) + (end-mode-3d) (end-drawing))