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 + -
显示快捷键?