📄 face.cpp
字号:
t->TVecs.uOffset = (float)(t->xShift - uOffset);
t->TVecs.vOffset = (float)(t->yShift - vOffset);
}
}
static void Face_UpdateWorldTextureVecs
(
Face *f
)
{
geFloat ang, sinv, cosv;
geVec3d uVec, vVec;
int WhichAxis;
TexInfo *t = &f->Tex;
assert (t != NULL);
// assert (t->xScale != 0.0f);
// assert (t->yScale != 0.0f);
#pragma message ("this is an ugly hack. Values should never be == 0.")
if (t->xScale == 0.0f) t->xScale = 1.0f;
if (t->yScale == 0.0f) t->yScale = 1.0f;
ang = UNITS_DEGREES_TO_RADIANS (-t->Rotate);
sinv = (geFloat)sin(ang);
cosv = (geFloat)cos(ang);
// the normal has to be normal, no?
assert ((t->VecNormal.X != 0.0f) ||
(t->VecNormal.Y != 0.0f) ||
(t->VecNormal.Z != 0.0f));
// Must check x, y, z in order to match tools.
WhichAxis = 0;
if (fabs (t->VecNormal.Y) > fabs (t->VecNormal.X))
{
if (fabs (t->VecNormal.Z) > fabs (t->VecNormal.Y))
{
WhichAxis = 2;
}
else
{
WhichAxis = 1;
}
}
else if (fabs (t->VecNormal.Z) > fabs (t->VecNormal.X))
{
WhichAxis = 2;
}
switch (WhichAxis)
{
case 0:
geVec3d_Set (&uVec, 0.0f, sinv, cosv);
geVec3d_Set (&vVec, 0.0f, -cosv, sinv);
break;
case 1:
geVec3d_Set (&uVec, cosv, 0.0f, sinv);
geVec3d_Set (&vVec, -sinv, 0.0f, cosv);
break;
case 2:
geVec3d_Set (&uVec, cosv, sinv, 0.0f);
geVec3d_Set (&vVec, sinv, -cosv, 0.0f);
break;
}
//version 1.10 now has a one to one unit to texel ratio
t->TVecs.uOffset = (geFloat)(t->xShift);
t->TVecs.vOffset = (geFloat)(t->yShift);
geVec3d_Scale(&uVec, (1.0f/t->xScale), &t->TVecs.uVec);
geVec3d_Scale(&vVec, (1.0f/t->yScale), &t->TVecs.vVec);
}
static void Face_UpdateTextureVecs
(
Face *f
)
{
if (Face_IsTextureLocked (f))
{
Face_UpdateLockedTextureVecs (f);
}
else
{
Face_UpdateWorldTextureVecs (f);
}
}
const TexInfo_Vectors *Face_GetTextureVecs(const Face *f)
{
assert(f != NULL);
// if info has been changed then we have to re-calculate the vecs...
if (f->Tex.DirtyFlag)
{
//make sure the texinfos plane and vecs are good
Face_SetPlaneFromFace((Face *)f);
// The cast is kinda ugly, but we really want the parameter
// to this function to be const!
// mutable would be nice here, huh?
Face_UpdateTextureVecs ((Face *)f);
((Face *)f)->Tex.DirtyFlag = GE_FALSE;
}
return &(f->Tex.TVecs);
}
int Face_GetTextureDibId(const Face *f)
{
assert(f != NULL);
return f->Tex.Dib;
}
char const *Face_GetTextureName(const Face *f)
{
assert(f != NULL);
return f->Tex.Name;
}
geFloat Face_GetMipMapBias(const Face *f)
{
assert (f != NULL);
return f->MipMapBias;
}
geFloat Face_GetTranslucency(const Face *f)
{
assert (f != NULL);
return f->Translucency;
}
geFloat Face_GetReflectivity(const Face *f)
{
assert (f != NULL);
return f->Reflectivity;
}
//check flags
geBoolean Face_IsSelected(const Face *f)
{
assert(f != NULL);
return (f->Flags & FACE_SELECTED)? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsFixedHull(const Face *f)
{
assert(f != NULL);
return (f->Flags & FACE_FIXEDHULL)? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsLight(const Face *f)
{
assert(f != NULL);
return (f->Flags & FACE_LIGHT)? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsMirror(const Face *f)
{
assert(f != NULL);
return (f->Flags & FACE_MIRROR)? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsFullBright(const Face *f)
{
assert(f != NULL);
return (f->Flags & FACE_FULLBRIGHT)? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsSky(const Face *f)
{
assert(f != NULL);
return (f->Flags & FACE_SKY)? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsGouraud(const Face *f)
{
assert(f != NULL);
return (f->Flags & FACE_GOURAUD)? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsFlat(const Face *f)
{
assert(f != NULL);
return (f->Flags & FACE_FLAT)? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsTextureLocked (const Face *f)
{
return (f->Flags & FACE_TEXTURELOCKED) ? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsVisible (const Face *f)
{
return (f->Flags & FACE_VISIBLE) ? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsSheet (const Face *f)
{
return (f->Flags & FACE_SHEET) ? GE_TRUE : GE_FALSE;
}
geBoolean Face_IsTransparent (const Face *f)
{
return (f->Flags & FACE_TRANSPARENT) ? GE_TRUE : GE_FALSE;
}
void Face_SetSelected(Face *f, const geBoolean bState)
{
assert(f != NULL);
f->Flags =(bState)? f->Flags|FACE_SELECTED : f->Flags&~FACE_SELECTED;
}
void Face_SetFixedHull(Face *f, const geBoolean bState)
{
assert(f != NULL);
f->Flags =(bState)? f->Flags|FACE_FIXEDHULL : f->Flags&~FACE_FIXEDHULL;
}
void Face_SetLight(Face *f, const geBoolean bState)
{
assert(f != NULL);
f->Flags =(bState)? f->Flags|FACE_LIGHT : f->Flags&~FACE_LIGHT;
}
void Face_SetMirror(Face *f, const geBoolean bState)
{
assert(f != NULL);
f->Flags =(bState)? f->Flags|FACE_MIRROR : f->Flags&~FACE_MIRROR;
}
void Face_SetSky(Face *f, const geBoolean bState)
{
assert(f != NULL);
f->Flags =(bState)? f->Flags|FACE_SKY : f->Flags&~FACE_SKY;
}
// Fullbright, flat, and gouraud are mutually exclusive
static void Face_SetShadingExclusive (Face *f, const int StateFlag)
{
// clear all face shading flags
f->Flags &= ~(FACE_FULLBRIGHT | FACE_GOURAUD | FACE_FLAT);
// set the desired flag
f->Flags |= StateFlag;
}
void Face_SetFullBright(Face *f, const geBoolean bState)
{
assert(f != NULL);
if (bState)
{
Face_SetShadingExclusive (f, FACE_FULLBRIGHT);
}
else
{
f->Flags &= ~FACE_FULLBRIGHT;
}
}
void Face_SetGouraud(Face *f, const geBoolean bState)
{
assert (f != NULL);
if (bState)
{
Face_SetShadingExclusive (f, FACE_GOURAUD);
}
else
{
f->Flags &= ~FACE_GOURAUD;
}
}
void Face_SetFlat(Face *f, const geBoolean bState)
{
assert (f != NULL);
if (bState)
{
Face_SetShadingExclusive (f, FACE_FLAT);
}
else
{
f->Flags &= ~FACE_FLAT;
}
}
void Face_SetTextureLock (Face *f, const geBoolean bState)
{
f->Flags = (bState) ? (f->Flags | FACE_TEXTURELOCKED) : (f->Flags & ~FACE_TEXTURELOCKED);
Face_InitFaceAngle( &f->Tex, &f->Face_Plane.Normal );
Face_SetTexturePos (f);
}
void Face_SetVisible (Face *f, const geBoolean bState)
{
f->Flags = (bState) ? (f->Flags | FACE_VISIBLE) : (f->Flags & ~FACE_VISIBLE);
}
void Face_SetSheet (Face *f, const geBoolean bState)
{
f->Flags = (bState) ? (f->Flags | FACE_SHEET) : (f->Flags & ~FACE_SHEET);
}
void Face_SetTransparent (Face *f, const geBoolean bState)
{
f->Flags = (bState) ? (f->Flags | FACE_TRANSPARENT) : (f->Flags & ~FACE_TRANSPARENT);
}
void Face_SetLightIntensity(Face *f, const int Value)
{
assert (f != NULL);
f->LightIntensity = Value;
}
void Face_SetLightScale(Face *f, const geFloat xScale, const geFloat yScale)
{
assert (f != NULL);
f->LightXScale = xScale;
f->LightYScale = yScale;
}
void Face_SetTextureScale(Face *f, const geFloat xScale, const geFloat yScale)
{
assert(f != NULL);
f->Tex.xScale = xScale;
f->Tex.yScale = yScale;
f->Tex.DirtyFlag = GE_TRUE;
}
void Face_SetTextureShift(Face *f, const int xShift, const int yShift)
{
assert(f != NULL);
f->Tex.xShift = xShift;
f->Tex.yShift = yShift;
f->Tex.DirtyFlag = GE_TRUE;
}
void Face_SetTextureRotate(Face *f, const geFloat Rotate)
{
assert(f != NULL);
f->Tex.Rotate = Rotate;
f->Tex.DirtyFlag = GE_TRUE;
}
void Face_SetTextureDibId(Face *f, const int Dib)
{
assert(f != NULL);
f->Tex.Dib = Dib;
}
void Face_SetTextureName(Face *f, const char *pName)
{
assert(f != NULL);
// copy the name (safely), and then nul-terminate
strncpy (f->Tex.Name, pName, sizeof (f->Tex.Name));
f->Tex.Name[sizeof (f->Tex.Name)-1] = '\0';
}
void Face_XfmTexture (Face *f, const geXForm3d *pXfm)
{
assert (f != NULL);
assert (pXfm != NULL);
geXForm3d_Multiply (pXfm, &f->Tex.XfmFaceAngle, &f->Tex.XfmFaceAngle);
}
void Face_SetTextureSize (Face *f, const int txSize, const int tySize)
{
assert (f != NULL);
f->Tex.txSize = txSize;
f->Tex.tySize = tySize;
}
void Face_SetMipMapBias (Face *f, const geFloat Bias)
{
assert (f != NULL);
f->MipMapBias = Bias;
}
void Face_SetTranslucency (Face *f, const geFloat trans)
{
assert (f != NULL);
f->Translucency = trans;
}
void Face_SetReflectivity (Face *f, const geFloat rscale)
{
assert (f != NULL);
f->Reflectivity = rscale;
}
void Face_CopyTexInfo(const Face *src, Face *dst)
{
assert(src);
assert(dst);
dst->Tex =src->Tex;
//make sure the texinfos plane and vecs are good
Face_SetPlaneFromFace(dst);
}
//copies texinfo, flags, light, value
void Face_CopyFaceInfo(const Face *src, Face *dst)
{
assert(src);
assert(dst);
dst->Flags =src->Flags;
dst->LightIntensity =src->LightIntensity;
dst->MipMapBias =src->MipMapBias;
dst->Translucency =src->Translucency;
dst->Reflectivity =src->Reflectivity;
dst->Tex =src->Tex;
dst->LightXScale =src->LightXScale;
dst->LightYScale =src->LightYScale;
//make sure the texinfos plane and vecs are good
Face_SetPlaneFromFace(dst);
}
void Face_Rotate(Face *f, const geXForm3d *pXfmRotate, const geVec3d *pCenter)
{
int i;
geVec3d *pPoint;
assert(f != NULL);
assert(pXfmRotate != NULL);
assert(pCenter != NULL);
for(i=0;i < f->NumPoints;i++)
{
pPoint =&f->Points[i];
geVec3d_Subtract(pPoint, pCenter, pPoint);
geXForm3d_Rotate(pXfmRotate, pPoint, pPoint);
geVec3d_Add(pPoint, pCenter, pPoint);
}
Face_SetPlaneFromFace(f);
Face_XfmTexture (f, pXfmRotate);
pPoint =&f->Tex.Pos;
geVec3d_Subtract(pPoint, pCenter, pPoint);
geXForm3d_Rotate(pXfmRotate, pPoint, pPoint);
geVec3d_Add(pPoint, pCenter, pPoint);
f->Tex.DirtyFlag = GE_TRUE;
}
void Face_Move(Face *f, const geVec3d *trans)
{
int i;
assert(f);
assert(trans);
for(i=0;i < f->NumPoints;i++)
{
geVec3d_Add(&f->Points[i], trans, &f->Points[i]);
}
Face_SetPlaneFromFace(f);
// Update position...
geVec3d_Add (&f->Tex.Pos, trans, &f->Tex.Pos);
f->Tex.DirtyFlag = GE_TRUE;
}
void Face_Transform(Face *f, const geXForm3d *pXfm)
{
int i;
assert(f != NULL);
assert(pXfm != NULL);
for(i=0;i < f->NumPoints;i++)
{
geXForm3d_Transform(pXfm, &f->Points[i], &f->Points[i]);
}
Face_SetPlaneFromFace(f);
Face_XfmTexture (f, pXfm);
f->Tex.DirtyFlag = GE_TRUE;
}
static void Face_UpdateFaceAngle (Face *f, const geVec3d *OldNormal)
/*
Compute rotation matrix from OldNormal to current normal (f->Tex.VecNormal),
and include that rotation in the XfmFaceAngle transform.
*/
{
geVec3d VecDest;
geVec3d VecAxis;
geFloat cosv, Theta;
geXForm3d Xfm;
// Compute rotation from
VecDest = f->Tex.VecNormal;
geVec3d_CrossProduct (&VecDest, OldNormal, &VecAxis);
cosv = geVec3d_DotProduct (&VecDest, OldNormal);
// Now here's an interesting twist.
// Due to floating point inaccuracies, the dot product of two supposedly
// normal vectors may result in a number larger than 1.0.
// If that happens, it's supposed to be 1.0, so we'll force it.
if (cosv > 1.0f)
{
cosv = 1.0f;
}
Theta = (geFloat)acos (cosv);
if (geVec3d_Normalize (&VecAxis) == 0.0f)
{
// If the resulting vector is 0 length,
// then a rotation about X will put us where we need to be.
geXForm3d_SetIdentity (&Xfm);
geXForm3d_RotateX (&Xfm, -Theta);
}
else
{
geQuaternion QRot;
geQuaternion_SetFromAxisAngle (&QRot, &VecAxis, -Theta);
geQuaternion_ToMatrix (&QRot, &Xfm);
}
// and include it in the face's rotation...
Face_XfmTexture (f, &Xfm);
}
void Face_Scale(Face *f, const geVec3d *ScaleVec)
{
int i;
assert(f);
assert(ScaleVec);
for(i=0;i < f->NumPoints;i++)
{
//no magnitude operation in vec3d
f->Points[i].X *=ScaleVec->X;
f->Points[i].Y *=ScaleVec->Y;
f->Points[i].Z *=ScaleVec->Z;
}
{
geVec3d OldNormal = f->Tex.VecNormal;
Face_SetPlaneFromFace(f);
Face_UpdateFaceAngle (f, &OldNormal);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -