mirror of https://github.com/bjornbytes/lovr.git
Support STL models;
Only binary STL files are supported right now, ASCII is more challenging.
This commit is contained in:
parent
a430ae06b8
commit
72a54bce2f
|
@ -12,6 +12,8 @@ ModelData* lovrModelDataCreate(Blob* source, ModelDataIO* io) {
|
|||
return model;
|
||||
} else if (lovrModelDataInitObj(model, source, io)) {
|
||||
return model;
|
||||
} else if (lovrModelDataInitStl(model, source, io)) {
|
||||
return model;
|
||||
}
|
||||
|
||||
lovrThrow("Unable to load model from '%s'", source->name);
|
||||
|
|
|
@ -221,5 +221,6 @@ typedef void* ModelDataIO(const char* filename, size_t* bytesRead);
|
|||
ModelData* lovrModelDataCreate(struct Blob* blob, ModelDataIO* io);
|
||||
ModelData* lovrModelDataInitGltf(ModelData* model, struct Blob* blob, ModelDataIO* io);
|
||||
ModelData* lovrModelDataInitObj(ModelData* model, struct Blob* blob, ModelDataIO* io);
|
||||
ModelData* lovrModelDataInitStl(ModelData* model, struct Blob* blob, ModelDataIO* io);
|
||||
void lovrModelDataDestroy(void* ref);
|
||||
void lovrModelDataAllocate(ModelData* model);
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#include "data/modelData.h"
|
||||
#include "data/blob.h"
|
||||
#include "core/maf.h"
|
||||
#include "core/util.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static ModelData* lovrModelDataInitStlAscii(ModelData* model, Blob* source, ModelDataIO* io) {
|
||||
lovrThrow("ASCII STL files are not supported yet");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// The binary format has an 80 byte header, followed by a u32 triangle count, followed by 50 byte
|
||||
// triangles. Each triangle has a vec3 normal, 3 vec3 vertices, and 2 bytes of padding.
|
||||
extern ModelData* lovrModelDataInitStlBinary(ModelData* model, Blob* source, ModelDataIO* io, uint32_t triangleCount) {
|
||||
char* data = (char*) source->data + 84;
|
||||
|
||||
uint32_t vertexCount = triangleCount * 3;
|
||||
size_t vertexBufferSize = vertexCount * 6 * sizeof(float);
|
||||
float* vertices = malloc(vertexBufferSize);
|
||||
lovrAssert(vertices, "Out of memory");
|
||||
|
||||
model->blobCount = 1;
|
||||
model->bufferCount = 1;
|
||||
model->attributeCount = 2;
|
||||
model->primitiveCount = 1;
|
||||
model->nodeCount = 1;
|
||||
|
||||
lovrModelDataAllocate(model);
|
||||
|
||||
model->blobs[0] = lovrBlobCreate(vertices, vertexBufferSize, "stl vertex data");
|
||||
model->buffers[0] = (ModelBuffer) { .data = (char*) vertices, .size = vertexBufferSize, .stride = 6 * sizeof(float) };
|
||||
model->attributes[0] = (ModelAttribute) { .count = vertexCount, .components = 3, .type = F32, .offset = 0 * sizeof(float) };
|
||||
model->attributes[1] = (ModelAttribute) { .count = vertexCount, .components = 3, .type = F32, .offset = 3 * sizeof(float) };
|
||||
model->primitives[0] = (ModelPrimitive) {
|
||||
.mode = DRAW_TRIANGLES,
|
||||
.material = ~0u,
|
||||
.attributes = {
|
||||
[ATTR_POSITION] = &model->attributes[0],
|
||||
[ATTR_NORMAL] = &model->attributes[1]
|
||||
}
|
||||
};
|
||||
model->nodes[0] = (ModelNode) {
|
||||
.matrix = true,
|
||||
.transform.matrix = MAT4_IDENTITY,
|
||||
.primitiveCount = 1,
|
||||
.skin = ~0u
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < triangleCount; i++) {
|
||||
memcpy(vertices + 3, data, 12);
|
||||
memcpy(vertices + 9, data, 12);
|
||||
memcpy(vertices + 15, data, 12), data += 12;
|
||||
memcpy(vertices + 0, data, 12), data += 12;
|
||||
memcpy(vertices + 6, data, 12), data += 12;
|
||||
memcpy(vertices + 12, data, 12), data += 12;
|
||||
vertices += 18;
|
||||
data += 2;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
ModelData* lovrModelDataInitStl(ModelData* model, Blob* source, ModelDataIO* io) {
|
||||
if (source->size > strlen("solid ") && !memcmp(source->data, "solid ", strlen("solid "))) {
|
||||
return lovrModelDataInitStlAscii(model, source, io);
|
||||
} else if (source->size > 84) {
|
||||
uint32_t triangleCount;
|
||||
memcpy(&triangleCount, (char*) source->data + 80, sizeof(triangleCount));
|
||||
if (source->size == 84 + 50 * triangleCount) {
|
||||
return lovrModelDataInitStlBinary(model, source, io, triangleCount);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -130,7 +130,8 @@ Model* lovrModelCreate(ModelData* data) {
|
|||
model->meshes = calloc(data->primitiveCount, sizeof(Mesh*));
|
||||
for (uint32_t i = 0; i < data->primitiveCount; i++) {
|
||||
ModelPrimitive* primitive = &data->primitives[i];
|
||||
model->meshes[i] = lovrMeshCreate(primitive->mode, NULL, 0);
|
||||
uint32_t vertexCount = primitive->attributes[ATTR_POSITION] ? primitive->attributes[ATTR_POSITION]->count : 0;
|
||||
model->meshes[i] = lovrMeshCreate(primitive->mode, NULL, vertexCount);
|
||||
|
||||
if (primitive->material != ~0u) {
|
||||
lovrMeshSetMaterial(model->meshes[i], model->materials[primitive->material]);
|
||||
|
|
Loading…
Reference in New Issue