コード例 #1
0
        public void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            var planeAnchor = anchor as ARPlaneAnchor;

            if (planeAnchor == null)
            {
                return;
            }

            Console.WriteLine($"didUpdateNode :{node.ChildNodes.Length}");

            foreach (var childNode in node.ChildNodes)
            {
                SCNPlane planeNode = childNode.Geometry as SCNPlane;
                if (planeNode != null)
                {
                    childNode.Position = new SCNVector3(planeAnchor.Center.X, 0f, planeAnchor.Center.Z);
                    planeNode.Width    = new nfloat(planeAnchor.Extent.X);
                    planeNode.Height   = new nfloat(planeAnchor.Extent.Z);
                }
                else if (childNode.Geometry is SCNText)
                {
                    childNode.Position = new SCNVector3(-0.3f, -0.55f, 0.25f);
                }
            }
        }
コード例 #2
0
 public override void OnNodeRemovedForAnchor(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (!(anchor is ARPlaneAnchor planeAnchor))
     {
         return;
     }
 }
コード例 #3
0
 /// <summary>
 /// Called when a node is added / detected
 /// </summary>
 public override void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is ARPlaneAnchor planeAnchor)
     {
         PlaceAnchorNode(node, planeAnchor);
     }
 }
コード例 #4
0
ファイル: ViewController.cs プロジェクト: rid00z/ARKitExample
 public override void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is ARPlaneAnchor planeAnchor)
     {
         //this.planeNodes[anchor.Identifier].Update(planeAnchor);
     }
 }
コード例 #5
0
        public override void OnNodeUpdatedForAnchor(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            base.OnNodeUpdatedForAnchor(renderer, node, anchor);

            if (!(anchor is ARFaceAnchor faceAnchor))
            {
                return;
            }

            Console.WriteLine(node);

            try
            {
                foreach (var thing in Faces.OfType <FaceNode>())
                {
                    thing.Update(faceAnchor.Geometry);

                    thing.EulerAngles = node.EulerAngles;
                    thing.RotateBy(0, 0, (float)Math.PI, 0);
                }
            } catch { }

            var blendShapes = faceAnchor.BlendShapes;

            // get the five strongest indicators to display
            var dominantParts = blendShapes.Dictionary
                                .GroupBy(x => $"{x.Key}".Split('_')[0], x => (NSNumber)x.Value)
                                .Select(x => new { Expression = x.Key, Value = x.Max(y => y.FloatValue) }) // take strongest of left or right when present
                                .OrderByDescending(x => x.Value)
                                .Select(x => $"{x.Expression}: {x.Value:P0}")
                                .Take(5)
                                .ToList();

            NaivelyAndIneffecientlyCheckForChangedExpression(node, blendShapes);
        }
コード例 #6
0
        public void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            // Place content only for anchors found by plane detection.
            if (anchor is ARPlaneAnchor && this.previewNode != null)
            {
                // Stop showing a preview version of the object to be placed.
                this.cupNode.RemoveFromParentNode();

                this.previewNode?.RemoveFromParentNode();
                this.previewNode?.Dispose();
                this.previewNode = null;

                // Add the cupNode to the scene's root node using the anchor's position.
                var cameraTransform = this.sceneView.Session.CurrentFrame?.Camera?.Transform;
                if (cameraTransform.HasValue)
                {
                    this.SetNewVirtualObjectToAnchor(this.cupNode, anchor, cameraTransform.Value);
                    this.sceneView.Scene.RootNode.AddChildNode(this.cupNode);

                    // Disable plane detection after the model has been added.
                    var configuration = new ARWorldTrackingConfiguration {
                        PlaneDetection = ARPlaneDetection.Horizontal
                    };
                    this.sceneView.Session.Run(configuration, default(ARSessionRunOptions));

                    // Set up positional audio to play in case the object moves offscreen.
                    this.PlaySound();
                }
            }
        }
コード例 #7
0
 public override void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is ARPlaneAnchor planeAnchor)
     {
         Console.WriteLine($"The (updated) extent of the anchor is [{planeAnchor.Extent.X}, {planeAnchor.Extent.Y}, {planeAnchor.Extent.Z}]");
     }
 }
コード例 #8
0
        public override void OnNodeAddedForAnchor(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            base.OnNodeAddedForAnchor(renderer, node, anchor);

            SoundManager.PlaySound("miss");

            var imageAnchor = anchor as ARImageAnchor;
            var refSize     = imageAnchor.ReferenceImage.PhysicalSize;
            var box         = new SCNBox
            {
                Width         = refSize.Width * 1.75f,
                Length        = refSize.Height * 1.75f,
                Height        = 0.0001f,
                ChamferRadius = 0
            };

            box.FirstMaterial.Diffuse.Contents = ShaderScene.Random();
            box.TileTexture(3);

            var pf = Prefabs[i++];

            node.AddChildNode(new SCNNode {
                Geometry = box
            });
            node.AddChildNode(pf);

            pf.Position = SCNVector3.Zero;
            pf.RunAction(SCNAction.RotateBy(0, 1.5f, 0, 0.01));
        }
コード例 #9
0
        /// <summary>
        /// Called when a node is updated
        /// </summary>
        public override void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            if (anchor is ARPlaneAnchor planeAnchor)
            {
                var currentPlaneNode = node.ChildNodes.FirstOrDefault();
                if (currentPlaneNode?.Geometry is SCNPlane currentPlane)
                {
                    currentPlaneNode.Position = new SCNVector3(planeAnchor.Center.X, 0.0f, planeAnchor.Center.Z);
                    currentPlane.Width        = planeAnchor.Extent.X;
                    currentPlane.Height       = planeAnchor.Extent.Z;
                }

                //planeAnchor.plan .planeGeometry.width = CGFloat(anchor.extent.x)
                //self.planeGeometry.height = CGFloat(anchor.extent.z)
                //self.position = SCNVector3Make(anchor.center.x, -0.002, anchor.center.z)

                //foreach (var chilNode in node.ChildNodes)
                //{
                //    //if (chilNode.i
                //}
                // self.planeGeometry.width = anchor.extent.x;
                //self.planeGeometry.height = anchor.extent.z;

                // When the plane is first created it's center is 0,0,0 and
                // the nodes transform contains the translation parameters.
                // As the plane is updated the planes translation remains the
                // same but it's center is updated so we need to update the 3D
                // geometry position
                //self.position = SCNVector3Make(anchor.center.x, 0,
                //planeAnchor.Identifier
                //System.Console.WriteLine($"The (updated) extent of the anchor is [{planeAnchor.Extent.X} , {planeAnchor.Extent.Y} , {planeAnchor.Extent.Z} ]");
            }
        }
コード例 #10
0
        public override void OnNodeAddedForAnchor(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            base.OnNodeAddedForAnchor(renderer, node, anchor);

            SoundManager.PlaySound("miss");

            var imageAnchor = anchor as ARImageAnchor;
            var refSize     = imageAnchor.ReferenceImage.PhysicalSize;
            var box         = new SCNBox
            {
                Width         = refSize.Width * .9f,
                Length        = refSize.Height * .9f,
                Height        = 0.0001f,
                ChamferRadius = 0
            };

            box.FirstMaterial.Diffuse.Contents = UIColor.White.ColorWithAlpha(.95f);

            var pf = Prefabs[i++];

            node.AddChildNode(new SCNNode {
                Geometry = box
            });
            node.AddChildNode(pf);

            pf.Position = SCNVector3.Zero;
        }
コード例 #11
0
 public void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     // Check for whether any environment textures have been generated.
     if (anchor is AREnvironmentProbeAnchor envProbeAnchor && !this.isEnvironmentTextureAvailable)
     {
         this.isEnvironmentTextureAvailable = envProbeAnchor.EnvironmentTexture != null;
     }
 }
コード例 #12
0
 public override void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (source.State.CurrentState == AppState.Scanning && anchor is ARPlaneAnchor)
     {
         var planeAnchor = anchor as ARPlaneAnchor;
         source.CurrentScan?.ScannedObject.TryToAlignWithPlanes(new[] { planeAnchor });
     }
 }
コード例 #13
0
 public virtual void DidSimulatePhysics(ISCNSceneRenderer renderer, double timeInSeconds)
 {
     // If we hit a wall, position needs to be adjusted
     if (positionNeedsAdjustment)
     {
         Character.Node.Position = replacementPosition;
     }
 }
コード例 #14
0
 public void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (!string.IsNullOrEmpty(anchor.Name) &&
         anchor.Name.StartsWith("panda", StringComparison.InvariantCulture))
     {
         node.AddChildNode(this.LoadRedPandaModel());
     }
 }
コード例 #15
0
ファイル: ViewController.cs プロジェクト: rid00z/ARKitExample
 public override void DidRemoveNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is ARPlaneAnchor planeAnchor)
     {
         this.planeNodes[anchor.Identifier].RemoveFromParentNode();
         this.planeNodes.Remove(anchor.Identifier);
     }
 }
コード例 #16
0
 public override async void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor != null && anchor is ARImageAnchor)
     {
         var imageAnchor = (ARImageAnchor)anchor;
         var imageName   = imageAnchor.ReferenceImage.Name;
         imageCapturedAction?.Invoke(imageName);
     }
 }
コード例 #17
0
ファイル: Program.cs プロジェクト: gwilkinson/ARKit_CSharp
 public override void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is ARPlaneAnchor)
     {
         var planeAnchor = anchor as ARPlaneAnchor;
         //BUG: Extent.Z should be at least a few dozen centimeters
         System.Console.WriteLine($"The (updated) extent of the anchor is [{planeAnchor.Extent.X}, {planeAnchor.Extent.Y}, {planeAnchor.Extent.Z}]");
     }
 }
コード例 #18
0
        public void DidRemoveNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            var planeAnchor = anchor as ARPlaneAnchor;

            if (planeAnchor != null)
            {
                serialQueue.DispatchAsync(() => RemovePlane(planeAnchor));
            }
        }
コード例 #19
0
 public override void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     // Check We Have A Valid ARFaceAnchor
     if (anchor != null && anchor is ARFaceAnchor faceAnchor)
     {
         faceNode.Transform = node.Transform;
         Update(faceAnchor);
     }
 }
コード例 #20
0
        public override void OnNodeUpdatedForAnchor(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            if (!(anchor is ARPlaneAnchor planeAnchor))
            {
                return;
            }

            UpdateARPlaneNode(node.ChildNodes[0], planeAnchor);
        }
コード例 #21
0
        public override void OnNodeAddedForAnchor(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            base.OnNodeAddedForAnchor(renderer, node, anchor);

            var plane = node.ChildNodes.First();

            plane.Geometry.FirstMaterial.Diffuse.Contents = ShaderScene.Random();
            plane.Geometry.TileTexture(2);
        }
コード例 #22
0
ファイル: ViewController.cs プロジェクト: rid00z/ARKitExample
 public override void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is ARPlaneAnchor planeAnchor)
     {
         var planeNode = new PlaneNode(planeAnchor);
         node.AddChildNode(planeNode);
         this.planeNodes.Add(anchor.Identifier, planeNode);
     }
 }
コード例 #23
0
        public override void OnNodeAddedForAnchor(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            base.OnNodeAddedForAnchor(renderer, node, anchor);

            if (anchor is ARObjectAnchor objectAnchor)
            {
                OnFoundThing(node, objectAnchor);
            }
        }
コード例 #24
0
 public override void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is ARPlaneAnchor planeAnchor)
     {
         DispatchQueue.MainQueue.DispatchAsync(() =>
         {
             updatePlane(planeAnchor);
         });
     }
 }
コード例 #25
0
        public void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
        {
            var planeAnchor = anchor as ARPlaneAnchor;

            if (planeAnchor != null)
            {
                UpdatePlane(planeAnchor);
                virtualObjectManager.CheckIfObjectShouldMoveOntoPlane(planeAnchor, node);
            }
        }
コード例 #26
0
 public void DidUpdateNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is BoardAnchor boardAnchor)
     {
         // Update the game board's scale from the board anchor
         // The transform will have already been updated - without the scale
         var width = (float)boardAnchor.Size.Width;
         node.Scale = new SCNVector3(width, width, width);
     }
 }
コード例 #27
0
 public override void DidAddNode(ISCNSceneRenderer renderer, SCNNode node, ARAnchor anchor)
 {
     if (anchor is ARFaceAnchor)
     {
         var faceGeometry = ARSCNFaceGeometry.Create(renderer.GetDevice());
         node.Geometry = faceGeometry;
         node.Geometry.FirstMaterial.FillMode = SCNFillMode.Fill;
         node.Opacity = 0.8f;
     }
 }
 public void Update(ISCNSceneRenderer renderer, double timeInSeconds)
 {
     using (var currentFrame = _sceneView?.Session?.CurrentFrame)
     {
         if (currentFrame == null || currentFrame?.Camera == null)
         {
             return;
         }
     }
 }
コード例 #29
0
            public override SCNNode GetNode(ISCNSceneRenderer renderer, ARAnchor anchor)
            {
                Console.WriteLine($"GetNode ({renderer}, {anchor})");

                var node = SCNNode.Create();

                node.Add(MakeBox(anchor));

                return(node);
            }
コード例 #30
0
        public virtual void Update(ISCNSceneRenderer renderer, double timeInSeconds)
        {
            if (previousUpdateTime == 0.0)
            {
                previousUpdateTime = timeInSeconds;
            }

            deltaTime          = timeInSeconds - previousUpdateTime;
            previousUpdateTime = timeInSeconds;

            SharedSceneView aView = (SharedSceneView)renderer;

            bool pressingLeft  = aView.KeysPressed.Contains(SharedSceneView.LeftKey);
            bool pressingRight = aView.KeysPressed.Contains(SharedSceneView.RightKey);
            bool pressingJump  = aView.KeysPressed.Contains(SharedSceneView.JumpKey);

            if (CurrentGameState == GameState.InGame && !GameLevel.HitByLavaReset)
            {
                if (pressingLeft)
                {
                    GameLevel.PlayerCharacter.PlayerWalkDirection = WalkDirection.Left;
                }
                else if (pressingRight)
                {
                    GameLevel.PlayerCharacter.PlayerWalkDirection = WalkDirection.Right;
                }

                if (pressingLeft || pressingRight)
                {
                    //Run if not running
                    GameLevel.PlayerCharacter.InRunAnimation = true;
                }
                else
                {
                    //Stop running if running
                    GameLevel.PlayerCharacter.InRunAnimation = false;
                }

                if (pressingJump)
                {
                    GameLevel.PlayerCharacter.PerformJumpAndStop(false);
                }
                else
                {
                    GameLevel.PlayerCharacter.PerformJumpAndStop(true);
                }
            }
            else if (CurrentGameState == GameState.PreGame || CurrentGameState == GameState.PostGame)
            {
                if (pressingJump)
                {
                    SetGameState(GameState.InGame);
                }
            }
        }
コード例 #31
0
		public virtual void DidSimulatePhysics (ISCNSceneRenderer renderer, double timeInSeconds)
		{
			// If we hit a wall, position needs to be adjusted
			if (positionNeedsAdjustment)
				Character.Node.Position = replacementPosition;
		}
コード例 #32
0
		public virtual void Update (ISCNSceneRenderer renderer, double timeInSeconds)
		{
			// delta time since last update
			if (Math.Abs (previousUpdateTime) < float.Epsilon)
				previousUpdateTime = timeInSeconds;

			double deltaTime = Math.Min (Math.Max (1.0 / 60.0, timeInSeconds - previousUpdateTime), 1f);
			previousUpdateTime = timeInSeconds;

			// Reset some states every frame
			maxPenetrationDistance = 0;
			positionNeedsAdjustment = false;

			SCNVector3 direction = GameView.CurrentDirection;
			SCNVector3 initialPosition = Character.Node.Position;

			// Move
			if (Math.Abs (direction.X) > float.Epsilon && Math.Abs (direction.Z) > float.Epsilon) {
				var characterSpeed = (float)deltaTime * CharacterSpeedFactor * .84f;
				Character.Node.Position = new SCNVector3 (
					initialPosition.X + direction.X * characterSpeed,
					initialPosition.Y + direction.Y * characterSpeed,
					initialPosition.Z + direction.Z * characterSpeed
				);

				// update orientation
				double angle = Math.Atan2 (direction.X, direction.Z);
				Character.Direction = (float)angle;
				Character.Walking = true;
			} else {
				Character.Walking = false;
			}

			var p0 = Character.Node.Position;
			var p1 = Character.Node.Position;

			p0.Y -= MaxJump;
			p1.Y += MaxRise;

			var options = new SCNPhysicsTest {
				CollisionBitMask = (nuint)(int)(Bitmask.Collision | Bitmask.Water),
				SearchMode = SCNPhysicsSearchMode.Closest
			};

			SCNHitTestResult[] results = GameView.Scene.PhysicsWorld.RayTestWithSegmentFromPoint (p1, p0, options);
			float groundY = -10;

			if (results.Length > 0) {
				
				SCNHitTestResult result = results [0];
				groundY = result.WorldCoordinates.Y;
				UpdateCameraWithCurrentGround (result.Node);
				SCNMaterial groundMaterial = result.Node.ChildNodes [0].Geometry.FirstMaterial;
				if (grassArea == groundMaterial) {
					Character.CurrentFloorMaterial = FloorMaterial.Grass;
				} else if (waterArea == groundMaterial) {
					if (Character.Burning) {
						Character.Pshhhh ();
						Character.Node.RunAction (SCNAction.Sequence (new [] {
							SCNAction.PlayAudioSource (pshhhSound, true),
							SCNAction.PlayAudioSource (aahSound, false)
						}));
					}

					Character.CurrentFloorMaterial = FloorMaterial.Water;

					options = new SCNPhysicsTest {
						CollisionBitMask = (nuint)(int)Bitmask.Collision,
						SearchMode = SCNPhysicsSearchMode.Closest
					};

					results = GameView.Scene.PhysicsWorld.RayTestWithSegmentFromPoint (p1, p0, options);
					result = results [0];
					groundY = result.WorldCoordinates.Y;
				} else {
					Character.CurrentFloorMaterial = FloorMaterial.Rock;
				}
			}

//			var nextPosition = Character.Node.Position;
//			const double threshold = 1e-5;
//
//			if (groundY < nextPosition.Y - threshold) {
//				// approximation of acceleration for a delta time
//				accelerationY += (float)(deltaTime * GravityAcceleration);
//				if (groundY < nextPosition.Y - 0.2)
//					Character.CurrentFloorMaterial = FloorMaterial.Air;
//			} else {
//				accelerationY = 0;
//			}
//
//			nextPosition.Y -= accelerationY;
//
//			// reset acceleration if we touch the ground
//			if (groundY > nextPosition.Y) {
//				accelerationY = 0;
//				nextPosition.Y = groundY;
//			}

			// Flames are static physics bodies, but they are moved by an action - So we need to tell the physics engine that the transforms did change.
			foreach (SCNNode flame in flames)
				flame.PhysicsBody.ResetTransform ();

			// Adjust the volume of the enemy based on the distance with the character.
			float distanceToClosestEnemy = float.MaxValue;
			SCNVector3 pos3 = Character.Node.Position;
			foreach (SCNNode enemy in enemies) {
				// distance to enemy
				SCNMatrix4 enemyMat = enemy.WorldTransform;
				var enemyPosition = new SCNVector3 (enemyMat.M41, enemyMat.M42, enemyMat.M43);
				float distance = SCNVector3.Subtract (pos3, enemyPosition).Length;
				distanceToClosestEnemy = Math.Min (distanceToClosestEnemy, distance);
			}

			// Adjust sounds volumes based on distance with the enemy.
			if (!gameIsComplete) {
				double fireVolume = 0.3 * Math.Max (0.0, Math.Min (1.0, 1.0 - (distanceToClosestEnemy - 1.2) / 1.6));
				var  mixerNode = flameThrowerSound.AudioNode as AVAudioMixerNode;
				if (mixerNode != null)
					mixerNode.Volume = (float)fireVolume;
			}
		}
コード例 #33
0
		public virtual void Update (ISCNSceneRenderer renderer, double timeInSeconds)
		{
			if (previousUpdateTime == 0.0)
				previousUpdateTime = timeInSeconds;

			deltaTime = timeInSeconds - previousUpdateTime;
			previousUpdateTime = timeInSeconds;

			SharedSceneView aView = (SharedSceneView)renderer;

			bool pressingLeft = aView.KeysPressed.Contains (SharedSceneView.LeftKey);
			bool pressingRight = aView.KeysPressed.Contains (SharedSceneView.RightKey);
			bool pressingJump = aView.KeysPressed.Contains (SharedSceneView.JumpKey);

			if (CurrentGameState == GameState.InGame && !GameLevel.HitByLavaReset) {
				if (pressingLeft)
					GameLevel.PlayerCharacter.PlayerWalkDirection = WalkDirection.Left;
				else if (pressingRight)
					GameLevel.PlayerCharacter.PlayerWalkDirection = WalkDirection.Right;

				if (pressingLeft || pressingRight)
					//Run if not running
					GameLevel.PlayerCharacter.InRunAnimation = true;
				else
					//Stop running if running
					GameLevel.PlayerCharacter.InRunAnimation = false;

				if (pressingJump)
					GameLevel.PlayerCharacter.PerformJumpAndStop (false);
				else
					GameLevel.PlayerCharacter.PerformJumpAndStop (true);
			} else if (CurrentGameState == GameState.PreGame || CurrentGameState == GameState.PostGame) {
				if (pressingJump)
					SetGameState (GameState.InGame);
			}
		}
コード例 #34
0
		public virtual void DidSimulatePhysics (ISCNSceneRenderer renderer, double timeInSeconds)
		{
			float defaultEngineForce = 300.0f;
			float defaultBrakingForce = 3.0f;
			float steeringClamp = 0.6f;
			float cameraDamping = 0.3f;

			GameView scnView = GameView;

			float engineForce = 0;
			float brakingForce = 0;

			var controllers = GCController.Controllers;
			float orientation = this.orientation;

			switch (scnView.TouchesCount) {
			case 1:
				engineForce = defaultEngineForce;
				reactor.BirthRate = reactorDefaultBirthRate;
				break;
			case 2:
				engineForce = -defaultEngineForce;
				reactor.BirthRate = 0;
				break;
			case 3:
				brakingForce = 100;
				reactor.BirthRate = 0;
				break;
			default:
				brakingForce = defaultBrakingForce;
				reactor.BirthRate = 0;
				break;
			}

			if (controllers != null && controllers.Length > 0) {
				GCController controller = controllers [0];
				GCGamepad pad = controller.Gamepad;
				GCControllerDirectionPad dpad = pad.DPad;

				if (dpad.Right.IsPressed) {
					if (orientationCum < 0f)
						orientationCum *= decrementOrientation;

					orientationCum += incrementOrientation;

					if (orientationCum > 1f)
						orientationCum = 1f;
				} else if (dpad.Left.IsPressed) {
					if (orientationCum > 0)
						orientationCum *= decrementOrientation;

					orientationCum -= incrementOrientation;

					if (orientationCum < -1)
						orientationCum = -1;
				} else {
					orientationCum *= decrementOrientation;
				}
			}

			vehicleSteering = -orientation;
			if (orientation == 0)
				vehicleSteering *= 0.9f;
			if (vehicleSteering < -steeringClamp)
				vehicleSteering = -steeringClamp;
			if (vehicleSteering > steeringClamp)
				vehicleSteering = steeringClamp;

			vehicle.SetSteeringAngle (vehicleSteering, 0);
			vehicle.SetSteeringAngle (vehicleSteering, 1);

			vehicle.ApplyEngineForce (engineForce, 2);
			vehicle.ApplyEngineForce (engineForce, 3);

			vehicle.ApplyBrakingForce (brakingForce, 2);
			vehicle.ApplyBrakingForce (brakingForce, 3);

			ReorientCarIfNeeded ();

			SCNNode car = vehicleNode.PresentationNode;
			SCNVector3 carPos = car.Position;
			var targetPos = new SCNVector3 (carPos.X, 30f, carPos.Z + 25f);
			var cameraPos = new SCNVector3 (cameraNode.Position);
			cameraPos = SCNVector3.Add (cameraPos, cameraDamping * (SCNVector3.Subtract (targetPos, cameraPos)));
			cameraNode.Position = cameraPos;

			if (scnView.InCarView) {
				var frontPosition = scnView.PointOfView.PresentationNode.ConvertPositionToNode (new SCNVector3 (0f, 0f, -30f), null);
				spotLightNode.Position = new SCNVector3 (frontPosition.X, 80f, frontPosition.Z);
				spotLightNode.Rotation = new SCNVector4 (1f, 0f, 0f, -(float)Math.PI / 2f);
			} else {
				spotLightNode.Position = new SCNVector3 (carPos.X, 80f, carPos.Z + 30f);
				spotLightNode.Rotation = new SCNVector4 (1f, 0f, 0f, -(float)(Math.PI / 2.8));
			}

			var overlayScene = (OverlayScene)scnView.OverlayScene;
			overlayScene.SpeedNeedle.ZRotation = -(vehicle.SpeedInKilometersPerHour * (float)Math.PI / maxSpeed);
		}
コード例 #35
0
 public static SCNHitTestResult[] HitTest(ISCNSceneRenderer This, CGPoint thePoint, SCNHitTestOptions options)
 {
     return This.HitTest (thePoint, options == null ? null : options.Dictionary);
 }