internal int PackIndices(BspTreeBuilder tb, int[] via, int[] aia, int ti) { for (int i = 0; i < m_zeroList.Count; i++) { var bti3 = m_zeroList[i]; var ti3 = 3 * ti; tb.GetTriangleVertexIndices(bti3, out via[ti3], out via[ti3 + 1], out via[ti3 + 2]); m_zeroList[i] = ti; aia[ti++] = tb.m_triangleAttributeIndexArray[bti3 / 3]; } if (m_negativeTree != null) { var nti = m_negativeTree.PackIndices(tb, via, aia, ti); m_negativeCount = nti - ti; ti = nti; } if (m_positiveTree != null) { var nti = m_positiveTree.PackIndices(tb, via, aia, ti); m_positiveCount = nti - ti; ti = nti; } return(ti); }
internal static void AddTriangle( BspTreeBuilder builder, int tiMul3, ref Triangle3d tr, V3d triangleNormal, ref BspNode node) { if (node != null) { node.AddTriangle(builder, tiMul3, ref tr, triangleNormal); } else { node = new BspNode(tiMul3, tr.P0, triangleNormal); } }
internal static void AddTriangle( BspTreeBuilder builder, int tiMul3, ref BspNode node) { Triangle3d tr; builder.GetTriangleVertexPositions(tiMul3, out tr.P0, out tr.P1, out tr.P2); V3d e0 = tr.P1 - tr.P0; V3d e1 = tr.P2 - tr.P0; V3d n = V3d.Cross(e0, e1); double len2 = n.LengthSquared; if (len2 > 0.0) { AddTriangle(builder, tiMul3, ref tr, n * (1.0 / Math.Sqrt(len2)), ref node); } }
internal int PackIndices(BspTreeBuilder tb, int[] via, int ti3) { for (int i = 0; i < m_zeroList.Count; i++) { tb.GetTriangleVertexIndices(m_zeroList[i], out via[ti3], out via[ti3 + 1], out via[ti3 + 2]); m_zeroList[i] = ti3; ti3 += 3; } if (m_negativeTree != null) { var nti3 = m_negativeTree.PackIndices(tb, via, ti3); m_negativeCount = nti3 - ti3; ti3 = nti3; } if (m_positiveTree != null) { var nti3 = m_positiveTree.PackIndices(tb, via, ti3); m_positiveCount = nti3 - ti3; ti3 = nti3; } return(ti3); }
internal void AddTriangle( BspTreeBuilder builder, int tiMul3, ref Triangle3d tr, V3d normal) { var htr = (V3d.Dot(m_normal, tr.P0 - m_point), V3d.Dot(m_normal, tr.P1 - m_point), V3d.Dot(m_normal, tr.P2 - m_point)); var signs = new[] { htr.Item1, htr.Item2, htr.Item3 }.AggregateSigns(builder.m_absoluteEpsilon); if (signs == Signs.Zero) { m_zeroList.Add(tiMul3); } else if ((signs & Signs.Negative) == Signs.None) { AddTriangle(builder, tiMul3, ref tr, normal, ref m_positiveTree); } else if ((signs & Signs.Positive) == Signs.None) { AddTriangle(builder, tiMul3, ref tr, normal, ref m_negativeTree); } else { // the triangle straddles the separating plane var positivePoints = new List <BspSplitPoint>(4); var negativePoints = new List <BspSplitPoint>(4); V3d firstPoint = tr.P0; double firstHeight = htr.Item1; bool firstPositive = firstHeight > 0.0; if (firstPositive) { positivePoints.Add(new BspSplitPoint(firstPoint, 0, 0.0)); } else { negativePoints.Add(new BspSplitPoint(firstPoint, 0, 0.0)); } V3d startPoint = firstPoint; double startHeight = firstHeight; bool startPositive = firstPositive; int start = 0; int end = 1; while (end < 3) { V3d endPoint = tr[end]; double endHeight = htr.Get(end); bool endPositive = endHeight > 0.0; if (startPositive != endPositive) { V3d direction = endPoint - startPoint; double t = -startHeight / V3d.Dot(m_normal, direction); V3d newPoint = startPoint + t * direction; // note, that the same split point (reference!) is // added to both lists! var sp = new BspSplitPoint(newPoint, start, t); positivePoints.Add(sp); negativePoints.Add(sp); } if (endPositive) { positivePoints.Add(new BspSplitPoint(endPoint, end, 0.0)); } else { negativePoints.Add(new BspSplitPoint(endPoint, end, 0.0)); } start = end; startPoint = endPoint; startHeight = endHeight; startPositive = endPositive; end++; } if (startPositive != firstPositive) { V3d direction = firstPoint - startPoint; double t = -startHeight / V3d.Dot(m_normal, direction); V3d newPoint = startPoint + t * direction; var sp = new BspSplitPoint(newPoint, start, t); positivePoints.Add(sp); negativePoints.Add(sp); } // in order to ensure that all fragments of a triangle are // consecutively stored, we walk through the two point lists // twice. for this we need a store of the triangle indices int[] positiveIndices = new int[2]; int[] negativeIndices = new int[2]; // first pass: generate the cloned triangles (fragments) and // the resulting triangle indices if (positivePoints.Count > 2) { for (int i = 1; i < positivePoints.Count - 1; i++) { positiveIndices[i - 1] = builder.AddClonedTriangle(tiMul3, positivePoints[0], positivePoints[i], positivePoints[i + 1]); } } if (negativePoints.Count > 2) { for (int i = 1; i < negativePoints.Count - 1; i++) { negativeIndices[i - 1] = builder.AddClonedTriangle(tiMul3, negativePoints[0], negativePoints[i], negativePoints[i + 1]); } } // second pass: add the fragments (with the triangle // indices) to the BSP-tree if (positivePoints.Count > 2) { for (int i = 0; i < positivePoints.Count - 2; i++) { AddTriangle(builder, positiveIndices[i], ref m_positiveTree); } } if (negativePoints.Count > 2) { for (int i = 0; i < negativePoints.Count - 2; i++) { AddTriangle(builder, negativeIndices[i], ref m_negativeTree); } } } }