void DebugRenderer::drawPoint(const b2Vec2& p, float32 size, const b2Color& color) { size_t n = rescaleVertices(&p, 1); render(DebugRenderer::Points, n, color, size); }
Mesh* loadModel(const char *filename, float size, int flags) { /* faces: only quads or triangles at the moment */ Mesh* mesh; Material *materials; FILE *f; char buf[120]; char namebuf[120]; char *path; float *vert; int *face; float *norm; int *normi; int *matIndex; float *vertex, *normal; int nNormals = 0; int nVertices = 0; int nFaces = 0; float *meshVerts; float *meshNorms; int *meshFacesize; int currentMat = 0; int matCount = 0; int *pMatCount = NULL; int iLine = 0; float t1[3], t2[3], t3[3]; int c, i, j, k, l, pos; int hasNorms = 0; int hasTexture = 0; int inv; if((f = fopen(filename, "r")) == 0) { fprintf(stderr, "could not open file\n"); return NULL; } vert = (float *) malloc(sizeof(float) * 3 * MAX_V); face = (int *) malloc(sizeof(int) * MODEL_FACESIZE * MAX_F); matIndex = (int *) malloc(sizeof(int) * MAX_F); normi = (int *) malloc(sizeof(int) * MODEL_FACESIZE * MAX_F); norm = (float *) malloc(sizeof(float) * 3 * MAX_N); while(fgets(buf, sizeof(buf), f)) { switch(buf[0]) { case 'm': /* material library? */ if(sscanf(buf, "mtllib %s ", namebuf) == 1) { /* load material library */ path = getFullPath(namebuf); if(path == NULL) { fprintf(stderr, "fatal: can't find mtllib '%s'\n", namebuf); exit(1); } matCount = loadMaterials(path, &materials); if(matCount <= 0) { fprintf(stderr, "fatal: no Materials loaded\n"); exit(1); } /* printf("loaded %d Materials\n", matCount); */ pMatCount = (int*) malloc(sizeof(int) * matCount); for(i = 0; i < matCount; i++) pMatCount[i] = 0; currentMat = 0; } else fprintf(stderr, "warning: ignored line %d\n", iLine); break; case 'u': case 'g': /* material name */ if(sscanf(buf, "usemtl %s ", namebuf) == 1) { for(i = 0; i < matCount; i++) { if(strcmp(namebuf, (materials + i)->name) == 0) { currentMat = i; break; /* break out of if */ } } } else currentMat = 0; break; case 'v': switch(buf[1]) { case ' ': /* vertex data */ if(nVertices >= MAX_V) { FAIL("vertex limit exceeded\n") ; } c = sscanf(buf, "v %f %f %f ", vert + nVertices * 3, vert + nVertices * 3 + 1, vert + nVertices * 3 + 2); for(i = c; i < 3; i++) { printf("this should not happen\n"); *(vert + nVertices * 3 + i) = 0; } nVertices++; break; case 'n': /* vertex normal */ hasNorms = 1; if(nVertices >= MAX_N) { FAIL("normals limit exceeded\n") ; } c = sscanf(buf, "vn %f %f %f ", norm + nNormals * 3, norm + nNormals * 3 + 1, norm + nNormals * 3 + 2); for(i = c; i < 3; i++) { printf("this should not happen\n"); *(norm + nNormals * 3 + i) = 0; break; } nNormals++; break; case 't': /* texture coordinate - ignored */ hasTexture = 1; break; } break; case 'f': if(nFaces * MODEL_FACESIZE >= MAX_F) { FAIL("face limit exceeded\n") ; } /* mark material */ *(matIndex + nFaces) = currentMat; if(matCount > 0 && pMatCount != NULL) pMatCount[currentMat]++; if(hasNorms) { int dummy1, dummy2, dummy3, dummy4; if (hasTexture) { c = sscanf(buf, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d ", face + nFaces * MODEL_FACESIZE, &dummy1, normi + nFaces * MODEL_FACESIZE, face + nFaces * MODEL_FACESIZE + 1, &dummy2, normi + nFaces * MODEL_FACESIZE + 1, face + nFaces * MODEL_FACESIZE + 2, &dummy3, normi + nFaces * MODEL_FACESIZE + 2, face + nFaces * MODEL_FACESIZE + 3, & dummy4, normi + nFaces * MODEL_FACESIZE + 3); } else { c = sscanf(buf, "f %d//%d %d//%d %d//%d %d//%d ", face + nFaces * MODEL_FACESIZE, normi + nFaces * MODEL_FACESIZE, face + nFaces * MODEL_FACESIZE + 1, normi + nFaces * MODEL_FACESIZE + 1, face + nFaces * MODEL_FACESIZE + 2, normi + nFaces * MODEL_FACESIZE + 2, face + nFaces * MODEL_FACESIZE + 3, normi + nFaces * MODEL_FACESIZE + 3); } for(i = c / 2; i < MODEL_FACESIZE; i++) { *(face + nFaces * MODEL_FACESIZE + i) = -1; *(normi + nFaces * MODEL_FACESIZE + i) = -1; } nFaces++; } else { /* TODO: add if(hasTexture) */ c = sscanf(buf, "f %d %d %d %d ", face + nFaces * MODEL_FACESIZE, face + nFaces * MODEL_FACESIZE + 1, face + nFaces * MODEL_FACESIZE + 2, face + nFaces * MODEL_FACESIZE + 3); for(i = c; i < MODEL_FACESIZE; i++) *(face + nFaces * MODEL_FACESIZE + i) = -1; nFaces++; } break; } iLine++; } if(hasNorms == 0) { /* create Normals */ for(i = 0; i < nFaces; i++) { t1[0] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 0) - 1) + 0); t1[1] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 0) - 1) + 1); t1[2] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 0) - 1) + 2); t2[0] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 1) - 1) + 0); t2[1] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 1) - 1) + 1); t2[2] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 1) - 1) + 2); t3[0] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 2) - 1) + 0); t3[1] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 2) - 1) + 1); t3[2] = *(vert + 3 * (*(face + i * MODEL_FACESIZE + 2) - 1) + 2); /* printf("face %d:\n", i); printf("v1: %f %f %f\n", t1[0], t1[1], t1[2]); printf("v2: %f %f %f\n", t2[0], t2[1], t2[1]); printf("v3: %f %f %f\n", t3[0], t3[1], t3[1]); */ t1[0] -= t3[0]; t1[1] -= t3[1]; t1[2] -= t3[2]; t2[0] -= t3[0]; t2[1] -= t3[1]; t2[2] -= t3[2]; normcrossprod(t1, t2, t3); /* printf("normal: %f %f %f\n\n", t3[0], t3[1], t3[2]); */ /* t3 now contains the face normal */ for(j = 0; j < MODEL_FACESIZE; j++) *(normi + i * MODEL_FACESIZE + j) = nNormals + 1; *(norm + nNormals * 3 + 0) = t3[0]; *(norm + nNormals * 3 + 1) = t3[1]; *(norm + nNormals * 3 + 2) = t3[2]; nNormals++; } /* printf("generated %d normals\n", nNormals); */ } if(matCount == 0) { /* create Default material */ float spec[] = { 0.77, 0.77, 0.77, 1.0 }; float dif[] = { 0.4, 0.4, 0.4, 1}; float amb[] = { 0.25, 0.25, 0.25, 1}; materials = (Material*) malloc(sizeof(Material)); materials->name = (char*) malloc(strlen("default") + 1); sprintf(materials->name, "default"); memcpy(materials->ambient, amb, 3 * sizeof(float)); memcpy(materials->diffuse, dif, 3 * sizeof(float)); memcpy(materials->specular, spec, 3 * sizeof(float)); matCount = 1; pMatCount = (int*) malloc(sizeof(int)); pMatCount[0] = nFaces; } /* everything is parsed, now allocate memory and */ /* rescale and get bbox */ /* copy data to Mesh structure */ /* new: sort into sub meshes with by materials */ if(flags & MODEL_INVERT_NORMALS) { /* invert normals */ /* printf("inverting normals...really!\n"); */ inv = -1; } else inv = 1; mesh = (Mesh*) malloc(sizeof(Mesh)); /* rescale */ rescaleVertices(vert, size, nVertices, mesh->bbox); mesh->nFaces = nFaces; mesh->nMaterials = matCount; mesh->materials = materials; mesh->meshparts = (MeshPart*) malloc(matCount * sizeof(MeshPart)); for(i = 0; i < matCount; i++) { meshVerts = (float*) malloc(pMatCount[i] * 3 * MODEL_FACESIZE * sizeof(float)); meshNorms = (float*) malloc(pMatCount[i] * 3 * MODEL_FACESIZE * sizeof(float)); meshFacesize = (int*) malloc(pMatCount[i] * sizeof(int)); /* printf("Material %d: %d faces\n", i, pMatCount[i]); */ (mesh->meshparts + i)->nFaces = pMatCount[i]; (mesh->meshparts + i)->vertices = meshVerts; (mesh->meshparts + i)->normals = meshNorms; (mesh->meshparts + i)->facesizes = meshFacesize; pos = 0; for(j = 0; j < nFaces; j++) { /* foreach face */ if(matIndex[j] == i) { *(meshFacesize + pos) = 0; /* printf("face %d\n", j); */ for(k = 0; k < MODEL_FACESIZE; k++) { /* foreach vertex of face */ if(*(face + j * MODEL_FACESIZE + k) != -1) { *(meshFacesize + pos) += 1; /* adjust facesize... */ /* copy face and normal data to meshVerts, meshNorms */ vertex = vert + 3 * ( *(face + j * MODEL_FACESIZE + k) - 1); normal = norm + 3 * ( *(normi + j * MODEL_FACESIZE + k) - 1); if(flags & MODEL_NORMALIZE) normalize(normal); for(l = 0; l < 3; l++) { /* printf("%f ", vertex[l]); */ *(meshVerts + 3 * (pos * MODEL_FACESIZE + k) + l) = *(vertex + l); *(meshNorms + 3 * (pos * MODEL_FACESIZE + k) + l) = inv * *(normal + l); } /* printf("\n"); */ } } pos++; if(pos > pMatCount[i]) { fprintf(stderr, "fatal: more faces than accounted for\n"); exit(1); } } } } free(vert); free(face); free(norm); free(normi); free(pMatCount); free(matIndex); fclose (f); /* printf("loaded model: %d vertices, %d normals, %d faces, %d materials\n", nVertices, nNormals, nFaces, matCount); */ return mesh; }
void DebugRenderer::drawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) { b2Vec2 v[2] = { p1, p2 }; size_t n = rescaleVertices(v, 2); render(DebugRenderer::Lines, n, color); }