using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Security.Cryptography; using UnityEngine; using WI; using static XED.WallBuilder; using Color = UnityEngine.Color; namespace XED { public class Wall : TwinObject { public enum VertexPoint { RightTop, LeftCenter, LeftTop, LeftBottom, RightCenter, RightBottom } public MeshFilter meshfilter; private LineRenderer lineRenderer; private MeshRenderer mr; public float height = 2; private float thickness = 0.1f; public Vector3 offset = new Vector3(0, 1, 0); public Vector3[] n_GonPoints = new Vector3[6]; private TwoPointLine line; public Color wallColor; private CreateWireFrame wireFrame; public HashSet includedPoints = new(); private Dictionary linePointTable = new Dictionary(); public LinePoint leftCenterPoint; public LinePoint rightCenterPoint; private Vector3[] linePoints = new Vector3[6]; private Vector3[] vertexs = new Vector3[6]; private BoxCollider boxCollider; public override void AfterAwake() { var mat = Resources.Load("Materials/Mat_WallMat"); wireFrame = new GameObject("WireFrame").AddComponent(); wireFrame.transform.SetParent(transform); wireFrame.Displayable(false); meshfilter = GetComponent(); mr = GetComponent(); mr.material = mat; wallColor = mr.material.color; lineRenderer = GetComponent(); line = new(lineRenderer); boxCollider = GetComponent(); physics.areabox = boxCollider; base.AfterAwake(); } public void Generate(LinePoint lcp, LinePoint rcp, Material lineMat, float thickness) { this.thickness = thickness; leftCenterPoint = lcp; rightCenterPoint = rcp; lcp.Connect(rcp); rcp.Connect(lcp); //SetVirtualEdgePoints(leftCenterPoint.position, rightCenterPoint.position, thickness); var dir = (rcp.position- lcp.position).normalized; var vt1 = dir * (thickness * 0.5f); var vp1 = RotateVector3(vt1, 90f); var vp2 = RotateVector3(vt1, -90f); var dir2 = (lcp.position - rcp.position).normalized; var vt2 = dir2 * (thickness * 0.5f); var vp3 = RotateVector3(vt2, 90f); var vp4 = RotateVector3(vt2, -90f); vp1 += lcp.position; vp4 += rcp.position; vp2 += lcp.position; vp3 += rcp.position; var points = new Vector3[] { vp2, vp3, vp1, vp4, lcp.position, rcp.position }; vertexs = points; for (int i = 0; i < vertexs.Length; i++) { linePoints[i] = vertexs[i]; } line.RendererUpdate(leftCenterPoint.position, rightCenterPoint.position); //BoxColliderSizeSetting(leftCenterPoint, rightCenterPoint); var distnace = Vector3.Distance(lcp.position, rcp.position)/*-0.1f<0 ? 0 : Vector3.Distance(p1.position, p2.position) - 0.1f*/; var pos = (lcp.position + rcp.position) * 0.5f; boxCollider.center = new Vector3(0f, height * 0.5f, 0f); boxCollider.size = new Vector3(thickness, 2f, distnace); transform.position = pos; boxCollider.transform.LookAt(rcp.position); SetActiveRenderer(true); line.LineRenderSetting(lineMat, this.thickness); boxCollider.enabled = false; for (int i = 0; i < 6; i++) { linePointTable.TryAdd((VirtualPoint)i, false); } } public void EdgeRecalculate() { SetVirtualEdgePoints(leftCenterPoint.position, rightCenterPoint.position); } public void PreviewLineUpdate() { SetVirtualEdgePoints(leftCenterPoint.position, rightCenterPoint.position); for (int i = 0; i < vertexs.Length; i++) { linePoints[i] = vertexs[i]; } //includedPoints.Clear(); //includedPoints.Add(leftCenterPoint); //includedPoints.Add(rightCenterPoint); line.RendererUpdate(leftCenterPoint.position, rightCenterPoint.position); //BoxColliderSizeSetting(leftCenterPoint, rightCenterPoint); //SetActiveRenderer(true); } public void MoveLine() { EdgeRecalculate(); line.RendererUpdate(leftCenterPoint.position, rightCenterPoint.position); } public void SetMeshVertice() { var vertices = new Vector3[] { linePoints[(int)VirtualPoint.RightTop], vertexs[(int)VirtualPoint.LeftCenter], linePoints[(int)VirtualPoint.LeftTop], linePoints[(int)VirtualPoint.LeftBottom], vertexs[(int)VirtualPoint.RightCenter], linePoints[(int)VirtualPoint.RightBottom] }; SetActiveRenderer(false); MeshDeformer(vertices.Length, vertices); } public Vector3[] GetApplyPointPositions(VirtualPoint[] vps) { var p1 = vertexs[(int)vps[0]]; var p2 = vertexs[(int)vps[1]]; var dir = (p2 - p1).normalized; var dir2 = (p1 - p2).normalized; p1 += (dir2 * 2f); p2 += (dir * 2f); return new Vector3[] { p1, p2 }; } public bool NearVritualEdgePoint(Vector3 point, VirtualPoint vp) { var p1 = vertexs[(int)vp]; var p2 = vertexs[(int)vp + 1]; var distance = Vector3.Distance(p1, point); var distance2 = Vector3.Distance(p2, point); if (distance < distance2) { if (linePointTable[vp]) { vp += 1; } } else { if (!linePointTable[vp + 1]) { vp += 1; } } SetVertex(vp, point); return true; } //�ش� line�� ���� Meshwall�� ���� private void MeshDeformer(int polygon, Vector3[] points) { if (points == null || points.Length == 0) return; if (PrevPointsCompare(points)) return; Matrix4x4 wolrdtoLocal = transform.worldToLocalMatrix; for (int i = 0; i < points.Length; i++) { Vector3 local = wolrdtoLocal.MultiplyPoint3x4(points[i]); n_GonPoints[i] = local; } // SetMeshData(polygon); // MeshRefresh(); } private bool PrevPointsCompare(Vector3[] points) { int index = 0; foreach (var point in points) { var distance = Vector3.Distance(n_GonPoints[index], point); if (distance > 0.01f) { return false; } index++; } return true; } public override void MaterialChange(Material mat) { mr.material = mat; } public LinePoint[] GetCenterPoints() { var centerPoints = new LinePoint[2] { leftCenterPoint, rightCenterPoint }; return centerPoints; } public Vector3[] GetLeftPointPositions() { var lt = vertexs[(int)VirtualPoint.LeftTop]; var lb = vertexs[(int)VirtualPoint.LeftBottom]; return new Vector3[] { lt, lb }; } public Vector3[] GetRightPointPositions() { var rt = vertexs[(int)VirtualPoint.RightTop]; var rb = vertexs[(int)VirtualPoint.RightBottom]; return new Vector3[] { rt, rb }; } public Vector3[] GetCenterPointPositions() { var ct = vertexs[(int)VirtualPoint.LeftCenter]; var cb = vertexs[(int)VirtualPoint.RightCenter]; return new Vector3[] { ct, cb }; } private void NearVertextPoint(Vector3 points, VirtualPoint vp) { var p1 = vertexs[(int)vp]; var p2 = vertexs[(int)vp + 1]; var distance = Vector3.Distance(p1, points); var distance2 = Vector3.Distance(p2, points); if (distance < distance2) { SetVertex(vp, points); } else { SetVertex(vp + 1, points); } } void SetVertex(VirtualPoint vp, Vector3 point) { linePoints[(int)vp] = point; linePointTable[vp] = true; } //Top,Top bottom, bottom �� �Ѵ� false�ų� �Ѵ� true �ΰ�쿡�� �����ϰ� //�����ϳ� true�� ����ѹ� ���ؾ��Ѵ�. public bool RefreshVirtualPoint(VirtualPoint cvp, VirtualPoint tvp, ref VirtualPoint[] vps) { if (linePointTable[cvp] != linePointTable[cvp + 2]) { vps = linePointTable[cvp] ? new VirtualPoint[2] { cvp + 2, cvp + 3 } : new VirtualPoint[2] { cvp, cvp + 1 }; return true; } if (linePointTable[tvp] != linePointTable[tvp + 2]) { vps = linePointTable[tvp] ? new VirtualPoint[2] { tvp + 1, tvp + 2 } : new VirtualPoint[2] { tvp - 1, tvp }; return true; } return false; } internal void CalculateCrossing(Wall subWall) { var mVL = GetLeftPointPositions(); var mVR = GetRightPointPositions(); var sVL = subWall.GetLeftPointPositions(); var sVR = subWall.GetRightPointPositions(); Vector3 crossPoint = Vector3.zero; //mvl[1], svl[0] �̶� ������ ��ġ //mvr[1],svr[0] �̶� ������ ��ġ false if (Wathf.GetCrossVector(mVL, sVL, ref crossPoint)) { NearVertextPoint(crossPoint, VirtualPoint.LeftTop); } if (Wathf.GetCrossVector(mVL, sVR, ref crossPoint)) { NearVertextPoint(crossPoint, VirtualPoint.LeftTop); } //----------------------------------------------------------------------------------- if (Wathf.GetCrossVector(mVR, sVL, ref crossPoint)) { NearVertextPoint(crossPoint, VirtualPoint.RightTop); } if (Wathf.GetCrossVector(mVR, sVR, ref crossPoint)) { NearVertextPoint(crossPoint, VirtualPoint.RightTop); } } public void PositionChange(LinePoint point) { //if (!movePoint.ContainsKey(point)) // return; var virtualPoint = VirtualPoint.LeftCenter; if (leftCenterPoint.Equals(point)) virtualPoint = VirtualPoint.LeftCenter; else virtualPoint = VirtualPoint.RightCenter; //var virtualPoint = movePoint[point]; linePoints[(int)virtualPoint] = point.position; line.RendererUpdate(leftCenterPoint.position, rightCenterPoint.position); } public void RealTimeLineRenderSetting(LinePoint p1, LinePoint p2) { line.RendererUpdate(p1.position, p2.position); BoxColliderSizeSetting(p1, p2); } private void BoxColliderSizeSetting(LinePoint p1, LinePoint p2) { var distnace = Vector3.Distance(p1.position, p2.position)/*-0.1f<0 ? 0 : Vector3.Distance(p1.position, p2.position) - 0.1f*/; var pos = (p1.position + p2.position) * 0.5f; boxCollider.center = new Vector3(0f, height * 0.5f, 0f); ; boxCollider.size = new Vector3(thickness, 2f, distnace); transform.position = pos; boxCollider.transform.LookAt(p2.position); } public override void SetDisplayable(bool value) { IsDisplayable = value; SetActiveRenderer(value); } public override void SetInteractible(bool value) { IsInteractible = value; physics.areabox.enabled = value; } void SetWallColor(Color color) { var mpb = new MaterialPropertyBlock(); mr.GetPropertyBlock(mpb); mpb.SetColor("_BaseColor", color); mr.SetPropertyBlock(mpb); } public override void Select() { Debug.Log("SelectWall"); SetWallColor(Color.red); line.Select(); } public override void Deselect() { //SetWallColor(wallColor); //line.Deselect(); } public void SetActiveRenderer(bool value) { if (IsDisplayable) { line.SetActive(value); wireFrame.Displayable(!value); mr.enabled = !value; var centrPoints = GetCenterPoints(); foreach (var point in centrPoints) { point.Displayable(value); } } else { line.SetActive(false); wireFrame.Displayable(false); mr.enabled = false; var centrPoints = GetCenterPoints(); foreach (var point in centrPoints) { point.Displayable(false); } } } public void Clear() { foreach (var kvp in linePointTable.ToList()) { linePointTable[kvp.Key] = false; } } public void Release() { foreach (var kvp in linePointTable.ToList()) { linePointTable[kvp.Key] = false; } foreach (var crashWall in crashWalls) { crashWall.crashWalls.Remove(this); } crashLinePoints.Clear(); crashWalls.Clear(); includedPoints.Clear(); var mpb = new MaterialPropertyBlock(); mr.GetPropertyBlock(mpb); mpb.SetColor("_BaseColor", wallColor); mr.SetPropertyBlock(mpb); line.Deselect(); gameObject.SetActive(false); } public void SetVirtualEdgePoints(Vector3 start, Vector3 end) { //var _thickness = thickness; var dir = (end - start).normalized; var vt1 = dir * (thickness * 0.5f); var vp1 = RotateVector3(vt1, 90f); var vp2 = RotateVector3(vt1, -90f); var dir2 = (start - end).normalized; var vt2 = dir2 * (thickness * 0.5f); var vp3 = RotateVector3(vt2, 90f); var vp4 = RotateVector3(vt2, -90f); vp1 += start; vp4 += end; vp2 += start; vp3 += end; var points = new Vector3[] { vp2, vp3, vp1, vp4, start, end }; vertexs= points; } Vector3 RotateVector3(Vector3 d, float rot) { var ea = Quaternion.AngleAxis(rot, Vector3.up) * d; return ea; } public HashSet crashLinePoints = new(); public HashSet crashWalls = new(); private void OnTriggerEnter(Collider other) { if (other.transform.TryGetComponent(out LinePoint point)) { crashLinePoints.Add(point); } if(other.transform.TryGetComponent(out Wall wall)) { crashWalls.Add(wall); } } private void OnTriggerExit(Collider other) { if (other.transform.TryGetComponent(out LinePoint point)) { crashLinePoints.Remove(point); } if (other.transform.TryGetComponent(out Wall wall)) { crashWalls.Remove(wall); } } public bool CheckVirtualPointConnection() { var b1 = linePointTable[VirtualPoint.LeftTop] == linePointTable[VirtualPoint.RightTop]; var b2 = linePointTable[VirtualPoint.LeftBottom] == linePointTable[VirtualPoint.RightBottom]; return b1 && b2; } //����� �׸���� public Vector3[] GetLeftLinePointPositions() { var lt = linePoints[(int)VirtualPoint.LeftTop]; var lb = linePoints[(int)VirtualPoint.LeftBottom]; return new Vector3[] { lt, lb }; } public Vector3[] GetRightLinePointPositions() { var rt = linePoints[(int)VirtualPoint.RightTop]; var rb = linePoints[(int)VirtualPoint.RightBottom]; return new Vector3[] { rt, rb }; } public Vector3[] GetCenterLinePointPositions() { var ct = linePoints[(int)VirtualPoint.LeftCenter]; var cb = linePoints[(int)VirtualPoint.RightCenter]; return new Vector3[] { ct, cb }; } internal bool isConnected(Wall target) { if(target.leftCenterPoint == leftCenterPoint || target.rightCenterPoint == leftCenterPoint) { return true; } if (target.leftCenterPoint == rightCenterPoint || target.rightCenterPoint == rightCenterPoint) { return true; } return false; } } }