From lordhavoc at icculus.org Fri Apr 7 20:42:44 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 7 Apr 2006 20:42:44 -0400 Subject: r688 - trunk Message-ID: <20060408004244.17527.qmail@icculus.org> Author: lordhavoc Date: 2006-04-07 20:42:44 -0400 (Fri, 07 Apr 2006) New Revision: 688 Modified: trunk/texture.c Log: less error messages when failing to load textures Modified: trunk/texture.c =================================================================== --- trunk/texture.c 2006-03-30 10:29:44 UTC (rev 687) +++ trunk/texture.c 2006-04-08 00:42:44 UTC (rev 688) @@ -365,7 +365,13 @@ if (!side) cubemapsize = pixels_width; if (!cubemappixels[side]) - Console_Printf("Texture_Load: failed to load cubemap \"%s\" because of missing side \"%s\"\n", r->name, cubemapname); + { + // if we can't even find the first side, don't complain about a + // missing side, instead let the resource manager complain about + // the resource failing to load + if (side) + Console_Printf("Texture_Load: failed to load cubemap \"%s\" because of missing side \"%s\"\n", r->name, cubemapname); + } else if (pixels_width != pixels_height) Console_Printf("Texture_Load: failed to load cubemap \"%s\" because side \"%s\" is not square\n", r->name, cubemapname); else if (pixels_width != cubemapsize) @@ -494,7 +500,8 @@ pixels = Texture_LoadTargaFile(r->name, &pixels_width, &pixels_height); if (!pixels) { - Console_Printf("Texture_Load: failed to load \"%s\"\n", r->name); + // the resource manager will complain for us + //Console_Printf("Texture_Load: failed to load \"%s\"\n", r->name); return; } From lordhavoc at icculus.org Fri Apr 7 20:45:03 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 7 Apr 2006 20:45:03 -0400 Subject: r689 - trunk Message-ID: <20060408004503.17994.qmail@icculus.org> Author: lordhavoc Date: 2006-04-07 20:45:02 -0400 (Fri, 07 Apr 2006) New Revision: 689 Modified: trunk/util.c trunk/util.h Log: added a util_convertobj command rewrote/replaced Util_WriteModel with Util_BuildModel system, which allows easier construction of md5mesh files by featuring vertex lookups and adaptive allocations (so you can simply add a triangle to the mesh for instance) Modified: trunk/util.c =================================================================== --- trunk/util.c 2006-04-08 00:42:44 UTC (rev 688) +++ trunk/util.c 2006-04-08 00:45:02 UTC (rev 689) @@ -240,48 +240,377 @@ #undef ReadNext } -// FIXME: this is very unlikely to overflow but it should be made buffer size safe at some point -void Util_WriteModel(const char *filename, NUint32 nummeshes, Util_Mesh *meshes) +void Util_BuildModel_Begin(Util_BuildModel *b) { + memset(b, 0, sizeof(*b)); +} + +void Util_BuildModel_End(Util_BuildModel *b) +{ + NUint32 i; + Util_BuildModel_Surface *surface; + for (i = 0, surface = b->data_surfaces;i < b->num_surfaces;i++, surface++) + { + Mem_Free(&surface->data_element3i); + Mem_Free(&surface->data_vertex8f); + } + Mem_Free(&b->data_surfaces); + memset(b, 0, sizeof(*b)); +} + +NUint32 Util_BuildModel_AddSurface(Util_BuildModel *b, const char *materialname) +{ + Util_BuildModel_Surface *surface; + if (b->num_surfaces >= b->max_surfaces) + { + b->max_surfaces = Max(b->max_surfaces * 2, 16); + Mem_ReAlloc(Global_Zone, &b->data_surfaces, b->max_surfaces * sizeof(Util_BuildModel_Surface)); + } + surface = b->data_surfaces + b->num_surfaces; + strncpy(surface->materialname, materialname, sizeof(surface->materialname) - 1); + b->num_surfaces++; + return b->num_surfaces - 1; +} + +NUint32 Util_BuildModel_AddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t) +{ + float *v; + Util_BuildModel_Surface *surface = b->data_surfaces + surfaceindex; + if (surface->num_vertices >= surface->max_vertices) + { + surface->max_vertices = Max(surface->max_vertices * 2, 1024); + Mem_ReAlloc(Global_Zone, &surface->data_vertex8f, surface->max_vertices * sizeof(float[8])); + } + v = surface->data_vertex8f + surface->num_vertices * 8; + v[0] = x; + v[1] = y; + v[2] = z; + v[3] = nx; + v[4] = ny; + v[5] = nz; + v[6] = s; + v[7] = t; + surface->num_vertices++; + return surface->num_vertices - 1; +} + +NUint32 Util_BuildModel_FindOrAddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t) +{ + NUint32 i; + float *v; + Util_BuildModel_Surface *surface = b->data_surfaces + surfaceindex; + for (i = 0, v = surface->data_vertex8f;i < surface->num_vertices;i++, v += 8) + if (fabs(v[0] - x) < 0.0001 && fabs(v[1] - y) < 0.0001 && fabs(v[2] - z) < 0.0001 && fabs(v[3] - nx) < 0.0001 && fabs(v[4] - ny) < 0.0001 && fabs(v[5] - nz) < 0.0001 && fabs(v[6] - s) < 0.0001 && fabs(v[7] - t) < 0.0001) + return i; + return Util_BuildModel_AddVertex(b, surfaceindex, x, y, z, nx, ny, nz, s, t); +} + +NUint32 Util_BuildModel_AddTriangle(Util_BuildModel *b, NUint32 surfaceindex, int e0, int e1, int e2) +{ + Util_BuildModel_Surface *surface = b->data_surfaces + surfaceindex; + NUint32 *e; + if (surface->num_triangles >= surface->max_triangles) + { + surface->max_triangles = Max(surface->max_triangles * 2, 1024); + Mem_ReAlloc(Global_Zone, &surface->data_element3i, surface->max_triangles * sizeof(int[3])); + } + e = surface->data_element3i + surface->num_triangles * 3; + e[0] = e0; + e[1] = e1; + e[2] = e2; + surface->num_triangles++; + return surface->num_triangles - 1; +} + +void Util_BuildModel_Write(Util_BuildModel *b, const char *filename) +{ + // FIXME: this is very unlikely to overflow but it should be made buffer size safe at some point NUint32 i, num; Nsize textsize, textmaxsize; char *text; + Util_BuildModel_Surface *surface; textmaxsize = 0x100000; - for (i = 0;i < nummeshes;i++) - textmaxsize += meshes[i].numvertices * 60 + meshes[i].numtriangles * 40; + for (i = 0, surface = b->data_surfaces;i < b->num_surfaces;i++, surface++) + textmaxsize += surface->num_vertices * 60 + surface->num_triangles * 40; textsize = 0; text = Mem_Alloc(Global_Zone, textmaxsize); - textsize += snprintf(text + textsize, textmaxsize - textsize, "MD5Version 10\ncommandline \"\"\n\nnumJoints 1\nnumMeshes %u\n\njoints {\n\t\"ROOT\"\t-1 ( 0.000000 0.000000 0.000000 ) ( 0.000000 0.000000 0.000000 ) // \n}\n", nummeshes); - for (i = 0;i < nummeshes;i++) + textsize += snprintf(text + textsize, textmaxsize - textsize, "MD5Version 10\ncommandline \"\"\n\nnumJoints 1\nnumMeshes %u\n\njoints {\n\t\"ROOT\"\t-1 ( 0.000000 0.000000 0.000000 ) ( 0.000000 0.000000 0.000000 ) // \n}\n", b->num_surfaces); + for (i = 0, surface = b->data_surfaces;i < b->num_surfaces;i++, surface++) { - if (textmaxsize < textsize + meshes[i].numvertices * 100 + meshes[i].numtriangles * 100 + meshes[i].numvertices * 100 + 1000) + if (textmaxsize < textsize + surface->num_vertices * 100 + surface->num_triangles * 100 + surface->num_vertices * 100 + 1000) { - textmaxsize = textsize + meshes[i].numvertices * 200 + meshes[i].numtriangles * 200 + meshes[i].numvertices * 200 + 2000; + textmaxsize = textsize + surface->num_vertices * 200 + surface->num_triangles * 200 + surface->num_vertices * 200 + 2000; Mem_ReAlloc(Global_Zone, &text, textmaxsize); } - textsize += snprintf(text + textsize, textmaxsize - textsize, "\nmesh {\n\tshader \"%s\"\n\n\tnumverts %u\n", meshes[i].materialname, meshes[i].numvertices); - for (num = 0;num < meshes[i].numvertices;num++) - textsize += snprintf(text + textsize, textmaxsize - textsize, "\tvert %u ( %.6f %.6f ) %u 1\n", num, meshes[i].texcoord2f[num*2+0], meshes[i].texcoord2f[num*2+1], num); - textsize += snprintf(text + textsize, textmaxsize - textsize, "\n\tnumtris %u\n", meshes[i].numtriangles); - for (num = 0;num < meshes[i].numtriangles;num++) - textsize += snprintf(text + textsize, textmaxsize - textsize, "\ttri %u %u %u %u\n", num, meshes[i].element3i[num*3+0], meshes[i].element3i[num*3+1], meshes[i].element3i[num*3+2]); - textsize += snprintf(text + textsize, textmaxsize - textsize, "\n\tnumweights %u\n", meshes[i].numvertices); - for (num = 0;num < meshes[i].numvertices;num++) - textsize += snprintf(text + textsize, textmaxsize - textsize, "\tweight %u 0 1.000000 ( %.6f %.6f %.6f )\n", num, meshes[i].vertex3f[num*3+0], meshes[i].vertex3f[num*3+1], meshes[i].vertex3f[num*3+2]); + textsize += snprintf(text + textsize, textmaxsize - textsize, "\nmesh {\n\tshader \"%s\"\n\n\tnumverts %u\n", surface->materialname, surface->num_vertices); + for (num = 0;num < surface->num_vertices;num++) + textsize += snprintf(text + textsize, textmaxsize - textsize, "\tvert %u ( %.6f %.6f ) %u 1\n", num, surface->data_vertex8f[num*8+6], surface->data_vertex8f[num*8+7], num); + textsize += snprintf(text + textsize, textmaxsize - textsize, "\n\tnumtris %u\n", surface->num_triangles); + for (num = 0;num < surface->num_triangles;num++) + textsize += snprintf(text + textsize, textmaxsize - textsize, "\ttri %u %u %u %u\n", num, surface->data_element3i[num*3+0], surface->data_element3i[num*3+1], surface->data_element3i[num*3+2]); + textsize += snprintf(text + textsize, textmaxsize - textsize, "\n\tnumweights %u\n", surface->num_vertices); + for (num = 0;num < surface->num_vertices;num++) + textsize += snprintf(text + textsize, textmaxsize - textsize, "\tweight %u 0 1.000000 ( %.6f %.6f %.6f )\n", num, surface->data_vertex8f[num*8+0], surface->data_vertex8f[num*8+1], surface->data_vertex8f[num*8+2]); textsize += snprintf(text + textsize, textmaxsize - textsize, "}\n"); } File_WriteFile(filename, text, textsize); Mem_Free(&text); } +#if 1 +void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend) +#else +static NUint32 default_remapcoords[3] = {0, 1, 2}; +static float default_scalecoords[3] = {1, 1, 1}; + +void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend, Nbool flip, NUint32 remapcoords[3], float scalecoords[3]) +#endif +{ + NUint32 linenumber = 0; + NSint32 surfaceindex = -1; + NUint32 num_vertices = 0, max_vertices = 0; + NUint32 num_normals = 0, max_normals = 0; + NUint32 num_texcoords = 0, max_texcoords = 0; + float *data_vertex3f = NULL; + float *data_normal3f = NULL; + float *data_texcoord2f = NULL; +#if 0 + if (remapcoords == NULL) + remapcoords = default_remapcoords; + if (scalecoords == NULL) + scalecoords = default_scalecoords; +#endif + while (text < textend) + { + Nbool comment = false; + NUint32 argc = 0; + char argv[64][256]; + // parse the line + linenumber++; + while (text < textend && *text != '\r' && *text != '\n') + { + if (comment || *text <= ' ') + text++; + else if (*text == '#') + comment = true; + else + { + NUint32 charnum; + for (charnum = 0;text < textend && *text > ' ';text++) + if (charnum < sizeof(argv[0]) - 1) + argv[argc][charnum++] = *text; + argv[argc++][charnum] = 0; + } + } + if (*text == '\r' && text[1] == '\n') + text++; + if (*text == '\n') + text++; + // now we have a command + if (argc < 1) + continue; + if (!String_Compare(argv[0], "v")) + { + // v -4.99960e-2 0.250000 -1.00000 + if (argc == 4) + { + if (num_vertices >= max_vertices) + { + max_vertices = Max(max_vertices * 2, 1024); + Mem_ReAlloc(Global_Zone, &data_vertex3f, max_vertices * sizeof(float[3])); + } +#if 1 + data_vertex3f[num_vertices*3+0] = atof(argv[1]); + data_vertex3f[num_vertices*3+2] = atof(argv[2]); + data_vertex3f[num_vertices*3+1] = atof(argv[3]); +#else + data_vertex3f[num_vertices*3+remapcoords[0]] = atof(argv[1]) * scalecoords[0]; + data_vertex3f[num_vertices*3+remapcoords[1]] = atof(argv[2]) * scalecoords[1]; + data_vertex3f[num_vertices*3+remapcoords[2]] = atof(argv[3]) * scalecoords[2]; +#endif + num_vertices++; + } + else + Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 3); + } + else if (!String_Compare(argv[0], "vn")) + { + // vn 1.99019e-6 2.65359e-5 -1.000000 + if (argc == 4) + { + if (num_normals >= max_normals) + { + max_normals = Max(max_normals * 2, 1024); + Mem_ReAlloc(Global_Zone, &data_normal3f, max_normals * sizeof(float[3])); + } +#if 1 + data_normal3f[num_normals*3+0] = atof(argv[1]); + data_normal3f[num_normals*3+2] = atof(argv[2]); + data_normal3f[num_normals*3+1] = atof(argv[3]); +#else + data_normal3f[num_normals*3+remapcoords[0]] = atof(argv[1]) * scalecoords[0]; + data_normal3f[num_normals*3+remapcoords[1]] = atof(argv[2]) * scalecoords[1]; + data_normal3f[num_normals*3+remapcoords[2]] = atof(argv[3]) * scalecoords[2]; +#endif + num_normals++; + } + else + Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 3); + } + else if (!String_Compare(argv[0], "vt")) + { + // vt 0.00000e+0 1.99019e-6 + if (argc == 3) + { + if (num_texcoords >= max_texcoords) + { + max_texcoords = Max(max_texcoords * 2, 1024); + Mem_ReAlloc(Global_Zone, &data_texcoord2f, max_texcoords * sizeof(float[2])); + } + data_texcoord2f[num_texcoords*2+0] = atof(argv[1]); + data_texcoord2f[num_texcoords*2+1] = -atof(argv[2]); + num_texcoords++; + } + else + Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 2); + } + else if (!String_Compare(argv[0], "usemtl")) + { + // usemtl mtrl/chrome + if (argc == 2) + surfaceindex = Util_BuildModel_AddSurface(b, argv[1]); + else + Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1); + } + else if (!String_Compare(argv[0], "f")) + { + // f 1/11/5 18/56/71 17/58/67 + NUint32 i; + NUint32 indices[64]; + if (argc >= 4) + { + if (surfaceindex == -1) + surfaceindex = Util_BuildModel_AddSurface(b, "default"); + for (i = 0;i < argc - 1;i++) + { + NUint32 j; + const char *s = argv[i+1]; + float v[3]; + float vn[3]; + float tc[2]; + // if there are 3 indices, they are vertex, texcoord, normal + // if there are 2 indices, they are vertex, texcoord + // if there is only one index, it is vertex + // so we just initialize the values to defaults, + // and update them as indices are read + VectorClear(v); + VectorClear(vn); + Vector2Clear(tc); + for (j = 0;j < 3;j++) + { + if (*s) + { + NSint32 k = atoi(s); + switch (j) + { + case 0: + if (k < 0) + k += num_vertices; + else + k--; + if (k >= 0 && k < num_vertices) + VectorCopy(data_vertex3f + k * 3, v); + else + Console_Printf("util_convertobj: %s:%i: invalid face vertex index (parameter #%i)\n", inputname, linenumber, i + 1); + break; + case 1: + if (k < 0) + k += num_texcoords; + else + k--; + if (k >= 0 && k < num_texcoords) + Vector2Copy(data_texcoord2f + k * 2, tc); + else + Console_Printf("util_convertobj: %s:%i: invalid face texcoord index (parameter #%i)\n", inputname, linenumber, i + 1); + break; + case 2: + if (k < 0) + k += num_normals; + else + k--; + if (k >= 0 && k < num_normals) + VectorCopy(data_normal3f + k * 3, vn); + else + Console_Printf("util_convertobj: %s:%i: invalid face vertexnormal index (parameter #%i)\n", inputname, linenumber, i + 1); + break; + } + } + // this weird code construct exits at NUL, or if the + // character is /, and then leaves s at the character + // after the NUL or / + while (*s) + { + if (*s == '/') + { + s++; + break; + } + s++; + } + } + indices[i] = Util_BuildModel_FindOrAddVertex(b, surfaceindex, v[0], v[1], v[2], vn[0], vn[1], vn[2], tc[0], tc[1]); + // make a triangle fan if we have enough vertices + if (i >= 2) + { +#if 0 + if (flip) + Util_BuildModel_AddTriangle(b, surfaceindex, indices[0], indices[i], indices[i-1]); + else +#endif + Util_BuildModel_AddTriangle(b, surfaceindex, indices[0], indices[i-1], indices[i]); + } + } + } + else + Console_Printf("util_convertobj: %s:%i: command %s takes %i or more parameters\n", inputname, linenumber, argv[0], 3); + } + else if (!String_Compare(argv[0], "o")) + { + // o cylinder1 + if (argc != 2) + Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1); + } + else if (!String_Compare(argv[0], "mtllib")) + { + // mtllib zrail2.mtl + if (argc != 2) + Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1); + } + else if (!String_Compare(argv[0], "g")) + { + // g cylinder1_mtrl/invisible + if (argc != 2) + Console_Printf("util_convertobj: %s:%i: command %s takes %i parameters\n", inputname, linenumber, argv[0], 1); + } + else + Console_Printf("util_convertobj: %s:%i: unknown obj command %s\n", inputname, linenumber, argv[0]); + } + if (data_vertex3f) + Mem_Free(&data_vertex3f); + if (data_normal3f) + Mem_Free(&data_normal3f); + if (data_texcoord2f) + Mem_Free(&data_texcoord2f); +} + static void Util_Shell_MakeTerrain(void) { - NUint32 i, tilesize, width, height, bx, by, tx, ty, tilewidth, tileheight, num, nummeshes, tileswidth, tilesheight; + NUint32 tilesize, width, height, bx, by, tx, ty, tilewidth, tileheight, num, tileswidth, tilesheight; NUint8 *pixels; const char *basename, *imagename, *materialname; char *tilename; Nvec terrainsize[3], texturesize[2], terrainscale[3], terrainorigin[3], texturescale[2]; - Util_Mesh *meshes, *mesh; + Util_BuildModel b; basename = Shell_Callback_GetArg(1); imagename = Shell_Callback_GetArg(2); tilesize = (int) Shell_Callback_GetArgValue(3); @@ -313,10 +642,295 @@ terrainorigin[2] = terrainsize[2] * -0.5; tileswidth = width / tilesize; tilesheight = height / tilesize; - nummeshes = 0; + Util_BuildModel_Begin(&b); for (by = 0;by < height;by += tilesize) + { for (bx = 0;bx < width;bx += tilesize) - nummeshes++; + { + NUint32 surfaceindex = Util_BuildModel_AddSurface(&b, materialname); + tilewidth = Bound(0, width - bx, tilesize+2); + tileheight = Bound(0, height - by, tilesize+2); + for (ty = 0, num = 0;ty < tileheight;ty++) + { + for (tx = 0;tx < tilewidth;tx++, num++) + { + NUint32 w = width*4; + NUint8 *p = pixels + ((by + ty) * width + (bx + tx)) * 4; + NUint32 pxi, pyi; + double px, py, pz, pxf, pyf; + px = bx + Bound(0.5, tx, tilewidth - 1.5); + py = by + Bound(0.5, ty, tileheight - 1.5); + pxi = (int)px; + pyi = (int)py; + pxf = px - pxi; + pyf = py - pyi; + p = pixels + (pyi * width + pxi) * 4; + pz = ((p[0]+p[1]+p[2])*(1.0-pxf)+(p[4]+p[5]+p[6])*(pxf))*(1.0-pyf)+((p[w+0]+p[w+1]+p[w+2])*(1.0-pxf)+(p[w+4]+p[w+5]+p[w+6])*(pxf))*(pyf); + // FIXME: this SHOULD calculate a valid surface normal!! + Util_BuildModel_AddVertex(&b, surfaceindex, px * terrainscale[0] + terrainorigin[0], py * terrainscale[1] + terrainorigin[1], pz * terrainscale[2] + terrainorigin[2], 0, 0, 1, (px * terrainscale[0] + terrainorigin[0]) * texturescale[0], (py * terrainscale[1] + terrainorigin[1]) * texturescale[1]); + } + } + for (ty = 0, num = 0;ty < tileheight-1;ty++) + { + for (tx = 0;tx < tilewidth-1;tx++, num += 6) + { + NUint32 i = ty*tilewidth+tx; + Util_BuildModel_AddTriangle(&b, surfaceindex, i, i+1, i+1+tilewidth); + Util_BuildModel_AddTriangle(&b, surfaceindex, i, i+1+tilewidth, i+tilewidth); + } + } + } + } + Mem_Free(&pixels); + tilename = String_APrintf(Global_Zone, "%s.md5mesh", basename); + Util_BuildModel_Write(&b, tilename); + String_Free(&tilename); + Util_BuildModel_End(&b); +} + +static Shell_SymbolDecl Util_Shell_MakeTerrain_Decl = { + "util_maketerrain", + "Turn a heightmap image into a set of md5mesh files.", + "Usage: util_maketerrain \n" + "Example: util_maketerrain maps/mymap/terrain maps/mymap/terrain.tga 32 1000 1000 1000 maps/mymap/grass 32 32\n" + "would produce md5mesh tiles named maps/mymap/terrain_00_00.md5mesh and up (each containing up to 33x33 vertices and 32x32x2 triangles) comprising a 1000m wide x 1000m long x 1000m high terrain with a material named maps/mymap/grass repeating every 32m x 32m", + "ssvvvvsvv", + (Shell_Symbol_Callback) Util_Shell_MakeTerrain +}; + +static void Util_Shell_ConvertOBJ(void) +{ + Nsize objtextsize; + Util_BuildModel b; + const char *inputname = Shell_Callback_GetArg(1); + const char *outputname = Shell_Callback_GetArg(2); +#if 0 + float scale = atof(Shell_Callback_GetArg(3)); + Nbool flip = atoi(Shell_Callback_GetArg(4)) != 0; + NUint32 conversionmode = atoi(Shell_Callback_GetArg(5)); + NUint32 remapcoords[3]; + float scalecoords[3]; +#endif + char *objtext = File_LoadFile(inputname, &objtextsize); + if (!objtext) + { + Shell_Callback_ThrowError("Could not open OBJ file\n"); + // SHELLTODO + return; + } + Util_BuildModel_Begin(&b); +#if 1 + Util_BuildModel_ImportOBJ(&b, inputname, objtext, objtext + objtextsize); +#else + scalecoords[0] = conversionmode & 1 ? -scale : scale; + scalecoords[1] = conversionmode & 2 ? -scale : scale; + scalecoords[2] = conversionmode & 4 ? -scale : scale; + switch((conversionmode / 8) % 6) + { + default: + case 0: remapcoords[0] = 0;remapcoords[1] = 1;remapcoords[2] = 2;break; + case 1: remapcoords[0] = 0;remapcoords[1] = 2;remapcoords[2] = 1;break; + case 2: remapcoords[0] = 1;remapcoords[1] = 0;remapcoords[2] = 2;break; + case 3: remapcoords[0] = 1;remapcoords[1] = 2;remapcoords[2] = 0;break; + case 4: remapcoords[0] = 2;remapcoords[1] = 0;remapcoords[2] = 1;break; + case 5: remapcoords[0] = 2;remapcoords[1] = 1;remapcoords[2] = 0;break; + } + Util_BuildModel_ImportOBJ(&b, inputname, objtext, objtext + objtextsize, flip, remapcoords, scalecoords); +#endif + Util_BuildModel_Write(&b, outputname); + Util_BuildModel_End(&b); + Mem_Free(&objtext); +} + +static Shell_SymbolDecl Util_Shell_ConvertOBJ_Decl = { + "util_convertobj", + "Turn a .obj model into a .md5mesh model file.", +#if 1 + "Usage: util_convertobj \n" + "Example: util_convertobj maps/mymap/mymodel.obj maps/mymap/mymodel.md5mesh", + "ss", +#else + "Usage: util_convertobj \n" + "Example: util_convertobj maps/mymap/mymodel.obj maps/mymap/mymodel.md5mesh 1 0 8\n" + "coordinate conversion mode is a special number that rotates and/or mirrors the geometry, it is in the range 0-47, example value for most 3D programs is 8", + "ssvvv", +#endif + (Shell_Symbol_Callback) Util_Shell_ConvertOBJ +}; + + + +/* +UNFINISHED +#define UTIL_SHELL_CONVERTLWO_FACE_MAXVERTS 4 +typedef struct Util_Shell_ConvertLWO_Face +{ + NUint32 surfaceindex; + NUint32 numpoints; + float point[UTIL_SHELL_CONVERTLWO_FACE_MAXVERTS][3]; +} +Util_Shell_ConvertLWO_Face; + +static void Util_Shell_ConvertLWO(void) +{ + NUint8 *lwodata; + Nsize lwosize; + + NUint32 i, tilesize, width, height, bx, by, tx, ty, tilewidth, tileheight, num, nummeshes, tileswidth, tilesheight; + NUint8 *pixels; + const char *basename, *imagename, *materialname; + char *tilename; + Nvec terrainsize[3], texturesize[2], terrainscale[3], terrainorigin[3], texturescale[2]; + Util_Mesh *meshes, *mesh; + + inputname = Shell_Callback_GetArg(1); + outputname = Shell_Callback_GetArg(2); + lwodata = File_LoadFile(inputname, &lwosize); + if (!lwodata) + { + Shell_Callback_ThrowError("Could not open LWO file\n"); + // SHELLTODO + return; + } + if (lwosize < 8 || memcmp(lwodata, "FORM", 4)) + { + Mem_Free(&lwodata); + Shell_Callback_ThrowError("Not an Interchange File Format (and therefore not an LWO file)\n"); + // SHELLTODO + return; + } + if ((lwodata[4] * 16777216 + lwodata[5] * 65536 + lwodata[6] * 256 + lwodata[7]) + 8 > lwosize) + { + Mem_Free(&lwodata); + Shell_Callback_ThrowError("Corrupt Interchange File Format file (truncated FORM chunk)\n"); + // SHELLTODO + return; + } + if (memcmp(lwodata + 8, "LWO2", 4)) + { + Mem_Free(&lwodata); + Shell_Callback_ThrowError("File is Interchange File Format but not an LWO2 (Lightwave 6 or later) file\n"); + // SHELLTODO + return; + } + lwodatastart = lwodata + 12; + lwodataend = lwodata + 8 + (lwodata[4] * 16777216 + lwodata[5] * 65536 + lwodata[6] * 256 + lwodata[7]); + chunk_pnts = NULL; + chunk_vmap_txuv = NULL; + chunk_pols_face = NULL; + chunk_ptag_surf = NULL; + chunk_vmap_txuv_numtexcoordcomponents = 0; + chunk_vmap_txuv_numtexcoords = 0; + chunk_vmap_txuv_texcoords = NULL; + for (chunk = lwodatastart;chunk <= lwodataend - 8;chunk = contentend) + { + chunksize = (chunk[4] * 16777216 + chunk[5] * 65536 + chunk[6] * 256 + chunk[7]); + content = chunk; + contentend = chunk + 8 + chunksize; + if (!memcmp(chunk, "PNTS")) + { + chunk_pnts = chunk; + continue; + } + if (!memcmp(chunk, "VMAP")) + { + // read type of vertex map + if (!memcmp(content, "TXUV", 4)) + { + // + chunk_vmap_txuv = chunk; + content += 4; + // read number of components + chunk_vmap_txuv_numtexcoordcomponents = content[0] * 256 + content[1]); + content += 2; + // skip name of this TXUV chunk, typically Texture + while (*content) + content++; + // skip to 4 byte boundary in file + while ((content - lwodatastart) & 3) + content++; + chunk_vmap_txuv_numtexcoords = (contentend - content) / (numtexcoordcomponents * 4); + chunk_vmap_txuv_texcoords = content; + } + continue; + } + if (!memcmp(chunk, "POLS", 4)) + { + // polygons + if (!memcmp(content, "FACE", 4)) + { + // polygons stored as short numpoints, short index[] + chunk_pols_face = chunk; + // count the number of triangles we'll be loading + content += 4; + polygons = content; + numtriangles = 0; + numpolygons = 0; + polygonmaterials = Mem_Alloc(Global_Zone, numpolygons * sizeof(short)); + while (content < contentend) + { + int p; + p = content[2] * 256 + content[3]; + content += 2; + numpolygons++; + if (p >= 3) + numtriangles += p - 2; + for (;p;p--) + content += 2; + } + } + continue; + } + if (!memcmp(chunk, "PTAG", 4)) + { + // polygon attributes + if (!memcmp(chunk, "SURF", 4)) + { + // list of polygons and their corresponding surfaces + chunk_ptag_surf = chunk; + } + continue; + } + if (!memcmp(chunk, "CLIP", 4)) + { + //unknown + content += 4; + imageindex++; + for (;content < contentend;content = nextcontent) + { + nextcontent = content + content[4] * 256 + content[5]; + if (!memcmp(content, "STIL", 4)) + { + // image name + strncpy(imagename[imageindex], content, sizeof(imagename[imageindex]) - 1); + } + } + } + if (!memcmp(chunk, "SURF", 4)) + { + materialindex++; + // surface name, often Default + while (*content) + content++; + // skip to 4 byte boundary in file + while ((content - lwodatastart) & 3) + content++; + for (;content < contentend;content = nextcontent) + { + nextcontent = content + content[4] * 256 + content[5]; + if (!memcmp(content, "IMAG", 4)) + { + // image index + materialimage[materialindex] = content[6] * 256 + content[7]; + } + } + } + } + + polygonmaterials = Mem_Alloc(Global_Zone, + for ( + + //nummeshes = tileswidth * tilesheight; meshes = Mem_Alloc(Global_Zone, nummeshes * sizeof(Util_Mesh)); mesh = meshes; @@ -394,29 +1008,18 @@ "ssvvvvsvv", (Shell_Symbol_Callback) Util_Shell_MakeTerrain }; +*/ -float skyboxvertex3f[6*4*3] = +float skyboxvertex[6][4][8] = { - 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, // px - -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, // nx - 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, // py - -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, // ny - -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, // pz - 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1 // nz + {{ 1, 1, 1, -1, 0, 0, 0, 1}, { 1, 1, -1, -1, 0, 0, 1, 1}, { 1, -1, -1, -1, 0, 0, 1, 0}, { 1, -1, 1, -1, 0, 0, 0, 0}}, // px + {{-1, -1, 1, 1, 0, 0, 1, 0}, {-1, -1, -1, 1, 0, 0, 0, 0}, {-1, 1, -1, 1, 0, 0, 0, 1}, {-1, 1, 1, 1, 0, 0, 1, 1}}, // nx + {{ 1, -1, 1, 0, -1, 0, 1, 1}, { 1, -1, -1, 0, -1, 0, 1, 0}, {-1, -1, -1, 0, -1, 0, 0, 0}, {-1, -1, 1, 0, -1, 0, 0, 1}}, // py + {{-1, 1, 1, 0, 1, 0, 0, 0}, {-1, 1, -1, 0, 1, 0, 0, 1}, { 1, 1, -1, 0, 1, 0, 1, 1}, { 1, 1, 1, 0, 1, 0, 1, 0}}, // ny + {{-1, 1, 1, 0, 0, -1, 0, 1}, { 1, 1, 1, 0, 0, -1, 1, 1}, { 1, -1, 1, 0, 0, -1, 1, 0}, {-1, -1, 1, 0, 0, -1, 0, 0}}, // pz + {{ 1, 1, -1, 0, 0, 1, 0, 1}, {-1, 1, -1, 0, 0, 1, 1, 1}, {-1, -1, -1, 0, 0, 1, 1, 0}, { 1, -1, -1, 0, 0, 1, 0, 0}} // nz }; -float skyboxtexcoord2f[6*4*2] = -{ - 0, 1, 1, 1, 1, 0, 0, 0, // px - 1, 0, 0, 0, 0, 1, 1, 1, // nx - 1, 1, 1, 0, 0, 0, 0, 1, // py - 0, 0, 0, 1, 1, 1, 1, 0, // ny - 0, 1, 1, 1, 1, 0, 0, 0, // pz - 0, 1, 1, 1, 1, 0, 0, 0 // nz -}; - -NUint32 skyboxelements[6] = {0, 2, 1, 0, 3, 2}; - const char *skyboxsuffix[6] = {"px", "nx", "py", "ny", "pz", "nz"}; static void Util_Shell_MakeSkyBox(void) @@ -424,29 +1027,28 @@ NUint32 i; double boxsize; const char *basefilename, *baseimagename; - char *filename, *materialname[6]; - float verts[6*4*3]; - Util_Mesh meshes[6]; + char *filename; + Util_BuildModel b; basefilename = Shell_Callback_GetArg(1); baseimagename = Shell_Callback_GetArg(2); boxsize = atof(Shell_Callback_GetArg(3)); + Util_BuildModel_Begin(&b); for (i = 0;i < 6;i++) { - materialname[i] = String_APrintf(Global_Zone, "%s_%s", baseimagename, skyboxsuffix[i]); - meshes[i].materialname = materialname[i]; - meshes[i].numvertices = 4; - meshes[i].vertex3f = verts + i*4*3; - meshes[i].texcoord2f = skyboxtexcoord2f + i*4*2; - meshes[i].numtriangles = 2; - meshes[i].element3i = skyboxelements; + NUint32 j; + NUint32 indices[4]; + char *materialname = String_APrintf(Global_Zone, "%s_%s", baseimagename, skyboxsuffix[i]); + NUint32 surfaceindex = Util_BuildModel_AddSurface(&b, materialname); + String_Free(&materialname); + for (j = 0;j < 4;j++) + indices[j] = Util_BuildModel_FindOrAddVertex(&b, surfaceindex, skyboxvertex[i][j][0], skyboxvertex[i][j][1], skyboxvertex[i][j][2], skyboxvertex[i][j][3], skyboxvertex[i][j][4], skyboxvertex[i][j][5], skyboxvertex[i][j][6], skyboxvertex[i][j][7]); + Util_BuildModel_AddTriangle(&b, surfaceindex, indices[0], indices[2], indices[1]); + Util_BuildModel_AddTriangle(&b, surfaceindex, indices[0], indices[3], indices[2]); } - for (i = 0;i < 72;i++) - verts[i] = skyboxvertex3f[i] * boxsize; filename = String_APrintf(Global_Zone, "%s.md5mesh", basefilename); - Util_WriteModel(filename, 6, meshes); + Util_BuildModel_Write(&b, filename); String_Free(&filename); - for (i = 0;i < 6;i++) - String_Free(&materialname[i]); + Util_BuildModel_End(&b); } static Shell_SymbolDecl Util_Shell_MakeSkyBox_Decl = { @@ -463,6 +1065,7 @@ { Shell_RegisterFunction(&Util_Shell_MakeTerrain_Decl); Shell_RegisterFunction(&Util_Shell_MakeSkyBox_Decl); + Shell_RegisterFunction(&Util_Shell_ConvertOBJ_Decl); } void Util_Quit(void) Modified: trunk/util.h =================================================================== --- trunk/util.h 2006-04-08 00:42:44 UTC (rev 688) +++ trunk/util.h 2006-04-08 00:45:02 UTC (rev 689) @@ -40,21 +40,39 @@ // lex the next token void Util_ParseC_Lex(Util_ParseC_Thread *thread); -typedef struct Util_Mesh +typedef struct Util_BuildModel_Surface { // no support for skeletal weighting since this is only used by utilities building simple models - const char *materialname; - NUint32 numvertices; - float *vertex3f; - float *texcoord2f; - NUint32 numtriangles; - NUint32 *element3i; + char materialname[64]; + NUint32 num_triangles, max_triangles; + NUint32 *data_element3i; + NUint32 num_vertices, max_vertices; + float *data_vertex8f; } -Util_Mesh; +Util_BuildModel_Surface; -// writes a .md5mesh file given an array of meshes -void Util_WriteModel(const char *filename, NUint32 nummeshes, Util_Mesh *meshes); +typedef struct Util_BuildModel +{ + NUint32 num_surfaces, max_surfaces; + Util_BuildModel_Surface *data_surfaces; + // no support for skeleton since this is only used by utilities building simple models +} +Util_BuildModel; +// a small system for easily building md5mesh files +void Util_BuildModel_Begin(Util_BuildModel *b); +void Util_BuildModel_End(Util_BuildModel *b); +NUint32 Util_BuildModel_AddSurface(Util_BuildModel *b, const char *materialname); +NUint32 Util_BuildModel_AddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t); +NUint32 Util_BuildModel_FindOrAddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t); +NUint32 Util_BuildModel_AddTriangle(Util_BuildModel *b, NUint32 surfaceindex, int e0, int e1, int e2); +void Util_BuildModel_Write(Util_BuildModel *b, const char *filename); +#if 1 +void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend); +#else +void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend, Nbool flip, NUint32 remapcoords[3], float scalecoords[3]); +#endif + void Util_Init(void); void Util_Quit(void); From lordhavoc at icculus.org Fri Apr 7 20:48:06 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 7 Apr 2006 20:48:06 -0400 Subject: r690 - trunk Message-ID: <20060408004806.18538.qmail@icculus.org> Author: lordhavoc Date: 2006-04-07 20:48:06 -0400 (Fri, 07 Apr 2006) New Revision: 690 Modified: trunk/util.c trunk/util.h Log: removed commented out portions of Util_BuildModel code Modified: trunk/util.c =================================================================== --- trunk/util.c 2006-04-08 00:45:02 UTC (rev 689) +++ trunk/util.c 2006-04-08 00:48:06 UTC (rev 690) @@ -357,14 +357,7 @@ Mem_Free(&text); } -#if 1 void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend) -#else -static NUint32 default_remapcoords[3] = {0, 1, 2}; -static float default_scalecoords[3] = {1, 1, 1}; - -void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend, Nbool flip, NUint32 remapcoords[3], float scalecoords[3]) -#endif { NUint32 linenumber = 0; NSint32 surfaceindex = -1; @@ -374,12 +367,6 @@ float *data_vertex3f = NULL; float *data_normal3f = NULL; float *data_texcoord2f = NULL; -#if 0 - if (remapcoords == NULL) - remapcoords = default_remapcoords; - if (scalecoords == NULL) - scalecoords = default_scalecoords; -#endif while (text < textend) { Nbool comment = false; @@ -419,15 +406,9 @@ max_vertices = Max(max_vertices * 2, 1024); Mem_ReAlloc(Global_Zone, &data_vertex3f, max_vertices * sizeof(float[3])); } -#if 1 data_vertex3f[num_vertices*3+0] = atof(argv[1]); data_vertex3f[num_vertices*3+2] = atof(argv[2]); data_vertex3f[num_vertices*3+1] = atof(argv[3]); -#else - data_vertex3f[num_vertices*3+remapcoords[0]] = atof(argv[1]) * scalecoords[0]; - data_vertex3f[num_vertices*3+remapcoords[1]] = atof(argv[2]) * scalecoords[1]; - data_vertex3f[num_vertices*3+remapcoords[2]] = atof(argv[3]) * scalecoords[2]; -#endif num_vertices++; } else @@ -443,15 +424,9 @@ max_normals = Max(max_normals * 2, 1024); Mem_ReAlloc(Global_Zone, &data_normal3f, max_normals * sizeof(float[3])); } -#if 1 data_normal3f[num_normals*3+0] = atof(argv[1]); data_normal3f[num_normals*3+2] = atof(argv[2]); data_normal3f[num_normals*3+1] = atof(argv[3]); -#else - data_normal3f[num_normals*3+remapcoords[0]] = atof(argv[1]) * scalecoords[0]; - data_normal3f[num_normals*3+remapcoords[1]] = atof(argv[2]) * scalecoords[1]; - data_normal3f[num_normals*3+remapcoords[2]] = atof(argv[3]) * scalecoords[2]; -#endif num_normals++; } else @@ -561,14 +536,7 @@ indices[i] = Util_BuildModel_FindOrAddVertex(b, surfaceindex, v[0], v[1], v[2], vn[0], vn[1], vn[2], tc[0], tc[1]); // make a triangle fan if we have enough vertices if (i >= 2) - { -#if 0 - if (flip) - Util_BuildModel_AddTriangle(b, surfaceindex, indices[0], indices[i], indices[i-1]); - else -#endif - Util_BuildModel_AddTriangle(b, surfaceindex, indices[0], indices[i-1], indices[i]); - } + Util_BuildModel_AddTriangle(b, surfaceindex, indices[0], indices[i-1], indices[i]); } } else @@ -704,13 +672,6 @@ Util_BuildModel b; const char *inputname = Shell_Callback_GetArg(1); const char *outputname = Shell_Callback_GetArg(2); -#if 0 - float scale = atof(Shell_Callback_GetArg(3)); - Nbool flip = atoi(Shell_Callback_GetArg(4)) != 0; - NUint32 conversionmode = atoi(Shell_Callback_GetArg(5)); - NUint32 remapcoords[3]; - float scalecoords[3]; -#endif char *objtext = File_LoadFile(inputname, &objtextsize); if (!objtext) { @@ -719,24 +680,7 @@ return; } Util_BuildModel_Begin(&b); -#if 1 Util_BuildModel_ImportOBJ(&b, inputname, objtext, objtext + objtextsize); -#else - scalecoords[0] = conversionmode & 1 ? -scale : scale; - scalecoords[1] = conversionmode & 2 ? -scale : scale; - scalecoords[2] = conversionmode & 4 ? -scale : scale; - switch((conversionmode / 8) % 6) - { - default: - case 0: remapcoords[0] = 0;remapcoords[1] = 1;remapcoords[2] = 2;break; - case 1: remapcoords[0] = 0;remapcoords[1] = 2;remapcoords[2] = 1;break; - case 2: remapcoords[0] = 1;remapcoords[1] = 0;remapcoords[2] = 2;break; - case 3: remapcoords[0] = 1;remapcoords[1] = 2;remapcoords[2] = 0;break; - case 4: remapcoords[0] = 2;remapcoords[1] = 0;remapcoords[2] = 1;break; - case 5: remapcoords[0] = 2;remapcoords[1] = 1;remapcoords[2] = 0;break; - } - Util_BuildModel_ImportOBJ(&b, inputname, objtext, objtext + objtextsize, flip, remapcoords, scalecoords); -#endif Util_BuildModel_Write(&b, outputname); Util_BuildModel_End(&b); Mem_Free(&objtext); @@ -745,16 +689,9 @@ static Shell_SymbolDecl Util_Shell_ConvertOBJ_Decl = { "util_convertobj", "Turn a .obj model into a .md5mesh model file.", -#if 1 "Usage: util_convertobj \n" "Example: util_convertobj maps/mymap/mymodel.obj maps/mymap/mymodel.md5mesh", "ss", -#else - "Usage: util_convertobj \n" - "Example: util_convertobj maps/mymap/mymodel.obj maps/mymap/mymodel.md5mesh 1 0 8\n" - "coordinate conversion mode is a special number that rotates and/or mirrors the geometry, it is in the range 0-47, example value for most 3D programs is 8", - "ssvvv", -#endif (Shell_Symbol_Callback) Util_Shell_ConvertOBJ }; Modified: trunk/util.h =================================================================== --- trunk/util.h 2006-04-08 00:45:02 UTC (rev 689) +++ trunk/util.h 2006-04-08 00:48:06 UTC (rev 690) @@ -67,11 +67,7 @@ NUint32 Util_BuildModel_FindOrAddVertex(Util_BuildModel *b, NUint32 surfaceindex, float x, float y, float z, float nx, float ny, float nz, float s, float t); NUint32 Util_BuildModel_AddTriangle(Util_BuildModel *b, NUint32 surfaceindex, int e0, int e1, int e2); void Util_BuildModel_Write(Util_BuildModel *b, const char *filename); -#if 1 void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend); -#else -void Util_BuildModel_ImportOBJ(Util_BuildModel *b, const char *inputname, const char *text, const char *textend, Nbool flip, NUint32 remapcoords[3], float scalecoords[3]); -#endif void Util_Init(void); void Util_Quit(void); From lordhavoc at icculus.org Fri Apr 7 22:42:42 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 7 Apr 2006 22:42:42 -0400 Subject: r691 - in trunk/base: gamedefs maps models models/infantry Message-ID: <20060408024242.785.qmail@icculus.org> Author: lordhavoc Date: 2006-04-07 22:42:27 -0400 (Fri, 07 Apr 2006) New Revision: 691 Added: trunk/base/models/infantry/ trunk/base/models/infantry/spawnpad.md5mesh trunk/base/models/infantry/spawnpad.tga trunk/base/models/vehicle/ Modified: trunk/base/gamedefs/entities.csv trunk/base/maps/test.ent Log: added Randy's spawnpad model fixed model names in entities.csv Modified: trunk/base/gamedefs/entities.csv =================================================================== --- trunk/base/gamedefs/entities.csv 2006-04-08 00:48:06 UTC (rev 690) +++ trunk/base/gamedefs/entities.csv 2006-04-08 02:42:27 UTC (rev 691) @@ -1,66 +1,66 @@ CodeName ParentCodeName EnglishName Class Model Mass Health Heal NoRemove Respawn I0C I0B I1C I1B I2C I2B I3C I3B I4C I4B I5C I5B I6C I6B I7C I7B I8C I8B I9C I9B AmmoMax AmmoRegen Projectile Shots Spread SemiRefire AutoRefire Physics StepHeight JumpVelocity Speed TopSpeed Acceleration Friction StopSpeed AirSpeed AirAcceleration AirFriction AirStopSpeed HoverThrust HoverAltitude Cloaking JumpFlight CrouchShield CrouchTurret LifeTime ImpactDelay FleshDamage ArmorDamage Force DamageRadius Shake ShakeRadius IdleAnim IdleFPS light Light light -model Model model default -model_sky Sky Model model_sky default +model Model model default.md5mesh +model_sky Sky Model model_sky default.md5mesh room Room room -infantry Infantry infantry infantry/infantry 90 200 10 itemmachinegun weapon itempistol pistol itemhandgrenade grenade1 itemhandgrenade grenade2 itemhandgrenade grenade3 infantry 0.3 4 5 10 2 10 20 0.02 0.1 0 -infscout Scout infantry infantry/scout 90 200 10 itemsniperrifle weapon itempistol pistol itemhandgrenade grenade1 itemhandgrenade grenade2 itemhandgrenade grenade3 infantry 0.3 4 5 10 2 10 20 0.02 0.1 0 TRUE -infhellion Hellion infantry infantry/hellion 90 200 10 itemmachinegun weapon itempistol pistol itemhandgrenade grenade1 itemhandgrenade grenade2 itemhandgrenade grenade3 infantry 0.3 8 6 10 2 10 20 1 0.03 1 TRUE -infmarauder Marauder infantry infantry/marauder 200 1000 40 itemminigun weapon itempistol pistol itemhandgrenade grenade1 itemhandgrenade grenade2 itemhandgrenade grenade3 itemhandgrenade grenade4 itemhandgrenade grenade5 infantry 0.3 6 5 10 2 10 20 0.2 0.03 0 TRUE -infgranite Granite infantry infantry/granite 400 2000 80 itemplasmacannon weapon infantry 0.3 12 4 10 2 10 20 0.01 0.03 0 TRUE -vehapc APC vehicle_apc vehicle/apc 3000 2000 50 weapon hover 0 0 0.2 1 20 0 0.01 5 20 0.5 -vehtankrailgun Railgun Hover Tank vehicle_tank vehicle/tankrailgun 3000 2000 50 weapontankrailgun weapon hover 0 0 0.2 1 20 0 0.01 5 20 0.5 -vehdropship Drop Ship vehicle_dropship vehicle/dropship 2000 2000 50 weapon vtol 0 0 0.5 2 40 1 0.01 5 -turretrailgun Railgun Turret turret turret/turretrail 1000 3000 150 weaponturretrailgun weapon default -turretvulcan Vulcan Turret turret turret/turretvulcan 1000 3000 150 weaponturretvulcan weapon default -turretartillery Artillery Turret turret turret/turretartillery 1000 3000 150 weaponturretartillery weapon default -spawninfantry Infantry Spawn Pad spawnpad spawn/infantry 500 500 25 TRUE 1 infantry spawn -spawninfscout Scout Spawn Pad spawnpad spawn/infantry 2000 1000 50 TRUE 10 infscout spawn -spawninfhellion Hellion Spawn Pad spawnpad spawn/infantry 2000 1000 50 TRUE 10 infhellion spawn -spawninfmarauder Marauder Spawn Pad spawnpad spawn/infantry 2000 1000 50 TRUE 10 infmarauder spawn -spawninfgranite Granite Spawn Pad spawnpad spawn/infantry 2000 1000 50 TRUE 10 infgranite spawn -spawnvehapc APC Spawn Pad vehiclepad spawn/vehicle 10000 2000 100 TRUE 50 vehapc spawn -spawnvehtankrailgun Railgun Hover Tank Spawn Pad vehiclepad spawn/vehicle 10000 2000 100 TRUE 50 vehtankrailgun spawn -spawnvehdropship Drop Ship Spawn Pad vehiclepad spawn/vehicle 10000 2000 100 TRUE 50 vehdropship spawn -spawnturretrailgun Railgun Turret Spawn Pad vehiclepad spawn/turret 10000 2000 100 TRUE 50 turretrailgun spawn -spawnturretvulcan Vulcan Turret Spawn Pad vehiclepad spawn/turret 10000 2000 100 TRUE 50 turretvulcan spawn -spawnturretartillery Artillery Turret Spawn Pad vehiclepad spawn/turret 10000 2000 100 TRUE 50 turretartillery spawn -itemhandgrenade Hand Grenade item weapon/handgrenade/body 0.2 projhandgrenade 1 0.1 0.5 0.5 -itempistol Pistol item weapon/pistol/body 1 60 projpistol 1 0.01 0.2 0.5 -itemmachinegun Machinegun item weapon/machinegun/body 5 400 projmachinegun 1 0.01 0.06 0.13 -itemshotgun Flechette Shotgun item weapon/shotgun/body 5 50 projshotgun 8 0.03 0.2 0.5 -itemminigun Minigun item weapon/minigun/body 20 1200 projminigun 1 0.02 0.05 0.05 -itemsniperrifle Sniper Rifle item weapon/sniperrifle/body 4 25 projsniperrifle 1 0.0001 0.5 1 -itemgrenadelauncher Grenade Launcher item weapon/grenadelauncher/body 3 50 projgrenadelauncher 1 0.02 0.5 0.5 -itemrocketlauncher Rocket Launcher item weapon/rocketlauncher/body 10 20 projrocketlauncher 1 0.001 0.3 0.3 -itemplasmacannon Plasma Cannon item weapon/plasmacannon/body 50 30 10 projplasmacannon 1 0.01 1 1 -weapontankrailgun Railgun weapon weapon/tankrailgun/body 50 10 2 projtankrailgun 1 0.0001 1 1 -weaponturretrailgun Railgun weapon weapon/turretrailgun/body 50 2 1 projturretrailgun 1 0.01 1 1 -weaponturretvulcan Vulcan Cannon weapon weapon/turretvulcan/body 200 20 20 projturretvulcan 1 0.03 0.06 0.06 -weaponturretartillery Artillery Cannon weapon weapon/turretartillery/body 200 1 0.2 projturretartillery 1 0.01 5 5 -projhandgrenade Live Hand Grenade projectile weapon/handgrenade/projectile 0.2 default 10 1 0.1 3 4 -projpistol Pistol Bullet projectile weapon/pistol/projectile 0.01 default 1300 1 0.1 60 0 -projmachinegun Machinegun Bullet projectile weapon/machinegun/projectile 0.005 default 800 1 0.1 60 0 -projshotgun Shotgun Flechette projectile weapon/shotgun/projectile 0.02 default 1100 1 0.1 60 0 -projminigun Minigun Bullet projectile weapon/minigun/projectile 0.01 default 800 1 0.1 60 0 -projsniperrifle Sniper Rifle Flechette projectile weapon/sniperrifle/projectile 0.01 default 4000 1 0.1 60 0 -projgrenadelauncher Grenade Launcher Grenade projectile weapon/grenadelauncher/projectile 0.5 default 100 1 0.1 60 2 -projrocketlauncher Rocket Launcher Rocket projectile weapon/rocketlauncher/projectile 1 default 100 5000 1000 1 0.1 60 0 -projplasmacannon Plasma Cannon Ball projectile weapon/plasmacannon/projectile 0.005 default 400 1 0.1 10 0 -projtankrailgun Railgun Bolt projectile weapon/tankrailgun/projectile 0.5 default 4000 1 0.1 60 0 -projturretrailgun Railgun Bolt projectile weapon/turretrailgun/projectile 0.1 default 4000 1 0.1 60 0 -projturretvulcan Vulcan Turret Bullet projectile weapon/turretvulcan/projectile 0.01 default 1000 1 0.1 60 0 -projturretartillery Artillery Cannon Shell projectile weapon/turretartillery/projectile 5 default 300 1 0.01 60 2 -expprojhandgrenade Hand Grenade Explosion explosion weapon/handgrenade/projectileexplosion 400 100 400 10 2 30 -expprojpistol Pistol Bullet Impact explosion weapon/pistol/projectileexplosion 50 30 0.1 0.01 0 0 -expprojmachinegun Machinegun Bullet Impact explosion weapon/machinegun/projectileexplosion 30 15 0.05 0.01 0 0 -expprojshotgun Shotgun Flechette Impact explosion weapon/shotgun/projectileexplosion 20 20 0.05 0.01 0 0 -expprojminigun Minigun Bullet Impact explosion weapon/minigun/projectileexplosion 30 15 0.05 0.01 0 0 -expprojsniperrifle Sniper Rifle Flechette Impact explosion weapon/sniperrifle/projectileexplosion 150 150 0.05 0.01 0 0 -expprojgrenadelauncher Grenade Launcher Grenade Explosion explosion weapon/grenadelauncher/projectileexplosion 300 100 300 10 2 30 -expprojrocketlauncher Rocket Launcher Rocket Explosion explosion weapon/rocketlauncher/projectileexplosion 300 100 300 10 2 30 -expprojplasmacannon Plasma Cannon Shell Explosion explosion weapon/plasmacannon/projectileexplosion 150 400 10 2 0 0 -expprojtankrailgun Railgun Bolt Impact explosion weapon/tankrailgun/projectileexplosion 200 900 50 0.5 1 10 -expprojturretrailgun Railgun Bolt Impact explosion weapon/turretrailgun/projectileexplosion 200 900 50 0.5 1 10 -expprojturretvulcan Vulcan Turret Bullet Impact explosion weapon/turretvulcan/projectileexplosion 20 30 1 0.01 0 0 -expprojturretartillery Artillery Cannon Shell Explosion explosion weapon/turretartillery/projectileexplosion 200 400 200 10 2 30 +infantry Infantry infantry models/infantry/infantry.md5mesh 90 200 10 itemmachinegun weapon itempistol pistol itemhandgrenade grenade1 itemhandgrenade grenade2 itemhandgrenade grenade3 infantry 0.3 4 5 10 2 10 20 0.02 0.1 0 +infscout Scout infantry models/infantry/scout.md5mesh 90 200 10 itemsniperrifle weapon itempistol pistol itemhandgrenade grenade1 itemhandgrenade grenade2 itemhandgrenade grenade3 infantry 0.3 4 5 10 2 10 20 0.02 0.1 0 TRUE +infhellion Hellion infantry models/infantry/hellion.md5mesh 90 200 10 itemmachinegun weapon itempistol pistol itemhandgrenade grenade1 itemhandgrenade grenade2 itemhandgrenade grenade3 infantry 0.3 8 6 10 2 10 20 1 0.03 1 TRUE +infmarauder Marauder infantry models/infantry/marauder.md5mesh 200 1000 40 itemminigun weapon itempistol pistol itemhandgrenade grenade1 itemhandgrenade grenade2 itemhandgrenade grenade3 itemhandgrenade grenade4 itemhandgrenade grenade5 infantry 0.3 6 5 10 2 10 20 0.2 0.03 0 TRUE +infgranite Granite infantry models/infantry/granite.md5mesh 400 2000 80 itemplasmacannon weapon infantry 0.3 12 4 10 2 10 20 0.01 0.03 0 TRUE +vehapc APC vehicle_apc models/vehicle/apc.md5mesh 3000 2000 50 weapon hover 0 0 0.2 1 20 0 0.01 5 20 0.5 +vehtankrailgun Railgun Hover Tank vehicle_tank models/vehicle/tankrailgun.md5mesh 3000 2000 50 weapontankrailgun weapon hover 0 0 0.2 1 20 0 0.01 5 20 0.5 +vehdropship Drop Ship vehicle_dropship models/vehicle/dropship.md5mesh 2000 2000 50 weapon vtol 0 0 0.5 2 40 1 0.01 5 +turretrailgun Railgun Turret vehicle_turret models/vehicle/turretrail.md5mesh 1000 3000 150 weaponturretrailgun weapon default +turretvulcan Vulcan Turret vehicle_turret models/vehicle/turretvulcan.md5mesh 1000 3000 150 weaponturretvulcan weapon default +turretartillery Artillery Turret vehicle_turret models/vehicle/turretartillery.md5mesh 1000 3000 150 weaponturretartillery weapon default +spawninfantry Infantry Spawn Pad spawnpad models/infantry/spawnpad.md5mesh 500 500 25 TRUE 1 infantry spawn +spawninfscout Scout Spawn Pad spawnpad models/infantry/spawnpad.md5mesh 2000 1000 50 TRUE 10 infscout spawn +spawninfhellion Hellion Spawn Pad spawnpad models/infantry/spawnpad.md5mesh 2000 1000 50 TRUE 10 infhellion spawn +spawninfmarauder Marauder Spawn Pad spawnpad models/infantry/spawnpad.md5mesh 2000 1000 50 TRUE 10 infmarauder spawn +spawninfgranite Granite Spawn Pad spawnpad models/infantry/spawnpad.md5mesh 2000 1000 50 TRUE 10 infgranite spawn +spawnvehapc APC Spawn Pad vehiclepad models/vehicle/spawnpad.md5mesh 10000 2000 100 TRUE 50 vehapc spawn +spawnvehtankrailgun Railgun Hover Tank Spawn Pad vehiclepad models/vehicle/spawnpad.md5mesh 10000 2000 100 TRUE 50 vehtankrailgun spawn +spawnvehdropship Drop Ship Spawn Pad vehiclepad models/vehicle/spawnpad.md5mesh 10000 2000 100 TRUE 50 vehdropship spawn +spawnturretrailgun Railgun Turret Spawn Pad vehiclepad models/vehicle/spawnpad.md5mesh 10000 2000 100 TRUE 50 turretrailgun spawn +spawnturretvulcan Vulcan Turret Spawn Pad vehiclepad models/vehicle/spawnpad.md5mesh 10000 2000 100 TRUE 50 turretvulcan spawn +spawnturretartillery Artillery Turret Spawn Pad vehiclepad models/vehicle/spawnpad.md5mesh 10000 2000 100 TRUE 50 turretartillery spawn +itemhandgrenade Hand Grenade item models/weapon/handgrenade/body.md5mesh 0.2 projhandgrenade 1 0.1 0.5 0.5 +itempistol Pistol item models/weapon/pistol/body.md5mesh 1 60 projpistol 1 0.01 0.2 0.5 +itemmachinegun Machinegun item models/weapon/machinegun/body.md5mesh 5 400 projmachinegun 1 0.01 0.06 0.13 +itemshotgun Flechette Shotgun item models/weapon/shotgun/body.md5mesh 5 50 projshotgun 8 0.03 0.2 0.5 +itemminigun Minigun item models/weapon/minigun/body.md5mesh 20 1200 projminigun 1 0.02 0.05 0.05 +itemsniperrifle Sniper Rifle item models/weapon/sniperrifle/body.md5mesh 4 25 projsniperrifle 1 0.0001 0.5 1 +itemgrenadelauncher Grenade Launcher item models/weapon/grenadelauncher/body.md5mesh 3 50 projgrenadelauncher 1 0.02 0.5 0.5 +itemrocketlauncher Rocket Launcher item models/weapon/rocketlauncher/body.md5mesh 10 20 projrocketlauncher 1 0.001 0.3 0.3 +itemplasmacannon Plasma Cannon item models/weapon/plasmacannon/body.md5mesh 50 30 10 projplasmacannon 1 0.01 1 1 +weapontankrailgun Railgun weapon models/weapon/tankrailgun/body.md5mesh 50 10 2 projtankrailgun 1 0.0001 1 1 +weaponturretrailgun Railgun weapon models/weapon/turretrailgun/body.md5mesh 50 2 1 projturretrailgun 1 0.01 1 1 +weaponturretvulcan Vulcan Cannon weapon models/weapon/turretvulcan/body.md5mesh 200 20 20 projturretvulcan 1 0.03 0.06 0.06 +weaponturretartillery Artillery Cannon weapon models/weapon/turretartillery/body.md5mesh 200 1 0.2 projturretartillery 1 0.01 5 5 +projhandgrenade Live Hand Grenade projectile models/weapon/handgrenade/projectile.md5mesh 0.2 default 10 1 0.1 3 4 +projpistol Pistol Bullet projectile models/weapon/pistol/projectile.md5mesh 0.01 default 1300 1 0.1 60 0 +projmachinegun Machinegun Bullet projectile models/weapon/machinegun/projectile.md5mesh 0.005 default 800 1 0.1 60 0 +projshotgun Shotgun Flechette projectile models/weapon/shotgun/projectile.md5mesh 0.02 default 1100 1 0.1 60 0 +projminigun Minigun Bullet projectile models/weapon/minigun/projectile.md5mesh 0.01 default 800 1 0.1 60 0 +projsniperrifle Sniper Rifle Flechette projectile models/weapon/sniperrifle/projectile.md5mesh 0.01 default 4000 1 0.1 60 0 +projgrenadelauncher Grenade Launcher Grenade projectile models/weapon/grenadelauncher/projectile.md5mesh 0.5 default 100 1 0.1 60 2 +projrocketlauncher Rocket Launcher Rocket projectile models/weapon/rocketlauncher/projectile.md5mesh 1 default 100 5000 1000 1 0.1 60 0 +projplasmacannon Plasma Cannon Ball projectile models/weapon/plasmacannon/projectile.md5mesh 0.005 default 400 1 0.1 10 0 +projtankrailgun Railgun Bolt projectile models/weapon/tankrailgun/projectile.md5mesh 0.5 default 4000 1 0.1 60 0 +projturretrailgun Railgun Bolt projectile models/weapon/turretrailgun/projectile.md5mesh 0.1 default 4000 1 0.1 60 0 +projturretvulcan Vulcan Turret Bullet projectile models/weapon/turretvulcan/projectile.md5mesh 0.01 default 1000 1 0.1 60 0 +projturretartillery Artillery Cannon Shell projectile models/weapon/turretartillery/projectile.md5mesh 5 default 300 1 0.01 60 2 +expprojhandgrenade Hand Grenade Explosion explosion models/weapon/handgrenade/projectileexplosion.md5mesh 400 100 400 10 2 30 +expprojpistol Pistol Bullet Impact explosion models/weapon/pistol/projectileexplosion.md5mesh 50 30 0.1 0.01 0 0 +expprojmachinegun Machinegun Bullet Impact explosion models/weapon/machinegun/projectileexplosion.md5mesh 30 15 0.05 0.01 0 0 +expprojshotgun Shotgun Flechette Impact explosion models/weapon/shotgun/projectileexplosion.md5mesh 20 20 0.05 0.01 0 0 +expprojminigun Minigun Bullet Impact explosion models/weapon/minigun/projectileexplosion.md5mesh 30 15 0.05 0.01 0 0 +expprojsniperrifle Sniper Rifle Flechette Impact explosion models/weapon/sniperrifle/projectileexplosion.md5mesh 150 150 0.05 0.01 0 0 +expprojgrenadelauncher Grenade Launcher Grenade Explosion explosion models/weapon/grenadelauncher/projectileexplosion.md5mesh 300 100 300 10 2 30 +expprojrocketlauncher Rocket Launcher Rocket Explosion explosion models/weapon/rocketlauncher/projectileexplosion.md5mesh 300 100 300 10 2 30 +expprojplasmacannon Plasma Cannon Shell Explosion explosion models/weapon/plasmacannon/projectileexplosion.md5mesh 150 400 10 2 0 0 +expprojtankrailgun Railgun Bolt Impact explosion models/weapon/tankrailgun/projectileexplosion.md5mesh 200 900 50 0.5 1 10 +expprojturretrailgun Railgun Bolt Impact explosion models/weapon/turretrailgun/projectileexplosion.md5mesh 200 900 50 0.5 1 10 +expprojturretvulcan Vulcan Turret Bullet Impact explosion models/weapon/turretvulcan/projectileexplosion.md5mesh 20 30 1 0.01 0 0 +expprojturretartillery Artillery Cannon Shell Explosion explosion models/weapon/turretartillery/projectileexplosion.md5mesh 200 400 200 10 2 30 Modified: trunk/base/maps/test.ent =================================================================== --- trunk/base/maps/test.ent 2006-04-08 00:48:06 UTC (rev 690) +++ trunk/base/maps/test.ent 2006-04-08 02:42:27 UTC (rev 691) @@ -4,7 +4,7 @@ "model" "maps/test/skybox.md5mesh" } { - "origin" "1 -29 13" + "origin" "0 -40 6.5" "classname" "spawninfantry" } { Added: trunk/base/models/infantry/spawnpad.md5mesh =================================================================== --- trunk/base/models/infantry/spawnpad.md5mesh 2006-04-08 00:48:06 UTC (rev 690) +++ trunk/base/models/infantry/spawnpad.md5mesh 2006-04-08 02:42:27 UTC (rev 691) @@ -0,0 +1,601 @@ +MD5Version 10 +commandline "" + +numJoints 1 +numMeshes 1 + +joints { + "ROOT" -1 ( 0.000000 0.000000 0.000000 ) ( 0.000000 0.000000 0.000000 ) // +} + +mesh { + shader "models/infantry/spawnpad" + + numverts 188 + vert 0 ( 0.662824 -0.543168 ) 0 1 + vert 1 ( 0.650430 -0.605478 ) 1 1 + vert 2 ( 0.650430 -0.480858 ) 2 1 + vert 3 ( 0.615134 -0.428034 ) 3 1 + vert 4 ( 0.615134 -0.658302 ) 4 1 + vert 5 ( 0.562310 -0.392738 ) 5 1 + vert 6 ( 0.562310 -0.693598 ) 6 1 + vert 7 ( 0.500000 -0.380344 ) 7 1 + vert 8 ( 0.437690 -0.392738 ) 8 1 + vert 9 ( 0.384866 -0.428034 ) 9 1 + vert 10 ( 0.349570 -0.480858 ) 10 1 + vert 11 ( 0.337176 -0.543168 ) 11 1 + vert 12 ( 0.500000 -0.705992 ) 12 1 + vert 13 ( 0.349570 -0.605478 ) 13 1 + vert 14 ( 0.384866 -0.658302 ) 14 1 + vert 15 ( 0.437690 -0.693598 ) 15 1 + vert 16 ( 0.129426 -0.080538 ) 16 1 + vert 17 ( 0.005874 -0.080538 ) 17 1 + vert 18 ( 0.005874 -0.014703 ) 18 1 + vert 19 ( 0.129426 -0.014703 ) 19 1 + vert 20 ( 0.995874 -0.014703 ) 20 1 + vert 21 ( 0.872322 -0.080538 ) 21 1 + vert 22 ( 0.872322 -0.014703 ) 22 1 + vert 23 ( 0.995874 -0.080538 ) 23 1 + vert 24 ( 0.748770 -0.080538 ) 24 1 + vert 25 ( 0.748770 -0.014703 ) 25 1 + vert 26 ( 0.625218 -0.080538 ) 26 1 + vert 27 ( 0.625218 -0.014703 ) 27 1 + vert 28 ( 0.501666 -0.080538 ) 28 1 + vert 29 ( 0.501666 -0.014703 ) 29 1 + vert 30 ( 0.378114 -0.080538 ) 30 1 + vert 31 ( 0.378114 -0.014703 ) 31 1 + vert 32 ( 0.254562 -0.014703 ) 32 1 + vert 33 ( 0.254562 -0.080538 ) 33 1 + vert 34 ( 0.131010 -0.080538 ) 34 1 + vert 35 ( 0.131010 -0.014703 ) 35 1 + vert 36 ( 0.007458 -0.014703 ) 36 1 + vert 37 ( 0.007458 -0.080538 ) 37 1 + vert 38 ( 0.870738 -0.080538 ) 38 1 + vert 39 ( 0.870738 -0.014703 ) 39 1 + vert 40 ( 0.994290 -0.014703 ) 40 1 + vert 41 ( 0.994290 -0.080538 ) 41 1 + vert 42 ( 0.747186 -0.014703 ) 42 1 + vert 43 ( 0.747186 -0.080538 ) 43 1 + vert 44 ( 0.623634 -0.080538 ) 44 1 + vert 45 ( 0.623634 -0.014703 ) 45 1 + vert 46 ( 0.500082 -0.014703 ) 46 1 + vert 47 ( 0.500082 -0.080538 ) 47 1 + vert 48 ( 0.376530 -0.080538 ) 48 1 + vert 49 ( 0.376530 -0.014703 ) 49 1 + vert 50 ( 0.252978 -0.080538 ) 50 1 + vert 51 ( 0.252978 -0.014703 ) 51 1 + vert 52 ( 0.907847 -0.712536 ) 52 1 + vert 53 ( 0.699371 -0.626182 ) 53 1 + vert 54 ( 0.715798 -0.543600 ) 54 1 + vert 55 ( 0.941450 -0.543600 ) 55 1 + vert 56 ( 0.699371 -0.461018 ) 56 1 + vert 57 ( 0.907847 -0.374664 ) 57 1 + vert 58 ( 0.652592 -0.391008 ) 58 1 + vert 59 ( 0.812152 -0.231448 ) 59 1 + vert 60 ( 0.582582 -0.344229 ) 60 1 + vert 61 ( 0.668936 -0.135753 ) 61 1 + vert 62 ( 0.500000 -0.327802 ) 62 1 + vert 63 ( 0.500000 -0.102150 ) 63 1 + vert 64 ( 0.331064 -0.135753 ) 64 1 + vert 65 ( 0.417418 -0.344229 ) 65 1 + vert 66 ( 0.187848 -0.231448 ) 66 1 + vert 67 ( 0.347408 -0.391008 ) 67 1 + vert 68 ( 0.300629 -0.461018 ) 68 1 + vert 69 ( 0.092153 -0.374664 ) 69 1 + vert 70 ( 0.284202 -0.543600 ) 70 1 + vert 71 ( 0.058550 -0.543600 ) 71 1 + vert 72 ( 0.092153 -0.712536 ) 72 1 + vert 73 ( 0.300629 -0.626182 ) 73 1 + vert 74 ( 0.187848 -0.855752 ) 74 1 + vert 75 ( 0.347408 -0.696192 ) 75 1 + vert 76 ( 0.417418 -0.742971 ) 76 1 + vert 77 ( 0.331064 -0.951447 ) 77 1 + vert 78 ( 0.500000 -0.759398 ) 78 1 + vert 79 ( 0.500000 -0.985050 ) 79 1 + vert 80 ( 0.668936 -0.951447 ) 80 1 + vert 81 ( 0.582582 -0.742971 ) 81 1 + vert 82 ( 0.812152 -0.855752 ) 82 1 + vert 83 ( 0.652592 -0.696192 ) 83 1 + vert 84 ( 0.130153 -0.015640 ) 84 1 + vert 85 ( 0.006226 -0.081240 ) 85 1 + vert 86 ( 0.006226 -0.015640 ) 86 1 + vert 87 ( 0.130153 -0.081240 ) 87 1 + vert 88 ( 0.254080 -0.015640 ) 88 1 + vert 89 ( 0.254080 -0.081240 ) 89 1 + vert 90 ( 0.378007 -0.015640 ) 90 1 + vert 91 ( 0.378007 -0.081240 ) 91 1 + vert 92 ( 0.501935 -0.015640 ) 92 1 + vert 93 ( 0.501935 -0.081240 ) 93 1 + vert 94 ( 0.625862 -0.081240 ) 94 1 + vert 95 ( 0.625862 -0.015640 ) 95 1 + vert 96 ( 0.749789 -0.081240 ) 96 1 + vert 97 ( 0.749789 -0.015640 ) 97 1 + vert 98 ( 0.873716 -0.081240 ) 98 1 + vert 99 ( 0.873716 -0.015640 ) 99 1 + vert 100 ( 0.997644 -0.081240 ) 100 1 + vert 101 ( 0.997644 -0.015640 ) 101 1 + vert 102 ( 0.130153 -0.081240 ) 102 1 + vert 103 ( 0.006226 -0.015640 ) 103 1 + vert 104 ( 0.130153 -0.015640 ) 104 1 + vert 105 ( 0.006226 -0.081240 ) 105 1 + vert 106 ( 0.254080 -0.081240 ) 106 1 + vert 107 ( 0.254080 -0.015640 ) 107 1 + vert 108 ( 0.378007 -0.081240 ) 108 1 + vert 109 ( 0.378007 -0.015640 ) 109 1 + vert 110 ( 0.501935 -0.081240 ) 110 1 + vert 111 ( 0.501935 -0.015640 ) 111 1 + vert 112 ( 0.625862 -0.015640 ) 112 1 + vert 113 ( 0.625862 -0.081240 ) 113 1 + vert 114 ( 0.749789 -0.015640 ) 114 1 + vert 115 ( 0.749789 -0.081240 ) 115 1 + vert 116 ( 0.873716 -0.015640 ) 116 1 + vert 117 ( 0.873716 -0.081240 ) 117 1 + vert 118 ( 0.997644 -0.015640 ) 118 1 + vert 119 ( 0.997644 -0.081240 ) 119 1 + vert 120 ( 0.914943 -0.715748 ) 120 1 + vert 121 ( 0.886864 -0.704117 ) 121 1 + vert 122 ( 0.918586 -0.544642 ) 122 1 + vert 123 ( 0.948978 -0.544642 ) 123 1 + vert 124 ( 0.886864 -0.385167 ) 124 1 + vert 125 ( 0.914943 -0.373537 ) 125 1 + vert 126 ( 0.796529 -0.249971 ) 126 1 + vert 127 ( 0.818019 -0.228481 ) 127 1 + vert 128 ( 0.661332 -0.159636 ) 128 1 + vert 129 ( 0.672963 -0.131557 ) 129 1 + vert 130 ( 0.501858 -0.127914 ) 130 1 + vert 131 ( 0.501858 -0.097522 ) 131 1 + vert 132 ( 0.330752 -0.131557 ) 132 1 + vert 133 ( 0.342383 -0.159636 ) 133 1 + vert 134 ( 0.207186 -0.249971 ) 134 1 + vert 135 ( 0.185696 -0.228481 ) 135 1 + vert 136 ( 0.088773 -0.373537 ) 136 1 + vert 137 ( 0.116851 -0.385167 ) 137 1 + vert 138 ( 0.085130 -0.544642 ) 138 1 + vert 139 ( 0.054738 -0.544642 ) 139 1 + vert 140 ( 0.088773 -0.715748 ) 140 1 + vert 141 ( 0.116851 -0.704117 ) 141 1 + vert 142 ( 0.207186 -0.839314 ) 142 1 + vert 143 ( 0.185696 -0.860804 ) 143 1 + vert 144 ( 0.330752 -0.957727 ) 144 1 + vert 145 ( 0.342383 -0.929649 ) 145 1 + vert 146 ( 0.501858 -0.961370 ) 146 1 + vert 147 ( 0.501858 -0.991762 ) 147 1 + vert 148 ( 0.672963 -0.957727 ) 148 1 + vert 149 ( 0.661332 -0.929649 ) 149 1 + vert 150 ( 0.796529 -0.839314 ) 150 1 + vert 151 ( 0.818019 -0.860804 ) 151 1 + vert 152 ( 0.008754 -0.076200 ) 152 1 + vert 153 ( 0.131398 -0.016200 ) 153 1 + vert 154 ( 0.008754 -0.016200 ) 154 1 + vert 155 ( 0.131398 -0.076200 ) 155 1 + vert 156 ( 0.866110 -0.076200 ) 156 1 + vert 157 ( 0.988754 -0.016200 ) 157 1 + vert 158 ( 0.866110 -0.016200 ) 158 1 + vert 159 ( 0.988754 -0.076200 ) 159 1 + vert 160 ( 0.743467 -0.076200 ) 160 1 + vert 161 ( 0.743467 -0.016200 ) 161 1 + vert 162 ( 0.620823 -0.076200 ) 162 1 + vert 163 ( 0.620823 -0.016200 ) 163 1 + vert 164 ( 0.498179 -0.076200 ) 164 1 + vert 165 ( 0.498179 -0.016200 ) 165 1 + vert 166 ( 0.375535 -0.016200 ) 166 1 + vert 167 ( 0.375535 -0.076200 ) 167 1 + vert 168 ( 0.252891 -0.016200 ) 168 1 + vert 169 ( 0.252891 -0.076200 ) 169 1 + vert 170 ( 0.130248 -0.016200 ) 170 1 + vert 171 ( 0.130248 -0.076200 ) 171 1 + vert 172 ( 0.007604 -0.016200 ) 172 1 + vert 173 ( 0.007604 -0.076200 ) 173 1 + vert 174 ( 0.867260 -0.016200 ) 174 1 + vert 175 ( 0.989904 -0.076200 ) 175 1 + vert 176 ( 0.989904 -0.016200 ) 176 1 + vert 177 ( 0.867260 -0.076200 ) 177 1 + vert 178 ( 0.744616 -0.016200 ) 178 1 + vert 179 ( 0.744616 -0.076200 ) 179 1 + vert 180 ( 0.621973 -0.016200 ) 180 1 + vert 181 ( 0.621973 -0.076200 ) 181 1 + vert 182 ( 0.499329 -0.016200 ) 182 1 + vert 183 ( 0.499329 -0.076200 ) 183 1 + vert 184 ( 0.376685 -0.076200 ) 184 1 + vert 185 ( 0.376685 -0.016200 ) 185 1 + vert 186 ( 0.254041 -0.076200 ) 186 1 + vert 187 ( 0.254041 -0.016200 ) 187 1 + + numtris 206 + tri 0 0 1 2 + tri 1 2 1 3 + tri 2 1 4 3 + tri 3 3 4 5 + tri 4 4 6 5 + tri 5 5 6 7 + tri 6 6 8 7 + tri 7 6 9 8 + tri 8 6 10 9 + tri 9 6 11 10 + tri 10 6 12 11 + tri 11 12 13 11 + tri 12 12 14 13 + tri 13 12 15 14 + tri 14 16 17 18 + tri 15 19 16 18 + tri 16 20 21 22 + tri 17 23 21 20 + tri 18 21 24 25 + tri 19 22 21 25 + tri 20 25 26 27 + tri 21 24 26 25 + tri 22 26 28 29 + tri 23 27 26 29 + tri 24 30 31 29 + tri 25 28 30 29 + tri 26 30 32 31 + tri 27 30 33 32 + tri 28 34 35 32 + tri 29 33 34 32 + tri 30 34 36 35 + tri 31 34 37 36 + tri 32 38 39 40 + tri 33 41 38 40 + tri 34 38 42 39 + tri 35 38 43 42 + tri 36 44 45 42 + tri 37 43 44 42 + tri 38 44 46 45 + tri 39 44 47 46 + tri 40 46 48 49 + tri 41 47 48 46 + tri 42 48 50 51 + tri 43 49 48 51 + tri 44 51 16 19 + tri 45 50 16 51 + tri 46 52 53 54 + tri 47 55 52 54 + tri 48 54 56 57 + tri 49 55 54 57 + tri 50 56 58 59 + tri 51 57 56 59 + tri 52 59 60 61 + tri 53 58 60 59 + tri 54 61 62 63 + tri 55 60 62 61 + tri 56 62 64 63 + tri 57 62 65 64 + tri 58 65 66 64 + tri 59 65 67 66 + tri 60 68 69 66 + tri 61 67 68 66 + tri 62 70 71 69 + tri 63 68 70 69 + tri 64 72 71 70 + tri 65 73 72 70 + tri 66 74 72 73 + tri 67 75 74 73 + tri 68 76 74 75 + tri 69 77 74 76 + tri 70 78 77 76 + tri 71 79 77 78 + tri 72 80 78 81 + tri 73 80 79 78 + tri 74 82 81 83 + tri 75 82 80 81 + tri 76 82 83 53 + tri 77 52 82 53 + tri 78 53 1 0 + tri 79 54 53 0 + tri 80 56 0 2 + tri 81 56 54 0 + tri 82 58 2 3 + tri 83 58 56 2 + tri 84 58 3 5 + tri 85 60 58 5 + tri 86 60 5 7 + tri 87 62 60 7 + tri 88 65 62 7 + tri 89 8 65 7 + tri 90 67 65 8 + tri 91 9 67 8 + tri 92 10 67 9 + tri 93 68 67 10 + tri 94 11 68 10 + tri 95 70 68 11 + tri 96 73 70 11 + tri 97 13 73 11 + tri 98 75 73 13 + tri 99 14 75 13 + tri 100 15 75 14 + tri 101 76 75 15 + tri 102 12 76 15 + tri 103 78 76 12 + tri 104 81 12 6 + tri 105 81 78 12 + tri 106 83 6 4 + tri 107 83 81 6 + tri 108 83 4 1 + tri 109 53 83 1 + tri 110 84 85 86 + tri 111 87 85 84 + tri 112 88 87 84 + tri 113 89 87 88 + tri 114 90 89 88 + tri 115 91 89 90 + tri 116 92 91 90 + tri 117 93 91 92 + tri 118 94 92 95 + tri 119 94 93 92 + tri 120 96 95 97 + tri 121 96 94 95 + tri 122 98 97 99 + tri 123 98 96 97 + tri 124 100 99 101 + tri 125 100 98 99 + tri 126 102 103 104 + tri 127 102 105 103 + tri 128 106 104 107 + tri 129 106 102 104 + tri 130 108 107 109 + tri 131 108 106 107 + tri 132 110 109 111 + tri 133 110 108 109 + tri 134 112 110 111 + tri 135 113 110 112 + tri 136 114 113 112 + tri 137 115 113 114 + tri 138 116 115 114 + tri 139 117 115 116 + tri 140 118 117 116 + tri 141 119 117 118 + tri 142 120 121 122 + tri 143 123 120 122 + tri 144 122 124 125 + tri 145 123 122 125 + tri 146 125 126 127 + tri 147 125 124 126 + tri 148 126 128 129 + tri 149 127 126 129 + tri 150 129 130 131 + tri 151 129 128 130 + tri 152 130 132 131 + tri 153 133 132 130 + tri 154 134 135 132 + tri 155 133 134 132 + tri 156 134 136 135 + tri 157 137 136 134 + tri 158 138 139 136 + tri 159 137 138 136 + tri 160 140 139 138 + tri 161 141 140 138 + tri 162 142 140 141 + tri 163 142 143 140 + tri 164 144 143 142 + tri 165 145 144 142 + tri 166 146 144 145 + tri 167 146 147 144 + tri 168 148 146 149 + tri 169 147 146 148 + tri 170 148 149 150 + tri 171 151 148 150 + tri 172 120 150 121 + tri 173 151 150 120 + tri 174 152 153 154 + tri 175 152 155 153 + tri 176 156 157 158 + tri 177 156 159 157 + tri 178 160 158 161 + tri 179 160 156 158 + tri 180 162 161 163 + tri 181 162 160 161 + tri 182 164 163 165 + tri 183 164 162 163 + tri 184 166 164 165 + tri 185 167 164 166 + tri 186 168 167 166 + tri 187 169 167 168 + tri 188 170 169 168 + tri 189 171 169 170 + tri 190 172 171 170 + tri 191 173 171 172 + tri 192 174 175 176 + tri 193 177 175 174 + tri 194 178 177 174 + tri 195 179 177 178 + tri 196 180 179 178 + tri 197 181 179 180 + tri 198 182 181 180 + tri 199 183 181 182 + tri 200 184 182 185 + tri 201 184 183 182 + tri 202 186 185 187 + tri 203 186 184 185 + tri 204 155 187 153 + tri 205 155 186 187 + + numweights 188 + weight 0 0 1.000000 ( 0.183927 0.000000 0.040000 ) + weight 1 0 1.000000 ( 0.169926 -0.070386 0.040000 ) + weight 2 0 1.000000 ( 0.169926 0.070386 0.040000 ) + weight 3 0 1.000000 ( 0.130056 0.130056 0.040000 ) + weight 4 0 1.000000 ( 0.130056 -0.130056 0.040000 ) + weight 5 0 1.000000 ( 0.070386 0.169926 0.040000 ) + weight 6 0 1.000000 ( 0.070386 -0.169926 0.040000 ) + weight 7 0 1.000000 ( 0.000000 0.183927 0.040000 ) + weight 8 0 1.000000 ( -0.070386 0.169926 0.040000 ) + weight 9 0 1.000000 ( -0.130056 0.130056 0.040000 ) + weight 10 0 1.000000 ( -0.169926 0.070386 0.040000 ) + weight 11 0 1.000000 ( -0.183927 0.000000 0.040000 ) + weight 12 0 1.000000 ( 0.000000 -0.183927 0.040000 ) + weight 13 0 1.000000 ( -0.169926 -0.070386 0.040000 ) + weight 14 0 1.000000 ( -0.130056 -0.130056 0.040000 ) + weight 15 0 1.000000 ( -0.070386 -0.169926 0.040000 ) + weight 16 0 1.000000 ( 0.405421 -0.167931 0.070000 ) + weight 17 0 1.000000 ( 0.438825 0.000000 0.070000 ) + weight 18 0 1.000000 ( 0.500000 0.000000 0.000000 ) + weight 19 0 1.000000 ( 0.461940 -0.191342 0.000000 ) + weight 20 0 1.000000 ( 0.500000 0.000000 0.000000 ) + weight 21 0 1.000000 ( 0.405421 0.167931 0.070000 ) + weight 22 0 1.000000 ( 0.461940 0.191342 0.000000 ) + weight 23 0 1.000000 ( 0.438825 0.000000 0.070000 ) + weight 24 0 1.000000 ( 0.310296 0.310296 0.070000 ) + weight 25 0 1.000000 ( 0.353553 0.353553 0.000000 ) + weight 26 0 1.000000 ( 0.167931 0.405421 0.070000 ) + weight 27 0 1.000000 ( 0.191342 0.461940 0.000000 ) + weight 28 0 1.000000 ( 0.000000 0.438825 0.070000 ) + weight 29 0 1.000000 ( 0.000000 0.500000 0.000000 ) + weight 30 0 1.000000 ( -0.167931 0.405421 0.070000 ) + weight 31 0 1.000000 ( -0.191342 0.461940 0.000000 ) + weight 32 0 1.000000 ( -0.353553 0.353553 0.000000 ) + weight 33 0 1.000000 ( -0.310296 0.310296 0.070000 ) + weight 34 0 1.000000 ( -0.405421 0.167931 0.070000 ) + weight 35 0 1.000000 ( -0.461940 0.191342 0.000000 ) + weight 36 0 1.000000 ( -0.500000 0.000000 0.000000 ) + weight 37 0 1.000000 ( -0.438825 0.000000 0.070000 ) + weight 38 0 1.000000 ( -0.405421 -0.167931 0.070000 ) + weight 39 0 1.000000 ( -0.461940 -0.191342 0.000000 ) + weight 40 0 1.000000 ( -0.500000 0.000000 0.000000 ) + weight 41 0 1.000000 ( -0.438825 0.000000 0.070000 ) + weight 42 0 1.000000 ( -0.353553 -0.353553 0.000000 ) + weight 43 0 1.000000 ( -0.310296 -0.310296 0.070000 ) + weight 44 0 1.000000 ( -0.167931 -0.405421 0.070000 ) + weight 45 0 1.000000 ( -0.191342 -0.461940 0.000000 ) + weight 46 0 1.000000 ( 0.000000 -0.500000 0.000000 ) + weight 47 0 1.000000 ( 0.000000 -0.438825 0.070000 ) + weight 48 0 1.000000 ( 0.167931 -0.405421 0.070000 ) + weight 49 0 1.000000 ( 0.191342 -0.461940 0.000000 ) + weight 50 0 1.000000 ( 0.310296 -0.310296 0.070000 ) + weight 51 0 1.000000 ( 0.353553 -0.353553 0.000000 ) + weight 52 0 1.000000 ( 0.405421 -0.167931 0.070000 ) + weight 53 0 1.000000 ( 0.198186 -0.082091 0.070000 ) + weight 54 0 1.000000 ( 0.214514 0.000000 0.070000 ) + weight 55 0 1.000000 ( 0.438825 0.000000 0.070000 ) + weight 56 0 1.000000 ( 0.198186 0.082091 0.070000 ) + weight 57 0 1.000000 ( 0.405421 0.167931 0.070000 ) + weight 58 0 1.000000 ( 0.151685 0.151685 0.070000 ) + weight 59 0 1.000000 ( 0.310296 0.310296 0.070000 ) + weight 60 0 1.000000 ( 0.082091 0.198186 0.070000 ) + weight 61 0 1.000000 ( 0.167931 0.405421 0.070000 ) + weight 62 0 1.000000 ( 0.000000 0.214514 0.070000 ) + weight 63 0 1.000000 ( 0.000000 0.438825 0.070000 ) + weight 64 0 1.000000 ( -0.167931 0.405421 0.070000 ) + weight 65 0 1.000000 ( -0.082091 0.198186 0.070000 ) + weight 66 0 1.000000 ( -0.310296 0.310296 0.070000 ) + weight 67 0 1.000000 ( -0.151685 0.151685 0.070000 ) + weight 68 0 1.000000 ( -0.198186 0.082091 0.070000 ) + weight 69 0 1.000000 ( -0.405421 0.167931 0.070000 ) + weight 70 0 1.000000 ( -0.214514 0.000000 0.070000 ) + weight 71 0 1.000000 ( -0.438825 0.000000 0.070000 ) + weight 72 0 1.000000 ( -0.405421 -0.167931 0.070000 ) + weight 73 0 1.000000 ( -0.198186 -0.082091 0.070000 ) + weight 74 0 1.000000 ( -0.310296 -0.310296 0.070000 ) + weight 75 0 1.000000 ( -0.151685 -0.151685 0.070000 ) + weight 76 0 1.000000 ( -0.082091 -0.198186 0.070000 ) + weight 77 0 1.000000 ( -0.167931 -0.405421 0.070000 ) + weight 78 0 1.000000 ( 0.000000 -0.214514 0.070000 ) + weight 79 0 1.000000 ( 0.000000 -0.438825 0.070000 ) + weight 80 0 1.000000 ( 0.167931 -0.405421 0.070000 ) + weight 81 0 1.000000 ( 0.082091 -0.198186 0.070000 ) + weight 82 0 1.000000 ( 0.310296 -0.310296 0.070000 ) + weight 83 0 1.000000 ( 0.151685 -0.151685 0.070000 ) + weight 84 0 1.000000 ( 0.554328 -0.229610 0.000000 ) + weight 85 0 1.000000 ( 0.600000 0.000000 0.053051 ) + weight 86 0 1.000000 ( 0.600000 0.000000 0.000000 ) + weight 87 0 1.000000 ( 0.554328 -0.229610 0.053051 ) + weight 88 0 1.000000 ( 0.424264 -0.424264 0.000000 ) + weight 89 0 1.000000 ( 0.424264 -0.424264 0.053051 ) + weight 90 0 1.000000 ( 0.229610 -0.554328 0.000000 ) + weight 91 0 1.000000 ( 0.229610 -0.554328 0.053051 ) + weight 92 0 1.000000 ( 0.000000 -0.600000 0.000000 ) + weight 93 0 1.000000 ( 0.000000 -0.600000 0.053051 ) + weight 94 0 1.000000 ( -0.229610 -0.554328 0.053051 ) + weight 95 0 1.000000 ( -0.229610 -0.554328 0.000000 ) + weight 96 0 1.000000 ( -0.424264 -0.424264 0.053051 ) + weight 97 0 1.000000 ( -0.424264 -0.424264 0.000000 ) + weight 98 0 1.000000 ( -0.554328 -0.229610 0.053051 ) + weight 99 0 1.000000 ( -0.554328 -0.229610 0.000000 ) + weight 100 0 1.000000 ( -0.600000 0.000000 0.053051 ) + weight 101 0 1.000000 ( -0.600000 0.000000 0.000000 ) + weight 102 0 1.000000 ( -0.554328 0.229610 0.053051 ) + weight 103 0 1.000000 ( -0.600000 0.000000 0.000000 ) + weight 104 0 1.000000 ( -0.554328 0.229610 0.000000 ) + weight 105 0 1.000000 ( -0.600000 0.000000 0.053051 ) + weight 106 0 1.000000 ( -0.424264 0.424264 0.053051 ) + weight 107 0 1.000000 ( -0.424264 0.424264 0.000000 ) + weight 108 0 1.000000 ( -0.229610 0.554328 0.053051 ) + weight 109 0 1.000000 ( -0.229610 0.554328 0.000000 ) + weight 110 0 1.000000 ( 0.000000 0.600000 0.053051 ) + weight 111 0 1.000000 ( 0.000000 0.600000 0.000000 ) + weight 112 0 1.000000 ( 0.229610 0.554328 0.000000 ) + weight 113 0 1.000000 ( 0.229610 0.554328 0.053051 ) + weight 114 0 1.000000 ( 0.424264 0.424264 0.000000 ) + weight 115 0 1.000000 ( 0.424264 0.424264 0.053051 ) + weight 116 0 1.000000 ( 0.554328 0.229610 0.000000 ) + weight 117 0 1.000000 ( 0.554328 0.229610 0.053051 ) + weight 118 0 1.000000 ( 0.600000 0.000000 0.000000 ) + weight 119 0 1.000000 ( 0.600000 0.000000 0.053051 ) + weight 120 0 1.000000 ( 0.554328 -0.229610 0.053051 ) + weight 121 0 1.000000 ( 0.516649 -0.214003 0.053051 ) + weight 122 0 1.000000 ( 0.559216 0.000000 0.053051 ) + weight 123 0 1.000000 ( 0.600000 0.000000 0.053051 ) + weight 124 0 1.000000 ( 0.516649 0.214003 0.053051 ) + weight 125 0 1.000000 ( 0.554328 0.229610 0.053051 ) + weight 126 0 1.000000 ( 0.395426 0.395426 0.053051 ) + weight 127 0 1.000000 ( 0.424264 0.424264 0.053051 ) + weight 128 0 1.000000 ( 0.214003 0.516649 0.053051 ) + weight 129 0 1.000000 ( 0.229610 0.554328 0.053051 ) + weight 130 0 1.000000 ( 0.000000 0.559216 0.053051 ) + weight 131 0 1.000000 ( 0.000000 0.600000 0.053051 ) + weight 132 0 1.000000 ( -0.229610 0.554328 0.053051 ) + weight 133 0 1.000000 ( -0.214003 0.516649 0.053051 ) + weight 134 0 1.000000 ( -0.395426 0.395426 0.053051 ) + weight 135 0 1.000000 ( -0.424264 0.424264 0.053051 ) + weight 136 0 1.000000 ( -0.554328 0.229610 0.053051 ) + weight 137 0 1.000000 ( -0.516649 0.214003 0.053051 ) + weight 138 0 1.000000 ( -0.559216 0.000000 0.053051 ) + weight 139 0 1.000000 ( -0.600000 0.000000 0.053051 ) + weight 140 0 1.000000 ( -0.554328 -0.229610 0.053051 ) + weight 141 0 1.000000 ( -0.516649 -0.214003 0.053051 ) + weight 142 0 1.000000 ( -0.395426 -0.395426 0.053051 ) + weight 143 0 1.000000 ( -0.424264 -0.424264 0.053051 ) + weight 144 0 1.000000 ( -0.229610 -0.554328 0.053051 ) + weight 145 0 1.000000 ( -0.214003 -0.516649 0.053051 ) + weight 146 0 1.000000 ( 0.000000 -0.559216 0.053051 ) + weight 147 0 1.000000 ( 0.000000 -0.600000 0.053051 ) + weight 148 0 1.000000 ( 0.229610 -0.554328 0.053051 ) + weight 149 0 1.000000 ( 0.214003 -0.516649 0.053051 ) + weight 150 0 1.000000 ( 0.395426 -0.395426 0.053051 ) + weight 151 0 1.000000 ( 0.424264 -0.424264 0.053051 ) + weight 152 0 1.000000 ( 0.559216 0.000000 0.053051 ) + weight 153 0 1.000000 ( 0.516649 -0.214003 0.000000 ) + weight 154 0 1.000000 ( 0.559216 0.000000 0.000000 ) + weight 155 0 1.000000 ( 0.516649 -0.214003 0.053051 ) + weight 156 0 1.000000 ( 0.516649 0.214003 0.053051 ) + weight 157 0 1.000000 ( 0.559216 0.000000 0.000000 ) + weight 158 0 1.000000 ( 0.516649 0.214003 0.000000 ) + weight 159 0 1.000000 ( 0.559216 0.000000 0.053051 ) + weight 160 0 1.000000 ( 0.395426 0.395426 0.053051 ) + weight 161 0 1.000000 ( 0.395426 0.395426 0.000000 ) + weight 162 0 1.000000 ( 0.214003 0.516649 0.053051 ) + weight 163 0 1.000000 ( 0.214003 0.516649 0.000000 ) + weight 164 0 1.000000 ( 0.000000 0.559216 0.053051 ) + weight 165 0 1.000000 ( 0.000000 0.559216 0.000000 ) + weight 166 0 1.000000 ( -0.214003 0.516649 0.000000 ) + weight 167 0 1.000000 ( -0.214003 0.516649 0.053051 ) + weight 168 0 1.000000 ( -0.395426 0.395426 0.000000 ) + weight 169 0 1.000000 ( -0.395426 0.395426 0.053051 ) + weight 170 0 1.000000 ( -0.516649 0.214003 0.000000 ) + weight 171 0 1.000000 ( -0.516649 0.214003 0.053051 ) + weight 172 0 1.000000 ( -0.559216 0.000000 0.000000 ) + weight 173 0 1.000000 ( -0.559216 0.000000 0.053051 ) + weight 174 0 1.000000 ( -0.516649 -0.214003 0.000000 ) + weight 175 0 1.000000 ( -0.559216 0.000000 0.053051 ) + weight 176 0 1.000000 ( -0.559216 0.000000 0.000000 ) + weight 177 0 1.000000 ( -0.516649 -0.214003 0.053051 ) + weight 178 0 1.000000 ( -0.395426 -0.395426 0.000000 ) + weight 179 0 1.000000 ( -0.395426 -0.395426 0.053051 ) + weight 180 0 1.000000 ( -0.214003 -0.516649 0.000000 ) + weight 181 0 1.000000 ( -0.214003 -0.516649 0.053051 ) + weight 182 0 1.000000 ( 0.000000 -0.559216 0.000000 ) + weight 183 0 1.000000 ( 0.000000 -0.559216 0.053051 ) + weight 184 0 1.000000 ( 0.214003 -0.516649 0.053051 ) + weight 185 0 1.000000 ( 0.214003 -0.516649 0.000000 ) + weight 186 0 1.000000 ( 0.395426 -0.395426 0.053051 ) + weight 187 0 1.000000 ( 0.395426 -0.395426 0.000000 ) +} Added: trunk/base/models/infantry/spawnpad.tga =================================================================== (Binary files differ) Property changes on: trunk/base/models/infantry/spawnpad.tga ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From lordhavoc at icculus.org Sat Apr 8 17:09:02 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 8 Apr 2006 17:09:02 -0400 Subject: r692 - trunk/game Message-ID: <20060408210902.23887.qmail@icculus.org> Author: lordhavoc Date: 2006-04-08 17:09:02 -0400 (Sat, 08 Apr 2006) New Revision: 692 Modified: trunk/game/g_entityclass.c trunk/game/g_world.c Log: renamed turret class to vehicle_turret spawn player above the spawn pad Modified: trunk/game/g_entityclass.c =================================================================== --- trunk/game/g_entityclass.c 2006-04-08 02:42:27 UTC (rev 691) +++ trunk/game/g_entityclass.c 2006-04-08 21:09:02 UTC (rev 692) @@ -279,23 +279,23 @@ { } -static void G_Object_Turret_Spawn(G_Entity *self) +static void G_Object_Vehicle_Turret_Spawn(G_Entity *self) { } -static void G_Object_Turret_Remove(G_Entity *self) +static void G_Object_Vehicle_Turret_Remove(G_Entity *self) { } -static void G_Object_Turret_Frame(G_Entity *self) +static void G_Object_Vehicle_Turret_Frame(G_Entity *self) { } -static void G_Object_Turret_WritePacket(G_Entity *self, G_PacketBuffer *buffer) +static void G_Object_Vehicle_Turret_WritePacket(G_Entity *self, G_PacketBuffer *buffer) { } -static void G_Object_Turret_ReadPacket(G_Entity *self, G_PacketBuffer *buffer, Nbool reset) +static void G_Object_Vehicle_Turret_ReadPacket(G_Entity *self, G_PacketBuffer *buffer, Nbool reset) { } @@ -682,12 +682,12 @@ "Provides protection from the hail of gunfire\nTODO: explain fields\n" }, { - "turret", - G_Object_Turret_Spawn, - G_Object_Turret_Remove, - G_Object_Turret_Frame, - G_Object_Turret_ReadPacket, - G_Object_Turret_WritePacket, + "vehicle_turret", + G_Object_Vehicle_Turret_Spawn, + G_Object_Vehicle_Turret_Remove, + G_Object_Vehicle_Turret_Frame, + G_Object_Vehicle_Turret_ReadPacket, + G_Object_Vehicle_Turret_WritePacket, G_SCOPE_RENDER_OPAQUE | G_SCOPE_RENDER_CASTSHADOW | G_SCOPE_RENDER_RECEIVELIGHT | G_SCOPE_BLOCK_EVERYTHING | G_SCOPE_NETWORK_RENDERABLE | G_SCOPE_NETWORK_HEARABLE, "Provides a hail of gunfire\nTODO: explain fields\n" }, Modified: trunk/game/g_world.c =================================================================== --- trunk/game/g_world.c 2006-04-08 02:42:27 UTC (rev 691) +++ trunk/game/g_world.c 2006-04-08 21:09:02 UTC (rev 692) @@ -512,6 +512,7 @@ position = spot->position; else position = GS.identityposition; + position.m.m[2][3] += 2; // set up player entity for this user player = G_Entity_New(NULL, G_EntityClass_ByName("infantry"), &position); player->localuserindex = user - GS.users; From lordhavoc at icculus.org Sat Apr 8 17:12:01 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 8 Apr 2006 17:12:01 -0400 Subject: r693 - in trunk: . game Message-ID: <20060408211201.24262.qmail@icculus.org> Author: lordhavoc Date: 2006-04-08 17:12:01 -0400 (Sat, 08 Apr 2006) New Revision: 693 Modified: trunk/game/g_entity.c trunk/game/g_render.c trunk/game/g_world.c trunk/model.c trunk/model.h trunk/modelanim.c trunk/modelanim.h trunk/r_main.c trunk/util.c Log: reworking model structure in preparation for changes in skeletal animation method Modified: trunk/game/g_entity.c =================================================================== --- trunk/game/g_entity.c 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/game/g_entity.c 2006-04-08 21:12:01 UTC (rev 693) @@ -205,7 +205,7 @@ entity->modelindex = modelindex; model = Resource_GetData(entity->modelindex); if (model) - for (meshindex = 0;meshindex < model->nummeshes;meshindex++) + for (meshindex = 0;meshindex < model->num_meshes;meshindex++) G_Entity_AddSurface(entity, meshindex); } Modified: trunk/game/g_render.c =================================================================== --- trunk/game/g_render.c 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/game/g_render.c 2006-04-08 21:12:01 UTC (rev 693) @@ -33,7 +33,7 @@ } if (!model) continue; - R_DrawMesh(model->meshes[surface->meshindex].resource_material, surface->meshindex, entity->transforms); + R_DrawMesh(model->data_meshes[surface->meshindex].resource_material, surface->meshindex, entity->transforms); } } @@ -66,7 +66,7 @@ currententity = entity; R_SetEntity(&entity->position.m, entity->cullradius, entity->modelindex); } - mesh = model->meshes + surface->meshindex; + mesh = model->data_meshes + surface->meshindex; material = Resource_GetData(mesh->resource_material); if (Resource_GetData(material->texture_background)) { Modified: trunk/game/g_world.c =================================================================== --- trunk/game/g_world.c 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/game/g_world.c 2006-04-08 21:12:01 UTC (rev 693) @@ -607,8 +607,8 @@ { if (!SpheresOverlap(movecenter, moveradius, surface->cullorigin, surface->cullradius) || !BoxesOverlap(movemins, movemaxs, surface->cullmins, surface->cullmaxs)) continue; - mesh = model->meshes + surface->meshindex; - Collision_Trace_CheckBrushes(&collisiontrace, mesh->numcollisionbrushes, mesh->collisionbrushes, mesh->collisionbrushes); + mesh = model->data_meshes + surface->meshindex; + Collision_Trace_CheckBrushes(&collisiontrace, mesh->num_collisionbrushes, mesh->data_collisionbrushes, mesh->data_collisionbrushes); } } Collision_Trace_End(&collisiontrace); Modified: trunk/model.c =================================================================== --- trunk/model.c 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/model.c 2006-04-08 21:12:01 UTC (rev 693) @@ -275,27 +275,26 @@ //numJoints 3 else if (Util_ParseC_MatchKeyword(&thread, "numJoints")) { - LoadInt(model->numtransforms, "after 'numJoints'"); - if (model->numtransforms < 1) + LoadInt(model->num_transforms, "after 'numJoints'"); + if (model->num_transforms < 1) { - Console_Printf("Model_Load: numJoints %i < 1\n", model->numtransforms); + Console_Printf("Model_Load: numJoints %i < 1\n", model->num_transforms); Abort(); } - model->transformnames = Mem_Alloc(r->memzone, model->numtransforms * sizeof(*model->transformnames)); - model->transformradius = Mem_Alloc(r->memzone, model->numtransforms * sizeof(*model->transformradius)); - model->basetransforms = Mem_Alloc(r->memzone, model->numtransforms * sizeof(*model->basetransforms)); - model->baseinversetransforms = Mem_Alloc(r->memzone, model->numtransforms * sizeof(*model->baseinversetransforms)); + model->max_transforms = model->num_transforms; + model->data_transforminfo = Mem_Alloc(r->memzone, model->max_transforms * sizeof(*model->data_transforminfo)); } //numMeshes 1 else if (Util_ParseC_MatchKeyword(&thread, "numMeshes")) { - LoadInt(model->nummeshes, "after 'numMeshes'"); - if (model->nummeshes < 1) + LoadInt(model->num_meshes, "after 'numMeshes'"); + if (model->num_meshes < 1) { - Console_Printf("Model_Load: numMeshes %i < 1\n", model->nummeshes); + Console_Printf("Model_Load: numMeshes %i < 1\n", model->num_meshes); Abort(); } - model->meshes = Mem_Alloc(r->memzone, model->nummeshes * sizeof(Model_Mesh)); + model->max_meshes = model->num_meshes; + model->data_meshes = Mem_Alloc(r->memzone, model->max_meshes * sizeof(Model_Mesh)); } //joints { // "root" -1 ( 0.000000 0.000000 0.000000 ) ( -0.707107 -0.000000 -0.000000 ) // @@ -309,31 +308,30 @@ for (jointnum = 0; !Util_ParseC_MatchKeyword(&thread, "}");jointnum++) { NSint32 parent; - double joint6[6]; // "root" -1 ( 0.000000 0.000000 0.000000 ) ( -0.707107 -0.000000 -0.000000 ) - LoadString(model->transformnames[jointnum], "for joint name"); + LoadString(model->data_transforminfo[jointnum].name, "for joint name"); LoadInt(parent, "as parent"); ExpectKeyword("(", "before first joint data list"); - LoadValue(joint6[0], "(joint 0)"); - LoadValue(joint6[1], "(joint 1)"); - LoadValue(joint6[2], "(joint 2)"); + LoadValue(model->data_transforminfo[jointnum].basepose[0], "(joint 0)"); + LoadValue(model->data_transforminfo[jointnum].basepose[1], "(joint 1)"); + LoadValue(model->data_transforminfo[jointnum].basepose[2], "(joint 2)"); ExpectKeyword(")", "after first joint data list"); ExpectKeyword("(", "before second joint data list"); - LoadValue(joint6[3], "(joint 3)"); - LoadValue(joint6[4], "(joint 4)"); - LoadValue(joint6[5], "(joint 5)"); + LoadValue(model->data_transforminfo[jointnum].basepose[3], "(joint 3)"); + LoadValue(model->data_transforminfo[jointnum].basepose[4], "(joint 4)"); + LoadValue(model->data_transforminfo[jointnum].basepose[5], "(joint 5)"); ExpectKeyword(")", "after second joint data list"); - Matrix4x4_CreateFromDoom3Joint(&model->basetransforms[jointnum], joint6[0], joint6[1], joint6[2], joint6[3], joint6[4], joint6[5]); - Matrix4x4_Invert_Simple(&model->baseinversetransforms[jointnum], &model->basetransforms[jointnum]); + Matrix4x4_CreateFromDoom3Joint(&model->data_transforminfo[jointnum].basematrix, model->data_transforminfo[jointnum].basepose[0], model->data_transforminfo[jointnum].basepose[1], model->data_transforminfo[jointnum].basepose[2], model->data_transforminfo[jointnum].basepose[3], model->data_transforminfo[jointnum].basepose[4], model->data_transforminfo[jointnum].basepose[5]); + Matrix4x4_Invert_Simple(&model->data_transforminfo[jointnum].baseinversematrix, &model->data_transforminfo[jointnum].basematrix); if (parent >= (NSint32)jointnum) { Console_Printf("Model_Load: joint.parent (%i) >= joint (%i)\n", parent, jointnum); Abort(); } } - if (jointnum != model->numtransforms) + if (jointnum != model->num_transforms) { - Console_Printf("Model_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, model->numtransforms); + Console_Printf("Model_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, model->num_transforms); Abort(); } } @@ -349,37 +347,40 @@ matrix4x4_t *matrix; ExpectKeyword("{", "after 'mesh'"); - if (meshnum >= model->nummeshes) + if (meshnum >= model->num_meshes) { - Console_Printf("Model_Load: meshnum (%i) >= nummeshes (%i)\n", meshnum, model->nummeshes); + Console_Printf("Model_Load: meshnum (%i) >= nummeshes (%i)\n", meshnum, model->num_meshes); Abort(); } - mesh = model->meshes + meshnum; + mesh = model->data_meshes + meshnum; for (;;) { // // meshes: v_pitch // shader "models/weapons/v_pitch" if (Util_ParseC_MatchKeyword(&thread, "shader")) { - char *shader = NULL; - LoadString(shader, "(shader name after 'shader')"); - mesh->resource_material = Resource_IndexForName(shader, RESOURCETYPE_MATERIAL, 0, 0); + LoadString(mesh->materialname, "(shader name after 'shader')"); + mesh->resource_material = Resource_IndexForName(mesh->materialname, RESOURCETYPE_MATERIAL, 0, 0); } // numverts 292 else if (Util_ParseC_MatchKeyword(&thread, "numverts")) { - LoadInt(mesh->numvertices, "after 'numverts'"); - if (mesh->numvertices < 3) + LoadInt(mesh->num_vertices, "after 'numverts'"); + if (mesh->num_vertices < 3) { - Console_Printf("Model_Load: numverts (%i) < 3\n", mesh->numvertices); + Console_Printf("Model_Load: numverts (%i) < 3\n", mesh->num_vertices); Abort(); } - mesh->vertex3f = Mem_Alloc(r->memzone, mesh->numvertices * sizeof(float[3])); - mesh->svector3f = Mem_Alloc(r->memzone, mesh->numvertices * sizeof(float[3])); - mesh->tvector3f = Mem_Alloc(r->memzone, mesh->numvertices * sizeof(float[3])); - mesh->normal3f = Mem_Alloc(r->memzone, mesh->numvertices * sizeof(float[3])); - mesh->texcoord2f = Mem_Alloc(r->memzone, mesh->numvertices * sizeof(float[2])); - md5weightrange = Mem_Alloc(Global_Zone, mesh->numvertices * sizeof(int[2])); + mesh->max_vertices = mesh->num_vertices; + mesh->data_vertex3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3])); + mesh->data_svector3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3])); + mesh->data_tvector3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3])); + mesh->data_normal3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3])); + mesh->data_texcoord2f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[2])); + mesh->data_lightmaptexcoord2f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[2])); + mesh->data_weightindex4i = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint32[4])); + mesh->data_weightvalue4f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[4])); + md5weightrange = Mem_Alloc(Global_Zone, mesh->max_vertices * sizeof(NUint32[2])); } // vert 0 ( 0.142532 0.983877 ) 0 1 // vert 1 ( 0.155314 0.987100 ) 1 1 @@ -389,17 +390,17 @@ NUint32 vertexnum; // 0 LoadInt(vertexnum, "after 'vert'"); - if (vertexnum >= mesh->numvertices) + if (vertexnum >= mesh->num_vertices) { - Console_Printf("Model_Load: vert (%i) >= numverts (%i)\n", vertexnum, mesh->numvertices); + Console_Printf("Model_Load: vert (%i) >= numverts (%i)\n", vertexnum, mesh->num_vertices); Abort(); } // ( ExpectKeyword("(", "before texture coords"); // 0.142532 - LoadValue(mesh->texcoord2f[vertexnum*2+0], "(first texcoord)"); + LoadValue(mesh->data_texcoord2f[vertexnum*2+0], "(first texcoord)"); // 0.983877 - LoadValue(mesh->texcoord2f[vertexnum*2+1], "(second texcoord)"); + LoadValue(mesh->data_texcoord2f[vertexnum*2+1], "(second texcoord)"); // ) ExpectKeyword(")", "after texture coords"); // 0 @@ -411,15 +412,16 @@ // numtris 274 else if (Util_ParseC_MatchKeyword(&thread, "numtris")) { - LoadInt(mesh->numtriangles, "after 'numtris'"); - if (mesh->numtriangles < 1) + LoadInt(mesh->num_triangles, "after 'numtris'"); + if (mesh->num_triangles < 1) { - Console_Printf("Model_Load: numtris (%i) < 1\n", mesh->numtriangles); + Console_Printf("Model_Load: numtris (%i) < 1\n", mesh->num_triangles); Abort(); } - mesh->element3i = Mem_Alloc(r->memzone, mesh->numtriangles * sizeof(int[3])); - mesh->neighbor3i = Mem_Alloc(r->memzone, mesh->numtriangles * sizeof(int[3])); - mesh->plane4f = Mem_Alloc(r->memzone, mesh->numtriangles * sizeof(float[4])); + mesh->max_triangles = mesh->num_triangles; + mesh->data_element3i = Mem_Alloc(r->memzone, mesh->max_triangles * sizeof(NUint32[3])); + mesh->data_neighbor3i = Mem_Alloc(r->memzone, mesh->max_triangles * sizeof(NSint32[3])); + mesh->data_plane4f = Mem_Alloc(r->memzone, mesh->max_triangles * sizeof(float[4])); } // tri 0 29 30 31 // tri 1 32 29 76 @@ -428,17 +430,17 @@ { NUint32 trianglenum; LoadInt(trianglenum, "after 'tri'"); - if (trianglenum >= mesh->numtriangles) + if (trianglenum >= mesh->num_triangles) { - Console_Printf("Model_Load: tri (%i) >= numtris (%i)\n", trianglenum, mesh->numtriangles); + Console_Printf("Model_Load: tri (%i) >= numtris (%i)\n", trianglenum, mesh->num_triangles); Abort(); } // TODO: boundscheck elements // note: this converts the clockwise triangles in the // md5mesh file to counterclockwise for OpenGL - LoadInt(mesh->element3i[trianglenum*3+2], "(first index)"); - LoadInt(mesh->element3i[trianglenum*3+1], "(second index)"); - LoadInt(mesh->element3i[trianglenum*3+0], "(third index)"); + LoadInt(mesh->data_element3i[trianglenum*3+2], "(first index)"); + LoadInt(mesh->data_element3i[trianglenum*3+1], "(second index)"); + LoadInt(mesh->data_element3i[trianglenum*3+0], "(third index)"); } // numweights 145 else if (Util_ParseC_MatchKeyword(&thread, "numweights")) @@ -468,9 +470,9 @@ md5weight = md5weights + weightnum; // 2 LoadInt(md5weight->jointnum, "(weight jointnum)"); - if (md5weight->jointnum >= model->numtransforms) + if (md5weight->jointnum >= model->num_transforms) { - Console_Printf("Model_Load: joint (%i) >= numtransforms (%i)\n", md5weight->jointnum, model->numtransforms); + Console_Printf("Model_Load: joint (%i) >= num_transforms (%i)\n", md5weight->jointnum, model->num_transforms); Abort(); } // 1.000000 @@ -495,65 +497,66 @@ break; } } - memset(mesh->vertex3f, 0, mesh->numvertices * sizeof(float[3])); - mesh->numweights = 0; - for (i = 0;i < mesh->numvertices;i++) + memset(mesh->data_vertex3f, 0, mesh->num_vertices * sizeof(float[3])); + mesh->num_weights = 0; + for (i = 0;i < mesh->num_vertices;i++) { Ndouble sum = 0; for (j = 0, md5weight = md5weights + md5weightrange[i*2+0];j < md5weightrange[i*2+1];j++, md5weight++) { - matrix = model->basetransforms + md5weight->jointnum; - mesh->vertex3f[i*3+0] += DotProduct4(md5weight->vertex, matrix->m[0]); - mesh->vertex3f[i*3+1] += DotProduct4(md5weight->vertex, matrix->m[1]); - mesh->vertex3f[i*3+2] += DotProduct4(md5weight->vertex, matrix->m[2]); + matrix = &model->data_transforminfo[md5weight->jointnum].basematrix; + mesh->data_vertex3f[i*3+0] += DotProduct4(md5weight->vertex, matrix->m[0]); + mesh->data_vertex3f[i*3+1] += DotProduct4(md5weight->vertex, matrix->m[1]); + mesh->data_vertex3f[i*3+2] += DotProduct4(md5weight->vertex, matrix->m[2]); sum += md5weight->vertex[3]; - mesh->numweights++; + mesh->num_weights++; } if (fabs(sum - 1) > 0.001) Console_Printf("vertex #%i (weights %i-%i) does not sum to 1! (sum = %f)\n", i, md5weightrange[i*2+0], md5weightrange[i*2+0]+md5weightrange[i*2+1], sum); } // compile the base frame of the mesh for static uses - Model_MeshVectors(mesh->numtriangles, mesh->element3i, mesh->numvertices, mesh->vertex3f, mesh->texcoord2f, mesh->svector3f, mesh->tvector3f, mesh->normal3f); - Model_MeshNeighbors(mesh->numtriangles, mesh->element3i, mesh->neighbor3i, mesh->numvertices); - Model_BuildTrianglePlanes(mesh->vertex3f, mesh->numtriangles, mesh->element3i, mesh->plane4f); + Model_MeshVectors(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f); + Model_MeshNeighbors(mesh->num_triangles, mesh->data_element3i, mesh->data_neighbor3i, mesh->num_vertices); + Model_BuildTrianglePlanes(mesh->data_vertex3f, mesh->num_triangles, mesh->data_element3i, mesh->data_plane4f); // collision brushes are for the static frame // TODO: load separate collision brush file for faster collisions? - mesh->numcollisionbrushes = mesh->numtriangles; - mesh->collisionbrushes = Collision_Brush_AllocBrushesForTriangleMesh(r->memzone, mesh->numtriangles); - Collision_Brush_UpdateTriangleMeshBrushes(mesh->collisionbrushes, mesh->numtriangles, mesh->element3i, mesh->vertex3f); + mesh->num_collisionbrushes = mesh->num_triangles; + mesh->max_collisionbrushes = mesh->num_collisionbrushes; + mesh->data_collisionbrushes = Collision_Brush_AllocBrushesForTriangleMesh(r->memzone, mesh->max_triangles); + Collision_Brush_UpdateTriangleMeshBrushes(mesh->data_collisionbrushes, mesh->num_triangles, mesh->data_element3i, mesh->data_vertex3f); // regenerate the weights from the static mesh and influences, // because we need weights with svector/tvector/normal information - mesh->weights = Mem_Alloc(r->memzone, mesh->numweights * sizeof(Model_Weight)); + mesh->weights = Mem_Alloc(r->memzone, mesh->num_weights * sizeof(Model_Weight)); weight = mesh->weights; - for (i = 0;i < mesh->numvertices;i++) + for (i = 0;i < mesh->num_vertices;i++) { if (!i && !meshnum) { - VectorCopy(mesh->vertex3f, model->basecullmins); - VectorCopy(mesh->vertex3f, model->basecullmaxs); + VectorCopy(mesh->data_vertex3f, model->basecullmins); + VectorCopy(mesh->data_vertex3f, model->basecullmaxs); } else { - model->basecullmins[0] = Min(model->basecullmins[0], mesh->vertex3f[i * 3 + 0]); - model->basecullmins[1] = Min(model->basecullmins[1], mesh->vertex3f[i * 3 + 1]); - model->basecullmins[2] = Min(model->basecullmins[2], mesh->vertex3f[i * 3 + 2]); - model->basecullmaxs[0] = Max(model->basecullmaxs[0], mesh->vertex3f[i * 3 + 0]); - model->basecullmaxs[1] = Max(model->basecullmaxs[1], mesh->vertex3f[i * 3 + 1]); - model->basecullmaxs[2] = Max(model->basecullmaxs[2], mesh->vertex3f[i * 3 + 2]); + model->basecullmins[0] = Min(model->basecullmins[0], mesh->data_vertex3f[i * 3 + 0]); + model->basecullmins[1] = Min(model->basecullmins[1], mesh->data_vertex3f[i * 3 + 1]); + model->basecullmins[2] = Min(model->basecullmins[2], mesh->data_vertex3f[i * 3 + 2]); + model->basecullmaxs[0] = Max(model->basecullmaxs[0], mesh->data_vertex3f[i * 3 + 0]); + model->basecullmaxs[1] = Max(model->basecullmaxs[1], mesh->data_vertex3f[i * 3 + 1]); + model->basecullmaxs[2] = Max(model->basecullmaxs[2], mesh->data_vertex3f[i * 3 + 2]); } if (!i) { - VectorCopy(mesh->vertex3f, mesh->basecullmins); - VectorCopy(mesh->vertex3f, mesh->basecullmaxs); + VectorCopy(mesh->data_vertex3f, mesh->basecullmins); + VectorCopy(mesh->data_vertex3f, mesh->basecullmaxs); } else { - mesh->basecullmins[0] = Min(mesh->basecullmins[0], mesh->vertex3f[i * 3 + 0]); - mesh->basecullmins[1] = Min(mesh->basecullmins[1], mesh->vertex3f[i * 3 + 1]); - mesh->basecullmins[2] = Min(mesh->basecullmins[2], mesh->vertex3f[i * 3 + 2]); - mesh->basecullmaxs[0] = Max(mesh->basecullmaxs[0], mesh->vertex3f[i * 3 + 0]); - mesh->basecullmaxs[1] = Max(mesh->basecullmaxs[1], mesh->vertex3f[i * 3 + 1]); - mesh->basecullmaxs[2] = Max(mesh->basecullmaxs[2], mesh->vertex3f[i * 3 + 2]); + mesh->basecullmins[0] = Min(mesh->basecullmins[0], mesh->data_vertex3f[i * 3 + 0]); + mesh->basecullmins[1] = Min(mesh->basecullmins[1], mesh->data_vertex3f[i * 3 + 1]); + mesh->basecullmins[2] = Min(mesh->basecullmins[2], mesh->data_vertex3f[i * 3 + 2]); + mesh->basecullmaxs[0] = Max(mesh->basecullmaxs[0], mesh->data_vertex3f[i * 3 + 0]); + mesh->basecullmaxs[1] = Max(mesh->basecullmaxs[1], mesh->data_vertex3f[i * 3 + 1]); + mesh->basecullmaxs[2] = Max(mesh->basecullmaxs[2], mesh->data_vertex3f[i * 3 + 2]); } for (j = 0, md5weight = md5weights + md5weightrange[i*2+0];j < md5weightrange[i*2+1];j++, md5weight++) { @@ -566,18 +569,18 @@ weight->vertex[2] = md5weight->vertex[2]; weight->vertex[3] = md5weight->vertex[3]; // calculate weights for the tangent space vectors - matrix = model->basetransforms + weight->transformindex; - weight->svector[0] = (mesh->svector3f[i*3+0] * matrix->m[0][0] + mesh->svector3f[i*3+1] * matrix->m[1][0] + mesh->svector3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; - weight->svector[1] = (mesh->svector3f[i*3+0] * matrix->m[0][1] + mesh->svector3f[i*3+1] * matrix->m[1][1] + mesh->svector3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; - weight->svector[2] = (mesh->svector3f[i*3+0] * matrix->m[0][2] + mesh->svector3f[i*3+1] * matrix->m[1][2] + mesh->svector3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; - weight->tvector[0] = (mesh->tvector3f[i*3+0] * matrix->m[0][0] + mesh->tvector3f[i*3+1] * matrix->m[1][0] + mesh->tvector3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; - weight->tvector[1] = (mesh->tvector3f[i*3+0] * matrix->m[0][1] + mesh->tvector3f[i*3+1] * matrix->m[1][1] + mesh->tvector3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; - weight->tvector[2] = (mesh->tvector3f[i*3+0] * matrix->m[0][2] + mesh->tvector3f[i*3+1] * matrix->m[1][2] + mesh->tvector3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; - weight->normal[0] = (mesh->normal3f[i*3+0] * matrix->m[0][0] + mesh->normal3f[i*3+1] * matrix->m[1][0] + mesh->normal3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; - weight->normal[1] = (mesh->normal3f[i*3+0] * matrix->m[0][1] + mesh->normal3f[i*3+1] * matrix->m[1][1] + mesh->normal3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; - weight->normal[2] = (mesh->normal3f[i*3+0] * matrix->m[0][2] + mesh->normal3f[i*3+1] * matrix->m[1][2] + mesh->normal3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; + matrix = &model->data_transforminfo[weight->transformindex].basematrix; + weight->svector[0] = (mesh->data_svector3f[i*3+0] * matrix->m[0][0] + mesh->data_svector3f[i*3+1] * matrix->m[1][0] + mesh->data_svector3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; + weight->svector[1] = (mesh->data_svector3f[i*3+0] * matrix->m[0][1] + mesh->data_svector3f[i*3+1] * matrix->m[1][1] + mesh->data_svector3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; + weight->svector[2] = (mesh->data_svector3f[i*3+0] * matrix->m[0][2] + mesh->data_svector3f[i*3+1] * matrix->m[1][2] + mesh->data_svector3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; + weight->tvector[0] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][0] + mesh->data_tvector3f[i*3+1] * matrix->m[1][0] + mesh->data_tvector3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; + weight->tvector[1] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][1] + mesh->data_tvector3f[i*3+1] * matrix->m[1][1] + mesh->data_tvector3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; + weight->tvector[2] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][2] + mesh->data_tvector3f[i*3+1] * matrix->m[1][2] + mesh->data_tvector3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; + weight->normal[0] = (mesh->data_normal3f[i*3+0] * matrix->m[0][0] + mesh->data_normal3f[i*3+1] * matrix->m[1][0] + mesh->data_normal3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; + weight->normal[1] = (mesh->data_normal3f[i*3+0] * matrix->m[0][1] + mesh->data_normal3f[i*3+1] * matrix->m[1][1] + mesh->data_normal3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; + weight->normal[2] = (mesh->data_normal3f[i*3+0] * matrix->m[0][2] + mesh->data_normal3f[i*3+1] * matrix->m[1][2] + mesh->data_normal3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; r = VectorLength(weight->vertex) / weight->vertex[3]; - model->transformradius[weight->transformindex] = Max(model->transformradius[weight->transformindex], r); + model->data_transforminfo[weight->transformindex].radius = Max(model->data_transforminfo[weight->transformindex].radius, r); weight++; } } @@ -619,31 +622,31 @@ { if (outvertex3f) { - memcpy(outvertex3f, mesh->vertex3f, mesh->numvertices * sizeof(float[3])); + memcpy(outvertex3f, mesh->data_vertex3f, mesh->num_vertices * sizeof(float[3])); if (outplane4f) - memcpy(outplane4f, mesh->plane4f, mesh->numtriangles * sizeof(float[4])); + memcpy(outplane4f, mesh->data_plane4f, mesh->num_triangles * sizeof(float[4])); } if (outsvector3f) - memcpy(outsvector3f, mesh->svector3f, mesh->numvertices * sizeof(float[3])); + memcpy(outsvector3f, mesh->data_svector3f, mesh->num_vertices * sizeof(float[3])); if (outtvector3f) - memcpy(outtvector3f, mesh->tvector3f, mesh->numvertices * sizeof(float[3])); + memcpy(outtvector3f, mesh->data_tvector3f, mesh->num_vertices * sizeof(float[3])); if (outnormal3f) - memcpy(outnormal3f, mesh->normal3f, mesh->numvertices * sizeof(float[3])); + memcpy(outnormal3f, mesh->data_normal3f, mesh->num_vertices * sizeof(float[3])); return; } if (outvertex3f) - memset(outvertex3f, 0, mesh->numvertices * sizeof(float[3])); + memset(outvertex3f, 0, mesh->num_vertices * sizeof(float[3])); if (outsvector3f) - memset(outsvector3f, 0, mesh->numvertices * sizeof(float[3])); + memset(outsvector3f, 0, mesh->num_vertices * sizeof(float[3])); if (outtvector3f) - memset(outtvector3f, 0, mesh->numvertices * sizeof(float[3])); + memset(outtvector3f, 0, mesh->num_vertices * sizeof(float[3])); if (outnormal3f) - memset(outnormal3f, 0, mesh->numvertices * sizeof(float[3])); + memset(outnormal3f, 0, mesh->num_vertices * sizeof(float[3])); // TODO: SSE assembly support if (outvertex3f && outsvector3f && outtvector3f && outnormal3f) { // fastpath for all properties at once - for (j = 0, weight = mesh->weights;j < mesh->numweights;j++, weight++) + for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) { matrix = transforms + weight->transformindex; index = weight->vertexindex*3; @@ -661,14 +664,14 @@ outnormal3f[index+2] += DotProduct(weight->normal, matrix->m[2]); } if (outplane4f) - Model_BuildTrianglePlanes(outvertex3f, mesh->numtriangles, mesh->element3i, outplane4f); + Model_BuildTrianglePlanes(outvertex3f, mesh->num_triangles, mesh->data_element3i, outplane4f); return; } // partial request, handle each in turn (usually only vertex) // FIXME: would it be worth saving separate weights for vertex? if (outvertex3f) { - for (j = 0, weight = mesh->weights;j < mesh->numweights;j++, weight++) + for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) { matrix = transforms + weight->transformindex; index = weight->vertexindex*3; @@ -677,11 +680,11 @@ outvertex3f[index+2] += DotProduct4(weight->vertex, matrix->m[2]); } if (outplane4f) - Model_BuildTrianglePlanes(outvertex3f, mesh->numtriangles, mesh->element3i, outplane4f); + Model_BuildTrianglePlanes(outvertex3f, mesh->num_triangles, mesh->data_element3i, outplane4f); } if (outsvector3f) { - for (j = 0, weight = mesh->weights;j < mesh->numweights;j++, weight++) + for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) { matrix = transforms + weight->transformindex; index = weight->vertexindex*3; @@ -692,7 +695,7 @@ } if (outtvector3f) { - for (j = 0, weight = mesh->weights;j < mesh->numweights;j++, weight++) + for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) { matrix = transforms + weight->transformindex; index = weight->vertexindex*3; @@ -703,7 +706,7 @@ } if (outnormal3f) { - for (j = 0, weight = mesh->weights;j < mesh->numweights;j++, weight++) + for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) { matrix = transforms + weight->transformindex; index = weight->vertexindex*3; @@ -739,7 +742,7 @@ Matrix4x4_OriginFromMatrix(transforms, origin); // TODO: scale radius based on longest vector in transform? - radius = model->transformradius[0]; + radius = model->data_transforminfo[0].radius; cullmins[0] = origin[0] - radius; cullmins[1] = origin[1] - radius; cullmins[2] = origin[2] - radius; @@ -747,11 +750,11 @@ cullmaxs[1] = origin[1] + radius; cullmaxs[2] = origin[2] + radius; - for (i = 1;i < model->numtransforms;i++) + for (i = 1;i < model->num_transforms;i++) { Matrix4x4_OriginFromMatrix(transforms + i, origin); // TODO: scale radius based on longest vector in transform? - radius = model->transformradius[i]; + radius = model->data_transforminfo[i].radius; cullmins[0] = Min(cullmins[0], origin[0] - radius); cullmins[1] = Min(cullmins[1], origin[1] - radius); cullmins[2] = Min(cullmins[2], origin[2] - radius); @@ -771,9 +774,9 @@ model = Resource_GetData(modelresource); if (!model) return; // no model - if (meshindex >= model->nummeshes) + if (meshindex >= model->num_meshes) return; // invalid mesh - mesh = model->meshes + meshindex; + mesh = model->data_meshes + meshindex; if (!transforms) { // easy case @@ -787,11 +790,11 @@ // array and then memset it and blend, add a weightrange array indexable // by vertex number to make this faster (no intermediate buffer involved) NUint32 i; - float *v, *vertex3f = Mem_Alloc(Global_Zone, mesh->numvertices * sizeof(float[3])); + float *v, *vertex3f = Mem_Alloc(Global_Zone, mesh->num_vertices * sizeof(float[3])); Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); VectorCopy(vertex3f, cullmins); VectorCopy(vertex3f, cullmaxs); - for (i = 0, v = vertex3f;i < mesh->numvertices;i++, v += 3) + for (i = 0, v = vertex3f;i < mesh->num_vertices;i++, v += 3) { cullmins[0] = Min(cullmins[0], v[0]); cullmins[1] = Min(cullmins[1], v[1]); @@ -811,8 +814,8 @@ model = Resource_GetData(modelresource); if (!model) return -1; // no model - for (i = 0;i < model->numtransforms;i++) - if (!String_Compare(model->transformnames[i], name)) + for (i = 0;i < model->num_transforms;i++) + if (!String_Compare(model->data_transforminfo[i].name, name)) return i; return -1; } @@ -825,12 +828,12 @@ NUint32 Model_GetNumMeshes(NUint32 resourceindex) { - return ((Model *)Resource_GetData(resourceindex))->nummeshes; + return ((Model *)Resource_GetData(resourceindex))->num_meshes; } NUint32 Model_GetNumTransforms(NUint32 resourceindex) { - return ((Model *)Resource_GetData(resourceindex))->numtransforms; + return ((Model *)Resource_GetData(resourceindex))->num_transforms; } const char **Model_GetTransformNames(NUint32 resourceindex) @@ -845,12 +848,12 @@ NUint32 Model_GetMeshMaterial(NUint32 resourceindex, NUint32 meshindex) { - return ((Model *)Resource_GetData(resourceindex))->meshes[meshindex].resource_material; + return ((Model *)Resource_GetData(resourceindex))->data_meshes[meshindex].resource_material; } NUint32 Model_GetMeshNumVertices(NUint32 resourceindex, NUint32 meshindex) { - return ((Model *)Resource_GetData(resourceindex))->meshes[meshindex].resource_material; + return ((Model *)Resource_GetData(resourceindex))->data_meshes[meshindex].resource_material; } // unfinished Modified: trunk/model.h =================================================================== --- trunk/model.h 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/model.h 2006-04-08 21:12:01 UTC (rev 693) @@ -4,6 +4,20 @@ #include "collision.h" +typedef struct Model_TransformInfo +{ + char *name; + + // doom3 joint pose format + float basepose[6]; + + matrix4x4_t basematrix; + matrix4x4_t baseinversematrix; + + float radius; +} +Model_TransformInfo; + typedef struct Model_Weight { // this struct is intended to be easy for SSE 4 component math ops @@ -27,64 +41,79 @@ typedef struct Model_Mesh { + char *materialname; + // material applied to this mesh NUint32 resource_material; - // number of vertices in this mesh - NUint32 numvertices; - // texture coordinates for vertices in this mesh - float *texcoord2f; - // number of triangles in this mesh - NUint32 numtriangles; + NUint32 num_triangles; + // amount of memory allocated for triangles in this mesh + NUint32 max_triangles; // triangle vertex indices - NUint32 *element3i; + NUint32 *data_element3i; // triangle neighbor indices, -1 means no neighbor on this edge - NSint32 *neighbor3i; + NSint32 *data_neighbor3i; // plane of each triangle for shadow casting // DotProduct4(plane4f, lightorigin) > 0 means the light is infront - float *plane4f; + float *data_plane4f; - // number of skeletal transforms to blend onto the vertex array - // (always >= numvertices) - NUint32 numweights; - // skeletal transform weights - Model_Weight *weights; - - // static mesh data for non-animated models + // number of vertices in this mesh + NUint32 num_vertices; + // amount of memory allocated for vertices in this mesh (used when loading/converting models) + NUint32 max_vertices; // note: vertex, svector, tvector, and normal form a valid [4][3] matrix // defining tangentspace at each vertex, simply transforming the light // using this tangentspace matrix gives a vector suitable for normalmapped // (aka bumpmapped) lighting. // location of vertex - float *vertex3f; + float *data_vertex3f; // direction of S texcoord - float *svector3f; + float *data_svector3f; // direction of T texcoord - float *tvector3f; + float *data_tvector3f; // direction of R texcoord (surface normal) - float *normal3f; + float *data_normal3f; + // texture coordinates for vertices in this mesh + float *data_texcoord2f; + // lightmap texture coordinates for vertices in this mesh + float *data_lightmaptexcoord2f; + // indices of up to 4 transforms per vertex + int *data_weightindex4i; + // blending influence values of up to 4 transforms per vertex + float *data_weightvalue4f; - // collision brushes for the static mesh - // (generally these are triangle brushes) - NUint32 numcollisionbrushes; - Collision_Brush *collisionbrushes; +#if 1 + // number of skeletal transforms to blend onto the vertex array + // (always >= numvertices) + NUint32 num_weights; + // skeletal transform weights + Model_Weight *weights; +#endif Nvec3 basecullmins; Nvec3 basecullmaxs; + + // number of collision burhses in this mesh + NUint32 num_collisionbrushes; + // amount of memory allocated for collision brushes in this mesh + NUint32 max_collisionbrushes; + // collision brushes for the static mesh + // (generally these are triangle brushes) + Collision_Brush *data_collisionbrushes; } Model_Mesh; + typedef struct Model { - NUint32 nummeshes; - Model_Mesh *meshes; + NUint32 num_meshes; + NUint32 max_meshes; + Model_Mesh *data_meshes; - NUint32 numtransforms; - char **transformnames; - float *transformradius; - matrix4x4_t *basetransforms; - matrix4x4_t *baseinversetransforms; + NUint32 num_transforms; + NUint32 max_transforms; + Model_TransformInfo *data_transforminfo; Nvec3 basecullmins; Nvec3 basecullmaxs; Modified: trunk/modelanim.c =================================================================== --- trunk/modelanim.c 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/modelanim.c 2006-04-08 21:12:01 UTC (rev 693) @@ -104,10 +104,10 @@ //numJoints 3 else if (Util_ParseC_MatchKeyword(&thread, "numJoints")) { - LoadInt(modelanim->numtransforms, "after 'numJoints'"); - if (modelanim->numtransforms < 1) + LoadInt(modelanim->num_transforms, "after 'numJoints'"); + if (modelanim->num_transforms < 1) { - Console_Printf("ModelAnim_Load: numJoints %i < 1\n", modelanim->numtransforms); + Console_Printf("ModelAnim_Load: numJoints %i < 1\n", modelanim->num_transforms); Abort(); } } @@ -130,7 +130,7 @@ Console_Printf("ModelAnim_Load: numAnimatedComponents %i < 0\n", modelanim->numvaluesperframe); Abort(); } - if (modelanim->numvaluesperframe > modelanim->numtransforms * 6) + if (modelanim->numvaluesperframe > modelanim->num_transforms * 6) { Console_Printf("ModelAnim_Load: numAnimatedComponents %i > numJoints * 6\n", modelanim->numvaluesperframe); Abort(); @@ -141,7 +141,7 @@ { NUint32 jointnum; ExpectKeyword("{", "after 'hierarchy'"); - modelanim->transforminfo = Mem_Alloc(r->memzone, modelanim->numtransforms * sizeof(*modelanim->transforminfo)); + modelanim->transforminfo = Mem_Alloc(r->memzone, modelanim->num_transforms * sizeof(*modelanim->transforminfo)); for (jointnum = 0; !Util_ParseC_MatchKeyword(&thread, "}");jointnum++) { NSint32 parent; @@ -178,9 +178,9 @@ modelanim->transforminfo[jointnum].firstvalue = firstcomponent; modelanim->transforminfo[jointnum].numvalues = numcomponents; } - if (jointnum != modelanim->numtransforms) + if (jointnum != modelanim->num_transforms) { - Console_Printf("ModelAnim_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, modelanim->numtransforms); + Console_Printf("ModelAnim_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, modelanim->num_transforms); Abort(); } } @@ -215,7 +215,7 @@ { NUint32 jointnum; ExpectKeyword("{", "after 'baseframe'"); - modelanim->basevalues = Mem_Alloc(r->memzone, modelanim->numtransforms * 6 * sizeof(*modelanim->basevalues)); + modelanim->basevalues = Mem_Alloc(r->memzone, modelanim->num_transforms * 6 * sizeof(*modelanim->basevalues)); modelanim->values = Mem_Alloc(r->memzone, modelanim->numframes * modelanim->numvaluesperframe * sizeof(*modelanim->values)); for (jointnum = 0; !Util_ParseC_MatchKeyword(&thread, "}");jointnum++) { @@ -231,9 +231,9 @@ LoadValue(modelanim->basevalues[jointnum*6+5], "(joint 5)"); ExpectKeyword(")", "after second joint data list"); } - if (jointnum != modelanim->numtransforms) + if (jointnum != modelanim->num_transforms) { - Console_Printf("ModelAnim_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, modelanim->numtransforms); + Console_Printf("ModelAnim_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, modelanim->num_transforms); Abort(); } } @@ -291,7 +291,7 @@ modelanim = Resource_GetData(resourceindex); if (!modelanim) return 0; // no modelanim - return modelanim->numtransforms; + return modelanim->num_transforms; } NUint32 ModelAnim_GetNumFrames(NUint32 resourceindex) @@ -326,12 +326,12 @@ model = Resource_GetData(modelresource); if (!model) return; // no model - if (model->numtransforms != modelanim->numtransforms) + if (model->num_transforms != modelanim->num_transforms) return; // error v1 = modelanim->values + frame1 * modelanim->numvaluesperframe; v2 = modelanim->values + frame2 * modelanim->numvaluesperframe; b = modelanim->basevalues; - for (transformnum = 0, info = modelanim->transforminfo;transformnum < modelanim->numtransforms;transformnum++, info++, b += 6) + for (transformnum = 0, info = modelanim->transforminfo;transformnum < modelanim->num_transforms;transformnum++, info++, b += 6) { NUint32 component; NUint32 valueflags = info->valueflags; @@ -347,6 +347,6 @@ pose[component] = b[component]; } Matrix4x4_CreateFromDoom3Joint(&posematrix, pose[0], pose[1], pose[2], pose[3], pose[4], pose[5]); - Matrix4x4_Concat(&relativematrix, &posematrix, &model->baseinversetransforms[transformnum]); + Matrix4x4_Concat(&relativematrix, &posematrix, &model->data_transforminfo[transformnum].baseinversematrix); } } Modified: trunk/modelanim.h =================================================================== --- trunk/modelanim.h 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/modelanim.h 2006-04-08 21:12:01 UTC (rev 693) @@ -18,13 +18,13 @@ // the quaternions are stored as canonical unit vectors in which w is // assumed to be negative (it is easy to regenerate any one component of a // unit vector if you know its sign) - NUint32 numtransforms; + NUint32 num_transforms; NUint32 numvaluesperframe; NUint32 numframes; float framerate; - ModelAnim_TransformInfo *transforminfo; // [numtransforms] + ModelAnim_TransformInfo *transforminfo; // [num_transforms] float *values; // [numframes*numvaluesperframe] - float *basevalues; // [numtransforms*6] + float *basevalues; // [num_transforms*6] } ModelAnim; Modified: trunk/r_main.c =================================================================== --- trunk/r_main.c 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/r_main.c 2006-04-08 21:12:01 UTC (rev 693) @@ -1172,9 +1172,9 @@ if (R.shadowbuilder_maxshadowmarklist < R.shadowbuilder_numshadowmarklist + innumtris) { R.shadowbuilder_maxshadowmarklist = R.shadowbuilder_numshadowmarklist + innumtris + 256; - Mem_ReAlloc(R.zone, &R.shadowbuilder_shadowmark, R.shadowbuilder_maxshadowmarklist * sizeof(int)); - Mem_ReAlloc(R.zone, &R.shadowbuilder_shadowmarklist, R.shadowbuilder_maxshadowmarklist * sizeof(int)); - Mem_ReAlloc(R.zone, &R.shadowbuilder_shadowelements, R.shadowbuilder_maxshadowmarklist * 24 * sizeof(int)); + Mem_ReAlloc(R.zone, &R.shadowbuilder_shadowmark, R.shadowbuilder_maxshadowmarklist * sizeof(NUint32)); + Mem_ReAlloc(R.zone, &R.shadowbuilder_shadowmarklist, R.shadowbuilder_maxshadowmarklist * sizeof(NUint32)); + Mem_ReAlloc(R.zone, &R.shadowbuilder_shadowelements, R.shadowbuilder_maxshadowmarklist * 24 * sizeof(NUint32)); } // increment R.shadowbuilder_shadowmarknum for marking which triangles are @@ -1183,8 +1183,8 @@ // if R.shadowbuilder_vertexupdatenum wrapped, clear the arrays if (R.shadowbuilder_shadowmarknum == 0) { - memset(R.shadowbuilder_shadowmark, 0, R.shadowbuilder_maxshadowmarklist * sizeof(int)); - memset(R.shadowbuilder_shadowelements, 0, R.shadowbuilder_maxshadowmarklist * 24 * sizeof(int)); + memset(R.shadowbuilder_shadowmark, 0, R.shadowbuilder_maxshadowmarklist * sizeof(NUint32)); + memset(R.shadowbuilder_shadowelements, 0, R.shadowbuilder_maxshadowmarklist * 24 * sizeof(NUint32)); R.shadowbuilder_shadowmarknum = 1; } @@ -1192,8 +1192,8 @@ if (R.shadowbuilder_maxvertexupdate < innumvertices) { R.shadowbuilder_maxvertexupdate = innumvertices + 256; - Mem_ReAlloc(R.zone, &R.shadowbuilder_vertexupdate, R.shadowbuilder_maxvertexupdate * sizeof(int)); - Mem_ReAlloc(R.zone, &R.shadowbuilder_vertexremap, R.shadowbuilder_maxvertexupdate * sizeof(int)); + Mem_ReAlloc(R.zone, &R.shadowbuilder_vertexupdate, R.shadowbuilder_maxvertexupdate * sizeof(NUint32)); + Mem_ReAlloc(R.zone, &R.shadowbuilder_vertexremap, R.shadowbuilder_maxvertexupdate * sizeof(NUint32)); } // increment R.shadowbuilder_vertexupdatenum for marking which vertices @@ -1202,8 +1202,8 @@ // if R.shadowbuilder_vertexupdatenum wrapped, clear the arrays if (R.shadowbuilder_vertexupdatenum == 0) { - memset(R.shadowbuilder_vertexupdate, 0, R.shadowbuilder_maxvertexupdate * sizeof(int)); - memset(R.shadowbuilder_vertexremap, 0, R.shadowbuilder_maxvertexupdate * sizeof(int)); + memset(R.shadowbuilder_vertexupdate, 0, R.shadowbuilder_maxvertexupdate * sizeof(NUint32)); + memset(R.shadowbuilder_vertexremap, 0, R.shadowbuilder_maxvertexupdate * sizeof(NUint32)); R.shadowbuilder_vertexupdatenum = 1; } @@ -1920,13 +1920,13 @@ material = Resource_GetData(materialresource); if (!material) return; // TODO: warning - if (meshindex >= model->nummeshes) + if (meshindex >= model->num_meshes) return; // TODO: warning - mesh = model->meshes + meshindex; - if (mesh->numvertices <= 0 || mesh->numtriangles <= 0) + mesh = model->data_meshes + meshindex; + if (!mesh->num_vertices < 1 || mesh->num_triangles < 1) return; // TODO: warning - R.speeds_data.numdrawmesh_vertices += mesh->numvertices; - R.speeds_data.numdrawmesh_triangles += mesh->numtriangles; + R.speeds_data.numdrawmesh_vertices += mesh->num_vertices; + R.speeds_data.numdrawmesh_triangles += mesh->num_triangles; switch (R.drawmode) { case R_DRAWMODE_ZFILL: @@ -1937,9 +1937,9 @@ Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); } else - vertex3f = mesh->vertex3f; + vertex3f = mesh->data_vertex3f; qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f); - R_DrawTriangles(0, mesh->numvertices, mesh->numtriangles, mesh->element3i); + R_DrawTriangles(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); R_CheckError(); break; case R_DRAWMODE_SKY: @@ -1951,10 +1951,10 @@ Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); } else - vertex3f = mesh->vertex3f; + vertex3f = mesh->data_vertex3f; qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f); - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoord2f); - R_DrawTriangles(0, mesh->numvertices, mesh->numtriangles, mesh->element3i); + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->data_texcoord2f); + R_DrawTriangles(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); R_CheckError(); break; case R_DRAWMODE_BACKGROUND: @@ -1965,15 +1965,15 @@ Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); } else - vertex3f = mesh->vertex3f; - for (i = 0, v = vertex3f, tc = R.varray_texcoord2f;i < mesh->numvertices;i++, v += 3, tc += 2) + vertex3f = mesh->data_vertex3f; + for (i = 0, v = vertex3f, tc = R.varray_texcoord2f;i < mesh->num_vertices;i++, v += 3, tc += 2) { tc[0] = VectorDistance(v, R.entityeyeorigin) * R.fog_rangerecip; tc[1] = 0; } qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f); qglClientActiveTextureARB(GL_TEXTURE0_ARB); - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoord2f); + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->data_texcoord2f); qglClientActiveTextureARB(GL_TEXTURE1_ARB); qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), R.varray_texcoord2f); @@ -1994,14 +1994,14 @@ R_CheckError(); R_SetBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - R_DrawTriangles(0, mesh->numvertices, mesh->numtriangles, mesh->element3i); + R_DrawTriangles(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); // fog darkening qglEnable(GL_TEXTURE_2D); R_CheckError(); R_SetBlendFunc(GL_SRC_ALPHA, GL_ONE); - R_DrawTriangles(0, mesh->numvertices, mesh->numtriangles, mesh->element3i); + R_DrawTriangles(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); R_CheckError(); break; case R_DRAWMODE_UNLIT: @@ -2016,18 +2016,18 @@ Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); } else - vertex3f = mesh->vertex3f; - for (i = 0, v = vertex3f, tc = R.varray_texcoord2f;i < mesh->numvertices;i++, v += 3, tc += 2) + vertex3f = mesh->data_vertex3f; + for (i = 0, v = vertex3f, tc = R.varray_texcoord2f;i < mesh->num_vertices;i++, v += 3, tc += 2) { tc[0] = VectorDistance(v, R.entityeyeorigin) * R.fog_rangerecip; tc[1] = 0; } qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f); qglClientActiveTextureARB(GL_TEXTURE0_ARB); - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoord2f); + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->data_texcoord2f); qglClientActiveTextureARB(GL_TEXTURE1_ARB); qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), R.varray_texcoord2f); - R_DrawTriangles(0, mesh->numvertices, mesh->numtriangles, mesh->element3i); + R_DrawTriangles(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); R_CheckError(); break; case R_DRAWMODE_LIT_SHADOWVOLUME: @@ -2041,11 +2041,11 @@ } else { - vertex3f = mesh->vertex3f; - plane4f = mesh->plane4f; + vertex3f = mesh->data_vertex3f; + plane4f = mesh->data_plane4f; } // generate shadowvolume in R.varray_vertex3f2 from vertex3f - tris = R_ConstructShadowVolume(mesh->numvertices, mesh->numtriangles, mesh->element3i, mesh->neighbor3i, vertex3f, &outverts, plane4f); + tris = R_ConstructShadowVolume(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, mesh->data_neighbor3i, vertex3f, &outverts, plane4f); qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), R.varray_vertex3f2); if (R.drawmode == R_DRAWMODE_LIT_VISIBLESHADOWVOLUME) { @@ -2109,10 +2109,10 @@ } else { - vertex3f = mesh->vertex3f; - svector3f = mesh->svector3f; - tvector3f = mesh->tvector3f; - normal3f = mesh->normal3f; + vertex3f = mesh->data_vertex3f; + svector3f = mesh->data_svector3f; + tvector3f = mesh->data_tvector3f; + normal3f = mesh->data_normal3f; } // bind the 3 material textures and the light cubemap and the fog mask texture @@ -2139,7 +2139,7 @@ // bind the texcoord and tangentspace vector arrays qglClientActiveTextureARB(GL_TEXTURE0_ARB); - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoord2f); + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->data_texcoord2f); qglClientActiveTextureARB(GL_TEXTURE1_ARB); qglTexCoordPointer(3, GL_FLOAT, sizeof(float[3]), svector3f); @@ -2189,7 +2189,7 @@ if (s->loc_SpecularScale >= 0) qglUniform1fARB(s->loc_SpecularScale, specularintensity); - R_DrawTriangles(0, mesh->numvertices, mesh->numtriangles, mesh->element3i); + R_DrawTriangles(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); R_CheckError(); break; case R_DRAWMODE_LIT_FINISH: @@ -2204,18 +2204,18 @@ Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); } else - vertex3f = mesh->vertex3f; - for (i = 0, v = vertex3f, tc = R.varray_texcoord2f;i < mesh->numvertices;i++, v += 3, tc += 2) + vertex3f = mesh->data_vertex3f; + for (i = 0, v = vertex3f, tc = R.varray_texcoord2f;i < mesh->num_vertices;i++, v += 3, tc += 2) { tc[0] = VectorDistance(v, R.entityeyeorigin) * R.fog_rangerecip; tc[1] = 0; } qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f); qglClientActiveTextureARB(GL_TEXTURE0_ARB); - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoord2f); + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->data_texcoord2f); qglClientActiveTextureARB(GL_TEXTURE1_ARB); qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), R.varray_texcoord2f); - R_DrawTriangles(0, mesh->numvertices, mesh->numtriangles, mesh->element3i); + R_DrawTriangles(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); R_CheckError(); break; case R_DRAWMODE_HUD: @@ -2227,10 +2227,10 @@ Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); } else - vertex3f = mesh->vertex3f; + vertex3f = mesh->data_vertex3f; qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f); - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->texcoord2f); - R_DrawTriangles(0, mesh->numvertices, mesh->numtriangles, mesh->element3i); + qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), mesh->data_texcoord2f); + R_DrawTriangles(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i); R_CheckError(); break; case R_DRAWMODE_LINES: @@ -2242,17 +2242,17 @@ Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); } else - vertex3f = mesh->vertex3f; + vertex3f = mesh->data_vertex3f; qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f); qglBegin(GL_LINES); - for (i = 0;i < mesh->numtriangles;i++) + for (i = 0;i < mesh->num_triangles;i++) { - qglArrayElement(mesh->element3i[i*3+0]); - qglArrayElement(mesh->element3i[i*3+1]); - qglArrayElement(mesh->element3i[i*3+1]); - qglArrayElement(mesh->element3i[i*3+2]); - qglArrayElement(mesh->element3i[i*3+2]); - qglArrayElement(mesh->element3i[i*3+0]); + qglArrayElement(mesh->data_element3i[i*3+0]); + qglArrayElement(mesh->data_element3i[i*3+1]); + qglArrayElement(mesh->data_element3i[i*3+1]); + qglArrayElement(mesh->data_element3i[i*3+2]); + qglArrayElement(mesh->data_element3i[i*3+2]); + qglArrayElement(mesh->data_element3i[i*3+0]); } qglEnd(); R_CheckError(); Modified: trunk/util.c =================================================================== --- trunk/util.c 2006-04-08 21:09:02 UTC (rev 692) +++ trunk/util.c 2006-04-08 21:12:01 UTC (rev 693) @@ -312,7 +312,7 @@ if (surface->num_triangles >= surface->max_triangles) { surface->max_triangles = Max(surface->max_triangles * 2, 1024); - Mem_ReAlloc(Global_Zone, &surface->data_element3i, surface->max_triangles * sizeof(int[3])); + Mem_ReAlloc(Global_Zone, &surface->data_element3i, surface->max_triangles * sizeof(NUint32[3])); } e = surface->data_element3i + surface->num_triangles * 3; e[0] = e0; @@ -879,11 +879,11 @@ tileheight = Bound(0, height - by, tilesize+2); //memset(mesh, 0, sizeof(mesh)); mesh->materialname = materialname; - mesh->vertex3f = Mem_Alloc(Global_Zone, (tilesize+2)*(tilesize+2) * sizeof(float[3])); - mesh->texcoord2f = Mem_Alloc(Global_Zone, (tilesize+2)*(tilesize+2) * sizeof(float[2])); - mesh->element3i = Mem_Alloc(Global_Zone, (tilesize+1)*(tilesize+1)*2 * sizeof(NUint32[3])); - mesh->numvertices = tilewidth*tileheight; - mesh->numtriangles = (tilewidth-1)*(tileheight-1)*2; + mesh->data_vertex3f = Mem_Alloc(Global_Zone, (tilesize+2)*(tilesize+2) * sizeof(float[3])); + mesh->data_texcoord2f = Mem_Alloc(Global_Zone, (tilesize+2)*(tilesize+2) * sizeof(float[2])); + mesh->data_element3i = Mem_Alloc(Global_Zone, (tilesize+1)*(tilesize+1)*2 * sizeof(NUint32[3])); + mesh->num_vertices = tilewidth*tileheight; + mesh->num_triangles = (tilewidth-1)*(tileheight-1)*2; for (ty = 0, num = 0;ty < tileheight;ty++) { for (tx = 0;tx < tilewidth;tx++, num++) @@ -900,11 +900,11 @@ pyf = py - pyi; p = pixels + (pyi * width + pxi) * 4; pz = ((p[0]+p[1]+p[2])*(1.0-pxf)+(p[4]+p[5]+p[6])*(pxf))*(1.0-pyf)+((p[w+0]+p[w+1]+p[w+2])*(1.0-pxf)+(p[w+4]+p[w+5]+p[w+6])*(pxf))*(pyf); - mesh->vertex3f[num*3+0] = px * terrainscale[0] + terrainorigin[0]; - mesh->vertex3f[num*3+1] = py * terrainscale[1] + terrainorigin[1]; - mesh->vertex3f[num*3+2] = pz * terrainscale[2] + terrainorigin[2]; - mesh->texcoord2f[num*2+0] = mesh->vertex3f[num*3+0] * texturescale[0]; - mesh->texcoord2f[num*2+1] = mesh->vertex3f[num*3+1] * texturescale[1]; + mesh->data_vertex3f[num*3+0] = px * terrainscale[0] + terrainorigin[0]; + mesh->data_vertex3f[num*3+1] = py * terrainscale[1] + terrainorigin[1]; + mesh->data_vertex3f[num*3+2] = pz * terrainscale[2] + terrainorigin[2]; + mesh->data_texcoord2f[num*2+0] = mesh->data_vertex3f[num*3+0] * texturescale[0]; + mesh->data_texcoord2f[num*2+1] = mesh->data_vertex3f[num*3+1] * texturescale[1]; } } for (ty = 0, num = 0;ty < tileheight-1;ty++) @@ -912,12 +912,12 @@ for (tx = 0;tx < tilewidth-1;tx++, num += 6) { NUint32 b = ty*tilewidth+tx; - mesh->element3i[num+0] = b; - mesh->element3i[num+1] = b+1; - mesh->element3i[num+2] = b+1+tilewidth; - mesh->element3i[num+3] = b; - mesh->element3i[num+4] = b+1+tilewidth; - mesh->element3i[num+5] = b+tilewidth; + mesh->data_element3i[num+0] = b; + mesh->data_element3i[num+1] = b+1; + mesh->data_element3i[num+2] = b+1+tilewidth; + mesh->data_element3i[num+3] = b; + mesh->data_element3i[num+4] = b+1+tilewidth; + mesh->data_element3i[num+5] = b+tilewidth; } } mesh++; @@ -929,9 +929,9 @@ Mem_Free(&pixels); for (i = 0, mesh = meshes;i < nummeshes;i++, mesh++) { - Mem_Free(&mesh->vertex3f); - Mem_Free(&mesh->texcoord2f); - Mem_Free(&mesh->element3i); + Mem_Free(&mesh->data_vertex3f); + Mem_Free(&mesh->data_texcoord2f); + Mem_Free(&mesh->data_element3i); } Mem_Free(&meshes); } From lordhavoc at icculus.org Sat Apr 8 17:49:27 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 8 Apr 2006 17:49:27 -0400 Subject: r694 - trunk Message-ID: <20060408214927.27496.qmail@icculus.org> Author: lordhavoc Date: 2006-04-08 17:49:27 -0400 (Sat, 08 Apr 2006) New Revision: 694 Modified: trunk/r_main.c Log: fix stupid bug in last commit Modified: trunk/r_main.c =================================================================== --- trunk/r_main.c 2006-04-08 21:12:01 UTC (rev 693) +++ trunk/r_main.c 2006-04-08 21:49:27 UTC (rev 694) @@ -1923,7 +1923,7 @@ if (meshindex >= model->num_meshes) return; // TODO: warning mesh = model->data_meshes + meshindex; - if (!mesh->num_vertices < 1 || mesh->num_triangles < 1) + if (mesh->num_vertices < 1 || mesh->num_triangles < 1) return; // TODO: warning R.speeds_data.numdrawmesh_vertices += mesh->num_vertices; R.speeds_data.numdrawmesh_triangles += mesh->num_triangles; From lordhavoc at icculus.org Sat Apr 8 17:50:07 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 8 Apr 2006 17:50:07 -0400 Subject: r695 - trunk Message-ID: <20060408215007.27611.qmail@icculus.org> Author: lordhavoc Date: 2006-04-08 17:50:07 -0400 (Sat, 08 Apr 2006) New Revision: 695 Modified: trunk/model.c Log: calculate strongest 4 vertex weights on each vertex, this is in preparation for matrix-palette skeletal animation code Modified: trunk/model.c =================================================================== --- trunk/model.c 2006-04-08 21:49:27 UTC (rev 694) +++ trunk/model.c 2006-04-08 21:50:07 UTC (rev 695) @@ -502,17 +502,44 @@ for (i = 0;i < mesh->num_vertices;i++) { Ndouble sum = 0; + NUint32 k; for (j = 0, md5weight = md5weights + md5weightrange[i*2+0];j < md5weightrange[i*2+1];j++, md5weight++) { matrix = &model->data_transforminfo[md5weight->jointnum].basematrix; mesh->data_vertex3f[i*3+0] += DotProduct4(md5weight->vertex, matrix->m[0]); mesh->data_vertex3f[i*3+1] += DotProduct4(md5weight->vertex, matrix->m[1]); mesh->data_vertex3f[i*3+2] += DotProduct4(md5weight->vertex, matrix->m[2]); + // store the best weights in the vertex's limited number of blend weights + for (k = 4;k >= 1 && mesh->data_weightvalue4f[i*4+k-1] < md5weight->vertex[3];k--) + { + if (k < 4) + { + mesh->data_weightindex4i[i*4+k] = mesh->data_weightindex4i[i*4+k-1]; + mesh->data_weightvalue4f[i*4+k] = mesh->data_weightvalue4f[i*4+k-1]; + } + } + if (k < 4) + { + mesh->data_weightindex4i[i*4+k] = md5weight->jointnum; + mesh->data_weightvalue4f[i*4+k] = md5weight->vertex[3]; + } sum += md5weight->vertex[3]; mesh->num_weights++; } if (fabs(sum - 1) > 0.001) Console_Printf("vertex #%i (weights %i-%i) does not sum to 1! (sum = %f)\n", i, md5weightrange[i*2+0], md5weightrange[i*2+0]+md5weightrange[i*2+1], sum); + if (mesh->data_weightvalue4f[i*4+3] > mesh->data_weightvalue4f[i*4+2] || mesh->data_weightvalue4f[i*4+2] > mesh->data_weightvalue4f[i*4+1] || mesh->data_weightvalue4f[i*4+1] > mesh->data_weightvalue4f[i*4+0]) + Console_Printf("vertex sorting error! vertex #%i has weights %i:%f %i:%f %i:%f %i:%f\n", i, mesh->data_weightindex4i[i*4+0], mesh->data_weightvalue4f[i*4+0], mesh->data_weightindex4i[i*4+1], mesh->data_weightvalue4f[i*4+1], mesh->data_weightindex4i[i*4+2], mesh->data_weightvalue4f[i*4+2], mesh->data_weightindex4i[i*4+3], mesh->data_weightvalue4f[i*4+3]); + // renormalize the array of strongest weights on this vertex + sum = 0; + for (k = 0;k < 4;k++) + sum += mesh->data_weightvalue4f[i*4+k]; + if (sum) + { + sum = 1.0f / sum; + for (k = 0;k < 4;k++) + mesh->data_weightvalue4f[i*4+k] *= sum; + } } // compile the base frame of the mesh for static uses Model_MeshVectors(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f); From lordhavoc at icculus.org Sat Apr 8 22:53:10 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 8 Apr 2006 22:53:10 -0400 Subject: r696 - trunk Message-ID: <20060409025310.1205.qmail@icculus.org> Author: lordhavoc Date: 2006-04-08 22:53:10 -0400 (Sat, 08 Apr 2006) New Revision: 696 Modified: trunk/model.c trunk/model.h trunk/r_main.c Log: changed skeletal animation blending code to use the matrix palette method (not yet hardware accelerated), this eliminates the weights array Modified: trunk/model.c =================================================================== --- trunk/model.c 2006-04-08 21:50:07 UTC (rev 695) +++ trunk/model.c 2006-04-09 02:53:10 UTC (rev 696) @@ -343,7 +343,6 @@ Model_MD5_Weight *md5weights = NULL, *md5weight = NULL; NUint32 *md5weightrange = NULL; NUint32 i, j; - Model_Weight *weight; matrix4x4_t *matrix; ExpectKeyword("{", "after 'mesh'"); @@ -498,7 +497,6 @@ } } memset(mesh->data_vertex3f, 0, mesh->num_vertices * sizeof(float[3])); - mesh->num_weights = 0; for (i = 0;i < mesh->num_vertices;i++) { Ndouble sum = 0; @@ -524,7 +522,6 @@ mesh->data_weightvalue4f[i*4+k] = md5weight->vertex[3]; } sum += md5weight->vertex[3]; - mesh->num_weights++; } if (fabs(sum - 1) > 0.001) Console_Printf("vertex #%i (weights %i-%i) does not sum to 1! (sum = %f)\n", i, md5weightrange[i*2+0], md5weightrange[i*2+0]+md5weightrange[i*2+1], sum); @@ -551,12 +548,10 @@ mesh->max_collisionbrushes = mesh->num_collisionbrushes; mesh->data_collisionbrushes = Collision_Brush_AllocBrushesForTriangleMesh(r->memzone, mesh->max_triangles); Collision_Brush_UpdateTriangleMeshBrushes(mesh->data_collisionbrushes, mesh->num_triangles, mesh->data_element3i, mesh->data_vertex3f); - // regenerate the weights from the static mesh and influences, - // because we need weights with svector/tvector/normal information - mesh->weights = Mem_Alloc(r->memzone, mesh->num_weights * sizeof(Model_Weight)); - weight = mesh->weights; + // calculate culling shapes for (i = 0;i < mesh->num_vertices;i++) { + NUint32 k; if (!i && !meshnum) { VectorCopy(mesh->data_vertex3f, model->basecullmins); @@ -585,30 +580,15 @@ mesh->basecullmaxs[1] = Max(mesh->basecullmaxs[1], mesh->data_vertex3f[i * 3 + 1]); mesh->basecullmaxs[2] = Max(mesh->basecullmaxs[2], mesh->data_vertex3f[i * 3 + 2]); } - for (j = 0, md5weight = md5weights + md5weightrange[i*2+0];j < md5weightrange[i*2+1];j++, md5weight++) + for (k = 0;k < 4 && mesh->data_weightvalue4f[i*4+k] > 0;k++) { - float r; - // copy properties from the md5weight struct - weight->vertexindex = i; - weight->transformindex = md5weight->jointnum; - weight->vertex[0] = md5weight->vertex[0]; - weight->vertex[1] = md5weight->vertex[1]; - weight->vertex[2] = md5weight->vertex[2]; - weight->vertex[3] = md5weight->vertex[3]; - // calculate weights for the tangent space vectors - matrix = &model->data_transforminfo[weight->transformindex].basematrix; - weight->svector[0] = (mesh->data_svector3f[i*3+0] * matrix->m[0][0] + mesh->data_svector3f[i*3+1] * matrix->m[1][0] + mesh->data_svector3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; - weight->svector[1] = (mesh->data_svector3f[i*3+0] * matrix->m[0][1] + mesh->data_svector3f[i*3+1] * matrix->m[1][1] + mesh->data_svector3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; - weight->svector[2] = (mesh->data_svector3f[i*3+0] * matrix->m[0][2] + mesh->data_svector3f[i*3+1] * matrix->m[1][2] + mesh->data_svector3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; - weight->tvector[0] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][0] + mesh->data_tvector3f[i*3+1] * matrix->m[1][0] + mesh->data_tvector3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; - weight->tvector[1] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][1] + mesh->data_tvector3f[i*3+1] * matrix->m[1][1] + mesh->data_tvector3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; - weight->tvector[2] = (mesh->data_tvector3f[i*3+0] * matrix->m[0][2] + mesh->data_tvector3f[i*3+1] * matrix->m[1][2] + mesh->data_tvector3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; - weight->normal[0] = (mesh->data_normal3f[i*3+0] * matrix->m[0][0] + mesh->data_normal3f[i*3+1] * matrix->m[1][0] + mesh->data_normal3f[i*3+2] * matrix->m[2][0]) * weight->vertex[3]; - weight->normal[1] = (mesh->data_normal3f[i*3+0] * matrix->m[0][1] + mesh->data_normal3f[i*3+1] * matrix->m[1][1] + mesh->data_normal3f[i*3+2] * matrix->m[2][1]) * weight->vertex[3]; - weight->normal[2] = (mesh->data_normal3f[i*3+0] * matrix->m[0][2] + mesh->data_normal3f[i*3+1] * matrix->m[1][2] + mesh->data_normal3f[i*3+2] * matrix->m[2][2]) * weight->vertex[3]; - r = VectorLength(weight->vertex) / weight->vertex[3]; - model->data_transforminfo[weight->transformindex].radius = Max(model->data_transforminfo[weight->transformindex].radius, r); - weight++; + NUint32 index = mesh->data_weightindex4i[i*4+k]; + Nvec3 v1, v; + Nvec r; + VectorCopy(mesh->data_vertex3f + i * 3, v1); + Matrix4x4_Transform(&model->data_transforminfo[index].baseinversematrix, v1, v); + r = VectorLength(v); + model->data_transforminfo[index].radius = Max(model->data_transforminfo[index].radius, r); } } Mem_Free(&md5weights); @@ -640,11 +620,29 @@ ////////////////////////////////////////////////////////////////////////////// // this function decodes weights to produce a renderable or collidable mesh -void Model_GetVertices(Model_Mesh *mesh, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f) +void Model_GetVertices(NUint32 resourceindex, NUint32 meshindex, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f) { + Model *model; + Model_Mesh *mesh; + const float *v; + const float *sv; + const float *tv; + const float *n; +#if 1 + NUint32 j, k, index; + const matrix4x4_t *matrix; + matrix4x4_t relativematrix[256]; // FIXME!! +#else NUint32 j, index; Model_Weight *weight; const matrix4x4_t *matrix; +#endif + model = Resource_GetData(resourceindex); + if (!model) + return; // no model + if (meshindex >= model->num_meshes) + return; // invalid mesh index + mesh = model->data_meshes + meshindex; if (!transforms) { if (outvertex3f) @@ -669,79 +667,52 @@ memset(outtvector3f, 0, mesh->num_vertices * sizeof(float[3])); if (outnormal3f) memset(outnormal3f, 0, mesh->num_vertices * sizeof(float[3])); - // TODO: SSE assembly support - if (outvertex3f && outsvector3f && outtvector3f && outnormal3f) + v = mesh->data_vertex3f; + sv = mesh->data_svector3f; + tv = mesh->data_tvector3f; + n = mesh->data_normal3f; + for (j = 0;j < model->num_transforms;j++) + Matrix4x4_Concat(relativematrix + j, transforms + j, &model->data_transforminfo[j].baseinversematrix); + for (j = 0, index = 0;j < mesh->num_vertices;j++, index += 3) { - // fastpath for all properties at once - for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) + float value; + for (k = 0;k < 4 && (value = mesh->data_weightvalue4f[j*4+k]);k++) { - matrix = transforms + weight->transformindex; - index = weight->vertexindex*3; - outvertex3f[index+0] += DotProduct4(weight->vertex, matrix->m[0]); - outvertex3f[index+1] += DotProduct4(weight->vertex, matrix->m[1]); - outvertex3f[index+2] += DotProduct4(weight->vertex, matrix->m[2]); - outsvector3f[index+0] += DotProduct(weight->svector, matrix->m[0]); - outsvector3f[index+1] += DotProduct(weight->svector, matrix->m[1]); - outsvector3f[index+2] += DotProduct(weight->svector, matrix->m[2]); - outtvector3f[index+0] += DotProduct(weight->tvector, matrix->m[0]); - outtvector3f[index+1] += DotProduct(weight->tvector, matrix->m[1]); - outtvector3f[index+2] += DotProduct(weight->tvector, matrix->m[2]); - outnormal3f[index+0] += DotProduct(weight->normal, matrix->m[0]); - outnormal3f[index+1] += DotProduct(weight->normal, matrix->m[1]); - outnormal3f[index+2] += DotProduct(weight->normal, matrix->m[2]); + matrix = relativematrix + mesh->data_weightindex4i[j*4+k]; + if (outvertex3f) + { + outvertex3f[index+0] += value * (DotProduct(v + index, matrix->m[0]) + matrix->m[0][3]); + outvertex3f[index+1] += value * (DotProduct(v + index, matrix->m[1]) + matrix->m[1][3]); + outvertex3f[index+2] += value * (DotProduct(v + index, matrix->m[2]) + matrix->m[2][3]); + } + if (outsvector3f) + { + outsvector3f[index+0] += value * DotProduct(sv + index, matrix->m[0]); + outsvector3f[index+1] += value * DotProduct(sv + index, matrix->m[1]); + outsvector3f[index+2] += value * DotProduct(sv + index, matrix->m[2]); + } + if (outtvector3f) + { + outtvector3f[index+0] += value * DotProduct(tv + index, matrix->m[0]); + outtvector3f[index+1] += value * DotProduct(tv + index, matrix->m[1]); + outtvector3f[index+2] += value * DotProduct(tv + index, matrix->m[2]); + } + if (outnormal3f) + { + outnormal3f[index+0] += value * DotProduct(n + index, matrix->m[0]); + outnormal3f[index+1] += value * DotProduct(n + index, matrix->m[1]); + outnormal3f[index+2] += value * DotProduct(n + index, matrix->m[2]); + } } - if (outplane4f) - Model_BuildTrianglePlanes(outvertex3f, mesh->num_triangles, mesh->data_element3i, outplane4f); - return; + if (outsvector3f) + VectorNormalize(outsvector3f + index); + if (outtvector3f) + VectorNormalize(outtvector3f + index); + if (outnormal3f) + VectorNormalize(outnormal3f + index); } - // partial request, handle each in turn (usually only vertex) - // FIXME: would it be worth saving separate weights for vertex? - if (outvertex3f) - { - for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) - { - matrix = transforms + weight->transformindex; - index = weight->vertexindex*3; - outvertex3f[index+0] += DotProduct4(weight->vertex, matrix->m[0]); - outvertex3f[index+1] += DotProduct4(weight->vertex, matrix->m[1]); - outvertex3f[index+2] += DotProduct4(weight->vertex, matrix->m[2]); - } - if (outplane4f) - Model_BuildTrianglePlanes(outvertex3f, mesh->num_triangles, mesh->data_element3i, outplane4f); - } - if (outsvector3f) - { - for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) - { - matrix = transforms + weight->transformindex; - index = weight->vertexindex*3; - outsvector3f[index+0] += DotProduct(weight->svector, matrix->m[0]); - outsvector3f[index+1] += DotProduct(weight->svector, matrix->m[1]); - outsvector3f[index+2] += DotProduct(weight->svector, matrix->m[2]); - } - } - if (outtvector3f) - { - for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) - { - matrix = transforms + weight->transformindex; - index = weight->vertexindex*3; - outtvector3f[index+0] += DotProduct(weight->tvector, matrix->m[0]); - outtvector3f[index+1] += DotProduct(weight->tvector, matrix->m[1]); - outtvector3f[index+2] += DotProduct(weight->tvector, matrix->m[2]); - } - } - if (outnormal3f) - { - for (j = 0, weight = mesh->weights;j < mesh->num_weights;j++, weight++) - { - matrix = transforms + weight->transformindex; - index = weight->vertexindex*3; - outnormal3f[index+0] += DotProduct(weight->normal, matrix->m[0]); - outnormal3f[index+1] += DotProduct(weight->normal, matrix->m[1]); - outnormal3f[index+2] += DotProduct(weight->normal, matrix->m[2]); - } - } + if (outvertex3f && outplane4f) + Model_BuildTrianglePlanes(outvertex3f, mesh->num_triangles, mesh->data_element3i, outplane4f); } void Model_GetCullBox(NUint32 modelresource, const matrix4x4_t *transforms, Nvec3 cullmins, Nvec3 cullmaxs) @@ -818,7 +789,7 @@ // by vertex number to make this faster (no intermediate buffer involved) NUint32 i; float *v, *vertex3f = Mem_Alloc(Global_Zone, mesh->num_vertices * sizeof(float[3])); - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); + Model_GetVertices(modelresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL); VectorCopy(vertex3f, cullmins); VectorCopy(vertex3f, cullmaxs); for (i = 0, v = vertex3f;i < mesh->num_vertices;i++, v += 3) Modified: trunk/model.h =================================================================== --- trunk/model.h 2006-04-08 21:50:07 UTC (rev 695) +++ trunk/model.h 2006-04-09 02:53:10 UTC (rev 696) @@ -18,27 +18,6 @@ } Model_TransformInfo; -typedef struct Model_Weight -{ - // this struct is intended to be easy for SSE 4 component math ops - // x y z and influence, x y z are prescaled by influence, so this is a - // simple DotProduct4 with the matrix. - float vertex[4]; - // x y z of vector along S texcoord (tangent space) - float svector[3]; - // number of vertex this weight influences - NUint32 vertexindex; - // x y z of vector along T texcoord (tangent space) - float tvector[3]; - // number of transform this weight is relative to - NUint32 transformindex; - // x y z of vector along normal (tangent space) - float normal[3]; - // unused space to pad this to 64 bytes - float pad; -} -Model_Weight; - typedef struct Model_Mesh { char *materialname; @@ -83,14 +62,6 @@ // blending influence values of up to 4 transforms per vertex float *data_weightvalue4f; -#if 1 - // number of skeletal transforms to blend onto the vertex array - // (always >= numvertices) - NUint32 num_weights; - // skeletal transform weights - Model_Weight *weights; -#endif - Nvec3 basecullmins; Nvec3 basecullmaxs; @@ -104,7 +75,6 @@ } Model_Mesh; - typedef struct Model { NUint32 num_meshes; @@ -125,7 +95,7 @@ // this function decodes skeletal vertex information to your supplied arrays // NOTE: outplane4f requires outvertex3f -void Model_GetVertices(Model_Mesh *mesh, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f); +void Model_GetVertices(NUint32 resourceindex, NUint32 meshindex, const matrix4x4_t *transforms, float *outvertex3f, float *outsvector3f, float *outtvector3f, float *outnormal3f, float *outplane4f); void Model_GetCullBox(NUint32 modelresource, const matrix4x4_t *transforms, Nvec3 cullmins, Nvec3 cullmaxs); void Model_GetMeshCullBox(NUint32 modelresource, NUint32 meshindex, const matrix4x4_t *transforms, Nvec3 cullmins, Nvec3 cullmaxs); NSint32 Model_GetTransformNumberForName(NUint32 modelresource, const char *name); Modified: trunk/r_main.c =================================================================== --- trunk/r_main.c 2006-04-08 21:50:07 UTC (rev 695) +++ trunk/r_main.c 2006-04-09 02:53:10 UTC (rev 696) @@ -1934,7 +1934,7 @@ if (transforms) { vertex3f = R.varray_vertex3f; - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL); } else vertex3f = mesh->data_vertex3f; @@ -1948,7 +1948,7 @@ if (transforms) { vertex3f = R.varray_vertex3f; - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL); } else vertex3f = mesh->data_vertex3f; @@ -1962,7 +1962,7 @@ if (transforms) { vertex3f = R.varray_vertex3f; - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL); } else vertex3f = mesh->data_vertex3f; @@ -2013,7 +2013,7 @@ if (transforms) { vertex3f = R.varray_vertex3f; - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL); } else vertex3f = mesh->data_vertex3f; @@ -2037,7 +2037,7 @@ { vertex3f = R.varray_vertex3f; plane4f = R.varray_plane4f; - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, plane4f); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, plane4f); } else { @@ -2105,7 +2105,7 @@ svector3f = R.varray_svector3f; tvector3f = R.varray_tvector3f; normal3f = R.varray_normal3f; - Model_GetVertices(mesh, transforms, vertex3f, svector3f, tvector3f, normal3f, NULL); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, svector3f, tvector3f, normal3f, NULL); } else { @@ -2201,7 +2201,7 @@ if (transforms) { vertex3f = R.varray_vertex3f; - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL); } else vertex3f = mesh->data_vertex3f; @@ -2224,7 +2224,7 @@ if (transforms) { vertex3f = R.varray_vertex3f; - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL); } else vertex3f = mesh->data_vertex3f; @@ -2239,7 +2239,7 @@ if (transforms) { vertex3f = R.varray_vertex3f; - Model_GetVertices(mesh, transforms, vertex3f, NULL, NULL, NULL, NULL); + Model_GetVertices(materialresource, meshindex, transforms, vertex3f, NULL, NULL, NULL, NULL); } else vertex3f = mesh->data_vertex3f; From lordhavoc at icculus.org Sat Apr 8 23:10:04 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 8 Apr 2006 23:10:04 -0400 Subject: r697 - trunk Message-ID: <20060409031004.3316.qmail@icculus.org> Author: lordhavoc Date: 2006-04-08 23:10:04 -0400 (Sat, 08 Apr 2006) New Revision: 697 Modified: trunk/model.c trunk/model.h Log: changed weight format to bytes to save memory (still vertex shader friendly) Modified: trunk/model.c =================================================================== --- trunk/model.c 2006-04-09 02:53:10 UTC (rev 696) +++ trunk/model.c 2006-04-09 03:10:04 UTC (rev 697) @@ -377,8 +377,8 @@ mesh->data_normal3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3])); mesh->data_texcoord2f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[2])); mesh->data_lightmaptexcoord2f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[2])); - mesh->data_weightindex4i = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint32[4])); - mesh->data_weightvalue4f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[4])); + mesh->data_weightindex4b = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint8[4])); + mesh->data_weightvalue4b = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint8[4])); md5weightrange = Mem_Alloc(Global_Zone, mesh->max_vertices * sizeof(NUint32[2])); } // vert 0 ( 0.142532 0.983877 ) 0 1 @@ -501,6 +501,10 @@ { Ndouble sum = 0; NUint32 k; + NUint32 wi[4]; + Nfloat wf[4]; + Vector4Clear(wi); + Vector4Clear(wf); for (j = 0, md5weight = md5weights + md5weightrange[i*2+0];j < md5weightrange[i*2+1];j++, md5weight++) { matrix = &model->data_transforminfo[md5weight->jointnum].basematrix; @@ -508,35 +512,41 @@ mesh->data_vertex3f[i*3+1] += DotProduct4(md5weight->vertex, matrix->m[1]); mesh->data_vertex3f[i*3+2] += DotProduct4(md5weight->vertex, matrix->m[2]); // store the best weights in the vertex's limited number of blend weights - for (k = 4;k >= 1 && mesh->data_weightvalue4f[i*4+k-1] < md5weight->vertex[3];k--) + for (k = 4;k >= 1 && mesh->data_weightvalue4b[i*4+k-1] < md5weight->vertex[3];k--) { if (k < 4) { - mesh->data_weightindex4i[i*4+k] = mesh->data_weightindex4i[i*4+k-1]; - mesh->data_weightvalue4f[i*4+k] = mesh->data_weightvalue4f[i*4+k-1]; + wi[k] = wi[k-1]; + wf[k] = wf[k-1]; } } if (k < 4) { - mesh->data_weightindex4i[i*4+k] = md5weight->jointnum; - mesh->data_weightvalue4f[i*4+k] = md5weight->vertex[3]; + wi[k] = md5weight->jointnum; + wf[k] = md5weight->vertex[3]; } sum += md5weight->vertex[3]; } if (fabs(sum - 1) > 0.001) Console_Printf("vertex #%i (weights %i-%i) does not sum to 1! (sum = %f)\n", i, md5weightrange[i*2+0], md5weightrange[i*2+0]+md5weightrange[i*2+1], sum); - if (mesh->data_weightvalue4f[i*4+3] > mesh->data_weightvalue4f[i*4+2] || mesh->data_weightvalue4f[i*4+2] > mesh->data_weightvalue4f[i*4+1] || mesh->data_weightvalue4f[i*4+1] > mesh->data_weightvalue4f[i*4+0]) - Console_Printf("vertex sorting error! vertex #%i has weights %i:%f %i:%f %i:%f %i:%f\n", i, mesh->data_weightindex4i[i*4+0], mesh->data_weightvalue4f[i*4+0], mesh->data_weightindex4i[i*4+1], mesh->data_weightvalue4f[i*4+1], mesh->data_weightindex4i[i*4+2], mesh->data_weightvalue4f[i*4+2], mesh->data_weightindex4i[i*4+3], mesh->data_weightvalue4f[i*4+3]); + if (wf[3] > wf[2] || wf[2] > wf[1] || wf[1] > wf[0]) + Console_Printf("vertex sorting error! vertex #%i has weights %i:%f %i:%f %i:%f %i:%f\n", i, wi[0], wf[0], wi[1], wf[1], wi[2], wf[2], wi[3], wf[3]); // renormalize the array of strongest weights on this vertex sum = 0; for (k = 0;k < 4;k++) - sum += mesh->data_weightvalue4f[i*4+k]; + sum += wf[k]; if (sum) { sum = 1.0f / sum; for (k = 0;k < 4;k++) - mesh->data_weightvalue4f[i*4+k] *= sum; + wf[k] *= sum; } + // now convert to the compact format used for longterm storage + for (k = 0;k < 4;k++) + { + mesh->data_weightindex4b[i*4+k] = (NUint8)wi[k]; + mesh->data_weightvalue4b[i*4+k] = (NUint8)(wf[k] * 255.0f); + } } // compile the base frame of the mesh for static uses Model_MeshVectors(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f); @@ -580,9 +590,9 @@ mesh->basecullmaxs[1] = Max(mesh->basecullmaxs[1], mesh->data_vertex3f[i * 3 + 1]); mesh->basecullmaxs[2] = Max(mesh->basecullmaxs[2], mesh->data_vertex3f[i * 3 + 2]); } - for (k = 0;k < 4 && mesh->data_weightvalue4f[i*4+k] > 0;k++) + for (k = 0;k < 4 && mesh->data_weightvalue4b[i*4+k] > 0;k++) { - NUint32 index = mesh->data_weightindex4i[i*4+k]; + NUint32 index = mesh->data_weightindex4b[i*4+k]; Nvec3 v1, v; Nvec r; VectorCopy(mesh->data_vertex3f + i * 3, v1); @@ -676,9 +686,9 @@ for (j = 0, index = 0;j < mesh->num_vertices;j++, index += 3) { float value; - for (k = 0;k < 4 && (value = mesh->data_weightvalue4f[j*4+k]);k++) + for (k = 0;k < 4 && (value = mesh->data_weightvalue4b[j*4+k] * (1.0f / 255.0f));k++) { - matrix = relativematrix + mesh->data_weightindex4i[j*4+k]; + matrix = relativematrix + mesh->data_weightindex4b[j*4+k]; if (outvertex3f) { outvertex3f[index+0] += value * (DotProduct(v + index, matrix->m[0]) + matrix->m[0][3]); Modified: trunk/model.h =================================================================== --- trunk/model.h 2006-04-09 02:53:10 UTC (rev 696) +++ trunk/model.h 2006-04-09 03:10:04 UTC (rev 697) @@ -58,9 +58,9 @@ // lightmap texture coordinates for vertices in this mesh float *data_lightmaptexcoord2f; // indices of up to 4 transforms per vertex - int *data_weightindex4i; + NUint8 *data_weightindex4b; // blending influence values of up to 4 transforms per vertex - float *data_weightvalue4f; + NUint8 *data_weightvalue4b; Nvec3 basecullmins; Nvec3 basecullmaxs; From lordhavoc at icculus.org Sat Apr 8 23:55:57 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 8 Apr 2006 23:55:57 -0400 Subject: r698 - trunk Message-ID: <20060409035557.8193.qmail@icculus.org> Author: lordhavoc Date: 2006-04-08 23:55:57 -0400 (Sat, 08 Apr 2006) New Revision: 698 Modified: trunk/model.c trunk/model.h Log: no longer stores skeletal data about md5mesh files that contain only one bone, this saves a bit of memory Modified: trunk/model.c =================================================================== --- trunk/model.c 2006-04-09 03:10:04 UTC (rev 697) +++ trunk/model.c 2006-04-09 03:55:57 UTC (rev 698) @@ -215,11 +215,12 @@ void Model_Load(ResourceEntry *r) { Util_ParseC_Thread thread; - NUint32 meshnum, version; + NUint32 meshnum, version, numjoints = 0; Nbool error; Nsize filesize; Model *model; char *filedata; + Nbool isskeletal = false; model = Mem_Alloc(r->memzone, sizeof(Model)); @@ -275,14 +276,19 @@ //numJoints 3 else if (Util_ParseC_MatchKeyword(&thread, "numJoints")) { - LoadInt(model->num_transforms, "after 'numJoints'"); - if (model->num_transforms < 1) + LoadInt(numjoints, "after 'numJoints'"); + if (numjoints < 1) { - Console_Printf("Model_Load: numJoints %i < 1\n", model->num_transforms); + Console_Printf("Model_Load: numJoints %i < 1\n", numjoints); Abort(); } - model->max_transforms = model->num_transforms; - model->data_transforminfo = Mem_Alloc(r->memzone, model->max_transforms * sizeof(*model->data_transforminfo)); + if (numjoints > 1) + { + isskeletal = true; + model->num_transforms = numjoints; + model->max_transforms = model->num_transforms; + model->data_transforminfo = Mem_Alloc(r->memzone, model->max_transforms * sizeof(*model->data_transforminfo)); + } } //numMeshes 1 else if (Util_ParseC_MatchKeyword(&thread, "numMeshes")) @@ -303,35 +309,44 @@ //} else if (Util_ParseC_MatchKeyword(&thread, "joints")) { + char *name = NULL; NUint32 jointnum; ExpectKeyword("{", "after 'joints'"); for (jointnum = 0; !Util_ParseC_MatchKeyword(&thread, "}");jointnum++) { NSint32 parent; + Nfloat pose[6]; // "root" -1 ( 0.000000 0.000000 0.000000 ) ( -0.707107 -0.000000 -0.000000 ) - LoadString(model->data_transforminfo[jointnum].name, "for joint name"); + LoadString(name, "for joint name"); LoadInt(parent, "as parent"); ExpectKeyword("(", "before first joint data list"); - LoadValue(model->data_transforminfo[jointnum].basepose[0], "(joint 0)"); - LoadValue(model->data_transforminfo[jointnum].basepose[1], "(joint 1)"); - LoadValue(model->data_transforminfo[jointnum].basepose[2], "(joint 2)"); + LoadValue(pose[0], "(joint 0)"); + LoadValue(pose[1], "(joint 1)"); + LoadValue(pose[2], "(joint 2)"); ExpectKeyword(")", "after first joint data list"); ExpectKeyword("(", "before second joint data list"); - LoadValue(model->data_transforminfo[jointnum].basepose[3], "(joint 3)"); - LoadValue(model->data_transforminfo[jointnum].basepose[4], "(joint 4)"); - LoadValue(model->data_transforminfo[jointnum].basepose[5], "(joint 5)"); + LoadValue(pose[3], "(joint 3)"); + LoadValue(pose[4], "(joint 4)"); + LoadValue(pose[5], "(joint 5)"); ExpectKeyword(")", "after second joint data list"); - Matrix4x4_CreateFromDoom3Joint(&model->data_transforminfo[jointnum].basematrix, model->data_transforminfo[jointnum].basepose[0], model->data_transforminfo[jointnum].basepose[1], model->data_transforminfo[jointnum].basepose[2], model->data_transforminfo[jointnum].basepose[3], model->data_transforminfo[jointnum].basepose[4], model->data_transforminfo[jointnum].basepose[5]); - Matrix4x4_Invert_Simple(&model->data_transforminfo[jointnum].baseinversematrix, &model->data_transforminfo[jointnum].basematrix); if (parent >= (NSint32)jointnum) { + String_Free(&name); Console_Printf("Model_Load: joint.parent (%i) >= joint (%i)\n", parent, jointnum); Abort(); } + if (isskeletal) + { + Matrix4x4_CreateFromDoom3Joint(&model->data_transforminfo[jointnum].basematrix, pose[0], pose[1], pose[2], pose[3], pose[4], pose[5]); + Matrix4x4_Invert_Simple(&model->data_transforminfo[jointnum].baseinversematrix, &model->data_transforminfo[jointnum].basematrix); + model->data_transforminfo[jointnum].name = name; + name = NULL; + } } - if (jointnum != model->num_transforms) + String_Free(&name); + if (jointnum != numjoints) { - Console_Printf("Model_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, model->num_transforms); + Console_Printf("Model_Load: final jointnum (%i) != numJoints (%i)\n", jointnum, numjoints); Abort(); } } @@ -377,8 +392,11 @@ mesh->data_normal3f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[3])); mesh->data_texcoord2f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[2])); mesh->data_lightmaptexcoord2f = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(float[2])); - mesh->data_weightindex4b = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint8[4])); - mesh->data_weightvalue4b = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint8[4])); + if (isskeletal) + { + mesh->data_weightindex4b = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint8[4])); + mesh->data_weightvalue4b = Mem_Alloc(r->memzone, mesh->max_vertices * sizeof(NUint8[4])); + } md5weightrange = Mem_Alloc(Global_Zone, mesh->max_vertices * sizeof(NUint32[2])); } // vert 0 ( 0.142532 0.983877 ) 0 1 @@ -469,9 +487,9 @@ md5weight = md5weights + weightnum; // 2 LoadInt(md5weight->jointnum, "(weight jointnum)"); - if (md5weight->jointnum >= model->num_transforms) + if (md5weight->jointnum >= numjoints) { - Console_Printf("Model_Load: joint (%i) >= num_transforms (%i)\n", md5weight->jointnum, model->num_transforms); + Console_Printf("Model_Load: joint (%i) >= numjoints (%i)\n", md5weight->jointnum, numjoints); Abort(); } // 1.000000 @@ -497,57 +515,68 @@ } } memset(mesh->data_vertex3f, 0, mesh->num_vertices * sizeof(float[3])); - for (i = 0;i < mesh->num_vertices;i++) + if (isskeletal) { - Ndouble sum = 0; - NUint32 k; - NUint32 wi[4]; - Nfloat wf[4]; - Vector4Clear(wi); - Vector4Clear(wf); - for (j = 0, md5weight = md5weights + md5weightrange[i*2+0];j < md5weightrange[i*2+1];j++, md5weight++) + // convert the skeletal data from doom3 vertex weights to + // matrix palette weights (usable by a vertex shader) + for (i = 0;i < mesh->num_vertices;i++) { - matrix = &model->data_transforminfo[md5weight->jointnum].basematrix; - mesh->data_vertex3f[i*3+0] += DotProduct4(md5weight->vertex, matrix->m[0]); - mesh->data_vertex3f[i*3+1] += DotProduct4(md5weight->vertex, matrix->m[1]); - mesh->data_vertex3f[i*3+2] += DotProduct4(md5weight->vertex, matrix->m[2]); - // store the best weights in the vertex's limited number of blend weights - for (k = 4;k >= 1 && mesh->data_weightvalue4b[i*4+k-1] < md5weight->vertex[3];k--) + Ndouble sum = 0; + NUint32 k; + NUint32 wi[4]; + Nfloat wf[4]; + Vector4Clear(wi); + Vector4Clear(wf); + for (j = 0, md5weight = md5weights + md5weightrange[i*2+0];j < md5weightrange[i*2+1];j++, md5weight++) { + matrix = &model->data_transforminfo[md5weight->jointnum].basematrix; + mesh->data_vertex3f[i*3+0] += DotProduct4(md5weight->vertex, matrix->m[0]); + mesh->data_vertex3f[i*3+1] += DotProduct4(md5weight->vertex, matrix->m[1]); + mesh->data_vertex3f[i*3+2] += DotProduct4(md5weight->vertex, matrix->m[2]); + // store the best weights in the vertex's limited number of blend weights + for (k = 4;k >= 1 && mesh->data_weightvalue4b[i*4+k-1] < md5weight->vertex[3];k--) + { + if (k < 4) + { + wi[k] = wi[k-1]; + wf[k] = wf[k-1]; + } + } if (k < 4) { - wi[k] = wi[k-1]; - wf[k] = wf[k-1]; + wi[k] = md5weight->jointnum; + wf[k] = md5weight->vertex[3]; } + sum += md5weight->vertex[3]; } - if (k < 4) + if (fabs(sum - 1) > 0.001) + Console_Printf("vertex #%i (weights %i-%i) does not sum to 1! (sum = %f)\n", i, md5weightrange[i*2+0], md5weightrange[i*2+0]+md5weightrange[i*2+1], sum); + if (wf[3] > wf[2] || wf[2] > wf[1] || wf[1] > wf[0]) + Console_Printf("vertex sorting error! vertex #%i has weights %i:%f %i:%f %i:%f %i:%f\n", i, wi[0], wf[0], wi[1], wf[1], wi[2], wf[2], wi[3], wf[3]); + // renormalize the array of strongest weights on this vertex + sum = 0; + for (k = 0;k < 4;k++) + sum += wf[k]; + if (sum) { - wi[k] = md5weight->jointnum; - wf[k] = md5weight->vertex[3]; + sum = 1.0f / sum; + for (k = 0;k < 4;k++) + wf[k] *= sum; } - sum += md5weight->vertex[3]; - } - if (fabs(sum - 1) > 0.001) - Console_Printf("vertex #%i (weights %i-%i) does not sum to 1! (sum = %f)\n", i, md5weightrange[i*2+0], md5weightrange[i*2+0]+md5weightrange[i*2+1], sum); - if (wf[3] > wf[2] || wf[2] > wf[1] || wf[1] > wf[0]) - Console_Printf("vertex sorting error! vertex #%i has weights %i:%f %i:%f %i:%f %i:%f\n", i, wi[0], wf[0], wi[1], wf[1], wi[2], wf[2], wi[3], wf[3]); - // renormalize the array of strongest weights on this vertex - sum = 0; - for (k = 0;k < 4;k++) - sum += wf[k]; - if (sum) - { - sum = 1.0f / sum; + // now convert to the compact format used for longterm storage for (k = 0;k < 4;k++) - wf[k] *= sum; + { + mesh->data_weightindex4b[i*4+k] = (NUint8)wi[k]; + mesh->data_weightvalue4b[i*4+k] = (NUint8)(wf[k] * 255.0f); + } } - // now convert to the compact format used for longterm storage - for (k = 0;k < 4;k++) - { - mesh->data_weightindex4b[i*4+k] = (NUint8)wi[k]; - mesh->data_weightvalue4b[i*4+k] = (NUint8)(wf[k] * 255.0f); - } } + else + { + // non-skeletal + for (i = 0;i < mesh->num_vertices;i++) + VectorCopy(md5weights[md5weightrange[i*2+0]].vertex, mesh->data_vertex3f + i*3); + } // compile the base frame of the mesh for static uses Model_MeshVectors(mesh->num_triangles, mesh->data_element3i, mesh->num_vertices, mesh->data_vertex3f, mesh->data_texcoord2f, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f); Model_MeshNeighbors(mesh->num_triangles, mesh->data_element3i, mesh->data_neighbor3i, mesh->num_vertices); @@ -590,15 +619,18 @@ mesh->basecullmaxs[1] = Max(mesh->basecullmaxs[1], mesh->data_vertex3f[i * 3 + 1]); mesh->basecullmaxs[2] = Max(mesh->basecullmaxs[2], mesh->data_vertex3f[i * 3 + 2]); } - for (k = 0;k < 4 && mesh->data_weightvalue4b[i*4+k] > 0;k++) + if (isskeletal) { - NUint32 index = mesh->data_weightindex4b[i*4+k]; - Nvec3 v1, v; - Nvec r; - VectorCopy(mesh->data_vertex3f + i * 3, v1); - Matrix4x4_Transform(&model->data_transforminfo[index].baseinversematrix, v1, v); - r = VectorLength(v); - model->data_transforminfo[index].radius = Max(model->data_transforminfo[index].radius, r); + for (k = 0;k < 4 && mesh->data_weightvalue4b[i*4+k] > 0;k++) + { + NUint32 index = mesh->data_weightindex4b[i*4+k]; + Nvec3 v1, v; + Nvec r; + VectorCopy(mesh->data_vertex3f + i * 3, v1); + Matrix4x4_Transform(&model->data_transforminfo[index].baseinversematrix, v1, v); + r = VectorLength(v); + model->data_transforminfo[index].radius = Max(model->data_transforminfo[index].radius, r); + } } } Mem_Free(&md5weights); @@ -653,7 +685,9 @@ if (meshindex >= model->num_meshes) return; // invalid mesh index mesh = model->data_meshes + meshindex; - if (!transforms) + // if the caller is not requesting skeletal animation or if the model + // doesn't even support animation, just return the undeformed arrays + if (!transforms || !mesh->data_weightvalue4b) { if (outvertex3f) { Modified: trunk/model.h =================================================================== --- trunk/model.h 2006-04-09 03:10:04 UTC (rev 697) +++ trunk/model.h 2006-04-09 03:55:57 UTC (rev 698) @@ -47,6 +47,8 @@ // (aka bumpmapped) lighting. // location of vertex float *data_vertex3f; + // TODO: these should be used only in the vertex shader + // TODO: when vertex shader is used, replace svector tvector normal with a 4 byte quaternion to save memory // direction of S texcoord float *data_svector3f; // direction of T texcoord @@ -57,6 +59,7 @@ float *data_texcoord2f; // lightmap texture coordinates for vertices in this mesh float *data_lightmaptexcoord2f; + // NOTE: on non-skeletal models all weight stuff is NULL! // indices of up to 4 transforms per vertex NUint8 *data_weightindex4b; // blending influence values of up to 4 transforms per vertex @@ -81,6 +84,7 @@ NUint32 max_meshes; Model_Mesh *data_meshes; + // NOTE: on non-skeletal models all transform stuff is 0 or NULL! NUint32 num_transforms; NUint32 max_transforms; Model_TransformInfo *data_transforminfo; From lordhavoc at icculus.org Sun Apr 9 20:28:19 2006 From: lordhavoc at icculus.org (lordhavoc at icculus.org) Date: 9 Apr 2006 20:28:19 -0400 Subject: r699 - trunk Message-ID: <20060410002819.15867.qmail@icculus.org> Author: lordhavoc Date: 2006-04-09 20:28:18 -0400 (Sun, 09 Apr 2006) New Revision: 699 Modified: trunk/collision.c trunk/collision.h Log: added Collision_Brush_FreeBrushesForTriangleMesh Modified: trunk/collision.c =================================================================== --- trunk/collision.c 2006-04-09 03:55:57 UTC (rev 698) +++ trunk/collision.c 2006-04-10 00:28:18 UTC (rev 699) @@ -105,6 +105,11 @@ return brushes; } +void Collision_Brush_FreeBrushesForTriangleMesh(Collision_Brush *brushes, NUint32 numtriangles) +{ + Mem_Free(&brushes); +} + void Collision_Brush_UpdateTriangleBrush(Collision_Brush *brush, const float *p0, const float *p1, const float *p2) { VectorCopy(p0, brush->points[0].point); Modified: trunk/collision.h =================================================================== --- trunk/collision.h 2006-04-09 03:55:57 UTC (rev 698) +++ trunk/collision.h 2006-04-10 00:28:18 UTC (rev 699) @@ -55,6 +55,7 @@ Collision_Brush; Collision_Brush *Collision_Brush_AllocBrushesForTriangleMesh(Mem_Zone *zone, NUint32 numtriangles); +void Collision_Brush_FreeBrushesForTriangleMesh(Collision_Brush *brush, NUint32 numtriangles); void Collision_Brush_UpdateTriangleBrush(Collision_Brush *brush, const float *p0, const float *p1, const float *p2); void Collision_Brush_UpdateTriangleMeshBrushes(Collision_Brush *brushes, NUint32 numtriangles, const NUint32 *element3i, const float *vertex3f); void Collision_Brush_UpdateCullingData(Collision_Brush *brush); From black at icculus.org Tue Apr 18 06:27:01 2006 From: black at icculus.org (black at icculus.org) Date: 18 Apr 2006 06:27:01 -0400 Subject: r700 - trunk/game Message-ID: <20060418102701.29422.qmail@icculus.org> Author: black Date: 2006-04-18 06:27:00 -0400 (Tue, 18 Apr 2006) New Revision: 700 Modified: trunk/game/m_menucore.c trunk/game/m_menucore.h Log: Fix a bug, add a type member to Menu_Item and move a few comments around, too. Modified: trunk/game/m_menucore.c =================================================================== --- trunk/game/m_menucore.c 2006-04-10 00:28:18 UTC (rev 699) +++ trunk/game/m_menucore.c 2006-04-18 10:27:00 UTC (rev 700) @@ -87,7 +87,7 @@ parent->subitems = item; } -void Menu_SubMenu_BringToFront(Menu_Item *item) +void Menu_SubMenu_BringToFocus(Menu_Item *item) { Menu_SubMenu *parent = item->parent; // FIXME: fix this @@ -95,6 +95,7 @@ return; Menu_Item_RemoveFromParent(item); Menu_SubMenu_AddAtFront(parent, item); + parent->selecteditem = item; } // TODO: use NString for everything @@ -126,12 +127,11 @@ break; } } - if (item == NULL) + if (item == NULL || item->type != MENU_ITEMTYPE_SUBMENU) { break; } name_start = name_end + 1; - // FIXME: we don't really know whether item is really a submenu... current_parent = (Menu_SubMenu*) item; } return item; @@ -189,7 +189,7 @@ Mem_Free(&item); } -Menu_Item *Menu_Generic_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint bytes) +Menu_Item *Menu_Generic_Create(Menu_SubMenu *parent, Menu_ItemType type, NSint x, NSint y, NUint bytes) { Menu_Item *item; assert( bytes >= sizeof(Menu_Item) ); @@ -201,6 +201,8 @@ item->KeyEvent = Menu_Generic_KeyPressIgnore; item->Destroy = Menu_Generic_Destroy; + item->type = type; + item->pos[0] = x; item->pos[1] = y; @@ -240,13 +242,13 @@ } return false; } -Menu_TextItem *Menu_Text_Create(Menu_SubMenu *parent, NSint x, NSint y, char *text, void *command, void (*UseItem) (struct Menu_TextItem *item, void *cookie)) +Menu_TextItem *Menu_Text_Create(Menu_SubMenu *parent, NSint x, NSint y, char *text, void *cookie, void (*UseItem) (struct Menu_TextItem *item, void *cookie)) { Menu_TextItem *it; - it = (Menu_TextItem*)Menu_Generic_Create(parent, x, y, sizeof(Menu_TextItem)); + it = (Menu_TextItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_TEXT, x, y, sizeof(Menu_TextItem)); it->super.Draw = Menu_Text_Draw; - if (command != NULL) + if (cookie != NULL) { it->super.MouseMove = Menu_Generic_MouseMoveSelectable; it->super.KeyEvent = Menu_Text_KeyPress; @@ -255,9 +257,9 @@ it->super.size[1] = 8; it->text = text; - it->cookie = command; + it->cookie = cookie; - if (UseItem == NULL && command) + if (UseItem == NULL && cookie) UseItem = Menu_Text_DefaultUse; it->UseItem = UseItem; @@ -352,7 +354,7 @@ Menu_EditItem *Menu_Edit_Create(Menu_SubMenu *parent, NSint x, NSint y, char *text) { Menu_EditItem *it; - it = (Menu_EditItem*)Menu_Generic_Create(parent, x, y, sizeof(Menu_EditItem)); + it = (Menu_EditItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_EDIT, x, y, sizeof(Menu_EditItem)); it->super.Draw = Menu_Edit_Draw; it->super.MouseMove = Menu_Generic_MouseMoveSelectable; @@ -439,7 +441,7 @@ NUint i; item->popup = Menu_SubMenu_Create(&Menu.rootmenu); - Menu_SubMenu_BringToFront(&item->popup->super); + Menu_SubMenu_BringToFocus(&item->popup->super); interior = Menu_SubMenu_Create(item->popup); interior->allowclose = false; Menu.grabs = &item->popup->super; @@ -477,7 +479,7 @@ { //list is pipe-seperated Menu_ComboItem *it; - it = (Menu_ComboItem*)Menu_Generic_Create(parent, x, y, sizeof(Menu_ComboItem)); + it = (Menu_ComboItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_COMBO, x, y, sizeof(Menu_ComboItem)); it->super.super.Draw = Menu_Combo_Draw; it->super.super.MouseMove = Menu_Generic_MouseMoveSelectable; @@ -554,7 +556,7 @@ Menu_PictureItem *Menu_Picture_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, NUint h, char *imagename, void *command, void (*UseItem) (struct Menu_PictureItem *item, void *cookie)) { Menu_PictureItem *it; - it = (Menu_PictureItem*)Menu_Generic_Create(parent, x, y, sizeof(Menu_PictureItem)); + it = (Menu_PictureItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_PICTURE, x, y, sizeof(Menu_PictureItem)); it->super.Draw = Menu_Picture_Draw; if (command != NULL) @@ -584,15 +586,8 @@ //sliderh items -void Menu_Slider_Draw(Menu_SliderItem *item, Menu_Inheritance *inh) +void Menu_Slider_Frame(Menu_SliderItem *item, Menu_Inheritance *inh) { - Nfloat frac; - -// R_SetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// R_SetColor(1, 1, 1, 1); -// R_SetTexture(Resource_IndexForName(item->imagename, RESOURCETYPE_TEXTURE, 0, 0)); -// R_DrawPic(item->super.pos[0] + inh->origin[0], item->super.pos[1] + inh->origin[1], item->super.size[0], item->super.size[1]); - if (Menu.grabs == &item->super) { { @@ -609,7 +604,17 @@ item->SliderChanged(item, item->cookie); } } +} +void Menu_Slider_Draw(Menu_SliderItem *item, Menu_Inheritance *inh) +{ + Nfloat frac; + +// R_SetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +// R_SetColor(1, 1, 1, 1); +// R_SetTexture(Resource_IndexForName(item->imagename, RESOURCETYPE_TEXTURE, 0, 0)); +// R_DrawPic(item->super.pos[0] + inh->origin[0], item->super.pos[1] + inh->origin[1], item->super.size[0], item->super.size[1]); + if (item->SliderUpdate) item->SliderUpdate(item, item->cookie); @@ -664,7 +669,7 @@ Menu_SliderItem *Menu_Slider_Create(Menu_SubMenu *parent, NUint axis, NSint x, NSint y, NUint w, NUint h, Nfloat minv, Nfloat maxv, Nfloat defaultv, void (*ChangeNotification)(Menu_SliderItem *item, void *cookie), void (*UpdateSlider)(Menu_SliderItem *item, void *cookie), void *cookie) { Menu_SliderItem *it; - it = (Menu_SliderItem*)Menu_Generic_Create(parent, x, y, sizeof(Menu_SliderItem)); + it = (Menu_SliderItem*)Menu_Generic_Create(parent, MENU_ITEMTYPE_SLIDER, x, y, sizeof(Menu_SliderItem)); it->super.Draw = Menu_Slider_Draw; it->super.MouseMove = Menu_Generic_MouseMoveSelectable; @@ -768,24 +773,23 @@ for (subitem = menu->subitems; subitem; subitem = next) { - next = subitem->next;//this funkyness is so that we can unlink and kill things in the draw function (if the need arises). + // this funkyness is so that we can unlink and kill things in the draw function (if the need arises). + next = subitem->next; subitem->Frame(subitem, &ninh, elapsedtime); } } void Menu_SubMenu_Draw(Menu_SubMenu *menu, Menu_Inheritance *inh) { - Menu_Item *subitem, *next; + Menu_Item *subitem; Menu_Inheritance ninh; Menu_SubMenu_SetupInheritance(menu, inh, &ninh); R_SetScissor(ninh.window.pos[0], ninh.window.pos[1], ninh.window.size[0], ninh.window.size[1]); - for (subitem = menu->subitems; subitem; subitem = next) + for (subitem = menu->subitems; subitem; subitem = subitem->next) { - // TODO: remove this since we only accept Frame to delete items, Draw should just draw them and don't do any management work like deleting our beloved items - next = subitem->next;//this funkyness is so that we can unlink and kill things in the draw function (if the need arises). subitem->Draw(subitem, &ninh); } @@ -795,7 +799,7 @@ { Menu_Item *subitem; - Menu_SubMenu_BringToFront(&item->super); + Menu_SubMenu_BringToFocus(&item->super); subitem = item->selecteditem; if (item->selecteditem) @@ -867,7 +871,7 @@ { Menu_SubMenu *menu; - menu = (Menu_SubMenu*) Menu_Generic_Create(NULL, 0, 0, sizeof(Menu_SubMenu)); + menu = (Menu_SubMenu*) Menu_Generic_Create(NULL, MENU_ITEMTYPE_SUBMENU, 0, 0, sizeof(Menu_SubMenu)); if( parent ) { Menu_SubMenu_AddAtFront(parent, &menu->super); Modified: trunk/game/m_menucore.h =================================================================== --- trunk/game/m_menucore.h 2006-04-10 00:28:18 UTC (rev 699) +++ trunk/game/m_menucore.h 2006-04-18 10:27:00 UTC (rev 700) @@ -17,6 +17,19 @@ } Menu_Inheritance; +typedef enum Menu_ItemType +{ + // use unknown to mark uninitialized type fields + MENU_ITEMTYPE_UNKNOWN = 0, + MENU_ITEMTYPE_SUBMENU, + MENU_ITEMTYPE_SLIDER, + MENU_ITEMTYPE_EDIT, + MENU_ITEMTYPE_COMBO, + MENU_ITEMTYPE_TEXT, + MENU_ITEMTYPE_PICTURE, +} +Menu_ItemType; + typedef struct Menu_Item { // pass an elapsedtime parameter to make animation-speed changes, etc. possible @@ -25,6 +38,8 @@ Nbool (*KeyEvent) (void *item, NUint mod, NUint sym, NUint character, Nbool downevent); void (*MouseMove) (void *item, Menu_Inheritance *inheritance); void (*Destroy) (void *item); + + Menu_ItemType type; char name[64]; NSint32 pos[2]; NSint32 size[2]; @@ -115,7 +130,7 @@ Menu_Item super; char *imagename; - // console command when clicked + // default: console command when clicked void *cookie; // called when the user uses (clicks) this item @@ -163,6 +178,13 @@ } Menu_ArrangeStyle; +typedef enum Menu_Axis +{ + MENU_AXIS_HORIZONAL, + MENU_AXIS_VERTICAL +} +Menu_Axis; + typedef struct MenuState { Menu_SubMenu rootmenu; @@ -186,11 +208,19 @@ // entry points for using the menu in other systems Menu_SubMenu *Menu_SubMenu_Create(Menu_SubMenu *parent); -Menu_SliderItem *Menu_VSlider_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, NUint h, Nfloat minv, Nfloat maxv, Nfloat defaultv, void (*ChangeNotification)(Menu_SliderItem *item, void *cookie), void (*UpdateSlider)(Menu_SliderItem *item, void *cookie), void *cookie);//vertical scrolling bar -Menu_SliderItem *Menu_HSlider_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, NUint h, Nfloat minv, Nfloat maxv, Nfloat defaultv, void (*ChangeNotification)(Menu_SliderItem *item, void *cookie), void (*UpdateSlider)(Menu_SliderItem *item, void *cookie), void *cookie);//horizontal scrolling bar -Menu_TextItem *Menu_Text_Create(Menu_SubMenu *parent, NSint x, NSint y, char *text, void *command, void (*UseItem) (struct Menu_TextItem *item, void *cookie)); //if usetextitem == null, interpret as a console command. if not null, command can be used as a magic cookie. If both null, item is non-selectable. -Menu_EditItem *Menu_Edit_Create(Menu_SubMenu *parent, NSint x, NSint y, char *text); //an item for editing text (fixme: needs callbacks and stuff) -Menu_ComboItem *Menu_Combo_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, char *defalt, char *list);//a list of multiple choices. -Menu_PictureItem *Menu_Picture_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, NUint h, char *imagename, void *command, void (*UseItem) (struct Menu_PictureItem *item, void *cookie)); //just a simple picture. clicking it can give a console command +// vertical scrolling bar +Menu_SliderItem *Menu_VSlider_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, NUint h, Nfloat minv, Nfloat maxv, Nfloat defaultv, void (*ChangeNotification)(Menu_SliderItem *item, void *cookie), void (*UpdateSlider)(Menu_SliderItem *item, void *cookie), void *cookie); +// horizontal scrolling bar +Menu_SliderItem *Menu_HSlider_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, NUint h, Nfloat minv, Nfloat maxv, Nfloat defaultv, void (*ChangeNotification)(Menu_SliderItem *item, void *cookie), void (*UpdateSlider)(Menu_SliderItem *item, void *cookie), void *cookie); +// if usetextitem == null, cookie is interpreted as a console command. if not null, command can be used +// as a magic cookie. If both null, item is non-selectable. +Menu_TextItem *Menu_Text_Create(Menu_SubMenu *parent, NSint x, NSint y, char *text, void *cookie, void (*UseItem) (struct Menu_TextItem *item, void *cookie)); +// an item for editing text +// FIXME: needs callbacks and stuff +Menu_EditItem *Menu_Edit_Create(Menu_SubMenu *parent, NSint x, NSint y, char *text); +// a list of multiple choices. +Menu_ComboItem *Menu_Combo_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, char *defalt, char *list); +// just a simple picture. clicking it can give a console command +Menu_PictureItem *Menu_Picture_Create(Menu_SubMenu *parent, NSint x, NSint y, NUint w, NUint h, char *imagename, void *command, void (*UseItem) (struct Menu_PictureItem *item, void *cookie)); #endif From black at icculus.org Tue Apr 18 07:01:00 2006 From: black at icculus.org (black at icculus.org) Date: 18 Apr 2006 07:01:00 -0400 Subject: r701 - trunk/game Message-ID: <20060418110100.938.qmail@icculus.org> Author: black Date: 2006-04-18 07:01:00 -0400 (Tue, 18 Apr 2006) New Revision: 701 Modified: trunk/game/g_util.c Log: Some small changes, either to make the code simpler/easier to understand or to keep it from breaking under special circumstances. Modified: trunk/game/g_util.c =================================================================== --- trunk/game/g_util.c 2006-04-18 10:27:00 UTC (rev 700) +++ trunk/game/g_util.c 2006-04-18 11:01:00 UTC (rev 701) @@ -1,7 +1,6 @@ #include "ncommon.h" #include "game/g_util.h" -#include "game/g_main.h" #include "lhnet.h" void G_GenerateChallenge(char *s, NUint32 challengebufferlength) @@ -10,7 +9,7 @@ if (challengebufferlength < 1) return; for (i = 0;i < challengebufferlength - 1;i++) - *s++ = 'A' + (rand() % 26); + *s++ = 'A' + (rand() % ('Z' - 'A' + 1)); *s = 0; } @@ -19,6 +18,9 @@ Nbool isvalue; Nbool found = false; int bufferpos; + // make sure the optimized code doesnt break when the key name is longer than the temp buffer + assert( strlen( key ) < bufferlength ); + // skip leading text (such as in a packet) while (*infostring && *infostring != '\\') infostring++; @@ -79,17 +81,19 @@ return; } inkey = in + 1; - for (i = 0;inkey[i] && inkey[i] != '\\';i++); + for (i = 0;inkey[i] && inkey[i] != '\\';i++) + ; // if we reached the end of the input key, but not the end of the // key we're looking for, then it's not a match - match = !key[i] && !String_NICompare(inkey, key, i); + match = strlen(key) == i && !String_NICompare(inkey, key, i); if (inkey[i] != '\\') { Console_Printf("G_InfoString_Set: infostring improperly terminated\n"); return; } invalue = inkey + i + 1; - for (i = 0;invalue[i] && invalue[i] != '\\';i++); + for (i = 0;invalue[i] && invalue[i] != '\\';i++) + ; in = invalue + i; if (match) { @@ -117,9 +121,11 @@ { while (*string && *string <= ' ') string++; - if (!*string) + if (!*string || numargs == maxargs) break; - arg = numargs < maxargs ? (args + numargs++ * maxargsize) : NULL; + + arg = args + numargs++ * maxargsize; + if ((quoted = *string == '"')) string++; for (i = 0;*string && (quoted ? *string != '"' : *string > ' ');i++) @@ -131,14 +137,14 @@ if (c == 0) break; if (c == 'n') - c = '\n'; + c = '\n'; } - if (arg && i < maxargsize - 1) + if (i < maxargsize - 1) { arg[i] = c; - arg[i+1] = 0; } } + arg[i] = 0; if (quoted && *string == '"') string++; }