private void AddPrimitive(SCNGeometry geometry, float yPos, CABasicAnimation rotationAnimation, SCNMaterial sharedMaterial) { var xPos = 13.0f * (float)Math.Sin((float)Math.PI * 2 * PrimitiveIndex / 9.0f); var zPos = 13.0f * (float)Math.Cos((float)Math.PI * 2 * PrimitiveIndex / 9.0f); var node = SCNNode.Create(); node.Position = new SCNVector3(xPos, yPos, zPos); node.Geometry = geometry; node.Geometry.FirstMaterial = sharedMaterial; CarouselNode.AddChildNode(node); PrimitiveIndex++; rotationAnimation.TimeOffset = -PrimitiveIndex; node.AddAnimation(rotationAnimation, new NSString("rotationAnimation")); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: break; case 1: // Set the slide's subtitle and display the primitves TextManager.SetSubtitle("Built-in parametric primitives"); PresentPrimitives(); break; case 2: // Hide the carousel and illustrate SCNText TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5f; SCNTransaction.SetCompletionBlock(() => { CarouselNode.RemoveFromParentNode(); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; PresentTextNode(); TextNode.Opacity = 1.0f; SCNTransaction.Commit(); }); CarouselNode.Opacity = 0.0f; SCNTransaction.Commit(); TextManager.SetSubtitle("Built-in 3D text"); TextManager.AddBulletAtLevel("SCNText", 0); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); break; case 3: // Hide the 3D text and introduce SCNShape SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5f; SCNTransaction.SetCompletionBlock(() => { if (TextNode != null) { TextNode.RemoveFromParentNode(); } presentationViewController.ShowsNewInSceneKitBadge(true); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.SetSubtitle("3D Shapes"); TextManager.AddBulletAtLevel("SCNShape", 0); TextManager.AddBulletAtLevel("Initializes with a NSBezierPath", 0); TextManager.AddBulletAtLevel("Extrusion and chamfer", 0); TextManager.AddCode("#aNode.Geometry = SCNShape.#Create# (aBezierPath, 10);#"); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); }); if (TextNode != null) { TextNode.Opacity = 0.0f; } SCNTransaction.Commit(); break; case 4: TextManager.FadeOutText(SlideTextManager.TextType.Bullet); TextManager.FadeOutText(SlideTextManager.TextType.Code); // Illustrate SCNShape, show the floor ouline Level2Node = Level2(); Level2OutlineNode = Level2Outline(); Level2Node.Position = Level2OutlineNode.Position = new SCNVector3(-11, 0, -5); Level2Node.Rotation = Level2OutlineNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); Level2Node.Opacity = Level2OutlineNode.Opacity = 0.0f; Level2Node.Scale = new SCNVector3(0.03f, 0.03f, 0); Level2OutlineNode.Scale = new SCNVector3(0.03f, 0.03f, 0.05f); GroundNode.AddChildNode(Level2OutlineNode); GroundNode.AddChildNode(Level2Node); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; Level2OutlineNode.Opacity = 1.0f; SCNTransaction.Commit(); break; case 5: presentationViewController.ShowsNewInSceneKitBadge(false); // Show the extruded floor SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; Level2Node.Opacity = 1.0f; Level2Node.Scale = new SCNVector3(0.03f, 0.03f, 0.05f); SCNTransaction.SetCompletionBlock(() => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.5f; // move the camera a little higher presentationViewController.CameraNode.Position = new SCNVector3(0, 7, -3); presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.7f); SCNTransaction.Commit(); }); SCNTransaction.Commit(); break; case 6: TextManager.FadeOutText(SlideTextManager.TextType.Subtitle); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); // Example of a custom geometry (Möbius strip) TextManager.SetSubtitle("Custom geometry"); TextManager.AddBulletAtLevel("Custom vertices, normals and texture coordinates", 0); TextManager.AddBulletAtLevel("SCNGeometry", 0); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // move the camera back to its previous position presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 0); presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)(Math.PI / 180.0)); Level2Node.Opacity = 0.0f; Level2OutlineNode.Opacity = 0.0f; SCNTransaction.Commit(); break; } }
// Create a carousel of 3D primitives private void PresentPrimitives() { // Create the carousel node. It will host all the primitives as child nodes. CarouselNode = SCNNode.Create(); CarouselNode.Position = new SCNVector3(0, 0.1f, -5); CarouselNode.Scale = new SCNVector3(0, 0, 0); // start infinitely small ContentNode.AddChildNode(CarouselNode); // Animate the scale to achieve a "grow" effect SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; CarouselNode.Scale = new SCNVector3(1, 1, 1); SCNTransaction.Commit(); // Rotate the carousel forever var rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 40.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)Math.PI * 2)); CarouselNode.AddAnimation(rotationAnimation, new NSString("rotationAnimation")); // A material shared by all the primitives var sharedMaterial = SCNMaterial.Create(); sharedMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap", "jpg")); sharedMaterial.Reflective.Intensity = 0.2f; sharedMaterial.DoubleSided = true; PrimitiveIndex = 0; // SCNBox var box = SCNBox.Create(5.0f, 5.0f, 5.0f, 5.0f * 0.05f); box.WidthSegmentCount = 4; box.HeightSegmentCount = 4; box.LengthSegmentCount = 4; box.ChamferSegmentCount = 4; AddPrimitive(box, 5.0f / 2, rotationAnimation, sharedMaterial); // SCNPyramid var pyramid = SCNPyramid.Create(5.0f * 0.8f, 5.0f, 5.0f * 0.8f); pyramid.WidthSegmentCount = 4; pyramid.HeightSegmentCount = 10; pyramid.LengthSegmentCount = 4; AddPrimitive(pyramid, 0, rotationAnimation, sharedMaterial); // SCNCone var cone = SCNCone.Create(0, 5.0f / 2, 5.0f); cone.RadialSegmentCount = 20; cone.HeightSegmentCount = 4; AddPrimitive(cone, 5.0f / 2, rotationAnimation, sharedMaterial); // SCNTube var tube = SCNTube.Create(5.0f * 0.25f, 5.0f * 0.5f, 5.0f); tube.HeightSegmentCount = 5; tube.RadialSegmentCount = 40; AddPrimitive(tube, 5.0f / 2, rotationAnimation, sharedMaterial); // SCNCapsule var capsule = SCNCapsule.Create(5.0f * 0.4f, 5.0f * 1.4f); capsule.HeightSegmentCount = 5; capsule.RadialSegmentCount = 20; AddPrimitive(capsule, 5.0f * 0.7f, rotationAnimation, sharedMaterial); // SCNCylinder var cylinder = SCNCylinder.Create(5.0f * 0.5f, 5.0f); cylinder.HeightSegmentCount = 5; cylinder.RadialSegmentCount = 40; AddPrimitive(cylinder, 5.0f / 2, rotationAnimation, sharedMaterial); // SCNSphere var sphere = SCNSphere.Create(5.0f * 0.5f); sphere.SegmentCount = 20; AddPrimitive(sphere, 5.0f / 2, rotationAnimation, sharedMaterial); // SCNTorus var torus = SCNTorus.Create(5.0f * 0.5f, 5.0f * 0.25f); torus.RingSegmentCount = 40; torus.PipeSegmentCount = 20; AddPrimitive(torus, 5.0f / 4, rotationAnimation, sharedMaterial); // SCNPlane var plane = SCNPlane.Create(5.0f, 5.0f); plane.WidthSegmentCount = 5; plane.HeightSegmentCount = 5; plane.CornerRadius = 5.0f * 0.1f; AddPrimitive(plane, 5.0f / 2, rotationAnimation, sharedMaterial); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: TextManager.SetSubtitle("Built-in parametric primitives"); break; case 1: PresentPrimitives(); break; case 2: // Hide the carousel and illustrate SCNText TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.SetCompletionBlock(() => { if (CarouselNode != null) { CarouselNode.RemoveFromParentNode(); } }); PresentTextNode(); TextNode.Opacity = 1.0f; if (CarouselNode != null) { CarouselNode.Position = new SCNVector3(0, CarouselNode.Position.Y, -50); CarouselNode.Opacity = 0.0f; } SCNTransaction.Commit(); TextManager.SetSubtitle("Built-in 3D text"); TextManager.AddBulletAtLevel("SCNText", 0); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); break; case 3: //Show bezier path var star = StarPath(3, 6); var shape = SCNShape.Create(star, 1); shape.ChamferRadius = 0.2f; shape.ChamferProfile = OutlineChamferProfilePath(); shape.ChamferMode = SCNChamferMode.Front; // that way only the outline of the model will be visible var outlineMaterial = SCNMaterial.Create(); outlineMaterial.Ambient.Contents = outlineMaterial.Diffuse.Contents = outlineMaterial.Specular.Contents = NSColor.Black; outlineMaterial.Emission.Contents = NSColor.White; outlineMaterial.DoubleSided = true; var tranparentMaterial = SCNMaterial.Create(); tranparentMaterial.Transparency = 0.0f; shape.Materials = new SCNMaterial[] { tranparentMaterial, tranparentMaterial, tranparentMaterial, outlineMaterial, outlineMaterial }; StarOutline = SCNNode.Create(); StarOutline.Geometry = shape; StarOutline.Position = new SCNVector3(0, 5, 30); StarOutline.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(0, (float)Math.PI * 2, 0, 10.0))); GroundNode.AddChildNode(StarOutline); // Hide the 3D text and introduce SCNShape SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; SCNTransaction.SetCompletionBlock(() => { TextNode.RemoveFromParentNode(); }); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.SetSubtitle("3D Shapes"); TextManager.AddBulletAtLevel("SCNShape", 0); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); StarOutline.Position = new SCNVector3(0, 5, 0); TextNode.Position = new SCNVector3(TextNode.Position.X, TextNode.Position.Y, -30); SCNTransaction.Commit(); break; case 4: star = StarPath(3, 6); shape = SCNShape.Create(star, 0); shape.ChamferRadius = 0.1f; StarNode = SCNNode.Create(); StarNode.Geometry = shape; var material = SCNMaterial.Create(); material.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/color_envmap", "png")); material.Diffuse.Contents = NSColor.Black; StarNode.Geometry.Materials = new SCNMaterial[] { material }; StarNode.Position = new SCNVector3(0, 5, 0); StarNode.Pivot = SCNMatrix4.CreateTranslation(0, 0, -0.5f); StarOutline.ParentNode.AddChildNode(StarNode); StarNode.EulerAngles = StarOutline.EulerAngles; StarNode.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(0, (float)Math.PI * 2, 0, 10.0))); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.SetCompletionBlock(() => { StarOutline.RemoveFromParentNode(); }); shape.ExtrusionDepth = 1; StarOutline.Opacity = 0.0f; SCNTransaction.Commit(); break; case 5: //OpenSubdiv TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.SetSubtitle("Subdivisions"); TextManager.AddBulletAtLevel("OpenSubdiv", 0); TextManager.AddCode("#aGeometry.#SubdivisionLevel# = anInteger;#"); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); //add boxes var boxesNode = SCNNode.Create(); var level0 = Utils.SCAddChildNode(boxesNode, "rccarBody_LP", "Scenes.scnassets/car/car_lowpoly", 10); level0.Position = new SCNVector3(-6, level0.Position.Y, 0); var label = Utils.SCBoxNode("0", new CGRect(0, 0, 40, 40), NSColor.Orange, 20.0f, true); label.Position = new SCNVector3(0, -35, 10); label.Scale = new SCNVector3(0.3f, 0.3f, 0.001f); level0.AddChildNode(label); boxesNode.Position = new SCNVector3(0, 0, 30); var level1 = level0.Clone(); /*foreach (var child in level1.ChildNodes) { * if (child.Name != "engine_LP") { * child.Geometry = (SCNGeometry)child.Geometry.Copy (); * child.Geometry.SubdivisionLevel = 3; * } * }*/ level1.Position = new SCNVector3(6, level1.Position.Y, 0); boxesNode.AddChildNode(level1); label = Utils.SCBoxNode("2", new CGRect(0, 0, 40, 40), NSColor.Orange, 20.0f, true); label.Position = new SCNVector3(0, -35, 10); label.Scale = new SCNVector3(0.3f, 0.3f, 0.001f); level1.AddChildNode(label); level0.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy((float)Math.PI * 2, new SCNVector3(0, 1, 0), 45.0))); level1.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy((float)Math.PI * 2, new SCNVector3(0, 1, 0), 45.0))); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; SCNTransaction.SetCompletionBlock(() => { StarNode.RemoveFromParentNode(); }); // move the camera back to its previous position presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 0); presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)Math.PI / 180.0f); StarNode.Position = new SCNVector3(StarNode.Position.X, StarNode.Position.Y, StarNode.Position.Z - 30); StarOutline.Position = new SCNVector3(StarOutline.Position.X, StarOutline.Position.Y, StarOutline.Position.Z - 30); GroundNode.AddChildNode(boxesNode); //move boxes in boxesNode.Position = new SCNVector3(0, 0, 3.5f); SCNTransaction.Commit(); break; } }