[Add] Thread fix
This commit is contained in:
@@ -9,7 +9,7 @@ namespace InfiniteWorld.VoxelWorld
|
||||
int worldSeed,
|
||||
Vector2Int chunkCoord,
|
||||
int chunkSize,
|
||||
IReadOnlyList<WorldPrefabCollection> collections,
|
||||
IReadOnlyList<WorldPrefabCollectionRuntime> collections,
|
||||
System.Func<Vector2Int, int> getBaseHeight)
|
||||
{
|
||||
if (collections == null || collections.Count == 0)
|
||||
@@ -25,15 +25,15 @@ namespace InfiniteWorld.VoxelWorld
|
||||
|
||||
for (int collectionIndex = 0; collectionIndex < collections.Count; collectionIndex++)
|
||||
{
|
||||
WorldPrefabCollection collection = collections[collectionIndex];
|
||||
if (collection == null || collection.entries == null || collection.entries.Count == 0 || collection.maxPlacementsPerChunk <= 0)
|
||||
WorldPrefabCollectionRuntime collection = collections[collectionIndex];
|
||||
if (collection == null || collection.Entries == null || collection.Entries.Count == 0 || collection.MaxPlacementsPerChunk <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int placementIndex = 0; placementIndex < collection.maxPlacementsPerChunk; placementIndex++)
|
||||
for (int placementIndex = 0; placementIndex < collection.MaxPlacementsPerChunk; placementIndex++)
|
||||
{
|
||||
if (!TryPickEntry(collection, worldSeed, chunkCoord, collectionIndex, placementIndex, out int entryIndex, out WorldPrefabEntry entry))
|
||||
if (!TryPickEntry(collection, worldSeed, chunkCoord, collectionIndex, placementIndex, out int entryIndex, out WorldPrefabEntryRuntime entry))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -71,18 +71,18 @@ namespace InfiniteWorld.VoxelWorld
|
||||
return new WorldChunkPlacementPlan(spawnPoints, terrainPatches, flattenedCells.Count > 0 ? flattenedCells : null);
|
||||
}
|
||||
|
||||
private static bool TryPickEntry(WorldPrefabCollection collection, int worldSeed, Vector2Int chunkCoord, int collectionIndex, int placementIndex, out int entryIndex, out WorldPrefabEntry entry)
|
||||
private static bool TryPickEntry(WorldPrefabCollectionRuntime collection, int worldSeed, Vector2Int chunkCoord, int collectionIndex, int placementIndex, out int entryIndex, out WorldPrefabEntryRuntime entry)
|
||||
{
|
||||
float totalWeight = 0f;
|
||||
for (int i = 0; i < collection.entries.Count; i++)
|
||||
for (int i = 0; i < collection.Entries.Count; i++)
|
||||
{
|
||||
WorldPrefabEntry candidate = collection.entries[i];
|
||||
if (candidate == null || candidate.prefab == null || candidate.weight <= 0f)
|
||||
WorldPrefabEntryRuntime candidate = collection.Entries[i];
|
||||
if (candidate == null || !candidate.HasPrefab || candidate.Weight <= 0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
totalWeight += candidate.weight;
|
||||
totalWeight += candidate.Weight;
|
||||
}
|
||||
|
||||
if (totalWeight <= 0f)
|
||||
@@ -94,15 +94,15 @@ namespace InfiniteWorld.VoxelWorld
|
||||
|
||||
float pick = WorldSeedUtility.Value01(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, 1)) * totalWeight;
|
||||
float accumulated = 0f;
|
||||
for (int i = 0; i < collection.entries.Count; i++)
|
||||
for (int i = 0; i < collection.Entries.Count; i++)
|
||||
{
|
||||
WorldPrefabEntry candidate = collection.entries[i];
|
||||
if (candidate == null || candidate.prefab == null || candidate.weight <= 0f)
|
||||
WorldPrefabEntryRuntime candidate = collection.Entries[i];
|
||||
if (candidate == null || !candidate.HasPrefab || candidate.Weight <= 0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
accumulated += candidate.weight;
|
||||
accumulated += candidate.Weight;
|
||||
if (pick <= accumulated)
|
||||
{
|
||||
entryIndex = i;
|
||||
@@ -111,10 +111,10 @@ namespace InfiniteWorld.VoxelWorld
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = collection.entries.Count - 1; i >= 0; i--)
|
||||
for (int i = collection.Entries.Count - 1; i >= 0; i--)
|
||||
{
|
||||
WorldPrefabEntry candidate = collection.entries[i];
|
||||
if (candidate == null || candidate.prefab == null || candidate.weight <= 0f)
|
||||
WorldPrefabEntryRuntime candidate = collection.Entries[i];
|
||||
if (candidate == null || !candidate.HasPrefab || candidate.Weight <= 0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -129,36 +129,36 @@ namespace InfiniteWorld.VoxelWorld
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool PassesSpawnChance(WorldPrefabEntry entry, int worldSeed, Vector2Int chunkCoord, int collectionIndex, int placementIndex)
|
||||
private static bool PassesSpawnChance(WorldPrefabEntryRuntime entry, int worldSeed, Vector2Int chunkCoord, int collectionIndex, int placementIndex)
|
||||
{
|
||||
if (entry == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry.spawnChancePercent <= 0f)
|
||||
if (entry.SpawnChancePercent <= 0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry.spawnChancePercent >= 100f)
|
||||
if (entry.SpawnChancePercent >= 100f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
float roll = WorldSeedUtility.Value01(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, 11)) * 100f;
|
||||
return roll <= entry.spawnChancePercent;
|
||||
return roll <= entry.SpawnChancePercent;
|
||||
}
|
||||
|
||||
private static bool TryPlanPlacement(
|
||||
int worldSeed,
|
||||
Vector2Int chunkCoord,
|
||||
int chunkSize,
|
||||
WorldPrefabCollection collection,
|
||||
WorldPrefabCollectionRuntime collection,
|
||||
int collectionIndex,
|
||||
int placementIndex,
|
||||
int entryIndex,
|
||||
WorldPrefabEntry entry,
|
||||
WorldPrefabEntryRuntime entry,
|
||||
int spawnOrdinal,
|
||||
HashSet<Vector2Int> occupiedCells,
|
||||
HashSet<Vector2Int> flattenedCells,
|
||||
@@ -172,20 +172,20 @@ namespace InfiniteWorld.VoxelWorld
|
||||
patch = null;
|
||||
|
||||
Vector2Int chunkOrigin = new Vector2Int(chunkCoord.x * chunkSize, chunkCoord.y * chunkSize);
|
||||
int attempts = Mathf.Max(1, collection.attemptsPerPlacement);
|
||||
int attempts = Mathf.Max(1, collection.AttemptsPerPlacement);
|
||||
for (int attempt = 0; attempt < attempts; attempt++)
|
||||
{
|
||||
int rotationSteps = entry.allowRotations ? WorldSeedUtility.Range(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, attempt, 2), 0, 4) : 0;
|
||||
Vector2Int footprint = GetFootprint(entry.footprint, rotationSteps);
|
||||
int rotationSteps = entry.AllowRotations ? WorldSeedUtility.Range(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, attempt, 2), 0, 4) : 0;
|
||||
Vector2Int footprint = GetFootprint(entry.Footprint, rotationSteps);
|
||||
if (footprint.x <= 0 || footprint.y <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int localMinX = collection.chunkEdgePadding;
|
||||
int localMinZ = collection.chunkEdgePadding;
|
||||
int localMaxX = chunkSize - collection.chunkEdgePadding - footprint.x;
|
||||
int localMaxZ = chunkSize - collection.chunkEdgePadding - footprint.y;
|
||||
int localMinX = collection.ChunkEdgePadding;
|
||||
int localMinZ = collection.ChunkEdgePadding;
|
||||
int localMaxX = chunkSize - collection.ChunkEdgePadding - footprint.x;
|
||||
int localMaxZ = chunkSize - collection.ChunkEdgePadding - footprint.y;
|
||||
if (localMaxX < localMinX || localMaxZ < localMinZ)
|
||||
{
|
||||
continue;
|
||||
@@ -194,14 +194,14 @@ namespace InfiniteWorld.VoxelWorld
|
||||
int localX = WorldSeedUtility.Range(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, attempt, 3), localMinX, localMaxX + 1);
|
||||
int localZ = WorldSeedUtility.Range(WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex, placementIndex, attempt, 4), localMinZ, localMaxZ + 1);
|
||||
RectInt footprintRect = new RectInt(localX, localZ, footprint.x, footprint.y);
|
||||
RectInt reservedRect = ExpandRect(footprintRect, Mathf.Max(0, entry.clearance), chunkSize);
|
||||
RectInt reservedRect = ExpandRect(footprintRect, Mathf.Max(0, entry.Clearance), chunkSize);
|
||||
|
||||
if (IntersectsOccupied(chunkOrigin, reservedRect, occupiedCells))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.placementMode == WorldPlacementMode.GroundOnly)
|
||||
if (entry.PlacementMode == WorldPlacementMode.GroundOnly)
|
||||
{
|
||||
if (!IsGroundArea(chunkOrigin, reservedRect, flattenedCells, getBaseHeight))
|
||||
{
|
||||
@@ -227,7 +227,7 @@ namespace InfiniteWorld.VoxelWorld
|
||||
long spawnId = WorldSeedUtility.ToStableId(
|
||||
WorldSeedUtility.Hash(worldSeed, chunkCoord.x, chunkCoord.y, collectionIndex),
|
||||
WorldSeedUtility.Hash(entryIndex, placementIndex, spawnOrdinal, footprintRect.x, footprintRect.y));
|
||||
spawnPoint = new WorldSpawnPoint(spawnId, chunkCoord, spawnOrdinal, collectionIndex, entryIndex, entry, position, Quaternion.Euler(0f, rotationY, 0f));
|
||||
spawnPoint = new WorldSpawnPoint(spawnId, chunkCoord, spawnOrdinal, collectionIndex, entryIndex, entry.Id, position, Quaternion.Euler(0f, rotationY, 0f));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -239,14 +239,14 @@ namespace InfiniteWorld.VoxelWorld
|
||||
int chunkSize,
|
||||
RectInt footprintRect,
|
||||
RectInt reservedRect,
|
||||
WorldPrefabEntry entry,
|
||||
WorldPrefabEntryRuntime entry,
|
||||
HashSet<Vector2Int> occupiedCells,
|
||||
HashSet<Vector2Int> flattenedCells,
|
||||
System.Func<Vector2Int, int> getBaseHeight,
|
||||
out WorldTerrainPatch patch,
|
||||
out List<Vector2Int> reservedCells)
|
||||
{
|
||||
int flattenPadding = Mathf.Max(entry.clearance, entry.flattenPadding);
|
||||
int flattenPadding = Mathf.Max(entry.Clearance, entry.FlattenPadding);
|
||||
RectInt flattenRect = ExpandRect(footprintRect, flattenPadding, chunkSize);
|
||||
List<Vector2Int> flattened = CollectCells(chunkOrigin, flattenRect);
|
||||
if (IntersectsOccupied(flattened, occupiedCells))
|
||||
@@ -256,7 +256,7 @@ namespace InfiniteWorld.VoxelWorld
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Vector2Int> corridor = TryBuildAccessCorridor(chunkOrigin, chunkSize, flattenRect, Mathf.Max(1, entry.flattenSearchRadius), occupiedCells, flattenedCells, getBaseHeight);
|
||||
List<Vector2Int> corridor = TryBuildAccessCorridor(chunkOrigin, chunkSize, flattenRect, Mathf.Max(1, entry.FlattenSearchRadius), occupiedCells, flattenedCells, getBaseHeight);
|
||||
if (corridor == null)
|
||||
{
|
||||
patch = null;
|
||||
|
||||
Reference in New Issue
Block a user