void BunishData::bunish() { pos += bunish_vec; radian += rot_speed; compute_world_mat(); #ifdef NDEBUG compute_z(); #endif }
void Surface::stop_photon(Photon& p) { if (p.is_valid()==false) return; if(isinf(_dCurvature)) { p.valid=false; return; } // flat case (intersect with z=0) if (p.dz==0.) { // TODO p.valid=false; return; } double tmin=-p.z/p.dz; if(_bIsFlat && (tmin<0.) ) { // in the past of the photon p.valid=false; return; } // TODO optimise in case of spherical // stop the photon in z=0 p.x+=tmin*p.dx; p.y+=tmin*p.dy; p.z=0.; if(_bIsFlat || _bIsPerfect) { p.valid=update_auto_diameter(p.x,p.y); return; } //compute the coef of the 2nd degree eq in t: //the equation is t^2A+tB+C=0 // use p.z=0. double dA=_dCurvature*(sqr(p.dx)+sqr(p.dy)+(_dConic+1.)*sqr(p.dz)); double dB=2.*(_dCurvature*(p.x*p.dx+p.y*p.dy)-p.dz); double dC=_dCurvature*(sqr(p.x)+sqr(p.y)); double tfinal; if (dA==0.) { if (dB==0.) { p.valid=false; return; } //the equation is now : t*dB+dC=0 so: tfinal=-dC/dB; } else //dA!=0 { //solve the equation double dB2=dB*dB; double delta=dB2-4.*dC*dA; if (delta<0.) { p.valid=false; return; } double t1,t2; if (delta!=dB2) // TODO enhance test { double sqrtDelta=sqrt(delta); t1=(2.*dC)/(+sqrtDelta-dB); t2=(2.*dC)/(-sqrtDelta-dB); } else { // delta~=dB2 // use approximate solution: if (dB!=0.) { t1=-dC/dB; t2=10.*t1; // to choose t1 } else { p.valid=false; // bug if we are here return; } } // select t that gives the lowest abs(z) //t1ok=abs(z+t1.*dz)<abs(z+t2.*dz); //oct ver if (t1*t1<t2*t2) // todo optimize tfinal=t1; else tfinal=t2; } // check if intersection is in the futur of the photon if ( tmin+tfinal<0 ) { p.valid=false; return; } p.x+=p.dx*tfinal; p.y+=p.dy*tfinal; p.z+=p.dz*tfinal; assert(p.is_valid()); p.valid=update_auto_diameter(p.x,p.y); if(!_bIsAspheric) return; //aspheric mode //p.x,p.y,p.z is already a good approximation of the surface (as a conic), but make some newton step double x=p.x; double y=p.y; // double z=p.z; double dOldT=0; for(int iLoop=0;iLoop<NB_ITER_STOP_NEWTON;iLoop++) { //reproject z on aspheric curve double zproj; compute_z(x,y,zproj); //compute normal on aspheric surface double nx,ny,nz; compute_normal(x,y,zproj,nx,ny,nz); //compute the d value to have the plane x*nx+y*ny+z*nz+d=0 double d=-(x*nx+y*ny+zproj*nz); //compute the intersect of this plane and the line defined by p (one newton step) double t=(-d-p.x*nx-p.y*ny-p.z*nz)/(p.dx*nx+p.dy*ny+p.dz*nz); //TODO tester !=0 double distSQ=sqr(t-dOldT)*(sqr(p.dx)+sqr(p.dy)+sqr(p.dz)); x=p.x+t*p.dx; y=p.y+t*p.dy; double z=p.z+t*p.dz; if(distSQ<sqr(RESOLUTION_STOP_NEWTON)) { p.x=x; p.y=y; p.z=z; p.valid=update_auto_diameter(p.x,p.y); return; } dOldT=t; } //too many iterations p.valid=false; return; }
LCMSHANDLE LCMSEXPORT cmsCIECAM02Init(LPcmsViewingConditions pVC) { LPcmsCIECAM02 lpMod; if((lpMod = (LPcmsCIECAM02) malloc(sizeof(cmsCIECAM02))) == NULL) { return (LCMSHANDLE) NULL; } ZeroMemory(lpMod, sizeof(cmsCIECAM02)); lpMod ->adoptedWhite.XYZ[0] = pVC ->whitePoint.X; lpMod ->adoptedWhite.XYZ[1] = pVC ->whitePoint.Y; lpMod ->adoptedWhite.XYZ[2] = pVC ->whitePoint.Z; lpMod -> LA = pVC ->La; lpMod -> Yb = pVC ->Yb; lpMod -> D = pVC ->D_value; lpMod -> surround = pVC ->surround; switch (lpMod -> surround) { case AVG_SURROUND_4: lpMod->F = 1.0; // Not included in CAM02 lpMod->c = 0.69; lpMod->Nc = 1.0; break; case CUTSHEET_SURROUND: lpMod->F = 0.8; lpMod->c = 0.41; lpMod->Nc = 0.8; break; case DARK_SURROUND: lpMod -> F = 0.8; lpMod -> c = 0.525; lpMod -> Nc = 0.8; break; case DIM_SURROUND: lpMod -> F = 0.9; lpMod -> c = 0.59; lpMod -> Nc = 0.95; break; default: // Average surround lpMod -> F = 1.0; lpMod -> c = 0.69; lpMod -> Nc = 1.0; } lpMod -> n = compute_n(lpMod); lpMod -> z = compute_z(lpMod); lpMod -> Nbb = computeNbb(lpMod); lpMod -> FL = computeFL(lpMod); lpMod -> D = computeD(lpMod); lpMod -> Ncb = lpMod -> Nbb; lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite); lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod); lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite); lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod); lpMod -> adoptedWhite = ComputeCorrelates(lpMod -> adoptedWhite, lpMod); return (LCMSHANDLE) lpMod; }
cmsHANDLE CMSEXPORT cmsCIECAM02Init(cmsContext ContextID, const cmsViewingConditions* pVC) { cmsCIECAM02* lpMod; _cmsAssert(pVC != NULL); if((lpMod = (cmsCIECAM02*) _cmsMallocZero(ContextID, sizeof(cmsCIECAM02))) == NULL) { return NULL; } lpMod ->ContextID = ContextID; lpMod ->adoptedWhite.XYZ[0] = pVC ->whitePoint.X; lpMod ->adoptedWhite.XYZ[1] = pVC ->whitePoint.Y; lpMod ->adoptedWhite.XYZ[2] = pVC ->whitePoint.Z; lpMod -> LA = pVC ->La; lpMod -> Yb = pVC ->Yb; lpMod -> D = pVC ->D_value; lpMod -> surround = pVC ->surround; switch (lpMod -> surround) { case CUTSHEET_SURROUND: lpMod->F = 0.8; lpMod->c = 0.41; lpMod->Nc = 0.8; break; case DARK_SURROUND: lpMod -> F = 0.8; lpMod -> c = 0.525; lpMod -> Nc = 0.8; break; case DIM_SURROUND: lpMod -> F = 0.9; lpMod -> c = 0.59; lpMod -> Nc = 0.95; break; default: // Average surround lpMod -> F = 1.0; lpMod -> c = 0.69; lpMod -> Nc = 1.0; } lpMod -> n = compute_n(lpMod); lpMod -> z = compute_z(lpMod); lpMod -> Nbb = computeNbb(lpMod); lpMod -> FL = computeFL(lpMod); if (lpMod -> D == D_CALCULATE) { lpMod -> D = computeD(lpMod); } lpMod -> Ncb = lpMod -> Nbb; lpMod -> adoptedWhite = XYZtoCAT02(lpMod -> adoptedWhite); lpMod -> adoptedWhite = ChromaticAdaptation(lpMod -> adoptedWhite, lpMod); lpMod -> adoptedWhite = CAT02toHPE(lpMod -> adoptedWhite); lpMod -> adoptedWhite = NonlinearCompression(lpMod -> adoptedWhite, lpMod); return (cmsHANDLE) lpMod; }
void GetLocalBounds(const SkPath& path, const SkDrawShadowRec& rec, const SkMatrix& ctm, SkRect* bounds) { SkRect ambientBounds = path.getBounds(); SkScalar occluderZ; if (SkScalarNearlyZero(rec.fZPlaneParams.fX) && SkScalarNearlyZero(rec.fZPlaneParams.fY)) { occluderZ = rec.fZPlaneParams.fZ; } else { occluderZ = compute_z(ambientBounds.fLeft, ambientBounds.fTop, rec.fZPlaneParams); occluderZ = SkTMax(occluderZ, compute_z(ambientBounds.fRight, ambientBounds.fTop, rec.fZPlaneParams)); occluderZ = SkTMax(occluderZ, compute_z(ambientBounds.fLeft, ambientBounds.fBottom, rec.fZPlaneParams)); occluderZ = SkTMax(occluderZ, compute_z(ambientBounds.fRight, ambientBounds.fBottom, rec.fZPlaneParams)); } SkScalar ambientBlur; SkScalar spotBlur; SkScalar spotScale; SkPoint spotOffset; if (ctm.hasPerspective()) { // transform ambient and spot bounds into device space ctm.mapRect(&ambientBounds); // get ambient blur (in device space) ambientBlur = SkDrawShadowMetrics::AmbientBlurRadius(occluderZ); // get spot params (in device space) SkPoint devLightPos = SkPoint::Make(rec.fLightPos.fX, rec.fLightPos.fY); ctm.mapPoints(&devLightPos, 1); SkDrawShadowMetrics::GetSpotParams(occluderZ, devLightPos.fX, devLightPos.fY, rec.fLightPos.fZ, rec.fLightRadius, &spotBlur, &spotScale, &spotOffset); } else { SkScalar devToSrcScale = SkScalarInvert(ctm.getMinScale()); // get ambient blur (in local space) SkScalar devSpaceAmbientBlur = SkDrawShadowMetrics::AmbientBlurRadius(occluderZ); ambientBlur = devSpaceAmbientBlur*devToSrcScale; // get spot params (in local space) SkDrawShadowMetrics::GetSpotParams(occluderZ, rec.fLightPos.fX, rec.fLightPos.fY, rec.fLightPos.fZ, rec.fLightRadius, &spotBlur, &spotScale, &spotOffset); // convert spot blur to local space spotBlur *= devToSrcScale; } // in both cases, adjust ambient and spot bounds SkRect spotBounds = ambientBounds; ambientBounds.outset(ambientBlur, ambientBlur); spotBounds.fLeft *= spotScale; spotBounds.fTop *= spotScale; spotBounds.fRight *= spotScale; spotBounds.fBottom *= spotScale; spotBounds.offset(spotOffset.fX, spotOffset.fY); spotBounds.outset(spotBlur, spotBlur); // merge bounds *bounds = ambientBounds; bounds->join(spotBounds); // outset a bit to account for floating point error bounds->outset(1, 1); // if perspective, transform back to src space if (ctm.hasPerspective()) { // TODO: create tighter mapping from dev rect back to src rect SkMatrix inverse; if (ctm.invert(&inverse)) { inverse.mapRect(bounds); } } }