refactor FullDataSource.neededForPos -> firstDataPosCanAffectSecond

Many thanks to Leetom for explaining the method
This commit is contained in:
James Seibel
2023-01-18 07:40:07 -06:00
parent 7f79f4d39d
commit e631785c9c
2 changed files with 29 additions and 8 deletions
@@ -8,6 +8,7 @@ import com.seibel.lod.core.pos.DhLodPos;
import com.seibel.lod.core.file.datafile.DataMetaFile;
import com.seibel.lod.core.datatype.ILodDataSource;
import com.seibel.lod.core.pos.DhSectionPos;
import com.seibel.lod.core.util.BitShiftUtil;
import com.seibel.lod.core.util.objects.UnclosableInputStream;
import com.seibel.lod.core.logging.DhLoggerBuilder;
import com.seibel.lod.core.util.LodUtil;
@@ -230,23 +231,43 @@ public class FullDataSource extends FullArrayView implements ILodDataSource
public static FullDataSource createEmpty(DhSectionPos pos) { return new FullDataSource(pos); }
public static boolean neededForPosition(DhSectionPos posToWrite, DhSectionPos posToTest)
/** Returns whether data at the given posToWrite can effect the target region file at posToTest. */
public static boolean firstDataPosCanAffectSecond(DhSectionPos posToWrite, DhSectionPos posToTest)
{
if (!posToWrite.overlaps(posToTest))
{
// the testPosition is outside the writePosition
return false;
if (posToTest.sectionDetailLevel > posToWrite.sectionDetailLevel)
}
else if (posToTest.sectionDetailLevel > posToWrite.sectionDetailLevel)
{
// the testPosition is larger (aka is less detailed) than the writePosition,
// more detailed sections shouldn't be updated by lower detail sections
return false;
if (posToWrite.sectionDetailLevel - posToTest.sectionDetailLevel <= SECTION_SIZE_OFFSET)
}
else if (posToWrite.sectionDetailLevel - posToTest.sectionDetailLevel <= SECTION_SIZE_OFFSET)
{
// if the difference in detail levels is very large, the posToWrite
// may be skipped, due to how we sample large detail levels by only
// getting the corners.
// In this case the difference isn't very large, so return true
return true;
byte sectPerData = (byte) (1 << (posToWrite.sectionDetailLevel - posToTest.sectionDetailLevel - SECTION_SIZE_OFFSET));
return posToTest.sectionX % sectPerData == 0 && posToTest.sectionZ % sectPerData == 0;
}
else
{
// the difference in detail levels is very large,
// check if the posToWrite is in a corner of posToTest
byte sectPerData = (byte) BitShiftUtil.powerOfTwo(posToWrite.sectionDetailLevel - posToTest.sectionDetailLevel - SECTION_SIZE_OFFSET);
return posToTest.sectionX % sectPerData == 0 && posToTest.sectionZ % sectPerData == 0;
}
}
public void writeFromLower(FullDataSource subData)
{
LodUtil.assertTrue(this.sectionPos.overlaps(subData.sectionPos));
LodUtil.assertTrue(subData.sectionPos.sectionDetailLevel < this.sectionPos.sectionDetailLevel);
if (!neededForPosition(this.sectionPos, subData.sectionPos))
if (!firstDataPosCanAffectSecond(this.sectionPos, subData.sectionPos))
return;
DhSectionPos lowerSectPos = subData.sectionPos;
byte detailDiff = (byte) (this.sectionPos.sectionDetailLevel - subData.sectionPos.sectionDetailLevel);
@@ -201,7 +201,7 @@ public class DataFileHandler implements IDataSourceProvider
//TODO: The following check is temporary as we only sample corner points, which means
// on a very different level, we may not need the entire section at all.
if (!FullDataSource.neededForPosition(basePos, subPos))
if (!FullDataSource.firstDataPosCanAffectSecond(basePos, subPos))
{
continue;
}
@@ -233,7 +233,7 @@ public class DataFileHandler implements IDataSourceProvider
private void recursiveGetDataFilesForPosition(int childIndex, DhSectionPos basePos, DhSectionPos pos, ArrayList<DataMetaFile> preexistingFiles, ArrayList<DhSectionPos> missingFilePositions)
{
DhSectionPos childPos = pos.getChildByIndex(childIndex);
if (FullDataSource.neededForPosition(basePos, childPos))
if (FullDataSource.firstDataPosCanAffectSecond(basePos, childPos))
{
DataMetaFile metaFile = this.files.get(childPos);
if (metaFile != null)