
Source code release, imported from: https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code All text files were converted to Unix format.
1275 lines
No EOL
38 KiB
C
1275 lines
No EOL
38 KiB
C
/*
|
|
* KJL 15:13:43 7/17/97 - frustrum.c
|
|
*
|
|
* Contains all the functions connected
|
|
* to the view frustrum and clipping
|
|
*
|
|
*/
|
|
#include "3dc.h"
|
|
#include "module.h"
|
|
#include "inline.h"
|
|
|
|
#include "stratdef.h"
|
|
#include "gamedef.h"
|
|
|
|
#include "kshape.h"
|
|
#include "kzsort.h"
|
|
#include "frustrum.h"
|
|
|
|
#include "particle.h"
|
|
|
|
#define UseLocalAssert Yes
|
|
#include "ourasert.h"
|
|
|
|
/*KJL****************************************************************************************
|
|
* G L O B A L S *
|
|
****************************************************************************************KJL*/
|
|
extern VECTORCH RotatedPts[];
|
|
|
|
extern DISPLAYBLOCK *Global_ODB_Ptr;
|
|
extern SHAPEHEADER *Global_ShapeHeaderPtr;
|
|
extern int *Global_ShapePoints;
|
|
extern int *Global_ShapeNormals;
|
|
|
|
extern VECTORCH LocalView;
|
|
|
|
#define FAR_Z_CLIP 0
|
|
#define FAR_Z_CLIP_RANGE 49000
|
|
/*KJL****************************************************************************************
|
|
* P R O T O T Y P E S *
|
|
****************************************************************************************KJL*/
|
|
/* GOURAUD POLYGON CLIPPING */
|
|
void (*GouraudPolygon_ClipWithNegativeX)(void);
|
|
void (*GouraudPolygon_ClipWithPositiveY)(void);
|
|
void (*GouraudPolygon_ClipWithNegativeY)(void);
|
|
void (*GouraudPolygon_ClipWithPositiveX)(void);
|
|
|
|
/* TEXTURED POLYGON CLIPPING */
|
|
void (*TexturedPolygon_ClipWithNegativeX)(void);
|
|
void (*TexturedPolygon_ClipWithPositiveY)(void);
|
|
void (*TexturedPolygon_ClipWithNegativeY)(void);
|
|
void (*TexturedPolygon_ClipWithPositiveX)(void);
|
|
|
|
/* GOURAUD TEXTURED POLYGON CLIPPING */
|
|
void (*GouraudTexturedPolygon_ClipWithNegativeX)(void);
|
|
void (*GouraudTexturedPolygon_ClipWithPositiveY)(void);
|
|
void (*GouraudTexturedPolygon_ClipWithNegativeY)(void);
|
|
void (*GouraudTexturedPolygon_ClipWithPositiveX)(void);
|
|
|
|
/* FRUSTRUM TESTS */
|
|
int (*ObjectWithinFrustrum)(DISPLAYBLOCK *dbPtr);
|
|
int (*ObjectCompletelyWithinFrustrum)(DISPLAYBLOCK *dbPtr);
|
|
int (*VertexWithinFrustrum)(RENDERVERTEX *vertexPtr);
|
|
void (*TestVerticesWithFrustrum)(void);
|
|
|
|
|
|
static void GouraudPolygon_Norm_ClipWithNegativeX(void);
|
|
static void GouraudPolygon_Wide_ClipWithNegativeX(void);
|
|
static void GouraudPolygon_Norm_ClipWithPositiveY(void);
|
|
static void GouraudPolygon_Wide_ClipWithPositiveY(void);
|
|
static void GouraudPolygon_Norm_ClipWithNegativeY(void);
|
|
static void GouraudPolygon_Wide_ClipWithNegativeY(void);
|
|
static void GouraudPolygon_Norm_ClipWithPositiveX(void);
|
|
static void GouraudPolygon_Wide_ClipWithPositiveX(void);
|
|
|
|
static void TexturedPolygon_Norm_ClipWithNegativeX(void);
|
|
static void TexturedPolygon_Wide_ClipWithNegativeX(void);
|
|
static void TexturedPolygon_Norm_ClipWithPositiveY(void);
|
|
static void TexturedPolygon_Wide_ClipWithPositiveY(void);
|
|
static void TexturedPolygon_Norm_ClipWithNegativeY(void);
|
|
static void TexturedPolygon_Wide_ClipWithNegativeY(void);
|
|
static void TexturedPolygon_Norm_ClipWithPositiveX(void);
|
|
static void TexturedPolygon_Wide_ClipWithPositiveX(void);
|
|
|
|
static void GouraudTexturedPolygon_Norm_ClipWithNegativeX(void);
|
|
static void GouraudTexturedPolygon_Wide_ClipWithNegativeX(void);
|
|
static void GouraudTexturedPolygon_Norm_ClipWithPositiveY(void);
|
|
static void GouraudTexturedPolygon_Wide_ClipWithPositiveY(void);
|
|
static void GouraudTexturedPolygon_Norm_ClipWithNegativeY(void);
|
|
static void GouraudTexturedPolygon_Wide_ClipWithNegativeY(void);
|
|
static void GouraudTexturedPolygon_Norm_ClipWithPositiveX(void);
|
|
static void GouraudTexturedPolygon_Wide_ClipWithPositiveX(void);
|
|
|
|
static int VertexWithin_Norm_Frustrum(RENDERVERTEX *vertexPtr);
|
|
static int VertexWithin_Wide_Frustrum(RENDERVERTEX *vertexPtr);
|
|
static int ObjectWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr);
|
|
static int ObjectWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr);
|
|
static int ObjectCompletelyWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr);
|
|
static int ObjectCompletelyWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr);
|
|
static void TestVerticesWith_Norm_Frustrum(void);
|
|
static void TestVerticesWith_Wide_Frustrum(void);
|
|
|
|
/*KJL****************************************************************************************
|
|
* F U N C T I O N S *
|
|
****************************************************************************************KJL*/
|
|
void SetFrustrumType(enum FrustrumType frustrumType)
|
|
{
|
|
switch (frustrumType)
|
|
{
|
|
default:
|
|
case FRUSTRUM_TYPE_NORMAL:
|
|
{
|
|
/* GOURAUD POLYGON CLIPPING */
|
|
GouraudPolygon_ClipWithNegativeX = GouraudPolygon_Norm_ClipWithNegativeX;
|
|
GouraudPolygon_ClipWithPositiveY = GouraudPolygon_Norm_ClipWithPositiveY;
|
|
GouraudPolygon_ClipWithNegativeY = GouraudPolygon_Norm_ClipWithNegativeY;
|
|
GouraudPolygon_ClipWithPositiveX = GouraudPolygon_Norm_ClipWithPositiveX;
|
|
|
|
/* TEXTURED POLYGON CLIPPING */
|
|
TexturedPolygon_ClipWithNegativeX = TexturedPolygon_Norm_ClipWithNegativeX;
|
|
TexturedPolygon_ClipWithPositiveY = TexturedPolygon_Norm_ClipWithPositiveY;
|
|
TexturedPolygon_ClipWithNegativeY = TexturedPolygon_Norm_ClipWithNegativeY;
|
|
TexturedPolygon_ClipWithPositiveX = TexturedPolygon_Norm_ClipWithPositiveX;
|
|
|
|
/* GOURAUD TEXTURED POLYGON CLIPPING */
|
|
GouraudTexturedPolygon_ClipWithNegativeX = GouraudTexturedPolygon_Norm_ClipWithNegativeX;
|
|
GouraudTexturedPolygon_ClipWithPositiveY = GouraudTexturedPolygon_Norm_ClipWithPositiveY;
|
|
GouraudTexturedPolygon_ClipWithNegativeY = GouraudTexturedPolygon_Norm_ClipWithNegativeY;
|
|
GouraudTexturedPolygon_ClipWithPositiveX = GouraudTexturedPolygon_Norm_ClipWithPositiveX;
|
|
|
|
/* FRUSTRUM TESTS */
|
|
TestVerticesWithFrustrum = TestVerticesWith_Norm_Frustrum;
|
|
ObjectWithinFrustrum = ObjectWithin_Norm_Frustrum;
|
|
ObjectCompletelyWithinFrustrum = ObjectCompletelyWithin_Norm_Frustrum;
|
|
VertexWithinFrustrum = VertexWithin_Norm_Frustrum;
|
|
|
|
break;
|
|
}
|
|
|
|
case FRUSTRUM_TYPE_WIDE:
|
|
{
|
|
/* GOURAUD POLYGON CLIPPING */
|
|
GouraudPolygon_ClipWithNegativeX = GouraudPolygon_Wide_ClipWithNegativeX;
|
|
GouraudPolygon_ClipWithPositiveY = GouraudPolygon_Wide_ClipWithPositiveY;
|
|
GouraudPolygon_ClipWithNegativeY = GouraudPolygon_Wide_ClipWithNegativeY;
|
|
GouraudPolygon_ClipWithPositiveX = GouraudPolygon_Wide_ClipWithPositiveX;
|
|
|
|
/* TEXTURED POLYGON CLIPPING */
|
|
TexturedPolygon_ClipWithNegativeX = TexturedPolygon_Wide_ClipWithNegativeX;
|
|
TexturedPolygon_ClipWithPositiveY = TexturedPolygon_Wide_ClipWithPositiveY;
|
|
TexturedPolygon_ClipWithNegativeY = TexturedPolygon_Wide_ClipWithNegativeY;
|
|
TexturedPolygon_ClipWithPositiveX = TexturedPolygon_Wide_ClipWithPositiveX;
|
|
|
|
/* GOURAUD TEXTURED POLYGON CLIPPING */
|
|
GouraudTexturedPolygon_ClipWithNegativeX = GouraudTexturedPolygon_Wide_ClipWithNegativeX;
|
|
GouraudTexturedPolygon_ClipWithPositiveY = GouraudTexturedPolygon_Wide_ClipWithPositiveY;
|
|
GouraudTexturedPolygon_ClipWithNegativeY = GouraudTexturedPolygon_Wide_ClipWithNegativeY;
|
|
GouraudTexturedPolygon_ClipWithPositiveX = GouraudTexturedPolygon_Wide_ClipWithPositiveX;
|
|
|
|
/* FRUSTRUM TESTS */
|
|
TestVerticesWithFrustrum = TestVerticesWith_Wide_Frustrum;
|
|
ObjectWithinFrustrum = ObjectWithin_Wide_Frustrum;
|
|
ObjectCompletelyWithinFrustrum = ObjectCompletelyWithin_Wide_Frustrum;
|
|
VertexWithinFrustrum = VertexWithin_Wide_Frustrum;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* clipping code macros - these are used as building blocks to assemble
|
|
clipping fns for different polygon types with the minimum of fuss */
|
|
#define ZCLIPPINGVALUE 4
|
|
//64
|
|
#define Clip_Z_Test(v) (ZCLIPPINGVALUE <= (v)->Z)
|
|
#define Clip_NX_Test(v) (-(v)->X <= (v)->Z)
|
|
#define Clip_PX_Test(v) ((v)->X <= (v)->Z)
|
|
#define Clip_NY_Test(v) (-(v)->Y <= (v)->Z)
|
|
#define Clip_PY_Test(v) ((v)->Y <= (v)->Z)
|
|
|
|
|
|
#define Clip_LoopStart(b) \
|
|
do \
|
|
{ \
|
|
RENDERVERTEX *nextVertexPtr; \
|
|
int nextVertexInside; \
|
|
\
|
|
/* setup pointer to next vertex, wrapping round if necessary */ \
|
|
if (!--verticesLeft) \
|
|
{ \
|
|
nextVertexPtr = (b); \
|
|
} \
|
|
else \
|
|
{ \
|
|
nextVertexPtr = curVertexPtr+1; \
|
|
} \
|
|
\
|
|
/* if current vertex is inside the plane, output it */ \
|
|
if (curVertexInside) \
|
|
{ \
|
|
numberOfPointsOutputted++; \
|
|
*outputVerticesPtr++ = *curVertexPtr; \
|
|
} \
|
|
\
|
|
/* test if next vertex is inside the plane */ \
|
|
nextVertexInside =
|
|
|
|
#define Clip_Z_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(ZCLIPPINGVALUE - curVertexPtr->Z), \
|
|
(nextVertexPtr->Z - curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
|
|
outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y); \
|
|
outputVerticesPtr->Z = ZCLIPPINGVALUE;
|
|
|
|
#define Clip_NX_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(curVertexPtr->Z + curVertexPtr->X), \
|
|
-(nextVertexPtr->X-curVertexPtr->X) - (nextVertexPtr->Z-curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
|
|
outputVerticesPtr->Z = -outputVerticesPtr->X; \
|
|
outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
|
|
|
|
#define Clip_PX_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(curVertexPtr->Z - curVertexPtr->X), \
|
|
(nextVertexPtr->X-curVertexPtr->X) - (nextVertexPtr->Z-curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
|
|
outputVerticesPtr->Z = outputVerticesPtr->X; \
|
|
outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
|
|
|
|
#define Clip_NY_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(curVertexPtr->Z + curVertexPtr->Y), \
|
|
-(nextVertexPtr->Y-curVertexPtr->Y) - (nextVertexPtr->Z-curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
|
|
outputVerticesPtr->Y = -(outputVerticesPtr->Z); \
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
|
|
|
|
#define Clip_PY_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(curVertexPtr->Z - curVertexPtr->Y), \
|
|
(nextVertexPtr->Y-curVertexPtr->Y) - (nextVertexPtr->Z-curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
|
|
outputVerticesPtr->Y = (outputVerticesPtr->Z); \
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
|
|
|
|
#define Clip_OutputUV \
|
|
outputVerticesPtr->U = curVertexPtr->U + MUL_FIXED(lambda,nextVertexPtr->U-curVertexPtr->U); \
|
|
outputVerticesPtr->V = curVertexPtr->V + MUL_FIXED(lambda,nextVertexPtr->V-curVertexPtr->V);
|
|
|
|
#define Clip_OutputI \
|
|
outputVerticesPtr->A = curVertexPtr->A + MUL_FIXED(lambda,nextVertexPtr->A-curVertexPtr->A); \
|
|
outputVerticesPtr->R = curVertexPtr->R + MUL_FIXED(lambda,nextVertexPtr->R-curVertexPtr->R); \
|
|
outputVerticesPtr->G = curVertexPtr->G + MUL_FIXED(lambda,nextVertexPtr->G-curVertexPtr->G); \
|
|
outputVerticesPtr->B = curVertexPtr->B + MUL_FIXED(lambda,nextVertexPtr->B-curVertexPtr->B); \
|
|
outputVerticesPtr->SpecularR = curVertexPtr->SpecularR + MUL_FIXED(lambda,nextVertexPtr->SpecularR-curVertexPtr->SpecularR); \
|
|
outputVerticesPtr->SpecularG = curVertexPtr->SpecularG + MUL_FIXED(lambda,nextVertexPtr->SpecularG-curVertexPtr->SpecularG); \
|
|
outputVerticesPtr->SpecularB = curVertexPtr->SpecularB + MUL_FIXED(lambda,nextVertexPtr->SpecularB-curVertexPtr->SpecularB);
|
|
|
|
#define Clip_LoopEnd(b) \
|
|
numberOfPointsOutputted++; \
|
|
outputVerticesPtr++; \
|
|
} \
|
|
\
|
|
/* okay, now the current vertex becomes what was the next vertex */ \
|
|
curVertexPtr = nextVertexPtr; \
|
|
curVertexInside = nextVertexInside; \
|
|
} \
|
|
while(verticesLeft); \
|
|
\
|
|
RenderPolygon.NumberOfVertices = numberOfPointsOutputted;
|
|
|
|
/* Wide screen versions of clip macros */
|
|
|
|
#define Clip_Wide_NX_Test(v) (-(v)->X <= (v)->Z*2)
|
|
#define Clip_Wide_PX_Test(v) ((v)->X <= (v)->Z*2)
|
|
#define Clip_Wide_NY_Test(v) (-(v)->Y <= (v)->Z*2)
|
|
#define Clip_Wide_PY_Test(v) ((v)->Y <= (v)->Z*2)
|
|
#define Clip_Wide_NX_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(-2*curVertexPtr->Z - curVertexPtr->X), \
|
|
(nextVertexPtr->X-curVertexPtr->X) - (-2)*(nextVertexPtr->Z-curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
|
|
outputVerticesPtr->Z = -outputVerticesPtr->X/2; \
|
|
outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
|
|
|
|
#define Clip_Wide_PX_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(2*curVertexPtr->Z - curVertexPtr->X), \
|
|
(nextVertexPtr->X-curVertexPtr->X) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
|
|
outputVerticesPtr->Z = outputVerticesPtr->X/2; \
|
|
outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
|
|
|
|
#define Clip_Wide_NY_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(2*curVertexPtr->Z + curVertexPtr->Y), \
|
|
-(nextVertexPtr->Y-curVertexPtr->Y) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
|
|
outputVerticesPtr->Y = -(outputVerticesPtr->Z*2); \
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
|
|
|
|
#define Clip_Wide_PY_OutputXYZ \
|
|
/* if one is in, and the other is out, output a clipped vertex */ \
|
|
if (nextVertexInside != curVertexInside) \
|
|
{ \
|
|
int lambda; \
|
|
\
|
|
lambda = DIV_FIXED \
|
|
( \
|
|
(2*curVertexPtr->Z - curVertexPtr->Y), \
|
|
(nextVertexPtr->Y-curVertexPtr->Y) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
|
|
); \
|
|
\
|
|
outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
|
|
outputVerticesPtr->Y = (outputVerticesPtr->Z*2); \
|
|
outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
|
|
|
|
|
|
/*KJL**************
|
|
* GOURAUD POLYGON *
|
|
**************KJL*/
|
|
|
|
/* Clip against Z plane */
|
|
void GouraudPolygon_ClipWithZ(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Z_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Z_Test(nextVertexPtr);
|
|
Clip_Z_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
|
|
/* Clip against negative X plane */
|
|
static void GouraudPolygon_Norm_ClipWithNegativeX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_NX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_NX_Test(nextVertexPtr);
|
|
Clip_NX_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
static void GouraudPolygon_Wide_ClipWithNegativeX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_Wide_NX_Test(nextVertexPtr);
|
|
Clip_Wide_NX_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
|
|
/* Clip against positive Y plane*/
|
|
static void GouraudPolygon_Norm_ClipWithPositiveY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_PY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_PY_Test(nextVertexPtr);
|
|
Clip_PY_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
static void GouraudPolygon_Wide_ClipWithPositiveY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Wide_PY_Test(nextVertexPtr);
|
|
Clip_Wide_PY_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
/* Clip against negative Y plane*/
|
|
static void GouraudPolygon_Norm_ClipWithNegativeY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_NY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_NY_Test(nextVertexPtr);
|
|
Clip_NY_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
static void GouraudPolygon_Wide_ClipWithNegativeY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_Wide_NY_Test(nextVertexPtr);
|
|
Clip_Wide_NY_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
|
|
/* Clip against positive X plane */
|
|
static void GouraudPolygon_Norm_ClipWithPositiveX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_PX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_PX_Test(nextVertexPtr);
|
|
Clip_PX_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
static void GouraudPolygon_Wide_ClipWithPositiveX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Wide_PX_Test(nextVertexPtr);
|
|
Clip_Wide_PX_OutputXYZ
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
/*KJL***************
|
|
* TEXTURED POLYGON *
|
|
***************KJL*/
|
|
|
|
/* Clip against Z plane */
|
|
void TexturedPolygon_ClipWithZ(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Z_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Z_Test(nextVertexPtr);
|
|
Clip_Z_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
/* Clip against negative X plane */
|
|
static void TexturedPolygon_Norm_ClipWithNegativeX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_NX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_NX_Test(nextVertexPtr);
|
|
Clip_NX_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
static void TexturedPolygon_Wide_ClipWithNegativeX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_Wide_NX_Test(nextVertexPtr);
|
|
Clip_Wide_NX_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
|
|
/* Clip against positive Y plane*/
|
|
static void TexturedPolygon_Norm_ClipWithPositiveY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_PY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_PY_Test(nextVertexPtr);
|
|
Clip_PY_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
static void TexturedPolygon_Wide_ClipWithPositiveY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Wide_PY_Test(nextVertexPtr);
|
|
Clip_Wide_PY_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
/* Clip against negative Y plane*/
|
|
static void TexturedPolygon_Norm_ClipWithNegativeY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_NY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_NY_Test(nextVertexPtr);
|
|
Clip_NY_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
static void TexturedPolygon_Wide_ClipWithNegativeY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_Wide_NY_Test(nextVertexPtr);
|
|
Clip_Wide_NY_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
|
|
/* Clip against positive X plane */
|
|
static void TexturedPolygon_Norm_ClipWithPositiveX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_PX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_PX_Test(nextVertexPtr);
|
|
Clip_PX_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
static void TexturedPolygon_Wide_ClipWithPositiveX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Wide_PX_Test(nextVertexPtr);
|
|
Clip_Wide_PX_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
|
|
|
|
|
|
/*KJL************************
|
|
* GOURAUD TEXTURED POLYGONS *
|
|
************************KJL*/
|
|
|
|
/* Clip against Z plane */
|
|
void GouraudTexturedPolygon_ClipWithZ(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Z_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Z_Test(nextVertexPtr);
|
|
Clip_Z_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
/* Clip against negative X plane */
|
|
static void GouraudTexturedPolygon_Norm_ClipWithNegativeX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_NX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_NX_Test(nextVertexPtr);
|
|
Clip_NX_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
static void GouraudTexturedPolygon_Wide_ClipWithNegativeX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_Wide_NX_Test(nextVertexPtr);
|
|
Clip_Wide_NX_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
|
|
/* Clip against positive Y plane*/
|
|
static void GouraudTexturedPolygon_Norm_ClipWithPositiveY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_PY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_PY_Test(nextVertexPtr);
|
|
Clip_PY_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
static void GouraudTexturedPolygon_Wide_ClipWithPositiveY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Wide_PY_Test(nextVertexPtr);
|
|
Clip_Wide_PY_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
/* Clip against negative Y plane*/
|
|
static void GouraudTexturedPolygon_Norm_ClipWithNegativeY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_NY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_NY_Test(nextVertexPtr);
|
|
Clip_NY_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
static void GouraudTexturedPolygon_Wide_ClipWithNegativeY(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
|
|
RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart((RenderPolygon.Vertices))
|
|
Clip_Wide_NY_Test(nextVertexPtr);
|
|
Clip_Wide_NY_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd(VerticesBuffer)
|
|
}
|
|
|
|
/* Clip against positive X plane */
|
|
static void GouraudTexturedPolygon_Norm_ClipWithPositiveX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_PX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_PX_Test(nextVertexPtr);
|
|
Clip_PX_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
static void GouraudTexturedPolygon_Wide_ClipWithPositiveX(void)
|
|
{
|
|
RENDERVERTEX *curVertexPtr = VerticesBuffer;
|
|
RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
|
|
int verticesLeft = RenderPolygon.NumberOfVertices;
|
|
int numberOfPointsOutputted=0;
|
|
|
|
int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
|
|
|
|
Clip_LoopStart(VerticesBuffer)
|
|
Clip_Wide_PX_Test(nextVertexPtr);
|
|
Clip_Wide_PX_OutputXYZ
|
|
Clip_OutputUV
|
|
Clip_OutputI
|
|
Clip_LoopEnd((RenderPolygon.Vertices))
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int PolygonWithinFrustrum(POLYHEADER *polyPtr)
|
|
{
|
|
char inFrustrumFlag=0;
|
|
char noClippingFlag=INSIDE_FRUSTRUM;
|
|
int *vertexNumberPtr = &polyPtr->Poly1stPt;
|
|
|
|
if (polyPtr->PolyFlags & iflag_notvis) return 0;
|
|
|
|
RenderPolygon.NumberOfVertices=0;
|
|
while(*vertexNumberPtr != Term)
|
|
{
|
|
int vertexNumber = *vertexNumberPtr++;
|
|
|
|
inFrustrumFlag |= FrustrumFlagForVertex[vertexNumber];
|
|
noClippingFlag &= FrustrumFlagForVertex[vertexNumber];
|
|
|
|
/* count the number of points in the polygon; this is used for all the loops that follow */
|
|
RenderPolygon.NumberOfVertices++;
|
|
}
|
|
|
|
if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
|
|
|
|
/* at this point we know that the poly is inside the view frustrum */
|
|
|
|
/* if not a sprite, test direction of poly */
|
|
if (!( (Global_ShapeHeaderPtr->shapeflags&ShapeFlag_Sprite) || (polyPtr->PolyFlags & iflag_no_bfc) ))
|
|
{
|
|
VECTORCH pop;
|
|
VECTORCH *normalPtr = (VECTORCH*)(Global_ShapeNormals + polyPtr->PolyNormalIndex);
|
|
|
|
#if 1
|
|
if(Global_ODB_Ptr->ObMorphCtrl)
|
|
{
|
|
extern MORPHDISPLAY MorphDisplay;
|
|
SHAPEHEADER *shape1Ptr;
|
|
VECTORCH *shape1PointsPtr;
|
|
VECTORCH *shape2PointsPtr;
|
|
|
|
/* Set up the morph data */
|
|
GetMorphDisplay(&MorphDisplay, Global_ODB_Ptr);
|
|
|
|
shape1Ptr = MorphDisplay.md_sptr1;
|
|
|
|
if(MorphDisplay.md_lerp == 0x0000)
|
|
{
|
|
shape1PointsPtr = (VECTORCH *)*shape1Ptr->points;
|
|
pop = shape1PointsPtr[polyPtr->Poly1stPt];
|
|
|
|
}
|
|
else if(MorphDisplay.md_lerp == 0xffff)
|
|
{
|
|
SHAPEHEADER *shape2Ptr = MorphDisplay.md_sptr2;
|
|
|
|
shape2PointsPtr = (VECTORCH *)*shape2Ptr->points;
|
|
pop = shape2PointsPtr[polyPtr->Poly1stPt];
|
|
}
|
|
else
|
|
{
|
|
SHAPEHEADER *shape2Ptr = MorphDisplay.md_sptr2;
|
|
|
|
shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points);
|
|
shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points);
|
|
|
|
{
|
|
VECTORCH vertex1 = shape1PointsPtr[polyPtr->Poly1stPt];
|
|
VECTORCH vertex2 = shape2PointsPtr[polyPtr->Poly1stPt];
|
|
|
|
if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) )
|
|
{
|
|
pop = vertex1;
|
|
}
|
|
else
|
|
{
|
|
/* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex
|
|
component has a magnitude greater than 32768 things will go wrong. */
|
|
pop.vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16);
|
|
pop.vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16);
|
|
pop.vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
/* Get the 1st polygon point as the POP */
|
|
VECTORCH *pointsArray = (VECTORCH*)(Global_ShapePoints);
|
|
pop = pointsArray[polyPtr->Poly1stPt];
|
|
}
|
|
pop.vx -= LocalView.vx;
|
|
pop.vy -= LocalView.vy;
|
|
pop.vz -= LocalView.vz;
|
|
|
|
if (Dot(&pop, normalPtr)>0) return 0;
|
|
}
|
|
|
|
if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
|
|
|
|
/* yes, we need to draw poly */
|
|
return 1;
|
|
}
|
|
|
|
int PolygonShouldBeDrawn(POLYHEADER *polyPtr)
|
|
{
|
|
|
|
/* at this point we know that the poly is inside the view frustrum */
|
|
if (polyPtr->PolyFlags & iflag_notvis) return 0;
|
|
|
|
#if 1
|
|
/* if not a sprite, test direction of poly */
|
|
if (!( (Global_ShapeHeaderPtr->shapeflags&ShapeFlag_Sprite) || (polyPtr->PolyFlags & iflag_no_bfc) ))
|
|
{
|
|
/* KJL 16:49:14 7/10/97 -
|
|
|
|
***** MORPHED NORMALS SUPPORT NOT YET ADDED *****
|
|
|
|
*/
|
|
VECTORCH pop;
|
|
VECTORCH *normalPtr = (VECTORCH*)(Global_ShapeNormals + polyPtr->PolyNormalIndex);
|
|
VECTORCH *pointsArray = (VECTORCH*)(Global_ShapePoints);
|
|
/* Get the 1st polygon point as the POP */
|
|
|
|
pop.vx = pointsArray[polyPtr->Poly1stPt].vx - LocalView.vx;
|
|
pop.vy = pointsArray[polyPtr->Poly1stPt].vy - LocalView.vy;
|
|
pop.vz = pointsArray[polyPtr->Poly1stPt].vz - LocalView.vz;
|
|
|
|
if (Dot(&pop, normalPtr)>0) return 0;
|
|
}
|
|
#endif
|
|
#if 0
|
|
{
|
|
int *vertexNumberPtr = &polyPtr->Poly1stPt;
|
|
RenderPolygon.NumberOfVertices=0;
|
|
while(*vertexNumberPtr++ != Term)
|
|
{
|
|
/* count the number of points in the polygon; this is used for all the loops that follow */
|
|
RenderPolygon.NumberOfVertices++;
|
|
}
|
|
}
|
|
#elif 0
|
|
RenderPolygon.NumberOfVertices = 3;
|
|
#else
|
|
{
|
|
int *vertexNumberPtr = &polyPtr->Poly1stPt;
|
|
if (vertexNumberPtr[3] == Term)
|
|
{
|
|
RenderPolygon.NumberOfVertices = 3;
|
|
}
|
|
else
|
|
{
|
|
RenderPolygon.NumberOfVertices = 4;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return 2;
|
|
}
|
|
|
|
/* KJL 16:18:59 7/7/97 - simple vertex test to be used in first
|
|
pass of subdividing code */
|
|
static int VertexWithin_Norm_Frustrum(RENDERVERTEX *vertexPtr)
|
|
{
|
|
int vertexFlag = 0;
|
|
|
|
if(Clip_Z_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
|
|
if(Clip_PX_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
|
|
if(Clip_NX_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
|
|
if(Clip_PY_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
|
|
if(Clip_NY_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
|
|
|
|
return vertexFlag;
|
|
}
|
|
|
|
static int VertexWithin_Wide_Frustrum(RENDERVERTEX *vertexPtr)
|
|
{
|
|
int vertexFlag = 0;
|
|
|
|
if(Clip_Z_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
|
|
if(Clip_Wide_PX_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
|
|
if(Clip_Wide_NX_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
|
|
if(Clip_Wide_PY_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
|
|
if(Clip_Wide_NY_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
|
|
|
|
return vertexFlag;
|
|
}
|
|
|
|
|
|
/* KJL 15:32:52 7/17/97 - Test to see if an object is in the view frustrum */
|
|
static int ObjectWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr)
|
|
{
|
|
// LOCALASSERT(dbPtr->ObShapeData->shaperadius);
|
|
|
|
#if FAR_Z_CLIP
|
|
if(dbPtr->ObView.vz-dbPtr->ObShapeData->shaperadius<=FAR_Z_CLIP_RANGE)
|
|
#endif
|
|
if (dbPtr->ObView.vz+dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
|
|
{
|
|
/* scale radius by square root of 2 */
|
|
int radius = MUL_FIXED(92682,dbPtr->ObShapeData->shaperadius);
|
|
|
|
if ((dbPtr->ObView.vx-dbPtr->ObView.vz)<=radius)
|
|
if ((-dbPtr->ObView.vx-dbPtr->ObView.vz)<=radius)
|
|
if ((dbPtr->ObView.vy-dbPtr->ObView.vz)<=radius)
|
|
if ((-dbPtr->ObView.vy-dbPtr->ObView.vz)<=radius)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
static int ObjectCompletelyWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr)
|
|
{
|
|
// LOCALASSERT(dbPtr->ObShapeData->shaperadius);
|
|
if (dbPtr->ObView.vz-dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
|
|
{
|
|
/* scale radius by square root of 2 */
|
|
int radius = MUL_FIXED(92682,dbPtr->ObShapeData->shaperadius);
|
|
|
|
if ((dbPtr->ObView.vz-dbPtr->ObView.vx)>=radius)
|
|
if ((dbPtr->ObView.vz+dbPtr->ObView.vx)>=radius)
|
|
if ((dbPtr->ObView.vz-dbPtr->ObView.vy)>=radius)
|
|
if ((dbPtr->ObView.vz+dbPtr->ObView.vy)>=radius)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
static int ObjectCompletelyWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int ObjectWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr)
|
|
{
|
|
if (dbPtr->ObView.vz+dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
|
|
{
|
|
/* scale radius by square root of 5 */
|
|
int radius = MUL_FIXED(146543,dbPtr->ObShapeData->shaperadius);
|
|
|
|
if ((dbPtr->ObView.vx-2*dbPtr->ObView.vz)<=radius)
|
|
if ((-dbPtr->ObView.vx-2*dbPtr->ObView.vz)<=radius)
|
|
if ((dbPtr->ObView.vy-2*dbPtr->ObView.vz)<=radius)
|
|
if ((-dbPtr->ObView.vy-2*dbPtr->ObView.vz)<=radius)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
char FrustrumFlagForVertex[maxrotpts];
|
|
|
|
void TestVerticesWith_Norm_Frustrum(void)
|
|
{
|
|
int v = Global_ShapeHeaderPtr->numpoints;
|
|
|
|
GLOBALASSERT(v>0);
|
|
|
|
while(v--)
|
|
{
|
|
char vertexFlag = 0;
|
|
|
|
#if FAR_Z_CLIP
|
|
if(ZCLIPPINGVALUE <= RotatedPts[v].vz && RotatedPts[v].vz<=FAR_Z_CLIP_RANGE)
|
|
#else
|
|
if(ZCLIPPINGVALUE <= RotatedPts[v].vz)
|
|
#endif
|
|
vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
|
|
|
|
if(-RotatedPts[v].vx <= RotatedPts[v].vz)
|
|
vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
|
|
|
|
if(RotatedPts[v].vx <= RotatedPts[v].vz)
|
|
vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
|
|
|
|
if(-RotatedPts[v].vy <= RotatedPts[v].vz)
|
|
vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
|
|
|
|
if(RotatedPts[v].vy <= RotatedPts[v].vz)
|
|
vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
|
|
|
|
FrustrumFlagForVertex[v] = vertexFlag;
|
|
}
|
|
}
|
|
void TestVerticesWith_Wide_Frustrum(void)
|
|
{
|
|
int v = Global_ShapeHeaderPtr->numpoints;
|
|
|
|
GLOBALASSERT(v>0);
|
|
|
|
while(v--)
|
|
{
|
|
char vertexFlag = 0;
|
|
|
|
if(ZCLIPPINGVALUE <= RotatedPts[v].vz)
|
|
vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
|
|
|
|
if(-RotatedPts[v].vx <= RotatedPts[v].vz*2)
|
|
vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
|
|
|
|
if(RotatedPts[v].vx <= RotatedPts[v].vz*2)
|
|
vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
|
|
|
|
if(-RotatedPts[v].vy <= RotatedPts[v].vz*2)
|
|
vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
|
|
|
|
if(RotatedPts[v].vy <= RotatedPts[v].vz*2)
|
|
vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
|
|
|
|
FrustrumFlagForVertex[v] = vertexFlag;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int DecalWithinFrustrum(DECAL *decalPtr)
|
|
{
|
|
char inFrustrumFlag;
|
|
char noClippingFlag;
|
|
|
|
if(ModuleCurrVisArray[decalPtr->ModuleIndex] != 2) return 0;
|
|
|
|
inFrustrumFlag=0;
|
|
noClippingFlag=INSIDE_FRUSTRUM;
|
|
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[3]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
|
|
if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
|
|
if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
|
|
|
|
/* yes, we need to draw poly */
|
|
return 1;
|
|
}
|
|
|
|
int QuadWithinFrustrum(void)
|
|
{
|
|
char inFrustrumFlag;
|
|
char noClippingFlag;
|
|
|
|
inFrustrumFlag=0;
|
|
noClippingFlag=INSIDE_FRUSTRUM;
|
|
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[3]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
|
|
if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
|
|
if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
|
|
|
|
/* yes, we need to draw poly */
|
|
return 1;
|
|
}
|
|
|
|
int TriangleWithinFrustrum(void)
|
|
{
|
|
char inFrustrumFlag;
|
|
char noClippingFlag;
|
|
|
|
inFrustrumFlag=0;
|
|
noClippingFlag=INSIDE_FRUSTRUM;
|
|
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
{
|
|
int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
|
|
inFrustrumFlag |= vertexFlag;
|
|
noClippingFlag &= vertexFlag;
|
|
}
|
|
|
|
if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
|
|
if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
|
|
|
|
/* yes, we need to draw poly */
|
|
return 1;
|
|
}
|
|
|
|
|