STL Loader
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "asset/asset.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/math.h"
|
||||
|
||||
errorret_t assetFileInit(
|
||||
assetfile_t *file,
|
||||
@@ -70,6 +71,19 @@ errorret_t assetFileRead(
|
||||
) {
|
||||
assertNotNull(file, "Asset file cannot be NULL.");
|
||||
assertNotNull(file->zipFile, "Asset file must be opened before reading.");
|
||||
|
||||
if(buffer == NULL) {
|
||||
size_t bytesRemaining = bufferSize;
|
||||
uint8_t tempBuffer[256];
|
||||
while(bytesRemaining > 0) {
|
||||
size_t chunkSize = mathMin(bytesRemaining, sizeof(tempBuffer));
|
||||
errorChain(assetFileRead(file, tempBuffer, chunkSize));
|
||||
file->position += chunkSize;
|
||||
bytesRemaining -= chunkSize;
|
||||
}
|
||||
file->lastRead = bufferSize;
|
||||
errorOk();
|
||||
}
|
||||
|
||||
// I assume zip_fread takes buffer NULL for skipping?
|
||||
zip_int64_t bytesRead = zip_fread(file->zipFile, buffer, bufferSize);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
assetmeshloader.c
|
||||
assettextureloader.c
|
||||
assettilesetloader.c
|
||||
)
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "asset/loader/display/assetmeshloader.h"
|
||||
#include "asset/asset.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/endian.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
errorret_t assetMeshLoader(assetfile_t *file) {
|
||||
assertNotNull(file, "Asset file cannot be null");
|
||||
|
||||
assetmeshoutput_t *output = (assetmeshoutput_t *)file->output;
|
||||
assertNotNull(output, "Output cannot be null");
|
||||
assertNotNull(output->outMesh, "Output mesh cannot be null");
|
||||
assertNotNull(output->outVertices, "Output vertices cannot be null");
|
||||
|
||||
// STL file loading
|
||||
errorChain(assetFileOpen(file));
|
||||
|
||||
// Skip the 80 byte header
|
||||
errorChain(assetFileRead(file, NULL, 80));
|
||||
if(file->lastRead != 80) errorThrow("Failed to skip STL header");
|
||||
|
||||
uint32_t triangleCount;
|
||||
errorChain(assetFileRead(file, &triangleCount, sizeof(uint32_t)));
|
||||
if(file->lastRead != sizeof(uint32_t)) errorThrow("Failed read tri count");
|
||||
// normalize
|
||||
triangleCount = endianLittleToHost32(triangleCount);
|
||||
|
||||
// Allocate mesh and vertex data
|
||||
errorret_t ret;
|
||||
meshvertex_t *verts = memoryAllocate(
|
||||
sizeof(meshvertex_t) * triangleCount * 3
|
||||
);
|
||||
*output->outVertices = verts;
|
||||
|
||||
// Read triangle data
|
||||
for(uint32_t i = 0; i < triangleCount; i++) {
|
||||
assetmeshstltriangle_t triData;
|
||||
ret = assetFileRead(file, &triData, sizeof(triData));
|
||||
if(ret.code != ERROR_OK) {
|
||||
memoryFree(verts);
|
||||
errorChain(ret);
|
||||
}
|
||||
|
||||
if(file->lastRead != sizeof(triData)) {
|
||||
memoryFree(verts);
|
||||
errorThrow("Failed to read triangle data");
|
||||
}
|
||||
|
||||
// Skip normals, we don't use them
|
||||
|
||||
// Fix endianess of of data
|
||||
for(uint8_t j = 0; j < 3; j++) {
|
||||
verts[i * 3 + j].color.r = (uint8_t)(endianLittleToHostFloat(
|
||||
triData.normal[0]
|
||||
) * 255.0f);
|
||||
verts[i * 3 + j].color.g = (uint8_t)(endianLittleToHostFloat(
|
||||
triData.normal[1]
|
||||
) * 255.0f);
|
||||
verts[i * 3 + j].color.b = (uint8_t)(endianLittleToHostFloat(
|
||||
triData.normal[2]
|
||||
) * 255.0f);
|
||||
verts[i * 3 + j].color.a = 0xFF;
|
||||
|
||||
verts[i * 3 + j].uv[0] = 0.0f; // No UV data in STL, just set to 0
|
||||
verts[i * 3 + j].uv[1] = 0.0f;
|
||||
|
||||
for(uint8_t k = 0; k < 3; k++) {
|
||||
verts[i * 3 + j].pos[k] = endianLittleToHostFloat(
|
||||
triData.positions[j][k]
|
||||
);
|
||||
}
|
||||
|
||||
// Convert Z-Up to Y-Up
|
||||
float_t temp = verts[i * 3 + j].pos[1];
|
||||
verts[i * 3 + j].pos[1] = verts[i * 3 + j].pos[2];
|
||||
verts[i * 3 + j].pos[2] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, init mesh
|
||||
ret = meshInit(
|
||||
output->outMesh,
|
||||
MESH_PRIMITIVE_TYPE_TRIANGLES,
|
||||
triangleCount * 3,
|
||||
verts
|
||||
);
|
||||
if(ret.code != ERROR_OK) {
|
||||
memoryFree(verts);
|
||||
errorChain(ret);
|
||||
}
|
||||
|
||||
ret = assetFileClose(file);
|
||||
if(ret.code != ERROR_OK) {
|
||||
errorCatch(errorPrint(meshDispose(output->outMesh)));
|
||||
memoryFree(verts);
|
||||
errorChain(ret);
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t assetMeshLoad(
|
||||
const char_t *path,
|
||||
mesh_t *outMesh,
|
||||
meshvertex_t **outVertices
|
||||
) {
|
||||
assertNotNull(path, "Path cannot be null");
|
||||
assertNotNull(outMesh, "Output mesh cannot be null");
|
||||
assertNotNull(outVertices, "Output vertices cannot be null");
|
||||
|
||||
assetmeshoutput_t output = { outMesh, outVertices };
|
||||
return assetLoad(path, &assetMeshLoader, NULL, &output);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "asset/asset.h"
|
||||
#include "display/mesh/mesh.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
typedef struct {
|
||||
mesh_t *outMesh;
|
||||
meshvertex_t **outVertices;
|
||||
} assetmeshoutput_t;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
vec3 normal;
|
||||
float_t positions[3][3];
|
||||
uint16_t attributeByteCount;
|
||||
} assetmeshstltriangle_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
assertStructSize(assetmeshstltriangle_t, 50);
|
||||
|
||||
/**
|
||||
* Loader for mesh assets.
|
||||
*
|
||||
* @param file Asset file to load the mesh from.
|
||||
* @return Any error that occurs during loading.
|
||||
*/
|
||||
errorret_t assetMeshLoader(assetfile_t *file);
|
||||
|
||||
/**
|
||||
* Handler for mesh assets.
|
||||
*
|
||||
* @param file Asset file to load the mesh from.
|
||||
* @return Any error that occurs during loading.
|
||||
*/
|
||||
errorret_t assetMeshLoad(
|
||||
const char_t *path,
|
||||
mesh_t *outMesh,
|
||||
meshvertex_t **outVertices
|
||||
);
|
||||
Reference in New Issue
Block a user