//=================================================================
//
// Copyright (c) Microsoft Corporation 1999 - All Rights Reserved.
//
//=================================================================

//-----------------------------------------------------------------------------
//
//     _TRANFORM_FN_NAME_ - Name to give to the transformation function.
//     _CLIP_             - Define to generate clip codes.
//
//-----------------------------------------------------------------------------


#if defined(_CLIP_)
void _TRANSFORM_FN_NAME_(D3DLVERTEX * pvtxSrc, int cvtxSrc, D3DMATRIX * pmtxSrc, D3DVIEWPORT2 * pvd, GRFCLIPVERTEX * pvtxDst)
#else
void _TRANSFORM_FN_NAME_(D3DLVERTEX * pvtxSrc, int cvtxSrc, D3DMATRIX * pmtxSrc, D3DVIEWPORT2 * pvd, D3DTLVERTEX * pvtxDst)
#endif
{

#if defined(_CLIP_)
    DWORD dwFlags;
#endif

    D3DVALUE hx, hy, hz, hw, invhw;
	D3DVALUE xScale, yScale, xOffset, yOffset;

	// Scale up to the view window.
	xScale = (float)pvd->dwWidth;
	yScale = - (float)pvd->dwHeight;

	// Top left corner of view window.
	xOffset = (float)pvd->dwX;
	yOffset = (float)(pvd->dwY + pvd->dwHeight);

	// Transform the verticies.
	while (cvtxSrc--)
	{
		// Generate the homogenous coordinates.
        hx = pvtxSrc->x * pmtxSrc->_11 + pvtxSrc->y * pmtxSrc->_21 +
             pvtxSrc->z * pmtxSrc->_31 + pmtxSrc->_41;
        hy = pvtxSrc->x * pmtxSrc->_12 + pvtxSrc->y * pmtxSrc->_22 +
             pvtxSrc->z * pmtxSrc->_32 + pmtxSrc->_42;
        hz = pvtxSrc->x * pmtxSrc->_13 + pvtxSrc->y * pmtxSrc->_23 +
             pvtxSrc->z * pmtxSrc->_33 + pmtxSrc->_43;
        hw = pvtxSrc->x * pmtxSrc->_14 + pvtxSrc->y * pmtxSrc->_24 +
             pvtxSrc->z * pmtxSrc->_34 + pmtxSrc->_44;

#ifdef APPLY_CLIP_MATRIX_SEPARATELY
		hx = (hx + hw) * 0.5f;
		hy = (hy + hw) * 0.5f;
#endif


#if defined(_CLIP_)

#ifdef CLIP_NEG1_TO_1
		// Generate clipping codes.
        if (hx < -hw)
        {
            dwFlags = CLIP_SIDE_LEFT;
        }
        else if (hx > hw)
        {
            dwFlags = CLIP_SIDE_RIGHT;
        }
        else
        {
            dwFlags = 0;
        }

        if (hy < -hw)
        {
            dwFlags |= CLIP_SIDE_TOP;
        }
        else if (hy > hw)
        {
            dwFlags |= CLIP_SIDE_BOTTOM;
        }

#else
		// Generate clipping codes.
        if (hx < 0)
        {
            dwFlags = CLIP_SIDE_LEFT;
        }
        else if (hx > hw)
        {
            dwFlags = CLIP_SIDE_RIGHT;
        }
        else
        {
            dwFlags = 0;
        }

        if (hy < 0)
        {
            dwFlags |= CLIP_SIDE_TOP;
        }
        else if (hy > hw)
        {
            dwFlags |= CLIP_SIDE_BOTTOM;
        }

#endif
        if (hz < 0)
        {
            dwFlags |= CLIP_SIDE_FRONT;
        }
        else if (hz > hw)
        {
            dwFlags |= CLIP_SIDE_BACK;
        }

        pvtxDst->dwFlags = dwFlags;
        pvtxDst->hx = hx;
        pvtxDst->hy = hy;
        pvtxDst->hz = hz;
		pvtxDst->hw = hw;
#endif

#if defined(_CLIP_)

		if (!dwFlags)
		{
			ASSERT(0.0F != hw);

#endif

#if !defined(_CLIP_)
			if (0.0F == hw)
			{
				invhw = HUGE_FLOAT_VALUE;
			}
			else
#endif
			{
				invhw = 1.0F / hw;
			}

			pvtxDst->sx  = hx * invhw * xScale + xOffset;
			pvtxDst->sy  = hy * invhw * yScale + yOffset;
			pvtxDst->sz  = hz * invhw;
			pvtxDst->rhw = invhw;

#if 0
			// Generate the screen coordinates.
			pvtxDst->sx  = (hx * dvClipWidth + hw * dvClipX) * invhw * xScale + xOffset;
			pvtxDst->sy  = (hy * dvClipHeight + hw * (dvClilpY - dvClipHeight)) * invhw * yScale + yOffset;
			pvtxDst->sz  = (hz * (dvMaxZ - dvMinZ) + hw * (-dvMinZ)) * invhw;
			pvtxDst->rhw = invhw;

			pvtxDst->sx  = hx * dvClipWidth * invhw * xScale + dvClipX * xScale + xOffset;
			pvtxDst->sy  = hy * dvClipHeight * invhw * yScale + (dvClipY - dvClipHeight) * xScale + yOffset;
			pvtxDst->sz  = hz * (dvMaxZ - dvMinZ) * invhw - dvMinz;
			pvtxDst->rhw = invhw;
#endif

#if defined(_CLIP_)

		}

#endif

        pvtxDst->tu       = pvtxSrc->tu;
        pvtxDst->tv       = pvtxSrc->tv;
        pvtxDst->color    = pvtxSrc->color;
        pvtxDst->specular = pvtxSrc->specular;

        pvtxSrc++;
        pvtxDst++;
    }
}

#undef _TRANSFORM_FN_NAME_
#undef _CLIP_
