示例#1
0
        static void SnapToLines(int[] indices, Vector3[] localVertices, Matrix4x4 localToWorld, ref SnapData snapData)
        {
            if (indices == null || localVertices == null)
            {
                return;
            }

            var worldVertex3 = MathConstants.zeroVector3;

            for (int i = 0; i < indices.Length; i += 2)
            {
                var index1       = indices[i + 0];
                var index2       = indices[i + 1];
                var worldVertex1 = localToWorld.MultiplyPoint(localVertices[index1]);
                var worldVertex2 = localToWorld.MultiplyPoint(localVertices[index2]);

                if (!SnapToLine(snapData.worldPoint, worldVertex1, worldVertex2, snapData.snapPlane, out worldVertex3))
                {
                    continue;
                }

                if (snapData.snapPlane.HasValue &&
                    Mathf.Abs(snapData.snapPlane.Value.Distance(worldVertex3)) >= MathConstants.DistanceEpsilon)
                {
                    continue;
                }

                var guiVertex2  = CameraUtility.WorldToGUIPoint(worldVertex3);
                var guiDistance = (guiVertex2 - snapData.guiPoint).sqrMagnitude * EdgeFudgeFactor;
                if (guiDistance + MathConstants.DistanceEpsilon >= snapData.closestDistanceSqr)
                {
                    continue;
                }

                snapData.closestDistanceSqr = guiDistance;
                snapData.outEdge            = new List <Vector3>()
                {
                    worldVertex1, worldVertex2
                };
                snapData.snappedWorldPoint = worldVertex3;
            }
        }
示例#2
0
        static void SnapToLines(Vector3[] worldVertices, int vertexCount, ref SnapData snapData)
        {
            if (worldVertices == null)
            {
                return;
            }

            var worldVertex3 = MathConstants.zeroVector3;

            for (int i = 0; i < vertexCount; i += 2)
            {
                var worldVertex1 = worldVertices[i + 0];
                var worldVertex2 = worldVertices[i + 1];

                if (!SnapToLine(snapData.worldPoint, worldVertex1, worldVertex2, snapData.snapPlane, out worldVertex3))
                {
                    continue;
                }

                if (snapData.snapPlane.HasValue &&
                    Mathf.Abs(snapData.snapPlane.Value.Distance(worldVertex3)) >= MathConstants.DistanceEpsilon)
                {
                    continue;
                }

                var guiVertex2  = CameraUtility.WorldToGUIPoint(worldVertex3);
                var guiDistance = (guiVertex2 - snapData.guiPoint).sqrMagnitude * EdgeFudgeFactor;
                if (guiDistance + MathConstants.DistanceEpsilon >= snapData.closestDistanceSqr)
                {
                    continue;
                }

                snapData.closestDistanceSqr = guiDistance;
                snapData.outEdge            = new List <Vector3>()
                {
                    worldVertex1, worldVertex2
                };
                snapData.snappedWorldPoint = worldVertex3;
            }
        }
示例#3
0
        public static bool SnapToVertices(CSGBrush brush, CSGPlane?snapPlane, Vector3 worldPosition, out List <Vector3> outEdgePoints,
                                          out Vector3 outPosition, float closestDistance = float.PositiveInfinity)
        {
            outPosition   = MathConstants.zeroVector3;
            outEdgePoints = null;

            if (!brush)
            {
                return(false);
            }

            var controlMesh = brush.ControlMesh;

            if (controlMesh == null)
            {
                return(false);
            }

            Vector3?outPoint = null;

            // Find an edge to snap against the point we're interested in
            var guiPoint           = CameraUtility.WorldToGUIPoint(worldPosition);
            var closestDistanceSqr = closestDistance * closestDistance;

            /*
             * var points				= controlMesh.vertices;
             * var edges				= controlMesh.edges;
             * var polygons			= controlMesh.polygons;
             * var localToWorld		= brush.transform.localToWorldMatrix;
             * for(int p = 0; p < polygons.Length; p++)
             * {
             *      var edgeIndices				= polygons[p].edgeIndices;
             *      for (int e = 0; e < edgeIndices.Length; e++)
             *      {
             *              var edgeIndex			= edgeIndices[e];
             *              if (!edges[edgeIndex].hardEdge)
             *                      continue;
             *
             *              var twinIndex			= edges[edgeIndex].twinIndex;
             *
             *              var vertexIndex1		= edges[edgeIndex].vertexIndex;
             *              var vertexIndex2		= edges[twinIndex].vertexIndex;
             *
             *              var vertex1				= localToWorld.MultiplyPoint(points[vertexIndex1]);
             *              var vertex2				= localToWorld.MultiplyPoint(points[vertexIndex2]);
             *
             *              if (!snapPlane.HasValue ||
             *                      Mathf.Abs(snapPlane.Value.Distance(vertex1)) < Constants.DistanceEpsilon)
             *              {
             *                      var guiVertex1		= (Vector3)CameraUtility.WorldToGUIPoint(vertex1);
             *                      var guiDistance		= (guiVertex1 - guiPoint).magnitude * VertexFudgeFactor;
             *                      if (guiDistance + Constants.DistanceEpsilon < closestDistance)
             *                      {
             *                              closestDistance = guiDistance;
             *                              outPoint		= vertex1;
             *                      }
             *              }
             *
             *              if (!snapPlane.HasValue ||
             *                      Mathf.Abs(snapPlane.Value.Distance(vertex2)) < Constants.DistanceEpsilon)
             *              {
             *                      var guiVertex2		= (Vector3)CameraUtility.WorldToGUIPoint(vertex2);
             *                      var guiDistance		= (guiVertex2 - guiPoint).magnitude * VertexFudgeFactor;
             *                      if (guiDistance + Constants.DistanceEpsilon < closestDistance)
             *                      {
             *                              closestDistance = guiDistance;
             *                              outPoint		= vertex2;
             *                      }
             *              }
             *      }
             * }*/

            var outline = BrushOutlineManager.GetBrushOutline(brush.brushNodeID);

            if (outline != null)
            {
                var localToWorld = brush.transform.localToWorldMatrix;
                var indices      = outline.visibleInnerLines;
                var vertices     = outline.vertices;
                if (indices != null && vertices != null)
                {
                    for (int i = 0; i < indices.Length; i += 2)
                    {
                        var index1  = indices[i + 0];
                        var index2  = indices[i + 1];
                        var vertex1 = localToWorld.MultiplyPoint(vertices[index1]);
                        var vertex2 = localToWorld.MultiplyPoint(vertices[index2]);

                        if (!snapPlane.HasValue ||
                            Mathf.Abs(snapPlane.Value.Distance(vertex1)) < MathConstants.DistanceEpsilon)
                        {
                            var guiVertex1  = CameraUtility.WorldToGUIPoint(vertex1);
                            var guiDistance = (guiVertex1 - guiPoint).sqrMagnitude * VertexFudgeFactor;
                            if (guiDistance + MathConstants.DistanceEpsilon < closestDistanceSqr)
                            {
                                closestDistanceSqr = guiDistance;
                                outPoint           = vertex1;
                                continue;
                            }
                        }

                        if (!snapPlane.HasValue ||
                            Mathf.Abs(snapPlane.Value.Distance(vertex2)) < MathConstants.DistanceEpsilon)
                        {
                            var guiVertex2  = CameraUtility.WorldToGUIPoint(vertex2);
                            var guiDistance = (guiVertex2 - guiPoint).sqrMagnitude * VertexFudgeFactor;
                            if (guiDistance + MathConstants.DistanceEpsilon < closestDistanceSqr)
                            {
                                closestDistanceSqr = guiDistance;
                                outPoint           = vertex2;
                                continue;
                            }
                        }
                    }
                }

                if ((RealtimeCSG.CSGSettings.VisibleHelperSurfaces & HelperSurfaceFlags.ShowCulledSurfaces) == HelperSurfaceFlags.ShowCulledSurfaces)
                {
                    indices  = outline.invisibleInnerLines;
                    vertices = outline.vertices;
                    if (indices != null && vertices != null)
                    {
                        for (int i = 0; i < indices.Length; i += 2)
                        {
                            var index1  = indices[i + 0];
                            var index2  = indices[i + 1];
                            var vertex1 = localToWorld.MultiplyPoint(vertices[index1]);
                            var vertex2 = localToWorld.MultiplyPoint(vertices[index2]);

                            if (!snapPlane.HasValue ||
                                Mathf.Abs(snapPlane.Value.Distance(vertex1)) < MathConstants.DistanceEpsilon)
                            {
                                var guiVertex1  = CameraUtility.WorldToGUIPoint(vertex1);
                                var guiDistance = (guiVertex1 - guiPoint).sqrMagnitude * VertexFudgeFactor;
                                if (guiDistance + MathConstants.DistanceEpsilon < closestDistanceSqr)
                                {
                                    closestDistanceSqr = guiDistance;
                                    outPoint           = vertex1;
                                }
                            }

                            if (!snapPlane.HasValue ||
                                Mathf.Abs(snapPlane.Value.Distance(vertex1)) < MathConstants.DistanceEpsilon)
                            {
                                var guiVertex2  = CameraUtility.WorldToGUIPoint(vertex2);
                                var guiDistance = (guiVertex2 - guiPoint).magnitude * VertexFudgeFactor;
                                if (guiDistance + MathConstants.DistanceEpsilon < closestDistanceSqr)
                                {
                                    closestDistanceSqr = guiDistance;
                                    outPoint           = vertex2;
                                }
                            }
                        }
                    }
                }
            }

            if (!outPoint.HasValue || float.IsInfinity(closestDistance))
            {
                return(false);
            }

            closestDistance = Mathf.Sqrt(closestDistanceSqr);
            outPosition     = outPoint.Value;
            outEdgePoints   = FindAllEdgesThatTouchPoint(brush, outPosition);
            return(true);
        }
示例#4
0
        public static bool SnapToEdge(Camera camera, CSGBrush brush, CSGPlane?_snapPlane, Vector3 _worldPoint, out List <Vector3> outEdgePoints,
                                      out Vector3 outPosition)                                          //, float _closestDistance = float.PositiveInfinity)
        {
            outPosition   = MathConstants.zeroVector3;
            outEdgePoints = null;

            if (!brush)
            {
                return(false);
            }

            var controlMesh = brush.ControlMesh;

            if (controlMesh == null || camera == null)
            {
                return(false);
            }

            var snapData = new SnapData
            {
                // Find an edge to snap against the point we're interested in
                worldPoint         = _worldPoint,
                guiPoint           = CameraUtility.WorldToGUIPoint(_worldPoint),
                closestDistance    = float.PositiveInfinity,
                closestDistanceSqr = float.PositiveInfinity,
                snapPlane          = _snapPlane,
                outEdge            = null,
                snappedWorldPoint  = MathConstants.PositiveInfinityVector3
            };

            var points       = controlMesh.Vertices;
            var edges        = controlMesh.Edges;
            var polygons     = controlMesh.Polygons;
            var localToWorld = brush.transform.localToWorldMatrix;

            if (_internal_snapEdgesUsed == null ||
                _internal_snapEdgesUsed.Length < edges.Length)
            {
                _internal_snapEdgesUsed = new bool[edges.Length];
                _internal_snapVertices  = new Vector3[edges.Length * 2];
            }
            Array.Clear(_internal_snapEdgesUsed, 0, _internal_snapEdgesUsed.Length);

            _internal_snapVertexCount = 0;
            for (int p = 0; p < polygons.Length; p++)
            {
                var edgeIndices = polygons[p].EdgeIndices;

                for (int e = 0; e < edgeIndices.Length; e++)
                {
                    var edgeIndex = edgeIndices[e];
                    if (!edges[edgeIndex].HardEdge)
                    {
                        continue;
                    }

                    if (_internal_snapEdgesUsed[edgeIndex])
                    {
                        continue;
                    }

                    var twin = controlMesh.GetTwinEdgeIndex(edgeIndex);
                    _internal_snapEdgesUsed[edgeIndex] = true;
                    _internal_snapEdgesUsed[twin]      = true;


                    var twinIndex    = edges[edgeIndex].TwinIndex;
                    var vertexIndex1 = edges[edgeIndex].VertexIndex;
                    var vertexIndex2 = edges[twinIndex].VertexIndex;

                    _internal_snapVertices[_internal_snapVertexCount + 0] = localToWorld.MultiplyPoint(points[vertexIndex1]);
                    _internal_snapVertices[_internal_snapVertexCount + 1] = localToWorld.MultiplyPoint(points[vertexIndex2]);

                    _internal_snapVertexCount += 2;
                }
            }

            if (_internal_snapVertexCount > 0)
            {
                SnapToLines(_internal_snapVertices, _internal_snapVertexCount, ref snapData);
            }

            var outline = BrushOutlineManager.GetBrushOutline(brush.brushNodeID);

            if (outline != null)
            {
                var vertices = outline.vertices;

                var indices = outline.visibleInnerLines;
                SnapToLines(indices, vertices, localToWorld, ref snapData);

                if ((RealtimeCSG.CSGSettings.VisibleHelperSurfaces & HelperSurfaceFlags.ShowCulledSurfaces) == HelperSurfaceFlags.ShowCulledSurfaces)
                {
                    indices = outline.invisibleInnerLines;
                    SnapToLines(indices, vertices, localToWorld, ref snapData);
                }
            }

            if (snapData.outEdge == null ||
                float.IsInfinity(snapData.closestDistanceSqr))
            {
                return(false);
            }

            snapData.closestDistance = Mathf.Sqrt(snapData.closestDistanceSqr);
            outEdgePoints            = snapData.outEdge;
            outPosition = snapData.snappedWorldPoint;
            return(true);
        }
示例#5
0
        public static Vector3 SnapToWorld(Camera camera, CSGPlane snapPlane, Vector3 unsnappedPosition, Vector3 snappedPosition, ref List <Vector3> snappingEdges, out CSGBrush snappedOnBrush, CSGBrush[] ignoreBrushes = null)
        {
            snappedOnBrush = null;

            test_points[0] = unsnappedPosition;
            test_points[1] = snappedPosition;
            worldIntersections.Clear();

            for (int i = 0; i < test_points.Length; i++)
            {
                var test_point2D = CameraUtility.WorldToGUIPoint(test_points[i]);
                LegacyBrushIntersection intersection;
                if (SceneQueryUtility.FindWorldIntersection(camera, test_point2D, out intersection))
                {
                    if (intersection.brush &&
                        intersection.brush.ControlMesh != null)
                    {
                        intersection.worldIntersection = GeometryUtility.ProjectPointOnPlane(snapPlane, intersection.worldIntersection);

                        worldIntersections.Add(intersection);
                    }
                }
            }

            var     old_difference           = snappedPosition - unsnappedPosition;
            var     old_difference_magnitude = old_difference.magnitude * 1.5f;
            Vector3 newSnappedPoint          = snappedPosition;

            CSGPlane?snappingPlane = snapPlane;

            for (int i = 0; i < worldIntersections.Count; i++)
            {
                if (ignoreBrushes != null &&
                    ArrayUtility.Contains(ignoreBrushes, worldIntersections[i].brush))
                {
                    continue;
                }

                List <Vector3> outEdgePoints;
                Vector3        outPosition;
                if (GridUtility.SnapToVertices(worldIntersections[i].brush,
                                               snappingPlane, unsnappedPosition,
                                               out outEdgePoints,
                                               out outPosition))
                {
                    var new_difference           = outPosition - unsnappedPosition;
                    var new_difference_magnitude = new_difference.magnitude;

                    if (new_difference_magnitude <= old_difference_magnitude + MathConstants.EqualityEpsilon)
                    {
                        old_difference_magnitude = new_difference_magnitude;
                        newSnappedPoint          = outPosition;
                        snappingEdges            = outEdgePoints;
                        snappedOnBrush           = worldIntersections[i].brush;
                    }
                }
                if (GridUtility.SnapToEdge(camera,
                                           worldIntersections[i].brush, snappingPlane ?? worldIntersections[i].worldPlane,
                                           worldIntersections[i].worldIntersection,
                                           out outEdgePoints,
                                           out outPosition))
                {
                    var new_difference           = outPosition - unsnappedPosition;
                    var new_difference_magnitude = new_difference.magnitude * 1.1f;

                    if (new_difference_magnitude <= old_difference_magnitude + MathConstants.EqualityEpsilon)
                    {
                        old_difference_magnitude = new_difference_magnitude;
                        newSnappedPoint          = outPosition;
                        snappingEdges            = outEdgePoints;
                        snappedOnBrush           = worldIntersections[i].brush;
                    }
                }
            }

            //snappingEdges = FindAllEdgesThatTouchPoint(snappedOnBrush, newSnappedPoint);
            return(newSnappedPoint);
        }