// Compute the rotation matrix from one point to another on a unit sphere. SCNMatrix4 RotationFromPoint(Vector3 start, Vector3 end) { var axis = Vector3.Cross(start, end); var angle = NMath.Atan2(axis.Length, Vector3.Dot(start, end)); return(SCNMatrix4.CreateFromAxisAngle(axis, (float)angle)); }
SCNMatrix4 MakeProjectionMatrix(UIInterfaceOrientation orientation) { const int bufferSize = 16; float[] projectionBuffer = new float[bufferSize]; unsafe { fixed(float *ptr = &projectionBuffer[0]) { SDPlugin.SixDegreesSDK_GetProjection(ptr, bufferSize); } } var matrix = new Matrix4 { Row0 = new Vector4(projectionBuffer[0], projectionBuffer[1], projectionBuffer[2], projectionBuffer[3]), Row1 = new Vector4(projectionBuffer[4], projectionBuffer[5], projectionBuffer[6], projectionBuffer[7]), Row2 = new Vector4(projectionBuffer[8], projectionBuffer[9], projectionBuffer[10], projectionBuffer[11]), Row3 = new Vector4(projectionBuffer[12], projectionBuffer[13], projectionBuffer[14], projectionBuffer[15]) }; var rotation = MakeInterfaceRotationRadians(orientation); var matrixRotated = CreateMatrixFromRotation(rotation, 0, 0, 1); var newMatrix = matrix * matrixRotated; SCNMatrix4 poseMatrix = new SCNMatrix4(newMatrix.Row0, newMatrix.Row1, newMatrix.Row2, newMatrix.Row3); return(poseMatrix); }
public void Elements() { var matrix = new SCNMatrix4( 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44); Assert.AreEqual((pfloat)11, matrix.M11, "M11"); Assert.AreEqual((pfloat)12, matrix.M12, "M12"); Assert.AreEqual((pfloat)13, matrix.M13, "M13"); Assert.AreEqual((pfloat)14, matrix.M14, "M14"); Assert.AreEqual((pfloat)21, matrix.M21, "M21"); Assert.AreEqual((pfloat)22, matrix.M22, "M22"); Assert.AreEqual((pfloat)23, matrix.M23, "M23"); Assert.AreEqual((pfloat)24, matrix.M24, "M24"); Assert.AreEqual((pfloat)31, matrix.M31, "M31"); Assert.AreEqual((pfloat)32, matrix.M32, "M32"); Assert.AreEqual((pfloat)33, matrix.M33, "M33"); Assert.AreEqual((pfloat)34, matrix.M34, "M34"); Assert.AreEqual((pfloat)41, matrix.M41, "M41"); Assert.AreEqual((pfloat)42, matrix.M42, "M42"); Assert.AreEqual((pfloat)43, matrix.M43, "M43"); Assert.AreEqual((pfloat)44, matrix.M44, "M44"); }
public void Constructor_CATransform3d() { var transform = new CATransform3D() { M11 = 11, M12 = 12, M13 = 13, M14 = 14, M21 = 21, M22 = 22, M23 = 23, M24 = 24, M31 = 31, M32 = 32, M33 = 33, M34 = 34, M41 = 41, M42 = 42, M43 = 43, M44 = 44, }; var matrix = new SCNMatrix4(transform); AssertEqual(matrix, "Constructor", 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44); }
nfloat GetGroundHeight(SCNMatrix4 matrix) { SCNVector3 start = new SCNVector3(matrix.M41, matrix.M42 + 1000, matrix.M43); SCNVector3 end = new SCNVector3(matrix.M41, matrix.M42 - 3000, matrix.M43); var options = NSDictionary.FromObjectsAndKeys(new NSObject[] { new NSNumber(GameCollisionCategory.Ground | GameCollisionCategory.Lava), (NSString)"closest" }, new NSObject[] { SCNPhysicsTestKeys.CollisionBitMaskKey, SCNPhysicsTestKeys.SearchModeKey }); SCNHitTestResult[] hits = GameSimulation.Sim.PhysicsWorld.RayTestWithSegmentFromPoint(start, end, options); if (hits == null || hits.Length == 0) { return(0); } foreach (SCNHitTestResult result in hits) { if (result.Node.PhysicsBody.CategoryBitMask != (GameCollisionCategory.Ground | GameCollisionCategory.Lava)) { return(result.WorldCoordinates.Y); } } return(0); }
public void Static_Invert() { var a = new SCNMatrix4( new SCNVector4(11, 12, 13, 14), new SCNVector4(21, 22, 23, 24), new SCNVector4(31, 32, 33, 34), new SCNVector4(41, 42, 43, 44)); var ex = Assert.Throws <InvalidOperationException> (() => SCNMatrix4.Invert(a), "Singular matrix"); Assert.That(ex.Message, Does.Contain("Matrix is singular and cannot be inverted"), "Singular matrix message"); a = new SCNMatrix4( 3, 5, 8, 9, 5, 3, 5, 8, 9, 6, 4, 2, 4, 6, 9, 8); var matrix = SCNMatrix4.Invert(a); AssertEqual(matrix, "Invert", (pfloat)(-0.6181818181818182), (pfloat)(0.3151515151515151), (pfloat)(-0.030303030303030304), (pfloat)(0.3878787878787879), (pfloat)(1.6363636363636365), (pfloat)(-0.696969696969697), (pfloat)(0.3939393939393939), (pfloat)(-1.2424242424242424), (pfloat)(-1.3818181818181818), (pfloat)(0.3515151515151515), (pfloat)(-0.30303030303030304), (pfloat)(1.2787878787878788), (pfloat)(0.6363636363636364), (pfloat)(-0.030303030303030304), (pfloat)(0.06060606060606061), (pfloat)(-0.5757575757575758)); }
private void HandleTap(UIGestureRecognizer gestureRecognize) { // Get current frame var currentFrame = SceneView.Session.CurrentFrame; if (currentFrame == null) { return; } // Create an image plane using a snapshot of the view var imagePlane = SCNPlane.Create(SceneView.Bounds.Width / 6000, SceneView.Bounds.Height / 6000); imagePlane.FirstMaterial.Diffuse.Contents = SceneView.Snapshot(); imagePlane.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // Create a plane node and add it to the scene var planeNode = SCNNode.FromGeometry(imagePlane); SceneView.Scene.RootNode.AddChildNode(planeNode); // Set transform of node to be 10cm in front of the camera var translation = SCNMatrix4.CreateTranslation(0, 0, 0.1f); var cameraTranslation = currentFrame.Camera.Transform.ToSCNMatrix4(); planeNode.Transform = SCNMatrix4.Mult(cameraTranslation, translation); }
void Initialize() { BackgroundColor = NSColor.Black; var root = scene.RootNode; root.AddChildNode(camNode); root.AddChildNode(viewsNode); var backgroundGeom = SCNBox.Create(10000, 10000, 10, 0); backgroundGeom.FirstMaterial = Materials.Plastic(Xyzw(0.8, 1, 0.8, 1), roughness: 0.1).SCNMaterial; var backgroundNode = SCNNode.FromGeometry(backgroundGeom); backgroundNode.Position = Xyz(0, 0, -5.01).ToSCNVector3(); viewsNode.AddChildNode(backgroundNode); AllowsCameraControl = true; scene.Background.ContentImage = new NSImage( NSBundle.MainBundle.PathForResource("environment", "jpg")); scene.Background.ContentsTransform = SCNMatrix4.CreateRotationX((float)(Math.PI / 2)); scene.LightingEnvironment.ContentImage = scene.Background.ContentImage; scene.LightingEnvironment.ContentsTransform = SCNMatrix4.CreateRotationX((float)(Math.PI / 2)); Scene = scene; UpdateCamera(); }
public void Set(float sx, float sy, float ex, float ey, ref Style style) { if (this.x != sx || this.y != sy || this.width != ex || this.height != ey) { //Console.WriteLine ($"({this.sx} == {sx} && {this.sy} == {sy} && {this.ex} == {ex} && {this.ey == ey})"); this.x = sx; this.y = sy; this.width = ex; this.height = ey; Transform = SCNMatrix4.Scale(width / 20, 1, height / 20) * SCNMatrix4.CreateRotationX((float)(Math.PI / 2)) * SCNMatrix4.CreateTranslation(x + width / 2, y + height / 2, 0) * style.Transform ; } if (ColorChanged(ref style)) { this.style.Color = style.Color; if (Geometry is SCNGeometry g) { g.FirstMaterial = GetNativeMaterial(style.Color); } } }
public void Set(float x, float y, float width, float height, float radius, ref Style style) { if (this.x != x || this.y != y || this.width != width || this.height != height || this.radius != radius) { //Console.WriteLine ($"({this.sx} == {sx} && {this.sy} == {sy} && {this.ex} == {ex} && {this.ey == ey})"); this.x = x; this.y = y; this.width = width; this.height = height; this.radius = radius; //Console.WriteLine (style.Transform); var g = SCNBox.Create(this.width, this.height, radius * 2, radius); g.FirstMaterial = GetNativeMaterial(style.Color); Geometry = g; base.Transform = SCNMatrix4.CreateTranslation(this.x + this.width / 2, this.y + this.height / 2, 0) * style.Transform ; } if (ColorChanged(ref style)) { this.style.Color = style.Color; if (Geometry is SCNGeometry g) { g.FirstMaterial = GetNativeMaterial(style.Color); } } }
public static void Center(this SCNNode self) { SCNVector3 min = SCNVector3.Zero, max = SCNVector3.Zero; self.GetBoundingBox(ref min, ref max); self.Pivot = SCNMatrix4.CreateTranslation(min.X + (self.Width() * 0.5F), min.Y + (self.Height() * 0.5F), 0); }
void CollectFlower(SCNNode node) { if (node.ParentNode == null) { return; } SCNNode soundEmitter = SCNNode.Create(); soundEmitter.Position = node.Position; node.ParentNode.AddChildNode(soundEmitter); soundEmitter.RunAction(SCNAction.Sequence(new [] { SCNAction.PlayAudioSource(collectFlowerSound, true), SCNAction.RemoveFromParentNode() })); node.RemoveFromParentNode(); // Check if game is complete. bool gameComplete = GameView.DidCollectAFlower(); // Edit some particles. SCNMatrix4 particlePosition = soundEmitter.WorldTransform; particlePosition.M42 += 0.1f; GameView.Scene.AddParticleSystem(collectParticles, particlePosition); if (gameComplete) { ShowEndScreen(); } }
void PlaceAnchorNode(SCNNode node, ARPlaneAnchor anchor) { var plane = SCNPlane.Create(anchor.Extent.X, anchor.Extent.Z); plane.FirstMaterial.Diffuse.Contents = UIColor.LightGray; var planeNode = SCNNode.FromGeometry(plane); //Locate the plane at the position of the anchor planeNode.Position = new SCNVector3(anchor.Extent.X, 0.0f, anchor.Extent.Z); //Rotate it to lie flat planeNode.Transform = SCNMatrix4.CreateRotationX((float)(Math.PI / 2.0)); node.AddChildNode(planeNode); //Mark the anchor with a small red box var box = new SCNBox { Height = 0.18f, Width = 0.18f, Length = 0.18f }; box.FirstMaterial.Diffuse.ContentColor = UIColor.Red; var anchorNode = new SCNNode { Position = new SCNVector3(0, 0, 0), Geometry = box }; planeNode.AddChildNode(anchorNode); }
public virtual SCNNode CreateARPlaneNode(ARPlaneAnchor anchor, UIColor color) { Console.WriteLine($"ADD: {anchor.Alignment}, {anchor.Extent}"); var material = new SCNMaterial(); material.Diffuse.Contents = color; var geometry = new SCNPlane { Width = anchor.Extent.X, Height = anchor.Extent.Z, Materials = new[] { material, material, material, material }, }; var rotation = SCNMatrix4.Identity; SCNMatrix4.CreateRotationX((float)-Math.PI / 2.0f, out rotation); var planeNode = new SCNNode { Geometry = geometry, Position = new SCNVector3(anchor.Center.X, 0, anchor.Center.Z), Transform = rotation, PhysicsBody = CreatePlanePhysics(geometry) }; return(planeNode); }
void AssertEqual(SCNMatrix4 matrix, string message, pfloat m11, pfloat m12, pfloat m13, pfloat m14, pfloat m21, pfloat m22, pfloat m23, pfloat m24, pfloat m31, pfloat m32, pfloat m33, pfloat m34, pfloat m41, pfloat m42, pfloat m43, pfloat m44 ) { if (CloseEnough(m11, matrix.M11) && CloseEnough(m12, matrix.M12) && CloseEnough(m13, matrix.M13) && CloseEnough(m14, matrix.M14) && CloseEnough(m21, matrix.M21) && CloseEnough(m22, matrix.M22) && CloseEnough(m23, matrix.M23) && CloseEnough(m24, matrix.M24) && CloseEnough(m31, matrix.M31) && CloseEnough(m32, matrix.M32) && CloseEnough(m33, matrix.M33) && CloseEnough(m34, matrix.M34) && CloseEnough(m41, matrix.M41) && CloseEnough(m42, matrix.M42) && CloseEnough(m43, matrix.M43) && CloseEnough(m44, matrix.M44)) { return; } var actualString = matrix.ToString(); var row1 = $"({m11}, {m12}, {m13}, {m14})"; var row2 = $"({m21}, {m22}, {m23}, {m24})"; var row3 = $"({m31}, {m32}, {m33}, {m34})"; var row4 = $"({m41}, {m42}, {m43}, {m44})"; var expectedString = $"{row1}\n{row2}\n{row3}\n{row4}"; Assert.Fail($"Expected matrix:\n{expectedString}\nActual matrix:\n{actualString}\n{message}"); }
public static SCNMatrix4 TranslateWithVector(this SCNMatrix4 matrix, SCNVector3 vector) { matrix.M41 += matrix.M11 * vector.X + matrix.M21 * vector.Y + matrix.M31 * vector.Z; matrix.M42 += matrix.M12 * vector.X + matrix.M22 * vector.Y + matrix.M32 * vector.Z; matrix.M43 += matrix.M13 * vector.X + matrix.M23 * vector.Y + matrix.M33 * vector.Z; return(matrix); }
int Building(float width, float length, float height, float posx, float posy, SCNScene scene, Random rnd) { var boxNode = new SCNNode() { Geometry = new SCNBox { Width = width, Height = height, Length = length, ChamferRadius = 0.02f }, Position = new SCNVector3(posx, height / 2.0f, posy) }; scene.RootNode.AddChildNode(boxNode); var buildings = new[] { "Content/building1.jpg", "Content/building2.jpg", "Content/building3.jpg" }; var material = new SCNMaterial(); material.Diffuse.Contents = UIImage.FromFile(buildings [rnd.Next(buildings.Length)]); material.Diffuse.ContentsTransform = SCNMatrix4.Scale(new SCNVector3(width, height, 1.0f)); material.Diffuse.WrapS = SCNWrapMode.Repeat; material.Diffuse.WrapT = SCNWrapMode.Repeat; material.Diffuse.MipFilter = SCNFilterMode.Linear; material.Diffuse.MagnificationFilter = SCNFilterMode.Linear; material.Specular.Contents = UIColor.Gray; material.LocksAmbientWithDiffuse = true; boxNode.Geometry.FirstMaterial = material; return(0); }
public static SCNMatrix4 SetPosition(this SCNMatrix4 matrix, SCNVector3 vector) { matrix.M41 = vector.X; matrix.M42 = vector.Y; matrix.M43 = vector.Z; return(matrix); }
SCNVector3 MakeThrowPosition(SCNMatrix4 transform) { var force = new Vector3(0.0f, 0.0f, -0.3f); var rotation = new SCNVector3(transform.M31, transform.M32, transform.M33); var rotatedForce = SCNVector3.Multiply(rotation, force) + new Vector3(0.0f, 0.1f, 0.0f); return(new SCNVector3(rotatedForce)); }
/// <summary>Transform a Position by the given Matrix</summary> /// <param name="pos">The position to transform</param> /// <param name="mat">The desired transformation</param> /// <returns>The transformed position</returns> public static SCNVector3 TransformPosition(SCNVector3 pos, SCNMatrix4 mat) { SCNVector3 p; p.X = SCNVector3.Dot(pos, new SCNVector3(mat.Column0)) + mat.Row3.X; p.Y = SCNVector3.Dot(pos, new SCNVector3(mat.Column1)) + mat.Row3.Y; p.Z = SCNVector3.Dot(pos, new SCNVector3(mat.Column2)) + mat.Row3.Z; return(p); }
public void CreateOrthographic_Out() { SCNMatrix4.CreateOrthographic(1, 2, 3, 4, out var matrix); AssertEqual(matrix, "CreateOrthographic", 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, -2, 0, 0, 0, -7, 1); }
/// <summary>Transform a SCNVector3 by the given Matrix, and project the resulting SCNVector4 back to a SCNVector3</summary> /// <param name="vec">The vector to transform</param> /// <param name="mat">The desired transformation</param> /// <param name="result">The transformed vector</param> public static void TransformPerspective(ref SCNVector3 vec, ref SCNMatrix4 mat, out SCNVector3 result) { SCNVector4 h; SCNVector3.Transform(ref vec, ref mat, out h); result.X = h.X / h.W; result.Y = h.Y / h.W; result.Z = h.Z / h.W; }
/// <summary>Transform a direction vector by the given Matrix /// Assumes the matrix has a bottom row of (0,0,0,1), that is the translation part is ignored. /// </summary> /// <param name="vec">The vector to transform</param> /// <param name="mat">The desired transformation</param> /// <returns>The transformed vector</returns> public static SCNVector3 TransformVector(SCNVector3 vec, SCNMatrix4 mat) { SCNVector3 v; v.X = SCNVector3.Dot(vec, new SCNVector3(mat.Column0)); v.Y = SCNVector3.Dot(vec, new SCNVector3(mat.Column1)); v.Z = SCNVector3.Dot(vec, new SCNVector3(mat.Column2)); return(v); }
public void CreatePerspectiveOffCenter_Out() { SCNMatrix4.CreatePerspectiveOffCenter(1, 2, 3, 4, 5, 6, out var matrix); AssertEqual(matrix, "CreatePerspectiveOffCenter", 10, 0, 0, 0, 0, 10, 0, 0, 3, 7, -11, -1, 0, 0, -60, 0); }
public void CreateOrthographicOffCenter_Out() { SCNMatrix4.CreateOrthographicOffCenter(1, 2, 3, 4, 5, 6, out var matrix); AssertEqual(matrix, "CreateOrthographicOffCenter", 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, -2, 0, -3, -7, -11, 1); }
public void CreateRotationZ_Out() { SCNMatrix4.CreateRotationZ((pfloat)(Math.PI / 3), out var matrix); AssertEqual(matrix, "CreateRotationZ", OhPointFive, SqrtThreeHalved, 0, 0, -SqrtThreeHalved, OhPointFive, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
public void CreateTranslation_Out() { SCNMatrix4.CreateTranslation(1, 2, 3, out var matrix); AssertEqual(matrix, "CreateTranslation", 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1); }
public void CreateFromAxisAngle_double_Out() { SCNMatrix4.CreateFromAxisAngle(new Vector3d(2, 2, 2), (double)(Math.PI / 3), out var matrix); AssertEqual(matrix, "CreateFromAxisAngle", TwoThirds, TwoThirds, -OneThird, 0, -OneThird, TwoThirds, TwoThirds, 0, TwoThirds, -OneThird, TwoThirds, 0, 0, 0, 0, 1); }
public void CreateFromAxisAngle_pfloat_Out() { SCNMatrix4.CreateFromAxisAngle(new SCNVector3(2, 2, 2), (pfloat)(Math.PI / 3), out var matrix); AssertEqual(matrix, "CreateFromAxisAngle", TwoThirds, TwoThirds, -OneThird, 0, -OneThird, TwoThirds, TwoThirds, 0, TwoThirds, -OneThird, TwoThirds, 0, 0, 0, 0, 1); }
public void CreatePerspectiveFieldOfView_Out() { SCNMatrix4.CreatePerspectiveFieldOfView((pfloat)(Math.PI / 3), 2, 3, 4, out var matrix); AssertEqual(matrix, "CreatePerspectiveFieldOfView", SqrtThreeHalved, 0, 0, 0, 0, SqrtThree, 0, 0, 0, 0, -7, -1, 0, 0, -24, 0); }
public static SCNSkinner Create(SCNGeometry baseGeometry, SCNNode [] bones, SCNMatrix4 [] boneInverseBindTransforms, SCNGeometrySource boneWeights, SCNGeometrySource boneIndices) { return _Create ( baseGeometry, bones, ToNSArray (boneInverseBindTransforms), boneWeights, boneIndices ); }
static SCNMatrix4[] FromNSArray(NSArray nsa) { if (nsa == null) return null; var count = nsa.Count; var ret = new SCNMatrix4 [count]; for (nuint i = 0; i < count; i++) ret [i] = Runtime.GetNSObject<NSValue> (nsa.ValueAt (i)).SCNMatrix4Value; return ret; }
static NSArray ToNSArray(SCNMatrix4 [] items) { if (items == null) return new NSArray (true); var count = items.Length; var buf = Marshal.AllocHGlobal ((IntPtr)(count * IntPtr.Size)); for (nint i = 0; i < count; i++) { var item = NSValue.FromSCNMatrix4 (items [i]); var h = item == null ? NSNull.Null.Handle : item.Handle; Marshal.WriteIntPtr (buf, (int)(i * IntPtr.Size), h); } var nsa = new NSArray (NSArray.FromObjects (buf, count)); Marshal.FreeHGlobal (buf); return nsa; }
public static SCNMatrix4 Interpolate (SCNMatrix4 scnm0, SCNMatrix4 scnmf, nfloat factor) { SCNVector4 p0 = scnm0.Row3; SCNVector4 pf = scnmf.Row3; var q0 = scnm0.ToQuaternion (); var qf = scnmf.ToQuaternion (); SCNVector4 pTmp = Lerp (p0, pf, factor); SCNQuaternion qTmp = SCNQuaternion.Slerp (q0, qf, (float)factor); SCNMatrix4 rTmp = qTmp.ToMatrix4 (); SCNMatrix4 transform = new SCNMatrix4 ( rTmp.M11, rTmp.M12, rTmp.M13, 0.0f, rTmp.M21, rTmp.M22, rTmp.M23, 0.0f, rTmp.M31, rTmp.M32, rTmp.M33, 0.0f, pTmp.X, pTmp.Y, pTmp.Z, 1.0f ); return transform; }
nfloat GetGroundHeight (SCNMatrix4 matrix) { SCNVector3 start = new SCNVector3 (matrix.M41, matrix.M42 + 1000, matrix.M43); SCNVector3 end = new SCNVector3 (matrix.M41, matrix.M42 - 3000, matrix.M43); var options = NSDictionary.FromObjectsAndKeys (new NSObject[] { new NSNumber (GameCollisionCategory.Ground | GameCollisionCategory.Lava), (NSString)"closest" }, new NSObject[] { SCNPhysicsTestKeys.CollisionBitMaskKey, SCNPhysicsTestKeys.SearchModeKey }); SCNHitTestResult[] hits = GameSimulation.Sim.PhysicsWorld.RayTestWithSegmentFromPoint (start, end, options); if (hits == null || hits.Length == 0) return 0; foreach (SCNHitTestResult result in hits) { if (result.Node.PhysicsBody.CategoryBitMask != (GameCollisionCategory.Ground | GameCollisionCategory.Lava)) return result.WorldCoordinates.Y; } return 0; }
// switch to the next introduction step void NextIntroductionStep () { IntroductionStep++; SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; SCNTransaction.SetCompletionBlock (() => { if (IntroductionStep >= 4) { //We did finish introduction step 4 //free some memory if (ShipHandle != null) ShipHandle.RemoveFromParentNode (); ShipHandle = null; ShipPivot = null; ShipNode = null; } if (IntroductionStep == 0) { //We did finish the whole introduction IntroNodeGroup.RemoveFromParentNode (); IntroNodeGroup = null; Next (); } }); if (IntroductionStep == 2) { var popTime = new DispatchTime (DispatchTime.Now, (long)(1 * NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter (popTime, () => { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1.0f; ShipNode.Opacity = 1.0f; ShipNode.RunAction (SCNAction.RepeatActionForever (SCNAction.RotateBy (0, NMath.PI, 0, 1.0))); SCNTransaction.Commit (); }); } if (IntroductionStep == 3) { //animate ship ShipNode.RemoveAllActions (); ShipNode.Rotation = new SCNVector4 (0, 0, 1, (float)(Math.PI / 4) * 0.5f); //make spotlight relative to the ship var newPosition = new SCNVector3 (50, 100, 0); var oldTransform = ShipPivot.ConvertTransformFromNode (SCNMatrix4.Identity, SpotLightNode); OldSpotTransform = SpotLightNode.Transform; SpotLightNode.RemoveFromParentNode (); SpotLightNode.Transform = oldTransform; ShipPivot.AddChildNode (SpotLightNode); SpotLightNode.Position = newPosition; // will animate implicitly SpotLightNode.EulerAngles = new SCNVector3 (-(float)Math.PI / 2, 0, 0); SpotLightNode.Light.SpotOuterAngle = 120; var action = SCNAction.Sequence (new [] { SCNAction.Wait (1), SCNAction.RepeatActionForever (SCNAction.RotateBy (0, NMath.PI, 0, 2)) }); ShipPivot.RunAction (action); var animation = CABasicAnimation.FromKeyPath ("position.x"); animation.From = new NSNumber (-50); animation.To = new NSNumber (50); animation.TimingFunction = CAMediaTimingFunction.FromName (CAMediaTimingFunction.EaseInEaseOut); animation.AutoReverses = true; animation.Duration = 2; animation.RepeatCount = float.MaxValue; animation.TimeOffset = animation.Duration * 0.5f; ShipPivot.ParentNode.AddAnimation (animation, null); var emitter = ShipNode.FindChildNode ("emitter", true); var ps = SCNParticleSystem.Create ("reactor.scnp", "assets.scnassets/particles"); ps.ParticleImage = new NSString ("assets.scnassets/textures/tspark.png"); emitter.AddParticleSystem (ps); ShipHandle.Position = new SCNVector3 (ShipHandle.Position.X, ShipHandle.Position.Y, ShipHandle.Position.Z - TEXT_Z_SPACING - 50); } if (IntroductionStep == 4) { //restore spot light config SpotLightNode.Light.SpotOuterAngle = 70; var oldTransform = SpotLightParentNode.ConvertTransformFromNode (SCNMatrix4.Identity, SpotLightNode); SpotLightNode.RemoveFromParentNode (); SpotLightNode.Transform = oldTransform; SpotLightParentNode.AddChildNode (SpotLightNode); SpotLightNode.Transform = OldSpotTransform; CameraNode.Position = new SCNVector3 (CameraNode.Position.X, CameraNode.Position.Y, CameraNode.Position.Z - TEXT_Z_SPACING); } if (IntroductionStep == 5) { IntroductionStep = 0;//introduction is over // jiterring is now useless since the screen will never be static again. var scnView = (SCNView)this.View; scnView.JitteringEnabled = false; AmbientLightNode.Light.Color = SKColorHelper.FromCommonWhiteAlpha (0.3f, 1.0f); SpotLightNode.Position = new SCNVector3 (0, 0, 0); SpotLightNode.EulerAngles = new SCNVector3 (-(float)(Math.PI / 4), 0, 0); CameraNode.Position = new SCNVector3 (0, 0, 120); CameraNode.EulerAngles = new SCNVector3 (0, 0, 0); } else { CameraNode.Position = new SCNVector3 (CameraNode.Position.X, CameraNode.Position.Y, CameraNode.Position.Z - TEXT_Z_SPACING); } SCNTransaction.Commit (); }
void HandlePan (WKPanGestureRecognizer panGesture) { if (!gameNodes.HasValue || !gameStarted) return; var gNodes = gameNodes.Value; var location = panGesture.LocationInObject; var bounds = panGesture.ObjectBounds; // Compute the projection of the interface point to the virtual trackball. var sphereLocation = SphereProjection (location, bounds); switch (panGesture.State) { case WKGestureRecognizerState.Began: // Record initial states. initialSphereLocation = sphereLocation; initialObject3DRotation = gNodes.Object.Transform; break; case WKGestureRecognizerState.Cancelled: case WKGestureRecognizerState.Ended: case WKGestureRecognizerState.Changed: // Compute the rotation and apply to the object. var currentRotation = RotationFromPoint (initialSphereLocation, sphereLocation); gNodes.Object.Transform = SCNMatrix4.Mult (initialObject3DRotation, currentRotation); break; default: Console.WriteLine ($"Unhandled gesture state: {panGesture.State}"); throw new InvalidProgramException (); } // End the game if the object has the initial orientation. if (panGesture.State == WKGestureRecognizerState.Ended) EndGameOnCorrectOrientation (); }