refactor: new string utils, refactor parse_obj()
| 3 files changed, 64 insertions(+), 23 deletions(-) | |||
|---|---|---|---|
| M | src/globals.h | +2 | -0 |
| M | src/mesh.cpp | +22 | -23 |
| A | src/util_string.h | +40 | -0 |
1@@ -1,3 +1,5 @@
2+#pragma once
3+
4 #include <stdint.h>
5
6 typedef int8_t i8;
M · src/mesh.cpp
+22, -23 1@@ -4,11 +4,9 @@
2 #include <stdlib.h>
3 #include <string.h>
4
5-#include <vector>
6-
7+#include "globals.h"
8 #include "util_math.h"
9-
10-using std::vector;
11+#include "util_string.h"
12
13 Mesh parse_obj(const char *filename) {
14 Mesh mesh;
15@@ -19,34 +17,37 @@ Mesh parse_obj(const char *filename) {
16 return mesh;
17 }
18
19- char line[1024];
20- while (fgets(line, sizeof(line), file)) {
21- if (strncmp(line, "#", 2) == 0 || strncmp(line, "\n", 2) == 0) {
22+ char line_buffer[1024];
23+ string line = {nullptr, 0};
24+
25+ while (fgets(line_buffer, sizeof(line_buffer), file)) {
26+ line = string_from_cstr(line_buffer);
27+ string_trim(&line);
28+
29+ if (line.size == 0 || line.str[0] == '#') {
30 continue;
31 }
32- if (strncmp(line, "v ", 2) == 0) {
33+ if (strncmp(line.str, "v ", 2) == 0) {
34 vec3f v;
35- sscanf(line, "v %f %f %f", &v.x, &v.y, &v.z);
36+ sscanf(line.str, "v %f %f %f", &v.x, &v.y, &v.z);
37 mesh.vertices.push_back(v);
38- } else if (strncmp(line, "vt ", 3) == 0) {
39+ } else if (strncmp(line.str, "vt ", 3) == 0) {
40 vec2f vt;
41- sscanf(line, "vt %f %f", &vt.x, &vt.y);
42+ sscanf(line.str, "vt %f %f", &vt.x, &vt.y);
43 mesh.texcoords.push_back(vt);
44- } else if (strncmp(line, "vn ", 3) == 0) {
45+ } else if (strncmp(line.str, "vn ", 3) == 0) {
46 vec3f vn;
47- sscanf(line, "vn %f %f %f", &vn.x, &vn.y, &vn.z);
48+ sscanf(line.str, "vn %f %f %f", &vn.x, &vn.y, &vn.z);
49 mesh.normals.push_back(vn);
50- } else if (strncmp(line, "f ", 2) == 0) {
51- char *face_token = strtok(line + 2, " \n\r");
52+ } else if (strncmp(line.str, "f ", 2) == 0) {
53+ char *face_token = strtok(line.str + 2, " \n\r");
54 while (face_token) {
55- Face idx = {0, 0, 0};
56- int v = 0, vt = 0, vn = 0;
57-
58+ Face idx = {0, 0, 0};
59+ int v = 0, vt = 0, vn = 0;
60 char *slash1 = strchr(face_token, '/');
61 if (slash1) {
62- *slash1 = '\0';
63- v = atoi(face_token);
64-
65+ *slash1 = '\0';
66+ v = atoi(face_token);
67 char *slash2 = strchr(slash1 + 1, '/');
68 if (slash2) {
69 *slash2 = '\0';
70@@ -58,11 +59,9 @@ Mesh parse_obj(const char *filename) {
71 } else {
72 v = atoi(face_token);
73 }
74-
75 if (v > 0) idx.vertex_idx = v - 1;
76 if (vt > 0) idx.vertex_texture_idx = vt - 1;
77 if (vn > 0) idx.vertex_normal_idx = vn - 1;
78-
79 mesh.faces.push_back(idx);
80 face_token = strtok(nullptr, " \n\r");
81 }
A · src/util_string.h
+40, -0 1@@ -0,0 +1,40 @@
2+#pragma once
3+
4+#include <string.h>
5+
6+#include "globals.h"
7+
8+// No allocs, all inplace, so scoped to caller.
9+// Don't use out of scope, unless using a custom allocator or you malloc outside
10+
11+typedef struct {
12+ char *str;
13+ u64 size;
14+} string;
15+
16+inline string string_from_cstr(char *cstr) {
17+ string s = {};
18+ if (cstr) {
19+ s.str = cstr;
20+ s.size = (u32)strlen(cstr);
21+ }
22+ return s;
23+}
24+
25+inline void string_trim(string *s) {
26+ size_t start = 0;
27+ size_t end = s->size;
28+ while (start < end &&
29+ (s->str[start] == ' ' || s->str[start] == '\t' ||
30+ s->str[start] == '\r' || s->str[start] == '\n')) {
31+ start++;
32+ }
33+ while (end > start &&
34+ (s->str[end - 1] == ' ' || s->str[end - 1] == '\t' ||
35+ s->str[end - 1] == '\r' || s->str[end - 1] == '\n')) {
36+ end--;
37+ }
38+ s->str += start;
39+ s->size = end - start;
40+}
41+}