124 lines
3.0 KiB
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;
|
|
}
|