@@ -5518,6 +5518,7 @@ static int IntPickInCube(int tvx, int tvy, int tvz, Vector3d& p1);
55185518
55195519DBL CracklePattern::EvaluateRaw (const Vector3d& EPoint, const Intersection *pIsection, const Ray *pRay, TraceThreadData *pThread) const
55205520{
5521+ Vector3d tmpPoint = EPoint;
55215522 DBL sum, minsum, minsum2, minsum3, tf;
55225523 int minVecIdx = 0 ;
55235524 Vector3d dv;
@@ -5527,22 +5528,29 @@ DBL CracklePattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIse
55275528 bool UseSquare = ( crackleMetric == 2 );
55285529 bool UseUnity = ( crackleMetric == 1 );
55295530
5531+ if (repeat.x ())
5532+ tmpPoint.x () = wrap (tmpPoint.x (), DBL (repeat.x ()));
5533+ if (repeat.y ())
5534+ tmpPoint.y () = wrap (tmpPoint.y (), DBL (repeat.y ()));
5535+ if (repeat.z ())
5536+ tmpPoint.z () = wrap (tmpPoint.z (), DBL (repeat.z ()));
5537+
55305538 /*
55315539 * This uses floor() not FLOOR, so it will not be a mirror
55325540 * image about zero in the range -1.0 to 1.0. The viewer
55335541 * won't see an artefact around the origin.
55345542 */
55355543
5536- flox = (int )floor (EPoint [X] - EPSILON);
5537- floy = (int )floor (EPoint [Y] - EPSILON);
5538- floz = (int )floor (EPoint [Z] - EPSILON);
5544+ flox = (int )floor (tmpPoint [X] - EPSILON);
5545+ floy = (int )floor (tmpPoint [Y] - EPSILON);
5546+ floz = (int )floor (tmpPoint [Z] - EPSILON);
55395547
55405548 /*
55415549 * Check to see if the input point is in the same unit cube as the last
55425550 * call to this function, to use cache of cubelets for speed.
55435551 */
55445552
5545- CrackleCellCoord ccoord (flox, floy, floz);
5553+ CrackleCellCoord ccoord (flox, floy, floz, repeat. x (), repeat. y (), repeat. z () );
55465554 pThread->Stats ()[CrackleCache_Tests]++;
55475555
55485556 CrackleCacheEntry dummy_entry;
@@ -5580,7 +5588,32 @@ DBL CracklePattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIse
55805588 // see InitializeCrackleCubes() below.
55815589 int *pc = gaCrackleCubeTable;
55825590 for (int i = 0 ; i < 81 ; i++, pc += 3 )
5583- IntPickInCube (flox + pc[X], floy + pc[Y], floz + pc[Z], entry->aCellNuclei [i]);
5591+ {
5592+ Vector3d wrappingOffset (0.0 );
5593+ int cacheX = flox + pc[X];
5594+ int cacheY = floy + pc[Y];
5595+ int cacheZ = floz + pc[Z];
5596+ if (repeat.x ())
5597+ {
5598+ int wrapped = wrapInt (cacheX, repeat.x ());
5599+ wrappingOffset.x () += (cacheX - wrapped);
5600+ cacheX = wrapped;
5601+ }
5602+ if (repeat.y ())
5603+ {
5604+ int wrapped = wrapInt (cacheY, repeat.y ());
5605+ wrappingOffset.y () += (cacheY - wrapped);
5606+ cacheY = wrapped;
5607+ }
5608+ if (repeat.z ())
5609+ {
5610+ int wrapped = wrapInt (cacheZ, repeat.z ());
5611+ wrappingOffset.z () += (cacheZ - wrapped);
5612+ cacheZ = wrapped;
5613+ }
5614+ IntPickInCube (cacheX, cacheY, cacheZ, entry->aCellNuclei [i]);
5615+ entry->aCellNuclei [i] += wrappingOffset;
5616+ }
55845617 }
55855618 else
55865619 {
@@ -5590,26 +5623,26 @@ DBL CracklePattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIse
55905623
55915624 // Find the 3 points with the 3 shortest distances from the input point.
55925625 // Set up the loop so the invariant is true: minsum <= minsum2 <= minsum3
5593- dv = entry->aCellNuclei [0 ] - EPoint ;
5626+ dv = entry->aCellNuclei [0 ] - tmpPoint ;
55945627
55955628 if (UseSquare)
55965629 {
55975630 minsum = dv.lengthSqr ();
55985631
5599- dv = entry->aCellNuclei [1 ] - EPoint ;
5632+ dv = entry->aCellNuclei [1 ] - tmpPoint ;
56005633 minsum2 = dv.lengthSqr ();
56015634
5602- dv = entry->aCellNuclei [2 ] - EPoint ;
5635+ dv = entry->aCellNuclei [2 ] - tmpPoint ;
56035636 minsum3 = dv.lengthSqr ();
56045637 }
56055638 else if (UseUnity)
56065639 {
56075640 minsum = fabs (dv[X]) + fabs (dv[Y]) + fabs (dv[Z]);
56085641
5609- dv = entry->aCellNuclei [1 ] - EPoint ;
5642+ dv = entry->aCellNuclei [1 ] - tmpPoint ;
56105643 minsum2 = fabs (dv[X]) + fabs (dv[Y]) + fabs (dv[Z]);
56115644
5612- dv = entry->aCellNuclei [2 ] - EPoint ;
5645+ dv = entry->aCellNuclei [2 ] - tmpPoint ;
56135646 minsum3 = fabs (dv[X]) + fabs (dv[Y]) + fabs (dv[Z]);
56145647 }
56155648 else
@@ -5618,12 +5651,12 @@ DBL CracklePattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIse
56185651 pow (fabs (dv[Y]), crackleMetric) +
56195652 pow (fabs (dv[Z]), crackleMetric);
56205653
5621- dv = entry->aCellNuclei [1 ] - EPoint ;
5654+ dv = entry->aCellNuclei [1 ] - tmpPoint ;
56225655 minsum2 = pow (fabs (dv[X]), crackleMetric) +
56235656 pow (fabs (dv[Y]), crackleMetric) +
56245657 pow (fabs (dv[Z]), crackleMetric);
56255658
5626- dv = entry->aCellNuclei [2 ] - EPoint ;
5659+ dv = entry->aCellNuclei [2 ] - tmpPoint ;
56275660 minsum3 = pow (fabs (dv[X]), crackleMetric) +
56285661 pow (fabs (dv[Y]), crackleMetric) +
56295662 pow (fabs (dv[Z]), crackleMetric);
@@ -5650,7 +5683,7 @@ DBL CracklePattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIse
56505683 // Loop for the 81 cubelets to find closest and 2nd closest.
56515684 for (int i = 3 ; i < 81 ; i++)
56525685 {
5653- dv = entry->aCellNuclei [i] - EPoint ;
5686+ dv = entry->aCellNuclei [i] - tmpPoint ;
56545687
56555688 if (UseSquare)
56565689 sum = dv.lengthSqr ();
0 commit comments