s3dut_mesh.c (3526B)
1 /* Copyright (C) 2016, 2017, 2020, 2021, 2023 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "s3dut.h" 17 #include "s3dut_mesh.h" 18 19 #include <rsys/mem_allocator.h> 20 21 /******************************************************************************* 22 * Helper functions 23 ******************************************************************************/ 24 static void 25 release_mesh(ref_T* ref) 26 { 27 struct s3dut_mesh* mesh; 28 ASSERT(ref); 29 mesh = CONTAINER_OF(ref, struct s3dut_mesh, ref); 30 darray_double_release(&mesh->coords); 31 darray_size_t_release(&mesh->ids); 32 MEM_RM(mesh->allocator, mesh); 33 } 34 35 /******************************************************************************* 36 * Exported functions 37 ******************************************************************************/ 38 res_T 39 s3dut_mesh_ref_get(struct s3dut_mesh* mesh) 40 { 41 if(!mesh) return RES_BAD_ARG; 42 ref_get(&mesh->ref); 43 return RES_OK; 44 } 45 46 res_T 47 s3dut_mesh_ref_put(struct s3dut_mesh* mesh) 48 { 49 if(!mesh) return RES_BAD_ARG; 50 ref_put(&mesh->ref, release_mesh); 51 return RES_OK; 52 } 53 54 res_T 55 s3dut_mesh_get_data(const struct s3dut_mesh* mesh, struct s3dut_mesh_data* data) 56 { 57 size_t ncoords, nids; 58 if(!mesh || !data) return RES_BAD_ARG; 59 60 data->positions = darray_double_cdata_get(&mesh->coords); 61 data->indices = darray_size_t_cdata_get(&mesh->ids); 62 63 ncoords = darray_double_size_get(&mesh->coords); 64 nids = darray_size_t_size_get(&mesh->ids); 65 ASSERT(ncoords % 3 == 0); /* Only 3D coordinates are supported */ 66 ASSERT(nids % 3 == 0); /* Only triangular primitives are supported */ 67 68 data->nvertices = ncoords / 3; 69 data->nprimitives = nids / 3; 70 71 return RES_OK; 72 } 73 74 /******************************************************************************* 75 * Local function 76 ******************************************************************************/ 77 res_T 78 mesh_create 79 (struct mem_allocator* allocator, 80 const enum s3dut_mesh_type type, 81 const size_t nvertices, 82 const size_t ntriangles, 83 struct s3dut_mesh** out_mesh) 84 { 85 struct s3dut_mesh* mesh = NULL; 86 struct mem_allocator* mem_allocator; 87 res_T res = RES_OK; 88 89 if(!out_mesh) { 90 res = RES_BAD_ARG; 91 goto error; 92 } 93 94 mem_allocator = allocator ? allocator : &mem_default_allocator; 95 mesh = MEM_CALLOC(mem_allocator, 1, sizeof(struct s3dut_mesh)); 96 if(!mesh) { 97 res = RES_MEM_ERR; 98 goto error; 99 } 100 mesh->allocator = mem_allocator; 101 mesh->type = type; 102 ref_init(&mesh->ref); 103 darray_double_init(mem_allocator, &mesh->coords); 104 darray_size_t_init(mem_allocator, &mesh->ids); 105 106 res = darray_double_resize(&mesh->coords, nvertices*3/*#coords*/); 107 if(res != RES_OK) goto error; 108 res = darray_size_t_resize(&mesh->ids, ntriangles*3/*#ids per triangle*/); 109 if(res != RES_OK) goto error; 110 111 exit: 112 if(out_mesh) *out_mesh = mesh; 113 return res; 114 error: 115 if(mesh) { 116 S3DUT(mesh_ref_put(mesh)); 117 mesh = NULL; 118 } 119 goto exit; 120 } 121