?? brush.cpp
字號:
while (pBrush != NULL)
{
BrushList_Remove (pList, pBrush);
Brush_Destroy(&pBrush);
pBrush = BrushList_GetNext (&bi);
}
}
Brush *BrushList_GetFirst
(
BrushList *pList,
BrushIterator *bi
)
{
if (pList == NULL) // post 0.55
{
MessageBox(NULL, "pList == NULL", "BrushList_GetFirst", MB_OK);
return NULL;
}
assert (pList != NULL);
assert (bi != NULL);
if (pList->First == NULL)
{
*bi = NULL;
}
else
{
*bi = pList->First->Next;
}
return pList->First;
}
Brush *BrushList_GetNext
(
BrushIterator *bi
)
{
assert (bi != NULL);
if (*bi == NULL)
{
return NULL;
}
else
{
Brush *b;
b = *bi;
*bi = (*bi)->Next;
return b;
}
}
Brush *BrushList_GetLast
(
BrushList *pList,
BrushIterator *bi
)
{
if (pList == NULL) // post 0.55
{
MessageBox(NULL, "pList == NULL", "BrushList_GetLast", MB_OK);
return NULL;
}
assert (pList != NULL);
assert (bi != NULL);
if (pList->Last == NULL)
{
*bi = NULL;
}
else
{
*bi = pList->Last->Prev;
}
return pList->Last;
}
Brush *BrushList_GetPrev
(
BrushIterator *bi
)
{
assert (bi != NULL);
if (*bi == NULL)
{
return NULL;
}
else
{
Brush *b;
b = *bi;
*bi = (*bi)->Prev;
return b;
}
}
int BrushList_Count
(
BrushList const *pList,
int CountFlags
)
{
int Count;
Brush *b;
// geBoolean bResult = GE_TRUE;
if (pList == NULL) // post 0.55
{
MessageBox(NULL, "pList == NULL", "BrushList_Count", MB_OK);
return 0;
}
assert (pList != NULL);
Count = 0;
b = pList->First;
while (b != NULL)
{
geBoolean CountIt;
switch (b->Type)
{
case BRUSH_MULTI :
CountIt = (CountFlags & BRUSH_COUNT_MULTI);
break;
case BRUSH_LEAF :
CountIt = (CountFlags & BRUSH_COUNT_LEAF);
break;
case BRUSH_CSG :
CountIt = (CountFlags & BRUSH_COUNT_CSG);
break;
default :
assert (0);
CountIt = GE_FALSE;
break;
}
if (CountIt)
{
++Count;
}
if ((b->Type == BRUSH_MULTI) && (!(CountFlags & BRUSH_COUNT_NORECURSE)))
{
Count += BrushList_Count (b->BList, CountFlags);
}
b = b->Next;
}
return Count;
}
// call CallBack for top level brushes in the list...
geBoolean BrushList_Enum
(
BrushList const *pList,
void * lParam,
BrushList_CB CallBack
)
{
geBoolean bResult = GE_TRUE ; // TRUE means entire list was processed
Brush * b;
if (pList == NULL) // post 0.55
{
MessageBox(NULL, "pList == NULL", "BrushList_Enum", MB_OK);
return GE_FALSE;
}
assert (pList != NULL);
b = pList->First;
while (b != NULL)
{
if( (bResult = CallBack( b, lParam )) == GE_FALSE )
break ;
b = b->Next;
}
return bResult ;
}
// call CallBack for all brushes in the list...
geBoolean BrushList_EnumAll
(
BrushList const *pList,
void * lParam,
BrushList_CB CallBack
)
{
geBoolean bResult = GE_TRUE ; // TRUE means entire list was processed
Brush * b;
if (pList == NULL) // post 0.55
{
MessageBox(NULL, "pList == NULL", "BrushList_EnumAll", MB_OK);
return GE_FALSE;
}
assert (pList != NULL);
b = pList->First;
while (b != NULL)
{
if( (bResult = CallBack( b, lParam )) == GE_FALSE )
break ;
if (b->Type == BRUSH_MULTI)
{
bResult = BrushList_EnumAll (b->BList, lParam, CallBack);
if (!bResult)
{
break;
}
}
b = b->Next;
}
return bResult ;
}
//traverses inorder
int BrushList_EnumLeafBrushes(const BrushList *pList,
void * pVoid,
BrushList_CB CallBack)
{
geBoolean bResult =GE_TRUE; // TRUE means entire list was processed
Brush *b;
if (pList == NULL) // post 0.55
{
MessageBox(NULL, "pList == NULL", "BrushList_EnumLeafBrushes", MB_OK);
return 0;
}
assert(pList != NULL);
for(b=pList->First;b;b=b->Next)
{
assert(b->Type!=BRUSH_CSG);
if(b->Type==BRUSH_MULTI)
{
if(!BrushList_EnumLeafBrushes(b->BList, pVoid, CallBack))
{
break;
}
}
else if( (bResult = CallBack( b, pVoid )) == GE_FALSE )
{
break;
}
}
return bResult ;
}
//grabs csg brushes and leafs with no children
//the exception being hollows which are all based
//on a parent multi and might contain a hollowcut
int BrushList_EnumCSGBrushes(const BrushList *pList,
void * pVoid,
BrushList_CB CallBack)
{
geBoolean bResult =GE_TRUE; // TRUE means entire list was processed
Brush *b;
assert(pList != NULL);
for(b=pList->First;b && bResult;b=b->Next)
{
switch (b->Type)
{
case BRUSH_MULTI :
bResult = BrushList_EnumCSGBrushes (b->BList, pVoid, CallBack);
break;
case BRUSH_LEAF :
if (b->BList)
{
bResult = BrushList_EnumCSGBrushes (b->BList, pVoid, CallBack);
}
else
{
if(!(b->Flags & (BRUSH_HOLLOW | BRUSH_HOLLOWCUT)))
{
bResult = CallBack (b, pVoid);
}
}
break;
case BRUSH_CSG :
bResult = CallBack (b, pVoid);
break;
default :
assert (0); // bad brush type
bResult = GE_FALSE;
break;
}
}
return bResult ;
}
geBoolean Brush_GetParent(const BrushList *pList, //list to search
const Brush *b, //brush to find
Brush **bParent) //parent returned
{
Brush *b2;
assert(b);
assert(pList);
assert(bParent);
for(b2=pList->First;b2;b2=b2->Next)
{
if(b2==b)
{
*bParent =(Brush *)b; //const override!
return GE_TRUE;
}
if(b2->Type==BRUSH_LEAF)
{
if(b2->BList)
{
if(Brush_GetParent(b2->BList, b, bParent))
{
*bParent =b2;
return GE_TRUE;
}
}
}
else if(b2->Type==BRUSH_MULTI)
{
if(Brush_GetParent(b2->BList, b, bParent))
{
*bParent =b2;
return GE_TRUE;
}
}
}
return GE_FALSE;
}
Brush * Brush_GetTopLevelParent
(
const BrushList *pList, //list to search
const Brush *b //brush to find
)
{
Brush const *bWork;
Brush *pImmediateParent;
bWork = b;
while (Brush_GetParent (pList, bWork, &pImmediateParent) == GE_TRUE)
{
if (bWork == pImmediateParent)
{
break;
}
bWork = pImmediateParent;
}
return (Brush *)bWork;
}
static geBoolean Brush_SelectMatchingFace(Brush *b, Face *f, Face **pMatchingFace)
{
Face *f2;
const Plane *p, *p2;
int i;
assert(b);
p =Face_GetPlane(f);
for(i=0;i < FaceList_GetNumFaces(b->Faces);i++)
{
f2 =FaceList_GetFace(b->Faces, i);
p2 =Face_GetPlane(f2);
if(b->Flags & BRUSH_SUBTRACT)
{
geVec3d InvNorm =p2->Normal;
geVec3d_Inverse(&InvNorm);
if(geVec3d_Compare(&p->Normal, &InvNorm, 0.01f))
{
if(((p->Dist + p2->Dist) > -0.01f)&&((p->Dist + p2->Dist) < 0.01f))
{
Face_SetSelected(f2, GE_TRUE);
*pMatchingFace = f2;
return GE_TRUE;
}
}
}
else
{
if(geVec3d_Compare(&p->Normal, &p2->Normal, 0.01f))
{
if(((p->Dist - p2->Dist) > -0.01f)&&((p->Dist - p2->Dist) < 0.01f))
{
Face_SetSelected(f2, GE_TRUE);
*pMatchingFace = f2;
return GE_TRUE;
}
}
}
}
return GE_FALSE;
}
static geBoolean BrushList_SelectMatchingCutFace
(
const BrushList *pList,
const Brush *b,
Face *f,
Brush **CutBrush,
Face **pMatchingFace
)
{
Brush *cb;
assert(b);
assert(CutBrush);
assert(pList);
assert(f);
if(b->Type==BRUSH_LEAF)
{
for(cb=pList->Last;cb;cb=cb->Prev)
{
if(cb==b)
{
break;
}
if(Brush_TestBoundsIntersect(b, &cb->BoundingBox))
{
if(cb->Type==BRUSH_MULTI)
{
if(BrushList_SelectMatchingCutFace(cb->BList, b, f, CutBrush, pMatchingFace))
{
return GE_TRUE;
}
}
else if(cb->Flags & BRUSH_SUBTRACT)
{
if(Brush_SelectMatchingFace(cb, f, pMatchingFace))
{
*CutBrush =cb;
return GE_TRUE;
}
}
}
}
}
return GE_FALSE;
}
Brush * BrushList_FindFaceParent (const BrushList *pList, const Face *pFace)
{
Brush *pBrush;
for (pBrush = pList->First; pBrush != NULL; pBrush = pBrush->Next)
{
switch (pBrush->Type)
{
case BRUSH_MULTI :
{
Brush *pFound;
pFound = BrushList_FindFaceParent (pBrush->BList, pFace);
if (pFound != NULL)
{
return pFound;
}
break;
}
case BRUSH_LEAF :
case BRUSH_CSG :
{
int i;
for(i=0;i < Brush_GetNumFaces(pBrush);i++)
{
Face *pCheckFace;
pCheckFace = Brush_GetFace (pBrush, i);
if (pFace == pCheckFace)
{
return pBrush;
}
}
break;;
}
default :
assert (0);
break;
}
}
return NULL;
}
Brush * BrushList_FindTopLevelFaceParent (const BrushList *pList, const Face *pFace)
{
Brush *bFound;
bFound = BrushList_FindFaceParent (pList, pFace);
if (bFound != NULL)
{
bFound = Brush_GetTopLevelParent (pList, bFound);
}
return bFound;
}
static geFloat dists[256];
static uint8 sides[256];
static uint8 fsides[256];
enum SideFlags
{
SIDE_FRONT =0,
SIDE_BACK =1,
SIDE_ON =2,
SIDE_SPLIT =3
};
//handle cases where two brushes share a coplanar face
static int Brush_MostlyOnSide(const Brush *b, const Plane *p)
{
int i, side;
geFloat max;
max =0;
side =SIDE_FRONT;
for(i=0;i < FaceList_GetNumFaces(b->Faces);i++)
{
Face_MostlyOnSide(FaceList_GetFace(b->Faces, i), p, &max, &side);
}
return side;
}
//Split the original brush by the face passed in returning
//the brush in front of and the brush behind the
//face passed in.
//front and back brush pointers should be null on entry
void Brush_SplitByFace(Brush *ogb, //original brush
Face *sf, //split face
Brush **fb, //front brush
Brush **bb) //back brush
{
const Plane *p;
int i;
uint8 cnt[3], fcnt[4];
FaceList *fl, *bl;
const Face *f;
Face *cpf, *ff, *bf, *midf;
geBoolean WasSplit =GE_FALSE;
assert(ogb);
assert
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -