Пример #1
0
        /// <summary>
        /// Calculates the angle of the first control point relative to compass north.
        /// </summary>
        private void CalculateCompassAngle(NetToolProxy netTool, IList <Measurement> measurements)
        {
            if (netTool.ControlPointsCount < 1)
            {
                return;
            }

            // Ignore if dragging from a node or segment
            if (netTool.ControlPoints[0].m_node != 0 || netTool.ControlPoints[0].m_segment != 0)
            {
                return;
            }

            var direction =
                netTool.ControlPoints[0].m_position.Flatten().DirectionTo(netTool.ControlPoints[1].m_position.Flatten());

            var north = Vector3.forward;

            var angleSize      = Vector3.Angle(north, direction);
            var angleDirection = Vector3.Normalize(north + direction);

            if (Mathf.Approximately(angleSize, 180f))
            {
                angleDirection = Vector3.right;
            }

            measurements.Add(new AngleMeasurement(angleSize, netTool.ControlPoints[0].m_position, angleDirection,
                                                  MeasurementFlags.Snap));
        }
Пример #2
0
        /// <summary>
        /// If there are 3 control points, calculates the angle between the three points
        /// </summary>
        private static void CalculateControlPointAngle(NetToolProxy netTool, ICollection <Measurement> measurements)
        {
            if (netTool.ControlPointsCount != 2)
            {
                return;
            }

            var p1 = netTool.ControlPoints[0];
            var p2 = netTool.ControlPoints[1];
            var p3 = netTool.ControlPoints[2];

            var d1 = Vector3.Normalize(p1.m_position.Flatten() - p2.m_position.Flatten());
            var d2 = Vector3.Normalize(p3.m_position.Flatten() - p2.m_position.Flatten());

            var angle          = Vector3.Angle(d1, d2);
            var angleDirection = Vector3.Normalize(d1 + d2);

            // 180deg angle special case
            if (angleDirection.sqrMagnitude < 0.5f)
            {
                angleDirection = Vector3.Cross(d1, Vector3.up);
            }

            measurements.Add(new AngleMeasurement(angle, p2.m_position, angleDirection,
                                                  MeasurementFlags.Primary | MeasurementFlags.Blueprint));
        }
Пример #3
0
        public void Update(NetToolProxy netTool)
        {
            _measurements.Clear();
            DebugState = "";

            if (!netTool.IsEnabled || netTool.Mode == NetTool.Mode.Upgrade)
            {
                return;
            }

            Segment.CalculateSegmentBranchAngles(netTool, _measurements);
            Segment.CalculateJoinAngles(netTool, _measurements);
            Node.CalculateBranchAngles(netTool, _measurements);
            Node.CalculateJoinAngles(netTool, _measurements);
            Guides.CalculateGuideLineAngle(netTool, _measurements);
            Guides.CalculateGuideLineDistance(netTool, _measurements);

            CalculateNearbySegments(netTool, _measurements);

            CalculateControlPointDistances(netTool, _measurements);
            CalculateControlPointAngle(netTool, _measurements);

            CalculateControlPointElevation(netTool, _measurements);
            CalculateCompassAngle(netTool, _measurements);
        }
        public void Update(NetToolProxy netTool)
        {
            _measurements.Clear();
            DebugState = "";

            if (!netTool.IsEnabled || netTool.Mode == NetTool.Mode.Upgrade)
            {
                return;
            }

            Segment.CalculateSegmentBranchAngles(netTool, _measurements);
            Segment.CalculateJoinAngles(netTool, _measurements);
            Node.CalculateBranchAngles(netTool, _measurements);
            Node.CalculateJoinAngles(netTool, _measurements);
            Guides.CalculateGuideLineAngle(netTool, _measurements);
            Guides.CalculateGuideLineDistance(netTool, _measurements);

            CalculateNearbySegments(netTool, _measurements);

            CalculateControlPointDistances(netTool, _measurements);
            CalculateControlPointAngle(netTool, _measurements);

            CalculateControlPointElevation(netTool, _measurements);
            CalculateCompassAngle(netTool, _measurements);
        }
        /// <summary>
        /// If there are 3 control points, calculates the angle between the three points
        /// </summary>
        private static void CalculateControlPointAngle(NetToolProxy netTool, ICollection<Measurement> measurements)
        {
            if (netTool.ControlPointsCount != 2)
            {
                return;
            }

            var p1 = netTool.ControlPoints[0];
            var p2 = netTool.ControlPoints[1];
            var p3 = netTool.ControlPoints[2];

            var d1 = Vector3.Normalize(p1.m_position.Flatten() - p2.m_position.Flatten());
            var d2 = Vector3.Normalize(p3.m_position.Flatten() - p2.m_position.Flatten());

            var angle = Vector3.Angle(d1, d2);
            var angleDirection = Vector3.Normalize(d1 + d2);

            // 180deg angle special case
            if (angleDirection.sqrMagnitude < 0.5f)
            {
                angleDirection = Vector3.Cross(d1, Vector3.up);
            }

            measurements.Add(new AngleMeasurement(angle, p2.m_position, angleDirection,
                MeasurementFlags.Primary | MeasurementFlags.Blueprint));
        }
Пример #6
0
        /// <summary>
        /// Attempt to locate the NetTool and create a NetToolProxy object if successful.
        /// </summary>
        /// <returns>A <c>NetToolProxy</c> object if successful, otherwise null.</returns>
        public static NetToolProxy Locate()
        {
            var toolType = typeof(NetTool);

            // Hack to include FineRoadHeights. If more mods start replacing the NetTool
            // it might be wise to implement an interface system like in Road Protractor
            if (AppDomain.CurrentDomain.GetAssemblies().Any(q => q.FullName.Contains("FineRoadHeights")))
            {
                toolType = Type.GetType("NetToolFine, FineRoadHeights") ?? toolType;
            }

            Debug.Log($"Looking for NetTool of type `{toolType}`");

            var tools = Object.FindObjectsOfType(toolType).Cast <ToolBase>().ToList();

            if (tools.Count == 0 && toolType != typeof(NetTool))
            {
                Debug.Log($"Falling back to default NetTool");
                toolType = typeof(NetTool);
                tools    = Object.FindObjectsOfType(toolType).Cast <ToolBase>().ToList();
            }

            Debug.Log($"Found Tools ({tools.Count}): " + string.Join(", ", tools.Select(q => q.name + $" ({q.GetInstanceID()})").ToArray()));

            if (tools.Count == 0)
            {
                Debug.LogError("Could not find NetTool");
                return(null);
            }

            if (tools.Count > 1)
            {
                // The "First" NetTool created is the one we want, since it's the one Unity seems to use.
                Debug.Log($"Multiple NetTool instances found, using cache to filter to an already known one.");
                tools = tools.Where(p => Cache.Contains(p.GetInstanceID())).ToList();
            }

            if (tools.Count > 1)
            {
                Debug.LogWarning("Still more than 1 NetTool instance found. Using the last one in the hopes it's the right one...");
            }

            var tool = tools.LastOrDefault();

            if (tool == null)
            {
                Debug.LogError("Failed to find NetTool");
                return(null);
            }

            if (!Cache.Contains(tool.GetInstanceID()))
            {
                Cache.Add(tool.GetInstanceID());
            }

            return(NetToolProxy.Create(tool));
        }
Пример #7
0
        public static NetToolProxy Create(ToolBase target)
        {
            NetToolProxy p;

            try
            {
                p = new NetToolProxy(target);
                return(p);
            }
            catch (Exception e)
            {
                Debug.LogError(string.Format("Error acquiring NetToolProxy from object {0}", target));
                Debug.LogError(e.ToString());
            }

            return(null);
        }
Пример #8
0
        /// <summary>
        /// Calculates distances between control points in the NetTool.
        /// </summary>
        private static void CalculateControlPointDistances(NetToolProxy netTool, ICollection <Measurement> measurements)
        {
            if (netTool.ControlPointsCount < 1)
            {
                return;
            }

            for (var i = 1; i < netTool.ControlPointsCount + 1; i++)
            {
                var p1 = netTool.ControlPoints[i - 1].m_position;
                var p2 = netTool.ControlPoints[i].m_position;

                var dist = Vector3.Distance(p1.Flatten(), p2.Flatten());
                var pos  = Vector3Extensions.Average(p1, p2);

                measurements.Add(new DistanceMeasurement(dist, pos, true, p1, p2, MeasurementFlags.HideOverlay));
            }
        }
        /// <summary>
        /// Calculates distances between control points in the NetTool.
        /// </summary>
        private static void CalculateControlPointDistances(NetToolProxy netTool, ICollection<Measurement> measurements)
        {
            if (netTool.ControlPointsCount < 1)
            {
                return;
            }

            for (var i = 1; i < netTool.ControlPointsCount + 1; i++)
            {
                var p1 = netTool.ControlPoints[i - 1].m_position;
                var p2 = netTool.ControlPoints[i].m_position;

                var dist = Vector3.Distance(p1.Flatten(), p2.Flatten());
                var pos = Vector3Extensions.Average(p1, p2);

                measurements.Add(new DistanceMeasurement(dist, pos, true, p1, p2, MeasurementFlags.HideOverlay));
            }
        }
Пример #10
0
        /// <summary>
        /// Calculates the elevation of each control point. The last control point will be marked as primary, others as secondary.
        /// </summary>
        private void CalculateControlPointElevation(NetToolProxy netTool, IList <Measurement> measurements)
        {
            for (var i = 0; i <= netTool.ControlPointsCount; i++)
            {
                // Only display the last control point elevation as a primary measurement
                var flag = i == netTool.ControlPointsCount ? MeasurementFlags.Primary : MeasurementFlags.Secondary;

                var controlPoint = netTool.ControlPoints[i];

                var e = controlPoint.m_elevation;

                var botPos = controlPoint.m_position;
                var topPos = controlPoint.m_position - new Vector3(0, controlPoint.m_elevation, 0);

                measurements.Add(new DistanceMeasurement(e, Vector3Extensions.Average(botPos, topPos), true, botPos,
                                                         topPos,
                                                         MeasurementFlags.HideOverlay | MeasurementFlags.Height | flag));
            }
        }
Пример #11
0
        /// <summary>
        /// Adds a distance measurement from the last control point to the closest segment.
        /// </summary>
        private static void CalculateNearbySegments(NetToolProxy netTool, ICollection <Measurement> measurements)
        {
            if (netTool.ControlPointsCount == 0)
            {
                return;
            }

            if (netTool.NodePositions.m_size <= 1)
            {
                return;
            }

            if (SnapController.SnappedGuideLine.HasValue)
            {
                return;
            }

            var lastNode = netTool.NodePositions[netTool.NodePositions.m_size - 1];

            int count;

            NetUtil.GetClosestSegments(netTool.NetInfo, lastNode.m_position, _segments, out count);

            if (count == 0)
            {
                return;
            }

            var p1 = lastNode.m_position;

            var minDist = float.MaxValue;
            var p       = Vector3.zero;
            var found   = false;

            for (var i = 0; i < count; i++)
            {
                if (netTool.ControlPoints[0].m_segment > 0 && _segments[i] == netTool.ControlPoints[0].m_segment)
                {
                    continue;
                }

                var s = NetManager.instance.m_segments.m_buffer[_segments[i]];

                if (!NetUtil.AreSimilarClass(s.Info, netTool.NetInfo))
                {
                    continue;
                }

                var p2 = s.GetClosestPosition(p1);

                // Discard if closest segment position is too close to the source node
                if (Vector3.Distance(netTool.ControlPoints[0].m_position, p2) < Settings.MinimumDistanceMeasure)
                {
                    continue;
                }

                var closestPoint = Util.ClosestPointOnLineSegment(p1, p2, netTool.ControlPoints[0].m_position);

                // Discard if the line contains the start control point
                if (Vector3.Distance(closestPoint, netTool.ControlPoints[0].m_position) <
                    Settings.MinimumDistanceMeasure)
                {
                    continue;
                }

                var direction = p2 - p1;
                var dist      = direction.sqrMagnitude;
                direction.Normalize();

                if (dist < minDist)
                {
                    minDist = dist;
                    p       = p2;
                    found   = true;
                }
            }

            if (found && Mathf.Sqrt(minDist) > Settings.MinimumDistanceMeasure)
            {
                measurements.Add(new DistanceMeasurement(Vector3.Distance(p1, p), Vector3Extensions.Average(p1, p), true,
                                                         p1, p,
                                                         MeasurementFlags.Secondary));
            }
        }
        public static NetToolProxy Create(ToolBase target)
        {
            NetToolProxy p;

            try
            {
                p = new NetToolProxy(target);
                return p;
            }
            catch (Exception e)
            {
                Debug.LogError(string.Format("Error acquiring NetToolProxy from object {0}", target));
                Debug.LogError(e.ToString());
            }

            return null;
        }
        /// <summary>
        /// Calculates the angle of the first control point relative to compass north.
        /// </summary>
        private void CalculateCompassAngle(NetToolProxy netTool, IList<Measurement> measurements)
        {
            if (netTool.ControlPointsCount < 1)
            {
                return;
            }

            // Ignore if dragging from a node or segment
            if (netTool.ControlPoints[0].m_node != 0 || netTool.ControlPoints[0].m_segment != 0)
            {
                return;
            }

            var direction =
                netTool.ControlPoints[0].m_position.Flatten().DirectionTo(netTool.ControlPoints[1].m_position.Flatten());

            var north = Vector3.forward;

            var angleSize = Vector3.Angle(north, direction);
            var angleDirection = Vector3.Normalize(north + direction);

            if (Mathf.Approximately(angleSize, 180f))
            {
                angleDirection = Vector3.right;
            }

            measurements.Add(new AngleMeasurement(angleSize, netTool.ControlPoints[0].m_position, angleDirection,
                MeasurementFlags.Snap));
        }
        /// <summary>
        /// Calculates the elevation of each control point. The last control point will be marked as primary, others as secondary.
        /// </summary>
        private void CalculateControlPointElevation(NetToolProxy netTool, IList<Measurement> measurements)
        {
            for (var i = 0; i <= netTool.ControlPointsCount; i++)
            {
                // Only display the last control point elevation as a primary measurement
                var flag = i == netTool.ControlPointsCount ? MeasurementFlags.Primary : MeasurementFlags.Secondary;

                var controlPoint = netTool.ControlPoints[i];

                var e = controlPoint.m_elevation;

                var botPos = controlPoint.m_position;
                var topPos = controlPoint.m_position - new Vector3(0, controlPoint.m_elevation, 0);

                measurements.Add(new DistanceMeasurement(e, Vector3Extensions.Average(botPos, topPos), true, botPos,
                    topPos,
                    MeasurementFlags.HideOverlay | MeasurementFlags.Height | flag));
            }
        }
        /// <summary>
        /// Adds a distance measurement from the last control point to the closest segment.
        /// </summary>
        private static void CalculateNearbySegments(NetToolProxy netTool, ICollection<Measurement> measurements)
        {
            if (netTool.ControlPointsCount == 0)
            {
                return;
            }

            if (netTool.NodePositions.m_size <= 1)
            {
                return;
            }

            if (SnapController.SnappedGuideLine.HasValue)
            {
                return;
            }

            var lastNode = netTool.NodePositions[netTool.NodePositions.m_size - 1];

            int count;

            NetUtil.GetClosestSegments(netTool.NetInfo, lastNode.m_position, _segments, out count);

            if (count == 0)
            {
                return;
            }

            var p1 = lastNode.m_position;

            var minDist = float.MaxValue;
            var p = Vector3.zero;
            var found = false;

            for (var i = 0; i < count; i++)
            {
                if (netTool.ControlPoints[0].m_segment > 0 && _segments[i] == netTool.ControlPoints[0].m_segment)
                {
                    continue;
                }

                var s = NetManager.instance.m_segments.m_buffer[_segments[i]];

                if (!NetUtil.AreSimilarClass(s.Info, netTool.NetInfo))
                {
                    continue;
                }

                var p2 = s.GetClosestPosition(p1);

                // Discard if closest segment position is too close to the source node
                if (Vector3.Distance(netTool.ControlPoints[0].m_position, p2) < Settings.MinimumDistanceMeasure)
                {
                    continue;
                }

                var closestPoint = Util.ClosestPointOnLineSegment(p1, p2, netTool.ControlPoints[0].m_position);

                // Discard if the line contains the start control point
                if (Vector3.Distance(closestPoint, netTool.ControlPoints[0].m_position) <
                    Settings.MinimumDistanceMeasure)
                {
                    continue;
                }

                var direction = p2 - p1;
                var dist = direction.sqrMagnitude;
                direction.Normalize();

                if (dist < minDist)
                {
                    minDist = dist;
                    p = p2;
                    found = true;
                }
            }

            if (found && Mathf.Sqrt(minDist) > Settings.MinimumDistanceMeasure)
            {
                measurements.Add(new DistanceMeasurement(Vector3.Distance(p1, p), Vector3Extensions.Average(p1, p), true,
                    p1, p,
                    MeasurementFlags.Secondary));
            }
        }