Files
SHI-Cesium/Assets/Scripts/RectangleMeasureGroup.cs
2025-09-15 22:09:10 +09:00

158 lines
5.0 KiB
C#

using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UI;
public class RectangleMeasureGroup : MeasureGroup
{
private PolygonMeasureGroupInfoPopup polygonMeasureGroupInfoPopup;
public override void AddPoint(Vector3 pos)
{
if(points.Count >= 3)
return;
points.Add(pos);
switch (points.Count)
{
case 1:
AddFirstPoint(pos);
break;
case 2:
AddSecondPoint(pos);
break;
case 3:
AddThirdPoint(pos);
break;
}
}
private void AddFirstPoint(Vector3 pos)
{
if (!polygonMeasureGroupInfoPopup)
{
polygonMeasureGroupInfoPopup = Instantiate(polygonInfoPopupPrefab).GetComponent<PolygonMeasureGroupInfoPopup>();
polygonMeasureGroupInfoPopup.InitUI(infoPopupRoot);
polygonMeasureGroupInfoPopup.transform.position = pos + new Vector3(20, 0, 20);
}
GameObject label = Instantiate(labelPrefab, pos, Quaternion.identity, labelRoot);
labels.Add(label);
}
private void AddSecondPoint(Vector3 pos)
{
while (labels.Count < 4)
{
GameObject label = Instantiate(labelPrefab, pos, Quaternion.identity, labelRoot);
labels.Add(label);
}
}
private void AddThirdPoint(Vector3 pos)
{
deleteButton = Instantiate(deleteButtonPrefab, points[0], Quaternion.identity, infoPopupRoot);
deleteButton.GetComponentInChildren<Button>().onClick.AddListener(() => DestroyAll());
deleteButton.transform.position = points[0] + new Vector3(-20, 0, 20);
FindAnyObjectByType<MeasureManager>().isMeasuring = false;
}
public override void EndMeasure()
{
DestroyAll();
FindAnyObjectByType<MeasureManager>().isMeasuring = false;
}
public override void DestroyAll()
{
base.DestroyAll();
Destroy(polygonMeasureGroupInfoPopup.gameObject);
Destroy(this);
}
public override void LateUpdate()
{
base.LateUpdate();
if (polygonMeasureGroupInfoPopup)
{
polygonMeasureGroupInfoPopup.transform.LookAt(polygonMeasureGroupInfoPopup.transform.position + cam.transform.forward);
float heightDiff = Mathf.Abs(cam.transform.position.y - polygonMeasureGroupInfoPopup.transform.position.y);
polygonMeasureGroupInfoPopup.transform.localScale = Vector3.one * (heightDiff * lineScaleMultiplier);
}
}
public override void UpdatePreviewLine(Vector3 mousePos)
{
if (line == null)
return;
if (points.Count == 1 && labels.Count == 1)
{
line.positionCount = 2;
line.SetPosition(0, points[0]);
line.SetPosition(1, mousePos);
Vector3 mid = (points[0] + mousePos) * 0.5f;
labels[0].transform.position = mid;
// 거리 계산
double3 llh_a = GeoUtils.GetLonLatHeight(cesiumGeoreference, points[0]);
double3 llh_b = GeoUtils.GetLonLatHeight(cesiumGeoreference, mousePos);
double dist = GeoUtils.Haversine(llh_a.x, llh_a.y, llh_b.x, llh_b.y);
labels[0].GetComponentInChildren<TextMeshProUGUI>().text = $"{dist:F1} m";
polygonMeasureGroupInfoPopup?.UpdateInfo("(없음)", llh_b.x, llh_b.y, dist, 0);
}
else if (points.Count == 2)
{
Vector3 a = points[0];
Vector3 b = points[1];
Vector3 ab = b - a;
// 직각 백터
Vector3 perp = new Vector3(-ab.z, 0, ab.x).normalized;
// 높이
Vector3 ac = mousePos - a;
float length = Vector3.Dot(ac, perp);
Vector3 c = b + perp * length;
Vector3 d = a + (c - b);
// 라인 업데이트
line.positionCount = 5;
line.SetPositions(new Vector3[] { a, b, c, d, a });
double totalDistance = 0;
double width = 0, height = 0;
Vector3[] corners = { a, b, c, d };
for (int i = 0; i < 4; i++)
{
int j = (i + 1) % 4;
Vector3 mid = (corners[i] + corners[j]) * 0.5f;
labels[i].transform.position = mid;
double3 llh_a = GeoUtils.GetLonLatHeight(cesiumGeoreference, corners[i]);
double3 llh_b = GeoUtils.GetLonLatHeight(cesiumGeoreference, corners[j]);
double dist = GeoUtils.Haversine(llh_a.x, llh_a.y, llh_b.x, llh_b.y);
labels[i].GetComponentInChildren<TextMeshProUGUI>().text = $"{dist:F1} m";
totalDistance += dist;
if (i == 0) width = dist;
if (i == 1) height = dist;
}
double area = width * height;
double3 llh_c = GeoUtils.GetLonLatHeight(cesiumGeoreference, c);
polygonMeasureGroupInfoPopup?.UpdateInfo("(없음)", llh_c.x, llh_c.y, totalDistance, area);
}
}
}