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; }
//----------------------------------------------------------------------- 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()); }
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); }