public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Fog"); TextManager.SetSubtitle("SCNScene"); TextManager.AddEmptyLine(); TextManager.AddCode("// set some fog\n\naScene.#fogColor# = aColor;\n\naScene.#fogStartDistance# = 50;\n\naScene.#fogEndDistance# = 100;#"); //add palm trees var palmTree = Utils.SCAddChildNode(GroundNode, "PalmTree", "Scenes.scnassets/palmTree/palm_tree", 15); palmTree.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); palmTree.Position = new SCNVector3(4, -1, 0); palmTree = palmTree.Clone(); GroundNode.AddChildNode(palmTree); palmTree.Position = new SCNVector3(0, -1, 7); palmTree = palmTree.Clone(); GroundNode.AddChildNode(palmTree); palmTree.Position = new SCNVector3(8, -1, 13); palmTree = palmTree.Clone(); GroundNode.AddChildNode(palmTree); palmTree.Position = new SCNVector3(13, -1, -7); palmTree = palmTree.Clone(); GroundNode.AddChildNode(palmTree); palmTree.Position = new SCNVector3(-13, -1, -14); palmTree = palmTree.Clone(); GroundNode.AddChildNode(palmTree); palmTree.Position = new SCNVector3(3, -1, -14); }
void ShowCodeExample(string code, string imageName, string extension) { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; TextManager.FadeOutText(SlideTextManager.TextType.Code); if (code != null) { var codeNode = TextManager.AddCode(code); SCNVector3 min, max; min = new SCNVector3(0, 0, 0); max = new SCNVector3(0, 0, 0); codeNode.GetBoundingBox(ref min, ref max); if (imageName != null) { SCNNode imageNode = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Scenes/earth/" + imageName, extension), 4.0f, false); imageNode.Position = new SCNVector3(max.X + 2.5f, min.Y + 0.2f, 0); codeNode.AddChildNode(imageNode); max.X += 4.0f; } codeNode.Position = new SCNVector3(6 - (min.X + max.X) / 2, 10 - min.Y, 0); } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Set the slide's title and subtile TextManager.SetTitle("Performance"); TextManager.SetSubtitle("Texturing"); // From now on, every text we add will fade in TextManager.FadesIn = true; break; case 1: TextManager.AddBulletAtLevel("Avoid unnecessarily large images", 0); break; case 2: TextManager.AddBulletAtLevel("Lock ambient and diffuse", 0); TextManager.AddCode("#aMaterial.#LocksAmbientWithDiffuse# = true;#"); break; case 3: TextManager.AddBulletAtLevel("Use mipmaps", 0); TextManager.AddCode("#aMaterial.Diffuse.#MipFilter# = #SCNFilterMode.Linear#;#"); break; } }
public override void SetupSlide(PresentationViewController presentationViewController) { // Set the slide's title and subtitle and add some text TextManager.SetTitle("Animations"); TextManager.SetSubtitle("Explicit animations"); TextManager.AddCode("#// Create an animation \n" + "animation = #CABasicAnimation#.FromKeyPath (\"rotation\"); \n\n" + "// Configure the animation \n" + "animation.#Duration# = 2.0f; \n" + "animation.#To# = NSValue.FromVector (new SCNVector4 (0, 1, 0, NMath.PI * 2)); \n" + "animation.#RepeatCount# = float.MaxValue; \n\n" + "// Play the animation \n" + "aNode.#AddAnimation #(animation, \"myAnimation\");#"); // A simple torus that we will animate to illustrate the code AnimatedNode = SCNNode.Create(); AnimatedNode.Position = new SCNVector3(9, 5.7f, 16); // Use an extra node that we can tilt it and cumulate that with the animation var torusNode = SCNNode.Create(); torusNode.Geometry = SCNTorus.Create(4.0f, 1.5f); torusNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI * 0.5f)); torusNode.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Red; torusNode.Geometry.FirstMaterial.Specular.Contents = NSColor.White; torusNode.Geometry.FirstMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap", "jpg")); torusNode.Geometry.FirstMaterial.FresnelExponent = 0.7f; AnimatedNode.AddChildNode(torusNode); ContentNode.AddChildNode(AnimatedNode); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Set the slide's title and subtitle and add some text TextManager.SetTitle("Animations"); TextManager.SetSubtitle("Implicit animations"); TextManager.AddCode("#// Begin a transaction \n" + "#SCNTransaction#.Begin (); \n" + "#SCNTransaction#.AnimationDuration = 2.0f; \n\n" + "// Change properties \n" + "aNode.#Opacity# = 1.0f; \n" + "aNode.#Rotation# = \n" + " new SCNVector4 (0, 1, 0, NMath.PI * 4); \n\n" + "// Commit the transaction \n" + "SCNTransaction.#Commit ()#;#"); // A simple torus that we will animate to illustrate the code AnimatedNode = SCNNode.Create(); AnimatedNode.Position = new SCNVector3(10, 7, 0); // Use an extra node that we can tilt it and cumulate that with the animation var torusNode = SCNNode.Create(); torusNode.Geometry = SCNTorus.Create(4.0f, 1.5f); torusNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI * 0.7f)); torusNode.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Red; torusNode.Geometry.FirstMaterial.Specular.Contents = NSColor.White; torusNode.Geometry.FirstMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap", "jpg")); torusNode.Geometry.FirstMaterial.FresnelExponent = 0.7f; AnimatedNode.AddChildNode(torusNode); ContentNode.AddChildNode(AnimatedNode); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Set the slide's title and subtitle and add some text. TextManager.SetTitle("Performance"); TextManager.SetSubtitle("Flattening"); TextManager.AddBulletAtLevel("Flatten node tree into single node", 0); TextManager.AddBulletAtLevel("Minimize draw calls", 0); TextManager.AddCode("#// Flatten node hierarchy \n" + "var flattenedNode = aNode.#FlattenedClone# ();#"); break; case 1: // Discard the text and show a 2D image. // Animate the image's position when it appears. TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); var imageNode = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/flattening", "png"), 20, false); imageNode.Position = new SCNVector3(0, 4.8f, 16); GroundNode.AddChildNode(imageNode); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; imageNode.Position = new SCNVector3(0, 4.8f, 8); SCNTransaction.Commit(); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: TextManager.SetTitle("Animation Events"); TextManager.AddBulletAtLevel("SCNAnimationEvent", 0); TextManager.AddBulletAtLevel("Smooth transitions", 0); TextManager.AddCode("#var anEvent = #SCNAnimationEvent.Create# (0.2, aBlock); \n" + "anAnimation.#AnimationEvents# = @[anEvent, anotherEvent];#"); var path = NSBundle.MainBundle.PathForResource("Sounds/bossaggro", "wav"); var soundUrl = NSUrl.FromFilename(path); var bossaggro = new NSSound(soundUrl, false); bossaggro.Play(); break; case 1: // Trigger the attack animation HeroSkeletonNode.AddAnimation(Animations [(int)CharacterAnimation.Attack], new NSString("attack")); break; case 2: TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.AddCode("#\n" + "\n" + "\n\n" + "anAnimation.FadeInDuration = #0.0#;\n" + "anAnimation.FadeOutDuration = #0.0#;#"); break; case 3: case 4: Animations[(int)CharacterAnimation.Attack].FadeInDuration = 0; Animations[(int)CharacterAnimation.Attack].FadeOutDuration = 0; // Trigger the attack animation HeroSkeletonNode.AddAnimation(Animations [(int)CharacterAnimation.Attack], new NSString("attack")); break; case 5: TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.AddCode("#\n" + "\n" + "\n\n" + "anAnimation.FadeInDuration = #0.3#;\n" + "anAnimation.FadeOutDuration = #0.3#;#"); break; case 6: case 7: Animations[(int)CharacterAnimation.Attack].FadeInDuration = 0.3f; Animations[(int)CharacterAnimation.Attack].FadeOutDuration = 0.3f; // Trigger the attack animation HeroSkeletonNode.AddAnimation(Animations [(int)CharacterAnimation.Attack], new NSString("attack")); break; } }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Rendering a Scene"); TextManager.AddBulletAtLevel("Assign the scene to the renderer", 0); TextManager.AddBulletAtLevel("Modifications of the scene graph are automatically reflected", 0); TextManager.AddCode("#// Assign the scene \nSCNView.#Scene# = aScene;#"); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Loading a DAE"); TextManager.SetSubtitle("Sample code"); TextManager.AddCode("#// Load a DAE" + "\n" + "var scene = SCNScene.#FromFile# (\"yourPath\");#"); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; switch (index) { case 0: // Set the slide's title and subtile and add some text TextManager.SetTitle("Node Attributes"); TextManager.SetSubtitle("Lights"); TextManager.AddBulletAtLevel("SCNLight", 0); TextManager.AddBulletAtLevel("Four light types", 0); TextManager.AddBulletAtLevel("Omni", 1); TextManager.AddBulletAtLevel("Directional", 1); TextManager.AddBulletAtLevel("Spot", 1); TextManager.AddBulletAtLevel("Ambient", 1); break; case 1: // Add some code var codeExampleNode = TextManager.AddCode("#aNode.#Light# = SCNLight.Create (); \naNode.Light.LightType = SCNLightType.Omni;#"); codeExampleNode.Position = new SCNVector3(14, 11, 1); // Add a light to the scene LightNode = SCNNode.Create(); LightNode.Light = SCNLight.Create(); LightNode.Light.LightType = SCNLightType.Omni; LightNode.Light.Color = NSColor.Black; // initially off LightNode.Light.SetAttribute(new NSNumber(30), SCNLightAttribute.AttenuationStartKey); LightNode.Light.SetAttribute(new NSNumber(40), SCNLightAttribute.AttenuationEndKey); LightNode.Position = new SCNVector3(5, 3.5f, 0); ContentNode.AddChildNode(LightNode); // Load two images to help visualize the light (on and off) LightOffImageNode = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/light-off", "tiff"), 7, false); LightOnImageNode = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/light-on", "tiff"), 7, false); LightOnImageNode.Opacity = 0; LightNode.AddChildNode(LightOnImageNode); LightNode.AddChildNode(LightOffImageNode); break; case 2: // Switch the light on SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; LightNode.Light.Color = NSColor.FromCalibratedRgba(1, 1, 0.8f, 1); LightOnImageNode.Opacity = 1.0f; LightOffImageNode.Opacity = 0.0f; SCNTransaction.Commit(); break; } SCNTransaction.Commit(); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Scene Manipulation"); TextManager.SetSubtitle("Code example"); TextManager.AddCode("#// Move a node to another position. \n" + "aNode.#Position# = new SCNVector3 (0, 0, 0); \n" + "aNode.#Scale# = new SCNVector3 (2, 2, 2); \n" + "aNode.#Rotation# = new SCNVector4 (x, y, z, angle); \n" + "aNode.#Opacity# = 0.5f;#"); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Shader Modifiers"); TextManager.AddBulletAtLevel("Inject custom GLSL code", 0); TextManager.AddBulletAtLevel("Combines with Scene Kit’s shaders", 0); TextManager.AddBulletAtLevel("Inject at specific stages", 0); TextManager.AddEmptyLine(); TextManager.AddCode("#aMaterial.#shaderModifiers# = @{ <Entry Point> : <GLSL Code> };#"); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Set the slide's title and subtitle and add some code TextManager.SetTitle("Scriptability"); TextManager.AddBulletAtLevel("Javascript bridge", 0); TextManager.AddCode("#// setup a JSContext for SceneKit\n" + "#SCNJavaScript.ExportModule# (aJSContext);\n\n" + "// reference a SceneKit object from JS\n" + "aJSContext.#GlobalObject# = aNode;\n\n" + "// execute a script\n" + "aJSContext.#EvaluateScript# (\"aNode.scale = {x:2, y:2, z:2};\");#"); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Loading a DAE"); TextManager.SetSubtitle("Sample code"); TextManager.AddCode("#// Load a DAE" + "\n" + "var scene = SCNScene.#FromFile# (\"yourPath\");#"); var image = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/daeAsResource", "png"), 9, false); image.Position = new SCNVector3(0, 3.2f, 7); GroundNode.AddChildNode(image); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("SpriteKit Overlays"); TextManager.AddBulletAtLevel("Game score, gauges, time, menus...", 0); TextManager.AddBulletAtLevel("Event handling", 0); var node = TextManager.AddCode("#scnView.#overlaySKScene# = aSKScene;#"); node.Position = new SCNVector3(9, 0, 0); var gameLoop = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/overlays", "png"), 10, false); gameLoop.Position = new SCNVector3(0, 2.9f, 13); GroundNode.AddChildNode(gameLoop); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Core Image"); TextManager.SetSubtitle("CI Filters"); TextManager.AddBulletAtLevel("Screen-space effects", 0); TextManager.AddBulletAtLevel("Applies to a node hierarchy", 0); TextManager.AddBulletAtLevel("Filter parameters are animatable", 0); TextManager.AddCode("#aNode.#filters# = @[filter1, filter2];#"); break; } }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Scene Manipulation"); TextManager.SetSubtitle("Retrieving a node"); TextManager.AddCode("#// Get by name \n" + "var aNode = scene.RootNode \n" + " .#FindChildNode #(\"aName\", true);#"); sceneGraphDiagramNode = SlideSceneGraph.SharedScenegraphDiagramNode(); SlideSceneGraph.ScenegraphDiagramGoToStep(7); sceneGraphDiagramNode.Opacity = 0.0f; sceneGraphDiagramNode.Position = new SCNVector3(1.5f, 8.0f, 0); ContentNode.AddChildNode(sceneGraphDiagramNode); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Materials"); TextManager.SetSubtitle("CALayer as texture"); TextManager.AddCode("#// Map a layer tree on a 3D object. \n" + "aNode.Geometry.FirstMaterial.Diffuse.#Contents# = #aLayerTree#;#"); // Add the model var intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(0, 3.9f, 8); intermediateNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); GroundNode.AddChildNode(intermediateNode); Utils.SCAddChildNode(intermediateNode, "frames", "Scenes/frames/frames", 8); presentationViewController.NarrowSpotlight(true); break; case 1: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Change the point of view to "frameCamera" (a camera defined in the "frames" scene) var frameCamera = ContentNode.FindChildNode("frameCamera", true); ((SCNView)presentationViewController.View).PointOfView = frameCamera; // The "frames" scene contains animations, update the end time of our main scene and start to play the animations ((SCNView)presentationViewController.View).Scene.SetAttribute(new NSNumber(7.33f), SCNScene.EndTimeAttributeKey); ((SCNView)presentationViewController.View).CurrentTime = 0; ((SCNView)presentationViewController.View).Playing = true; ((SCNView)presentationViewController.View).Loops = true; PlayerLayer1 = ConfigurePlayer(NSBundle.MainBundle.PathForResource("Movies/movie1", "mov"), "PhotoFrame-Vertical"); PlayerLayer2 = ConfigurePlayer(NSBundle.MainBundle.PathForResource("Movies/movie2", "mov"), "PhotoFrame-Horizontal"); SCNTransaction.Commit(); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: TextManager.SetTitle("Animation Events"); TextManager.AddBulletAtLevel("SCNAnimationEvent", 0); TextManager.AddCode("#var anEvent = #SCNAnimationEvent.Create# (0.2, aBlock); \n" + "anAnimation.#AnimationEvents# = @[anEvent, anotherEvent];#"); // Warm up NSSound by playing an empty sound. // Otherwise the first sound may take some time to start playing and will be desynchronised. var path = NSBundle.MainBundle.PathForResource("Sounds/emptySound", "m4a"); var soundUrl = NSUrl.FromFilename(path); var emptySound = new NSSound(soundUrl, false); emptySound.Play(); break; case 1: case 2: // Trigger the attack animation HeroSkeletonNode.AddAnimation(Animations [(int)CharacterAnimation.Attack], new NSString("attack")); break; case 3: // Trigger the walk animation HeroSkeletonNode.AddAnimation(Animations [(int)CharacterAnimation.Walk], new NSString("walk")); break; case 4: // Trigger the death animation // Make sure to remove the "idle" animation and prevent the model from intersecting with the floor. HeroSkeletonNode.RemoveAllAnimations(); HeroSkeletonNode.AddAnimation(Animations [(int)CharacterAnimation.Die], new NSString("death")); SCNTransaction.Begin(); //TODO heroSkeletonNode.ParentNode.Transform = SCNMatrix4.CreateTranslation (new SCNVector3 (0, 0, 40)); //CATransform3DTranslate(_heroSkeletonNode.parentNode.transform, 0, 0, 40); SCNTransaction.Commit(); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.5f; var cameraNode = presentationViewController.CameraNode; switch (index) { case 0: break; case 1: // Add a code snippet TextManager.AddCode("#aCamera.#FocalDistance# = 16.0f; \n" + "aCamera.#FocalBlurRadius# = 8.0f;#"); break; case 2: // Turn on DOF to illustrate the code snippet cameraNode.Camera.FocalDistance = 16; cameraNode.Camera.FocalSize = 1.5f; cameraNode.Camera.Aperture = 0.3f; cameraNode.Camera.FocalBlurRadius = 8; break; case 3: // Focus far away cameraNode.Camera.FocalDistance = 35; cameraNode.Camera.FocalSize = 4; cameraNode.Camera.Aperture = 0.1f; // and update the code snippet TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.AddEmptyLine(); TextManager.AddCode("#aCamera.#FocalDistance# = #35.0f#; \n" + "aCamera.#FocalBlurRadius# = 8.0f;#"); break; } SCNTransaction.Commit(); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Create a node to own the "sign" model, make it to be close to the camera, rotate by 90 degree because it's oriented with z as the up axis var intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(0, 0, 7); intermediateNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); GroundNode.AddChildNode(intermediateNode); // Load the "sign" model var signNode = Utils.SCAddChildNode(intermediateNode, "sign", "Scenes.scnassets/intersection/intersection", 10); signNode.Position = new SCNVector3(4, 0, 0.05f); // Re-parent every node that holds a camera otherwise they would inherit the scale from the "sign" model. // This is not a problem except that the scale affects the zRange of cameras and so it would be harder to get the transition from one camera to another right var cameraNodes = new List <SCNNode> (); foreach (SCNNode child in signNode) { if (child.Camera != null) { cameraNodes.Add(child); } } foreach (var cameraNode in cameraNodes) { var previousWorldTransform = cameraNode.WorldTransform; intermediateNode.AddChildNode(cameraNode); // re-parent cameraNode.Transform = intermediateNode.ConvertTransformFromNode(previousWorldTransform, null); cameraNode.Scale = new SCNVector3(1, 1, 1); } // Set the slide's title and subtitle and add some text TextManager.SetTitle("Node Attributes"); TextManager.SetSubtitle("SCNCamera"); TextManager.AddBulletAtLevel("Point of view for renderers", 0); TextManager.AddCode("#aNode.#Camera# = #SCNCamera#.Create (); \naView.#PointOfView# = aNode;#"); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Javascript code example", 0); TextManager.AddCode("#\n#//allocate a node#\n" + "var aNode = SCNNode.Create ();\n\n" + "#//change opacity#\n" + "aNode.Opacity = 0.5f;\n\n" + "#//remove from parent#\n" + "aNode.RemoveFromParentNode ();\n\n" + "#//animate implicitly#\n" + "SCNTransaction.Begin ();\n" + "SCNTransaction.AnimationDuration = 1.0f;\n" + "aNode.Scale = new SCNVector3 (2, 2, 2);\n" + "SCNTransaction.Commit ();#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 2: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.AddBulletAtLevel("Tools", 0); TextManager.AddBulletAtLevel("Debugging", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5f; switch (index) { case 0: TextManager.SetTitle("Materials"); TextManager.SetSubtitle("Code example"); TextManager.AddCode("#// Access the geometry attribute of a node \n" + "var geometry = node.#Geometry#; \n\n" + "// Create a new \"red\" material \n" + "var aMaterial = #SCNMaterial.Create ()#; \n" + "aMaterial.#Diffuse#.Contents = NSColor.Red; \n\n" + "// Set this material to our geometry \n" + "geometry.#FirstMaterial# = aMaterial;#"); TextManager.HighlightCodeChunks(null); break; case 1: TextManager.HighlightCodeChunks(new int[] { 0 }); break; case 2: TextManager.HighlightCodeChunks(new int[] { 1, 2 }); break; case 3: TextManager.HighlightCodeChunks(new int[] { 3 }); break; } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Node Attributes"); TextManager.SetSubtitle("Camera"); TextManager.AddBulletAtLevel("Point of view for renderers", 0); // Start with the "sign" model hidden var group = ContentNode.FindChildNode("group", true); group.Scale = new SCNVector3(0, 0, 0); group.Hidden = true; break; case 1: // Reveal the model (unhide then scale) group = ContentNode.FindChildNode("group", true); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; group.Hidden = false; SCNTransaction.Commit(); SCNTransaction.AnimationDuration = 1.0f; group.Scale = new SCNVector3(1, 1, 1); break; case 2: TextManager.AddCode("#aNode.#Camera# = #SCNCamera#.Create (); \naView.#PointOfView# = aNode;#"); break; case 3: // Switch to camera1 SCNTransaction.AnimationDuration = 2.0f; ((SCNView)presentationViewController.View).PointOfView = ContentNode.FindChildNode("camera1", true); break; case 4: // Switch to camera2 SCNTransaction.AnimationDuration = 2.0f; ((SCNView)presentationViewController.View).PointOfView = ContentNode.FindChildNode("camera2", true); break; case 5: // On completion add some code SCNTransaction.SetCompletionBlock(() => { TextManager.FadesIn = true; TextManager.AddEmptyLine(); TextManager.AddCode("#aNode.#Camera#.XFov = angleInDegrees;#"); }); // Switch back to the default camera SCNTransaction.AnimationDuration = 1.0f; ((SCNView)presentationViewController.View).PointOfView = presentationViewController.CameraNode; break; case 6: // Switch to camera 3 SCNTransaction.AnimationDuration = 1.0f; var target = ContentNode.FindChildNode("camera3", true); // Don't let the default transition animate the FOV (we will animate the FOV separately) var wantedFOV = target.Camera.XFov; target.Camera.XFov = ((SCNView)presentationViewController.View).PointOfView.Camera.XFov; // Animate point of view with an ease-in/ease-out function SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); ((SCNView)presentationViewController.View).PointOfView = target; SCNTransaction.Commit(); // Animate the FOV with the default timing function (for a better looking transition) SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; ((SCNView)presentationViewController.View).PointOfView.Camera.XFov = wantedFOV; SCNTransaction.Commit(); break; case 7: // Switch to camera 4 var cameraNode = ContentNode.FindChildNode("camera4", true); // Don't let the default transition animate the FOV (we will animate the FOV separately) wantedFOV = cameraNode.Camera.XFov; cameraNode.Camera.XFov = ((SCNView)presentationViewController.View).PointOfView.Camera.XFov; // Animate point of view with the default timing function SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; ((SCNView)presentationViewController.View).PointOfView = cameraNode; SCNTransaction.Commit(); // Animate the FOV with an ease-in/ease-out function SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); ((SCNView)presentationViewController.View).PointOfView.Camera.XFov = wantedFOV; SCNTransaction.Commit(); break; case 8: // Quickly switch back to the default camera SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; ((SCNView)presentationViewController.View).PointOfView = presentationViewController.CameraNode; SCNTransaction.Commit(); break; } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Constraints"); TextManager.SetSubtitle("SCNConstraint"); TextManager.AddBulletAtLevel("Applied sequentially at render time", 0); TextManager.AddBulletAtLevel("Only affect presentation values", 0); TextManager.AddCode("#aNode.#Constraints# = new SCNConstraint[] { aConstraint, anotherConstraint, ... };#"); // Tweak the near clipping plane of the spot light to get a precise shadow map presentationViewController.SpotLight.Light.SetAttribute(new NSNumber(10), SCNLightAttribute.ShadowNearClippingKey); break; case 1: // Remove previous text TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Code); // Add new text TextManager.SetSubtitle("SCNLookAtConstraint"); TextManager.AddBulletAtLevel("Makes a node to look at another node", 0); TextManager.AddCode("#nodeA.Constraints = new SCNConstraint[] { #SCNLookAtConstraint.Create# (nodeB) };#"); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 2: // Setup the scene SetupLookAtScene(); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Dim the text and move back a little bit TextManager.TextNode.Opacity = 0.5f; presentationViewController.CameraHandle.Position = presentationViewController.CameraNode.ConvertPositionToNode(new SCNVector3(0, 0, 5.0f), presentationViewController.CameraHandle.ParentNode); SCNTransaction.Commit(); break; case 3: // Add constraints to the arrows var container = ContentNode.FindChildNode("arrowContainer", true); // "Look at" constraint var constraint = SCNLookAtConstraint.Create(BallNode); var i = 0; foreach (var arrow in container.ChildNodes) { var delayInSeconds = 0.1 * i++; var popTime = new DispatchTime(DispatchTime.Now, (long)(delayInSeconds * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Animate to the result of applying the constraint ((SCNNode)arrow.ChildNodes [0]).Rotation = new SCNVector4(0, 1, 0, (float)(Math.PI / 2)); arrow.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit(); }); } break; case 4: // Create a keyframe animation to move the ball var animation = CAKeyFrameAnimation.FromKeyPath("position"); animation.KeyTimes = new NSNumber[] { 0.0f, (1.0f / 8.0f), (2.0f / 8.0f), (3.0f / 8.0f), (4.0f / 8.0f), (5.0f / 8.0f), (6.0f / 8.0f), (7.0f / 8.0f), 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector(new SCNVector3(0, 0.0f, 0)), NSValue.FromVector(new SCNVector3(20.0f, 0.0f, 20.0f)), NSValue.FromVector(new SCNVector3(40.0f, 0.0f, 0)), NSValue.FromVector(new SCNVector3(20.0f, 0.0f, -20.0f)), NSValue.FromVector(new SCNVector3(0, 0.0f, 0)), NSValue.FromVector(new SCNVector3(-20.0f, 0.0f, 20.0f)), NSValue.FromVector(new SCNVector3(-40.0f, 0.0f, 0)), NSValue.FromVector(new SCNVector3(-20.0f, 0.0f, -20.0f)), NSValue.FromVector(new SCNVector3(0, 0.0f, 0)) }; animation.CalculationMode = CAAnimation.AnimationCubicPaced; // smooth the movement between keyframes animation.RepeatCount = float.MaxValue; animation.Duration = 10.0f; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear); BallNode.AddAnimation(animation, new NSString("ballNodeAnimation")); // Rotate the ball to give the illusion of a rolling ball // We need two animations to do that: // - one rotation to orient the ball in the right direction // - one rotation to spin the ball animation = CAKeyFrameAnimation.FromKeyPath("rotation"); animation.KeyTimes = new NSNumber[] { 0.0f, (0.7f / 8.0f), (1.0f / 8.0f), (2.0f / 8.0f), (3.0f / 8.0f), (3.3f / 8.0f), (4.7f / 8.0f), (5.0f / 8.0f), (6.0f / 8.0f), (7.0f / 8.0f), (7.3f / 8.0f), 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI + Math.PI / 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2 - Math.PI / 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI - Math.PI / 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI / 4))) }; animation.RepeatCount = float.MaxValue; animation.Duration = 10.0f; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear); BallNode.AddAnimation(animation, new NSString("ballNodeAnimation2")); var rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 1.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector(new SCNVector4(1, 0, 0, (float)(Math.PI * 2))); BallNode.ChildNodes [1].AddAnimation(rotationAnimation, new NSString("ballNodeRotation")); break; case 5: // Add a constraint to the camera SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; constraint = SCNLookAtConstraint.Create(BallNode); presentationViewController.CameraNode.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit(); break; case 6: // Add a constraint to the light SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; var cameraTarget = ContentNode.FindChildNode("cameraTarget", true); constraint = SCNLookAtConstraint.Create(cameraTarget); presentationViewController.SpotLight.Constraints = new SCNConstraint[] { constraint }; SCNTransaction.Commit(); break; } }
public override void PresentStep(int switchIndex, PresentationViewController presentationViewController) { switch (switchIndex) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Core Image"); TextManager.SetSubtitle("CI Filters"); TextManager.AddBulletAtLevel("Screen-space effects", 0); TextManager.AddBulletAtLevel("Applies to a node hierarchy", 0); TextManager.AddBulletAtLevel("Filter parameters are animatable", 0); TextManager.AddCode("#aNode.#Filters# = new CIFilter[] { filter1, filter2 };#"); break; case 1: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; // Dim the text and move back a little TextManager.TextNode.Opacity = 0.0f; presentationViewController.CameraHandle.Position = presentationViewController.CameraNode.ConvertPositionToNode(new SCNVector3(0, 0, 5.0f), presentationViewController.CameraHandle.ParentNode); SCNTransaction.Commit(); // Reveal the grid GroupNode.Opacity = 1; break; case 2: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Highlight an item HighlightContact(13, presentationViewController); SCNTransaction.Commit(); break; case 3: var index = 13; var subStep = 0; // Successively select items for (var i = 0; i < 5; ++i) { var popTime = new DispatchTime(DispatchTime.Now, (long)(i * 0.2 * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.2f; UnhighlightContact(index); if (subStep++ == 3) { index += ColumnCount; } else { index++; } HighlightContact(index, presentationViewController); SCNTransaction.Commit(); }); } break; case 4: // BLUR+DESATURATE in the background, GLOW in the foreground // Here we will change the node hierarchy in order to group all the nodes in the background under a single node. // This way we can use a single Core Image filter and apply it on the whole grid, and have another CI filter for the node in the foreground. var selectionParent = HeroNode.ParentNode; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; // Stop the animations of the selected node HeroNode.Transform = HeroNode.PresentationNode.Transform; // set the current rotation to the current presentation value HeroNode.RemoveAllAnimations(); // Re-parent the node by preserving its world tranform var wantedWorldTransform = selectionParent.WorldTransform; GroupNode.ParentNode.AddChildNode(selectionParent); selectionParent.Transform = selectionParent.ParentNode.ConvertTransformFromNode(wantedWorldTransform, null); SCNTransaction.Commit(); // Add CIFilters SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // A negative 'centerX' value means no scaling. //TODO HeroNode.Filters [0].SetValueForKey (new NSNumber (-1), new NSString ("centerX")); // Move the selection to the foreground selectionParent.Rotation = new SCNVector4(0, 1, 0, 0); HeroNode.Transform = ContentNode.ConvertTransformToNode(SCNMatrix4.CreateTranslation(0, Altitude, 29), selectionParent); HeroNode.Scale = new SCNVector3(1, 1, 1); HeroNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.25f); // Upon completion, rotate the selection forever SCNTransaction.SetCompletionBlock(() => { var animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 4.0f; animation.From = NSValue.FromVector(new SCNVector4(0, 1, 0, 0)); animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, NMath.PI * 2)); animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.RepeatCount = float.MaxValue; HeroNode.ChildNodes [0].AddAnimation(animation, new NSString("heroNodeAnimation")); }); // Add the filters var blurFilter = CIFilter.FromName("CIGaussianBlur"); blurFilter.SetDefaults(); blurFilter.Name = "blur"; blurFilter.SetValueForKey(new NSNumber(0), CIFilterInputKey.Radius); var desaturateFilter = CIFilter.FromName("CIColorControls"); desaturateFilter.SetDefaults(); desaturateFilter.Name = "desaturate"; GroupNode.Filters = new CIFilter[] { blurFilter, desaturateFilter }; SCNTransaction.Commit(); // Increate the blur radius and desaturate progressively SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 2; GroupNode.SetValueForKey(new NSNumber(10), new NSString("filters.blur.inputRadius")); GroupNode.SetValueForKey(new NSNumber(0.1), new NSString("filters.desaturate.inputSaturation")); SCNTransaction.Commit(); break; } }
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; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: // Hide everything (in case the user went backward) for (var i = 1; i < 4; i++) { var teapot = GroundNode.FindChildNode("Teapot" + i, true); teapot.Opacity = 0.0f; } break; case 1: // Move the camera and adjust the clipping plane SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 3; presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 200); presentationViewController.CameraNode.Camera.ZFar = 500.0f; SCNTransaction.Commit(); break; case 2: // Revert to original position SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 0); presentationViewController.CameraNode.Camera.ZFar = 100.0f; SCNTransaction.Commit(); break; case 3: var numberNodes = new SCNNode[] { AddNumberNode("64k", -17), AddNumberNode("6k", -9), AddNumberNode("3k", -1), AddNumberNode("1k", 6.5f), AddNumberNode("256", 14) }; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Move the camera and the text presentationViewController.CameraHandle.Position = new SCNVector3(presentationViewController.CameraHandle.Position.X, presentationViewController.CameraHandle.Position.Y + 6, presentationViewController.CameraHandle.Position.Z); TextManager.TextNode.Position = new SCNVector3(TextManager.TextNode.Position.X, TextManager.TextNode.Position.Y + 6, TextManager.TextNode.Position.Z); // Show the remaining resolutions for (var i = 0; i < 5; i++) { var numberNode = numberNodes [i]; numberNode.Position = new SCNVector3(numberNode.Position.X, 7, -5); var teapot = GroundNode.FindChildNode("Teapot" + i, true); teapot.Opacity = 1.0f; teapot.Rotation = new SCNVector4(0, 0, 1, (float)(Math.PI / 4)); teapot.Position = new SCNVector3((i - 2) * 8, 5, teapot.Position.Z); } SCNTransaction.Commit(); break; case 4: presentationViewController.ShowsNewInSceneKitBadge(true); // Remove the numbers RemoveNumberNodes(); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; // Add some text and code TextManager.SetSubtitle("SCNLevelOfDetail"); TextManager.AddCode("#var lod1 = SCNLevelOfDetail.#CreateWithWorldSpaceDistance# (aGeometry, aDistance); \n" + "geometry.#LevelsOfDetail# = new SCNLevelOfDetail { lod1, lod2, ..., lodn };#"); // Animation the merge for (int i = 0; i < 5; i++) { var teapot = GroundNode.FindChildNode("Teapot" + i, true); teapot.Opacity = i == 0 ? 1.0f : 0.0f; teapot.Rotation = new SCNVector4(0, 0, 1, 0); teapot.Position = new SCNVector3(0, -5, teapot.Position.Z); } // Move the camera and the text presentationViewController.CameraHandle.Position = new SCNVector3(presentationViewController.CameraHandle.Position.X, presentationViewController.CameraHandle.Position.Y - 3, presentationViewController.CameraHandle.Position.Z); TextManager.TextNode.Position = new SCNVector3(TextManager.TextNode.Position.X, TextManager.TextNode.Position.Y - 3, TextManager.TextNode.Position.Z); SCNTransaction.Commit(); break; case 5: presentationViewController.ShowsNewInSceneKitBadge(false); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 3; // Change the lighting to remove the front light and rise the main light presentationViewController.UpdateLightingWithIntensities(new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.3f }); presentationViewController.RiseMainLight(true); // Remove some text TextManager.FadeOutText(SlideTextManager.TextType.Title); TextManager.FadeOutText(SlideTextManager.TextType.Subtitle); TextManager.FadeOutText(SlideTextManager.TextType.Code); SCNTransaction.Commit(); // Retrieve the main teapot var maintTeapot = GroundNode.FindChildNode("Teapot0", true); // The distances to use for each LOD var distances = new float[] { 30, 50, 90, 150 }; // An array of SCNLevelOfDetail instances that we will build var levelsOfDetail = new SCNLevelOfDetail[4]; for (var i = 1; i < 5; i++) { var teapotNode = GroundNode.FindChildNode("Teapot" + i, true); var teapot = teapotNode.Geometry; // Unshare the material because we will highlight the different levels of detail with different colors in the next step teapot.FirstMaterial = (SCNMaterial)teapot.FirstMaterial.Copy(); // Build the SCNLevelOfDetail instance var levelOfDetail = SCNLevelOfDetail.CreateWithWorldSpaceDistance(teapot, distances [i - 1]); levelsOfDetail [i - 1] = levelOfDetail; } maintTeapot.Geometry.LevelsOfDetail = levelsOfDetail; // Duplicate and move the teapots var startTime = CAAnimation.CurrentMediaTime(); var delay = 0.2; var rowCount = 9; var columnCount = 12; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; // Change the far clipping plane to be able to see far away presentationViewController.CameraNode.Camera.ZFar = 1000.0; for (var j = 0; j < columnCount; j++) { for (var i = 0; i < rowCount; i++) { // Clone var clone = maintTeapot.Clone(); maintTeapot.ParentNode.AddChildNode(clone); // Animate var animation = CABasicAnimation.FromKeyPath("position"); animation.Additive = true; animation.Duration = 1.0; animation.To = NSValue.FromVector(new SCNVector3((i - rowCount / 2.0f) * 12.0f, 5 + (columnCount - j) * 15.0f, 0)); animation.From = NSValue.FromVector(new SCNVector3(0, 0, 0)); animation.BeginTime = startTime + delay; // desynchronize // Freeze at the end of the animation animation.RemovedOnCompletion = false; animation.FillMode = CAFillMode.Forwards; clone.AddAnimation(animation, new NSString("cloneAnimation")); // Animate the hidden property to automatically show the node when the position animation starts animation = CABasicAnimation.FromKeyPath("hidden"); animation.Duration = delay + 0.01; animation.FillMode = CAFillMode.Both; animation.From = new NSNumber(1); animation.To = new NSNumber(0); clone.AddAnimation(animation, new NSString("cloneAnimation2")); delay += 0.05; } } SCNTransaction.Commit(); // Animate the camera while we duplicate the nodes SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0 + rowCount * columnCount * 0.05; var position = presentationViewController.CameraHandle.Position; presentationViewController.CameraHandle.Position = new SCNVector3(position.X, position.Y + 5, position.Z); presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, presentationViewController.CameraPitch.Rotation.W - ((float)(Math.PI / 4) * 0.1f)); SCNTransaction.Commit(); break; case 6: // Highlight the levels of detail with colors var teapotChild = GroundNode.FindChildNode("Teapot0", true); var colors = new NSColor[] { NSColor.Red, NSColor.Orange, NSColor.Yellow, NSColor.Green }; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; for (var i = 0; i < 4; i++) { var levelOfDetail = teapotChild.Geometry.LevelsOfDetail [i]; levelOfDetail.Geometry.FirstMaterial.Multiply.Contents = colors [i]; } SCNTransaction.Commit(); break; } }
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; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.AddBulletAtLevel("Image", 0); TextManager.AddBulletAtLevel("Name / Path / URL", 1); TextManager.AddBulletAtLevel("NSImage / UIImage / NSData", 1); TextManager.AddBulletAtLevel("SKTexture", 1); TextManager.FlipInText(SlideTextManager.TextType.Bullet); var code = TextManager.AddCode("#material.diffuse.contents = #@\"slate.jpg\"#;#"); code.Position = new SCNVector3(code.Position.X + 6, code.Position.Y - 6.5f, code.Position.Z); Material.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/slate", "jpg")); Material.Normal.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/slate-bump", "png")); Material.Normal.Intensity = 0; break; case 2: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; Material.Normal.Intensity = 5.0f; Material.Specular.Contents = NSColor.Gray; SCNTransaction.Commit(); code = TextManager.AddCode("#material.normal.contents = #[SKTexture textureByGeneratingNormalMap]#;#"); code.Position = new SCNVector3(code.Position.X + 2, code.Position.Y - 6.5f, code.Position.Z); break; case 3: TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Live contents", 0); TextManager.AddBulletAtLevel("CALayer tree", 1); TextManager.AddBulletAtLevel("SKScene (new)", 1); TextManager.FlipInText(SlideTextManager.TextType.Bullet); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; Material.Normal.Intensity = 2.0f; SCNTransaction.Commit(); PlayerLayer1 = ConfigurePlayer(NSBundle.MainBundle.PathForResource("Movies/movie1", "mov"), "material-cube"); break; case 4: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Cube map", 0); TextManager.AddBulletAtLevel("NSArray of 6 items", 1); TextManager.FlipInText(SlideTextManager.TextType.Bullet); code = TextManager.AddCode("#material.reflective.contents = #@[aright.png, left.png ... front.png]#;#"); code.Position = new SCNVector3(code.Position.X, code.Position.Y - 9.5f, code.Position.Z); var image = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/cubemap", "png"), 12, false); image.Position = new SCNVector3(-10, 9, 0); image.Opacity = 0; ContentNode.AddChildNode(image); Object.Geometry = SCNTorus.Create(W * 0.5f, W * 0.2f); Material = Object.Geometry.FirstMaterial; Object.Rotation = new SCNVector4(1, 0, 0, (float)Math.PI / 2); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; var right = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/right", "tga")); var left = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/left", "tga")); var top = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/top", "tga")); var bottom = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/bottom", "tga")); var back = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/back", "tga")); var front = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/front", "tga")); var materialContents = new NSMutableArray(); materialContents.AddObjects(new NSObject[] { right, left, top, bottom, back, front }); Material.Reflective.Contents = materialContents; Material.Diffuse.Contents = NSColor.Red; image.Opacity = 1.0f; SCNTransaction.Commit(); break; } }