123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- /******************************************************************************
- @File PVRTTrans.cpp
- @Title PVRTTrans
- @Version
- @Copyright Copyright (C) Imagination Technologies Limited.
- @Platform ANSI compatible
- @Description Set of functions used for 3D transformations and projections.
- ******************************************************************************/
- #include <string.h>
- #include "PVRTGlobal.h"
- #include "PVRTContext.h"
- #include "PVRTFixedPoint.h"
- #include "PVRTMatrix.h"
- #include "PVRTTrans.h"
- /****************************************************************************
- ** Functions
- ****************************************************************************/
- /*!***************************************************************************
- @Function PVRTBoundingBoxCompute
- @Output pBoundingBox
- @Input pV
- @Input nNumberOfVertices
- @Description Calculate the eight vertices that surround an object.
- This "bounding box" is used later to determine whether
- the object is visible or not.
- This function should only be called once to determine the
- object's bounding box.
- *****************************************************************************/
- void PVRTBoundingBoxCompute(
- PVRTBOUNDINGBOX * const pBoundingBox,
- const PVRTVECTOR3 * const pV,
- const int nNumberOfVertices)
- {
- int i;
- VERTTYPE MinX, MaxX, MinY, MaxY, MinZ, MaxZ;
- /* Inialise values to first vertex */
- MinX=pV->x; MaxX=pV->x;
- MinY=pV->y; MaxY=pV->y;
- MinZ=pV->z; MaxZ=pV->z;
- /* Loop through all vertices to find extremas */
- for (i=1; i<nNumberOfVertices; i++)
- {
- /* Minimum and Maximum X */
- if (pV[i].x < MinX) MinX = pV[i].x;
- if (pV[i].x > MaxX) MaxX = pV[i].x;
- /* Minimum and Maximum Y */
- if (pV[i].y < MinY) MinY = pV[i].y;
- if (pV[i].y > MaxY) MaxY = pV[i].y;
- /* Minimum and Maximum Z */
- if (pV[i].z < MinZ) MinZ = pV[i].z;
- if (pV[i].z > MaxZ) MaxZ = pV[i].z;
- }
- /* Assign the resulting extremas to the bounding box structure */
- /* Point 0 */
- pBoundingBox->Point[0].x=MinX;
- pBoundingBox->Point[0].y=MinY;
- pBoundingBox->Point[0].z=MinZ;
- /* Point 1 */
- pBoundingBox->Point[1].x=MinX;
- pBoundingBox->Point[1].y=MinY;
- pBoundingBox->Point[1].z=MaxZ;
- /* Point 2 */
- pBoundingBox->Point[2].x=MinX;
- pBoundingBox->Point[2].y=MaxY;
- pBoundingBox->Point[2].z=MinZ;
- /* Point 3 */
- pBoundingBox->Point[3].x=MinX;
- pBoundingBox->Point[3].y=MaxY;
- pBoundingBox->Point[3].z=MaxZ;
- /* Point 4 */
- pBoundingBox->Point[4].x=MaxX;
- pBoundingBox->Point[4].y=MinY;
- pBoundingBox->Point[4].z=MinZ;
- /* Point 5 */
- pBoundingBox->Point[5].x=MaxX;
- pBoundingBox->Point[5].y=MinY;
- pBoundingBox->Point[5].z=MaxZ;
- /* Point 6 */
- pBoundingBox->Point[6].x=MaxX;
- pBoundingBox->Point[6].y=MaxY;
- pBoundingBox->Point[6].z=MinZ;
- /* Point 7 */
- pBoundingBox->Point[7].x=MaxX;
- pBoundingBox->Point[7].y=MaxY;
- pBoundingBox->Point[7].z=MaxZ;
- }
- /*!***************************************************************************
- @Function PVRTBoundingBoxComputeInterleaved
- @Output pBoundingBox
- @Input pV
- @Input nNumberOfVertices
- @Input i32Offset
- @Input i32Stride
- @Description Calculate the eight vertices that surround an object.
- This "bounding box" is used later to determine whether
- the object is visible or not.
- This function should only be called once to determine the
- object's bounding box.
- Takes interleaved data using the first vertex's offset
- and the stride to the next vertex thereafter
- *****************************************************************************/
- void PVRTBoundingBoxComputeInterleaved(
- PVRTBOUNDINGBOX * const pBoundingBox,
- const unsigned char * const pV,
- const int nNumberOfVertices,
- const int i32Offset,
- const int i32Stride)
- {
- int i;
- VERTTYPE MinX, MaxX, MinY, MaxY, MinZ, MaxZ;
- // point ot first vertex
- PVRTVECTOR3 *pVertex =(PVRTVECTOR3*)(pV+i32Offset);
- /* Inialise values to first vertex */
- MinX=pVertex->x; MaxX=pVertex->x;
- MinY=pVertex->y; MaxY=pVertex->y;
- MinZ=pVertex->z; MaxZ=pVertex->z;
- /* Loop through all vertices to find extremas */
- for (i=1; i<nNumberOfVertices; i++)
- {
- pVertex = (PVRTVECTOR3*)( (unsigned char*)(pVertex)+i32Stride);
- /* Minimum and Maximum X */
- if (pVertex->x < MinX) MinX = pVertex->x;
- if (pVertex->x > MaxX) MaxX = pVertex->x;
- /* Minimum and Maximum Y */
- if (pVertex->y < MinY) MinY = pVertex->y;
- if (pVertex->y > MaxY) MaxY = pVertex->y;
- /* Minimum and Maximum Z */
- if (pVertex->z < MinZ) MinZ = pVertex->z;
- if (pVertex->z > MaxZ) MaxZ = pVertex->z;
- }
- /* Assign the resulting extremas to the bounding box structure */
- /* Point 0 */
- pBoundingBox->Point[0].x=MinX;
- pBoundingBox->Point[0].y=MinY;
- pBoundingBox->Point[0].z=MinZ;
- /* Point 1 */
- pBoundingBox->Point[1].x=MinX;
- pBoundingBox->Point[1].y=MinY;
- pBoundingBox->Point[1].z=MaxZ;
- /* Point 2 */
- pBoundingBox->Point[2].x=MinX;
- pBoundingBox->Point[2].y=MaxY;
- pBoundingBox->Point[2].z=MinZ;
- /* Point 3 */
- pBoundingBox->Point[3].x=MinX;
- pBoundingBox->Point[3].y=MaxY;
- pBoundingBox->Point[3].z=MaxZ;
- /* Point 4 */
- pBoundingBox->Point[4].x=MaxX;
- pBoundingBox->Point[4].y=MinY;
- pBoundingBox->Point[4].z=MinZ;
- /* Point 5 */
- pBoundingBox->Point[5].x=MaxX;
- pBoundingBox->Point[5].y=MinY;
- pBoundingBox->Point[5].z=MaxZ;
- /* Point 6 */
- pBoundingBox->Point[6].x=MaxX;
- pBoundingBox->Point[6].y=MaxY;
- pBoundingBox->Point[6].z=MinZ;
- /* Point 7 */
- pBoundingBox->Point[7].x=MaxX;
- pBoundingBox->Point[7].y=MaxY;
- pBoundingBox->Point[7].z=MaxZ;
- }
- /*!******************************************************************************
- @Function PVRTBoundingBoxIsVisible
- @Output pNeedsZClipping
- @Input pBoundingBox
- @Input pMatrix
- @Return TRUE if the object is visible, FALSE if not.
- @Description Determine if a bounding box is "visible" or not along the
- Z axis.
- If the function returns TRUE, the object is visible and should
- be displayed (check bNeedsZClipping to know if Z Clipping needs
- to be done).
- If the function returns FALSE, the object is not visible and thus
- does not require to be displayed.
- bNeedsZClipping indicates whether the object needs Z Clipping
- (i.e. the object is partially visible).
- - *pBoundingBox is a pointer to the bounding box structure.
- - *pMatrix is the World, View & Projection matrices combined.
- - *bNeedsZClipping is TRUE if Z clipping is required.
- *****************************************************************************/
- bool PVRTBoundingBoxIsVisible(
- const PVRTBOUNDINGBOX * const pBoundingBox,
- const PVRTMATRIX * const pMatrix,
- bool * const pNeedsZClipping)
- {
- VERTTYPE fX, fY, fZ, fW;
- int i, nX0, nX1, nY0, nY1, nZ;
- nX0 = 8;
- nX1 = 8;
- nY0 = 8;
- nY1 = 8;
- nZ = 8;
- /* Transform the eight bounding box vertices */
- i = 8;
- while(i)
- {
- i--;
- fX = pMatrix->f[ 0]*pBoundingBox->Point[i].x +
- pMatrix->f[ 4]*pBoundingBox->Point[i].y +
- pMatrix->f[ 8]*pBoundingBox->Point[i].z +
- pMatrix->f[12];
- fY = pMatrix->f[ 1]*pBoundingBox->Point[i].x +
- pMatrix->f[ 5]*pBoundingBox->Point[i].y +
- pMatrix->f[ 9]*pBoundingBox->Point[i].z +
- pMatrix->f[13];
- fZ = pMatrix->f[ 2]*pBoundingBox->Point[i].x +
- pMatrix->f[ 6]*pBoundingBox->Point[i].y +
- pMatrix->f[10]*pBoundingBox->Point[i].z +
- pMatrix->f[14];
- fW = pMatrix->f[ 3]*pBoundingBox->Point[i].x +
- pMatrix->f[ 7]*pBoundingBox->Point[i].y +
- pMatrix->f[11]*pBoundingBox->Point[i].z +
- pMatrix->f[15];
- if(fX < -fW)
- nX0--;
- else if(fX > fW)
- nX1--;
- if(fY < -fW)
- nY0--;
- else if(fY > fW)
- nY1--;
- if(fZ < 0)
- nZ--;
- }
- if(nZ)
- {
- if(!(nX0 * nX1 * nY0 * nY1))
- {
- *pNeedsZClipping = false;
- return false;
- }
- if(nZ == 8)
- {
- *pNeedsZClipping = false;
- return true;
- }
- *pNeedsZClipping = true;
- return true;
- }
- else
- {
- *pNeedsZClipping = false;
- return false;
- }
- }
- /*!***************************************************************************
- @Function Name PVRTTransformVec3Array
- @Output pOut Destination for transformed vectors
- @Input nOutStride Stride between vectors in pOut array
- @Input pV Input vector array
- @Input nInStride Stride between vectors in pV array
- @Input pMatrix Matrix to transform the vectors
- @Input nNumberOfVertices Number of vectors to transform
- @Description Transform all vertices [X Y Z 1] in pV by pMatrix and
- store them in pOut.
- *****************************************************************************/
- void PVRTTransformVec3Array(
- PVRTVECTOR4 * const pOut,
- const int nOutStride,
- const PVRTVECTOR3 * const pV,
- const int nInStride,
- const PVRTMATRIX * const pMatrix,
- const int nNumberOfVertices)
- {
- const PVRTVECTOR3 *pSrc;
- PVRTVECTOR4 *pDst;
- int i;
- pSrc = pV;
- pDst = pOut;
- /* Transform all vertices with *pMatrix */
- for (i=0; i<nNumberOfVertices; ++i)
- {
- pDst->x = VERTTYPEMUL(pMatrix->f[ 0], pSrc->x) +
- VERTTYPEMUL(pMatrix->f[ 4], pSrc->y) +
- VERTTYPEMUL(pMatrix->f[ 8], pSrc->z) +
- pMatrix->f[12];
- pDst->y = VERTTYPEMUL(pMatrix->f[ 1], pSrc->x) +
- VERTTYPEMUL(pMatrix->f[ 5], pSrc->y) +
- VERTTYPEMUL(pMatrix->f[ 9], pSrc->z) +
- pMatrix->f[13];
- pDst->z = VERTTYPEMUL(pMatrix->f[ 2], pSrc->x) +
- VERTTYPEMUL(pMatrix->f[ 6], pSrc->y) +
- VERTTYPEMUL(pMatrix->f[10], pSrc->z) +
- pMatrix->f[14];
- pDst->w = VERTTYPEMUL(pMatrix->f[ 3], pSrc->x) +
- VERTTYPEMUL(pMatrix->f[ 7], pSrc->y) +
- VERTTYPEMUL(pMatrix->f[11], pSrc->z) +
- pMatrix->f[15];
- pDst = (PVRTVECTOR4*)((char*)pDst + nOutStride);
- pSrc = (PVRTVECTOR3*)((char*)pSrc + nInStride);
- }
- }
- /*!***************************************************************************
- @Function PVRTTransformArray
- @Output pTransformedVertex Destination for transformed vectors
- @Input pV Input vector array
- @Input nNumberOfVertices Number of vectors to transform
- @Input pMatrix Matrix to transform the vectors
- @Input fW W coordinate of input vector (e.g. use 1 for position, 0 for normal)
- @Description Transform all vertices in pVertex by pMatrix and store them in
- pTransformedVertex
- - pTransformedVertex is the pointer that will receive transformed vertices.
- - pVertex is the pointer to untransformed object vertices.
- - nNumberOfVertices is the number of vertices of the object.
- - pMatrix is the matrix used to transform the object.
- *****************************************************************************/
- void PVRTTransformArray(
- PVRTVECTOR3 * const pTransformedVertex,
- const PVRTVECTOR3 * const pV,
- const int nNumberOfVertices,
- const PVRTMATRIX * const pMatrix,
- const VERTTYPE fW)
- {
- int i;
- /* Transform all vertices with *pMatrix */
- for (i=0; i<nNumberOfVertices; ++i)
- {
- pTransformedVertex[i].x = VERTTYPEMUL(pMatrix->f[ 0], pV[i].x) +
- VERTTYPEMUL(pMatrix->f[ 4], pV[i].y) +
- VERTTYPEMUL(pMatrix->f[ 8], pV[i].z) +
- VERTTYPEMUL(pMatrix->f[12], fW);
- pTransformedVertex[i].y = VERTTYPEMUL(pMatrix->f[ 1], pV[i].x) +
- VERTTYPEMUL(pMatrix->f[ 5], pV[i].y) +
- VERTTYPEMUL(pMatrix->f[ 9], pV[i].z) +
- VERTTYPEMUL(pMatrix->f[13], fW);
- pTransformedVertex[i].z = VERTTYPEMUL(pMatrix->f[ 2], pV[i].x) +
- VERTTYPEMUL(pMatrix->f[ 6], pV[i].y) +
- VERTTYPEMUL(pMatrix->f[10], pV[i].z) +
- VERTTYPEMUL(pMatrix->f[14], fW);
- }
- }
- /*!***************************************************************************
- @Function PVRTTransformArrayBack
- @Output pTransformedVertex
- @Input pVertex
- @Input nNumberOfVertices
- @Input pMatrix
- @Description Transform all vertices in pVertex by the inverse of pMatrix
- and store them in pTransformedVertex.
- - pTransformedVertex is the pointer that will receive transformed vertices.
- - pVertex is the pointer to untransformed object vertices.
- - nNumberOfVertices is the number of vertices of the object.
- - pMatrix is the matrix used to transform the object.
- *****************************************************************************/
- void PVRTTransformArrayBack(
- PVRTVECTOR3 * const pTransformedVertex,
- const PVRTVECTOR3 * const pVertex,
- const int nNumberOfVertices,
- const PVRTMATRIX * const pMatrix)
- {
- PVRTMATRIX mBack;
- PVRTMatrixInverse(mBack, *pMatrix);
- PVRTTransformArray(pTransformedVertex, pVertex, nNumberOfVertices, &mBack);
- }
- /*!***************************************************************************
- @Function PVRTTransformBack
- @Output pOut
- @Input pV
- @Input pM
- @Description Transform vertex pV by the inverse of pMatrix
- and store in pOut.
- *****************************************************************************/
- void PVRTTransformBack(
- PVRTVECTOR4 * const pOut,
- const PVRTVECTOR4 * const pV,
- const PVRTMATRIX * const pM)
- {
- VERTTYPE *ppfRows[4];
- VERTTYPE pfIn[20];
- int i;
- const PVRTMATRIX *pMa;
- #if defined(BUILD_OGL) || defined(BUILD_OGLES) || defined(BUILD_OGLES2)
- PVRTMATRIX mT;
- PVRTMatrixTranspose(mT, *pM);
- pMa = &mT;
- #else
- pMa = pM;
- #endif
- for(i = 0; i < 4; ++i)
- {
- /*
- Set up the array of pointers to matrix coefficients
- */
- ppfRows[i] = &pfIn[i * 5];
- /*
- Copy the 4x4 matrix into RHS of the 5x4 matrix
- */
- memcpy(&ppfRows[i][1], &pMa->f[i * 4], 4 * sizeof(float));
- }
- /*
- Copy the "result" vector into the first column of the 5x4 matrix
- */
- ppfRows[0][0] = pV->x;
- ppfRows[1][0] = pV->y;
- ppfRows[2][0] = pV->z;
- ppfRows[3][0] = pV->w;
- /*
- Solve a set of 4 linear equations
- */
- PVRTMatrixLinearEqSolve(&pOut->x, ppfRows, 4);
- }
- /*!***************************************************************************
- @Function PVRTTransform
- @Output pOut
- @Input pV
- @Input pM
- @Description Transform vertex pV by pMatrix and store in pOut.
- *****************************************************************************/
- void PVRTTransform(
- PVRTVECTOR4 * const pOut,
- const PVRTVECTOR4 * const pV,
- const PVRTMATRIX * const pM)
- {
- pOut->x = VERTTYPEMUL(pM->f[0], pV->x) + VERTTYPEMUL(pM->f[4], pV->y) + VERTTYPEMUL(pM->f[8], pV->z) + VERTTYPEMUL(pM->f[12], pV->w);
- pOut->y = VERTTYPEMUL(pM->f[1], pV->x) + VERTTYPEMUL(pM->f[5], pV->y) + VERTTYPEMUL(pM->f[9], pV->z) + VERTTYPEMUL(pM->f[13], pV->w);
- pOut->z = VERTTYPEMUL(pM->f[2], pV->x) + VERTTYPEMUL(pM->f[6], pV->y) + VERTTYPEMUL(pM->f[10], pV->z) + VERTTYPEMUL(pM->f[14], pV->w);
- pOut->w = VERTTYPEMUL(pM->f[3], pV->x) + VERTTYPEMUL(pM->f[7], pV->y) + VERTTYPEMUL(pM->f[11], pV->z) + VERTTYPEMUL(pM->f[15], pV->w);
- }
- /*****************************************************************************
- End of file (PVRTTrans.cpp)
- *****************************************************************************/
|