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

118 lines
3.1 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];
2016-11-02 04:52:32 +00:00
float transformedVertex[4] = {
2016-10-31 20:54:32 +00:00
vertex.x,
vertex.y,
vertex.z,
1.f
};
2016-11-02 04:52:32 +00:00
mat4_multiplyVector(newTransform, transformedVertex);
vec_pusharr(vertices, transformedVertex, 3);
if (modelData->hasNormals) {
ModelVertex normal = mesh->normals.data[v];
vec_push(vertices, normal.x);
vec_push(vertices, normal.y);
vec_push(vertices, normal.z);
}
2016-10-31 20:54:32 +00:00
}
// 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-11-05 22:56:58 +00:00
Model* lovrModelCreate(void* data, int size) {
2016-11-12 23:20:04 +00:00
Model* model = malloc(sizeof(Model));
2016-11-08 22:44:03 +00:00
if (!model) return NULL;
2016-11-05 22:56:58 +00:00
model->modelData = lovrModelDataCreate(data, size);
2016-11-08 22:44:03 +00:00
if (!model->modelData) return NULL;
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;
vec_init(&format);
2016-11-02 04:52:32 +00:00
BufferAttribute position = { .name = "position", .type = BUFFER_FLOAT, .size = 3 };
2016-10-31 20:54:32 +00:00
vec_push(&format, position);
2016-11-02 04:52:32 +00:00
if (model->modelData->hasNormals) {
BufferAttribute normal = { .name = "normal", .type = BUFFER_FLOAT, .size = 3 };
vec_push(&format, normal);
}
int components = model->modelData->hasNormals ? 6 : 3;
model->buffer = lovrBufferCreate(vertices.length / components, &format, BUFFER_TRIANGLES, BUFFER_STATIC);
2016-11-13 07:18:53 +00:00
lovrBufferSetVertices(model->buffer, (void*) vertices.data, vertices.length * sizeof(float));
2016-10-31 20:54:32 +00:00
lovrBufferSetVertexMap(model->buffer, indices.data, indices.length);
2016-11-08 22:51:58 +00:00
model->texture = NULL;
2016-10-31 20:54:32 +00:00
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
}
2016-11-08 22:51:58 +00:00
Texture* lovrModelGetTexture(Model* model) {
return model->texture;
}
void lovrModelSetTexture(Model* model, Texture* texture) {
model->texture = texture;
}