Example #1
0
/*
 =======================================================================================================================
 =======================================================================================================================
 */
void FaceToBrushPrimitFace(face_t *f) {
	idVec3D	texX, texY;
	idVec3D	proj;

	// ST of (0,0) (1,0) (0,1)
	idVec5	ST[3];	// [ point index ] [ xyz ST ]

	//
	// ++timo not used as long as brushprimit_texdef and texdef are static
	// f->brushprimit_texdef.contents=f->texdef.contents;
	// f->brushprimit_texdef.flags=f->texdef.flags;
	// f->brushprimit_texdef.value=f->texdef.value;
	// strcpy(f->brushprimit_texdef.name,f->texdef.name);
	//
#ifdef _DEBUG
	if (f->plane[0] == 0.0f && f->plane[1] == 0.0f && f->plane[2] == 0.0f) {
		common->Printf("Warning : f->plane.normal is (0,0,0) in FaceToBrushPrimitFace\n");
	}

	// check d_texture
	if (!f->d_texture) {
		common->Printf("Warning : f.d_texture is NULL in FaceToBrushPrimitFace\n");
		return;
	}
#endif
	// compute axis base
	ComputeAxisBase(f->plane.Normal(), texX, texY);

	// compute projection vector
	VectorCopy( f->plane, proj );
	VectorScale(proj, -f->plane[3], proj);

	//
	// (0,0) in plane axis base is (0,0,0) in world coordinates + projection on the
	// affine plane (1,0) in plane axis base is texX in world coordinates + projection
	// on the affine plane (0,1) in plane axis base is texY in world coordinates +
	// projection on the affine plane use old texture code to compute the ST coords of
	// these points
	//
	VectorCopy(proj, ST[0]);
	EmitTextureCoordinates(ST[0], f->d_texture, f);
	VectorCopy(texX, ST[1]);
	VectorAdd(ST[1], proj, ST[1]);
	EmitTextureCoordinates(ST[1], f->d_texture, f);
	VectorCopy(texY, ST[2]);
	VectorAdd(ST[2], proj, ST[2]);
	EmitTextureCoordinates(ST[2], f->d_texture, f);

	// compute texture matrix
	f->brushprimit_texdef.coords[0][2] = ST[0][3];
	f->brushprimit_texdef.coords[1][2] = ST[0][4];
	f->brushprimit_texdef.coords[0][0] = ST[1][3] - f->brushprimit_texdef.coords[0][2];
	f->brushprimit_texdef.coords[1][0] = ST[1][4] - f->brushprimit_texdef.coords[1][2];
	f->brushprimit_texdef.coords[0][1] = ST[2][3] - f->brushprimit_texdef.coords[0][2];
	f->brushprimit_texdef.coords[1][1] = ST[2][4] - f->brushprimit_texdef.coords[1][2];
}
Example #2
0
void Face_GetScale_BrushPrimit(face_t *face, float *s, float *t, float *rot) {
	idVec3D	texS, texT;
	ComputeAxisBase(face->plane.Normal(), texS, texT);

	if (face == NULL || face->face_winding == NULL) {
		return;
	}
	// find ST coordinates for the center of the face
	double	Os = 0, Ot = 0;
	for (int i = 0; i < face->face_winding->GetNumPoints(); i++) {
		Os += DotProduct((*face->face_winding)[i], texS);
		Ot += DotProduct((*face->face_winding)[i], texT);
	}

	Os /= face->face_winding->GetNumPoints();
	Ot /= face->face_winding->GetNumPoints();

	brushprimit_texdef_t	*pBP = &face->brushprimit_texdef;

	// here we have a special case, M is a translation and it's inverse is easy
	float					BPO[2][3];
	float					aux[2][3];
	float					m[2][3];
	memset(&m, 0, sizeof (float) *6);
	m[0][0] = 1;
	m[1][1] = 1;
	m[0][2] = -Os;
	m[1][2] = -Ot;
	BPMatMul(m, pBP->coords, aux);
	m[0][2] = Os;
	m[1][2] = Ot;			// now M^-1
	BPMatMul(aux, m, BPO);

	// apply a given scale (on S and T)
	ConvertTexMatWithQTexture(BPO, face->d_texture, aux, NULL);

	*s = idMath::Sqrt(aux[0][0] * aux[0][0] + aux[1][0] * aux[1][0]);
	*t = idMath::Sqrt(aux[0][1] * aux[0][1] + aux[1][1] * aux[1][1]);

	// compute rotate value
	if (idMath::Fabs(face->brushprimit_texdef.coords[0][0]) < ZERO_EPSILON)
	{
		// rotate is +-90
		if (face->brushprimit_texdef.coords[1][0] > 0) {
			*rot = 90.0f;
		}
		else {
			*rot = -90.0f;
		}
	}
	else {
		*rot = RAD2DEG(atan2(face->brushprimit_texdef.coords[1][0] / (*s) ? (*s) : 1.0f, face->brushprimit_texdef.coords[0][0] / (*t) ? (*t) : 1.0f));
	}


}
Example #3
0
/*
=================
idMapBrushSide::GetTextureVectors
=================
*/
void idMapBrushSide::GetTextureVectors( idVec4 v[2] ) const {
	int i;
	idVec3 texX, texY;

	ComputeAxisBase( plane.Normal(), texX, texY );
	for ( i = 0; i < 2; i++ ) {
		v[i][0] = texX[0] * texMat[i][0] + texY[0] * texMat[i][1];
		v[i][1] = texX[1] * texMat[i][0] + texY[1] * texMat[i][1];
		v[i][2] = texX[2] * texMat[i][0] + texY[2] * texMat[i][1];
		v[i][3] = texMat[i][2] + ( origin * v[i].ToVec3() );
	}
}
Example #4
0
//
// =======================================================================================================================
//    compute texture coordinates for the winding points
// =======================================================================================================================
//
void EmitBrushPrimitTextureCoordinates(face_t *f, idWinding *w, patchMesh_t *patch) {
	idVec3D	texX, texY;
	double	x, y;

	if (f== NULL || (w == NULL && patch == NULL)) {
		return;
	}

	// compute axis base
	ComputeAxisBase(f->plane.Normal(), texX, texY);

	//
	// in case the texcoords matrix is empty, build a default one same behaviour as if
	// scale[0]==0 && scale[1]==0 in old code
	//
	if (	f->brushprimit_texdef.coords[0][0] == 0 &&
			f->brushprimit_texdef.coords[1][0] == 0 &&
			f->brushprimit_texdef.coords[0][1] == 0 &&
			f->brushprimit_texdef.coords[1][1] == 0 ) {
		f->brushprimit_texdef.coords[0][0] = 1.0f;
		f->brushprimit_texdef.coords[1][1] = 1.0f;
		ConvertTexMatWithQTexture(&f->brushprimit_texdef, NULL, &f->brushprimit_texdef, f->d_texture);
	}

	int i;
	if (w) {
		for (i = 0; i < w->GetNumPoints(); i++) {
			x = DotProduct((*w)[i], texX);
			y = DotProduct((*w)[i], texY);
			(*w)[i][3] = f->brushprimit_texdef.coords[0][0] * x + f->brushprimit_texdef.coords[0][1] * y + f->brushprimit_texdef.coords[0][2];
			(*w)[i][4] = f->brushprimit_texdef.coords[1][0] * x + f->brushprimit_texdef.coords[1][1] * y + f->brushprimit_texdef.coords[1][2];
		}
	}
	
	if (patch) {
		int j;
		for ( i = 0; i < patch->width; i++ ) {
			for ( j = 0; j < patch->height; j++ ) {
				x = DotProduct(patch->ctrl(i, j).xyz, texX);
				y = DotProduct(patch->ctrl(i, j).xyz, texY);
				patch->ctrl(i, j).st.x = f->brushprimit_texdef.coords[0][0] * x + f->brushprimit_texdef.coords[0][1] * y + f->brushprimit_texdef.coords[0][2];
				patch->ctrl(i, j).st.y = f->brushprimit_texdef.coords[1][0] * x + f->brushprimit_texdef.coords[1][1] * y + f->brushprimit_texdef.coords[1][2];
			}
		}
	}
}
Example #5
0
//
// =======================================================================================================================
//    call Face_MoveTexture_BrushPrimit after idVec3D computation
// =======================================================================================================================
//
void Select_ShiftTexture_BrushPrimit(face_t *f, float x, float y, bool autoAdjust) {
#if 0
	idVec3D	texS, texT;
	idVec3D	delta;
	ComputeAxisBase(f->plane.normal, texS, texT);
	VectorScale(texS, x, texS);
	VectorScale(texT, y, texT);
	VectorCopy(texS, delta);
	VectorAdd(delta, texT, delta);
	Face_MoveTexture_BrushPrimit(f, delta);
#else
	if (autoAdjust) {
		x /= f->d_texture->GetEditorImage()->uploadWidth;
		y /= f->d_texture->GetEditorImage()->uploadHeight;
	}
	f->brushprimit_texdef.coords[0][2] += x;
	f->brushprimit_texdef.coords[1][2] += y;
	EmitBrushPrimitTextureCoordinates(f, f->face_winding);
#endif
}
Example #6
0
//
// =======================================================================================================================
//    texture locking
// =======================================================================================================================
//
void Face_MoveTexture_BrushPrimit(face_t *f, idVec3 delta) {
	idVec3D	texS, texT;
	double	tx, ty;
	idVec3D	M[3];	// columns of the matrix .. easier that way
	double	det;
	idVec3D	D[2];

	// compute plane axis base ( doesn't change with translation )
	ComputeAxisBase(f->plane.Normal(), texS, texT);

	// compute translation vector in plane axis base
	tx = DotProduct(delta, texS);
	ty = DotProduct(delta, texT);

	// fill the data vectors
	M[0][0] = tx;
	M[0][1] = 1.0f + tx;
	M[0][2] = tx;
	M[1][0] = ty;
	M[1][1] = ty;
	M[1][2] = 1.0f + ty;
	M[2][0] = 1.0f;
	M[2][1] = 1.0f;
	M[2][2] = 1.0f;
	D[0][0] = f->brushprimit_texdef.coords[0][2];
	D[0][1] = f->brushprimit_texdef.coords[0][0] + f->brushprimit_texdef.coords[0][2];
	D[0][2] = f->brushprimit_texdef.coords[0][1] + f->brushprimit_texdef.coords[0][2];
	D[1][0] = f->brushprimit_texdef.coords[1][2];
	D[1][1] = f->brushprimit_texdef.coords[1][0] + f->brushprimit_texdef.coords[1][2];
	D[1][2] = f->brushprimit_texdef.coords[1][1] + f->brushprimit_texdef.coords[1][2];

	// solve
	det = SarrusDet(M[0], M[1], M[2]);
	f->brushprimit_texdef.coords[0][0] = SarrusDet(D[0], M[1], M[2]) / det;
	f->brushprimit_texdef.coords[0][1] = SarrusDet(M[0], D[0], M[2]) / det;
	f->brushprimit_texdef.coords[0][2] = SarrusDet(M[0], M[1], D[0]) / det;
	f->brushprimit_texdef.coords[1][0] = SarrusDet(D[1], M[1], M[2]) / det;
	f->brushprimit_texdef.coords[1][1] = SarrusDet(M[0], D[1], M[2]) / det;
	f->brushprimit_texdef.coords[1][2] = SarrusDet(M[0], M[1], D[1]) / det;
}
Example #7
0
// Timo
// brush primitive texture shifting, using camera view to select translations :
void CCamWnd::ShiftTexture_BrushPrimit(face_t *f, int x, int y)
{
	vec3_t texS,texT;
	vec3_t viewX,viewY;
	int XS,XT,YS,YT;
	int outS,outT;
#ifdef _DEBUG
	if (!g_qeglobals.m_bBrushPrimitMode)
	{
		Sys_Printf("Warning : unexpected call to CCamWnd::ShiftTexture_BrushPrimit with brush primitive mode disbaled\n");
		return;
	}
#endif
	// compute face axis base
	ComputeAxisBase( f->plane.normal, texS, texT );
	// compute camera view vectors
	VectorCopy( m_Camera.vup, viewY );
	VectorCopy( m_Camera.vright, viewX );
	// compute best vectors
	ComputeBest2DVector( viewX, texS, texT, XS, XT );
	ComputeBest2DVector( viewY, texS, texT, YS, YT );
	// check this is not a degenerate case
	if ( ( XS == YS ) && ( XT == YT ) )
	{
#ifdef _DEBUG
		Sys_Printf("Warning : degenerate best vectors axis base in CCamWnd::ShiftTexture_BrushPrimit\n");
#endif
		// forget it
		Select_ShiftTexture_BrushPrimit( f, x, y );
		return;
	}
	// compute best fitted translation in face axis base
	outS = XS*x + YS*y;
	outT = XT*x + YT*y;
	// call actual texture shifting code
	Select_ShiftTexture_BrushPrimit( f, outS, outT );
}
Example #8
0
void Face_FlipTexture_BrushPrimit(face_t *f, bool y) {

	float s, t, rot;
	Face_GetScale_BrushPrimit(f, &s, &t, &rot);
	if (y) {
		Face_SetExplicitScale_BrushPrimit(f, 0.0, -t);
	} else {
		Face_SetExplicitScale_BrushPrimit(f, -s, 0.0);
	}
#if 0

	idVec3D	texS, texT;
	ComputeAxisBase(f->plane.normal, texS, texT);
	double	Os = 0, Ot = 0;
	for (int i = 0; i < f->face_winding->numpoints; i++) {
		Os += DotProduct(f->face_winding->p[i], texS);
		Ot += DotProduct(f->face_winding->p[i], texT);
	}

	Ot = abs(Ot);
	Ot *= t;
	Ot /= f->d_texture->GetEditorImage()->uploadHeight;

	Os = abs(Os);
	Os *= s;
	Os /= f->d_texture->GetEditorImage()->uploadWidth;

	
	if (y) {
		Face_FitTexture_BrushPrimit(f, texS, texT, -Ot, 1.0);
	} else {
		Face_FitTexture_BrushPrimit(f, texS, texT, 1.0, -Os);
	}
	EmitBrushPrimitTextureCoordinates(f, f->face_winding);
#endif
}
Example #9
0
File: fog.c Project: otty/cake3
/*
====================
ChopFaceByBrush

There may be a fragment contained in the brush
====================
*/
qboolean ChopFaceByBrush(drawSurface_t * ds, bspBrush_t * b)
{
	int             i, j;
	side_t         *s;
	plane_t        *plane;
	winding_t      *w;
	winding_t      *front, *back;
	winding_t      *outside[MAX_BRUSH_SIDES];
	int             numOutside;
	drawSurface_t  *newds;
	drawVert_t     *dv;
	shaderInfo_t   *si;
	float           mins[2];

	// brush primitive :
	// axis base
	vec3_t          texX, texY;
	vec_t           x, y;

	w = WindingFromDrawSurf(ds);
	numOutside = 0;

	for(i = 0; i < b->numsides; i++)
	{
		s = &b->sides[i];
		if(s->backSide)
		{
			continue;
		}
		plane = &mapPlanes[s->planenum];

		// handle coplanar outfacing (don't fog)
		if(ds->side->planenum == s->planenum)
		{
			return qfalse;
		}

		// handle coplanar infacing (keep inside)
		if((ds->side->planenum ^ 1) == s->planenum)
		{
			continue;
		}

		// general case
		ClipWindingEpsilon(w, plane->normal, plane->dist, ON_EPSILON, &front, &back);
		FreeWinding(w);
		if(!back)
		{
			// nothing actually contained inside
			for(j = 0; j < numOutside; j++)
			{
				FreeWinding(outside[j]);
			}
			return qfalse;
		}
		if(front)
		{
			if(numOutside == MAX_BRUSH_SIDES)
			{
				Error("MAX_BRUSH_SIDES");
			}
			outside[numOutside] = front;
			numOutside++;
		}
		w = back;
	}

	// all of outside fragments become seperate drawsurfs
	// linked to the same side
	c_fogFragment += numOutside;
	s = ds->side;

	for(i = 0; i < numOutside; i++)
	{
		newds = DrawSurfaceForSide(ds->mapBrush, s, outside[i]);
		FreeWinding(outside[i]);
	}


	// replace ds->verts with the verts for w
	ds->numVerts = w->numpoints;
	free(ds->verts);

	ds->verts = malloc(ds->numVerts * sizeof(*ds->verts));
	memset(ds->verts, 0, ds->numVerts * sizeof(*ds->verts));

	si = s->shaderInfo;

	mins[0] = 9999;
	mins[1] = 9999;

	// compute s/t coordinates from brush primitive texture matrix
	// compute axis base
	ComputeAxisBase(mapPlanes[s->planenum].normal, texX, texY);

	for(j = 0; j < w->numpoints; j++)
	{
		dv = ds->verts + j;
		VectorCopy(w->p[j], dv->xyz);

		if(g_bBrushPrimit == BPRIMIT_OLDBRUSHES)
		{
			// calculate texture s/t
			dv->st[0] = s->vecs[0][3] + DotProduct(s->vecs[0], dv->xyz);
			dv->st[1] = s->vecs[1][3] + DotProduct(s->vecs[1], dv->xyz);
			dv->st[0] /= si->width;
			dv->st[1] /= si->height;
		}
		else
		{
			// calculate texture s/t from brush primitive texture matrix
			x = DotProduct(dv->xyz, texX);
			y = DotProduct(dv->xyz, texY);
			dv->st[0] = s->texMat[0][0] * x + s->texMat[0][1] * y + s->texMat[0][2];
			dv->st[1] = s->texMat[1][0] * x + s->texMat[1][1] * y + s->texMat[1][2];
		}

		if(dv->st[0] < mins[0])
		{
			mins[0] = dv->st[0];
		}
		if(dv->st[1] < mins[1])
		{
			mins[1] = dv->st[1];
		}

		// copy normal
		VectorCopy(mapPlanes[s->planenum].normal, dv->normal);
	}

	// adjust the texture coordinates to be as close to 0 as possible
	if(!si->globalTexture)
	{
		mins[0] = floor(mins[0]);
		mins[1] = floor(mins[1]);
		for(i = 0; i < w->numpoints; i++)
		{
			dv = ds->verts + i;
			dv->st[0] -= mins[0];
			dv->st[1] -= mins[1];
		}
	}

	return qtrue;
}
Example #10
0
/*
 =======================================================================================================================
 =======================================================================================================================
 */
void TextureLockTransformation_BrushPrimit(face_t *f) {
	idVec3D	Orig, texS, texT;		// axis base of initial plane

	// used by transformation algo
	idVec3D	temp;
	int		j;
	//idVec3D	vRotate;				// rotation vector

	idVec3D	rOrig, rvecS, rvecT;	// geometric transformation of (0,0) (1,0) (0,1) { initial plane axis base }
	idVec3	rNormal;
	idVec3D	rtexS, rtexT;	// axis base for the transformed plane
	idVec3D	lOrig, lvecS, lvecT;	// [2] are not used ( but usefull for debugging )
	idVec3D	M[3];
	double	det;
	idVec3D	D[2];

	// silence compiler warnings
	rOrig.Zero();
	rvecS = rOrig;
	rvecT = rOrig;
	rNormal.x = rOrig.x;
	rNormal.y = rOrig.y;
	rNormal.z = rOrig.z;

	// compute plane axis base
	ComputeAxisBase(f->plane.Normal(), texS, texT);
	Orig.x = vec3_origin.x;
	Orig.y = vec3_origin.y;
	Orig.z = vec3_origin.z;

	//
	// compute coordinates of (0,0) (1,0) (0,1) ( expressed in initial plane axis base
	// ) after transformation (0,0) (1,0) (0,1) ( expressed in initial plane axis base
	// ) <-> (0,0,0) texS texT ( expressed world axis base ) input: Orig, texS, texT
	// (and the global locking params) ouput: rOrig, rvecS, rvecT, rNormal
	//
	if (txlock_bRotation) {
/*
		// rotation vector
		vRotate.x = vec3_origin.x;
		vRotate.y = vec3_origin.y;
		vRotate.z = vec3_origin.z;
		vRotate[txl_nAxis] = txl_fDeg;
		VectorRotate3Origin(Orig, vRotate, txl_vOrigin, rOrig);
		VectorRotate3Origin(texS, vRotate, txl_vOrigin, rvecS);
		VectorRotate3Origin(texT, vRotate, txl_vOrigin, rvecT);

		// compute normal of plane after rotation
		VectorRotate3(f->plane.Normal(), vRotate, rNormal);
*/
	}
	else {
		VectorSubtract(Orig, txl_origin, temp);
		for (j = 0; j < 3; j++) {
			rOrig[j] = DotProduct(temp, txl_matrix[j]) + txl_origin[j];
		}

		VectorSubtract(texS, txl_origin, temp);
		for (j = 0; j < 3; j++) {
			rvecS[j] = DotProduct(temp, txl_matrix[j]) + txl_origin[j];
		}

		VectorSubtract(texT, txl_origin, temp);
		for (j = 0; j < 3; j++) {
			rvecT[j] = DotProduct(temp, txl_matrix[j]) + txl_origin[j];
		}

		//
		// we also need the axis base of the target plane, apply the transformation matrix
		// to the normal too..
		//
		for (j = 0; j < 3; j++) {
			rNormal[j] = DotProduct(f->plane, txl_matrix[j]);
		}
	}

	// compute rotated plane axis base
	ComputeAxisBase(rNormal, rtexS, rtexT);

	// compute S/T coordinates of the three points in rotated axis base ( in M matrix )
	lOrig[0] = DotProduct(rOrig, rtexS);
	lOrig[1] = DotProduct(rOrig, rtexT);
	lvecS[0] = DotProduct(rvecS, rtexS);
	lvecS[1] = DotProduct(rvecS, rtexT);
	lvecT[0] = DotProduct(rvecT, rtexS);
	lvecT[1] = DotProduct(rvecT, rtexT);
	M[0][0] = lOrig[0];
	M[1][0] = lOrig[1];
	M[2][0] = 1.0f;
	M[0][1] = lvecS[0];
	M[1][1] = lvecS[1];
	M[2][1] = 1.0f;
	M[0][2] = lvecT[0];
	M[1][2] = lvecT[1];
	M[2][2] = 1.0f;

	// fill data vector
	D[0][0] = f->brushprimit_texdef.coords[0][2];
	D[0][1] = f->brushprimit_texdef.coords[0][0] + f->brushprimit_texdef.coords[0][2];
	D[0][2] = f->brushprimit_texdef.coords[0][1] + f->brushprimit_texdef.coords[0][2];
	D[1][0] = f->brushprimit_texdef.coords[1][2];
	D[1][1] = f->brushprimit_texdef.coords[1][0] + f->brushprimit_texdef.coords[1][2];
	D[1][2] = f->brushprimit_texdef.coords[1][1] + f->brushprimit_texdef.coords[1][2];

	// solve
	det = SarrusDet(M[0], M[1], M[2]);
	f->brushprimit_texdef.coords[0][0] = SarrusDet(D[0], M[1], M[2]) / det;
	f->brushprimit_texdef.coords[0][1] = SarrusDet(M[0], D[0], M[2]) / det;
	f->brushprimit_texdef.coords[0][2] = SarrusDet(M[0], M[1], D[0]) / det;
	f->brushprimit_texdef.coords[1][0] = SarrusDet(D[1], M[1], M[2]) / det;
	f->brushprimit_texdef.coords[1][1] = SarrusDet(M[0], D[1], M[2]) / det;
	f->brushprimit_texdef.coords[1][2] = SarrusDet(M[0], M[1], D[1]) / det;
}
Example #11
0
/*
 =======================================================================================================================
 =======================================================================================================================
 */
void Face_SetExplicitScale_BrushPrimit(face_t *face, float s, float t) {
	idVec3D	texS, texT;
	ComputeAxisBase(face->plane.Normal(), texS, texT);

	// find ST coordinates for the center of the face
	double	Os = 0, Ot = 0;

	for (int i = 0; i < face->face_winding->GetNumPoints(); i++) {
		Os += DotProduct((*face->face_winding)[i], texS);
		Ot += DotProduct((*face->face_winding)[i], texT);
	}

	Os /= face->face_winding->GetNumPoints();
	Ot /= face->face_winding->GetNumPoints();

	brushprimit_texdef_t	*pBP = &face->brushprimit_texdef;

	// here we have a special case, M is a translation and it's inverse is easy
	float					BPO[2][3];
	float					aux[2][3];
	float					m[2][3];
	memset(&m, 0, sizeof (float) *6);
	m[0][0] = 1;
	m[1][1] = 1;
	m[0][2] = -Os;
	m[1][2] = -Ot;
	BPMatMul(m, pBP->coords, aux);
	m[0][2] = Os;
	m[1][2] = Ot;			// now M^-1
	BPMatMul(aux, m, BPO);

	// apply a given scale (on S and T)
	ConvertTexMatWithQTexture(BPO, face->d_texture, aux, NULL);

	// reset the scale (normalize the matrix)
	double	v1, v2;
	v1 = idMath::Sqrt(aux[0][0] * aux[0][0] + aux[1][0] * aux[1][0]);
	v2 = idMath::Sqrt(aux[0][1] * aux[0][1] + aux[1][1] * aux[1][1]);

	if (s == 0.0) {
		s = v1;
	}
	if (t == 0.0) {
		t = v2;
	}

	double	sS, sT;

	// put the values for scale on S and T here:
	sS = s / v1;
	sT = t / v2;
	aux[0][0] *= sS;
	aux[1][0] *= sS;
	aux[0][1] *= sT;
	aux[1][1] *= sT;
	ConvertTexMatWithQTexture(aux, NULL, BPO, face->d_texture);
	BPMatMul(m, BPO, aux);	// m is M^-1
	m[0][2] = -Os;
	m[1][2] = -Ot;
	BPMatMul(aux, m, pBP->coords);

	// now emit the coordinates on the winding
	EmitBrushPrimitTextureCoordinates(face, face->face_winding);
}
Example #12
0
static void ConvertBrush(FILE * f, int num, bspBrush_t * brush, vec3_t origin)
{
	int             i, j;
	bspBrushSide_t *side;
	side_t         *buildSide;
	bspShader_t    *shader;
	char           *texture;
	bspPlane_t     *plane;
	plane_t        *buildPlane;
	vec3_t          pts[3];
	bspDrawVert_t  *vert[3];
	int             valid;


	/* start brush */
	fprintf(f, "\t// brush %d\n", num);
	fprintf(f, "\t{\n");
	fprintf(f, "\tbrushDef\n");
	fprintf(f, "\t{\n");

	/* clear out build brush */
	for(i = 0; i < buildBrush->numsides; i++)
	{
		buildSide = &buildBrush->sides[i];
		if(buildSide->winding != NULL)
		{
			FreeWinding(buildSide->winding);
			buildSide->winding = NULL;
		}
	}
	buildBrush->numsides = 0;

	/* iterate through bsp brush sides */
	for(i = 0; i < brush->numSides; i++)
	{
		/* get side */
		side = &bspBrushSides[brush->firstSide + i];

		/* get shader */
		if(side->shaderNum < 0 || side->shaderNum >= numBSPShaders)
			continue;
		shader = &bspShaders[side->shaderNum];
		if(!Q_stricmp(shader->shader, "default") || !Q_stricmp(shader->shader, "noshader"))
			continue;

		/* get plane */
		plane = &bspPlanes[side->planeNum];

		/* add build side */
		buildSide = &buildBrush->sides[buildBrush->numsides];
		buildBrush->numsides++;

		/* tag it */
		buildSide->shaderInfo = ShaderInfoForShader(shader->shader);
		buildSide->planenum = side->planeNum;
		buildSide->winding = NULL;
	}

	/* make brush windings */
	if(!CreateBrushWindings(buildBrush))
		return;

	/* iterate through build brush sides */
	for(i = 0; i < buildBrush->numsides; i++)
	{
		/* get build side */
		buildSide = &buildBrush->sides[i];

		/* get plane */
		buildPlane = &mapplanes[buildSide->planenum];

		/* dummy check */
		if(buildSide->shaderInfo == NULL || buildSide->winding == NULL)
			continue;

		// st-texcoords -> texMat block
		// start out with dummy
		VectorSet(buildSide->texMat[0], 1 / 32.0, 0, 0);
		VectorSet(buildSide->texMat[1], 0, 1 / 32.0, 0);

		// find surface for this side (by brute force)
		// surface format:
		//   - meshverts point in pairs of three into verts
		//   - (triangles)
		//   - find the triangle that has most in common with our side
		GetBestSurfaceTriangleMatchForBrushside(buildSide, vert);
		valid = 0;

		if(vert[0] && vert[1] && vert[2])
		{
			int             i;
			vec3_t          texX, texY;
			vec3_t          xy1I, xy1J, xy1K;
			vec2_t          stI, stJ, stK;
			vec_t           D, D0, D1, D2;

			ComputeAxisBase(buildPlane->normal, texX, texY);

			VectorSet(xy1I, DotProduct(vert[0]->xyz, texX), DotProduct(vert[0]->xyz, texY), 1);
			VectorSet(xy1J, DotProduct(vert[1]->xyz, texX), DotProduct(vert[1]->xyz, texY), 1);
			VectorSet(xy1K, DotProduct(vert[2]->xyz, texX), DotProduct(vert[2]->xyz, texY), 1);
			stI[0] = vert[0]->st[0];
			stI[1] = vert[0]->st[1];
			stJ[0] = vert[1]->st[0];
			stJ[1] = vert[1]->st[1];
			stK[0] = vert[2]->st[0];
			stK[1] = vert[2]->st[1];

			//   - solve linear equations:
			//     - (x, y) := xyz . (texX, texY)
			//     - st[i] = texMat[i][0]*x + texMat[i][1]*y + texMat[i][2]
			//       (for three vertices)
			D = Det3x3(xy1I[0], xy1I[1], 1, xy1J[0], xy1J[1], 1, xy1K[0], xy1K[1], 1);
			if(D != 0)
			{
				for(i = 0; i < 2; ++i)
				{
					D0 = Det3x3(stI[i], xy1I[1], 1, stJ[i], xy1J[1], 1, stK[i], xy1K[1], 1);
					D1 = Det3x3(xy1I[0], stI[i], 1, xy1J[0], stJ[i], 1, xy1K[0], stK[i], 1);
					D2 = Det3x3(xy1I[0], xy1I[1], stI[i], xy1J[0], xy1J[1], stJ[i], xy1K[0], xy1K[1], stK[i]);
					VectorSet(buildSide->texMat[i], D0 / D, D1 / D, D2 / D);
					valid = 1;
				}
			}
			else
				fprintf(stderr,
						"degenerate triangle found when solving texMat equations for\n(%f %f %f) (%f %f %f) (%f %f %f)\n( %f %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n( %f %f %f ) -> ( %f %f )\n",
						buildPlane->normal[0], buildPlane->normal[1], buildPlane->normal[2], vert[0]->normal[0],
						vert[0]->normal[1], vert[0]->normal[2], texX[0], texX[1], texX[2], texY[0], texY[1], texY[2],
						vert[0]->xyz[0], vert[0]->xyz[1], vert[0]->xyz[2], xy1I[0], xy1I[1], vert[1]->xyz[0], vert[1]->xyz[1],
						vert[1]->xyz[2], xy1J[0], xy1J[1], vert[2]->xyz[0], vert[2]->xyz[1], vert[2]->xyz[2], xy1K[0], xy1K[1]);
		}
		else if(strncmp(buildSide->shaderInfo->shader, "textures/common/", 16))
			fprintf(stderr, "no matching triangle for brushside using %s (hopefully nobody can see this side anyway)\n",
					buildSide->shaderInfo->shader);

		/* get texture name */
		if(!Q_strncasecmp(buildSide->shaderInfo->shader, "textures/", 9))
			texture = buildSide->shaderInfo->shader + 9;
		else
			texture = buildSide->shaderInfo->shader;

		/* get plane points and offset by origin */
		for(j = 0; j < 3; j++)
		{
			VectorAdd(buildSide->winding->p[j], origin, pts[j]);
			//% pts[ j ][ 0 ] = SNAP_INT_TO_FLOAT * floor( pts[ j ][ 0 ] * SNAP_FLOAT_TO_INT + 0.5f );
			//% pts[ j ][ 1 ] = SNAP_INT_TO_FLOAT * floor( pts[ j ][ 1 ] * SNAP_FLOAT_TO_INT + 0.5f );
			//% pts[ j ][ 2 ] = SNAP_INT_TO_FLOAT * floor( pts[ j ][ 2 ] * SNAP_FLOAT_TO_INT + 0.5f );
		}

		/* print brush side */
		/* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 0 0.500000 0.500000 0 0 0 */
		fprintf(f,
				"\t\t( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( %.3f %.3f %.3f ) ( ( %.8f %.8f %.8f ) ( %.8f %.8f %.8f ) ) %s %d 0 0\n",
				pts[0][0], pts[0][1], pts[0][2], pts[1][0], pts[1][1], pts[1][2], pts[2][0], pts[2][1], pts[2][2],
				buildSide->texMat[0][0], buildSide->texMat[0][1], buildSide->texMat[0][2], buildSide->texMat[1][0],
				buildSide->texMat[1][1], buildSide->texMat[1][2], texture,
				// DEBUG: valid ? 0 : C_DETAIL
				0);
		// TODO write brush primitives format here
	}

	/* end brush */
	fprintf(f, "\t}\n");
	fprintf(f, "\t}\n\n");
}
Example #13
0
// experimental stuff, work directly on BP
static void OnTest( GtkWidget *widget, gpointer data ){
	if ( !g_qeglobals.m_bBrushPrimitMode ) {
		Sys_FPrintf( SYS_WRN, "BP mode required\n" );
		return;
	}
	if ( g_ptrSelectedFaces.GetSize() != 1 ) {
		Sys_FPrintf( SYS_WRN, "Expected single face selection\n" );
		return;
	}
	brush_t *b = reinterpret_cast<brush_t*>( g_ptrSelectedFaceBrushes.GetAt( 0 ) );
	face_t *selFace = reinterpret_cast<face_t*>( g_ptrSelectedFaces.GetAt( 0 ) );
	// get the ST axis base for the face
	vec3_t texS,texT;
	ComputeAxisBase( selFace->plane.normal, texS, texT );
	// find ST coordinates for the center of the face
	float Os = 0,Ot = 0;
	int i;
	for ( i = 0; i < selFace->face_winding->numpoints; i++ )
	{
		Os += DotProduct( selFace->face_winding->points[i],texS );
		Ot += DotProduct( selFace->face_winding->points[i],texT );
	}
	Os /= selFace->face_winding->numpoints;
	Ot /= selFace->face_winding->numpoints;
	brushprimit_texdef_t *pBP = &selFace->brushprimit_texdef;

	// (FIXME: initial version, before axis base change optimize)

	// we need to compute our BP matrix in this new axis base (O,texS,texT)
	// the general case if BPO = M * BP * M^-1
	//   where BPO is transformation expressed in (O,texS,texT)
	//         M is the axis base change from (origin,texS,texT) to (O,texS,texT)
	// here we have a special case, M is a translation and it's inverse is easy
	vec_t BPO[2][3];
	vec_t aux[2][3];
	vec_t m[2][3];
	memset( &m, 0, sizeof( vec_t ) * 6 );
	m[0][0] = 1; m[1][1] = 1; m[0][2] = -Os; m[1][2] = -Ot;
	BPMatMul( m, pBP->coords, aux );
	m[0][2] = Os; m[1][2] = Ot; // now M^-1
	BPMatMul( aux, m, BPO );

#if 0
	// apply a scaling
	// scale factors against S and T axis, we apply on top of the existing matrix
	// <1 will decrease the texel/world resolution, >1 will increase
	float sS = 1.025,sT = 1.025;
	BPMatScale( BPO,sS,sT );
#endif
#if 0
	// apply a rotation
	float theta = 5;
	BPMatRotate( BPO,theta );
#endif
#if 0
	// read the scale
	ConvertTexMatWithQTexture( BPO, selFace->d_texture, aux, NULL );
	// reset the scale (normalize the matrix)
	vec_t v1,v2;
	v1 = sqrt( aux[0][0] * aux[0][0] + aux[1][0] * aux[1][0] );
	v2 = sqrt( aux[0][1] * aux[0][1] + aux[1][1] * aux[1][1] );
	// if reading the scale values, we have them here:
	Sys_Printf( "Current Scale: S: %g T: %g\n", v1, v2 );
	return;
#endif
#if 1
	// apply a given scale (on S and T)
	ConvertTexMatWithQTexture( BPO, selFace->d_texture, aux, NULL );
	// reset the scale (normalize the matrix)
	vec_t v1,v2;
	v1 = sqrt( aux[0][0] * aux[0][0] + aux[1][0] * aux[1][0] );
	v2 = sqrt( aux[0][1] * aux[0][1] + aux[1][1] * aux[1][1] );
	vec_t sS,sT;
	// put the values for scale on S and T here:
	sS = 1.2 / v1;
	sT = 0.8 / v2;
	aux[0][0] *= sS; aux[1][0] *= sS;
	aux[0][1] *= sT; aux[1][1] *= sT;
	ConvertTexMatWithQTexture( aux, NULL, BPO, selFace->d_texture );
#endif

	// now BPO must be expressed back in (origin,texS,texT) axis base BP = M^-1 * BPO * M
	BPMatMul( m, BPO, aux ); // m is M^-1
	m[0][2] = -Os; m[1][2] = -Ot;
	BPMatMul( aux, m, pBP->coords );

	// now emit the coordinates on the winding
	EmitBrushPrimitTextureCoordinates( selFace, selFace->face_winding );
	Sys_UpdateWindows( W_CAMERA );
}