home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
WD_SRC.ZIP
/
SOURCE
/
BSP.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-07
|
5KB
|
233 lines
#include "..\Source\LastWolf.hpp"
BOOL bsp_TraverseAndDrawTree( CLine *pRootLine )
{
// Get which side the player is on of pRootLine.
// Visit that side, pRootLine, then the opposite side.
CLine *pFirst, *pSecond;
CLine *pLeft, *pRight;
CLine *pDrawRoot;
SideDir pruneVal, viewSide;
// Test if it's possible to prune off a whole subtree (by not calling
// bsp_TraverseAndDrawTree()).
pruneVal = dr_PruneTree(pRootLine);
switch( pruneVal )
{
case LeftSide:
pLeft = NULL;
pRight = pRootLine->pRight;
break;
case RightSide:
pLeft = pRootLine->pLeft;
pRight = NULL;
break;
case Intersect:
pLeft = pRootLine->pLeft;
pRight = pRootLine->pRight;
break;
}
// Determine the order to draw the subtrees based on which side of
// pRootLine the player is on.
viewSide = bsp_PlayerSide(&player, pRootLine);
if( viewSide == LeftSide )
{
pFirst = pLeft;
pSecond = pRight;
pDrawRoot = pRootLine;
}
else
{
pFirst = pRight;
pSecond = pLeft;
pDrawRoot = pRootLine;
}
// Do the drawing.
if( pFirst != NULL )
if( bsp_TraverseAndDrawTree( pFirst ) == FALSE )
return FALSE;
if( pDrawRoot != NULL )
if( dr_DrawWall( pDrawRoot, viewSide ) == ScreenCompletelyDrawn )
return FALSE;
if( pSecond != NULL )
if( bsp_TraverseAndDrawTree( pSecond ) == FALSE )
return FALSE;
return TRUE;
}
SideDir bsp_PlayerSide( Player *pPlayer, CLine *pLine )
{
Angle lineAngle;
Fixed rotatedPlayerY;
lineAngle = GetAngle( pLine->pPoint1->localX, pLine->pPoint1->localY,
pLine->pPoint2->localX, pLine->pPoint2->localY );
lineAngle = (ANGLE_RES - lineAngle) & ANGLE_MASK;
// Rotate all of pToSplit's vertices *around* pMainLine's first Point.
RotatePointYOnly( pLine->pPoint1->localX, pLine->pPoint1->localY,
lineAngle, pPlayer->xPos, pPlayer->yPos,
&rotatedPlayerY );
if( UNFIX(rotatedPlayerY) >= pLine->pPoint1->localY )
return LeftSide;
else
return RightSide;
}
void RotatePointYOnly( DWORD xOrigin, DWORD yOrigin, Angle rotateAngle, DWORD pointX, DWORD pointY, Fixed *pDestY )
{
Fixed x, y;
x = pointX - xOrigin;
y = pointY - yOrigin;
*pDestY = (SAFE_SIN(rotateAngle) * x) + (SAFE_COS(rotateAngle) * y);
*pDestY += FIX(yOrigin);
}
void RotatePoint( DWORD xOrigin, DWORD yOrigin, Angle rotateAngle, DWORD pointX, DWORD pointY, Fixed *pDestX, Fixed *pDestY )
{
Fixed x, y;
x = pointX - xOrigin;
y = pointY - yOrigin;
*pDestX = (SAFE_COS(rotateAngle) * x) - (SAFE_SIN(rotateAngle) * y);
*pDestX += FIX(xOrigin);
*pDestY = (SAFE_SIN(rotateAngle) * x) + (SAFE_COS(rotateAngle) * y);
*pDestY += FIX(yOrigin);
}
void RotatePointFixed( Fixed xOrigin, Fixed yOrigin, Angle rotateAngle, Fixed pointX, Fixed pointY, Fixed *pDestX, Fixed *pDestY )
{
Fixed x, y;
x = pointX - xOrigin;
y = pointY - yOrigin;
*pDestX = FMul(SAFE_COS(rotateAngle), x) - FMul(SAFE_SIN(rotateAngle), y);
*pDestX += FIX(xOrigin);
*pDestY = FMul(SAFE_SIN(rotateAngle), x) + FMul(SAFE_COS(rotateAngle), y);
*pDestY += FIX(yOrigin);
}
Angle GetAngle( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
{
Fixed slope, slopeLookup;
Angle lookupAngle;
DWORD wholeX, wholeY;
BOOL yOnTop;
wholeX = x2 - x1;
wholeY = y2 - y1;
if( 0 == wholeX )
{
if( wholeY > 0 )
return HALF_PI;
else
return HALF_PI + PI;
}
else if( 0 == wholeY )
{
if( wholeX > 0 )
return 0;
else
return PI;
}
if( ABS(wholeX) > ABS(wholeY) )
yOnTop = TRUE;
else
yOnTop = FALSE;
if( yOnTop )
slope = FDiv( FIX(wholeY), FIX(wholeX) );
else
slope = FDiv( FIX(wholeX), FIX(wholeY) );
//slopeLookup = R_UNFIX( FMul(slope, FIX(ANGLE_RES-1)) );
slopeLookup = W_UNFIX( slope * (ANGLE_RES-1) );
if( slopeLookup < 0 )
lookupAngle = ATAN_TABLE[-slopeLookup];
else
lookupAngle = ATAN_TABLE[slopeLookup];
if( !yOnTop )
lookupAngle = (Angle)(HALF_PI - lookupAngle);
if( wholeX > 0 && wholeY < 0 )
return (CIRCLE - lookupAngle);
else if( wholeX < 0 && wholeY < 0 )
return (Angle)(PI + lookupAngle);
else if( wholeX < 0 && wholeY > 0 )
return (Angle)(PI - lookupAngle);
else if( wholeX > 0 && wholeY > 0 )
return (Angle)lookupAngle;
return lookupAngle;
}
SideDir bsp_PruneTree( CLine *pLine )
{
pLine=pLine;
return Intersect;
}
CLine *bsp_GetParentFromLine( CLine *pRootLine, CLine *pChildLine )
{
CLine *pRetVal;
if( pRootLine->pLeft == pChildLine || pRootLine->pRight == pChildLine )
return pRootLine;
else
{
if( pRootLine->pLeft != NULL )
{
pRetVal = bsp_GetParentFromLine( pRootLine->pLeft, pChildLine );
if( pRetVal != NULL )
return pRetVal;
}
if( pRootLine->pRight != NULL )
{
pRetVal = bsp_GetParentFromLine( pRootLine->pRight, pChildLine );
if( pRetVal != NULL )
return pRetVal;
}
}
return NULL;
}