/**
  * Internal. Typically after a hit: Recompute the new curves and upcoming collission candidates.
  *
  * @param hitMask
  * @return bitmask of rocks with new curves
  */
 int doRecomputeCurvesAndCollissionTimes(
     final int hitMask, double t0, final RockSet<Pos> cp, final RockSet<Vel> cv) {
   int computedMask = 0;
   // first compute the new curves:
   // TUNE Parallel
   for (int i16 = RockSet.ROCKS_PER_SET - 1; i16 >= 0; i16--) {
     if (!RockSet.isSet(hitMask, i16)) continue;
     curveStore.add(i16, t0, doComputeCurve(i16, t0, cp, cv, NoSweep), _30);
     computedMask |= 1 << i16;
   }
   // then add all combinations of potential collissions
   t0 += hitDt;
   // TUNE Parallel
   for (int i16 = RockSet.ROCKS_PER_SET - 1; i16 >= 0; i16--) {
     if (!RockSet.isSet(computedMask, i16)) continue;
     for (int j16 = RockSet.ROCKS_PER_SET - 1; j16 >= 0; j16--) {
       if (i16 == j16 || i16 > j16 && RockSet.isSet(computedMask, j16)) continue;
       collissionStore.replace(
           i16,
           j16,
           collissionDetector.compute(
               t0, _30, curveStore.getCurve(i16), curveStore.getCurve(j16)));
     }
   }
   return computedMask;
 }
 private void recompute(final double currentTime, final boolean complete) {
   if (getSuspended()) return;
   if (complete) {
     {
       // initial
       final double t0 = 0.0;
       // TUNE Parallel
       // initial curves:
       for (int i16 = RockSet.ROCKS_PER_SET - 1; i16 >= 0; i16--) {
         curveStore.reset(i16);
         curveStore.add(i16, t0, doComputeCurve(i16, t0, initialPos, initialSpeed, NoSweep), _30);
       }
       // initial collission detection:
       collissionStore.clear();
       // TUNE Parallel
       for (int i16 = RockSet.ROCKS_PER_SET - 1; i16 >= 0; i16--)
         for (int j16 = i16 - 1; j16 >= 0; j16--)
           // log.info("collissionDetect " + i + ", " + j);
           collissionStore.add(
               collissionDetector.compute(
                   t0, _30, curveStore.getCurve(i16), curveStore.getCurve(j16)),
               i16,
               j16);
     }
     final AffineTransform m = new AffineTransform();
     // NaN-safe time range check (are we navigating known ground?):
     while (currentTime > doGetNextHit().t) {
       final Tupel nh = doGetNextHit();
       if (log.isDebugEnabled()) log.debug(nh.a + " - " + nh.b + " : " + nh.t);
       doUpdatePosAndVel(nh.t, tmpPos, tmpVel);
       // compute collission(s);
       final int mask = collider.compute(tmpPos, tmpVel, m);
       if (mask == 0) break;
       doRecomputeCurvesAndCollissionTimes(mask, nh.t, tmpPos, tmpVel);
     }
   }
   doUpdatePosAndVel(currentTime, currentPos, currentVel);
 }