public static SCAddChildNode ( SCNNode container, string name, string path, nfloat scale ) : SCNNode | ||
container | SCNNode | |
name | string | |
path | string | |
scale | nfloat | |
return | SCNNode |
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 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"); }
private SCNNode AddTeapot(int index, float x, SCNNode parent) { var teapotNode = Utils.SCAddChildNode(parent, "Teapot" + index, "Scenes/lod/lod", 11); teapotNode.Geometry.FirstMaterial.Reflective.Intensity = 0.8f; teapotNode.Geometry.FirstMaterial.FresnelExponent = 1.0f; var yOffset = index == 4 ? 0.0f : index * 20.0f; teapotNode.Position = new SCNVector3(x, -10 - yOffset, 0.1f); return(teapotNode); }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("Depth of Field"); TextManager.SetSubtitle("SCNCamera"); // Create a node that will contain the chess board var intermediateNode = SCNNode.Create(); intermediateNode.Scale = new SCNVector3(35.0f, 35.0f, 35.0f); intermediateNode.Position = new SCNVector3(0, 2.1f, 20); intermediateNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); ContentNode.AddChildNode(intermediateNode); // Load the chess model and add to "intermediateNode" Utils.SCAddChildNode(intermediateNode, "Line01", "Scenes/chess/chess", 1); }
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) { TextManager.SetTitle("Extending Scene Kit with OpenGL"); TextManager.SetSubtitle("Material custom program"); TextManager.AddBulletAtLevel("Custom GLSL code per material", 0); TextManager.AddBulletAtLevel("Overrides Scene Kit’s rendering", 0); TextManager.AddBulletAtLevel("Geometry attributes are provided", 0); TextManager.AddBulletAtLevel("Transform uniforms are also provided", 0); // Add a torus and animate it TorusNode = Utils.SCAddChildNode(GroundNode, "torus", "Scenes/torus/torus", 10); TorusNode.Position = new SCNVector3(8, 8, 4); TorusNode.Name = "object"; var rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 10.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); TorusNode.AddAnimation(rotationAnimation, new NSString("torusRotation")); }
public void ShowsNewInSceneKitBadge(bool showsBadge) { if (NewBadgeNode != null && showsBadge) { return; // already visible } if (NewBadgeNode == null && !showsBadge) { return; // already invisible } // Load the model and the animation if (NewBadgeNode == null) { NewBadgeNode = SCNNode.Create(); var badgeNode = Utils.SCAddChildNode(NewBadgeNode, "newBadge", "Scenes/newBadge", 1); NewBadgeNode.Scale = new SCNVector3(0.03f, 0.03f, 0.03f); NewBadgeNode.Opacity = 0; NewBadgeNode.Position = new SCNVector3(50, 20, -10); NewBadgeNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); var imageNode = NewBadgeNode.FindChildNode("badgeImage", true); imageNode.Geometry.FirstMaterial.Emission.Intensity = 0.0f; CameraPitch.AddChildNode(NewBadgeNode); NewBadgeAnimation = badgeNode.GetAnimation(badgeNode.GetAnimationKeys() [0]); badgeNode.RemoveAllAnimations(); NewBadgeAnimation.Speed = 1.5f; NewBadgeAnimation.FillMode = CAFillMode.Both; NewBadgeAnimation.UsesSceneTimeBase = false; NewBadgeAnimation.RemovedOnCompletion = false; } // Play if (showsBadge) { NewBadgeNode.AddAnimation(NewBadgeAnimation, new NSString("badgeAnimation")); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 2; NewBadgeNode.Position = new SCNVector3(14, 8, -20); SCNTransaction.SetCompletionBlock(() => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 3; if (NewBadgeNode != null) { SCNNode ropeNode = NewBadgeNode.FindChildNode("rope02", true); ropeNode.Opacity = 0.0f; } SCNTransaction.Commit(); }); NewBadgeNode.Opacity = 1.0f; SCNNode imageNode = NewBadgeNode.FindChildNode("badgeImage", true); imageNode.Geometry.FirstMaterial.Emission.Intensity = 0.4f; SCNTransaction.Commit(); } // Or hide else { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.5f; SCNTransaction.SetCompletionBlock(() => { if (NewBadgeNode != null) { NewBadgeNode.RemoveFromParentNode(); NewBadgeNode = null; } }); NewBadgeNode.Position = new SCNVector3(14, 50, -20); NewBadgeNode.Opacity = 0.0f; SCNTransaction.Commit(); } }
public override void SetupSlide(PresentationViewController presentationViewController) { // Set the slide's title and subtile and add some text TextManager.SetTitle("Node Attributes"); TextManager.SetSubtitle("Geometry"); 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/teapots/teapotLowRes", 17); TeapotNodeForUVs = Utils.SCAddChildNode(allTeapotsNode, "Teapot", "Scenes/teapots/teapot", 17); TeapotNodeForMaterials = Utils.SCAddChildNode(allTeapotsNode, "teapotMaterials", "Scenes/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.Normal.Intensity = 0.3f; 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); 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); TeapotNodeForPositionsAndNormals.AddChildNode(PositionsVisualizationNode); TeapotNodeForPositionsAndNormals.AddChildNode(NormalsVisualizationNode); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); switch (index) { case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.SetSubtitle("API"); TextManager.AddEmptyLine(); TextManager.AddCode("#aMaterial.#ShaderModifiers# = new SCNShaderModifiers {\n" + " <Entry Point> = <GLSL Code>\n" + "};#"); TextManager.FlipInText(SlideTextManager.TextType.Code); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); break; case 2: TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.AddEmptyLine(); TextManager.AddCode("#aMaterial.#ShaderModifiers# = new SCNShaderModifiers { \n" + " EntryCGPointragment = \n" + " new Vector3 (1.0f) - #output#.Color.GetRgb () \n" + "};#"); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 3: TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("Entry points"); TextManager.AddBulletAtLevel("Geometry", 0); TextManager.AddBulletAtLevel("Surface", 0); TextManager.AddBulletAtLevel("Lighting", 0); TextManager.AddBulletAtLevel("Fragment", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); break; case 4: SCNTransaction.AnimationDuration = 1; TextManager.HighlightBullet(0); // Create a (very) tesselated plane var plane = SCNPlane.Create(10, 10); plane.WidthSegmentCount = 200; plane.HeightSegmentCount = 200; // Setup the material (same as the floor) plane.FirstMaterial.Diffuse.WrapS = SCNWrapMode.Mirror; plane.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Mirror; plane.FirstMaterial.Diffuse.Contents = new NSImage("/Library/Desktop Pictures/Circles.jpg"); plane.FirstMaterial.Diffuse.ContentsTransform = SCNMatrix4.CreateFromAxisAngle(new SCNVector3(0, 0, 1), NMath.PI / 4); plane.FirstMaterial.Specular.Contents = NSColor.White; plane.FirstMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap", "jpg")); plane.FirstMaterial.Reflective.Intensity = 0.0f; // Create a node to hold that plane PlaneNode = SCNNode.Create(); PlaneNode.Position = new SCNVector3(0, 0.1f, 0); PlaneNode.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); PlaneNode.Scale = new SCNVector3(5, 5, 1); PlaneNode.Geometry = plane; ContentNode.AddChildNode(PlaneNode); // Attach the "wave" shader modifier, and set an initial intensity value of 0 var shaderFile = NSBundle.MainBundle.PathForResource("Shaders/wave", "shader"); var geometryModifier = File.ReadAllText(shaderFile); PlaneNode.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = geometryModifier }; PlaneNode.Geometry.SetValueForKey(new NSNumber(0.0f), new NSString("intensity")); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; // Show the pseudo code for the deformation var textNode = TextManager.AddCode("#float len = #geometry#.Position.Xy.Length;\n" + "aMaterial.ShaderModifiers = new SCNShaderModifiers { \n" + " #EntryPointGeometry# = geometry.Position.Y \n" + "};#"); textNode.Position = new SCNVector3(8.5f, 7, 0); SCNTransaction.Commit(); break; case 5: // Progressively increase the intensity SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 2; PlaneNode.Geometry.SetValueForKey(new NSNumber(1.0f), new NSString("intensity")); PlaneNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f; SCNTransaction.Commit(); // Redraw forever ((SCNView)presentationViewController.View).Playing = true; ((SCNView)presentationViewController.View).Loops = true; break; case 6: SCNTransaction.AnimationDuration = 1; TextManager.FadeOutText(SlideTextManager.TextType.Code); // Hide the plane used for the previous modifier PlaneNode.Geometry.SetValueForKey(new NSNumber(0.0f), new NSString("intensity")); PlaneNode.Geometry.FirstMaterial.Reflective.Intensity = 0.0f; PlaneNode.Opacity = 0.0f; // Create a sphere to illustrate the "car paint" modifier var sphere = SCNSphere.Create(6); sphere.SegmentCount = 100; sphere.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/noise", "png")); sphere.FirstMaterial.Diffuse.WrapS = SCNWrapMode.Repeat; sphere.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Repeat; sphere.FirstMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap3", "jpg")); sphere.FirstMaterial.FresnelExponent = 1.3f; SphereNode = SCNNode.FromGeometry(sphere); SphereNode.Position = new SCNVector3(5, 6, 0); GroundNode.AddChildNode(SphereNode); // Attach the "car paint" shader modifier shaderFile = NSBundle.MainBundle.PathForResource("Shaders/carPaint", "shader"); var surfaceModifier = File.ReadAllText(shaderFile); sphere.FirstMaterial.ShaderModifiers = new SCNShaderModifiers { EntryPointSurface = surfaceModifier }; var rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 15.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.By = NSValue.FromVector(new SCNVector4(0, 1, 0, -(float)(Math.PI * 2))); SphereNode.AddAnimation(rotationAnimation, new NSString("sphereNodeAnimation")); TextManager.HighlightBullet(1); break; case 7: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.5f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); // Move the camera closer presentationViewController.CameraNode.Position = new SCNVector3(5, -0.5f, -17); SCNTransaction.Commit(); break; case 8: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); // Move back presentationViewController.CameraNode.Position = new SCNVector3(0, 0, 0); SCNTransaction.Commit(); break; case 9: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; // Hide the sphere used for the previous modifier SphereNode.Opacity = 0.0f; SphereNode.Position = new SCNVector3(6, 4, -8); SCNTransaction.Commit(); SCNTransaction.AnimationDuration = 0; TextManager.HighlightBullet(2); // Load the model, animate var intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(4, 0.1f, 10); TorusNode = Utils.SCAddChildNode(intermediateNode, "torus", "Scenes/torus/torus", 11); rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 10.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); TorusNode.AddAnimation(rotationAnimation, new NSString("torusNodeAnimation")); GroundNode.AddChildNode(intermediateNode); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; intermediateNode.Position = new SCNVector3(4, 0.1f, 0); SCNTransaction.Commit(); break; case 10: // Attach the shader modifier shaderFile = NSBundle.MainBundle.PathForResource("Shaders/toon", "shader"); var lightingModifier = File.ReadAllText(shaderFile); TorusNode.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointLightingModel = lightingModifier }; break; case 11: SCNTransaction.AnimationDuration = 1.0f; // Hide the torus used for the previous modifier TorusNode.Position = new SCNVector3(TorusNode.Position.X, TorusNode.Position.Y, TorusNode.Position.Z - 10); TorusNode.Opacity = 0.0f; // Load the model, animate intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(4, -2.6f, 14); intermediateNode.Scale = new SCNVector3(70, 70, 70); XRayNode = Utils.SCAddChildNode(intermediateNode, "node", "Scenes/bunny", 12); XRayNode.Position = new SCNVector3(0, 0, 0); XRayNode.Opacity = 0.0f; GroundNode.AddChildNode(intermediateNode); rotationAnimation = CABasicAnimation.FromKeyPath("rotation"); rotationAnimation.Duration = 10.0f; rotationAnimation.RepeatCount = float.MaxValue; rotationAnimation.From = NSValue.FromVector(new SCNVector4(0, 1, 0, 0)); rotationAnimation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); intermediateNode.AddAnimation(rotationAnimation, new NSString("bunnyNodeAnimation")); TextManager.HighlightBullet(3); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; XRayNode.Opacity = 1.0f; intermediateNode.Position = new SCNVector3(4, -2.6f, -2); SCNTransaction.Commit(); break; case 12: // Attach the "x ray" modifier shaderFile = NSBundle.MainBundle.PathForResource("Shaders/xRay", "shader"); var fragmentModifier = File.ReadAllText(shaderFile); XRayNode.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointFragment = fragmentModifier }; XRayNode.Geometry.FirstMaterial.ReadsFromDepthBuffer = false; break; case 13: // Highlight everything TextManager.HighlightBullet(-1); // Hide the node used for the previous modifier XRayNode.Opacity = 0.0f; XRayNode.ParentNode.Position = new SCNVector3(4, -2.6f, -5); // Create the model sphere = SCNSphere.Create(5); sphere.SegmentCount = 150; // tesselate a lot VirusNode = SCNNode.FromGeometry(sphere); VirusNode.Position = new SCNVector3(3, 6, 0); VirusNode.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)(Math.PI / 180.0f)); GroundNode.AddChildNode(VirusNode); // Set the shader modifiers var geomFile = NSBundle.MainBundle.PathForResource("Shaders/sm_geom", "shader"); var surfFile = NSBundle.MainBundle.PathForResource("Shaders/sm_surf", "shader"); var lightFile = NSBundle.MainBundle.PathForResource("Shaders/sm_light", "shader"); var fragFile = NSBundle.MainBundle.PathForResource("Shaders/sm_frag", "shader"); geometryModifier = File.ReadAllText(geomFile); surfaceModifier = File.ReadAllText(surfFile); lightingModifier = File.ReadAllText(lightFile); fragmentModifier = File.ReadAllText(fragFile); VirusNode.Geometry.FirstMaterial.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = geometryModifier, EntryPointSurface = surfaceModifier, EntryPointLightingModel = lightingModifier, EntryPointFragment = fragmentModifier }; break; case 14: SCNTransaction.AnimationDuration = 1.0f; // Hide the node used for the previous modifier VirusNode.Opacity = 0.0f; VirusNode.Position = new SCNVector3(3, 6, -10); // Change the text TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("SCNShadable"); TextManager.AddBulletAtLevel("Protocol adopted by SCNMaterial and SCNGeometry", 0); TextManager.AddBulletAtLevel("Shaders parameters are animatable", 0); TextManager.AddBulletAtLevel("Texture samplers are bound to a SCNMaterialProperty", 0); TextManager.AddCode("#var aProperty = SCNMaterialProperty.#Create# (anImage);\n" + "aMaterial.#SetValueForKey# (aProperty, #new NSString# (\"aSampler\"));#"); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 1: // Load the scene var intermediateNode = SCNNode.Create(); intermediateNode.Position = new SCNVector3(0.0f, 0.1f, -24.5f); intermediateNode.Scale = new SCNVector3(2.3f, 1.0f, 1.0f); intermediateNode.Opacity = 0.0f; RoomNode = Utils.SCAddChildNode(intermediateNode, "Mesh", "Scenes/cornell-box/cornell-box", 15); ContentNode.AddChildNode(intermediateNode); // Hide the light maps for now foreach (var material in RoomNode.Geometry.Materials) { material.Multiply.Intensity = 0.0f; material.LightingModelName = SCNLightingModel.Blinn; } // Animate the point of view with an implicit animation. // On completion add to move the camera from right to left and back and forth. SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; SCNTransaction.SetCompletionBlock(() => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 2; SCNTransaction.SetCompletionBlock(() => { var animation = CABasicAnimation.FromKeyPath("position"); animation.Duration = 10.0f; animation.Additive = true; animation.To = NSValue.FromVector(new SCNVector3(-5, 0, 0)); animation.From = NSValue.FromVector(new SCNVector3(5, 0, 0)); animation.TimeOffset = -animation.Duration / 2; animation.AutoReverses = true; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.RepeatCount = float.MaxValue; presentationViewController.CameraNode.AddAnimation(animation, new NSString("myAnim")); }); presentationViewController.CameraHandle.Position = presentationViewController.CameraHandle.ConvertPositionToNode(new SCNVector3(0, +5, -30), presentationViewController.CameraHandle.ParentNode); presentationViewController.CameraPitch.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 4) * 0.2f); SCNTransaction.Commit(); }); intermediateNode.Opacity = 1.0f; SCNTransaction.Commit(); break; case 2: // Remove the lighting by using a constant lighing model (no lighting) foreach (var material in RoomNode.Geometry.Materials) { material.LightingModelName = SCNLightingModel.Constant; } break; case 3: // Activate the light maps smoothly SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; foreach (var material in RoomNode.Geometry.Materials) { material.Multiply.Intensity = 1.0f; } SCNTransaction.Commit(); break; } }