brush.cpp
来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 2,619 行 · 第 1/5 页
CPP
2,619 行
{
MemFile_fprintf(pMemFile, "( ");
for (int j = 0; j < 3; j++)
{
if (fa->planepts[i][j] == static_cast<int>(fa->planepts[i][j]))
MemFile_fprintf(pMemFile, "%i ", static_cast<int>(fa->planepts[i][j]));
else
MemFile_fprintf(pMemFile, "%f ", fa->planepts[i][j]);
}
MemFile_fprintf(pMemFile, ") ");
}
if (g_qeglobals.bSurfacePropertiesPlugin)
{
g_pMemFile = pMemFile;
#ifdef _DEBUG
if (!fa->pData)
Sys_Printf("ERROR: unexpected IPluginTexdef* is NULL in Brush_Write\n");
else
#endif
GETPLUGINTEXDEF(fa)->WriteTexdef( QERApp_MapPrintf_MEMFILE );
}
else
{
pname = fa->texdef.name;
if (pname[0] == 0)
pname = "unnamed";
MemFile_fprintf (pMemFile, "%s %i %i %i ", pname,
(int)fa->texdef.shift[0], (int)fa->texdef.shift[1],
(int)fa->texdef.rotate);
if (fa->texdef.scale[0] == (int)fa->texdef.scale[0])
MemFile_fprintf (pMemFile, "%i ", (int)fa->texdef.scale[0]);
else
MemFile_fprintf (pMemFile, "%f ", (float)fa->texdef.scale[0]);
if (fa->texdef.scale[1] == (int)fa->texdef.scale[1])
MemFile_fprintf (pMemFile, "%i", (int)fa->texdef.scale[1]);
else
MemFile_fprintf (pMemFile, "%f", (float)fa->texdef.scale[1]);
MemFile_fprintf (pMemFile, " %i %i %i", fa->texdef.contents, fa->texdef.flags, fa->texdef.value);
}
MemFile_fprintf (pMemFile, "\n");
}
MemFile_fprintf (pMemFile, "}\n");
}
}
/*
=============
Brush_Create
Create non-textured blocks for entities
The brush is NOT linked to any list
=============
*/
brush_t *Brush_Create (vec3_t mins, vec3_t maxs, texdef_t *texdef)
{
int i, j;
vec3_t pts[4][2];
face_t *f;
brush_t *b;
// brush primitive mode : convert texdef to brushprimit_texdef ?
// most of the time texdef is empty
if (g_qeglobals.m_bBrushPrimitMode)
{
// check texdef is empty .. if there are cases it's not we need to write some conversion code
if (texdef->shift[0]!=0 || texdef->shift[1]!=0 || texdef->scale[0]!=0 || texdef->scale[1]!=0 || texdef->rotate!=0)
Sys_Printf("Warning : non-zero texdef detected in Brush_Create .. need brush primitive conversion\n");
}
for (i=0 ; i<3 ; i++)
{
if (maxs[i] < mins[i])
Error ("Brush_InitSolid: backwards");
}
b = Brush_Alloc();
pts[0][0][0] = mins[0];
pts[0][0][1] = mins[1];
pts[1][0][0] = mins[0];
pts[1][0][1] = maxs[1];
pts[2][0][0] = maxs[0];
pts[2][0][1] = maxs[1];
pts[3][0][0] = maxs[0];
pts[3][0][1] = mins[1];
for (i=0 ; i<4 ; i++)
{
pts[i][0][2] = mins[2];
pts[i][1][0] = pts[i][0][0];
pts[i][1][1] = pts[i][0][1];
pts[i][1][2] = maxs[2];
}
for (i=0 ; i<4 ; i++)
{
f = Face_Alloc();
f->texdef = *texdef;
f->texdef.flags &= ~SURF_KEEP;
f->texdef.contents &= ~CONTENTS_KEEP;
f->next = b->brush_faces;
b->brush_faces = f;
j = (i+1)%4;
VectorCopy (pts[j][1], f->planepts[0]);
VectorCopy (pts[i][1], f->planepts[1]);
VectorCopy (pts[i][0], f->planepts[2]);
}
f = Face_Alloc();
f->texdef = *texdef;
f->texdef.flags &= ~SURF_KEEP;
f->texdef.contents &= ~CONTENTS_KEEP;
f->next = b->brush_faces;
b->brush_faces = f;
VectorCopy (pts[0][1], f->planepts[0]);
VectorCopy (pts[1][1], f->planepts[1]);
VectorCopy (pts[2][1], f->planepts[2]);
f = Face_Alloc();
f->texdef = *texdef;
f->texdef.flags &= ~SURF_KEEP;
f->texdef.contents &= ~CONTENTS_KEEP;
f->next = b->brush_faces;
b->brush_faces = f;
VectorCopy (pts[2][0], f->planepts[0]);
VectorCopy (pts[1][0], f->planepts[1]);
VectorCopy (pts[0][0], f->planepts[2]);
return b;
}
/*
=============
Brush_CreatePyramid
Create non-textured pyramid for light entities
The brush is NOT linked to any list
=============
*/
brush_t *Brush_CreatePyramid (vec3_t mins, vec3_t maxs, texdef_t *texdef)
{
//++timo handle new brush primitive ? return here ??
return Brush_Create(mins, maxs, texdef);
for (int i=0 ; i<3 ; i++)
if (maxs[i] < mins[i])
Error ("Brush_InitSolid: backwards");
brush_t* b = Brush_Alloc();
vec3_t corners[4];
float fMid = Q_rint(mins[2] + (Q_rint((maxs[2] - mins[2]) / 2)));
corners[0][0] = mins[0];
corners[0][1] = mins[1];
corners[0][2] = fMid;
corners[1][0] = mins[0];
corners[1][1] = maxs[1];
corners[1][2] = fMid;
corners[2][0] = maxs[0];
corners[2][1] = maxs[1];
corners[2][2] = fMid;
corners[3][0] = maxs[0];
corners[3][1] = mins[1];
corners[3][2] = fMid;
vec3_t top, bottom;
top[0] = Q_rint(mins[0] + ((maxs[0] - mins[0]) / 2));
top[1] = Q_rint(mins[1] + ((maxs[1] - mins[1]) / 2));
top[2] = Q_rint(maxs[2]);
VectorCopy(top, bottom);
bottom[2] = mins[2];
// sides
for (i = 0; i < 4; i++)
{
face_t* f = Face_Alloc();
f->texdef = *texdef;
f->texdef.flags &= ~SURF_KEEP;
f->texdef.contents &= ~CONTENTS_KEEP;
f->next = b->brush_faces;
b->brush_faces = f;
int j = (i+1)%4;
VectorCopy (top, f->planepts[0]);
VectorCopy (corners[i], f->planepts[1]);
VectorCopy(corners[j], f->planepts[2]);
f = Face_Alloc();
f->texdef = *texdef;
f->texdef.flags &= ~SURF_KEEP;
f->texdef.contents &= ~CONTENTS_KEEP;
f->next = b->brush_faces;
b->brush_faces = f;
VectorCopy (bottom, f->planepts[2]);
VectorCopy (corners[i], f->planepts[1]);
VectorCopy(corners[j], f->planepts[0]);
}
return b;
}
/*
=============
Brush_MakeSided
Makes the current brush have the given number of 2d sides
=============
*/
void Brush_MakeSided (int sides)
{
int i, axis;
vec3_t mins, maxs;
brush_t *b;
texdef_t *texdef;
face_t *f;
vec3_t mid;
float width;
float sv, cv;
if (sides < 3)
{
Sys_Status ("Bad sides number", 0);
return;
}
if (sides >= MAX_POINTS_ON_WINDING-4)
{
Sys_Printf("too many sides.\n");
return;
}
if (!QE_SingleBrush ())
{
Sys_Status ("Must have a single brush selected", 0 );
return;
}
b = selected_brushes.next;
VectorCopy (b->mins, mins);
VectorCopy (b->maxs, maxs);
texdef = &g_qeglobals.d_texturewin.texdef;
Brush_Free (b);
if (g_pParentWnd->ActiveXY())
{
switch(g_pParentWnd->ActiveXY()->GetViewType())
{
case XY: axis = 2; break;
case XZ: axis = 1; break;
case YZ: axis = 0; break;
}
}
else
{
axis = 2;
}
// find center of brush
width = 8;
for (i = 0; i < 3; i++)
{
mid[i] = (maxs[i] + mins[i]) * 0.5;
if (i == axis) continue;
if ((maxs[i] - mins[i]) * 0.5 > width)
width = (maxs[i] - mins[i]) * 0.5;
}
b = Brush_Alloc();
// create top face
f = Face_Alloc();
f->texdef = *texdef;
f->next = b->brush_faces;
b->brush_faces = f;
f->planepts[2][(axis+1)%3] = mins[(axis+1)%3]; f->planepts[2][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[2][axis] = maxs[axis];
f->planepts[1][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[1][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[1][axis] = maxs[axis];
f->planepts[0][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[0][(axis+2)%3] = maxs[(axis+2)%3]; f->planepts[0][axis] = maxs[axis];
// create bottom face
f = Face_Alloc();
f->texdef = *texdef;
f->next = b->brush_faces;
b->brush_faces = f;
f->planepts[0][(axis+1)%3] = mins[(axis+1)%3]; f->planepts[0][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[0][axis] = mins[axis];
f->planepts[1][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[1][(axis+2)%3] = mins[(axis+2)%3]; f->planepts[1][axis] = mins[axis];
f->planepts[2][(axis+1)%3] = maxs[(axis+1)%3]; f->planepts[2][(axis+2)%3] = maxs[(axis+2)%3]; f->planepts[2][axis] = mins[axis];
for (i=0 ; i<sides ; i++)
{
f = Face_Alloc();
f->texdef = *texdef;
f->next = b->brush_faces;
b->brush_faces = f;
sv = sin (i*3.14159265*2/sides);
cv = cos (i*3.14159265*2/sides);
f->planepts[0][(axis+1)%3] = floor(mid[(axis+1)%3]+width*cv+0.5);
f->planepts[0][(axis+2)%3] = floor(mid[(axis+2)%3]+width*sv+0.5);
f->planepts[0][axis] = mins[axis];
f->planepts[1][(axis+1)%3] = f->planepts[0][(axis+1)%3];
f->planepts[1][(axis+2)%3] = f->planepts[0][(axis+2)%3];
f->planepts[1][axis] = maxs[axis];
f->planepts[2][(axis+1)%3] = floor(f->planepts[0][(axis+1)%3] - width*sv + 0.5);
f->planepts[2][(axis+2)%3] = floor(f->planepts[0][(axis+2)%3] + width*cv + 0.5);
f->planepts[2][axis] = maxs[axis];
}
Brush_AddToList (b, &selected_brushes);
Entity_LinkBrush (world_entity, b);
Brush_Build( b );
Sys_UpdateWindows (W_ALL);
}
/*
=============
Brush_Free
Frees the brush with all of its faces and display list.
Unlinks the brush from whichever chain it is in.
Decrements the owner entity's brushcount.
Removes owner entity if this was the last brush
unless owner is the world.
Removes from groups
=============
*/
void Brush_Free (brush_t *b, bool bRemoveNode)
{
face_t *f, *next;
epair_t *ep, *enext;
// remove from group
if (bRemoveNode)
Group_RemoveBrush(b);
// free the patch if it's there
if (b->patchBrush)
{
Patch_Delete(b->pPatch);
}
// free faces
for (f=b->brush_faces ; f ; f=next)
{
next = f->next;
Face_Free( f );
}
//Timo : free brush epairs
for (ep = b->epairs ; ep ; ep=enext )
{
enext = ep->next;
free (ep->key);
free (ep->value);
free (ep);
}
// unlink from active/selected list
if (b->next)
Brush_RemoveFromList (b);
// unlink from entity list
if (b->onext)
Entity_UnlinkBrush (b);
free (b);
}
/*
=============
Face_MemorySize
=============
*/
int Face_MemorySize(face_t *f )
{
int size = 0;
if (f->face_winding)
{
size += _msize(f->face_winding);
}
//f->texdef.~texdef_t();;
size += _msize(f);
return size;
}
/*
=============
Brush_MemorySize
=============
*/
int Brush_MemorySize(brush_t *b)
{
face_t *f;
epair_t *ep;
int size = 0;
//
if (b->patchBrush)
{
size += Patch_MemorySize(b->pPatch);
}
//
for (f = b->brush_faces; f; f = f->next)
{
size += Face_MemorySize(f);
}
//
for (ep = b->epairs; ep; ep = ep->next )
{
size += _msize(ep->key);
size += _msize(ep->value);
size += _msize(ep);
}
size += _msize(b);
return size;
}
/*
============
Brush_Clone
Does NOT add the new brush to any lists
============
*/
brush_t *Brush_Clone (brush_t *b)
{
brush_t *n = NULL;
face_t *f, *nf;
if (b->patchBrush)
{
patchMesh_t *p = Patch_Duplicate(b->pPatch);
Brush_RemoveFromList(p->pSymbiot);
Entity_UnlinkBrush(p->pSymbiot);
n = p->pSymbiot;
}
else
{
n = Brush_Alloc();
n->numberId = g_nBrushId++;
n->owner = b->owner;
for (f=b->brush_faces ; f ; f=f->next)
{
nf = Face_Clone( f );
nf->next = n->brush_faces;
n->brush_faces = nf;
}
}
return n;
}
/*
============
Brush_Clone
Does NOT add the new brush to any lists
============
*/
brush_t *Brush_FullClone(brush_t *b)
{
brush_t *n = NULL;
face_t *f, *nf, *f2, *nf2;
int j;
if (b->patchBrush)
{
patchMesh_t *p = Patch_Duplicate(b->pPatch);
Brush_RemoveFromList(p->pSymbiot);
Entity_UnlinkBrush(p->pSymbiot);
n = p->pSymbiot;
n->owner = b->owner;
Brush_Build(n);
}
else
{
n = Brush_Alloc();
n->numberId = g_nBrushId++;
n->owner = b->owner;
VectorCopy(b->mins, n->mins);
VectorCopy(b->maxs, n->maxs);
//
for (f = b->brush_faces; f; f = f->next)
{
if (f->original) con
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?