Esempio n. 1
0
        /// <inheritdoc/>
        public override Vector3 Intersect(ScaledRay ray)
        {
            Vector3 intersection;

            Intersect(ray, out intersection);
            return(intersection);
        }
 private void FaceCenterIntersections()
 {
     foreach (var face in topology.internalFaces)
     {
         var position  = facePositions[face];
         var normal    = surface.GetNormal(position);
         var ray       = new ScaledRay(position + normal, -normal);
         var foundFace = partitioning.FindFace(ray);
         Assert.AreEqual(face, foundFace, string.Format("Face center: {0}", facePositions[face]));
     }
 }
Esempio n. 3
0
 /// <inheritdoc/>
 public override bool Intersect(ScaledRay ray, out Vector3 intersection)
 {
     if (!isInverted)
     {
         return(Geometry.IntersectForwardExternal(new Sphere(Vector3.zero, radius), ray, out intersection));
     }
     else
     {
         return(Geometry.IntersectForwardInternal(new Sphere(Vector3.zero, radius), ray, out intersection));
     }
 }
Esempio n. 4
0
        /// <summary>
        /// Finds the face with which the given ray intersects.
        /// </summary>
        /// <param name="ray">The ray to intersect with the manifold to find which face it intersects.</param>
        /// <returns>The first face which is intersected by the given ray, or an empty face if the ray does not intersect the manifold at all.</returns>
        public Topology.Face FindFace(ScaledRay ray)
        {
            Vector3 intersection;

            if (_surface.Intersect(ray, out intersection))
            {
                return(FindFace(intersection));
            }
            else
            {
                return(new Topology.Face());
            }
        }
 private void FaceEdgeMidpointWeightedIntersections()
 {
     foreach (var face in topology.internalFaces)
     {
         foreach (var edge in face.edges)
         {
             var position  = (edgeMidpoints[edge] * 4f + facePositions[face]) * 0.2f;
             var normal    = surface.GetNormal(position);
             var ray       = new ScaledRay(position + normal, -normal);
             var foundFace = partitioning.FindFace(ray);
             Assert.AreEqual(face, foundFace, string.Format("Face center: {0}, Ray target: {1}, Edge midpoint: {2}", facePositions[face], position, edgeMidpoints[edge]));
         }
     }
 }
Esempio n. 6
0
 /// <inheritdoc/>
 public override bool Intersect(ScaledRay ray, out Vector3 intersection)
 {
     return(Geometry.Intersect(plane, ray, out intersection));
 }
Esempio n. 7
0
 /// <inheritdoc/>
 public override Vector3 Intersect(ScaledRay ray)
 {
     return(Geometry.Intersect(plane, ray));
 }
Esempio n. 8
0
        protected void GetGhostRegions(Camera camera, float bufferRadius, List <GhostRegion> ghostRegions)
        {
            // Get the six planes of the frustum volume, and expand them outward based on the buffer radius.
            var frustumPlanes = UnityEngine.GeometryUtility.CalculateFrustumPlanes(camera);

            if (bufferRadius != 0f)
            {
                for (int i = 0; i < frustumPlanes.Length; ++i)
                {
                    frustumPlanes[i] = new Plane(frustumPlanes[i].normal, frustumPlanes[i].distance + bufferRadius);
                }
            }

            // Find the eight corners of the camera view frustum.
            var corners = Geometry.FindFrustumCorners(camera, frustumPlanes);

            // Find the maximum ghost region index extents based on these eight corners.
            IntVector3 min = new IntVector3(int.MaxValue, int.MaxValue, int.MaxValue);
            IntVector3 max = new IntVector3(int.MinValue, int.MinValue, int.MinValue);

            for (int i = 0; i < corners.Length; ++i)
            {
                ExpandIndexBounds(GetGhostRegionIndex(corners[i]), ref min, ref max);
            }

            // If the bounds are limited to a single dimension, then just return a linear array of ghost regions.
            if (min.y == max.y && min.z == max.z)
            {
                int startIndex = 0;
                for (int x = min.x; x <= max.x; ++x)
                {
                    if (x == 0 && min.y == 0 && min.z == 0)
                    {
                        continue;                                                         // The 0,0,0 region is the real region, not a ghost region, so skip it.
                    }
                    InsertGhostRegion(new IntVector3(x, min.y, min.z), ghostRegions, ref startIndex);
                }
                return;
            }
            else if (min.x == max.x && min.z == max.z)
            {
                int startIndex = 0;
                for (int y = min.y; y <= max.y; ++y)
                {
                    if (min.x == 0 && y == 0 && min.z == 0)
                    {
                        continue;                                                         // The 0,0,0 region is the real region, not a ghost region, so skip it.
                    }
                    InsertGhostRegion(new IntVector3(min.x, y, min.z), ghostRegions, ref startIndex);
                }
                return;
            }
            else if (min.x == max.x && min.y == max.y)
            {
                int startIndex = 0;
                for (int z = min.z; z <= max.z; ++z)
                {
                    if (min.x == 0 && min.y == 0 && z == 0)
                    {
                        continue;                                                         // The 0,0,0 region is the real region, not a ghost region, so skip it.
                    }
                    InsertGhostRegion(new IntVector3(min.x, min.y, z), ghostRegions, ref startIndex);
                }
                return;
            }

            // If we haven't returned yet, then the bounds are not limited to a single dimension, which means that not all
            // regions in the determined bounds are guaranteed to actually intersect with the frustum, and there's no value
            // in returning any regions that don't intersect.  However, returning such regions shouldn't actually cause any
            // harm in terms of correctness, only performance, so there's some leeway for doing the rejection.

            int unwrappedAxis;

            if (!axis0IsWrapped)
            {
                unwrappedAxis = 0;
            }
            else if (!axis1IsWrapped)
            {
                unwrappedAxis = 1;
            }
            else if (!axis2IsWrapped)
            {
                unwrappedAxis = 2;
            }
            else
            {
                unwrappedAxis = -1;
            }

            var regionCorners = unwrappedAxis == -1 ? new Vector3[8] : null;
            var regionLines   = unwrappedAxis != -1 ? new ScaledRay[4] : null;

            if (unwrappedAxis == -1)
            {
                int startIndex = 0;
                for (int z = min.z; z <= max.z; ++z)
                {
                    for (int y = min.y; y <= max.y; ++y)
                    {
                        for (int x = min.x; x <= max.x; ++x)
                        {
                            if (x == 0 && y == 0 && z == 0)
                            {
                                continue;                                                         // The 0,0,0 region is the real region, not a ghost region, so skip it.
                            }
                            regionCorners[0] = _transformedAxis0Vector * x + _transformedAxis1Vector * y + _transformedAxis2Vector * z;
                            regionCorners[1] = regionCorners[0] + _transformedAxis0Vector;
                            regionCorners[2] = regionCorners[0] + _transformedAxis1Vector;
                            regionCorners[3] = regionCorners[0] + _transformedAxis2Vector;
                            regionCorners[4] = regionCorners[1] + _transformedAxis1Vector;
                            regionCorners[5] = regionCorners[2] + _transformedAxis2Vector;
                            regionCorners[6] = regionCorners[3] + _transformedAxis0Vector;
                            regionCorners[7] = regionCorners[4] + _transformedAxis2Vector;

                            bool exclude = false;
                            foreach (var plane in frustumPlanes)
                            {
                                if (Geometry.AllAreBelow(regionCorners, plane))
                                {
                                    exclude = true;
                                    break;
                                }
                            }

                            if (!exclude)
                            {
                                InsertGhostRegion(new IntVector3(x, y, z), ghostRegions, ref startIndex);
                            }
                        }
                    }
                }
            }
            else
            {
                int startIndex = 0;
                for (int z = min.z; z <= max.z; ++z)
                {
                    for (int y = min.y; y <= max.y; ++y)
                    {
                        for (int x = min.x; x <= max.x; ++x)
                        {
                            if (x == 0 && y == 0 && z == 0)
                            {
                                continue;                                                         // The 0,0,0 region is the real region, not a ghost region, so skip it.
                            }
                            switch (unwrappedAxis)
                            {
                            case 0:
                                regionLines[0] = new ScaledRay(_transformedAxis1Vector * y + _transformedAxis2Vector * z, _transformedAxis0Vector);
                                regionLines[1] = new ScaledRay(regionLines[0].origin + _transformedAxis1Vector, _transformedAxis0Vector);
                                regionLines[2] = new ScaledRay(regionLines[0].origin + _transformedAxis2Vector, _transformedAxis0Vector);
                                regionLines[3] = new ScaledRay(regionLines[1].origin + _transformedAxis2Vector, _transformedAxis0Vector);
                                break;

                            case 1:
                                regionLines[0] = new ScaledRay(_transformedAxis0Vector * x + _transformedAxis2Vector * z, _transformedAxis1Vector);
                                regionLines[1] = new ScaledRay(regionLines[0].origin + _transformedAxis0Vector, _transformedAxis1Vector);
                                regionLines[2] = new ScaledRay(regionLines[0].origin + _transformedAxis2Vector, _transformedAxis1Vector);
                                regionLines[3] = new ScaledRay(regionLines[1].origin + _transformedAxis2Vector, _transformedAxis1Vector);
                                break;

                            case 2:
                                regionLines[0] = new ScaledRay(_transformedAxis0Vector * x + _transformedAxis1Vector * y, _transformedAxis2Vector);
                                regionLines[1] = new ScaledRay(regionLines[0].origin + _transformedAxis0Vector, _transformedAxis2Vector);
                                regionLines[2] = new ScaledRay(regionLines[0].origin + _transformedAxis1Vector, _transformedAxis2Vector);
                                regionLines[3] = new ScaledRay(regionLines[1].origin + _transformedAxis1Vector, _transformedAxis2Vector);
                                break;

                            default:
                                throw new System.NotImplementedException();
                            }

                            bool exclude = true;
                            foreach (var plane in frustumPlanes)
                            {
                                var minT = float.NegativeInfinity;
                                var maxT = float.PositiveInfinity;
                                if (Geometry.TruncateLineSegment(regionLines[0], plane, ref minT, ref maxT) <= 0f)
                                {
                                    continue;
                                }
                                if (Geometry.TruncateLineSegment(regionLines[1], plane, ref minT, ref maxT) <= 0f)
                                {
                                    continue;
                                }
                                if (Geometry.TruncateLineSegment(regionLines[2], plane, ref minT, ref maxT) <= 0f)
                                {
                                    continue;
                                }
                                if (Geometry.TruncateLineSegment(regionLines[3], plane, ref minT, ref maxT) <= 0f)
                                {
                                    continue;
                                }

                                exclude = false;
                                break;
                            }

                            if (!exclude)
                            {
                                InsertGhostRegion(new IntVector3(x, y, z), ghostRegions, ref startIndex);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 9
0
 /// <inheritdoc/>
 public abstract bool Intersect(ScaledRay ray, out Vector3 intersection);
Esempio n. 10
0
 /// <inheritdoc/>
 public abstract Vector3 Intersect(ScaledRay ray);