Skip to content

Commit

Permalink
Use dyn_array in wavefront mtllib parser
Browse files Browse the repository at this point in the history
Starting to look much better. Another neat thing about dyn_array is that
if you are okay with a shallow copy, you can just value-assign them. No
function for a deep copy yet, will see how much I need it first.
  • Loading branch information
vkoskiv committed Nov 7, 2023
1 parent e0e267c commit 29d8602
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 41 deletions.
29 changes: 8 additions & 21 deletions src/utils/loaders/formats/wavefront/mtlloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,22 @@
#include "../../../assert.h"
#include "../../textureloader.h"

static size_t countMaterials(textBuffer *buffer) {
size_t mtlCount = 0;
char *head = firstLine(buffer);
while (head) {
if (stringStartsWith("newmtl", head)) mtlCount++;
head = nextLine(buffer);
}
logr(debug, "File contains %zu materials\n", mtlCount);
firstLine(buffer);
return mtlCount;
}

static struct color parse_color(lineBuffer *line) {
ASSERT(line->amountOf.tokens == 4);
return (struct color){ atof(nextToken(line)), atof(nextToken(line)), atof(nextToken(line)), 1.0f };
}

struct material *parseMTLFile(const char *filePath, int *mtlCount, struct file_cache *cache) {
struct material_arr parse_mtllib(const char *filePath, struct file_cache *cache) {
size_t bytes = 0;
char *rawText = load_file(filePath, &bytes, cache);
if (!rawText) return NULL;
if (!rawText) return (struct material_arr){ 0 };
logr(debug, "Loading MTL at %s\n", filePath);
textBuffer *file = newTextBuffer(rawText);
free(rawText);

char *assetPath = get_file_path(filePath);

size_t materialAmount = countMaterials(file);
struct material *materials = calloc(materialAmount, sizeof(*materials));
size_t currentMaterialIdx = 0;
struct material_arr materials = { 0 };
struct material *current = NULL;

char *head = firstLine(file);
Expand All @@ -64,11 +50,12 @@ struct material *parseMTLFile(const char *filePath, int *mtlCount, struct file_c
head = nextLine(file);
continue;
} else if (stringEquals(first, "newmtl")) {
current = &materials[currentMaterialIdx++];
size_t idx = material_arr_add(&materials, (struct material){ 0 });
current = &materials.items[idx];
if (!peekNextToken(&line)) {
logr(warning, "newmtl without a name on line %zu\n", line.current.line);
free(materials);
return NULL;
material_arr_free(&materials);
return (struct material_arr){ 0 };
}
current->name = stringCopy(peekNextToken(&line));
} else if (stringEquals(first, "Ka")) {
Expand Down Expand Up @@ -117,6 +104,6 @@ struct material *parseMTLFile(const char *filePath, int *mtlCount, struct file_c

destroyTextBuffer(file);
free(assetPath);
if (mtlCount) *mtlCount = (int)materialAmount;
logr(debug, "Found %zu materials\n", materials.count);
return materials;
}
3 changes: 2 additions & 1 deletion src/utils/loaders/formats/wavefront/mtlloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
#pragma once

struct file_cache;
struct material_arr;

struct material *parseMTLFile(const char *filePath, int *mtlCount, struct file_cache *cache);
struct material_arr parse_mtllib(const char *filePath, struct file_cache *cache);
31 changes: 12 additions & 19 deletions src/utils/loaders/formats/wavefront/wavefront.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@

#include "wavefront.h"

static int findMaterialIndex(struct material *materialSet, int materialCount, char *mtlName) {
for (int i = 0; i < materialCount; ++i) {
if (stringEquals(materialSet[i].name, mtlName)) {
return i;
}
}
return 0;
}

static struct vector parseVertex(lineBuffer *line) {
ASSERT(line->amountOf.tokens == 4);
return (struct vector){ atof(nextToken(line)), atof(nextToken(line)), atof(nextToken(line)) };
Expand Down Expand Up @@ -122,9 +113,8 @@ struct mesh *parseWavefront(const char *filePath, size_t *finalMeshCount, struct
//size_t currentMesh = 0;
size_t valid_meshes = 0;

struct material *materialSet = NULL;
int materialCount = 0;
int currentMaterialIndex = 0;
struct material_arr mtllib = { 0 };
int current_material_idx = 0;

//FIXME: Handle more than one mesh
struct mesh *meshes = calloc(1, sizeof(*meshes));
Expand Down Expand Up @@ -168,16 +158,21 @@ struct mesh *parseWavefront(const char *filePath, size_t *finalMeshCount, struct
//TODO: Check if we actually need the file totals here
fixIndices(&p, currentMeshPtr->vertices.count, currentMeshPtr->texture_coords.count, currentMeshPtr->normals.count);
surface_area += get_poly_area(&p, currentMeshPtr->vertices.items);
p.materialIndex = currentMaterialIndex;
p.materialIndex = current_material_idx;
p.hasNormals = p.normalIndex[0] != -1;
poly_arr_add(&currentMeshPtr->polygons, p);
}
} else if (stringEquals(first, "usemtl")) {
currentMaterialIndex = findMaterialIndex(materialSet, materialCount, peekNextToken(&line));
char *name = peekNextToken(&line);
for (size_t i = 0; i < mtllib.count; ++i) {
if (stringEquals(mtllib.items[i].name, name)) {
current_material_idx = i;
}
}
} else if (stringEquals(first, "mtllib")) {
char *mtlFilePath = stringConcat(assetPath, peekNextToken(&line));
windowsFixPath(mtlFilePath);
materialSet = parseMTLFile(mtlFilePath, &materialCount, cache);
mtllib = parse_mtllib(mtlFilePath, cache);
free(mtlFilePath);
} else {
char *fileName = get_file_name(filePath);
Expand All @@ -193,11 +188,9 @@ struct mesh *parseWavefront(const char *filePath, size_t *finalMeshCount, struct
free(rawText);
free(assetPath);

if (materialSet) {
if (mtllib.count) {
for (size_t i = 0; i < meshCount; ++i) {
for (size_t m = 0; m < materialCount; ++m) {
material_arr_add(&meshes[i].materials, materialSet[m]);
}
meshes[i].materials = mtllib;
}
} else {
for (size_t i = 0; i < meshCount; ++i) {
Expand Down

0 comments on commit 29d8602

Please sign in to comment.