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); }
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/intersection/intersection", 30); signNode.Position = new SCNVector3(4, -2, 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 NSMutableArray(); foreach (SCNNode child in signNode) { if (child.Camera != null) { cameraNodes.Add(child); } } for (nuint i = 0; i < cameraNodes.Count; i++) { var cameraNode = new SCNNode(cameraNodes.ValueAt((uint)i)); var previousWorldTransform = cameraNode.WorldTransform; intermediateNode.AddChildNode(cameraNode); // re-parent cameraNode.Transform = intermediateNode.ConvertTransformFromNode(previousWorldTransform, null); cameraNode.Scale = new SCNVector3(1, 1, 1); } }
public override void SetupSlide(PresentationViewController presentationViewController) { // Load the character and add it to the scene var heroNode = Utils.SCAddChildNode(GroundNode, "heroGroup", "Scenes/hero/hero", 0.0f); heroNode.Scale = new SCNVector3(0.023f, 0.023f, 0.023f); heroNode.Position = new SCNVector3(0.0f, 0.0f, 15.0f); heroNode.Rotation = new SCNVector4(1.0f, 0.0f, 0.0f, -(float)(Math.PI / 2)); GroundNode.AddChildNode(heroNode); // Convert sceneTime-based animations into systemTime-based animations. // Animations loaded from DAE files will play according to the `currentTime` property of the scene renderer if this one is playing // (see the SCNSceneRenderer protocol). Here we don't play a specific DAE so we want the animations to animate as soon as we add // them to the scene (i.e have them to play according the time of the system when the animation was added). HeroSkeletonNode = heroNode.FindChildNode("skeleton", true); foreach (var animationKey in HeroSkeletonNode.GetAnimationKeys()) { // Find all the animations. Make them system time based and repeat forever. // And finally replace the old animation. var animation = HeroSkeletonNode.GetAnimation(animationKey); animation.UsesSceneTimeBase = false; animation.RepeatCount = float.MaxValue; HeroSkeletonNode.AddAnimation(animation, animationKey); } // Load other animations so that we will use them later SetAnimation(CharacterAnimation.Attack, "attackID", "attack"); SetAnimation(CharacterAnimation.Die, "DeathID", "death"); SetAnimation(CharacterAnimation.Walk, "WalkID", "walk"); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Load the scene var intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(6, 9, 0); intermediateNode.Scale = new SCNVector3(1.4f, 1, 1); GroundNode.AddChildNode(intermediateNode); MapNode = Utils.SCAddChildNode(intermediateNode, "Map", "Scenes/map/foldingMap", 25); MapNode.Position = new SCNVector3(0, 0, 0); MapNode.Opacity = 0.0f; // Use a bunch of shader modifiers to simulate ambient occlusion when the map is folded var geomFile = NSBundle.MainBundle.PathForResource("Shaders/mapGeometry", "shader"); var fragFile = NSBundle.MainBundle.PathForResource("Shaders/mapFragment", "shader"); var lightFile = NSBundle.MainBundle.PathForResource("Shaders/mapLighting", "shader"); var geometryModifier = File.ReadAllText(geomFile); var fragmentModifier = File.ReadAllText(fragFile); var lightingModifier = File.ReadAllText(lightFile); MapNode.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = geometryModifier, EntryPointFragment = fragmentModifier, EntryPointLightingModel = lightingModifier }; }
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 SetupSlide(PresentationViewController presentationViewController) { // Add some text TextManager.SetTitle("Loading a 3D Scene"); TextManager.SetSubtitle("DAE Documents"); NodesToDim = new List <SCNNode> (); TextManager.AddBulletAtLevel("Geometries", 0); TextManager.AddBulletAtLevel("Animations", 0); NodesToDim.Add(TextManager.AddBulletAtLevel("Textures", 0)); NodesToDim.Add(TextManager.AddBulletAtLevel("Lighting", 0)); NodesToDim.Add(TextManager.AddBulletAtLevel("Cameras", 0)); NodesToDim.Add(TextManager.AddBulletAtLevel("Skinning", 0)); NodesToDim.Add(TextManager.AddBulletAtLevel("Morphing", 0)); // And an image resting on the ground DaeIcon = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/dae file icon", "png"), 10, false); DaeIcon.Position = new SCNVector3(6, 4.5f, 1); GroundNode.AddChildNode(DaeIcon); AbcIcon = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/abc file icon", "png"), 10, false); AbcIcon.Position = new SCNVector3(6, 4.5f, 30); GroundNode.AddChildNode(AbcIcon); }
private void PresentTextNode() { TextNode = SplittedStylizedText("I❤︎SceneKit"); TextNode.Scale = new SCNVector3(0.017f, 0.0187f, 0.017f); TextNode.Opacity = 0.0f; TextNode.Position = new SCNVector3(-14, 0, 0); GroundNode.AddChildNode(TextNode); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Per-Frame Updates"); TextManager.SetSubtitle("Game Loop"); var gameLoop = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/gameLoop", "png"), 17, false); gameLoop.Position = new SCNVector3(0, 6, 10); GroundNode.AddChildNode(gameLoop); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Related Sessions"); // load the "related.png" image and show it mapped on a plane var relatedImage = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/related", "png"), 35, false); relatedImage.Position = new SCNVector3(0, 10, 0); relatedImage.CastsShadow = false; GroundNode.AddChildNode(relatedImage); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Shadows"); TextManager.AddBulletAtLevel("Static", 0); TextManager.AddBulletAtLevel("Dynamic", 0); TextManager.AddBulletAtLevel("Projected", 0); var sceneryHolder = SCNNode.Create(); sceneryHolder.Name = "scenery"; sceneryHolder.Position = new SCNVector3(5, -19, 12); GroundNode.AddChildNode(sceneryHolder); //add scenery var scenery = Utils.SCAddChildNode(sceneryHolder, "scenery", "Scenes.scnassets/banana/level", 130); scenery.Position = new SCNVector3(-291.374969f, 1.065581f, -30.519293f); scenery.Scale = new SCNVector3(0.044634f, 0.044634f, 0.044634f); scenery.Rotation = new SCNVector4(1, 0, 0, -NMath.PI / 2); PalmTree = Utils.SCAddChildNode(GroundNode, "PalmTree", "Scenes.scnassets/palmTree/palm_tree", 15); PalmTree.Position = new SCNVector3(3, -1, 7); PalmTree.Rotation = new SCNVector4(1, 0, 0, -NMath.PI / 2); foreach (var child in PalmTree.ChildNodes) { child.CastsShadow = false; } //add a static shadow var shadowPlane = SCNNode.FromGeometry(SCNPlane.Create(15, 15)); shadowPlane.EulerAngles = new SCNVector3(-NMath.PI / 2, (float)(Math.PI / 4) * 0.5f, 0); shadowPlane.Position = new SCNVector3(0.5f, 0.1f, 2); shadowPlane.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Images/staticShadow", "tiff")); GroundNode.AddChildNode(shadowPlane); StaticShadowNode = shadowPlane; StaticShadowNode.Opacity = 0; var character = Utils.SCAddChildNode(GroundNode, "explorer", "Scenes.scnassets/explorer/explorer_skinned", 9); var animScene = SCNScene.FromFile("Scenes.scnassets/explorer/idle"); var animatedNode = animScene.RootNode.FindChildNode("Bip001_Pelvis", true); character.AddAnimation(animatedNode.GetAnimation(animatedNode.GetAnimationKeys() [0]), new NSString("idle")); character.EulerAngles = new SCNVector3(0, NMath.PI / 2, NMath.PI / 2); character.Position = new SCNVector3(20, 0, 7); Character = character; }
public override void SetupSlide(PresentationViewController presentationViewController) { // Set the slide's title and subtitle and add some text TextManager.SetTitle("Scene Graph"); TextManager.SetSubtitle("Scene"); TextManager.AddBulletAtLevel("SCNScene", 0); TextManager.AddBulletAtLevel("Starting point", 0); // Setup the diagram var diagramNode = SlideSceneGraph.SharedScenegraphDiagramNode(); GroundNode.AddChildNode(diagramNode); }
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 DidOrderIn(PresentationViewController presentationViewController) { // Bring up a screenshot of the editor var editorScreenshotNode = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/editor", "png"), 14, true); editorScreenshotNode.Position = new SCNVector3(17, 4.1f, 5); editorScreenshotNode.Rotation = new SCNVector4(0, 1, 0, -(float)(Math.PI / 1.5f)); GroundNode.AddChildNode(editorScreenshotNode); // Animate it (rotate and move) SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; editorScreenshotNode.Position = new SCNVector3(7.5f, 4.1f, 5); editorScreenshotNode.Rotation = new SCNVector4(0, 1, 0, -(float)(Math.PI / 6.0f)); SCNTransaction.Commit(); }
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 DidOrderIn (PresentationViewController presentationViewController) { // Bring up a screenshot of the editor var editorScreenshotNode = Utils.SCPlaneNode (NSBundle.MainBundle.PathForResource ("Images/particleEditor", "png"), 14, true); editorScreenshotNode.Geometry.FirstMaterial.Diffuse.MipFilter = SCNFilterMode.Linear; editorScreenshotNode.Position = new SCNVector3 (17, 3.8f, 5); editorScreenshotNode.Rotation = new SCNVector4 (0, 1, 0, -(float)Math.PI / 1.5f); GroundNode.AddChildNode (editorScreenshotNode); // Animate it (rotate and move) SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; editorScreenshotNode.Position = new SCNVector3 (7, 3.8f, 5); editorScreenshotNode.Rotation = new SCNVector4 (0, 1, 0, -(float)Math.PI / 7); SCNTransaction.Commit (); }
private SCNNode AddNumberNode(string numberString, float x) { var numberNode = Utils.SCLabelNode(numberString, Utils.LabelSize.Large, true); numberNode.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Orange; numberNode.Geometry.FirstMaterial.Ambient.Contents = NSColor.Orange; numberNode.Position = new SCNVector3(x, 50, 0); numberNode.Name = "number"; var text = (SCNText)numberNode.Geometry; text.ExtrusionDepth = 5; GroundNode.AddChildNode(numberNode); return(numberNode); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Add some text TextManager.SetTitle("Working with DAE Files"); TextManager.SetSubtitle("DAE Files on OS X"); // DAE icon var daeIconNode = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/dae file icon", "png"), 5, false); daeIconNode.Position = new SCNVector3(0, 2.3f, 0); GroundNode.AddChildNode(daeIconNode); // Preview icon and text var previewIconNode = Utils.SCPlaneNodeWithImage(Utils.SCImageFromApplication("Preview"), 3, false); previewIconNode.Position = new SCNVector3(-5, 1.3f, 11); GroundNode.AddChildNode(previewIconNode); var previewTextNode = Utils.SCLabelNode("Preview", Utils.LabelSize.Small, false); previewTextNode.Position = new SCNVector3(-5.5f, 0, 13); GroundNode.AddChildNode(previewTextNode); // Quicklook icon and text var qlIconNode = Utils.SCPlaneNodeWithImage(Utils.SCImageFromApplication("Finder"), 3, false); qlIconNode.Position = new SCNVector3(0, 1.3f, 11); GroundNode.AddChildNode(qlIconNode); var qlTextNode = Utils.SCLabelNode("QuickLook", Utils.LabelSize.Small, false); qlTextNode.Position = new SCNVector3(-1.11f, 0, 13); GroundNode.AddChildNode(qlTextNode); // Xcode icon and text var xcodeIconNode = Utils.SCPlaneNodeWithImage(Utils.SCImageFromApplication("Xcode"), 3, false); xcodeIconNode.Position = new SCNVector3(5, 1.3f, 11); GroundNode.AddChildNode(xcodeIconNode); var xcodeTextNode = Utils.SCLabelNode("Xcode", Utils.LabelSize.Small, false); xcodeTextNode.Position = new SCNVector3(3.8f, 0, 13); GroundNode.AddChildNode(xcodeTextNode); }
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 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 SetupSlide(PresentationViewController presentationViewController) { // Create a node for Earth and another node to display clouds // Use the 'pivot' property to tilt Earth because we don't want to see the north pole. EarthNode = SCNNode.Create(); EarthNode.Pivot = SCNMatrix4.CreateFromAxisAngle(new SCNVector3(1, 0, 0), (float)(Math.PI * 0.1f)); EarthNode.Position = new SCNVector3(6, 7.2f, -2); EarthNode.Geometry = SCNSphere.Create(7.2f); CloudsNode = SCNNode.Create(); CloudsNode.Geometry = SCNSphere.Create(7.9f); GroundNode.AddChildNode(EarthNode); EarthNode.AddChildNode(CloudsNode); // Initially hide everything EarthNode.Opacity = 0.0f; CloudsNode.Opacity = 0.0f; EarthNode.Geometry.FirstMaterial.Ambient.Intensity = 0; EarthNode.Geometry.FirstMaterial.Normal.Intensity = 0; EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0; EarthNode.Geometry.FirstMaterial.Emission.Intensity = 0; // Use a shader modifier to display an environment map independently of the lighting model used EarthNode.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointFragment = " _output.color.rgb -= _surface.reflective.rgb * _lightingContribution.diffuse;" + "_output.color.rgb += _surface.reflective.rgb;" }; // Add animations 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))); EarthNode.AddAnimation(rotationAnimation, new NSString("earthNodeAnimation")); rotationAnimation.Duration = 100.0f; CloudsNode.AddAnimation(rotationAnimation, new NSString("cloudsNodeAnimation")); }
private void PresentWalls(PresentationViewController presentationViewController) { //add spheres and container var height = 2; var width = 1; var count = 3; var margin = 2; var totalWidth = count * (margin + width); var blockMesh = CreateBlockMesh(new SCNVector3(width, height, width)); for (int i = 0; i < count; i++) { //create a static block var wall = SCNNode.Create(); wall.Position = new SCNVector3((i - (count / 2)) * (width + margin), -height / 2, totalWidth / 2); wall.Geometry = blockMesh; wall.Name = "container-wall"; wall.PhysicsBody = SCNPhysicsBody.CreateStaticBody(); GroundNode.AddChildNode(wall); wall.RunAction(SCNAction.MoveBy(new SCNVector3(0, height, 0), 0.5f)); //one more wall = (SCNNode)wall.Copy(); wall.Position = new SCNVector3((i - (count / 2)) * (width + margin), -height / 2, -totalWidth / 2); GroundNode.AddChildNode(wall); // one more wall = (SCNNode)wall.Copy(); wall.Position = new SCNVector3(totalWidth / 2, -height / 2, (i - (count / 2)) * (width + margin)); GroundNode.AddChildNode(wall); //one more wall = (SCNNode)wall.Copy(); wall.Position = new SCNVector3(-totalWidth / 2, -height / 2, (i - (count / 2)) * (width + margin)); GroundNode.AddChildNode(wall); } }
public override void SetupSlide(PresentationViewController presentationViewController) { // Load the character and add it to the scene var heroNode = Utils.SCAddChildNode(GroundNode, "bossGroup", "Scenes.scnassets/boss/boss", 0.0f); heroNode.Scale = new SCNVector3(0.015f, 0.015f, 0.015f); heroNode.Position = new SCNVector3(3.0f, 0.0f, 15.0f); heroNode.Rotation = new SCNVector4(1.0f, 0.0f, 0.0f, -(float)(Math.PI / 2)); GroundNode.AddChildNode(heroNode); // Convert sceneTime-based animations into systemTime-based animations. // Animations loaded from DAE files will play according to the `currentTime` property of the scene renderer if this one is playing // (see the SCNSceneRenderer protocol). Here we don't play a specific DAE so we want the animations to animate as soon as we add // them to the scene (i.e have them to play according the time of the system when the animation was added). HeroSkeletonNode = heroNode.FindChildNode("skeleton", true); // Load other animations so that we will use them later SetAnimation(CharacterAnimation.Attack, "attackID", "boss_attack"); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Levels of Detail"); ((SCNView)presentationViewController.View).AllowsCameraControl = true; var intermediateNode = SCNNode.Create(); intermediateNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); GroundNode.AddChildNode(intermediateNode); // Load two resolutions AddTeapot(0, -5, intermediateNode); // high res AddTeapot(4, +5, intermediateNode); // low res // Load the other resolutions but hide them for (var i = 1; i < 4; i++) { var teapotNode = AddTeapot(i, 5, intermediateNode); teapotNode.Opacity = 0.0f; } }
public override void SetupSlide(PresentationViewController presentationViewController) { // Using a scene source allows us to retrieve the animations using their identifier var path = NSBundle.MainBundle.PathForResource("Scenes/skinning/skinning", "dae"); var sceneURL = NSUrl.FromFilename(path); var sceneSource = SCNSceneSource.FromUrl(sceneURL, (NSDictionary)null); // Place the character in the scene var error = new NSError(); var scene = sceneSource.SceneWithOption((SCNSceneLoadingOptions)null, out error); CharacterNode = scene.RootNode.FindChildNode("avatar_attach", true); CharacterNode.Scale = new SCNVector3(0.004f, 0.004f, 0.004f); CharacterNode.Position = new SCNVector3(5, 0, 12); CharacterNode.Rotation = new SCNVector4(0, 1, 0, -(float)(Math.PI / 8)); CharacterNode.Hidden = true; GroundNode.AddChildNode(CharacterNode); SkeletonNode = CharacterNode.FindChildNode("skeleton", true); // Prepare the other resources //TODO LoadGhostEffect (); ExtractAnimation(sceneSource); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Slide's title and subtitle TextManager.SetTitle("Assets Catalog"); TextManager.SetSubtitle(".scnassets folders"); TextManager.AddBulletAtLevel("Manage your assets", 0); TextManager.AddBulletAtLevel("Add DAE files and referenced textures", 0); TextManager.AddBulletAtLevel("Optimized at build time", 0); TextManager.AddBulletAtLevel("Compilation options", 0); TextManager.AddBulletAtLevel("Geometry interleaving", 1); TextManager.AddBulletAtLevel("PVRTC, Up axis", 1); var intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(0, 0, 7); GroundNode.AddChildNode(intermediateNode); // Load the "folder" model var folder = Utils.SCAddChildNode(intermediateNode, "folder", "Scenes.scnassets/assetCatalog/assetCatalog", 8); folder.Position = new SCNVector3(5, 0, 2); folder.Rotation = new SCNVector4(0, 1, 0, -(float)(Math.PI / 4) * 0.9f); }
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: 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 SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Constraints"); TextManager.SetSubtitle("SCNIKConstraint"); TextManager.AddBulletAtLevel("Inverse Kinematics", 0); TextManager.AddBulletAtLevel("Node chain", 0); TextManager.AddBulletAtLevel("Target", 0); //load the hero Hero = Utils.SCAddChildNode(GroundNode, "heroGroup", "Scenes.scnassets/hero/hero", 12); Hero.Position = new SCNVector3(0, 0, 5); Hero.Rotation = new SCNVector4(1, 0, 0, -(nfloat)Math.PI / 2); //hide the sword var sword = Hero.FindChildNode("sword", true); sword.Hidden = true; //load attack animation var path = NSBundle.MainBundle.PathForResource("Scenes.scnassets/hero/attack", "dae"); var source = SCNSceneSource.FromUrl(NSUrl.FromFilename(path), (NSDictionary)null); Attack = (CAAnimation)source.GetEntryWithIdentifier("attackID", new Class("CAAnimation")); Attack.RepeatCount = 0; Attack.FadeInDuration = 0.1f; Attack.FadeOutDuration = 0.3f; Attack.Speed = 0.75f; Attack.AnimationEvents = new SCNAnimationEvent[] { SCNAnimationEvent.Create(0.55f, (CAAnimation animation, NSObject animatedObject, bool playingBackward) => { if (IkActive) { DestroyTarget(); } }) }; AnimationDuration = Attack.Duration; //setup IK var hand = Hero.FindChildNode("Bip01_R_Hand", true); var clavicle = Hero.FindChildNode("Bip01_R_Clavicle", true); var head = Hero.FindChildNode("Bip01_Head", true); Ik = SCNIKConstraint.Create(clavicle); hand.Constraints = new SCNConstraint[] { Ik }; Ik.InfluenceFactor = 0.0f; //add target Target = SCNNode.Create(); Target.Position = new SCNVector3(-4, 7, 10); Target.Opacity = 0; Target.Geometry = SCNPlane.Create(2, 2); Target.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Images/target", "png")); GroundNode.AddChildNode(Target); //look at LookAt = SCNLookAtConstraint.Create(Target); LookAt.InfluenceFactor = 0; head.Constraints = new SCNConstraint[] { LookAt }; ((SCNView)presentationViewController.View).WeakSceneRendererDelegate = this; }
private void BuildImageGrid() { // Create a root node for the grid GroupNode = SCNNode.Create(); // Retrieve the template node to replicate var scene = SCNScene.FromFile("Contacts/contact"); var templateNode = scene.RootNode.FindChildNode("people", true); for (int k = 0, j = 0; j < RowCount; j++) { for (var i = 0; i < ColumnCount; i++, k++) { // Hierarchy : __groupNode > container > node var container = SCNNode.Create(); var node = templateNode.Clone(); node.Name = "contact" + k; GroupNode.AddChildNode(container); container.AddChildNode(node); if (k == 28) { HeroNode = node; } // Curved layout var angle = 0.12f * ((ColumnCount - 1) / 2.0f - i); var x = NMath.Cos(angle + (float)(Math.PI / 2)) * 500.0f; var z = NMath.Sin(angle + (float)(Math.PI / 2)) * 500.0f; container.Position = new SCNVector3(x, j * 60, -z + 400); container.Rotation = new SCNVector4(0, 1, 0, angle); // We want a different image on each elemement and to do that we need to // unshare the geometry first and then unshare the material var geometryNode = node.ChildNodes [0]; geometryNode.Geometry = (SCNGeometry)geometryNode.Geometry.Copy(); var materialCopy = (SCNMaterial)geometryNode.Geometry.Materials [1].Copy(); materialCopy.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Contacts/contact" + (k % ContactImageCount), "jpg")); geometryNode.Geometry.ReplaceMaterial(1, materialCopy); // Animate (rotate forever) var animation = CAKeyFrameAnimation.GetFromKeyPath("rotation"); animation.Duration = 4.0f; animation.KeyTimes = new NSNumber[] { 0.0f, 0.3f, 1.0f }; animation.Values = new NSObject[] { NSValue.FromVector(new SCNVector4(0, 1, 0, 0)), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))), NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))) }; var tf = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimingFunctions = new CAMediaTimingFunction[] { tf, tf, tf }; animation.RepeatCount = float.MaxValue; animation.BeginTime = CAAnimation.CurrentMediaTime() + 1.0f + j * 0.1f + i * 0.05f; // desynchronize the animations node.AddAnimation(animation, new NSString("animation")); } } // Add the group to the scene GroupNode.Scale = new SCNVector3(0.03f, 0.03f, 0.03f); GroupNode.Position = new SCNVector3(0, Altitude - 2.8f, 18); GroupNode.Opacity = 0.0f; GroundNode.AddChildNode(GroupNode); }
public override void SetupSlide(PresentationViewController presentationViewController) { // Set the slide's title and subtile and add some text TextManager.SetTitle("Node Attributes"); TextManager.SetSubtitle("SCNGeometry"); TextManager.AddBulletAtLevel("Triangles", 0); TextManager.AddBulletAtLevel("Vertices", 0); TextManager.AddBulletAtLevel("Normals", 0); TextManager.AddBulletAtLevel("UVs", 0); TextManager.AddBulletAtLevel("Materials", 0); // We create a container for several versions of the teapot model // - one teapot to show positions and normals // - one teapot to show texture coordinates // - one teapot to show materials var allTeapotsNode = SCNNode.Create(); allTeapotsNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); GroundNode.AddChildNode(allTeapotsNode); TeapotNodeForPositionsAndNormals = Utils.SCAddChildNode(allTeapotsNode, "TeapotLowRes", "Scenes.scnassets/teapots/teapotLowRes", 17); TeapotNodeForUVs = Utils.SCAddChildNode(allTeapotsNode, "Teapot", "Scenes.scnassets/teapots/teapot", 17); TeapotNodeForMaterials = Utils.SCAddChildNode(allTeapotsNode, "teapotMaterials", "Scenes.scnassets/teapots/teapotMaterial", 17); TeapotNodeForPositionsAndNormals.Position = new SCNVector3(4, 0, 0); TeapotNodeForUVs.Position = new SCNVector3(4, 0, 0); TeapotNodeForMaterials.Position = new SCNVector3(4, 0, 0); foreach (var child in TeapotNodeForMaterials.ChildNodes) { foreach (var material in child.Geometry.Materials) { material.Multiply.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes.scnassets/teapots/UVs", "png")); material.Multiply.WrapS = SCNWrapMode.Repeat; material.Multiply.WrapT = SCNWrapMode.Repeat; //material.Reflective.Contents = NSColor.White; //material.Reflective.Intensity = 3.0f; //material.FresnelExponent = 3.0f; } } // Animate the teapots (rotate forever) var rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 40.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector(new SCNVector4(0, 0, 1, (float)(Math.PI * 2))); TeapotNodeForPositionsAndNormals.AddAnimation(rotationAnimation, new NSString("teapotNodeForPositionsAndNormalsAnimation")); TeapotNodeForUVs.AddAnimation(rotationAnimation, new NSString("teapotNodeForUVsAnimation")); TeapotNodeForMaterials.AddAnimation(rotationAnimation, new NSString("teapotNodeForMaterialsAnimation")); // Load the "explode" shader modifier and add it to the geometry //var explodeShaderPath = NSBundle.MainBundle.PathForResource ("Shaders/explode", "shader"); //var explodeShaderSource = System.IO.File.ReadAllText (explodeShaderPath); // TODO TeapotNodeForPositionsAndNormals.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = explodeShaderSource }; PositionsVisualizationNode = SCNNode.Create(); NormalsVisualizationNode = SCNNode.Create(); // Build nodes that will help visualize the vertices (position and normal) BuildVisualizationsOfNode(TeapotNodeForPositionsAndNormals, ref PositionsVisualizationNode, ref NormalsVisualizationNode); NormalsVisualizationNode.CastsShadow = false; TeapotNodeForMaterials.AddChildNode(PositionsVisualizationNode); TeapotNodeForMaterials.AddChildNode(NormalsVisualizationNode); }