예제 #1
0
    bool DiCullNode::IsIn( DiAABB &box )
    {
        if (box.IsNull()) 
        {
            return false;
        }

        if (box.IsInfinite())
        {
            return true;
        }

        DiVec3 center = mWorldAABB.GetMaximum().midPoint( mWorldAABB.GetMinimum() );

        DiVec3 bmin = box.GetMinimum();
        DiVec3 bmax = box.GetMaximum();

        bool centre = ( bmax > center && bmin < center );
        if (!centre)
        {
            return false;
        }

        DiVec3 octreeSize = bmax - bmin;
        DiVec3 nodeSize = mWorldAABB.GetMaximum() - mWorldAABB.GetMinimum();
        return nodeSize < octreeSize;
    }
예제 #2
0
    //-----------------------------------------------------------------------
    DiPlane::Side DiPlane::getSide (const DiAABB& box) const
    {
        if (box.IsNull()) 
            return NO_SIDE;
        if (box.IsInfinite())
            return BOTH_SIDE;

        return getSide(box.GetCenter(), box.GetHalfSize());
    }
예제 #3
0
	void DiFocusedShadowPolicy::getShadowCamera (const DiSceneManager *sm, const DiCamera *cam, 
		const DiViewport *vp, const DiLight *light, DiCamera *texCam, size_t iteration) const
	{
		// check availability - viewport not needed
		DI_ASSERT_MESSAGE(sm != NULL, "SceneManager is NULL");
		DI_ASSERT_MESSAGE(cam != NULL, "Camera (viewer) is NULL");
		DI_ASSERT_MESSAGE(light != NULL, "Light is NULL");
		DI_ASSERT_MESSAGE(texCam != NULL, "Camera (texture) is NULL");
		mLightFrustumCameraCalculated = false;

		texCam->SetNearClipDistance(light->DeriveShadowNearClipDistance(cam));
		texCam->SetFarClipDistance(light->DeriveShadowFarClipDistance(cam));

		// calculate standard shadow mapping matrix
		DiMat4 LView, LProj;
		calculateShadowMappingMatrix(*sm, *cam, *light, &LView, &LProj, NULL);

		// build scene bounding box
		auto& visInfo = texCam->GetVisBoundsInfo();
		DiAABB sceneBB = visInfo.aabb;
		DiAABB receiverAABB = cam->GetVisBoundsInfo().receiverAabb;
		sceneBB.Merge(receiverAABB);
		sceneBB.Merge(cam->GetDerivedPosition());

		// in case the sceneBB is empty (e.g. nothing visible to the cam) simply
		// return the standard shadow mapping matrix
		if (sceneBB.IsNull())
		{
			texCam->SetCustomViewMatrix(true, LView);
			texCam->SetCustomProjectionMatrix(true, LProj);
			return;
		}

		// calculate the intersection body B
		mPointListBodyB.reset();
		calculateB(*sm, *cam, *light, sceneBB, receiverAABB, &mPointListBodyB);

		// in case the bodyB is empty (e.g. nothing visible to the light or the cam)
		// simply return the standard shadow mapping matrix
		if (mPointListBodyB.getPointCount() == 0)
		{
			texCam->SetCustomViewMatrix(true, LView);
			texCam->SetCustomProjectionMatrix(true, LProj);
			return;
		}

		// transform to light space: y -> -z, z -> y
		LProj = msNormalToLightSpace * LProj;

		// calculate LVS so it does not need to be calculated twice
		// calculate the body L \cap V \cap S to make sure all returned points are in 
		// front of the camera
		mPointListBodyLVS.reset();
		calculateLVS(*sm, *cam, *light, sceneBB, &mPointListBodyLVS);

		// fetch the viewing direction
		const DiVec3 viewDir = getLSProjViewDir(LProj * LView, *cam, mPointListBodyLVS);

		// The light space will be rotated in such a way, that the projected light view 
		// always points upwards, so the up-vector is the y-axis (we already prepared the
		// light space for this usage).The transformation matrix is set up with the
		// following parameters:
		// - position is the origin
		// - the view direction is the calculated viewDir
		// - the up vector is the y-axis
		LProj = buildViewMatrix(DiVec3::ZERO, viewDir, DiVec3::UNIT_Y) * LProj;

		// map bodyB to unit cube
		LProj = transformToUnitCube(LProj * LView, mPointListBodyB) * LProj;

		// transform from light space to normal space: y -> z, z -> -y
		LProj = msLightSpaceToNormal * LProj;

		// set the two custom matrices
		texCam->SetCustomViewMatrix(true, LView);
		texCam->SetCustomProjectionMatrix(true, LProj);
	}