Пример #1
0
void Warp_EPoint (VECTOR TPoint, VECTOR EPoint, TPATTERN *TPat)
{
   VECTOR PTurbulence,RP;
   int Axis,i,temp_rand;
   int blockX = 0, blockY = 0, blockZ = 0 ;
   SNGL BlkNum;
   DBL  Length;
   DBL  Strength;
   WARP *Warp=TPat->Warps;
   TURB *Turb;
   TRANS *Tr;
   REPEAT *Repeat;
   BLACK_HOLE *Black_Hole;
   VECTOR Delta, Center;

   Assign_Vector(TPoint, EPoint);

   while (Warp != NULL)
   {
      switch(Warp->Warp_Type)
      {
        case CLASSIC_TURB_WARP:
          if ((TPat->Type == MARBLE_PATTERN) ||
              (TPat->Type == NO_PATTERN)     ||
              (TPat->Type == WOOD_PATTERN))
          {
             break;
          }
        /* If not a special type, fall through to next case */

        case EXTRA_TURB_WARP:
          Turb=(TURB *)Warp;
          DTurbulence (PTurbulence, TPoint, Turb);
          TPoint[X] += PTurbulence[X] * Turb->Turbulence[X];
          TPoint[Y] += PTurbulence[Y] * Turb->Turbulence[Y];
          TPoint[Z] += PTurbulence[Z] * Turb->Turbulence[Z];
          break;

        case NO_WARP:
          break;

        case TRANSFORM_WARP:
          Tr=(TRANS *)Warp;
          MInvTransPoint(TPoint, TPoint, &(Tr->Trans));
          break;

        case REPEAT_WARP:
          Repeat=(REPEAT *)Warp;
          Assign_Vector(RP,TPoint);
          Axis=Repeat->Axis;
          BlkNum=(SNGL)floor(TPoint[Axis]/Repeat->Width);
          
          RP[Axis]=TPoint[Axis]-BlkNum*Repeat->Width;
          
          if (((int)BlkNum) & 1)
          {          
             VEvaluateEq(RP,Repeat->Flip);
             if ( Repeat->Flip[Axis] < 0 ) 
             {
                RP[Axis] = Repeat->Width+RP[Axis];
             }
          }

          VAddScaledEq(RP,BlkNum,Repeat->Offset);
          Assign_Vector(TPoint,RP);
          break;

        case BLACK_HOLE_WARP:
          Black_Hole = (BLACK_HOLE *) Warp ;
          Assign_Vector (Center, Black_Hole->Center) ;

          if (Black_Hole->Repeat)
          {
            /* first, get the block number we're in for each dimension  */
            /* block numbers are (currently) calculated relative to 0   */
            /* we use floor () since it correctly returns -1 for the
               first block below 0 in each axis                         */
            /* one final point - we could run into overflow problems if
               the repeat vector was small and the scene very large.    */
            if (Black_Hole->Repeat_Vector [X] >= Small_Tolerance)
              blockX = (int) floor (TPoint [X] / Black_Hole->Repeat_Vector [X]) ;

            if (Black_Hole->Repeat_Vector [Y] >= Small_Tolerance)
              blockY = (int) floor (TPoint [Y] / Black_Hole->Repeat_Vector [Y]) ;

            if (Black_Hole->Repeat_Vector [Z] >= Small_Tolerance)
              blockZ = (int) floor (TPoint [Z] / Black_Hole->Repeat_Vector [Z]) ;

            if (Black_Hole->Uncertain)
            {
              /* if the position is uncertain calculate the new one first */
              /* this will allow the same numbers to be returned by frand */
              
              temp_rand = POV_GET_OLD_RAND(); /*protect seed*/
  
              POV_SRAND (Hash3d (blockX, blockY, blockZ)) ;
              Center [X] += FRAND () * Black_Hole->Uncertainty_Vector [X] ;
              Center [Y] += FRAND () * Black_Hole->Uncertainty_Vector [Y] ;
              Center [Z] += FRAND () * Black_Hole->Uncertainty_Vector [Z] ;
              POV_SRAND (temp_rand) ;  /*restore*/
            }

            Center [X] += Black_Hole->Repeat_Vector [X] * blockX ;
            Center [Y] += Black_Hole->Repeat_Vector [Y] * blockY ;
            Center [Z] += Black_Hole->Repeat_Vector [Z] * blockZ ;
          }

          VSub (Delta, TPoint, Center) ;
          VLength (Length, Delta) ;

          /* Length is the distance from the centre of the black hole */
          if (Length >= Black_Hole->Radius) break ;

          if (Black_Hole->Type == 0)
          {
            /* now convert the length to a proportion (0 to 1) that the point
               is from the edge of the black hole. a point on the perimeter
               of the black hole will be 0.0 ; a point at the centre will be
               1.0 ; a point exactly halfway will be 0.5, and so forth. */
            Length = (Black_Hole->Radius - Length) / Black_Hole->Radius ;

            /* Strength is the magnitude of the transformation effect. firstly,
               apply the Power variable to Length. this is meant to provide a
               means of controlling how fast the power of the Black Hole falls
               off from its centre. if Power is 2.0, then the effect is inverse
               square. increasing power will cause the Black Hole to be a lot
               weaker in its effect towards its perimeter. 
               
               finally we multiply Strength with the Black Hole's Strength
               variable. if the resultant value exceeds 1.0 we clip it to 1.0.
               this means a point will never be transformed by more than its
               original distance from the centre. the result of this clipping
               is that you will have an 'exclusion' area near the centre of
               the black hole where all points whose final value exceeded or
               equalled 1.0 were moved by a fixed amount. this only happens
               if the Strength value of the Black Hole was greater than one. */

            Strength = pow (Length, Black_Hole->Power) * Black_Hole->Strength ;
            if (Strength > 1.0) Strength = 1.0 ;
            
            /* if the Black Hole is inverted, it gives the impression of 'push-
               ing' the pattern away from its centre. otherwise it sucks. */
            VScaleEq (Delta, Black_Hole->Inverted ? -Strength : Strength) ;

            /* add the scaled Delta to the input point to end up with TPoint. */
            VAddEq (TPoint, Delta) ;
          }
          break;
          
        /* 10/23/1998 Talious added SPherical Cylindrical and toroidal
        warps */

        case CYLINDRICAL_WARP:
          warp_cylindrical(TPoint, (CYLW *)Warp);
          break;

        case PLANAR_WARP:
          warp_planar(TPoint, (PLANARW *)Warp);
          break;
      
        case SPHERICAL_WARP:
          warp_spherical(TPoint, (SPHEREW *)Warp);
          break;

        case TOROIDAL_WARP:
          warp_toroidal(TPoint, (TOROIDAL *) Warp);
          break;
          
        default:
          Error("Warp type %d not yet implemented",Warp->Warp_Type);
      }
      Warp=Warp->Next_Warp;
   }

   for (i=X; i<=Z; i++)
     if (TPoint[i] > COORDINATE_LIMIT)
       TPoint[i]= COORDINATE_LIMIT;
     else
       if (TPoint[i] < -COORDINATE_LIMIT)
         TPoint[i] = -COORDINATE_LIMIT;

}
Пример #2
0
/**
 * Vector-valued "Noise"
 */
void
bn_noise_vec(fastf_t *point, fastf_t *result)
{
    register int	jx, jy, jz;
    int ix, iy, iz;		/* lower integer lattice point */
    double x, y, z;		/* corrected point */
    double		px, py, pz, s;
    double		sx, sy, sz, tx, ty, tz;
    short		m;
    point_t p, f;
    int ip[3];


    if ( ! ht.hashTableValid ) bn_noise_init();


    /* sets:
     * x, y, z to range [0..maxval],
     * ix, iy, iz to integer portion,
     * fx, fy, fz to fractional portion
     */
    filter_args( point, p, f, ip);
    ix = ip[X];
    iy = ip[Y];
    iz = ip[Z];

    x = p[X];
    y = p[Y];
    z = p[Z];

    jx = ix+1;   jy = iy + 1;   jz = iz + 1;

    sx = SMOOTHSTEP(x - ix);
    sy = SMOOTHSTEP(y - iy);
    sz = SMOOTHSTEP(z - iz);

    /* the complement values of sx, sy, sz */
    tx = 1.0 - sx;
    ty = 1.0 - sy;
    tz = 1.0 - sz;

    /*
     *  interpolate!
     */
    m = Hash3d( ix, iy, iz ) & 0xFF;
    px = x-ix;
    py = y-iy;
    pz = z-iz;
    s = tx*ty*tz;
    result[0] = INCRSUM(m, s, px, py, pz);
    result[1] = INCRSUM(m+4, s, px, py, pz);
    result[2] = INCRSUM(m+8, s, px, py, pz);

    m = Hash3d( jx, iy, iz ) & 0xFF;
    px = x-jx;
    s = sx*ty*tz;
    result[0] += INCRSUM(m, s, px, py, pz);
    result[1] += INCRSUM(m+4, s, px, py, pz);
    result[2] += INCRSUM(m+8, s, px, py, pz);

    m = Hash3d( jx, jy, iz ) & 0xFF;
    py = y-jy;
    s = sx*sy*tz;
    result[0] += INCRSUM(m, s, px, py, pz);
    result[1] += INCRSUM(m+4, s, px, py, pz);
    result[2] += INCRSUM(m+8, s, px, py, pz);

    m = Hash3d( ix, jy, iz ) & 0xFF;
    px = x-ix;
    s = tx*sy*tz;
    result[0] += INCRSUM(m, s, px, py, pz);
    result[1] += INCRSUM(m+4, s, px, py, pz);
    result[2] += INCRSUM(m+8, s, px, py, pz);

    m = Hash3d( ix, jy, jz ) & 0xFF;
    pz = z-jz;
    s = tx*sy*sz;
    result[0] += INCRSUM(m, s, px, py, pz);
    result[1] += INCRSUM(m+4, s, px, py, pz);
    result[2] += INCRSUM(m+8, s, px, py, pz);

    m = Hash3d( jx, jy, jz ) & 0xFF;
    px = x-jx;
    s = sx*sy*sz;
    result[0] += INCRSUM(m, s, px, py, pz);
    result[1] += INCRSUM(m+4, s, px, py, pz);
    result[2] += INCRSUM(m+8, s, px, py, pz);

    m = Hash3d( jx, iy, jz ) & 0xFF;
    py = y-iy;
    s = sx*ty*sz;
    result[0] += INCRSUM(m, s, px, py, pz);
    result[1] += INCRSUM(m+4, s, px, py, pz);
    result[2] += INCRSUM(m+8, s, px, py, pz);

    m = Hash3d( ix, iy, jz ) & 0xFF;
    px = x-ix;
    s = tx*ty*sz;
    result[0] += INCRSUM(m, s, px, py, pz);
    result[1] += INCRSUM(m+4, s, px, py, pz);
    result[2] += INCRSUM(m+8, s, px, py, pz);
}
Пример #3
0
/**
 *@brief
 * Robert Skinner's Perlin-style "Noise" function
 *
 * Results are in the range [-0.5 .. 0.5].  Unlike many implementations,
 * this function provides random noise at the integer lattice values.
 * However this produces much poorer quality and should be avoided if
 * possible.
 *
 * The power distribution of the result has no particular shape, though it
 * isn't as flat as the literature would have one believe.
 */
double
bn_noise_perlin(fastf_t *point)
{
    register int	jx, jy, jz;
    int ix, iy, iz;	/* lower integer lattice point */
    double x, y, z;	/* corrected point */
    double fx, fy, fz;	/* distance above integer lattice point */
    double	sx, sy, sz, tx, ty, tz;
    double	sum;
    short	m;
    point_t p, f;
    int ip[3];

    if (!ht.hashTableValid) bn_noise_init();
    else {
/*		CK_HT(); */
    }

    /* IS: const fastf_t *, point_t, point_t, int[3] */
    /* NE: fastf_t *, fastf_t *, fastf_t *, int *    */
    filter_args( point, p, f, ip);
    ix = ip[X];
    iy = ip[Y];
    iz = ip[Z];

    fx = f[X];
    fy = f[Y];
    fz = f[Z];

    x = p[X];
    y = p[Y];
    z = p[Z];

    jx = ix + 1; /* (jx, jy, jz) = integer lattice point above (ix, iy, iz) */
    jy = iy + 1;
    jz = iz + 1;

    sx = SMOOTHSTEP(fx);
    sy = SMOOTHSTEP(fy);
    sz = SMOOTHSTEP(fz);

    /* the complement values of sx, sy, sz */
    tx = 1.0 - sx;
    ty = 1.0 - sy;
    tz = 1.0 - sz;

    /*
     *  interpolate!
     */
    /* get a repeatable random # 0..4096 & 0xFF*/
    m = Hash3d( ix, iy, iz ) & 0xFF;
    sum = INCRSUM(m, (tx*ty*tz), (x-ix), (y-iy), (z-iz));

    m = Hash3d( jx, iy, iz ) & 0xFF;
    sum += INCRSUM(m, (sx*ty*tz), (x-jx), (y-iy), (z-iz));

    m = Hash3d( ix, jy, iz ) & 0xFF;
    sum += INCRSUM(m, (tx*sy*tz), (x-ix), (y-jy), (z-iz));

    m = Hash3d( jx, jy, iz ) & 0xFF;
    sum += INCRSUM(m, (sx*sy*tz), (x-jx), (y-jy), (z-iz));

    m = Hash3d( ix, iy, jz ) & 0xFF;
    sum += INCRSUM(m, (tx*ty*sz), (x-ix), (y-iy), (z-jz));

    m = Hash3d( jx, iy, jz ) & 0xFF;
    sum += INCRSUM(m, (sx*ty*sz), (x-jx), (y-iy), (z-jz));

    m = Hash3d( ix, jy, jz ) & 0xFF;
    sum += INCRSUM(m, (tx*sy*sz), (x-ix), (y-jy), (z-jz));

    m = Hash3d( jx, jy, jz ) & 0xFF;
    sum += INCRSUM(m, (sx*sy*sz), (x-jx), (y-jy), (z-jz));

    return sum;

}
Пример #4
0
bool BlackHoleWarp::WarpPoint(Vector3d& TPoint) const
{
    Vector3d C = Center;

    if (Repeat)
    {
        int blockX = 0, blockY = 0, blockZ = 0;

        /* first, get the block number we're in for each dimension  */
        /* block numbers are (currently) calculated relative to 0   */
        /* we use floor () since it correctly returns -1 for the
            first block below 0 in each axis                         */
        /* one final point - we could run into overflow problems if
            the repeat vector was small and the scene very large.    */
        if (Repeat_Vector[X] >= EPSILON)
            blockX = (int) floor (TPoint[X] / Repeat_Vector[X]);

        if (Repeat_Vector[Y] >= EPSILON)
            blockY = (int) floor (TPoint[Y] / Repeat_Vector[Y]);

        if (Repeat_Vector[Z] >= EPSILON)
            blockZ = (int) floor (TPoint[Z] / Repeat_Vector[Z]);

        if (Uncertain)
        {
            /* if the position is uncertain calculate the new one first */
            /* this will allow the same numbers to be returned by frand */

            int seed = Hash3d (blockX, blockY, blockZ);
            C[X] += WarpRands(seed)     * Uncertainty_Vector[X];
            C[Y] += WarpRands(seed + 1) * Uncertainty_Vector[Y];
            C[Z] += WarpRands(seed + 2) * Uncertainty_Vector[Z];
        }

        C[X] += Repeat_Vector[X] * blockX;
        C[Y] += Repeat_Vector[Y] * blockY;
        C[Z] += Repeat_Vector[Z] * blockZ;
    }

    Vector3d Delta = TPoint - C;
    DBL Length = Delta.length();

    /* Length is the distance from the centre of the black hole */
    if (Length >= Radius)
        return true;

    if (Type == 0)
    {
        /* now convert the length to a proportion (0 to 1) that the point
            is from the edge of the black hole. a point on the perimeter
            of the black hole will be 0.0; a point at the centre will be
            1.0; a point exactly halfway will be 0.5, and so forth. */
        Length = (Radius - Length) / Radius;

        /* Strength is the magnitude of the transformation effect. firstly,
            apply the Power variable to Length. this is meant to provide a
            means of controlling how fast the power of the Black Hole falls
            off from its centre. if Power is 2.0, then the effect is inverse
            square. increasing power will cause the Black Hole to be a lot
            weaker in its effect towards its perimeter.

            finally we multiply Strength with the Black Hole's Strength
            variable. if the resultant value exceeds 1.0 we clip it to 1.0.
            this means a point will never be transformed by more than its
            original distance from the centre. the result of this clipping
            is that you will have an 'exclusion' area near the centre of
            the black hole where all points whose final value exceeded or
            equalled 1.0 were moved by a fixed amount. this only happens
            if the Strength value of the Black Hole was greater than one. */

        DBL S = pow (Length, Power) * Strength;
        if (S > 1.0) S = 1.0;

        /* if the Black Hole is inverted, it gives the impression of 'push-
            ing' the pattern away from its centre. otherwise it sucks. */
        Delta *= (Inverted ? -S : S);

        /* add the scaled Delta to the input point to end up with TPoint. */
        TPoint += Delta;
    }

    return true;
}
Пример #5
0
/*************
 * DESCRIPTION:   Vector-valued noise function
 * INPUT:         v        noise position
 *                r        result vector
 * OUTPUT:        none
 *************/
void DNoise(VECTOR *v, VECTOR *r, short *hashTable)
{
	int ix, iy, iz, jx, jy, jz;
	float x, y, z;
	float px, py, pz, s;
	float sx, sy, sz, tx, ty, tz;
	short m;
	float tytz,sxsy,tysz,txsy;
	float *incrsum_tmp;

	/* ensures the values are positive. */
	x = v->x - MINX;
	y = v->y - MINY;
	z = v->z - MINZ;

	/* its equivalent integer lattice point. */
	ix = (int)floor(x);
	iy = (int)floor(y);
	iz = (int)floor(z);
	jx = ix + 1;
	jy = iy + 1;
	jz = iz + 1;

	sx = SCURVE(x - ix);
	sy = SCURVE(y - iy);
	sz = SCURVE(z - iz);

	/* the complement values of sx,sy,sz */
	tx = 1.f - sx;
	ty = 1.f - sy;
	tz = 1.f - sz;

	tytz = ty*tz;
	sxsy = sx*sy;
	tysz = ty*sz;
	txsy = tx*sy;

	/*
	 *  interpolate!
	 */
	m = Hash3d( ix, iy, iz ) & 0xFF;
	px = x-ix;  py = y-iy;  pz = z-iz;
	s = tx*tytz;
	INCRSUM(r->x=, m,  s,px,py,pz);
	INCRSUM(r->y=, m+4,s,px,py,pz);
	INCRSUM(r->z=, m+8,s,px,py,pz);

	m = Hash3d( jx, iy, iz ) & 0xFF;
	px = x-jx;
	s = sx*tytz;
	INCRSUM(r->x+=, m,  s,px,py,pz);
	INCRSUM(r->y+=, m+4,s,px,py,pz);
	INCRSUM(r->z+=, m+8,s,px,py,pz);

	m = Hash3d( jx, jy, iz ) & 0xFF;
	py = y-jy;
	s = sxsy*tz;
	INCRSUM(r->x+=, m,  s,px,py,pz);
	INCRSUM(r->y+=, m+4,s,px,py,pz);
	INCRSUM(r->z+=, m+8,s,px,py,pz);

	m = Hash3d( ix, jy, iz ) & 0xFF;
	px = x-ix;
	s = txsy*tz;
	INCRSUM(r->x+=, m,  s,px,py,pz);
	INCRSUM(r->y+=, m+4,s,px,py,pz);
	INCRSUM(r->z+=, m+8,s,px,py,pz);

	m = Hash3d( ix, jy, jz ) & 0xFF;
	pz = z-jz;
	s = txsy*sz;
	INCRSUM(r->x+=, m,  s,px,py,pz);
	INCRSUM(r->y+=, m+4,s,px,py,pz);
	INCRSUM(r->z+=, m+8,s,px,py,pz);

	m = Hash3d( jx, jy, jz ) & 0xFF;
	px = x-jx;
	s = sxsy*sz;
	INCRSUM(r->x+=, m,  s,px,py,pz);
	INCRSUM(r->y+=, m+4,s,px,py,pz);
	INCRSUM(r->z+=, m+8,s,px,py,pz);

	m = Hash3d( jx, iy, jz ) & 0xFF;
	py = y-iy;
	s = sx*tysz;
	INCRSUM(r->x+=, m,  s,px,py,pz);
	INCRSUM(r->y+=, m+4,s,px,py,pz);
	INCRSUM(r->z+=, m+8,s,px,py,pz);

	m = Hash3d( ix, iy, jz ) & 0xFF;
	px = x-ix;
	s = tx*tysz;
	INCRSUM(r->x+=, m,  s,px,py,pz);
	INCRSUM(r->y+=, m+4,s,px,py,pz);
	INCRSUM(r->z+=, m+8,s,px,py,pz);
}
Пример #6
0
/*************
 * DESCRIPTION:   Noise function
 * INPUT:         v        noise position
 * OUTPUT:        noise
 *************/
float Noise(VECTOR *v, short *hashTable)
{
	int ix, iy, iz, jx, jy, jz;
	float x, y, z;
	float sx, sy, sz, tx, ty, tz;
	float sum,sum1,sum2, sumj,sumj1,sumj2, res;
	short m;
	float t,s,ts1,ts2;
	float *incrsum_tmp;

	/* ensures the values are positive. */
	x = v->x - MINX;
	y = v->y - MINY;
	z = v->z - MINZ;

	/* its equivalent integer lattice point. */
	ix = (int)floor(x);
	iy = (int)floor(y);
	iz = (int)floor(z);
	jx = ix + 1;
	jy = iy + 1;
	jz = iz + 1;

	sum = x - ix;
	sumj = x - jx;
	sx = SCURVE(sum);
	sum1 = y - iy;
	sumj1 = y - jy;
	sy = SCURVE(sum1);
	sum2 = z - iz;
	sumj2 = z - jz;
	sz = SCURVE(sum2);

	/* the complement values of sx,sy,sz */
	tx = 1.f - sx;
	ty = 1.f - sy;
	tz = 1.f - sz;

	t = ty*tz;
	s = sx*sy;
	ts1 = ty*sz;
	ts2 = tx*sy;

	m = Hash3d( ix, iy, iz ) & 0xFF;
	INCRSUM(res= , m, (tx*t),   sum,  sum1,  sum2);

	m = Hash3d( jx, iy, iz ) & 0xFF;
	INCRSUM(res+=, m, (sx*t),   sumj, sum1,  sum2);

	m = Hash3d( ix, jy, iz ) & 0xFF;
	INCRSUM(res+=, m, (ts2*tz), sum,  sumj1, sum2);

	m = Hash3d( jx, jy, iz ) & 0xFF;
	INCRSUM(res+=, m, (s*tz),   sumj, sumj1, sum2);

	m = Hash3d( ix, iy, jz ) & 0xFF;
	INCRSUM(res+=, m, (tx*ts1), sum,  sum1,  sumj2);

	m = Hash3d( jx, iy, jz ) & 0xFF;
	INCRSUM(res+=, m, (sx*ts1), sumj, sum1,  sumj2);

	m = Hash3d( ix, jy, jz ) & 0xFF;
	INCRSUM(res+=, m, (ts2*sz), sum,  sumj1, sumj2);

	m = Hash3d( jx, jy, jz ) & 0xFF;
	INCRSUM(res+=, m, (s*sz),   sumj, sumj1, sumj2);

	return res;
}