예제 #1
0
        private void Open()
        {
            if (IsOpen || IsAnimating)
            {
                return;
            }

            // Open animation
            SCNTransaction.Begin();
            SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);
            SCNTransaction.AnimationDuration       = AnimationDuration / 4f;
            FocusSquareNode().Opacity = 1.0f;

            foreach (var segment in Segments)
            {
                segment.Open();
            }

            SCNTransaction.SetCompletionBlock(() => {
                FocusSquareNode().RunAction(PulseAction(), "pulse");
            });
            SCNTransaction.Commit();

            // Scale/bounce animation
            SCNTransaction.Begin();
            SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);
            SCNTransaction.AnimationDuration       = AnimationDuration / 4f;
            FocusSquareNode().SetUniformScale(FocusSquareSize);
            SCNTransaction.Commit();

            IsOpen = true;
        }
예제 #2
0
        private void PerformOpenAnimation()
        {
            if (!this.isBorderOpen && !this.isAnimating)
            {
                this.isBorderOpen = true;
                this.isAnimating  = true;

                // Open animation
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration       = GameBoard.AnimationDuration / 4f;
                SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);

                this.borderNode.Opacity = 1f;
                foreach (var segment in this.borderSegments)
                {
                    segment.Open();
                }

                this.Scale = new SCNVector3(GameBoard.MinimumScale, GameBoard.MinimumScale, GameBoard.MinimumScale);

                // completion is run on main-thread
                SCNTransaction.SetCompletionBlock(() =>
                {
                    SCNTransaction.Begin();
                    this.borderNode.RunAction(this.PulseAction(), "pulse");
                    this.isAnimating = false;
                    SCNTransaction.Commit();
                });


                SCNTransaction.Commit();
            }
        }
예제 #3
0
        void SetupCamera()
        {
            SCNNode     pov      = GameView.PointOfView;
            const float altitude = 1f;
            const float distance = 10f;

            cameraYHandle = SCNNode.Create();
            cameraXHandle = SCNNode.Create();

            cameraYHandle.Position = new SCNVector3(0f, altitude, 0f);
            cameraYHandle.AddChildNode(cameraXHandle);
            GameView.Scene.RootNode.AddChildNode(cameraYHandle);

            pov.EulerAngles = new SCNVector3(0f, 0f, 0f);
            pov.Position    = new SCNVector3(0f, 0f, distance);

            cameraYHandle.Rotation = new SCNVector4(0f, 1f, 0f, (float)Math.PI / 2f + (float)Math.PI / 4f * 3f);
            cameraXHandle.Rotation = new SCNVector4(1f, 0f, 0f, -(float)Math.PI / 4f * 0.125f);
            cameraXHandle.AddChildNode(pov);

            // Animate camera on launch and prevent the user from manipulating the camera until the end of the animation
            lockCamera = true;
            SCNTransaction.Begin();
            SCNTransaction.SetCompletionBlock(() => {
                lockCamera = false;
            });

            var cameraYAnimation = CABasicAnimation.FromKeyPath("rotation.w");

            cameraYAnimation.From           = NSNumber.FromDouble(Math.PI * 2 - cameraYHandle.Rotation.W);
            cameraYAnimation.To             = NSNumber.FromDouble(0.0);
            cameraYAnimation.Additive       = true;
            cameraYAnimation.BeginTime      = CAAnimation.CurrentMediaTime() + 3;
            cameraYAnimation.FillMode       = CAFillMode.Both;
            cameraYAnimation.Duration       = 5.0;
            cameraYAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
            cameraYHandle.AddAnimation(cameraYAnimation, null);

            var cameraXAnimation = CABasicAnimation.FromKeyPath("rotation.w");

            cameraXAnimation.From           = NSNumber.FromDouble(-Math.PI / 2 + cameraXHandle.Rotation.W);
            cameraXAnimation.To             = NSNumber.FromDouble(0.0);
            cameraXAnimation.Additive       = true;
            cameraXAnimation.FillMode       = CAFillMode.Both;
            cameraXAnimation.Duration       = 5.0;
            cameraXAnimation.BeginTime      = CAAnimation.CurrentMediaTime() + 3;
            cameraXAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
            cameraXHandle.AddAnimation(cameraXAnimation, null);

            SCNTransaction.Commit();

            var lookAtConstraint = SCNLookAtConstraint.Create(Character.Node.FindChildNode("Bip001_Head", true));

            lookAtConstraint.InfluenceFactor = 0;
            pov.Constraints = new SCNConstraint[] { lookAtConstraint };
        }
예제 #4
0
        private void Close(bool flash = false)
        {
            if (!IsOpen || IsAnimating)
            {
                return;
            }

            IsAnimating = true;
            StopPulsing(FocusSquareNode());

            // Close animation
            SCNTransaction.Begin();
            SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);
            SCNTransaction.AnimationDuration       = AnimationDuration / 2f;
            FocusSquareNode().Opacity = 0.99f;
            SCNTransaction.SetCompletionBlock(() => {
                SCNTransaction.Begin();
                SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);
                SCNTransaction.AnimationDuration       = AnimationDuration / 4f;

                foreach (var segment in segments)
                {
                    segment.Close();
                }

                SCNTransaction.SetCompletionBlock(() => {
                    IsAnimating = false;
                });
                SCNTransaction.Commit();
            });
            SCNTransaction.Commit();

            // Scale/bounce animation
            FocusSquareNode().AddAnimation(ScaleAnimation("transform.scale.x"), "transform.scale.y");
            FocusSquareNode().AddAnimation(ScaleAnimation("transform.scale.y"), "transform.scale.y");
            FocusSquareNode().AddAnimation(ScaleAnimation("transform.scale.z"), "transform.scale.z");

            // Flash?
            if (flash)
            {
                var waitAction    = SCNAction.Wait(AnimationDuration * 0.75f);
                var fadeInAction  = SCNAction.FadeOpacityTo(0.25f, AnimationDuration * 0.125f);
                var fadeOutAction = SCNAction.FadeOpacityTo(0.0f, AnimationDuration * 0.125f);
                FillPlane.RunAction(SCNAction.Sequence(new SCNAction[] { waitAction, fadeInAction, fadeOutAction }));

                var flashSquareAction = FlashAnimation(AnimationDuration * 0.25f);
                foreach (var segment in Segments)
                {
                    segment.RunAction(SCNAction.Sequence(new[] { waitAction, flashSquareAction }));
                }
            }

            IsOpen = false;
        }
예제 #5
0
 void RemoveNumberNodes()
 {
     // Move, fade and remove on completion
     foreach (var node in GroundNode.ChildNodes)
     {
         if (node.Name == "number")
         {
             SCNTransaction.Begin();
             SCNTransaction.AnimationDuration = 1;
             SCNTransaction.SetCompletionBlock(node.RemoveFromParentNode);
             node.Opacity  = 0.0f;
             node.Position = new SCNVector3(node.Position.X, node.Position.Y, node.Position.Z - 20);
             SCNTransaction.Commit();
         }
     }
 }
예제 #6
0
        // Animate (fade out) to remove the text of specified type
        public void FadeOutText(TextType type)
        {
            var node = SubGroups [(int)type];

            SubGroups [(int)type] = null;
            if (node != null)
            {
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = FLIP_DURATION;
                SCNTransaction.SetCompletionBlock(node.RemoveFromParentNode);
                node.Opacity = 0;
                SCNTransaction.Commit();

                // Reset the baseline to what it was before adding this text
                CurrentBaseline = Math.Max(CurrentBaseline, BaselinePerType [(int)type]);
            }
        }
예제 #7
0
        private void PerformCloseAnimation(bool flash = false)
        {
            if (this.isBorderOpen && !this.isAnimating)
            {
                this.isBorderOpen = false;
                this.isAnimating  = true;

                this.borderNode.RemoveAction("pulse");
                this.borderNode.Opacity = 1f;

                // Close animation
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration       = GameBoard.AnimationDuration / 2f;
                SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);

                this.borderNode.Opacity = 0.99f;
                SCNTransaction.SetCompletionBlock(() =>
                {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration       = GameBoard.AnimationDuration / 2f;
                    SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);

                    foreach (var segment in this.borderSegments)
                    {
                        segment.Close();
                    }

                    SCNTransaction.SetCompletionBlock(() =>
                    {
                        this.isAnimating = false;
                    });

                    SCNTransaction.Commit();
                });

                SCNTransaction.Commit();

                if (flash)
                {
                    var waitAction    = SCNAction.Wait(GameBoard.AnimationDuration * 0.75f);
                    var fadeInAction  = SCNAction.FadeOpacityTo(0.6f, GameBoard.AnimationDuration * 0.125f);
                    var fadeOutAction = SCNAction.FadeOpacityTo(0f, GameBoard.AnimationDuration * 0.125f);
                    this.FillPlane.RunAction(SCNAction.Sequence(new SCNAction[] { waitAction, fadeOutAction, fadeInAction }));
                }
            }
        }
예제 #8
0
        protected void PerformEnemyDieWithExplosion(SCNNode enemy, SCNVector3 direction)
        {
            var explositionScene = SCNScene.FromFile("art.scnassets/enemy/enemy_explosion.scn");

            if (explositionScene != null)
            {
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration       = 0.4f;
                SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseOut);

                SCNTransaction.SetCompletionBlock(() =>
                {
                    explositionScene.RootNode.EnumerateHierarchy((SCNNode node, out bool stop) =>
                    {
                        stop = false;
                        if (node.ParticleSystems != null)
                        {
                            foreach (var particle in node.ParticleSystems)
                            {
                                enemy.AddParticleSystem(particle);
                            }
                        }
                    });

                    // Hide
                    if (enemy.ChildNodes.Length > 0)
                    {
                        enemy.ChildNodes[0].Opacity = 0f;
                    }
                });

                direction.Y = 0;
                enemy.RemoveAllAnimations();
                enemy.EulerAngles = new SCNVector3(enemy.EulerAngles.X, enemy.EulerAngles.X + (float)Math.PI * 4.0f, enemy.EulerAngles.Z);

                enemy.WorldPosition += SCNVector3.Normalize(direction) * 1.5f;
                this.PositionAgentFromNode();

                SCNTransaction.Commit();
            }
            else
            {
                Console.WriteLine("Missing enemy_explosion.scn");
            }
        }
        private void WillOrderOutSlide(int slideIndex)
        {
            var slide = GetSlide(slideIndex, false);

            if (slide != null)
            {
                var node = slide.ContentNode;

                // Fade out and remove on completion
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                SCNTransaction.SetCompletionBlock(() => node.RemoveFromParentNode());
                node.Opacity = 0.0f;
                SCNTransaction.Commit();

                slide.WillOrderOut(this);

                SlideCache.Remove(slideIndex.ToString());
            }
        }
예제 #10
0
        public void AnimateBallGrowAndDrop()
        {
            // the block is the total time of the transcation, so sub-blocks are limited by that too
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = this.properties.GrowAnimationTime;

            // correct the rope sim by animating back to reset pose no matter what
            var fixupLaunchAnimationTime = 0.1f;

            this.rope.InterpolateToRestPoseAnimation(fixupLaunchAnimationTime);

            // first scale the ball from small to original size
            if (this.Projectile != null)
            {
                this.Projectile.Scale = this.projectileScale;
            }

            SCNTransaction.SetCompletionBlock(() =>
            {
                // after back to scale, then run the ball drop
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = this.properties.DropAnimationTime;

                // next drop from ballOriginInactiveAbove to ballOriginInactive
                if (this.Projectile != null)
                {
                    this.Projectile.WorldPosition = this.ballOriginInactiveBelow.WorldPosition;
                }

                SCNTransaction.SetCompletionBlock(() =>
                {
                    // only allow the ball to be grabbed after animation completes
                    this.ballCanBeGrabbed = true;
                });

                SCNTransaction.Commit();
            });

            SCNTransaction.Commit();
        }
예제 #11
0
파일: GameView.cs 프로젝트: zrma/PolyGlot
        // forward click event to the game view controller
        public override void MouseDown(NSEvent theEvent)
        {
            // Called when a mouse click occurs

            // check what nodes are clicked
            var p          = ConvertPointFromView(theEvent.LocationInWindow, null);
            var hitResults = HitTest(p, (NSDictionary)null);

            // check that we clicked on at least one object
            if (hitResults.Length > 0)
            {
                // retrieved the first clicked object
                var result = hitResults[0];

                // get its material
                var material = result.Node.Geometry.FirstMaterial;

                // highlight it
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.5f;

                // on completion - unhighlight
                SCNTransaction.SetCompletionBlock(() =>
                {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 0.5f;

                    material.Emission.Contents = NSColor.Black;

                    SCNTransaction.Commit();
                });

                material.Emission.Contents = NSColor.Red;

                SCNTransaction.Commit();
            }

            base.MouseDown(theEvent);
        }
예제 #12
0
        void HandleTap(UIGestureRecognizer gestureRecognize)
        {
            // retrieve the SCNView
            var scnView = (SCNView)View;

            // check what nodes are tapped
            CGPoint p = gestureRecognize.LocationInView(scnView);

            SCNHitTestResult[] hitResults = scnView.HitTest(p, (SCNHitTestOptions)null);

            // check that we clicked on at least one object
            if (hitResults.Length > 0)
            {
                // retrieved the first clicked object
                SCNHitTestResult result = hitResults [0];

                // get its material
                SCNMaterial material = result.Node.Geometry.FirstMaterial;

                // highlight it
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.5f;

                // on completion - unhighlight
                SCNTransaction.SetCompletionBlock(() => {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 0.5f;

                    material.Emission.Contents = UIColor.Black;

                    SCNTransaction.Commit();
                });

                material.Emission.Contents = UIColor.Red;

                SCNTransaction.Commit();
            }
        }
예제 #13
0
        // End the game by showing the congratulation screen after fading the object to white.
        void EndGame()
        {
            var gNodes = gameNodes.Value;

            textUpdateTimer?.Invalidate();
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = 0.5;
            SCNTransaction.SetCompletionBlock(() => {
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.3;
                SCNTransaction.SetCompletionBlock(() => {
                    ShowCongratulation();
                    gNodes.ObjectMaterial.Emission.Contents = UIColor.Black;
                    gameStarted = false;
                });
                SCNTransaction.Commit();
            });

            gNodes.Object.Transform = SCNMatrix4.Identity;
            gNodes.ObjectMaterial.Emission.Contents = UIColor.White;
            gNodes.ObjectMaterial.Transparency      = 0;

            SCNTransaction.Commit();
        }
예제 #14
0
        // Animate (flip) to remove the text of specified type
        public void FlipOutText(TextType type)
        {
            var node = SubGroups [(int)type];

            SubGroups [(int)type] = null;
            if (node != null)
            {
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0;
                node.Position = new SCNVector3(-PIVOT_X, 0, 0);
                node.Pivot    = SCNMatrix4.CreateTranslation(-PIVOT_X, 0, 0);
                SCNTransaction.Commit();

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = FLIP_DURATION;
                SCNTransaction.SetCompletionBlock(node.RemoveFromParentNode);
                node.Rotation = new SCNVector4(0, 1, 0, FLIP_ANGLE);
                node.Opacity  = 0;
                SCNTransaction.Commit();
            }

            // Reset the baseline to what it was before adding this text
            CurrentBaseline = Math.Max(CurrentBaseline, BaselinePerType [(int)type]);
        }
        public void ShowsNewInSceneKitBadge(bool showsBadge)
        {
            if (NewBadgeNode != null && showsBadge)
            {
                return;                 // already visible
            }
            if (NewBadgeNode == null && !showsBadge)
            {
                return;                 // already invisible
            }
            // Load the model and the animation
            if (NewBadgeNode == null)
            {
                NewBadgeNode = SCNNode.Create();

                var badgeNode = Utils.SCAddChildNode(NewBadgeNode, "newBadge", "Scenes.scnassets/newBadge", 1);
                NewBadgeNode.Scale    = new SCNVector3(0.03f, 0.03f, 0.03f);
                NewBadgeNode.Opacity  = 0;
                NewBadgeNode.Position = new SCNVector3(50, 20, -10);
                NewBadgeNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2));

                var imageNode = NewBadgeNode.FindChildNode("badgeImage", true);
                imageNode.Geometry.FirstMaterial.Emission.Intensity = 0.0f;

                CameraPitch.AddChildNode(NewBadgeNode);

                NewBadgeAnimation = badgeNode.GetAnimation(badgeNode.GetAnimationKeys() [0]);
                badgeNode.RemoveAllAnimations();

                NewBadgeAnimation.Speed               = 1.5f;
                NewBadgeAnimation.FillMode            = CAFillMode.Both;
                NewBadgeAnimation.UsesSceneTimeBase   = false;
                NewBadgeAnimation.RemovedOnCompletion = false;
                NewBadgeAnimation.RepeatCount         = 0;
            }

            // Play
            if (showsBadge)
            {
                NewBadgeNode.AddAnimation(NewBadgeAnimation, new NSString("badgeAnimation"));

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 2;
                NewBadgeNode.Position            = new SCNVector3(14, 8, -20);

                SCNTransaction.SetCompletionBlock(() => {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 3;
                    if (NewBadgeNode != null)
                    {
                        SCNNode ropeNode = NewBadgeNode.FindChildNode("rope02", true);
                        ropeNode.Opacity = 0.0f;
                    }
                    SCNTransaction.Commit();
                });

                NewBadgeNode.Opacity = 1.0f;
                SCNNode imageNode = NewBadgeNode.FindChildNode("badgeImage", true);
                imageNode.Geometry.FirstMaterial.Emission.Intensity = 0.4f;
                SCNTransaction.Commit();
            }

            // Or hide
            else
            {
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.5f;
                SCNTransaction.SetCompletionBlock(() => {
                    if (NewBadgeNode != null)
                    {
                        NewBadgeNode.RemoveFromParentNode();
                        NewBadgeNode = null;
                    }
                });
                NewBadgeNode.Position = new SCNVector3(14, 50, -20);
                NewBadgeNode.Opacity  = 0.0f;
                SCNTransaction.Commit();
            }
        }
예제 #16
0
        void StartGame()
        {
            if (!gameNodes.HasValue)
            {
                throw new InvalidProgramException("Nodes not set");
            }

            var startSequence = SCNAction.Sequence(new SCNAction [] {
                // Wait for 1 second.
                SCNAction.Wait(1),
                SCNAction.Group(new SCNAction[] {
                    SCNAction.FadeIn(0.3),

                    // Start the game.
                    SCNAction.Run(node => {
                        if (!gameNodes.HasValue)
                        {
                            return;
                        }
                        var gNodes = gameNodes.Value;

                        var rnd = new Random();

                        // Compute a random orientation for the object3D.
                        var theta = (float)(Math.PI * rnd.NextDouble());
                        var phi   = (float)(Math.Acos(2 * rnd.NextDouble() - 1) / NMath.PI);

                        var axis = new Vector3 {
                            X = (float)(Math.Cos(theta) * Math.Sin(phi)),
                            Y = (float)(Math.Sin(theta) * Math.Sin(phi)),
                            Z = (float)Math.Cos(theta)
                        };
                        var angle = (float)(2 * Math.PI * rnd.NextDouble());

                        SCNTransaction.Begin();
                        SCNTransaction.AnimationDuration = 0.3;
                        SCNTransaction.SetCompletionBlock(() => gameStarted = true);

                        gNodes.ObjectMaterial.Transparency = 1;
                        gNodes.Object.Transform            = SCNMatrix4.CreateFromAxisAngle(axis, angle);

                        SCNTransaction.Commit();
                    })
                })
            });

            gameNodes.Value.Object.RunAction(startSequence);

            // Load and set the background image.
            var backgroundImage = UIImage.FromBundle("art.scnassets/background.png");

            sceneInterface.Scene.Background.Contents = backgroundImage;

            // Hide particles, set camera projection to orthographic.
            particleRemovalTimer?.Invalidate();
            gameNodes.Value.CongratulationsLabel.RemoveFromParent();
            gameNodes.Value.Confetti.Hidden = true;
            gameNodes.Value.Camera.UsesOrthographicProjection = true;

            // Reset the countdown.
            countdown = 30;
            gameNodes.Value.CountdownLabel.Text      = countdown.ToString();
            gameNodes.Value.CountdownLabel.FontColor = GameColors.DefaultFont;
            gameNodes.Value.CountdownLabel.Position  = new CGPoint(ContentFrame.Width / 2, ContentFrame.Height - 30);

            textUpdateTimer?.Invalidate();
            textUpdateTimer = NSTimer.CreateRepeatingScheduledTimer(1, UpdateText);
        }
        public void GoToSlide(int slideIndex)
        {
            int oldIndex = CurrentSlideIndex;

            // Load the slide at the specified index
            var slide = GetSlide(slideIndex, true);

            if (slide == null)
            {
                return;
            }

            // Compute the playback direction (did the user select next or previous?)
            var direction = slideIndex >= CurrentSlideIndex ? 1 : -1;

            // Update badge
            ShowsNewInSceneKitBadge(slide.IsNewIn10_10);

            // If we are playing backward, we need to use the slide we come from to play the correct transition (backward)
            int transitionSlideIndex = direction == 1 ? slideIndex : CurrentSlideIndex;
            var transitionSlide      = GetSlide(transitionSlideIndex, true);

            // Make sure that the next operations are synchronized by using a transaction
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = 0;

            var rootNode      = slide.ContentNode;
            var textContainer = slide.TextManager.TextNode;

            var offset = new SCNVector3(transitionSlide.TransitionOffsetX, 0.0f, transitionSlide.TransitionOffsetZ);

            offset.X *= direction;
            offset.Z *= direction;

            // Rotate offset based on current yaw
            var cosa = Math.Cos(-CameraHandle.Rotation.W);
            var sina = Math.Sin(-CameraHandle.Rotation.W);

            var tmpX = offset.X * cosa - offset.Z * sina;

            offset.Z = (float)(offset.X * sina + offset.Z * cosa);
            offset.X = (float)tmpX;

            // If we don't move, fade in
            if (offset.X == 0 && offset.Y == 0 && offset.Z == 0 && transitionSlide.TransitionRotation == 0)
            {
                rootNode.Opacity = 0;
            }

            // Don't animate the first slide
            bool shouldAnimate = !(slideIndex == 0 && CurrentSlideIndex == 0);

            // Update current slide index
            CurrentSlideIndex = slideIndex;

            // Go to step 0
            GoToSlideStep(0);

            // Add the slide to the scene graph
            ((SCNView)View).Scene.RootNode.AddChildNode(rootNode);

            // Fade in, update paramters and notify on completion
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = (shouldAnimate ? slide.TransitionDuration : 0);
            SCNTransaction.SetCompletionBlock(() => DidOrderInSlide(slideIndex));
            rootNode.Opacity = 1;

            CameraHandle.Position = new SCNVector3(CameraHandle.Position.X + offset.X, slide.Altitude, CameraHandle.Position.Z + offset.Z);
            CameraHandle.Rotation = new SCNVector4(0, 1, 0, (float)(CameraHandle.Rotation.W + transitionSlide.TransitionRotation * (Math.PI / 180.0f) * direction));
            CameraPitch.Rotation  = new SCNVector4(1, 0, 0, (float)(slide.Pitch * (Math.PI / 180.0f)));

            UpdateLightingForSlide(slideIndex);

            Floor.Reflectivity         = slide.FloorReflectivity;
            Floor.ReflectionFalloffEnd = slide.FloorFalloff;
            SCNTransaction.Commit();

            // Compute the position of the text (in world space, relative to the camera)
            var textWorldTransform = SCNMatrix4.Mult(SCNMatrix4.CreateTranslation(0, -3.3f, -28), CameraNode.WorldTransform);

            // Place the rest of the slide
            rootNode.Transform = textWorldTransform;
            rootNode.Position  = new SCNVector3(rootNode.Position.X, 0, rootNode.Position.Z);  // clear altitude
            rootNode.Rotation  = new SCNVector4(0, 1, 0, CameraHandle.Rotation.W);             // use same rotation as the camera to simplify the placement of the elements in slides

            // Place the text
            textContainer.Transform = textContainer.ParentNode.ConvertTransformFromNode(textWorldTransform, null);

            // Place the ground node
            var localPosition = new SCNVector3(0, 0, 0);
            var worldPosition = slide.GroundNode.ParentNode.ConvertPositionToNode(localPosition, null);

            worldPosition.Y = 0;             // make it touch the ground

            localPosition             = slide.GroundNode.ParentNode.ConvertPositionFromNode(worldPosition, null);
            slide.GroundNode.Position = localPosition;

            // Update the floor image if needed
            string  floorImagePath = null;
            NSImage floorImage     = null;

            if (slide.FloorImageName != null)
            {
                floorImagePath = NSBundle.MainBundle.PathForResource("SharedTextures/" + slide.FloorImageName, slide.FloorImageExtension);
                floorImage     = new NSImage(floorImagePath);
            }
            UpdateFloorImage(floorImage, slide);

            SCNTransaction.Commit();

            // Preload the next slide after some delay
            var delayInSeconds = 1.5;
            var popTime        = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC));

            DispatchQueue.MainQueue.DispatchAfter(popTime, () => {
                PrepareSlide(slideIndex + 1);
            });

            // Order out previous slide if any
            if (oldIndex != CurrentSlideIndex)
            {
                WillOrderOutSlide(oldIndex);
            }
        }
예제 #18
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            //animate by default
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = 1;

            switch (index)
            {
            case 0:
                SCNTransaction.AnimationDuration = 0;

                // Set the slide's title and subtitle and add some text
                TextManager.SetTitle("Morphing");
                TextManager.AddBulletAtLevel("Linear morph between multiple targets", 0);

                // Initial state, no ambient occlusion
                // This also shows how uniforms from shader modifiers can be set using KVC
                MapNode.Geometry.SetValueForKey(new NSNumber(0), new NSString("ambientOcclusionYFactor"));
                break;

            case 1:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                // Reveal the map and show the gauges
                MapNode.Opacity = 1.0f;

                GaugeAProgressNode = SCNNode.Create();
                GaugeBProgressNode = SCNNode.Create();

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0;
                GaugeANode          = Utils.SCGaugeNode("Target A", ref GaugeAProgressNode);
                GaugeANode.Position = new SCNVector3(-10.5f, 15, -5);
                ContentNode.AddChildNode(GaugeANode);

                GaugeBNode          = Utils.SCGaugeNode("Target B", ref GaugeBProgressNode);
                GaugeBNode.Position = new SCNVector3(-10.5f, 13, -5);
                ContentNode.AddChildNode(GaugeBNode);
                SCNTransaction.Commit();
                break;

            case 2:
                // Morph and update the gauges
                GaugeAProgressNode.Scale = new SCNVector3(1, 1, 1);
                MapNode.Morpher.SetWeight(0.65f, 0);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                GaugeAProgressNode.Opacity       = 1.0f;
                SCNTransaction.Commit();

                var shadowPlane = MapNode.ChildNodes [0];
                shadowPlane.Scale = new SCNVector3(0.35f, 1, 1);

                MapNode.ParentNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.75f);
                break;

            case 3:
                // Morph and update the gauges
                GaugeAProgressNode.Scale = new SCNVector3(1, 0.01f, 1);
                MapNode.Morpher.SetWeight(0, 0);

                shadowPlane       = MapNode.ChildNodes [0];
                shadowPlane.Scale = new SCNVector3(1, 1, 1);

                MapNode.ParentNode.Rotation = new SCNVector4(1, 0, 0, 0);

                SCNTransaction.SetCompletionBlock(() => {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 0.5f;
                    GaugeAProgressNode.Opacity       = 0.0f;
                    SCNTransaction.Commit();
                });
                break;

            case 4:
                // Morph and update the gauges
                GaugeBProgressNode.Scale = new SCNVector3(1, 1, 1);
                MapNode.Morpher.SetWeight(0.4f, 1);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.1f;
                GaugeBProgressNode.Opacity       = 1.0f;
                SCNTransaction.Commit();

                shadowPlane       = MapNode.ChildNodes [0];
                shadowPlane.Scale = new SCNVector3(1, 0.6f, 1);

                MapNode.ParentNode.Rotation = new SCNVector4(0, 1, 0, -(float)(Math.PI / 4) * 0.5f);
                break;

            case 5:
                // Morph and update the gauges
                GaugeBProgressNode.Scale = new SCNVector3(1, 0.01f, 1);
                MapNode.Morpher.SetWeight(0, 1);

                shadowPlane       = MapNode.ChildNodes [0];
                shadowPlane.Scale = new SCNVector3(1, 1, 1);

                MapNode.ParentNode.Rotation = new SCNVector4(0, 1, 0, 0);

                SCNTransaction.SetCompletionBlock(() => {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 0.5f;
                    GaugeBProgressNode.Opacity       = 0.0f;
                    SCNTransaction.Commit();
                });
                break;

            case 6:
                // Morph and update the gauges
                GaugeAProgressNode.Scale = new SCNVector3(1, 1, 1);
                GaugeBProgressNode.Scale = new SCNVector3(1, 1, 1);

                MapNode.Morpher.SetWeight(0.65f, 0);
                MapNode.Morpher.SetWeight(0.30f, 1);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.1f;
                GaugeAProgressNode.Opacity       = 1.0f;
                GaugeBProgressNode.Opacity       = 1.0f;
                SCNTransaction.Commit();

                shadowPlane         = MapNode.ChildNodes [0];
                shadowPlane.Scale   = new SCNVector3(0.4f, 0.7f, 1);
                shadowPlane.Opacity = 0.2f;

                MapNode.Geometry.SetValueForKey(new NSNumber(0.35f), new NSString("ambientOcclusionYFactor"));
                MapNode.Position            = new SCNVector3(0, 0, 5);
                MapNode.ParentNode.Rotation = new SCNVector4(0, 1, 0, -(float)(Math.PI / 4) * 0.5f);
                MapNode.Rotation            = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.75f);
                break;

            case 7:
                SCNTransaction.AnimationDuration = 0.5f;

                // Hide everything and update the text
                MapNode.Opacity    = 0;
                GaugeANode.Opacity = 0.0f;
                GaugeBNode.Opacity = 0.0f;

                TextManager.SetSubtitle("SCNMorpher");
                TextManager.AddBulletAtLevel("Topology must match", 0);
                TextManager.AddBulletAtLevel("Can be loaded from DAEs", 0);
                TextManager.AddBulletAtLevel("Can be created programmatically", 0);

                break;
            }
            SCNTransaction.Commit();
        }
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case 0:
                TextManager.SetSubtitle("Built-in parametric primitives");
                break;

            case 1:
                PresentPrimitives();
                break;

            case 2:
                // Hide the carousel and illustrate SCNText
                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                SCNTransaction.SetCompletionBlock(() => {
                    if (CarouselNode != null)
                    {
                        CarouselNode.RemoveFromParentNode();
                    }
                });

                PresentTextNode();

                TextNode.Opacity = 1.0f;

                if (CarouselNode != null)
                {
                    CarouselNode.Position = new SCNVector3(0, CarouselNode.Position.Y, -50);
                    CarouselNode.Opacity  = 0.0f;
                }

                SCNTransaction.Commit();

                TextManager.SetSubtitle("Built-in 3D text");
                TextManager.AddBulletAtLevel("SCNText", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Subtitle);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                break;

            case 3:
                //Show bezier path
                var star = StarPath(3, 6);

                var shape = SCNShape.Create(star, 1);
                shape.ChamferRadius  = 0.2f;
                shape.ChamferProfile = OutlineChamferProfilePath();
                shape.ChamferMode    = SCNChamferMode.Front;

                // that way only the outline of the model will be visible
                var outlineMaterial = SCNMaterial.Create();
                outlineMaterial.Ambient.Contents  = outlineMaterial.Diffuse.Contents = outlineMaterial.Specular.Contents = NSColor.Black;
                outlineMaterial.Emission.Contents = NSColor.White;
                outlineMaterial.DoubleSided       = true;

                var tranparentMaterial = SCNMaterial.Create();
                tranparentMaterial.Transparency = 0.0f;

                shape.Materials = new SCNMaterial[] {
                    tranparentMaterial,
                    tranparentMaterial,
                    tranparentMaterial,
                    outlineMaterial,
                    outlineMaterial
                };

                StarOutline          = SCNNode.Create();
                StarOutline.Geometry = shape;
                StarOutline.Position = new SCNVector3(0, 5, 30);
                StarOutline.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(0, (float)Math.PI * 2, 0, 10.0)));

                GroundNode.AddChildNode(StarOutline);

                // Hide the 3D text and introduce SCNShape
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                SCNTransaction.SetCompletionBlock(() => {
                    TextNode.RemoveFromParentNode();
                });

                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                TextManager.SetSubtitle("3D Shapes");

                TextManager.AddBulletAtLevel("SCNShape", 0);

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

                StarOutline.Position = new SCNVector3(0, 5, 0);
                TextNode.Position    = new SCNVector3(TextNode.Position.X, TextNode.Position.Y, -30);


                SCNTransaction.Commit();
                break;

            case 4:
                star = StarPath(3, 6);

                shape = SCNShape.Create(star, 0);
                shape.ChamferRadius = 0.1f;

                StarNode          = SCNNode.Create();
                StarNode.Geometry = shape;
                var material = SCNMaterial.Create();
                material.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/color_envmap", "png"));
                material.Diffuse.Contents    = NSColor.Black;
                StarNode.Geometry.Materials  = new SCNMaterial[] { material };
                StarNode.Position            = new SCNVector3(0, 5, 0);
                StarNode.Pivot = SCNMatrix4.CreateTranslation(0, 0, -0.5f);
                StarOutline.ParentNode.AddChildNode(StarNode);

                StarNode.EulerAngles = StarOutline.EulerAngles;
                StarNode.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(0, (float)Math.PI * 2, 0, 10.0)));

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                SCNTransaction.SetCompletionBlock(() => {
                    StarOutline.RemoveFromParentNode();
                });

                shape.ExtrusionDepth = 1;
                StarOutline.Opacity  = 0.0f;

                SCNTransaction.Commit();
                break;

            case 5:
                //OpenSubdiv
                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                TextManager.SetSubtitle("Subdivisions");

                TextManager.AddBulletAtLevel("OpenSubdiv", 0);
                TextManager.AddCode("#aGeometry.#SubdivisionLevel# = anInteger;#");

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

                //add boxes
                var boxesNode = SCNNode.Create();

                var level0 = Utils.SCAddChildNode(boxesNode, "rccarBody_LP", "Scenes.scnassets/car/car_lowpoly", 10);
                level0.Position = new SCNVector3(-6, level0.Position.Y, 0);

                var label = Utils.SCBoxNode("0", new CGRect(0, 0, 40, 40), NSColor.Orange, 20.0f, true);
                label.Position = new SCNVector3(0, -35, 10);
                label.Scale    = new SCNVector3(0.3f, 0.3f, 0.001f);
                level0.AddChildNode(label);

                boxesNode.Position = new SCNVector3(0, 0, 30);

                var level1 = level0.Clone();

                /*foreach (var child in level1.ChildNodes) {
                 *      if (child.Name != "engine_LP") {
                 *              child.Geometry = (SCNGeometry)child.Geometry.Copy ();
                 *              child.Geometry.SubdivisionLevel = 3;
                 *      }
                 * }*/

                level1.Position = new SCNVector3(6, level1.Position.Y, 0);
                boxesNode.AddChildNode(level1);

                label          = Utils.SCBoxNode("2", new CGRect(0, 0, 40, 40), NSColor.Orange, 20.0f, true);
                label.Position = new SCNVector3(0, -35, 10);
                label.Scale    = new SCNVector3(0.3f, 0.3f, 0.001f);
                level1.AddChildNode(label);

                level0.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy((float)Math.PI * 2, new SCNVector3(0, 1, 0), 45.0)));
                level1.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy((float)Math.PI * 2, new SCNVector3(0, 1, 0), 45.0)));

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                SCNTransaction.SetCompletionBlock(() => {
                    StarNode.RemoveFromParentNode();
                });

                // move the camera back to its previous position
                presentationViewController.CameraNode.Position  = new SCNVector3(0, 0, 0);
                presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)Math.PI / 180.0f);

                StarNode.Position    = new SCNVector3(StarNode.Position.X, StarNode.Position.Y, StarNode.Position.Z - 30);
                StarOutline.Position = new SCNVector3(StarOutline.Position.X, StarOutline.Position.Y, StarOutline.Position.Z - 30);

                GroundNode.AddChildNode(boxesNode);

                //move boxes in
                boxesNode.Position = new SCNVector3(0, 0, 3.5f);

                SCNTransaction.Commit();
                break;
            }
        }
예제 #20
0
        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;
            }
        }
예제 #21
0
        public override void PresentStep(int switchIndex, PresentationViewController presentationViewController)
        {
            switch (switchIndex)
            {
            case 0:
                // Set the slide's title and subtitle and add some text
                TextManager.SetTitle("Core Image");
                TextManager.SetSubtitle("CI Filters");

                TextManager.AddBulletAtLevel("Screen-space effects", 0);
                TextManager.AddBulletAtLevel("Applies to a node hierarchy", 0);
                TextManager.AddBulletAtLevel("Filter parameters are animatable", 0);
                TextManager.AddCode("#aNode.#Filters# = new CIFilter[] { filter1, filter2 };#");
                break;

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

                // Reveal the grid
                GroupNode.Opacity = 1;
                break;

            case 2:
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                // Highlight an item
                HighlightContact(13, presentationViewController);
                SCNTransaction.Commit();
                break;

            case 3:
                var index   = 13;
                var subStep = 0;

                // Successively select items
                for (var i = 0; i < 5; ++i)
                {
                    var popTime = new DispatchTime(DispatchTime.Now, (long)(i * 0.2 * Utils.NSEC_PER_SEC));
                    DispatchQueue.MainQueue.DispatchAfter(popTime, () => {
                        SCNTransaction.Begin();
                        SCNTransaction.AnimationDuration = 0.2f;
                        UnhighlightContact(index);

                        if (subStep++ == 3)
                        {
                            index += ColumnCount;
                        }
                        else
                        {
                            index++;
                        }

                        HighlightContact(index, presentationViewController);
                        SCNTransaction.Commit();
                    });
                }
                break;

            case 4:
                // BLUR+DESATURATE in the background, GLOW in the foreground

                // Here we will change the node hierarchy in order to group all the nodes in the background under a single node.
                // This way we can use a single Core Image filter and apply it on the whole grid, and have another CI filter for the node in the foreground.

                var selectionParent = HeroNode.ParentNode;

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0;
                // Stop the animations of the selected node
                HeroNode.Transform = HeroNode.PresentationNode.Transform;                 // set the current rotation to the current presentation value
                HeroNode.RemoveAllAnimations();

                // Re-parent the node by preserving its world tranform
                var wantedWorldTransform = selectionParent.WorldTransform;
                GroupNode.ParentNode.AddChildNode(selectionParent);
                selectionParent.Transform = selectionParent.ParentNode.ConvertTransformFromNode(wantedWorldTransform, null);
                SCNTransaction.Commit();

                // Add CIFilters

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                // A negative 'centerX' value means no scaling.
                //TODO HeroNode.Filters [0].SetValueForKey (new NSNumber (-1), new NSString ("centerX"));

                // Move the selection to the foreground
                selectionParent.Rotation = new SCNVector4(0, 1, 0, 0);
                HeroNode.Transform       = ContentNode.ConvertTransformToNode(SCNMatrix4.CreateTranslation(0, Altitude, 29), selectionParent);
                HeroNode.Scale           = new SCNVector3(1, 1, 1);
                HeroNode.Rotation        = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.25f);

                // Upon completion, rotate the selection forever
                SCNTransaction.SetCompletionBlock(() => {
                    var animation            = CABasicAnimation.FromKeyPath("rotation");
                    animation.Duration       = 4.0f;
                    animation.From           = NSValue.FromVector(new SCNVector4(0, 1, 0, 0));
                    animation.To             = NSValue.FromVector(new SCNVector4(0, 1, 0, NMath.PI * 2));
                    animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                    animation.RepeatCount    = float.MaxValue;

                    HeroNode.ChildNodes [0].AddAnimation(animation, new NSString("heroNodeAnimation"));
                });

                // Add the filters
                var blurFilter = CIFilter.FromName("CIGaussianBlur");
                blurFilter.SetDefaults();
                blurFilter.Name = "blur";
                blurFilter.SetValueForKey(new NSNumber(0), CIFilterInputKey.Radius);

                var desaturateFilter = CIFilter.FromName("CIColorControls");
                desaturateFilter.SetDefaults();
                desaturateFilter.Name = "desaturate";
                GroupNode.Filters     = new CIFilter[] { blurFilter, desaturateFilter };
                SCNTransaction.Commit();

                // Increate the blur radius and desaturate progressively
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 2;
                GroupNode.SetValueForKey(new NSNumber(10), new NSString("filters.blur.inputRadius"));
                GroupNode.SetValueForKey(new NSNumber(0.1), new NSString("filters.desaturate.inputSaturation"));
                SCNTransaction.Commit();

                break;
            }
        }
예제 #22
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();
        }
예제 #23
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case 0:
                break;

            case 1:
                // Set the slide's subtitle and display the primitves
                TextManager.SetSubtitle("Built-in parametric primitives");
                PresentPrimitives();
                break;

            case 2:
                // Hide the carousel and illustrate SCNText
                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.5f;
                SCNTransaction.SetCompletionBlock(() => {
                    CarouselNode.RemoveFromParentNode();

                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 1;
                    PresentTextNode();
                    TextNode.Opacity = 1.0f;
                    SCNTransaction.Commit();
                });
                CarouselNode.Opacity = 0.0f;
                SCNTransaction.Commit();

                TextManager.SetSubtitle("Built-in 3D text");
                TextManager.AddBulletAtLevel("SCNText", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Subtitle);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                break;

            case 3:
                // Hide the 3D text and introduce SCNShape
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.5f;
                SCNTransaction.SetCompletionBlock(() => {
                    if (TextNode != null)
                    {
                        TextNode.RemoveFromParentNode();
                    }

                    presentationViewController.ShowsNewInSceneKitBadge(true);

                    TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);
                    TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                    TextManager.SetSubtitle("3D Shapes");

                    TextManager.AddBulletAtLevel("SCNShape", 0);
                    TextManager.AddBulletAtLevel("Initializes with a NSBezierPath", 0);
                    TextManager.AddBulletAtLevel("Extrusion and chamfer", 0);

                    TextManager.AddCode("#aNode.Geometry = SCNShape.#Create# (aBezierPath, 10);#");

                    TextManager.FlipInText(SlideTextManager.TextType.Subtitle);
                    TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                    TextManager.FlipInText(SlideTextManager.TextType.Code);
                });
                if (TextNode != null)
                {
                    TextNode.Opacity = 0.0f;
                }
                SCNTransaction.Commit();
                break;

            case 4:
                TextManager.FadeOutText(SlideTextManager.TextType.Bullet);
                TextManager.FadeOutText(SlideTextManager.TextType.Code);

                // Illustrate SCNShape, show the floor ouline
                Level2Node        = Level2();
                Level2OutlineNode = Level2Outline();

                Level2Node.Position     = Level2OutlineNode.Position = new SCNVector3(-11, 0, -5);
                Level2Node.Rotation     = Level2OutlineNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2));
                Level2Node.Opacity      = Level2OutlineNode.Opacity = 0.0f;
                Level2Node.Scale        = new SCNVector3(0.03f, 0.03f, 0);
                Level2OutlineNode.Scale = new SCNVector3(0.03f, 0.03f, 0.05f);

                GroundNode.AddChildNode(Level2OutlineNode);
                GroundNode.AddChildNode(Level2Node);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                Level2OutlineNode.Opacity        = 1.0f;
                SCNTransaction.Commit();
                break;

            case 5:
                presentationViewController.ShowsNewInSceneKitBadge(false);

                // Show the extruded floor
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                Level2Node.Opacity = 1.0f;
                Level2Node.Scale   = new SCNVector3(0.03f, 0.03f, 0.05f);

                SCNTransaction.SetCompletionBlock(() => {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 1.5f;
                    // move the camera a little higher
                    presentationViewController.CameraNode.Position  = new SCNVector3(0, 7, -3);
                    presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.7f);
                    SCNTransaction.Commit();
                });
                SCNTransaction.Commit();
                break;

            case 6:
                TextManager.FadeOutText(SlideTextManager.TextType.Subtitle);
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                // Example of a custom geometry (Möbius strip)
                TextManager.SetSubtitle("Custom geometry");

                TextManager.AddBulletAtLevel("Custom vertices, normals and texture coordinates", 0);
                TextManager.AddBulletAtLevel("SCNGeometry", 0);

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

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                // move the camera back to its previous position
                presentationViewController.CameraNode.Position  = new SCNVector3(0, 0, 0);
                presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)(Math.PI / 180.0));

                Level2Node.Opacity        = 0.0f;
                Level2OutlineNode.Opacity = 0.0f;

                SCNTransaction.Commit();

                break;
            }
        }
예제 #24
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case 0:
                // Adjust the near clipping plane of the spotlight to maximize the precision of the dynamic drop shadows
                presentationViewController.SpotLight.Light.SetAttribute(new NSNumber(30), SCNLightAttribute.ShadowNearClippingKey);

                // Show what needs to be shown, hide what needs to be hidden
                PositionsVisualizationNode.Opacity = 1.0f;
                NormalsVisualizationNode.Opacity   = 1.0f;
                TeapotNodeForUVs.Opacity           = 0.0f;
                TeapotNodeForMaterials.Opacity     = 1.0f;

                TeapotNodeForPositionsAndNormals.Opacity = 0.0f;

                // Don't highlight bullets (this is useful when we go back from the next slide)
                TextManager.HighlightBullet(-1);
                break;

            case 1:
                TextManager.HighlightBullet(0);

                // Animate the "explodeValue" parameter (uniform) of the shader modifier
                var explodeAnimation = CABasicAnimation.FromKeyPath("explodeValue");
                explodeAnimation.Duration       = 2.0f;
                explodeAnimation.RepeatCount    = float.MaxValue;
                explodeAnimation.AutoReverses   = true;
                explodeAnimation.To             = new NSNumber(20);
                explodeAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                TeapotNodeForPositionsAndNormals.Geometry.AddAnimation(explodeAnimation, new NSString("expode"));
                break;

            case 2:
                TextManager.HighlightBullet(1);

                // Remove the "explode" animation and freeze the "explodeValue" parameter to the current value
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0;
                var explodeValue = TeapotNodeForPositionsAndNormals.PresentationNode.Geometry.ValueForKey(new NSString("explodeValue"));
                TeapotNodeForPositionsAndNormals.Geometry.SetValueForKey(explodeValue, new NSString("explodeValue"));
                TeapotNodeForPositionsAndNormals.Geometry.RemoveAllAnimations();
                SCNTransaction.Commit();

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                SCNTransaction.SetCompletionBlock(() => {
                    // Animate to a "no explosion" state and show the positions on completion
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration   = 1.0f;
                    PositionsVisualizationNode.Opacity = 1.0f;
                    SCNTransaction.Commit();
                });
                TeapotNodeForPositionsAndNormals.Geometry.SetValueForKey(new NSNumber(0.0f), new NSString("explodeValue"));
                SCNTransaction.Commit();
                break;

            case 3:
                TextManager.HighlightBullet(2);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration   = 1.0f;
                PositionsVisualizationNode.Opacity = 0.0f;
                NormalsVisualizationNode.Opacity   = 1.0f;
                SCNTransaction.Commit();
                break;

            case 4:
                TextManager.HighlightBullet(3);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration         = 0;
                NormalsVisualizationNode.Hidden          = true;
                TeapotNodeForUVs.Opacity                 = 1.0f;
                TeapotNodeForPositionsAndNormals.Opacity = 0.0f;
                SCNTransaction.Commit();
                break;

            case 5:
                TextManager.HighlightBullet(4);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0;
                TeapotNodeForUVs.Hidden          = true;
                TeapotNodeForMaterials.Opacity   = 1.0f;
                SCNTransaction.Commit();
                break;
            }
        }