private void AssignEdges(ConvexHull a, ConvexHull b, bool[] pointAbovePlane, Vector3 pointOnPlane, Vector3 normalPlane, out bool[] edgeIntersectsPlane, out EdgeHit[] edgeHits) { edgeIntersectsPlane = new bool[edges.Count]; edgeHits = new EdgeHit[edges.Count]; foreach (Edge edge in edges) { bool abovePlane0 = pointAbovePlane[edge.point0.index]; bool abovePlane1 = pointAbovePlane[edge.point1.index]; if (abovePlane0 && abovePlane1) { a.edges.Add(edge); } else if (!abovePlane0 && !abovePlane1) { b.edges.Add(edge); } else { //Split edge float denominator = Vector3.Dot(edge.line, normalPlane); float scalar = Mathf.Clamp01(Vector3.Dot(pointOnPlane - edge.point0.position, normalPlane) / denominator); Vector3 intersection = edge.point0.position + edge.line * scalar; //Create new points Point pointA = new Point(intersection); Point pointB = new Point(intersection); a.points.Add(pointA); b.points.Add(pointB); //Create new edges Edge splitA, splitB; if (pointAbovePlane[edge.point0.index]) { splitA = new Edge(pointA, edge.point0); splitB = new Edge(pointB, edge.point1); } else { splitA = new Edge(pointA, edge.point1); splitB = new Edge(pointB, edge.point0); } a.edges.Add(splitA); b.edges.Add(splitB); //Set flags edgeIntersectsPlane[edge.index] = true; edgeHits[edge.index] = new EdgeHit(); edgeHits[edge.index].scalar = scalar; edgeHits[edge.index].splitA = splitA; edgeHits[edge.index].splitB = splitB; } } }
protected override void ProcessMessage(IpcMessageType type, byte[] data) { if (type == IpcMessageType.AnonIpcClipboardData) { ClipboardDataReceived?.Invoke(this, new AnonIpcClipboardDataMessage(data).Data); } else if (type == IpcMessageType.AnonIpcEdgeHit) { EdgeHit?.Invoke(this, new AnonIpcEdgeHitMessage(data).HitEdge); } else if (type == IpcMessageType.AnonIpcDisplayConfigReply) { DisplayConfigUpdated?.Invoke(this, new AnonIpcDisplayConfigMessage(data).Config); } else if (type == IpcMessageType.AnonIpcLMouseStateReply) { LeftMouseStateUpdated?.Invoke(this, new AnonIpcLMouseStateMessage(data).LeftMouseState); } else if (type == IpcMessageType.AnonIpcDoDragDrop) { DataDropped?.Invoke(this, new AnonIpcDoDragDropMessage(data).DropData); } else if (type == IpcMessageType.AnonIpcDragDropCancelled) { DragDropCancelled?.Invoke(this, null); } else if (type == IpcMessageType.AnonIpcDragDropSuccess) { DragDropSuccess?.Invoke(this, null); } else if (type == IpcMessageType.AnonIpcDragDropComplete) { DragDropComplete?.Invoke(this, null); } else if (type == IpcMessageType.AnonIpcStreamReadRequest) { HandleReadStreamRequest(new AnonIpcReadStreamRequestMessage(data)); } else if (type == IpcMessageType.AnonIpcRequestFileToken) { HandleTokenRequest(new AnonIpcRequestFileTokenMessage(data)); } }
private void TimerCallback(object sync) { GetCursorPos(out POINT pos); if (pos.Y == screenBounds.Top) { EdgeHit?.Invoke(this, BoundEdge.Top); } else if (pos.Y == screenBounds.Bottom) { EdgeHit?.Invoke(this, BoundEdge.Bottom); } else if (pos.X == screenBounds.Left) { EdgeHit?.Invoke(this, BoundEdge.Left); } else if (pos.X == screenBounds.Right) { EdgeHit?.Invoke(this, BoundEdge.Right); } }
public static EdgeHit FindClosestEdge(NativeArray <Edge> edges, Vector3 position) { var closestDist = float.MaxValue; var closestPoint = Vector3.zero; var closestEdge = Edge.Empty; foreach (var edge in edges) { var nearest = Math3d.ProjectPointOnLineSegment(edge.Start, edge.End, position); //var edgeDist = math.distance(nearest, position); // NavMesh GetTriangulation() (which this edge data is extracted from) sometimes doesn't follow the NavMesh properly // An example here: https://forum.unity.com/threads/navmesh-calculatetriangulation-produces-inaccurate-meshes.293894/ // So testing distance with XY will sync the difference on horizontal plane, then we'll need to and the test // for vertical difference or underpass/overpass areas of the nav-mesh will give false-positives. var edgeDist = FastDistanceXZ(nearest, position); if (edgeDist < closestDist) { if (Math.Abs(nearest.y - position.y) <= 0.5f) { closestPoint = nearest; closestDist = edgeDist; closestEdge = edge; } } } var result = new EdgeHit { Distance = closestDist, Position = closestPoint, Edge = closestEdge }; return(result); }
private void TimerCallback(object sync) { Thread.CurrentThread.Name = "CursorMonitorThread"; if (SwitchToInputDesktop) { SwitchToInputDesktop = false; WinDesktop.SwitchThreadToInputDesktop(); } if (!GetCursorPos(out POINT pos)) { if (!WinDesktop.GetThreadDesktop().InputDesktop) { WinDesktop.SwitchThreadToInputDesktop(); } return; } if (pos.Y == screenBounds.Top) { EdgeHit?.Invoke(this, BoundEdge.Top); } else if (pos.Y == screenBounds.Bottom) { EdgeHit?.Invoke(this, BoundEdge.Bottom); } else if (pos.X == screenBounds.Left) { EdgeHit?.Invoke(this, BoundEdge.Left); } else if (pos.X == screenBounds.Right) { EdgeHit?.Invoke(this, BoundEdge.Right); } }
private void AssignTriangles(Hull a, Hull b, bool[] pointAbovePlane, bool[] edgeIntersectsPlane, EdgeHit[] edgeHits, int[] oldToNewVertex, out IList <Edge> cutEdgesA, out IList <Edge> cutEdgesB) { cutEdgesA = new List <Edge>(); cutEdgesB = new List <Edge>(); foreach (Triangle triangle in triangles) { bool abovePlane0 = pointAbovePlane[triangle.point0.index]; bool abovePlane1 = pointAbovePlane[triangle.point1.index]; bool abovePlane2 = pointAbovePlane[triangle.point2.index]; if (abovePlane0 && abovePlane1 && abovePlane2) { // Assign this triangle to hull A triangle.vertex0 = oldToNewVertex[triangle.vertex0]; triangle.vertex1 = oldToNewVertex[triangle.vertex1]; triangle.vertex2 = oldToNewVertex[triangle.vertex2]; a.triangles.Add(triangle); } else if (!abovePlane0 && !abovePlane1 && !abovePlane2) { // Assign this triangle to hull B triangle.vertex0 = oldToNewVertex[triangle.vertex0]; triangle.vertex1 = oldToNewVertex[triangle.vertex1]; triangle.vertex2 = oldToNewVertex[triangle.vertex2]; b.triangles.Add(triangle); } else { // Split triangle Point topPoint; Edge edge0, edge1, edge2; int vertex0, vertex1, vertex2; if (edgeIntersectsPlane[triangle.edge0.index] && edgeIntersectsPlane[triangle.edge1.index]) { topPoint = triangle.point1; edge0 = triangle.edge0; edge1 = triangle.edge1; edge2 = triangle.edge2; vertex0 = triangle.vertex0; vertex1 = triangle.vertex1; vertex2 = triangle.vertex2; } else if (edgeIntersectsPlane[triangle.edge1.index] && edgeIntersectsPlane[triangle.edge2.index]) { topPoint = triangle.point2; edge0 = triangle.edge1; edge1 = triangle.edge2; edge2 = triangle.edge0; vertex0 = triangle.vertex1; vertex1 = triangle.vertex2; vertex2 = triangle.vertex0; } else { topPoint = triangle.point0; edge0 = triangle.edge2; edge1 = triangle.edge0; edge2 = triangle.edge1; vertex0 = triangle.vertex2; vertex1 = triangle.vertex0; vertex2 = triangle.vertex1; } EdgeHit edgeHit0 = edgeHits[edge0.index]; EdgeHit edgeHit1 = edgeHits[edge1.index]; // Convert edge hit scalars to the triangle winding order float scalar0 = topPoint == edge0.point1 ? edgeHit0.scalar : 1.0f - edgeHit0.scalar; float scalar1 = topPoint == edge1.point0 ? edgeHit1.scalar : 1.0f - edgeHit1.scalar; Edge cutEdgeA, cutEdgeB; if (pointAbovePlane[topPoint.index]) { // Assign top triangle to hull A, bottom triangle to hull B cutEdgeA = new Edge(edgeHit1.splitA.point0, edgeHit0.splitA.point0); cutEdgeB = new Edge(edgeHit1.splitB.point0, edgeHit0.splitB.point0); a.edges.Add(cutEdgeA); b.edges.Add(cutEdgeB); SplitTriangle(a, b, edgeHit0.splitA, edgeHit1.splitA, cutEdgeA, edgeHit0.splitB, edgeHit1.splitB, cutEdgeB, edge2, vertex0, vertex1, vertex2, scalar0, scalar1, oldToNewVertex); } else { // Assign top triangle to hull B, bottom triangle to hull A cutEdgeA = new Edge(edgeHit0.splitA.point0, edgeHit1.splitA.point0); cutEdgeB = new Edge(edgeHit0.splitB.point0, edgeHit1.splitB.point0); a.edges.Add(cutEdgeA); b.edges.Add(cutEdgeB); SplitTriangle(b, a, edgeHit0.splitB, edgeHit1.splitB, cutEdgeB, edgeHit0.splitA, edgeHit1.splitA, cutEdgeA, edge2, vertex0, vertex1, vertex2, scalar0, scalar1, oldToNewVertex); } cutEdgesA.Add(cutEdgeA); cutEdgesB.Add(cutEdgeB); } } }
private List <Edge>[] AssignTriangles(ConvexHull a, ConvexHull b, bool[] pointAbovePlane, bool[] edgeIntersectsPlane, EdgeHit[] edgeHits, int[] oldToNewVertex) { List <Edge> cutEdgesA = new List <Edge>(); List <Edge> cutEdgesB = new List <Edge>(); List <Edge>[] result = new List <Edge> [2]; foreach (Triangle triangle in triangles) { bool abovePlane0 = pointAbovePlane[triangle.point0.index]; bool abovePlane1 = pointAbovePlane[triangle.point1.index]; bool abovePlane2 = pointAbovePlane[triangle.point2.index]; if (abovePlane0 && abovePlane1 && abovePlane2) { triangle.vertex0 = oldToNewVertex[triangle.vertex0]; triangle.vertex1 = oldToNewVertex[triangle.vertex1]; triangle.vertex2 = oldToNewVertex[triangle.vertex2]; a.triangles.Add(triangle); } else if (!abovePlane0 && !abovePlane1 && !abovePlane2) { triangle.vertex0 = oldToNewVertex[triangle.vertex0]; triangle.vertex1 = oldToNewVertex[triangle.vertex1]; triangle.vertex2 = oldToNewVertex[triangle.vertex2]; b.triangles.Add(triangle); } else { //Split triangle Point topPoint; Edge edge0, edge1, edge2; int vertex0, vertex1, vertex2; if (edgeIntersectsPlane[triangle.edge0.index] && edgeIntersectsPlane[triangle.edge1.index]) { topPoint = triangle.point1; edge0 = triangle.edge0; edge1 = triangle.edge1; edge2 = triangle.edge2; vertex0 = triangle.vertex0; vertex1 = triangle.vertex1; vertex2 = triangle.vertex2; } else if (edgeIntersectsPlane[triangle.edge1.index] && edgeIntersectsPlane[triangle.edge2.index]) { topPoint = triangle.point2; edge0 = triangle.edge1; edge1 = triangle.edge2; edge2 = triangle.edge0; vertex0 = triangle.vertex1; vertex1 = triangle.vertex2; vertex2 = triangle.vertex0; } else { topPoint = triangle.point0; edge0 = triangle.edge2; edge1 = triangle.edge0; edge2 = triangle.edge1; vertex0 = triangle.vertex2; vertex1 = triangle.vertex0; vertex2 = triangle.vertex1; } EdgeHit edgeHit0 = edgeHits[edge0.index]; EdgeHit edgeHit1 = edgeHits[edge1.index]; //Convert edge hit scalars float scalar0 = topPoint == edge0.point1 ? edgeHit0.scalar : 1.0f - edgeHit0.scalar; float scalar1 = topPoint == edge1.point0 ? edgeHit1.scalar : 1.0f - edgeHit1.scalar; Edge cutEdgeA, cutEdgeB; if (pointAbovePlane[topPoint.index]) { //Assign top triangle to A, bottom triangle to B cutEdgeA = new Edge(edgeHit1.splitA.point0, edgeHit0.splitA.point0); cutEdgeB = new Edge(edgeHit1.splitB.point0, edgeHit0.splitB.point0); a.edges.Add(cutEdgeA); b.edges.Add(cutEdgeB); SplitTriangle(a, b, edgeHit0.splitA, edgeHit1.splitA, cutEdgeA, edgeHit0.splitB, edgeHit1.splitB, cutEdgeB, edge2, vertex0, vertex1, vertex2, scalar0, scalar1, oldToNewVertex); } else { //Assign top triangle to B, bottom triangle to A cutEdgeA = new Edge(edgeHit0.splitA.point0, edgeHit1.splitA.point0); cutEdgeB = new Edge(edgeHit0.splitB.point0, edgeHit1.splitB.point0); a.edges.Add(cutEdgeA); b.edges.Add(cutEdgeB); SplitTriangle(b, a, edgeHit0.splitB, edgeHit1.splitB, cutEdgeB, edgeHit0.splitA, edgeHit1.splitA, cutEdgeA, edge2, vertex0, vertex1, vertex2, scalar0, scalar1, oldToNewVertex); } cutEdgesA.Add(cutEdgeA); cutEdgesB.Add(cutEdgeB); } } result[0] = cutEdgesA; result[1] = cutEdgesB; return(result); }
protected virtual void HandleEdgeHit(Edge edge) { EdgeHit?.Invoke(this, edge); }
protected void OnEdgeHit(Edge edge) { EdgeHit?.Invoke(this, edge); }