static errcode GetRecurseObject(SceneHandle scene, FILE *dfile, RotMat rmat, TransMat tmat) { char token[256], objname[128], name[128], texname[128], urlname[100]; RotMat localrmat, newrmat; TransMat localtmat, newtmat; float txrepa, txrepb, a, b; int numvert, numsurf, surf, materialnum, numrefs, numkids, data; int i, j; apivector * vertexarray = NULL; apivector * normalarray = NULL; int * refarray = NULL; tri_list * tlist = NULL; errcode rc = PARSENOERR; /* zero out variables */ numvert = numsurf = surf = materialnum = numrefs = numkids = data = 0; RmatIdentity(localrmat); localtmat[0] = 0.0; localtmat[1] = 0.0; localtmat[2] = 0.0; fscanf(dfile, "%s", objname); fscanf(dfile, "%s", token); if (!stringcmp(token, "NAME")) { GetAC3DString(dfile, name); fscanf(dfile, "%s", token); } if (!stringcmp(token, "DATA")) { fscanf(dfile, "%d", &data); fscanf(dfile, "%s", token); } if (!stringcmp(token, "TEXTURE")) { fscanf(dfile, "%s", texname); fscanf(dfile, "%s", token); } if (!stringcmp(token, "TEXREP")) { fscanf(dfile, "%f %f", &txrepa, &txrepb); fscanf(dfile, "%s", token); } if (!stringcmp(token, "ROT")) { for (j=0; j<3; j++) { for(i=0; i<3; i++) { fscanf(dfile, "%f", &localrmat[j][i]); } } fscanf(dfile, "%s", token); } if (!stringcmp(token, "LOC")) { for (j=0; j<3; j++) { fscanf(dfile, "%f", &localtmat[j]); } fscanf(dfile, "%s", token); } if (!stringcmp(token, "ROT")) { for (j=0; j<3; j++) { for(i=0; i<3; i++) { fscanf(dfile, "%f", &localrmat[j][i]); } } fscanf(dfile, "%s", token); } /* Perform Matrix Transforms for local coordinate system */ RmatTmatMult(newtmat, rmat, localtmat); newtmat[0] += tmat[0]; newtmat[1] += tmat[1]; newtmat[2] += tmat[2]; RmatMult(newrmat, rmat, localrmat); if (!stringcmp(token, "URL")) { fscanf(dfile, "%s", urlname); fscanf(dfile, "%s", token); } if (!stringcmp(token, "TEXTURE")) { GetAC3DString(dfile, token); fscanf(dfile, "%s", token); } if (!stringcmp(token, "NUMVERT")) { TransMat vtx, tvtx; fscanf(dfile, "%d", &numvert); vertexarray = (apivector *) malloc(numvert * sizeof(apivector)); normalarray = (apivector *) malloc(numvert * sizeof(apivector)); /* initialize the normal array */ clear_normals(normalarray, numvert); /* load and transform vertices */ for (i=0; i<numvert; i++) { fscanf(dfile, "%f %f %f", &vtx[0], &vtx[1], &vtx[2]); /* transform vertices */ RmatTmatMult(tvtx, newrmat, vtx); vertexarray[i].x = tvtx[0] + newtmat[0]; vertexarray[i].y = tvtx[1] + newtmat[1]; vertexarray[i].z = tvtx[2] + newtmat[2]; } fscanf(dfile, "%s", token); } if (!stringcmp(token, "NUMSURF")) { fscanf(dfile, "%d", &numsurf); fscanf(dfile, "%s", token); for (j=0; j<numsurf; j++) { numrefs = surf = materialnum = 0; if (!stringcmp(token, "SURF")) { /* COMPILER BUG!!! */ /* This is messed up friend.. */ /* if done using a normal fscanf() the program nails its */ /* stack, and seg faults. This *must* be a compiler or */ /* libc bug. */ #if 1 fscanf(dfile, "%s", token); sscanf(token, "%x", &surf); #else fscanf(dfile, "%x", &surf); #endif fscanf(dfile, "%s", token); } if (!stringcmp(token, "MAT")) { fscanf(dfile, "%d", &materialnum); fscanf(dfile, "%s", token); } if (!stringcmp(token, "REFS")) fscanf(dfile, "%d", &numrefs); else return (rc |= PARSEBADSYNTAX); refarray = (int *) malloc(numrefs * sizeof(int)); for (i=0; i<numrefs; i++) { fscanf(dfile, "%d %f %f", &refarray[i], &a, &b); } /* generate triangles/polygons here */ /* ignore all lines, points and other non-surface primatives */ if ((surf & 0xF) == 0) { int v0, vold, vnew; apivector trinorm; /* add in surface normal to vertices */ trinorm = tri_normal(&vertexarray[refarray[1]], &vertexarray[refarray[0]], &vertexarray[refarray[2]]); for (i=0; i<numrefs; i++) { normalarray[refarray[i]].x += trinorm.x; normalarray[refarray[i]].y += trinorm.y; normalarray[refarray[i]].z += trinorm.z; } v0 = refarray[0]; vold = refarray[1]; for (i=2; i<numrefs; i++) { vnew = refarray[i]; tlist_add_tri(&tlist, vold, v0, vnew, surf & 0x10, materialnum); vold = vnew; } } free(refarray); refarray=NULL; fscanf(dfile, "%s", token); } } if ((vertexarray != NULL) && (normalarray != NULL)) { /* now that all vertex normals have been summed, we'll renormalize */ renormalize_normals(normalarray, numvert); gen_triangles(scene, tlist, vertexarray, normalarray); tlist_delete(&tlist); } /* free vertex and normal arrays */ if (vertexarray != NULL) free(vertexarray); vertexarray = NULL; if (normalarray != NULL) free(normalarray); normalarray = NULL; if (!stringcmp(token, "KIDS")) fscanf(dfile, "%d", &numkids); else return (rc |= PARSEBADSYNTAX); /* Recurse to handle child geometry */ while (numkids > 0) { rc |= GetString(dfile, "OBJECT"); rc |= GetRecurseObject(scene, dfile, newrmat, newtmat); numkids--; } return rc; }
void * tlist_delete_last (tlist *lst) { return tlist_delete(lst, lst->size - 1); }