Files
Fishing2/Assets/Infinity Code/Real World Terrain/Scripts/Containers/RealWorldTerrainContainer.cs
2025-06-09 00:11:54 +08:00

169 lines
5.8 KiB
C#

/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.Linq;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
/// <summary>
/// This class is added to the resulting container.\n
/// It contains all information about terrains.
/// </summary>
[Serializable]
[AddComponentMenu("")]
public class RealWorldTerrainContainer : RealWorldTerrainMonoBase
{
/// <summary>
/// Billboard start.
/// </summary>
public float billboardStart = 50;
/// <summary>
/// Detail density.
/// </summary>
public float detailDensity = 1;
/// <summary>
/// Detail distance.
/// </summary>
public float detailDistance = 80;
/// <summary>
/// The folder in the project where located terrains.
/// </summary>
public string folder;
/// <summary>
/// Count of terrains.
/// </summary>
public RealWorldTerrainVector2i terrainCount;
/// <summary>
/// Title
/// </summary>
public string title;
/// <summary>
/// Tree distance.
/// </summary>
public float treeDistance = 2000;
/// <summary>
/// The array of elements that belong to the current process of generation.
/// </summary>
public RealWorldTerrainItem[] terrains;
/// <summary>
/// Gets all instances of RealWorldTerrainContainer.
/// </summary>
/// <returns>Instances of RealWorldTerrainContainer</returns>
public static RealWorldTerrainContainer[] GetInstances()
{
return RealWorldTerrainUtils.FindObjectsOfType<RealWorldTerrainContainer>();
}
public override RealWorldTerrainItem GetItemByWorldPosition(Vector3 worldPosition)
{
for (int i = 0; i < terrains.Length; i++)
{
RealWorldTerrainItem item = terrains[i];
if (item == null) continue;
Bounds b = new Bounds(item.bounds.center, item.bounds.size);
if (b.min.x <= worldPosition.x && b.min.z <= worldPosition.z && b.max.x >= worldPosition.x && b.max.z >= worldPosition.z)
{
return item;
}
}
return null;
}
public override bool GetWorldPosition(double lng, double lat, out Vector3 worldPosition)
{
worldPosition = new Vector3();
if (!Contains(lng, lat))
{
Debug.Log("Wrong coordinates");
return false;
}
if (terrains == null || terrains.Length == 0) return false;
double mx, my;
RealWorldTerrainGeo.LatLongToMercat(lng, lat, out mx, out my);
double lX = RealWorldTerrainMath.Clamp((mx - leftMercator) / (rightMercator - leftMercator), 0, 1);
double lZ = RealWorldTerrainMath.Clamp(1 - (my - topMercator) / (bottomMercator - topMercator), 0, 1);
Bounds cb = new Bounds(bounds.center, bounds.size);
double x = cb.size.x * lX + cb.min.x;
double z = cb.size.z * lZ + cb.min.z;
if (prefs.resultType == RealWorldTerrainResultType.terrain)
{
Terrain terrain = null;
for (int i = 0; i < terrains.Length; i++)
{
RealWorldTerrainItem item = terrains[i];
Bounds b = new Bounds(item.bounds.center, item.bounds.size);
if (b.min.x <= x && b.min.z <= z && b.max.x >= x && b.max.z >= z)
{
terrain = item.terrain;
break;
}
}
if (terrain == null) return false;
double ix = (x - terrain.gameObject.transform.position.x) / terrain.terrainData.size.x;
double iz = (z - terrain.gameObject.transform.position.z) / terrain.terrainData.size.z;
double y = terrain.terrainData.GetInterpolatedHeight((float)ix, (float)iz) + terrain.gameObject.transform.position.y;
worldPosition.x = (float)x;
worldPosition.y = (float)y;
worldPosition.z = (float)z;
}
else if (prefs.resultType == RealWorldTerrainResultType.mesh)
{
bool success = false;
for (int i = 0; i < terrains.Length; i++)
{
RealWorldTerrainItem item = terrains[i];
Bounds b = new Bounds(item.bounds.center, item.bounds.size);
if (b.min.x <= x && b.min.z <= z && b.max.x >= x && b.max.z >= z)
{
float y = 0;
RaycastHit[] hits = Physics.RaycastAll(new Vector3((float)x, item.bounds.max.y + 10, (float)z), Vector3.down, float.MaxValue);
foreach (RaycastHit hit in hits)
{
if (hit.transform.gameObject.GetComponentInParent<RealWorldTerrainItem>() != null)
{
y = hit.point.y;
break;
}
}
worldPosition.x = (float)x;
worldPosition.y = y;
worldPosition.z = (float)z;
success = true;
break;
}
}
if (!success) return false;
}
return true;
}
public override bool GetWorldPosition(Vector2 coordinates, out Vector3 worldPosition)
{
return GetWorldPosition(coordinates.x, coordinates.y, out worldPosition);
}
}
}