소스 검색

REVIEWED: `ExportMesh()` #2220

raysan5 3 년 전
부모
커밋
ef5be632fe
2개의 변경된 파일90개의 추가작업 그리고 69개의 파일을 삭제
  1. 63 55
      examples/models/models_mesh_generation.c
  2. 27 14
      src/rmodels.c

+ 63 - 55
examples/models/models_mesh_generation.c

@@ -5,64 +5,15 @@
 *   This example has been created using raylib 1.8 (www.raylib.com)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
 *
-*   Copyright (c) 2017 Ramon Santamaria (Ray San)
+*   Copyright (c) 2017-2021 Ramon Santamaria (@raysan5)
 *
 ********************************************************************************************/
 
 #include "raylib.h"
 
-#define NUM_MODELS  9      // Parametric 3d shapes to generate
+#define NUM_MODELS  9               // Parametric 3d shapes to generate
 
-void AllocateMeshData(Mesh* mesh, int triangleCount)
-{
-    mesh->vertexCount = triangleCount * 3;
-    mesh->triangleCount = triangleCount;
-
-    mesh->vertices = (float*)MemAlloc(mesh->vertexCount * 3 * sizeof(float));
-    mesh->texcoords = (float*)MemAlloc(mesh->vertexCount * 2 * sizeof(float));
-    mesh->normals = (float*)MemAlloc(mesh->vertexCount * 3 * sizeof(float));
-}
-
-// generate a simple triangle mesh from code
-Mesh MakeMesh()
-{
-    Mesh mesh = { 0 };
-    AllocateMeshData(&mesh, 1);
-
-    // vertex at the origin
-    mesh.vertices[0] = 0;
-    mesh.vertices[1] = 0;
-    mesh.vertices[2] = 0;
-    mesh.normals[0] = 0;
-    mesh.normals[1] = 1;
-    mesh.normals[2] = 0;
-    mesh.texcoords[0] = 0;
-    mesh.texcoords[1] = 0;
-
-    // vertex at 1,0,2
-    mesh.vertices[3] = 1;
-    mesh.vertices[4] = 0;
-    mesh.vertices[5] = 2;
-    mesh.normals[3] = 0;
-    mesh.normals[4] = 1;
-    mesh.normals[5] = 0;
-    mesh.texcoords[2] = 0.5f;
-    mesh.texcoords[3] = 1.0f;
-
-    // vertex at 2,0,0
-    mesh.vertices[6] = 2;
-    mesh.vertices[7] = 0;
-    mesh.vertices[8] = 0;
-    mesh.normals[6] = 0;
-    mesh.normals[7] = 1;
-    mesh.normals[8] = 0;
-    mesh.texcoords[4] = 1;
-    mesh.texcoords[5] =0;
-
-    UploadMesh(&mesh, false);
-
-    return mesh;
-}
+static Mesh GenMeshCustom(void);    // Generate a simple triangle mesh from code
 
 int main(void)
 {
@@ -88,7 +39,18 @@ int main(void)
     models[5] = LoadModelFromMesh(GenMeshTorus(0.25f, 4.0f, 16, 32));
     models[6] = LoadModelFromMesh(GenMeshKnot(1.0f, 2.0f, 16, 128));
     models[7] = LoadModelFromMesh(GenMeshPoly(5, 2.0f));
-    models[8] = LoadModelFromMesh(MakeMesh());
+    models[8] = LoadModelFromMesh(GenMeshCustom());
+    
+    // Generated meshes could be exported as .obj files
+    //ExportMesh(models[0].meshes[0], "plane.obj");
+    //ExportMesh(models[1].meshes[0], "cube.obj");
+    //ExportMesh(models[2].meshes[0], "sphere.obj");
+    //ExportMesh(models[3].meshes[0], "hemisphere.obj");
+    //ExportMesh(models[4].meshes[0], "cylinder.obj");
+    //ExportMesh(models[5].meshes[0], "torus.obj");
+    //ExportMesh(models[6].meshes[0], "knot.obj");
+    //ExportMesh(models[7].meshes[0], "poly.obj");
+    //ExportMesh(models[8].meshes[0], "custom.obj");
 
     // Set checked texture as default diffuse component for all models material
     for (int i = 0; i < NUM_MODELS; i++) models[i].materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
@@ -157,7 +119,7 @@ int main(void)
                 case 5: DrawText("TORUS", 680, 10, 20, DARKBLUE); break;
                 case 6: DrawText("KNOT", 680, 10, 20, DARKBLUE); break;
                 case 7: DrawText("POLY", 680, 10, 20, DARKBLUE); break;
-                case 8: DrawText("Parametric(custom)", 580, 10, 20, DARKBLUE); break;
+                case 8: DrawText("Custom (triangle)", 580, 10, 20, DARKBLUE); break;
                 default: break;
             }
 
@@ -176,4 +138,50 @@ int main(void)
     //--------------------------------------------------------------------------------------
 
     return 0;
-}
+}
+
+// Generate a simple triangle mesh from code
+static Mesh GenMeshCustom(void)
+{
+    Mesh mesh = { 0 };
+    mesh.triangleCount = 1;
+    mesh.vertexCount = mesh.triangleCount*3;
+    mesh.vertices = (float *)MemAlloc(mesh.vertexCount*3*sizeof(float));    // 3 vertices, 3 coordinates each (x, y, z)
+    mesh.texcoords = (float *)MemAlloc(mesh.vertexCount*2*sizeof(float));   // 3 vertices, 2 coordinates each (x, y)
+    mesh.normals = (float *)MemAlloc(mesh.vertexCount*3*sizeof(float));     // 3 vertices, 3 coordinates each (x, y, z)
+
+    // Vertex at (0, 0, 0)
+    mesh.vertices[0] = 0;
+    mesh.vertices[1] = 0;
+    mesh.vertices[2] = 0;
+    mesh.normals[0] = 0;
+    mesh.normals[1] = 1;
+    mesh.normals[2] = 0;
+    mesh.texcoords[0] = 0;
+    mesh.texcoords[1] = 0;
+
+    // Vertex at (1, 0, 2)
+    mesh.vertices[3] = 1;
+    mesh.vertices[4] = 0;
+    mesh.vertices[5] = 2;
+    mesh.normals[3] = 0;
+    mesh.normals[4] = 1;
+    mesh.normals[5] = 0;
+    mesh.texcoords[2] = 0.5f;
+    mesh.texcoords[3] = 1.0f;
+
+    // Vertex at (2, 0, 0)
+    mesh.vertices[6] = 2;
+    mesh.vertices[7] = 0;
+    mesh.vertices[8] = 0;
+    mesh.normals[6] = 0;
+    mesh.normals[7] = 1;
+    mesh.normals[8] = 0;
+    mesh.texcoords[4] = 1;
+    mesh.texcoords[5] =0;
+
+    // Upload mesh data from CPU (RAM) to GPU (VRAM) memory
+    UploadMesh(&mesh, false);
+
+    return mesh;
+}

+ 27 - 14
src/rmodels.c

@@ -1649,13 +1649,13 @@ bool ExportMesh(Mesh mesh, const char *fileName)
     if (IsFileExtension(fileName, ".obj"))
     {
         // Estimated data size, it should be enough...
-        int dataSize = mesh.vertexCount/3*(int)strlen("v 0000.00f 0000.00f 0000.00f") +
-                       mesh.vertexCount/2*(int)strlen("vt 0.000f 0.00f") +
-                       mesh.vertexCount/3*(int)strlen("vn 0.000f 0.00f 0.00f") +
-                       mesh.triangleCount/3*(int)strlen("f 00000/00000/00000 00000/00000/00000 00000/00000/00000");
+        int dataSize = mesh.vertexCount*(int)strlen("v 0000.00f 0000.00f 0000.00f") +
+                       mesh.vertexCount*(int)strlen("vt 0.000f 0.00f") +
+                       mesh.vertexCount*(int)strlen("vn 0.000f 0.00f 0.00f") +
+                       mesh.triangleCount*(int)strlen("f 00000/00000/00000 00000/00000/00000 00000/00000/00000");
 
         // NOTE: Text data buffer size is estimated considering mesh data size
-        char *txtData = (char *)RL_CALLOC(dataSize + 2000, sizeof(char));
+        char *txtData = (char *)RL_CALLOC(dataSize*2 + 2000, sizeof(char));
 
         int byteCount = 0;
         byteCount += sprintf(txtData + byteCount, "# //////////////////////////////////////////////////////////////////////////////////\n");
@@ -1665,7 +1665,7 @@ bool ExportMesh(Mesh mesh, const char *fileName)
         byteCount += sprintf(txtData + byteCount, "# // more info and bugs-report:  github.com/raysan5/raylib                        //\n");
         byteCount += sprintf(txtData + byteCount, "# // feedback and support:       ray[at]raylib.com                                //\n");
         byteCount += sprintf(txtData + byteCount, "# //                                                                              //\n");
-        byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018 Ramon Santamaria (@raysan5)                               //\n");
+        byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018-2021 Ramon Santamaria (@raysan5)                          //\n");
         byteCount += sprintf(txtData + byteCount, "# //                                                                              //\n");
         byteCount += sprintf(txtData + byteCount, "# //////////////////////////////////////////////////////////////////////////////////\n\n");
         byteCount += sprintf(txtData + byteCount, "# Vertex Count:     %i\n", mesh.vertexCount);
@@ -1688,9 +1688,22 @@ bool ExportMesh(Mesh mesh, const char *fileName)
             byteCount += sprintf(txtData + byteCount, "vn %.3f %.3f %.3f\n", mesh.normals[v], mesh.normals[v + 1], mesh.normals[v + 2]);
         }
 
-        for (int i = 0; i < mesh.triangleCount; i++)
+        if (mesh.indices != NULL)
         {
-            byteCount += sprintf(txtData + byteCount, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", i, i, i, i + 1, i + 1, i + 1, i + 2, i + 2, i + 2);
+            for (int i = 0, v = 0; i < mesh.triangleCount; i++, v += 3)
+            {
+                byteCount += sprintf(txtData + byteCount, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", 
+                    mesh.indices[v] + 1, mesh.indices[v] + 1, mesh.indices[v] + 1,
+                    mesh.indices[v + 1] + 1, mesh.indices[v + 1] + 1, mesh.indices[v + 1] + 1,
+                    mesh.indices[v + 2] + 1, mesh.indices[v + 2] + 1, mesh.indices[v + 2] + 1);
+            }
+        }
+        else
+        {
+            for (int i = 0, v = 1; i < mesh.triangleCount; i++, v += 3)
+            {
+                byteCount += sprintf(txtData + byteCount, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", v, v, v, v + 1, v + 1, v + 1, v + 2, v + 2, v + 2);
+            }
         }
 
         byteCount += sprintf(txtData + byteCount, "\n");
@@ -2252,14 +2265,14 @@ Mesh GenMeshCube(float width, float height, float length)
     int k = 0;
 
     // Indices can be initialized right now
-    for (int i = 0; i < 36; i+=6)
+    for (int i = 0; i < 36; i += 6)
     {
         mesh.indices[i] = 4*k;
-        mesh.indices[i+1] = 4*k+1;
-        mesh.indices[i+2] = 4*k+2;
-        mesh.indices[i+3] = 4*k;
-        mesh.indices[i+4] = 4*k+2;
-        mesh.indices[i+5] = 4*k+3;
+        mesh.indices[i + 1] = 4*k + 1;
+        mesh.indices[i + 2] = 4*k + 2;
+        mesh.indices[i + 3] = 4*k;
+        mesh.indices[i + 4] = 4*k + 2;
+        mesh.indices[i + 5] = 4*k + 3;
 
         k++;
     }