コード例 #1
0
ファイル: SlidePhysics.cs プロジェクト: chamons/mac-samples-1
        private void PresentPrimitives(PresentationViewController presentationViewController)
        {
            var count  = 100;
            var spread = 0.0f;

            // create a cube with a sphere shape
            for (int i = 0; i < count; ++i)
            {
                var model = SCNNode.Create();
                model.Position    = GroundNode.ConvertPositionToNode(new SCNVector3(RandFloat(-1, 1), RandFloat(30, 50), RandFloat(-1, 1)), null);
                model.EulerAngles = new SCNVector3(RandFloat(0, NMath.PI * 2), RandFloat(0, NMath.PI * 2), RandFloat(0, NMath.PI * 2));

                var size          = new SCNVector3(RandFloat(1.0, 1.5), RandFloat(1.0, 1.5), RandFloat(1.0, 1.5));
                var random        = new Random((int)DateTime.Now.Ticks);
                int geometryIndex = random.Next(0, 7);
                switch (geometryIndex)
                {
                case 0:                 // Box
                    model.Geometry = SCNBox.Create(size.X, size.Y, size.Z, 0);
                    break;

                case 1:                 // Pyramid
                    model.Geometry = SCNPyramid.Create(size.X, size.Y, size.Z);
                    break;

                case 2:                 // Sphere
                    model.Geometry = SCNSphere.Create(size.X);
                    break;

                case 3:                 // Cylinder
                    model.Geometry = SCNCylinder.Create(size.X, size.Y);
                    break;

                case 4:                 // Tube
                    model.Geometry = SCNTube.Create(size.X, size.X + size.Z, size.Y);
                    break;

                case 5:                 // Capsule
                    model.Geometry = SCNCapsule.Create(size.X, size.Y + 2 * size.X);
                    break;

                case 6:                 // Torus
                    model.Geometry = SCNTorus.Create(size.X, NMath.Min(size.X, size.Y) / 2);
                    break;

                default:
                    break;
                }

                model.Geometry.FirstMaterial.Multiply.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/texture", "png"));

                model.PhysicsBody                 = SCNPhysicsBody.CreateDynamicBody();
                model.PhysicsBody.Velocity        = new SCNVector3(RandFloat(-spread, spread), -10, RandFloat(-spread, spread));
                model.PhysicsBody.AngularVelocity = new SCNVector4(RandFloat(-1, 1), RandFloat(-1, 1), RandFloat(-1, 1), RandFloat(-3, 3));

                Shapes.Add(model);

                ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode(model);
            }
        }
コード例 #2
0
        public override void TouchesBegan(NSSet touches, UIEvent evt)
        {
            var forcePower = 10;

            base.TouchesBegan(touches, evt);
            var pointOfView = this.SceneView.PointOfView;
            var transform   = pointOfView.Transform;
            var location    = new SCNVector3(transform.M41, transform.M42, transform.M43);
            var orientation = new SCNVector3(-transform.M31, -transform.M32, -transform.M33);
            var position    = location + orientation;
            var pokeball    = new SCNNode()
            {
                Geometry = SCNSphere.Create(0.15f),
            };

            pokeball.Geometry.FirstMaterial.Diffuse.ContentImage = UIImage.FromBundle("pokeball");
            pokeball.Position    = position;
            pokeball.PhysicsBody = SCNPhysicsBody.CreateDynamicBody();
            pokeball.PhysicsBody.PhysicsShape       = SCNPhysicsShape.Create(pokeball);
            pokeball.PhysicsBody.ContactTestBitMask = (int)BitMaskCategory.Pokemon;
            pokeball.PhysicsBody.CategoryBitMask    = (int)BitMaskCategory.Pokeball;

            pokeball.PhysicsBody.ApplyForce(new SCNVector3(orientation.X * forcePower, orientation.Y * forcePower, orientation.Z * forcePower), true);
            SceneView.Scene.RootNode.AddChildNode(pokeball);
        }
コード例 #3
0
ファイル: SlidePhysics.cs プロジェクト: chamons/mac-samples-1
        private SCNNode CreatePoolBall(SCNVector3 position)
        {
            var model = SCNNode.Create();

            model.Position = position;
            model.Geometry = SCNSphere.Create(0.7f);
            model.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes.scnassets/pool/pool_8", "png"));
            model.PhysicsBody = SCNPhysicsBody.CreateDynamicBody();
            return(model);
        }
コード例 #4
0
ファイル: CubeNode.cs プロジェクト: rid00z/ARKitExample
        public CubeNode(float size, UIColor color)
        {
            var rootNode = new SCNNode
            {
                Geometry    = CreateGeometry(size, color),
                Position    = new SCNVector3(0, size / 2, 0),
                PhysicsBody = SCNPhysicsBody.CreateDynamicBody()
            };

            AddChildNode(rootNode);
        }
コード例 #5
0
ファイル: SlidePhysics.cs プロジェクト: chamons/mac-samples-1
        private SCNNode CreateBlock(SCNVector3 position, SCNVector3 size)
        {
            if (DiceMesh == null)
            {
                DiceMesh = CreateBlockMesh(size);
            }

            var model = SCNNode.Create();

            model.Position    = position;
            model.Geometry    = DiceMesh;
            model.PhysicsBody = SCNPhysicsBody.CreateDynamicBody();

            return(model);
        }
コード例 #6
0
        private void AddWoodenBlockToScene(SCNScene scene, NSString imageName, SCNVector3 position)
        {
            var block = SCNNode.Create();

            block.Position = position;
            block.Geometry = new SCNBox {
                Width         = 5f,
                Height        = 5f,
                Length        = 5f,
                ChamferRadius = 0f
            };

            block.Geometry.FirstMaterial.Diffuse.Contents  = imageName;
            block.Geometry.FirstMaterial.Diffuse.MipFilter = SCNFilterMode.Linear;
            block.PhysicsBody = SCNPhysicsBody.CreateDynamicBody();
            scene.RootNode.AddChildNode(block);
        }
コード例 #7
0
ファイル: SlidePhysics.cs プロジェクト: chamons/mac-samples-1
        private void PresentHinge(PresentationViewController presentationViewController)
        {
            var count = 10.0f;

            var material = SCNMaterial.Create();

            material.Diffuse.Contents        = NSColor.White;
            material.Specular.Contents       = NSColor.White;
            material.LocksAmbientWithDiffuse = true;

            var cubeWidth  = 10.0f / count;
            var cubeHeight = 0.2f;
            var cubeLength = 5.0f;
            var offset     = 0;
            var height     = 5 + count * cubeWidth;

            SCNNode oldModel = null;

            for (int i = 0; i < count; ++i)
            {
                var model = SCNNode.Create();

                var worldtr = GroundNode.ConvertTransformToNode(SCNMatrix4.CreateTranslation(-offset + cubeWidth * i, height, 5), null);

                model.Transform = worldtr;

                model.Geometry = SCNBox.Create(cubeWidth, cubeHeight, cubeLength, 0);
                model.Geometry.FirstMaterial = material;

                var body = SCNPhysicsBody.CreateDynamicBody();
                body.Restitution  = 0.6f;
                model.PhysicsBody = body;

                ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode(model);

                var joint = SCNPhysicsHingeJoint.Create(model.PhysicsBody, new SCNVector3(0, 0, 1), new SCNVector3(-cubeWidth * 0.5f, 0, 0), (oldModel != null ? oldModel.PhysicsBody : null), new SCNVector3(0, 0, 1), new SCNVector3(cubeWidth * 0.5f, 0, 0));
                ((SCNView)presentationViewController.View).Scene.PhysicsWorld.AddBehavior(joint);

                Hinges.Add(model);

                oldModel = model;
            }
        }
コード例 #8
0
ファイル: SlidePhysics.cs プロジェクト: chamons/mac-samples-1
        private void PresentMeshes(PresentationViewController presentationViewController)
        {
            // add meshes
            var container = SCNNode.Create();
            var black     = Utils.SCAddChildNode(container, "teapot", "Scenes.scnassets/lod/midResTeapot.dae", 5);

            int count = 100;

            for (int i = 0; i < count; ++i)
            {
                var worldPos = GroundNode.ConvertPositionToNode(new SCNVector3(RandFloat(-1, 1), RandFloat(30, 50), RandFloat(-1, 1)), null);

                var node = (SCNNode)black.Copy();
                node.Position             = worldPos;
                node.PhysicsBody          = SCNPhysicsBody.CreateDynamicBody();
                node.PhysicsBody.Friction = 0.5f;

                ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode(node);
                Meshes.Add(node);
            }
        }
        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
            base.TouchesEnded(touches, evt);
            if (!SessionStarted || PlaneTrackingEnabled)
            {
                return;
            }

            var frame = SCNView.Session.CurrentFrame;

            if (frame is null)
            {
                return;
            }

            using (frame)
            {
                var hits   = frame.HitTest(new CoreGraphics.CGPoint(0.5, 0.5), ARHitTestResultType.ExistingPlaneUsingExtent);
                var target = hits.FirstOrDefault(x => x.Anchor as ARPlaneAnchor != null);
                if (target == null)
                {
                    return;
                }

                var wt = target.WorldTransform.ToSCNMatrix4();

                var next = Prefabs.Random().Clone();
                next.Scale    = new SCNVector3(.15f, .15f, .0005f);
                next.Position = new SCNVector3(wt.Column3.X, wt.Column3.Y + .5f, wt.Column3.Z);
                next.Look(SCNView.PointOfView.WorldPosition);

                var body = SCNPhysicsBody.CreateDynamicBody();
                body.PhysicsShape = SCNPhysicsShape.Create(next, new NSDictionary());
                body.Restitution  = 0.5f;
                body.Friction     = 0.5f;
                next.PhysicsBody  = body;

                SCNView.Scene.RootNode.AddChildNode(next);
            }
        }
コード例 #10
0
        private SCNNode SetupVehicle(SCNScene scene)
        {
            var carScene    = SCNScene.FromFile("rc_car", ResourceManager.ResourceFolder, (NSDictionary)null);
            var chassisNode = carScene.RootNode.FindChildNode("rccarBody", false);

            chassisNode.Position = new SCNVector3(0f, 10f, 30f);
            chassisNode.Rotation = new SCNVector4(0f, 1f, 0f, (float)Math.PI);

            var body = SCNPhysicsBody.CreateDynamicBody();

            body.AllowsResting   = false;
            body.Mass            = 80f;
            body.Restitution     = 0.1f;
            body.Friction        = 0.5f;
            body.RollingFriction = 0f;

            chassisNode.PhysicsBody = body;

            var frontCameraNode = SCNNode.Create();

            frontCameraNode.Position    = new SCNVector3(0f, 3.5f, 2.5f);
            frontCameraNode.Rotation    = new SCNVector4(0f, 1f, 0f, (float)Math.PI);
            frontCameraNode.Camera      = SCNCamera.Create();
            frontCameraNode.Camera.XFov = 75f;
            frontCameraNode.Camera.ZFar = 500f;

            chassisNode.AddChildNode(frontCameraNode);

            scene.RootNode.AddChildNode(chassisNode);

            var pipeNode = chassisNode.FindChildNode("pipe", true);

            reactor = SCNParticleSystem.Create("reactor", ResourceManager.ResourceFolder);
            reactor.ParticleImage   = ResourceManager.GetResourcePath("spark.png");
            reactorDefaultBirthRate = reactor.BirthRate;
            reactor.BirthRate       = 0;
            pipeNode.AddParticleSystem(reactor);

            SCNNode wheel0Node = chassisNode.FindChildNode("wheelLocator_FL", true);
            SCNNode wheel1Node = chassisNode.FindChildNode("wheelLocator_FR", true);
            SCNNode wheel2Node = chassisNode.FindChildNode("wheelLocator_RL", true);
            SCNNode wheel3Node = chassisNode.FindChildNode("wheelLocator_RR", true);

            var wheel0 = SCNPhysicsVehicleWheel.Create(wheel0Node);
            var wheel1 = SCNPhysicsVehicleWheel.Create(wheel1Node);
            var wheel2 = SCNPhysicsVehicleWheel.Create(wheel2Node);
            var wheel3 = SCNPhysicsVehicleWheel.Create(wheel3Node);

            var min = SCNVector3.Zero;
            var max = SCNVector3.Zero;

            wheel0Node.GetBoundingBox(ref min, ref max);
            float wheelHalfWidth = 0.5f * (max.X - min.X);

            wheel0.ConnectionPosition = SCNVector3.Add(wheel0Node.ConvertPositionToNode(SCNVector3.Zero, chassisNode), new SCNVector3(wheelHalfWidth, 0f, 0f));
            wheel1.ConnectionPosition = SCNVector3.Subtract(wheel1Node.ConvertPositionToNode(SCNVector3.Zero, chassisNode), new SCNVector3(wheelHalfWidth, 0f, 0f));
            wheel2.ConnectionPosition = SCNVector3.Add(wheel2Node.ConvertPositionToNode(SCNVector3.Zero, chassisNode), new SCNVector3(wheelHalfWidth, 0f, 0f));
            wheel3.ConnectionPosition = SCNVector3.Subtract(wheel3Node.ConvertPositionToNode(SCNVector3.Zero, chassisNode), new SCNVector3(wheelHalfWidth, 0f, 0f));

            var vehicle = SCNPhysicsVehicle.Create(chassisNode.PhysicsBody,
                                                   new SCNPhysicsVehicleWheel[] { wheel0, wheel1, wheel2, wheel3 });

            scene.PhysicsWorld.AddBehavior(vehicle);
            this.vehicle = vehicle;

            return(chassisNode);
        }
コード例 #11
0
        private void SetupSceneElements(SCNScene scene)
        {
            AddTrainToScene(scene, new SCNVector3(-5f, 20f, -40f));
            AddWoodenBlockToScene(scene, ResourceManager.GetResourcePath("WoodCubeA.jpg"), new SCNVector3(-10f, 15f, 10f));
            AddWoodenBlockToScene(scene, ResourceManager.GetResourcePath("WoodCubeB.jpg"), new SCNVector3(-9f, 10f, 10f));
            AddWoodenBlockToScene(scene, ResourceManager.GetResourcePath("WoodCubeC.jpg"), new SCNVector3(20f, 15f, -11f));
            AddWoodenBlockToScene(scene, ResourceManager.GetResourcePath("WoodCubeA.jpg"), new SCNVector3(25f, 5f, -20f));

            var wallBox = new SCNBox {
                Width         = 400f,
                Height        = 100f,
                Length        = 4f,
                ChamferRadius = 0f
            };

            var wall = SCNNode.FromGeometry(wallBox);

            wall.Geometry.FirstMaterial.Diffuse.Contents          = ResourceManager.GetResourcePath("wall.jpg");
            wall.Geometry.FirstMaterial.Diffuse.ContentsTransform = SCNMatrix4.Mult(
                SCNMatrix4.Scale(24f, 2f, 1f),
                SCNMatrix4.CreateTranslation(0f, 1f, 0f)
                );

            wall.Geometry.FirstMaterial.Diffuse.WrapS = SCNWrapMode.Repeat;
            wall.Geometry.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Mirror;
            wall.Geometry.FirstMaterial.DoubleSided   = false;
            wall.CastsShadow = false;
            wall.Geometry.FirstMaterial.LocksAmbientWithDiffuse = true;

            wall.Position    = new SCNVector3(0f, 50f, -92f);
            wall.PhysicsBody = SCNPhysicsBody.CreateStaticBody();
            scene.RootNode.AddChildNode(wall);

            wall          = wall.Clone();
            wall.Position = new SCNVector3(202f, 50f, 0f);
            wall.Rotation = new SCNVector4(0f, 1f, 0f, (float)Math.PI / 2f);
            scene.RootNode.AddChildNode(wall);

            wall          = wall.Clone();
            wall.Position = new SCNVector3(-202f, 50f, 0f);
            wall.Rotation = new SCNVector4(0f, 1f, 0f, -(float)Math.PI / 2f);
            scene.RootNode.AddChildNode(wall);

            var planeGeometry = new SCNPlane {
                Width  = 400f,
                Height = 100f
            };

            var backWall = SCNNode.FromGeometry(planeGeometry);

            backWall.Geometry.FirstMaterial = wall.Geometry.FirstMaterial;
            backWall.Position    = new SCNVector3(0f, 50f, 200f);
            backWall.Rotation    = new SCNVector4(0f, 1f, 0f, (float)Math.PI);
            backWall.CastsShadow = false;
            backWall.PhysicsBody = SCNPhysicsBody.CreateStaticBody();
            scene.RootNode.AddChildNode(backWall);

            planeGeometry = new SCNPlane {
                Width  = 400f,
                Height = 400f
            };

            var ceilNode = SCNNode.FromGeometry(planeGeometry);

            ceilNode.Position = new SCNVector3(0f, 100f, 0f);
            ceilNode.Rotation = new SCNVector4(1f, 0f, 0f, (float)Math.PI / 2f);
            ceilNode.Geometry.FirstMaterial.DoubleSided = false;
            ceilNode.CastsShadow = false;
            ceilNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = true;
            scene.RootNode.AddChildNode(ceilNode);

            var rnd = new Random();

            for (int i = 0; i < 4; i++)
            {
                AddWoodenBlockToScene(scene, ResourceManager.GetResourcePath("WoodCubeA.jpg"),
                                      new SCNVector3(rnd.Next(0, 60) - 30f, 20f, rnd.Next(0, 40) - 20f));
                AddWoodenBlockToScene(scene, ResourceManager.GetResourcePath("WoodCubeB.jpg"),
                                      new SCNVector3(rnd.Next(0, 60) - 30f, 20f, rnd.Next(0, 40) - 20f));
                AddWoodenBlockToScene(scene, ResourceManager.GetResourcePath("WoodCubeC.jpg"),
                                      new SCNVector3(rnd.Next(0, 60) - 30f, 20f, rnd.Next(0, 40) - 20f));
            }

            var blockBox = new SCNBox {
                Width         = 22f,
                Height        = 0.2f,
                Length        = 34f,
                ChamferRadius = 0f
            };

            var block = SCNNode.Create();

            block.Position = new SCNVector3(20f, 10f, -16f);
            block.Rotation = new SCNVector4(0f, 1f, 0f, (float)-Math.PI / 4f);
            block.Geometry = blockBox;

            var frontMat = SCNMaterial.Create();

            frontMat.LocksAmbientWithDiffuse = true;
            frontMat.Diffuse.Contents        = ResourceManager.GetResourcePath("book_front.jpg");
            frontMat.Diffuse.MipFilter       = SCNFilterMode.Linear;

            var backMat = SCNMaterial.Create();

            backMat.LocksAmbientWithDiffuse = true;
            backMat.Diffuse.Contents        = ResourceManager.GetResourcePath("book_back.jpg");
            backMat.Diffuse.MipFilter       = SCNFilterMode.Linear;

            block.Geometry.Materials = new SCNMaterial[] { frontMat, backMat };
            block.PhysicsBody        = SCNPhysicsBody.CreateDynamicBody();
            scene.RootNode.AddChildNode(block);

            var rug = SCNNode.Create();

            rug.Position = new SCNVector3(0f, 0.01f, 0f);
            rug.Rotation = new SCNVector4(1f, 0f, 0f, (float)Math.PI / 2f);
            var path = UIBezierPath.FromRoundedRect(new CGRect(-50f, -30f, 100f, 50f), 2.5f);

            path.Flatness = 0.1f;
            rug.Geometry  = SCNShape.Create(path, 0.05f);
            rug.Geometry.FirstMaterial.LocksAmbientWithDiffuse = true;
            rug.Geometry.FirstMaterial.Diffuse.Contents        = ResourceManager.GetResourcePath("carpet.jpg");
            scene.RootNode.AddChildNode(rug);

            var ball = SCNNode.Create();

            ball.Position = new SCNVector3(-5f, 5f, -18f);
            ball.Geometry = SCNSphere.Create(5f);
            ball.Geometry.FirstMaterial.LocksAmbientWithDiffuse   = true;
            ball.Geometry.FirstMaterial.Diffuse.Contents          = ResourceManager.GetResourcePath("ball.jpg");
            ball.Geometry.FirstMaterial.Diffuse.ContentsTransform = SCNMatrix4.Scale(2f, 1f, 1f);
            ball.Geometry.FirstMaterial.Diffuse.WrapS             = SCNWrapMode.Mirror;
            ball.PhysicsBody             = SCNPhysicsBody.CreateDynamicBody();
            ball.PhysicsBody.Restitution = 0.9f;
            scene.RootNode.AddChildNode(ball);
        }
コード例 #12
0
        private void AddTrainToScene(SCNScene scene, SCNVector3 position)
        {
            var max        = SCNVector3.Zero;
            var min        = SCNVector3.Zero;
            var trainScene = SCNScene.FromFile("train_flat", ResourceManager.ResourceFolder, (NSDictionary)null);

            foreach (var node in trainScene.RootNode.ChildNodes)
            {
                if (node.Geometry != null)
                {
                    node.Position = new SCNVector3(
                        node.Position.X + position.X,
                        node.Position.Y + position.Y,
                        node.Position.Z + position.Z
                        );

                    max = SCNVector3.Zero;
                    min = SCNVector3.Zero;

                    node.GetBoundingBox(ref min, ref max);

                    var body     = SCNPhysicsBody.CreateDynamicBody();
                    var boxShape = new SCNBox {
                        Width         = max.X - min.X,
                        Height        = max.Y - min.Y,
                        Length        = max.Z - min.Z,
                        ChamferRadius = 0f
                    };

                    body.PhysicsShape = SCNPhysicsShape.Create(boxShape, (NSDictionary)null);
                    node.Pivot        = SCNMatrix4.CreateTranslation(0f, -min.Y, 0f);
                    node.PhysicsBody  = body;
                    scene.RootNode.AddChildNode(node);
                }
            }

            var smokeHandle         = scene.RootNode.FindChildNode("Smoke", true);
            var smokeParticleSystem = SCNParticleSystem.Create("smoke", ResourceManager.ResourceFolder);

            smokeParticleSystem.ParticleImage = ResourceManager.GetResourcePath("smoke.png");
            smokeHandle.AddParticleSystem(smokeParticleSystem);

            var engineCar = scene.RootNode.FindChildNode("EngineCar", false);
            var wagon1    = scene.RootNode.FindChildNode("Wagon1", false);
            var wagon2    = scene.RootNode.FindChildNode("Wagon2", false);

            max = SCNVector3.Zero;
            min = SCNVector3.Zero;
            engineCar.GetBoundingBox(ref min, ref max);

            var wmax = SCNVector3.Zero;
            var wmin = SCNVector3.Zero;

            wagon1.GetBoundingBox(ref wmin, ref wmax);

            var anchorA = new SCNVector3(max.X, min.Y, 0f);
            var anchorB = new SCNVector3(wmin.X, wmin.Y, 0f);

            var joint = SCNPhysicsBallSocketJoint.Create(engineCar.PhysicsBody, anchorA, wagon1.PhysicsBody, anchorB);

            scene.PhysicsWorld.AddBehavior(joint);

            joint = SCNPhysicsBallSocketJoint.Create(wagon1.PhysicsBody,
                                                     new SCNVector3(wmax.X + 0.1f, wmin.Y, 0f),
                                                     wagon2.PhysicsBody,
                                                     new SCNVector3(wmin.X - 0.1f, wmin.Y, 0f)
                                                     );

            scene.PhysicsWorld.AddBehavior(joint);
        }
コード例 #13
0
ファイル: SlidePhysics.cs プロジェクト: chamons/mac-samples-1
        public override void PresentStep(int index, PresentationViewController presentationViewController)
        {
            Step = index;

            switch (index)
            {
            case 0:
                break;

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

                TextManager.SetSubtitle("SCNPhysicsBody");

                TextManager.FlipInText(SlideTextManager.TextType.Subtitle);

                TextManager.AddBulletAtLevel("Dynamic Bodies", 0);

                // Add some code
                TextManager.AddCode("#// Make a node dynamic\n"
                                    + "aNode.#physicsBody# = [SCNPhysicsBody #dynamicBody#];#");

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

            case 2:
                //add a cube
                var worldPos = GroundNode.ConvertPositionToNode(new SCNVector3(0, 12, 2), null);
                var dice     = CreateBlock(worldPos, new SCNVector3(1.5f, 1.5f, 1.5f));
                dice.PhysicsBody = null;                 //wait!
                dice.Rotation    = new SCNVector4(0, 0, 1, (float)(Math.PI / 4) * 0.5f);
                dice.Scale       = new SCNVector3(0.001f, 0.001f, 0.001f);

                ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode(dice);
                SCNTransaction.Begin();
                SCNTransaction.AnimationDuration = 0.75f;
                dice.Scale = new SCNVector3(2, 2, 2);
                SCNTransaction.Commit();

                Dices.Add(dice);
                break;

            case 3:
                foreach (var node in Dices)
                {
                    node.PhysicsBody = SCNPhysicsBody.CreateDynamicBody();
                }
                break;

            case 4:
                PresentDices(presentationViewController);
                break;

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

                TextManager.AddBulletAtLevel("Manipulate with forces", 0);

                // Add some code
                TextManager.AddCode("#// Apply an impulse\n"
                                    + "[aNode.physicsBody #applyForce:#aVector3 #atPosition:#aVector3 #impulse:#YES];#");

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

            case 6:
                // remove dices
                var center = new SCNVector3(0, -5, 20);
                center = GroundNode.ConvertPositionToNode(center, null);

                Explosion(center, Dices);

                var popTime = new DispatchTime(DispatchTime.Now, (long)(1 * Utils.NSEC_PER_SEC));
                DispatchQueue.MainQueue.DispatchAfter(popTime, () => {
                    TextManager.FlipOutText(SlideTextManager.TextType.Code);
                    TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                    TextManager.AddBulletAtLevel("Static Bodies", 0);
                    TextManager.AddCode("#// Make a node static\n"
                                        + "aNode.#physicsBody# = [SCNPhysicsBody #staticBody#];#");
                    TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                    TextManager.FlipInText(SlideTextManager.TextType.Code);
                });
                break;

            case 7:
                PresentWalls(presentationViewController);
                break;

            case 8:
                PresentBalls(presentationViewController);
                break;

            case 9:
                //remove walls
                var walls = new List <SCNNode> ();
                GroundNode.EnumerateChildNodes(delegate(SCNNode node, out bool stop) {
                    stop = false;
                    if (node.Name == "container-wall")
                    {
                        node.RunAction(SCNAction.Sequence(new SCNAction [] {
                            SCNAction.MoveBy(new SCNVector3(0, -2, 0), 0.5),
                            SCNAction.RemoveFromParentNode()
                        }));
                        walls.Add(node);
                    }
                    return(stop);
                });
                break;

            case 10:
                // remove balls
                center = new SCNVector3(0, -5, 5);
                center = GroundNode.ConvertPositionToNode(center, null);
                Explosion(center, Balls);

                popTime = new DispatchTime(DispatchTime.Now, (long)(0.5 * Utils.NSEC_PER_SEC));
                DispatchQueue.MainQueue.DispatchAfter(popTime, () => {
                    TextManager.FlipOutText(SlideTextManager.TextType.Code);
                    TextManager.FlipOutText(SlideTextManager.TextType.Bullet);

                    TextManager.AddBulletAtLevel("Kinematic Bodies", 0);
                    TextManager.AddCode("#// Make a node kinematic\n"
                                        + "aNode.#physicsBody# = [SCNPhysicsBody #kinematicBody#];#");
                    TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                    TextManager.FlipInText(SlideTextManager.TextType.Code);
                });
                break;

            case 11:
                var boxNode = SCNNode.Create();
                boxNode.Geometry = SCNBox.Create(10, 0.2f, 10, 0);
                boxNode.Position = new SCNVector3(0, 5, MIDDLE_Z);
                boxNode.Geometry.FirstMaterial.Emission.Contents = NSColor.DarkGray;
                boxNode.PhysicsBody = SCNPhysicsBody.CreateKinematicBody();
                boxNode.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(0, 0, NMath.PI * 2, 2.0)));
                GroundNode.AddChildNode(boxNode);
                KinematicItems.Add(boxNode);

                var invisibleWall = SCNNode.Create();
                invisibleWall.Geometry = SCNBox.Create(4, 40, 10, 0);
                invisibleWall.Position = new SCNVector3(-7, 0, MIDDLE_Z);
                invisibleWall.Geometry.FirstMaterial.Transparency = 0;
                invisibleWall.PhysicsBody = SCNPhysicsBody.CreateStaticBody();
                GroundNode.AddChildNode(invisibleWall);
                KinematicItems.Add(invisibleWall);

                invisibleWall          = (SCNNode)invisibleWall.Copy();
                invisibleWall.Position = new SCNVector3(7, 0, MIDDLE_Z);
                GroundNode.AddChildNode(invisibleWall);
                KinematicItems.Add(invisibleWall);

                invisibleWall          = (SCNNode)invisibleWall.Copy();
                invisibleWall.Geometry = SCNBox.Create(10, 40, 4, 0);
                invisibleWall.Geometry.FirstMaterial.Transparency = 0;
                invisibleWall.Position    = new SCNVector3(0, 0, MIDDLE_Z - 7);
                invisibleWall.PhysicsBody = SCNPhysicsBody.CreateStaticBody();
                GroundNode.AddChildNode(invisibleWall);
                KinematicItems.Add(invisibleWall);

                invisibleWall          = (SCNNode)invisibleWall.Copy();
                invisibleWall.Position = new SCNVector3(0, 0, MIDDLE_Z + 7);
                GroundNode.AddChildNode(invisibleWall);
                KinematicItems.Add(invisibleWall);


                for (int i = 0; i < 100; i++)
                {
                    var ball = SCNNode.Create();
                    worldPos      = boxNode.ConvertPositionToNode(new SCNVector3(RandFloat(-4, 4), RandFloat(10, 30), RandFloat(-1, 4)), null);
                    ball.Position = worldPos;
                    ball.Geometry = SCNSphere.Create(0.5f);
                    ball.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Cyan;
                    ball.PhysicsBody = SCNPhysicsBody.CreateDynamicBody();
                    ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode(ball);

                    KinematicItems.Add(ball);
                }
                break;

            case 12:
                TextManager.FlipOutText(SlideTextManager.TextType.Code);
                TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);
                TextManager.SetSubtitle("SCNPhysicsShape");
                TextManager.AddCode("#// Configure the physics shape\n\n"
                                    + "aNode.physicsBody.#physicsShape# = \n\t[#SCNPhysicsShape# shapeWithGeometry:aGeometry options:options];#");
                TextManager.FlipInText(SlideTextManager.TextType.Bullet);
                TextManager.FlipInText(SlideTextManager.TextType.Code);

                KinematicItems[0].RunAction(SCNAction.Sequence(new SCNAction[] {
                    SCNAction.FadeOut(0.5),
                    SCNAction.RemoveFromParentNode()
                }));
                for (int i = 1; i < 5; i++)
                {
                    KinematicItems[i].RemoveFromParentNode();
                }

                KinematicItems = null;
                break;

            case 13:
                //add meshes
                PresentMeshes(presentationViewController);
                break;

            case 14:
                // remove meshes
                center = new SCNVector3(0, -5, 20);
                center = GroundNode.ConvertPositionToNode(center, null);
                Explosion(center, Meshes);
                break;

            case 15:
                // add shapes
                PresentPrimitives(presentationViewController);
                break;

            case 16:
                // remove shapes
                center = new SCNVector3(0, -5, 20);
                center = GroundNode.ConvertPositionToNode(center, null);
                Explosion(center, Shapes);

                popTime = new DispatchTime(DispatchTime.Now, (long)(0.5 * Utils.NSEC_PER_SEC));
                DispatchQueue.MainQueue.DispatchAfter(popTime, () => {
                    TextManager.FlipOutText(SlideTextManager.TextType.Code);
                    TextManager.FlipOutText(SlideTextManager.TextType.Bullet);
                    TextManager.FlipOutText(SlideTextManager.TextType.Subtitle);

                    TextManager.SetSubtitle("SCNPhysicsBehavior");
                    TextManager.AddCode("#// setup a physics behavior\n\n"
                                        + "#SCNPhysicsHingeJoint# *joint = [SCNPhysicsHingeJoint\n\n"
                                        + "jointWithBodyA:#nodeA.physicsBody# axisA:[...] anchorA:[...]\n\n"
                                        + "bodyB:#nodeB.physicsBody# axisB:[...] anchorB:[...]];\n\n\n"
                                        + "[scene.#physicsWorld# addBehavior:joint];#");

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

            case 17:
                //add meshes
                PresentHinge(presentationViewController);
                break;

            case 18:
                //remove constraints
                ((SCNView)presentationViewController.View).Scene.PhysicsWorld.RemoveAllBehaviors();

                foreach (var node in Hinges)
                {
                    node.RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.Wait(3.0), SCNAction.FadeOut(0.5), SCNAction.RemoveFromParentNode() }));
                }

                break;

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

                TextManager.SetSubtitle("More...");

                TextManager.FlipInText(SlideTextManager.TextType.Subtitle);

                TextManager.AddBulletAtLevel("SCNPhysicsField", 0);
                TextManager.AddBulletAtLevel("SCNPhysicsVehicle", 0);

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