示例#1
0
        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);
            }
        }
示例#2
0
        private void LocalHost_EdgeHit(object sender, BoundEdge edge)
        {
            if (!LocalInput)
            {
                return;
            }

            OnAnyEdgeHit(ConnectedClient.LocalHost, edge);
        }
示例#3
0
        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");
        }
示例#4
0
        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;
                }
            }
        }
示例#5
0
 private void IpcRead_EdgeHit(object sender, BoundEdge edge)
 {
     EdgeHit(edge);
 }
示例#6
0
        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);
        }
示例#7
0
        /// <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);
        }
示例#8
0
        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;
            }
            }
        }
示例#9
0
        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);
        }
示例#10
0
 private void CurMonitor_EdgeHit(object sender, BoundEdge edge)
 {
     //Tell the service that the cursor has hit the specific edge
     ipcWrite.SendEdgeHit(edge);
 }