📄 face.cpp
字号:
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 + -