Skip to content

Commit

Permalink
feat: support for zone terrain (#2648)
Browse files Browse the repository at this point in the history
  • Loading branch information
dalkia authored Nov 1, 2024
1 parent 7d23fd3 commit f425bfd
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 40 deletions.
8 changes: 5 additions & 3 deletions Explorer/Assets/DCL/Landscape/TerrainGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class TerrainGenerator : IDisposable, IContainParcel
private const float ROOT_VERTICAL_SHIFT = -0.01f; // fix for not clipping with scene (potential) floor

// increment this number if we want to force the users to generate a new terrain cache
private const int CACHE_VERSION = 8;
private const int CACHE_VERSION = 9;

private const float PROGRESS_COUNTER_EMPTY_PARCEL_DATA = 0.1f;
private const float PROGRESS_COUNTER_TERRAIN_DATA = 0.3f;
Expand Down Expand Up @@ -89,15 +89,17 @@ public TerrainGenerator(IMemoryProfiler profilingProvider, bool measureTime = fa
terrains = new List<Terrain>();
}

public void Initialize(TerrainGenerationData terrainGenData, ref NativeList<int2> emptyParcels, ref NativeParallelHashSet<int2> ownedParcels, string parcelChecksum)
public void Initialize(TerrainGenerationData terrainGenData, ref NativeList<int2> emptyParcels,
ref NativeParallelHashSet<int2> ownedParcels, string parcelChecksum, bool isZone)
{
this.ownedParcels = ownedParcels;
this.emptyParcels = emptyParcels;
this.terrainGenData = terrainGenData;

parcelSize = terrainGenData.parcelSize;
factory = new TerrainFactory(terrainGenData);
localCache = new TerrainGeneratorLocalCache(terrainGenData.seed, this.terrainGenData.chunkSize, CACHE_VERSION, parcelChecksum);
localCache = new TerrainGeneratorLocalCache(terrainGenData.seed, this.terrainGenData.chunkSize,
CACHE_VERSION, parcelChecksum, isZone);

chunkDataGenerator = new TerrainChunkDataGenerator(localCache, timeProfiler, terrainGenData, reportData);
boundariesGenerator = new TerrainBoundariesGenerator(factory, parcelSize);
Expand Down
2 changes: 1 addition & 1 deletion Explorer/Assets/DCL/Landscape/TerrainGeneratorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public async UniTask GenerateAsync()
{
IMemoryProfiler memoryProfiler = new Profiler();
gen = new TerrainGenerator(memoryProfiler, true, clearCache);
gen.Initialize(genData, ref emptyParcels, ref ownedParcels, "");
gen.Initialize(genData, ref emptyParcels, ref ownedParcels, "", false);
await gen.GenerateTerrainAndShowAsync(worldSeed, digHoles, hideTrees, hideDetails);
}

Expand Down
12 changes: 9 additions & 3 deletions Explorer/Assets/DCL/Landscape/Utils/LandscapeParcelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,25 @@ public static FetchParcelResult Empty() =>

public class LandscapeParcelService
{
private const string MANIFEST_URL = "https://places-dcf8abb.s3.amazonaws.com/WorldManifest.json";
private const string ORG_MANIFEST_URL = "https://places-dcf8abb.s3.amazonaws.com/WorldManifest.json";
private const string ZONE_MANIFEST_URL = "https://places-e22845c.s3.us-east-1.amazonaws.com/WorldManifest.json";

private readonly IWebRequestController webRequestController;
private readonly string currentManifestURL;

public LandscapeParcelService(IWebRequestController webRequestController)
public LandscapeParcelService(IWebRequestController webRequestController, bool isZone)
{
currentManifestURL = isZone ? ZONE_MANIFEST_URL : ORG_MANIFEST_URL;
this.webRequestController = webRequestController;
}

public async UniTask<FetchParcelResult> LoadManifestAsync(CancellationToken ct)
{
try
{
string? result = await webRequestController.GetAsync(new CommonArguments(URLAddress.FromString(MANIFEST_URL)), ct, ReportCategory.LANDSCAPE)
var result = await webRequestController
.GetAsync(new CommonArguments(URLAddress.FromString(currentManifestURL)), ct,
ReportCategory.LANDSCAPE)
.StoreTextAsync();

if (result != null)
Expand Down
77 changes: 49 additions & 28 deletions Explorer/Assets/DCL/Landscape/Utils/TerrainGeneratorLocalCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class TerrainLocalCache
private string checksum;
private const string FILE_NAME = "/terrain_cache";
private const string DICTIONARY_PATH = "/terrain_cache_dictionaries/";
private const string ZONE_MODIFIER = "_zone";


public const string ALPHA_MAPS = "alphaMaps";
Expand Down Expand Up @@ -76,56 +77,69 @@ public class TerrainLocalCache

private TerrainLocalCache() { }

public void SaveMetadataToFile(int seed, int chunkSize, int version, string parcelChecksum)
public void SaveMetadataToFile(int seed, int chunkSize, int version, string parcelChecksum, bool isZone)
{
var path = GetFilePath(seed, chunkSize, version);
var path = GetFilePath(seed, chunkSize, version, isZone);
checksum = parcelChecksum;
using FileStream fileStream = File.Create(path);
FORMATTER.Serialize(fileStream, this);
}

public void SaveArrayToFile<T>(string name, string offsetX, string offsetZ, T[] arrayToSave) where T : struct
public void SaveArrayToFile<T>(string name, string offsetX, string offsetZ, T[] arrayToSave, bool isZone)
where T : struct
{
var pathForDictionary = GetDictionaryFilePath(name, offsetX, offsetZ);
var pathForDictionary = GetDictionaryFilePath(name, offsetX, offsetZ, isZone);
using var fileStreamForHeights = File.Create(pathForDictionary);
FORMATTER.Serialize(fileStreamForHeights, arrayToSave);
}

public void SaveArrayToFile<T>(string name, string offsetX, string offsetZ, string layer, T[] arrayToSave)
public void SaveArrayToFile<T>(string name, string offsetX, string offsetZ, string layer, T[] arrayToSave,
bool isZone)
where T : struct
{
var pathForDictionary = GetDictionaryFilePath(name, offsetX, offsetZ, layer);
var pathForDictionary = GetDictionaryFilePath(name, offsetX, offsetZ, layer, isZone);
using var fileStreamForHeights = File.Create(pathForDictionary);
FORMATTER.Serialize(fileStreamForHeights, arrayToSave);
}

public async UniTask<T[]> RetrieveArrayFromFileAsync<T>(string name, string offsetX, string offsetZ)
public async UniTask<T[]> RetrieveArrayFromFileAsync<T>(string name, string offsetX, string offsetZ,
bool isZone)
{
await using var fileStream =
new FileStream(GetDictionaryFilePath(name, offsetX, offsetZ), FileMode.Open);
new FileStream(GetDictionaryFilePath(name, offsetX, offsetZ, isZone), FileMode.Open);
return await UniTask.RunOnThreadPool(() => (T[])FORMATTER.Deserialize(fileStream));
}

public async UniTask<T[]> RetrieveArrayFromFileAsync<T>(string name, string offsetX, string offsetZ,
string layer)
string layer, bool isZone)
{
await using var fileStream =
new FileStream(GetDictionaryFilePath(name, offsetX, offsetZ, layer), FileMode.Open);
new FileStream(GetDictionaryFilePath(name, offsetX, offsetZ, layer, isZone), FileMode.Open);
return await UniTask.RunOnThreadPool(() => (T[])FORMATTER.Deserialize(fileStream));
}

private static string GetDictionaryFilePath(string name, string x, string y)
private static string GetDictionaryFilePath(string name, string x, string y, bool isZone)
{
if (isZone)
return GetDictionaryDirectory() + $"{name}{ZONE_MODIFIER}_{x}_{y}.data";

return GetDictionaryDirectory() + $"{name}_{x}_{y}.data";
}

private static string GetDictionaryFilePath(string name, string x, string y, string layer)
private static string GetDictionaryFilePath(string name, string x, string y, string layer, bool isZone)
{
if (isZone)
return GetDictionaryDirectory() + $"{name}{ZONE_MODIFIER}_{x}_{y}_{layer}.data";

return GetDictionaryDirectory() + $"{name}_{x}_{y}_{layer}.data";
}

private static string GetFilePath(int seed, int chunkSize, int version)
private static string GetFilePath(int seed, int chunkSize, int version, bool isZone)
{
if (isZone)
return Application.persistentDataPath + FILE_NAME + ZONE_MODIFIER +
$"_{seed}_{chunkSize}_v{version}.data";

return Application.persistentDataPath + FILE_NAME + $"_{seed}_{chunkSize}_v{version}.data";
}

Expand All @@ -134,14 +148,15 @@ private static string GetDictionaryDirectory()
return Application.persistentDataPath + DICTIONARY_PATH;
}

public static async UniTask<TerrainLocalCache> LoadAsync(int seed, int chunkSize, int version, string parcelChecksum, bool force)
public static async UniTask<TerrainLocalCache> LoadAsync(int seed, int chunkSize, int version,
string parcelChecksum, bool force, bool isZone)
{
var emptyCache = new TerrainLocalCache
{
checksum = parcelChecksum,
};

string? filePath = GetFilePath(seed, chunkSize, version);
var filePath = GetFilePath(seed, chunkSize, version, isZone);
var dictionaryPath = GetDictionaryDirectory();

CheckCorruptStates();
Expand Down Expand Up @@ -199,24 +214,26 @@ public class TerrainGeneratorLocalCache
private readonly int chunkSize;
private readonly int version;
private readonly string parcelChecksum;
private readonly bool isZone;

public TerrainGeneratorLocalCache(int seed, int chunkSize, int version, string parcelChecksum)
public TerrainGeneratorLocalCache(int seed, int chunkSize, int version, string parcelChecksum, bool isZone)
{
this.seed = seed;
this.chunkSize = chunkSize;
this.version = version;
this.parcelChecksum = parcelChecksum;
this.isZone = isZone;
}

public async UniTask LoadAsync(bool force)
{
localCache = await TerrainLocalCache.LoadAsync(seed, chunkSize, version, parcelChecksum, force);
localCache = await TerrainLocalCache.LoadAsync(seed, chunkSize, version, parcelChecksum, force, isZone);
ReportHub.Log(ReportCategory.LANDSCAPE, "Landscape cache loaded and its validity status is: " + localCache.IsValid());
}

public void Save()
{
localCache.SaveMetadataToFile(seed, chunkSize, version, parcelChecksum);
localCache.SaveMetadataToFile(seed, chunkSize, version, parcelChecksum, isZone);
}

public bool IsValid() =>
Expand All @@ -226,15 +243,17 @@ public async UniTask<float[,]> GetHeightsAsync(int offsetX, int offsetZ)
{
var heightMaps = await localCache.RetrieveArrayFromFileAsync<float>(TerrainLocalCache.HEIGHTS,
offsetX.ToString(),
offsetZ.ToString());
offsetZ.ToString(),
isZone);
return UnFlatten(heightMaps, localCache.heightX, localCache.heightY);
}

public async UniTask<float[,,]> GetAlphaMapsAsync(int offsetX, int offsetZ)
{
var alphaMaps = await localCache.RetrieveArrayFromFileAsync<float>(TerrainLocalCache.ALPHA_MAPS,
offsetX.ToString(),
offsetZ.ToString());
offsetZ.ToString(),
isZone);
return UnFlatten(alphaMaps, localCache.alphaX, localCache.alphaY, localCache.alphaZ);
}

Expand All @@ -244,14 +263,15 @@ public async UniTask<TreeInstance[]> GetTreesAsync(int offsetX, int offsetZ)
var treesDTO =
await localCache.RetrieveArrayFromFileAsync<TreeInstanceDTO>(TerrainLocalCache.TREES,
offsetX.ToString(),
offsetZ.ToString());
offsetZ.ToString(),
isZone);
return treesDTO.Select(TreeInstanceDTO.ToOriginal).ToArray();
}

public async UniTask<int[,]> GetDetailLayerAsync(int offsetX, int offsetZ, int layer)
{
var detailLayer = await localCache.RetrieveArrayFromFileAsync<int>(TerrainLocalCache.DETAIL_LAYER,
offsetX.ToString(), offsetZ.ToString(), layer.ToString());
offsetX.ToString(), offsetZ.ToString(), layer.ToString(), isZone);
return UnFlatten(detailLayer, localCache.detailX, localCache.detailY);
}

Expand All @@ -260,7 +280,8 @@ public async UniTask<bool[,]> GetHolesAsync(int offsetX, int offsetZ)
try
{
var holesLayer =
await localCache.RetrieveArrayFromFileAsync<bool>("holes", offsetX.ToString(), offsetZ.ToString());
await localCache.RetrieveArrayFromFileAsync<bool>("holes", offsetX.ToString(), offsetZ.ToString(),
isZone);
return UnFlatten(holesLayer, localCache.holesX, localCache.holesY);
}
catch (Exception e)
Expand All @@ -273,7 +294,7 @@ public void SaveHoles(int offsetX, int offsetZ, bool[,] valuePairValue)
{
(bool[] array, int row, int col) valueTuple = Flatten(valuePairValue);
localCache.SaveArrayToFile(TerrainLocalCache.HOLES, offsetX.ToString(), offsetZ.ToString(),
valueTuple.array);
valueTuple.array, isZone);
localCache.holesX = valueTuple.row;
localCache.holesY = valueTuple.col;
}
Expand All @@ -283,7 +304,7 @@ public void SaveHeights(int offsetX, int offsetZ, float[,] heightArray)
{
(float[] array, int row, int col) valueTuple = Flatten(heightArray);
localCache.SaveArrayToFile(TerrainLocalCache.HEIGHTS, offsetX.ToString(), offsetZ.ToString(),
valueTuple.array);
valueTuple.array, isZone);
localCache.heightX = valueTuple.row;
localCache.heightY = valueTuple.col;
}
Expand All @@ -292,7 +313,7 @@ public void SaveAlphaMaps(int offsetX, int offsetZ, float[,,] alphaMaps)
{
(float[] array, int x, int y, int z) valueTuple = Flatten(alphaMaps);
localCache.SaveArrayToFile(TerrainLocalCache.ALPHA_MAPS, offsetX.ToString(), offsetZ.ToString(),
valueTuple.array);
valueTuple.array, isZone);
localCache.alphaX = valueTuple.x;
localCache.alphaY = valueTuple.y;
localCache.alphaZ = valueTuple.z;
Expand All @@ -301,14 +322,14 @@ public void SaveAlphaMaps(int offsetX, int offsetZ, float[,,] alphaMaps)
public void SaveTreeInstances(int offsetX, int offsetZ, TreeInstance[] instances)
{
localCache.SaveArrayToFile(TerrainLocalCache.TREES, offsetX.ToString(), offsetZ.ToString(),
instances.Select(TreeInstanceDTO.Copy).ToArray());
instances.Select(TreeInstanceDTO.Copy).ToArray(), isZone);
}

public void SaveDetailLayer(int offsetX, int offsetZ, int layer, int[,] detailLayer)
{
(int[] array, int row, int col) valueTuple = Flatten(detailLayer);
localCache.SaveArrayToFile(TerrainLocalCache.DETAIL_LAYER, offsetX.ToString(), offsetZ.ToString(),
layer.ToString(), valueTuple.array);
layer.ToString(), valueTuple.array, isZone);
localCache.detailX = valueTuple.row;
localCache.detailY = valueTuple.col;
}
Expand Down
11 changes: 7 additions & 4 deletions Explorer/Assets/DCL/PluginSystem/Global/LandscapePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class LandscapePlugin : IDCLGlobalPlugin<LandscapeSettings>
private readonly IDebugContainerBuilder debugContainerBuilder;
private readonly MapRendererTextureContainer textureContainer;
private readonly bool enableLandscape;
private readonly bool isZone;
private ProvidedAsset<RealmPartitionSettingsAsset> realmPartitionSettings;
private ProvidedAsset<LandscapeData> landscapeData;
private ProvidedAsset<ParcelData> parcelData;
Expand All @@ -41,18 +42,19 @@ public LandscapePlugin(SatelliteFloor floor,
IDebugContainerBuilder debugContainerBuilder,
MapRendererTextureContainer textureContainer,
IWebRequestController webRequestController,
bool enableLandscape)
bool enableLandscape,
bool isZone)
{
this.floor = floor;
this.assetsProvisioner = assetsProvisioner;
this.debugContainerBuilder = debugContainerBuilder;
this.textureContainer = textureContainer;
this.enableLandscape = enableLandscape;

this.isZone = isZone;
this.terrainGenerator = terrainGenerator;
this.worldTerrainGenerator = worldTerrainGenerator;

parcelService = new LandscapeParcelService(webRequestController);
parcelService = new LandscapeParcelService(webRequestController, isZone);
}

public void Dispose()
Expand Down Expand Up @@ -90,7 +92,8 @@ public async UniTask InitializeAsync(LandscapeSettings settings, CancellationTok
parcelChecksum = fetchParcelResult.Checksum;
}

terrainGenerator.Initialize(landscapeData.Value.terrainData, ref emptyParcels, ref ownedParcels, parcelChecksum);
terrainGenerator.Initialize(landscapeData.Value.terrainData, ref emptyParcels, ref ownedParcels,
parcelChecksum, isZone);
worldTerrainGenerator.Initialize(landscapeData.Value.worldsTerrainData);
}

Expand Down
3 changes: 3 additions & 0 deletions Explorer/Assets/Scripts/Global/Dynamic/BootstrapContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class BootstrapContainer : DCLGlobalContainer<BootstrapSettings>
public bool LocalSceneDevelopment { get; private set; }
public bool UseRemoteAssetBundles { get; private set; }

public DecentralandEnvironment Environment { get; private set; }

public override void Dispose()
{
base.Dispose();
Expand Down Expand Up @@ -85,6 +87,7 @@ public static async UniTask<BootstrapContainer> CreateAsync(
ApplicationParametersParser = applicationParametersParser,
DebugSettings = debugSettings,
WorldVolumeMacBus = new WorldVolumeMacBus(),
Environment = sceneLoaderSettings.DecentralandEnvironment
};

await bootstrapContainer.InitializeContainerAsync<BootstrapContainer, BootstrapSettings>(settingsContainer, ct, async container =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,10 @@ async UniTask InitializeContainersAsync(IPluginSettingsContainer settingsContain
var genesisTerrain = new TerrainGenerator(staticContainer.Profiler);
var worldsTerrain = new WorldTerrainGenerator();
var satelliteView = new SatelliteFloor();
var landscapePlugin = new LandscapePlugin(satelliteView, genesisTerrain, worldsTerrain, assetsProvisioner, debugBuilder, container.MapRendererContainer.TextureContainer, staticContainer.WebRequestsContainer.WebRequestController, dynamicWorldParams.EnableLandscape);
var landscapePlugin = new LandscapePlugin(satelliteView, genesisTerrain, worldsTerrain, assetsProvisioner,
debugBuilder, container.MapRendererContainer.TextureContainer,
staticContainer.WebRequestsContainer.WebRequestController, dynamicWorldParams.EnableLandscape,
bootstrapContainer.Environment.Equals(DecentralandEnvironment.Zone));

IMultiPool MultiPoolFactory() =>
new DCLMultiPool();
Expand Down

0 comments on commit f425bfd

Please sign in to comment.