Beispiel #1
0
void ModelPreviewCanvas::AddjustCameraPos()
{
	_Assert(mCamera != NULL);
	_Assert(mModel != NULL);

	AABBox bound;
	mModel->CalcDynamicAABBox(IDENTITY_MATRIX, &bound);

	float width = bound.GetSize().x;
	float height = bound.GetSize().y;
	float length = bound.GetSize().z;

	float aspect = 0;
	float fov = 0;
	mCamera->GetCameraParams(NULL, NULL, &fov, &aspect);

	float distY = (height / 2.0f) / tan(fov / 2.0f);
	float distX = (height / 2.0f) / (aspect * tan(fov / 2.0f));

	float dist = Max(distX, distY);

	mCamera->SetWorldPosition(bound.GetCenter());
	mCamera->Translate(0, 0, -dist - length);
	mCamera->LookAt(bound.GetCenter());

	HoverCameraController* hoverCameraController = New HoverCameraController(5.0f, 20.0f, -4*PI/9, 4*PI/9, 
		2.0f, 1000.0f, bound.GetCenter(), dist + length);

	mCamera->SetCameraController(hoverCameraController);
}
Beispiel #2
0
void ShadowMapRenderer::setupVirtualLightCamera(Camera* camera, DirectionalLightNode* lightNode, int cascadeIndex)
{
	const float BOUND_EXPAND_FACTOR = 0.8f;

	_Assert(camera != NULL);
	_Assert(cascadeIndex >= 0 && cascadeIndex < CASCADE_COUNTS);

	DirectionalLight* dirLight = lightNode->GetDirLight();
	Vector3 lightDir = dirLight->GetDirection();
	lightDir.Normalize();

	Vector3 frustumPos[5];
	{
		float farZ = 0;
		float aspect = 0;
		float fov = 0;

		camera->GetCameraParams(NULL, &farZ, &fov, &aspect);
		farZ *= calcCascadeDist(cascadeIndex);


		float fy = farZ * tanf(fov / 2.0f);
		float fx = aspect * fy;

		frustumPos[0] = Vector3::Zero;
		frustumPos[1] = Vector3(-fx,  fy, farZ);
		frustumPos[2] = Vector3( fx,  fy, farZ);
		frustumPos[3] = Vector3(-fx, -fy, farZ);
		frustumPos[4] = Vector3( fx, -fy, farZ);
	}

	D3DXMATRIX matCameraViewInv;
	D3DXMatrixInverse(&matCameraViewInv, 0, &camera->ViewMatrix());

	D3DXMATRIX matLightView;
	{
		Vector3 lightPos = lightNode->GetWorldPosition();

		D3DXMATRIX matRotTranspose, matTransInverse;
		D3DXMatrixTranspose(&matRotTranspose, &(lightNode->GetWorldOrient().Matrix()));
		D3DXMatrixTranslation(&matTransInverse, -lightPos.x, -lightPos.y, -lightPos.z);
		matLightView = matTransInverse * matRotTranspose; 
	}

	AABBox lightSpaceBound;
	for(int i = 0; i < 5; ++i)
	{
		Vector3 posW = PosVecTransform(frustumPos[i], matCameraViewInv);
		Vector3	posL = PosVecTransform(posW, matLightView);	

		lightSpaceBound = AABBox::CombinePoint(lightSpaceBound, posL);
	}

	float nearZ = 0.1f;
	float farZ = 0;
	float width = 0;
	float height = 0;
	{
		Vector3 lookDir = camera->GetWorldForward();
		lookDir.Normalize();

		float adjustFactor = lookDir.Dot(lightDir);		// lookDir与lightDir贴近时, 向后扩展virtualCamera范围
		float expandDist = adjustFactor * BOUND_EXPAND_FACTOR * fabsf(lightSpaceBound.mMax.z - lightSpaceBound.mMin.z);

		Vector3 centerL = lightSpaceBound.GetCenter();
		D3DXMATRIX matLightViewInv;
		D3DXMatrixInverse(&matLightViewInv, 0, &matLightView);

		Vector3 centerW = PosVecTransform(centerL, matLightViewInv);
		float lightDist = fabsf(lightSpaceBound.mMax.z - lightSpaceBound.mMin.z) / 2.0f;
		width = fabsf(lightSpaceBound.mMax.x - lightSpaceBound.mMin.x);
		height = fabsf(lightSpaceBound.mMax.y - lightSpaceBound.mMin.y);

		farZ = 2.0f * lightDist + expandDist;
		mVirtualCamera[cascadeIndex].pos = centerW - (lightDist + expandDist) * lightDir;
	}

	D3DXMATRIX matLightProj;
	D3DXMatrixOrthoLH(&matLightProj, width, height, nearZ, farZ);

	D3DXMATRIX matVirtualCameraView;
	{
		Vector3 virtualCameraPos = mVirtualCamera[cascadeIndex].pos;

		D3DXMATRIX matRotTranspose, matTransInverse;
		D3DXMatrixTranspose(&matRotTranspose, &(lightNode->GetWorldOrient().Matrix()));
		D3DXMatrixTranslation(&matTransInverse, -virtualCameraPos.x, -virtualCameraPos.y, -virtualCameraPos.z);
		matVirtualCameraView = matTransInverse * matRotTranspose; 

		mVirtualCamera[cascadeIndex].bound = AABBox::MatTransform(AABBox(Vector3(0, 0, farZ/2.0f), width, height, farZ), 
			InversedMatrix(matVirtualCameraView));
	}

	mVirtualCamera[cascadeIndex].matVP = matVirtualCameraView * matLightProj;
}