1115 lines
34 KiB
C#
1115 lines
34 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Unity.Burst.CompilerServices;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using UnityEngine.EventSystems;
|
||
using XRLib;
|
||
using XED.Interfaces;
|
||
using XED.Manage;
|
||
using XED.RuntimeGizmo;
|
||
|
||
namespace XED
|
||
{
|
||
public class WallBuilder : MonoBehaviour, ISingle, IInputHandler, IModeController
|
||
{
|
||
public enum VirtualPoint
|
||
{
|
||
LeftTop,
|
||
LeftBottom,
|
||
RightTop,
|
||
RightBottom,
|
||
LeftCenter,
|
||
RightCenter,
|
||
}
|
||
public enum BuilderState
|
||
{
|
||
None,
|
||
PointModfiy,
|
||
PointRemove,
|
||
Drawing
|
||
}
|
||
|
||
public float thickness;
|
||
private GameObject renderParent;
|
||
private Material lineMat;
|
||
|
||
public Action<TwinObject> onRemoveWallGroupEvent;
|
||
|
||
//wall
|
||
private HashSet<Wall> walls = new();
|
||
private List<Wall> removeLines = new();
|
||
private List<LinePoint> cPoints = new();
|
||
private HashSet<LinePoint> linePoints = new();
|
||
private List<WallGroup> wallgroups = new();
|
||
|
||
Dictionary<WallGroup, List<LinePoint>> groupTable = new();
|
||
private HashSet<(Wall, Wall)> edgeTable = new();
|
||
public Dictionary<LinePoint, HashSet<Wall>> connectLines = new();
|
||
|
||
private Wall tempWall;
|
||
private LinePoint clickedPoint;
|
||
private LinePoint handlePoint;
|
||
private LinePoint pilePoint;
|
||
|
||
private HashSet<Wall> pointAddWalls = new();
|
||
private HashSet<LinePoint> addPoints = new();
|
||
|
||
public LinePoint prf_LinePoint;
|
||
public Wall prf_Wall;
|
||
public WallGroup prf_WallGroup;
|
||
|
||
private FloorCreateManager fm;
|
||
|
||
private int cc;
|
||
public Action<HashSet<Wall>> onCreateWallMesh;
|
||
int index;
|
||
|
||
public Dictionary<LinePoint, HashSet<Wall>> pointToWall = new();
|
||
|
||
internal event Action onDrawStart;
|
||
private MeshCreator meshCreator;
|
||
public class Group
|
||
{
|
||
public List<LinePoint> points = new();
|
||
public List<Wall> wallLines = new();
|
||
|
||
public void AddWallLine(Wall wallLine)
|
||
{
|
||
if (wallLines.Contains(wallLine))
|
||
return;
|
||
wallLines.Add(wallLine);
|
||
}
|
||
}
|
||
|
||
private RTGController rtgController;
|
||
public override void AfterAwake()
|
||
{
|
||
renderParent = new GameObject("LineRenderParent");
|
||
lineMat = Resources.Load<Material>("Materials/Mat_LineRender");
|
||
fm = FindSingle<FloorCreateManager>();
|
||
|
||
prf_LinePoint = Resources.Load<LinePoint>("Prefabs/PRF_LinePoint");
|
||
prf_Wall = Resources.Load<Wall>("Prefabs/PRF_Wall");
|
||
prf_WallGroup = Resources.Load<WallGroup>("Prefabs/PRF_WallGroup");
|
||
|
||
meshCreator = FindSingle<MeshCreator>();
|
||
rtgController = new();
|
||
handler = GetInputHandler();
|
||
}
|
||
|
||
public void SetWallViewMode(ViewMode mode)
|
||
{
|
||
switch (mode)
|
||
{
|
||
case ViewMode.TopView:
|
||
//2D View <20>϶<EFBFBD>
|
||
break;
|
||
case ViewMode.PerspectiveView:
|
||
MeshCreate();
|
||
break;
|
||
}
|
||
}
|
||
|
||
public void DrawWallStart()
|
||
{
|
||
SetDrawState(BuilderState.Drawing);
|
||
}
|
||
public void SetDrawState(BuilderState state)
|
||
{
|
||
drawState = state;
|
||
//GizmoController 수정해야함.
|
||
switch (drawState)
|
||
{
|
||
case BuilderState.Drawing:
|
||
DrawStart();
|
||
break;
|
||
case BuilderState.PointModfiy:
|
||
//기지모 생성?
|
||
break;
|
||
case BuilderState.PointRemove:
|
||
//나중에 팝업??
|
||
break;
|
||
default:
|
||
MeshCreate();
|
||
break;
|
||
}
|
||
}
|
||
|
||
public void RemoveSelectedPoint(LinePoint lp)
|
||
{
|
||
if (lp == null)
|
||
return;
|
||
//해당 포인트 제거
|
||
var removeWalls = new List<Wall>();
|
||
foreach (var removeWall in pointToWall[lp])
|
||
{
|
||
removeWalls.Add(removeWall);
|
||
}
|
||
for (int i= 0; i<removeWalls.Count; i++)
|
||
{
|
||
//ToDo..연결된 포인트가 없는 Point찾아서 제거
|
||
DisconnectLine(removeWalls[i]);
|
||
Destroy(removeWalls[i].gameObject);
|
||
}
|
||
Remove(lp);
|
||
}
|
||
|
||
public LinePoint CreateLinePoint(Vector3 pos)
|
||
{
|
||
var result = Instantiate(prf_LinePoint);
|
||
result.transform.SetParent(renderParent.transform);
|
||
result.name = cc++.ToString();
|
||
result.transform.position = pos;
|
||
pointToWall.TryAdd(result, new());
|
||
linePoints.Add(result);
|
||
return result;
|
||
}
|
||
|
||
void MeshCreate()
|
||
{
|
||
//여기서 수정해야함.......
|
||
foreach (var wall in walls)
|
||
{
|
||
wall.SetActiveRenderer(false);
|
||
}
|
||
meshCreator.MeshDeformer(walls);
|
||
onCreateWallMesh?.Invoke(walls);
|
||
}
|
||
|
||
private Wall CreateWall(LinePoint lcp, LinePoint rcp)
|
||
{
|
||
var result = Instantiate(prf_Wall);
|
||
result.Generate(lcp, rcp, lineMat, thickness);
|
||
result.name = "WallLine" + index++;
|
||
walls.Add(result);
|
||
pointToWall[lcp].Add(result);
|
||
pointToWall[rcp].Add(result);
|
||
return result;
|
||
}
|
||
|
||
|
||
BuilderState drawState;
|
||
public void DrawStart()
|
||
{
|
||
foreach (var wall in walls)
|
||
{
|
||
wall.SetActiveRenderer(true);
|
||
}
|
||
handlePoint = CreateLinePoint(hitPos);
|
||
onDrawStart?.Invoke();
|
||
}
|
||
|
||
|
||
public void Remove(TwinObject to)
|
||
{
|
||
if(to is WallGroup wg)
|
||
{
|
||
RemoveGroup(wg);
|
||
return;
|
||
}
|
||
if (to is not Wall wall)
|
||
return;
|
||
|
||
LinePoint lcp = wall.leftCenterPoint;
|
||
LinePoint rcp = wall.rightCenterPoint;
|
||
|
||
var lcpn = lcp != null;
|
||
var rcpn = rcp != null;
|
||
if (lcpn && rcpn)
|
||
{
|
||
DisconnectLine(wall);
|
||
if (lcp.connectPoints.Count == 0)
|
||
{
|
||
linePoints.Remove(lcp);
|
||
connectLines.Remove(lcp);
|
||
}
|
||
if (rcp.connectPoints.Count == 0)
|
||
{
|
||
linePoints.Remove(rcp);
|
||
connectLines.Remove(rcp);
|
||
}
|
||
}
|
||
walls.Remove(wall);
|
||
wall.Release();
|
||
|
||
ConnectWallReSetting(lcp);
|
||
ConnectWallReSetting(rcp);
|
||
Grouping();
|
||
}
|
||
|
||
void RemoveGroup(WallGroup wallGroup)
|
||
{
|
||
if (!wallgroups.Contains(wallGroup))
|
||
{
|
||
return;
|
||
}
|
||
|
||
var wallgroupLines = wallGroup.groupWalls;
|
||
foreach (Wall removeWall in wallgroupLines)
|
||
{
|
||
var lcp = removeWall.leftCenterPoint;
|
||
var rcp = removeWall.rightCenterPoint;
|
||
connectLines.Remove(lcp);
|
||
connectLines.Remove(rcp);
|
||
|
||
linePoints.Remove(lcp);
|
||
linePoints.Remove(rcp);
|
||
|
||
lcp.Release();
|
||
rcp.Release();
|
||
walls.Remove(removeWall);
|
||
removeWall.Release();
|
||
}
|
||
wallgroups.Remove(wallGroup);
|
||
groupTable.Remove(wallGroup);
|
||
wallGroup.Release();
|
||
}
|
||
|
||
public void WallReset()
|
||
{
|
||
foreach (var wall in /*drawLineSystem.*/walls)
|
||
{
|
||
wall.Release();
|
||
}
|
||
foreach (var linepoint in linePoints)
|
||
{
|
||
linepoint.Release();
|
||
}
|
||
|
||
foreach (var group in groupTable.Keys)
|
||
{
|
||
group.Release();
|
||
}
|
||
|
||
walls.Clear();
|
||
edgeTable.Clear();
|
||
linePoints.Clear();
|
||
groupTable.Clear();
|
||
removeLines.Clear();
|
||
connectLines.Clear();
|
||
}
|
||
|
||
internal void WallGroupMoveResetting()
|
||
{
|
||
foreach (var wall in walls)
|
||
{
|
||
CalculateLineCrossing(wall);
|
||
}
|
||
CrossLineDivide();
|
||
PointsConnectLineCalculate();
|
||
//MeshCreate();
|
||
}
|
||
|
||
//Material 벽 Mat 교체
|
||
public void TargetWallMatChange(TwinObject targetWall, Material changemat)
|
||
{
|
||
targetWall.MaterialChange(changemat);
|
||
}
|
||
|
||
class WallDivider
|
||
{
|
||
public Wall target;
|
||
public List<LinePoint> dividePoints = new();
|
||
|
||
public WallDivider(Wall target)
|
||
{
|
||
this.target = target;
|
||
}
|
||
|
||
public void AddDividePoint(LinePoint point)
|
||
{
|
||
dividePoints.Add(point);
|
||
}
|
||
|
||
public List<(LinePoint, LinePoint)> Divide()
|
||
{
|
||
dividePoints.Add(target.leftCenterPoint);
|
||
dividePoints.Add(target.rightCenterPoint);
|
||
dividePoints = dividePoints.OrderBy(x => Vector3.Distance(target.leftCenterPoint.position, x.position)).ToList();
|
||
List<(LinePoint, LinePoint)> results = new();
|
||
for(int i =0;i<dividePoints.Count-1;i++)
|
||
{
|
||
results.Add((dividePoints[i], dividePoints[i + 1]));
|
||
}
|
||
|
||
target.leftCenterPoint.Disconnect(target.rightCenterPoint);
|
||
target.rightCenterPoint.Disconnect(target.leftCenterPoint);
|
||
return results;
|
||
}
|
||
}
|
||
|
||
void Remove(LinePoint lp)
|
||
{
|
||
linePoints.Remove(lp);
|
||
pointToWall.Remove(lp);
|
||
Destroy(lp.gameObject);
|
||
}
|
||
|
||
void BuildWall(Vector3 endPos)
|
||
{
|
||
if (pilePoint == null)
|
||
{
|
||
BuildFirstWall(endPos);
|
||
}
|
||
else
|
||
{
|
||
if (Vector3.Distance(pilePoint.position, endPos) < 0.1f)
|
||
return;
|
||
|
||
if (TryGetNearPoint(endPos, out LinePoint point))
|
||
{
|
||
tempWall.leftCenterPoint.Disconnect(handlePoint);
|
||
tempWall.rightCenterPoint = point;
|
||
tempWall.leftCenterPoint.Connect(point);
|
||
Remove(handlePoint);
|
||
handlePoint = point;
|
||
}
|
||
|
||
var fixWall = BuildContinuesWall(endPos);
|
||
CalculateLineCrossing(fixWall);
|
||
|
||
var lps = fixWall.GetCenterPointPositions();
|
||
|
||
Dictionary<Wall, WallDivider> dividers = new();
|
||
foreach (var wall in walls)
|
||
{
|
||
var lps2 = wall.GetCenterPointPositions();
|
||
Vector3 cp = Vector3.zero;
|
||
// continue;
|
||
|
||
if (fixWall.isConnected(wall))
|
||
continue;
|
||
|
||
if (!Wathf.GetCrossVector(lps, lps2, ref cp))
|
||
continue;
|
||
|
||
if(!TryGetNearPoint(cp, out LinePoint clp))
|
||
clp = CreateLinePoint(cp);
|
||
|
||
dividers.TryAdd(wall, new WallDivider(wall));
|
||
dividers[wall].AddDividePoint(clp);
|
||
|
||
dividers.TryAdd(fixWall, new WallDivider(fixWall));
|
||
dividers[fixWall].AddDividePoint(clp);
|
||
}
|
||
|
||
foreach(var w in dividers)
|
||
{
|
||
var dividedLines = w.Value.Divide();
|
||
foreach(var dl in dividedLines)
|
||
{
|
||
CreateWall(dl.Item1, dl.Item2);
|
||
}
|
||
Break(w.Key);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void Break(Wall wall)
|
||
{
|
||
walls.Remove(wall);
|
||
var lcp = wall.leftCenterPoint;
|
||
var rcp = wall.rightCenterPoint;
|
||
|
||
pointToWall[lcp].Remove(wall);
|
||
pointToWall[rcp].Remove(wall);
|
||
rcp.Disconnect(lcp);
|
||
lcp.Disconnect(rcp);
|
||
|
||
if (lcp.connectPoints.Count == 0)
|
||
{
|
||
linePoints.Remove(lcp);
|
||
pointToWall.Remove(lcp);
|
||
}
|
||
|
||
if(rcp.connectPoints.Count == 0)
|
||
{
|
||
linePoints.Remove(rcp);
|
||
pointToWall.Remove(rcp);
|
||
}
|
||
wall.Deselect();
|
||
Destroy(wall.gameObject);
|
||
}
|
||
|
||
Wall BuildContinuesWall(Vector3 p)
|
||
{
|
||
var endPoint = handlePoint;
|
||
endPoint.transform.position = p;
|
||
pilePoint = endPoint;
|
||
handlePoint = CreateLinePoint(p);
|
||
var fixWall = tempWall;
|
||
tempWall = CreateWall(pilePoint, handlePoint);
|
||
return fixWall;
|
||
}
|
||
|
||
|
||
void BuildFirstWall(Vector3 p)
|
||
{
|
||
if (TryGetNearPoint(p, out LinePoint point))
|
||
{
|
||
pilePoint = point;
|
||
handlePoint = CreateLinePoint(p);
|
||
}
|
||
else
|
||
{
|
||
pilePoint = CreateLinePoint(p);
|
||
}
|
||
tempWall = CreateWall(pilePoint, handlePoint);
|
||
}
|
||
|
||
bool TryGetNearPoint(Vector3 pos, out LinePoint point)
|
||
{
|
||
point = linePoints
|
||
.Where(x => Vector3.Distance(x.position, pos) < 0.05f)
|
||
.FirstOrDefault();
|
||
|
||
return point != null && point != handlePoint;
|
||
}
|
||
|
||
#region wall
|
||
private bool OverlapLine(Wall tWall)
|
||
{
|
||
var crashPoints = tWall.crashLinePoints
|
||
.OrderByDescending(x => Vector3.Distance(tWall.rightCenterPoint.position, x.position)).ToList();
|
||
if (crashPoints.Count < 2)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
var crashWalls = tWall.crashWalls.ToList();
|
||
if (crashPoints.Count == 2)
|
||
{
|
||
if (!RemoveCrashWall(tWall, crashWalls))
|
||
{
|
||
WallConnecting(crashPoints[0], crashPoints[1], tWall);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
DisconnectLine(tWall);
|
||
walls.Remove(tWall);
|
||
tWall.Release();
|
||
|
||
var newWalls = new List<Wall>();
|
||
for (int i = 0; i < crashPoints.Count - 1; i++)
|
||
{
|
||
var newLine = CreateWall(crashPoints[i], crashPoints[i + 1]);
|
||
WallConnecting(newLine);
|
||
newWalls.Add(newLine);
|
||
}
|
||
foreach (var newWall in newWalls)
|
||
{
|
||
RemoveCrashWall(newWall, crashWalls);
|
||
WallConnecting(newWall);
|
||
tWall = newWall;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
private bool RemoveCrashWall(Wall newWall, List<Wall> crashWalls)
|
||
{
|
||
var newLcp = newWall.leftCenterPoint;
|
||
var newRcp = newWall.rightCenterPoint;
|
||
|
||
foreach (var crashWall in crashWalls)
|
||
{
|
||
if (newWall == crashWall)
|
||
continue;
|
||
var crashLcp = crashWall.leftCenterPoint;
|
||
var crashRcp = crashWall.rightCenterPoint;
|
||
|
||
if (newLcp.Equals(crashLcp) && newRcp.Equals(crashRcp))
|
||
{
|
||
DisconnectLine(crashWall);
|
||
walls.Remove(crashWall);
|
||
crashWall.Release();
|
||
return false;
|
||
}
|
||
else if (newLcp.Equals(crashRcp) && newRcp.Equals(crashLcp))
|
||
{
|
||
DisconnectLine(crashWall);
|
||
walls.Remove(crashWall);
|
||
crashWall.Release();
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
void CalculateLineCrossing(Wall target)
|
||
{
|
||
var lps = target.GetCenterPointPositions();
|
||
|
||
foreach (var wall2 in walls)
|
||
{
|
||
if (target == wall2)
|
||
continue;
|
||
|
||
var lps2 = wall2.GetCenterPointPositions();
|
||
Vector3 cp = Vector3.zero;
|
||
|
||
if (!Wathf.GetCrossVector(lps, lps2, ref cp))
|
||
continue;
|
||
|
||
var clp = CreateLinePoint(cp);
|
||
|
||
if (target.includedPoints.Add(clp))
|
||
{
|
||
pointAddWalls.Add(target);
|
||
}
|
||
if (wall2.includedPoints.Add(clp))
|
||
{
|
||
pointAddWalls.Add(wall2);
|
||
}
|
||
|
||
pointToWall[clp].Add(target);
|
||
pointToWall[clp].Add(wall2);
|
||
//connectLines[clp].Add(target);
|
||
//connectLines[clp].Add(wall2);
|
||
addPoints.Add(clp);
|
||
}
|
||
}
|
||
|
||
private void CrossLineDivide()
|
||
{
|
||
//ũ<>ν<EFBFBD><CEBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
var newLines = new List<Wall>();
|
||
foreach (var wall in pointAddWalls)
|
||
{
|
||
wall.Clear();
|
||
var lcp = wall.leftCenterPoint;
|
||
var rcp = wall.rightCenterPoint;
|
||
LinePoint curr;
|
||
LinePoint prev;
|
||
var crossPoints = wall.includedPoints.
|
||
OrderBy(l => Vector3.Distance(l.position, lcp.position)).ToList();
|
||
|
||
DisconnectLine(wall);
|
||
|
||
for (int i = 0; i < crossPoints.Count - 1; i++)
|
||
{
|
||
prev = crossPoints[i];
|
||
curr = crossPoints[i + 1];
|
||
Wall target = null;
|
||
if (i == 0)
|
||
{
|
||
target = wall;
|
||
addPoints.Add(prev);
|
||
}
|
||
else
|
||
{
|
||
target = CreateWall(prev, curr);
|
||
wall.includedPoints.Remove(curr);
|
||
//connectLines[curr].Remove(wall);
|
||
pointToWall[curr].Remove(wall);
|
||
|
||
}
|
||
newLines.Add(target);
|
||
addPoints.Add(curr);
|
||
WallConnecting(prev, curr, target);
|
||
}
|
||
}
|
||
foreach (var addWall in newLines)
|
||
{
|
||
walls.Add(addWall);
|
||
}
|
||
//crossPointTable.Clear();
|
||
pointAddWalls.Clear();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Group
|
||
|
||
private void Grouping()
|
||
{
|
||
cPoints = new(linePoints);
|
||
if (cPoints.Count == 0)
|
||
{
|
||
foreach (var removeGroup in wallgroups)
|
||
{
|
||
removeGroup.Release();
|
||
}
|
||
groupTable.Clear();
|
||
wallgroups.Clear();
|
||
return;
|
||
}
|
||
|
||
var groupList = new List<Group>();
|
||
var removeGroups = new List<WallGroup>();
|
||
|
||
PointsGroup(ref groupList);
|
||
|
||
int count = wallgroups.Count - groupList.Count;
|
||
if (count > 0)
|
||
{
|
||
for (int i = wallgroups.Count - 1; i == groupList.Count; i--)
|
||
{
|
||
removeGroups.Add(wallgroups[i]);
|
||
groupTable.Remove(wallgroups[i]);
|
||
wallgroups.Remove(wallgroups[i]);
|
||
}
|
||
}
|
||
else if (count < 0)
|
||
{
|
||
for (int i = 0; i < Mathf.Abs(count); i++)
|
||
{
|
||
CreateWallGroup();
|
||
}
|
||
}
|
||
|
||
int index = 0;
|
||
foreach (var group in wallgroups)
|
||
{
|
||
foreach (var linepoint in groupList[index].points)
|
||
{
|
||
linepoint.transform.SetParent(group.linepoints);
|
||
}
|
||
|
||
group.groupWalls = groupList[index].wallLines.ToHashSet();
|
||
foreach (var wall in groupList[index].wallLines)
|
||
{
|
||
wall.transform.SetParent(group.walls);
|
||
}
|
||
|
||
group.groupPoints = groupList[index].points.ToHashSet();
|
||
groupTable[group] = groupList[index].points;
|
||
index++;
|
||
}
|
||
|
||
foreach (var removeGroup in removeGroups)
|
||
{
|
||
removeGroup.Release();
|
||
}
|
||
}
|
||
|
||
private WallGroup CreateWallGroup()
|
||
{
|
||
var group = Instantiate(prf_WallGroup);
|
||
|
||
groupTable.Add(group, new());
|
||
wallgroups.Add(group);
|
||
group.onRemove = onRemoveWallGroupEvent;
|
||
return group;
|
||
}
|
||
|
||
private void ContainGroup(LinePoint point, Group wallgroup)
|
||
{
|
||
if (wallgroup.points.Contains(point))
|
||
return;
|
||
wallgroup.points.Add(point);
|
||
|
||
foreach (var line in connectLines[point])
|
||
{
|
||
wallgroup.AddWallLine(line);
|
||
}
|
||
}
|
||
|
||
private void AddPointGroup(LinePoint point, Group wallgroup)
|
||
{
|
||
if (wallgroup.points.Contains(point))
|
||
{
|
||
cPoints.Remove(point);
|
||
return;
|
||
}
|
||
|
||
wallgroup.points.Add(point);
|
||
foreach (var line in connectLines[point])
|
||
{
|
||
wallgroup.AddWallLine(line);
|
||
}
|
||
cPoints.Remove(point);
|
||
|
||
var points = point.connectPoints;
|
||
foreach (var cp in points)
|
||
{
|
||
if (cp.Equals(point))
|
||
{
|
||
ContainGroup(cp, wallgroup);
|
||
continue;
|
||
}
|
||
AddPointGroup(cp, wallgroup);
|
||
}
|
||
}
|
||
void PointsGroup(ref List<Group> groupList)
|
||
{
|
||
var wallGroup = new Group();
|
||
AddPointGroup(cPoints[0], wallGroup);
|
||
groupList.Add(wallGroup);
|
||
|
||
if (cPoints.Count != 0)
|
||
{
|
||
PointsGroup(ref groupList);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region Ray cast Events
|
||
|
||
bool onStayMap;
|
||
bool onClickMap;
|
||
bool onClickPoint;
|
||
Vector3 hitPos;
|
||
void UpdateLoop()
|
||
{
|
||
//DrawWall끝나고 Mesh 계산하는 부분이 빠져서 수정해야함.
|
||
if (drawState == BuilderState.Drawing)
|
||
{
|
||
if (onStayMap)
|
||
{
|
||
if (!onClickMap && onClickPoint)
|
||
{
|
||
|
||
}
|
||
else if (onClickMap && !onClickPoint)
|
||
{
|
||
//OverLap 검사?
|
||
BuildWall(hitPos);
|
||
PointsConnectLineCalculate();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
internal void OnStayMap(RaycastHit hit, Component component)
|
||
{
|
||
Debug.Log($"OnStayMap");
|
||
if (!drawState.Equals(BuilderState.Drawing))
|
||
return;
|
||
|
||
onStayMap = true;
|
||
hitPos = new Vector3(hit.point.x, hit.point.y, hit.point.z);
|
||
handlePoint.transform.position = hitPos;
|
||
|
||
if (tempWall != null)
|
||
{
|
||
tempWall.PreviewLineUpdate();
|
||
}
|
||
}
|
||
|
||
internal void OnClickLinePoint(RaycastHit hit, Component component)
|
||
{
|
||
if (drawState.Equals(BuilderState.Drawing))
|
||
return;
|
||
|
||
var tempPoint = component as LinePoint;
|
||
|
||
onClickPoint = true;
|
||
clickedPoint = tempPoint;
|
||
switch (drawState)
|
||
{
|
||
case BuilderState.PointModfiy:
|
||
break;
|
||
case BuilderState.PointRemove:
|
||
RemoveSelectedPoint(clickedPoint);
|
||
break;
|
||
}
|
||
}
|
||
|
||
internal void OnClickMap(RaycastHit hit, Component component)
|
||
{
|
||
if (EventSystem.current.currentSelectedGameObject != null)
|
||
return;
|
||
Debug.Log("OnClickMap");
|
||
onClickMap = true;
|
||
}
|
||
#endregion
|
||
|
||
private void DisconnectLine(Wall removeWall)
|
||
{
|
||
var p1 = removeWall.leftCenterPoint;
|
||
var p2 = removeWall.rightCenterPoint;
|
||
pointToWall[p1].Remove(removeWall);
|
||
pointToWall[p2].Remove(removeWall);
|
||
|
||
// connectLines[p1].Remove(removeWall);
|
||
// connectLines[p2].Remove(removeWall);
|
||
}
|
||
|
||
private void WallConnecting(Wall newWall)
|
||
{
|
||
newWall.PreviewLineUpdate();
|
||
//connectLines[newWall.leftCenterPoint].Add(newWall);
|
||
//connectLines[newWall.rightCenterPoint].Add(newWall);
|
||
pointToWall[newWall.leftCenterPoint].Add(newWall);
|
||
pointToWall[newWall.rightCenterPoint].Add(newWall);
|
||
foreach (var wallgroup in wallgroups)
|
||
{
|
||
if (wallgroup.ContainPointInWallGroup(newWall))
|
||
{
|
||
wallgroup.AddWall(newWall);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void WallConnecting(LinePoint p1, LinePoint p2, Wall newWall)
|
||
{
|
||
newWall.PreviewLineUpdate();
|
||
|
||
pointToWall[p1].Add(newWall);
|
||
pointToWall[p2].Add(newWall);
|
||
//connectLines[p1].Add(newWall);
|
||
//connectLines[p2].Add(newWall);
|
||
|
||
foreach (var wallgroup in wallgroups)
|
||
{
|
||
if (wallgroup.ContainPointInWallGroup(newWall))
|
||
{
|
||
wallgroup.AddWall(newWall);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void ConnectWallReSetting(LinePoint point)
|
||
{
|
||
foreach (var reviseWall in connectLines[point])
|
||
{
|
||
reviseWall.EdgeRecalculate();
|
||
var centerPoints = reviseWall.GetCenterPoints();
|
||
foreach (var pp in centerPoints)
|
||
{
|
||
foreach (var wall in connectLines[pp])
|
||
{
|
||
wall.Clear();
|
||
foreach (var subLine in connectLines[pp])
|
||
{
|
||
if (wall == subLine)
|
||
continue;
|
||
|
||
wall.CalculateCrossing(subLine);
|
||
subLine.CalculateCrossing(wall);
|
||
}
|
||
}
|
||
|
||
edgeTable.Clear();
|
||
|
||
foreach (var wall in connectLines[pp])
|
||
{
|
||
foreach (var crossLine in connectLines[pp])
|
||
{
|
||
if (wall == crossLine)
|
||
continue;
|
||
VirtualEdgePoint(wall, crossLine);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
addPoints.Clear();
|
||
}
|
||
|
||
private void PointsConnectLineCalculate()
|
||
{
|
||
foreach (var pp in addPoints)
|
||
{
|
||
ConnectLineVertexCalculate(pp);
|
||
}
|
||
addPoints.Clear();
|
||
}
|
||
|
||
private void ConnectLineVertexCalculate(LinePoint pp)
|
||
{
|
||
foreach (var wall in pointToWall[pp]) //connectLines[pp]
|
||
{
|
||
wall.Clear();
|
||
foreach (var subLine in pointToWall[pp]) //connectLines[pp]
|
||
{
|
||
if (wall == subLine)
|
||
continue;
|
||
|
||
wall.CalculateCrossing(subLine);
|
||
subLine.CalculateCrossing(wall);
|
||
}
|
||
}
|
||
|
||
edgeTable.Clear();
|
||
|
||
foreach (var wall in pointToWall[pp]) //connectLines[pp]
|
||
{
|
||
foreach (var crossLine in pointToWall[pp]) //connectLines[pp]
|
||
{
|
||
if (wall == crossLine)
|
||
continue;
|
||
VirtualEdgePoint(wall, crossLine);
|
||
}
|
||
}
|
||
}
|
||
|
||
void VirtualEdgePoint(Wall wall1, Wall wall2)
|
||
{
|
||
if (wall2 == wall1)
|
||
return;
|
||
if (edgeTable.Contains((wall1, wall2)))
|
||
return;
|
||
if (edgeTable.Contains((wall2, wall1)))
|
||
return;
|
||
|
||
VirtualPoint[] newLineVP = new VirtualPoint[2];
|
||
VirtualPoint[] crossLineVP = new VirtualPoint[2];
|
||
|
||
if (!wall1.RefreshVirtualPoint(VirtualPoint.LeftTop, VirtualPoint.LeftBottom, ref newLineVP))
|
||
{
|
||
return;
|
||
}
|
||
|
||
wall2.RefreshVirtualPoint(VirtualPoint.LeftTop, VirtualPoint.LeftBottom, ref crossLineVP);
|
||
var crossPoint = Vector3.zero;
|
||
var mVL = wall1.GetApplyPointPositions(newLineVP);
|
||
var sVR = wall2.GetApplyPointPositions(crossLineVP);
|
||
if (Wathf.GetCrossVector(mVL, sVR, ref crossPoint))
|
||
{
|
||
if (wall1.NearVritualEdgePoint(crossPoint, newLineVP[0]))
|
||
{
|
||
edgeTable.Add((wall1, wall2));
|
||
}
|
||
|
||
if (wall2.NearVritualEdgePoint(crossPoint, crossLineVP[0]))
|
||
{
|
||
edgeTable.Add((wall2, wall1));
|
||
}
|
||
}
|
||
}
|
||
|
||
InputHandler handler;
|
||
|
||
void MouseUp()
|
||
{
|
||
onStayMap = false;
|
||
onClickMap = false;
|
||
onClickPoint = false;
|
||
Debug.Log("Mouse Up");
|
||
}
|
||
|
||
public InputHandler GetInputHandler()
|
||
{
|
||
Dictionary<KeyCode, Action> downKeyActions = new();
|
||
downKeyActions.Add(KeyCode.Q, DrawEnd);
|
||
downKeyActions.Add(KeyCode.Mouse0, Pointing);
|
||
|
||
Dictionary<KeyCode, Action> upKeyActions = new();
|
||
upKeyActions.Add(KeyCode.Mouse0, MouseUp);
|
||
|
||
InputHandler result = new InputHandler(null, downKeyActions, upKeyActions,null, UpdateLoop);
|
||
return result;
|
||
}
|
||
|
||
public void StatusEnterEvent()
|
||
{
|
||
var raycaster = FindSingle<Raycaster>();
|
||
raycaster.AddEvent(Raycaster.EventType.FirstStay, typeof (Map), OnStayMap);
|
||
raycaster.AddEvent(Raycaster.EventType.FirstClick, typeof(Map), OnClickMap);
|
||
raycaster.AddEvent(Raycaster.EventType.FirstClick, typeof(LinePoint), OnClickLinePoint);
|
||
|
||
FindSingle<UserInputManager>().SetHandler(handler);
|
||
}
|
||
|
||
public void StatusExitEvent()
|
||
{
|
||
var raycaster = FindSingle<Raycaster>();
|
||
raycaster.RemoveEvent(Raycaster.EventType.FirstStay, typeof(Map), OnStayMap);
|
||
raycaster.RemoveEvent(Raycaster.EventType.FirstClick, typeof(Map), OnClickMap);
|
||
raycaster.RemoveEvent(Raycaster.EventType.FirstClick, typeof(LinePoint), OnClickLinePoint);
|
||
FindSingle<UserInputManager>().RemoveHandler(handler);
|
||
}
|
||
|
||
void Pointing()
|
||
{
|
||
|
||
}
|
||
|
||
void DrawEnd()
|
||
{
|
||
Debug.Log($"DrawEnd");
|
||
if (handlePoint != null)
|
||
{
|
||
linePoints.Remove(handlePoint);
|
||
pointToWall.Remove(handlePoint);
|
||
handlePoint.Release();
|
||
Destroy(handlePoint.gameObject);
|
||
}
|
||
|
||
if (pilePoint != null)
|
||
{
|
||
if (pilePoint.connectPoints.Count == 0)
|
||
{
|
||
linePoints.Remove(pilePoint);
|
||
pointToWall.Remove(pilePoint);
|
||
pilePoint.Release();
|
||
}
|
||
pilePoint = null;
|
||
}
|
||
|
||
if (tempWall != null)
|
||
{
|
||
walls.Remove(tempWall);
|
||
tempWall.Release();
|
||
Destroy(tempWall.gameObject);
|
||
}
|
||
|
||
tempWall = null;
|
||
handlePoint = null;
|
||
clickedPoint = null;
|
||
SetDrawState(BuilderState.None);
|
||
}
|
||
public ModePanel.ProgramMode mode => ModePanel.ProgramMode.WallDrawing;
|
||
|
||
#if UNITY_EDITOR
|
||
public float gizmoTh;
|
||
public float gizmosp;
|
||
|
||
|
||
private void OnDrawGizmos()
|
||
{
|
||
foreach (var wall in walls)
|
||
{
|
||
var lfps = wall.GetLeftLinePointPositions();
|
||
var rfps = wall.GetRightLinePointPositions();
|
||
var cfps = wall.GetCenterPointPositions();
|
||
|
||
Handles.color = Color.yellow;
|
||
Handles.DrawLine(lfps[0], lfps[1], gizmoTh);
|
||
Handles.color = Color.red;
|
||
Handles.DrawLine(rfps[0], rfps[1], gizmoTh);
|
||
Handles.color = Color.white;
|
||
Handles.DrawLine(cfps[0], cfps[1], gizmoTh);
|
||
Gizmos.color = Color.blue;
|
||
Gizmos.DrawSphere(lfps[0], gizmosp);
|
||
Gizmos.DrawSphere(lfps[1], gizmosp);
|
||
Gizmos.color = Color.green;
|
||
Gizmos.DrawSphere(rfps[0], gizmosp);
|
||
Gizmos.DrawSphere(rfps[1], gizmosp);
|
||
}
|
||
|
||
if (pilePoint != null)
|
||
{
|
||
Gizmos.color = Color.cyan;
|
||
Gizmos.DrawSphere(pilePoint.position, 0.1f);
|
||
}
|
||
|
||
if (clickedPoint != null)
|
||
{
|
||
Gizmos.color = Color.white;
|
||
Gizmos.DrawSphere(clickedPoint.position, 0.1f);
|
||
}
|
||
|
||
Handles.color = Color.white;
|
||
GUIStyle gs = new GUIStyle();
|
||
gs.fontStyle = FontStyle.Bold;
|
||
gs.fontSize = 20;
|
||
|
||
int i = 0;
|
||
foreach(var l in linePoints)
|
||
{
|
||
Handles.Label(l.position, $"{i++}", gs);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|