예제 #1
0
	void BunishData::bunish()
	{
		pos += bunish_vec;
		radian += rot_speed;
		compute_world_mat();
#ifdef NDEBUG
		compute_z();
#endif
	}
예제 #2
0
파일: Surface.cpp 프로젝트: edeforas/Astree
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;
}
예제 #3
0
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;
      
}
예제 #4
0
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;

}
예제 #5
0
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);
        }
    }
}