Exemple #1
0
        public override void TouchesEnded(NSSet touches, UIEvent evt)
        {
            //TODO 2.2 Interactuando con elementos de pantalla
            base.TouchesEnded(touches, evt);

            if (touches.AnyObject is UITouch touch)
            {
                CGPoint point = touch.LocationInView(this.sceneView);

                SCNHitTestOptions hitTestOptions = new SCNHitTestOptions();

                SCNHitTestResult[] hits = sceneView.HitTest(point, hitTestOptions);
                SCNHitTestResult   hit  = hits.FirstOrDefault();

                if (hit == null)
                {
                    return;
                }

                SCNNode node = hit.Node;

                if (node == null)
                {
                    return;
                }

                node.RemoveFromParentNode();
            }
        }
Exemple #2
0
        void HandleTapGesture(UITapGestureRecognizer sender)
        {
            SCNView areaPanned = sender.View as SCNView;
            CGPoint point      = sender.LocationInView(areaPanned);

            SCNHitTestResult[] hitResults = areaPanned.HitTest(point, new SCNHitTestOptions());
            SCNHitTestResult   hit        = hitResults.FirstOrDefault();

            if (hit != null)
            {
                SCNNode node = hit.Node;
                if (node != null)
                {
                    if (!isAnimating)
                    {
                        node.AddRotationAction(SCNActionTimingMode.Linear, 3, true);
                        isAnimating = true;
                    }
                    else
                    {
                        node.RemoveAction("rotation");
                        isAnimating = false;
                    }
                }
            }
        }
        private CGPoint ScreenPositionFromHittest(SCNHitTestResult phoneScreenEyeLHitTestResult, SCNHitTestResult phoneScreenEyeRHitTestResult)
        {
            CGPoint eyeLLookAt = new CGPoint();
            CGPoint eyeRLookAt = new CGPoint();

            eyeRLookAt.X = (nfloat)phoneScreenEyeRHitTestResult.LocalCoordinates.X / (phoneScreenSize.Width / 2) * phoneScreenPointSize.Width + compensation.Width;
            eyeRLookAt.Y = (nfloat)phoneScreenEyeRHitTestResult.LocalCoordinates.Y / (phoneScreenSize.Height / 2) * (phoneScreenPointSize.Height + compensation.Height);

            eyeLLookAt.X = (nfloat)phoneScreenEyeLHitTestResult.LocalCoordinates.X / (phoneScreenSize.Width / 2) * phoneScreenPointSize.Width + compensation.Width;
            eyeLLookAt.Y = (nfloat)phoneScreenEyeLHitTestResult.LocalCoordinates.Y / (phoneScreenSize.Height / 2) * (phoneScreenPointSize.Height + compensation.Height);

            // Smooth
            // Add the latest position and keep up to 9 recent position to smooth with.
            // Add it to first array position
            eyeLookAtPositionXs[0] = ((eyeRLookAt.X + eyeLLookAt.X) / 2);
            eyeLookAtPositionYs[0] = (-(eyeRLookAt.Y + eyeLLookAt.Y) / 2);
            // Copy rest of readings
            Array.Copy(eyeLookAtPositionXsTmp, 0, eyeLookAtPositionXs, 1, SmoothThreshold - 1);
            Array.Copy(eyeLookAtPositionYsTmp, 0, eyeLookAtPositionYs, 1, SmoothThreshold - 1);
            // Cache readings
            eyeLookAtPositionXs.CopyTo(eyeLookAtPositionXsTmp, 0);
            eyeLookAtPositionYs.CopyTo(eyeLookAtPositionYsTmp, 0);

            // Calc average
            float smoothEyeLookAtPositionX = eyeLookAtPositionXs.Average();
            float smoothEyeLookAtPositionY = eyeLookAtPositionYs.Average();

            return(new CGPoint(smoothEyeLookAtPositionX, smoothEyeLookAtPositionY));
        }
Exemple #4
0
        void HandleRotateGesture(UIRotationGestureRecognizer sender)
        {
            SCNView areaPanned = sender.View as SCNView;
            CGPoint point      = sender.LocationInView(areaPanned);

            SCNHitTestResult[] hitResults = areaPanned.HitTest(point, new SCNHitTestOptions());
            SCNHitTestResult   hit        = hitResults.FirstOrDefault();

            if (hit != null)
            {
                SCNNode node = hit.Node;
                zAngle          += (float)(-sender.Rotation);
                node.EulerAngles = new SCNVector3(node.EulerAngles.X, node.EulerAngles.Y, zAngle);
            }
        }
Exemple #5
0
        void HandleTapGesture(UITapGestureRecognizer sender)
        {
            SCNView areaPanned = sender.View as SCNView;
            CGPoint point      = sender.LocationInView(areaPanned);

            SCNHitTestResult[] hitResults = areaPanned.HitTest(point, new SCNHitTestOptions());
            SCNHitTestResult   hit        = hitResults.FirstOrDefault();

            if (hit != null)
            {
                SCNNode node = hit.Node;
                if (node != null)
                {
                    node.RemoveFromParentNode();
                }
            }
        }
Exemple #6
0
        void HandlePinchGesture(UIPinchGestureRecognizer sender)
        {
            SCNView areaPanned = sender.View as SCNView;
            CGPoint point      = sender.LocationInView(areaPanned);

            SCNHitTestResult[] hitResults = areaPanned.HitTest(point, new SCNHitTestOptions());
            SCNHitTestResult   hit        = hitResults.FirstOrDefault();

            if (hit != null)
            {
                SCNNode node = hit.Node;

                float scaleX = (float)sender.Scale * node.Scale.X;
                float scaleY = (float)sender.Scale * node.Scale.Y;

                node.Scale   = new SCNVector3(scaleX, scaleY, zPosition / 2);
                sender.Scale = 1; // Reset the node scale value
            }
        }
Exemple #7
0
        void HandleTap(UIGestureRecognizer gestureRecognize)
        {
            // retrieve the SCNView
            var scnView = (SCNView)View;

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

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

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

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

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

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

                    material.Emission.Contents = UIColor.Black;

                    SCNTransaction.Commit();
                });

                material.Emission.Contents = UIColor.Red;

                SCNTransaction.Commit();
            }
        }
        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;
                }
            }
        }