private void BuildStrip(Strip Strip) { uint Start = Strip.Start; bool ClockWise = false; TriOrder Order = Strip.Order; //Create a new strip Primitive p = new Primitive(PrimType.TriangleStrip); m_PrimitivesVector.Add(p); AddTriangle(m_Triangles[Start].m_Elem, Order, true); MarkTriAsTaken(Start); //Loop while we can further extend the strip var Node = m_Triangles[Start]; for (uint Size = 1; Size < Strip.Size; Size++) { var Link = LinkToNeighbour(Node, ClockWise, ref Order, true); Debug.Assert(Link != null); //Go to the next triangle Node = Link.Terminal; MarkTriAsTaken(Node.m_Elem.m_Index); ClockWise = !ClockWise; } }
private void Stripify() { while (!m_TriHeap.Empty) { //There is no triangle in the candidates list, refill it with the loneliest triangle uint HeapTop = m_TriHeap.Position(0); m_Candidates.Add(HeapTop); while (m_Candidates.Count != 0) { //Note: FindBestStrip empties the candidate list, while BuildStrip refills it Strip TriStrip = FindBestStrip(); if (TriStrip.Size >= m_MinStripSize) { BuildStrip(TriStrip); } } if (!m_TriHeap.Removed(HeapTop)) { m_TriHeap.Erase(HeapTop); } //Eliminate all the triangles that have now become useless while ((!m_TriHeap.Empty) && (m_TriHeap.Top == 0)) { m_TriHeap.Pop(); } } }
public void Challenge(Strip Strip, uint Degree, uint CacheHits) { if (Strip.Size < m_MinStripSize) return; if (!m_Cache) { //Cache is disabled, take the longest strip if (Strip.Size > m_Strip.Size) m_Strip = Strip; } else { //Cache simulator enabled if (CacheHits > m_CacheHits) { //Priority 1: Keep the strip with the best cache hit count m_Strip = Strip; m_Degree = Degree; m_CacheHits = CacheHits; } else if ((CacheHits == m_CacheHits) && (((m_Strip.Size != 0) && (Degree < m_Degree)) || (Strip.Size > m_Strip.Size))) { //Priority 2: Keep the strip with the loneliest start triangle //Priority 3: Keep the longest strip m_Strip = Strip; m_Degree = Degree; } } }
public void Challenge(Strip Strip, uint Degree, uint CacheHits) { if (Strip.Size < m_MinStripSize) { return; } if (!m_Cache) { //Cache is disabled, take the longest strip if (Strip.Size > m_Strip.Size) { m_Strip = Strip; } } else { //Cache simulator enabled if (CacheHits > m_CacheHits) { //Priority 1: Keep the strip with the best cache hit count m_Strip = Strip; m_Degree = Degree; m_CacheHits = CacheHits; } else if ((CacheHits == m_CacheHits) && (((m_Strip.Size != 0) && (Degree < m_Degree)) || (Strip.Size > m_Strip.Size))) { //Priority 2: Keep the strip with the loneliest start triangle //Priority 3: Keep the longest strip m_Strip = Strip; m_Degree = Degree; } } }
private Strip FindBestStrip() { //Allow to restore the cache (modified by ExtendTriToStrip) and implicitly reset the cache hit count CacheSimulator CacheBackup = m_Cache; Policy policy = new Policy(m_MinStripSize, Cache); while (m_Candidates.Count != 0) { uint Candidate = m_Candidates[m_Candidates.Count - 1]; m_Candidates.RemoveAt(m_Candidates.Count - 1); //Discard useless triangles from the candidate list if (m_Triangles[Candidate].Marked || m_TriHeap[Candidate] == 0) { continue; } //Try to extend the triangle in the 3 possible forward directions for (uint i = 0; i < 3; i++) { Strip Strip = ExtendToStrip(Candidate, (TriOrder)i); policy.Challenge(Strip, m_TriHeap[Strip.Start], m_Cache.HitCount); m_Cache = CacheBackup; } //Try to extend the triangle in the 6 possible backward directions if (m_BackwardSearch) { for (uint i = 0; i < 3; i++) { Strip Strip = BackExtendToStrip(Candidate, (TriOrder)i, false); if (Strip != null) { policy.Challenge(Strip, m_TriHeap[Strip.Start], m_Cache.HitCount); } m_Cache = CacheBackup; } for (uint i = 0; i < 3; i++) { Strip Strip = BackExtendToStrip(Candidate, (TriOrder)i, true); if (Strip != null) { policy.Challenge(Strip, m_TriHeap[Strip.Start], m_Cache.HitCount); } m_Cache = CacheBackup; } } } return(policy.BestStrip); }