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