private static void CalculateAngles(Vector3 anglePosition, Vector3 guideDirection, Vector3 incomingDirection, ICollection<Measurement> measurements) { guideDirection = guideDirection.Flatten().normalized; incomingDirection = incomingDirection.Flatten().normalized; var angleSize = Vector3.Angle(guideDirection, incomingDirection); var angleDirection = Vector3.Normalize(guideDirection + incomingDirection); var otherAngleSize = 180f - angleSize; var otherAngleDirection = Vector3.Normalize(-guideDirection + incomingDirection); if (otherAngleSize < angleSize) { Util.Swap(ref angleSize, ref otherAngleSize); Util.Swap(ref angleDirection, ref otherAngleDirection); } measurements.Add(new AngleMeasurement(angleSize, anglePosition, angleDirection, MeasurementFlags.Primary | MeasurementFlags.Guide)); if (Mathf.Abs(angleSize - 180f) < 0.5f || Mathf.Abs(otherAngleSize - 180f) < 0.5f) { return; } measurements.Add(new AngleMeasurement(otherAngleSize, anglePosition, otherAngleDirection, MeasurementFlags.Secondary | MeasurementFlags.Guide)); }
private static void TestLine(NetInfo netInfo, Vector3 startPoint, Vector3 endPoint, Vector3 l1, Vector3 l2, IList<GuideLine> lines, ushort segmentId = 0, ushort nodeId = 0) { var p = Util.LineIntersectionPoint(startPoint.xz(), endPoint.xz(), l1.xz(), l2.xz()); // Lines never meet, discard if (!p.HasValue) { return; } var intersect = new Vector3(p.Value.x, 0, p.Value.y); var intersectDistanceSqr = Vector3Extensions.DistanceSquared(intersect, endPoint.Flatten()); // Discard if intersect is silly distance away if (intersectDistanceSqr > Settings.MaxGuideLineQueryDistanceSqr) { return; } var guideDirection = l1.Flatten().DirectionTo(l2.Flatten()); var intersectDirection = l1.Flatten().DirectionTo(intersect); // Ignore guides in the wrong direction if (Mathf.Abs(Vector3Extensions.GetSignedAngleBetween(guideDirection, intersectDirection, Vector3.up)) > 90f) { return; } intersect.y = TerrainManager.instance.SampleRawHeightSmooth(intersect); var intersectDistance = Mathf.Sqrt(intersectDistanceSqr); var line = new GuideLine(l1, intersect, netInfo.m_halfWidth*2f, intersectDistance, segmentId); int index; if (IsDuplicate(lines, line, out index)) { var d = lines[index]; // If a duplicate, check if it is closer than the duplicate if (Vector3Extensions.DistanceSquared(d.Origin, endPoint) > Vector3Extensions.DistanceSquared(l1, endPoint)) { lines[index] = line; } return; } // Check for intersection with existing nodes var ra = Vector3.Cross(guideDirection, Vector3.up); var quad = new Quad3(l1 + ra, l1 - ra, intersect + ra, intersect - ra); if (NetManager.instance.OverlapQuad(Quad2.XZ(quad), 0, 1280f, ItemClass.CollisionType.Undefined, netInfo.m_class.m_layer, nodeId, 0, segmentId)) { return; } lines.Add(line); }
private static bool CanNodeBranchInDirection(ushort nodeId, Vector3 direction) { var closestSegmentId = NetNodeUtility.GetClosestSegmentId(nodeId, direction); var exitDirection = NetNodeUtility.GetSegmentExitDirection(nodeId, closestSegmentId); var exitAngle = Vector3Extensions.GetSignedAngleBetween(direction.Flatten(), exitDirection.Flatten(), Vector3.up); return Mathf.Abs(exitAngle) >= 45f; }