示例#1
0
        // Load movies and display movie layers
        private AVPlayerLayer ConfigurePlayer(string movieName, string hostingNodeName)
        {
            var player = AVPlayer.FromUrl(NSUrl.FromFilename(movieName));

            player.ActionAtItemEnd = AVPlayerActionAtItemEnd.None;             // loop

            NSNotificationCenter.DefaultCenter.AddObserver(this, new Selector("PlayerItemDidReachEnd"), AVPlayerItem.DidPlayToEndTimeNotification, player.CurrentItem);

            player.Play();

            // Set an arbitrary frame. This frame will be the size of our movie texture so if it is too small it will appear scaled up and blurry, and if it is too big it will be slow
            var playerLayer = new AVPlayerLayer();

            playerLayer.Player          = player;
            playerLayer.ContentsGravity = AVPlayerLayer.GravityResizeAspectFill;
            playerLayer.Frame           = new CGRect(0, 0, 600, 800);

            // Use a parent layer with a background color set to black
            // That way if the movie is stil loading and the frame is transparent, we won't see holes in the model
            var backgroundLayer = CALayer.Create();

            backgroundLayer.BackgroundColor = NSColor.Black.CGColor;
            backgroundLayer.Frame           = new CGRect(0, 0, 600, 800);
            backgroundLayer.AddSublayer(playerLayer);

            var frameNode = ContentNode.FindChildNode(hostingNodeName, true);
            var material  = frameNode.Geometry.FirstMaterial;

            material.Diffuse.Contents = backgroundLayer;

            return(playerLayer);
        }
示例#2
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            SCNTransaction.Begin();
            switch (index)
            {
            case 0:
                break;

            case 1:
                // Switch to camera1
                SCNTransaction.AnimationDuration = 2.0f;
                ((SCNView)presentationViewController.View).PointOfView = ContentNode.FindChildNode("camera1", true);
                break;

            case 2:
                // Switch to camera2
                SCNTransaction.AnimationDuration = 2.0f;
                ((SCNView)presentationViewController.View).PointOfView = ContentNode.FindChildNode("camera2", true);
                break;

            case 3:
                // Switch back to the default camera
                SCNTransaction.AnimationDuration = 1.0f;
                ((SCNView)presentationViewController.View).PointOfView = presentationViewController.CameraNode;
                break;
            }
            SCNTransaction.Commit();
        }
        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("Materials");
                TextManager.SetSubtitle("CALayer as texture");

                TextManager.AddCode("#// Map a layer tree on a 3D object. \n"
                                    + "aNode.Geometry.FirstMaterial.Diffuse.#Contents# = #aLayerTree#;#");

                // Add the model
                var intermediateNode = SCNNode.Create();
                intermediateNode.Position = new SCNVector3(0, 3.9f, 8);
                intermediateNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2));
                GroundNode.AddChildNode(intermediateNode);
                Utils.SCAddChildNode(intermediateNode, "frames", "Scenes/frames/frames", 8);

                presentationViewController.NarrowSpotlight(true);
                break;

            case 1:
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;

                // Change the point of view to "frameCamera" (a camera defined in the "frames" scene)
                var frameCamera = ContentNode.FindChildNode("frameCamera", true);
                ((SCNView)presentationViewController.View).PointOfView = frameCamera;

                // The "frames" scene contains animations, update the end time of our main scene and start to play the animations
                ((SCNView)presentationViewController.View).Scene.SetAttribute(new NSNumber(7.33f), SCNScene.EndTimeAttributeKey);
                ((SCNView)presentationViewController.View).CurrentTime = 0;
                ((SCNView)presentationViewController.View).Playing     = true;
                ((SCNView)presentationViewController.View).Loops       = true;

                PlayerLayer1 = ConfigurePlayer(NSBundle.MainBundle.PathForResource("Movies/movie1", "mov"), "PhotoFrame-Vertical");
                PlayerLayer2 = ConfigurePlayer(NSBundle.MainBundle.PathForResource("Movies/movie2", "mov"), "PhotoFrame-Horizontal");

                SCNTransaction.Commit();
                break;
            }
        }
示例#4
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case 0:
                // Set the slide's title and subtitle and add some text
                TextManager.SetTitle("Constraints");
                TextManager.SetSubtitle("SCNConstraint");

                TextManager.AddBulletAtLevel("Applied sequentially at render time", 0);
                TextManager.AddBulletAtLevel("Only affect presentation values", 0);

                TextManager.AddCode("#aNode.#Constraints# = new SCNConstraint[] { aConstraint, anotherConstraint, ... };#");

                // Tweak the near clipping plane of the spot light to get a precise shadow map
                presentationViewController.SpotLight.Light.SetAttribute(new NSNumber(10), SCNLightAttribute.ShadowNearClippingKey);
                break;

            case 1:
                // Remove previous text
                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.FlipOutText(SlideTextManager.TextType.Code);

                // Add new text
                TextManager.SetSubtitle("SCNLookAtConstraint");
                TextManager.AddBulletAtLevel("Makes a node to look at another node", 0);
                TextManager.AddCode("#nodeA.Constraints = new SCNConstraint[] { #SCNLookAtConstraint.Create# (nodeB) };#");

                TextManager.FlipInText(SlideTextManager.TextType.Subtitle);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                TextManager.FlipInText(SlideTextManager.TextType.Code);
                break;

            case 2:
                // Setup the scene
                SetupLookAtScene();

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                // Dim the text and move back a little bit
                TextManager.TextNode.Opacity = 0.5f;
                presentationViewController.CameraHandle.Position = presentationViewController.CameraNode.ConvertPositionToNode(new SCNVector3(0, 0, 5.0f), presentationViewController.CameraHandle.ParentNode);
                SCNTransaction.Commit();
                break;

            case 3:
                // Add constraints to the arrows
                var container = ContentNode.FindChildNode("arrowContainer", true);

                // "Look at" constraint
                var constraint = SCNLookAtConstraint.Create(BallNode);

                var i = 0;
                foreach (var arrow in container.ChildNodes)
                {
                    var delayInSeconds = 0.1 * i++;
                    var popTime        = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC));
                    DispatchQueue.MainQueue.DispatchAfter(popTime, () => {
                        SCNTransaction.Begin();
                        SCNTransaction.AnimationDuration = 1;
                        // Animate to the result of applying the constraint
                        ((SCNNode)arrow.ChildNodes [0]).Rotation = new SCNVector4(0, 1, 0, (float)(Math.PI / 2));
                        arrow.Constraints = new SCNConstraint[] { constraint };
                        SCNTransaction.Commit();
                    });
                }
                break;

            case 4:
                // Create a keyframe animation to move the ball
                var animation = CAKeyFrameAnimation.FromKeyPath("position");
                animation.KeyTimes = new NSNumber[] {
                    0.0f,
                    (1.0f / 8.0f),
                    (2.0f / 8.0f),
                    (3.0f / 8.0f),
                    (4.0f / 8.0f),
                    (5.0f / 8.0f),
                    (6.0f / 8.0f),
                    (7.0f / 8.0f),
                    1.0f
                };

                animation.Values = new NSObject[] {
                    NSValue.FromVector(new SCNVector3(0, 0.0f, 0)),
                    NSValue.FromVector(new SCNVector3(20.0f, 0.0f, 20.0f)),
                    NSValue.FromVector(new SCNVector3(40.0f, 0.0f, 0)),
                    NSValue.FromVector(new SCNVector3(20.0f, 0.0f, -20.0f)),
                    NSValue.FromVector(new SCNVector3(0, 0.0f, 0)),
                    NSValue.FromVector(new SCNVector3(-20.0f, 0.0f, 20.0f)),
                    NSValue.FromVector(new SCNVector3(-40.0f, 0.0f, 0)),
                    NSValue.FromVector(new SCNVector3(-20.0f, 0.0f, -20.0f)),
                    NSValue.FromVector(new SCNVector3(0, 0.0f, 0))
                };

                animation.CalculationMode = CAAnimation.AnimationCubicPaced;                 // smooth the movement between keyframes
                animation.RepeatCount     = float.MaxValue;
                animation.Duration        = 10.0f;
                animation.TimingFunction  = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear);
                BallNode.AddAnimation(animation, new NSString("ballNodeAnimation"));

                // Rotate the ball to give the illusion of a rolling ball
                // We need two animations to do that:
                // - one rotation to orient the ball in the right direction
                // - one rotation to spin the ball
                animation          = CAKeyFrameAnimation.FromKeyPath("rotation");
                animation.KeyTimes = new NSNumber[] {
                    0.0f,
                    (0.7f / 8.0f),
                    (1.0f / 8.0f),
                    (2.0f / 8.0f),
                    (3.0f / 8.0f),
                    (3.3f / 8.0f),
                    (4.7f / 8.0f),
                    (5.0f / 8.0f),
                    (6.0f / 8.0f),
                    (7.0f / 8.0f),
                    (7.3f / 8.0f),
                    1.0f
                };

                animation.Values = new NSObject[] {
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 2))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI + Math.PI / 2))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 4))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 4))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 2))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI - Math.PI / 2))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))),
                    NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4)))
                };

                animation.RepeatCount    = float.MaxValue;
                animation.Duration       = 10.0f;
                animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear);
                BallNode.AddAnimation(animation, new NSString("ballNodeAnimation2"));

                var rotationAnimation = CABasicAnimation.FromKeyPath("rotation");
                rotationAnimation.Duration    = 1.0f;
                rotationAnimation.RepeatCount = float.MaxValue;
                rotationAnimation.To          = NSValue.FromVector(new SCNVector4(1, 0, 0, (float)(Math.PI * 2)));
                BallNode.ChildNodes [1].AddAnimation(rotationAnimation, new NSString("ballNodeRotation"));
                break;

            case 5:
                // Add a constraint to the camera
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                constraint = SCNLookAtConstraint.Create(BallNode);
                presentationViewController.CameraNode.Constraints = new SCNConstraint[] { constraint };
                SCNTransaction.Commit();
                break;

            case 6:
                // Add a constraint to the light
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                var cameraTarget = ContentNode.FindChildNode("cameraTarget", true);
                constraint = SCNLookAtConstraint.Create(cameraTarget);
                presentationViewController.SpotLight.Constraints = new SCNConstraint[] { constraint };
                SCNTransaction.Commit();
                break;
            }
        }
示例#5
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            SCNTransaction.Begin();
            switch (index)
            {
            case 0:
                // Set the slide's title and subtitle and add some text
                TextManager.SetTitle("Node Attributes");
                TextManager.SetSubtitle("Camera");
                TextManager.AddBulletAtLevel("Point of view for renderers", 0);

                // Start with the "sign" model hidden
                var group = ContentNode.FindChildNode("group", true);
                group.Scale  = new SCNVector3(0, 0, 0);
                group.Hidden = true;
                break;

            case 1:
                // Reveal the model (unhide then scale)
                group = ContentNode.FindChildNode("group", true);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0;
                group.Hidden = false;
                SCNTransaction.Commit();

                SCNTransaction.AnimationDuration = 1.0f;
                group.Scale = new SCNVector3(1, 1, 1);
                break;

            case 2:
                TextManager.AddCode("#aNode.#Camera# = #SCNCamera#.Create (); \naView.#PointOfView# = aNode;#");
                break;

            case 3:
                // Switch to camera1
                SCNTransaction.AnimationDuration = 2.0f;
                ((SCNView)presentationViewController.View).PointOfView = ContentNode.FindChildNode("camera1", true);
                break;

            case 4:
                // Switch to camera2
                SCNTransaction.AnimationDuration = 2.0f;
                ((SCNView)presentationViewController.View).PointOfView = ContentNode.FindChildNode("camera2", true);
                break;

            case 5:
                // On completion add some code
                SCNTransaction.SetCompletionBlock(() => {
                    TextManager.FadesIn = true;
                    TextManager.AddEmptyLine();
                    TextManager.AddCode("#aNode.#Camera#.XFov = angleInDegrees;#");
                });

                // Switch back to the default camera
                SCNTransaction.AnimationDuration = 1.0f;
                ((SCNView)presentationViewController.View).PointOfView = presentationViewController.CameraNode;
                break;

            case 6:
                // Switch to camera 3
                SCNTransaction.AnimationDuration = 1.0f;
                var target = ContentNode.FindChildNode("camera3", true);

                // Don't let the default transition animate the FOV (we will animate the FOV separately)
                var wantedFOV = target.Camera.XFov;
                target.Camera.XFov = ((SCNView)presentationViewController.View).PointOfView.Camera.XFov;

                // Animate point of view with an ease-in/ease-out function
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration       = 1.0f;
                SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                ((SCNView)presentationViewController.View).PointOfView = target;
                SCNTransaction.Commit();

                // Animate the FOV with the default timing function (for a better looking transition)
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                ((SCNView)presentationViewController.View).PointOfView.Camera.XFov = wantedFOV;
                SCNTransaction.Commit();
                break;

            case 7:
                // Switch to camera 4
                var cameraNode = ContentNode.FindChildNode("camera4", true);

                // Don't let the default transition animate the FOV (we will animate the FOV separately)
                wantedFOV = cameraNode.Camera.XFov;
                cameraNode.Camera.XFov = ((SCNView)presentationViewController.View).PointOfView.Camera.XFov;

                // Animate point of view with the default timing function
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                ((SCNView)presentationViewController.View).PointOfView = cameraNode;
                SCNTransaction.Commit();

                // Animate the FOV with an ease-in/ease-out function
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration       = 1.0f;
                SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                ((SCNView)presentationViewController.View).PointOfView.Camera.XFov = wantedFOV;
                SCNTransaction.Commit();
                break;

            case 8:
                // Quickly switch back to the default camera
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                ((SCNView)presentationViewController.View).PointOfView = presentationViewController.CameraNode;
                SCNTransaction.Commit();
                break;
            }
            SCNTransaction.Commit();
        }
示例#6
0
        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("Performance");
                TextManager.SetSubtitle("Copying");

                TextManager.AddBulletAtLevel("Attributes are shared by default", 0);
                TextManager.AddBulletAtLevel("Unshare if needed", 0);
                TextManager.AddBulletAtLevel("Copying geometries is cheap", 0);

                break;

            case 1:
                // New "Node B" box
                var nodeB = Utils.SCBoxNode("Node B", new CGRect(-55, -36, 110, 50), GreenColor, 10, true);
                nodeB.Name     = "nodeB";
                nodeB.Position = new SCNVector3(140, 0, 0);
                nodeB.Opacity  = 0;

                var nodeA = ContentNode.FindChildNode("nodeA", true);
                nodeA.AddChildNode(nodeB);

                // Arrow from "Root Node" to "Node B"
                var arrowNode = SCNNode.Create();
                arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(140, 3), new CGSize(10, 14), 4, true), 0);
                arrowNode.Position = new SCNVector3(-130, 60, 0);
                arrowNode.Rotation = new SCNVector4(0, 0, 1, -(float)(Math.PI * 0.12f));
                arrowNode.Geometry.FirstMaterial.Diffuse.Contents = GreenColor;
                nodeB.AddChildNode(arrowNode);

                // Arrow from "Node B" to the shared geometry
                arrowNode          = SCNNode.Create();
                arrowNode.Name     = "arrow-shared-geometry";
                arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(140, 3), new CGSize(10, 14), 4, false), 0);
                arrowNode.Position = new SCNVector3(0, -28, 0);
                arrowNode.Rotation = new SCNVector4(0, 0, 1, (float)(Math.PI * 1.12f));
                arrowNode.Geometry.FirstMaterial.Diffuse.Contents = PurpleColor;
                nodeB.AddChildNode(arrowNode);

                // Reveal
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                nodeB.Opacity = 1.0f;

                // Show the related code
                TextManager.AddCode("#// Copy a node \n"
                                    + "var nodeB = nodeA.#Copy# ();#");
                SCNTransaction.Commit();
                break;

            case 2:
                var geometryNodeA = ContentNode.FindChildNode("geometry", true);
                var oldArrowNode  = ContentNode.FindChildNode("arrow-shared-geometry", true);

                // New "Geometry" box
                var geometryNodeB = Utils.SCBoxNode("Geometry", new CGRect(-55, -20, 110, 40), PurpleColor, 10, true);
                geometryNodeB.Position = new SCNVector3(140, 0, 0);
                geometryNodeB.Opacity  = 0;
                geometryNodeA.AddChildNode(geometryNodeB);

                // Arrow from "Node B" to the new geometry
                arrowNode          = SCNNode.Create();
                arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(55, 3), new CGSize(10, 14), 4, false), 0);
                arrowNode.Position = new SCNVector3(0, 75, 0);
                arrowNode.Rotation = new SCNVector4(0, 0, 1, -(float)(Math.PI * 0.5f));
                arrowNode.Geometry.FirstMaterial.Diffuse.Contents = PurpleColor;
                geometryNodeB.AddChildNode(arrowNode);

                // Arrow from the new geometry to "Material"
                arrowNode          = SCNNode.Create();
                arrowNode.Name     = "arrow-shared-material";
                arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(140, 3), new CGSize(10, 14), 4, true), 0);
                arrowNode.Position = new SCNVector3(-130, -80, 0);
                arrowNode.Rotation = new SCNVector4(0, 0, 1, (float)(Math.PI * 0.12f));
                arrowNode.Geometry.FirstMaterial.Diffuse.Contents = RedColor;
                geometryNodeB.AddChildNode(arrowNode);

                // Reveal
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                geometryNodeB.Opacity            = 1.0f;
                oldArrowNode.Opacity             = 0.0f;

                // Show the related code
                TextManager.AddEmptyLine();
                TextManager.AddCode("#// Unshare geometry \n"
                                    + "nodeB.Geometry = nodeB.Geometry.#Copy# ();#");
                SCNTransaction.Commit();
                break;

            case 3:
                var materialANode = ContentNode.FindChildNode("material", true);
                oldArrowNode = ContentNode.FindChildNode("arrow-shared-material", true);

                // New "Material" box
                var materialBNode = Utils.SCBoxNode("Material", new CGRect(-55, -20, 110, 40), NSColor.Orange, 10, true);
                materialBNode.Position = new SCNVector3(140, 0, 0);
                materialBNode.Opacity  = 0;
                materialANode.AddChildNode(materialBNode);

                // Arrow from the unshared geometry to the new material
                arrowNode          = SCNNode.Create();
                arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(55, 3), new CGSize(10, 14), 4, false), 0);
                arrowNode.Position = new SCNVector3(0, 75, 0);
                arrowNode.Rotation = new SCNVector4(0, 0, 1, -(float)(Math.PI * 0.5f));
                arrowNode.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Orange;
                materialBNode.AddChildNode(arrowNode);

                // Reveal
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                materialBNode.Opacity            = 1.0f;
                oldArrowNode.Opacity             = 0.0f;
                SCNTransaction.Commit();
                break;
            }
        }