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); }
//----------------------------------------------------------------------- void LiSPSMShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, const Viewport *vp, const Light *light, Camera *texCam) const { // check availability - viewport not needed OgreAssert(sm != NULL, "SceneManager is NULL"); OgreAssert(cam != NULL, "Camera (viewer) is NULL"); OgreAssert(light != NULL, "Light is NULL"); OgreAssert(texCam != NULL, "Camera (texture) is NULL"); mLightFrustumCameraCalculated = false; // calculate standard shadow mapping matrix Matrix4 LView, LProj; calculateShadowMappingMatrix(*sm, *cam, *light, &LView, &LProj, NULL); // build scene bounding box const VisibleObjectsBoundsInfo& visInfo = sm->getShadowCasterBoundsInfo(light); AxisAlignedBox sceneBB = visInfo.aabb; sceneBB.merge(sm->getVisibleObjectsBoundsInfo(cam).aabb); 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, &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 calculateLVS(*sm, *cam, *light, sceneBB, &mPointListBodyLVS); // fetch the viewing direction const Vector3 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(Vector3::ZERO, viewDir, Vector3::UNIT_Y) * LProj; // calculate LiSPSM projection LProj = calculateLiSPSM(LProj * LView, mPointListBodyB, mPointListBodyLVS, *sm, *cam, *light) * 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; // LView = Lv^-1 // LProj = Switch_{-ls} * FocusBody * P * L_r * Switch_{ls} * L_p texCam->setCustomViewMatrix(true, LView); texCam->setCustomProjectionMatrix(true, LProj); }
void setup(Args *args, B_matrix *B, C_matrix *c){ mwIndex i; Count count = {0}; mwIndex numBlocks = 0; mwIndex n = args->n; mwIndex* coreBlocks2, *new_perm; B->invDiag = 0; for (i = 0 ; i < n ; i++){ if (args->map[i] > numBlocks){ numBlocks = args->map[i]; } } numBlocks++; coreBlocks2 = (mwIndex*) malloc((numBlocks+1) * sizeof (mwIndex)); new_perm = (mwIndex*) malloc(n * sizeof (mwIndex)); for (i = 0 ; i < (numBlocks+1); i++){ coreBlocks2[i]=0; } for (i = 0 ; i < n ; i++){ coreBlocks2[args->map[i]+1]++ ; } for (i = 1 ; i < (numBlocks+1); i++){ coreBlocks2[i]=coreBlocks2[i] + coreBlocks2[i-1]; } for (i = 0 ; i < n ; i++){ new_perm[coreBlocks2[args->map[i]]] = i; coreBlocks2[args->map[i]]++; } for (i = 0 ; i < (numBlocks+1); i++){ coreBlocks2[i]=0; } for (i = 0 ; i < n ; i++){ coreBlocks2[args->map[i]+1]++ ; } for (i = 1 ; i < (numBlocks+1); i++){ coreBlocks2[i]=coreBlocks2[i] + coreBlocks2[i-1]; } coreBlocks2[numBlocks] = n; args->coreBlocks = coreBlocks2; args->perm = new_perm; args->numCoreBlocks = numBlocks; args->reversed_perm = (mwIndex*) malloc(args->n * sizeof (mwIndex)); c->blocks = (mwIndex*) malloc(sizeof(mwIndex)*(args->numCoreBlocks*args->numCoreBlocks+1)); B->vc_idx = 0; B->starts = (mwIndex*)malloc((n+1) * sizeof (mwIndex)); for(i = 0; i < n ; i++){ args->reversed_perm[args->perm[i]] = i; } for(i = 0; i < (args->numCoreBlocks*args->numCoreBlocks+1); i++){ c->blocks[i] = 0; } count_ans_create_C_blocks(args, c, &count); // note that currently, the size of block ij is held at C_blocks[i*args.numCoreBlocks+j+1] c->cols = (idx_type*)malloc(count.ans_C * sizeof (idx_type)); c->rows = (idx_type*)malloc(count.ans_C * sizeof (idx_type)); c->vals = (double*)malloc(count.ans_C * sizeof (double)); if(args->type){ B->cols = (idx_type*) malloc(count.ans_B * sizeof (idx_type)); B->vals = (double*) malloc(count.ans_B * sizeof (double)); calculateB(args, B, c, &count); } else{ B->cols = (idx_type*)malloc(count.ans_B_lower * sizeof (idx_type)); B->vals = (double*)malloc(count.ans_B_lower * sizeof (double)); calculateBLower(args, B, c, &count); } }