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