예제 #1
0
        private void DestroyTarget()
        {
            Target.Opacity = 0;
            var ps = SCNParticleSystem.Create("explosion", "Particles");

            Target.AddParticleSystem(ps);
        }
예제 #2
0
        public MovingEntity()
            : base(NSUrl.FromString(
                       NSBundle.MainBundle.BundleUrl.AbsoluteString + $"Models.scnassets/rc_car.dae"
                       ))
        {
            _greyMaterial = new SCNMaterial();
            _greyMaterial.Diffuse.Contents = UIImage.FromFile("Models.scnassets/rc_car_grey_texture.png");

            _colorMaterial = new SCNMaterial();
            _colorMaterial.Diffuse.Contents = UIImage.FromFile("Models.scnassets/rc_car_texture.png");

            _exhaust              = SCNParticleSystem.Create("Exhaust", "Models.scnassets");
            _configuredBirthRate  = _exhaust.BirthRate;
            _exhaust.BirthRate    = 0;
            _exhaust.ParticleSize = _modelScale;
        }
예제 #3
0
        SCNNode CreateTorchNode()
        {
            SCNGeometry geometry = SCNBox.Create(20f, 100f, 20f, 0f);

            geometry.FirstMaterial.Diffuse.Contents = AppKit.NSColor.Brown;
            var template = new SCNNode {
                Geometry = geometry
            };

            var particleEmitter = new SCNNode {
                Position = new SCNVector3(0f, 50f, 0f)
            };

            SCNParticleSystem fire = GameSimulation.LoadParticleSystemWithName("torch", "spark");

            particleEmitter.AddParticleSystem(fire);
            particleEmitter.Light = TorchLight;

            template.AddChildNode(particleEmitter);
            return(template);
        }
예제 #4
0
        private void LoadParticles()
        {
            var particleScene = SCNScene.FromFile("art.scnassets/character/jump_dust.scn");
            var particleNode  = particleScene.RootNode.FindChildNode("particle", true);

            this.jumpDustParticle = particleNode.ParticleSystems.FirstOrDefault();

            particleScene = SCNScene.FromFile("art.scnassets/particles/burn.scn");
            var burnParticleNode = particleScene.RootNode.FindChildNode("particles", true);

            var particleEmitter = new SCNNode();

            this.characterOrientation.AddChildNode(particleEmitter);

            this.fireEmitter           = burnParticleNode.FindChildNode("fire", true).ParticleSystems[0];
            this.fireEmitterBirthRate  = fireEmitter.BirthRate;
            this.fireEmitter.BirthRate = 0f;

            this.smokeEmitter           = burnParticleNode.FindChildNode("smoke", true).ParticleSystems[0];
            this.smokeEmitterBirthRate  = smokeEmitter.BirthRate;
            this.smokeEmitter.BirthRate = 0f;

            this.whiteSmokeEmitter           = burnParticleNode.FindChildNode("whiteSmoke", true).ParticleSystems[0];
            this.whiteSmokeEmitterBirthRate  = whiteSmokeEmitter.BirthRate;
            this.whiteSmokeEmitter.BirthRate = 0f;

            particleScene           = SCNScene.FromFile("art.scnassets/particles/particles_spin.scn");
            this.spinParticle       = (particleScene.RootNode.FindChildNode("particles_spin", true)?.ParticleSystems?.FirstOrDefault());
            this.spinCircleParticle = (particleScene.RootNode.FindChildNode("particles_spin_circle", true)?.ParticleSystems?.FirstOrDefault());

            particleEmitter.Position = new SCNVector3(0f, 0.05f, 0f);
            particleEmitter.AddParticleSystem(this.fireEmitter);
            particleEmitter.AddParticleSystem(this.smokeEmitter);
            particleEmitter.AddParticleSystem(this.whiteSmokeEmitter);

            this.spinParticleAttach = this.model.FindChildNode("particles_spin_circle", true);
        }
예제 #5
0
        SCNNode CreateLargeBanana()
        {
            //Create model
            if (largeBananaCollectable == null)
            {
                var   node      = GameSimulation.LoadNodeWithName("banana", GameSimulation.PathForArtResource("level/banana.dae"));
                float scaleMode = 0.5f * 10 / 4;
                node.Scale = new SCNVector3(scaleMode, scaleMode, scaleMode);


                SCNSphere       sphereGeometry = SCNSphere.Create(100);
                SCNPhysicsShape physicsShape   = SCNPhysicsShape.Create(sphereGeometry, new SCNPhysicsShapeOptions());
                node.PhysicsBody = SCNPhysicsBody.CreateBody(SCNPhysicsBodyType.Kinematic, physicsShape);

                // Only collide with player and ground
                node.PhysicsBody.CollisionBitMask = GameCollisionCategory.Player | GameCollisionCategory.Ground;
                // Declare self in the banana category
                node.PhysicsBody.CategoryBitMask = GameCollisionCategory.Coin;

                // Rotate forever.
                SCNAction rotateCoin = SCNAction.RotateBy(0f, 8f, 0f, 2f);
                SCNAction repeat     = SCNAction.RepeatActionForever(rotateCoin);

                node.Rotation = new SCNVector4(0f, 1f, 0f, (nfloat)Math.PI / 2);
                node.RunAction(repeat);

                largeBananaCollectable = node;
            }

            SCNNode nodeSparkle = largeBananaCollectable.Clone();

            SCNParticleSystem newSystem = GameSimulation.LoadParticleSystemWithName("sparkle");

            nodeSparkle.AddParticleSystem(newSystem);

            return(nodeSparkle);
        }
		public override void AwakeFromNib ()
		{
			GameView = (GameView)View;
			// Create a new scene.
			SCNScene scene = SCNScene.FromFile ("game.scnassets/level.scn");

			// Set the scene to the view and loops for the animation of the bamboos
			GameView.Scene = scene;
			GameView.Playing = true;
			GameView.Loops = true;

			Character = new Character ();

			SetupCamera ();
			SetupSounds ();
			SetupMusic ();

			// setup particles
			collectParticles = SCNParticleSystem.Create ("collect.scnp", "game.scnassets");
			collectParticles.ParticleImage = PathForArtResource ("textures/glow01.png");
			collectParticles.Loops = false;

			confetti = SCNParticleSystem.Create ("confetti.scnp", "game.scnassets");
			confetti.ParticleImage = PathForArtResource ("textures/confetti.png");

			// Add the character to the scene.
			scene.RootNode.AddChildNode (Character.Node);

			// Place it
			SCNNode sp = scene.RootNode.FindChildNode ("startingPoint", true);
			Character.Node.Transform = sp.Transform;

			// Setup physics masks and physics shape
			SCNNode[] collisionNodes = scene.RootNode.FindNodes ((SCNNode node, out bool stop) => {
				bool? collidable = node.Name?.Contains ("collision");
				stop = false;
				return collidable.HasValue && collidable.Value;
			});

			foreach (SCNNode node in collisionNodes) {
				node.Hidden = false;
				SetupCollisionNodes (node);
			}

			// Setup physics masks and physics shape
			flames = scene.RootNode.FindNodes ((SCNNode node, out bool stop) => {
				stop = false;
				if (node.Name == "flame") {
					node.PhysicsBody.CategoryBitMask = (nuint)(int)Bitmask.Enemy;
					return true;
				}

				return false;
			});

			enemies = scene.RootNode.FindNodes ((SCNNode node, out bool stop) => {
				stop = false;
				return node.Name == "enemy";
			});

			// Setup delegates
			GameView.Scene.PhysicsWorld.ContactDelegate = this;
			GameView.SceneRendererDelegate = this;

			// setup view overlays
			GameView.Setup ();
			SetupAutomaticCameraPositions ();
		}
예제 #7
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);
        }
예제 #8
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);
        }
		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;
		}
예제 #10
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;
            }
        }
예제 #11
0
		//present particle slide
		void ShowParticlesSlide ()
		{
			//restore defaults
			((SCNView)View).Scene.PhysicsWorld.Gravity = new SCNVector3 (0, -9.8f, 0);

			//add truck
			var fireTruckScene = SCNScene.FromFile ("assets.scnassets/models/firetruck");
			var fireTruck = fireTruckScene.RootNode.FindChildNode ("firetruck", true);
			var emitter = fireTruck.FindChildNode ("emitter", true);
			Handle = fireTruck.FindChildNode ("handle", true);

			fireTruck.Position = new SCNVector3 (120, 10, 0);
			fireTruck.Scale = new SCNVector3 (0.2f, 0.2f, 0.2f);
			fireTruck.Rotation = new SCNVector4 (0, 1, 0, (float)Math.PI / 2);

			Scene.RootNode.AddChildNode (fireTruck);

			//add fire container
			var fireContainerScene = SCNScene.FromFile ("assets.scnassets/models/bac");
			FireContainer = fireContainerScene.RootNode.FindChildNode ("box", true);
			FireContainer.Scale = new SCNVector3 (0.5f, 0.25f, 0.25f);
			Scene.RootNode.AddChildNode (FireContainer);

			//preload it to avoid frame drop
			//(SCNView)this.View prepareObject:_scene shouldAbortBlock:nil];

			FireTruck = fireTruck;

			//collider
			var colliderNode = SCNNode.Create ();
			colliderNode.Geometry = SCNBox.Create (50, 2, 25, 0);
			#if __IOS__
			colliderNode.Geometry.FirstMaterial.Diffuse.Contents = new UIImage ("assets.scnassets/models/train_wood.jpg");
			#else
			colliderNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("assets.scnassets/textures/train_wood", "jpg"));
			#endif
			colliderNode.Position = new SCNVector3 (60, 260, 5);
			Scene.RootNode.AddChildNode (colliderNode);

			var moveIn = SCNAction.MoveBy (0, -215, 0, 1.0);
			moveIn.TimingMode = SCNActionTimingMode.EaseOut;
			colliderNode.RunAction (SCNAction.Sequence (new [] { SCNAction.Wait (2), moveIn }));

			var animation = CABasicAnimation.FromKeyPath ("eulerAngles");
			animation.From = NSValue.FromVector (new SCNVector3 (0, 0, 0));
			animation.To = NSValue.FromVector (new SCNVector3 (0, 0, 2 * (float)Math.PI));
			animation.BeginTime = CAAnimation.CurrentMediaTime () + 0.5f;
			animation.Duration = 2;
			animation.RepeatCount = float.MaxValue;
			colliderNode.AddAnimation (animation, null);
			Collider = colliderNode;

			SCNParticleSystem ps;

			//add fire
			var fireHolder = SCNNode.Create ();
			Emitter = fireHolder;
			fireHolder.Position = new SCNVector3 (0, 0, 0);
			ps = SCNParticleSystem.Create ("fire.scnp", "assets.scnassets/particles/");
			ps.ParticleImage = new NSString ("assets.scnassets/textures/fire.png");
			Smoke = SCNParticleSystem.Create ("smoke.scnp", "assets.scnassets/particles/");
			Smoke.ParticleImage = new NSString ("assets.scnassets/textures/smoke.png");
			Smoke.BirthRate = 0;
			fireHolder.AddParticleSystem (ps);

			var smokeEmitter = SCNNode.Create ();
			smokeEmitter.Position = new SCNVector3 (0, 0, 0.5f);
			smokeEmitter.AddParticleSystem (Smoke);
			fireHolder.AddChildNode (smokeEmitter);
			Scene.RootNode.AddChildNode (fireHolder);

			Fire = ps;

			//add water
			ps = SCNParticleSystem.Create ("sparks.scnp", "assets.scnassets/particles/");
			ps.ParticleImage = new NSString ("assets.scnassets/textures/spark.png");
			ps.BirthRate = 0;
			ps.SpeedFactor = 3.0f;
			ps.ColliderNodes = new [] { FloorNode, colliderNode };
			emitter.AddParticleSystem (ps);

			var tr = SCNAction.MoveBy (new SCNVector3 (60, 0, 0), 1);
			tr.TimingMode = SCNActionTimingMode.EaseInEaseOut;
		}
예제 #12
0
		//present spritekit integration slide
		void ShowSpriteKitSlide ()
		{
			//place camera
			SCNTransaction.Begin ();
			SCNTransaction.AnimationDuration = 2;
			CameraHandle.Position = new SCNVector3 (CameraHandle.Position.X + 200, 60, 0);
			SCNTransaction.Commit ();

			//load plok particles
			Plok = SCNParticleSystem.Create ("plok.scnp", "assets.scnassets/particles");

			//create a spinning object
			Torus = SCNNode.Create ();
			Torus.Position = new SCNVector3 (CameraHandle.Position.X, 60, 10);
			Torus.Geometry = SCNTorus.Create (W / 2, W / 6);
			Torus.PhysicsBody = SCNPhysicsBody.CreateStaticBody ();
			Torus.Opacity = 0.0f;

			var material = Torus.Geometry.FirstMaterial;
			material.Specular.Contents = SKColorHelper.FromCommonWhiteAlpha (0.5f, 1);
			material.Shininess = 2.0f;

			#if __IOS__
			material.Normal.Contents = new UIImage ("images/wood-normal.png");
			#else
			material.Normal.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("images/wood-normal", "png"));
			#endif

			Scene.RootNode.AddChildNode (Torus);
			Torus.RunAction (SCNAction.RepeatActionForever (SCNAction.RotateBy (NMath.PI * 2, new SCNVector3 (0.4f, 1, 0), 8)));

			//preload it to avoid frame drop
			//[(SCNView*)self.view prepareObject:_scene shouldAbortBlock:nil];

			Scene.PhysicsWorld.WeakContactDelegate = this;

			//setup material
			var skScene = SKScene.FromSize (new CGSize (SPRITE_SIZE, SPRITE_SIZE));
			skScene.BackgroundColor = SKColor.White;
			material.Diffuse.Contents = skScene;

			SCNTransaction.Begin ();
			SCNTransaction.AnimationDuration = 1;
			SCNTransaction.SetCompletionBlock (StartLaunchingColors);

			Torus.Opacity = 1.0f;

			SCNTransaction.Commit ();
		}
예제 #13
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;
			}
		}
예제 #14
0
        public override void AwakeFromNib()
        {
            GameView = (GameView)View;
            // Create a new scene.
            SCNScene scene = SCNScene.FromFile("game.scnassets/level.scn");

            // Set the scene to the view and loops for the animation of the bamboos
            GameView.Scene   = scene;
            GameView.Playing = true;
            GameView.Loops   = true;

            Character = new Character();

            SetupCamera();
            SetupSounds();
            SetupMusic();

            // setup particles
            collectParticles = SCNParticleSystem.Create("collect.scnp", "game.scnassets");
            collectParticles.ParticleImage = PathForArtResource("textures/glow01.png");
            collectParticles.Loops         = false;

            confetti = SCNParticleSystem.Create("confetti.scnp", "game.scnassets");
            confetti.ParticleImage = PathForArtResource("textures/confetti.png");

            // Add the character to the scene.
            scene.RootNode.AddChildNode(Character.Node);

            // Place it
            SCNNode sp = scene.RootNode.FindChildNode("startingPoint", true);

            Character.Node.Transform = sp.Transform;

            // Setup physics masks and physics shape
            SCNNode[] collisionNodes = scene.RootNode.FindNodes((SCNNode node, out bool stop) => {
                bool?collidable = node.Name?.Contains("collision");
                stop            = false;
                return(collidable.HasValue && collidable.Value);
            });

            foreach (SCNNode node in collisionNodes)
            {
                node.Hidden = false;
                SetupCollisionNodes(node);
            }

            // Setup physics masks and physics shape
            flames = scene.RootNode.FindNodes((SCNNode node, out bool stop) => {
                stop = false;
                if (node.Name == "flame")
                {
                    node.PhysicsBody.CategoryBitMask = (nuint)(int)Bitmask.Enemy;
                    return(true);
                }

                return(false);
            });

            enemies = scene.RootNode.FindNodes((SCNNode node, out bool stop) => {
                stop = false;
                return(node.Name == "enemy");
            });

            // Setup delegates
            GameView.Scene.PhysicsWorld.ContactDelegate = this;
            GameView.SceneRendererDelegate = this;

            // setup view overlays
            GameView.Setup();
            SetupAutomaticCameraPositions();
        }