Beispiel #1
0
        // ReoptimizeLinkOrder minimizes the cases where links L and L+1 share a common node.
        public static void ReoptimizeLinkOrder(SoftBody psb)
        {
            AlignedLinkArray links = psb.Links;
            AlignedNodeArray nodes = psb.Nodes;
            int nLinks             = links.Count;
            int nNodes             = nodes.Count;

            List <Link>                readyList     = new List <Link>();
            Dictionary <Link, Link>    linkBuffer    = new Dictionary <Link, Link>();
            Dictionary <Link, LinkDep> linkDeps      = new Dictionary <Link, LinkDep>();
            Dictionary <Node, Link>    nodeWrittenAt = new Dictionary <Node, Link>();

            Dictionary <Link, Link> linkDepA = new Dictionary <Link, Link>();           // Link calculation input is dependent upon prior calculation #N
            Dictionary <Link, Link> linkDepB = new Dictionary <Link, Link>();

            foreach (Link link in links)
            {
                Node ar = link.Nodes[0];
                Node br = link.Nodes[1];
                linkBuffer.Add(link, new Link(btSoftBody_Link_new2(link.Native)));

                LinkDep linkDep;
                if (nodeWrittenAt.ContainsKey(ar))
                {
                    linkDepA[link] = nodeWrittenAt[ar];
                    linkDeps.TryGetValue(nodeWrittenAt[ar], out linkDep);
                    linkDeps[nodeWrittenAt[ar]] = new LinkDep()
                    {
                        Next = linkDep, Value = link
                    };
                }

                if (nodeWrittenAt.ContainsKey(br))
                {
                    linkDepB[link] = nodeWrittenAt[br];
                    linkDeps.TryGetValue(nodeWrittenAt[br], out linkDep);
                    linkDeps[nodeWrittenAt[br]] = new LinkDep()
                    {
                        Next = linkDep, Value = link, LinkB = true
                    };
                }

                if (!linkDepA.ContainsKey(link) && !linkDepB.ContainsKey(link))
                {
                    readyList.Add(link);
                }

                // Update the nodes to mark which ones are calculated by this link
                nodeWrittenAt[ar] = link;
                nodeWrittenAt[br] = link;
            }

            int i = 0;

            while (readyList.Count != 0)
            {
                Link link = readyList[0];
                links[i++] = linkBuffer[link];
                readyList.RemoveAt(0);

                LinkDep linkDep;
                linkDeps.TryGetValue(link, out linkDep);
                while (linkDep != null)
                {
                    link = linkDep.Value;

                    if (linkDep.LinkB)
                    {
                        linkDepB.Remove(link);
                    }
                    else
                    {
                        linkDepA.Remove(link);
                    }

                    // Add this dependent link calculation to the ready list if *both* inputs are clear
                    if (!linkDepA.ContainsKey(link) && !linkDepB.ContainsKey(link))
                    {
                        readyList.Add(link);
                    }
                    linkDep = linkDep.Next;
                }
            }

            foreach (Link link in linkBuffer.Values)
            {
                btSoftBody_Link_delete(link.Native);
            }
        }
        // ReoptimizeLinkOrder minimizes the cases where links L and L+1 share a common node.
		public static void ReoptimizeLinkOrder(SoftBody psb)
		{
            AlignedLinkArray links = psb.Links;
            AlignedNodeArray nodes = psb.Nodes;
            int nLinks = links.Count;
            int nNodes = nodes.Count;

            List<Link> readyList = new List<Link>();
            Dictionary<Link, Link> linkBuffer = new Dictionary<Link, Link>();
            Dictionary<Link, LinkDep> linkDeps = new Dictionary<Link, LinkDep>();
            Dictionary<Node, Link> nodeWrittenAt = new Dictionary<Node, Link>();

            Dictionary<Link, Link> linkDepA = new Dictionary<Link, Link>(); // Link calculation input is dependent upon prior calculation #N
            Dictionary<Link, Link> linkDepB = new Dictionary<Link, Link>();

            foreach (Link link in links)
            {
                Node ar = link.Nodes[0];
                Node br = link.Nodes[1];
                linkBuffer.Add(link, new Link(btSoftBody_Link_new2(link._native)));

                LinkDep linkDep;
                if (nodeWrittenAt.ContainsKey(ar))
                {
                    linkDepA[link] = nodeWrittenAt[ar];
                    linkDeps.TryGetValue(nodeWrittenAt[ar], out linkDep);
                    linkDeps[nodeWrittenAt[ar]] = new LinkDep() { Next = linkDep, Value = link};
                }

                if (nodeWrittenAt.ContainsKey(br))
                {
                    linkDepB[link] = nodeWrittenAt[br];
                    linkDeps.TryGetValue(nodeWrittenAt[br], out linkDep);
                    linkDeps[nodeWrittenAt[br]] = new LinkDep() { Next = linkDep, Value = link, LinkB = true };
                }

                if (!linkDepA.ContainsKey(link) && !linkDepB.ContainsKey(link))
                {
                    readyList.Add(link);
                }

                // Update the nodes to mark which ones are calculated by this link
                nodeWrittenAt[ar] = link;
                nodeWrittenAt[br] = link;
            }

            int i = 0;
            while (readyList.Count != 0)
            {
                Link link = readyList[0];
                links[i++] = linkBuffer[link];
                readyList.RemoveAt(0);

                LinkDep linkDep;
                linkDeps.TryGetValue(link, out linkDep);
                while (linkDep != null)
                {
                    link = linkDep.Value;

                    if (linkDep.LinkB)
                    {
                        linkDepB.Remove(link);
                    }
                    else
                    {
                        linkDepA.Remove(link);
                    }

                    // Add this dependent link calculation to the ready list if *both* inputs are clear
                    if (!linkDepA.ContainsKey(link) && !linkDepB.ContainsKey(link))
                    {
                        readyList.Add(link);
                    }
                    linkDep = linkDep.Next;
                }
            }

            foreach (Link link in linkBuffer.Values)
            {
                btSoftBody_Element_delete(link._native);
            }
		}