/// <summary> /// Test changes between two compressed Vector3 elements and return the ideal BitCullingLevel for that change. /// </summary> public static BitCullingLevel GetGuessableBitCullLevel(CompressedElement oldComp, CompressedElement newComp, FloatRange[] fr, BitCullingLevel maxCullLvl) { for (BitCullingLevel lvl = maxCullLvl; lvl > 0; lvl--) { // Starting guess is the new lower bits using the previous upperbits if (Compare(newComp, (oldComp.ZeroLowerBits(lvl) | newComp.ZeroUpperBits(lvl)))) { return(lvl); } } return(BitCullingLevel.NoCulling); }
/// <summary> /// Attempts to guess the most likely upperbits state by seeing if each axis of the new position would be /// closer to the old one if the upper bit is incremented by one, two, three etc. Stops trying when it fails to get a better result than the last increment. /// </summary> /// <param name="oldcpos">Last best position test against.</param> /// <returns>Returns a corrected CompressPos</returns> public static CompressedElement GuessUpperBits(this CompressedElement newcpos, CompressedElement oldcpos, FloatRange[] axesranges) { CompressedElement oldUppers = oldcpos.ZeroLowerBits(); CompressedElement newLowers = newcpos.ZeroUpperBits(); CompressedElement bestGuess = oldUppers + newLowers; for (int axis = 0; axis < 3; axis++) { // value that will increase or decrease the upperbits by one uint increment = ((uint)1 << axesranges[axis].lowerBits); int multiplier = 1; // start by just applying the old uppers to the new lowers. This is the distance to beat. long lastguessdist = System.Math.Abs((long)bestGuess[axis] - oldcpos[axis]); bool lookup = true; bool lookdn = true; while (multiplier < 3) // 3 is arbitrary) { if (lookup) { // This will break if user is using the full 32 bits for an axis and they use lbits near a map edge. Should be longs to avoid that. long guessup = (long)bestGuess[axis] + increment; long updist = guessup - oldcpos[axis]; // Stop looking up if : 1. this increment is worse than best so far, value is above range max if (updist > lastguessdist || guessup > axesranges[axis].maxvalue) { lookup = false; } else // if (updist < lastguessdist) { bestGuess[axis] = (uint)guessup; lastguessdist = updist; lookdn = false; continue; } } if (lookdn) { long guessdn = ((long)bestGuess[axis] - increment); // keep as long so we can test for < 0 long dndist = oldcpos[axis] - guessdn; // Stop looking downp if : 1. this increment is worse than best so far, 2. value is below 0, or 3. value is above range max if (dndist > lastguessdist || guessdn < 0) { lookdn = false; continue; // Continue is here to prevent hitting the end break without exhausting look up } else // if (dndist < lastguessdist) { bestGuess[axis] = (uint)guessdn; lastguessdist = dndist; lookup = false; continue; } } // No improvements found, we are done looking. break; } } return(bestGuess); }
//public static CompressedPos GuessUpperBitsOld(CompressedPos oldcpos, CompressedPos newcpos) //{ // CompressedPos bestGuess = new CompressedPos(); // CompressedPos oldUppers = oldcpos.ZeroLowerBits(); // for (int i = 0; i < 3; i++) // { // uint original = newcpos[i] | oldUppers[i]; // // guess if the upperbits increased or decreased based on whether lower bits were a high or low number // uint prevLowers = oldcpos[i] & maxValue[lowerBitcount[i]]; // uint midwayValue = maxValue[lowerBitcount[i] - 1]; // // value that will increase or decrease the upperbits by one // int increment = (prevLowers > midwayValue) ? (1 << lowerBitcount[i]) : -(1 << lowerBitcount[i]); // uint offset = newcpos[i] | (oldUppers[i] + increment); // int distorig = Mathf.Abs(oldcpos[i] - original); // int distoffs = Mathf.Abs(oldcpos[i] - offset); // bestGuess[i] = (distorig < distoffs) ? original : offset; // if (distorig > distoffs) Debug.Log("Used guess "); // } // return bestGuess; //} /// <summary> /// Attempts to guess the most likely upperbits state by seeing if each axis of the new position would be /// closer to the old one if the upper bit is incremented by one, two, three etc. Stops trying when it fails to get a better result than the last increment. /// </summary> /// <param name="oldcpos">Last best position test against.</param> /// <returns>Returns a corrected CompressPos</returns> public static CompressedElement GuessUpperBits(this CompressedElement newcpos, CompressedElement oldcpos) { CompressedElement oldUppers = oldcpos.ZeroLowerBits(); CompressedElement newLowers = newcpos.ZeroUpperBits(); CompressedElement bestGuess = oldUppers + newLowers; for (int i = 0; i < 3; i++) { // value that will increase or decrease the upperbits by one uint increment = ((uint)1 << AxisRanges(i).lowerBits); int multiplier = 1; // start by just applying the old uppers to the new lowers. This is the distance to beat. //uint lastguess = oldUppers[i] | newLowers[i]; long lastguessdist = System.Math.Abs((long)bestGuess[i] - oldcpos[i]); bool lookup = true; bool lookdn = true; while (multiplier < 10) { if (lookup) { uint guessup = bestGuess[i] + increment; long updist = guessup - oldcpos[i]; if (updist < lastguessdist) { bestGuess[i] = guessup; lastguessdist = updist; lookdn = false; continue; } } if (lookdn) { uint guessdn = (uint)((long)bestGuess[i] - increment); long dndist = (long)oldcpos[i] - guessdn; if (dndist < lastguessdist) { bestGuess[i] = guessdn; lastguessdist = dndist; lookup = false; continue; } } // No improvements found, we are done looking. break; //multiplier++; //Debug.Log("increment " + ((uint)(increment * multiplier)).PrintBitMask(lowerBitcount[i])); //Debug.Log("oldpositn " + oldcpos[i].PrintBitMask(lowerBitcount[i])); //Debug.Log("lastguess " + lastguess.PrintBitMask(lowerBitcount[i])); //Debug.Log(" - - - -"); } //bestGuess[i] = lastguess; } return(bestGuess); }