public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Set the slide's title and subtitle TextManager.SetTitle("Scene Graph"); TextManager.SetSubtitle("Summary"); break; case 1: // A node that will help visualize the position of the stars WireframeBoxNode = SCNNode.Create(); WireframeBoxNode.Rotation = new SCNVector4(0, 1, 0, (float)(Math.PI / 4)); WireframeBoxNode.Geometry = SCNBox.Create(1, 1, 1, 0); WireframeBoxNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/box_wireframe", "png")); WireframeBoxNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting WireframeBoxNode.Geometry.FirstMaterial.DoubleSided = true; // double sided // Sun SunNode = SCNNode.Create(); SunNode.Position = new SCNVector3(0, 30, 0); ContentNode.AddChildNode(SunNode); SunNode.AddChildNode((SCNNode)WireframeBoxNode.Copy()); // Earth-rotation (center of rotation of the Earth around the Sun) var earthRotationNode = SCNNode.Create(); SunNode.AddChildNode(earthRotationNode); // Earth-group (will contain the Earth, and the Moon) EarthGroupNode = SCNNode.Create(); EarthGroupNode.Position = new SCNVector3(15, 0, 0); earthRotationNode.AddChildNode(EarthGroupNode); // Earth EarthNode = (SCNNode)WireframeBoxNode.Copy(); EarthNode.Position = new SCNVector3(0, 0, 0); EarthGroupNode.AddChildNode(EarthNode); // Rotate the Earth around the Sun var animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 10.0f; animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; earthRotationNode.AddAnimation(animation, new NSString("earth rotation around sun")); // Rotate the Earth animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 1.0f; animation.From = NSValue.FromVector(new SCNVector4(0, 1, 0, 0)); animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; EarthNode.AddAnimation(animation, new NSString("earth rotation")); break; case 2: // Moon-rotation (center of rotation of the Moon around the Earth) var moonRotationNode = SCNNode.Create(); EarthGroupNode.AddChildNode(moonRotationNode); // Moon MoonNode = (SCNNode)WireframeBoxNode.Copy(); MoonNode.Position = new SCNVector3(5, 0, 0); moonRotationNode.AddChildNode(MoonNode); // Rotate the moon around the Earth animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 1.5f; animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; moonRotationNode.AddAnimation(animation, new NSString("moon rotation around earth")); // Rotate the moon animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 1.5f; animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; MoonNode.AddAnimation(animation, new NSString("moon rotation")); break; case 3: // Add geometries (spheres) to represent the stars SunNode.Geometry = SCNSphere.Create(2.5f); EarthNode.Geometry = SCNSphere.Create(1.5f); MoonNode.Geometry = SCNSphere.Create(0.75f); // Add a textured plane to represent Earth's orbit var earthOrbit = SCNNode.Create(); earthOrbit.Opacity = 0.4f; earthOrbit.Geometry = SCNPlane.Create(31, 31); earthOrbit.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/orbit", "png")); earthOrbit.Geometry.FirstMaterial.Diffuse.MipFilter = SCNFilterMode.Linear; earthOrbit.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); earthOrbit.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting SunNode.AddChildNode(earthOrbit); break; case 4: // Add a halo to the Sun (a simple textured plane that does not write to depth) SunHaloNode = SCNNode.Create(); SunHaloNode.Geometry = SCNPlane.Create(30, 30); SunHaloNode.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)(Math.PI / 180.0f)); SunHaloNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/sun-halo", "png")); SunHaloNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting SunHaloNode.Geometry.FirstMaterial.WritesToDepthBuffer = false; // do not write to depth SunHaloNode.Opacity = 0.2f; SunNode.AddChildNode(SunHaloNode); // Add materials to the stars EarthNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-diffuse-mini", "jpg")); EarthNode.Geometry.FirstMaterial.Emission.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-emissive-mini", "jpg")); EarthNode.Geometry.FirstMaterial.Specular.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-specular-mini", "jpg")); MoonNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/moon", "jpg")); SunNode.Geometry.FirstMaterial.Multiply.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/sun", "jpg")); SunNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/sun", "jpg")); SunNode.Geometry.FirstMaterial.Multiply.Intensity = 0.5f; SunNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; SunNode.Geometry.FirstMaterial.Multiply.WrapS = SunNode.Geometry.FirstMaterial.Diffuse.WrapS = SunNode.Geometry.FirstMaterial.Multiply.WrapT = SunNode.Geometry.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Repeat; EarthNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = MoonNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = SunNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = true; EarthNode.Geometry.FirstMaterial.Shininess = 0.1f; EarthNode.Geometry.FirstMaterial.Specular.Intensity = 0.5f; MoonNode.Geometry.FirstMaterial.Specular.Contents = NSColor.Gray; // Achieve a lava effect by animating textures animation = CABasicAnimation.FromKeyPath("contentsTransform"); animation.Duration = 10.0f; var animationTransform1 = CATransform3D.MakeTranslation(0, 0, 0); animationTransform1 = animationTransform1.Concat(CATransform3D.MakeScale(3, 3, 3)); var animationTransform2 = CATransform3D.MakeTranslation(1, 0, 0); animationTransform2 = animationTransform1.Concat(CATransform3D.MakeScale(3, 3, 3)); animation.From = NSValue.FromCATransform3D(animationTransform1); animation.To = NSValue.FromCATransform3D(animationTransform2); animation.RepeatCount = float.MaxValue; SunNode.Geometry.FirstMaterial.Diffuse.AddAnimation(animation, new NSString("sun-texture")); animation = CABasicAnimation.FromKeyPath("contentsTransform"); animation.Duration = 30.0f; animationTransform1 = CATransform3D.MakeTranslation(0, 0, 0); animationTransform1 = animationTransform1.Concat(CATransform3D.MakeScale(5, 5, 5)); animationTransform2 = CATransform3D.MakeTranslation(1, 0, 0); animationTransform2 = animationTransform1.Concat(CATransform3D.MakeScale(5, 5, 5)); animation.From = NSValue.FromCATransform3D(animationTransform1); animation.To = NSValue.FromCATransform3D(animationTransform2); animation.RepeatCount = float.MaxValue; SunNode.Geometry.FirstMaterial.Multiply.AddAnimation(animation, new NSString("sun-texture2")); break; case 5: // We will turn off all the lights in the scene and add a new light // to give the impression that the Sun lights the scene var lightNode = SCNNode.Create(); lightNode.Light = SCNLight.Create(); lightNode.Light.Color = NSColor.Black; // initially switched off lightNode.Light.LightType = SCNLightType.Omni; SunNode.AddChildNode(lightNode); // Configure attenuation distances because we don't want to light the floor lightNode.Light.SetAttribute(new NSNumber(20), SCNLightAttribute.AttenuationEndKey); lightNode.Light.SetAttribute(new NSNumber(19.5), SCNLightAttribute.AttenuationStartKey); // Animation SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; lightNode.Light.Color = NSColor.White; // switch on presentationViewController.UpdateLightingWithIntensities(new float[] { 0.0f }); //switch off all the other lights SunHaloNode.Opacity = 0.5f; // make the halo stronger SCNTransaction.Commit(); break; } }
internal NSDictionary ToDictionary() { int n = 0; if (DirectionsMode.HasValue) { n++; } #if !WATCH if (MapType.HasValue) { n++; } #endif if (MapCenter.HasValue) { n++; } if (MapSpan.HasValue) { n++; } #if !WATCH if (ShowTraffic.HasValue) { n++; } if (Camera != null) { n++; } #endif if (n == 0) { return(null); } var keys = new NSObject [n]; var values = new NSObject [n]; int i = 0; if (DirectionsMode.HasValue) { keys [i] = MKMapItem.MKLaunchOptionsDirectionsModeKey; NSString v = MKMapItem.MKLaunchOptionsDirectionsModeDriving; switch (DirectionsMode.Value) { case MKDirectionsMode.Driving: v = MKMapItem.MKLaunchOptionsDirectionsModeDriving; break; case MKDirectionsMode.Transit: v = MKMapItem.MKLaunchOptionsDirectionsModeTransit; break; case MKDirectionsMode.Walking: v = MKMapItem.MKLaunchOptionsDirectionsModeWalking; break; #if !TV case MKDirectionsMode.Default: v = MKMapItem.MKLaunchOptionsDirectionsModeDefault; break; #endif } values [i++] = v; } #if !WATCH // MapType: __WATCHOS_PROHIBITED if (MapType.HasValue) { keys [i] = MKMapItem.MKLaunchOptionsMapTypeKey; values [i++] = new NSNumber((int)MapType.Value); } #endif if (MapCenter.HasValue) { keys [i] = MKMapItem.MKLaunchOptionsMapCenterKey; values [i++] = NSValue.FromMKCoordinate(MapCenter.Value); } if (MapSpan.HasValue) { keys [i] = MKMapItem.MKLaunchOptionsMapSpanKey; values [i++] = NSValue.FromMKCoordinateSpan(MapSpan.Value); } #if !WATCH // ShowsTraffic: __WATCHOS_PROHIBITED if (ShowTraffic.HasValue) { keys [i] = MKMapItem.MKLaunchOptionsShowsTrafficKey; values [i++] = new NSNumber(ShowTraffic.Value); } #endif #if !WATCH // MKLaunchOptionsCameraKey is allowed in WatchOS, but there's no MKMapCamera type. if (Camera != null) { keys [i] = MKMapItem.MKLaunchOptionsCameraKey; values [i++] = Camera; } #endif return(NSDictionary.FromObjectsAndKeys(values, keys)); }
private void InitElements() { // Enable back navigation using swipe. NavigationController.InteractivePopGestureRecognizer.Delegate = null; new AppDelegate().disableAllOrientation = true; keyboard_height = (float)(View.Frame.Height / 2); // Fires when keyboard shows. keyboardShowObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, (notification) => { NSValue nsKeyboardBounds = (NSValue)notification.UserInfo.ObjectForKey(UIKeyboard.BoundsUserInfoKey); keyboardBounds = nsKeyboardBounds.RectangleFValue; keyboard_height = keyboardBounds.Height; //if (needToScroll) //{ //if ((View.Frame.Height - keyboardBounds.Height - 50) < 360) //{ //scrollView.ContentOffset = new CoreGraphics.CGPoint(0, keyboardBounds.Height - 100); //} //} }); // Fires when keyboard hides. keyboardHideObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, (notification) => { //centering scroll //scrollView.ContentOffset = new CoreGraphics.CGPoint(0, 0); }); var deviceModel = Xamarin.iOS.DeviceHardware.Model; //image_bgIV.Frame = new Rectangle(0, 0, Convert.ToInt32(View.Frame.Width), Convert.ToInt32(View.Frame.Height)); if (deviceModel.Contains("X")) { headerView.Frame = new Rectangle(0, 0, Convert.ToInt32(View.Frame.Width), (Convert.ToInt32(View.Frame.Height) / 10) + 8); backBn.Frame = new Rectangle(0, (Convert.ToInt32(View.Frame.Width) / 20) + 20, Convert.ToInt32(View.Frame.Width) / 8, Convert.ToInt32(View.Frame.Width) / 8); headerLabel.Frame = new Rectangle(Convert.ToInt32(View.Frame.Width) / 5, (Convert.ToInt32(View.Frame.Width) / 12) + 20, (Convert.ToInt32(View.Frame.Width) / 5) * 3, Convert.ToInt32(View.Frame.Width) / 18); resetBn.Frame = new Rectangle(Convert.ToInt32(View.Frame.Width - View.Frame.Width / 4), Convert.ToInt32(View.Frame.Width) / 12 + 20, Convert.ToInt32(View.Frame.Width) / 4, Convert.ToInt32(View.Frame.Width) / 19); } else { headerView.Frame = new Rectangle(0, 0, Convert.ToInt32(View.Frame.Width), (Convert.ToInt32(View.Frame.Height) / 10)); backBn.Frame = new Rectangle(0, Convert.ToInt32(View.Frame.Width) / 20, Convert.ToInt32(View.Frame.Width) / 8, Convert.ToInt32(View.Frame.Width) / 8); headerLabel.Frame = new Rectangle(Convert.ToInt32(View.Frame.Width) / 5, Convert.ToInt32(View.Frame.Width) / 12, (Convert.ToInt32(View.Frame.Width) / 5) * 3, Convert.ToInt32(View.Frame.Width) / 18); resetBn.Frame = new Rectangle(Convert.ToInt32(View.Frame.Width - View.Frame.Width / 4), Convert.ToInt32(View.Frame.Width) / 12, Convert.ToInt32(View.Frame.Width) / 4, Convert.ToInt32(View.Frame.Width) / 19); } headerView.BackgroundColor = UIColor.FromRGB(36, 43, 52); View.BackgroundColor = UIColor.FromRGB(36, 43, 52); headerLabel.Text = "Домашний адрес"; activityIndicator.Color = UIColor.FromRGB(255, 99, 62); activityIndicator.Frame = new Rectangle((int)(View.Frame.Width / 2 - View.Frame.Width / 20), (int)(headerView.Frame.Height * 2), (int)(View.Frame.Width / 10), (int)(View.Frame.Width / 10)); backBn.ImageEdgeInsets = new UIEdgeInsets(backBn.Frame.Height / 3.5F, backBn.Frame.Width / 2.35F, backBn.Frame.Height / 3.5F, backBn.Frame.Width / 3); scrollView.Frame = new Rectangle(0, Convert.ToInt32(headerView.Frame.Y + headerView.Frame.Height), Convert.ToInt32(View.Frame.Width), (Convert.ToInt32(View.Frame.Height - headerView.Frame.Height))); scrollView.KeyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive; scrollView.Hidden = true; applyAddressBn.BackgroundColor = UIColor.FromRGB(255, 99, 62); view_in_scroll.Frame = new Rectangle(0, 0 /*Convert.ToInt32(headerView.Frame.Y + headerView.Frame.Height*1.2)*/, Convert.ToInt32(View.Frame.Width), Convert.ToInt32(scrollView.Frame.Height /*- headerView.Frame.Height * 1.2)*/)); CountryTextField = new FloatingTextField { TranslatesAutoresizingMaskIntoConstraints = false, Placeholder = "Страна", TextColor = UIColor.White, ReturnKeyType = UIReturnKeyType.Next }; CountryTextField.ShouldReturn = _ => RegionTextField.BecomeFirstResponder(); RegionTextField = new FloatingTextField { TranslatesAutoresizingMaskIntoConstraints = false, Placeholder = "Регион", TextColor = UIColor.White, ReturnKeyType = UIReturnKeyType.Next }; RegionTextField.ShouldReturn = _ => CityTextField.BecomeFirstResponder(); CityTextField = new FloatingTextField { TranslatesAutoresizingMaskIntoConstraints = false, Placeholder = "Город", TextColor = UIColor.White, ReturnKeyType = UIReturnKeyType.Next }; CityTextField.ShouldReturn = _ => DetailAddressTextField.BecomeFirstResponder(); DetailAddressTextField = new FloatingTextField { TranslatesAutoresizingMaskIntoConstraints = false, Placeholder = "Улица, Дом, Корпус, Квартира", TextColor = UIColor.White, ReturnKeyType = UIReturnKeyType.Next }; DetailAddressTextField.ShouldReturn = _ => IndexTextField.BecomeFirstResponder(); IndexTextField = new FloatingTextField { TranslatesAutoresizingMaskIntoConstraints = false, Placeholder = "Индекс", TextColor = UIColor.White, KeyboardType = UIKeyboardType.NumberPad, ReturnKeyType = UIReturnKeyType.Next }; IndexTextField.ShouldReturn = _ => NotationTextField.BecomeFirstResponder(); NotationTextField = new FloatingTextField { TranslatesAutoresizingMaskIntoConstraints = false, Placeholder = "Примечание", TextColor = UIColor.White, ReturnKeyType = UIReturnKeyType.Done }; NotationTextField.ShouldReturn = _ => View.EndEditing(true);//CoordsTextField.BecomeFirstResponder(); CoordsTextField = new FloatingTextField { TranslatesAutoresizingMaskIntoConstraints = false, Placeholder = "Координаты", TextColor = UIColor.White, ReturnKeyType = UIReturnKeyType.Done }; CoordsTextField.ShouldReturn = _ => View.EndEditing(true); CoordsRemoveBn = new UIButton { BackgroundColor = UIColor.Clear }; CoordsRemoveBn.Frame = new CoreGraphics.CGRect(0, 430, View.Frame.Width, 60); //CountryTextField.EditingDidBegin += SetInsets; //RegionTextField.EditingDidBegin += SetInsets; //CityTextField.EditingDidBegin += SetInsets; //DetailAddressTextField.EditingDidBegin += SetInsets; //IndexTextField.EditingDidBegin += SetInsets; //NotationTextField.EditingDidBegin += SetInsets; view_in_scroll.AddSubviews(CountryTextField, RegionTextField, CityTextField, DetailAddressTextField, IndexTextField, NotationTextField, CoordsTextField, CoordsRemoveBn); view_in_scroll.AddConstraints(new NSLayoutConstraint[] { CountryTextField.TopAnchor.ConstraintEqualTo(view_in_scroll.TopAnchor, 12), CountryTextField.LeadingAnchor.ConstraintEqualTo(view_in_scroll.LeadingAnchor, 16), CountryTextField.TrailingAnchor.ConstraintEqualTo(view_in_scroll.TrailingAnchor, -16), CountryTextField.HeightAnchor.ConstraintEqualTo(48), RegionTextField.TopAnchor.ConstraintEqualTo(CountryTextField.TopAnchor, 70), RegionTextField.LeadingAnchor.ConstraintEqualTo(CountryTextField.LeadingAnchor, 0), RegionTextField.TrailingAnchor.ConstraintEqualTo(CountryTextField.TrailingAnchor, 0), RegionTextField.HeightAnchor.ConstraintEqualTo(48), CityTextField.TopAnchor.ConstraintEqualTo(RegionTextField.TopAnchor, 70), CityTextField.LeadingAnchor.ConstraintEqualTo(RegionTextField.LeadingAnchor, 0), CityTextField.TrailingAnchor.ConstraintEqualTo(RegionTextField.TrailingAnchor, 0), CityTextField.HeightAnchor.ConstraintEqualTo(48), DetailAddressTextField.TopAnchor.ConstraintEqualTo(CityTextField.TopAnchor, 70), DetailAddressTextField.LeadingAnchor.ConstraintEqualTo(CityTextField.LeadingAnchor, 0), DetailAddressTextField.TrailingAnchor.ConstraintEqualTo(CityTextField.TrailingAnchor, 0), DetailAddressTextField.HeightAnchor.ConstraintEqualTo(48), IndexTextField.TopAnchor.ConstraintEqualTo(DetailAddressTextField.TopAnchor, 70), IndexTextField.LeadingAnchor.ConstraintEqualTo(DetailAddressTextField.LeadingAnchor, 0), IndexTextField.TrailingAnchor.ConstraintEqualTo(DetailAddressTextField.TrailingAnchor, 0), IndexTextField.HeightAnchor.ConstraintEqualTo(48), NotationTextField.TopAnchor.ConstraintEqualTo(IndexTextField.TopAnchor, 70), NotationTextField.LeadingAnchor.ConstraintEqualTo(IndexTextField.LeadingAnchor, 0), NotationTextField.TrailingAnchor.ConstraintEqualTo(IndexTextField.TrailingAnchor, 0), NotationTextField.HeightAnchor.ConstraintEqualTo(48), CoordsTextField.TopAnchor.ConstraintEqualTo(NotationTextField.TopAnchor, 70), CoordsTextField.LeadingAnchor.ConstraintEqualTo(NotationTextField.LeadingAnchor, 0), CoordsTextField.TrailingAnchor.ConstraintEqualTo(NotationTextField.TrailingAnchor, 0), CoordsTextField.HeightAnchor.ConstraintEqualTo(48), CoordsRemoveBn.TopAnchor.ConstraintEqualTo(NotationTextField.TopAnchor, 70), CoordsRemoveBn.LeadingAnchor.ConstraintEqualTo(NotationTextField.LeadingAnchor, 0), CoordsRemoveBn.TrailingAnchor.ConstraintEqualTo(NotationTextField.TrailingAnchor, 0), CoordsRemoveBn.HeightAnchor.ConstraintEqualTo(48), }); resetBn.SetTitle("Сбросить", UIControlState.Normal); applyAddressBn.SetTitle("ПОДТВЕРДИТЬ АДРЕС", UIControlState.Normal); mapAddressBn.Layer.BorderColor = UIColor.FromRGB(255, 99, 62).CGColor; mapAddressBn.Layer.BorderWidth = 1f; mapAddressBn.SetTitle("ВЫБРАТЬ НА КАРТЕ", UIControlState.Normal); applyAddressBn.Font = UIFont.FromName(Constants.fira_sans, 15f); mapAddressBn.Font = UIFont.FromName(Constants.fira_sans, 15f); resetBn.Font = UIFont.FromName(Constants.fira_sans, 15f); if (!deviceModel.Contains("e 5") && !deviceModel.Contains("e 4") && !deviceModel.ToLower().Contains("e se")) { applyAddressBn.Frame = new Rectangle(Convert.ToInt32(View.Frame.Width) / 15, 600, Convert.ToInt32(View.Frame.Width) - ((Convert.ToInt32(View.Frame.Width) / 15) * 2), Convert.ToInt32(View.Frame.Height) / 12); mapAddressBn.Frame = new Rectangle(Convert.ToInt32(View.Frame.Width) / 15, Convert.ToInt32(applyAddressBn.Frame.Y - (int)(applyAddressBn.Frame.Height + 10)), Convert.ToInt32(View.Frame.Width) - ((Convert.ToInt32(View.Frame.Width) / 15) * 2), Convert.ToInt32(View.Frame.Height) / 12); } else { applyAddressBn.Frame = new Rectangle(Convert.ToInt32(View.Frame.Width) / 15, Convert.ToInt32(view_in_scroll.Frame.Height + 60 - headerView.Frame.Height / 3), Convert.ToInt32(View.Frame.Width) - ((Convert.ToInt32(View.Frame.Width) / 15) * 2), Convert.ToInt32(View.Frame.Height) / 12); mapAddressBn.Frame = new Rectangle(Convert.ToInt32(View.Frame.Width) / 15, Convert.ToInt32(applyAddressBn.Frame.Y - (int)(applyAddressBn.Frame.Height + 10)), Convert.ToInt32(View.Frame.Width) - ((Convert.ToInt32(View.Frame.Width) / 15) * 2), Convert.ToInt32(View.Frame.Height) / 12); var diff = view_in_scroll.Frame.Height - (applyAddressBn.Frame.Y + applyAddressBn.Frame.Height); if (diff < 0) { view_in_scroll.Frame = new Rectangle(0, 0 /*Convert.ToInt32(headerView.Frame.Y + headerView.Frame.Height*1.2)*/, Convert.ToInt32(View.Frame.Width), Convert.ToInt32(applyAddressBn.Frame.Y + applyAddressBn.Frame.Height)); } } SetScrollViewContentSize(); }
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; } }
private static void Check(NSValue val) { Assert.IsNotNull(val, "Value cannot be null"); Assert.AreNotEqual(IntPtr.Zero, val.NativePointer, "Native pointer cannot be null"); }
protected override void OnElementChanged(ElementChangedEventArgs <Editor> e) { base.OnElementChanged(e); if (e.NewElement != null) { var view = (RoundedEditor)Element; //Control.LeftView = new UIView(new CGRect(0f, 0f, 9f, 20f)); //Control.LeftViewMode = UITextFieldViewMode.Always; Control.KeyboardAppearance = UIKeyboardAppearance.Dark; Control.ReturnKeyType = UIReturnKeyType.Done; Control.Layer.CornerRadius = Convert.ToSingle(view.CornerRadius); Control.Layer.BorderColor = view.BorderColor.ToCGColor(); Control.Layer.BorderWidth = view.BorderWidth; Control.ClipsToBounds = true; RegisterForKeyboardNotifications(); } if (e.OldElement != null) { UnregisterForKeyboardNotifications(); } if (Control != null) { Control.ScrollEnabled = false; } //Sets maximum number of lines *Not too sure about this one* CGSize size = Control.Text.StringSize(Control.Font, Control.Frame.Size, UILineBreakMode.WordWrap); int numLines = (int)(size.Height / Control.Font.LineHeight); if (numLines >= 5) { Control.ScrollEnabled = true; } void RegisterForKeyboardNotifications() { if (_keyboardShowObserver == null) { _keyboardShowObserver = UIKeyboard.Notifications.ObserveWillShow(OnKeyboardShow); } if (_keyboardHideObserver == null) { _keyboardHideObserver = UIKeyboard.Notifications.ObserveWillHide(OnKeyboardHide); } } void OnKeyboardShow(object sender, UIKeyboardEventArgs args) { NSValue result = (NSValue)args.Notification.UserInfo.ObjectForKey(new NSString(UIKeyboard.FrameEndUserInfoKey)); CGSize keyboardSize = result.RectangleFValue.Size; if (Element != null) { Element.Margin = new Thickness(0, 0, 0, keyboardSize.Height); //push the entry up to keyboard height when keyboard is activated } } void OnKeyboardHide(object sender, UIKeyboardEventArgs args) { if (Element != null) { Element.Margin = new Thickness(0); //set the margins to zero when keyboard is dismissed } } void UnregisterForKeyboardNotifications() { if (_keyboardShowObserver != null) { _keyboardShowObserver.Dispose(); _keyboardShowObserver = null; } if (_keyboardHideObserver != null) { _keyboardHideObserver.Dispose(); _keyboardHideObserver = null; } } }
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; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); switch (index) { case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.SetSubtitle("API"); TextManager.AddEmptyLine(); TextManager.AddCode("#aMaterial.#ShaderModifiers# = new SCNShaderModifiers {\n" + " <Entry Point> = <GLSL Code>\n" + "};#"); TextManager.FlipInText(SlideTextManager.TextType.Code); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); break; case 2: TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.AddEmptyLine(); TextManager.AddCode("#aMaterial.#ShaderModifiers# = new SCNShaderModifiers { \n" + " EntryCGPointragment = \n" + " new Vector3 (1.0f) - #output#.Color.GetRgb () \n" + "};#"); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 3: TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("Entry points"); TextManager.AddBulletAtLevel("Geometry", 0); TextManager.AddBulletAtLevel("Surface", 0); TextManager.AddBulletAtLevel("Lighting", 0); TextManager.AddBulletAtLevel("Fragment", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); break; case 4: SCNTransaction.AnimationDuration = 1; TextManager.HighlightBullet(0); // Create a (very) tesselated plane var plane = SCNPlane.Create(10, 10); plane.WidthSegmentCount = 200; plane.HeightSegmentCount = 200; // Setup the material (same as the floor) plane.FirstMaterial.Diffuse.WrapS = SCNWrapMode.Mirror; plane.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Mirror; plane.FirstMaterial.Diffuse.Contents = new NSImage("/Library/Desktop Pictures/Circles.jpg"); plane.FirstMaterial.Diffuse.ContentsTransform = SCNMatrix4.CreateFromAxisAngle(new SCNVector3(0, 0, 1), NMath.PI / 4); plane.FirstMaterial.Specular.Contents = NSColor.White; plane.FirstMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap", "jpg")); plane.FirstMaterial.Reflective.Intensity = 0.0f; // Create a node to hold that plane PlaneNode = SCNNode.Create(); PlaneNode.Position = new SCNVector3(0, 0.1f, 0); PlaneNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); PlaneNode.Scale = new SCNVector3(5, 5, 1); PlaneNode.Geometry = plane; ContentNode.AddChildNode(PlaneNode); // Attach the "wave" shader modifier, and set an initial intensity value of 0 var shaderFile = NSBundle.MainBundle.PathForResource("Shaders/wave", "shader"); var geometryModifier = File.ReadAllText(shaderFile); PlaneNode.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = geometryModifier }; PlaneNode.Geometry.SetValueForKey(new NSNumber(0.0f), new NSString("intensity")); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; // Show the pseudo code for the deformation var textNode = TextManager.AddCode("#float len = #geometry#.Position.Xy.Length;\n" + "aMaterial.ShaderModifiers = new SCNShaderModifiers { \n" + " #EntryPointGeometry# = geometry.Position.Y \n" + "};#"); textNode.Position = new SCNVector3(8.5f, 7, 0); SCNTransaction.Commit(); break; case 5: // Progressively increase the intensity SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 2; PlaneNode.Geometry.SetValueForKey(new NSNumber(1.0f), new NSString("intensity")); PlaneNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f; SCNTransaction.Commit(); // Redraw forever ((SCNView)presentationViewController.View).Playing = true; ((SCNView)presentationViewController.View).Loops = true; break; case 6: SCNTransaction.AnimationDuration = 1; TextManager.FadeOutText(SlideTextManager.TextType.Code); // Hide the plane used for the previous modifier PlaneNode.Geometry.SetValueForKey(new NSNumber(0.0f), new NSString("intensity")); PlaneNode.Geometry.FirstMaterial.Reflective.Intensity = 0.0f; PlaneNode.Opacity = 0.0f; // Create a sphere to illustrate the "car paint" modifier var sphere = SCNSphere.Create(6); sphere.SegmentCount = 100; sphere.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/noise", "png")); sphere.FirstMaterial.Diffuse.WrapS = SCNWrapMode.Repeat; sphere.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Repeat; sphere.FirstMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap3", "jpg")); sphere.FirstMaterial.FresnelExponent = 1.3f; SphereNode = SCNNode.FromGeometry(sphere); SphereNode.Position = new SCNVector3(5, 6, 0); GroundNode.AddChildNode(SphereNode); // Attach the "car paint" shader modifier shaderFile = NSBundle.MainBundle.PathForResource("Shaders/carPaint", "shader"); var surfaceModifier = File.ReadAllText(shaderFile); sphere.FirstMaterial.ShaderModifiers = new SCNShaderModifiers { EntryPointSurface = surfaceModifier }; var rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 15.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.By = NSValue.FromVector(new SCNVector4(0, 1, 0, -(float)(Math.PI * 2))); SphereNode.AddAnimation(rotationAnimation, new NSString("sphereNodeAnimation")); TextManager.HighlightBullet(1); break; case 7: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.5f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); // Move the camera closer presentationViewController.CameraNode.Position = new SCNVector3(5, -0.5f, -17); SCNTransaction.Commit(); break; case 8: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); // Move back presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 0); SCNTransaction.Commit(); break; case 9: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; // Hide the sphere used for the previous modifier SphereNode.Opacity = 0.0f; SphereNode.Position = new SCNVector3(6, 4, -8); SCNTransaction.Commit(); SCNTransaction.AnimationDuration = 0; TextManager.HighlightBullet(2); // Load the model, animate var intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(4, 0.1f, 10); TorusNode = Utils.SCAddChildNode(intermediateNode, "torus", "Scenes/torus/torus", 11); rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 10.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); TorusNode.AddAnimation(rotationAnimation, new NSString("torusNodeAnimation")); GroundNode.AddChildNode(intermediateNode); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; intermediateNode.Position = new SCNVector3(4, 0.1f, 0); SCNTransaction.Commit(); break; case 10: // Attach the shader modifier shaderFile = NSBundle.MainBundle.PathForResource("Shaders/toon", "shader"); var lightingModifier = File.ReadAllText(shaderFile); TorusNode.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointLightingModel = lightingModifier }; break; case 11: SCNTransaction.AnimationDuration = 1.0f; // Hide the torus used for the previous modifier TorusNode.Position = new SCNVector3(TorusNode.Position.X, TorusNode.Position.Y, TorusNode.Position.Z - 10); TorusNode.Opacity = 0.0f; // Load the model, animate intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(4, -2.6f, 14); intermediateNode.Scale = new SCNVector3(70, 70, 70); XRayNode = Utils.SCAddChildNode(intermediateNode, "node", "Scenes/bunny", 12); XRayNode.Position = new SCNVector3(0, 0, 0); XRayNode.Opacity = 0.0f; GroundNode.AddChildNode(intermediateNode); rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 10.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.From = NSValue.FromVector(new SCNVector4(0, 1, 0, 0)); rotationAnimation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); intermediateNode.AddAnimation(rotationAnimation, new NSString("bunnyNodeAnimation")); TextManager.HighlightBullet(3); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; XRayNode.Opacity = 1.0f; intermediateNode.Position = new SCNVector3(4, -2.6f, -2); SCNTransaction.Commit(); break; case 12: // Attach the "x ray" modifier shaderFile = NSBundle.MainBundle.PathForResource("Shaders/xRay", "shader"); var fragmentModifier = File.ReadAllText(shaderFile); XRayNode.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointFragment = fragmentModifier }; XRayNode.Geometry.FirstMaterial.ReadsFromDepthBuffer = false; break; case 13: // Highlight everything TextManager.HighlightBullet(-1); // Hide the node used for the previous modifier XRayNode.Opacity = 0.0f; XRayNode.ParentNode.Position = new SCNVector3(4, -2.6f, -5); // Create the model sphere = SCNSphere.Create(5); sphere.SegmentCount = 150; // tesselate a lot VirusNode = SCNNode.FromGeometry(sphere); VirusNode.Position = new SCNVector3(3, 6, 0); VirusNode.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)(Math.PI / 180.0f)); GroundNode.AddChildNode(VirusNode); // Set the shader modifiers var geomFile = NSBundle.MainBundle.PathForResource("Shaders/sm_geom", "shader"); var surfFile = NSBundle.MainBundle.PathForResource("Shaders/sm_surf", "shader"); var lightFile = NSBundle.MainBundle.PathForResource("Shaders/sm_light", "shader"); var fragFile = NSBundle.MainBundle.PathForResource("Shaders/sm_frag", "shader"); geometryModifier = File.ReadAllText(geomFile); surfaceModifier = File.ReadAllText(surfFile); lightingModifier = File.ReadAllText(lightFile); fragmentModifier = File.ReadAllText(fragFile); VirusNode.Geometry.FirstMaterial.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = geometryModifier, EntryPointSurface = surfaceModifier, EntryPointLightingModel = lightingModifier, EntryPointFragment = fragmentModifier }; break; case 14: SCNTransaction.AnimationDuration = 1.0f; // Hide the node used for the previous modifier VirusNode.Opacity = 0.0f; VirusNode.Position = new SCNVector3(3, 6, -10); // Change the text TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("SCNShadable"); TextManager.AddBulletAtLevel("Protocol adopted by SCNMaterial and SCNGeometry", 0); TextManager.AddBulletAtLevel("Shaders parameters are animatable", 0); TextManager.AddBulletAtLevel("Texture samplers are bound to a SCNMaterialProperty", 0); TextManager.AddCode("#var aProperty = SCNMaterialProperty.#Create# (anImage);\n" + "aMaterial.#SetValueForKey# (aProperty, #new NSString# (\"aSampler\"));#"); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case (int)ParticleSteps.Fire: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Particle Image", 0); TextManager.AddBulletAtLevel("Color over life duration", 0); TextManager.AddBulletAtLevel("Size over life duration", 0); TextManager.AddBulletAtLevel("Several blend modes", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); var hole = SCNNode.Create(); hole.Geometry = SCNTube.Create(1.7f, 1.9f, 1.5f); hole.Position = new SCNVector3(0, 0, HOLE_Z); hole.Scale = new SCNVector3(1, 0, 1); GroundNode.AddChildNode(hole); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5f; hole.Scale = new SCNVector3(1, 1, 1); SCNTransaction.Commit(); var ps = SCNParticleSystem.Create("fire", "Particles"); hole.AddParticleSystem(ps); Hole = hole; break; case (int)ParticleSteps.FireScreen: ps = Hole.ParticleSystems [0]; ps.BlendMode = SCNParticleBlendMode.Screen; break; case (int)ParticleSteps.Local: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Local vs Global", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); Hole.RemoveAllParticleSystems(); Hole2 = Hole.Clone(); Hole2.Geometry = (SCNGeometry)Hole.Geometry.Copy(); Hole2.Position = new SCNVector3(0, -2, HOLE_Z - 4); GroundNode.AddChildNode(Hole2); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5; Hole2.Position = new SCNVector3(0, 0, HOLE_Z - 4); SCNTransaction.Commit(); ps = SCNParticleSystem.Create("reactor", "Particles"); ps.ParticleColorVariation = new SCNVector4(0, 0, 0.5f, 0); Hole.AddParticleSystem(ps); var localPs = (SCNParticleSystem)ps.Copy(); localPs.ParticleImage = ps.ParticleImage; localPs.Local = true; Hole2.AddParticleSystem(localPs); var animation = CABasicAnimation.FromKeyPath("position"); animation.From = NSValue.FromVector(new SCNVector3(7, 0, HOLE_Z)); animation.To = NSValue.FromVector(new SCNVector3(-7, 0, HOLE_Z)); animation.BeginTime = CAAnimation.CurrentMediaTime() + 0.75; animation.Duration = 8; animation.AutoReverses = true; animation.RepeatCount = float.MaxValue; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimeOffset = animation.Duration / 2; Hole.AddAnimation(animation, new NSString("animateHole")); animation = CABasicAnimation.FromKeyPath("position"); animation.From = NSValue.FromVector(new SCNVector3(-7, 0, HOLE_Z - 4)); animation.To = NSValue.FromVector(new SCNVector3(7, 0, HOLE_Z - 4)); animation.BeginTime = CAAnimation.CurrentMediaTime() + 0.75; animation.Duration = 8; animation.AutoReverses = true; animation.RepeatCount = float.MaxValue; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimeOffset = animation.Duration / 2; Hole2.AddAnimation(animation, new NSString("animateHole")); break; case (int)ParticleSteps.Gravity: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Affected by gravity", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); Hole2.RemoveAllParticleSystems(); Hole2.RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.ScaleTo(0, 0.5), SCNAction.RemoveFromParentNode() })); Hole.RemoveAllParticleSystems(); Hole.RemoveAnimation(new NSString("animateHole"), 0.5f); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5; var tube = (SCNTube)Hole.Geometry; tube.InnerRadius = 0.3f; tube.OuterRadius = 0.4f; tube.Height = 1.0f; SCNTransaction.Commit(); ps = SCNParticleSystem.Create("sparks", "Particles"); Hole.RemoveAllParticleSystems(); Hole.AddParticleSystem(ps); foreach (var child in ((SCNView)presentationViewController.View).Scene.RootNode.ChildNodes) { if (child.Geometry != null) { if (child.Geometry.GetType() == typeof(SCNFloor)) { FloorNode = child; } } } /*FloorNode = ((SCNView)presentationViewController.View).Scene.RootNode.FindNodes ((SCNNode child, out bool stop) => { * stop = false; * if (child.Geometry != null) * stop = (child.Geometry.GetType () == typeof(SCNFloor)); * return stop; * });*/ /*FloorNode = [presentationViewController.view.scene.rootNode childNodesPassingTest:^BOOL(SCNNode *child, BOOL *stop) { * return [child.geometry isKindOfClass:[SCNFloor class]]; * }][0];*/ ps.ColliderNodes = new SCNNode[] { FloorNode }; break; case (int)ParticleSteps.Collider: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Affected by colliders", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); var boxNode = SCNNode.Create(); boxNode.Geometry = SCNBox.Create(5, 0.2f, 5, 0); boxNode.Position = new SCNVector3(0, 7, HOLE_Z); boxNode.Geometry.FirstMaterial.Emission.Contents = NSColor.DarkGray; GroundNode.AddChildNode(boxNode); ps = Hole.ParticleSystems [0]; ps.ColliderNodes = new SCNNode[] { FloorNode, boxNode }; animation = CABasicAnimation.FromKeyPath("eulerAngles"); animation.From = NSValue.FromVector(new SCNVector3(0, 0, (nfloat)Math.PI / 4 * 1.7f)); animation.To = NSValue.FromVector(new SCNVector3(0, 0, -(nfloat)Math.PI / 4 * 1.7f)); animation.BeginTime = CAAnimation.CurrentMediaTime() + 0.5; animation.Duration = 2; animation.AutoReverses = true; animation.RepeatCount = float.MaxValue; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimeOffset = animation.Duration / 2; boxNode.AddAnimation(animation, new NSString("animateHole")); BoxNode = boxNode; break; case (int)ParticleSteps.Fields: Hole.RemoveAllParticleSystems(); Hole.RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.ScaleTo(0, 0.75), SCNAction.RemoveFromParentNode() })); BoxNode.RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.MoveBy(0, 15, 0, 1.0), SCNAction.RemoveFromParentNode() })); var particleHolder = SCNNode.Create(); particleHolder.Position = new SCNVector3(0, 20, HOLE_Z); GroundNode.AddChildNode(particleHolder); ParticleHolder = particleHolder; TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Affected by physics fields", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); ps = SCNParticleSystem.Create("snow", "Particles"); ps.AffectedByPhysicsFields = true; ParticleHolder.AddParticleSystem(ps); Snow = ps; //physics field var field = SCNPhysicsField.CreateTurbulenceField(50, 1); field.HalfExtent = new SCNVector3(20, 20, 20); field.Strength = 4.0f; var fieldOwner = SCNNode.Create(); fieldOwner.Position = new SCNVector3(0, 5, HOLE_Z); GroundNode.AddChildNode(fieldOwner); fieldOwner.PhysicsField = field; FieldOwner = fieldOwner; ps.ColliderNodes = new SCNNode[] { FloorNode }; break; case (int)ParticleSteps.FieldsVortex: VortexFieldOwner = SCNNode.Create(); VortexFieldOwner.Position = new SCNVector3(0, 5, HOLE_Z); GroundNode.AddChildNode(VortexFieldOwner); //tornado var worldOrigin = new SCNVector3(FieldOwner.WorldTransform.M41, FieldOwner.WorldTransform.M42, FieldOwner.WorldTransform.M43); var worldAxis = new SCNVector3(0, 1, 0); var vortex = SCNPhysicsField.CustomField((SCNVector3 position, SCNVector3 velocity, float mass, float charge, double timeInSeconds) => { var l = new SCNVector3(); l.X = worldOrigin.X - position.X; l.Z = worldOrigin.Z - position.Z; SCNVector3 t = Cross(worldAxis, l); var d2 = (l.X * l.X + l.Z * l.Z); var vs = (nfloat)(VS / Math.Sqrt(d2)); var fy = (nfloat)(1.0 - (Math.Min(1.0, (position.Y / 15.0)))); return(new SCNVector3(t.X * vs + l.X * (nfloat)VW * fy, 0, t.Z * vs + l.Z * (nfloat)VW * fy)); }); vortex.HalfExtent = new SCNVector3(100, 100, 100); VortexFieldOwner.PhysicsField = vortex; break; case (int)ParticleSteps.SubSystems: FieldOwner.RemoveFromParentNode(); ParticleHolder.RemoveAllParticleSystems(); Snow.DampingFactor = -1; TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Sub-particle system on collision", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); ps = SCNParticleSystem.Create("rain", "Particles"); var pss = SCNParticleSystem.Create("plok", "Particles"); pss.IdleDuration = 0; pss.Loops = false; ps.SystemSpawnedOnCollision = pss; ParticleHolder.AddParticleSystem(ps); ps.ColliderNodes = new SCNNode[] { FloorNode }; break; case (int)ParticleSteps.Confetti: ParticleHolder.RemoveAllParticleSystems(); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Custom blocks", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); ps = SCNParticleSystem.Create(); ps.EmitterShape = SCNBox.Create(20, 9, 5, 0); ps.BirthRate = 100; ps.ParticleLifeSpan = 10; ps.ParticleLifeSpanVariation = 0; ps.SpreadingAngle = 20; ps.ParticleSize = 0.25f; ps.ParticleVelocity = 10; ps.ParticleVelocityVariation = 19; ps.BirthDirection = SCNParticleBirthDirection.Constant; ps.EmittingDirection = new SCNVector3(0, -1, 0); ps.BirthLocation = SCNParticleBirthLocation.Volume; ps.ParticleImage = new NSImage(NSBundle.MainBundle.PathForResource("Particles/confetti", "png")); ps.LightingEnabled = true; ps.OrientationMode = SCNParticleOrientationMode.Free; ps.SortingMode = SCNParticleSortingMode.Distance; ps.ParticleAngleVariation = 180; ps.ParticleAngularVelocity = 200; ps.ParticleAngularVelocityVariation = 400; ps.ParticleColor = NSColor.Green; ps.ParticleColorVariation = new SCNVector4(0.2f, 0.1f, 0.1f, 0); ps.ParticleBounce = 0; ps.ParticleFriction = 0.6f; ps.ColliderNodes = new SCNNode[] { FloorNode }; ps.BlendMode = SCNParticleBlendMode.Alpha; var floatAnimation = CAKeyFrameAnimation.FromKeyPath(""); floatAnimation.Values = new NSNumber[] { 1, 1, 0 }; floatAnimation.KeyTimes = new NSNumber[] { 0, 0.9f, 1 }; floatAnimation.Duration = 1.0f; floatAnimation.Additive = false; //ps.PropertyControllers = @{ SCNParticlePropertyOpacity: [SCNParticlePropertyController controllerWithAnimation:floatAnimation] }; //ps.HandleEvent (SCNParticleEvent.Birth, /*[ps handleEvent:SCNParticleEventBirth forProperties:@[SCNParticlePropertyColor] withBlock:^(void **data, size_t *dataStride, uint32_t *indices , NSInteger count) { * * for (int i = 0; i < count; ++i) { * var col = (float *)((char *)data[0] + dataStride[0] * i); * if (rand() & 0x1) { // swith green for red * col[0] = col[1]; * col[1] = 0; * } * * } * }];*/ /*[ps handleEvent:SCNParticleEventCollision forProperties:@[SCNParticlePropertyAngle, SCNParticlePropertyRotationAxis, SCNParticlePropertyAngularVelocity, SCNParticlePropertyVelocity, SCNParticlePropertyContactNormal] withBlock:^(void **data, size_t *dataStride, uint32_t *indices , NSInteger count) { * * for (NSInteger i = 0; i < count; ++i) { * // fix orientation * float *angle = (float *)((char *)data[0] + dataStride[0] * indices[i]); * float *axis = (float *)((char *)data[1] + dataStride[1] * indices[i]); * * float *colNrm = (float *)((char *)data[4] + dataStride[4] * indices[i]); * SCNVector3 collisionNormal = {colNrm[0], colNrm[1], colNrm[2]}; * SCNVector3 cp = SCNVector3CrossProduct(collisionNormal, SCNVector3Make(0, 0, 1)); * CGFloat cpLen = SCNVector3Length(cp); * angle[0] = asin(cpLen); * * axis[0] = cp.x / cpLen; * axis[1] = cp.y / cpLen; * axis[2] = cp.z / cpLen; * * // kill angular rotation * float *angVel = (float *)((char *)data[2] + dataStride[2] * indices[i]); * angVel[0] = 0; * * if (colNrm[1] > 0.4) { * float *vel = (float *)((char *)data[3] + dataStride[3] * indices[i]); * vel[0] = 0; * vel[1] = 0; * vel[2] = 0; * } * } * }];*/ ParticleHolder.AddParticleSystem(ps); break; case (int)ParticleSteps.EmitterCube: ParticleHolder.RemoveAllParticleSystems(); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Emitter shape", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); ParticleHolder.RemoveFromParentNode(); ps = SCNParticleSystem.Create("emitters", "Particles"); ps.Local = true; ParticleHolder.AddParticleSystem(ps); var node = SCNNode.Create(); node.Position = new SCNVector3(3, 6, HOLE_Z); node.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy((float)Math.PI * 2, new SCNVector3(0.3f, 1, 0), 8))); GroundNode.AddChildNode(node); Bokeh = ps; node.AddParticleSystem(ps); break; case (int)ParticleSteps.EmitterSphere: Bokeh.EmitterShape = SCNSphere.Create(5); break; case (int)ParticleSteps.EmitterTorus: Bokeh.EmitterShape = SCNTorus.Create(5, 1); break; } }
private void BuildImageGrid() { // Create a root node for the grid GroupNode = SCNNode.Create(); // Retrieve the template node to replicate var scene = SCNScene.FromFile("Contacts/contact"); var templateNode = scene.RootNode.FindChildNode("people", true); for (int k = 0, j = 0; j < RowCount; j++) { for (var i = 0; i < ColumnCount; i++, k++) { // Hierarchy : __groupNode > container > node var container = SCNNode.Create(); var node = templateNode.Clone(); node.Name = "contact" + k; GroupNode.AddChildNode(container); container.AddChildNode(node); if (k == 28) { HeroNode = node; } // Curved layout var angle = 0.12f * ((ColumnCount - 1) / 2.0f - i); var x = NMath.Cos(angle + (float)(Math.PI / 2)) * 500.0f; var z = NMath.Sin(angle + (float)(Math.PI / 2)) * 500.0f; container.Position = new SCNVector3(x, j * 60, -z + 400); container.Rotation = new SCNVector4(0, 1, 0, angle); // We want a different image on each elemement and to do that we need to // unshare the geometry first and then unshare the material var geometryNode = node.ChildNodes [0]; geometryNode.Geometry = (SCNGeometry)geometryNode.Geometry.Copy(); var materialCopy = (SCNMaterial)geometryNode.Geometry.Materials [1].Copy(); materialCopy.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Contacts/contact" + (k % ContactImageCount), "jpg")); geometryNode.Geometry.ReplaceMaterial(1, materialCopy); // Animate (rotate forever) var animation = CAKeyFrameAnimation.GetFromKeyPath("rotation"); animation.Duration = 4.0f; animation.KeyTimes = new NSNumber[] { 0.0f, 0.3f, 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector(new SCNVector4(0, 1, 0, 0)), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))) }; var tf = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimingFunctions = new CAMediaTimingFunction[] { tf, tf, tf }; animation.RepeatCount = float.MaxValue; animation.BeginTime = CAAnimation.CurrentMediaTime() + 1.0f + j * 0.1f + i * 0.05f; // desynchronize the animations node.AddAnimation(animation, new NSString("animation")); } } // Add the group to the scene GroupNode.Scale = new SCNVector3(0.03f, 0.03f, 0.03f); GroupNode.Position = new SCNVector3(0, Altitude - 2.8f, 18); GroupNode.Opacity = 0.0f; GroundNode.AddChildNode(GroupNode); }
private void BuildTransitionComposition(AVMutableComposition composition, AVMutableVideoComposition videoComposition, AVMutableAudioMix audioMix) { CMTime nextClipStartTime = CMTime.Zero; int clipsCount = Clips.Count; // Make transitionDuration no greater than half the shortest clip duration. CMTime transitionDuration = TransitionDuration; Console.WriteLine("Clips Count:" + clipsCount); Console.WriteLine("Clips Range Count:" + ClipTimeRanges.Count); for (int i = 0; i < clipsCount; i++) { NSValue clipTimeRange = ClipTimeRanges [i]; if (clipTimeRange != null) { CMTime halfClipDuration = clipTimeRange.CMTimeRangeValue.Duration; halfClipDuration.TimeScale *= 2; transitionDuration = CMTime.GetMinimum(transitionDuration, halfClipDuration); } } // Add two video tracks and two audio tracks. var compositionVideoTracks = new AVMutableCompositionTrack [] { composition.AddMutableTrack(AVMediaType.Video, 0), composition.AddMutableTrack(AVMediaType.Video, 0) }; var compositionAudioTracks = new AVMutableCompositionTrack [] { composition.AddMutableTrack(AVMediaType.Audio, 0), composition.AddMutableTrack(AVMediaType.Audio, 0) }; var passThroughTimeRanges = new CMTimeRange[clipsCount]; var transitionTimeRanges = new CMTimeRange[clipsCount]; // Place clips into alternating video & audio tracks in composition, overlapped by transitionDuration. for (int i = 0; i < clipsCount; i++) { int alternatingIndex = i % 2; AVAsset asset = Clips [i]; NSValue clipTimeRange = ClipTimeRanges [i]; CMTimeRange timeRangeInAsset; if (clipTimeRange != null) { timeRangeInAsset = clipTimeRange.CMTimeRangeValue; } else { timeRangeInAsset = new CMTimeRange(); timeRangeInAsset.Start = CMTime.Zero; timeRangeInAsset.Duration = asset.Duration; } NSError error; AVAssetTrack clipVideoTrack = asset.TracksWithMediaType(AVMediaType.Video) [0]; compositionVideoTracks [alternatingIndex].InsertTimeRange(timeRangeInAsset, clipVideoTrack, nextClipStartTime, out error); AVAssetTrack clipAudioTrack = asset.TracksWithMediaType(AVMediaType.Audio) [0]; compositionAudioTracks [alternatingIndex].InsertTimeRange(timeRangeInAsset, clipAudioTrack, nextClipStartTime, out error); // Remember the time range in which this clip should pass through. // First clip ends with a transition. // Second clip begins with a transition. // Exclude that transition from the pass through time ranges CMTimeRange timeRange = new CMTimeRange(); timeRange.Start = nextClipStartTime; timeRange.Duration = timeRangeInAsset.Duration; passThroughTimeRanges [i] = timeRange; if (i > 0) { passThroughTimeRanges[i].Start = CMTime.Add(passThroughTimeRanges[i].Start, transitionDuration); passThroughTimeRanges[i].Duration = CMTime.Subtract(passThroughTimeRanges[i].Duration, transitionDuration); } if (i + 1 < clipsCount) { passThroughTimeRanges[i].Duration = CMTime.Subtract(passThroughTimeRanges[i].Duration, transitionDuration); } // The end of this clip will overlap the start of the next by transitionDuration. // (Note: this arithmetic falls apart if timeRangeInAsset.duration < 2 * transitionDuration.) nextClipStartTime = CMTime.Add(nextClipStartTime, timeRangeInAsset.Duration); nextClipStartTime = CMTime.Subtract(nextClipStartTime, transitionDuration); // Remember the time range for the transition to the next item if (i + 1 < clipsCount) { transitionTimeRanges [i] = new CMTimeRange() { Start = nextClipStartTime, Duration = transitionDuration }; } } List <AVVideoCompositionInstruction> instructions = new List <AVVideoCompositionInstruction> (); List <AVMutableAudioMixInputParameters> trackMixArray = new List <AVMutableAudioMixInputParameters> (); // Set up the video composition if we are to perform crossfade transitions between clips. for (int i = 0; i < clipsCount; i++) { int alternatingIndex = i % 2; AVMutableVideoCompositionInstruction passThroughInstructions = AVMutableVideoCompositionInstruction.Create() as AVMutableVideoCompositionInstruction; passThroughInstructions.TimeRange = passThroughTimeRanges [i]; AVMutableVideoCompositionLayerInstruction passThroughLayerInstructions = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(compositionVideoTracks [alternatingIndex]); passThroughInstructions.LayerInstructions = new AVVideoCompositionLayerInstruction[] { passThroughLayerInstructions }; instructions.Add(passThroughInstructions); if (i + 1 < clipsCount) { var transitionInstruction = AVMutableVideoCompositionInstruction.Create() as AVMutableVideoCompositionInstruction; transitionInstruction.TimeRange = transitionTimeRanges [i]; var fromLayer = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(compositionVideoTracks [alternatingIndex]); var toLayer = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(compositionVideoTracks [1 - alternatingIndex]); // Fade in the toLayer by setting a ramp from 0.0 to 1.0. toLayer.SetOpacityRamp(0.0f, 1.0f, transitionTimeRanges [i]); transitionInstruction.LayerInstructions = new AVVideoCompositionLayerInstruction[] { toLayer, fromLayer, }; instructions.Add(transitionInstruction); // Add AudioMix to fade in the volume ramps var trackMix = AVMutableAudioMixInputParameters.FromTrack(compositionAudioTracks[0]); trackMix.SetVolumeRamp(1f, 0f, transitionTimeRanges[0]); trackMixArray.Add(trackMix); trackMix = AVMutableAudioMixInputParameters.FromTrack(compositionAudioTracks[1]); trackMix.SetVolumeRamp(0f, 1f, transitionTimeRanges[0]); trackMix.SetVolumeRamp(1f, 1f, passThroughTimeRanges[1]); trackMixArray.Add(trackMix); } } videoComposition.Instructions = instructions.ToArray(); audioMix.InputParameters = trackMixArray.ToArray(); }
private void CreateLayers(UIImage image) { if (image == null) { return; } Layer.Sublayers = new CALayer[0]; var imageFrame = new CGRect( Frame.Width / 2f - Frame.Width / 4f, Frame.Height / 2f - Frame.Height / 4f, Frame.Width / 2f, Frame.Height / 2f); var imgCenterPoint = new CGPoint(imageFrame.GetMidX(), imageFrame.GetMidY()); var lineFrame = new CGRect( imageFrame.X - imageFrame.Width / 4f, imageFrame.Y - imageFrame.Height / 4f, imageFrame.Width * 1.5f, imageFrame.Height * 1.5f); //=============== // circle layer //=============== circleShape = new CAShapeLayer(); circleShape.Bounds = imageFrame; circleShape.Position = imgCenterPoint; circleShape.Path = UIBezierPath.FromOval(imageFrame).CGPath; circleShape.FillColor = circleColor.CGColor; circleShape.Transform = CATransform3D.MakeScale(0.0f, 0.0f, 1.0f); Layer.AddSublayer(circleShape); circleMaskShape = new CAShapeLayer(); circleMaskShape.Bounds = imageFrame; circleMaskShape.Position = imgCenterPoint; circleMaskShape.FillRule = CAShapeLayer.FillRuleEvenOdd; circleShape.Mask = circleMaskShape; var maskPath = UIBezierPath.FromRect(imageFrame); maskPath.AddArc(imgCenterPoint, 0.1f, 0.0f, fPI * 2f, true); circleMaskShape.Path = maskPath.CGPath; //=============== // line layer //=============== lineShapes = new CAShapeLayer[5]; for (int i = 0; i < 5; i++) { var line = new CAShapeLayer(); line.Bounds = lineFrame; line.Position = imgCenterPoint; line.MasksToBounds = true; line.Actions = NSDictionary.FromObjectsAndKeys( new[] { NSNull.Null, NSNull.Null }, new[] { (NSString)"strokeStart", (NSString)"strokeEnd" }); line.StrokeColor = linesColor.CGColor; line.LineWidth = 1.25f; line.MiterLimit = 1.25f; var path = new CGPath(); path.MoveToPoint(lineFrame.GetMidX(), lineFrame.GetMidY()); path.AddLineToPoint(lineFrame.X + lineFrame.Width / 2f, lineFrame.Y); line.Path = path; line.LineCap = CAShapeLayer.CapRound; line.LineJoin = CAShapeLayer.JoinRound; line.StrokeStart = 0.0f; line.StrokeEnd = 0.0f; line.Opacity = 0.0f; line.Transform = CATransform3D.MakeRotation(fPI / 5f * (i * 2f + 1f), 0.0f, 0.0f, 1.0f); Layer.AddSublayer(line); lineShapes[i] = line; } //=============== // image layer //=============== imageShape = new CAShapeLayer(); imageShape.Bounds = imageFrame; imageShape.Position = imgCenterPoint; imageShape.Path = UIBezierPath.FromRect(imageFrame).CGPath; imageShape.FillColor = Checked ? Color.CGColor : SkeletonColor.CGColor; imageShape.Actions = NSDictionary.FromObjectAndKey(NSNull.Null, (NSString)"fillColor"); Layer.AddSublayer(imageShape); imageShape.Mask = new CALayer(); imageShape.Mask.Contents = image.CGImage; imageShape.Mask.Bounds = imageFrame; imageShape.Mask.Position = imgCenterPoint; //============================== // circle transform animation //============================== circleTransform.Values = new[] { NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f, 0.0f, 1.0f)), // 0/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.5f, 0.5f, 1.0f)), // 1/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.0f, 1.0f, 1.0f)), // 2/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f, 1.2f, 1.0f)), // 3/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.3f, 1.3f, 1.0f)), // 4/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.37f, 1.37f, 1.0f)), // 5/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.4f, 1.4f, 1.0f)), // 6/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.4f, 1.4f, 1.0f)) // 10/10 }; circleTransform.KeyTimes = new[] { NSNumber.FromDouble(0.0), // 0/10 NSNumber.FromDouble(0.1), // 1/10 NSNumber.FromDouble(0.2), // 2/10 NSNumber.FromDouble(0.3), // 3/10 NSNumber.FromDouble(0.4), // 4/10 NSNumber.FromDouble(0.5), // 5/10 NSNumber.FromDouble(0.6), // 6/10 NSNumber.FromDouble(1.0) // 10/10 }; circleMaskTransform.Values = new[] { NSValue.FromCATransform3D(CATransform3D.Identity), // 0/10 NSValue.FromCATransform3D(CATransform3D.Identity), // 2/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 1.25f, imageFrame.Height * 1.25f, 1.0f)), // 3/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 2.688f, imageFrame.Height * 2.688f, 1.0f)), // 4/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 3.923f, imageFrame.Height * 3.923f, 1.0f)), // 5/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 4.375f, imageFrame.Height * 4.375f, 1.0f)), // 6/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 4.731f, imageFrame.Height * 4.731f, 1.0f)), // 7/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 5.0f, imageFrame.Height * 5.0f, 1.0f)), // 9/10 NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 5.0f, imageFrame.Height * 5.0f, 1.0f)) // 10/10 }; circleMaskTransform.KeyTimes = new[] { NSNumber.FromDouble(0.0), // 0/10 NSNumber.FromDouble(0.2), // 2/10 NSNumber.FromDouble(0.3), // 3/10 NSNumber.FromDouble(0.4), // 4/10 NSNumber.FromDouble(0.5), // 5/10 NSNumber.FromDouble(0.6), // 6/10 NSNumber.FromDouble(0.7), // 7/10 NSNumber.FromDouble(0.9), // 9/10 NSNumber.FromDouble(1.0) // 10/10 }; //============================== // line stroke animation //============================== lineStrokeStart.Values = new[] { NSNumber.FromDouble(0.0), // 0/18 NSNumber.FromDouble(0.0), // 1/18 NSNumber.FromDouble(0.18), // 2/18 NSNumber.FromDouble(0.2), // 3/18 NSNumber.FromDouble(0.26), // 4/18 NSNumber.FromDouble(0.32), // 5/18 NSNumber.FromDouble(0.4), // 6/18 NSNumber.FromDouble(0.6), // 7/18 NSNumber.FromDouble(0.71), // 8/18 NSNumber.FromDouble(0.89), // 17/18 NSNumber.FromDouble(0.92) // 18/18 }; lineStrokeStart.KeyTimes = new[] { NSNumber.FromDouble(0.0), // 0/18 NSNumber.FromDouble(0.056), // 1/18 NSNumber.FromDouble(0.111), // 2/18 NSNumber.FromDouble(0.167), // 3/18 NSNumber.FromDouble(0.222), // 4/18 NSNumber.FromDouble(0.278), // 5/18 NSNumber.FromDouble(0.333), // 6/18 NSNumber.FromDouble(0.389), // 7/18 NSNumber.FromDouble(0.444), // 8/18 NSNumber.FromDouble(0.944), // 17/18 NSNumber.FromDouble(1.0), // 18/18 }; lineStrokeEnd.Values = new[] { NSNumber.FromDouble(0.0), // 0/18 NSNumber.FromDouble(0.0), // 1/18 NSNumber.FromDouble(0.32), // 2/18 NSNumber.FromDouble(0.48), // 3/18 NSNumber.FromDouble(0.64), // 4/18 NSNumber.FromDouble(0.68), // 5/18 NSNumber.FromDouble(0.92), // 17/18 NSNumber.FromDouble(0.92) // 18/18 }; lineStrokeEnd.KeyTimes = new[] { NSNumber.FromDouble(0.0), // 0/18 NSNumber.FromDouble(0.056), // 1/18 NSNumber.FromDouble(0.111), // 2/18 NSNumber.FromDouble(0.167), // 3/18 NSNumber.FromDouble(0.222), // 4/18 NSNumber.FromDouble(0.278), // 5/18 NSNumber.FromDouble(0.944), // 17/18 NSNumber.FromDouble(1.0), // 18/18 }; lineOpacity.Values = new[] { NSNumber.FromDouble(1.0), // 0/30 NSNumber.FromDouble(1.0), // 12/30 NSNumber.FromDouble(0.0) // 17/30 }; lineOpacity.KeyTimes = new[] { NSNumber.FromDouble(0.0), // 0/30 NSNumber.FromDouble(0.4), // 12/30 NSNumber.FromDouble(0.567) // 17/30 }; //============================== // image transform animation //============================== imageTransform.Values = new[] { NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f, 0.0f, 1.0f)), // 0/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f, 0.0f, 1.0f)), // 3/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f, 1.2f, 1.0f)), // 9/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.25f, 1.25f, 1.0f)), // 10/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f, 1.2f, 1.0f)), // 11/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.9f, 0.9f, 1.0f)), // 14/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.875f, 0.875f, 1.0f)), // 15/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.875f, 0.875f, 1.0f)), // 16/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.9f, 0.9f, 1.0f)), // 17/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.013f, 1.013f, 1.0f)), // 20/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.025f, 1.025f, 1.0f)), // 21/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(1.013f, 1.013f, 1.0f)), // 22/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.96f, 0.96f, 1.0f)), // 25/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.95f, 0.95f, 1.0f)), // 26/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.96f, 0.96f, 1.0f)), // 27/30 NSValue.FromCATransform3D(CATransform3D.MakeScale(0.99f, 0.99f, 1.0f)), // 29/30 NSValue.FromCATransform3D(CATransform3D.Identity) // 30/30 }; imageTransform.KeyTimes = new[] { NSNumber.FromDouble(0.0), // 0/30 NSNumber.FromDouble(0.1), // 3/30 NSNumber.FromDouble(0.3), // 9/30 NSNumber.FromDouble(0.333), // 10/30 NSNumber.FromDouble(0.367), // 11/30 NSNumber.FromDouble(0.467), // 14/30 NSNumber.FromDouble(0.5), // 15/30 NSNumber.FromDouble(0.533), // 16/30 NSNumber.FromDouble(0.567), // 17/30 NSNumber.FromDouble(0.667), // 20/30 NSNumber.FromDouble(0.7), // 21/30 NSNumber.FromDouble(0.733), // 22/30 NSNumber.FromDouble(0.833), // 25/30 NSNumber.FromDouble(0.867), // 26/30 NSNumber.FromDouble(0.9), // 27/30 NSNumber.FromDouble(0.967), // 29/30 NSNumber.FromDouble(1.0) // 30/30 }; // re-set the durations Duration = duration; }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Hide everything (in case the user went backward) for (var i = 1; i < 4; i++) { var teapot = GroundNode.FindChildNode("Teapot" + i, true); teapot.Opacity = 0.0f; } break; case 1: // Move the camera and adjust the clipping plane SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 3; presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 200); presentationViewController.CameraNode.Camera.ZFar = 500.0f; SCNTransaction.Commit(); break; case 2: // Revert to original position SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 0); presentationViewController.CameraNode.Camera.ZFar = 100.0f; SCNTransaction.Commit(); break; case 3: var numberNodes = new SCNNode[] { AddNumberNode("64k", -17), AddNumberNode("6k", -9), AddNumberNode("3k", -1), AddNumberNode("1k", 6.5f), AddNumberNode("256", 14) }; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Move the camera and the text presentationViewController.CameraHandle.Position = new SCNVector3(presentationViewController.CameraHandle.Position.X, presentationViewController.CameraHandle.Position.Y + 6, presentationViewController.CameraHandle.Position.Z); TextManager.TextNode.Position = new SCNVector3(TextManager.TextNode.Position.X, TextManager.TextNode.Position.Y + 6, TextManager.TextNode.Position.Z); // Show the remaining resolutions for (var i = 0; i < 5; i++) { var numberNode = numberNodes [i]; numberNode.Position = new SCNVector3(numberNode.Position.X, 7, -5); var teapot = GroundNode.FindChildNode("Teapot" + i, true); teapot.Opacity = 1.0f; teapot.Rotation = new SCNVector4(0, 0, 1, (float)(Math.PI / 4)); teapot.Position = new SCNVector3((i - 2) * 8, 5, teapot.Position.Z); } SCNTransaction.Commit(); break; case 4: presentationViewController.ShowsNewInSceneKitBadge(true); // Remove the numbers RemoveNumberNodes(); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Add some text and code TextManager.SetSubtitle("SCNLevelOfDetail"); TextManager.AddCode("#var lod1 = SCNLevelOfDetail.#CreateWithWorldSpaceDistance# (aGeometry, aDistance); \n" + "geometry.#LevelsOfDetail# = new SCNLevelOfDetail { lod1, lod2, ..., lodn };#"); // Animation the merge for (int i = 0; i < 5; i++) { var teapot = GroundNode.FindChildNode("Teapot" + i, true); teapot.Opacity = i == 0 ? 1.0f : 0.0f; teapot.Rotation = new SCNVector4(0, 0, 1, 0); teapot.Position = new SCNVector3(0, -5, teapot.Position.Z); } // Move the camera and the text presentationViewController.CameraHandle.Position = new SCNVector3(presentationViewController.CameraHandle.Position.X, presentationViewController.CameraHandle.Position.Y - 3, presentationViewController.CameraHandle.Position.Z); TextManager.TextNode.Position = new SCNVector3(TextManager.TextNode.Position.X, TextManager.TextNode.Position.Y - 3, TextManager.TextNode.Position.Z); SCNTransaction.Commit(); break; case 5: presentationViewController.ShowsNewInSceneKitBadge(false); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 3; // Change the lighting to remove the front light and rise the main light presentationViewController.UpdateLightingWithIntensities(new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.3f }); presentationViewController.RiseMainLight(true); // Remove some text TextManager.FadeOutText(SlideTextManager.TextType.Title); TextManager.FadeOutText(SlideTextManager.TextType.Subtitle); TextManager.FadeOutText(SlideTextManager.TextType.Code); SCNTransaction.Commit(); // Retrieve the main teapot var maintTeapot = GroundNode.FindChildNode("Teapot0", true); // The distances to use for each LOD var distances = new float [4] { 30, 50, 90, 150 }; // An array of SCNLevelOfDetail instances that we will build var levelsOfDetail = new SCNLevelOfDetail[4]; for (var i = 1; i < 5; i++) { var teapotNode = GroundNode.FindChildNode("Teapot" + i, true); var teapot = teapotNode.Geometry; // Unshare the material because we will highlight the different levels of detail with different colors in the next step teapot.FirstMaterial = (SCNMaterial)teapot.FirstMaterial.Copy(); // Build the SCNLevelOfDetail instance var levelOfDetail = SCNLevelOfDetail.CreateWithWorldSpaceDistance(teapot, distances [i - 1]); levelsOfDetail [i - 1] = levelOfDetail; } maintTeapot.Geometry.LevelsOfDetail = levelsOfDetail; // Duplicate and move the teapots var startTime = CAAnimation.CurrentMediaTime(); var delay = 0.2; var rowCount = 9; var columnCount = 12; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; // Change the far clipping plane to be able to see far away presentationViewController.CameraNode.Camera.ZFar = 1000.0; for (var j = 0; j < columnCount; j++) { for (var i = 0; i < rowCount; i++) { // Clone var clone = maintTeapot.Clone(); maintTeapot.ParentNode.AddChildNode(clone); // Animate var animation = CABasicAnimation.FromKeyPath("position"); animation.Additive = true; animation.Duration = 1.0; animation.To = NSValue.FromVector(new SCNVector3((i - rowCount / 2.0f) * 12.0f, 5 + (columnCount - j) * 15.0f, 0)); animation.From = NSValue.FromVector(new SCNVector3(0, 0, 0)); animation.BeginTime = startTime + delay; // desynchronize // Freeze at the end of the animation animation.RemovedOnCompletion = false; animation.FillMode = CAFillMode.Forwards; clone.AddAnimation(animation, new NSString("cloneAnimation")); // Animate the hidden property to automatically show the node when the position animation starts animation = CABasicAnimation.FromKeyPath("hidden"); animation.Duration = delay + 0.01; animation.FillMode = CAFillMode.Both; animation.From = new NSNumber(1); animation.To = new NSNumber(0); clone.AddAnimation(animation, new NSString("cloneAnimation2")); delay += 0.05; } } SCNTransaction.Commit(); // Animate the camera while we duplicate the nodes SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0 + rowCount * columnCount * 0.05; var position = presentationViewController.CameraHandle.Position; presentationViewController.CameraHandle.Position = new SCNVector3(position.X, position.Y + 5, position.Z); presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, presentationViewController.CameraPitch.Rotation.W - ((float)(Math.PI / 4) * 0.1f)); SCNTransaction.Commit(); break; case 6: // Highlight the levels of detail with colors var teapotChild = GroundNode.FindChildNode("Teapot0", true); var colors = new NSColor[] { NSColor.Red, NSColor.Orange, NSColor.Yellow, NSColor.Green }; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; for (var i = 0; i < 4; i++) { var levelOfDetail = teapotChild.Geometry.LevelsOfDetail [i]; levelOfDetail.Geometry.FirstMaterial.Multiply.Contents = colors [i]; } SCNTransaction.Commit(); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 1: // Load the scene var intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(0.0f, 0.1f, -24.5f); intermediateNode.Scale = new SCNVector3(2.3f, 1.0f, 1.0f); intermediateNode.Opacity = 0.0f; RoomNode = Utils.SCAddChildNode(intermediateNode, "Mesh", "Scenes/cornell-box/cornell-box", 15); ContentNode.AddChildNode(intermediateNode); // Hide the light maps for now foreach (var material in RoomNode.Geometry.Materials) { material.Multiply.Intensity = 0.0f; material.LightingModelName = SCNLightingModel.Blinn; } // Animate the point of view with an implicit animation. // On completion add to move the camera from right to left and back and forth. SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; SCNTransaction.SetCompletionBlock(() => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 2; SCNTransaction.SetCompletionBlock(() => { var animation = CABasicAnimation.FromKeyPath("position"); animation.Duration = 10.0f; animation.Additive = true; animation.To = NSValue.FromVector(new SCNVector3(-5, 0, 0)); animation.From = NSValue.FromVector(new SCNVector3(5, 0, 0)); animation.TimeOffset = -animation.Duration / 2; animation.AutoReverses = true; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.RepeatCount = float.MaxValue; presentationViewController.CameraNode.AddAnimation(animation, new NSString("myAnim")); }); presentationViewController.CameraHandle.Position = presentationViewController.CameraHandle.ConvertPositionToNode(new SCNVector3(0, +5, -30), presentationViewController.CameraHandle.ParentNode); presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.2f); SCNTransaction.Commit(); }); intermediateNode.Opacity = 1.0f; SCNTransaction.Commit(); break; case 2: // Remove the lighting by using a constant lighing model (no lighting) foreach (var material in RoomNode.Geometry.Materials) { material.LightingModelName = SCNLightingModel.Constant; } break; case 3: // Activate the light maps smoothly SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; foreach (var material in RoomNode.Geometry.Materials) { material.Multiply.Intensity = 1.0f; } SCNTransaction.Commit(); break; } }
public virtual bool InsertTimeRanges(NSValue cmTimeRanges, AVAssetTrack[] tracks, CMTime startTime, out NSError error) { return(InsertTimeRanges(new NSValue [] { cmTimeRanges }, tracks, startTime, out error)); }
// compatibility method public virtual void GenerateCGImagesAsynchronously(NSValue cmTimesRequestedTimes, AVAssetImageGeneratorCompletionHandler handler) { NSValue[] values = new NSValue[] { cmTimesRequestedTimes }; GenerateCGImagesAsynchronously(values, handler); }
void buildTransitionComposition(AVMutableComposition composition, AVMutableVideoComposition videoComposition) { CMTime nextClipStartTime = CMTime.Zero; int clipsCount = Clips.Count; // Make transitionDuration no greater than half the shortest clip duration. CMTime transitionDuration = TransitionDuration; foreach (var clipTimeRange in ClipTimeRanges) { if (clipTimeRange == null) { continue; } CMTime halfClipDuration = clipTimeRange.CMTimeRangeValue.Duration; halfClipDuration.TimeScale *= 2; transitionDuration = CMTime.GetMinimum(transitionDuration, halfClipDuration); } // Add two video tracks and two audio tracks. var compositionVideoTracks = new AVMutableCompositionTrack [2]; var compositionAudioTracks = new AVMutableCompositionTrack [2]; compositionVideoTracks [0] = composition.AddMutableTrack(AVMediaType.Video, 0); compositionVideoTracks [1] = composition.AddMutableTrack(AVMediaType.Video, 0); compositionAudioTracks [0] = composition.AddMutableTrack(AVMediaType.Audio, 0); compositionAudioTracks [1] = composition.AddMutableTrack(AVMediaType.Audio, 0); var passThroughTimeRanges = new CMTimeRange[clipsCount]; var transitionTimeRanges = new CMTimeRange[clipsCount]; // Place clips into alternating video & audio tracks in composition, overlapped by transitionDuration. for (int i = 0; i < clipsCount; i++) { int alternatingIndex = i % 2; AVAsset asset = Clips [i]; NSValue clipTimeRange = ClipTimeRanges [i]; CMTimeRange timeRangeInAsset; if (clipTimeRange != null) { timeRangeInAsset = clipTimeRange.CMTimeRangeValue; } else { timeRangeInAsset = new CMTimeRange { Start = CMTime.Zero, Duration = asset.Duration }; } NSError error = new NSError(); AVAssetTrack clipVideoTrack = asset.TracksWithMediaType(AVMediaType.Video) [0]; compositionVideoTracks [alternatingIndex].InsertTimeRange(timeRangeInAsset, clipVideoTrack, nextClipStartTime, out error); AVAssetTrack clipAudioTrack = asset.TracksWithMediaType(AVMediaType.Audio) [0]; compositionAudioTracks [alternatingIndex].InsertTimeRange(timeRangeInAsset, clipAudioTrack, nextClipStartTime, out error); // Remember the time range in which this clip should pass through. // First clip ends with a transition. // Second clip begins with a transition. // Exclude that transition from the pass through time ranges passThroughTimeRanges [i] = new CMTimeRange { Start = nextClipStartTime, Duration = timeRangeInAsset.Duration }; if (i > 0) { passThroughTimeRanges[i].Start = CMTime.Add(passThroughTimeRanges[i].Start, transitionDuration); passThroughTimeRanges[i].Duration = CMTime.Subtract(passThroughTimeRanges[i].Duration, transitionDuration); } if (i + 1 < clipsCount) { passThroughTimeRanges[i].Duration = CMTime.Subtract(passThroughTimeRanges[i].Duration, transitionDuration); } // The end of this clip will overlap the start of the next by transitionDuration. // (Note: this arithmetic falls apart if timeRangeInAsset.duration < 2 * transitionDuration.) nextClipStartTime = CMTime.Add(nextClipStartTime, timeRangeInAsset.Duration); nextClipStartTime = CMTime.Subtract(nextClipStartTime, transitionDuration); // Remember the time range for the transition to the next item. if (i + 1 < clipsCount) { transitionTimeRanges [i] = new CMTimeRange() { Start = nextClipStartTime, Duration = transitionDuration }; } } // Set up the video composition to perform cross dissolve or diagonal wipe transitions between clips. var instructions = new List <AVVideoCompositionInstruction> (); // Cycle between "pass through A", "transition from A to B", "pass through B" for (int i = 0; i < clipsCount; i++) { int alternatingIndex = i % 2; // if (videoComposition.CustomVideoCompositorClass != null) { // var videoInstruction = new CustomVideoCompositionInstruction (compositionVideoTracks [alternatingIndex].TrackID, passThroughTimeRanges [i]); // instructions.Add (videoInstruction); // } else { // // Pass through clip i. // var passThroughInstruction = AVMutableVideoCompositionInstruction.Create () as AVMutableVideoCompositionInstruction; // passThroughInstruction.TimeRange = passThroughTimeRanges [i]; // var passThroughLayer = AVMutableVideoCompositionLayerInstruction.FromAssetTrack (compositionVideoTracks [alternatingIndex]); // passThroughInstruction.LayerInstructions = new [] { passThroughLayer }; // instructions.Add (passThroughInstruction); // // } //TODO: Remove following call if previous works if (videoComposition.CustomVideoCompositorClass.Name != "nil") { var videoInstruction = new CustomVideoCompositionInstruction(compositionVideoTracks [alternatingIndex].TrackID, passThroughTimeRanges [i]); instructions.Add(videoInstruction); } else { // Pass through clip i. var passThroughInstruction = AVMutableVideoCompositionInstruction.Create() as AVMutableVideoCompositionInstruction; passThroughInstruction.TimeRange = passThroughTimeRanges [i]; var passThroughLayer = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(compositionVideoTracks [alternatingIndex]); passThroughInstruction.LayerInstructions = new [] { passThroughLayer }; instructions.Add(passThroughInstruction); } if (i + 1 < clipsCount) { // Add transition from clip i to clip i+1. // if (videoComposition.CustomVideoCompositorClass != null) { // var videoInstruction = new CustomVideoCompositionInstruction (new NSNumber [] { // compositionVideoTracks [0].TrackID, // compositionVideoTracks [1].TrackID // }, transitionTimeRanges [1]); // // if (alternatingIndex == 0) { // videoInstruction.ForegroundTrackID = compositionVideoTracks [alternatingIndex].TrackID; // videoInstruction.BackgroundTrackID = compositionVideoTracks [1 - alternatingIndex].TrackID; // } // // instructions.Add (videoInstruction); // } else { // var transitionInstruction = AVMutableVideoCompositionInstruction.Create () as AVMutableVideoCompositionInstruction; // transitionInstruction.TimeRange = transitionTimeRanges [i]; // var fromLayer = AVMutableVideoCompositionLayerInstruction.FromAssetTrack (compositionVideoTracks [alternatingIndex]); // var toLayer = AVMutableVideoCompositionLayerInstruction.FromAssetTrack (compositionVideoTracks [1 - alternatingIndex]); // transitionInstruction.LayerInstructions = new [] { toLayer, fromLayer }; // instructions.Add (transitionInstruction); // } // TODO: remove following call if previous works if (videoComposition.CustomVideoCompositorClass.Name != "nil") { NSNumber[] sources = new NSNumber[] { new NSNumber(compositionVideoTracks [0].TrackID), new NSNumber(compositionVideoTracks [1].TrackID) }; var videoInstructions = new CustomVideoCompositionInstruction(sources, transitionTimeRanges [i]); if (alternatingIndex == 0) { videoInstructions.ForegroundTrackID = compositionVideoTracks [alternatingIndex].TrackID; videoInstructions.BackgroundTrackID = compositionVideoTracks [1 - alternatingIndex].TrackID; } instructions.Add(videoInstructions); Console.WriteLine("Add transition from clip i to clip i+1"); } else { AVMutableVideoCompositionInstruction transitionInstruction = AVMutableVideoCompositionInstruction.Create() as AVMutableVideoCompositionInstruction; transitionInstruction.TimeRange = transitionTimeRanges [i]; AVMutableVideoCompositionLayerInstruction fromLayer = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(compositionVideoTracks [alternatingIndex]); AVMutableVideoCompositionLayerInstruction toLayer = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(compositionVideoTracks [1 - alternatingIndex]); transitionInstruction.LayerInstructions = new AVVideoCompositionLayerInstruction[] { fromLayer, toLayer, }; instructions.Add(transitionInstruction); } } } videoComposition.Instructions = instructions.ToArray(); }
public static void SetFloat4(this SCNGeometry geometry, string uniform, SCNVector4 value) { geometry.SetValueForKey(NSValue.FromVector(value), new NSString(uniform)); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Set the slide's title and subtile and add some text TextManager.SetTitle("Node Attributes"); TextManager.SetSubtitle("SCNGeometry"); TextManager.AddBulletAtLevel("Triangles", 0); TextManager.AddBulletAtLevel("Vertices", 0); TextManager.AddBulletAtLevel("Normals", 0); TextManager.AddBulletAtLevel("UVs", 0); TextManager.AddBulletAtLevel("Materials", 0); // We create a container for several versions of the teapot model // - one teapot to show positions and normals // - one teapot to show texture coordinates // - one teapot to show materials var allTeapotsNode = SCNNode.Create(); allTeapotsNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); GroundNode.AddChildNode(allTeapotsNode); TeapotNodeForPositionsAndNormals = Utils.SCAddChildNode(allTeapotsNode, "TeapotLowRes", "Scenes.scnassets/teapots/teapotLowRes", 17); TeapotNodeForUVs = Utils.SCAddChildNode(allTeapotsNode, "Teapot", "Scenes.scnassets/teapots/teapot", 17); TeapotNodeForMaterials = Utils.SCAddChildNode(allTeapotsNode, "teapotMaterials", "Scenes.scnassets/teapots/teapotMaterial", 17); TeapotNodeForPositionsAndNormals.Position = new SCNVector3(4, 0, 0); TeapotNodeForUVs.Position = new SCNVector3(4, 0, 0); TeapotNodeForMaterials.Position = new SCNVector3(4, 0, 0); foreach (var child in TeapotNodeForMaterials.ChildNodes) { foreach (var material in child.Geometry.Materials) { material.Multiply.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes.scnassets/teapots/UVs", "png")); material.Multiply.WrapS = SCNWrapMode.Repeat; material.Multiply.WrapT = SCNWrapMode.Repeat; //material.Reflective.Contents = NSColor.White; //material.Reflective.Intensity = 3.0f; //material.FresnelExponent = 3.0f; } } // Animate the teapots (rotate forever) var rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 40.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector(new SCNVector4(0, 0, 1, (float)(Math.PI * 2))); TeapotNodeForPositionsAndNormals.AddAnimation(rotationAnimation, new NSString("teapotNodeForPositionsAndNormalsAnimation")); TeapotNodeForUVs.AddAnimation(rotationAnimation, new NSString("teapotNodeForUVsAnimation")); TeapotNodeForMaterials.AddAnimation(rotationAnimation, new NSString("teapotNodeForMaterialsAnimation")); // Load the "explode" shader modifier and add it to the geometry //var explodeShaderPath = NSBundle.MainBundle.PathForResource ("Shaders/explode", "shader"); //var explodeShaderSource = System.IO.File.ReadAllText (explodeShaderPath); // TODO TeapotNodeForPositionsAndNormals.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = explodeShaderSource }; PositionsVisualizationNode = SCNNode.Create(); NormalsVisualizationNode = SCNNode.Create(); // Build nodes that will help visualize the vertices (position and normal) BuildVisualizationsOfNode(TeapotNodeForPositionsAndNormals, ref PositionsVisualizationNode, ref NormalsVisualizationNode); NormalsVisualizationNode.CastsShadow = false; TeapotNodeForMaterials.AddChildNode(PositionsVisualizationNode); TeapotNodeForMaterials.AddChildNode(NormalsVisualizationNode); }
public void RotateToStatusBarFrame(NSValue statusBarFrameValue) { // current interface orientation var orientation = UIApplication.SharedApplication.StatusBarOrientation; // is the statusBar visible before rotation? var visibleBeforeTransformation = !ReallyHidden; // store a flag, if the StatusBar is currently shrinked var shrinkedBeforeTransformation = Shrinked; // hide and then unhide after rotation if (visibleBeforeTransformation) { SetHidden(true, true); SetDetailViewHidden(true, false); } const float pi = (float) Math.PI; switch (orientation) { case UIInterfaceOrientation.Portrait: Transform = CGAffineTransform.MakeIdentity(); // .Identity; Frame = new RectangleF(0f, 0f, ScreenWidth, StatusBarHeight); SmallFrame = new RectangleF(Frame.Size.Width - WidthSmall, 0.0f, WidthSmall, Frame.Size.Height); break; case UIInterfaceOrientation.LandscapeRight: Transform = CGAffineTransform.MakeRotation(pi*(90f)/180.0f); Frame = new RectangleF(ScreenWidth - StatusBarHeight, 0, StatusBarHeight, ScreenHeight); SmallFrame = new RectangleF(ScreenHeight - WidthSmall, 0, WidthSmall, StatusBarHeight); break; case UIInterfaceOrientation.LandscapeLeft: Transform = CGAffineTransform.MakeRotation(pi*(-90f)/180.0f); Frame = new RectangleF(0f, 0f, StatusBarHeight, ScreenHeight); SmallFrame = new RectangleF(ScreenHeight - WidthSmall, 0f, WidthSmall, StatusBarHeight); break; case UIInterfaceOrientation.PortraitUpsideDown: Transform = CGAffineTransform.MakeRotation(pi); Frame = new RectangleF(0f, ScreenHeight - StatusBarHeight, ScreenWidth, StatusBarHeight); SmallFrame = new RectangleF(Frame.Size.Width - WidthSmall, 0f, WidthSmall, Frame.Size.Height); break; } BackgroundView.Frame = BackgroundViewFrameForStatusBarInterfaceOrientation(); // if the statusBar is currently shrinked, update the frames for the new rotation state if (shrinkedBeforeTransformation) { // the oldBackgroundViewFrame is the frame of the whole StatusBar OldBackgroundViewFrame = new RectangleF(0f, 0f, UIInterfaceOrientation.Portrait == orientation || UIInterfaceOrientation.PortraitUpsideDown == orientation ? ScreenWidth : ScreenHeight, StatusBarHeight); // the backgroundView gets the newly computed smallFrame BackgroundView.Frame = SmallFrame; } // make visible after given time if (visibleBeforeTransformation) { // TODO: // somehow this doesn't work anymore since rotation-method was changed from // DeviceDidRotate-Notification to StatusBarFrameChanged-Notification // therefore iplemented it with a UIView-Animation instead //[self performSelector:@selector(setHiddenUsingAlpha:) withObject:[NSNumber numberWithBool:NO] afterDelay:kRotationAppearDelay]; Animate(AppearAnimationDuration, _rotationAppearDelay, UIViewAnimationOptions.CurveEaseInOut, () => SetHiddenUsingAlpha(false), null); } }
private void DisplayViewController(NSViewController vc) { BeginInvokeOnMainThread(() => { NSWindow w = box.Window; bool ended = w.MakeFirstResponder(w); if (!ended) { AppKitFramework.NSBeep(); return; } // get the new View NSView newView = vc.View; // Get the old View NSView oldView = (NSView)box.ContentView; if (oldView == newView) { return; } // Compute the new window frame CGSize currentSize = oldView.Frame.Size; CGSize newSize = newView.Frame.Size; nfloat deltaWidth = newSize.Width - currentSize.Width; nfloat deltaHeight = newSize.Height - currentSize.Height; CGRect windowframe = w.Frame; windowframe.Size = new CGSize(windowframe.Size.Width, windowframe.Size.Height + deltaHeight); windowframe.Location = new CGPoint(windowframe.Location.X, windowframe.Location.Y - deltaHeight); windowframe.Size = new CGSize(windowframe.Size.Width + deltaWidth, windowframe.Size.Height); NSDictionary windowResize = NSDictionary.FromObjectsAndKeys(new NSObject[] { w, NSValue.FromCGRect(windowframe) }, new NSObject[] { NSViewAnimation.TargetKey, NSViewAnimation.EndFrameKey }); NSDictionary oldViewFadeOut = NSDictionary.FromObjectsAndKeys(new NSObject[] { oldView, NSViewAnimation.FadeOutEffect }, new NSObject[] { NSViewAnimation.TargetKey, NSViewAnimation.EffectKey }); NSDictionary newViewFadeOut = NSDictionary.FromObjectsAndKeys(new NSObject[] { newView, NSViewAnimation.FadeOutEffect }, new NSObject[] { NSViewAnimation.TargetKey, NSViewAnimation.EffectKey }); NSDictionary fadeIn = NSDictionary.FromObjectsAndKeys(new NSObject[] { newView, NSViewAnimation.FadeInEffect }, new NSObject[] { NSViewAnimation.TargetKey, NSViewAnimation.EffectKey }); NSViewAnimation animation = new NSViewAnimation(new NSDictionary[] { oldViewFadeOut }); animation.AnimationBlockingMode = NSAnimationBlockingMode.Blocking; animation.AnimationCurve = NSAnimationCurve.Linear; animation.Duration = 0.1; animation.StartAnimation(); NSViewAnimation animation2 = new NSViewAnimation(new NSDictionary[] { newViewFadeOut }); animation2.AnimationBlockingMode = NSAnimationBlockingMode.Blocking; animation2.Duration = 0.0; animation2.StartAnimation(); box.ContentView = newView; NSViewAnimation animation3 = new NSViewAnimation(new NSDictionary[] { windowResize }); animation3.AnimationBlockingMode = NSAnimationBlockingMode.Blocking; animation3.AnimationCurve = NSAnimationCurve.EaseInOut; animation3.Duration = 0.2; animation3.StartAnimation(); NSViewAnimation animation4 = new NSViewAnimation(new NSDictionary[] { fadeIn }); animation4.AnimationBlockingMode = NSAnimationBlockingMode.Blocking; animation4.AnimationCurve = NSAnimationCurve.Linear; animation4.Duration = 0.1; animation4.StartAnimation(); }); }