Ejemplo n.º 1
0
 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);
 }
Ejemplo n.º 2
0
 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);
     }
 }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
 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);
 }
Ejemplo n.º 5
0
        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);
                    }
                }
            }
        }