eclass.cpp

来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 912 行 · 第 1/2 页

CPP
912
字号
#include "stdafx.h"
#include "qe3.h"
#include "io.h"
#include "pakstuff.h"
//#include "qertypes.h"

eclass_t	*eclass = NULL;
eclass_t	*eclass_bad = NULL;
char		eclass_directory[1024];

// md3 cache for misc_models
eclass_t *g_md3Cache = NULL;

/*

the classname, color triple, and bounding box are parsed out of comments
A ? size means take the exact brush size.

/*QUAKED <classname> (0 0 0) ?
/*QUAKED <classname> (0 0 0) (-8 -8 -8) (8 8 8)

Flag names can follow the size description:

/*QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK GOLD_KEY SILVER_KEY

*/

void CleanEntityList(eclass_t *&pList)
{
  while (pList)
  {
    eclass_t* pTemp = pList->next;

    entitymodel *model = pList->model;
    while (model != NULL)
    {
      delete []model->pTriList;
      model = model->pNext;
    }
    
    if (pList->modelpath)
      free(pList->modelpath);
	  if (pList->skinpath)			// PGM
		  free(pList->skinpath);		// PGM
    
    free(pList->name);
    free(pList->comments);
    free(pList);
    pList = pTemp;
  }

  pList = NULL;

}


void CleanUpEntities()
{
  CleanEntityList(eclass);
  CleanEntityList(g_md3Cache);
/*
  while (eclass)
  {
    eclass_t* pTemp = eclass->next;
    delete []eclass->pTriList;
    
    if (eclass->modelpath)
      free(eclass->modelpath);
	  if (eclass->skinpath)			// PGM
		  free(eclass->skinpath);		// PGM
    
    free(eclass->name);
    free(eclass->comments);
    free(eclass);
    eclass = pTemp;
  }

  eclass = NULL;
*/
  if (eclass_bad)
  {
    free(eclass_bad->name);
    free(eclass_bad->comments);
    free(eclass_bad);
    eclass_bad = NULL;
  }
}

void ExtendBounds(vec3_t v, vec3_t &vMin, vec3_t &vMax)
{
	for (int i = 0 ;i < 3 ;i++)
	{
		vec_t f = v[i];
		
    if (f < vMin[i])
    {
			vMin[i] = f;
    }

    if (f > vMax[i])
    {
			vMax[i] = f;
    }
	}
}



// FIXME: this code is a TOTAL clusterfuck
//
void LoadModel(const char *pLocation, eclass_t *e, vec3_t &vMin, vec3_t &vMax, entitymodel *&pModel, const char *pSkin)
{
  // this assumes a path only and uses tris.md2
  // for the model and skin.pcx for the skin
  char cPath[1024];
  char cSkin[1024];
  char cFullLocation[1024];
	//struct _finddata_t fileinfo;

  vMin[0] = vMin[1] = vMin[2] = 99999;
  vMax[0] = vMax[1] = vMax[2] = -99999;

  bool bMD3 = false;
  bool bASE = false;

  strcpy( cFullLocation, pLocation );

  if (strstr(pLocation, ".md3"))
  {
    bMD3 = true;
  }
  else if (strstr(pLocation, ".md2") != NULL)
  {
	  sprintf( cFullLocation, "%stris.md2", pLocation);
  }
  else if (strstr(pLocation, ".ase") != NULL)
  {
    bASE = true;
  }

  sprintf( cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), cFullLocation);

  Sys_Printf("Loading model %s...", cPath);
  unsigned char* p = NULL;
  bool bOpen = (LoadFile(cPath, reinterpret_cast<void**>(&p)) > 0);
  if (!bOpen)
  {
    Sys_Printf(" failed. Trying PAK file...");
//    sprintf (cPath, "%stris.md2", pLocation);
	  strcpy (cPath, cFullLocation);
	  bOpen = (PakLoadAnyFile(cPath, reinterpret_cast<void**>(&p)) > 0);
  }

  if (bOpen)
  {
    Sys_Printf(" successful.\n");

    if (bASE)
    {
/*
      free(p);
      CString strOut;
      ::GetTempPath(1024, strOut.GetBuffer(1024));
      strOut.ReleaseBuffer();
      AddSlash(strOut);
      strOut += "Temp.ase";
      CopyFile(cPath, strOut, false);
      CString strIn = strOut;
      FindReplace(strOut, ".ase", ".md3");
      strcpy(cPath, strIn);
      strcpy(cSkin, strOut);
      Q3Data_ProduceTempMD3(ValueForKey(g_qeglobals.d_project_entity, "basepath"), cPath, cSkin);
      CString strModel = cPath;
      if (LoadFile(strOut.GetBuffer(0), reinterpret_cast<void**>(&p)) == 0)
      {
        Sys_Printf(" Conversion from ASE failed.\n");
        return;
      }
      bMD3 = true;
*/
    }

    if (bMD3)
    {
	    md3Header_t header;
	    md3Surface_t *pSurface;
    	header = *(md3Header_t *)p;
      if (pSkin != NULL)
      {
        strcpy(cSkin, pSkin);
      }
	    else
      {
		    cSkin[0] = '\0';
      }
      int n = header.numFrames;
    	pSurface = (md3Surface_t *) (p + header.ofsSurfaces);
    	for (int z = 0; z < header.numSurfaces; z++ )
	    {
        int nTris = pSurface->numTriangles;
        
        //unsigned char* pTris = reinterpret_cast<unsigned char*>(pSurface);
        //pTris += pSurface->ofsTriangles;

        if (nTris > 0)
        {
          int nStart = 0;
          if (pModel->pTriList == NULL)
          {
		        pModel->nModelPosition = 0;
            pModel->pTriList = new trimodel[nTris];
            pModel->nTriCount = nTris;
          }
          else
          {
            // already have one so we need to reallocate
            int nNewCount = pModel->nTriCount + nTris;
            trimodel* pNewModels = new trimodel[nNewCount];
            for (int i = 0; i < pModel->nTriCount; i++)
            {
              memcpy(&pNewModels[i], &pModel->pTriList[i], sizeof(trimodel));
            }
            nStart = pModel->nTriCount;
            pModel->nTriCount = nNewCount;
            //nTris = nNewCount;
            delete [] pModel->pTriList;
            pModel->pTriList = pNewModels;
          }
          
          md3Triangle_t *pTris = reinterpret_cast<md3Triangle_t*>((reinterpret_cast<unsigned char*>(pSurface) + pSurface->ofsTriangles));
          md3XyzNormal_t *pXyz = reinterpret_cast<md3XyzNormal_t*>((reinterpret_cast<unsigned char*>(pSurface) + pSurface->ofsXyzNormals));
          if (e->nFrame < pSurface->numFrames)
          {
            pXyz += (e->nFrame * pSurface->numVerts);
          }

          md3St_t *pST = reinterpret_cast<md3St_t*>((reinterpret_cast<unsigned char*>(pSurface) + pSurface->ofsSt)); 

          for (int i = 0; i < nTris; i++)
          {
            for (int k = 0; k < 3; k ++)
            {
              for (int j = 0; j < 3; j++)
              {
                //e->pTriList[i].v[k][j] = (f->verts[tri.index_xyz[k]].v[j] * f->scale[j] + f->translate[j]);
                pModel->pTriList[nStart].v[k][j] = pXyz[pTris[i].indexes[k]].xyz[j] * MD3_XYZ_SCALE;
              }
		          pModel->pTriList[nStart].st[k][0] = pST[pTris[i].indexes[k]].st[0];
		          pModel->pTriList[nStart].st[k][1] = pST[pTris[i].indexes[k]].st[1];
 		          ExtendBounds (pModel->pTriList[nStart].v[k], vMin, vMax);
		        }
            nStart++;
		      }

        }

        md3Shader_t *pShader = reinterpret_cast<md3Shader_t*>((reinterpret_cast<unsigned char*>(pSurface) + pSurface->ofsShaders)); 
        sprintf (cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), pShader->name);
        strlwr(cPath);
 	      pModel->nTextureBind = Texture_LoadSkin(cPath, &pModel->nSkinWidth, &pModel->nSkinHeight);
        if (pModel->nTextureBind == -1)
        {
          Sys_Printf("Model skin load failed on texture %s\n", cPath);
        }
		    pSurface = (md3Surface_t *) ((( char * ) pSurface) + pSurface->ofsEnd);
        pModel->pNext = reinterpret_cast<entitymodel_t*>(qmalloc(sizeof(entitymodel_t)));
        pModel = pModel->pNext;
      }
    }
    else
    {

      dmdl_t model;
      daliasframe_t *f;
      unsigned char* pTris = p;
      dstvert_t *pST = NULL;
      int nTris = 0;

      // grab model params
      memcpy(&model, p, sizeof(dmdl_t));
      f = (daliasframe_t*)(p + model.ofs_frames);
      pTris += model.ofs_tris;
      pST = reinterpret_cast<dstvert_t*>(p + model.ofs_st);
      nTris = model.num_tris;

	    if(pSkin)
	    {
		    strcpy (cSkin, pSkin);
		    if ((cSkin[strlen(cSkin)-1] == '\\') || (cSkin[strlen(cSkin)-1] == '/'))
			    strcat(cSkin, "skin.pcx\0");
	    }
	    else
      {
		    strcpy(cSkin, (char *)(p + model.ofs_skins));
      }

      sprintf (cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), cSkin);
      strlwr(cPath);
      pModel->nTextureBind = Texture_LoadSkin(cPath, &pModel->nSkinWidth, &pModel->nSkinHeight);
      if (pModel->nTextureBind == -1)
      {
        Sys_Printf("Model skin load failed on texture %s\n", cPath);
      }
      int nStart = 0;
      if (pModel->pTriList == NULL)
      {
		    pModel->nModelPosition = 0;
        pModel->pTriList = new trimodel[nTris];
        pModel->nTriCount = nTris;
      }
      else
      {
        // already have one so we need to reallocate
        int nNewCount = pModel->nTriCount + nTris;
        trimodel* pNewModels = new trimodel[nNewCount];
        for (int i = 0; i < pModel->nTriCount; i++)
        {
          memcpy(&pNewModels[i], &pModel->pTriList[i], sizeof(trimodel));
        }
        nStart = pModel->nTriCount;
        pModel->nTriCount = nNewCount;
        nTris = nNewCount;
        delete [] pModel->pTriList;
        pModel->pTriList = pNewModels;
      }
      
      for (int i = nStart; i < nTris; i++)
      {
        dtriangle_t tri;
        memcpy(&tri, pTris, sizeof(dtriangle_t));
        for (int k = 0; k < 3; k ++)
        {
          for (int j = 0; j < 3; j++)
          {
            pModel->pTriList[i].v[k][j] = (f->verts[tri.index_xyz[k]].v[j] * f->scale[j] + f->translate[j]);
          }

          pModel->pTriList[i].st[k][0] = pST[tri.index_st[k]].s / pModel->nSkinWidth;
          pModel->pTriList[i].st[k][1] = pST[tri.index_st[k]].t / pModel->nSkinHeight;;
          ExtendBounds (pModel->pTriList[i].v[k], vMin, vMax);
		    }
        pTris += sizeof(dtriangle_t);
		  }
    }
    free(p);
  }
  else
  {
    Sys_Printf(" failed.\n");
  }

#if 0
  if (pModel->pTriList != NULL && pModel->nTriCount > 0 && !bMD3)
  {
	  if(fabs(vMin[2]) < ((vMax[2]-vMin[2]) / 10.0))	// > 90% above 0 point.
	    pModel->nModelPosition = 1;
//	sprintf (cPath, "%s/%sskin.pcx", ValueForKey(g_qeglobals.d_project_entity, "basepath"), pLocation);
    sprintf (cPath, "%s/%s", ValueForKey(g_qeglobals.d_project_entity, "basepath"), cSkin);
 	  pModel->nTextureBind = Texture_LoadSkin(cPath, &pModel->nSkinWidth, &pModel->nSkinHeight);
    if (pModel->nTextureBind == -1)
    {
//      sprintf (cPath, "%sskin.pcx", pLocation);
		  strcpy (cPath, cSkin);
      pModel->nTextureBind = Texture_LoadSkin(cPath, &pModel->nSkinWidth, &pModel->nSkinHeight);
    }
  }
#endif

}

void setSpecialLoad(eclass_t *e, const char* pWhat, char*& p)
{
  CString str = e->comments;
  int n = str.Find(pWhat);
  if (n >= 0)
  {
    char* pText = e->comments + n + strlen(pWhat);
    if (*pText == '\"')
      pText++;

    str = "";
    while (*pText != '\"' && *pText != '\0')
    {
      str += *pText;
      pText++;
    }
    if (str.GetLength() > 0)
    {         
      p = strdup(str);
      //--LoadModel(str, e);
    }
  }
}

char	*debugname;

eclass_t *Eclass_InitFromText (char *text)
{
	char	*t;
	int		len;
	int		r, i;
	char	parms[256], *p;
	eclass_t	*e;
	char	color[128];

	e = (eclass_t*)qmalloc(sizeof(*e));
	memset (e, 0, sizeof(*e));
	
	text += strlen("/*QUAKED ");
	
// grab the name
	text = COM_Parse (text);
	e->name = (char*)qmalloc (strlen(com_token)+1);
	strcpy (e->name, com_token);
	debugname = e->name;
	
// grab the color, reformat as texture name
	r = sscanf (text," (%f %f %f)", &e->color[0], &e->color[1], &e->color[2]);
	if (r != 3)
		return e;
	sprintf (color, "(%f %f %f)", e->color[0], e->color[1], e->color[2]);
	//strcpy (e->texdef.name, color);
	e->texdef.SetName(color);

	while (*text != ')')
	{
		if (!*text)
			return e;
		text++;
	}
	text++;
	
// get the size	
	text = COM_Parse (text);
	if (com_token[0] == '(')
	{	// parse the size as two vectors
		e->fixedsize = true;
		r = sscanf (text,"%f %f %f) (%f %f %f)", &e->mins[0], &e->mins[1], &e->mins[2],
			&e->maxs[0], &e->maxs[1], &e->maxs[2]);
		if (r != 6)
			return e;

		for (i=0 ; i<2 ; i++)
		{
			while (*text != ')')
			{
				if (!*text)
					return e;
				text++;
			}
			text++;
		}
	}
	else
	{	// use the brushes
	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?