Beispiel #1
0
LTBOOL gr_IntersectPlanes(
	LTPlane &plane0,
	LTPlane &plane1,
	LTPlane &plane2,
	LTVector &vOut)
{
	LTMatrix mPlanes;

	/*
		Math behind this:

		Plane equation is Ax + By + Cz - D = 0
		Standard matrix equation Ax = b.

		So stick the plane equations into the A matrix:

		A B C -D	(from plane 0)
		A B C -D	(from plane 1)
		A B C -D	(from plane 2)
		0 0 0  1

		then the b vector is:
		[0 0 0 1]

		and we're solving for the x vector so:
		~AAx = ~Ab
		x = ~Ab
	*/

	mPlanes.Init(
		plane0.m_Normal[0], plane0.m_Normal[1], plane0.m_Normal[2], -plane0.m_Dist,
		plane1.m_Normal[0], plane1.m_Normal[1], plane1.m_Normal[2], -plane1.m_Dist,
		plane2.m_Normal[0], plane2.m_Normal[1], plane2.m_Normal[2], -plane2.m_Dist,
		0.0f, 0.0f, 0.0f, 1.0f);

	// If we can't invert the matrix, then two or more planes are equal.
	if(!mPlanes.Inverse())
		return LTFALSE;

	// Since our b vector is all zeros, we don't need to do a full matrix multiply.
	// vOut = mPlaneNormal * vPlaneDist;
	vOut.Init(
		mPlanes.m[0][3],
		mPlanes.m[1][3],
		mPlanes.m[2][3]);

	vOut *= (1.0f / mPlanes.m[3][3]);
	return LTTRUE;
}
Beispiel #2
0
//Given a stage to install it on, it will grab the global world envmap transform
//and apply it into the texture transform on that stage
void d3d_SetEnvMapTransform(RTexture* pEnvMap, uint32 nStage)
{
	//determine how many times the texture will be tiling.

	float fScale = g_CV_EnvScale;

	//now see if it is okay to divide by it, since that will provide proper scaling
	if(fabs(fScale) > 0.001f)
		fScale = -0.5f / fScale;

	//now apply our custom scale
	LTMatrix mScale;

	if(pEnvMap->IsCubeMap())
	{
		PD3DDEVICE->SetTextureStageState(nStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
		mScale = g_ViewParams.m_mWorldEnvMap;
	}
	else
	{
		PD3DDEVICE->SetTextureStageState(nStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
		mScale.Init(fScale,	0.0f,	0.0f, 0.5f,
					0.0f,   fScale, 0.0f, 0.5f,
					0.0f,	0.0f,   1.0f, 0.0f,
					0.0f,   0.0f,   0.0f, 1.0f);

		//now multiply the two together to get our result
		mScale = mScale * g_ViewParams.m_mWorldEnvMap;
	}

	LTMatrix& m = mScale;

	//now setup the D3D version of our matrix
	D3DMATRIX mat;
	mat._11 = m.m[0][0]; mat._12 = m.m[1][0]; mat._13 = m.m[2][0]; mat._14 = m.m[3][0];
	mat._21 = m.m[0][1]; mat._22 = m.m[1][1]; mat._23 = m.m[2][1]; mat._24 = m.m[3][1];
	mat._31 = m.m[0][2]; mat._32 = m.m[1][2]; mat._33 = m.m[2][2]; mat._34 = m.m[3][2];
	mat._41 = m.m[0][3]; mat._42 = m.m[1][3]; mat._43 = m.m[2][3]; mat._44 = m.m[3][3];

	//and install the transform
	PD3DDEVICE->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + nStage), &mat);
	PD3DDEVICE->SetTextureStageState(nStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR | nStage);

}
Beispiel #3
0
// Sets up pParams.
// pPos and pRotation are the view position and orientation.
// pRect is the rectangle on the screen that the viewing window maps into.
// pScale is an extra scale that scales all the coordinates up.
bool d3d_InitFrustum2(ViewParams *pParams, 
	ViewBoxDef *pViewBox, 
	float screenMinX, float screenMinY, float screenMaxX, float screenMaxY,
	const LTMatrix *pMat, const LTVector& vScale, ViewParams::ERenderMode eMode)
{
	LTMatrix mTempWorld, mRotation, mScale;
	LTMatrix mFOVScale, mBackTransform;
	LTMatrix mDevice, mBackTranslate;
	float leftX, rightX, topY, bottomY, normalZ;
	uint32 i;
	LTVector forwardVec, zPlanePos, vTrans;
	LTMatrix mProjectionTransform; //mUnit, mPerspective;
	
	pParams->m_mIdentity.Identity();
	pParams->m_mInvView = *pMat;


	// Here's how the viewing works:
	// The world to camera transformation rotates and translates
	// the world into camera space.
	// The camera to clip transformation just scales the sides so the
	// field of view is 90 degrees (faster to clip in).
	// Clipping takes place on NEARZ and g_ViewParams.m_FarZ.
	// In terms of Z buffer calculations, the maximum Z is MAX_FARZ (that way,
	// when the farZ clipping plane is changed, sz and rhw stay the same).



	/////// Copy stuff in and setup view limits.

	memcpy(&pParams->m_ViewBox, pViewBox, sizeof(pParams->m_ViewBox));
	pMat->GetTranslation(pParams->m_Pos);

	pParams->m_FarZ = pViewBox->m_FarZ;
	if(pParams->m_FarZ < 3.0f) pParams->m_FarZ = 3.0f;
	if(pParams->m_FarZ > MAX_FARZ) pParams->m_FarZ = MAX_FARZ;
	pParams->m_NearZ = pViewBox->m_NearZ;
	
	pParams->m_Rect.left = (int)RoundFloatToInt(screenMinX);
	pParams->m_Rect.top = (int)RoundFloatToInt(screenMinY);
	pParams->m_Rect.right = (int)RoundFloatToInt(screenMaxX);
	pParams->m_Rect.bottom = (int)RoundFloatToInt(screenMaxY);

	/////// Setup all the matrices.

	// Setup the rotation and translation transforms.
	mRotation = *pMat;
	mRotation.SetTranslation(0.0f, 0.0f, 0.0f);
	Mat_GetBasisVectors(&mRotation, &pParams->m_Right, &pParams->m_Up, &pParams->m_Forward);

	// We want to transpose (ie: when we're looking left, rotate the world to the right..)
	MatTranspose3x3(&mRotation);
	mBackTranslate.Init(
		1, 0, 0, -pParams->m_Pos.x,
		0, 1, 0, -pParams->m_Pos.y,
		0, 0, 1, -pParams->m_Pos.z,
		0, 0, 0, 1);
	MatMul(&mTempWorld, &mRotation, &mBackTranslate);
	
	// Scale it to get the full world transform.
	mScale.Init(
		vScale.x, 0, 0, 0,
		0, vScale.y, 0, 0,
		0, 0, vScale.z, 0,
		0, 0, 0, 1);
	MatMul(&pParams->m_mView, &mScale, &mTempWorld);

	// Shear so the center of projection is (0,0,COP.z)
	LTMatrix mShear;
	mShear.Init(
		1.0f, 0.0f, -pViewBox->m_COP.x/pViewBox->m_COP.z, 0.0f,
		0.0f, 1.0f, -pViewBox->m_COP.y/pViewBox->m_COP.z, 0.0f,
		0.0f, 0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f);

	// Figure out X and Y scale to get frustum into unit slopes.
	float fFovXScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[0];
	float fFovYScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[1];

	// Squash the sides to 45 degree angles.
	mFOVScale.Init(
		fFovXScale, 0.0f, 0.0f, 0.0f,
		0.0f, fFovYScale, 0.0f, 0.0f,
		0.0f, 0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f);

	// Setup the projection transform.
	d3d_SetupPerspectiveMatrix(&mProjectionTransform, pViewBox->m_NearZ, pParams->m_FarZ);

	// Setup the projection space (-1<x<1) to device space transformation.
	pParams->m_fScreenWidth = (screenMaxX - screenMinX);
	pParams->m_fScreenHeight = (screenMaxY - screenMinY);
	
	// Setup the device transform.  It subtracts 0.4 to account for the FP's tendency
	// to slip above and below 0.5.
	Mat_Identity(&mDevice);
	mDevice.m[0][0] = pParams->m_fScreenWidth * 0.5f - 0.0001f;
	mDevice.m[0][3] = screenMinX + pParams->m_fScreenWidth * 0.5f;
	mDevice.m[1][1] = -(pParams->m_fScreenHeight * 0.5f - 0.0001f);
	mDevice.m[1][3] = screenMinY + pParams->m_fScreenHeight * 0.5f;


	// Precalculate useful matrices.
	pParams->m_DeviceTimesProjection = mDevice * mProjectionTransform;
	pParams->m_FullTransform = pParams->m_DeviceTimesProjection * mFOVScale * mShear * pParams->m_mView;

	pParams->m_mProjection = mProjectionTransform * mFOVScale * mShear;
	
	/////// Setup the view frustum points in camera space.
	
	float xNearZ, yNearZ, xFarZ, yFarZ;
	xNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z;
	yNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z;
	xFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z;
	yFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z;

	pParams->m_ViewPoints[0].Init(-xNearZ, yNearZ,  pParams->m_NearZ);	// Near Top Left
	pParams->m_ViewPoints[1].Init(xNearZ,  yNearZ,  pParams->m_NearZ);	// Near Top Right
	pParams->m_ViewPoints[2].Init(-xNearZ, -yNearZ, pParams->m_NearZ);	// Near Bottom Left
	pParams->m_ViewPoints[3].Init(xNearZ,  -yNearZ, pParams->m_NearZ);	// Near Bottom Right

	pParams->m_ViewPoints[4].Init(-xFarZ, yFarZ,  pParams->m_FarZ);	// Far Top Left
	pParams->m_ViewPoints[5].Init(xFarZ,  yFarZ,  pParams->m_FarZ);	// Far Top Right
	pParams->m_ViewPoints[6].Init(-xFarZ, -yFarZ, pParams->m_FarZ);	// Far Bottom Left
	pParams->m_ViewPoints[7].Init(xFarZ,  -yFarZ, pParams->m_FarZ);	// Far Bottom Right

	// Transform them into world space.
	for(i=0; i < 8; i++)
	{
		MatVMul_InPlace_Transposed3x3(&pParams->m_mView, &pParams->m_ViewPoints[i]);
		pParams->m_ViewPoints[i] += pParams->m_Pos;
	}

	// Get the AABB of the view frustum
	pParams->m_ViewAABBMin = pParams->m_ViewPoints[0];
	pParams->m_ViewAABBMax = pParams->m_ViewPoints[0];
	for(i=1; i < 8; i++)
	{
		VEC_MIN(pParams->m_ViewAABBMin, pParams->m_ViewAABBMin, pParams->m_ViewPoints[i]);
		VEC_MAX(pParams->m_ViewAABBMax, pParams->m_ViewAABBMax, pParams->m_ViewPoints[i]);
	}

	/////// Setup the camera-space clipping planes.

	leftX = pViewBox->m_COP.x - pViewBox->m_WindowSize[0];
	rightX = pViewBox->m_COP.x + pViewBox->m_WindowSize[0];
	topY = pViewBox->m_COP.y + pViewBox->m_WindowSize[1];
	bottomY = pViewBox->m_COP.y - pViewBox->m_WindowSize[1];
	normalZ = pViewBox->m_COP.z;
	
	LTPlane CSClipPlanes[NUM_CLIPPLANES];
	CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Init(0.0f, 0.0f, 1.0f);		// Near Z
	CSClipPlanes[CPLANE_NEAR_INDEX].m_Dist = 1.0f;

	CSClipPlanes[CPLANE_FAR_INDEX].m_Normal.Init(0.0f, 0.0f, -1.0f);			// Far Z
	CSClipPlanes[CPLANE_FAR_INDEX].m_Dist = -pParams->m_FarZ;
	
	CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Init(normalZ,  0.0f, -leftX);		// Left
	CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Init(-normalZ, 0.0f, rightX);		// Right
	CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Init(0.0f,  -normalZ, topY);		// Top
	CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Init(0.0f,  normalZ, -bottomY);	// Bottom

	CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Norm();
	CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Norm();

	CSClipPlanes[CPLANE_LEFT_INDEX].m_Dist = CSClipPlanes[CPLANE_RIGHT_INDEX].m_Dist = 0.0f;
	CSClipPlanes[CPLANE_TOP_INDEX].m_Dist = CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Dist = 0.0f;

	// Now setup the world space clipping planes.
	mBackTransform = pParams->m_mView;
	MatTranspose3x3(&mBackTransform);
	for(i=0; i < NUM_CLIPPLANES; i++)
	{
		if(i != CPLANE_NEAR_INDEX && i != CPLANE_FAR_INDEX)
		{
			MatVMul_3x3(&pParams->m_ClipPlanes[i].m_Normal, &mBackTransform, &CSClipPlanes[i].m_Normal);
			pParams->m_ClipPlanes[i].m_Dist = pParams->m_ClipPlanes[i].m_Normal.Dot(pParams->m_Pos);
		}
	}

	// The Z planes need to be handled a little differently.
	forwardVec.Init(mRotation.m[2][0], mRotation.m[2][1], mRotation.m[2][2]);

	zPlanePos = forwardVec * pViewBox->m_NearZ;
	zPlanePos += pParams->m_Pos;

	MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal, 
		&mBackTransform, &CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal);

	pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Dist = 
		pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Dot(zPlanePos);

	zPlanePos = forwardVec * pParams->m_FarZ;
	zPlanePos += pParams->m_Pos;
	
	MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal,
		&mBackTransform, &CSClipPlanes[CPLANE_FAR_INDEX].m_Normal);

	pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Dist = 
		pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal.Dot(zPlanePos);

	// Remember AABB Corners the planes are pointing at
	for (uint32 nPlaneLoop = 0; nPlaneLoop < NUM_CLIPPLANES; ++nPlaneLoop)
	{
		pParams->m_AABBPlaneCorner[nPlaneLoop] = 
			GetAABBPlaneCorner(pParams->m_ClipPlanes[nPlaneLoop].m_Normal);
	}

	// Default the world transform to identity
	pParams->m_mInvWorld.Identity();

	//setup the environment mapping info
	pParams->m_mWorldEnvMap.SetBasisVectors(&pParams->m_Right, &pParams->m_Up, &pParams->m_Forward);

	//turn off glowing by default
	pParams->m_eRenderMode = eMode;

	d3d_SetupSkyStuff(g_pSceneDesc->m_SkyDef, pParams);
	return true;
}