Esempio n. 1
0
 /// <summary>
 /// Generates a uniform distributed random sample on the given triangle using
 /// two random variables x1 and x2.
 /// </summary>
 public static V3d Triangle(Triangle3d t, double x1, double x2)
 {
     return(Triangle(t.P0, t.P1, t.P2, x1, x2));
 }
Esempio n. 2
0
 public DistLine3Triangle3(Line3d LineIn, Triangle3d TriangleIn)
 {
     this.triangle = TriangleIn; this.line = LineIn;
 }
Esempio n. 3
0
 /// <summary>
 /// Generates a uniform distributed random sample on the given triangle using
 /// two random series (seriesIndex,  seriesIndex + 1).
 /// </summary>
 public static V3d Triangle(Triangle3d t, IRandomSeries rnd, int seriesIndex)
 {
     return(Triangle(t.P0, t.P1, t.P2,
                     rnd.UniformDouble(seriesIndex),
                     rnd.UniformDouble(seriesIndex + 1)));
 }
Esempio n. 4
0
 public DistPoint3Triangle3(Vector3D PointIn, Triangle3d TriangleIn)
 {
     point = PointIn; triangle = TriangleIn;
 }
Esempio n. 5
0
    public static Plane3d FromTriangle(Triangle3d t)
    {
        Plane3d result = new Plane3d(Vector3L.Cross(t.m_point1 - t.m_point0, t.m_point2 - t.m_point0), t.m_point0);

        return(result);
    }
Esempio n. 6
0
 public DistSegment3Triangle3(Segment3d SegmentIn, Triangle3d TriangleIn)
 {
     this.triangle = TriangleIn; this.segment = SegmentIn;
 }
Esempio n. 7
0
 public void CodeTriangle3d(ref Triangle3d v)
 {
     CodeV3d(ref v.P0); CodeV3d(ref v.P1); CodeV3d(ref v.P2);
 }
 public void CodeTriangle3d(ref Triangle3d v)
 {
     AddValue(v.ToString());
 }
 public void CodeTriangle3d(ref Triangle3d v)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// An array getter, optimized by reusing mappings.
 /// </summary>
 /// <param name="triangleIndex">The triangle index offset.</param>
 /// <param name="positionComponent">The position component.</param>
 /// <param name="count">Number of triangles.</param>
 public Triangle3d[] Get3d(string positionComponent, uint triangleIndex, uint count)
 {
     Triangle3d[] data = new Triangle3d[count];
     Get(positionComponent, triangleIndex, data);
     return(data);
 }
Esempio n. 11
0
    public override void Selected(SelectionType button)
    {
        nullifyHitPos = true;
        transform.parent.SendMessage("Selected", button, SendMessageOptions.DontRequireReceiver);
        if (button == SelectionType.SELECTALL)
        {
            BlockMove = true;
        }
        else
        {
            MeshFilter mf   = GetComponent <MeshFilter>();
            Mesh       mesh = mf.sharedMesh;
            currentHit = transform.InverseTransformPoint(AppState.instance.lastHitPosition);
            Vector3d      target = currentHit;
            System.Random rand   = new System.Random();
            int           count  = 0;
            //
            // The algorithm will find local optima - repeat until you get the tru optima
            // but limit the interation using a count
            //
            Int32 current = 0;
            while (count < dmesh.VertexCount)
            {
                count++;
                //
                // choose a random starting point
                //
                current = rand.Next(0, dmesh.VertexCount);
                Vector3d vtx         = dmesh.GetVertex(current);
                double   currentDist = vtx.DistanceSquared(target);
                //
                // find the ring of triangles around the current point
                //
                int iter = 0;
                while (true)
                {
                    iter++;
                    //    throw new InvalidOperationException("Meh One Ring operation invalid : " + res.ToString());
                    //
                    // Interate through the vertices in the one Ring and find the clost to the target point
                    //
                    bool flag = false;
                    foreach (Int32 v in dmesh.VtxVerticesItr(current))
                    {
                        Vector3d thisVtx  = dmesh.GetVertex(v);
                        double   thisDist = thisVtx.DistanceSquared(target);
                        if (thisDist < currentDist)
                        {
                            flag        = true;
                            current     = v;
                            vtx         = thisVtx;
                            currentDist = thisDist;
                        }
                    }
                    //
                    // if the current point as closest - then  have a local optima
                    //
                    if (!flag)
                    {
                        break;
                    }
                }
                //
                // we now have a local optima
                // to check for a global optima look to see if hit is contained by one of the triangles in the one ring
                //
                bool f2 = false;
                foreach (Int32 t in dmesh.VtxTrianglesItr(current))
                {
                    Index3i    tri      = dmesh.GetTriangle(t);
                    Triangle3d triangle = new Triangle3d(
                        dmesh.GetVertex(tri.a),
                        dmesh.GetVertex(tri.b),
                        dmesh.GetVertex(tri.c)
                        );
                    double[] xs = new double[3] {
                        triangle.V0.x, triangle.V1.x, triangle.V2.x
                    };
                    double[] ys = new double[3] {
                        triangle.V0.y, triangle.V1.y, triangle.V2.y
                    };
                    double[] zs = new double[3] {
                        triangle.V0.z, triangle.V1.z, triangle.V2.z
                    };

                    if (
                        target.x >= xs.Min() &&
                        target.x <= xs.Max() &&
                        target.y >= ys.Min() &&
                        target.y <= ys.Max() &&
                        target.z >= zs.Min() &&
                        target.z <= zs.Max()
                        )
                    {
                        f2            = true;
                        currentHitTri = tri;
                    }
                }
                //
                // if we found on triamgle that contain the current hit then we have finished
                //
                if (f2)
                {
                    break;
                }
            }
            if (count >= dmesh.VertexCount)
            {
                //
                // This is the unoptimized verion but it is guaranteed to find a solution if one exits
                //

                current = -1;
                float currentDist = float.MaxValue;
                if (currentHit != null)
                {
                    for (int i = 0; i < mesh.vertices.Length; i++)
                    {
                        Vector3 vtx  = mesh.vertices[i];
                        float   dist = (currentHit - vtx).sqrMagnitude;
                        if (dist < currentDist)
                        {
                            current     = i;
                            currentDist = dist;
                        }
                    }
                }
                //
                // Check that the closet vertex to the point is an actual solution
                //
                bool f2 = false;
                foreach (Int32 t in dmesh.VtxTrianglesItr(current))
                {
                    Index3i    tri      = dmesh.GetTriangle(t);
                    Triangle3d triangle = new Triangle3d(
                        dmesh.GetVertex(tri.a),
                        dmesh.GetVertex(tri.b),
                        dmesh.GetVertex(tri.c)
                        );
                    double[] xs = new double[3] {
                        triangle.V0.x, triangle.V1.x, triangle.V2.x
                    };
                    double[] ys = new double[3] {
                        triangle.V0.y, triangle.V1.y, triangle.V2.y
                    };
                    double[] zs = new double[3] {
                        triangle.V0.z, triangle.V1.z, triangle.V2.z
                    };

                    if (
                        target.x >= xs.Min() &&
                        target.x <= xs.Max() &&
                        target.y >= ys.Min() &&
                        target.y <= ys.Max() &&
                        target.z >= zs.Min() &&
                        target.z <= zs.Max()
                        )
                    {
                        f2            = true;
                        currentHitTri = tri;
                    }
                }
                //
                // if we found on triamgle that contain the current hit then we have finished
                //
                if (!f2)
                {
                    Debug.LogError(" Mesh Vertex Search : No Solution Found");
                    return;
                }
            }
            selectedVertex              = current;
            sphere                      = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            sphere.transform.position   = transform.TransformPoint(mesh.vertices[current]);
            sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
            sphere.transform.parent     = transform;
        }
    }
 /// <summary>
 /// Gets triangle.
 /// </summary>
 /// <param name="index">The triangle index.</param>
 /// <param name="positionComponent">The component where we look for position, must be
 /// Vector2f format.</param>
 /// <remarks>This is not performance wise getter.</remarks>
 public void Get(uint index, Triangle3d storage)
 {
     Get(CommonComponents.Position, index, storage);
 }
Esempio n. 13
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);
                    }
                }
            }
        }
Esempio n. 14
0
 public DistTriangle3Triangle3(Triangle3d Triangle0in, Triangle3d Triangle1in)
 {
     this.triangle0 = Triangle0in; this.triangle1 = Triangle1in;
 }
Esempio n. 15
0
 /// <summary>
 /// Obtains a collection of triangles.
 /// </summary>
 /// <param name="index">The base index.</param>
 /// <param name="count">Number of triangles.</param>
 /// <returns>The triangle collection.</returns>
 public Triangle3d[] Get(uint index, uint count)
 {
     Triangle3d[] data = new Triangle3d[count];
     Get(index, data);
     return(data);
 }
Esempio n. 16
0
        bool IntersectsSegment(ref Plane3d plane, ref Triangle3d triangle, Vector3D end0, Vector3D end1)
        {
            // Compute the 2D representations of the triangle vertices and the
            // segment endpoints relative to the plane of the triangle.  Then
            // compute the intersection in the 2D space.

            // Project the triangle and segment onto the coordinate plane most
            // aligned with the plane normal.
            int    maxNormal = 0;
            double fmax      = Math.Abs(plane.Normal.x);
            double absMax    = Math.Abs(plane.Normal.y);

            if (absMax > fmax)
            {
                maxNormal = 1;
                fmax      = absMax;
            }
            absMax = Math.Abs(plane.Normal.z);
            if (absMax > fmax)
            {
                maxNormal = 2;
            }

            Triangle2d projTri = new Triangle2d();
            Vector2D   projEnd0 = Vector2D.Zero, projEnd1 = Vector2D.Zero;
            int        i;

            if (maxNormal == 0)
            {
                // Project onto yz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].yz;
                    projEnd0.x = end0.y;
                    projEnd0.y = end0.z;
                    projEnd1.x = end1.y;
                    projEnd1.y = end1.z;
                }
            }
            else if (maxNormal == 1)
            {
                // Project onto xz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].xz;
                    projEnd0.x = end0.x;
                    projEnd0.y = end0.z;
                    projEnd1.x = end1.x;
                    projEnd1.y = end1.z;
                }
            }
            else
            {
                // Project onto xy-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].xy;
                    projEnd0.x = end0.x;
                    projEnd0.y = end0.y;
                    projEnd1.x = end1.x;
                    projEnd1.y = end1.y;
                }
            }

            Segment2d             projSeg = new Segment2d(projEnd0, projEnd1);
            IntrSegment2Triangle2 calc    = new IntrSegment2Triangle2(projSeg, projTri);

            if (!calc.Find())
            {
                return(false);
            }

            Vector2dTuple2 intr = new Vector2dTuple2();

            if (calc.Type == IntersectionType.Segment)
            {
                Result   = IntersectionResult.Intersects;
                Type     = IntersectionType.Segment;
                Quantity = 2;
                intr.V0  = calc.Point0;
                intr.V1  = calc.Point1;
            }
            else
            {
                Debug.Assert(calc.Type == IntersectionType.Point);
                //"Intersection must be a point\n";
                Result   = IntersectionResult.Intersects;
                Type     = IntersectionType.Point;
                Quantity = 1;
                intr.V0  = calc.Point0;
            }

            // Unproject the segment of intersection.
            if (maxNormal == 0)
            {
                double invNX = ((double)1) / plane.Normal.x;
                for (i = 0; i < Quantity; ++i)
                {
                    double y = intr[i].x;
                    double z = intr[i].y;
                    double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z);
                    Points[i] = new Vector3D(x, y, z);
                }
            }
            else if (maxNormal == 1)
            {
                double invNY = ((double)1) / plane.Normal.y;
                for (i = 0; i < Quantity; ++i)
                {
                    double x = intr[i].x;
                    double z = intr[i].y;
                    double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z);
                    Points[i] = new Vector3D(x, y, z);
                }
            }
            else
            {
                double invNZ = ((double)1) / plane.Normal.z;
                for (i = 0; i < Quantity; ++i)
                {
                    double x = intr[i].x;
                    double y = intr[i].y;
                    double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y);
                    Points[i] = new Vector3D(x, y, z);
                }
            }

            return(true);
        }
Esempio n. 17
0
        // [RMS] this only tests some basic cases...
        public static void test_RayBoxIntersect()
        {
            Random rand = new Random(316136327);

            // check that box hit works
            for (int ii = 0; ii < 1000; ++ii)
            {
                // generate random triangle
                Triangle3d       t      = new Triangle3d(rand.PointInRange(10), rand.PointInRange(10), rand.PointInRange(10));
                AxisAlignedBox3d bounds = new AxisAlignedBox3d(t.V0);
                bounds.Contain(t.V1);
                bounds.Contain(t.V2);
                Vector3d c = (t.V0 + t.V1 + t.V2) / 3.0;
                for (int jj = 0; jj < 1000; ++jj)
                {
                    Vector3d d   = rand.Direction();
                    Ray3d    ray = new Ray3d(c - 100 * d, d);
                    IntrRay3AxisAlignedBox3 bhit = new IntrRay3AxisAlignedBox3(ray, bounds);
                    Debug.Assert(bhit.Find());
                    IntrRay3Triangle3 thit = new IntrRay3Triangle3(ray, t);
                    Debug.Assert(thit.Find());
                    Debug.Assert(bhit.RayParam0 < thit.RayParameter);
                }
            }

            int N = 100;

            for (int ii = 0; ii < N; ++ii)
            {
                // generate random boxes
                Vector3d         c     = rand.PointInRange(10);
                Vector3d         e     = rand.PositivePoint();
                AxisAlignedBox3d aabox = new AxisAlignedBox3d(c - e, c + e);
                Box3d            obox  = new Box3d(c, Vector3d.AxisX, Vector3d.AxisY, Vector3d.AxisZ, e);
                double           r     = aabox.DiagonalLength;

                // center-out tests
                for (int jj = 0; jj < N; ++jj)
                {
                    Ray3d ray = new Ray3d(c, rand.Direction());
                    assert_same_hit(aabox, obox, ray, true);
                }

                // outside-in tests
                for (int jj = 0; jj < N; ++jj)
                {
                    Vector3d p   = c + 2 * r * rand.Direction();
                    Ray3d    ray = new Ray3d(p, (c - p).Normalized);
                    assert_same_hit(aabox, obox, ray, true);
                }
            }



            // random rays
            int hits   = 0;
            int InnerN = 1000;

            for (int ii = 0; ii < N; ++ii)
            {
                // generate random boxe
                Vector3d c = rand.PointInRange(10);
                Vector3d e = rand.PositivePoint();

                // every tenth box, set an axis to degenerate
                if (ii % 10 == 0)
                {
                    e[rand.Next() % 3] = 0;
                }


                AxisAlignedBox3d aabox = new AxisAlignedBox3d(c - e, c + e);
                Box3d            obox  = new Box3d(c, Vector3d.AxisX, Vector3d.AxisY, Vector3d.AxisZ, e);
                double           r     = aabox.DiagonalLength;


                TrivialBox3Generator boxgen = new TrivialBox3Generator()
                {
                    Box = obox
                };
                boxgen.Generate();
                DMesh3 mesh = new DMesh3();
                boxgen.MakeMesh(mesh);

                for (int i = 0; i < InnerN; ++i)
                {
                    Vector3d target = c + rand.PointInRange(r);
                    Vector3d o      = c + rand.PointInRange(10 * r);
                    Ray3d    ray    = new Ray3d(o, (target - o).Normalized);
                    assert_same_hit(aabox, obox, ray, false);

                    int  hitT     = MeshQueries.FindHitTriangle_LinearSearch(mesh, ray);
                    bool bMeshHit = (hitT != DMesh3.InvalidID);
                    if (bMeshHit)
                    {
                        ++hits;
                    }
                    IntrRay3AxisAlignedBox3 aabbhit = new IntrRay3AxisAlignedBox3(ray, aabox);
                    Debug.Assert(aabbhit.Find() == bMeshHit);
                    Debug.Assert(aabbhit.Test() == bMeshHit);
                }
            }

            System.Console.WriteLine("hit {0} of {1} rays", hits, N * InnerN);
        }
Esempio n. 18
0
 public IntrTriangle3Triangle3(Triangle3d t0, Triangle3d t1)
 {
     triangle0 = t0;
     triangle1 = t1;
 }
Esempio n. 19
0
 /// <summary>
 ///     Draws the triangle.
 /// </summary>
 /// <param name="triangle">Triangle.</param>
 /// <param name="color">Color.</param>
 /// <param name="duration">Duration.</param>
 public static void DrawTriangle(Triangle3d triangle, Color color, float duration)
 {
     DrawLine(triangle.lineA, color, duration);
     DrawLine(triangle.lineB, color, duration);
     DrawLine(triangle.lineC, color, duration);
 }
Esempio n. 20
0
        bool GetCoplanarIntersection(ref Plane3d plane, ref Triangle3d tri0, ref Triangle3d tri1)
        {
            // Project triangles onto coordinate plane most aligned with plane
            // normal.
            int    maxNormal = 0;
            double fmax      = Math.Abs(plane.Normal.x);
            double absMax    = Math.Abs(plane.Normal.y);

            if (absMax > fmax)
            {
                maxNormal = 1;
                fmax      = absMax;
            }
            absMax = Math.Abs(plane.Normal.z);
            if (absMax > fmax)
            {
                maxNormal = 2;
            }

            Triangle2d projTri0 = new Triangle2d(), projTri1 = new Triangle2d();
            int        i;

            if (maxNormal == 0)
            {
                // Project onto yz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].yz;
                    projTri1[i] = tri1[i].yz;
                }
            }
            else if (maxNormal == 1)
            {
                // Project onto xz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].xz;
                    projTri1[i] = tri1[i].xz;
                }
            }
            else
            {
                // Project onto xy-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].xy;
                    projTri1[i] = tri1[i].xy;
                }
            }

            // 2D triangle intersection routines require counterclockwise ordering.
            Vector2D save;
            Vector2D edge0 = projTri0[1] - projTri0[0];
            Vector2D edge1 = projTri0[2] - projTri0[0];

            if (edge0.DotPerp(edge1) < (double)0)
            {
                // Triangle is clockwise, reorder it.
                save        = projTri0[1];
                projTri0[1] = projTri0[2];
                projTri0[2] = save;
            }

            edge0 = projTri1[1] - projTri1[0];
            edge1 = projTri1[2] - projTri1[0];
            if (edge0.DotPerp(edge1) < (double)0)
            {
                // Triangle is clockwise, reorder it.
                save        = projTri1[1];
                projTri1[1] = projTri1[2];
                projTri1[2] = save;
            }

            IntrTriangle2Triangle2 intr = new IntrTriangle2Triangle2(projTri0, projTri1);

            if (!intr.Find())
            {
                return(false);
            }

            PolygonPoints = new Vector3D[intr.Quantity];

            // Map 2D intersections back to the 3D triangle space.
            Quantity = intr.Quantity;
            if (maxNormal == 0)
            {
                double invNX = ((double)1) / plane.Normal.x;
                for (i = 0; i < Quantity; i++)
                {
                    double y = intr.Points[i].x;
                    double z = intr.Points[i].y;
                    double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z);
                    PolygonPoints[i] = new Vector3D(x, y, z);
                }
            }
            else if (maxNormal == 1)
            {
                double invNY = ((double)1) / plane.Normal.y;
                for (i = 0; i < Quantity; i++)
                {
                    double x = intr.Points[i].x;
                    double z = intr.Points[i].y;
                    double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z);
                    PolygonPoints[i] = new Vector3D(x, y, z);
                }
            }
            else
            {
                double invNZ = ((double)1) / plane.Normal.z;
                for (i = 0; i < Quantity; i++)
                {
                    double x = intr.Points[i].x;
                    double y = intr.Points[i].y;
                    double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y);
                    PolygonPoints[i] = new Vector3D(x, y, z);
                }
            }

            Result = IntersectionResult.Intersects;
            Type   = IntersectionType.Polygon;
            return(true);
        }
Esempio n. 21
0
        /// <summary>
        ///     Splits the quad into two triangles. Note, corners ABCD are assumed to be
        ///     in order.
        /// </summary>
        /// <param name="a">Corner A.</param>
        /// <param name="b">Corner B.</param>
        /// <param name="c">Corner C.</param>
        /// <param name="d">Corner D.</param>
        /// <param name="t1">Triangle 1.</param>
        /// <param name="t2">Triangle 1.</param>
        public static void SplitQuad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, out Triangle3d t1, out Triangle3d t2)
        {
            float diagonal1 = (a - c).sqrMagnitude;
            float diagonal2 = (b - d).sqrMagnitude;

            if (diagonal1 < diagonal2)
            {
                t1 = new Triangle3d(a, b, c);
                t2 = new Triangle3d(a, c, d);
            }
            else
            {
                t1 = new Triangle3d(a, b, d);
                t2 = new Triangle3d(b, c, d);
            }
        }
    static void SplitBVHNode(BVHNode node, Mesh3d model, int depth)
    {
        if (depth-- <= 0)       // Decrements depth
        {
            return;
        }

        if (node.m_children == null)
        {
            // Only split if this node contains triangles
            if (node.m_triangles.Count > 0)
            {
                node.m_children = new BVHNode[8];

                Vector3L c = node.m_bounds.m_pos;
                Vector3L e = node.m_bounds.GetHalfSize() * 0.5f;

                node.m_children[0].m_bounds = new AABB3d(c + new Vector3L(-e.x, +e.y, -e.z), node.m_bounds.GetHalfSize());
                node.m_children[1].m_bounds = new AABB3d(c + new Vector3L(+e.x, +e.y, -e.z), node.m_bounds.GetHalfSize());
                node.m_children[2].m_bounds = new AABB3d(c + new Vector3L(-e.x, +e.y, +e.z), node.m_bounds.GetHalfSize());
                node.m_children[3].m_bounds = new AABB3d(c + new Vector3L(+e.x, +e.y, +e.z), node.m_bounds.GetHalfSize());
                node.m_children[4].m_bounds = new AABB3d(c + new Vector3L(-e.x, -e.y, -e.z), node.m_bounds.GetHalfSize());
                node.m_children[5].m_bounds = new AABB3d(c + new Vector3L(+e.x, -e.y, -e.z), node.m_bounds.GetHalfSize());
                node.m_children[6].m_bounds = new AABB3d(c + new Vector3L(-e.x, -e.y, +e.z), node.m_bounds.GetHalfSize());
                node.m_children[7].m_bounds = new AABB3d(c + new Vector3L(+e.x, -e.y, +e.z), node.m_bounds.GetHalfSize());
            }
        }

        // If this node was just split
        if (node.m_children != null && node.m_triangles.Count > 0)
        {
            for (int i = 0; i < 8; ++i)
            { // For each child
                // Count how many triangles each child will contain
                //node.m_children[i].numTriangles = 0;
                for (int j = 0; j < node.m_triangles.Count; ++j)
                {
                    Triangle3d t = node.m_triangles[j];
                    if (IntersectionTest3D.Triangle3dWithAABB3d(t, node.m_children[i].m_bounds))
                    {
                        node.m_children[i].m_triangles.Add(t);
                    }
                }
//              if (node.children[i].numTriangles == 0) {
//                  continue;
//              }
//              node.children[i].triangles = new int[node.children[i].numTriangles];
//              int index = 0; // Add the triangles in the new child arrau
//              for (int j = 0; j < node.numTriangles; ++j)
//                 {
//                  Triangle t = model.triangles[node.triangles[j]];
//                  if (TriangleAABB(t, node.children[i].bounds)) {
//                      node.children[i].triangles[index++] = node.triangles[j];
//                  }
//              }
            }

            //node.numTriangles = 0;
            //delete[] node.triangles;
            node.m_triangles.Clear();

            // Recurse
            for (int i = 0; i < 8; ++i)
            {
                SplitBVHNode(node.m_children[i], model, depth);
            }
        }
    }