public void SendEdgeHit(BoundEdge edge) { try { byte[] data = new byte[5]; Buffer.BlockCopy(BitConverter.GetBytes(5), 0, data, 0, 4); switch (edge) { case BoundEdge.Bottom: data[4] = (byte)IPCMessageType.EdgeHitBottom; break; case BoundEdge.Left: data[4] = (byte)IPCMessageType.EdgeHitLeft; break; case BoundEdge.Right: data[4] = (byte)IPCMessageType.EdgeHitRight; break; case BoundEdge.Top: data[4] = (byte)IPCMessageType.EdgeHitTop; break; } pWrite.Write(data, 0, data.Length); pWrite.Flush(); }catch (Exception ex) { ISLogger.Write("IPC->Failed to send edge hit message: " + ex.Message); } }
private void LocalHost_EdgeHit(object sender, BoundEdge edge) { if (!LocalInput) { return; } OnAnyEdgeHit(ConnectedClient.LocalHost, edge); }
public KDTree(List<Sphere> spheres, int maxPrimsPerNode) { // Store reference _primitives = spheres; _nodes = new KdTreeNode[0]; _maxPrims = maxPrimsPerNode; // Guess a usefull bound on the maximum tree depth _maxDepth = 8 + (int)(1.3*Math.Log(spheres.Count, 2)); // calculate primitive bounds, plus overall scene bounds BBox[] allPrimBounds = new BBox[_primitives.Count]; for (int i=0; i<_primitives.Count; i++) { allPrimBounds[i] = _primitives[i].getBounds(); _bounds.union( allPrimBounds[i] ); } // Allocate temporary working space BoundEdge[][] edges = new BoundEdge[3][]; for (int i = 0; i < 3; i++) { edges[i] = new BoundEdge[2 * _primitives.Count]; } // Allocate array to store overlaping primitive indices int[] primNums = new int[_primitives.Count]; int primNumsBase = 0; for(int i=0; i<_primitives.Count; i++) { primNums[i]=i; } // Arries to hold subarries of primitive indices int[] prims0 = new int[_primitives.Count]; int prims1Base = 0; int[] prims1 = new int[ (_maxDepth+1) * _primitives.Count]; Console.WriteLine("Building Tree with " + _primitives.Count + " primitives...\n"); // Start recursive construction tree buildTree(0, _bounds, allPrimBounds, primNums, primNumsBase, _primitives.Count, _maxDepth, edges, prims0, prims1, prims1Base, 0); Console.WriteLine("Finished building tree with " + nextFreeNode + " nodes"); }
private void EdgeHit(BoundEdge edge) { if (cSocket.IsStateConnected()) { switch (edge) { case BoundEdge.Bottom: cSocket?.SendCommand(MessageType.ClientBoundsBottom); break; case BoundEdge.Left: cSocket?.SendCommand(MessageType.ClientBoundsLeft); break; case BoundEdge.Right: cSocket?.SendCommand(MessageType.ClientBoundsRight); break; case BoundEdge.Top: cSocket?.SendCommand(MessageType.ClientBoundsTop); break; } } }
private void IpcRead_EdgeHit(object sender, BoundEdge edge) { EdgeHit(edge); }
private void buildTree( int nodeNum, BBox nodeBounds, BBox[] allPrimBounds, int[] primNums, int primNumsBase, int nPrimitives, int depth, BoundEdge[][] edges, int[] prims0, int[] prims1, int prims1base, int badRefines) { string indent = "".PadLeft(_maxDepth - depth); if (nextFreeNode == nAllocedNodes) { int nAlloc = Math.Max(2*nAllocedNodes, 512); KdTreeNode[] n = new KdTreeNode[nAlloc]; if (nAllocedNodes > 0) Array.Copy(_nodes, n, nAllocedNodes); _nodes = n; nAllocedNodes = nAlloc; } ++nextFreeNode; // *** Termination: Stop recursion if we have few enough nodes or the max depth has been reached *** if (nPrimitives <= _maxPrims || depth == 0) { _nodes[nodeNum] = KdTreeNode.makeLeaf(primNums, primNumsBase, nPrimitives); #if DEBUG Console.WriteLine(indent + _nodes[nodeNum]); #endif return; } // *** Not reached termination, so pick split plane and continue recursion *** Axis bestAxis = Axis.none; int bestOffset = -1; float bestCost = float.PositiveInfinity; float oldCost = iCost * (float)nPrimitives; float totalSA = nodeBounds.surfaceArea(); float invTotalSA = 1.0f/totalSA; Vector3 d = nodeBounds.pMax - nodeBounds.pMin; Axis axis = nodeBounds.longestAxis(); // Start by checking the longest axis int retries = 0; retrySplit: // Fill edge lists for (int i=0; i<nPrimitives; i++) { int primIndex = primNums[primNumsBase + i]; BBox bbox = allPrimBounds[primIndex]; edges[(int)axis][2*i] = new BoundEdge( getAxisVal(bbox.pMin, axis), primIndex, true); edges[(int)axis][2*i+1] = new BoundEdge(getAxisVal(bbox.pMax, axis), primIndex, false); } Array.Sort(edges[(int)axis], 0, 2*nPrimitives); // sort the edges of the first n primitives (2*n edges) // Find the best split by checking cost of every possible split plane int nBelow = 0, nAbove = nPrimitives; for (int i=0; i<2*nPrimitives; i++) { if( edges[(int)axis][i].type == BoundType.End) --nAbove; float edgeT = edges[(int)axis][i].t; if (edgeT > getAxisVal(nodeBounds.pMin, axis) && edgeT < getAxisVal(nodeBounds.pMax, axis) ) { // Compute split cost for the ith edge Axis otherAxis0 = (Axis) ( ((int)axis+1) % 3); Axis otherAxis1 = (Axis) ( ((int)axis+2) % 3); float belowSA = 2* (getAxisVal(d, otherAxis0) * getAxisVal(d, otherAxis1) + (edgeT - getAxisVal(nodeBounds.pMin, axis)) * (getAxisVal(d, otherAxis0) + getAxisVal(d, otherAxis1))); float aboveSA = 2*(getAxisVal(d, otherAxis0) * getAxisVal(d, otherAxis1) + (getAxisVal(nodeBounds.pMax, axis) - edgeT) * (getAxisVal(d, otherAxis0) + getAxisVal(d, otherAxis1))); float pBelow = belowSA * invTotalSA; float pAbove = aboveSA * invTotalSA; float eb = (nAbove == 0 || nBelow == 0) ? emptyBonus : 0; float cost = tCost + iCost * (1-eb) * (pBelow * nBelow + pAbove * nAbove); // Save this split if it is better the previous split position if(cost < bestCost) { bestCost = cost; bestAxis = axis; bestOffset = i; } } if (edges[(int)axis][i].type == BoundType.Start) ++nBelow; } // Create a leaf node if no good split was found if(bestAxis == Axis.none && retries < 2) { ++retries; axis = (Axis) ( ((int)axis+1) % 3); goto retrySplit; } if (bestCost > oldCost) ++badRefines; if (( bestCost > 4.0f * oldCost && nPrimitives < 16) || bestAxis == Axis.none || badRefines == 3) { _nodes[nodeNum] = KdTreeNode.makeLeaf(primNums, primNumsBase, nPrimitives); #if DEBUG Console.WriteLine(indent + _nodes[nodeNum] + " (split failure)"); #endif return; } // Classifiy primitives with respect to split int n0=0, n1=0; for (int i=0; i<bestOffset; i++) { if(edges[(int)bestAxis][i].type == BoundType.Start) prims0[n0++] = edges[(int)bestAxis][i].primNum; } for (int i=bestOffset+1; i<2*nPrimitives; i++) { if(edges[(int)bestAxis][i].type == BoundType.End) prims1[prims1base + n1++] = edges[(int)bestAxis][i].primNum; } // Ititalize child nodes float tsplit = edges[(int)bestAxis][bestOffset].t; BBox bounds0 = nodeBounds, bounds1 = nodeBounds; setAxisVal(ref bounds0.pMax, bestAxis, tsplit); setAxisVal(ref bounds1.pMin, bestAxis, tsplit); #if DEBUG KdTreeNode testNode = KdTreeNode.makeInternal(bestAxis, nextFreeNode, tsplit); int[] aboveIndices = new int[n1]; int[] belowIndices = new int[n0]; Array.Copy(prims0, belowIndices, n0); Array.Copy(prims1, prims1base, aboveIndices, 0, n1); Console.WriteLine(indent + testNode); Console.WriteLine(indent + " Above: { " + String.Join(",", aboveIndices) + " }"); Console.WriteLine(indent + " Below: { " + String.Join(",", belowIndices) + " }"); #endif buildTree(nodeNum+1, bounds0, allPrimBounds, prims0, 0, n0, depth-1, edges, prims0, prims1, prims1base+nPrimitives-1, badRefines); int aboveChild = nextFreeNode; _nodes[nodeNum] = KdTreeNode.makeInternal(bestAxis, aboveChild, tsplit); buildTree(aboveChild, bounds1, allPrimBounds, prims1, prims1base, n1, depth-1, edges, prims0, prims1, prims1base+nPrimitives-1, badRefines); }
/// <summary> /// Builds the Kd-Tree /// </summary> /// <param name="nodeNum"> /// The current node index /// </param> /// <param name="nodeBounds"> /// The node's bounding box /// </param> /// <param name="allPrimBounds"> /// The primitive's bounding boxes /// </param> /// <param name="primNums"> /// Array of primitive indices /// </param> /// <param name="numberOfPrimitives"> /// Number of primitives to build from /// </param> /// <param name="depth"> /// The current recursion depth /// </param> /// <param name="edges"> /// Array of edges /// </param> /// <param name="prims0"> /// /// </param> /// <param name="prims1"> /// /// </param> /// <param name="badRefines"> /// Amount of bad refines /// </param> public void BuildTree(int nodeNum, BoundingBox nodeBounds, List<BoundingBox> allPrimBounds, int[] primNums, int numberOfPrimitives, int depth, List<BoundEdge>[] edges, int[] prims0, int[] prims1, int primIndex, int badRefines) { if (_nextFreeNode == _numberOfAllocatedNodes) { int nAlloc = Math.Max (2 * _numberOfAllocatedNodes, 512); KdAcceleratorNode[] n = new KdAcceleratorNode[nAlloc]; if (_numberOfAllocatedNodes > 0) { _nodes.CopyTo (n, 0); } _nodes = n; _numberOfAllocatedNodes = nAlloc; } ++_nextFreeNode; // Initialize leaf nodes if termination criteria is met if (numberOfPrimitives <= _maxPrimitives || depth == 0) { _nodes[nodeNum].InitLeaf (primNums, numberOfPrimitives); return; } // Initialize interior node and continue recursion. // Choose split axis position for interior node int bestAxis = -1, bestOffset = -1; double bestCost = double.PositiveInfinity; double oldCost = _isectCost * numberOfPrimitives; double totalSA = nodeBounds.SurfaceArea; double invTotalSA = 1.0 / totalSA; Vector d = nodeBounds.pMax - nodeBounds.pMin; int axis = nodeBounds.MaximumExtent; int retries = 0; while (true) { // Initialize edges for axis for (int i = 0; i < numberOfPrimitives; ++i) { int pn = (int)primNums[i]; BoundingBox box = allPrimBounds[pn]; edges[axis][2 * i] = new BoundEdge (box.pMin[axis], pn, true); edges[axis][2 * i + 1] = new BoundEdge (box.pMax[axis], pn, false); } edges[axis].Sort (0, 2 * numberOfPrimitives, comparer); // Compute cost of all splits for axis to find best int nBelow = 0, nAbove = numberOfPrimitives; for (int i = 0; i < 2 * numberOfPrimitives; ++i) { if (edges[axis][i].Type == BoundEdge.EdgeType.End) --nAbove; double edget = edges[axis][i].t; if (edget > nodeBounds.pMin[axis] && edget < nodeBounds.pMax[axis]) { int otherAxis0 = (axis + 1) % 3, otherAxis1 = (axis + 2) % 3; double belowSA = 2 * (d[otherAxis0] * d[otherAxis1] + (edget - nodeBounds.pMin[axis]) * (d[otherAxis0] + d[otherAxis1])); double aboveSA = 2 * (d[otherAxis0] * d[otherAxis1] + (nodeBounds.pMax[axis] - edget) * (d[otherAxis0] + d[otherAxis1])); double pBelow = belowSA * invTotalSA; double pAbove = aboveSA * invTotalSA; double eb = (nAbove == 0 || nBelow == 0) ? _emptyBonus : 0.0; double cost = _traversalCost + _isectCost * (1.0 - eb) * (pBelow * nBelow + pAbove * nAbove); // Update best split if this is the lowest so far if (cost < bestCost) { bestCost = cost; bestAxis = axis; bestOffset = i; } } if (edges[axis][i].Type == BoundEdge.EdgeType.Start) ++nBelow; } // Create leaf if no good splits were found if (bestAxis == -1 && retries < 2) { ++retries; axis = (axis + 1) % 3; continue; } break; } if (bestCost > oldCost) ++badRefines; if ((bestCost > 4.0 * oldCost && numberOfPrimitives < 16) || bestAxis == -1 || badRefines == 3) { _nodes[nodeNum].InitLeaf (primNums, numberOfPrimitives); return; } // Classify primitives with respect to split int n0 = 0, n1 = 0; for (int i = 0; i < bestOffset; ++i) if (edges[bestAxis][i].Type == BoundEdge.EdgeType.Start) prims0[n0++] = edges[bestAxis][i].PrimitiveNumber; for (int i = bestOffset + 1; i < 2 * numberOfPrimitives; ++i) if (edges[bestAxis][i].Type == BoundEdge.EdgeType.End) prims1[primIndex + n1++] = edges[bestAxis][i].PrimitiveNumber; // Recursively initialize child nodes double tsplit = edges[bestAxis][bestOffset].t; BoundingBox bounds0 = new BoundingBox (nodeBounds), bounds1 = new BoundingBox(nodeBounds); bounds0.pMax[bestAxis] = bounds1.pMin[bestAxis] = tsplit; BuildTree (nodeNum + 1, bounds0, allPrimBounds, prims0, n0, depth - 1, edges, prims0, prims1, numberOfPrimitives + primIndex, badRefines); int aboveChild = _nextFreeNode; _nodes[nodeNum].InitInterior (bestAxis, aboveChild, tsplit); BuildTree (aboveChild, bounds1, allPrimBounds, prims1, n1, depth - 1, edges, prims0, prims1, numberOfPrimitives + primIndex, badRefines); }
private void OnAnyEdgeHit(object sender, BoundEdge edge) { if (!EnableMouseSwitchClients) { return; } ConnectedClient c = sender as ConnectedClient; if (c != currentInputClient && c != ConnectedClient.LocalHost) { //Make sure the client that reports this is actually the focused client return; } //Check that no application is in fullscreen mode if (procMonitor.FullscreenApplicationRunning && DisableMouseSwitchWhileFullscreen && c == ConnectedClient.LocalHost) { return; } switch (edge) { case BoundEdge.Bottom: { if (c.BelowClient != null) { if (!c.BelowClient.Connected) { c.BelowClient = null; break; } //Console.WriteLine("Switching to {0} (under {1})", c.BelowClient.ClientName, c.ClientName); SwitchInputToClient(c.BelowClient.ClientGuid); } break; } case BoundEdge.Top: { if (c.AboveClient != null) { if (!c.AboveClient.Connected) { c.AboveClient = null; break; } //Console.WriteLine("Switching to {0} (above {1})", c.AboveClient.ClientName, c.ClientName); SwitchInputToClient(c.AboveClient.ClientGuid);; } break; } case BoundEdge.Left: { if (c.LeftClient != null) { if (!c.LeftClient.Connected) { c.LeftClient = null; break; } //Console.WriteLine("Switching to {0} (left of {1})", c.LeftClient.ClientName, c.ClientName); SwitchInputToClient(c.LeftClient.ClientGuid); } break; } case BoundEdge.Right: { if (c.RightClient != null) { if (!c.RightClient.Connected) { c.RightClient = null; break; } //Console.WriteLine("Switching to {0} (right of {1})", c.RightClient.ClientName, c.ClientName); SwitchInputToClient(c.RightClient.ClientGuid); } break; } } }
public void SetClientEdge(ConnectedClientInfo clientA, BoundEdge sideof, ConnectedClientInfo clientB) { ConnectedClient a = null; if (clientA != null) { a = clientMan.GetClientFromGuid(clientA.ClientId); } ConnectedClient b = clientMan.GetClientFromGuid(clientB.ClientId); if (a == null) { switch (sideof) { case BoundEdge.Left: if (b.LeftClient != null) { b.LeftClient.RightClient = null; } break; case BoundEdge.Right: if (b.RightClient != null) { b.RightClient.LeftClient = null; } break; case BoundEdge.Bottom: if (b.BelowClient != null) { b.BelowClient.AboveClient = null; } break; case BoundEdge.Top: if (b.AboveClient != null) { b.AboveClient.BelowClient = null; } break; } } switch (sideof) { case BoundEdge.Bottom: b.BelowClient = a; if (a != null) { a.AboveClient = b; } break; case BoundEdge.Right: b.RightClient = a; if (a != null) { a.LeftClient = b; } break; case BoundEdge.Left: b.LeftClient = a; if (a != null) { a.RightClient = b; } break; case BoundEdge.Top: b.AboveClient = a; if (a != null) { a.BelowClient = b; } break; } if (a == null) { ISLogger.Write("Set None {0}of {1}", sideof, b.ClientName); } else { ISLogger.Write("Set {0} {1}of {2}", a.ClientName, sideof, b.ClientName); } DisplayConfigChanged(this, null); }
private void CurMonitor_EdgeHit(object sender, BoundEdge edge) { //Tell the service that the cursor has hit the specific edge ipcWrite.SendEdgeHit(edge); }