pmesh.cpp

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

CPP
2,635
字号
	face_t		*f;
	for (f=b->brush_faces ; f ; f=f->next) 
  {
		f->texdef.flags |= SURF_PATCH; 
	}

  // FIXME: this entire type of linkage needs to be fixed
  b->pPatch = pm;
  pm->pSymbiot = b;
  pm->bSelected = false;
  pm->bOverlay = false;
  pm->bDirty = true;
  pm->nListID = -1;

  if (bLinkToWorld)
  {
    Brush_AddToList (b, &active_brushes);
	  Entity_LinkBrush (world_entity, b);
    Brush_Build(b);
  }

  return b;
}

void Patch_SetPointIntensities(int n)
{
#if 0
	patchMesh_t	*p = patchMeshes[n];
  for (int i = 0; i < p->width; i++)
  {
    for (int j = 0; j < p->height; j++)
    {

    }
  }
#endif
}

// very approximate widths and heights

/*
==================
Patch_Width
==================
*/
float Patch_Width(patchMesh_t *p)
{
  float f = 0;
  for (int i = 0; i < p->width-1; i++)
  {
    vec3_t vTemp;
    VectorSubtract(p->ctrl[i][0].xyz, p->ctrl[i+1][0].xyz, vTemp);
    f += VectorLength(vTemp);
  }
  return f;
}

float Patch_WidthDistanceTo(patchMesh_t *p, int j)
{
  float f = 0;
  for (int i = 0; i < j; i++)
  {
    vec3_t vTemp;
    VectorSubtract(p->ctrl[i][0].xyz, p->ctrl[i+1][0].xyz, vTemp);
    f += VectorLength(vTemp);
  }
  return f;
}



/*
==================
Patch_Height
==================
*/
float Patch_Height(patchMesh_t *p)
{
  float f = 0;
  for (int i = 0; i < p->height-1; i++)
  {
    vec3_t vTemp;
    VectorSubtract(p->ctrl[0][i].xyz, p->ctrl[0][i+1].xyz, vTemp);
    f += VectorLength(vTemp);
  }
  return f;
}

float Patch_HeightDistanceTo(patchMesh_t *p, int j)
{
  float f = 0;
  for (int i = 0; i < j; i++)
  {
    vec3_t vTemp;
    VectorSubtract(p->ctrl[0][i].xyz, p->ctrl[0][i+1].xyz, vTemp);
    f += VectorLength(vTemp);
  }
  return f;
}



/*
==================
Patch_Naturalize
==================
texture = TotalTexture * LengthToThisControlPoint / TotalControlPointLength

dist( this control point to first control point ) / dist ( last control pt to first)
*/
void Patch_Naturalize(patchMesh_t *p)
{
  int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? p->d_texture->width * 0.5 : p->d_texture->width;
  int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? p->d_texture->height * 0.5 : p->d_texture->height;
  float fPWidth = Patch_Width(p);
  float fPHeight = Patch_Height(p);
  float xAccum = 0;
  for ( int i = 0 ; i < p->width ; i++ ) 
  {
    float yAccum = 0;
	  for ( int j = 0 ; j < p->height ; j++ ) 
    {
		  p->ctrl[i][j].st[0] = (fPWidth / nWidth) * xAccum / fPWidth;
		  p->ctrl[i][j].st[1] = (fPHeight / nHeight) * yAccum / fPHeight;
		  yAccum = Patch_HeightDistanceTo(p,j+1);
      //p->ctrl[i][j][3] = (fPWidth / nWidth) * (float)i / (p->width - 1);
		  //p->ctrl[i][j][4] = (fPHeight/ nHeight) * (float)j / (p->height - 1);
	  }
    xAccum = Patch_WidthDistanceTo(p,i+1);
  }
  p->bDirty = true;
}

/*
  if (bIBevel)
  {
    VectorCopy(p->ctrl[1][0], p->ctrl[1][1]);
  }

  if (bIEndcap)
  {
    VectorCopy(p->ctrl[3][0], p->ctrl[4][1]);
    VectorCopy(p->ctrl[2][0], p->ctrl[3][1]);
    VectorCopy(p->ctrl[2][0], p->ctrl[2][1]);
    VectorCopy(p->ctrl[2][0], p->ctrl[1][1]);
    VectorCopy(p->ctrl[1][0], p->ctrl[0][1]);
    VectorCopy(p->ctrl[1][0], p->ctrl[0][2]);
    VectorCopy(p->ctrl[1][0], p->ctrl[1][2]);
    VectorCopy(p->ctrl[2][0], p->ctrl[2][2]);
    VectorCopy(p->ctrl[3][0], p->ctrl[3][2]);
    VectorCopy(p->ctrl[3][0], p->ctrl[4][2]);
  }
*/

int Index3By[][2] =
{
  {0,0},
  {1,0},
  {2,0},
  {2,1},
  {2,2},
  {1,2},
  {0,2},
  {0,1},
  {0,0},
  {0,0},
  {0,0},
  {0,0},
  {0,0},
  {0,0},
  {0,0}
};

int Index5By[][2] =
{
  {0,0},
  {1,0},
  {2,0},
  {3,0},
  {4,0},
  {4,1},
  {4,2},
  {4,3},
  {4,4},
  {3,4},
  {2,4},
  {1,4},
  {0,4},
  {0,3},
  {0,2},
  {0,1}
};



int Interior3By[][2] =
{
  {1,1}
};

int Interior5By[][2] =
{
  {1,1},
  {2,1},
  {3,1},
  {1,2},
  {2,2},
  {3,2},
  {1,3},
  {2,3},
  {3,3}
};

int Interior3ByCount = sizeof(Interior3By) / sizeof(int[2]);
int Interior5ByCount = sizeof(Interior5By) / sizeof(int[2]);

face_t* Patch_GetAxisFace(patchMesh_t *p)
{
  face_t *f = NULL;
  vec3_t vTemp;
  brush_t *b = p->pSymbiot;

	for (f = b->brush_faces ; f ; f = f->next) 
  {
    VectorSubtract(f->face_winding->points[1], f->face_winding->points[0], vTemp);
    int nScore = 0;

    // default edge faces on caps are 8 high so
    // as soon as we hit one that is bigger it should be on the right axis
    for (int j = 0; j < 3; j++)
    {
      if (vTemp[j] > 8)
        nScore++;
    }

    if (nScore > 0)
      break;
  }

  if (f == NULL)
    f = b->brush_faces;
  return f;
}

int g_nFaceCycle = 0;

face_t* nextFace(patchMesh_t *p)
{
  brush_t *b = p->pSymbiot;
  face_t *f = NULL;
  int n = 0;
	for (f = b->brush_faces ; f && n <= g_nFaceCycle; f = f->next) 
  {
    n++;
  }
  g_nFaceCycle++;
  if (g_nFaceCycle > 5)
  {
    g_nFaceCycle =0;
    f = b->brush_faces;
  }

  return f;
}


extern void EmitTextureCoordinates ( float *xyzst, qtexture_t *q, face_t *f);
void Patch_CapTexture(patchMesh_t *p, bool bFaceCycle = false)
{
  Patch_MeshNormals(p);
  face_t *f = (bFaceCycle) ? nextFace(p) : Patch_GetAxisFace(p);
  vec3_t vSave;
  VectorCopy(f->plane.normal, vSave);
  
  float fRotate = f->texdef.rotate;
  f->texdef.rotate = 0;
  float fScale[2];
  fScale[0] = f->texdef.scale[0];
  fScale[1] = f->texdef.scale[1];
  f->texdef.scale[0] = 0.5;
  f->texdef.scale[1] = 0.5;
  float fShift[2];
  fShift[0] = f->texdef.shift[0];
  fShift[1] = f->texdef.shift[1];
  f->texdef.shift[0] = 0;
  f->texdef.shift[1] = 0;
  
  for (int i = 0; i < p->width; i++)
  {
    for (int j = 0; j < p->height; j++)
    {
      if (!bFaceCycle)
      {
        VectorCopy(p->ctrl[i][j].normal, f->plane.normal);
      }
		  EmitTextureCoordinates( p->ctrl[i][j].xyz, f->d_texture, f);
    }
  }
  VectorCopy(vSave, f->plane.normal);
  f->texdef.rotate = fRotate;
  f->texdef.scale[0] = fScale[0];
  f->texdef.scale[1] = fScale[1];
  f->texdef.shift[0] = fShift[0];
  f->texdef.shift[1] = fShift[1];
  p->bDirty = true;
}

void FillPatch(patchMesh_t *p, vec3_t v)
{
  for (int i = 0; i < p->width; i++)
  {
    for (int j = 0; j < p->height; j++)
    {
      VectorCopy(v, p->ctrl[i][j].xyz);
    }
  }
}

brush_t* Cap(patchMesh_t *pParent, bool bByColumn, bool bFirst)
{
  brush_t *b;
  patchMesh_t *p;
  vec3_t vMin, vMax;
  int i, j;

  bool bSmall = true;
  // make a generic patch
  if (pParent->width <= 9)
  {
    b = Patch_GenericMesh(3, 3, 2, false);
  }
  else
  {
    b = Patch_GenericMesh(5, 5, 2, false);
    bSmall = false;
  }

  if (!b)
  {
    Sys_Printf("Unable to cap. You may need to ungroup the patch.\n");
    return NULL;
  }

  p = b->pPatch;
  p->type |= PATCH_CAP;

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

  // we seam the column edge, FIXME: this might need to be able to seem either edge
  // 
  int nSize = (bByColumn) ? pParent->width : pParent->height;
  int nIndex = (bFirst) ? 0 : (bByColumn) ? pParent->height-1 : pParent->width-1;

  FillPatch(p, pParent->ctrl[0][nIndex].xyz);

  for (i = 0; i < nSize; i++)
  {
    if (bByColumn)
    {
      if (bSmall)
      {
        VectorCopy(pParent->ctrl[i][nIndex].xyz, p->ctrl[Index3By[i][0]][Index3By[i][1]].xyz);
      }
      else
      {
        VectorCopy(pParent->ctrl[i][nIndex].xyz, p->ctrl[Index5By[i][0]][Index5By[i][1]].xyz);
      }
    }
    else
    {
      if (bSmall)
      {
        VectorCopy(pParent->ctrl[nIndex][i].xyz, p->ctrl[Index3By[i][0]][Index3By[i][1]].xyz);
      }
      else
      {
        VectorCopy(pParent->ctrl[nIndex][i].xyz, p->ctrl[Index5By[i][0]][Index5By[i][1]].xyz);
      }
    }
  
    for (j = 0; j < 3; j++)
    {
      float f = (bSmall) ? p->ctrl[Index3By[i][0]][Index3By[i][1]].xyz[j] : p->ctrl[Index5By[i][0]][Index5By[i][1]].xyz[j];
      if (f < vMin[j])
        vMin[j] = f;
      if (f > vMax[j])
        vMax[j] = f;
    }
  }

  vec3_t vTemp;
  for (j = 0; j < 3; j++)
  {
    vTemp[j] = vMin[j] + abs((vMax[j] - vMin[j]) * 0.5);
  }

  int nCount = (bSmall) ? Interior3ByCount : Interior5ByCount;
  for (j = 0; j < nCount; j++)
  {
    if (bSmall)
    {
      VectorCopy(vTemp, p->ctrl[Interior3By[j][0]][Interior3By[j][1]].xyz);
    }
    else
    {
      VectorCopy(vTemp, p->ctrl[Interior5By[j][0]][Interior5By[j][1]].xyz);
    }
  }

  if (bFirst)
  {
    drawVert_t vertTemp;
    for (i = 0; i < p->width; i++)
    {
      for (j = 0; j < p->height / 2; j++)
      {
        memcpy(&vertTemp, &p->ctrl[i][p->height - 1- j], sizeof (drawVert_t));
        memcpy(&p->ctrl[i][p->height - 1 - j], &p->ctrl[i][j], sizeof(drawVert_t));
        memcpy(&p->ctrl[i][j], &vertTemp, sizeof(drawVert_t));
      }
    }
  }

  Patch_Rebuild(p);
  Patch_CapTexture(p);
  return p->pSymbiot;
}

brush_t* CapSpecial(patchMesh_t *pParent, int nType, bool bFirst)
{
  brush_t *b;
  patchMesh_t *p;
  vec3_t vMin, vMax, vTemp;
  int i, j;

  if (nType == CCapDialog::IENDCAP)
    b = Patch_GenericMesh(5, 3, 2, false);
  else
    b = Patch_GenericMesh(3, 3, 2, false);

  if (!b)
  {
    Sys_Printf("Unable to cap. Make sure you ungroup before re-capping.");
    return NULL;
  }

  p = b->pPatch;
  p->type |= PATCH_CAP;

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

  int nSize = pParent->width;
  int nIndex = (bFirst) ? 0 : pParent->height-1;

  // parent bounds are used for some things
  Patch_CalcBounds(pParent, vMin, vMax);

  for (j = 0; j < 3; j++)
  {
    vTemp[j] = vMin[j] + abs((vMax[j] - vMin[j]) * 0.5);
  }

  if (nType == CCapDialog::IBEVEL)
  {
    VectorCopy(pParent->ctrl[0][nIndex].xyz, p->ctrl[0][0].xyz);
    VectorCopy(pParent->ctrl[2][nIndex].xyz, p->ctrl[0][2].xyz);
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p->ctrl[0][1].xyz);
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p->ctrl[2][2].xyz);
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p->ctrl[1][0].xyz);
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p->ctrl[1][1].xyz);
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p->ctrl[1][2].xyz);
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p->ctrl[2][0].xyz);
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p->ctrl[2][1].xyz);
  }
  else if (nType == CCapDialog::BEVEL)
  {
    vec3_t p1, p2, p3, p4, temp, dir;

    VectorCopy(pParent->ctrl[0][nIndex].xyz, p3);
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p1);
    VectorCopy(pParent->ctrl[2][nIndex].xyz, p2);

    VectorSubtract(p3, p2, dir);
    VectorNormalize(dir);
    VectorSubtract(p1, p2, temp);
    vec_t dist = _DotProduct(temp, dir);

    VectorScale(dir, dist, temp);

    VectorAdd(p2, temp, temp);

    VectorSubtract(temp, p1, temp);
    VectorScale(temp, 2, temp);
    VectorAdd(p1, temp, p4);

    VectorCopy(p4, p->ctrl[0][0].xyz);
    VectorCopy(p4, p->ctrl[1][0].xyz);
    VectorCopy(p4, p->ctrl[0][1].xyz);
    VectorCopy(p4, p->ctrl[1][1].xyz);
    VectorCopy(p4, p->ctrl[0][2].xyz);
    VectorCopy(p4, p->ctrl[1][2].xyz);
    VectorCopy(p3, p->ctrl[2][0].xyz);
    VectorCopy(p1, p->ctrl[2][1].xyz);
    VectorCopy(p2, p->ctrl[2][2].xyz);

  }
  else if (nType == CCapDialog::ENDCAP)
  {
    VectorAdd(pParent->ctrl[4][nIndex].xyz, pParent->ctrl[0][nIndex].xyz, vTemp);
    VectorScale(vTemp, 0.5, vTemp);
    VectorCopy(pParent->ctrl[0][nIndex].xyz, p->ctrl[0][0].xyz);
                       VectorCopy(vTemp, p->ctrl[1][0].xyz);
    VectorCopy(pParent->ctrl[4][nIndex].xyz, p->ctrl[2][0].xyz);

    VectorCopy(pParent->ctrl[2][nIndex].xyz, p->ctrl[0][2].xyz);
    VectorCopy(pParent->ctrl[2][nIndex].xyz, p->ctrl[1][2].xyz);
    VectorCopy(pParent->ctrl[2][nIndex].xyz, p->ctrl[2][2].xyz);
    VectorCopy(pParent->ctrl[2][nIndex].xyz, p->ctrl[1][1].xyz);
    
    VectorCopy(pParent->ctrl[1][nIndex].xyz, p->ctrl[0][1].xyz);
    VectorCopy(pParent->ctrl[3][nIndex].xyz, p->ctrl[2][1].xyz);
  }
  else
  {
    VectorCopy(pParent->ctrl[0][nIndex].xyz, p->ctrl[0][0].xyz);

⌨️ 快捷键说明

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