/* !!! FONCTION INUTILISEE !!! */ void CscScaling(CscMatrix *cscmtx, PASTIX_FLOAT *transcsc, PASTIX_FLOAT *rhs, PASTIX_FLOAT *rhs2) { const PASTIX_INT itercscf=0; PASTIX_INT itercol; PASTIX_INT iterval; PASTIX_FLOAT *rowscal; PASTIX_FLOAT *colscal; #ifdef CSC_LOG fprintf(stdout, "-> CscScaling \n"); #endif rowscal = (PASTIX_FLOAT *) memAlloc(CSC_COLNBR(cscmtx,0)*sizeof(PASTIX_FLOAT)); colscal = (PASTIX_FLOAT *) memAlloc(CSC_COLNBR(cscmtx,0)*sizeof(PASTIX_FLOAT)); for (itercol=0; itercol<CSC_COLNBR(cscmtx,itercscf); itercol++) { rowscal[itercol] = 0; colscal[itercol] = 0; } /* Compute Scaling */ for (itercol=0; itercol<CSC_COLNBR(cscmtx,itercscf); itercol++) { for (iterval=CSC_COL(cscmtx,itercscf,itercol); iterval<CSC_COL(cscmtx,itercscf,itercol+1); iterval++) { colscal[itercol] += ABS_FLOAT(CSC_VAL(cscmtx,iterval)); rowscal[CSC_ROW(cscmtx,iterval)] += ABS_FLOAT(CSC_VAL(cscmtx,iterval)); } } /* Apply Scaling */ for (itercol=0; itercol<CSC_COLNBR(cscmtx,itercscf); itercol++) { for (iterval=CSC_COL(cscmtx,itercscf,itercol); iterval<CSC_COL(cscmtx,itercscf,itercol+1); iterval++) { CSC_VAL(cscmtx,iterval) /= colscal[itercol]; CSC_VAL(cscmtx,iterval) /= rowscal[CSC_ROW(cscmtx,iterval)]; if (transcsc != NULL) { transcsc[iterval] /= rowscal[itercol]; transcsc[iterval] /= colscal[CSC_ROW(cscmtx,iterval)]; } } if (rhs != NULL) rhs[itercol] /= rowscal[itercol]; if (rhs2 != NULL) rhs2[itercol] *= colscal[itercol]; } memFree_null(rowscal); memFree_null(colscal); #ifdef CSC_LOG fprintf(stdout, "<- CscScaling \n"); #endif }
/* * Function: PASTIX_potrf * * Factorization LLt BLAS2 3 terms * * > A = LL^T * * Parameters: * A - Matrix to factorize * n - Size of A * stride - Stide between 2 columns of the matrix * nbpivot - IN/OUT pivot number. * critere - Pivoting threshold. * */ void PASTIX_potrf (PASTIX_FLOAT * A, PASTIX_INT n, PASTIX_INT stride, PASTIX_INT *nbpivot, double critere) { PASTIX_INT k; PASTIX_FLOAT *tmp,*tmp1; for (k=0;k<n;k++) { tmp=A+k* (stride+1); #ifdef USE_CSC if (ABS_FLOAT(*tmp)<critere) { (*tmp) = (PASTIX_FLOAT)critere; (*nbpivot)++; } #endif #ifdef TYPE_COMPLEX *tmp = (PASTIX_FLOAT)csqrt(*tmp); #else *tmp = (PASTIX_FLOAT)sqrt(*tmp); if (*tmp < 0) { errorPrint ("Negative diagonal term\n"); EXIT (MOD_SOPALIN, INTERNAL_ERR); } #endif tmp1=tmp+1; SOPALIN_SCAL (n-k-1,(fun/(*tmp)),tmp1,iun); SOPALIN_SYR ("L",n-k-1,-fun,tmp1,iun,tmp1+stride,stride); } }
/* * Function: PASTIX_getrf * * LU Factorization of one (diagonal) block * $A = LU$ * * For each column : * - Divide the column by the diagonal element. * - Substract the product of the subdiagonal part by * the line after the diagonal element from the * matrix under the diagonal element. * * Parameters: * A - Matrix to factorize * m - number of rows of the Matrix A * n - number of cols of the Matrix A * stride - Stide between 2 columns of the matrix * nbpivot - IN/OUT pivot number. * critere - Pivoting threshold. */ void PASTIX_getrf ( PASTIX_FLOAT *A, PASTIX_INT m, PASTIX_INT n, PASTIX_INT stride, PASTIX_INT *nbpivot, double critere) { PASTIX_INT j; PASTIX_FLOAT *tmp; PASTIX_FLOAT *tmp1; for (j=0; j<MIN(m,n); j++) { tmp = A + j* (stride+1); /* A[j][j] */ tmp1 = tmp+1; /* A[j+1][j] */ #ifdef USE_CSC if (ABS_FLOAT(*tmp) < critere) { (*tmp) = (PASTIX_FLOAT)critere; (*nbpivot)++; } #endif /* A[k][j] = A[k][j]/A[j] (j], k = j+1 .. n */ SOPALIN_SCAL ((m-j-1), (fun/(*tmp)), tmp1, iun); if (j +1 < MIN(m,n)) { /* A[k][l] = A[k][l] - A[k][j]*A[j,l] , k,l = j+1..n*/ SOPALIN_GER ((m-j-1), (n-j-1), -fun, tmp1, iun, tmp+stride, stride, tmp+stride+1, stride); } } /* Test sur la dernier valeur diag */ tmp = A + (n-1)*(stride+1); #ifdef USE_CSC if (ABS_FLOAT(*tmp) < critere) { (*tmp) = (PASTIX_FLOAT)critere; (*nbpivot)++; } #endif }
/* * Function: PASTIX_hetrf * * Factorization LDLt BLAS2 3 terms. * * In complex : A is hermitian. * * > A = LDL^T * * Parameters: * A - Matrix to factorize * n - Size of A * stride - Stide between 2 columns of the matrix * nbpivot - IN/OUT pivot number. * critere - Pivoting threshold. */ void PASTIX_hetrf ( PASTIX_FLOAT * A, PASTIX_INT n, PASTIX_INT stride, PASTIX_INT *nbpivot, double critere) { PASTIX_INT k; PASTIX_FLOAT *tmp,*tmp1; for (k=0;k<n;k++) { tmp=A+k* (stride+1); #ifdef USE_CSC if (ABS_FLOAT(*tmp)<critere) { (*tmp) = (PASTIX_FLOAT)critere; (*nbpivot)++; } #endif tmp1=tmp+1; SOPALIN_SCAL (n-k-1,(fun/(*tmp)),tmp1,iun); SOPALIN_HER ("L",n-k-1,-(*tmp),tmp1,iun,tmp1+stride,stride); } }
/* !!! INUTILISEE, non testee !!! */ void CscDiagDom(CscMatrix *cscmtx) { PASTIX_INT itercblk; PASTIX_INT itercoltab; PASTIX_INT iterval; PASTIX_INT itercol=0; PASTIX_INT diag=0; double sum41; #ifdef CSC_LOG fprintf(stdout, "-> CscDiagDom \n"); #endif for (itercblk=0; itercblk<CSC_FNBR(cscmtx); itercblk++) { for (itercoltab=0; itercoltab<CSC_COLNBR(cscmtx,itercblk); itercoltab++) { sum41 = 0; for (iterval=CSC_COL(cscmtx,itercblk,itercoltab); iterval<CSC_COL(cscmtx,itercblk,itercoltab+1); iterval++) { if (CSC_ROW(cscmtx,iterval) != itercol) sum41 += ABS_FLOAT(CSC_VAL(cscmtx,iterval)); else diag = iterval; } CSC_VAL(cscmtx,diag) = sum41+1; itercol++; } } #ifdef CSC_LOG fprintf(stdout, "<- CscDiagDom \n"); #endif }
/* !!! FONCTION INUTILISEE !!! */ void CscScaling2(char *Type, PASTIX_INT Ncol, PASTIX_INT *col, PASTIX_INT *row, PASTIX_FLOAT *val, PASTIX_FLOAT *rhs, PASTIX_FLOAT *rhs2) { PASTIX_INT itercol; PASTIX_INT iterval; PASTIX_FLOAT *rowscal; PASTIX_FLOAT *colscal; const PASTIX_INT flag = (Type[1] != 'S'); #ifdef CSC_LOG fprintf(stdout, "-> CscScaling2 \n"); #endif if (flag) rowscal = (PASTIX_FLOAT *) memAlloc(Ncol*sizeof(PASTIX_FLOAT)); else rowscal = NULL; colscal = (PASTIX_FLOAT *) memAlloc(Ncol*sizeof(PASTIX_FLOAT)); if (flag) if (rowscal == NULL) errorPrint( "CscScaling2 : Not enough memory for rowscal\n"); if (colscal == NULL) errorPrint( "CscScalign2 : Nto enough memory for colscal\n"); for (itercol=0; itercol<Ncol; itercol++) { if (flag) rowscal[itercol] = 0; colscal[itercol] = 0; } for (itercol=0; itercol<Ncol; itercol++) { for (iterval=col[itercol]; iterval<col[itercol+1]; iterval++) { colscal[itercol] += ABS_FLOAT(val[iterval-1]); if (flag) rowscal[row[iterval-1]-1] += ABS_FLOAT(val[iterval-1]); } } for (itercol=0; itercol<Ncol; itercol++) { for (iterval=col[itercol]; iterval<col[itercol+1]; iterval++) { val[iterval-1] /= colscal[itercol]; if (flag) val[iterval-1] /= rowscal[row[iterval-1]-1]; else val[iterval-1] /= colscal[itercol]; } if (rhs != NULL) { if (flag) rhs[itercol] /= rowscal[itercol]; else rhs[itercol] /= colscal[itercol]; } if (rhs2 != NULL) rhs2[itercol] *= colscal[itercol]; } if (flag) memFree_null(rowscal); memFree_null(colscal); #ifdef CSC_LOG fprintf(stdout, "<- CscScaling2 \n"); #endif }
Vector Raytracer::shade(Ray const &ray, int &rayDepth, Intersection const &intersection, Material const &material, Scene const &scene) { // - iterate over all lights, calculating ambient/diffuse/specular contribution // - use shadow rays to determine shadows // - integrate the contributions of each light // - include emission of the surface material // - call Raytracer::trace for reflection/refraction colors // Don't reflect/refract if maximum ray recursion depth has been reached! //!!! USEFUL NOTES: attenuate factor = 1.0 / (a0 + a1 * d + a2 * d * d)..., ambient light doesn't attenuate, nor does it affected by shadow //!!! USEFUL NOTES: don't accept shadow intersection far away than the light position //!!! USEFUL NOTES: for each kind of ray, i.e. shadow ray, reflected ray, and primary ray, the accepted furthest depth are different Vector diffuse(0); Vector ambient(0); Vector specular(0); Vector v = -ray.direction.normalized(); Vector n = intersection.normal.normalized(); Vector reflect = (-v + 2 * v.dot(n) * n).normalized(); for (auto lightIter = scene.lights.begin(); lightIter != scene.lights.end(); lightIter++) { // @@@@@@ YOUR CODE HERE // calculate local illumination here, remember to add all the lights together // also test shadow here, if a point is in shadow, multiply its diffuse and specular color by (1 - material.shadow) Vector l = (lightIter->position - intersection.position).normalized(); Vector r = (-l + 2 * n.dot(l)*n).normalized(); Vector view = (scene.camera.position - intersection.position).normalized(); double d = //(intersection.position - ray.origin).length()+ (lightIter->position - intersection.position).length(); double attenuation = 1.0 / (lightIter->ambient[0] + d*lightIter->attenuation[1] +d *d*lightIter->attenuation[2]); Ray shadowRay = Ray(intersection.position + (lightIter->position - intersection.position).normalized()* 1e-6,(lightIter->position - intersection.position).normalized()); Intersection hit = intersection; bool isShadow = false; Vector delAmbient = material.ambient * lightIter->ambient; Vector delDiffuse = material.diffuse * lightIter->diffuse * max(0.0, n.dot(l)) * attenuation; Vector delSpecular = material.specular * lightIter->specular * pow(max(0.0, r.dot(view)), material.shininess) * attenuation; for (int x = 0; x< scene.objects.size(); x++) { if (scene.objects[x]->intersect(shadowRay, hit)) { isShadow = true; } } if (isShadow) { ambient += delAmbient; diffuse += delDiffuse * (1 - material.shadow); specular += delSpecular * (1 - material.shadow); } else { ambient += delAmbient; diffuse += delDiffuse; specular += delSpecular; } } Vector reflectedLight(0); if ((!(ABS_FLOAT(material.reflect) < 1e-6)) && (rayDepth < MAX_RAY_RECURSION)) { // @@@@@@ YOUR CODE HERE // calculate reflected color using trace() recursively Ray reflect_ray(intersection.position + reflect*1e-6, reflect); double depth = DBL_MAX; trace(reflect_ray, rayDepth, scene, reflectedLight, depth); } return material.emission + ambient + diffuse + specular + material.reflect * reflectedLight; }
Vector Raytracer::shade(Ray const &ray, int &rayDepth, Intersection const &intersection, Material const &material, Scene const &scene) { // - iterate over all lights, calculating ambient/diffuse/specular contribution // - use shadow rays to determine shadows // - integrate the contributions of each light // - include emission of the surface material // - call Raytracer::trace for reflection/refraction colors // Don't reflect/refract if maximum ray recursion depth has been reached! //!!! USEFUL NOTES: attenuate factor = 1.0 / (a0 + a1 * d + a2 * d * d)..., ambient light doesn't attenuate, nor does it affected by shadow //!!! USEFUL NOTES: don't accept shadow intersection far away than the light position //!!! USEFUL NOTES: for each kind of ray, i.e. shadow ray, reflected ray, and primary ray, the accepted furthest depth are different Vector diffuse(0); Vector ambient(0); Vector specular(0); Vector refractedLight(0); for (auto lightIter = scene.lights.begin(); lightIter != scene.lights.end(); lightIter++) { // calculate local illumination here, remember to add all the lights together // also test shadow here, if a point is in shadow, multiply its diffuse and specular color by (1 - material.shadow) Vector newAmbient = (lightIter->ambient * material.ambient); Vector normalI = intersection.normal.normalized(); Vector incomingLight = (lightIter->position - intersection.position).normalized(); float diffuseDot = max(normalI.dot(incomingLight), 0.0); Vector newDiffuse = (diffuseDot * material.diffuse * lightIter->diffuse); Vector reflectedLight = (-2 * (incomingLight.dot(normalI))* normalI + incomingLight).normalized(); Vector viewVector = ray.direction.normalized(); float specularDot = max(viewVector.dot(reflectedLight), 0.0); Vector newSpecular = (pow(specularDot, material.shininess) * material.specular * lightIter->specular); // create shadow ray Intersection shdHit; Ray shadowRay = Ray((intersection.position + (incomingLight * 0.000001)), incomingLight); double lightDist = (lightIter->position - intersection.position).length(); shdHit.depth = lightDist; bool hitShadow = false; for(auto it = scene.objects.begin(); it != scene.objects.end(); ++ it) { Object * curObj = *it; if (curObj->intersect(shadowRay, shdHit)) { hitShadow = true; } } double attFactor = (lightIter->attenuation[0] + lightIter->attenuation[1] * lightDist + lightIter->attenuation[2] * lightDist * lightDist); if (hitShadow) { newSpecular = newSpecular * (1 - material.shadow); newDiffuse = newDiffuse * (1 - material.shadow); } newSpecular = newSpecular / attFactor; newDiffuse = newDiffuse / attFactor; specular += newSpecular; ambient += newAmbient; diffuse += newDiffuse; } Vector reflectedLight(0); if ((!(ABS_FLOAT(material.reflect) < 1e-6)) && (rayDepth < MAX_RAY_RECURSION)) { if (!ray.refracting) { //inside a refracting object // calculate reflected color using trace() recursively Vector normalI = intersection.normal.normalized(); Vector reflectedDir = (-2 * (ray.direction.dot(normalI))* normalI + ray.direction).normalized(); Ray reflectRay = Ray((intersection.position + (reflectedDir * 0.000001)), reflectedDir); double superdepth = DBL_MAX; trace(reflectRay, rayDepth, scene, reflectedLight, superdepth); } } if ((!(ABS_FLOAT(material.refract) < 1e-6)) && (rayDepth < MAX_RAY_RECURSION)) { Vector normalI = intersection.normal.normalized(); double refractn = 1.0; if (ray.refracting) { //inside a refracting object refractn = material.rfrIndex / 1.0; } else { refractn = 1.0 / material.rfrIndex; } double cosI = normalI.dot(ray.direction); double sinT2 = refractn * refractn * (1.0 - cosI * cosI); if (sinT2 <= 1.0) { Vector refractDir = refractn * ray.direction - (refractn + sqrt(1.0 - sinT2)) * normalI; Ray refractRay = Ray((intersection.position + (refractDir * 0.001)), refractDir, !(ray.refracting)); double superdepth = DBL_MAX; trace(refractRay, rayDepth, scene, refractedLight, superdepth); } } return material.emission + ambient + diffuse + specular + material.reflect * reflectedLight + material.refract * refractedLight; }