brush.cpp
来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 2,619 行 · 第 1/5 页
CPP
2,619 行
#include "stdafx.h"
#include <assert.h>
#include "qe3.h"
#include "winding.h"
// globals
int g_nBrushId = 0;
const char* Brush_Name(brush_t *b)
{
static char cBuff[1024];
b->numberId = g_nBrushId++;
if (g_qeglobals.m_bBrushPrimitMode)
{
sprintf(cBuff, "Brush %i", b->numberId);
Brush_SetEpair(b, "Name", cBuff);
}
return cBuff;
}
brush_t *Brush_Alloc()
{
brush_t *b = (brush_t*)qmalloc(sizeof(brush_t));
return b;
}
void PrintWinding (winding_t *w)
{
int i;
printf ("-------------\n");
for (i=0 ; i<w->numpoints ; i++)
printf ("(%5.2f, %5.2f, %5.2f)\n", w->points[i][0]
, w->points[i][1], w->points[i][2]);
}
void PrintPlane (plane_t *p)
{
printf ("(%5.2f, %5.2f, %5.2f) : %5.2f\n", p->normal[0], p->normal[1],
p->normal[2], p->dist);
}
void PrintVector (vec3_t v)
{
printf ("(%5.2f, %5.2f, %5.2f)\n", v[0], v[1], v[2]);
}
/*
=============================================================================
TEXTURE COORDINATES
=============================================================================
*/
/*
==================
textureAxisFromPlane
==================
*/
vec3_t baseaxis[18] =
{
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
};
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
{
int bestaxis;
float dot,best;
int i;
best = 0;
bestaxis = 0;
for (i=0 ; i<6 ; i++)
{
dot = DotProduct (pln->normal, baseaxis[i*3]);
if (dot > best)
{
best = dot;
bestaxis = i;
}
}
VectorCopy (baseaxis[bestaxis*3+1], xv);
VectorCopy (baseaxis[bestaxis*3+2], yv);
}
float lightaxis[3] = {0.6, 0.8, 1.0};
/*
================
SetShadeForPlane
Light different planes differently to
improve recognition
================
*/
float SetShadeForPlane (plane_t *p)
{
int i;
float f;
// axial plane
for (i=0 ; i<3 ; i++)
if (fabs(p->normal[i]) > 0.9)
{
f = lightaxis[i];
return f;
}
// between two axial planes
for (i=0 ; i<3 ; i++)
if (fabs(p->normal[i]) < 0.1)
{
f = (lightaxis[(i+1)%3] + lightaxis[(i+2)%3])/2;
return f;
}
// other
f= (lightaxis[0] + lightaxis[1] + lightaxis[2]) / 3;
return f;
}
vec3_t vecs[2];
float shift[2];
/*
================
Face_Alloc
================
*/
face_t *Face_Alloc( void )
{
face_t *f = (face_t*)qmalloc( sizeof( *f ) );
if (g_qeglobals.bSurfacePropertiesPlugin)
f->pData = static_cast<void *>( g_SurfaceTable.m_pfnTexdefAlloc( f ) );
return f;
}
/*
================
Face_Free
================
*/
void Face_Free( face_t *f )
{
assert( f != 0 );
if ( f->face_winding )
{
free( f->face_winding );
f->face_winding = 0;
}
if (g_qeglobals.bSurfacePropertiesPlugin)
{
#ifdef _DEBUG
if ( !f->pData )
{
Sys_Printf("WARNING: unexpected IPluginTexdef is NULL in Face_Free\n");
}
else
#endif
GETPLUGINTEXDEF(f)->DecRef();
}
f->texdef.~texdef_t();;
free( f );
}
/*
================
Face_Clone
================
*/
face_t *Face_Clone (face_t *f)
{
face_t *n;
n = Face_Alloc();
n->texdef = f->texdef;
memcpy (n->planepts, f->planepts, sizeof(n->planepts));
// all other fields are derived, and will be set by Brush_Build
return n;
}
/*
================
Face_FullClone
makes an exact copy of the face
================
*/
face_t *Face_FullClone (face_t *f)
{
face_t *n;
n = Face_Alloc();
n->texdef = f->texdef;
memcpy(n->planepts, f->planepts, sizeof(n->planepts));
memcpy(&n->plane, &f->plane, sizeof(plane_t));
if (f->face_winding)
n->face_winding = Winding_Clone(f->face_winding);
else
n->face_winding = NULL;
n->d_texture = Texture_ForName( n->texdef.name );
return n;
}
/*
================
Clamp
================
*/
void Clamp(float& f, int nClamp)
{
float fFrac = f - static_cast<int>(f);
f = static_cast<int>(f) % nClamp;
f += fFrac;
}
/*
================
Face_MoveTexture
================
*/
void Face_MoveTexture(face_t *f, vec3_t delta)
{
vec3_t vX, vY;
/*
#ifdef _DEBUG
if (g_PrefsDlg.m_bBrushPrimitMode)
Sys_Printf("Warning : Face_MoveTexture not done in brush primitive mode\n");
#endif
*/
if (g_qeglobals.m_bBrushPrimitMode)
Face_MoveTexture_BrushPrimit( f, delta );
else
{
TextureAxisFromPlane(&f->plane, vX, vY);
vec3_t vDP, vShift;
vDP[0] = DotProduct(delta, vX);
vDP[1] = DotProduct(delta, vY);
double fAngle = f->texdef.rotate / 180 * Q_PI;
double c = cos(fAngle);
double s = sin(fAngle);
vShift[0] = vDP[0] * c - vDP[1] * s;
vShift[1] = vDP[0] * s + vDP[1] * c;
if (!f->texdef.scale[0])
f->texdef.scale[0] = 1;
if (!f->texdef.scale[1])
f->texdef.scale[1] = 1;
f->texdef.shift[0] -= vShift[0] / f->texdef.scale[0];
f->texdef.shift[1] -= vShift[1] / f->texdef.scale[1];
// clamp the shifts
Clamp(f->texdef.shift[0], f->d_texture->width);
Clamp(f->texdef.shift[1], f->d_texture->height);
}
}
/*
================
Face_SetColor
================
*/
void Face_SetColor (brush_t *b, face_t *f, float fCurveColor)
{
float shade;
qtexture_t *q;
q = f->d_texture;
// set shading for face
shade = SetShadeForPlane (&f->plane);
if (g_pParentWnd->GetCamera()->Camera().draw_mode == cd_texture && !b->owner->eclass->fixedsize)
{
//if (b->curveBrush)
// shade = fCurveColor;
f->d_color[0] =
f->d_color[1] =
f->d_color[2] = shade;
}
else
{
f->d_color[0] = shade*q->color[0];
f->d_color[1] = shade*q->color[1];
f->d_color[2] = shade*q->color[2];
}
}
/*
================
Face_TextureVectors
TTimo: NOTE: this is never to get called while in brush primitives mode
================
*/
void Face_TextureVectors (face_t *f, float STfromXYZ[2][4])
{
vec3_t pvecs[2];
int sv, tv;
float ang, sinv, cosv;
float ns, nt;
int i,j;
qtexture_t *q;
texdef_t *td;
#ifdef _DEBUG
//++timo when playing with patches, this sometimes get called and the Warning is displayed
// find some way out ..
if (g_qeglobals.m_bBrushPrimitMode && !g_qeglobals.bNeedConvert)
Sys_Printf("Warning : illegal call of Face_TextureVectors in brush primitive mode\n");
#endif
td = &f->texdef;
q = f->d_texture;
memset (STfromXYZ, 0, 8*sizeof(float));
if (!td->scale[0])
td->scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
if (!td->scale[1])
td->scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1;
// get natural texture axis
TextureAxisFromPlane(&f->plane, pvecs[0], pvecs[1]);
// rotate axis
if (td->rotate == 0)
{ sinv = 0 ; cosv = 1; }
else if (td->rotate == 90)
{ sinv = 1 ; cosv = 0; }
else if (td->rotate == 180)
{ sinv = 0 ; cosv = -1; }
else if (td->rotate == 270)
{ sinv = -1 ; cosv = 0; }
else
{
ang = td->rotate / 180 * Q_PI;
sinv = sin(ang);
cosv = cos(ang);
}
if (pvecs[0][0])
sv = 0;
else if (pvecs[0][1])
sv = 1;
else
sv = 2;
if (pvecs[1][0])
tv = 0;
else if (pvecs[1][1])
tv = 1;
else
tv = 2;
for (i=0 ; i<2 ; i++) {
ns = cosv * pvecs[i][sv] - sinv * pvecs[i][tv];
nt = sinv * pvecs[i][sv] + cosv * pvecs[i][tv];
STfromXYZ[i][sv] = ns;
STfromXYZ[i][tv] = nt;
}
// scale
for (i=0 ; i<2 ; i++)
for (j=0 ; j<3 ; j++)
STfromXYZ[i][j] = STfromXYZ[i][j] / td->scale[i];
// shift
STfromXYZ[0][3] = td->shift[0];
STfromXYZ[1][3] = td->shift[1];
for (j=0 ; j<4 ; j++) {
STfromXYZ[0][j] /= q->width;
STfromXYZ[1][j] /= q->height;
}
}
/*
================
Face_MakePlane
================
*/
void Face_MakePlane (face_t *f)
{
int j;
vec3_t t1, t2, t3;
// convert to a vector / dist plane
for (j=0 ; j<3 ; j++)
{
t1[j] = f->planepts[0][j] - f->planepts[1][j];
t2[j] = f->planepts[2][j] - f->planepts[1][j];
t3[j] = f->planepts[1][j];
}
CrossProduct(t1,t2, f->plane.normal);
if (VectorCompare (f->plane.normal, vec3_origin))
printf ("WARNING: brush plane with no normal\n");
VectorNormalize (f->plane.normal);
f->plane.dist = DotProduct (t3, f->plane.normal);
}
/*
================
EmitTextureCoordinates
================
*/
void EmitTextureCoordinates ( float *xyzst, qtexture_t *q, face_t *f)
{
float STfromXYZ[2][4];
Face_TextureVectors (f, STfromXYZ);
xyzst[3] = DotProduct (xyzst, STfromXYZ[0]) + STfromXYZ[0][3];
xyzst[4] = DotProduct (xyzst, STfromXYZ[1]) + STfromXYZ[1][3];
}
//==========================================================================
/*
================
Brush_MakeFacePlanes
================
*/
void Brush_MakeFacePlanes (brush_t *b)
{
face_t *f;
for (f=b->brush_faces ; f ; f=f->next)
{
Face_MakePlane (f);
}
}
/*
================
DrawBrushEntityName
================
*/
void DrawBrushEntityName (brush_t *b)
{
char *name;
//float a, s, c;
//vec3_t mid;
//int i;
if (!b->owner)
return; // during contruction
if (b->owner == world_entity)
return;
if (b != b->owner->brushes.onext)
return; // not key brush
// MERGEME
#if 0
if (!(g_qeglobals.d_savedinfo.exclude & EXCLUDE_ANGLES))
{
// draw the angle pointer
a = FloatForKey (b->owner, "angle");
if (a)
{
s = sin (a/180*Q_PI);
c = cos (a/180*Q_PI);
for (i=0 ; i<3 ; i++)
mid[i] = (b->mins[i] + b->maxs[i])*0.5;
qglBegin (GL_LINE_STRIP);
qglVertex3fv (mid);
mid[0] += c*8;
mid[1] += s*8;
mid[2] += s*8;
qglVertex3fv (mid);
mid[0] -= c*4;
mid[1] -= s*4;
mid[2] -= s*4;
mid[0] -= s*4;
mid[1] += c*4;
mid[2] += c*4;
qglVertex3fv (mid);
mid[0] += c*4;
mid[1] += s*4;
mid[2] += s*4;
mid[0] += s*4;
mid[1] -= c*4;
mid[2] -= c*4;
qglVertex3fv (mid);
mid[0] -= c*4;
mid[1] -= s*4;
mid[2] -= s*4;
mid[0] += s*4;
mid[1] -= c*4;
mid[2] -= c*4;
qglVertex3fv (mid);
qglEnd ();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?