Beispiel #1
0
    private ColorPacket256 Shade(Intersections isect, RayPacket256 rays, Scene scene, int depth)
    {
        var ds          = rays.Dirs;
        var pos         = isect.Distances * ds + rays.Starts;
        var normals     = scene.Normals(isect.ThingIndices, pos);
        var reflectDirs = ds - (Multiply(VectorPacket256.DotProduct(normals, ds), Vector256.Create(2.0f)) * normals);
        var colors      = GetNaturalColor(isect.ThingIndices, pos, normals, reflectDirs, scene);

        if (depth >= MaxDepth)
        {
            return(colors + new ColorPacket256(.5f, .5f, .5f));
        }

        return(colors + GetReflectionColor(isect.ThingIndices, pos + (Vector256.Create(0.001f) * reflectDirs), normals, reflectDirs, scene, depth));
    }
Beispiel #2
0
    public MeshCutter(int initialArraySize)
    {
        PositiveMesh = new TempMesh(initialArraySize);
        NegativeMesh = new TempMesh(initialArraySize);

        addedPairs  = new List <Vector3>(initialArraySize);
        ogVertices  = new List <Vector3>(initialArraySize);
        ogTriangles = new List <int>(initialArraySize * 3);
        ogNormals   = new List <Vector3>(initialArraySize);

        intersectPair = new Vector3[2];
        tempTriangle  = new Vector3[3];

        intersect = new Intersections();
    }
Beispiel #3
0
        public void TestHitAllNegativeDistance()
        {
            var sphere = new Sphere();

            var i1 = new Intersection(-1, sphere);
            var i2 = new Intersection(-2, sphere);

            var intersections = new Intersections
            {
                i2,
                i1
            };

            Assert.IsNull(intersections.Hit()?.Shape);
        }
Beispiel #4
0
        public void RefractedColorWithAnOpaqueSurfaceTest()
        {
            var w     = GetDefaultWorld();
            var shape = w.Shapes[0];
            var r     = Helper.Ray(Helper.CreatePoint(0, 0, -5), Helper.CreateVector(0, 0, 1));
            var xs    = new Intersections
            {
                new Intersection(4, shape),
                new Intersection(6, shape)
            };
            var comps = xs[0].Compute(r, xs);
            var c     = w.RefractedColor(comps, 5);

            Check.That(c).IsEqualTo(Color.Black);
        }
Beispiel #5
0
        public void TestHitNegativeDistance()
        {
            var sphere = new Sphere();

            var i1 = new Intersection(-1, sphere);
            var i2 = new Intersection(1, sphere);

            var intersections = new Intersections
            {
                i2,
                i1
            };

            Assert.AreEqual(i2, intersections.Hit());
        }
Beispiel #6
0
    /// <summary>
    /// Slice a mesh by the slice plane.
    /// We assume the plane is already in the mesh's local coordinate frame
    /// Returns posMesh and negMesh, which are the resuling meshes on both sides of the plane 
    /// (posMesh on the same side as the plane's normal, negMesh on the opposite side)
    /// </summary>
    public bool SliceMesh(Mesh mesh, ref Plane slice)
    {

        // Let's always fill the vertices array so that we can access it even if the mesh didn't intersect
        mesh.GetVertices(ogVertices);

        // 1. Verify if the bounds intersect first
        if (!Intersections.BoundPlaneIntersect(mesh, ref slice))
            return false;

        mesh.GetTriangles(ogTriangles, 0);
        mesh.GetNormals(ogNormals);
        mesh.GetUVs(0, ogUvs);

        PositiveMesh.Clear();
        NegativeMesh.Clear();
        addedPairs.Clear();

        // 2. Separate old vertices in new meshes
        for(int i = 0; i < ogVertices.Count; ++i)
        {
            if (slice.GetDistanceToPoint(ogVertices[i]) >= 0)
                PositiveMesh.AddVertex(ogVertices, ogNormals, ogUvs, i);
            else
                NegativeMesh.AddVertex(ogVertices, ogNormals, ogUvs, i);
        }

        // 2.5 : If one of the mesh has no vertices, then it doesn't intersect
        if (NegativeMesh.vertices.Count == 0 || PositiveMesh.vertices.Count == 0)
            return false;

        // 3. Separate triangles and cut those that intersect the plane
        for (int i = 0; i < ogTriangles.Count; i += 3)
        {
            if (intersect.TrianglePlaneIntersect(ogVertices, ogUvs, ogTriangles, i, ref slice, PositiveMesh, NegativeMesh, intersectPair))
                addedPairs.AddRange(intersectPair);
        }

        if (addedPairs.Count > 0)
        {
            //FillBoundaryGeneral(addedPairs);
            FillBoundaryFace(addedPairs);
            return true;
        } else
        {
            throw new UnityException("Error: if added pairs is empty, we should have returned false earlier");
        }
    }
Beispiel #7
0
        public void RefractedColorIsBlackForTotalInternalRefraction()
        {
            var w = World.Default();
            var s = w.Objects[0];

            s.Material.Transparency    = 1.0f;
            s.Material.RefractiveIndex = 1.5f;
            var r  = new Ray(new Point(0, 0, MathF.Sqrt(2f) / 2f), new Vector(0, 1, 0));
            var xs = Intersections.Create(
                new Intersection(-MathF.Sqrt(2f) / 2f, s),
                new Intersection(MathF.Sqrt(2f) / 2f, s));
            // Inside sphere so look at second intersection.
            var comps = new IntersectionInfo(xs[1], r, xs);

            PhongShading.RefractedColor(w, comps, 5).Should().Be(Colors.Black);
        }
Beispiel #8
0
        public void TestRefractColor()
        {
            var world = WorldBuilder.DefaultWorld();
            var ray   = new Ray(Tuple.Point(0, 0, -5), Tuple.Vector(0, 0, 1));

            var xs = new Intersections
            {
                new Intersection(4, world.Shapes[0]),
                new Intersection(6, world.Shapes[0])
            };

            var comps = Computation.Prepare(xs[0], ray, xs);
            var col   = world.RefractColor(comps, 5);

            Assert.AreEqual(new Color(0, 0, 0), col);
        }
Beispiel #9
0
        public void RefractedColorTotalInternalReflection()
        {
            var world  = new DefaultWorld();
            var sphere = world.Shapes[0];

            sphere.Material.Transparency    = 1;
            sphere.Material.RefractiveIndex = 1.5f;

            var ray           = new Ray(new Point(0, 0, MathF.Sqrt(2) / 2), Vector.UnitY);
            var intersections = new Intersections(new Intersection(-MathF.Sqrt(2) / 2, sphere), new Intersection(MathF.Sqrt(2) / 2, sphere));
            var info          = new IntersectionInfo(intersections, intersections[1], ray);

            var actual = world.RefractedColor(info, 5);

            Assert.Equal(Color.Black, actual);
        }
Beispiel #10
0
        public void RefractedColorMaxRecursiveDepth()
        {
            var world  = new DefaultWorld();
            var sphere = world.Shapes[0];

            sphere.Material.Transparency    = 1;
            sphere.Material.RefractiveIndex = 1.5f;

            var ray           = new Ray(new Point(0, 0, -5), Vector.UnitZ);
            var intersections = new Intersections(new Intersection(4, sphere), new Intersection(6, sphere));
            var info          = new IntersectionInfo(intersections, intersections[0], ray);

            var actual = world.RefractedColor(info, 0);

            Assert.Equal(Color.Black, actual);
        }
        public void TestWorldRefractedColorTotalInternalReflection()
        {
            var w     = World.Default;
            var shape = w.Objects[0];

            shape.Material.Transparency    = 1.0;
            shape.Material.RefractiveIndex = 1.5;
            var r     = new Ray(new Point(0, 0, MathHelper.SQRT2 / 2.0), Vector.VectorY);
            var i1    = new Intersection(-MathHelper.SQRT2 / 2.0, shape);
            var i2    = new Intersection(MathHelper.SQRT2 / 2.0, shape);
            var xs    = new Intersections(i1, i2);
            var comps = xs[1].PrepareComputations(r, xs);
            var c     = w.RefractedColor(comps, 5);

            Assert.AreEqual(c, Color.Black);
        }
        public void TestWorldRefractedColorMaxRecursion()
        {
            var w     = World.Default;
            var shape = w.Objects[0];

            shape.Material.Transparency    = 1.0;
            shape.Material.RefractiveIndex = 1.5;
            var r     = new Ray(new Point(0, 0, -5), Vector.VectorZ);
            var i1    = new Intersection(4, shape);
            var i2    = new Intersection(6, shape);
            var xs    = new Intersections(i1, i2);
            var comps = xs[0].PrepareComputations(r, xs);
            var c     = w.RefractedColor(comps, 0);

            Assert.AreEqual(c, Color.Black);
        }
Beispiel #13
0
        public void GivenIntersectionHit_WhenIntersectionsHaveMixedTimeValue_ThenReturnLowestPositiveIntersection()
        {
            // Arrange
            var sphere        = new Sphere();
            var i1            = new Intersection(5, sphere);
            var i2            = new Intersection(7, sphere);
            var i3            = new Intersection(-3, sphere);
            var i4            = new Intersection(2, sphere);
            var intersections = new Intersections(i1, i2, i3, i4);

            // Act
            var hit = intersections.Hit();

            // Assert
            Assert.Equal(i4, hit);
        }
Beispiel #14
0
        public void DeterminesN1AndN2()
        {
            var a = Spheres.GlassSphere();

            a.SetTransform(Transform.Scale(2f));
            a.Material.RefractiveIndex = 1.5f;

            var b = Spheres.GlassSphere();

            b.SetTransform(Transform.TranslateZ(-0.25f));
            b.Material.RefractiveIndex = 2.0f;

            var c = Spheres.GlassSphere();

            c.SetTransform(Transform.TranslateZ(0.25f));
            c.Material.RefractiveIndex = 2.5f;

            var r  = new Ray(new Point(0, 0, -4), new Vector(0, 0, 1));
            var xs = Intersections.Create(
                new Intersection(2.00f, a),
                new Intersection(2.75f, b),
                new Intersection(3.25f, c),
                new Intersection(4.75f, b),
                new Intersection(5.25f, c),
                new Intersection(6.00f, a)
                );

            var comps = new List <IntersectionInfo>();

            for (var i = 0; i < xs.Count; i++)
            {
                comps.Add(new IntersectionInfo(xs[i], r, xs));
            }

            comps[0].N1.Should().Be(1.0f);
            comps[0].N2.Should().Be(1.5f);
            comps[1].N1.Should().Be(1.5f);
            comps[1].N2.Should().Be(2.0f);
            comps[2].N1.Should().Be(2.0f);
            comps[2].N2.Should().Be(2.5f);
            comps[3].N1.Should().Be(2.5f);
            comps[3].N2.Should().Be(2.5f);
            comps[4].N1.Should().Be(2.5f);
            comps[4].N2.Should().Be(1.5f);
            comps[5].N1.Should().Be(1.5f);
            comps[5].N2.Should().Be(1.0f);
        }
Beispiel #15
0
    public static List <Triangle> TriangulatePoints(List <Vertex> points)
    {
        //Generate the convex hull - will also remove the points from points list which are not on the hull
        List <Vertex> pointsOnConvexHull = HullAlgorithms.JarvisMarch(points);

        //Triangulate the convex hull
        List <Triangle> triangles = TriangulateHullAlgorithms.TriangulateConvexPolygon(pointsOnConvexHull);

        //Add the remaining points and split the triangles
        for (int i = 0; i < points.Count; i++)
        {
            Vertex currentPoint = points[i];

            //2d space
            Vector2 p = new Vector2(currentPoint.position.x, currentPoint.position.z);

            //Which triangle is this point in?
            for (int j = 0; j < triangles.Count; j++)
            {
                Triangle t = triangles[j];

                Vector2 p1 = new Vector2(t.v1.position.x, t.v1.position.z);
                Vector2 p2 = new Vector2(t.v2.position.x, t.v2.position.z);
                Vector2 p3 = new Vector2(t.v3.position.x, t.v3.position.z);

                if (Intersections.IsPointInTriangle(p1, p2, p3, p))
                {
                    //Create 3 new triangles
                    Triangle t1 = new Triangle(t.v1, t.v2, currentPoint);
                    Triangle t2 = new Triangle(t.v2, t.v3, currentPoint);
                    Triangle t3 = new Triangle(t.v3, t.v1, currentPoint);

                    //Remove the old triangle
                    triangles.Remove(t);

                    //Add the new triangles
                    triangles.Add(t1);
                    triangles.Add(t2);
                    triangles.Add(t3);

                    break;
                }
            }
        }

        return(triangles);
    }
        /// <summary>
        /// General Hittesting on the infinite plane defined by the element transforms
        /// </summary>
        /// <param name="touch">The touch to be tested</param>
        /// <param name="prevpos">Calculate Intersection point for previous position</param>
        /// <returns>If the touch hits then an Intersection point otherwise null</returns>
        public IntersectionPoint PreparePlanarShapeHitTest(Touch touch, bool prevpos)
        {
            // when first hit consider the display transformation then
            // for the rest of the interaction consider the interaction transform
            touch.GetPreviousWorldPosition(Context, out var popos, out var pdir);
            var hit = Intersections.PlaneRay(
                prevpos ? popos : touch.WorldPosition,
                prevpos ? pdir : touch.ViewDir,
                DisplayMatrix,
                out var ispoint,
                out var planarpoint);

            return(hit ? new IntersectionPoint(ispoint, planarpoint, this, touch)
            {
                SurfaceSpace = planarpoint * 2
            } : null);
        }
Beispiel #17
0
        public void TestIntersectionList()
        {
            var sphere = new Sphere();
            var i1     = new Intersection(1, sphere);
            var i2     = new Intersection(2, sphere);

            var intersections = new Intersections
            {
                i1,
                i2
            };

            Assert.AreEqual(intersections.Count, 2);

            Assert.AreEqual(intersections[0].Distance, 1, Epsilon);
            Assert.AreEqual(intersections[1].Distance, 2, Epsilon);
        }
        public Vector3?Raycast(Ray ray)
        {
            var corners = GetCorners();

            for (int i = 0; i < corners.Count; i++)
            {
                var v1 = corners[i];
                var v2 = corners[(i + 1) % corners.Count];

                if (Intersections.LineTriangleIntersection(ray, v1, v2, CenterPoint, out var intersectionPoint) == 1)
                {
                    return(intersectionPoint);
                }
            }

            return(null);
        }
Beispiel #19
0
        public override void IntersectLocal(ref Tuple origin, ref Tuple direction, Intersections intersections)
        {
            Intersections leftXs = new Intersections();

            Left.Intersect(ref origin, ref direction, leftXs);
            var rightXs = new Intersections();

            Right.Intersect(ref origin, ref direction, rightXs);
            Intersections result;

            if (leftXs.Any() || rightXs.Any())
            {
                var xs = new Intersections(leftXs.Concat(rightXs));
                result = Filter(xs);
                intersections.AddRange(result);
            }
        }
Beispiel #20
0
        public override Intersections IntersectLocal(Ray ray)
        {
            var xs = new Intersections();
            var a  = ray.Direction.X * ray.Direction.X - ray.Direction.Y * ray.Direction.Y + ray.Direction.Z * ray.Direction.Z;
            var b  = 2 * ray.Origin.X * ray.Direction.X - 2 * ray.Origin.Y * ray.Direction.Y + 2 * ray.Origin.Z * ray.Direction.Z;
            var c  = ray.Origin.X * ray.Origin.X - ray.Origin.Y * ray.Origin.Y + ray.Origin.Z * ray.Origin.Z;

            if (Math.Abs(a) <= double.Epsilon && Math.Abs(b) > double.Epsilon)
            {
                var t = -c / (2 * b);
                xs.Add(new Intersection(t, this));
            }

            if (Math.Abs(a) > double.Epsilon)
            {
                var disc = b * b - 4 * a * c;
                if (disc >= 0)
                {
                    var t0 = (-b - Math.Sqrt(disc)) / (2 * a);
                    var t1 = (-b + Math.Sqrt(disc)) / (2 * a);

                    if (t0 > t1)
                    {
                        var tmp = t0;
                        t0 = t1;
                        t1 = tmp;
                    }

                    var y0 = ray.Origin.Y + t0 * ray.Direction.Y;
                    if (Minimum < y0 && y0 < Maximum)
                    {
                        xs.Add(new Intersection(t0, this));
                    }

                    var y1 = ray.Origin.Y + t1 * ray.Direction.Y;
                    if (Minimum < y1 && y1 < Maximum)
                    {
                        xs.Add(new Intersection(t1, this));
                    }
                }
            }

            IntersectCaps(ray, xs);
            xs.Sort();
            return(xs);
        }
        public void FilteringAListOfIntersections(string operation, int x0, int x1)
        {
            var s1 = new Sphere();
            var s2 = new Cube();

            var c  = new CSG(Operation.OfKind(operation), s1, s1);
            var xs = new Intersections(
                new Intersection(1, s1),
                new Intersection(2, s2),
                new Intersection(3, s1),
                new Intersection(4, s2));
            var result = c.FilterIntersections(xs);

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(xs[x0], result[0]);
            Assert.AreEqual(xs[x1], result[1]);
        }
Beispiel #22
0
        public List <Road> PathToRoadList()
        {
            var listRoads = new List <Road>();

            foreach (var road in City.Instance.Roads)
            {
                if (Intersections.FindAll(i => i.Location == road.Start)
                    .FindAll(i => i.Location == road.End).Count > 0)
                {
                    listRoads.Add(road);
                }
            }
            listRoads.Add(GPSSystem.NearestRoad(Start));
            listRoads.Add(GPSSystem.NearestRoad(End));

            return(listRoads);
        }
Beispiel #23
0
        public void TestN1N2AtIntersections(int index, double expectedN1, double expectedN2)
        {
            var sphereA = new Sphere
            {
                Transform = Matrix4.Scaling(2, 2, 2),
                Material  = new Material
                {
                    RefractiveIndex = 1.5
                }
            };

            var sphereB = new Sphere
            {
                Transform = Matrix4.Translation(0, 0, -0.25),
                Material  = new Material
                {
                    RefractiveIndex = 2.0
                }
            };
            var sphereC = new Sphere
            {
                Transform = Matrix4.Translation(0, 0, 0.25),
                Material  = new Material
                {
                    RefractiveIndex = 2.5
                }
            };

            var ray = new Ray(Tuple.Point(0, 0, -4), Tuple.Vector(0, 0, 1));
            var xs  = new Intersections
            {
                new Intersection(2, sphereA),
                new Intersection(2.75, sphereB),
                new Intersection(3.25, sphereC),
                new Intersection(4.75, sphereB),
                new Intersection(5.25, sphereC),
                new Intersection(6, sphereA),
            };


            var comp = Computation.Prepare(xs[index], ray, xs);

            Assert.AreEqual(expectedN1, comp.N1, Epsilon);
            Assert.AreEqual(expectedN2, comp.N2, Epsilon);
        }
Beispiel #24
0
        public override Intersections IntersectLocal(Ray ray)
        {
            var xs = new Intersections();
            var a  = ray.Direction.X * ray.Direction.X + ray.Direction.Z * ray.Direction.Z;

            // ray is not parallel to the y axis
            if (a > double.Epsilon)
            {
                var b    = 2 * ray.Origin.X * ray.Direction.X + 2 * ray.Origin.Z * ray.Direction.Z;
                var c    = ray.Origin.X * ray.Origin.X + ray.Origin.Z * ray.Origin.Z - 1;
                var disc = b * b - 4 * a * c;

                // ray does not intersect the cylinder
                if (disc < 0)
                {
                    return(xs);
                }

                var t0 = (-b - Math.Sqrt(disc)) / (2 * a);
                var t1 = (-b + Math.Sqrt(disc)) / (2 * a);

                if (t0 > t1)
                {
                    var t = t0;
                    t0 = t1;
                    t1 = t;
                }

                var y0 = ray.Origin.Y + t0 * ray.Direction.Y;
                if (Minimum < y0 && y0 < Maximum)
                {
                    xs.Add(new Intersection(t0, this));
                }

                var y1 = ray.Origin.Y + t1 * ray.Direction.Y;
                if (Minimum < y1 && y1 < Maximum)
                {
                    xs.Add(new Intersection(t1, this));
                }
            }

            IntersectCaps(ray, xs);
            xs.Sort();
            return(xs);
        }
Beispiel #25
0
    //Are two AABB intersecting?
    private void AABB_AABB()
    {
        MyVector2 t1_p1 = t1_p1_trans.position.ToMyVector2();
        MyVector2 t1_p2 = t1_p2_trans.position.ToMyVector2();
        MyVector2 t1_p3 = t1_p3_trans.position.ToMyVector2();

        MyVector2 t2_p1 = t2_p1_trans.position.ToMyVector2();
        MyVector2 t2_p2 = t2_p2_trans.position.ToMyVector2();
        MyVector2 t2_p3 = t2_p3_trans.position.ToMyVector2();

        Triangle2 t1 = new Triangle2(t1_p1, t1_p2, t1_p3);
        Triangle2 t2 = new Triangle2(t2_p1, t2_p2, t2_p3);

        bool isIntersecting = Intersections.AABB_AABB_2D(
            t1.MinX(), t1.MaxX(), t1.MinY(), t1.MaxY(),
            t2.MinX(), t2.MaxX(), t2.MinY(), t2.MaxY());

        Debug.Log("AABB intersecting: " + isIntersecting);

        //Display the rectangles and the vertices we use to make the rectangles
        Vector3 r1_size = new Vector3(t1.MaxX() - t1.MinX(), 0.01f, t1.MaxY() - t1.MinY());
        Vector3 r2_size = new Vector3(t2.MaxX() - t2.MinX(), 0.01f, t2.MaxY() - t2.MinY());

        Vector3 r1_center = new Vector3(t1.MinX() + (r1_size.x * 0.5f), 0f, t1.MinY() + (r1_size.z * 0.5f));
        Vector3 r2_center = new Vector3(t2.MinX() + (r2_size.x * 0.5f), 0f, t2.MinY() + (r2_size.z * 0.5f));

        Gizmos.color = Color.white;

        Gizmos.DrawCube(r1_center, r1_size);

        float r = 0.1f;

        //Gizmos.DrawWireSphere(t1_p1.ToVector3(), r);
        //Gizmos.DrawWireSphere(t1_p2.ToVector3(), r);
        //Gizmos.DrawWireSphere(t1_p3.ToVector3(), r);

        Gizmos.color = isIntersecting ? Color.red : Color.white;


        Gizmos.DrawCube(r2_center, r2_size);

        //Gizmos.DrawWireSphere(t2_p1.ToVector3(), r);
        //Gizmos.DrawWireSphere(t2_p2.ToVector3(), r);
        //Gizmos.DrawWireSphere(t2_p3.ToVector3(), r);
    }
Beispiel #26
0
        public void RefractedColorAtTheMaximumRecursiveDepthTest()
        {
            var w     = GetDefaultWorld();
            var shape = w.Shapes[0];

            shape.Material.Transparency    = 1.0;
            shape.Material.RefractiveIndex = 1.5;
            var r  = Helper.Ray(Helper.CreatePoint(0, 0, -5), Helper.CreateVector(0, 0, 1));
            var xs = new Intersections
            {
                new Intersection(4, shape),
                new Intersection(6, shape)
            };
            var comps = xs[0].Compute(r, xs);
            var c     = w.RefractedColor(comps, 0);

            Check.That(c).IsEqualTo(Color.Black);
        }
Beispiel #27
0
        public void RayHitsCsgObjectTest()
        {
            var sphere1 = new Sphere();
            var sphere2 = new Sphere();

            sphere2.Translate(0, 0, 0.5);

            var csg = new CsgUnion(sphere1, sphere2);
            var r   = Helper.Ray(0, 0, -5, 0, 0, 1);
            var xs  = new Intersections();

            csg.IntersectLocal(ref r.Origin, ref r.Direction, xs);
            Check.That(xs).CountIs(2);
            Check.That(xs[0].T).IsEqualTo(4);
            Check.That(xs[0].Object).IsEqualTo(sphere1);
            Check.That(xs[1].T).IsEqualTo(6.5);
            Check.That(xs[1].Object).IsEqualTo(sphere2);
        }
Beispiel #28
0
        public override Intersections IntersectLocal(Ray ray)
        {
            Intersections leftXs  = Left.Intersect(ray);
            var           rightXs = Right.Intersect(ray);
            Intersections result;

            if (leftXs.Any() || rightXs.Any())
            {
                var xs = new Intersections(leftXs.Concat(rightXs));
                result = Filter(xs);
            }
            else
            {
                result = new Intersections();
            }

            return(result);
        }
Beispiel #29
0
        private void CleanInternal(IToolContext context)
        {
            Intersections?.ForEach(i => i.Clear(context));
            Filters?.ForEach(f => f.Clear(context));

            CurrentState = State.StartPoint;

            if (_line != null)
            {
                context.WorkingContainer.Shapes.Remove(_line);
                context.Renderer.SelectedShapes.Remove(_line.StartPoint);
                context.Renderer.SelectedShapes.Remove(_line.Point);
                _line = null;
            }

            context.Release?.Invoke();
            context.Invalidate?.Invoke();
        }
Beispiel #30
0
        /// <summary>
        /// Поиск пересечений с лучом
        /// </summary>
        /// <param name="rayPos">Начало луча</param>
        /// <param name="rayDir">Направление луча</param>
        /// <param name="rayLength">Длина луча</param>
        /// <param name="pos">Место пересечения</param>
        /// <param name="normal">Нормаль пересечения</param>
        /// <returns>True если есть пересечение</returns>
        internal override bool RayHit(Vec3 rayPos, Vec3 rayDir, float rayLength, out Vec3 pos, out Vec3 normal)
        {
            // Если есть с чем пересекаться
            if (Indices != null && Vertices != null)
            {
                if (Indices.Length > 0)
                {
                    float range = float.MaxValue;
                    bool  hit = false;
                    Vec3  hpos = Vec3.Zero, hnorm = Vec3.Zero;
                    for (int i = 0; i < Indices.Length; i += 3)
                    {
                        Vec3 v0 = Vertices[Indices[i + 0]];
                        Vec3 v1 = Vertices[Indices[i + 1]];
                        Vec3 v2 = Vertices[Indices[i + 2]];
                        Vec3 hp, hn;
                        if (Intersections.RayTriangle(rayPos, rayDir, v0, v1, v2, false, out hp, out hn))
                        {
                            float d = (hp - rayPos).LengthSquared;
                            if (d < range)
                            {
                                range = d;
                                hpos  = hp;
                                hnorm = hn;
                                hit   = true;
                            }
                        }
                    }

                    range = (float)Math.Sqrt(range);
                    if (hit && range <= rayLength)
                    {
                        pos    = hpos;
                        normal = hnorm;
                        return(true);
                    }
                }
            }

            // Пересечения нет
            pos    = Vec3.Zero;
            normal = Vec3.UnitZ;
            return(false);
        }