/// <summary> /// unfinished! /// </summary> /// <param name="track"></param> /// <param name="selectedPoint"></param> public static void AddTwist(TrackBuildRTrack track, int selectedPoint) { TrackBuildRPoint atPoint = track[selectedPoint]; TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1); float twistDistance = Mathf.Min((lastPoint.arcLength + atPoint.arcLength) * 0.333f, track.maxJumpLength); Vector3 twistDirection = atPoint.trackDirection; Vector3 twistMiddle = atPoint.worldPosition; Vector3 twistUp = atPoint.trackUp; Vector3 twistAxis = Vector3.Cross(twistDirection, twistUp); float twistRadius = track.twistRadius; Vector3 twistStartPosition = -twistDirection * (twistDistance * 0.33f); Vector3 twistEndPosition = twistDirection * (twistDistance * 0.33f); Vector3 twistCentreHeight = twistUp * twistRadius; Quaternion twistAngle = Quaternion.LookRotation(twistDirection, twistUp); Vector3 twistCenter = atPoint.worldPosition + Vector3.up * twistRadius; float controlPointLength = twistRadius / (Mathf.PI); int numberOfPoints = track.twistPoints; float arcPercent = 1.0f / numberOfPoints; TrackBuildRPoint[] loopPoints = new TrackBuildRPoint[numberOfPoints + 1]; for (int i = 0; i < numberOfPoints; i++) { float pointArcPercent = arcPercent * i; float radA = Mathf.PI * 2 * (pointArcPercent + 0.5f); Vector3 pointLoopPosition = twistAngle * ((new Vector3(Mathf.Sin(radA), Mathf.Cos(radA), 0)) * twistRadius); float smoothI = pointArcPercent * pointArcPercent * (3.0f - 2.0f * pointArcPercent); Vector3 lateral = Vector3.Lerp(twistStartPosition, twistEndPosition, pointArcPercent + (pointArcPercent - smoothI)); Vector3 pointPosition = (pointLoopPosition) + lateral; Vector3 pointDirection = Vector3.Cross(-pointLoopPosition, twistAxis).normalized; TrackBuildRPoint newTrackPoint = track.InsertPoint(selectedPoint + 1 + i); newTrackPoint.worldPosition = twistCenter + pointPosition; newTrackPoint.trackUpQ = Quaternion.LookRotation(-pointLoopPosition, pointDirection); newTrackPoint.forwardControlPoint = newTrackPoint.worldPosition + (pointDirection * controlPointLength); loopPoints[i] = newTrackPoint; } atPoint.worldPosition += twistStartPosition; atPoint.trackUpQ = Quaternion.LookRotation(Vector3.up, atPoint.trackDirection); atPoint.forwardControlPoint = atPoint.worldPosition + (twistDirection * controlPointLength) - twistAxis; loopPoints[6] = atPoint; // _trackBuildR.pointMode = TrackBuildR.pointModes.transform; for (int i = 0; i < numberOfPoints + 1; i++) { loopPoints[i].extrudeTrack = true; loopPoints[i].extrudeTrackBottom = true; loopPoints[i].extrudeLength = 0.5f; loopPoints[i].RecalculateStoredValues(); } }
public static void AddLoop(TrackBuildRTrack track, int selectedPointIndex) { TrackBuildRPoint atPoint = track[selectedPointIndex]; int atPointIndex = selectedPointIndex; float loopRadius = track.loopRadius; float trackWidth = atPoint.width; Vector3 trackDirection = atPoint.trackDirection.normalized; Vector3 trackUp = atPoint.trackUpQ * Vector3.forward; Vector3 trackCross = atPoint.trackCross; Vector3 entryPosition = atPoint.worldPosition + (trackCross * trackWidth * 0.6f); Vector3 loopAxis = Vector3.Cross(trackDirection, trackUp); Vector3 loopCenter = atPoint.worldPosition + Vector3.up * loopRadius; Quaternion loopAngle = Quaternion.FromToRotation(Vector3.right, trackDirection); float controlPointLength = loopRadius / (Mathf.PI); Vector3 controlPointLateral = -loopAxis; int numberOfPoints = 6; float arcPercent = 1.0f / numberOfPoints; TrackBuildRPoint[] loopPoints = new TrackBuildRPoint[7]; for (int i = 0; i < numberOfPoints; i++) { float pointArcPercent = arcPercent * i; TrackBuildRPoint newTrackPoint = track.InsertPoint(atPointIndex + 1); float rad = Mathf.PI * 2 * (pointArcPercent + 0.5f); Vector3 pointLoopPosition = loopAngle * ((new Vector3(Mathf.Sin(rad), Mathf.Cos(rad), 0)) * loopRadius); Vector3 lateral = Vector3.Lerp((trackCross * trackWidth * -0.6f), (trackCross * trackWidth * 0.6f), pointArcPercent); Vector3 pointPosition = (pointLoopPosition) + lateral; Vector3 pointDirection = Vector3.Cross(-pointLoopPosition, loopAxis).normalized; newTrackPoint.worldPosition = loopCenter + pointPosition; newTrackPoint.trackUpQ = Quaternion.LookRotation(-pointLoopPosition, pointDirection); newTrackPoint.forwardControlPoint = newTrackPoint.worldPosition + (pointDirection * controlPointLength) - controlPointLateral; loopPoints[i] = newTrackPoint; } atPoint.worldPosition = entryPosition; atPoint.trackUpQ = Quaternion.LookRotation(Vector3.up, atPoint.trackDirection); atPoint.forwardControlPoint = atPoint.worldPosition + (trackDirection * controlPointLength) + controlPointLateral; loopPoints[6] = atPoint; // _trackBuildR.pointMode = TrackBuildR.pointModes.transform; for (int i = 0; i < numberOfPoints + 1; i++) { loopPoints[i].extrudeTrack = true; loopPoints[i].extrudeTrackBottom = true; loopPoints[i].extrudeLength = 0.5f; loopPoints[i].RecalculateStoredValues(); } }
public static void AddJumpTwist(TrackBuildRTrack track, int selectedPoint) { TrackBuildRPoint atPoint = track[selectedPoint]; TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1); TrackBuildRPoint nextPoint = track.GetPoint(selectedPoint + 1); float trackPartDistance = lastPoint.arcLength + atPoint.arcLength; float jumpDistance = Mathf.Min(trackPartDistance * 0.333f, track.maxJumpLength); float trackWidth = atPoint.width * 0.5f; Vector3 startCross = atPoint.trackCross; Vector3 jumpDirection = atPoint.trackDirection; Vector3 jumpMiddle = atPoint.worldPosition; Quaternion atPointUpQ = atPoint.trackUpQ; Quaternion trackUpJump = Quaternion.AngleAxis(track.twistAngle, -jumpDirection); Quaternion trackCrossExit = trackUpJump * (atPointUpQ); Quaternion trackCrossEntry = Quaternion.Inverse(trackUpJump) * (atPointUpQ); Vector3 jumpLateral = startCross * track.twistAngle / 33.3f; Vector3 jumpHeight = atPointUpQ * (Vector3.forward * track.jumpHeight); Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f) + jumpHeight - jumpLateral; Vector3 jumpEndPosition = jumpMiddle + jumpDirection * (jumpDistance * 0.33f) + jumpHeight + jumpLateral; lastPoint.extrudeTrack = true; lastPoint.extrudeLength = track.jumpHeight; lastPoint.extrudeCurveEnd = true; lastPoint.extrudeTrackBottom = true; atPoint.Reset(); atPoint.worldPosition = jumpStartPosition; atPoint.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpStartPosition + jumpHeight; atPoint.trackUpQ = trackCrossExit; atPoint.render = false; TrackBuildRPoint jumpEnd = track.InsertPoint(selectedPoint + 1); jumpEnd.worldPosition = jumpEndPosition; jumpEnd.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpEndPosition - jumpHeight; jumpEnd.trackUpQ = trackCrossEntry; jumpEnd.extrudeTrack = true; jumpEnd.extrudeLength = track.jumpHeight; jumpEnd.extrudeCurveEnd = true; jumpEnd.extrudeTrackBottom = true; atPoint.RecalculateStoredValues(); jumpEnd.RecalculateStoredValues(); }
public static void AddJump(TrackBuildRTrack track, int selectedPoint) { TrackBuildRPoint atPoint = track[selectedPoint]; TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1); TrackBuildRPoint nextPoint = track.GetPoint(selectedPoint + 1); float trackPartDistance = lastPoint.arcLength + atPoint.arcLength; float jumpDistance = Mathf.Min(trackPartDistance * 0.333f, track.maxJumpLength); Vector3 jumpDirection = atPoint.trackDirection; Vector3 jumpMiddle = atPoint.worldPosition; Vector3 startCross = atPoint.trackCross; float trackWidth = atPoint.width * 0.5f; Quaternion trackUp = atPoint.trackUpQ; Vector3 jumpHeight = trackUp * (Vector3.forward * track.jumpHeight); Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f); Vector3 jumpEndPosition = jumpMiddle + jumpDirection * (jumpDistance * 0.33f); lastPoint.extrudeTrack = true; lastPoint.extrudeLength = track.jumpHeight; lastPoint.extrudeCurveEnd = true; atPoint.Reset(); atPoint.worldPosition = jumpStartPosition + jumpHeight; atPoint.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpStartPosition + jumpHeight * 2; atPoint.trackUpQ = trackUp; atPoint.render = false; TrackBuildRPoint jumpEnd = track.InsertPoint(selectedPoint + 1); jumpEnd.worldPosition = jumpEndPosition + jumpHeight; jumpEnd.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpEndPosition; jumpEnd.trackUpQ = trackUp; jumpEnd.extrudeTrack = true; jumpEnd.extrudeLength = track.jumpHeight; jumpEnd.extrudeCurveEnd = true; atPoint.RecalculateStoredValues(); jumpEnd.RecalculateStoredValues(); }
public static void AddJump(TrackBuildRTrack track, int selectedPoint) { TrackBuildRPoint atPoint = track[selectedPoint]; TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1); // TrackBuildRPoint nextPoint = track.GetPoint(selectedPoint + 1); float trackPartDistance = lastPoint.arcLength + atPoint.arcLength; float jumpDistance = Mathf.Min(trackPartDistance * 0.333f, track.maxJumpLength); Vector3 jumpDirection = atPoint.trackDirection; Vector3 jumpMiddle = atPoint.worldPosition; // Vector3 startCross = atPoint.trackCross; // float trackWidth = atPoint.width * 0.5f; Quaternion trackUp = atPoint.trackUpQ; Vector3 jumpHeight = trackUp * (Vector3.forward * track.jumpHeight); Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f); Vector3 jumpEndPosition = jumpMiddle + jumpDirection * (jumpDistance * 0.33f); lastPoint.extrudeTrack = true; lastPoint.extrudeLength = track.jumpHeight; lastPoint.extrudeCurveEnd = true; atPoint.Reset(); atPoint.worldPosition = jumpStartPosition + jumpHeight; atPoint.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpStartPosition + jumpHeight * 2; atPoint.trackUpQ = trackUp; atPoint.render = false; TrackBuildRPoint jumpEnd = track.InsertPoint(selectedPoint + 1); jumpEnd.worldPosition = jumpEndPosition + jumpHeight; jumpEnd.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpEndPosition; jumpEnd.trackUpQ = trackUp; jumpEnd.extrudeTrack = true; jumpEnd.extrudeLength = track.jumpHeight; jumpEnd.extrudeCurveEnd = true; atPoint.RecalculateStoredValues(); jumpEnd.RecalculateStoredValues(); }
public static void AddJumpTwist(TrackBuildRTrack track, int selectedPoint) { TrackBuildRPoint atPoint = track[selectedPoint]; TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1); // TrackBuildRPoint nextPoint = track.GetPoint(selectedPoint + 1); float trackPartDistance = lastPoint.arcLength + atPoint.arcLength; float jumpDistance = Mathf.Min(trackPartDistance * 0.333f, track.maxJumpLength); // float trackWidth = atPoint.width * 0.5f; Vector3 startCross = atPoint.trackCross; Vector3 jumpDirection = atPoint.trackDirection; Vector3 jumpMiddle = atPoint.worldPosition; Quaternion atPointUpQ = atPoint.trackUpQ; Quaternion trackUpJump = Quaternion.AngleAxis(track.twistAngle, -jumpDirection); Quaternion trackCrossExit = trackUpJump * (atPointUpQ); Quaternion trackCrossEntry = Quaternion.Inverse(trackUpJump) * (atPointUpQ); Vector3 jumpLateral = startCross * track.twistAngle / 33.3f; Vector3 jumpHeight = atPointUpQ * (Vector3.forward * track.jumpHeight); Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f) + jumpHeight - jumpLateral; Vector3 jumpEndPosition = jumpMiddle + jumpDirection * (jumpDistance * 0.33f) + jumpHeight + jumpLateral; lastPoint.extrudeTrack = true; lastPoint.extrudeLength = track.jumpHeight; lastPoint.extrudeCurveEnd = true; lastPoint.extrudeTrackBottom = true; atPoint.Reset(); atPoint.worldPosition = jumpStartPosition; atPoint.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpStartPosition + jumpHeight; atPoint.trackUpQ = trackCrossExit; atPoint.render = false; TrackBuildRPoint jumpEnd = track.InsertPoint(selectedPoint + 1); jumpEnd.worldPosition = jumpEndPosition; jumpEnd.forwardControlPoint = jumpDirection * (jumpDistance * 0.5f) + jumpEndPosition - jumpHeight; jumpEnd.trackUpQ = trackCrossEntry; jumpEnd.extrudeTrack = true; jumpEnd.extrudeLength = track.jumpHeight; jumpEnd.extrudeCurveEnd = true; jumpEnd.extrudeTrackBottom = true; atPoint.RecalculateStoredValues(); jumpEnd.RecalculateStoredValues(); }
/// <summary> /// unfinished! /// </summary> /// <param name="track"></param> /// <param name="selectedPoint"></param> public static void AddTwist(TrackBuildRTrack track, int selectedPoint) { TrackBuildRPoint atPoint = track[selectedPoint]; TrackBuildRPoint lastPoint = track.GetPoint(selectedPoint - 1); float twistDistance = Mathf.Min((lastPoint.arcLength + atPoint.arcLength) * 0.333f, track.maxJumpLength); Vector3 twistDirection = atPoint.trackDirection; // Vector3 twistMiddle = atPoint.worldPosition; Vector3 twistUp = atPoint.trackUp; Vector3 twistAxis = Vector3.Cross(twistDirection, twistUp); float twistRadius = track.twistRadius; Vector3 twistStartPosition = -twistDirection * (twistDistance * 0.33f); Vector3 twistEndPosition = twistDirection * (twistDistance * 0.33f); // Vector3 twistCentreHeight = twistUp * twistRadius; Quaternion twistAngle = Quaternion.LookRotation(twistDirection, twistUp); Vector3 twistCenter = atPoint.worldPosition + Vector3.up * twistRadius; float controlPointLength = twistRadius / (Mathf.PI); int numberOfPoints = track.twistPoints; float arcPercent = 1.0f / numberOfPoints; TrackBuildRPoint[] loopPoints = new TrackBuildRPoint[numberOfPoints+1]; for (int i = 0; i < numberOfPoints; i++) { float pointArcPercent = arcPercent * i; float radA = Mathf.PI * 2 * (pointArcPercent + 0.5f); Vector3 pointLoopPosition = twistAngle * ((new Vector3(Mathf.Sin(radA), Mathf.Cos(radA), 0)) * twistRadius); float smoothI = pointArcPercent * pointArcPercent * (3.0f - 2.0f * pointArcPercent); Vector3 lateral = Vector3.Lerp(twistStartPosition, twistEndPosition, pointArcPercent + (pointArcPercent - smoothI)); Vector3 pointPosition = (pointLoopPosition) + lateral; Vector3 pointDirection = Vector3.Cross(-pointLoopPosition, twistAxis).normalized; TrackBuildRPoint newTrackPoint = track.InsertPoint(selectedPoint + 1 + i); newTrackPoint.worldPosition = twistCenter + pointPosition; newTrackPoint.trackUpQ = Quaternion.LookRotation(-pointLoopPosition, pointDirection); newTrackPoint.forwardControlPoint = newTrackPoint.worldPosition + (pointDirection * controlPointLength); loopPoints[i] = newTrackPoint; } atPoint.worldPosition += twistStartPosition; atPoint.trackUpQ = Quaternion.LookRotation(Vector3.up, atPoint.trackDirection); atPoint.forwardControlPoint = atPoint.worldPosition + (twistDirection * controlPointLength) - twistAxis; loopPoints[6] = atPoint; // _trackBuildR.pointMode = TrackBuildR.pointModes.transform; for (int i = 0; i < numberOfPoints + 1; i++) { loopPoints[i].extrudeTrack = true; loopPoints[i].extrudeTrackBottom = true; loopPoints[i].extrudeLength = 0.5f; loopPoints[i].RecalculateStoredValues(); } }
void OnSceneGUI() { if (_track.drawMode) { DrawTrack(); return; } if (SceneView.focusedWindow != null) { SceneView.focusedWindow.wantsMouseMove = false; } Vector3 position = _trackBuildR.transform.position; Camera sceneCamera = Camera.current; _handleSize = HandleUtility.GetHandleSize(_trackBuildR.transform.position) * 0.1f; int realNumberOfPoints = _track.realNumberOfPoints; Ray mouseRay = Camera.current.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); Quaternion mouseLookDirection = Quaternion.LookRotation(-mouseRay.direction); int numberOfCurves = _track.numberOfCurves; switch (_trackBuildR.mode) { case TrackBuildR.modes.track: Handles.color = TrackBuildRColours.GREEN; switch (_trackBuildR.pointMode) { case TrackBuildR.pointModes.add: if (SceneView.focusedWindow != null) { SceneView.focusedWindow.wantsMouseMove = true; } if (Event.current.type == EventType.MouseMove) { Repaint(); } Handles.color = TrackBuildRColours.GREY; for (int i = 0; i < _track.realNumberOfPoints; i++) { Vector3 pointPos = _track[i].worldPosition; float handleSize = HandleUtility.GetHandleSize(pointPos); Handles.DotCap(0, pointPos, Quaternion.identity, handleSize * 0.05f); } Handles.color = TrackBuildRColours.GREEN; float mousePercentage = NearestmMousePercentage(); // _track.GetNearestPoint(mousePlanePoint); Vector3 mouseTrackPoint = _track.GetTrackPosition(mousePercentage) + position; Handles.Label(mouseTrackPoint, "Add New Track Point"); float newPointHandleSize = HandleUtility.GetHandleSize(mouseTrackPoint) * HANDLE_SCALE; if (Handles.Button(mouseTrackPoint, mouseLookDirection, newPointHandleSize, newPointHandleSize, Handles.DotCap)) { int newPointIndex = _track.GetLastPointIndex(mousePercentage); TrackBuildRPoint newPoint = _track.InsertPoint(newPointIndex + 1); newPoint.worldPosition = mouseTrackPoint; newPoint.width = _track.GetTrackWidth(mousePercentage); newPoint.crownAngle = _track.GetTrackCrownAngle(mousePercentage); selectedPoint = newPointIndex + 1; GUI.changed = true; _trackBuildR.pointMode = TrackBuildR.pointModes.transform; } break; case TrackBuildR.pointModes.remove: if (SceneView.focusedWindow != null) { SceneView.focusedWindow.wantsMouseMove = true; } Handles.color = TrackBuildRColours.RED; for (int i = 0; i < realNumberOfPoints; i++) { TrackBuildRPoint point = _track[i]; float pointHandleSize = HandleUtility.GetHandleSize(point.worldPosition) * HANDLE_SCALE; Handles.Label(point.worldPosition, "Remove Track Point"); if (Handles.Button(point.worldPosition, mouseLookDirection, pointHandleSize, pointHandleSize, Handles.DotCap)) { _track.RemovePoint(point); GUI.changed = true; _trackBuildR.pointMode = TrackBuildR.pointModes.transform; } } break; default: SceneGUIPointBased(); break; } //draw track outline for (int i = 0; i < numberOfCurves; i++) { TrackBuildRPoint curve = _track[i]; if (curve == null) { continue; } int curvePoints = curve.storedPointSize; float dotPA = Vector3.Dot(sceneCamera.transform.forward, curve.worldPosition - sceneCamera.transform.position); float dotPB = Vector3.Dot(sceneCamera.transform.forward, curve.nextPoint.worldPosition - sceneCamera.transform.position); if (dotPA < 0 && dotPB < 0) { continue; } float curveDistance = Vector3.Distance(sceneCamera.transform.position, curve.center); int pointJump = Mathf.Max((int)(curveDistance / 20.0f), 1); Color trackOutline = curve.render ? TrackBuildRColours.GREEN : TrackBuildRColours.RED; Color trackOutlineA = trackOutline; trackOutlineA.a = 0.5f; for (int p = pointJump; p < curvePoints; p += pointJump) { int indexA = p - pointJump; int indexB = p; if (p + pointJump > curvePoints - 1) { indexB = curvePoints - 1; } Handles.color = trackOutlineA; Handles.DrawLine(curve.sampledPoints[indexA] + position, curve.sampledPoints[indexB] + position); Handles.color = trackOutline; Vector3 trackCrossWidth = curve.sampledTrackCrosses[indexA] * (curve.sampledWidths[indexA] * 0.5f); Handles.DrawLine(curve.sampledPoints[indexA] + trackCrossWidth + position, curve.sampledPoints[indexB] + trackCrossWidth + position); Handles.DrawLine(curve.sampledPoints[indexA] - trackCrossWidth + position, curve.sampledPoints[indexB] - trackCrossWidth + position); } } break; case TrackBuildR.modes.boundary: //draw boundary outline for (int i = 0; i < numberOfCurves; i++) { TrackBuildRPoint curve = _track[i]; int curvePoints = curve.storedPointSize; float dotPA = Vector3.Dot(sceneCamera.transform.forward, curve.worldPosition - sceneCamera.transform.position); float dotPB = Vector3.Dot(sceneCamera.transform.forward, curve.nextPoint.worldPosition - sceneCamera.transform.position); if (dotPA < 0 && dotPB < 0) { continue; } float curveDistance = Vector3.Distance(sceneCamera.transform.position, curve.center); int pointJump = Mathf.Max((int)(curveDistance / 20.0f), 1); for (int p = pointJump; p < curvePoints; p += pointJump) { int indexA = p - pointJump; int indexB = p; if (p + pointJump > curvePoints - 1) { indexB = curvePoints - 1; } if (_track.disconnectBoundary) { Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(curve.sampledLeftBoundaryPoints[indexA] + position, curve.sampledLeftBoundaryPoints[indexB] + position); Handles.color = TrackBuildRColours.RED; Handles.DrawLine(curve.sampledRightBoundaryPoints[indexA] + position, curve.sampledRightBoundaryPoints[indexB] + position); } else { Vector3 trackCrossWidth = curve.sampledTrackCrosses[indexA] * (curve.sampledWidths[indexA] * 0.5f); Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(curve.sampledPoints[indexA] + trackCrossWidth + position, curve.sampledPoints[indexB] + trackCrossWidth + position); Handles.color = TrackBuildRColours.RED; Handles.DrawLine(curve.sampledPoints[indexA] - trackCrossWidth + position, curve.sampledPoints[indexB] - trackCrossWidth + position); } } } SceneGUIPointBased(); break; case TrackBuildR.modes.textures: for (int i = 0; i < numberOfCurves; i++) { TrackBuildRPoint thisCurve = _track[i]; float pointHandleSize = HandleUtility.GetHandleSize(thisCurve.center) * HANDLE_SCALE; Handles.color = (i == selectedCurveIndex) ? TrackBuildRColours.RED : TrackBuildRColours.BLUE; if (Handles.Button(thisCurve.center, Quaternion.identity, pointHandleSize, pointHandleSize, Handles.DotCap)) { selectedCurveIndex = i; GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; GUI.changed = true; } } Handles.color = TrackBuildRColours.RED; TrackBuildRPoint selectedCurve = _track[selectedCurveIndex]; int numberOfSelectedCurvePoints = selectedCurve.storedPointSize; for (int i = 0; i < numberOfSelectedCurvePoints - 1; i++) { Vector3 leftPointA = selectedCurve.sampledLeftBoundaryPoints[i]; Vector3 leftPointB = selectedCurve.sampledLeftBoundaryPoints[i + 1]; Vector3 rightPointA = selectedCurve.sampledRightBoundaryPoints[i]; Vector3 rightPointB = selectedCurve.sampledRightBoundaryPoints[i + 1]; Handles.DrawLine(leftPointA, leftPointB); Handles.DrawLine(rightPointA, rightPointB); if (i == 0) { Handles.DrawLine(leftPointA, rightPointA); } if (i == numberOfSelectedCurvePoints - 2) { Handles.DrawLine(leftPointB, rightPointB); } } break; case TrackBuildR.modes.terrain: //nothing break; case TrackBuildR.modes.stunt: SceneGUIPointBased(); TrackBuildRPoint atPoint = _track[selectedPoint]; TrackBuildRPoint lastPoint = _track.GetPoint(selectedPoint - 1); TrackBuildRPoint nextPoint = _track.GetPoint(selectedPoint + 1); float trackWidth; Vector3 startCross; Vector3 p0, p1, p2, p3, p4, p5, p6, p7; switch (_trackBuildR.stuntMode) { case TrackBuildR.stuntModes.loop: atPoint = _track[selectedPoint]; trackWidth = atPoint.width; float loopRadius = _track.loopRadius; Vector3 loopPosition = atPoint.worldPosition; Vector3 trackDirection = atPoint.trackDirection.normalized; Vector3 trackup = atPoint.trackUpQ * Vector3.forward; Vector3 trackCross = atPoint.trackCross; Vector3 loopCentreHeight = loopRadius * trackup; Quaternion loopAngle = Quaternion.FromToRotation(Vector3.right, trackDirection); for (float i = 0; i < 0.99f; i += 0.01f) { float radA = Mathf.PI * 2 * (i + 0.5f); float radB = Mathf.PI * 2 * (i + 0.51f); Vector3 pointLoopPositionA = loopAngle * ((new Vector3(Mathf.Sin(radA), Mathf.Cos(radA), 0)) * loopRadius); Vector3 pointLoopPositionB = loopAngle * ((new Vector3(Mathf.Sin(radB), Mathf.Cos(radB), 0)) * loopRadius); Vector3 lateral = Vector3.Lerp((trackCross * trackWidth * -0.6f), (trackCross * trackWidth * 0.6f), i); Vector3 pointPositionA = (pointLoopPositionA) + lateral + loopPosition + loopCentreHeight; Vector3 pointPositionB = (pointLoopPositionB) + lateral + loopPosition + loopCentreHeight; Handles.DrawLine(pointPositionA, pointPositionB); } break; case TrackBuildR.stuntModes.jump: atPoint = _track[selectedPoint]; lastPoint = _track.GetPoint(selectedPoint - 1); nextPoint = _track.GetPoint(selectedPoint + 1); float trackPartDistance = lastPoint.arcLength + atPoint.arcLength; float jumpDistance = Mathf.Min(trackPartDistance * 0.333f, _track.maxJumpLength); Vector3 jumpDirection = atPoint.trackDirection; Vector3 jumpMiddle = atPoint.worldPosition; startCross = atPoint.trackCross; trackWidth = atPoint.width * 0.5f; Quaternion trackUp = atPoint.trackUpQ; Vector3 jumpHeight = trackUp * (Vector3.forward * _track.jumpHeight); Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f); Vector3 jumpEndPosition = jumpMiddle + jumpDirection * (jumpDistance * 0.33f); p0 = lastPoint.worldPosition + trackWidth * startCross; p1 = lastPoint.worldPosition - trackWidth * startCross; p2 = jumpStartPosition + trackWidth * startCross + jumpHeight; p3 = jumpStartPosition - trackWidth * startCross + jumpHeight; p4 = jumpEndPosition + trackWidth * startCross + jumpHeight; p5 = jumpEndPosition - trackWidth * startCross + jumpHeight; p6 = nextPoint.worldPosition + trackWidth * startCross; p7 = nextPoint.worldPosition - trackWidth * startCross; Handles.DrawLine(p0, p2); Handles.DrawLine(p1, p3); Handles.DrawLine(p0, p1); Handles.DrawLine(p2, p3); Handles.DrawLine(p2, p2 - jumpHeight); Handles.DrawLine(p3, p3 - jumpHeight); Handles.DrawLine(p0, p2 - jumpHeight); Handles.DrawLine(p1, p3 - jumpHeight); Handles.DrawLine(p4, p6); Handles.DrawLine(p5, p7); Handles.DrawLine(p4, p5); Handles.DrawLine(p6, p7); Handles.DrawLine(p4, p4 - jumpHeight); Handles.DrawLine(p5, p5 - jumpHeight); Handles.DrawLine(p6, p4 - jumpHeight); Handles.DrawLine(p7, p5 - jumpHeight); break; // case TrackBuildR.stuntModes.twist: // // atPoint = _track[selectedPoint]; // lastPoint = _track.GetPoint(selectedPoint - 1); // // float twistDistance = Mathf.Min((lastPoint.arcLength + atPoint.arcLength) * 0.333f, _track.maxJumpLength); // // Vector3 twistDirection = atPoint.trackDirection; // Vector3 twistMiddle = atPoint.worldPosition; // Vector3 twistUp = atPoint.trackUp; // float twistRadius = _track.twistRadius; // Vector3 twistStartPosition = twistMiddle - twistDirection * (twistDistance * 0.33f); // Vector3 twistEndPosition = twistMiddle + twistDirection * (twistDistance * 0.33f); // Vector3 twistCentreHeight = twistUp * twistRadius; // Quaternion twistAngle = Quaternion.LookRotation(twistDirection, twistUp); // for(float i = 0; i < 0.99f; i += 0.01f ) // { // float radA = Mathf.PI * 2 * (i+0.5f); // float radB = Mathf.PI * 2 * (i+0.51f); // Vector3 pointLoopPositionA = twistAngle * ((new Vector3(Mathf.Sin(radA), Mathf.Cos(radA), 0)) * twistRadius); // Vector3 pointLoopPositionB = twistAngle * ((new Vector3(Mathf.Sin(radB), Mathf.Cos(radB), 0)) * twistRadius); // float smoothI = i * i * (3.0f - 2.0f * i); // Vector3 lateral = Vector3.Lerp(twistStartPosition, twistEndPosition, i + (i-smoothI)); // Vector3 pointPositionA = (pointLoopPositionA) + lateral + twistCentreHeight; // Vector3 pointPositionB = (pointLoopPositionB) + lateral + twistCentreHeight; // Handles.DrawLine(pointPositionA, pointPositionB); // } // // break; case TrackBuildR.stuntModes.jumptwist: atPoint = _track[selectedPoint]; lastPoint = _track.GetPoint(selectedPoint - 1); nextPoint = _track.GetPoint(selectedPoint + 1); float trackTPartDistance = lastPoint.arcLength + atPoint.arcLength; float jumpTDistance = Mathf.Min(trackTPartDistance * 0.333f, _track.maxJumpLength); trackWidth = atPoint.width * 0.5f; startCross = atPoint.trackCross; Vector3 jumpTDirection = atPoint.trackDirection; Vector3 jumpTMiddle = atPoint.worldPosition; Quaternion atPointUpQ = atPoint.trackUpQ; Quaternion trackUpJump = Quaternion.AngleAxis(_track.twistAngle, -jumpTDirection); Vector3 trackCrossExit = trackUpJump * startCross; Vector3 trackCrossEntry = Quaternion.Inverse(trackUpJump) * startCross; Vector3 jumpLateral = startCross * _track.twistAngle / 33.3f; Vector3 jumpTHeight = atPointUpQ * (Vector3.forward * _track.jumpHeight); Vector3 jumpTStartPosition = jumpTMiddle - jumpTDirection * (jumpTDistance * 0.33f) + jumpTHeight - jumpLateral; Vector3 jumpTEndPosition = jumpTMiddle + jumpTDirection * (jumpTDistance * 0.33f) + jumpTHeight + jumpLateral; p0 = lastPoint.worldPosition + trackWidth * startCross; p1 = lastPoint.worldPosition - trackWidth * startCross; p2 = jumpTStartPosition + trackWidth * trackCrossExit; p3 = jumpTStartPosition - trackWidth * trackCrossExit; p4 = jumpTEndPosition + trackWidth * trackCrossEntry; p5 = jumpTEndPosition - trackWidth * trackCrossEntry; p6 = nextPoint.worldPosition + trackWidth * startCross; p7 = nextPoint.worldPosition - trackWidth * startCross; Handles.DrawLine(p0, p2); Handles.DrawLine(p1, p3); Handles.DrawLine(p0, p1); Handles.DrawLine(p2, p3); // Handles.DrawLine(p2, p2 - jumpTHeight); // Handles.DrawLine(p3, p3 - jumpTHeight); // Handles.DrawLine(p0, p2 - jumpTHeight); // Handles.DrawLine(p1, p3 - jumpTHeight); Handles.DrawLine(p4, p6); Handles.DrawLine(p5, p7); Handles.DrawLine(p4, p5); Handles.DrawLine(p6, p7); // Handles.DrawLine(p4, p4 - jumpTHeight); // Handles.DrawLine(p5, p5 - jumpTHeight); // Handles.DrawLine(p6, p4 - jumpTHeight); // Handles.DrawLine(p7, p5 - jumpTHeight); break; } break; case TrackBuildR.modes.diagram: if (SceneView.focusedWindow != null) { SceneView.focusedWindow.wantsMouseMove = true; } if (!_track.showDiagram) { break; } Plane diagramPlane = new Plane(Vector3.up, position); float diagramDistance; float crossSize = _handleSize * 10; switch (_trackBuildR.track.assignedPoints) { case 0: //display the diagram scale points Vector3 diagramPointA = _track.scalePointA; Vector3 diagramPointB = _track.scalePointB; if (diagramPointA != Vector3.zero || diagramPointB != Vector3.zero) { Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(diagramPointA, diagramPointA + Vector3.left * crossSize); Handles.DrawLine(diagramPointA, diagramPointA + Vector3.right * crossSize); Handles.DrawLine(diagramPointA, diagramPointA + Vector3.forward * crossSize); Handles.DrawLine(diagramPointA, diagramPointA + Vector3.back * crossSize); Handles.color = TrackBuildRColours.GREEN; Handles.DrawLine(diagramPointB, diagramPointB + Vector3.left * crossSize); Handles.DrawLine(diagramPointB, diagramPointB + Vector3.right * crossSize); Handles.DrawLine(diagramPointB, diagramPointB + Vector3.forward * crossSize); Handles.DrawLine(diagramPointB, diagramPointB + Vector3.back * crossSize); Handles.color = TrackBuildRColours.RED; Handles.DrawLine(diagramPointA, diagramPointB); } break; case 1: //place the first of two scale points to define the diagram scale size Ray diagramRay = Camera.current.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); if (diagramPlane.Raycast(diagramRay, out diagramDistance)) { Vector3 diagramPlanePoint = diagramRay.GetPoint(diagramDistance); Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.left * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.right * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.forward * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.back * crossSize); Handles.color = new Color(0, 0, 0, 0); if (Handles.Button(diagramPlanePoint, Quaternion.identity, crossSize, crossSize, Handles.DotCap)) { _track.scalePointA = diagramPlanePoint; _track.assignedPoints = 2; } } break; case 2: //place the second of two scale points to define the diagram scale Vector3 diagramPoint1 = _track.scalePointA; Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(diagramPoint1, diagramPoint1 + Vector3.left * crossSize); Handles.DrawLine(diagramPoint1, diagramPoint1 + Vector3.right * crossSize); Handles.DrawLine(diagramPoint1, diagramPoint1 + Vector3.forward * crossSize); Handles.DrawLine(diagramPoint1, diagramPoint1 + Vector3.back * crossSize); Ray diagramRayB = Camera.current.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); if (diagramPlane.Raycast(diagramRayB, out diagramDistance)) { Vector3 diagramPlanePoint = diagramRayB.GetPoint(diagramDistance); Handles.color = TrackBuildRColours.RED; Handles.DrawLine(diagramPlanePoint, diagramPoint1); Handles.color = TrackBuildRColours.GREEN; Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.left * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.right * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.forward * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.back * crossSize); Handles.color = new Color(0, 0, 0, 0); if (Handles.Button(diagramPlanePoint, Quaternion.identity, crossSize, crossSize, Handles.DotCap)) { _track.scalePointB = diagramPlanePoint; _track.assignedPoints = 0; //wUpdateDiagram(); } } break; } break; } if (Event.current.type == EventType.ValidateCommand) { switch (Event.current.commandName) { case "UndoRedoPerformed": // Debug.Log("UndoRedoPerformed"); _trackBuildR.ForceFullRecalculation(); GUI.changed = true; return; } } if (GUI.changed) { UpdateGui(); } }