Esempio n. 1
0
void ComputeAbsolute(face_t* f, vec3_t& p1, vec3_t& p2, vec3_t& p3)
{
	vec3_t ex,ey,ez;	        // local axis base

#ifdef _DEBUG
	if (g_qeglobals.m_bBrushPrimitMode)
		Sys_Printf("Warning : illegal call of ComputeAbsolute in brush primitive mode\n");
#endif

	// compute first local axis base
	TextureAxisFromPlane(&f->plane, ex, ey);
	CrossProduct(ex, ey, ez);

	vec3_t aux;
	VectorCopy(ex, aux);
	VectorScale(aux, -f->texdef.shift[0], aux);
	VectorCopy(aux, p1);
	VectorCopy(ey, aux);
	VectorScale(aux, -f->texdef.shift[1], aux);
	VectorAdd(p1, aux, p1);
	VectorCopy(p1, p2);
	VectorAdd(p2, ex, p2);
	VectorCopy(p1, p3);
	VectorAdd(p3, ey, p3);
	VectorCopy(ez, aux);
	VectorScale(aux, -f->texdef.rotate, aux);
	VectorRotate(p1, aux, p1);
	VectorRotate(p2, aux, p2);
	VectorRotate(p3, aux, p3);
	// computing rotated local axis base
	vec3_t rex,rey;
	VectorCopy(ex, rex);
	VectorRotate(rex, aux, rex);
	VectorCopy(ey, rey);
	VectorRotate(rey, aux, rey);

	ComputeScale(rex,rey,p1,f);
	ComputeScale(rex,rey,p2,f);
	ComputeScale(rex,rey,p3,f);

	// project on normal plane
	// along ez 
	// assumes plane normal is normalized
	ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p1);
	ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p2);
	ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p3);
};
Esempio n. 2
0
void ComputeAbsolute( face_s* f, edVec3_c& p1, edVec3_c& p2, edVec3_c& p3 )
{
	edVec3_c ex, ey, ez;          // local axis base
	
#ifdef _DEBUG
	if ( g_qeglobals.m_bBrushPrimitMode )
		Sys_Printf( "Warning : illegal call of ComputeAbsolute in brush primitive mode\n" );
#endif
		
	// compute first local axis base
	TextureAxisFromPlane( f->plane, ex, ey );
	ez.crossProduct( ex, ey );
	
	edVec3_c aux = ex * -f->texdef.shift[0];
	p1 = aux;
	aux = ey * -f->texdef.shift[1];
	p1 += aux;
	p2 = p1;
	p2 += ex;
	p3 = p1;
	p3 += ey;
	aux = ez;
	aux *= -f->texdef.rotate;
	VectorRotate( p1, aux, p1 );
	VectorRotate( p2, aux, p2 );
	VectorRotate( p3, aux, p3 );
	// computing rotated local axis base
	edVec3_c rex = ex;
	VectorRotate( rex, aux, rex );
	edVec3_c rey = ey;
	VectorRotate( rey, aux, rey );
	
	ComputeScale( rex, rey, p1, f );
	ComputeScale( rex, rey, p2, f );
	ComputeScale( rex, rey, p3, f );
	
	// project on normal plane
	// along ez
	// assumes plane normal is normalized
	f->plane.projectOnPlane( ez, p1 );
	f->plane.projectOnPlane( ez, p2 );
	f->plane.projectOnPlane( ez, p3 );
};
Esempio n. 3
0
void ComputeAbsolute(face_t* f, vec3_t& p1, vec3_t& p2, vec3_t& p3)
{
	vec3_t ex,ey,ez;	        // local axis base

  // compute first local axis base
  TextureAxisFromPlane(&f->plane, ex, ey);
  CrossProduct(ex, ey, ez);
	    
	vec3_t aux;
  VectorCopy(ex, aux);
  VectorScale(aux, -f->texdef.shift[0], aux);
  VectorCopy(aux, p1);
  VectorCopy(ey, aux);
  VectorScale(aux, -f->texdef.shift[1], aux);
  VectorAdd(p1, aux, p1);
  VectorCopy(p1, p2);
  VectorAdd(p2, ex, p2);
  VectorCopy(p1, p3);
  VectorAdd(p3, ey, p3);
  VectorCopy(ez, aux);
  VectorScale(aux, -f->texdef.rotate, aux);
  VectorRotate(p1, aux, p1);
  VectorRotate(p2, aux, p2);
  VectorRotate(p3, aux, p3);
	// computing rotated local axis base
	vec3_t rex,rey;
  VectorCopy(ex, rex);
  VectorRotate(rex, aux, rex);
  VectorCopy(ey, rey);
  VectorRotate(rey, aux, rey);

  ComputeScale(rex,rey,p1,f);
	ComputeScale(rex,rey,p2,f);
	ComputeScale(rex,rey,p3,f);

	// project on normal plane
	// along ez 
	// assumes plane normal is normalized
	ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p1);
	ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p2);
	ProjectOnPlane(f->plane.normal,f->plane.dist,ez,p3);
};
Esempio n. 4
0
void EmitTextureCoordinates(float *xyzst,qtexture_t *q,face_t *f)
{
	float		s,t,ns,nt,ang,sinv,cosv;
	vec3_t		vecs[2];
	texdef_t	*td;

	// get natural texture axis
	TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);

	td = &f->texdef;

	ang		= td->rotate/180.0f*pMath_PI;
	sinv	= sin(ang);
	cosv	= cos(ang);

	if (!td->scale[0])
		td->scale[0] = 1.0f;
	if (!td->scale[1])
		td->scale[1] = 1.0f;

	s = Math_DotProduct(xyzst,vecs[0]);
	t = Math_DotProduct(xyzst,vecs[1]);

	ns = cosv * s - sinv * t;
	nt = sinv * s +  cosv * t;

	s = ns/td->scale[0] + td->shift[0];
	t = nt/td->scale[1] + td->shift[1];

	// gl scales everything from 0 to 1
	s /= q->width;
	t /= q->height;

	xyzst[3] = s;
	xyzst[4] = t;
}
Esempio n. 5
0
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, const Vector& origin)
{
	Vector	vecs[2];
	int		sv, tv;
	vec_t	ang, sinv, cosv;
	vec_t	ns, nt;
	texinfo_t	tx;
	int		i, j;

	if (!bt->name[0])
		return 0;

	memset (&tx, 0, sizeof(tx));

	// HLTOOLS - add support for texture vectors stored in the map file
	if (g_nMapFileVersion < 220)
	{
		TextureAxisFromPlane(plane, vecs[0], vecs[1]);
	}

	if (!bt->textureWorldUnitsPerTexel[0])
		bt->textureWorldUnitsPerTexel[0] = 1;
	if (!bt->textureWorldUnitsPerTexel[1])
		bt->textureWorldUnitsPerTexel[1] = 1;


	float shiftScaleU = 1.0f / 16.0f;
	float shiftScaleV = 1.0f / 16.0f;

	if (g_nMapFileVersion < 220)
	{
	// rotate axis
		if (bt->rotate == 0)
			{ sinv = 0 ; cosv = 1; }
		else if (bt->rotate == 90)
			{ sinv = 1 ; cosv = 0; }
		else if (bt->rotate == 180)
			{ sinv = 0 ; cosv = -1; }
		else if (bt->rotate == 270)
			{ sinv = -1 ; cosv = 0; }
		else
		{	
			ang = bt->rotate / 180 * M_PI;
			sinv = sin(ang);
			cosv = cos(ang);
		}

		if (vecs[0][0])
			sv = 0;
		else if (vecs[0][1])
			sv = 1;
		else
			sv = 2;
					
		if (vecs[1][0])
			tv = 0;
		else if (vecs[1][1])
			tv = 1;
		else
			tv = 2;
						
		for (i=0 ; i<2 ; i++)
		{
			ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
			nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
			vecs[i][sv] = ns;
			vecs[i][tv] = nt;
		}

		for (i=0 ; i<2 ; i++)
		{
			for (j=0 ; j<3 ; j++)
			{
				tx.textureVecsTexelsPerWorldUnits[i][j] = vecs[i][j] / bt->textureWorldUnitsPerTexel[i];
				tx.lightmapVecsLuxelsPerWorldUnits[i][j] = tx.textureVecsTexelsPerWorldUnits[i][j] / 16.0f;
			}
		}
	}
	else
	{
		tx.textureVecsTexelsPerWorldUnits[0][0] = bt->UAxis[0] / bt->textureWorldUnitsPerTexel[0];
		tx.textureVecsTexelsPerWorldUnits[0][1] = bt->UAxis[1] / bt->textureWorldUnitsPerTexel[0];
		tx.textureVecsTexelsPerWorldUnits[0][2] = bt->UAxis[2] / bt->textureWorldUnitsPerTexel[0];

		tx.textureVecsTexelsPerWorldUnits[1][0] = bt->VAxis[0] / bt->textureWorldUnitsPerTexel[1];
		tx.textureVecsTexelsPerWorldUnits[1][1] = bt->VAxis[1] / bt->textureWorldUnitsPerTexel[1];
		tx.textureVecsTexelsPerWorldUnits[1][2] = bt->VAxis[2] / bt->textureWorldUnitsPerTexel[1];

		tx.lightmapVecsLuxelsPerWorldUnits[0][0] = bt->UAxis[0] / bt->lightmapWorldUnitsPerLuxel;
		tx.lightmapVecsLuxelsPerWorldUnits[0][1] = bt->UAxis[1] / bt->lightmapWorldUnitsPerLuxel;
		tx.lightmapVecsLuxelsPerWorldUnits[0][2] = bt->UAxis[2] / bt->lightmapWorldUnitsPerLuxel;
		
		tx.lightmapVecsLuxelsPerWorldUnits[1][0] = bt->VAxis[0] / bt->lightmapWorldUnitsPerLuxel;
		tx.lightmapVecsLuxelsPerWorldUnits[1][1] = bt->VAxis[1] / bt->lightmapWorldUnitsPerLuxel;
		tx.lightmapVecsLuxelsPerWorldUnits[1][2] = bt->VAxis[2] / bt->lightmapWorldUnitsPerLuxel;

		shiftScaleU = bt->textureWorldUnitsPerTexel[0] / bt->lightmapWorldUnitsPerLuxel;
		shiftScaleV = bt->textureWorldUnitsPerTexel[1] / bt->lightmapWorldUnitsPerLuxel;
	}

	tx.textureVecsTexelsPerWorldUnits[0][3] = bt->shift[0] + 
		DOT_PRODUCT( origin, tx.textureVecsTexelsPerWorldUnits[0] );
	tx.textureVecsTexelsPerWorldUnits[1][3] = bt->shift[1] + 
		DOT_PRODUCT( origin, tx.textureVecsTexelsPerWorldUnits[1] );
	
	tx.lightmapVecsLuxelsPerWorldUnits[0][3] = shiftScaleU * bt->shift[0] +
		DOT_PRODUCT( origin, tx.lightmapVecsLuxelsPerWorldUnits[0] );
	tx.lightmapVecsLuxelsPerWorldUnits[1][3] = shiftScaleV * bt->shift[1] +
		DOT_PRODUCT( origin, tx.lightmapVecsLuxelsPerWorldUnits[1] );
	
	tx.flags = bt->flags;
	tx.texdata = FindOrCreateTexData( bt->name );

	// find the texinfo
	return FindOrCreateTexInfo( tx );
}
Esempio n. 6
0
/*
=================
ParseRawBrush

parses the sides into buildBrush->sides[], nothing else.
no validation, back plane removal, etc.
=================
*/
static void ParseRawBrush( bool onlyLights )
{
	side_t		*side;
	float		planePoints[3][3];
	int		planenum;
	char 		name[MAX_SHADERPATH];
	char		shader[MAX_SHADERPATH];
	shaderInfo_t	*si;
	token_t		token;
	vects_t		vects;
	int		flags;
	
	buildBrush->numsides = 0;
	buildBrush->detail = false;
	
	if( g_bBrushPrimit == BRUSH_RADIANT )
		Com_CheckToken( mapfile, "{" );
	
	while( 1 )
	{
		if( !Com_ReadToken( mapfile, SC_ALLOW_NEWLINES|SC_COMMENT_SEMICOLON, &token ))
			break;
		if( !com.stricmp( token.string, "}" )) break;
		if( g_bBrushPrimit == BRUSH_RADIANT )
		{
			while( 1 )
			{
				if( com.strcmp( token.string, "(" ))
					Com_ReadToken( mapfile, 0, &token );
				else break;
				Com_ReadToken( mapfile, SC_ALLOW_NEWLINES, &token );
			}
		}
		Com_SaveToken( mapfile, &token );
		
		if( buildBrush->numsides >= MAX_BUILD_SIDES )
			Sys_Break( "Entity %i, Brush %i MAX_BUILD_SIDES\n", buildBrush->entityNum, buildBrush->brushNum );
		
		side = &buildBrush->sides[ buildBrush->numsides ];
		Mem_Set( side, 0, sizeof( *side ));
		buildBrush->numsides++;
		
		// read the three point plane definition
		Com_Parse1DMatrix( mapfile, 3, planePoints[0] );
		Com_Parse1DMatrix( mapfile, 3, planePoints[1] );
		Com_Parse1DMatrix( mapfile, 3, planePoints[2] );
		
		// read the texture matrix
		if( g_bBrushPrimit == BRUSH_RADIANT )
			Com_Parse2DMatrix( mapfile, 2, 3, (float *)side->texMat );
		
		// read the texturedef or shadername
		Com_ReadToken( mapfile, SC_ALLOW_PATHNAMES|SC_PARSE_GENERIC, &token );
		com.strncpy( name, token.string, sizeof( name ));
		
		if( g_bBrushPrimit == BRUSH_WORLDCRAFT_22 || g_bBrushPrimit == BRUSH_GEARCRAFT_40 ) // Worldcraft 2.2+
                    {
			// texture U axis
			Com_ReadToken( mapfile, 0, &token );
			if( com.strcmp( token.string, "[" )) Sys_Break( "missing '[' in texturedef (U)\n" );
			Com_ReadFloat( mapfile, false, &vects.hammer.UAxis[0] );
			Com_ReadFloat( mapfile, false, &vects.hammer.UAxis[1] );
			Com_ReadFloat( mapfile, false, &vects.hammer.UAxis[2] );
			Com_ReadFloat( mapfile, false, &vects.hammer.shift[0] );
			Com_ReadToken( mapfile, 0, &token );
			if( com.strcmp( token.string, "]" )) Sys_Break( "missing ']' in texturedef (U)\n" );

			// texture V axis
			Com_ReadToken( mapfile, 0, &token );
			if( com.strcmp( token.string, "[" )) Sys_Break( "missing '[' in texturedef (V)\n" );
			Com_ReadFloat( mapfile, false, &vects.hammer.VAxis[0] );
			Com_ReadFloat( mapfile, false, &vects.hammer.VAxis[1] );
			Com_ReadFloat( mapfile, false, &vects.hammer.VAxis[2] );
			Com_ReadFloat( mapfile, false, &vects.hammer.shift[1] );
			Com_ReadToken( mapfile, 0, &token );
			if( com.strcmp( token.string, "]" )) Sys_Break( "missing ']' in texturedef (V)\n");

			// texture rotation is implicit in U/V axes.
			Com_ReadToken( mapfile, 0, &token );
			vects.hammer.rotate = 0;

			// texure scale
			Com_ReadFloat( mapfile, false, &vects.hammer.scale[0] );
			Com_ReadFloat( mapfile, false, &vects.hammer.scale[1] );

			if( g_bBrushPrimit == BRUSH_GEARCRAFT_40 )
			{
				Com_ReadLong( mapfile, false, &flags );	// read gearcraft flags
				Com_SkipRestOfLine( mapfile );	// gearcraft lightmap scale and rotate

				if( flags & GEARBOX_DETAIL )
					side->compileFlags |= C_DETAIL;

			}
                    }
		else if( g_bBrushPrimit == BRUSH_WORLDCRAFT_21 || g_bBrushPrimit == BRUSH_QUARK )
		{
			// worldcraft 2.1-, old Radiant, QuArK
			Com_ReadFloat( mapfile, false, &vects.hammer.shift[0] );
			Com_ReadFloat( mapfile, false, &vects.hammer.shift[1] );
			Com_ReadFloat( mapfile, false, &vects.hammer.rotate );
			Com_ReadFloat( mapfile, false, &vects.hammer.scale[0] );
			Com_ReadFloat( mapfile, SC_COMMENT_SEMICOLON, &vects.hammer.scale[1] );
                    }

		// set default flags and values
		com.sprintf( shader, "textures/%s", name );
		if( onlyLights ) si = &shaderInfo[0];
		else si = ShaderInfoForShader( shader );

		side->shaderInfo = si;
		side->surfaceFlags = si->surfaceFlags;
		side->contentFlags = si->contentFlags;
		side->compileFlags = si->compileFlags;
		side->value = si->value;
		
		// bias texture shift for non-radiant sides
		if( g_bBrushPrimit != BRUSH_RADIANT && si->globalTexture == false )
		{
			vects.hammer.shift[0] -= (floor( vects.hammer.shift[0] / si->shaderWidth ) * si->shaderWidth);
			vects.hammer.shift[1] -= (floor( vects.hammer.shift[1] / si->shaderHeight ) * si->shaderHeight);
		}
		
		// historically, there are 3 integer values at the end of a brushside line in a .map file.
		// in quake 3, the only thing that mattered was the first of these three values, which
		// was previously the content flags. and only then did a single bit matter, the detail
		// bit. because every game has its own special flags for specifying detail, the
		// traditionally game-specified BASECONT_DETAIL flag was overridden for Q3Map 2.3.0
		// by C_DETAIL, defined in q3map2.h. the value is exactly as it was before, but
		// is stored in compileFlags, as opposed to contentFlags, for multiple-game
		// portability. :sigh:
                    if( g_bBrushPrimit != BRUSH_QUARK && Com_ReadToken( mapfile, SC_COMMENT_SEMICOLON, &token ))
		{
			// overwrite shader values directly from .map file
			Com_SaveToken( mapfile, &token );
			Com_ReadLong( mapfile, false, &flags );
			Com_ReadLong( mapfile, false, NULL );
			Com_ReadLong( mapfile, false, NULL );
			if( flags & C_DETAIL ) side->compileFlags |= C_DETAIL;
		}		

		if( mapfile->TXcommand == '1' || mapfile->TXcommand == '2' )
		{
			// we are QuArK mode and need to translate some numbers to align textures its way
			// from QuArK, the texture vectors are given directly from the three points
			vec3_t          texMat[2];
			float           dot22, dot23, dot33, mdet, aa, bb, dd;
			int             j, k;

			g_bBrushPrimit = BRUSH_QUARK;	// we can detect it only here
			k = mapfile->TXcommand - '0';
			for( j = 0; j < 3; j++ )
				texMat[1][j] = (planePoints[k][j] - planePoints[0][j]) * (0.0078125f);	// QuArK magic value

			k = 3 - k;
			for( j = 0; j < 3; j++ )
				texMat[0][j] = (planePoints[k][j] - planePoints[0][j]) * (0.0078125f);	// QuArK magic value

			dot22 = DotProduct( texMat[0], texMat[0] );
			dot23 = DotProduct( texMat[0], texMat[1] );
			dot33 = DotProduct( texMat[1], texMat[1] );
			mdet = dot22 * dot33 - dot23 * dot23;
			if( mdet < 1E-6 && mdet > -1E-6 )
			{
				aa = bb = dd = 0;
				MsgDev( D_WARN, "Entity %i, Brush %i: degenerate QuArK-style texture: \n", buildBrush->entityNum, buildBrush->brushNum );
			}
			else
			{
				mdet = 1.0 / mdet;
				aa = dot33 * mdet;
				bb = -dot23 * mdet;
				dd = dot22 * mdet;
			}
			for( j = 0; j < 3; j++ )
			{
				vects.quark.vecs[0][j] = aa * texMat[0][j] + bb * texMat[1][j];
				vects.quark.vecs[1][j] = -(bb * texMat[0][j] + dd * texMat[1][j]);
			}
			vects.quark.vecs[0][3] = -DotProduct( vects.quark.vecs[0], planePoints[0] );
			vects.quark.vecs[1][3] = -DotProduct( vects.quark.vecs[1], planePoints[0] );
		}

		// find the plane number
		planenum = MapPlaneFromPoints( planePoints );
		if( planenum == -1 )
		{
			MsgDev( D_ERROR, "Entity %i, Brush %i: plane with no normal\n", buildBrush->entityNum, buildBrush->brushNum );
			continue;
		}
		side->planenum = planenum;

		if( g_bBrushPrimit == BRUSH_QUARK ) 
		{
			// QuArK format completely matched with internal
			// FIXME: don't calculate vecs, use QuArK texMat instead ?
			Mem_Copy( side->vecs, vects.quark.vecs, sizeof( side->vecs ));
		}
		else if( g_bBrushPrimit != BRUSH_RADIANT )
		{
			vec3_t	vecs[2];
			float	ang, sinv, cosv, ns, nt;
			int	i, j, sv, tv;
			
			if( g_bBrushPrimit == BRUSH_WORLDCRAFT_21 )
				TextureAxisFromPlane( &mapplanes[planenum], vecs[0], vecs[1] );
			if( !vects.hammer.scale[0] ) vects.hammer.scale[0] = 1.0f;
			if( !vects.hammer.scale[1] ) vects.hammer.scale[1] = 1.0f;

			if( g_bBrushPrimit == BRUSH_WORLDCRAFT_21 )
			{
				// rotate axis
				if( vects.hammer.rotate == 0 )
				{
					sinv = 0;
					cosv = 1;
				}
				else if( vects.hammer.rotate == 90 )
				{
					sinv = 1;
					cosv = 0;
				}
				else if( vects.hammer.rotate == 180 )
				{
					sinv = 0;
					cosv = -1;
				}
				else if( vects.hammer.rotate == 270 )
				{
					sinv = -1;
					cosv = 0;
				}
				else
				{
					ang = vects.hammer.rotate / 180 * M_PI;
					sinv = sin( ang );
					cosv = cos( ang );
				}
				if( vecs[0][0] ) sv = 0;
				else if( vecs[0][1] ) sv = 1;
				else sv = 2;

				if( vecs[1][0] ) tv = 0;
				else if( vecs[1][1] ) tv = 1;
				else tv = 2;
			
				for( i = 0; i < 2; i++ )
				{
					ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
					nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
					vecs[i][sv] = ns;
					vecs[i][tv] = nt;
				}

				for( i = 0; i < 2; i++ )
					for( j = 0; j < 3; j++ )
						side->vecs[i][j] = vecs[i][j] / vects.hammer.scale[i];
			}
			else if( g_bBrushPrimit == BRUSH_WORLDCRAFT_22 || g_bBrushPrimit == BRUSH_GEARCRAFT_40 )
			{
				float	scale;

				scale = 1.0f / vects.hammer.scale[0];
				VectorScale( vects.hammer.UAxis, scale, side->vecs[0] );
				scale = 1.0f / vects.hammer.scale[1];
				VectorScale( vects.hammer.VAxis, scale, side->vecs[1] );
			}

			// add shifts
			side->vecs[0][3] = vects.hammer.shift[0];
			side->vecs[1][3] = vects.hammer.shift[1];
		}
	}
	
	if( g_bBrushPrimit == BRUSH_RADIANT )
	{
		Com_SaveToken( mapfile, &token );
		Com_CheckToken( mapfile, "}" );
		Com_CheckToken( mapfile, "}" );
	}
}
Esempio n. 7
0
/**
 * @sa BaseLightForFace
 */
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, const vec3_t origin, qboolean isTerrain)
{
	vec3_t vecs[2];
	int sv, tv;
	vec_t ang, sinv, cosv;
	dBspTexinfo_t tx, *tc;
	int i, j, k;
	float shift[2];
	vec3_t scaledOrigin;

	if (!bt->name[0])
		return 0;

	OBJZERO(tx);
	Q_strncpyz(tx.texture, bt->name, sizeof(tx.texture));

	TextureAxisFromPlane(plane, vecs[0], vecs[1], isTerrain);

	/* dot product of a vertex location with the [4] part will produce a
	 * texcoord (s or t depending on the first index) */
	VectorScale(origin, 1.0 / bt->scale[0], scaledOrigin);
	shift[0] = DotProduct(scaledOrigin, vecs[0]);
	VectorScale(origin, 1.0 / bt->scale[1], scaledOrigin);
	shift[1] = DotProduct(scaledOrigin, vecs[1]);

	if (!bt->scale[0])
		bt->scale[0] = 1;
	if (!bt->scale[1])
		bt->scale[1] = 1;

	/* rotate axis */
	if (bt->rotate == 0) {
		sinv = 0;
		cosv = 1;
	} else if (bt->rotate == 90) {
		sinv = 1;
		cosv = 0;
	} else if (bt->rotate == 180) {
		sinv = 0;
		cosv = -1;
	} else if (bt->rotate == 270) {
		sinv = -1;
		cosv = 0;
	} else {
		ang = bt->rotate * torad;
		sinv = sin(ang);
		cosv = cos(ang);
	}

	shift[0] = cosv * shift[0] - sinv * shift[1];
	shift[1] = sinv * shift[0] + cosv * shift[1];

	if (vecs[0][0])
		sv = 0;
	else if (vecs[0][1])
		sv = 1;
	else
		sv = 2;

	if (vecs[1][0])
		tv = 0;
	else if (vecs[1][1])
		tv = 1;
	else
		tv = 2;

	for (i = 0; i < 2; i++) {
		const vec_t ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
		const vec_t nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
		vecs[i][sv] = ns;
		vecs[i][tv] = nt;
	}

	for (i = 0; i < 2; i++)
		for (j = 0; j < 3; j++)
			tx.vecs[i][j] = vecs[i][j] / bt->scale[i];

	/* texture offsets */
	tx.vecs[0][3] = bt->shift[0] + shift[0];
	tx.vecs[1][3] = bt->shift[1] + shift[1];

	tx.surfaceFlags = bt->surfaceFlags;
	tx.value = bt->value;

	/* find the texinfo */
	tc = curTile->texinfo;
	for (i = 0; i < curTile->numtexinfo; i++, tc++) {
		if (tc->surfaceFlags != tx.surfaceFlags)
			continue;
		if (tc->value != tx.value)
			continue;
		if (!Q_streq(tc->texture, tx.texture))
			continue;
		for (j = 0; j < 2; j++) {
			for (k = 0; k < 4; k++) {
				if (tc->vecs[j][k] != tx.vecs[j][k])
					goto skip;
			}
		}
		return i;
skip:;
	}
	if (curTile->numtexinfo >= MAX_MAP_TEXINFO)
		Sys_Error("MAX_MAP_TEXINFO overflow");
	*tc = tx;
	curTile->numtexinfo++;

	return i;
}
Esempio n. 8
0
void ParseBrushFace (entity_t *ent, mbrush_t **brushpointer, brushtype_t brushtype)
{
	int			i, j, sv, tv, hltexdef, facecontents, faceflags, facevalue, q2brushface, q3brushface, bpface;
	vec_t		planepts[3][3], t1[3], t2[3], d, rotate, scale[2], vecs[2][4], ang, sinv, cosv, ns, nt, bp[2][3];
	mface_t		*f, *f2;
	plane_t	plane;
	texinfo_t	tx;
	mbrush_t	*b;

	if (brushtype == BRUSHTYPE_PATCHDEF2 || brushtype == BRUSHTYPE_PATCHDEF3)
		return;
	// read the three point plane definition
	if (strcmp (token, "(") )
		Error ("parsing brush on line %d\n", scriptline);
	GetToken (false);
	planepts[0][0] = atof(token);
	GetToken (false);
	planepts[0][1] = atof(token);
	GetToken (false);
	planepts[0][2] = atof(token);
	GetToken (false);
	if (!strcmp(token, ")"))
	{
		GetToken (false);
		if (strcmp(token, "("))
			Error("parsing brush on line %d\n", scriptline);
		GetToken (false);
		planepts[1][0] = atof(token);
		GetToken (false);
		planepts[1][1] = atof(token);
		GetToken (false);
		planepts[1][2] = atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);

		GetToken (false);
		if (strcmp(token, "("))
			Error("parsing brush on line %d\n", scriptline);
		GetToken (false);
		planepts[2][0] = atof(token);
		GetToken (false);
		planepts[2][1] = atof(token);
		GetToken (false);
		planepts[2][2] = atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);

		// convert points to a plane
		VectorSubtract(planepts[0], planepts[1], t1);
		VectorSubtract(planepts[2], planepts[1], t2);
		CrossProduct(t1, t2, plane.normal);
		VectorNormalize(plane.normal);
		plane.dist = DotProduct(planepts[1], plane.normal);
	}
	else
	{
		// oh, it's actually a 4 value plane
		plane.normal[0] = planepts[0][0];
		plane.normal[1] = planepts[0][1];
		plane.normal[2] = planepts[0][2];
		plane.dist = -atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);
	}

	// read the texturedef
	memset (&tx, 0, sizeof(tx));
	GetToken (false);
	bpface = false;
	hltexdef = false;
	if (!strcmp(token, "("))
	{
		// brush primitives, utterly insane
		bpface = true;
		// (
		GetToken(false);
		// (
		GetToken(false);
		bp[0][0] = atof(token);
		GetToken(false);
		bp[0][1] = atof(token);
		GetToken(false);
		bp[0][2] = atof(token);
		GetToken(false);
		// )
		GetToken(false);
		// (
		GetToken(false);
		bp[1][0] = atof(token);
		GetToken(false);
		bp[1][1] = atof(token);
		GetToken(false);
		bp[1][2] = atof(token);
		GetToken(false);
		// )
		GetToken (false);
		GetToken (false);
		tx.miptex = FindMiptex (token);
		rotate = 0;
		scale[0] = 1;
		scale[1] = 1;
	}
	else
	{
		// if the texture name contains a / then this is a q2/q3 brushface
		// strip off the path, wads don't use a path on texture names
		tx.miptex = FindMiptex (token);
		GetToken (false);
		if (!strcmp(token, "["))
		{
			hltexdef = true;
			// S vector
			GetToken(false);
			vecs[0][0] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][1] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][2] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][3] = (vec_t)atof(token);
			// ]
			GetToken(false);
			// [
			GetToken(false);
			// T vector
			GetToken(false);
			vecs[1][0] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][1] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][2] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][3] = (vec_t)atof(token);
			// ]
			GetToken(false);

			// rotation (unused - implicit in tex coords)
			GetToken(false);
			rotate = 0;
		}
		else
		{
			vecs[0][3] = (vec_t)atof(token); // LordHavoc: float coords
			GetToken (false);
			vecs[1][3] = (vec_t)atof(token); // LordHavoc: float coords
			GetToken (false);
			rotate = atof(token); // LordHavoc: float coords
		}

		GetToken (false);
		scale[0] = (vec_t)atof(token); // LordHavoc: was already float coords
		GetToken (false);
		scale[1] = (vec_t)atof(token); // LordHavoc: was already float coords
	}
	// q3 .map properties, currently unused but parsed
	facecontents = 0;
	faceflags = 0;
	facevalue = 0;
	q2brushface = false;
	q3brushface = false;
	if (GetToken (false))
	{
		q2brushface = true;
		facecontents = atoi(token);
		if (GetToken (false))
		{
			faceflags = atoi(token);
			if (GetToken (false))
			{
				q2brushface = false;
				q3brushface = true;
				facevalue = atoi(token);
			}
		}
	}
	// skip trailing info (the 3 q3 .map parameters for example)
	while (GetToken (false));

	if (DotProduct(plane.normal, plane.normal) < 0.1)
	{
		printf ("WARNING: brush plane with no normal on line %d\n", scriptline);
		return;
	}

	if (bpface)
	{
		// fake proper texture vectors from QuakeEd style
		TextureAxisFromPlane(&plane, vecs[0], vecs[1], true);
		// FIXME: deal with the bp stuff here
		printf("warning: brush primitive texturing not yet supported (line %d)\n", scriptline);
		// generic texturing
		tx.vecs[0][0] = vecs[0][0];
		tx.vecs[0][1] = vecs[0][1];
		tx.vecs[0][2] = vecs[0][2];
		tx.vecs[0][3] = vecs[0][3];
		tx.vecs[1][0] = vecs[1][0];
		tx.vecs[1][1] = vecs[1][1];
		tx.vecs[1][2] = vecs[1][2];
		tx.vecs[1][3] = vecs[1][3];
	}
	else
	{
		if (hltexdef)
		{
			for (i = 0; i < 2; i++)
			{
				d = 1.0 / (scale[i] ? scale[i] : 1.0);
				for (j = 0; j < 3; j++)
					tx.vecs[i][j] = vecs[i][j] * d;
				tx.vecs[i][3] = vecs[i][3] /*+ DotProduct(origin, tx.vecs[i])*/;
// Sajt: ripped the commented out bit from the HL compiler code, not really sure what it is exactly doing
// 'origin': origin set on bmodel by origin brush or origin key
			}
		}
		else
		{
			// fake proper texture vectors from QuakeEd style
			TextureAxisFromPlane(&plane, vecs[0], vecs[1], q3brushface);

			// rotate axis
				 if (rotate ==  0) {sinv = 0;cosv = 1;}
			else if (rotate == 90) {sinv = 1;cosv = 0;}
			else if (rotate == 180) {sinv = 0;cosv = -1;}
			else if (rotate == 270) {sinv = -1;cosv = 0;}
			else {ang = rotate * (Q_PI / 180);sinv = sin(ang);cosv = cos(ang);}

			// LordHavoc: I don't quite understand this
			for (sv = 0;sv < 2 && !vecs[0][sv];sv++);
			for (tv = 0;tv < 2 && !vecs[1][tv];tv++);

			for (i = 0;i < 2;i++)
			{
				// rotate
				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
				nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
				vecs[i][sv] = ns;
				vecs[i][tv] = nt;
				// scale and store into texinfo
				d = 1.0 / (scale[i] ? scale[i] : 1.0);
				for (j = 0;j < 3;j++)
					tx.vecs[i][j] = vecs[i][j] * d;
				tx.vecs[i][3] = vecs[i][3];
			}
		}
	}

	/*
	// LordHavoc: fix for CheckFace: point off plane errors in some maps (most notably QOOLE ones),
	// and hopefully preventing most 'portal clipped away' warnings
	VectorNormalize (plane.normal);
	for (j = 0;j < 3;j++)
		plane.normal[j] = (Q_rint((vec_t) plane.normal[j] * (vec_t) 8.0)) * (vec_t) (1.0 / 8.0);
	VectorNormalize (plane.normal);
	plane.dist = DotProduct (t3, plane.normal);
	d = (Q_rint(plane.dist * 8.0)) * (1.0 / 8.0);
	//if (fabs(d - plane.dist) >= (0.4 / 8.0))
	//	printf("WARNING: correcting minor math errors in brushface on line %d\n", scriptline);
	plane.dist = d;
	*/

	/*
	VectorNormalize (plane.normal);
	plane.dist = DotProduct (t3, plane.normal);

	VectorCopy(plane.normal, v);
	//for (j = 0;j < 3;j++)
	//	v[j] = (Q_rint((vec_t) v[j] * (vec_t) 32.0)) * (vec_t) (1.0 / 32.0);
	VectorNormalize (v);
	d = (Q_rint(DotProduct (t3, v) * 8.0)) * (1.0 / 8.0);

	// if deviation is too high, warn  (frequently happens on QOOLE maps)
	if (fabs(DotProduct(v, plane.normal) - 1.0) > (0.5 / 32.0)
	 || fabs(d - plane.dist) >= (0.25 / 8.0))
		printf("WARNING: minor misalignment of brushface on line %d\n"
			   "normal     %f %f %f (l: %f d: %f)\n"
			   "rounded to %f %f %f (l: %f d: %f r: %f)\n",
			   scriptline,
			   (vec_t) plane.normal[0], (vec_t) plane.normal[1], (vec_t) plane.normal[2], (vec_t) sqrt(DotProduct(plane.normal, plane.normal)), (vec_t) DotProduct (t3, plane.normal),
			   (vec_t) v[0], (vec_t) v[1], (vec_t) v[2], (vec_t) sqrt(DotProduct(v, v)), (vec_t) DotProduct(t3, v), (vec_t) d);
	//VectorCopy(v, plane.normal);
	//plane.dist = d;
	*/

	b = *brushpointer;
	if (b)
	{
		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i = 0;i < 3;i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
					break;
			}
			if (i==3)
				break;
		}
		if (f2)
		{
			printf ("WARNING: brush with duplicate plane (first point is at %g %g %g, .map file line number %d)\n", planepts[0][0], planepts[0][1], planepts[0][2], scriptline);
			return;
		}
	}
	else
	{
		b = &mapbrushes[nummapbrushes];
		nummapbrushes++;
		b->next = ent->brushes;
		ent->brushes = b;
		*brushpointer = b;
	}

	f = qmalloc(sizeof(mface_t));
	f->next = b->faces;
	b->faces = f;
	f->plane = plane;
	f->texinfo = FindTexinfo (&tx);
	nummapbrushfaces++;
}
Esempio n. 9
0
void AbsoluteToLocal( const class edPlane_c& normal2, face_s* f, edVec3_c& p1, edVec3_c& p2, edVec3_c& p3 )
{
	edVec3_c ex, ey, ez;
	
#ifdef _DEBUG
	if ( g_qeglobals.m_bBrushPrimitMode )
		Sys_Printf( "Warning : illegal call of AbsoluteToLocal in brush primitive mode\n" );
#endif
		
	// computing new local axis base
	TextureAxisFromPlane( normal2, ex, ey );
	ez.crossProduct( ex, ey );
	
	// projecting back on (ex,ey)
	Back( ez, p1 );
	Back( ez, p2 );
	Back( ez, p3 );
	
	edVec3_c aux = p2 - p1;
	
	float x = aux.dotProduct( ex );
	float y = aux.dotProduct( ey );
	f->texdef.rotate = RAD2DEG( atan2( y, x ) );
	
	// computing rotated local axis base
	aux = ez;
	aux *= f->texdef.rotate;
	edVec3_c rex = ex;
	VectorRotate( rex, aux, rex );
	edVec3_c rey = ey;
	VectorRotate( rey, aux, rey );
	
	// scale
	aux = p2 - p1;
	f->texdef.scale[0] = aux.dotProduct( rex );
	aux = p3 - p1;
	f->texdef.scale[1] = aux.dotProduct( rey );
	
	// shift
	// only using p1
	x = rex.dotProduct( p1 );
	y = rey.dotProduct( p1 );
	x /= f->texdef.scale[0];
	y /= f->texdef.scale[1];
	
	p1 = rex * x;
	aux = rey * y;
	aux *= y;
	p1 += aux;
	aux = ez * -f->texdef.rotate;
	VectorRotate( p1, aux, p1 );
	f->texdef.shift[0] = -p1.dotProduct( ex );
	f->texdef.shift[1] = -p1.dotProduct( ey );
	
	// stored rot is good considering local axis base
	// change it if necessary
	f->texdef.rotate = -f->texdef.rotate;
	
	Clamp( f->texdef.shift[0], f->d_texture->width );
	Clamp( f->texdef.shift[1], f->d_texture->height );
	Clamp( f->texdef.rotate, 360 );
	
}
Esempio n. 10
0
static void
SetTexinfo_QuakeEd(const plane_t *plane, const int shift[2], int rotate,
		   const vec_t scale[2], texinfo_t *out)
{
    int i, j;
    vec3_t vecs[2];
    int sv, tv;
    vec_t ang, sinv, cosv;
    vec_t ns, nt;

    TextureAxisFromPlane(plane, vecs[0], vecs[1]);

    /* Normalize the Texture rotation */
    rotate %= 360;
    while (rotate < 0)
	rotate += 360;

    // rotate axis
    switch (rotate) {
    case 0:
	sinv = 0;
	cosv = 1;
	break;
    case 90:
	sinv = 1;
	cosv = 0;
	break;
    case 180:
	sinv = 0;
	cosv = -1;
	break;
    case 270:
	sinv = -1;
	cosv = 0;
	break;
    default:
	ang = (vec_t)rotate / 180 * Q_PI;
	sinv = sin(ang);
	cosv = cos(ang);
    }

    if (vecs[0][0])
	sv = 0;
    else if (vecs[0][1])
	sv = 1;
    else
	sv = 2;

    if (vecs[1][0])
	tv = 0;
    else if (vecs[1][1])
	tv = 1;
    else
	tv = 2;

    for (i = 0; i < 2; i++) {
	ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
	nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
	vecs[i][sv] = ns;
	vecs[i][tv] = nt;
    }

    for (i = 0; i < 2; i++)
	for (j = 0; j < 3; j++)
	    /* Interpret zero scale as no scaling */
	    out->vecs[i][j] = vecs[i][j] / (scale[i] ? scale[i] : 1);

    out->vecs[0][3] = shift[0];
    out->vecs[1][3] = shift[1];
}
Esempio n. 11
0
void AbsoluteToLocal(plane_t normal2, face_t* f, vec3_t& p1, vec3_t& p2, vec3_t& p3)
{
	vec3_t ex,ey,ez;
	// computing new local axis base
  TextureAxisFromPlane(&normal2, ex, ey);
  CrossProduct(ex, ey, ez);

  // projecting back on (ex,ey)
	Back(ez,p1);
	Back(ez,p2);
	Back(ez,p3);

	vec3_t aux;
	// rotation
  VectorCopy(p2, aux);
  VectorSubtract(aux, p1,aux);
	
	float x = DotProduct(aux,ex);
	float y = DotProduct(aux,ey);
  f->texdef.rotate = 180 * atan2(y,x) / Q_PI;

	vec3_t rex,rey;
	// computing rotated local axis base
  VectorCopy(ez, aux);
  VectorScale(aux, f->texdef.rotate, aux);
  VectorCopy(ex, rex);
  VectorRotate(rex, aux, rex);
  VectorCopy(ey, rey);
  VectorRotate(rey, aux, rey);

	// scale
  VectorCopy(p2, aux);
  VectorSubtract(aux, p1, aux);
  f->texdef.scale[0] = DotProduct(aux, rex);
  VectorCopy(p3, aux);
  VectorSubtract(aux, p1, aux);
  f->texdef.scale[1] = DotProduct(aux, rey);

	// shift
	// only using p1
	x = DotProduct(rex,p1);
	y = DotProduct(rey,p1);                 
	x /= f->texdef.scale[0];
	y /= f->texdef.scale[1];

  VectorCopy(rex, p1);
  VectorScale(p1, x, p1);
  VectorCopy(rey, aux);
  VectorScale(aux, y, aux);
  VectorAdd(p1, aux, p1);
  VectorCopy(ez, aux);
  VectorScale(aux, -f->texdef.rotate, aux);
  VectorRotate(p1, aux, p1);
	f->texdef.shift[0] = -DotProduct(p1, ex);
	f->texdef.shift[1] = -DotProduct(p1, ey);

	// stored rot is good considering local axis base
	// change it if necessary
	f->texdef.rotate = -f->texdef.rotate;

  Clamp(f->texdef.shift[0], f->d_texture->width);
  Clamp(f->texdef.shift[1], f->d_texture->height);
  Clamp(f->texdef.rotate, 360);

}
Esempio n. 12
0
File: map.c Progetto: kellyrm/Q1
/*
=================
ParseBrush
=================
*/
void ParseBrush (void)
{
	mbrush_t  *b;
	mface_t	  *f, *f2;
	vec3_t	  planepts[3];
	vec3_t	  t1, t2, t3, VAxis[2];
	int	  i, j, Faces;
	texinfo_t tx;
	vec_t	  d;
	vec_t	  shift[2], rotate, scale[2];
	qboolean  ok, Valve220;

        ExtendArray(mapbrushes, nummapbrushes);
	b = &mapbrushes[nummapbrushes];
	b->Line = scriptline;

	ok = GetToken (true);

	while (ok)
	{
		txcommand = 0;
		if (!strcmp (token, "}") )
		{
			if (!options.onlyents)
			{
				if (InvalidBrush(b, &Faces))
				{
					// Too few faces in brush or not closed; drop it
					DropBrush (b);
					nummapfaces -= Faces;
					// Note: texinfo array is not corrected here
					return;
				}
			}

			if (options.SortFace)
				SortFaces(b);

			break;
		}

	// read the three point plane definition
		for (i=0 ; i<3 ; i++)
		{
			if (i != 0)
				GetToken (true);
			if (strcmp (token, "(") )
				Message (MSGERR, "Invalid brush plane format on line %d", scriptline);

			for (j=0 ; j<3 ; j++)
			{
				GetToken (false);
				planepts[i][j] = atof(token);	// AR: atof
			}

			GetToken (false);
			if (strcmp (token, ")") )
				Message (MSGERR, "Invalid brush plane format on line %d", scriptline);

		}

	// read the texturedef
		memset (&tx, 0, sizeof(tx));
		GetToken (false);

		if (options.Q2Map)
			Q2ToQ1Tex (token);

		// Check texture name length
		if (strlen(token) > sizeof(char16) - 1)
			Message (MSGERR, "Texture name \"%s\" too long on line %d", token, scriptline);

		if (options.SolidMap && num_entities == 1 && token[0] == '*' ||
		    options.noents && num_entities > 1)
		{
			// No liquid worldbrushes or only worldbrushes allowed; drop brush
			DropBrush (b);

			while (GetToken(true) && strcmp(token, "}"))
				;

			return;
		}

		Valve220 = false;

		tx.miptex = FindMiptex (token);
		GetToken (false);
		
		if (!strcmp (token, "["))
		{
			// Valve 220 map import
			Valve220 = true;
			GetValveTex (VAxis[0]);
		}

		shift[0] = atoi(token);
		GetToken (false);
		
		if (Valve220)
		{
			// Skip ]
			GetToken (false);
			GetValveTex (VAxis[1]);
		}

		shift[1] = atoi(token);
		GetToken (false);

		if (Valve220)
			GetToken (false); // Skip ]

		rotate = atoi(token);
		GetToken (false);
		scale[0] = atof(token);
		GetToken (false);
		scale[1] = atof(token);

		if (options.Q2Map)
		{
			// Skip extra Q2 style face info
			GetToken (false);
			GetToken (false);
			GetToken (false);
		}

		ok = GetToken (true); // Note : scriptline normally gets advanced here

		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i=0 ; i<3 ; i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
					break;
			}
			if (i==3)
				break;
		}
		if (f2)
		{
			Message (MSGWARN, "Brush with duplicate plane on line %d", scriptline - 1);
			continue;
		}

		f = AllocOther(sizeof(mface_t));

	// convert to a vector / dist plane
		for (j=0 ; j<3 ; j++)
		{
			t1[j] = planepts[0][j] - planepts[1][j];
			t2[j] = planepts[2][j] - planepts[1][j];
			t3[j] = planepts[1][j];
		}

		CrossProduct(t1,t2, f->plane.normal);
		if (VectorCompare (f->plane.normal, vec3_origin))
		{
			Message (MSGWARN, "Brush plane with no normal on line %d", scriptline - 1);
			FreeOther (f);
			continue;
		}
		VectorNormalize (f->plane.normal);
		f->plane.dist = DotProduct (t3, f->plane.normal);

		f->next = b->faces;
		b->faces = f;

		if (txcommand=='1' || txcommand=='2')
		{		// from QuArK, the texture vectors are given directly from the three points
			vec3_t	TexPt[2];
			int		k;
			vec_t	dot22, dot23, dot33, mdet, aa, bb, dd;

			k = txcommand-'0';
			for (j=0; j<3; j++)
				TexPt[1][j] = (planepts[k][j] - planepts[0][j]) * ScaleCorrection;
			k = 3-k;
			for (j=0; j<3; j++)
				TexPt[0][j] = (planepts[k][j] - planepts[0][j]) * ScaleCorrection;

			dot22 = DotProduct (TexPt[0], TexPt[0]);
			dot23 = DotProduct (TexPt[0], TexPt[1]);
			dot33 = DotProduct (TexPt[1], TexPt[1]);
			mdet = dot22*dot33-dot23*dot23;
			if (mdet<1E-6 && mdet>-1E-6)
			{
				aa = bb = dd = 0;
				Message (MSGWARN, "Degenerate QuArK-style brush texture on line %d", scriptline - 1);
			}
			else
			{
				mdet = 1.0/mdet;
      			aa = dot33*mdet;
      			bb = -dot23*mdet;
				//cc = -dot23*mdet;     // cc = bb
				dd = dot22*mdet;
			}

			for (j=0; j<3; j++)
			{
				tx.vecs[0][j] = aa * TexPt[0][j] + bb * TexPt[1][j];
				tx.vecs[1][j] = -(/*cc*/ bb * TexPt[0][j] + dd * TexPt[1][j]);
			}

			tx.vecs[0][3] = -DotProduct(tx.vecs[0], planepts[0]);
			tx.vecs[1][3] = -DotProduct(tx.vecs[1], planepts[0]);
		}
		else if (Valve220)
		{
			// Valve 220 texturedef
			vec3_t vec;
			vec_t  tscale;

			// Prevent division by zero
			if (!scale[0])
				scale[0] = 1;
			if (!scale[1])
				scale[1] = 1;

			// FIXME: If origin brushes are in use, this is where to fix their tex alignment!!!
			for (i = 0; i < 2; ++i)
			{
				tscale = 1 / scale[i];
				VectorScale(VAxis[i], tscale, vec);
				
				for (j = 0; j < 3; ++j)
					tx.vecs[i][j] = (float)vec[j];
				
				tx.vecs[i][3] = (float)shift[i] + DotProduct(vec3_origin, vec);
			}
		}
		else
	//
	// fake proper texture vectors from QuakeEd style
	//
		{
			vec3_t	vecs[2];
			int		sv, tv;
			vec_t	ang, sinv, cosv;
			vec_t	ns, nt;

			TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);

			if (!scale[0])
				scale[0] = 1;
			if (!scale[1])
				scale[1] = 1;

		// rotate axis
			if (rotate == 0)
				{ sinv = 0 ; cosv = 1; }
			else if (rotate == 90)
				{ sinv = 1 ; cosv = 0; }
			else if (rotate == 180)
				{ sinv = 0 ; cosv = -1; }
			else if (rotate == 270)
				{ sinv = -1 ; cosv = 0; }
			else
			{
				ang = rotate / 180 * Q_PI;
				sinv = sin(ang);
				cosv = cos(ang);
			}

			if (vecs[0][0])
				sv = 0;
			else if (vecs[0][1])
				sv = 1;
			else
				sv = 2;

			if (vecs[1][0])
				tv = 0;
			else if (vecs[1][1])
				tv = 1;
			else
				tv = 2;

			for (i=0 ; i<2 ; i++)
			{
				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
				nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
				vecs[i][sv] = ns;
				vecs[i][tv] = nt;
			}

			for (i=0 ; i<2 ; i++)
				for (j=0 ; j<3 ; j++)
					tx.vecs[i][j] = vecs[i][j] / scale[i];

			tx.vecs[0][3] = shift[0];
			tx.vecs[1][3] = shift[1];
		}

	// unique the texinfo
		f->texinfo = FindTexinfo (&tx);
		nummapfaces++;
	};

	nummapbrushes++;
	b->next = mapent->brushes;
	mapent->brushes = b;
}
Esempio n. 13
0
/*
=================
ParseBrush
=================
*/
void ParseBrush (void)
{
	int			i, j, sv, tv, hltexdef;
	vec_t		planepts[3][3], t1[3], t2[3], d, rotate, scale[2], vecs[2][4], ang, sinv, cosv, ns, nt;
	mbrush_t	*b;
	mface_t		*f, *f2;
	plane_t	plane;
	texinfo_t	tx;

	b = &mapbrushes[nummapbrushes];
	nummapbrushes++;
	b->next = mapent->brushes;
	mapent->brushes = b;

	do
	{
		if (!GetToken (true))
			break;
		if (!strcmp (token, "}") )
			break;

		// read the three point plane definition
		for (i = 0;i < 3;i++)
		{
			if (i != 0)
				GetToken (true);
			if (strcmp (token, "(") )
				Error ("parsing brush on line %d\n", scriptline);

			for (j = 0;j < 3;j++)
			{
				GetToken (false);
				planepts[i][j] = atof(token); // LordHavoc: float coords
			}

			GetToken (false);
			if (strcmp (token, ")") )
				Error ("parsing brush on line %d\n", scriptline);
		}

		//fflush(stdout);

		// convert points to a plane
		VectorSubtract(planepts[0], planepts[1], t1);
		VectorSubtract(planepts[2], planepts[1], t2);
		CrossProduct(t1, t2, plane.normal);
		VectorNormalize(plane.normal);
		plane.dist = DotProduct(planepts[1], plane.normal);

		// read the texturedef
		memset (&tx, 0, sizeof(tx));
		GetToken (false);
		tx.miptex = FindMiptex (token);
		GetToken (false);
		if ((hltexdef = !strcmp(token, "[")))
		{
			// S vector
			GetToken(false);
			vecs[0][0] = atof(token);
			GetToken(false);
			vecs[0][1] = atof(token);
			GetToken(false);
			vecs[0][2] = atof(token);
			GetToken(false);
			vecs[0][3] = atof(token);
			// ]
			GetToken(false);
			// [
			GetToken(false);
			// T vector
			GetToken(false);
			vecs[1][0] = atof(token);
			GetToken(false);
			vecs[1][1] = atof(token);
			GetToken(false);
			vecs[1][2] = atof(token);
			GetToken(false);
			vecs[1][3] = atof(token);
			// ]
			GetToken(false);
		}
		else
		{
			vecs[0][3] = atof(token); // LordHavoc: float coords
			GetToken (false);
			vecs[1][3] = atof(token); // LordHavoc: float coords
		}
		GetToken (false);
		rotate = atof(token);	 // LordHavoc: float coords
		GetToken (false);
		scale[0] = atof(token); // LordHavoc: was already float coords
		GetToken (false);
		scale[1] = atof(token); // LordHavoc: was already float coords

		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i = 0;i < 3;i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
					break;
			}
			if (i==3)
				break;
		}
		if (f2)
		{
			printf ("WARNING: brush with duplicate plane (first point is at %g %g %g, .map file line number %d)\n", planepts[0][0], planepts[0][1], planepts[0][2], scriptline);
			continue;
		}

		if (DotProduct(plane.normal, plane.normal) < 0.1)
		{
			printf ("WARNING: brush plane with no normal on line %d\n", scriptline);
			continue;
		}

		/*
		// LordHavoc: fix for CheckFace: point off plane errors in some maps (most notably QOOLE ones),
		// and hopefully preventing most 'portal clipped away' warnings
		VectorNormalize (plane.normal);
		for (j = 0;j < 3;j++)
			plane.normal[j] = (Q_rint((vec_t) plane.normal[j] * (vec_t) 8.0)) * (vec_t) (1.0 / 8.0);
		VectorNormalize (plane.normal);
		plane.dist = DotProduct (t3, plane.normal);
		d = (Q_rint(plane.dist * 8.0)) * (1.0 / 8.0);
		//if (fabs(d - plane.dist) >= (0.4 / 8.0))
		//	printf("WARNING: correcting minor math errors in brushface on line %d\n", scriptline);
		plane.dist = d;
		*/

		/*
		VectorNormalize (plane.normal);
		plane.dist = DotProduct (t3, plane.normal);

		VectorCopy(plane.normal, v);
		//for (j = 0;j < 3;j++)
		//	v[j] = (Q_rint((vec_t) v[j] * (vec_t) 32.0)) * (vec_t) (1.0 / 32.0);
		VectorNormalize (v);
		d = (Q_rint(DotProduct (t3, v) * 8.0)) * (1.0 / 8.0);

		// if deviation is too high, warn  (frequently happens on QOOLE maps)
		if (fabs(DotProduct(v, plane.normal) - 1.0) > (0.5 / 32.0)
		 || fabs(d - plane.dist) >= (0.25 / 8.0))
			printf("WARNING: minor misalignment of brushface on line %d\n"
			       "normal     %f %f %f (l: %f d: %f)\n"
			       "rounded to %f %f %f (l: %f d: %f r: %f)\n",
			       scriptline,
			       (vec_t) plane.normal[0], (vec_t) plane.normal[1], (vec_t) plane.normal[2], (vec_t) sqrt(DotProduct(plane.normal, plane.normal)), (vec_t) DotProduct (t3, plane.normal),
			       (vec_t) v[0], (vec_t) v[1], (vec_t) v[2], (vec_t) sqrt(DotProduct(v, v)), (vec_t) DotProduct(t3, v), (vec_t) d);
		//VectorCopy(v, plane.normal);
		//plane.dist = d;
		*/

		if (!hltexdef)
		{
			// fake proper texture vectors from QuakeEd style
			TextureAxisFromPlane(&plane, vecs[0], vecs[1]);
		}

		// rotate axis
		     if (rotate ==  0) {sinv = 0;cosv = 1;}
		else if (rotate == 90) {sinv = 1;cosv = 0;}
		else if (rotate == 180) {sinv = 0;cosv = -1;}
		else if (rotate == 270) {sinv = -1;cosv = 0;}
		else {ang = rotate * (Q_PI / 180);sinv = sin(ang);cosv = cos(ang);}

		// LordHavoc: I don't quite understand this
		for (sv = 0;sv < 2 && !vecs[0][sv];sv++);
		for (tv = 0;tv < 2 && !vecs[1][tv];tv++);

		for (i = 0;i < 2;i++)
		{
			// rotate
			ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
			nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
			vecs[i][sv] = ns;
			vecs[i][tv] = nt;
			// scale and store into texinfo
			d = 1.0 / (scale[i] ? scale[i] : 1.0);
			for (j = 0;j < 3;j++)
				tx.vecs[i][j] = vecs[i][j] * d;
			tx.vecs[i][3] = vecs[i][3];
		}

		f = malloc(sizeof(mface_t));
		f->next = b->faces;
		b->faces = f;
		f->plane = plane;
		f->texinfo = FindTexinfo (&tx);
		nummapbrushfaces++;
	}
	while (1);
}
Esempio n. 14
0
static void
SetTexinfo_QuakeEd(int shift[2], int rotate, vec_t scale[2], texinfo_t *tx)
{
    int i, j;
    vec3_t vecs[2];
    int sv, tv;
    vec_t ang, sinv, cosv;
    vec_t ns, nt;

    TextureAxisFromPlane(&(map.rgFaces[map.iFaces].plane), vecs[0], vecs[1]);

    if (!scale[0])
	scale[0] = 1;
    if (!scale[1])
	scale[1] = 1;

    // rotate axis
    if (rotate == 0) {
	sinv = 0;
	cosv = 1;
    } else if (rotate == 90) {
	sinv = 1;
	cosv = 0;
    } else if (rotate == 180) {
	sinv = 0;
	cosv = -1;
    } else if (rotate == 270) {
	sinv = -1;
	cosv = 0;
    } else {
	ang = (vec_t)rotate / 180 * Q_PI;
	sinv = sin(ang);
	cosv = cos(ang);
    }

    if (vecs[0][0])
	sv = 0;
    else if (vecs[0][1])
	sv = 1;
    else
	sv = 2;

    if (vecs[1][0])
	tv = 0;
    else if (vecs[1][1])
	tv = 1;
    else
	tv = 2;

    for (i = 0; i < 2; i++) {
	ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
	nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
	vecs[i][sv] = ns;
	vecs[i][tv] = nt;
    }

    for (i = 0; i < 2; i++)
	for (j = 0; j < 3; j++)
	    tx->vecs[i][j] = vecs[i][j] / scale[i];

    tx->vecs[0][3] = shift[0];
    tx->vecs[1][3] = shift[1];
}
Esempio n. 15
0
void ParseBrush (void)

{

	mbrush_t		*b;

	mface_t		*f, *f2;

	vec3_t		planepts[3];

	vec3_t			t1, t2, t3;

	int			i,j;

	texinfo_t	tx;

	double		d;

	float		shift[2], rotate, scale[2];

	char		name[64];



	b = &mapbrushes[nummapbrushes];

		

	do

	{

		if (!GetToken (true))

			break;

		if (!strcmp (token, "}") )

			break;

		

	// read the three point plane definition

		for (i=0 ; i<3 ; i++)

		{

			if (i != 0)

				GetToken (true);

			if (strcmp (token, "(") )

				logerror ("parsing brush"); // jkrige - was Error()

			

			for (j=0 ; j<3 ; j++)

			{

				GetToken (false);

				// jkrige - floating point texture support
				//planepts[i][j] = atoi(token);
				planepts[i][j] = atof(token);
				// jkrige - floating point texture support

			}

			

			GetToken (false);

			if (strcmp (token, ")") )

				logerror ("parsing brush"); // jkrige - was Error()

				

		}



	// read the texturedef

		memset (&tx, 0, sizeof(tx));

		GetToken (false);



		strcpy (name, token);	// JDC 8/8/97: for origin texture



		tx.miptex = FindMiptex (token);
		
		GetToken (false);
		
		shift[0] = atoi(token);
		
		GetToken (false);
		
		shift[1] = atoi(token);
		
		GetToken (false);
		
		rotate = atoi(token);	
		
		GetToken (false);

		scale[0] = atof(token);

		GetToken (false);

		scale[1] = atof(token);

		GetToken (false);

		b->Light = atol(token);



		// if the three points are all on a previous plane, it is a

		// duplicate plane

		for (f2 = b->faces ; f2 ; f2=f2->next)

		{

			for (i=0 ; i<3 ; i++)

			{

				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;

				if (d < -ON_EPSILON || d > ON_EPSILON)

					break;

			}

			if (i==3)

				break;

		}

		if (f2)		

		{

			logprint ("WARNING: brush with duplicate plane\n");

			continue;

		}



		f = malloc(sizeof(mface_t));

		f->next = b->faces;

		b->faces = f;

		

	// convert to a vector / dist plane

		for (j=0 ; j<3 ; j++)

		{

			t1[j] = planepts[0][j] - planepts[1][j];

			t2[j] = planepts[2][j] - planepts[1][j];

			t3[j] = planepts[1][j];

		}

		

		CrossProduct(t1,t2, f->plane.normal);

		if (VectorCompare (f->plane.normal, vec3_origin))

		{

			logprint ("WARNING: brush plane with no normal\n");

			b->faces = f->next;

			free (f);

			break;

		}

		VectorNormalize (f->plane.normal);

		f->plane.dist = DotProduct (t3, f->plane.normal);



	//

	// fake proper texture vectors from QuakeEd style

	//

		{

			vec3_t	vecs[2];

			int		sv, tv;

			float	ang, sinv, cosv;

			float	ns, nt;

			

			TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);

		

			if (!scale[0])

				scale[0] = 1;

			if (!scale[1])

				scale[1] = 1;

		

		

		// rotate axis

			if (rotate == 0)

				{ sinv = 0 ; cosv = 1; }

			else if (rotate == 90)

				{ sinv = 1 ; cosv = 0; }

			else if (rotate == 180)

				{ sinv = 0 ; cosv = -1; }

			else if (rotate == 270)

				{ sinv = -1 ; cosv = 0; }

			else

			{	

				ang = rotate / 180 * Q_PI;

				sinv = sin(ang);

				cosv = cos(ang);

			}

		

			if (vecs[0][0])

				sv = 0;

			else if (vecs[0][1])

				sv = 1;

			else

				sv = 2;

						

			if (vecs[1][0])

				tv = 0;

			else if (vecs[1][1])

				tv = 1;

			else

				tv = 2;

							

			for (i=0 ; i<2 ; i++)

			{

				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];

				nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];

				vecs[i][sv] = ns;

				vecs[i][tv] = nt;

			}

		

			for (i=0 ; i<2 ; i++)

				for (j=0 ; j<3 ; j++)

					tx.vecs[i][j] = vecs[i][j] / scale[i];

		

			tx.vecs[0][3] = shift[0];

			tx.vecs[1][3] = shift[1];

		}

	

	// unique the texinfo

		f->texinfo = FindTexinfo (&tx);		

	} while (1);



	// JDC 8/8/97

	// origin brushes are removed, but they set

	// the rotation origin for the rest of the brushes

	// in the entity

	//

	if (Q_strncasecmp (name, "origin",6))

	{	// keep it

		nummapbrushes++;

		b->next = mapent->brushes;

		mapent->brushes = b;

	}

	else

	{	// don't save the brush, just use as entity origin

		char	string[32];

		vec3_t	origin;



		if (num_entities == 1)

			logerror ("Origin brushes not allowed in world"); // jkrige - was Error()



		BrushOrigin (b, origin);



		sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);

		SetKeyValue (mapent, "origin", string);



		VectorCopy (origin, mapent->origin);



		memset (b, 0, sizeof(*b));

	}

}
Esempio n. 16
0
/*
=================
ParseBrush
=================
*/
void ParseBrush (void)
{
	mbrush_t	*b;
	mface_t		*f, *f2;
	vec3_t		planepts[3];
	vec3_t		t1, t2, t3;
	int			i,j;
	texinfo_t	tx;
	vec_t		d;
	float		shift[2], rotate, scale[2];

	b = &mapbrushes[nummapbrushes];
	nummapbrushes++;
	b->next = mapent->brushes;
	mapent->brushes = b;

	do
	{
		if (!GetToken (true))
			break;
		if (!strcmp (token, "}") )
			break;

		// read the three point plane definition
		for (i=0 ; i<3 ; i++)
		{
			if (i != 0)
				GetToken (true);
			if (strcmp (token, "(") )
				Error ("parsing brush");

			for (j=0 ; j<3 ; j++)
			{
				GetToken (false);
				planepts[i][j] = atof(token); // LordHavoc: float coords
			}

			GetToken (false);
			if (strcmp (token, ")") )
				Error ("parsing brush");
		}

		fflush(stdout);
		// read the texturedef
		memset (&tx, 0, sizeof(tx));
		GetToken (false);
		tx.miptex = FindMiptex (token);
		GetToken (false);
		shift[0] = atof(token); // LordHavoc: float coords
		GetToken (false);
		shift[1] = atof(token); // LordHavoc: float coords
		GetToken (false);
		rotate = atof(token);	 // LordHavoc: float coords
		GetToken (false);
		scale[0] = atof(token); // LordHavoc: was already float coords
		GetToken (false);
		scale[1] = atof(token); // LordHavoc: was already float coords

		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i=0 ; i<3 ; i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
				break;
			}
			if (i==3)
				break;
		}
		if (f2)		
		{
			printf ("WARNING: brush with duplicate plane\n");
			continue;
		}

		f = malloc(sizeof(mface_t));
		f->next = b->faces;
		b->faces = f;

		// convert to a vector / dist plane
		for (j=0 ; j<3 ; j++)
		{
			t1[j] = planepts[0][j] - planepts[1][j];
			t2[j] = planepts[2][j] - planepts[1][j];
			t3[j] = planepts[1][j];
		}

		CrossProduct(t1,t2, f->plane.normal);
		if (VectorCompare (f->plane.normal, vec3_origin))
		{
			printf ("WARNING: brush plane with no normal\n");
			b->faces = f->next;
			free (f);
			break;
		}
		VectorNormalize (f->plane.normal);
		f->plane.dist = DotProduct (t3, f->plane.normal);

		//
		// fake proper texture vectors from QuakeEd style
		//
		{
			vec3_t	vecs[2];
			int		sv, tv;
			float	ang, sinv, cosv;
			float	ns, nt;

			TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);

			if (!scale[0])
				scale[0] = 1;
			if (!scale[1])
				scale[1] = 1;

			// rotate axis
			if (rotate == 0)
			{ sinv = 0 ; cosv = 1; }
			else if (rotate == 90)
			{ sinv = 1 ; cosv = 0; }
			else if (rotate == 180)
			{ sinv = 0 ; cosv = -1; }
			else if (rotate == 270)
			{ sinv = -1 ; cosv = 0; }
			else
			{	
				ang = rotate / 180 * Q_PI;
				sinv = sin(ang);
				cosv = cos(ang);
			}

			if (vecs[0][0])
				sv = 0;
			else if (vecs[0][1])
				sv = 1;
			else
				sv = 2;
					
			if (vecs[1][0])
				tv = 0;
			else if (vecs[1][1])
				tv = 1;
			else
				tv = 2;
						
			for (i=0 ; i<2 ; i++)
			{
				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
				nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
				vecs[i][sv] = ns;
				vecs[i][tv] = nt;
			}

			for (i=0 ; i<2 ; i++)
			for (j=0 ; j<3 ; j++)
			tx.vecs[i][j] = vecs[i][j] / scale[i];

			tx.vecs[0][3] = shift[0];
			tx.vecs[1][3] = shift[1];
		}

		// unique the texinfo
		f->texinfo = FindTexinfo (&tx);		
	} while (1);
}
Esempio n. 17
0
void BeginTexturingFace (brush_t *b, face_t *f, qtexture_t *q)
{
	vec3_t	pvecs[2];
	int		sv, tv;
	float	ang, sinv, cosv;
	float	ns, nt;
	int		i,j;
	float	shade;

	// get natural texture axis
	TextureAxisFromPlane(&f->plane, pvecs[0], pvecs[1]);

	// set shading for face
	shade = SetShadeForPlane(&f->plane);
	if (camera.draw_mode == cd_texture && !b->owner->eclass->fixedsize)
	{
		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];
	}

	if (camera.draw_mode != cd_texture)
		return;

	if (!f->texdef.scale[0])
		f->texdef.scale[0] = 1;
	if (!f->texdef.scale[1])
		f->texdef.scale[1] = 1;


// rotate axis
	if (f->texdef.rotate == 0)
		{ sinv = 0 ; cosv = 1; }
	else if (f->texdef.rotate == 90)
		{ sinv = 1 ; cosv = 0; }
	else if (f->texdef.rotate == 180)
		{ sinv = 0 ; cosv = -1; }
	else if (f->texdef.rotate == 270)
		{ sinv = -1 ; cosv = 0; }
	else
	{
		ang = f->texdef.rotate / 180.0f*pMath_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];
		vecs[i][sv] = ns;
		vecs[i][tv] = nt;
	}

	for (i=0 ; i<2 ; i++)
		for (j=0 ; j<3 ; j++)
			vecs[i][j] = vecs[i][j] / f->texdef.scale[i];
}
Esempio n. 18
0
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, const Vector& origin)
{
	Vector	vecs[2];
	int		sv, tv;
	vec_t	ang, sinv, cosv;
	vec_t	ns, nt;
	texinfo_t	tx, *tc;
	int		i, j, k;

	if (!bt->name[0])
		return 0;

	memset (&tx, 0, sizeof(tx));

	// HLTOOLS - add support for texture vectors stored in the map file
	if (g_nMapFileVersion < 220)
	{
		TextureAxisFromPlane(plane, vecs[0], vecs[1]);
	}

	if (!bt->textureWorldUnitsPerTexel[0])
		bt->textureWorldUnitsPerTexel[0] = 1;
	if (!bt->textureWorldUnitsPerTexel[1])
		bt->textureWorldUnitsPerTexel[1] = 1;


	if (g_nMapFileVersion < 220)
	{
	// rotate axis
		if (bt->rotate == 0)
			{ sinv = 0 ; cosv = 1; }
		else if (bt->rotate == 90)
			{ sinv = 1 ; cosv = 0; }
		else if (bt->rotate == 180)
			{ sinv = 0 ; cosv = -1; }
		else if (bt->rotate == 270)
			{ sinv = -1 ; cosv = 0; }
		else
		{	
			ang = bt->rotate / 180 * M_PI;
			sinv = sin(ang);
			cosv = cos(ang);
		}

		if (vecs[0][0])
			sv = 0;
		else if (vecs[0][1])
			sv = 1;
		else
			sv = 2;
					
		if (vecs[1][0])
			tv = 0;
		else if (vecs[1][1])
			tv = 1;
		else
			tv = 2;
						
		for (i=0 ; i<2 ; i++)
		{
			ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
			nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
			vecs[i][sv] = ns;
			vecs[i][tv] = nt;
		}

		for (i=0 ; i<2 ; i++)
		{
			for (j=0 ; j<3 ; j++)
			{
				tx.textureVecsTexelsPerWorldUnits[i][j] = vecs[i][j] / bt->textureWorldUnitsPerTexel[i];
				tx.lightmapVecsLuxelsPerWorldUnits[i][j] = tx.textureVecsTexelsPerWorldUnits[i][j] / 16.0f;
			}
		}
	}
	else
	{
		tx.textureVecsTexelsPerWorldUnits[0][0] = bt->UAxis[0] / bt->textureWorldUnitsPerTexel[0];
		tx.textureVecsTexelsPerWorldUnits[0][1] = bt->UAxis[1] / bt->textureWorldUnitsPerTexel[0];
		tx.textureVecsTexelsPerWorldUnits[0][2] = bt->UAxis[2] / bt->textureWorldUnitsPerTexel[0];

		tx.textureVecsTexelsPerWorldUnits[1][0] = bt->VAxis[0] / bt->textureWorldUnitsPerTexel[1];
		tx.textureVecsTexelsPerWorldUnits[1][1] = bt->VAxis[1] / bt->textureWorldUnitsPerTexel[1];
		tx.textureVecsTexelsPerWorldUnits[1][2] = bt->VAxis[2] / bt->textureWorldUnitsPerTexel[1];

		tx.lightmapVecsLuxelsPerWorldUnits[0][0] = bt->UAxis[0] / bt->lightmapWorldUnitsPerLuxel;
		tx.lightmapVecsLuxelsPerWorldUnits[0][1] = bt->UAxis[1] / bt->lightmapWorldUnitsPerLuxel;
		tx.lightmapVecsLuxelsPerWorldUnits[0][2] = bt->UAxis[2] / bt->lightmapWorldUnitsPerLuxel;
		
		tx.lightmapVecsLuxelsPerWorldUnits[1][0] = bt->VAxis[0] / bt->lightmapWorldUnitsPerLuxel;
		tx.lightmapVecsLuxelsPerWorldUnits[1][1] = bt->VAxis[1] / bt->lightmapWorldUnitsPerLuxel;
		tx.lightmapVecsLuxelsPerWorldUnits[1][2] = bt->VAxis[2] / bt->lightmapWorldUnitsPerLuxel;
	}

	tx.textureVecsTexelsPerWorldUnits[0][3] = bt->shift[0] + 
		DOT_PRODUCT( origin, tx.textureVecsTexelsPerWorldUnits[0] );
	tx.textureVecsTexelsPerWorldUnits[1][3] = bt->shift[1] + 
		DOT_PRODUCT( origin, tx.textureVecsTexelsPerWorldUnits[1] );
	
	tx.lightmapVecsLuxelsPerWorldUnits[0][3] = bt->shift[0] +
		DOT_PRODUCT( origin, tx.lightmapVecsLuxelsPerWorldUnits[0] );
	tx.lightmapVecsLuxelsPerWorldUnits[1][3] = bt->shift[1] +
		DOT_PRODUCT( origin, tx.lightmapVecsLuxelsPerWorldUnits[1] );
	
	tx.flags = bt->flags;

	//
	// find the texinfo
	//
	if ( numtexinfo >= MAX_MAP_TEXINFO )
	{
		Error( "Map has too many texinfos, MAX_MAP_TEXINFO == %i\n", MAX_MAP_TEXINFO );
	}

	tc = texinfo;
	tx.texdata = FindTexData( bt->name );
	for (i=0 ; i<numtexinfo ; i++, tc++)
	{
		if (tc->flags != tx.flags)
			continue;
		bool skip = false;
		for (j=0 ; j<2 && !skip; j++)
		{
			if ( tc->texdata != tx.texdata )
			{
				skip = true;
				break;
			}
			for (k=0 ; k<4 && !skip; k++)
			{
				if (tc->textureVecsTexelsPerWorldUnits[j][k] != tx.textureVecsTexelsPerWorldUnits[j][k])
				{
					skip = true;
					break;
				}
				if( tc->lightmapVecsLuxelsPerWorldUnits[j][k] != tx.lightmapVecsLuxelsPerWorldUnits[j][k] )
				{
					skip = true;
					break;
				}
			}
		}

		if ( skip )
		{
			continue;
		}

		return i;
	}

	*tc = tx;

	if ( onlyents )
	{
		Error( "FindOrCreateTexInfo:  Tried to create new texinfo during -onlyents compile!\n" );
	}

	numtexinfo++;

	return i;
}
Esempio n. 19
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
int TexinfoForBrushTexture(plane_t *plane, brush_texture_t *bt, vec3_t origin)
{
	vec3_t	vecs[2];
	int		sv, tv;
	vec_t	ang, sinv, cosv;
	vec_t	ns, nt;
	texinfo_t	tx, *tc;
	int		i, j, k;
	float	shift[2];
	brush_texture_t		anim;
	int				mt;

	if (!bt->name[0])
		return 0;

	memset (&tx, 0, sizeof(tx));
	strcpy (tx.texture, bt->name);

	TextureAxisFromPlane(plane, vecs[0], vecs[1]);

	shift[0] = DotProduct (origin, vecs[0]);
	shift[1] = DotProduct (origin, vecs[1]);

	if (!bt->scale[0])
		bt->scale[0] = 1;
	if (!bt->scale[1])
		bt->scale[1] = 1;


// rotate axis
	if (bt->rotate == 0)
		{ sinv = 0 ; cosv = 1; }
	else if (bt->rotate == 90)
		{ sinv = 1 ; cosv = 0; }
	else if (bt->rotate == 180)
		{ sinv = 0 ; cosv = -1; }
	else if (bt->rotate == 270)
		{ sinv = -1 ; cosv = 0; }
	else
	{	
		ang = bt->rotate / 180 * Q_PI;
		sinv = sin(ang);
		cosv = cos(ang);
	}

	if (vecs[0][0])
		sv = 0;
	else if (vecs[0][1])
		sv = 1;
	else
		sv = 2;
				
	if (vecs[1][0])
		tv = 0;
	else if (vecs[1][1])
		tv = 1;
	else
		tv = 2;
					
	for (i=0 ; i<2 ; i++)
	{
		ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
		nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
		vecs[i][sv] = ns;
		vecs[i][tv] = nt;
	}

	for (i=0 ; i<2 ; i++)
		for (j=0 ; j<3 ; j++)
			tx.vecs[i][j] = vecs[i][j] / bt->scale[i];

	tx.vecs[0][3] = bt->shift[0] + shift[0];
	tx.vecs[1][3] = bt->shift[1] + shift[1];
	tx.flags = bt->flags;
	tx.value = bt->value;

	//
	// find the texinfo
	//
	tc = texinfo;
	for (i=0 ; i<numtexinfo ; i++, tc++)
	{
		if (tc->flags != tx.flags)
			continue;
		if (tc->value != tx.value)
			continue;
		for (j=0 ; j<2 ; j++)
		{
			if (strcmp (tc->texture, tx.texture))
				goto skip;
			for (k=0 ; k<4 ; k++)
			{
				if (tc->vecs[j][k] != tx.vecs[j][k])
					goto skip;
			}
		}
		return i;
skip:;
	}
	*tc = tx;
	numtexinfo++;

	// load the next animation
	mt = FindMiptex (bt->name);
	if (textureref[mt].animname[0])
	{
		anim = *bt;
		strcpy (anim.name, textureref[mt].animname);
		tc->nexttexinfo = TexinfoForBrushTexture (plane, &anim, origin);
	}
	else
		tc->nexttexinfo = -1;


	return i;
} //end of the function TexinfoForBrushTexture
Esempio n. 20
0
// =====================================================================================
//  TexinfoForBrushTexture
// =====================================================================================
int             TexinfoForBrushTexture(const plane_t* const plane, brush_texture_t* bt, const vec3_t origin)
{
    vec3_t          vecs[2];
    int             sv, tv;
    vec_t           ang, sinv, cosv;
    vec_t           ns, nt;
    texinfo_t       tx;
    texinfo_t*      tc;
    int             i, j, k;

    memset(&tx, 0, sizeof(tx));
	if(!strncmp(bt->name,"BEVEL",5))
	{
		tx.flags |= TEX_BEVEL;
		safe_strncpy(bt->name,"NULL",5);
	}
    tx.miptex = FindMiptex(bt->name);

    // Note: FindMiptex() still needs to be called here to add it to the global miptex array

    // Very Sleazy Hack 104 - since the tx.miptex index will be bogus after we sort the miptex array later
    // Put the string name of the miptex in this "index" until after we are done sorting it in WriteMiptex().
    tx.miptex = texmap64_store(strdup(bt->name));

    // set the special flag
    if (bt->name[0] == '*'
        || !strncasecmp(bt->name, "sky", 3)

// =====================================================================================
//Cpt_Andrew - Env_Sky Check
// =====================================================================================
        || !strncasecmp(bt->name, "env_sky", 5)
// =====================================================================================

        || !strncasecmp(bt->name, "clip", 4)
        || !strncasecmp(bt->name, "origin", 6)
#ifdef ZHLT_NULLTEX // AJM
        || !strncasecmp(bt->name, "null", 4)
#endif
        || !strncasecmp(bt->name, "aaatrigger", 10)
       )
    {
        tx.flags |= TEX_SPECIAL;
    }

    if (bt->txcommand)
    {
        memcpy(tx.vecs, bt->vects.quark.vects, sizeof(tx.vecs));
        if (origin[0] || origin[1] || origin[2])
        {
            tx.vecs[0][3] += DotProduct(origin, tx.vecs[0]);
            tx.vecs[1][3] += DotProduct(origin, tx.vecs[1]);
        }
    }
    else
    {
        if (g_nMapFileVersion < 220)
        {
            TextureAxisFromPlane(plane, vecs[0], vecs[1]);
        }

        if (!bt->vects.valve.scale[0])
        {
            bt->vects.valve.scale[0] = 1;
        }
        if (!bt->vects.valve.scale[1])
        {
            bt->vects.valve.scale[1] = 1;
        }

        if (g_nMapFileVersion < 220)
        {
            // rotate axis
            if (bt->vects.valve.rotate == 0)
            {
                sinv = 0;
                cosv = 1;
            }
            else if (bt->vects.valve.rotate == 90)
            {
                sinv = 1;
                cosv = 0;
            }
            else if (bt->vects.valve.rotate == 180)
            {
                sinv = 0;
                cosv = -1;
            }
            else if (bt->vects.valve.rotate == 270)
            {
                sinv = -1;
                cosv = 0;
            }
            else
            {
                ang = bt->vects.valve.rotate / 180 * Q_PI;
                sinv = sin(ang);
                cosv = cos(ang);
            }

            if (vecs[0][0])
            {
                sv = 0;
            }
            else if (vecs[0][1])
            {
                sv = 1;
            }
            else
            {
                sv = 2;
            }

            if (vecs[1][0])
            {
                tv = 0;
            }
            else if (vecs[1][1])
            {
                tv = 1;
            }
            else
            {
                tv = 2;
            }

            for (i = 0; i < 2; i++)
            {
                ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
                nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
                vecs[i][sv] = ns;
                vecs[i][tv] = nt;
            }

            for (i = 0; i < 2; i++)
            {
                for (j = 0; j < 3; j++)
                {
                    tx.vecs[i][j] = vecs[i][j] / bt->vects.valve.scale[i];
                }
            }
        }
        else
        {
            vec_t           scale;

            scale = 1 / bt->vects.valve.scale[0];
            VectorScale(bt->vects.valve.UAxis, scale, tx.vecs[0]);

            scale = 1 / bt->vects.valve.scale[1];
            VectorScale(bt->vects.valve.VAxis, scale, tx.vecs[1]);
        }

        tx.vecs[0][3] = bt->vects.valve.shift[0] + DotProduct(origin, tx.vecs[0]);
        tx.vecs[1][3] = bt->vects.valve.shift[1] + DotProduct(origin, tx.vecs[1]);
    }

    //
    // find the g_texinfo
    //
    ThreadLock();
    tc = g_texinfo;
    for (i = 0; i < g_numtexinfo; i++, tc++)
    {
        // Sleazy hack 104, Pt 3 - Use strcmp on names to avoid dups
        if (strcmp(texmap64_retrieve((tc->miptex)), texmap64_retrieve((tx.miptex))) != 0)
        {
            continue;
        }
        if (tc->flags != tx.flags)
        {
            continue;
        }
        for (j = 0; j < 2; j++)
        {
            for (k = 0; k < 4; k++)
            {
                if (tc->vecs[j][k] != tx.vecs[j][k])
                {
                    goto skip;
                }
            }
        }
        ThreadUnlock();
        return i;
skip:;
    }

    hlassume(g_numtexinfo < MAX_MAP_TEXINFO, assume_MAX_MAP_TEXINFO);

    *tc = tx;
    g_numtexinfo++;
    ThreadUnlock();
    return i;
}