⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 face.cpp

📁 3D游戏场景编辑器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	f->Tex.DirtyFlag = GE_TRUE;
}

void	Face_Shear(Face *f, const geVec3d *ShearVec, const geVec3d *ShearAxis)
{
	int		i;

	assert(f);
	assert(ShearVec);
	assert(ShearAxis);

	for(i=0;i < f->NumPoints;i++)
	{
		geFloat	dot;

		dot	=geVec3d_DotProduct(&f->Points[i], ShearVec);
		geVec3d_MA(&f->Points[i], dot, ShearAxis, &f->Points[i]);
	}
	{
		geVec3d OldNormal = f->Tex.VecNormal;
		Face_SetPlaneFromFace(f);
		Face_UpdateFaceAngle (f, &OldNormal);
	}
	f->Tex.DirtyFlag = GE_TRUE;
}

void	Face_GetBounds(const Face *f, Box3d *b)
{
	int i;

	assert(f != NULL);
	assert(b != NULL);

	Box3d_SetBogusBounds(b);
	for(i=0;i < f->NumPoints;i++)
	{
		Box3d_AddPoint(b, f->Points[i].X, f->Points[i].Y, f->Points[i].Z);
	}
}

void	Face_GetCenter(const Face *f, geVec3d *pCenter)
{
	Box3d Box;

	assert(f != NULL);
	assert(pCenter != NULL);

	Face_GetBounds(f, &Box);
	Box3d_GetCenter(&Box, pCenter);
}

void	Face_WriteToMap(const Face *f, FILE *wf)
{
	char	szTemp[_MAX_PATH];
	
	assert(f);
	assert(wf);

	{
		int OutputFlags;

		OutputFlags = 0;
		if (f->Flags & FACE_MIRROR)		OutputFlags	|= ffMirror;
		if (f->Flags & FACE_FULLBRIGHT) OutputFlags	|= ffFullBright;
		if (f->Flags & FACE_SKY)		OutputFlags	|= ffSky;
		if (f->Flags & FACE_LIGHT)		OutputFlags	|= ffLight;
		if (f->Flags & FACE_GOURAUD)	OutputFlags	|= ffGouraud;
		if (f->Flags & FACE_FLAT)		OutputFlags	|= ffFlat;
		if (f->Flags & FACE_TRANSPARENT) OutputFlags |= ffTranslucent;
		TypeIO_WriteInt(wf, OutputFlags);
	}

	TypeIO_WriteFloat (wf, f->MipMapBias);
	TypeIO_WriteFloat (wf, f->Translucency);
	TypeIO_WriteFloat (wf, (geFloat)f->LightIntensity);	//engine expects float
	TypeIO_WriteFloat (wf, f->Reflectivity);

	strcpy(szTemp, Face_GetTextureName (f));
	TypeIO_WriteBlock(wf, szTemp, 32);
	{
		#pragma message ("New texture vector output!")
		const TexInfo_Vectors *TVecs = Face_GetTextureVecs (f);
		geVec3d uVec, vVec;
		const geFloat xScale = f->Tex.xScale/f->LightXScale;
		const geFloat yScale = f->Tex.yScale/f->LightYScale;

		/*
		  The texture vectors returned have the entire scale value
		  included.  We need to back out the scale and use the
		  LightScale instead.  The Scale values that we send to
		  the tools will be Scale/LightScale.
		*/
		// Back out original scale and scale by LightScale
		geVec3d_Scale (&TVecs->uVec, xScale, &uVec);
		geVec3d_Scale (&TVecs->vVec, yScale, &vVec);

		// u vector, scale, offset
		TypeIO_WriteVec3d (wf, &uVec);
		TypeIO_WriteFloat (wf, xScale);
		TypeIO_WriteFloat (wf, TVecs->uOffset);

		// v vector, scale, offset
		TypeIO_WriteVec3d (wf, &vVec);
		TypeIO_WriteFloat (wf, yScale);
		TypeIO_WriteFloat (wf, TVecs->vOffset);
	}

	TypeIO_WriteBlock (wf, &f->Face_Plane, sizeof (Plane));
}

void	Face_WriteToQuakeMap(const Face *f, FILE *wf)
{
	int		xShift, yShift;
	geFloat	xScale, yScale, Rotate;
	
	assert(f);
	assert(wf);

	fprintf(wf, "( %f %f %f ) ",
		(f->Points[0].X),
		-(f->Points[0].Z),
		(f->Points[0].Y));
	fprintf(wf, "( %f %f %f ) ",
		(f->Points[1].X),
		-(f->Points[1].Z),
		(f->Points[1].Y));
	fprintf(wf, "( %f %f %f ) ",
		(f->Points[2].X),
		-(f->Points[2].Z),
		(f->Points[2].Y));

	Face_GetTextureShift (f, &xShift, &yShift);
	Face_GetTextureScale (f, &xScale, &yScale);
	Rotate	= Face_GetTextureRotate (f);

	fprintf(wf, Face_GetTextureName (f));
	fprintf(wf, " %d %d %d %f %f\n", Rotate, xShift, yShift, xScale, yScale);
}

geBoolean Face_Write(const Face *f, FILE *wf)
{
	int		i, xShift, yShift, Rotate;
	geFloat xScale, yScale, rot;

	assert(f);
	assert(wf);

	if (fprintf(wf, "\t\tNumPoints %d\n", f->NumPoints) < 0) return GE_FALSE;
	if (fprintf(wf, "\t\tFlags %d\n", f->Flags) < 0) return GE_FALSE;
	if (fprintf(wf, "\t\tLight %d\n", f->LightIntensity) < 0) return GE_FALSE;
	if (fprintf(wf, "\t\tMipMapBias %f\n", f->MipMapBias) < 0) return GE_FALSE;
	if (fprintf(wf, "\t\tTranslucency %f\n", f->Translucency) < 0) return GE_FALSE;
	if (fprintf(wf, "\t\tReflectivity %f\n", f->Reflectivity) < 0) return GE_FALSE;

	for(i=0;i < f->NumPoints;i++)
	{
		if (fprintf(wf, "\t\t\tVec3d %f %f %f\n", f->Points[i].X, f->Points[i].Y, f->Points[i].Z) < 0) return GE_FALSE;
	}

	Face_GetTextureShift (f, &xShift, &yShift);
	Face_GetTextureScale (f, &xScale, &yScale);
	rot		=Face_GetTextureRotate (f);
	Rotate	=Units_Round(rot);

	{
		char QuotedValue[SCANNER_MAXDATA];

		// Quote the texture name
		Util_QuoteString (Face_GetTextureName (f), QuotedValue);
		if (fprintf(wf, "\t\t\tTexInfo Rotate %d Shift %d %d Scale %f %f Name %s\n",
			Rotate, xShift, yShift, xScale, yScale, QuotedValue) < 0) return GE_FALSE;
	}

	if (fprintf(wf, "\t\tLightScale %f %f\n", f->LightXScale, f->LightYScale) < 0) return GE_FALSE;

	if (fprintf (wf, "%s", "\tTransform\t") < 0) return GE_FALSE;	
	if (!TypeIO_WriteXForm3dText (wf, &(f->Tex.XfmFaceAngle))) return GE_FALSE;

	if (fprintf (wf, "%s", "\tPos\t") < 0) return GE_FALSE;	
	if( !TypeIO_WriteVec3dText(wf, &f->Tex.Pos )) return GE_FALSE;

	return GE_TRUE;
}

Face	*Face_CreateFromFile
	(
	  Parse3dt *Parser, 
	  int VersionMajor, 
	  int VersionMinor, 
	  const char **Expected
	)
{
	Face	*f = NULL;
	int		i, flg, NumPnts, xShift, yShift, tempint, Light;
	geFloat MipMapBias, Reflectivity, Translucency;
	geFloat	fVal, xScale, yScale;
	geVec3d	*tmpPnts = NULL;
	geBoolean LoadResult;
	char	szTemp[_MAX_PATH];

	assert(Parser != NULL);

	LoadResult = GE_FALSE;
	if (!Parse3dt_GetInt (Parser, (*Expected = "NumPoints"), &NumPnts)) goto DoneLoad;

	// read face flags and value...
	if((VersionMajor == 1) && (VersionMinor < 8))
	{
		fVal=0.0f;
		flg	=0;
	}
	else
	{
		if (!Parse3dt_GetInt (Parser, (*Expected = "Flags"), &flg)) goto DoneLoad;
		if ((VersionMajor == 1) && (VersionMinor < 25))
		{
			if (!Parse3dt_GetFloat (Parser, (*Expected = "FaceValue"), &fVal)) goto DoneLoad;
			// FaceValue is ignored
			fVal	=0.0f;
		}
	}
	//xlate old flags
	if ((VersionMajor == 1) && (VersionMinor < 13))
	{
		int	flg2	=0;
		if(flg	&	oldLIGHT)		flg2	|=	FACE_LIGHT;
		if(flg	&	oldMIRROR)		flg2	|=	FACE_MIRROR;
		if(flg	&	oldFULLBRIGHT)	flg2	|=	FACE_FULLBRIGHT;
		if(flg	&	oldSKY)			flg2	|=	FACE_SKY;
		flg	=flg2;
	}

	// clear previously unused flag values
	if ((VersionMajor == 1) && (VersionMinor <= 10))
	{
		flg  &= ~(FACE_MIRROR | FACE_FULLBRIGHT | FACE_SKY);
	}
	if ((VersionMajor == 1) && (VersionMinor < 25))
	{
		// clear previously unused shading values
		flg &= ~(FACE_GOURAUD | FACE_FLAT);
	}
	if ((VersionMajor == 1) && (VersionMinor < 30))
	{
		flg &= ~FACE_TRANSPARENT;
	}

	// don't allow selected faces on load
	flg &= ~FACE_SELECTED;

	if ((VersionMajor > 1) || ((VersionMajor == 1) && (VersionMinor >= 13)))
	{
		if (!Parse3dt_GetInt (Parser, (*Expected = "Light"), &Light)) goto DoneLoad;
	}
	else
	{
		Light = FACE_DEFAULT_LIGHT;
	}

	if ((VersionMajor > 1) || ((VersionMajor == 1) && (VersionMinor >= 25)))
	{
		if (!Parse3dt_GetFloat (Parser, (*Expected = "MipMapBias"), &MipMapBias)) goto DoneLoad;
	}
	else
	{
		MipMapBias = FACE_DEFAULT_BIAS;
	}
	if ((VersionMajor > 1) || ((VersionMajor == 1) && (VersionMinor >= 27)))
	{
		if (!Parse3dt_GetFloat (Parser, (*Expected = "Translucency"), &Translucency)) goto DoneLoad;
		if (!Parse3dt_GetFloat (Parser, (*Expected = "Reflectivity"), &Reflectivity)) goto DoneLoad;
	}
	else
	{
		Translucency = FACE_DEFAULT_TRANSLUCENCY;
		Reflectivity = FACE_DEFAULT_REFLECTIVITY;
	}

	tmpPnts	= (geVec3d*)geRam_Allocate(sizeof(geVec3d) * NumPnts);
	if(tmpPnts)
	{
		geFloat	LightXScale = 1.0f;
		geFloat LightYScale = 1.0f;
		if((VersionMajor == 1) && (VersionMinor < 4))
		{
			/*
			  From version 1.3 to 1.4 we changed back to a right-handed coordinate system.
			  So, to load a 1.3 or earlier file, we need to reverse the windings
			  and flip the Z on every point.
			*/
			for(i=NumPnts-1;i >= 0;i--)
			{
				if (!Parse3dt_GetVec3d (Parser, (*Expected = "Vec3d"), &tmpPnts[i])) goto DoneLoad;

				//flip z
				tmpPnts[i].Z	=-tmpPnts[i].Z;
			}
		}
		else
		{
			for(i=0;i < NumPnts;i++)
			{
				if (!Parse3dt_GetVec3d (Parser, (*Expected = "Vec3d"), &tmpPnts[i])) goto DoneLoad;
			}
		}
		f	=Face_Create(NumPnts, tmpPnts, 0);
		geRam_Free (tmpPnts);
		tmpPnts = NULL;

		if(f)
		{
			f->Flags	=flg;
			f->LightIntensity = Light;
			f->MipMapBias = MipMapBias;
			f->Reflectivity = Reflectivity;
			f->Translucency = Translucency;
		}
		if (!Parse3dt_ScanExpectingText (Parser, (*Expected = "TexInfo"))) goto DoneLoad;
		if (!Parse3dt_GetInt (Parser, (*Expected = "Rotate"), &tempint)) goto DoneLoad;
		if (!Parse3dt_GetInt (Parser, (*Expected = "Shift"), &xShift)) goto DoneLoad;
		if (!Parse3dt_GetInt (Parser, NULL, &yShift)) goto DoneLoad;
		if (!Parse3dt_GetFloat (Parser, (*Expected = "Scale"), &xScale)) goto DoneLoad;
		if (!Parse3dt_GetFloat (Parser, NULL, &yScale)) goto DoneLoad;
		if((VersionMajor > 1) || ((VersionMajor == 1) && (VersionMinor >= 24)))
		{
			// Version 1.24 and later we quote the texture names
			if (!Parse3dt_GetLiteral (Parser, (*Expected = "Name"), szTemp)) goto DoneLoad;
		}
		else
		{	
			if (!Parse3dt_GetIdentifier (Parser, (*Expected = "Name"), szTemp)) goto DoneLoad;
		}

		if (!((VersionMajor == 1) && (VersionMinor <= 16)))
		{
			if (!Parse3dt_GetFloat (Parser, (*Expected = "LightScale"), &LightXScale)) goto DoneLoad;
			if (!Parse3dt_GetFloat (Parser, NULL, &LightYScale)) goto DoneLoad;
		}
		if(f)
		{
			Face_InitTexInfo(&f->Tex, &f->Face_Plane.Normal);

			Face_SetTextureName (f, szTemp);
			Face_SetTextureRotate (f, (geFloat)tempint);
			Face_SetTextureShift (f, xShift, yShift);
			Face_SetTextureScale (f, xScale, yScale);
			Face_SetTexturePos (f);

			if ((VersionMajor == 1) && (VersionMinor <= 16))
			{
				f->LightXScale = xScale;
				f->LightYScale = yScale;
			}
			else
			{
				f->LightXScale = LightXScale;
				f->LightYScale = LightYScale;
			}
			if((VersionMajor == 1) && (VersionMinor < 29))
			{
				Face_SetVisible(f, GE_TRUE);
			}
			if (((VersionMajor == 1) && (VersionMinor > 31)))
			{
				if (!Parse3dt_GetXForm3d (Parser, (*Expected = "Transform"), &f->Tex.XfmFaceAngle)) goto DoneLoad;
				if (!Parse3dt_GetVec3d (Parser, (*Expected = "Pos"), &f->Tex.Pos)) goto DoneLoad;
			}
		}
		LoadResult = GE_TRUE;
	}
DoneLoad:
	if (LoadResult == GE_FALSE)
	{
		if (f != NULL)
		{
			Face_Destroy (&f);
		}
		if (tmpPnts != NULL)
		{
			geRam_Free (tmpPnts);
		}
	}
	return f;
}

void	Face_GetSplitInfo(const Face *f, const Plane *p, geFloat *dists, uint8 *sides, uint8 *cnt)
{
	int	i;

	assert(f);
	assert(dists);
	assert(sides);
	assert(cnt);

	cnt[0]=cnt[1]=cnt[2]=0;

	for(i=0;i < f->NumPoints;i++)
	{
		dists[i]=geVec3d_DotProduct(&f->Points[i], &p->Normal)-p->Dist;
		if(dists[i] > ON_EPSILON)
		{
			sides[i]=SIDE_FRONT;
		}
		else if(dists[i] < -ON_EPSILON)
		{
			sides[i]=SIDE_BACK;
		}
		else
		{
			sides[i]=SIDE_ON;
		}
		cnt[sides[i]]++;
	}
	sides[i]=sides[0];
	dists[i]=dists[0];
}

void	Face_Split(const Face	*f,		//original face
				   const Plane	*p,		//split plane
				   Face			**ff,	//front face (null)
				   Face			**bf,	//back face (null)
				   geFloat		*dists,	//plane dists per vert
				   uint8		*sides)	//plane sides per vert
{
	geVec3d	*p1, *p2, mid;
	int		nfp, nbp, i, j;
	geFloat	dot;

	assert(f);
	assert(p);
	assert(ff);
	assert(bf);
	assert(*ff==NULL);
	assert(*bf==NULL);
	assert(dists);
	assert(sides);

	p1	=f->Points;
	for(i=nfp=nbp=0;i < f->NumPoints;i++, p1++)
	{
		if(sides[i]==SIDE_ON)
		{
			geVec3d_Copy(p1, &spf[nfp]);
			geVec3d_Copy(p1, &spb[nbp]);
			nfp++;	nbp++;	//Dont ++ in params!
			continue;
		}
		if(sides[i]==SIDE_FRONT)
		{
			geVec3d_Copy(p1, &spf[nfp]);
			nfp++;
		}
		if(sides[i]==SIDE_BACK)
		{
			geVec3d_Copy(p1, &spb[nbp]);
			nbp++;
		}
		if(sides[i+1]==SIDE_ON || sides[i+1]==sides[i])
			continue;

		p2	=&f->Points[(i+1) % f->NumPoints];
		dot	=dists[i] / (dists[i]-dists[i+1]);
		for(j=0;j<3;j++)
		{
			if(VectorToSUB(p->Normal, j)==1)
			{
				VectorToSUB(mid, j)	=p->Dist;
			}
			else if(VectorToSUB(p->Normal, j)==-1)
			{
				VectorToSUB(mid, j)	=-p->Dist;
			}
			else
			{
				VectorToSUB(mid, j)	=VectorToSUB(*p1, j)+
					dot*(VectorToSUB(*p2, j)	-VectorToSUB(*p1, j));
			}
		}

		//split goes to both sides
		geVec3d_Copy(&mid, &spf[nfp]);
		nfp++;
		geVec3d_Copy(&mid, &spb[nbp]);
		nbp++;
	}
	*ff	=Face_Create(nfp, spf, 0);
	*bf	=Face_Create(nbp, spb, 0);

	if(*ff)
	{
		Face_CopyFaceInfo(f, *ff);
	}
	if(*bf)
	{
		Face_CopyFaceInfo(f, *bf);
	}
}

void	Face_Clip(Face *f, const Plane *p, geFloat *dists, uint8 *sides)
{
	geVec3d	*p1, *p2, mid;
	int		nfp, nbp, i, j;
	geFloat	dot;

	assert(f);
	assert(p);
	assert(dists);
	assert(sides);

	p1	=f->Points;
	for(i=nfp=nbp=0;i < f->NumPoints;i++, p1++)
	{
		if(sides[i]==SIDE_ON)
		{
			geVec3d_Copy(p1, &spb[nbp]);
			nbp++;
			continue;
		}
		if(sides[i]==SIDE_BACK)
		{
			geVec3d_Copy(p1, &spb[nbp]);
			nbp++;
		}
		if(sides[i+1]==SIDE_ON || sides[i+1]==sides[i])
			continue;

		p2	=&f->Points[(i+1) % f->NumPoints];
		dot	=dists[i] / (dists[i]-dists[i+1]);
		for(j=0;j<3;j++)
		{
			if(VectorToSUB(p->Normal, j)==1)
			{
				VectorToSUB(mid, j)	=p->Dist;
			}
			else if(VectorToSUB(p->Normal, j)==-1)
			{
				VectorToSUB(mid, j)	=-p->Dist;
			}
			else
			{
				VectorToSUB(mid, j)	=VectorToSUB(*p1, j)+
					dot*(VectorToSUB(*p2, j)	-VectorToSUB(*p1, j));
			}
		}
		geVec3d_Copy(&mid, &spb[nbp]);
		nbp++;
	}
	geRam_Free (f->Points);
	f->NumPoints	=nbp;
	f->Points		=(geVec3d *) geRam_Allocate(sizeof(geVec3d)*nbp);
	memcpy(f->Points, spb, sizeof(geVec3d)*nbp);
}

geFloat	Face_PlaneDistance(const Face *f, geVec3d *pos)
{
	assert(f);
	assert(pos);

	return	(geVec3d_DotProduct(&f->Face_Plane.Normal, pos)
				-f->Face_Plane.Dist);
}

void	Face_MostlyOnSide(const Face *f, const Plane *p, geFloat *max, int *side)
{
	int		i;
	geFloat	d;

	for(i=0;i < f->NumPoints;i++)
	{
		d	=geVec3d_DotProduct(&f->Points[i], &p->Normal) - p->Dist;
		if(d > *max)
		{
			*max	=d;
			*side	=SIDE_FRONT;
		}
		if(-d > *max)
		{
			*max	=-d;
			*side	=SIDE_BACK;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -