Skip to content

Instantly share code, notes, and snippets.

@majorpakhom
Created August 25, 2014 15:43
Show Gist options
  • Save majorpakhom/f02bae35f8232508afbb to your computer and use it in GitHub Desktop.
Save majorpakhom/f02bae35f8232508afbb to your computer and use it in GitHub Desktop.
int l3dh_load_geometry_obj(l3dh_model_t *model, char *path, int storeDouble) {
FILE *inputFile = fopen(path, "r");
if(inputFile == NULL) {
return 0;
}
double dRead[3];
int iRead[9];
double *verticies = NULL;
double *verticiesPrepared = NULL;
float *verticiesPreparedF = NULL;
size_t verticiesLength = 0;
double *textureCoordinates = NULL;
double *textureCoordinatesPrepared = NULL;
float *textureCoordinatesPreparedF = NULL;
size_t textureCoordinatesLength = 0;
double *normals = NULL;
double *normalsPrepared = NULL;
float *normalsPreparedF = NULL;
size_t normalsLength = 0;
int *faces = NULL;
size_t facesLength = 0;
size_t facesCount = 0;
char line[1024];
while(fgets(line, 1024, inputFile) != NULL) {
if(line[0] == '#' || strlen(line) == 0) {
continue;
} else if(line[0] == 'v' && line[1] == ' ') {
if(sscanf(line, "v %lf %lf %lf\n", &dRead[0], &dRead[1], &dRead[2]) == 3) {
verticies = (double*) realloc(verticies, (verticiesLength + 3) * sizeof(double));
if(verticies == NULL) {
return -1;
}
memcpy(verticies+verticiesLength, &dRead, 3*sizeof(double));
verticiesLength += 3;
} else {
return -2;
}
} else if(line[0] == 'v' && line[1] == 't') {
// ignore W if it is present
if(sscanf(line, "vt %lf %lf %lf\n", &dRead[0], &dRead[1], &dRead[2]) > 1) {
textureCoordinates = (double*) realloc(textureCoordinates, (textureCoordinatesLength + 2) * sizeof(double));
if(textureCoordinates == NULL) {
return -3;
}
memcpy(textureCoordinates+textureCoordinatesLength, &dRead, 2*sizeof(double));
textureCoordinatesLength += 2;
} else {
return -4;
}
} else if(line[0] == 'v' && line[1] == 'n') {
if(sscanf(line, "vn %lf %lf %lf\n", &dRead[0], &dRead[1], &dRead[2]) == 3) {
normals = (double*) realloc(normals, (normalsLength + 3) * sizeof(double));
if(normals == NULL) {
return -5;
}
memcpy(normals+normalsLength, &dRead, 3*sizeof(double));
normalsLength += 3;
} else {
return -6;
}
} else if(line[0] == 'f' && line[1] == ' ') {
if(sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", &iRead[0], &iRead[1], &iRead[2], &iRead[3], &iRead[4], &iRead[5], &iRead[6], &iRead[7], &iRead[8]) == 9) {
faces = (int*) realloc(faces, (facesLength + 9) * sizeof(int));
if(faces == NULL) {
return -7;
}
memcpy(faces+facesLength, &iRead, 9*sizeof(int));
facesLength += 9;
++facesCount;
} else {
return -8;
}
} else {
// ignore any unconditional string
continue;
}
}
fclose(inputFile);
verticiesPrepared = (double*) malloc(facesCount * 9 * sizeof(double));
verticiesPreparedF = (float*) malloc(facesCount * 9 * sizeof(float));
textureCoordinatesPrepared = (double*) malloc(facesCount * 6 * sizeof(double));
textureCoordinatesPreparedF = (float*) malloc(facesCount * 6 * sizeof(float));
normalsPrepared = (double*) malloc(facesCount * 9 * sizeof(double));
normalsPreparedF = (float*) malloc(facesCount * 9 * sizeof(float));
size_t i;
for(i = 0; i < facesCount; ++i) {
memcpy(&verticiesPrepared[i*9], &verticies[(faces[i*9] - 1)*3], 3*sizeof(double));
memcpy(&verticiesPrepared[i*9 + 3], &verticies[(faces[i*9 + 3] - 1)*3], 3*sizeof(double));
memcpy(&verticiesPrepared[i*9 + 6], &verticies[(faces[i*9 + 6] - 1)*3], 3*sizeof(double));
memcpy(&textureCoordinatesPrepared[i*6], &textureCoordinates[(faces[i*9 + 1] - 1)*2], 2*sizeof(double));
memcpy(&textureCoordinatesPrepared[i*6 + 2], &textureCoordinates[(faces[i*9 + 4] - 1)*2], 2*sizeof(double));
memcpy(&textureCoordinatesPrepared[i*6 + 4], &textureCoordinates[(faces[i*9 + 7] - 1)*2], 2*sizeof(double));
memcpy(&normalsPrepared[i*9], &normals[(faces[i*9 + 2] - 1)*3], 3*sizeof(double));
memcpy(&normalsPrepared[i*9 + 3], &normals[(faces[i*9 + 5] - 1)*3], 3*sizeof(double));
memcpy(&normalsPrepared[i*9 + 6], &normals[(faces[i*9 + 8] - 1)*3], 3*sizeof(double));
}
free(faces);
free(verticies);
free(normals);
free(textureCoordinates);
// convert to floats
for(i = 0; i < facesCount * 9; ++i) {
verticiesPreparedF[i] = (float) verticiesPrepared[i];
}
for(i = 0; i < facesCount * 6; ++i) {
textureCoordinatesPreparedF[i] = (float) textureCoordinatesPrepared[i];
}
for(i = 0; i < facesCount * 9; ++i) {
normalsPreparedF[i] = (float) normalsPrepared[i];
}
if(storeDouble) {
model->verticies.doubles = verticiesPrepared;
model->textureCoordinates.doubles = textureCoordinatesPrepared;
model->normals.doubles = normalsPrepared;
} else {
free(verticiesPrepared);
free(textureCoordinatesPrepared);
free(normalsPrepared);
model->verticies.doubles = NULL;
model->textureCoordinates.doubles = NULL;
model->normals.doubles = NULL;
}
model->verticies.floats = verticiesPreparedF;
model->textureCoordinates.floats = textureCoordinatesPreparedF;
model->normals.floats = normalsPreparedF;
model->verticies.length = facesCount * 9;
model->textureCoordinates.length = facesCount * 6;
model->normals.length = facesCount * 9;
model->facesCount = facesCount;
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment