rendlib/object.c

124 lines
3.0 KiB
C

#include "include/object.h"
#include "include/math.h"
#include <math.h>
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
static int load_vertices(struct model *m, struct aiMesh *ms) {
m->vertices_num = ms->mNumVertices;
int len = m->vertices_num * sizeof(struct aiVector3D);
m->vertices = malloc(len);
if (m->vertices == NULL) {
return -1;
}
memset(m->vertices, 0, len);
memcpy(m->vertices, ms->mVertices, len);
return 0;
}
static int load_indices(struct model *m, struct aiMesh *ms) {
for (int face_index = 0; face_index < ms->mNumFaces; face_index++) {
struct aiFace *face = &(ms->mFaces[face_index]);
long start = m->indices_num;
m->indices_num += face->mNumIndices;
m->indices = (unsigned int *) realloc(m->indices, sizeof(unsigned int)*m->indices_num);
if (m->indices == NULL) {
return -1;
}
memcpy(&m->indices[start], face->mIndices, sizeof(unsigned int)*face->mNumIndices);
}
return 0;
}
static int load_normals(struct model *m, struct aiMesh *ms) {
m->normals_num = ms->mNumVertices;
int len = m->vertices_num * sizeof(struct aiVector3D);
m->normals = malloc(len);
if (m->vertices == NULL) {
return -1;
}
memset(m->normals, 0, len);
memcpy(m->normals, ms->mNormals, len);
return 0;
}
struct model *load_model(const char *path) {
int ret = 0;
struct model *nm = malloc(sizeof(struct model));
if (nm == NULL) {
return NULL;
}
memset(nm, 0, sizeof(struct model));
const struct aiScene *scene = aiImportFile(path, aiProcess_Triangulate);
if (scene == NULL) {
free(nm);
return NULL;
}
for (int mesh_index = 0; mesh_index < scene->mNumMeshes; mesh_index++) {
struct aiMesh *mesh = scene->mMeshes[mesh_index];
ret = load_vertices(nm, mesh);
if (ret < 0) {
free(nm);
aiReleaseImport(scene);
return NULL;
}
ret = load_indices(nm, mesh);
if (ret < 0) {
free(nm->vertices);
free(nm);
aiReleaseImport(scene);
return NULL;
}
ret = load_normals(nm, mesh);
if (ret < 0) {
free(nm->vertices);
free(nm->indices);
free(nm);
aiReleaseImport(scene);
return NULL;
}
}
return nm;
}
struct object *create_object(struct object **o, float mass, struct model *model) {
struct object *no = malloc(sizeof(struct object));
if (no == NULL) {
return NULL;
}
memset(no, 0, sizeof(struct object));
no->mass = mass;
no->scale = 1.0f;
no->model = model;
glm_vec4_one(no->position);
glm_vec3_one(no->color);
for (int i = 0; i < 3; i++) {
no->color[i] = 0.5f + (fabs(frand48()) / 2);
}
if (*o == NULL) {
*o = no;
return no;
}
struct object *previous_object = *o;
no->next = previous_object;
*o = no;
return no;
}