public void RestartExperience(NSObject sender) { if (!RestartExperienceButton.Enabled || IsLoadingObject) { return; } RestartExperienceButton.Enabled = false; UserFeedback.CancelAllScheduledMessages(); UserFeedback.DismissPresentedAlert(); UserFeedback.ShowMessage("STARTING A NEW SESSION"); virtualObjectManager.RemoveAllVirtualObjects(); AddObjectButton.SetImage(UIImage.FromBundle("add"), UIControlState.Normal); AddObjectButton.SetImage(UIImage.FromBundle("addPressed"), UIControlState.Highlighted); if (FocusSquare != null) { FocusSquare.Hidden = true; } ResetTracking(); RestartExperienceButton.SetImage(UIImage.FromBundle("restart"), UIControlState.Normal); // Disable Restart button for a second in order to give the session enough time to restart. var when = new DispatchTime(DispatchTime.Now, new TimeSpan(0, 0, 1)); DispatchQueue.MainQueue.DispatchAfter(when, () => SetupFocusSquare()); }
public override int GetHashCode() { int hash = 1; if (scheduleTime_ != null) { hash ^= ScheduleTime.GetHashCode(); } if (dispatchTime_ != null) { hash ^= DispatchTime.GetHashCode(); } if (responseTime_ != null) { hash ^= ResponseTime.GetHashCode(); } if (responseStatus_ != null) { hash ^= ResponseStatus.GetHashCode(); } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { // Set the slide's title TextManager.SetTitle ("Labs"); // Add two labs var lab1TitleNode = Utils.SCBoxNode ("Scene Kit Lab", new CGRect (-375, -35, 750, 70), NSColor.FromCalibratedWhite (0.15f, 1.0f), 0.0f, false); lab1TitleNode.Scale = new SCNVector3 (0.02f, 0.02f, 0.02f); lab1TitleNode.Position = new SCNVector3 (-2.8f, 30.7f, 10.0f); lab1TitleNode.Rotation = new SCNVector4 (1, 0, 0, (float)(Math.PI)); lab1TitleNode.Opacity = 0.0f; var lab2TitleNode = (SCNNode)lab1TitleNode.Copy (); lab2TitleNode.Position = new SCNVector3 (-2.8f, 29.2f, 10.0f); ContentNode.AddChildNode (lab1TitleNode); ContentNode.AddChildNode (lab2TitleNode); var lab1InfoNode = AddLabInfoNode ("\nGraphics and Games Lab A\nTuesday 4:00PM", 30.7f); var lab2InfoNode = AddLabInfoNode ("\nGraphics and Games Lab A\nWednesday 9:00AM", 29.2f); var delayInSeconds = 0.75; var popTime = new DispatchTime (DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; lab1TitleNode.Opacity = lab2TitleNode.Opacity = 1.0f; lab1TitleNode.Rotation = lab2TitleNode.Rotation = new SCNVector4 (1, 0, 0, 0); lab1InfoNode.Opacity = lab2InfoNode.Opacity = 1.0f; lab1InfoNode.Rotation = lab2InfoNode.Rotation = new SCNVector4 (0, 1, 0, 0); SCNTransaction.Commit (); }); }
private void ShowResult(IList <Barcode> barcodes, Action completion) { DispatchQueue.MainQueue.DispatchAsync(() => { var result = new ScanResult(barcodes); var alert = UIAlertController.Create("Scan Results", result.Text, UIAlertControllerStyle.Alert); alert.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, action => { DismissViewController(true, null); completion.Invoke(); })); this.PresentViewController(alert, true, () => { if (!SettingsManager.Instance.ContinuousModeEnabled) { return; } var delta = new TimeSpan(0, 0, 0, 0, ShownDurationInContinuousModeInMilliSecs); var dispatchTime = new DispatchTime(DispatchTime.Now, delta); DispatchQueue.MainQueue.DispatchAfter(dispatchTime, () => { this.DismissViewController(true, completion); }); }); }); }
public void ButtonFinished(ButtonView button, UIView trackingView, UITouch location) { double delayInSeconds; buttonDraggedToPad = false; miniPadView.Layer.BorderWidth = 0; CGPoint point = location.LocationInView(miniPadView); if (miniPadView.PointInside(point, null)) { UpdateScoreForDroppedButton(button); UIView.Animate(.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation(10f * (float)Math.PI / 180), async() => { await UIView.AnimateAsync(.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation(-10f * (float)Math.PI / 180)); await UIView.AnimateAsync(.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation(10f * (float)Math.PI / 180)); await UIView.AnimateAsync(.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation(-10f * (float)Math.PI / 180)); await UIView.AnimateAsync(.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation(0)); }); } delayInSeconds = 0.5; var popTime = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, async() => { await UIView.AnimateAsync(0.35f, () => { CGRect bounds = trackingView.Bounds; bounds.Size = new CGSize(10, 10); trackingView.Bounds = bounds; }); trackingView.RemoveFromSuperview(); }); }
public override void PresentStep (int index, PresentationViewController presentationViewController) { // Set the slide's title TextManager.SetTitle ("Labs"); // Add two labs var lab1TitleNode = Utils.SCBoxNode ("Scene Kit Lab", new CGRect (-375, -35, 750, 70), NSColor.FromCalibratedWhite (0.15f, 1.0f), 0.0f, false); lab1TitleNode.Scale = new SCNVector3 (0.02f, 0.02f, 0.02f); lab1TitleNode.Position = new SCNVector3 (-2.8f, 30.7f, 10.0f); lab1TitleNode.Rotation = new SCNVector4 (1, 0, 0, (float)(Math.PI)); lab1TitleNode.Opacity = 0.0f; var lab2TitleNode = (SCNNode)lab1TitleNode.Copy (); lab2TitleNode.Position = new SCNVector3 (-2.8f, 29.2f, 10.0f); ContentNode.AddChildNode (lab1TitleNode); ContentNode.AddChildNode (lab2TitleNode); var lab1InfoNode = AddLabInfoNode ("\nGraphics and Games Lab A\nTuesday 4:00PM", 30.7f); var lab2InfoNode = AddLabInfoNode ("\nGraphics and Games Lab A\nWednesday 9:00AM", 29.2f); var delayInSeconds = 0.75; var popTime = new DispatchTime (DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; lab1TitleNode.Opacity = lab2TitleNode.Opacity = 1.0f; lab1TitleNode.Rotation = lab2TitleNode.Rotation = new SCNVector4 (1, 0, 0, 0); lab1InfoNode.Opacity = lab2InfoNode.Opacity = 1.0f; lab1InfoNode.Rotation = lab2InfoNode.Rotation = new SCNVector4 (0, 1, 0, 0); SCNTransaction.Commit (); }); }
private void FailIfSimulator() { if (Runtime.Arch != Arch.SIMULATOR) { return; } Console.WriteLine("You will not be able to receive push notifications in the simulator."); if (NSUserDefaults.StandardUserDefaults.BoolForKey("ua-simulator-warning-disabled")) { return; } UIAlertController alertController = UIAlertController.Create(title: "Notice", message: "You will not be able " + "to receive push notifications in the simulator.", preferredStyle: UIAlertControllerStyle.Alert); UIAlertAction cancelAction = UIAlertAction.Create(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: null); alertController.AddAction(cancelAction); DispatchTime delay = new DispatchTime(DispatchTime.Now, 500000000); DispatchQueue.MainQueue.DispatchAfter(delay, () => { Window.RootViewController.PresentViewController(alertController, true, null); }); }
private void adjustOffsetForTransition() { var currentPage = this.CurrentPage; var popTime = new DispatchTime(DispatchTime.Now, (long)(NSEC_PER_SEC * 0.1) / NSEC_PER_SEC); DispatchQueue.MainQueue.DispatchAfter(popTime, () => GotoPage(currentPage)); }
public override void DidSelectPost() { string shortenedUrl = ""; try { foreach (NSItemProvider itemProvider in this.ExtensionContext.InputItems[0].Attachments) { if (itemProvider.HasItemConformingTo(MobileCoreServices.UTType.URL)) { itemProvider.LoadItem(MobileCoreServices.UTType.URL, null, async(item, error) => { if (item is NSUrl) { var urlToShorten = ((NSUrl)item).AbsoluteUrl.ToString(); var request = new ShortRequest { TagWt = false, TagUtm = false, Campaign = ContentText, Mediums = new List <string>() { "twitter" }, Input = urlToShorten }; var defaults = new NSUserDefaults(Constants.GroupName, NSUserDefaultsType.SuiteName); var url = defaults.StringForKey(Constants.IOS_SettingsKey); shortenedUrl = await ShorteningService.ShortenUrl(request, url); InvokeOnMainThread(() => { UIPasteboard clipboard = UIPasteboard.General; clipboard.String = shortenedUrl; UIAlertController alert = UIAlertController.Create("Share extension", $"https://{shortenedUrl} has been copied!", UIAlertControllerStyle.Alert); PresentViewController(alert, true, () => { var dt = new DispatchTime(DispatchTime.Now, TimeSpan.FromSeconds(1)); DispatchQueue.MainQueue.DispatchAfter(dt, () => { ExtensionContext.CompleteRequest(null, null); }); }); }); } }); } } } catch (Exception ex) { Console.WriteLine(ex); } }
void StartSingleVariantAsync(int paramIndex) { var afterTime = new DispatchTime(DispatchTime.Now, (long)250 * NSEC_PER_MILISEC); DispatchQueue.MainQueue.DispatchAfter(afterTime, () => { StartSingleVariant(paramIndex); }); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Skinning"); TextManager.AddBulletAtLevel("Animate characters", 0); TextManager.AddBulletAtLevel("Deform geometries with a skeleton", 0); TextManager.AddBulletAtLevel("Joints and bones", 0); // Animate the character CharacterNode.AddAnimation(IdleAnimationGroup, new NSString("idleAnimation")); // The character is hidden. Wait a little longer before showing it // otherwise it may slow down the transition from the previous slide var delayInSeconds = 1.5; var popTime = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; CharacterNode.Hidden = false; CharacterNode.Opacity = 0; SCNTransaction.Commit(); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.5; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn); CharacterNode.Opacity = 1; SCNTransaction.Commit(); }); break; case 1: SCNTransaction.AnimationDuration = 1.5f; //TODO SetShowsBones (true); break; case 2: CharacterNode.AddAnimation(AnimationGroup1, new NSString("animation")); break; case 3: SCNTransaction.AnimationDuration = 1.5f; //TODO SetShowsBones (false); break; case 4: CharacterNode.AddAnimation(AnimationGroup1, new NSString("animation")); break; } SCNTransaction.Commit(); }
void goForthZombies() { manageVisibleZombies(); statusView.Status = "Your program has started. The zombies are massing"; const double delayInSeconds = 2; var popTime = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, ZombiesOnATimer); }
public override void PresentStep (int index, PresentationViewController presentationViewController) { TextManager.SetTitle ("Creating a Scene"); TextManager.AddBulletAtLevel ("Creating programmatically", 0); TextManager.AddBulletAtLevel ("Loading a scene from a file", 0); var delayInSeconds = 1.0; var popTime = new DispatchTime (DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { TextManager.HighlightBullet (1); }); }
/// <summary> /// Some view controllers that inherit from BaseViewController have UI elements, e.g., close button, /// on the top in View stack that leads to it being read first by VO eventhough a UIAccessibility.PostNotification /// is being called to indicate another element that should be in focus. This can be addressed by removing the UIView /// that is read first to focus on the element that should be targeted by UIAccessibility.PostNotification call, and /// put it back into accessibility elements after a short delay (1 sec). /// </summary> /// <param name="uiViewToDisable">UIView to be removed from VoiceOver reading hierarchy</param> protected void PostAccessibilityNotificationAndReenableElement(UIView uiViewToDisable, UIView uiViewPostNotification) { if (UIAccessibility.IsVoiceOverRunning) { UIAccessibility.PostNotification(UIAccessibilityPostNotification.LayoutChanged, uiViewPostNotification); uiViewToDisable.IsAccessibilityElement = false; DispatchTime when = new DispatchTime(DispatchTime.Now, TimeSpan.FromSeconds(1)); DispatchQueue.MainQueue.DispatchAfter(when, () => { uiViewToDisable.IsAccessibilityElement = true; }); } }
public override void PresentStep (int index, PresentationViewController presentationViewController) { SCNTransaction.Begin (); switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle ("Skinning"); TextManager.AddBulletAtLevel ("Animate characters", 0); TextManager.AddBulletAtLevel ("Deform geometries with a skeleton", 0); TextManager.AddBulletAtLevel ("Joints and bones", 0); // Animate the character CharacterNode.AddAnimation (IdleAnimationGroup, new NSString ("idleAnimation")); // The character is hidden. Wait a little longer before showing it // otherwise it may slow down the transition from the previous slide var delayInSeconds = 1.5; var popTime = new DispatchTime (DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0; CharacterNode.Hidden = false; CharacterNode.Opacity = 0; SCNTransaction.Commit (); SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1.5; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName (CAMediaTimingFunction.EaseIn); CharacterNode.Opacity = 1; SCNTransaction.Commit (); }); break; case 1: SCNTransaction.AnimationDuration = 1.5f; //TODO SetShowsBones (true); break; case 2: CharacterNode.AddAnimation (AnimationGroup1, new NSString ("animation")); break; case 3: SCNTransaction.AnimationDuration = 1.5f; //TODO SetShowsBones (false); break; case 4: CharacterNode.AddAnimation (AnimationGroup1, new NSString ("animation")); break; } SCNTransaction.Commit (); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { TextManager.SetTitle("Creating a Scene"); TextManager.AddBulletAtLevel("Creating programmatically", 0); TextManager.AddBulletAtLevel("Loading a scene from a file", 0); var delayInSeconds = 1.0; var popTime = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { TextManager.HighlightBullet(1); }); }
public void NeverTooLate() { Assert.That(DispatchTime.Now.Nanoseconds, Is.EqualTo(0), "Now"); Assert.That(DispatchTime.Forever.Nanoseconds, Is.EqualTo(unchecked ((ulong)~0)), "Forever"); var dt = new DispatchTime(1); Assert.That(dt.Nanoseconds, Is.EqualTo(1), "1"); dt = new DispatchTime(DispatchTime.Now, 0); Assert.That(dt.Nanoseconds, Is.Not.EqualTo(0), "!0"); var dt2 = new DispatchTime(dt, Int32.MaxValue); Assert.That(dt2.Nanoseconds, Is.GreaterThan(dt.Nanoseconds), "later"); }
public void Start(Action <NSData, NSError> completionHandler) { this.completionHandler = completionHandler; downloadState.Queue = new DispatchQueue("download_queue"); downloadState.Queue.DispatchAsync(() => { try { var data = NSData.FromUrl(downloadURL); downloadState.DownloadTimer = new DispatchSource.Timer(downloadState.Queue); int downloadedBytes = 0; int randomMilliseconds = new Random().Next(0, 500); var delay = new DispatchTime(DispatchTime.Now, (long)(TimerInterval * NanosecondsPerSecond - randomMilliseconds * NanosecondsPerMillisecond)); downloadState.DownloadTimer.SetTimer(delay, (long)TimerInterval * NanosecondsPerSecond, 0); downloadState.DownloadTimer.SetEventHandler(() => { downloadedBytes += (int)(BatchSize * TimerInterval); if (downloadedBytes >= (int)data.Length) { downloadState.DownloadTimer.Cancel(); return; } DidDownloadData(downloadedBytes); }); downloadState.DownloadTimer.SetCancelHandler(() => { if (downloadedBytes >= (int)data.Length) { DidFinishDownload(data); } else { DidFailDownloadWithError(downloadState.DownloadError); } downloadState.DownloadTimer = null; }); WillBeginDownload((int)data.Length); downloadState.DownloadTimer.Resume(); } catch (Exception) { var error = new NSError(NSError.CocoaErrorDomain, 0, null); DidFailDownloadWithError(error); } }); }
bool TryLoadFirstBatch() { bool haveNoPost = PostCells.Count == 0 || lastPostSeenOnServer == null; if (haveNoPost) { // We dispatch it after two seconds to give the server time to index the new post // TODO: https://trello.com/c/cWWQXKYY var dispatchTime = new DispatchTime(DispatchTime.Now, 2 * 1000000000); DispatchQueue.MainQueue.DispatchAfter(dispatchTime, () => { // If we get here, we must have no posts. That must mean that last time we tried loading a batch nothing came through so we locked the method. Let's unlock it haveOldestPost = false; LoadBatch(); }); } return(haveNoPost); }
partial void SaveButton_TouchUpInside(UIButton sender) { var s = new NSUserDefaults(Constants.GroupName, NSUserDefaultsType.SuiteName); s.SetString(shortenedUrlLocation.Text, Constants.IOS_SettingsKey); s.Synchronize(); UIAlertController alert = UIAlertController.Create("Share extension", "Shortening URL has been saved!", UIAlertControllerStyle.Alert); PresentViewController(alert, true, () => { var dt = new DispatchTime(DispatchTime.Now, TimeSpan.FromSeconds(1)); DispatchQueue.MainQueue.DispatchAfter(dt, () => { alert.DismissViewController(true, null); }); }); }
public void OpenToast(string text) { var rootViewController = UIApplication.SharedApplication.KeyWindow.RootViewController; var alertController = UIAlertController.Create(string.Empty, text, UIAlertControllerStyle.Alert); alertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); rootViewController.PresentViewController(alertController, true, () => { var delayTime = new DispatchTime(DispatchTime.Now, 3000000000); DispatchQueue.MainQueue.DispatchAlert(delayTime, () => { alertController.DismissViewController(true, null); }); }); }
void ZombiesOnATimer() { if (paused) { return; } TimerEvent eventType = nextZombieEvent(); statusView.Status = StringForZombieEvent(eventType); meterView.ZombieLevel = meterView.ZombieLevel + ZombieFactorForEvent(eventType); MonitorZombiePressure(); manageVisibleZombies(); var popTime = new DispatchTime(DispatchTime.Now, (long)6 * NSEC_PER_SEC); DispatchQueue.MainQueue.DispatchAfter(popTime, ZombiesOnATimer); }
public void Start (Action<NSData, NSError> completionHandler) { this.completionHandler = completionHandler; downloadState.Queue = new DispatchQueue ("download_queue"); downloadState.Queue.DispatchAsync (() => { try { var data = NSData.FromUrl (downloadURL); downloadState.DownloadTimer = new DispatchSource.Timer (downloadState.Queue); int downloadedBytes = 0; int randomMilliseconds = new Random ().Next (0, 500); var delay = new DispatchTime (DispatchTime.Now, (long)(TimerInterval * NanosecondsPerSecond - randomMilliseconds * NanosecondsPerMillisecond)); downloadState.DownloadTimer.SetTimer (delay, (long)TimerInterval * NanosecondsPerSecond, 0); downloadState.DownloadTimer.SetEventHandler (() => { downloadedBytes += (int)(BatchSize * TimerInterval); if (downloadedBytes >= (int)data.Length) { downloadState.DownloadTimer.Cancel (); return; } DidDownloadData (downloadedBytes); }); downloadState.DownloadTimer.SetCancelHandler (() => { if (downloadedBytes >= (int)data.Length) DidFinishDownload (data); else DidFailDownloadWithError (downloadState.DownloadError); downloadState.DownloadTimer = null; }); WillBeginDownload ((int)data.Length); downloadState.DownloadTimer.Resume (); } catch (Exception) { var error = new NSError (NSError.CocoaErrorDomain, 0, null); DidFailDownloadWithError (error); } }); }
public void MergeFrom(Attempt other) { if (other == null) { return; } if (other.scheduleTime_ != null) { if (scheduleTime_ == null) { scheduleTime_ = new global::Google.Protobuf.WellKnownTypes.Timestamp(); } ScheduleTime.MergeFrom(other.ScheduleTime); } if (other.dispatchTime_ != null) { if (dispatchTime_ == null) { dispatchTime_ = new global::Google.Protobuf.WellKnownTypes.Timestamp(); } DispatchTime.MergeFrom(other.DispatchTime); } if (other.responseTime_ != null) { if (responseTime_ == null) { responseTime_ = new global::Google.Protobuf.WellKnownTypes.Timestamp(); } ResponseTime.MergeFrom(other.ResponseTime); } if (other.responseStatus_ != null) { if (responseStatus_ == null) { responseStatus_ = new global::Google.Rpc.Status(); } ResponseStatus.MergeFrom(other.ResponseStatus); } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); }
public override void PresentStep (int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle ("Constraints"); TextManager.SetSubtitle ("SCNConstraint"); TextManager.AddBulletAtLevel ("Applied sequentially at render time", 0); TextManager.AddBulletAtLevel ("Only affect presentation values", 0); TextManager.AddCode ("#aNode.#Constraints# = new SCNConstraint[] { aConstraint, anotherConstraint, ... };#"); // Tweak the near clipping plane of the spot light to get a precise shadow map presentationViewController.SpotLight.Light.SetAttribute (new NSNumber (10), SCNLightAttribute.ShadowNearClippingKey); break; case 1: // Remove previous text TextManager.FlipOutText (SlideTextManager.TextType.Subtitle); TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.FlipOutText (SlideTextManager.TextType.Code); // Add new text TextManager.SetSubtitle ("SCNLookAtConstraint"); TextManager.AddBulletAtLevel ("Makes a node to look at another node", 0); TextManager.AddCode ("#nodeA.Constraints = new SCNConstraint[] { #SCNLookAtConstraint.Create# (nodeB) };#"); TextManager.FlipInText (SlideTextManager.TextType.Subtitle); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Code); break; case 2: // Setup the scene SetupLookAtScene (); SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; // Dim the text and move back a little bit TextManager.TextNode.Opacity = 0.5f; presentationViewController.CameraHandle.Position = presentationViewController.CameraNode.ConvertPositionToNode (new SCNVector3 (0, 0, 5.0f), presentationViewController.CameraHandle.ParentNode); SCNTransaction.Commit (); break; case 3: // Add constraints to the arrows var container = ContentNode.FindChildNode ("arrowContainer", true); // "Look at" constraint var constraint = SCNLookAtConstraint.Create (BallNode); var i = 0; foreach (var arrow in container.ChildNodes) { var delayInSeconds = 0.1 * i++; var popTime = new DispatchTime (DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; // Animate to the result of applying the constraint ((SCNNode)arrow.ChildNodes [0]).Rotation = new SCNVector4 (0, 1, 0, (float)(Math.PI / 2)); arrow.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit (); }); } break; case 4: // Create a keyframe animation to move the ball var animation = CAKeyFrameAnimation.GetFromKeyPath ("position"); animation.KeyTimes = new NSNumber[] { 0.0f, (1.0f / 8.0f), (2.0f / 8.0f), (3.0f / 8.0f), (4.0f / 8.0f), (5.0f / 8.0f), (6.0f / 8.0f), (7.0f / 8.0f), 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector (new SCNVector3 (0, 0.0f, 0)), NSValue.FromVector (new SCNVector3 (20.0f, 0.0f, 20.0f)), NSValue.FromVector (new SCNVector3 (40.0f, 0.0f, 0)), NSValue.FromVector (new SCNVector3 (20.0f, 0.0f, -20.0f)), NSValue.FromVector (new SCNVector3 (0, 0.0f, 0)), NSValue.FromVector (new SCNVector3 (-20.0f, 0.0f, 20.0f)), NSValue.FromVector (new SCNVector3 (-40.0f, 0.0f, 0)), NSValue.FromVector (new SCNVector3 (-20.0f, 0.0f, -20.0f)), NSValue.FromVector (new SCNVector3 (0, 0.0f, 0)) }; animation.CalculationMode = CAKeyFrameAnimation.AnimationCubicPaced; // smooth the movement between keyframes animation.RepeatCount = float.MaxValue; animation.Duration = 10.0f; animation.TimingFunction = CAMediaTimingFunction.FromName (CAMediaTimingFunction.Linear); BallNode.AddAnimation (animation, new NSString ("ballNodeAnimation")); // Rotate the ball to give the illusion of a rolling ball // We need two animations to do that: // - one rotation to orient the ball in the right direction // - one rotation to spin the ball animation = CAKeyFrameAnimation.GetFromKeyPath ("rotation"); animation.KeyTimes = new NSNumber[] { 0.0f, (0.7f / 8.0f), (1.0f / 8.0f), (2.0f / 8.0f), (3.0f / 8.0f), (3.3f / 8.0f), (4.7f / 8.0f), (5.0f / 8.0f), (6.0f / 8.0f), (7.0f / 8.0f), (7.3f / 8.0f), 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI / 2))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI + Math.PI / 2))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI * 2 - Math.PI / 4))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI * 2 - Math.PI / 4))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI * 2 - Math.PI / 2))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI - Math.PI / 2))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI / 4))) }; animation.RepeatCount = float.MaxValue; animation.Duration = 10.0f; animation.TimingFunction = CAMediaTimingFunction.FromName (CAMediaTimingFunction.Linear); BallNode.AddAnimation (animation, new NSString ("ballNodeAnimation2")); var rotationAnimation = CABasicAnimation.FromKeyPath ("rotation"); rotationAnimation.Duration = 1.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector (new SCNVector4 (1, 0, 0, (float)(Math.PI * 2))); BallNode.ChildNodes [1].AddAnimation (rotationAnimation, new NSString ("ballNodeRotation")); break; case 5: // Add a constraint to the camera SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; constraint = SCNLookAtConstraint.Create (BallNode); presentationViewController.CameraNode.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit (); break; case 6: // Add a constraint to the light SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; var cameraTarget = ContentNode.FindChildNode ("cameraTarget", true); constraint = SCNLookAtConstraint.Create (cameraTarget); presentationViewController.SpotLight.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit (); break; } }
public override void PresentStep (int switchIndex, PresentationViewController presentationViewController) { switch (switchIndex) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle ("Core Image"); TextManager.SetSubtitle ("CI Filters"); TextManager.AddBulletAtLevel ("Screen-space effects", 0); TextManager.AddBulletAtLevel ("Applies to a node hierarchy", 0); TextManager.AddBulletAtLevel ("Filter parameters are animatable", 0); TextManager.AddCode ("#aNode.#Filters# = new CIFilter[] { filter1, filter2 };#"); break; case 1: SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1.0f; // Dim the text and move back a little TextManager.TextNode.Opacity = 0.0f; presentationViewController.CameraHandle.Position = presentationViewController.CameraNode.ConvertPositionToNode (new SCNVector3 (0, 0, 5.0f), presentationViewController.CameraHandle.ParentNode); SCNTransaction.Commit (); // Reveal the grid GroupNode.Opacity = 1; break; case 2: SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; // Highlight an item HighlightContact (13, presentationViewController); SCNTransaction.Commit (); break; case 3: var index = 13; var subStep = 0; // Successively select items for (var i = 0; i < 5; ++i) { var popTime = new DispatchTime (DispatchTime.Now, (Int64)(i * 0.2 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0.2f; UnhighlightContact (index); if (subStep++ == 3) index += ColumnCount; else index++; HighlightContact (index, presentationViewController); SCNTransaction.Commit (); }); } break; case 4: // BLUR+DESATURATE in the background, GLOW in the foreground // Here we will change the node hierarchy in order to group all the nodes in the background under a single node. // This way we can use a single Core Image filter and apply it on the whole grid, and have another CI filter for the node in the foreground. var selectionParent = HeroNode.ParentNode; SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0; // Stop the animations of the selected node HeroNode.Transform = HeroNode.PresentationNode.Transform; // set the current rotation to the current presentation value HeroNode.RemoveAllAnimations (); // Re-parent the node by preserving its world tranform var wantedWorldTransform = selectionParent.WorldTransform; GroupNode.ParentNode.AddChildNode (selectionParent); selectionParent.Transform = selectionParent.ParentNode.ConvertTransformFromNode (wantedWorldTransform, null); SCNTransaction.Commit (); // Add CIFilters SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; // A negative 'centerX' value means no scaling. //TODO HeroNode.Filters [0].SetValueForKey (new NSNumber (-1), new NSString ("centerX")); // Move the selection to the foreground selectionParent.Rotation = new SCNVector4 (0, 1, 0, 0); HeroNode.Transform = ContentNode.ConvertTransformToNode (SCNMatrix4.CreateTranslation (0, Altitude, 29), selectionParent); HeroNode.Scale = new SCNVector3 (1, 1, 1); HeroNode.Rotation = new SCNVector4 (1, 0, 0, -(float)(Math.PI / 4) * 0.25f); // Upon completion, rotate the selection forever SCNTransaction.SetCompletionBlock (() => { var animation = CABasicAnimation.FromKeyPath ("rotation"); animation.Duration = 4.0f; animation.From = NSValue.FromVector (new SCNVector4 (0, 1, 0, 0)); animation.To = NSValue.FromVector (new SCNVector4 (0, 1, 0, NMath.PI * 2)); animation.TimingFunction = CAMediaTimingFunction.FromName (CAMediaTimingFunction.EaseInEaseOut); animation.RepeatCount = float.MaxValue; HeroNode.ChildNodes [0].AddAnimation (animation, new NSString ("heroNodeAnimation")); }); // Add the filters var blurFilter = CIFilter.FromName ("CIGaussianBlur"); blurFilter.SetDefaults (); blurFilter.Name = "blur"; blurFilter.SetValueForKey (new NSNumber (0), CIFilterInputKey.Radius); var desaturateFilter = CIFilter.FromName ("CIColorControls"); desaturateFilter.SetDefaults (); desaturateFilter.Name = "desaturate"; GroupNode.Filters = new CIFilter[] { blurFilter, desaturateFilter }; SCNTransaction.Commit (); // Increate the blur radius and desaturate progressively SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 2; GroupNode.SetValueForKey (new NSNumber (10), new NSString ("filters.blur.inputRadius")); GroupNode.SetValueForKey (new NSNumber (0.1), new NSString ("filters.desaturate.inputSaturation")); SCNTransaction.Commit (); break; } }
void PerformRandomUpdate() { if (WifiEnabled && ScanForNetworks) { var updatedNetworks = new List <Network> (); if (AvailableNetworks != null) { updatedNetworks.AddRange(AvailableNetworks); } if (updatedNetworks.Count == 0) { AvailableNetworks = allNetworks; } else { var random = new Random(DateTime.Now.Millisecond); var shouldRemove = random.Next(0, 3) == 0; if (shouldRemove) { var removeCount = random.Next(0, updatedNetworks.Count); for (int i = 0; i < removeCount; i++) { var removeIndex = random.Next(0, updatedNetworks.Count); updatedNetworks.RemoveAt(removeIndex); } } var shouldAdd = random.Next(0, 3) == 0; if (shouldAdd) { var allNetworksSet = new List <Network> (allNetworks); var updatedNetworksSet = new List <Network> (updatedNetworks); var notPresentNetworksSet = new List <Network> (allNetworksSet); foreach (var network in updatedNetworksSet) { notPresentNetworksSet.Remove(network); } if (notPresentNetworksSet.Count > 0) { var addCount = random.Next(0, notPresentNetworksSet.Count); for (int i = 0; i < addCount; i++) { var removeIndex = random.Next(0, notPresentNetworksSet.Count); var networkToAdd = notPresentNetworksSet [removeIndex]; notPresentNetworksSet.Remove(networkToAdd); updatedNetworksSet.Add(networkToAdd); } } updatedNetworks = updatedNetworksSet; } UpdateAvailableNetworks(updatedNetworks.ToArray()); } // notify updateHandler(this); } var deadline = new DispatchTime(DispatchTime.Now, new TimeSpan(0, 0, 4)); DispatchQueue.MainQueue.DispatchAfter(deadline, () => PerformRandomUpdate()); }
void zombiesOnATimer () { if (paused) return; TimerEvent eventType = nextZombieEvent (); statusView.Status = stringForZombieEvent (eventType); meterView.ZombieLevel = meterView.ZombieLevel + zombieFactorForEvent (eventType); monitorZombiePressure (); manageVisibleZombies (); var popTime = new DispatchTime (DispatchTime.Now, (long)6 * NSEC_PER_SEC); DispatchQueue.MainQueue.DispatchAfter (popTime, () => zombiesOnATimer ()); }
public override string ToString() { var str = Message + " DispatchTime: " + DispatchTime.ToString("hh:mm:ss.fffffff"); return(str); }
public override void PresentStep(int switchIndex, PresentationViewController presentationViewController) { switch (switchIndex) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Core Image"); TextManager.SetSubtitle("CI Filters"); TextManager.AddBulletAtLevel("Screen-space effects", 0); TextManager.AddBulletAtLevel("Applies to a node hierarchy", 0); TextManager.AddBulletAtLevel("Filter parameters are animatable", 0); TextManager.AddCode("#aNode.#Filters# = new CIFilter[] { filter1, filter2 };#"); break; case 1: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; // Dim the text and move back a little TextManager.TextNode.Opacity = 0.0f; presentationViewController.CameraHandle.Position = presentationViewController.CameraNode.ConvertPositionToNode(new SCNVector3(0, 0, 5.0f), presentationViewController.CameraHandle.ParentNode); SCNTransaction.Commit(); // Reveal the grid GroupNode.Opacity = 1; break; case 2: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Highlight an item HighlightContact(13, presentationViewController); SCNTransaction.Commit(); break; case 3: var index = 13; var subStep = 0; // Successively select items for (var i = 0; i < 5; ++i) { var popTime = new DispatchTime(DispatchTime.Now, (long)(i * 0.2 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.2f; UnhighlightContact(index); if (subStep++ == 3) { index += ColumnCount; } else { index++; } HighlightContact(index, presentationViewController); SCNTransaction.Commit(); }); } break; case 4: // BLUR+DESATURATE in the background, GLOW in the foreground // Here we will change the node hierarchy in order to group all the nodes in the background under a single node. // This way we can use a single Core Image filter and apply it on the whole grid, and have another CI filter for the node in the foreground. var selectionParent = HeroNode.ParentNode; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; // Stop the animations of the selected node HeroNode.Transform = HeroNode.PresentationNode.Transform; // set the current rotation to the current presentation value HeroNode.RemoveAllAnimations(); // Re-parent the node by preserving its world tranform var wantedWorldTransform = selectionParent.WorldTransform; GroupNode.ParentNode.AddChildNode(selectionParent); selectionParent.Transform = selectionParent.ParentNode.ConvertTransformFromNode(wantedWorldTransform, null); SCNTransaction.Commit(); // Add CIFilters SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // A negative 'centerX' value means no scaling. //TODO HeroNode.Filters [0].SetValueForKey (new NSNumber (-1), new NSString ("centerX")); // Move the selection to the foreground selectionParent.Rotation = new SCNVector4(0, 1, 0, 0); HeroNode.Transform = ContentNode.ConvertTransformToNode(SCNMatrix4.CreateTranslation(0, Altitude, 29), selectionParent); HeroNode.Scale = new SCNVector3(1, 1, 1); HeroNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.25f); // Upon completion, rotate the selection forever SCNTransaction.SetCompletionBlock(() => { var animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 4.0f; animation.From = NSValue.FromVector(new SCNVector4(0, 1, 0, 0)); animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, NMath.PI * 2)); animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.RepeatCount = float.MaxValue; HeroNode.ChildNodes [0].AddAnimation(animation, new NSString("heroNodeAnimation")); }); // Add the filters var blurFilter = CIFilter.FromName("CIGaussianBlur"); blurFilter.SetDefaults(); blurFilter.Name = "blur"; blurFilter.SetValueForKey(new NSNumber(0), CIFilterInputKey.Radius); var desaturateFilter = CIFilter.FromName("CIColorControls"); desaturateFilter.SetDefaults(); desaturateFilter.Name = "desaturate"; GroupNode.Filters = new CIFilter[] { blurFilter, desaturateFilter }; SCNTransaction.Commit(); // Increate the blur radius and desaturate progressively SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 2; GroupNode.SetValueForKey(new NSNumber(10), new NSString("filters.blur.inputRadius")); GroupNode.SetValueForKey(new NSNumber(0.1), new NSString("filters.desaturate.inputSaturation")); SCNTransaction.Commit(); break; } }
void goForthZombies () { manageVisibleZombies (); statusView.Status = "Your program has started. The zombies are massing"; double delayInSeconds = 2; var popTime = new DispatchTime (DispatchTime.Now, (long)(delayInSeconds * NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => zombiesOnATimer ()); }
void PresentStep (nint step) { var overlay = (SpriteKitOverlayScene)((SCNView)View).OverlayScene; if (CameraHandleTransforms [(int)step].M11 == 0) { CameraHandleTransforms [(int)step] = CameraHandle.Transform; CameraOrientationTransforms [(int)step] = CameraOrientation.Transform; } switch (step) { case 1: overlay.ShowLabel ("Physics"); overlay.RunAction (SKAction.Sequence (new [] { SKAction.WaitForDuration (2), SKAction.Run (() => { if (Step == 1) overlay.ShowLabel (null); }) })); var popTime = new DispatchTime (DispatchTime.Now, (long)(0.0 * NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, ShowPhysicsSlide); break; case 2: overlay.ShowLabel ("Particles"); overlay.RunAction (SKAction.Sequence (new [] { SKAction.WaitForDuration (4), SKAction.Run (() => { if (Step == 2) overlay.ShowLabel (null); }) })); ShowParticlesSlide (); break; case 3: overlay.ShowLabel ("Physics Fields"); overlay.RunAction (SKAction.Sequence (new [] { SKAction.WaitForDuration (2), SKAction.Run (() => { if (Step == 3) overlay.ShowLabel (null); }) })); ShowPhysicsFields (); break; case 4: overlay.ShowLabel ("SceneKit + SpriteKit"); overlay.RunAction (SKAction.Sequence (new [] { SKAction.WaitForDuration (4), SKAction.Run (() => { if (Step == 4) overlay.ShowLabel (null); }) })); ShowSpriteKitSlide (); break; case 5: overlay.ShowLabel ("SceneKit + Shaders"); ShowShadersSlide (); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { Step = index; switch (index) { case 0: break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.SetSubtitle("SCNPhysicsBody"); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.AddBulletAtLevel("Dynamic Bodies", 0); // Add some code TextManager.AddCode("#// Make a node dynamic\n" + "aNode.#physicsBody# = [SCNPhysicsBody #dynamicBody#];#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 2: //add a cube var worldPos = GroundNode.ConvertPositionToNode(new SCNVector3(0, 12, 2), null); var dice = CreateBlock(worldPos, new SCNVector3(1.5f, 1.5f, 1.5f)); dice.PhysicsBody = null; //wait! dice.Rotation = new SCNVector4(0, 0, 1, (float)(Math.PI / 4) * 0.5f); dice.Scale = new SCNVector3(0.001f, 0.001f, 0.001f); ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode(dice); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; dice.Scale = new SCNVector3(2, 2, 2); SCNTransaction.Commit(); Dices.Add(dice); break; case 3: foreach (var node in Dices) { node.PhysicsBody = SCNPhysicsBody.CreateDynamicBody(); } break; case 4: PresentDices(presentationViewController); break; case 5: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.AddBulletAtLevel("Manipulate with forces", 0); // Add some code TextManager.AddCode("#// Apply an impulse\n" + "[aNode.physicsBody #applyForce:#aVector3 #atPosition:#aVector3 #impulse:#YES];#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 6: // remove dices var center = new SCNVector3(0, -5, 20); center = GroundNode.ConvertPositionToNode(center, null); Explosion(center, Dices); var popTime = new DispatchTime(DispatchTime.Now, (long)(1 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Static Bodies", 0); TextManager.AddCode("#// Make a node static\n" + "aNode.#physicsBody# = [SCNPhysicsBody #staticBody#];#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); }); break; case 7: PresentWalls(presentationViewController); break; case 8: PresentBalls(presentationViewController); break; case 9: //remove walls var walls = new List <SCNNode> (); GroundNode.EnumerateChildNodes(delegate(SCNNode node, out bool stop) { stop = false; if (node.Name == "container-wall") { node.RunAction(SCNAction.Sequence(new SCNAction [] { SCNAction.MoveBy(new SCNVector3(0, -2, 0), 0.5), SCNAction.RemoveFromParentNode() })); walls.Add(node); } return(stop); }); break; case 10: // remove balls center = new SCNVector3(0, -5, 5); center = GroundNode.ConvertPositionToNode(center, null); Explosion(center, Balls); popTime = new DispatchTime(DispatchTime.Now, (long)(0.5 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Kinematic Bodies", 0); TextManager.AddCode("#// Make a node kinematic\n" + "aNode.#physicsBody# = [SCNPhysicsBody #kinematicBody#];#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); }); break; case 11: var boxNode = SCNNode.Create(); boxNode.Geometry = SCNBox.Create(10, 0.2f, 10, 0); boxNode.Position = new SCNVector3(0, 5, MIDDLE_Z); boxNode.Geometry.FirstMaterial.Emission.Contents = NSColor.DarkGray; boxNode.PhysicsBody = SCNPhysicsBody.CreateKinematicBody(); boxNode.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(0, 0, NMath.PI * 2, 2.0))); GroundNode.AddChildNode(boxNode); KinematicItems.Add(boxNode); var invisibleWall = SCNNode.Create(); invisibleWall.Geometry = SCNBox.Create(4, 40, 10, 0); invisibleWall.Position = new SCNVector3(-7, 0, MIDDLE_Z); invisibleWall.Geometry.FirstMaterial.Transparency = 0; invisibleWall.PhysicsBody = SCNPhysicsBody.CreateStaticBody(); GroundNode.AddChildNode(invisibleWall); KinematicItems.Add(invisibleWall); invisibleWall = (SCNNode)invisibleWall.Copy(); invisibleWall.Position = new SCNVector3(7, 0, MIDDLE_Z); GroundNode.AddChildNode(invisibleWall); KinematicItems.Add(invisibleWall); invisibleWall = (SCNNode)invisibleWall.Copy(); invisibleWall.Geometry = SCNBox.Create(10, 40, 4, 0); invisibleWall.Geometry.FirstMaterial.Transparency = 0; invisibleWall.Position = new SCNVector3(0, 0, MIDDLE_Z - 7); invisibleWall.PhysicsBody = SCNPhysicsBody.CreateStaticBody(); GroundNode.AddChildNode(invisibleWall); KinematicItems.Add(invisibleWall); invisibleWall = (SCNNode)invisibleWall.Copy(); invisibleWall.Position = new SCNVector3(0, 0, MIDDLE_Z + 7); GroundNode.AddChildNode(invisibleWall); KinematicItems.Add(invisibleWall); for (int i = 0; i < 100; i++) { var ball = SCNNode.Create(); worldPos = boxNode.ConvertPositionToNode(new SCNVector3(RandFloat(-4, 4), RandFloat(10, 30), RandFloat(-1, 4)), null); ball.Position = worldPos; ball.Geometry = SCNSphere.Create(0.5f); ball.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Cyan; ball.PhysicsBody = SCNPhysicsBody.CreateDynamicBody(); ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode(ball); KinematicItems.Add(ball); } break; case 12: TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("SCNPhysicsShape"); TextManager.AddCode("#// Configure the physics shape\n\n" + "aNode.physicsBody.#physicsShape# = \n\t[#SCNPhysicsShape# shapeWithGeometry:aGeometry options:options];#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); KinematicItems[0].RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.FadeOut(0.5), SCNAction.RemoveFromParentNode() })); for (int i = 1; i < 5; i++) { KinematicItems[i].RemoveFromParentNode(); } KinematicItems = null; break; case 13: //add meshes PresentMeshes(presentationViewController); break; case 14: // remove meshes center = new SCNVector3(0, -5, 20); center = GroundNode.ConvertPositionToNode(center, null); Explosion(center, Meshes); break; case 15: // add shapes PresentPrimitives(presentationViewController); break; case 16: // remove shapes center = new SCNVector3(0, -5, 20); center = GroundNode.ConvertPositionToNode(center, null); Explosion(center, Shapes); popTime = new DispatchTime(DispatchTime.Now, (long)(0.5 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("SCNPhysicsBehavior"); TextManager.AddCode("#// setup a physics behavior\n\n" + "#SCNPhysicsHingeJoint# *joint = [SCNPhysicsHingeJoint\n\n" + "jointWithBodyA:#nodeA.physicsBody# axisA:[...] anchorA:[...]\n\n" + "bodyB:#nodeB.physicsBody# axisB:[...] anchorB:[...]];\n\n\n" + "[scene.#physicsWorld# addBehavior:joint];#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Code); }); break; case 17: //add meshes PresentHinge(presentationViewController); break; case 18: //remove constraints ((SCNView)presentationViewController.View).Scene.PhysicsWorld.RemoveAllBehaviors(); foreach (var node in Hinges) { node.RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.Wait(3.0), SCNAction.FadeOut(0.5), SCNAction.RemoveFromParentNode() })); } break; case 19: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.SetSubtitle("More..."); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.AddBulletAtLevel("SCNPhysicsField", 0); TextManager.AddBulletAtLevel("SCNPhysicsVehicle", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; } }
void PreventAccidentalNext (nfloat delay) { PreventNext = true; //disable the next button for "delay" seconds to prevent accidental tap var overlay = (SpriteKitOverlayScene)((SCNView)View).OverlayScene; overlay.NextButton.RunAction (SKAction.FadeAlphaBy (-0.5f, 0.5f)); overlay.PreviousButton.RunAction (SKAction.FadeAlphaBy (-0.5f, 0.5f)); var popTime = new DispatchTime (DispatchTime.Now, (long)(delay * NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { PreventNext = false; overlay.PreviousButton.RunAction (SKAction.FadeAlphaTo (Step > 1 ? 1 : 0, 0.75f)); overlay.NextButton.RunAction (SKAction.FadeAlphaTo (IntroductionStep == 0 && Step < 5 ? 1 : 0, 0.75f)); }); }
public void HandlePan (CGPoint p) { var scnView = (SCNView)this.View; if (Step == 2) { //particles var pTmp = scnView.ProjectPoint (new SCNVector3 (0, 0, 0)); var p3d = scnView.UnprojectPoint (new SCNVector3 (p.X, p.Y, pTmp.Z)); var handlePos = Handle.WorldTransform; var dy = (float)Math.Max (0, p3d.Y - handlePos.M42); var dx = handlePos.M41 - p3d.X; var angle = (float)Math.Atan2 (dy, dx); angle -= 35.0f * (float)Math.PI / 180.0f; //handle is 35 degree by default //clamp if (angle < MIN_ANGLE) angle = MIN_ANGLE; if (angle > MAX_ANGLE) angle = MAX_ANGLE; var popTime = new DispatchTime (DispatchTime.Now, (long)(HIT_DELAY * NSEC_PER_SEC)); if (angle <= 0.66 && angle >= 0.48) { DispatchQueue.MainQueue.DispatchAfter (popTime, () => { //hit the fire! HitFire = true; }); } else { DispatchQueue.MainQueue.DispatchAfter (popTime, () => { //hit the fire! HitFire = false; }); } Handle.Rotation = new SCNVector4 (1, 0, 0, angle); } if (Step == 3) { //bubbles MoveEmitter (p); } }
public static void DispatchAfter(this DispatchQueue self, TimeSpan delay, Action action) { var time = new DispatchTime(DispatchTime.Now, delay.Ticks * 100); self.DispatchAfter(time, action); }
// switch to the next introduction step void NextIntroductionStep () { IntroductionStep++; SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; SCNTransaction.SetCompletionBlock (() => { if (IntroductionStep >= 4) { //We did finish introduction step 4 //free some memory if (ShipHandle != null) ShipHandle.RemoveFromParentNode (); ShipHandle = null; ShipPivot = null; ShipNode = null; } if (IntroductionStep == 0) { //We did finish the whole introduction IntroNodeGroup.RemoveFromParentNode (); IntroNodeGroup = null; Next (); } }); if (IntroductionStep == 2) { var popTime = new DispatchTime (DispatchTime.Now, (long)(1 * NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1.0f; ShipNode.Opacity = 1.0f; ShipNode.RunAction (SCNAction.RepeatActionForever (SCNAction.RotateBy (0, NMath.PI, 0, 1.0))); SCNTransaction.Commit (); }); } if (IntroductionStep == 3) { //animate ship ShipNode.RemoveAllActions (); ShipNode.Rotation = new SCNVector4 (0, 0, 1, (float)(Math.PI / 4) * 0.5f); //make spotlight relative to the ship var newPosition = new SCNVector3 (50, 100, 0); var oldTransform = ShipPivot.ConvertTransformFromNode (SCNMatrix4.Identity, SpotLightNode); OldSpotTransform = SpotLightNode.Transform; SpotLightNode.RemoveFromParentNode (); SpotLightNode.Transform = oldTransform; ShipPivot.AddChildNode (SpotLightNode); SpotLightNode.Position = newPosition; // will animate implicitly SpotLightNode.EulerAngles = new SCNVector3 (-(float)Math.PI / 2, 0, 0); SpotLightNode.Light.SpotOuterAngle = 120; var action = SCNAction.Sequence (new [] { SCNAction.Wait (1), SCNAction.RepeatActionForever (SCNAction.RotateBy (0, NMath.PI, 0, 2)) }); ShipPivot.RunAction (action); var animation = CABasicAnimation.FromKeyPath ("position.x"); animation.From = new NSNumber (-50); animation.To = new NSNumber (50); animation.TimingFunction = CAMediaTimingFunction.FromName (CAMediaTimingFunction.EaseInEaseOut); animation.AutoReverses = true; animation.Duration = 2; animation.RepeatCount = float.MaxValue; animation.TimeOffset = animation.Duration * 0.5f; ShipPivot.ParentNode.AddAnimation (animation, null); var emitter = ShipNode.FindChildNode ("emitter", true); var ps = SCNParticleSystem.Create ("reactor.scnp", "assets.scnassets/particles"); ps.ParticleImage = new NSString ("assets.scnassets/textures/tspark.png"); emitter.AddParticleSystem (ps); ShipHandle.Position = new SCNVector3 (ShipHandle.Position.X, ShipHandle.Position.Y, ShipHandle.Position.Z - TEXT_Z_SPACING - 50); } if (IntroductionStep == 4) { //restore spot light config SpotLightNode.Light.SpotOuterAngle = 70; var oldTransform = SpotLightParentNode.ConvertTransformFromNode (SCNMatrix4.Identity, SpotLightNode); SpotLightNode.RemoveFromParentNode (); SpotLightNode.Transform = oldTransform; SpotLightParentNode.AddChildNode (SpotLightNode); SpotLightNode.Transform = OldSpotTransform; CameraNode.Position = new SCNVector3 (CameraNode.Position.X, CameraNode.Position.Y, CameraNode.Position.Z - TEXT_Z_SPACING); } if (IntroductionStep == 5) { IntroductionStep = 0;//introduction is over // jiterring is now useless since the screen will never be static again. var scnView = (SCNView)this.View; scnView.JitteringEnabled = false; AmbientLightNode.Light.Color = SKColorHelper.FromCommonWhiteAlpha (0.3f, 1.0f); SpotLightNode.Position = new SCNVector3 (0, 0, 0); SpotLightNode.EulerAngles = new SCNVector3 (-(float)(Math.PI / 4), 0, 0); CameraNode.Position = new SCNVector3 (0, 0, 120); CameraNode.EulerAngles = new SCNVector3 (0, 0, 0); } else { CameraNode.Position = new SCNVector3 (CameraNode.Position.X, CameraNode.Position.Y, CameraNode.Position.Z - TEXT_Z_SPACING); } SCNTransaction.Commit (); }
bool TryLoadFirstBatch() { bool haveNoPost = PostCells.Count == 0 || lastPostSeenOnServer == null; if(haveNoPost) { // We dispatch it after two seconds to give the server time to index the new post // TODO: https://trello.com/c/cWWQXKYY var dispatchTime = new DispatchTime (DispatchTime.Now, 2 * 1000000000); DispatchQueue.MainQueue.DispatchAfter (dispatchTime, () => { // If we get here, we must have no posts. That must mean that last time we tried loading a batch nothing came through so we locked the method. Let's unlock it haveOldestPost = false; LoadBatch (); }); } return haveNoPost; }
public override void PresentStep(int index, PresentationViewController presentationViewController) { float delay = 0; switch (index) { case 0: break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Available on OS X 10.8+ and iOS 8.0", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); //show some nice icons Icon1 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/Badge_X", "png"), 7, false); Icon1.Position = new SCNVector3(-20, 3.5f, 5); GroundNode.AddChildNode(Icon1); Icon2 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/Badge_iOS", "png"), 7, false); Icon2.Position = new SCNVector3(20, 3.5f, 5); GroundNode.AddChildNode(Icon2); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; Icon1.Position = new SCNVector3(-6, 3.5f, 5); Icon2.Position = new SCNVector3(6, 3.5f, 5); SCNTransaction.Commit(); break; case 2: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; Icon1.Position = new SCNVector3(-6, 3.5f, -5); Icon2.Position = new SCNVector3(6, 3.5f, -5); Icon1.Opacity = 0.0f; Icon2.Opacity = 0.0f; SCNTransaction.Commit(); foreach (var node in Boxes) { var popTime = new DispatchTime(DispatchTime.Now, (Int64)(delay * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5f; node.Rotation = new SCNVector4(1, 0, 0, 0); node.Scale = new SCNVector3(0.02f, 0.02f, 0.02f); node.Opacity = 1.0f; SCNTransaction.Commit(); }); delay += 0.05f; } TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("Graphic Frameworks"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); break; } }
public void ButtonFinished (ButtonView button, UIView trackingView, UITouch location) { double delayInSeconds = 0; buttonDraggedToPad = false; miniPadView.Layer.BorderWidth = 0; CGPoint point = location.LocationInView (miniPadView); if (miniPadView.PointInside (point, null)) { updateScoreForDroppedButton (button); UIView.Animate (.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation (10f * (float)Math.PI / 180), async () => { await UIView.AnimateAsync (.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation (-10f * (float)Math.PI / 180)); await UIView.AnimateAsync (.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation (10f * (float)Math.PI / 180)); await UIView.AnimateAsync (.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation (-10f * (float)Math.PI / 180)); await UIView.AnimateAsync (.1f, () => trackingView.Transform = CGAffineTransform.MakeRotation (0)); }); } delayInSeconds = 0.5; var popTime = new DispatchTime (DispatchTime.Now, (long)(delayInSeconds * NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, async () => { await UIView.AnimateAsync (0.35f, () => { CGRect bounds = trackingView.Bounds; bounds.Size = new CGSize (10, 10); trackingView.Bounds = bounds; }); trackingView.RemoveFromSuperview (); }); }
public void GoToSlide(int slideIndex) { int oldIndex = CurrentSlideIndex; // Load the slide at the specified index var slide = GetSlide(slideIndex, true); if (slide == null) { return; } // Compute the playback direction (did the user select next or previous?) var direction = slideIndex >= CurrentSlideIndex ? 1 : -1; // Update badge ShowsNewInSceneKitBadge(slide.IsNewIn10_10); // If we are playing backward, we need to use the slide we come from to play the correct transition (backward) int transitionSlideIndex = direction == 1 ? slideIndex : CurrentSlideIndex; var transitionSlide = GetSlide(transitionSlideIndex, true); // Make sure that the next operations are synchronized by using a transaction SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; var rootNode = slide.ContentNode; var textContainer = slide.TextManager.TextNode; var offset = new SCNVector3(transitionSlide.TransitionOffsetX, 0.0f, transitionSlide.TransitionOffsetZ); offset.X *= direction; offset.Z *= direction; // Rotate offset based on current yaw var cosa = Math.Cos(-CameraHandle.Rotation.W); var sina = Math.Sin(-CameraHandle.Rotation.W); var tmpX = offset.X * cosa - offset.Z * sina; offset.Z = (float)(offset.X * sina + offset.Z * cosa); offset.X = (float)tmpX; // If we don't move, fade in if (offset.X == 0 && offset.Y == 0 && offset.Z == 0 && transitionSlide.TransitionRotation == 0) { rootNode.Opacity = 0; } // Don't animate the first slide bool shouldAnimate = !(slideIndex == 0 && CurrentSlideIndex == 0); // Update current slide index CurrentSlideIndex = slideIndex; // Go to step 0 GoToSlideStep(0); // Add the slide to the scene graph ((SCNView)View).Scene.RootNode.AddChildNode(rootNode); // Fade in, update paramters and notify on completion SCNTransaction.Begin(); SCNTransaction.AnimationDuration = (shouldAnimate ? slide.TransitionDuration : 0); SCNTransaction.SetCompletionBlock(() => DidOrderInSlide(slideIndex)); rootNode.Opacity = 1; CameraHandle.Position = new SCNVector3(CameraHandle.Position.X + offset.X, slide.Altitude, CameraHandle.Position.Z + offset.Z); CameraHandle.Rotation = new SCNVector4(0, 1, 0, (float)(CameraHandle.Rotation.W + transitionSlide.TransitionRotation * (Math.PI / 180.0f) * direction)); CameraPitch.Rotation = new SCNVector4(1, 0, 0, (float)(slide.Pitch * (Math.PI / 180.0f))); UpdateLightingForSlide(slideIndex); Floor.Reflectivity = slide.FloorReflectivity; Floor.ReflectionFalloffEnd = slide.FloorFalloff; SCNTransaction.Commit(); // Compute the position of the text (in world space, relative to the camera) var textWorldTransform = SCNMatrix4.Mult(SCNMatrix4.CreateTranslation(0, -3.3f, -28), CameraNode.WorldTransform); // Place the rest of the slide rootNode.Transform = textWorldTransform; rootNode.Position = new SCNVector3(rootNode.Position.X, 0, rootNode.Position.Z); // clear altitude rootNode.Rotation = new SCNVector4(0, 1, 0, CameraHandle.Rotation.W); // use same rotation as the camera to simplify the placement of the elements in slides // Place the text textContainer.Transform = textContainer.ParentNode.ConvertTransformFromNode(textWorldTransform, null); // Place the ground node var localPosition = new SCNVector3(0, 0, 0); var worldPosition = slide.GroundNode.ParentNode.ConvertPositionToNode(localPosition, null); worldPosition.Y = 0; // make it touch the ground localPosition = slide.GroundNode.ParentNode.ConvertPositionFromNode(worldPosition, null); slide.GroundNode.Position = localPosition; // Update the floor image if needed string floorImagePath = null; NSImage floorImage = null; if (slide.FloorImageName != null) { floorImagePath = NSBundle.MainBundle.PathForResource("SharedTextures/" + slide.FloorImageName, slide.FloorImageExtension); floorImage = new NSImage(floorImagePath); } UpdateFloorImage(floorImage, slide); SCNTransaction.Commit(); // Preload the next slide after some delay var delayInSeconds = 1.5; var popTime = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { PrepareSlide(slideIndex + 1); }); // Order out previous slide if any if (oldIndex != CurrentSlideIndex) { WillOrderOutSlide(oldIndex); } }
public override void PresentStep (int index, PresentationViewController presentationViewController) { Step = index; switch (index) { case 0: break; case 1: TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.SetSubtitle ("SCNPhysicsBody"); TextManager.FlipInText (SlideTextManager.TextType.Subtitle); TextManager.AddBulletAtLevel ("Dynamic Bodies", 0); // Add some code TextManager.AddCode ("#// Make a node dynamic\n" + "aNode.#physicsBody# = [SCNPhysicsBody #dynamicBody#];#"); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Code); break; case 2: //add a cube var worldPos = GroundNode.ConvertPositionToNode (new SCNVector3 (0, 12, 2), null); var dice = CreateBlock (worldPos, new SCNVector3 (1.5f, 1.5f, 1.5f)); dice.PhysicsBody = null; //wait! dice.Rotation = new SCNVector4 (0, 0, 1, (float)(Math.PI / 4) * 0.5f); dice.Scale = new SCNVector3 (0.001f, 0.001f, 0.001f); ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode (dice); SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0.75f; dice.Scale = new SCNVector3 (2, 2, 2); SCNTransaction.Commit (); Dices.Add (dice); break; case 3: foreach (var node in Dices) node.PhysicsBody = SCNPhysicsBody.CreateDynamicBody (); break; case 4: PresentDices (presentationViewController); break; case 5: TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.FlipOutText (SlideTextManager.TextType.Code); TextManager.AddBulletAtLevel ("Manipulate with forces", 0); // Add some code TextManager.AddCode ("#// Apply an impulse\n" + "[aNode.physicsBody #applyForce:#aVector3 #atPosition:#aVector3 #impulse:#YES];#"); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Code); break; case 6: // remove dices var center = new SCNVector3 (0, -5, 20); center = GroundNode.ConvertPositionToNode (center, null); Explosion (center, Dices); var popTime = new DispatchTime (DispatchTime.Now, (long)(1 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { TextManager.FlipOutText (SlideTextManager.TextType.Code); TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel ("Static Bodies", 0); TextManager.AddCode ("#// Make a node static\n" + "aNode.#physicsBody# = [SCNPhysicsBody #staticBody#];#"); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Code); }); break; case 7: PresentWalls (presentationViewController); break; case 8: PresentBalls (presentationViewController); break; case 9: //remove walls var walls = new List<SCNNode> (); GroundNode.EnumerateChildNodes (delegate(SCNNode node, out bool stop) { stop = false; if (node.Name == "container-wall") { node.RunAction (SCNAction.Sequence (new SCNAction [] { SCNAction.MoveBy (new SCNVector3 (0, -2, 0), 0.5), SCNAction.RemoveFromParentNode () })); walls.Add (node); } return stop; }); break; case 10: // remove balls center = new SCNVector3 (0, -5, 5); center = GroundNode.ConvertPositionToNode (center, null); Explosion (center, Balls); popTime = new DispatchTime (DispatchTime.Now, (long)(0.5 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { TextManager.FlipOutText (SlideTextManager.TextType.Code); TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel ("Kinematic Bodies", 0); TextManager.AddCode ("#// Make a node kinematic\n" + "aNode.#physicsBody# = [SCNPhysicsBody #kinematicBody#];#"); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Code); }); break; case 11: var boxNode = SCNNode.Create (); boxNode.Geometry = SCNBox.Create (10, 0.2f, 10, 0); boxNode.Position = new SCNVector3 (0, 5, MIDDLE_Z); boxNode.Geometry.FirstMaterial.Emission.Contents = NSColor.DarkGray; boxNode.PhysicsBody = SCNPhysicsBody.CreateKinematicBody (); boxNode.RunAction (SCNAction.RepeatActionForever (SCNAction.RotateBy (0, 0, NMath.PI * 2, 2.0))); GroundNode.AddChildNode (boxNode); KinematicItems.Add (boxNode); var invisibleWall = SCNNode.Create (); invisibleWall.Geometry = SCNBox.Create (4, 40, 10, 0); invisibleWall.Position = new SCNVector3 (-7, 0, MIDDLE_Z); invisibleWall.Geometry.FirstMaterial.Transparency = 0; invisibleWall.PhysicsBody = SCNPhysicsBody.CreateStaticBody (); GroundNode.AddChildNode (invisibleWall); KinematicItems.Add (invisibleWall); invisibleWall = (SCNNode)invisibleWall.Copy (); invisibleWall.Position = new SCNVector3 (7, 0, MIDDLE_Z); GroundNode.AddChildNode (invisibleWall); KinematicItems.Add (invisibleWall); invisibleWall = (SCNNode)invisibleWall.Copy (); invisibleWall.Geometry = SCNBox.Create (10, 40, 4, 0); invisibleWall.Geometry.FirstMaterial.Transparency = 0; invisibleWall.Position = new SCNVector3 (0, 0, MIDDLE_Z - 7); invisibleWall.PhysicsBody = SCNPhysicsBody.CreateStaticBody (); GroundNode.AddChildNode (invisibleWall); KinematicItems.Add (invisibleWall); invisibleWall = (SCNNode)invisibleWall.Copy (); invisibleWall.Position = new SCNVector3 (0, 0, MIDDLE_Z + 7); GroundNode.AddChildNode (invisibleWall); KinematicItems.Add (invisibleWall); for (int i = 0; i < 100; i++) { var ball = SCNNode.Create (); worldPos = boxNode.ConvertPositionToNode (new SCNVector3 (RandFloat (-4, 4), RandFloat (10, 30), RandFloat (-1, 4)), null); ball.Position = worldPos; ball.Geometry = SCNSphere.Create (0.5f); ball.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Cyan; ball.PhysicsBody = SCNPhysicsBody.CreateDynamicBody (); ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode (ball); KinematicItems.Add (ball); } break; case 12: TextManager.FlipOutText (SlideTextManager.TextType.Code); TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.FlipOutText (SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle ("SCNPhysicsShape"); TextManager.AddCode ("#// Configure the physics shape\n\n" + "aNode.physicsBody.#physicsShape# = \n\t[#SCNPhysicsShape# shapeWithGeometry:aGeometry options:options];#"); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Code); KinematicItems[0].RunAction (SCNAction.Sequence (new SCNAction[] { SCNAction.FadeOut (0.5), SCNAction.RemoveFromParentNode () })); for (int i = 1; i < 5; i++) KinematicItems[i].RemoveFromParentNode (); KinematicItems = null; break; case 13: //add meshes PresentMeshes (presentationViewController); break; case 14: // remove meshes center = new SCNVector3 (0, -5, 20); center = GroundNode.ConvertPositionToNode (center, null); Explosion (center, Meshes); break; case 15: // add shapes PresentPrimitives (presentationViewController); break; case 16: // remove shapes center = new SCNVector3 (0, -5, 20); center = GroundNode.ConvertPositionToNode (center, null); Explosion (center, Shapes); popTime = new DispatchTime (DispatchTime.Now, (long)(0.5 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { TextManager.FlipOutText (SlideTextManager.TextType.Code); TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.FlipOutText (SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle ("SCNPhysicsBehavior"); TextManager.AddCode ("#// setup a physics behavior\n\n" + "#SCNPhysicsHingeJoint# *joint = [SCNPhysicsHingeJoint\n\n" + "jointWithBodyA:#nodeA.physicsBody# axisA:[...] anchorA:[...]\n\n" + "bodyB:#nodeB.physicsBody# axisB:[...] anchorB:[...]];\n\n\n" + "[scene.#physicsWorld# addBehavior:joint];#"); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Subtitle); TextManager.FlipInText (SlideTextManager.TextType.Code); }); break; case 17: //add meshes PresentHinge (presentationViewController); break; case 18: //remove constraints ((SCNView)presentationViewController.View).Scene.PhysicsWorld.RemoveAllBehaviors (); foreach (var node in Hinges) node.RunAction (SCNAction.Sequence (new SCNAction[] { SCNAction.Wait (3.0), SCNAction.FadeOut (0.5), SCNAction.RemoveFromParentNode () })); break; case 19: TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.FlipOutText (SlideTextManager.TextType.Subtitle); TextManager.FlipOutText (SlideTextManager.TextType.Code); TextManager.SetSubtitle ("More..."); TextManager.FlipInText (SlideTextManager.TextType.Subtitle); TextManager.AddBulletAtLevel ("SCNPhysicsField", 0); TextManager.AddBulletAtLevel ("SCNPhysicsVehicle", 0); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Code); break; } }
public void GoToSlide (int slideIndex) { int oldIndex = CurrentSlideIndex; // Load the slide at the specified index var slide = GetSlide (slideIndex, true); if (slide == null) return; // Compute the playback direction (did the user select next or previous?) var direction = slideIndex >= CurrentSlideIndex ? 1 : -1; // Update badge ShowsNewInSceneKitBadge (slide.IsNewIn10_9); // If we are playing backward, we need to use the slide we come from to play the correct transition (backward) int transitionSlideIndex = direction == 1 ? slideIndex : CurrentSlideIndex; var transitionSlide = GetSlide (transitionSlideIndex, true); // Make sure that the next operations are synchronized by using a transaction SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0; var rootNode = slide.ContentNode; var textContainer = slide.TextManager.TextNode; var offset = new SCNVector3 (transitionSlide.TransitionOffsetX, 0.0f, transitionSlide.TransitionOffsetZ); offset.X *= direction; offset.Z *= direction; // Rotate offset based on current yaw var cosa = Math.Cos (-CameraHandle.Rotation.W); var sina = Math.Sin (-CameraHandle.Rotation.W); var tmpX = offset.X * cosa - offset.Z * sina; offset.Z = (float)(offset.X * sina + offset.Z * cosa); offset.X = (float)tmpX; // If we don't move, fade in if (offset.X == 0 && offset.Y == 0 && offset.Z == 0 && transitionSlide.TransitionRotation == 0) rootNode.Opacity = 0; // Don't animate the first slide bool shouldAnimate = !(slideIndex == 0 && CurrentSlideIndex == 0); // Update current slide index CurrentSlideIndex = slideIndex; // Go to step 0 GoToSlideStep (0); // Add the slide to the scene graph ((SCNView)View).Scene.RootNode.AddChildNode (rootNode); // Fade in, update paramters and notify on completion SCNTransaction.Begin (); SCNTransaction.AnimationDuration = (shouldAnimate ? slide.TransitionDuration : 0); SCNTransaction.SetCompletionBlock (() => DidOrderInSlide (slideIndex)); rootNode.Opacity = 1; CameraHandle.Position = new SCNVector3 (CameraHandle.Position.X + offset.X, slide.Altitude, CameraHandle.Position.Z + offset.Z); CameraHandle.Rotation = new SCNVector4 (0, 1, 0, (float)(CameraHandle.Rotation.W + transitionSlide.TransitionRotation * (Math.PI / 180.0f) * direction)); CameraPitch.Rotation = new SCNVector4 (1, 0, 0, (float)(slide.Pitch * (Math.PI / 180.0f))); UpdateLightingForSlide (slideIndex); Floor.Reflectivity = slide.FloorReflectivity; Floor.ReflectionFalloffEnd = slide.FloorFalloff; SCNTransaction.Commit (); // Compute the position of the text (in world space, relative to the camera) var textWorldTransform = SCNMatrix4.Mult (SCNMatrix4.CreateTranslation (0, -3.3f, -28), CameraNode.WorldTransform); // Place the rest of the slide rootNode.Transform = textWorldTransform; rootNode.Position = new SCNVector3 (rootNode.Position.X, 0, rootNode.Position.Z); // clear altitude rootNode.Rotation = new SCNVector4 (0, 1, 0, CameraHandle.Rotation.W); // use same rotation as the camera to simplify the placement of the elements in slides // Place the text textContainer.Transform = textContainer.ParentNode.ConvertTransformFromNode (textWorldTransform, null); // Place the ground node var localPosition = new SCNVector3 (0, 0, 0); var worldPosition = slide.GroundNode.ParentNode.ConvertPositionToNode (localPosition, null); worldPosition.Y = 0; // make it touch the ground localPosition = slide.GroundNode.ParentNode.ConvertPositionFromNode (worldPosition, null); slide.GroundNode.Position = localPosition; // Update the floor image if needed string floorImagePath = null; NSImage floorImage = null; if (slide.FloorImageName != null) { floorImagePath = NSBundle.MainBundle.PathForResource ("SharedTextures/" + slide.FloorImageName, slide.FloorImageExtension); floorImage = new NSImage (floorImagePath); } UpdateFloorImage (floorImage, slide); SCNTransaction.Commit (); // Preload the next slide after some delay var delayInSeconds = 1.5; var popTime = new DispatchTime (DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { PrepareSlide (slideIndex + 1); }); // Order out previous slide if any if (oldIndex != CurrentSlideIndex) WillOrderOutSlide (oldIndex); }
public override void PresentStep (int index, PresentationViewController presentationViewController) { float delay = 0; switch (index) { case 0: break; case 1: TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine (); TextManager.AddBulletAtLevel ("Available on OS X 10.8+ and iOS 8.0", 0); TextManager.FlipInText (SlideTextManager.TextType.Bullet); //show some nice icons Icon1 = Utils.SCPlaneNode (NSBundle.MainBundle.PathForResource ("Images/Badge_X", "png"), 7, false); Icon1.Position = new SCNVector3 (-20, 3.5f, 5); GroundNode.AddChildNode (Icon1); Icon2 = Utils.SCPlaneNode (NSBundle.MainBundle.PathForResource ("Images/Badge_iOS", "png"), 7, false); Icon2.Position = new SCNVector3 (20, 3.5f, 5); GroundNode.AddChildNode (Icon2); SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0.75f; Icon1.Position = new SCNVector3 (-6, 3.5f, 5); Icon2.Position = new SCNVector3 (6, 3.5f, 5); SCNTransaction.Commit (); break; case 2: SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0.75f; Icon1.Position = new SCNVector3 (-6, 3.5f, -5); Icon2.Position = new SCNVector3 (6, 3.5f, -5); Icon1.Opacity = 0.0f; Icon2.Opacity = 0.0f; SCNTransaction.Commit (); foreach (var node in Boxes) { var popTime = new DispatchTime (DispatchTime.Now, (Int64)(delay * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0.5f; node.Rotation = new SCNVector4 (1, 0, 0, 0); node.Scale = new SCNVector3 (0.02f, 0.02f, 0.02f); node.Opacity = 1.0f; SCNTransaction.Commit (); }); delay += 0.05f; } TextManager.FlipOutText (SlideTextManager.TextType.Bullet); TextManager.FlipOutText (SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle ("Graphic Frameworks"); TextManager.FlipInText (SlideTextManager.TextType.Bullet); TextManager.FlipInText (SlideTextManager.TextType.Subtitle); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Constraints"); TextManager.SetSubtitle("SCNConstraint"); TextManager.AddBulletAtLevel("Applied sequentially at render time", 0); TextManager.AddBulletAtLevel("Only affect presentation values", 0); TextManager.AddCode("#aNode.#Constraints# = new SCNConstraint[] { aConstraint, anotherConstraint, ... };#"); // Tweak the near clipping plane of the spot light to get a precise shadow map presentationViewController.SpotLight.Light.SetAttribute(new NSNumber(10), SCNLightAttribute.ShadowNearClippingKey); break; case 1: // Remove previous text TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Code); // Add new text TextManager.SetSubtitle("SCNLookAtConstraint"); TextManager.AddBulletAtLevel("Makes a node to look at another node", 0); TextManager.AddCode("#nodeA.Constraints = new SCNConstraint[] { #SCNLookAtConstraint.Create# (nodeB) };#"); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 2: // Setup the scene SetupLookAtScene(); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Dim the text and move back a little bit TextManager.TextNode.Opacity = 0.5f; presentationViewController.CameraHandle.Position = presentationViewController.CameraNode.ConvertPositionToNode(new SCNVector3(0, 0, 5.0f), presentationViewController.CameraHandle.ParentNode); SCNTransaction.Commit(); break; case 3: // Add constraints to the arrows var container = ContentNode.FindChildNode("arrowContainer", true); // "Look at" constraint var constraint = SCNLookAtConstraint.Create(BallNode); var i = 0; foreach (var arrow in container.ChildNodes) { var delayInSeconds = 0.1 * i++; var popTime = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Animate to the result of applying the constraint ((SCNNode)arrow.ChildNodes [0]).Rotation = new SCNVector4(0, 1, 0, (float)(Math.PI / 2)); arrow.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit(); }); } break; case 4: // Create a keyframe animation to move the ball var animation = CAKeyFrameAnimation.FromKeyPath("position"); animation.KeyTimes = new NSNumber[] { 0.0f, (1.0f / 8.0f), (2.0f / 8.0f), (3.0f / 8.0f), (4.0f / 8.0f), (5.0f / 8.0f), (6.0f / 8.0f), (7.0f / 8.0f), 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector(new SCNVector3(0, 0.0f, 0)), NSValue.FromVector(new SCNVector3(20.0f, 0.0f, 20.0f)), NSValue.FromVector(new SCNVector3(40.0f, 0.0f, 0)), NSValue.FromVector(new SCNVector3(20.0f, 0.0f, -20.0f)), NSValue.FromVector(new SCNVector3(0, 0.0f, 0)), NSValue.FromVector(new SCNVector3(-20.0f, 0.0f, 20.0f)), NSValue.FromVector(new SCNVector3(-40.0f, 0.0f, 0)), NSValue.FromVector(new SCNVector3(-20.0f, 0.0f, -20.0f)), NSValue.FromVector(new SCNVector3(0, 0.0f, 0)) }; animation.CalculationMode = CAAnimation.AnimationCubicPaced; // smooth the movement between keyframes animation.RepeatCount = float.MaxValue; animation.Duration = 10.0f; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear); BallNode.AddAnimation(animation, new NSString("ballNodeAnimation")); // Rotate the ball to give the illusion of a rolling ball // We need two animations to do that: // - one rotation to orient the ball in the right direction // - one rotation to spin the ball animation = CAKeyFrameAnimation.FromKeyPath("rotation"); animation.KeyTimes = new NSNumber[] { 0.0f, (0.7f / 8.0f), (1.0f / 8.0f), (2.0f / 8.0f), (3.0f / 8.0f), (3.3f / 8.0f), (4.7f / 8.0f), (5.0f / 8.0f), (6.0f / 8.0f), (7.0f / 8.0f), (7.3f / 8.0f), 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI + Math.PI / 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI - Math.PI / 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))) }; animation.RepeatCount = float.MaxValue; animation.Duration = 10.0f; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear); BallNode.AddAnimation(animation, new NSString("ballNodeAnimation2")); var rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 1.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector(new SCNVector4(1, 0, 0, (float)(Math.PI * 2))); BallNode.ChildNodes [1].AddAnimation(rotationAnimation, new NSString("ballNodeRotation")); break; case 5: // Add a constraint to the camera SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; constraint = SCNLookAtConstraint.Create(BallNode); presentationViewController.CameraNode.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit(); break; case 6: // Add a constraint to the light SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; var cameraTarget = ContentNode.FindChildNode("cameraTarget", true); constraint = SCNLookAtConstraint.Create(cameraTarget); presentationViewController.SpotLight.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit(); break; } }
public static void DispatchAfter (this DispatchQueue self, TimeSpan delay, Action action) { var time = new DispatchTime (DispatchTime.Now, delay.Ticks * 100); self.DispatchAfter (time, action); }