public void PlaceLeft() { TrackSection section = null; if (trackLayer.CurrentSection != null) { section = trackLayer.PlaceTrack(length, -angle); } else { RaycastHit hit; if (FirstPersonController.Main.RaycastCameraForward(out hit, 1000.0f, terrainMask)) { section = trackLayer.StartTrack(hit.point + Vector3.up * 0.01f, GetNewTrackRotation(hit), length, -angle); } } if (section != null) { TrackFactory.Instance.PlaceAndRegisterSection(section, true); DeselectIfConnected(); } }
private bool TryPlaceTrack(TrackSection from, bool fromEnd, TrackSection to, bool toEnd) { Vector3 intersection; fromPoint = fromEnd ? from.EndPosition : from.Position; toPoint = toEnd ? to.EndPosition : to.Position; fromRotation = fromEnd ? from.EndRotation : Helper.InvertTrackRotation(from.Rotation); // Note that this is pointing towards the section being build toRotation = toEnd ? to.EndRotation : Helper.InvertTrackRotation(to.Rotation); if (Helper.LineLineIntersection(out intersection, fromPoint, fromRotation * Vector3.forward, toPoint, toRotation * Vector3.forward)) { float d1, d2, shortestDistance; d1 = shortestDistance = Vector3.Distance(intersection, fromPoint); d2 = Vector3.Distance(intersection, toPoint); if (d2 < shortestDistance) { shortestDistance = d2; } // Calculate curvature float curve = 180.0f - Quaternion.Angle(fromRotation, toRotation); // Check if the curve should go left or right var cross = Vector3.Cross(fromRotation * Vector3.forward, (toPoint - fromPoint)); if (cross.y < 0) { // Go left curve = -curve; } // Calculate straight length var straightLength = Mathf.Max(d1, d2) - shortestDistance; trackLayer.Reposition(from, !fromEnd); if (d1 == d2) { // Place only curve trackLayer.PlaceTrack(CalculateCurveLength(curve, 0, 0), curve); TrackFactory.Instance.PlaceAndRegisterSection(trackLayer.CurrentSection, true); } else if (shortestDistance == d1) { // Place curve first, then straight trackLayer.PlaceTrack(CalculateCurveLength(curve, 0, straightLength), curve); TrackFactory.Instance.PlaceAndRegisterSection(trackLayer.CurrentSection); trackLayer.PlaceTrack(straightLength); TrackFactory.Instance.PlaceAndRegisterSection(trackLayer.CurrentSection, true); } else if (shortestDistance == d2) { // Place straight first, then curve trackLayer.PlaceTrack(straightLength); TrackFactory.Instance.PlaceAndRegisterSection(trackLayer.CurrentSection); trackLayer.PlaceTrack(CalculateCurveLength(curve, straightLength, 0), curve); TrackFactory.Instance.PlaceAndRegisterSection(trackLayer.CurrentSection, true); } trackLayer.Reposition(null, false); return(true); } // TODO: Add in-line check else if (Quaternion.Angle(fromRotation, Helper.InvertTrackRotation(toRotation)) < 0.5f) { trackLayer.Reposition(fromSection, !fromEnd); trackLayer.PlaceTrack(Vector3.Distance(fromPoint, toPoint)); TrackFactory.Instance.PlaceAndRegisterSection(trackLayer.CurrentSection, true); return(true); } return(false); }