Esempio n. 1
0
	DiVec3 DiFocusedShadowPolicy::getNearCameraPoint_ws(const DiMat4& viewMatrix, 
		const PointListBody& bodyLVS) const
	{
		if (bodyLVS.getPointCount() == 0)
			return DiVec3(0,0,0);

		DiVec3 nearEye = viewMatrix * bodyLVS.getPoint(0),	// for comparison
			nearWorld = bodyLVS.getPoint(0);				// represents the final point

		// store the vertex with the highest z-value which is the nearest point
		for (size_t i = 1; i < bodyLVS.getPointCount(); ++i)
		{
			const DiVec3& vWorld = bodyLVS.getPoint(i);

			// comparison is done from the viewer
			DiVec3 vEye = viewMatrix * vWorld;

			if (vEye.z > nearEye.z)
			{
				nearEye		= vEye;
				nearWorld	= vWorld;
			}
		}

		return nearWorld;
	}
Esempio n. 2
0
	DiMat4 DiFocusedShadowPolicy::transformToUnitCube(const DiMat4& m, 
		const PointListBody& body) const
	{
		// map the transformed body AAB points to the unit cube (-1/-1/-1) / (+1/+1/+1) corners
		DiAABB aab_trans;

		for (size_t i = 0; i < body.getPointCount(); ++i)
		{
			aab_trans.Merge(m * body.getPoint(i));
		}

		DiVec3 vMin, vMax;

		vMin = aab_trans.GetMinimum();
		vMax = aab_trans.GetMaximum();

		const DiVec3 trans(-(vMax.x + vMin.x) / (vMax.x - vMin.x),
			-(vMax.y + vMin.y) / (vMax.y - vMin.y),
			-(vMax.z + vMin.z) / (vMax.z - vMin.z));

		const DiVec3 scale(2 / (vMax.x - vMin.x),
			2 / (vMax.y - vMin.y),
			2 / (vMax.z - vMin.z));

		DiMat4 mOut(DiMat4::IDENTITY);
		mOut.setTrans(trans);
		mOut.setScale(scale);

		return mOut;
	}
	//-----------------------------------------------------------------------
	Matrix4 FocusedShadowCameraSetup::transformToUnitCube(const Matrix4& m, 
		const PointListBody& body) const
	{
		// map the transformed body AAB points to the unit cube (-1/-1/-1) / (+1/+1/+1) corners
		AxisAlignedBox aab_trans;

		for (size_t i = 0; i < body.getPointCount(); ++i)
		{
			aab_trans.merge(m * body.getPoint(i));
		}

		Vector3 vMin, vMax;

		vMin = aab_trans.getMinimum();
		vMax = aab_trans.getMaximum();

		const Vector3 trans(-(vMax.x + vMin.x) / (vMax.x - vMin.x),
			-(vMax.y + vMin.y) / (vMax.y - vMin.y),
			-(vMax.z + vMin.z) / (vMax.z - vMin.z));

		const Vector3 scale(2 / (vMax.x - vMin.x),
			2 / (vMax.y - vMin.y),
			2 / (vMax.z - vMin.z));

		Matrix4 mOut(Matrix4::IDENTITY);
		mOut.setTrans(trans);
		mOut.setScale(scale);

		return mOut;
	}
Esempio n. 4
0
	void DiFocusedShadowPolicy::PointListBody::merge(const PointListBody& plb)
	{
		size_t size = plb.getPointCount();
		for (size_t i = 0; i < size; ++i)
		{
			this->addPoint(plb.getPoint(i));
		}
	}
	//-----------------------------------------------------------------------
	Matrix4 LiSPSMShadowCameraSetup::calculateLiSPSM(const Matrix4& lightSpace, 
		const PointListBody& bodyB, const PointListBody& bodyLVS,
		const SceneManager& sm, const Camera& cam, const Light& light) const
	{
		// set up bodyB AAB in light space
		AxisAlignedBox bodyBAAB_ls;
		for (size_t i = 0; i < bodyB.getPointCount(); ++i)
		{
			bodyBAAB_ls.merge(lightSpace * bodyB.getPoint(i));
		}

		// near camera point in light space
		const Vector3 e_ls = lightSpace * getNearCameraPoint_ws(cam.getViewMatrix(), bodyLVS);

		// C_start has x and y of e and z from the bodyABB_ls (we look down the negative z axis, so take the maximum z value)
		const Vector3 C_start_ls(e_ls.x, e_ls.y, bodyBAAB_ls.getMaximum().z);

		// calculate the optimal distance between origin and near plane
		Real n_opt;

		if (mUseSimpleNOpt)
			n_opt = calculateNOptSimple(bodyLVS, cam);
		else
			n_opt = calculateNOpt(lightSpace, bodyBAAB_ls, bodyLVS, cam);

		// in case n_opt is null, uniform shadow mapping will be done
		if (n_opt <= 0.0)
		{
			return Matrix4::IDENTITY;
		}

		// calculate the projection center C which is n units behind the near plane of P
		// we look into the negative z direction so add n
		const Vector3 C(C_start_ls + n_opt * Vector3::UNIT_Z);

		// set up a transformation matrix to transform the light space to its new origin
		Matrix4 lightSpaceTranslation(Matrix4::IDENTITY);
		lightSpaceTranslation.setTrans(-C);

		// range from bMin to bMax; d = |B_z_far - B_z_near|
		Real d = Math::Abs(bodyBAAB_ls.getMaximum().z - bodyBAAB_ls.getMinimum().z);

		// set up the LiSPSM perspective transformation
		// build up frustum to map P onto the unit cube with (-1/-1/-1) and (+1/+1/+1)
		Matrix4 P = buildFrustumProjection(-1, 1, -1, 1, n_opt, n_opt + d);

		return P * lightSpaceTranslation;
	}