1
0
Fork 0
mirror of https://github.com/bjornbytes/lovr.git synced 2024-07-03 04:53:35 +00:00
lovr/src/graphics/model.c

90 lines
2.4 KiB
C
Raw Normal View History

2016-07-09 05:27:34 +00:00
#include "model.h"
2016-11-02 03:56:29 +00:00
#include "graphics.h"
2016-10-04 04:54:27 +00:00
#include <stdlib.h>
2016-10-31 20:54:32 +00:00
static void visitNode(ModelData* modelData, ModelNode* node, mat4 transform, vec_float_t* vertices, vec_uint_t* indices) {
mat4 newTransform;
if (!transform) {
newTransform = mat4_init();
} else {
newTransform = mat4_copy(transform);
}
mat4_multiply(newTransform, node->transform);
int indexOffset = vertices->length / 3;
// Meshes
for (int m = 0; m < node->meshes.length; m++) {
ModelMesh* mesh = modelData->meshes.data[node->meshes.data[m]];
// Transformed vertices
for (int v = 0; v < mesh->vertices.length; v++) {
ModelVertex vertex = mesh->vertices.data[v];
float v[4] = {
vertex.x,
vertex.y,
vertex.z,
1.f
};
mat4_multiplyVector(newTransform, v);
vec_pusharr(vertices, v, 3);
}
// Face vertex indices
for (int f = 0; f < mesh->faces.length; f++) {
ModelFace face = mesh->faces.data[f];
for (int v = 0; v < face.indices.length; v++) {
vec_push(indices, face.indices.data[v] + indexOffset);
}
}
}
for (int c = 0; c < node->children.length; c++) {
visitNode(modelData, node->children.data[c], newTransform, vertices, indices);
}
}
2016-10-04 04:54:27 +00:00
Model* lovrModelCreate(const char* filename) {
Model* model = malloc(sizeof(model));
model->modelData = lovrModelDataCreate(filename);
2016-10-31 20:54:32 +00:00
vec_float_t vertices;
vec_init(&vertices);
vec_uint_t indices;
vec_init(&indices);
visitNode(model->modelData, model->modelData->root, NULL, &vertices, &indices);
BufferFormat format;
BufferAttribute position = { .name = "position", .type = BUFFER_FLOAT, .size = 3 };
vec_init(&format);
vec_push(&format, position);
model->buffer = lovrBufferCreate(vertices.length / 3, &format, BUFFER_TRIANGLES, BUFFER_STATIC);
lovrBufferSetVertices(model->buffer, vertices.data, vertices.length / 3);
lovrBufferSetVertexMap(model->buffer, indices.data, indices.length);
vec_deinit(&vertices);
vec_deinit(&indices);
2016-10-04 04:54:27 +00:00
return model;
}
void lovrModelDestroy(Model* model) {
lovrModelDataDestroy(model->modelData);
2016-11-01 00:35:43 +00:00
lovrBufferDestroy(model->buffer);
2016-10-04 04:54:27 +00:00
free(model);
}
2016-10-31 20:54:32 +00:00
2016-11-02 03:56:29 +00:00
void lovrModelDraw(Model* model, float x, float y, float z, float size, float angle, float ax, float ay, float az) {
lovrGraphicsPush();
lovrGraphicsTransform(x, y, z, size, size, size, angle, ax, ay, az);
2016-10-31 20:54:32 +00:00
lovrBufferDraw(model->buffer);
2016-11-02 03:56:29 +00:00
lovrGraphicsPop();
2016-10-31 20:54:32 +00:00
}