private bool IsNearPolyEdge(Vector3 pos, float size) { if (size < 0.01f) { return(false); } for (int i = 0; i < points.Length - 1; i++) { if (WorldGenTool.GetEdgeDist(pos, points[i].position, points[i + 1].position) < size) { return(true); } } if (WorldGenTool.GetEdgeDist(pos, points[points.Length - 1].position, points[0].position) < size) { return(true); } return(false); }
//In world space private bool IsInsideZone(Vector3 pos) { return(WorldGenTool.IsPointInPolygon(pos, points)); }
public void SpawnBiomeGroup(BiomeSpawnData data, int index) { Random.InitState(seed + index); //Each group should have its own seed, so if one group change the other is not affected spawned_items_group.Clear(); float area_size = WorldGenTool.AreaSizePolygon(points); float density_dist = (150f - data.variance) / data.density; //Density determine minimum distance between each object of same group int spawn_max = Mathf.RoundToInt(data.density * area_size / (10f * data.variance)); //Determine max number of objects GameObject parent = new GameObject(data.name); parent.transform.SetParent(transform); parent.transform.localPosition = Vector3.zero; Vector3 min = WorldGenTool.GetPolygonMin(points); Vector3 max = WorldGenTool.GetPolygonMax(points); for (int i = 0; i < iterations; i++) { if (spawned_items_group.Count > spawn_max) { return; } Vector3 pos = new Vector3(Random.Range(min.x, max.x), this.data.elevation, Random.Range(min.z, max.z)); if (IsInsideZone(pos)) { GameObject prefab = data.PickRandomPrefab(); if (prefab != null) { WorldGenObject properties = prefab.GetComponent <WorldGenObject>(); float gsize = (properties != null) ? properties.size_group : 0.25f; //Group size float csize = (properties != null) ? properties.size : 0.25f; //Colliding size if (!IsNearOther(pos, csize) && IsFitDensity(pos, density_dist, gsize)) { bool is_valid; if (properties != null && properties.type == WorldGenObjectType.AvoidEdge) { is_valid = !IsNearPolyEdge(pos, properties.edge_dist); } else if (properties != null && properties.type == WorldGenObjectType.NearEdge) { is_valid = IsNearPolyEdge(pos, properties.edge_dist) && !IsNearPolyEdge(pos, csize); } else { is_valid = !IsNearPolyEdge(pos, csize); } if (is_valid) { GameObject nobj = InstantiatePrefab(prefab, parent.transform); nobj.transform.position = pos; if (data.random_rotation) { nobj.transform.rotation = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f); } if (data.random_scale > 0.01f) { nobj.transform.localScale = Vector3.one * (1f + Random.Range(-data.random_scale, data.random_scale)); } if (properties == null) { Collider collide = nobj.GetComponentInChildren <Collider>(); csize = collide != null ? collide.bounds.extents.magnitude : 0.25f; } spawned_items.Add(nobj); spawned_items_group.Add(nobj); group_size[nobj] = gsize; collider_size[nobj] = csize; } } } } } }