Ejemplo n.º 1
0
void Perturb_Normal(Vector3d& Layer_Normal, const TNORMAL *Tnormal, const Vector3d& EPoint, Intersection *Intersection, const Ray *ray, TraceThreadData *Thread)
{
    Vector3d TPoint,P1;
    DBL value1,Amount;
    int i;
    shared_ptr<NormalBlendMap> Blend_Map;

    if (Tnormal==NULL)
    {
        return;
    }

    /* If normal_map present, use it and return */

    Blend_Map = std::tr1::dynamic_pointer_cast<NormalBlendMap>(Tnormal->Blend_Map);
    if (Blend_Map != NULL)
    {
        if (Tnormal->Type == UV_MAP_PATTERN)
        {
            Vector2d UV_Coords;

            /* Don't bother warping, simply get the UV vect of the intersection */
            Intersection->Object->UVCoord(UV_Coords, Intersection, Thread);
            TPoint[X] = UV_Coords[U];
            TPoint[Y] = UV_Coords[V];
            TPoint[Z] = 0;

            Perturb_Normal(Layer_Normal,Blend_Map->Blend_Map_Entries[0].Vals,TPoint,Intersection,ray,Thread);
            Layer_Normal.normalize();
            Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */

            return;
        }
        else if (Tnormal->Type != AVERAGE_PATTERN)
        {
            const NormalBlendMapEntry *Prev, *Cur;
            DBL prevWeight, curWeight;

            /* NK 19 Nov 1999 added Warp_EPoint */
            Warp_EPoint (TPoint, EPoint, Tnormal);
            value1 = Evaluate_TPat(Tnormal, TPoint, Intersection, ray, Thread);

            Blend_Map->Search (value1,Prev,Cur,prevWeight,curWeight);

            Warp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));
            P1 = Layer_Normal;

            Warp_EPoint (TPoint, EPoint, Tnormal);

            Perturb_Normal(Layer_Normal,Cur->Vals,TPoint,Intersection,ray,Thread);

            if (Prev != Cur)
            {
                Perturb_Normal(P1,Prev->Vals,TPoint,Intersection,ray,Thread);

                Layer_Normal = prevWeight * P1 + curWeight * Layer_Normal;
            }

            UnWarp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

            Layer_Normal.normalize();

            Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */

            return;
        }
        // TODO - what if Tnormal->Type == AVERAGE_PATTERN?
    }

    /* No normal_map. */

    if (Tnormal->Type <= LAST_NORM_ONLY_PATTERN)
    {
        Warp_Normal(Layer_Normal,Layer_Normal, Tnormal,
                    Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

        Warp_EPoint (TPoint, EPoint, Tnormal);

        switch (Tnormal->Type)
        {
        case BITMAP_PATTERN:
            bump_map    (TPoint, Tnormal, Layer_Normal);
            break;
        case BUMPS_PATTERN:
            bumps       (TPoint, Tnormal, Layer_Normal);
            break;
        case DENTS_PATTERN:
            dents       (TPoint, Tnormal, Layer_Normal, Thread);
            break;
        case RIPPLES_PATTERN:
            ripples     (TPoint, Tnormal, Layer_Normal, Thread);
            break;
        case WAVES_PATTERN:
            waves       (TPoint, Tnormal, Layer_Normal, Thread);
            break;
        case WRINKLES_PATTERN:
            wrinkles    (TPoint, Tnormal, Layer_Normal);
            break;
        case QUILTED_PATTERN:
            quilted     (TPoint, Tnormal, Layer_Normal);
            break;
        case FACETS_PATTERN:
            facets      (TPoint, Tnormal, Layer_Normal, Thread);
            break;
        case AVERAGE_PATTERN:
            Do_Average_Normals (TPoint, Tnormal, Layer_Normal, Intersection, ray, Thread);
            break;
        default:
            throw POV_EXCEPTION_STRING("Normal pattern not yet implemented.");
        }

        UnWarp_Normal(Layer_Normal,Layer_Normal, Tnormal,
                      Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));
    }
    else
    {
        shared_ptr<SlopeBlendMap> slopeMap = std::tr1::dynamic_pointer_cast<SlopeBlendMap>(Tnormal->Blend_Map);

        Warp_Normal(Layer_Normal,Layer_Normal, Tnormal,
                    Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

        // TODO FIXME - two magic fudge factors
        Amount=Tnormal->Amount * -5.0; /*fudge factor*/
        Amount*=0.02/Tnormal->Delta; /* NK delta */

        /* warp the center point first - this is the last warp */
        Warp_EPoint(TPoint,EPoint,Tnormal);

        for(i=0; i<=3; i++)
        {
            P1 = TPoint + (DBL)Tnormal->Delta * Pyramid_Vect[i]; /* NK delta */
            value1 = Do_Slope_Map(Evaluate_TPat(Tnormal, P1, Intersection, ray, Thread), slopeMap.get());
            Layer_Normal += (value1*Amount) * Pyramid_Vect[i];
        }

        UnWarp_Normal(Layer_Normal,Layer_Normal,Tnormal,
                      Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

    }

    if ( Intersection )
        Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */
}
Ejemplo n.º 2
0
void Perturb_Normal(VECTOR Layer_Normal, const TNORMAL *Tnormal, const VECTOR EPoint, Intersection *Intersection, const Ray *ray, TraceThreadData *Thread)
{
	VECTOR TPoint,P1;
	DBL value1,value2,Amount;
	int i;
	BLEND_MAP *Blend_Map;
	BLEND_MAP_ENTRY *Prev, *Cur;

	if (Tnormal==NULL)
	{
		return;
	}

	/* If normal_map present, use it and return */

	if ((Blend_Map=Tnormal->Blend_Map) != NULL)
	{
		if ((Blend_Map->Type == NORMAL_TYPE) && (Tnormal->Type == UV_MAP_PATTERN))
		{
			UV_VECT UV_Coords;

			Cur = &(Tnormal->Blend_Map->Blend_Map_Entries[0]);

			/* Don't bother warping, simply get the UV vect of the intersection */
			Intersection->Object->UVCoord(UV_Coords, Intersection, Thread);
			TPoint[X] = UV_Coords[U];
			TPoint[Y] = UV_Coords[V];
			TPoint[Z] = 0;

			Perturb_Normal(Layer_Normal,Cur->Vals.Tnormal,TPoint,Intersection,ray,Thread);
			VNormalizeEq(Layer_Normal);
			Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */

			return;
		}
		else if ((Blend_Map->Type == NORMAL_TYPE) && (Tnormal->Type != AVERAGE_PATTERN))
		{
			/* NK 19 Nov 1999 added Warp_EPoint */
			Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal);
			value1 = Evaluate_TPat((TPATTERN *)Tnormal,TPoint,Intersection,ray,Thread);

			Search_Blend_Map (value1,Blend_Map,&Prev,&Cur);

			Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));
			Assign_Vector(P1,Layer_Normal);

			Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal);

			Perturb_Normal(Layer_Normal,Cur->Vals.Tnormal,TPoint,Intersection,ray,Thread);

			if (Prev != Cur)
			{
				Perturb_Normal(P1,Prev->Vals.Tnormal,TPoint,Intersection,ray,Thread);

				value2 = (value1-Prev->value)/(Cur->value-Prev->value);
				value1 = 1.0-value2;

				VLinComb2(Layer_Normal,value1,P1,value2,Layer_Normal);
			}

			UnWarp_Normal(Layer_Normal,Layer_Normal,(TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

			VNormalizeEq(Layer_Normal);

			Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */

			return;
		}
	}

	/* No normal_map. */

	if (Tnormal->Type <= LAST_NORM_ONLY_PATTERN)
	{
		Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal,
		            Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

		Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal);

		switch (Tnormal->Type)
		{
			case BITMAP_PATTERN:    bump_map    (TPoint, Tnormal, Layer_Normal);            break;
			case BUMPS_PATTERN:     bumps       (TPoint, Tnormal, Layer_Normal);            break;
			case DENTS_PATTERN:     dents       (TPoint, Tnormal, Layer_Normal, Thread);    break;
			case RIPPLES_PATTERN:   ripples     (TPoint, Tnormal, Layer_Normal, Thread);    break;
			case WAVES_PATTERN:     waves       (TPoint, Tnormal, Layer_Normal, Thread);    break;
			case WRINKLES_PATTERN:  wrinkles    (TPoint, Tnormal, Layer_Normal);            break;
			case QUILTED_PATTERN:   quilted     (TPoint, Tnormal, Layer_Normal);            break;
			case FACETS_PATTERN:    facets      (TPoint, Tnormal, Layer_Normal, Thread);    break;
			case AVERAGE_PATTERN:   Do_Average_Normals (TPoint, Tnormal, Layer_Normal, Intersection, ray, Thread); break;
			default:
				throw POV_EXCEPTION_STRING("Normal pattern not yet implemented.");
		}

		UnWarp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal,
		              Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));
	}
	else
	{
		Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal,
		            Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

		Amount=Tnormal->Amount * -5.0; /*fudge factor*/
		Amount*=0.02/Tnormal->Delta; /* NK delta */

		/* warp the center point first - this is the last warp */
		Warp_EPoint(TPoint,EPoint,(TPATTERN *)Tnormal);

		for(i=0; i<=3; i++)
		{
			VAddScaled(P1,TPoint,Tnormal->Delta,Pyramid_Vect[i]); /* NK delta */
			value1 = Do_Slope_Map(Evaluate_TPat((TPATTERN *)Tnormal,P1,Intersection,ray,Thread),Blend_Map);
			VAddScaledEq(Layer_Normal,value1*Amount,Pyramid_Vect[i]);
		}

		UnWarp_Normal(Layer_Normal,Layer_Normal,(TPATTERN *)Tnormal,
		              Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

	}

	if ( Intersection )
		Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */
}