- loadmodel->modeldatatypestring = "OBJ";
-
- loadmodel->type = mod_alias;
- loadmodel->AnimateVertices = NULL;
- loadmodel->DrawSky = NULL;
- loadmodel->DrawAddWaterPlanes = NULL;
- loadmodel->Draw = R_Q1BSP_Draw;
- loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
- loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
- loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
- loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
- loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
- loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
- loadmodel->DrawLight = R_Q1BSP_DrawLight;
- loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
- loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
- loadmodel->PointSuperContents = NULL;
-
- // parse the OBJ text now
- for(;;)
- {
- if (!*text)
- break;
- linenumber++;
- linelen = 0;
- for (linelen = 0;text[linelen] && text[linelen] != '\r' && text[linelen] != '\n';linelen++)
- line[linelen] = text[linelen];
- line[linelen] = 0;
- for (argc = 0;argc < (int)(sizeof(argv)/sizeof(argv[0]));argc++)
- argv[argc] = "";
- argc = 0;
- s = line;
- while (*s == ' ' || *s == '\t')
- s++;
- while (*s)
- {
- argv[argc++] = s;
- while (*s > ' ')
- s++;
- if (!*s)
- break;
- *s++ = 0;
- while (*s == ' ' || *s == '\t')
- s++;
- }
- if (!argc)
- continue;
- if (argv[0][0] == '#')
- continue;
- if (!strcmp(argv[0], "v"))
- {
- if (maxv <= numv)
- {
- maxv *= 2;
- oldv = v;
- v = Mem_Alloc(tempmempool, maxv * sizeof(float[3]));
- if (oldv)
- {
- memcpy(v, oldv, numv * sizeof(float[3]));
- Mem_Free(oldv);
- }
- }
- v[numv*3+0] = atof(argv[1]);
- v[numv*3+1] = atof(argv[2]);
- v[numv*3+2] = atof(argv[3]);
- numv++;
- }
- else if (!strcmp(argv[0], "vt"))
- {
- if (maxvt <= numvt)
- {
- maxvt *= 2;
- oldvt = vt;
- vt = Mem_Alloc(tempmempool, maxvt * sizeof(float[2]));
- if (oldvt)
- {
- memcpy(vt, oldvt, numvt * sizeof(float[2]));
- Mem_Free(oldvt);
- }
- }
- vt[numvt*2+0] = atof(argv[1]);
- vt[numvt*2+1] = atof(argv[2]);
- numvt++;
- }
- else if (!strcmp(argv[0], "vn"))
- {
- if (maxvn <= numvn)
- {
- maxvn *= 2;
- oldvn = vn;
- vn = Mem_Alloc(tempmempool, maxvn * sizeof(float[3]));
- if (oldvn)
- {
- memcpy(vn, oldvn, numvn * sizeof(float[3]));
- Mem_Free(oldvn);
- }
- }
- vn[numvn*3+0] = atof(argv[1]);
- vn[numvn*3+1] = atof(argv[2]);
- vn[numvn*3+2] = atof(argv[3]);
- numvn++;
- }
- else if (!strcmp(argv[0], "f"))
- {
- if (!surface)
- {
- if (maxsurfaces <= numsurfaces)
- {
- maxsurfaces++;
- oldsurfaces = surfaces;
- surfaces = Mem_Alloc(tempmempool, maxsurfaces * sizeof(*surfaces));
- if (oldsurfaces)
- {
- memcpy(surfaces, oldsurfaces, numsurfaces * sizeof(*surfaces));
- Mem_Free(oldsurfaces);
- }
- }
- surface = surfaces + numsurfaces++;
- surface->
- }
- for (j = 1;j < argc;j++)
- {
- index1 = atoi(argv[j]);
- while(argv[j][0] && argv[j][0] != '/')
- argv[j]++;
- if (argv[j][0])
- argv[j]++;
- if (index1 < 0)
- index1 = numv + 1 - index1;
- index2 = atoi(argv[j]);
- if (index2 < 0)
- index2 = numvt + 1 - index2;
- while(argv[j][0] && argv[j][0] != '/')
- argv[j]++;
- if (argv[j][0])
- argv[j]++;
- index3 = atoi(argv[j]);
- if (index3 < 0)
- index3 = numvn + 1 - index3;
- hashindex = (index1 + index2 * 3571 + index3 * 42589) & (numhashindex - 1);
- for (hash = verthash[hashindex];hash;hash = hash->next)
- if (hash->surface == numsurfaces-1 && hash->v == index1 && hash->vt == index2 && hash->vn == index3)
- break;
- if (!hash)
- {
- if (maxverthash <= numverthash)
- {
- maxverthash *= 2;
- oldverthashdata = verthashdata;
- verthashdata = Mem_Alloc(tempmempool, maxverthash * sizeof(*verthashdata));
- if (oldverthashdata)
- {
- memcpy(verthashdata, oldverthashdata, numverthash * sizeof(*verthashdata));
- Mem_Free(oldverthashdata);
- }
- }
- hash = verthashdata + numverthash++;
- hash->next = verthash[hashindex];
- hash->s = numsurfaces;
- hash->v = index1;
- hash->vt = index2;
- hash->vn = index3;
- verthash[hashindex] = hash;
- }
- index = (int)((size_t)(hash - verthashdata));
- if (j == 1)
- first = index;
- else if (j >= 3)
- {
- if (maxtriangles <= numtriangles)
- {
- maxtriangles *= 2;
- oldelement3i = element3i;
- element3i = Mem_Alloc(tempmempool, numtriangles * sizeof(int[3]));
- if (oldelement3i)
- {
- memcpy(element3i, oldelement3i, numtriangles * sizeof(int[3]));
- Mem_Free(oldelement3i);
- }
- }
- element3i[numtriangles*3+0] = first;
- element3i[numtriangles*3+1] = prev;
- element3i[numtriangles*3+2] = index;
- numtriangles++;
- }
- prev = index;
- }
- }
- else if (!strcmp(argv[0], "o") || !strcmp(argv[0], "g"))
- surface = NULL;
- else if (!!strcmp(argv[0], "usemtl"))
- {
- surface = NULL;
- strlcpy(materialname, argv[1], sizeof(materialname);
- }
- text += linelen;
- if (*text == '\r')
- text++;
- if (*text == '\n')
- text++;
- }
-
- if (skinfiles)
- Mod_FreeSkinFiles(skinfiles);
-
- // now that we have the OBJ data loaded as-is, we can convert it
- loadmodel->numskins = LittleLong(pinmodel->num_skins);
- numxyz = LittleLong(pinmodel->num_xyz);
- numst = LittleLong(pinmodel->num_st);
- loadmodel->surfmesh.num_triangles = LittleLong(pinmodel->num_tris);
- loadmodel->numframes = LittleLong(pinmodel->num_frames);
- loadmodel->surfmesh.num_morphframes = loadmodel->numframes;
- loadmodel->num_poses = loadmodel->surfmesh.num_morphframes;
- skinwidth = LittleLong(pinmodel->skinwidth);
- skinheight = LittleLong(pinmodel->skinheight);
- iskinwidth = 1.0f / skinwidth;
- iskinheight = 1.0f / skinheight;
-
- loadmodel->num_surfaces = 1;
- loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
- data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->numframes * sizeof(animscene_t) + loadmodel->numframes * sizeof(float[6]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + loadmodel->surfmesh.num_triangles * sizeof(int[3]));
- loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
- loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
- loadmodel->sortedmodelsurfaces[0] = 0;
- loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t);
- loadmodel->surfmesh.data_morphmd2framesize6f = (float *)data;data += loadmodel->numframes * sizeof(float[6]);
- loadmodel->surfmesh.data_element3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]);
- loadmodel->surfmesh.data_neighbor3i = (int *)data;data += loadmodel->surfmesh.num_triangles * sizeof(int[3]);
-
- loadmodel->synctype = ST_RAND;
-
- // load the skins
- inskin = (char *)(base + LittleLong(pinmodel->ofs_skins));
- skinfiles = Mod_LoadSkinFiles();
- if (skinfiles)
- {
- loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
- loadmodel->num_texturesperskin = loadmodel->num_surfaces;
- loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
- Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures, skinfiles, "default", "");
- Mod_FreeSkinFiles(skinfiles);
- }
- else if (loadmodel->numskins)
- {
- // skins found (most likely not a player model)
- loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
- loadmodel->num_texturesperskin = loadmodel->num_surfaces;
- loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
- for (i = 0;i < loadmodel->numskins;i++, inskin += MD2_SKINNAME)
- Mod_LoadTextureFromQ3Shader(loadmodel->data_textures + i * loadmodel->num_surfaces, inskin, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP | TEXF_COMPRESS);
- }
- else
- {
- // no skins (most likely a player model)
- loadmodel->numskins = 1;
- loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
- loadmodel->num_texturesperskin = loadmodel->num_surfaces;
- loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
- Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures, NULL);
- }
-
- loadmodel->skinscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins);
- for (i = 0;i < loadmodel->numskins;i++)
- {
- loadmodel->skinscenes[i].firstframe = i;
- loadmodel->skinscenes[i].framecount = 1;
- loadmodel->skinscenes[i].loop = true;
- loadmodel->skinscenes[i].framerate = 10;
- }
-
- // load the triangles and stvert data
- inst = (unsigned short *)(base + LittleLong(pinmodel->ofs_st));
- intri = (md2triangle_t *)(base + LittleLong(pinmodel->ofs_tris));
- md2verthash = (struct md2verthash_s **)Mem_Alloc(tempmempool, 65536 * sizeof(hash));
- md2verthashdata = (struct md2verthash_s *)Mem_Alloc(tempmempool, loadmodel->surfmesh.num_triangles * 3 * sizeof(*hash));
- // swap the triangle list
- loadmodel->surfmesh.num_vertices = 0;
- for (i = 0;i < loadmodel->surfmesh.num_triangles;i++)