Beispiel #1
0
        public override void SetupSlide(PresentationViewController presentationViewController)
        {
            TextManager.SetTitle("Fog");
            TextManager.SetSubtitle("SCNScene");

            TextManager.AddEmptyLine();
            TextManager.AddCode("// set some fog\n\naScene.#fogColor# = aColor;\n\naScene.#fogStartDistance# = 50;\n\naScene.#fogEndDistance# = 100;#");

            //add palm trees
            var palmTree = Utils.SCAddChildNode(GroundNode, "PalmTree", "Scenes.scnassets/palmTree/palm_tree", 15);

            palmTree.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2));
            palmTree.Position = new SCNVector3(4, -1, 0);

            palmTree = palmTree.Clone();
            GroundNode.AddChildNode(palmTree);
            palmTree.Position = new SCNVector3(0, -1, 7);

            palmTree = palmTree.Clone();
            GroundNode.AddChildNode(palmTree);
            palmTree.Position = new SCNVector3(8, -1, 13);

            palmTree = palmTree.Clone();
            GroundNode.AddChildNode(palmTree);
            palmTree.Position = new SCNVector3(13, -1, -7);

            palmTree = palmTree.Clone();
            GroundNode.AddChildNode(palmTree);
            palmTree.Position = new SCNVector3(-13, -1, -14);

            palmTree = palmTree.Clone();
            GroundNode.AddChildNode(palmTree);
            palmTree.Position = new SCNVector3(3, -1, -14);
        }
        public override void SetupSlide(PresentationViewController presentationViewController)
        {
            TextManager.SetTitle("Shader Modifiers");

            TextManager.AddBulletAtLevel("Inject custom GLSL code", 0);
            TextManager.AddBulletAtLevel("Combines with Scene Kit’s shaders", 0);
            TextManager.AddBulletAtLevel("Inject at specific stages", 0);

            TextManager.AddEmptyLine();
            TextManager.AddCode("#aMaterial.#shaderModifiers# = @{ <Entry Point> : <GLSL Code> };#");
        }
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case 0:
                break;

            case 1:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddEmptyLine();
                TextManager.AddBulletAtLevel("Portability", 0);
                TextManager.AddBulletAtLevel("Performance", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                break;
            }
        }
Beispiel #4
0
        public override void SetupSlide(PresentationViewController presentationViewController)
        {
            TextManager.SetTitle("More Information");

            TextManager.AddTextAtLevel("Allan Schaffer", 0);
            TextManager.AddTextAtLevel("Graphics and Game Technologies Evangelist", 1);
            TextManager.AddTextAtLevel("*****@*****.**", 2);
            TextManager.AddEmptyLine();

            TextManager.AddTextAtLevel("Documentation", 0);
            TextManager.AddTextAtLevel("Scene Kit Programming Guide", 1);
            TextManager.AddTextAtLevel("http://developer.apple.com", 2);
            TextManager.AddEmptyLine();

            TextManager.AddTextAtLevel("Apple Developer Forums", 0);
            TextManager.AddTextAtLevel("http://devforums.apple.com", 2);
            TextManager.AddEmptyLine();
        }
Beispiel #5
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = 1.5f;

            var cameraNode = presentationViewController.CameraNode;

            switch (index)
            {
            case 0:
                break;

            case 1:
                // Add a code snippet
                TextManager.AddCode("#aCamera.#FocalDistance# = 16.0f; \n"
                                    + "aCamera.#FocalBlurRadius# = 8.0f;#");
                break;

            case 2:
                // Turn on DOF to illustrate the code snippet
                cameraNode.Camera.FocalDistance   = 16;
                cameraNode.Camera.FocalSize       = 1.5f;
                cameraNode.Camera.Aperture        = 0.3f;
                cameraNode.Camera.FocalBlurRadius = 8;
                break;

            case 3:
                // Focus far away
                cameraNode.Camera.FocalDistance = 35;
                cameraNode.Camera.FocalSize     = 4;
                cameraNode.Camera.Aperture      = 0.1f;

                // and update the code snippet
                TextManager.FadeOutText(SlideTextManager.TextType.Code);
                TextManager.AddEmptyLine();
                TextManager.AddCode("#aCamera.#FocalDistance# = #35.0f#; \n"
                                    + "aCamera.#FocalBlurRadius# = 8.0f;#");
                break;
            }

            SCNTransaction.Commit();
        }
Beispiel #6
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case 0:
                break;

            case 1:
                TextManager.FlipOutText(SlideTextManager.TextType.Code);
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddEmptyLine();
                TextManager.AddBulletAtLevel("Javascript code example", 0);
                TextManager.AddCode("#\n#//allocate a node#\n"
                                    + "var aNode = SCNNode.Create ();\n\n"
                                    + "#//change opacity#\n"
                                    + "aNode.Opacity = 0.5f;\n\n"
                                    + "#//remove from parent#\n"
                                    + "aNode.RemoveFromParentNode ();\n\n"
                                    + "#//animate implicitly#\n"
                                    + "SCNTransaction.Begin ();\n"
                                    + "SCNTransaction.AnimationDuration = 1.0f;\n"
                                    + "aNode.Scale = new SCNVector3 (2, 2, 2);\n"
                                    + "SCNTransaction.Commit ();#");

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

                break;

            case 2:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.FlipOutText(SlideTextManager.TextType.Code);
                TextManager.AddBulletAtLevel("Tools", 0);
                TextManager.AddBulletAtLevel("Debugging", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                break;
            }
        }
Beispiel #7
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case 0:
                break;

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

                TextManager.AddBulletAtLevel("Image", 0);
                TextManager.AddBulletAtLevel("Name / Path / URL", 1);
                TextManager.AddBulletAtLevel("NSImage / UIImage / NSData", 1);
                TextManager.AddBulletAtLevel("SKTexture", 1);

                TextManager.FlipInText(SlideTextManager.TextType.Bullet);


                var code = TextManager.AddCode("#material.diffuse.contents = #@\"slate.jpg\"#;#");
                code.Position = new SCNVector3(code.Position.X + 6, code.Position.Y - 6.5f, code.Position.Z);

                Material.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/slate", "jpg"));
                Material.Normal.Contents  = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/slate-bump", "png"));
                Material.Normal.Intensity = 0;
                break;

            case 2:
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                Material.Normal.Intensity        = 5.0f;
                Material.Specular.Contents       = NSColor.Gray;
                SCNTransaction.Commit();

                code          = TextManager.AddCode("#material.normal.contents = #[SKTexture textureByGeneratingNormalMap]#;#");
                code.Position = new SCNVector3(code.Position.X + 2, code.Position.Y - 6.5f, code.Position.Z);
                break;

            case 3:
                TextManager.FadeOutText(SlideTextManager.TextType.Code);
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddBulletAtLevel("Live contents", 0);
                TextManager.AddBulletAtLevel("CALayer tree", 1);
                TextManager.AddBulletAtLevel("SKScene (new)", 1);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                Material.Normal.Intensity        = 2.0f;
                SCNTransaction.Commit();

                PlayerLayer1 = ConfigurePlayer(NSBundle.MainBundle.PathForResource("Movies/movie1", "mov"), "material-cube");
                break;

            case 4:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddEmptyLine();

                TextManager.AddBulletAtLevel("Cube map", 0);
                TextManager.AddBulletAtLevel("NSArray of 6 items", 1);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                code          = TextManager.AddCode("#material.reflective.contents = #@[aright.png, left.png ... front.png]#;#");
                code.Position = new SCNVector3(code.Position.X, code.Position.Y - 9.5f, code.Position.Z);

                var image = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/cubemap", "png"), 12, false);
                image.Position = new SCNVector3(-10, 9, 0);
                image.Opacity  = 0;
                ContentNode.AddChildNode(image);

                Object.Geometry = SCNTorus.Create(W * 0.5f, W * 0.2f);
                Material        = Object.Geometry.FirstMaterial;
                Object.Rotation = new SCNVector4(1, 0, 0, (float)Math.PI / 2);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1;
                var right            = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/right", "tga"));
                var left             = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/left", "tga"));
                var top              = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/top", "tga"));
                var bottom           = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/bottom", "tga"));
                var back             = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/back", "tga"));
                var front            = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/front", "tga"));
                var materialContents = new NSMutableArray();
                materialContents.AddObjects(new NSObject[] { right, left, top, bottom, back, front });
                Material.Reflective.Contents = materialContents;
                Material.Diffuse.Contents    = NSColor.Red;
                image.Opacity = 1.0f;
                SCNTransaction.Commit();
                break;
            }
        }
Beispiel #8
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();
        }
Beispiel #9
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case (int)ParticleSteps.Fire:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                TextManager.AddEmptyLine();
                TextManager.AddBulletAtLevel("Particle Image", 0);
                TextManager.AddBulletAtLevel("Color over life duration", 0);
                TextManager.AddBulletAtLevel("Size over life duration", 0);
                TextManager.AddBulletAtLevel("Several blend modes", 0);

                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                var hole = SCNNode.Create();
                hole.Geometry = SCNTube.Create(1.7f, 1.9f, 1.5f);
                hole.Position = new SCNVector3(0, 0, HOLE_Z);
                hole.Scale    = new SCNVector3(1, 0, 1);

                GroundNode.AddChildNode(hole);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.5f;

                hole.Scale = new SCNVector3(1, 1, 1);

                SCNTransaction.Commit();

                var ps = SCNParticleSystem.Create("fire", "Particles");
                hole.AddParticleSystem(ps);

                Hole = hole;
                break;

            case (int)ParticleSteps.FireScreen:
                ps           = Hole.ParticleSystems [0];
                ps.BlendMode = SCNParticleBlendMode.Screen;
                break;

            case (int)ParticleSteps.Local:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                TextManager.AddBulletAtLevel("Local vs Global", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                Hole.RemoveAllParticleSystems();
                Hole2          = Hole.Clone();
                Hole2.Geometry = (SCNGeometry)Hole.Geometry.Copy();
                Hole2.Position = new SCNVector3(0, -2, HOLE_Z - 4);
                GroundNode.AddChildNode(Hole2);
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.5;
                Hole2.Position = new SCNVector3(0, 0, HOLE_Z - 4);
                SCNTransaction.Commit();

                ps = SCNParticleSystem.Create("reactor", "Particles");
                ps.ParticleColorVariation = new SCNVector4(0, 0, 0.5f, 0);
                Hole.AddParticleSystem(ps);

                var localPs = (SCNParticleSystem)ps.Copy();
                localPs.ParticleImage = ps.ParticleImage;
                localPs.Local         = true;
                Hole2.AddParticleSystem(localPs);

                var animation = CABasicAnimation.FromKeyPath("position");
                animation.From           = NSValue.FromVector(new SCNVector3(7, 0, HOLE_Z));
                animation.To             = NSValue.FromVector(new SCNVector3(-7, 0, HOLE_Z));
                animation.BeginTime      = CAAnimation.CurrentMediaTime() + 0.75;
                animation.Duration       = 8;
                animation.AutoReverses   = true;
                animation.RepeatCount    = float.MaxValue;
                animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                animation.TimeOffset     = animation.Duration / 2;
                Hole.AddAnimation(animation, new NSString("animateHole"));

                animation                = CABasicAnimation.FromKeyPath("position");
                animation.From           = NSValue.FromVector(new SCNVector3(-7, 0, HOLE_Z - 4));
                animation.To             = NSValue.FromVector(new SCNVector3(7, 0, HOLE_Z - 4));
                animation.BeginTime      = CAAnimation.CurrentMediaTime() + 0.75;
                animation.Duration       = 8;
                animation.AutoReverses   = true;
                animation.RepeatCount    = float.MaxValue;
                animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                animation.TimeOffset     = animation.Duration / 2;
                Hole2.AddAnimation(animation, new NSString("animateHole"));
                break;

            case (int)ParticleSteps.Gravity:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                TextManager.AddBulletAtLevel("Affected by gravity", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                Hole2.RemoveAllParticleSystems();
                Hole2.RunAction(SCNAction.Sequence(new SCNAction[] {
                    SCNAction.ScaleTo(0, 0.5),
                    SCNAction.RemoveFromParentNode()
                }));
                Hole.RemoveAllParticleSystems();
                Hole.RemoveAnimation(new NSString("animateHole"), 0.5f);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.5;

                var tube = (SCNTube)Hole.Geometry;
                tube.InnerRadius = 0.3f;
                tube.OuterRadius = 0.4f;
                tube.Height      = 1.0f;

                SCNTransaction.Commit();

                ps = SCNParticleSystem.Create("sparks", "Particles");
                Hole.RemoveAllParticleSystems();
                Hole.AddParticleSystem(ps);

                foreach (var child in ((SCNView)presentationViewController.View).Scene.RootNode.ChildNodes)
                {
                    if (child.Geometry != null)
                    {
                        if (child.Geometry.GetType() == typeof(SCNFloor))
                        {
                            FloorNode = child;
                        }
                    }
                }

                /*FloorNode = ((SCNView)presentationViewController.View).Scene.RootNode.FindNodes ((SCNNode child, out bool stop) => {
                 *      stop = false;
                 *      if (child.Geometry != null)
                 *              stop = (child.Geometry.GetType () == typeof(SCNFloor));
                 *      return stop;
                 * });*/

                /*FloorNode = [presentationViewController.view.scene.rootNode childNodesPassingTest:^BOOL(SCNNode *child, BOOL *stop) {
                 *      return [child.geometry isKindOfClass:[SCNFloor class]];
                 * }][0];*/

                ps.ColliderNodes = new SCNNode[] { FloorNode };

                break;

            case (int)ParticleSteps.Collider:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                TextManager.AddBulletAtLevel("Affected by colliders", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                var boxNode = SCNNode.Create();
                boxNode.Geometry = SCNBox.Create(5, 0.2f, 5, 0);
                boxNode.Position = new SCNVector3(0, 7, HOLE_Z);
                boxNode.Geometry.FirstMaterial.Emission.Contents = NSColor.DarkGray;

                GroundNode.AddChildNode(boxNode);

                ps = Hole.ParticleSystems [0];
                ps.ColliderNodes = new SCNNode[] { FloorNode, boxNode };

                animation                = CABasicAnimation.FromKeyPath("eulerAngles");
                animation.From           = NSValue.FromVector(new SCNVector3(0, 0, NMath.PI / 4 * 1.7f));
                animation.To             = NSValue.FromVector(new SCNVector3(0, 0, -NMath.PI / 4 * 1.7f));
                animation.BeginTime      = CAAnimation.CurrentMediaTime() + 0.5;
                animation.Duration       = 2;
                animation.AutoReverses   = true;
                animation.RepeatCount    = float.MaxValue;
                animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                animation.TimeOffset     = animation.Duration / 2;
                boxNode.AddAnimation(animation, new NSString("animateHole"));

                BoxNode = boxNode;
                break;

            case (int)ParticleSteps.Fields:
                Hole.RemoveAllParticleSystems();

                Hole.RunAction(SCNAction.Sequence(new SCNAction[] {
                    SCNAction.ScaleTo(0, 0.75),
                    SCNAction.RemoveFromParentNode()
                }));

                BoxNode.RunAction(SCNAction.Sequence(new SCNAction[] {
                    SCNAction.MoveBy(0, 15, 0, 1.0),
                    SCNAction.RemoveFromParentNode()
                }));

                var particleHolder = SCNNode.Create();
                particleHolder.Position = new SCNVector3(0, 20, HOLE_Z);
                GroundNode.AddChildNode(particleHolder);

                ParticleHolder = particleHolder;

                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddBulletAtLevel("Affected by physics fields", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                ps = SCNParticleSystem.Create("snow", "Particles");
                ps.AffectedByPhysicsFields = true;
                ParticleHolder.AddParticleSystem(ps);
                Snow = ps;

                //physics field
                var field = SCNPhysicsField.CreateTurbulenceField(50, 1);
                field.HalfExtent = new SCNVector3(20, 20, 20);
                field.Strength   = 4.0f;

                var fieldOwner = SCNNode.Create();
                fieldOwner.Position = new SCNVector3(0, 5, HOLE_Z);

                GroundNode.AddChildNode(fieldOwner);
                fieldOwner.PhysicsField = field;
                FieldOwner = fieldOwner;

                ps.ColliderNodes = new SCNNode[] { FloorNode };
                break;

            case (int)ParticleSteps.FieldsVortex:
                VortexFieldOwner          = SCNNode.Create();
                VortexFieldOwner.Position = new SCNVector3(0, 5, HOLE_Z);

                GroundNode.AddChildNode(VortexFieldOwner);

                //tornado
                var worldOrigin = new SCNVector3(FieldOwner.WorldTransform.M41, FieldOwner.WorldTransform.M42, FieldOwner.WorldTransform.M43);
                var worldAxis   = new SCNVector3(0, 1, 0);

                var vortex = SCNPhysicsField.CustomField((SCNVector3 position, SCNVector3 velocity, float mass, float charge, double timeInSeconds) => {
                    var l        = new SCNVector3();
                    l.X          = worldOrigin.X - position.X;
                    l.Z          = worldOrigin.Z - position.Z;
                    SCNVector3 t = Cross(worldAxis, l);
                    var d2       = (l.X * l.X + l.Z * l.Z);
                    var vs       = (nfloat)(VS / Math.Sqrt(d2));
                    var fy       = (nfloat)(1.0 - (Math.Min(1.0, (position.Y / 15.0))));
                    return(new SCNVector3(t.X * vs + l.X * (nfloat)VW * fy, 0, t.Z * vs + l.Z * (nfloat)VW * fy));
                });
                vortex.HalfExtent             = new SCNVector3(100, 100, 100);
                VortexFieldOwner.PhysicsField = vortex;
                break;

            case (int)ParticleSteps.SubSystems:
                FieldOwner.RemoveFromParentNode();
                ParticleHolder.RemoveAllParticleSystems();
                Snow.DampingFactor = -1;

                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddBulletAtLevel("Sub-particle system on collision", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                ps = SCNParticleSystem.Create("rain", "Particles");
                var pss = SCNParticleSystem.Create("plok", "Particles");
                pss.IdleDuration = 0;
                pss.Loops        = false;

                ps.SystemSpawnedOnCollision = pss;

                ParticleHolder.AddParticleSystem(ps);
                ps.ColliderNodes = new SCNNode[] { FloorNode };
                break;

            case (int)ParticleSteps.Confetti:
                ParticleHolder.RemoveAllParticleSystems();

                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddBulletAtLevel("Custom blocks", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                ps = SCNParticleSystem.Create();
                ps.EmitterShape                     = SCNBox.Create(20, 9, 5, 0);
                ps.BirthRate                        = 100;
                ps.ParticleLifeSpan                 = 10;
                ps.ParticleLifeSpanVariation        = 0;
                ps.SpreadingAngle                   = 20;
                ps.ParticleSize                     = 0.25f;
                ps.ParticleVelocity                 = 10;
                ps.ParticleVelocityVariation        = 19;
                ps.BirthDirection                   = SCNParticleBirthDirection.Constant;
                ps.EmittingDirection                = new SCNVector3(0, -1, 0);
                ps.BirthLocation                    = SCNParticleBirthLocation.Volume;
                ps.ParticleImage                    = new NSImage(NSBundle.MainBundle.PathForResource("Particles/confetti", "png"));
                ps.LightingEnabled                  = true;
                ps.OrientationMode                  = SCNParticleOrientationMode.Free;
                ps.SortingMode                      = SCNParticleSortingMode.Distance;
                ps.ParticleAngleVariation           = 180;
                ps.ParticleAngularVelocity          = 200;
                ps.ParticleAngularVelocityVariation = 400;
                ps.ParticleColor                    = NSColor.Green;
                ps.ParticleColorVariation           = new SCNVector4(0.2f, 0.1f, 0.1f, 0);
                ps.ParticleBounce                   = 0;
                ps.ParticleFriction                 = 0.6f;
                ps.ColliderNodes                    = new SCNNode[] { FloorNode };
                ps.BlendMode                        = SCNParticleBlendMode.Alpha;

                var floatAnimation = CAKeyFrameAnimation.FromKeyPath("");
                floatAnimation.Values   = new NSNumber[] { 1, 1, 0 };
                floatAnimation.KeyTimes = new NSNumber[] { 0, 0.9f, 1 };
                floatAnimation.Duration = 1.0f;
                floatAnimation.Additive = false;

                //ps.PropertyControllers = @{ SCNParticlePropertyOpacity: [SCNParticlePropertyController controllerWithAnimation:floatAnimation] };
                //ps.HandleEvent (SCNParticleEvent.Birth,

                /*[ps handleEvent:SCNParticleEventBirth forProperties:@[SCNParticlePropertyColor] withBlock:^(void **data, size_t *dataStride, uint32_t *indices , NSInteger count) {
                 *
                 *      for (int i = 0; i < count; ++i) {
                 *              var col = (float *)((char *)data[0] + dataStride[0] * i);
                 *              if (rand() & 0x1) { // swith green for red
                 *                      col[0] = col[1];
                 *                      col[1] = 0;
                 *              }
                 *
                 *      }
                 * }];*/

                /*[ps handleEvent:SCNParticleEventCollision forProperties:@[SCNParticlePropertyAngle, SCNParticlePropertyRotationAxis, SCNParticlePropertyAngularVelocity, SCNParticlePropertyVelocity, SCNParticlePropertyContactNormal] withBlock:^(void **data, size_t *dataStride, uint32_t *indices , NSInteger count) {
                 *
                 *      for (NSInteger i = 0; i < count; ++i) {
                 *              // fix orientation
                 *              float *angle = (float *)((char *)data[0] + dataStride[0] * indices[i]);
                 *              float *axis = (float *)((char *)data[1] + dataStride[1] * indices[i]);
                 *
                 *              float *colNrm = (float *)((char *)data[4] + dataStride[4] * indices[i]);
                 *              SCNVector3 collisionNormal = {colNrm[0], colNrm[1], colNrm[2]};
                 *              SCNVector3 cp = SCNVector3CrossProduct(collisionNormal, SCNVector3Make(0, 0, 1));
                 *              CGFloat cpLen = SCNVector3Length(cp);
                 *              angle[0] = asin(cpLen);
                 *
                 *              axis[0] = cp.x / cpLen;
                 *              axis[1] = cp.y / cpLen;
                 *              axis[2] = cp.z / cpLen;
                 *
                 *              // kill angular rotation
                 *              float *angVel = (float *)((char *)data[2] + dataStride[2] * indices[i]);
                 *              angVel[0] = 0;
                 *
                 *              if (colNrm[1] > 0.4) {
                 *                      float *vel = (float *)((char *)data[3] + dataStride[3] * indices[i]);
                 *                      vel[0] = 0;
                 *                      vel[1] = 0;
                 *                      vel[2] = 0;
                 *              }
                 *      }
                 * }];*/

                ParticleHolder.AddParticleSystem(ps);
                break;

            case (int)ParticleSteps.EmitterCube:
                ParticleHolder.RemoveAllParticleSystems();

                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddBulletAtLevel("Emitter shape", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                ParticleHolder.RemoveFromParentNode();

                ps       = SCNParticleSystem.Create("emitters", "Particles");
                ps.Local = true;
                ParticleHolder.AddParticleSystem(ps);

                var node = SCNNode.Create();
                node.Position = new SCNVector3(3, 6, HOLE_Z);
                node.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(NMath.PI * 2, new SCNVector3(0.3f, 1, 0), 8)));
                GroundNode.AddChildNode(node);
                Bokeh = ps;

                node.AddParticleSystem(ps);
                break;

            case (int)ParticleSteps.EmitterSphere:
                Bokeh.EmitterShape = SCNSphere.Create(5);
                break;

            case (int)ParticleSteps.EmitterTorus:
                Bokeh.EmitterShape = SCNTorus.Create(5, 1);
                break;
            }
        }
Beispiel #10
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case (int)TechniqueSteps.Intro:
                break;

            case (int)TechniqueSteps.Code:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                PlistGroup.RemoveFromParentNode();

                TextManager.AddEmptyLine();
                TextManager.AddCode("#// Load a technique\nSCNTechnique *technique = [SCNTechnique #techniqueWithDictionary#:aDictionary];\n\n\n"
                                    + "// Chain techniques\ntechnique = [SCNTechnique #techniqueBySequencingTechniques#:@[t1, t2 ...];\n\n\n\t\t\t\t\t"
                                    + "// Set a technique\naSCNView.#technique# = technique;#");

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

            case (int)TechniqueSteps.Files:
                Pass2.RemoveFromParentNode();

                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddBulletAtLevel("Load from Plist", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Code);

                PlistGroup = SCNNode.Create();
                ContentNode.AddChildNode(PlistGroup);

                //add plist icon
                var node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/plist", "png"), 8, true);
                node.Position = new SCNVector3(0, 3.7f, 10);
                PlistGroup.AddChildNode(node);

                //add plist icon
                node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/vsh", "png"), 3, true);
                for (var i = 0; i < 5; i++)
                {
                    node          = node.Clone();
                    node.Position = new SCNVector3(6, 1.4f, 10 - i);
                    PlistGroup.AddChildNode(node);
                }

                node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/fsh", "png"), 3, true);
                for (var i = 0; i < 5; i++)
                {
                    node          = node.Clone();
                    node.Position = new SCNVector3(9, 1.4f, 10 - i);
                    PlistGroup.AddChildNode(node);
                }
                break;

            case (int)TechniqueSteps.Plist:
                //add plist icon
                node          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique", "png"), 9, true);
                node.Position = new SCNVector3(0, 3.5f, 10.1f);
                node.Opacity  = 0.0f;
                PlistGroup.AddChildNode(node);
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                node.Position = new SCNVector3(0, 3.5f, 11);
                node.Opacity  = 1.0f;
                SCNTransaction.Commit();
                break;

            case (int)TechniqueSteps.Pass1:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                node          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass1", "png"), 15, true);
                node.Position = new SCNVector3(0, 3.5f, 10.1f);
                node.Opacity  = 0.0f;
                ContentNode.AddChildNode(node);
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                node.Position = new SCNVector3(0, 3.5f, 11);
                node.Opacity  = 1.0f;
                SCNTransaction.Commit();
                Pass1 = node;
                break;

            case (int)TechniqueSteps.Passes3:
                Pass1.RemoveFromParentNode();
                Pass2          = SCNNode.Create();
                Pass2.Opacity  = 0.0f;
                Pass2.Position = new SCNVector3(0, 3.5f, 6);

                node          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass2", "png"), 8, true);
                node.Position = new SCNVector3(-8, 0, 0);
                Pass2.AddChildNode(node);

                node          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass3", "png"), 8, true);
                node.Position = new SCNVector3(0, 0, 0);
                Pass2.AddChildNode(node);

                node          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass4", "png"), 8, true);
                node.Position = new SCNVector3(8, 0, 0);
                Pass2.AddChildNode(node);

                ContentNode.AddChildNode(Pass2);
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                Pass2.Position = new SCNVector3(0, 3.5f, 9);
                Pass2.Opacity  = 1.0f;
                SCNTransaction.Commit();
                break;

            case (int)TechniqueSteps.Passes3Connected:
                TextManager.AddEmptyLine();
                TextManager.AddBulletAtLevel("Connect pass inputs / outputs", 0);

                node          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/link", "png"), 8.75f, true);
                node.Position = new SCNVector3(0.01f, -2, 0);
                node.Opacity  = 0.0f;
                Pass2.AddChildNode(node);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                var n = Pass2.ChildNodes [0];
                n.Position = new SCNVector3(-7.5f, -0.015f, 0);

                n          = Pass2.ChildNodes [2];
                n.Position = new SCNVector3(7.5f, 0.02f, 0);

                node.Opacity = 1.0f;

                SCNTransaction.Commit();
                break;

            case (int)TechniqueSteps.Sample:
                TextManager.FlipOutText(SlideTextManager.TextType.Code);
                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);
                TextManager.SetSubtitle("Example: simple depth of field");
                TextManager.FlipInText(SlideTextManager.TextType.Code);

                Pass3 = SCNNode.Create();

                node          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass5", "png"), 15, true);
                node.Position = new SCNVector3(-3, 5, 10.1f);
                node.Opacity  = 0.0f;
                Pass3.AddChildNode(node);

                var t0 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique0", "png"), 4, false);
                t0.Position = new SCNVector3(-8.5f, 1.5f, 10.1f);
                t0.Opacity  = 0.0f;
                Pass3.AddChildNode(t0);

                var t1 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique1", "png"), 4, false);
                t1.Position = new SCNVector3(-3.6f, 1.5f, 10.1f);
                t1.Opacity  = 0.0f;
                Pass3.AddChildNode(t1);

                var t2 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique2", "png"), 4, false);
                t2.Position = new SCNVector3(1.4f, 1.5f, 10.1f);
                t2.Opacity  = 0.0f;
                Pass3.AddChildNode(t2);

                var t3 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique3", "png"), 8, false);
                t3.Position = new SCNVector3(8, 5, 10.1f);
                t3.Opacity  = 0.0f;
                Pass3.AddChildNode(t3);

                ContentNode.AddChildNode(Pass3);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                node.Opacity = 1.0f;
                t0.Opacity   = 1.0f;
                t1.Opacity   = 1.0f;
                t2.Opacity   = 1.0f;
                t3.Opacity   = 1.0f;
                SCNTransaction.Commit();
                break;
            }
        }
Beispiel #11
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            // Animate by default
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = 0;

            switch (index)
            {
            case 0:
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                break;

            case 1:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddEmptyLine();
                TextManager.AddCode("#// Rotate forever\n"
                                    + "[aNode #runAction:#\n"
                                    + "  [SCNAction repeatActionForever:\n"
                                    + "  [SCNAction rotateByX:0 y:M_PI*2 z:0 duration:5.0]]];#");

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

            case 2:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.FlipOutText(SlideTextManager.TextType.Code);

                TextManager.AddBulletAtLevel("Move", 0);
                TextManager.AddBulletAtLevel("Rotate", 0);
                TextManager.AddBulletAtLevel("Scale", 0);
                TextManager.AddBulletAtLevel("Opacity", 0);
                TextManager.AddBulletAtLevel("Remove", 0);
                TextManager.AddBulletAtLevel("Wait", 0);
                TextManager.AddBulletAtLevel("Custom block", 0);

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

            case 3:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddEmptyLine();
                TextManager.AddBulletAtLevel("Directly targets the render tree", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                break;

            case 4:
                TextManager.AddBulletAtLevel("node.position / node.presentationNode.position", 0);

                //labels
                var label1 = TextManager.AddTextAtLevel("Action", 0);
                label1.Position = new SCNVector3(-15, 3, 0);
                var label2 = TextManager.AddTextAtLevel("Animation", 0);
                label2.Position = new SCNVector3(-15, -2, 0);

                //animation
                var animNode = SCNNode.Create();
                var cubeSize = 4.0f;
                animNode.Position = new SCNVector3(-5, cubeSize / 2, 0);

                var cube = SCNBox.Create(cubeSize, cubeSize, cubeSize, 0.05f * cubeSize);

                cube.FirstMaterial.Diffuse.Contents  = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/texture", "png"));
                cube.FirstMaterial.Diffuse.MipFilter = SCNFilterMode.Linear;
                cube.FirstMaterial.Diffuse.WrapS     = SCNWrapMode.Repeat;
                cube.FirstMaterial.Diffuse.WrapT     = SCNWrapMode.Repeat;
                animNode.Geometry = cube;
                ContentNode.AddChildNode(animNode);

                SCNTransaction.Begin();


                SCNNode           animPosIndicator = null;
                SCNAnimationEvent startEvt         = SCNAnimationEvent.Create(0, (CAAnimation animation, NSObject animatedObject, bool playingBackward) => {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 0;
                    animPosIndicator.Position        = new SCNVector3(10, animPosIndicator.Position.Y, animPosIndicator.Position.Z);
                    SCNTransaction.Commit();
                });
                SCNAnimationEvent endEvt = SCNAnimationEvent.Create(1, (CAAnimation animation, NSObject animatedObject, bool playingBackward) => {
                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration = 0;
                    animPosIndicator.Position        = new SCNVector3(-5, animPosIndicator.Position.Y, animPosIndicator.Position.Z);
                    SCNTransaction.Commit();
                });

                var anim = CABasicAnimation.FromKeyPath("position.x");
                anim.Duration        = 3;
                anim.From            = new NSNumber(0.0);
                anim.To              = new NSNumber(15.0);
                anim.Additive        = true;
                anim.AutoReverses    = true;
                anim.AnimationEvents = new SCNAnimationEvent[] { startEvt, endEvt };
                anim.RepeatCount     = float.MaxValue;
                animNode.AddAnimation(anim, new NSString("cubeAnimation"));

                //action
                var actionNode = SCNNode.Create();
                actionNode.Position = new SCNVector3(-5, cubeSize * 1.5f + 1, 0);
                actionNode.Geometry = cube;

                ContentNode.AddChildNode(actionNode);

                var mv = SCNAction.MoveBy(15, 0, 0, 3);

                actionNode.RunAction(SCNAction.RepeatActionForever(SCNAction.Sequence(new SCNAction[] {
                    mv,
                    mv.ReversedAction()
                })));

                //position indicator
                var positionIndicator = SCNNode.Create();
                positionIndicator.Geometry = SCNCylinder.Create(0.5f, 0.01f);
                positionIndicator.Geometry.FirstMaterial.Diffuse.Contents  = NSColor.Red;
                positionIndicator.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant;
                positionIndicator.EulerAngles = new SCNVector3(NMath.PI / 2, 0, 0);
                positionIndicator.Position    = new SCNVector3(0, 0, cubeSize * 0.5f);
                actionNode.AddChildNode(positionIndicator);

                //anim pos indicator
                animPosIndicator          = positionIndicator.Clone();
                animPosIndicator.Position = new SCNVector3(5, cubeSize / 2, cubeSize * 0.5f);
                ContentNode.AddChildNode(animPosIndicator);

                SCNTransaction.Commit();

                break;
            }
            SCNTransaction.Commit();
        }
Beispiel #12
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = 1.5f;

            var cameraNode = presentationViewController.CameraNode;

            switch (index)
            {
            case 0:
                break;

            case 1:
                // Add a code snippet
                TextManager.AddCode("#aCamera.#FocalDistance# = 16.0f; \n"
                                    + "aCamera.#FocalBlurRadius# = 8.0f;#");
                break;

            case 2:
                // Turn on DOF to illustrate the code snippet
                cameraNode.Camera.FocalDistance   = 16;
                cameraNode.Camera.FocalSize       = 1.5f;
                cameraNode.Camera.Aperture        = 0.3f;
                cameraNode.Camera.FocalBlurRadius = 8;
                break;

            case 3:
                // Focus far away
                cameraNode.Camera.FocalDistance = 35;
                cameraNode.Camera.FocalSize     = 4;
                cameraNode.Camera.Aperture      = 0.1f;

                // and update the code snippet
                TextManager.FadeOutText(SlideTextManager.TextType.Code);
                TextManager.AddEmptyLine();
                TextManager.AddCode("#aCamera.#FocalDistance# = #35.0f#; \n"
                                    + "aCamera.#FocalBlurRadius# = 8.0f;#");
                break;

            case 4:
                // Remove the code
                TextManager.FadeOutText(SlideTextManager.TextType.Subtitle);
                TextManager.FadeOutText(SlideTextManager.TextType.Code);

                // Move the camera and adjust tje focal distance
                presentationViewController.CameraHandle.Position = presentationViewController.CameraHandle.ConvertPositionToNode(new SCNVector3(0, -3, -6), presentationViewController.CameraHandle.ParentNode);
                cameraNode.Camera.FocalDistance = 27;

                // Move the light back a little
                presentationViewController.MainLight.Position = presentationViewController.MainLight.ConvertPositionToNode(new SCNVector3(0, 3, 6), presentationViewController.MainLight.ParentNode);
                break;

            case 5:
                // Focus near
                cameraNode.Camera.FocalDistance = 10;
                cameraNode.Camera.FocalSize     = 1;
                cameraNode.Camera.Aperture      = 0.3f;
                break;
            }

            SCNTransaction.Commit();
        }
Beispiel #13
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            switch (index)
            {
            case 0:
                break;

            case 1:
                TextManager.HighlightBullet(0);

                StaticShadowNode.Opacity = 1;

                var node = TextManager.AddCode("#aMaterial.#multiply#.contents = aShadowMap;#");
                node.Position = new SCNVector3(node.Position.X, node.Position.Y - 4, node.Position.Z);
                foreach (var child in node.ChildNodes)
                {
                    child.RenderingOrder = 1;
                    foreach (var m in child.Geometry.Materials)
                    {
                        m.ReadsFromDepthBuffer = false;
                    }
                }
                break;

            case 2:
                //move the tree
                PalmTree.RunAction(SCNAction.RotateBy(0, NMath.PI * 4, 0, 8));
                break;

            case 3:
                TextManager.FadesIn = true;
                TextManager.FadeOutText(SlideTextManager.TextType.Code);
                TextManager.AddEmptyLine();

                node = TextManager.AddCode("#aLight.#castsShadow# = YES;#");
                foreach (SCNNode child in node.ChildNodes)
                {
                    child.RenderingOrder = 1;
                    foreach (SCNMaterial m in child.Geometry.Materials)
                    {
                        m.ReadsFromDepthBuffer = false;
                        m.WritesToDepthBuffer  = false;
                    }
                }

                node.Position = new SCNVector3(node.Position.X, node.Position.Y - 6, node.Position.Z);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;

                var spot = presentationViewController.SpotLight;
                OldSpotShadowColor      = spot.Light.ShadowColor;
                spot.Light.ShadowColor  = NSColor.Black;
                spot.Light.ShadowRadius = 3;

                var tp = TextManager.TextNode.Position;

                var superNode = presentationViewController.CameraNode.ParentNode.ParentNode;

                var p0 = GroundNode.ConvertPositionToNode(SCNVector3.Zero, null);
                var p1 = GroundNode.ConvertPositionToNode(new SCNVector3(20, 0, 0), null);
                var tr = new SCNVector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);

                var p = superNode.Position;
                p.X  += tr.X;
                p.Y  += tr.Y;
                p.Z  += tr.Z;
                tp.X += 20;
                tp.Y += 0;
                tp.Z += 0;
                superNode.Position            = p;
                TextManager.TextNode.Position = tp;
                SCNTransaction.Commit();

                TextManager.HighlightBullet(1);

                break;

            case 4:
                //move the light
                var lightPivot = SCNNode.Create();
                lightPivot.Position = Character.Position;
                GroundNode.AddChildNode(lightPivot);

                spot            = presentationViewController.SpotLight;
                OldSpotPosition = spot.Position;
                OldSpotParent   = spot.ParentNode;
                OldSpotZNear    = spot.Light.ZNear;

                spot.Light.ZNear = 20;
                spot.Position    = lightPivot.ConvertPositionFromNode(spot.Position, spot.ParentNode);
                lightPivot.AddChildNode(spot);

                //add an object to represent the light
                var lightModel  = SCNNode.Create();
                var lightHandle = SCNNode.Create();
                var cone        = SCNCone.Create(0, 0.5f, 1);
                cone.RadialSegmentCount = 10;
                cone.HeightSegmentCount = 5;
                lightModel.Geometry     = cone;
                lightModel.Geometry.FirstMaterial.Emission.Contents = NSColor.Yellow;
                lightHandle.Position   = new SCNVector3(spot.Position.X * DIST, spot.Position.Y * DIST, spot.Position.Z * DIST);
                lightModel.CastsShadow = false;
                lightModel.EulerAngles = new SCNVector3(NMath.PI / 2, 0, 0);
                lightHandle.AddChildNode(lightModel);
                lightHandle.Constraints = new SCNConstraint[] { SCNLookAtConstraint.Create(Character) };
                lightPivot.AddChildNode(lightHandle);
                LightHandle = lightHandle;

                var animation = CABasicAnimation.FromKeyPath("eulerAngles.z");
                animation.From           = new NSNumber((nfloat)(Math.PI / 4) * 1.7f);
                animation.To             = new NSNumber((nfloat)(-Math.PI / 4) * 0.3f);
                animation.Duration       = 4;
                animation.AutoReverses   = true;
                animation.RepeatCount    = float.MaxValue;
                animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                animation.TimeOffset     = animation.Duration / 2;
                lightPivot.AddAnimation(animation, new NSString("lightAnim"));
                break;

            case 5:
                TextManager.FadeOutText(SlideTextManager.TextType.Code);
                var text = TextManager.AddCode("#aLight.#shadowMode# =\n#SCNShadowModeModulated#;\naLight.#gobo# = anImage;#");
                text.Position = new SCNVector3(text.Position.X, text.Position.Y - 6, text.Position.Z);
                text.EnumerateChildNodes((SCNNode child, out bool stop) => {
                    stop = false;
                    child.RenderingOrder = 1;
                    foreach (var m in child.Geometry.Materials)
                    {
                        m.ReadsFromDepthBuffer = false;
                        m.WritesToDepthBuffer  = false;
                    }
                    return(stop);
                });

                LightHandle.RemoveFromParentNode();

                RestoreSpotPosition(presentationViewController);
                TextManager.HighlightBullet(2);


                spot = presentationViewController.SpotLight;
                spot.Light.CastsShadow = false;

                var head = Character.FindChildNode("Bip001_Pelvis", true);

                node                      = SCNNode.Create();
                node.Light                = SCNLight.Create();
                node.Light.LightType      = SCNLightType.Spot;
                node.Light.SpotOuterAngle = 30;
                node.Constraints          = new SCNConstraint[] { SCNLookAtConstraint.Create(head) };
                node.Position             = new SCNVector3(0, 220, 0);
                node.Light.ZNear          = 10;
                node.Light.ZFar           = 1000;
                node.Light.Gobo.Contents  = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/blobShadow", "jpg"));
                node.Light.Gobo.Intensity = 0.65f;
                node.Light.ShadowMode     = SCNShadowMode.Modulated;

                //exclude character from shadow
                node.Light.CategoryBitMask = 0x1;
                Character.FindNodes((SCNNode child, out bool stop) => {
                    stop = false;
                    child.CategoryBitMask = 0x2;
                    return(stop);
                });

                Projector = node;
                Character.AddChildNode(node);

                break;
            }
        }
Beispiel #14
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;
            }
        }
Beispiel #15
0
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            SCNTransaction.Begin();

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

                TextManager.SetSubtitle("API");

                TextManager.AddEmptyLine();
                TextManager.AddCode("#aMaterial.#ShaderModifiers# = new SCNShaderModifiers {\n"
                                    + "     <Entry Point> = <GLSL Code>\n"
                                    + "};#");
                TextManager.FlipInText(SlideTextManager.TextType.Code);
                TextManager.FlipInText(SlideTextManager.TextType.Subtitle);

                break;

            case 2:
                TextManager.FlipOutText(SlideTextManager.TextType.Code);

                TextManager.AddEmptyLine();
                TextManager.AddCode("#aMaterial.#ShaderModifiers# = new SCNShaderModifiers { \n"
                                    + "     EntryCGPointragment = \n"
                                    + "     new Vector3 (1.0f) - #output#.Color.GetRgb () \n"
                                    + "};#");

                TextManager.FlipInText(SlideTextManager.TextType.Code);

                break;

            case 3:
                TextManager.FlipOutText(SlideTextManager.TextType.Code);
                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);

                TextManager.SetSubtitle("Entry points");

                TextManager.AddBulletAtLevel("Geometry", 0);
                TextManager.AddBulletAtLevel("Surface", 0);
                TextManager.AddBulletAtLevel("Lighting", 0);
                TextManager.AddBulletAtLevel("Fragment", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                TextManager.FlipInText(SlideTextManager.TextType.Subtitle);

                break;

            case 4:
                SCNTransaction.AnimationDuration = 1;

                TextManager.HighlightBullet(0);

                // Create a (very) tesselated plane
                var plane = SCNPlane.Create(10, 10);
                plane.WidthSegmentCount  = 200;
                plane.HeightSegmentCount = 200;

                // Setup the material (same as the floor)
                plane.FirstMaterial.Diffuse.WrapS             = SCNWrapMode.Mirror;
                plane.FirstMaterial.Diffuse.WrapT             = SCNWrapMode.Mirror;
                plane.FirstMaterial.Diffuse.Contents          = new NSImage("/Library/Desktop Pictures/Circles.jpg");
                plane.FirstMaterial.Diffuse.ContentsTransform = SCNMatrix4.CreateFromAxisAngle(new SCNVector3(0, 0, 1), NMath.PI / 4);
                plane.FirstMaterial.Specular.Contents         = NSColor.White;
                plane.FirstMaterial.Reflective.Contents       = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap", "jpg"));
                plane.FirstMaterial.Reflective.Intensity      = 0.0f;

                // Create a node to hold that plane
                PlaneNode          = SCNNode.Create();
                PlaneNode.Position = new SCNVector3(0, 0.1f, 0);
                PlaneNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2));
                PlaneNode.Scale    = new SCNVector3(5, 5, 1);
                PlaneNode.Geometry = plane;
                ContentNode.AddChildNode(PlaneNode);

                // Attach the "wave" shader modifier, and set an initial intensity value of 0
                var shaderFile       = NSBundle.MainBundle.PathForResource("Shaders/wave", "shader");
                var geometryModifier = File.ReadAllText(shaderFile);
                PlaneNode.Geometry.ShaderModifiers = new SCNShaderModifiers {
                    EntryPointGeometry = geometryModifier
                };
                PlaneNode.Geometry.SetValueForKey(new NSNumber(0.0f), new NSString("intensity"));

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0;
                // Show the pseudo code for the deformation
                var textNode = TextManager.AddCode("#float len = #geometry#.Position.Xy.Length;\n"
                                                   + "aMaterial.ShaderModifiers = new SCNShaderModifiers { \n"
                                                   + "     #EntryPointGeometry# = geometry.Position.Y \n"
                                                   + "};#");

                textNode.Position = new SCNVector3(8.5f, 7, 0);
                SCNTransaction.Commit();
                break;

            case 5:
                // Progressively increase the intensity
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 2;
                PlaneNode.Geometry.SetValueForKey(new NSNumber(1.0f), new NSString("intensity"));
                PlaneNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f;
                SCNTransaction.Commit();

                // Redraw forever
                ((SCNView)presentationViewController.View).Playing = true;
                ((SCNView)presentationViewController.View).Loops   = true;
                break;

            case 6:
                SCNTransaction.AnimationDuration = 1;

                TextManager.FadeOutText(SlideTextManager.TextType.Code);

                // Hide the plane used for the previous modifier
                PlaneNode.Geometry.SetValueForKey(new NSNumber(0.0f), new NSString("intensity"));
                PlaneNode.Geometry.FirstMaterial.Reflective.Intensity = 0.0f;
                PlaneNode.Opacity = 0.0f;

                // Create a sphere to illustrate the "car paint" modifier
                var sphere = SCNSphere.Create(6);
                sphere.SegmentCount = 100;
                sphere.FirstMaterial.Diffuse.Contents    = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/noise", "png"));
                sphere.FirstMaterial.Diffuse.WrapS       = SCNWrapMode.Repeat;
                sphere.FirstMaterial.Diffuse.WrapT       = SCNWrapMode.Repeat;
                sphere.FirstMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap3", "jpg"));
                sphere.FirstMaterial.FresnelExponent     = 1.3f;

                SphereNode          = SCNNode.FromGeometry(sphere);
                SphereNode.Position = new SCNVector3(5, 6, 0);
                GroundNode.AddChildNode(SphereNode);

                // Attach the "car paint" shader modifier
                shaderFile = NSBundle.MainBundle.PathForResource("Shaders/carPaint", "shader");
                var surfaceModifier = File.ReadAllText(shaderFile);
                sphere.FirstMaterial.ShaderModifiers = new SCNShaderModifiers {
                    EntryPointSurface = surfaceModifier
                };

                var rotationAnimation = CABasicAnimation.FromKeyPath("rotation");
                rotationAnimation.Duration    = 15.0f;
                rotationAnimation.RepeatCount = float.MaxValue;
                rotationAnimation.By          = NSValue.FromVector(new SCNVector4(0, 1, 0, -(float)(Math.PI * 2)));
                SphereNode.AddAnimation(rotationAnimation, new NSString("sphereNodeAnimation"));

                TextManager.HighlightBullet(1);
                break;

            case 7:
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration       = 1.5f;
                SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                // Move the camera closer
                presentationViewController.CameraNode.Position = new SCNVector3(5, -0.5f, -17);
                SCNTransaction.Commit();
                break;

            case 8:
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration       = 1.0f;
                SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                // Move back
                presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 0);
                SCNTransaction.Commit();
                break;

            case 9:
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                // Hide the sphere used for the previous modifier
                SphereNode.Opacity  = 0.0f;
                SphereNode.Position = new SCNVector3(6, 4, -8);
                SCNTransaction.Commit();

                SCNTransaction.AnimationDuration = 0;

                TextManager.HighlightBullet(2);

                // Load the model, animate
                var intermediateNode = SCNNode.Create();
                intermediateNode.Position = new SCNVector3(4, 0.1f, 10);
                TorusNode = Utils.SCAddChildNode(intermediateNode, "torus", "Scenes/torus/torus", 11);

                rotationAnimation             = CABasicAnimation.FromKeyPath("rotation");
                rotationAnimation.Duration    = 10.0f;
                rotationAnimation.RepeatCount = float.MaxValue;
                rotationAnimation.To          = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2)));
                TorusNode.AddAnimation(rotationAnimation, new NSString("torusNodeAnimation"));

                GroundNode.AddChildNode(intermediateNode);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                intermediateNode.Position        = new SCNVector3(4, 0.1f, 0);
                SCNTransaction.Commit();

                break;

            case 10:
                // Attach the shader modifier
                shaderFile = NSBundle.MainBundle.PathForResource("Shaders/toon", "shader");
                var lightingModifier = File.ReadAllText(shaderFile);
                TorusNode.Geometry.ShaderModifiers = new SCNShaderModifiers {
                    EntryPointLightingModel = lightingModifier
                };
                break;

            case 11:
                SCNTransaction.AnimationDuration = 1.0f;

                // Hide the torus used for the previous modifier
                TorusNode.Position = new SCNVector3(TorusNode.Position.X, TorusNode.Position.Y, TorusNode.Position.Z - 10);
                TorusNode.Opacity  = 0.0f;

                // Load the model, animate
                intermediateNode          = SCNNode.Create();
                intermediateNode.Position = new SCNVector3(4, -2.6f, 14);
                intermediateNode.Scale    = new SCNVector3(70, 70, 70);

                XRayNode          = Utils.SCAddChildNode(intermediateNode, "node", "Scenes/bunny", 12);
                XRayNode.Position = new SCNVector3(0, 0, 0);
                XRayNode.Opacity  = 0.0f;

                GroundNode.AddChildNode(intermediateNode);

                rotationAnimation             = CABasicAnimation.FromKeyPath("rotation");
                rotationAnimation.Duration    = 10.0f;
                rotationAnimation.RepeatCount = float.MaxValue;
                rotationAnimation.From        = NSValue.FromVector(new SCNVector4(0, 1, 0, 0));
                rotationAnimation.To          = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2)));
                intermediateNode.AddAnimation(rotationAnimation, new NSString("bunnyNodeAnimation"));

                TextManager.HighlightBullet(3);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 1.0f;
                XRayNode.Opacity          = 1.0f;
                intermediateNode.Position = new SCNVector3(4, -2.6f, -2);
                SCNTransaction.Commit();
                break;

            case 12:
                // Attach the "x ray" modifier
                shaderFile = NSBundle.MainBundle.PathForResource("Shaders/xRay", "shader");
                var fragmentModifier = File.ReadAllText(shaderFile);
                XRayNode.Geometry.ShaderModifiers = new SCNShaderModifiers {
                    EntryPointFragment = fragmentModifier
                };
                XRayNode.Geometry.FirstMaterial.ReadsFromDepthBuffer = false;
                break;

            case 13:
                // Highlight everything
                TextManager.HighlightBullet(-1);

                // Hide the node used for the previous modifier
                XRayNode.Opacity             = 0.0f;
                XRayNode.ParentNode.Position = new SCNVector3(4, -2.6f, -5);

                // Create the model
                sphere = SCNSphere.Create(5);
                sphere.SegmentCount = 150;                 // tesselate a lot

                VirusNode          = SCNNode.FromGeometry(sphere);
                VirusNode.Position = new SCNVector3(3, 6, 0);
                VirusNode.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)(Math.PI / 180.0f));
                GroundNode.AddChildNode(VirusNode);

                // Set the shader modifiers
                var geomFile  = NSBundle.MainBundle.PathForResource("Shaders/sm_geom", "shader");
                var surfFile  = NSBundle.MainBundle.PathForResource("Shaders/sm_surf", "shader");
                var lightFile = NSBundle.MainBundle.PathForResource("Shaders/sm_light", "shader");
                var fragFile  = NSBundle.MainBundle.PathForResource("Shaders/sm_frag", "shader");
                geometryModifier = File.ReadAllText(geomFile);
                surfaceModifier  = File.ReadAllText(surfFile);
                lightingModifier = File.ReadAllText(lightFile);
                fragmentModifier = File.ReadAllText(fragFile);
                VirusNode.Geometry.FirstMaterial.ShaderModifiers = new SCNShaderModifiers {
                    EntryPointGeometry      = geometryModifier,
                    EntryPointSurface       = surfaceModifier,
                    EntryPointLightingModel = lightingModifier,
                    EntryPointFragment      = fragmentModifier
                };
                break;

            case 14:
                SCNTransaction.AnimationDuration = 1.0f;

                // Hide the node used for the previous modifier
                VirusNode.Opacity  = 0.0f;
                VirusNode.Position = new SCNVector3(3, 6, -10);

                // Change the text
                TextManager.FadeOutText(SlideTextManager.TextType.Code);
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);

                TextManager.SetSubtitle("SCNShadable");

                TextManager.AddBulletAtLevel("Protocol adopted by SCNMaterial and SCNGeometry", 0);
                TextManager.AddBulletAtLevel("Shaders parameters are animatable", 0);
                TextManager.AddBulletAtLevel("Texture samplers are bound to a SCNMaterialProperty", 0);

                TextManager.AddCode("#var aProperty = SCNMaterialProperty.#Create# (anImage);\n"
                                    + "aMaterial.#SetValueForKey# (aProperty, #new NSString# (\"aSampler\"));#");

                TextManager.FlipInText(SlideTextManager.TextType.Subtitle);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                TextManager.FlipInText(SlideTextManager.TextType.Code);
                break;
            }
            SCNTransaction.Commit();
        }
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            float delay = 0;

            switch (index)
            {
            case 0:
                break;

            case 1:
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.AddEmptyLine();
                TextManager.AddBulletAtLevel("Available on OS X 10.8+ and iOS 8.0", 0);
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);

                //show some nice icons
                Icon1          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/Badge_X", "png"), 7, false);
                Icon1.Position = new SCNVector3(-20, 3.5f, 5);
                GroundNode.AddChildNode(Icon1);

                Icon2          = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/Badge_iOS", "png"), 7, false);
                Icon2.Position = new SCNVector3(20, 3.5f, 5);
                GroundNode.AddChildNode(Icon2);

                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                Icon1.Position = new SCNVector3(-6, 3.5f, 5);
                Icon2.Position = new SCNVector3(6, 3.5f, 5);
                SCNTransaction.Commit();
                break;

            case 2:
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                Icon1.Position = new SCNVector3(-6, 3.5f, -5);
                Icon2.Position = new SCNVector3(6, 3.5f, -5);
                Icon1.Opacity  = 0.0f;
                Icon2.Opacity  = 0.0f;
                SCNTransaction.Commit();

                foreach (var node in Boxes)
                {
                    var popTime = new DispatchTime(DispatchTime.Now, (Int64)(delay * Utils.NSEC_PER_SEC));
                    DispatchQueue.MainQueue.DispatchAfter(popTime, () => {
                        SCNTransaction.Begin();
                        SCNTransaction.AnimationDuration = 0.5f;

                        node.Rotation = new SCNVector4(1, 0, 0, 0);
                        node.Scale    = new SCNVector3(0.02f, 0.02f, 0.02f);
                        node.Opacity  = 1.0f;

                        SCNTransaction.Commit();
                    });

                    delay += 0.05f;
                }


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

                TextManager.SetSubtitle("Graphic Frameworks");

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

                break;
            }
        }