/// <summary>
        /// Note, that the parallel implementation of this method could be
        /// optimized, by providing separate node types for parallel and non
        /// parallel execution.
        /// </summary>
        internal void SortBackToFront(
            BspTree t, TargetArrays target,
            int ti, V3d eye, bool mainTask, Action <Action> runChild)
        {
            int    nti    = ti;
            double height = V3d.Dot(m_normal, eye - m_point);

            if (height >= 0.0)
            {
                ti += m_negativeCount;
                var ti3 = ti * 3;
                foreach (int oti in m_zeroList)
                {
                    t.GetTriangleVertexIndices(oti * 3,
                                               out target.Via[ti3],
                                               out target.Via[ti3 + 1],
                                               out target.Via[ti3 + 2]);
                    ti3           += 3;
                    target.Aia[ti] = (t.m_triangleAttributeIndexArray != null) ? t.m_triangleAttributeIndexArray[oti] : 0;
                    ti++;
                }
            }
            else
            {
                nti += m_positiveCount;
                var nti3 = nti * 3;
                foreach (int oti in m_zeroList)
                {
                    t.GetTriangleVertexIndices(oti * 3,
                                               out target.Via[nti3],
                                               out target.Via[nti3 + 1],
                                               out target.Via[nti3 + 2]);
                    nti3           += 3;
                    target.Aia[nti] = (t.m_triangleAttributeIndexArray != null) ? t.m_triangleAttributeIndexArray[oti] : 0;
                    nti++;
                }
            }
            if (m_negativeTree != null)
            {
                if (mainTask && m_negativeCount < c_taskChunkSize)
                {
                    target.Finished.AddCount(1);
                    runChild(() =>
                    {
                        m_negativeTree.SortBackToFront(
                            t, target, nti, eye, false, runChild);
                        target.Finished.Signal();
                    });
                }
                else
                {
                    m_negativeTree.SortBackToFront(
                        t, target, nti, eye, mainTask, runChild);
                }
            }
            if (m_positiveTree != null)
            {
                if (mainTask && m_positiveCount < c_taskChunkSize)
                {
                    target.Finished.AddCount(1);
                    runChild(() =>
                    {
                        m_positiveTree.SortBackToFront(
                            t, target, ti, eye, false, runChild);
                        target.Finished.Signal();
                    });
                }
                else
                {
                    m_positiveTree.SortBackToFront(
                        t, target, ti, eye, mainTask, runChild);
                }
            }
        }
        internal void SortFrontToBack(
            BspTree t, TargetArray via,
            int ti3, V3d eye, bool mainTask, Action <Action> runChild)
        {
            int    nti3   = ti3;
            double height = V3d.Dot(m_normal, eye - m_point);

            if (height < 0.0)
            {
                ti3 += m_negativeCount;
                foreach (int tiMul3 in m_zeroList)
                {
                    t.GetTriangleVertexIndices(tiMul3,
                                               out via.Via[ti3],
                                               out via.Via[ti3 + 1],
                                               out via.Via[ti3 + 2]);
                    ti3 += 3;
                }
            }
            else
            {
                nti3 += m_positiveCount;
                foreach (int tiMul3 in m_zeroList)
                {
                    t.GetTriangleVertexIndices(tiMul3,
                                               out via.Via[nti3],
                                               out via.Via[nti3 + 1],
                                               out via.Via[nti3 + 2]);
                    nti3 += 3;
                }
            }
            if (m_positiveTree != null)
            {
                if (mainTask && m_positiveCount < c_taskChunkSize)
                {
                    via.Finished.AddCount(1);
                    runChild(() =>
                    {
                        m_positiveTree.SortFrontToBack(
                            t, via, ti3, eye, false, runChild);
                        via.Finished.Signal();
                    });
                }
                else
                {
                    m_positiveTree.SortFrontToBack(
                        t, via, ti3, eye, mainTask, runChild);
                }
            }
            if (m_negativeTree != null)
            {
                if (mainTask && m_negativeCount < c_taskChunkSize)
                {
                    via.Finished.AddCount(1);
                    runChild(() =>
                    {
                        m_negativeTree.SortFrontToBack(
                            t, via, nti3, eye, false, runChild);
                        via.Finished.Signal();
                    });
                }
                else
                {
                    m_negativeTree.SortFrontToBack(
                        t, via, nti3, eye, mainTask, runChild);
                }
            }
        }