Esempio n. 1
0
/*************
 * DESCRIPTION:   Vector-based procedural fBm
 * INPUT:         v           position
 *                H           fractal increment parameter
 *                lacunarity  gap between successive frequencies
 *                octaves     number of frequencies in the fBm
 *                r           result vector
 * OUTPUT:        -
 *************/
void VfBm(VECTOR *vec, float omega, float lambda, int octaves, VECTOR *r, short *hashTable)
{
	float l,o;
	int i;
	VECTOR p, res;

	r->x = 0.f;
	r->y = 0.f;
	r->z = 0.f;
	l = 1.f;
	o = 1.f;
	p = *vec;
	for(i=0; i<octaves; i++)
	{
		p.x *= l;
		p.y *= l;
		p.z *= l;
		DNoise(&p, &res, hashTable);
		r->x += res.x * o;
		r->y += res.y * o;
		r->z += res.z * o;
		l *= lambda;
		o *= omega;
	}
}
Esempio n. 2
0
void BrickMaterial::normal_texture (Vector3D& v)
{
  float a = 30*scale, b = 0.3f, // frequency and intensity of the bumps
        h = hypot(v.x,v.y,v.z); // normalization of normal vector
  if (h) { a /= h; b *= h; }
  float px = a*v.x, py = 3*a*v.y, pz = a*v.z;
  DNoise(px,py,pz);
  v.x += b*px; v.y += b*py; v.z += b*pz;
}
Esempio n. 3
0
static void bumps (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal)
{
    Vector3d bump_turb;

    /* Get normal displacement value. */

    DNoise (bump_turb, EPoint);

    /* Displace "normal". */

    normal += (DBL)Tnormal->Amount * bump_turb;
}
Esempio n. 4
0
static void bumps (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal)
{
	VECTOR bump_turb;

	/* Get normal displacement value. */

	DNoise (bump_turb, EPoint);

	/* Displace "normal". */

	VAddScaledEq(normal, Tnormal->Amount, bump_turb);
}
Esempio n. 5
0
static void dents (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal, const TraceThreadData *Thread)
{
    DBL noise;
    Vector3d stucco_turb;

    noise = Noise (EPoint, GetNoiseGen(Tnormal, Thread));

    noise = noise * noise * noise * Tnormal->Amount;

    /* Get normal displacement value. */

    DNoise(stucco_turb, EPoint);

    /* Displace "normal". */

    normal += noise * stucco_turb;
}
Esempio n. 6
0
static void dents (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal, const TraceThreadData *Thread)
{
	DBL noise;
	VECTOR stucco_turb;

	noise = Noise (EPoint, GetNoiseGen((TPATTERN*)Tnormal, Thread));

	noise = noise * noise * noise * Tnormal->Amount;

	/* Get normal displacement value. */

	DNoise(stucco_turb, EPoint);

	/* Displace "normal". */

	VAddScaledEq(normal, noise, stucco_turb);
}
Esempio n. 7
0
/*************
 * DESCRIPTION:   Noise function
 * INPUT:         v        noise position
 * OUTPUT:        noise
 *************/
float VLNoise(VECTOR *v, short *hashTable)
{
	VECTOR offset, r;

	offset.x = v->x + 0.5f;        /* misregister domain */
	offset.y = v->y + 0.5f;
	offset.z = v->z + 0.5f;

	DNoise( &offset, &r, hashTable);   /* get a random vector */

	/* ``point'' is the domain; distort domain by adding ``offset'' */
	r.x += v->x;
	r.y += v->y;
	r.z += v->z;

	return Noise(&r, hashTable);         /* distorted-domain noise */

}
Esempio n. 8
0
static void wrinkles (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal)
{
    register int i;
    register DBL scale = 1.0;
    Vector3d result, value, value2;

    result = Vector3d(0.0, 0.0, 0.0);

    for (i = 0; i < 10; scale *= 2.0, i++)
    {
        value2 = EPoint * scale;
        DNoise(value, value2);

        result[X] += fabs(value[X] / scale);
        result[Y] += fabs(value[Y] / scale);
        result[Z] += fabs(value[Z] / scale);
    }

    /* Displace "normal". */

    normal += (DBL)Tnormal->Amount * result;
}
Esempio n. 9
0
static void wrinkles (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal)
{
	register int i;
	register DBL scale = 1.0;
	VECTOR result, value, value2;

	Make_Vector(result, 0.0, 0.0, 0.0);

	for (i = 0; i < 10; scale *= 2.0, i++)
	{
		VScale(value2,EPoint,scale);
		DNoise(value, value2);

		result[X] += fabs(value[X] / scale);
		result[Y] += fabs(value[Y] / scale);
		result[Z] += fabs(value[Z] / scale);
	}

	/* Displace "normal". */

	VAddScaledEq(normal, Tnormal->Amount, result);
}
Esempio n. 10
0
static void facets (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal, TraceThreadData *Thread)
{
    int      i;
    int      thisseed;
    DBL      sum, minsum;
    Vector3d sv, tv, dv, t1, add, newnormal, pert;
    DBL      scale;
    int      UseSquare;
    int      UseUnity;
    DBL      Metric;

    Vector3d *cv = Thread->Facets_Cube;
    Metric = dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsMetric;

    UseSquare = (Metric == 2 );
    UseUnity  = (Metric == 1 );

    normal.normalize();

    if ( dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsCoords )
    {
        tv = EPoint;
    }
    else
    {
        tv = normal;
    }

    if ( dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsSize < 1e-6 )
    {
        scale = 1e6;
    }
    else
    {
        scale = 1. / dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsSize;
    }

    tv *= scale;

    /*
     * Check to see if the input point is in the same unit cube as the last
     * call to this function, to use cache of cubelets for speed.
     */

    thisseed = PickInCube(tv, t1);

    if (thisseed != Thread->Facets_Last_Seed)
    {
        /*
         * No, not same unit cube.  Calculate the random points for this new
         * cube and its 80 neighbours which differ in any axis by 1 or 2.
         * Why distance of 2?  If there is 1 point in each cube, located
         * randomly, it is possible for the closest random point to be in the
         * cube 2 over, or the one two over and one up.  It is NOT possible
         * for it to be two over and two up.  Picture a 3x3x3 cube with 9 more
         * cubes glued onto each face.
         */

        /* Now store a points for this cube and each of the 80 neighbour cubes. */

        int cvc = 0;

        for (add[X] = -2.0; add[X] < 2.5; add[X] +=1.0)
        {
            for (add[Y] = -2.0; add[Y] < 2.5; add[Y] += 1.0)
            {
                for (add[Z] = -2.0; add[Z] < 2.5; add[Z] += 1.0)
                {
                    /* For each cubelet in a 5x5 cube. */

                    if ((fabs(add[X])>1.5)+(fabs(add[Y])>1.5)+(fabs(add[Z])>1.5) <= 1.0)
                    {
                        /* Yes, it's within a 3d knight move away. */

                        sv = tv + add;

                        PickInCube(sv, t1);

                        cv[cvc] = t1;
                        cvc++;
                    }
                }
            }
        }

        Thread->Facets_Last_Seed = thisseed;
        Thread->Facets_CVC = cvc;
    }

    /*
     * Find the point with the shortest distance from the input point.
     */

    dv = cv[0] - tv;
    if ( UseSquare )
    {
        minsum  = dv.lengthSqr();
    }
    else if ( UseUnity )
    {
        minsum = dv[X]+dv[Y]+dv[Z];
    }
    else
    {
        minsum = pow(fabs(dv[X]), Metric)+
                 pow(fabs(dv[Y]), Metric)+
                 pow(fabs(dv[Z]), Metric);
    }

    newnormal = cv[0];

    /* Loop for the 81 cubelets to find closest. */

    for (i = 1; i < Thread->Facets_CVC; i++)
    {
        dv = cv[i] - tv;

        if ( UseSquare )
        {
            sum  = dv.lengthSqr();
        }
        else
        {
            if ( UseUnity )
            {
                sum = dv[X]+dv[Y]+dv[Z];
            }
            else
            {
                sum = pow(fabs(dv[X]), Metric)+
                      pow(fabs(dv[Y]), Metric)+
                      pow(fabs(dv[Z]), Metric);
            }
        }

        if (sum < minsum)
        {
            minsum = sum;
            newnormal = cv[i];
        }
    }

    if ( dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsCoords )
    {
        DNoise( pert, newnormal );
        sum = dot(pert, normal);
        newnormal = normal * sum;
        pert -= newnormal;
        normal += dynamic_cast<FacetsPattern*>(Tnormal->pattern.get())->facetsCoords * pert;
    }
    else
    {
        normal = newnormal;
    }
}
Esempio n. 11
0
static void facets (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal, TraceThreadData *Thread)
{
	int    i;
	int    thisseed;
	DBL    sum, minsum;
	VECTOR sv, tv, dv, t1, add, newnormal, pert;
	DBL    scale;
	int    UseSquare;
	int    UseUnity;
	DBL    Metric;

	VECTOR *cv = Thread->Facets_Cube;
	Metric = Tnormal->Vals.Facets.Metric;

	UseSquare = (Metric == 2 );
	UseUnity  = (Metric == 1 );

	VNormalize( normal, normal );

	if ( Tnormal->Vals.Facets.UseCoords )
	{
		Assign_Vector(tv,EPoint);
	}
	else
	{
		Assign_Vector(tv,normal);
	}

	if ( Tnormal->Vals.Facets.Size < 1e-6 )
	{
		scale = 1e6;
	}
	else
	{
		scale = 1. / Tnormal->Vals.Facets.Size;
	}

	VScaleEq( tv, scale );

	/*
	 * Check to see if the input point is in the same unit cube as the last
	 * call to this function, to use cache of cubelets for speed.
	 */

	thisseed = PickInCube(tv, t1);

	if (thisseed != Thread->Facets_Last_Seed)
	{
		/*
		 * No, not same unit cube.  Calculate the random points for this new
		 * cube and its 80 neighbours which differ in any axis by 1 or 2.
		 * Why distance of 2?  If there is 1 point in each cube, located
		 * randomly, it is possible for the closest random point to be in the
		 * cube 2 over, or the one two over and one up.  It is NOT possible
		 * for it to be two over and two up.  Picture a 3x3x3 cube with 9 more
		 * cubes glued onto each face.
		 */

		/* Now store a points for this cube and each of the 80 neighbour cubes. */

		int cvc = 0;

		for (add[X] = -2.0; add[X] < 2.5; add[X] +=1.0)
		{
			for (add[Y] = -2.0; add[Y] < 2.5; add[Y] += 1.0)
			{
				for (add[Z] = -2.0; add[Z] < 2.5; add[Z] += 1.0)
				{
					/* For each cubelet in a 5x5 cube. */

					if ((fabs(add[X])>1.5)+(fabs(add[Y])>1.5)+(fabs(add[Z])>1.5) <= 1.0)
					{
						/* Yes, it's within a 3d knight move away. */

						VAdd(sv, tv, add);

						PickInCube(sv, t1);

						cv[cvc][X] = t1[X];
						cv[cvc][Y] = t1[Y];
						cv[cvc][Z] = t1[Z];
						cvc++;
					}
				}
			}
		}

		Thread->Facets_Last_Seed = thisseed;
		Thread->Facets_CVC = cvc;
	}

	/*
	 * Find the point with the shortest distance from the input point.
	 */

	VSub(dv, cv[0], tv);
	if ( UseSquare )
	{
		minsum  = VSumSqr(dv);
	}
	else if ( UseUnity )
	{
		minsum = dv[X]+dv[Y]+dv[Z];
	}
	else
	{
		minsum = pow(fabs(dv[X]), Metric)+
		         pow(fabs(dv[Y]), Metric)+
		         pow(fabs(dv[Z]), Metric);
	}

	Assign_Vector( newnormal, cv[0] );

	/* Loop for the 81 cubelets to find closest. */

	for (i = 1; i < Thread->Facets_CVC; i++)
	{
		VSub(dv, cv[i], tv);

		if ( UseSquare )
		{
			sum  = VSumSqr(dv);
		}
		else
		{
			if ( UseUnity )
			{
				sum = dv[X]+dv[Y]+dv[Z];
			}
			else
			{
				sum = pow(fabs(dv[X]), Metric)+
				      pow(fabs(dv[Y]), Metric)+
				      pow(fabs(dv[Z]), Metric);
			}
		}

		if (sum < minsum)
		{
			minsum = sum;
			Assign_Vector( newnormal, cv[i] );
		}
	}

	if ( Tnormal->Vals.Facets.UseCoords )
	{
		DNoise( pert, newnormal );
		VDot( sum, pert, normal );
		VScale( newnormal, normal, sum );
		VSubEq( pert, newnormal );
		VAddScaledEq( normal, Tnormal->Vals.Facets.UseCoords, pert );
	}
	else
	{
		Assign_Vector( normal, newnormal );
	}
}