diff options
| author | Connor Thomson <blumatrikz@gmail.com> | 2026-09-10 19:16:42 -0700 |
|---|---|---|
| committer | Connor Thomson <blumatrikz@gmail.com> | 2026-09-10 19:16:42 -0700 |
| commit | a618f7c8d4e8df65d9d2542d9032c32973e42981 (patch) | |
| tree | 79e1a9eccd4d1ad61daf4c14f2e3c76638f37597 /src/obj.c | |
| parent | e9d4cbaa3c44337115d672d2038a7b73745181c8 (diff) | |
Switch away from Wavefront & more
Diffstat (limited to 'src/obj.c')
| -rw-r--r-- | src/obj.c | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/src/obj.c b/src/obj.c deleted file mode 100644 index 4887d52..0000000 --- a/src/obj.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Tuxánci 2 - A first person shooter - * Copyright (C) 2007-2011 Tuxánci Development Team - * Copyright (C) 2025-2026 Connor Thomson - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -#include <stdbool.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "obj.h" - -typedef struct ta_obj_position { - float value[3]; -} ta_obj_position; - -typedef struct ta_obj_face { - int position_indices[3]; -} ta_obj_face; - -static bool ta_obj_push_vertex(ta_obj_mesh *mesh, size_t *capacity, const ta_obj_vertex *vertex) { - if (mesh->vertex_count == *capacity) { - size_t next_capacity = *capacity == 0 ? 1024 : *capacity * 2; - ta_obj_vertex *vertices = realloc(mesh->vertices, next_capacity * sizeof(*vertices)); - if (!vertices) { - return false; - } - mesh->vertices = vertices; - *capacity = next_capacity; - } - mesh->vertices[mesh->vertex_count++] = *vertex; - return true; -} - -bool ta_obj_parse(const unsigned char *data, size_t size, ta_obj_mesh *mesh) { - ta_obj_position *positions = NULL; - ta_obj_face *faces = NULL; - float *normal_accum = NULL; - size_t position_count = 0; - size_t face_count = 0; - size_t position_capacity = 0; - size_t face_capacity = 0; - size_t vertex_capacity = 0; - bool success = false; - - memset(mesh, 0, sizeof(*mesh)); - char *text = malloc(size + 1); - if (!text) { - return false; - } - memcpy(text, data, size); - text[size] = '\0'; - - char *line = text; - while (line && *line) { - char *next_line = strchr(line, '\n'); - if (next_line) { - *next_line = '\0'; - } - - if (line[0] == 'v' && line[1] == ' ') { - ta_obj_position position; - if (sscanf(line + 2, "%f %f %f", &position.value[0], &position.value[1], &position.value[2]) != 3) { - goto done; - } - if (position_count == position_capacity) { - size_t next_capacity = position_capacity == 0 ? 1024 : position_capacity * 2; - ta_obj_position *grown = realloc(positions, next_capacity * sizeof(*grown)); - if (!grown) { - goto done; - } - positions = grown; - position_capacity = next_capacity; - } - positions[position_count++] = position; - } else if (line[0] == 'f' && line[1] == ' ') { - ta_obj_face face; - int discarded_normal_indices[3]; - bool has_normals = sscanf(line + 2, "%d//%d %d//%d %d//%d", - &face.position_indices[0], &discarded_normal_indices[0], - &face.position_indices[1], &discarded_normal_indices[1], - &face.position_indices[2], &discarded_normal_indices[2]) == 6; - if (!has_normals && sscanf(line + 2, "%d %d %d", - &face.position_indices[0], &face.position_indices[1], &face.position_indices[2]) != 3) { - goto done; - } - for (int index = 0; index < 3; index++) { - if (face.position_indices[index] <= 0 || (size_t)face.position_indices[index] > position_count) { - goto done; - } - } - if (face_count == face_capacity) { - size_t next_capacity = face_capacity == 0 ? 1024 : face_capacity * 2; - ta_obj_face *grown = realloc(faces, next_capacity * sizeof(*grown)); - if (!grown) { - goto done; - } - faces = grown; - face_capacity = next_capacity; - } - faces[face_count++] = face; - } - - if (!next_line) { - break; - } - line = next_line + 1; - } - - if (position_count == 0 || face_count == 0) { - goto done; - } - - normal_accum = calloc(position_count * 3, sizeof(*normal_accum)); - if (!normal_accum) { - goto done; - } - - for (size_t index = 0; index < face_count; index++) { - const float *first = positions[faces[index].position_indices[0] - 1].value; - const float *second = positions[faces[index].position_indices[1] - 1].value; - const float *third = positions[faces[index].position_indices[2] - 1].value; - float edge_a[3] = {second[0] - first[0], second[1] - first[1], second[2] - first[2]}; - float edge_b[3] = {third[0] - first[0], third[1] - first[1], third[2] - first[2]}; - float face_normal[3] = { - edge_a[1] * edge_b[2] - edge_a[2] * edge_b[1], - edge_a[2] * edge_b[0] - edge_a[0] * edge_b[2], - edge_a[0] * edge_b[1] - edge_a[1] * edge_b[0], - }; - for (int corner = 0; corner < 3; corner++) { - size_t position_index = (size_t)(faces[index].position_indices[corner] - 1); - normal_accum[position_index * 3 + 0] += face_normal[0]; - normal_accum[position_index * 3 + 1] += face_normal[1]; - normal_accum[position_index * 3 + 2] += face_normal[2]; - } - } - - for (size_t index = 0; index < position_count; index++) { - float *normal = &normal_accum[index * 3]; - float length = sqrtf(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]); - if (length > 0.0f) { - normal[0] /= length; - normal[1] /= length; - normal[2] /= length; - } else { - normal[0] = 0.0f; - normal[1] = 0.0f; - normal[2] = 1.0f; - } - } - - for (size_t index = 0; index < face_count; index++) { - for (int corner = 0; corner < 3; corner++) { - size_t position_index = (size_t)(faces[index].position_indices[corner] - 1); - ta_obj_vertex vertex; - memcpy(vertex.position, positions[position_index].value, sizeof(vertex.position)); - memcpy(vertex.normal, &normal_accum[position_index * 3], sizeof(vertex.normal)); - if (!ta_obj_push_vertex(mesh, &vertex_capacity, &vertex)) { - goto done; - } - } - } - - success = mesh->vertex_count > 0; -done: - if (!success) { - ta_obj_free(mesh); - } - free(positions); - free(faces); - free(normal_accum); - free(text); - return success; -} - -void ta_obj_free(ta_obj_mesh *mesh) { - free(mesh->vertices); - mesh->vertices = NULL; - mesh->vertex_count = 0; -} |