public UpdateLightingWithIntensities ( float intensities ) : void | ||
intensities | float | |
return | void |
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 [4] { 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: // Set the slide's title and subtitle TextManager.SetTitle("Scene Graph"); TextManager.SetSubtitle("Summary"); break; case 1: // A node that will help visualize the position of the stars WireframeBoxNode = SCNNode.Create(); WireframeBoxNode.Rotation = new SCNVector4(0, 1, 0, (float)(Math.PI / 4)); WireframeBoxNode.Geometry = SCNBox.Create(1, 1, 1, 0); WireframeBoxNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/box_wireframe", "png")); WireframeBoxNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting WireframeBoxNode.Geometry.FirstMaterial.DoubleSided = true; // double sided // Sun SunNode = SCNNode.Create(); SunNode.Position = new SCNVector3(0, 30, 0); ContentNode.AddChildNode(SunNode); SunNode.AddChildNode((SCNNode)WireframeBoxNode.Copy()); // Earth-rotation (center of rotation of the Earth around the Sun) var earthRotationNode = SCNNode.Create(); SunNode.AddChildNode(earthRotationNode); // Earth-group (will contain the Earth, and the Moon) EarthGroupNode = SCNNode.Create(); EarthGroupNode.Position = new SCNVector3(15, 0, 0); earthRotationNode.AddChildNode(EarthGroupNode); // Earth EarthNode = (SCNNode)WireframeBoxNode.Copy(); EarthNode.Position = new SCNVector3(0, 0, 0); EarthGroupNode.AddChildNode(EarthNode); // Rotate the Earth around the Sun var animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 10.0f; animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; earthRotationNode.AddAnimation(animation, new NSString("earth rotation around sun")); // Rotate the Earth animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 1.0f; animation.From = NSValue.FromVector(new SCNVector4(0, 1, 0, 0)); animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; EarthNode.AddAnimation(animation, new NSString("earth rotation")); break; case 2: // Moon-rotation (center of rotation of the Moon around the Earth) var moonRotationNode = SCNNode.Create(); EarthGroupNode.AddChildNode(moonRotationNode); // Moon MoonNode = (SCNNode)WireframeBoxNode.Copy(); MoonNode.Position = new SCNVector3(5, 0, 0); moonRotationNode.AddChildNode(MoonNode); // Rotate the moon around the Earth animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 1.5f; animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; moonRotationNode.AddAnimation(animation, new NSString("moon rotation around earth")); // Rotate the moon animation = CABasicAnimation.FromKeyPath("rotation"); animation.Duration = 1.5f; animation.To = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; MoonNode.AddAnimation(animation, new NSString("moon rotation")); break; case 3: // Add geometries (spheres) to represent the stars SunNode.Geometry = SCNSphere.Create(2.5f); EarthNode.Geometry = SCNSphere.Create(1.5f); MoonNode.Geometry = SCNSphere.Create(0.75f); // Add a textured plane to represent Earth's orbit var earthOrbit = SCNNode.Create(); earthOrbit.Opacity = 0.4f; earthOrbit.Geometry = SCNPlane.Create(31, 31); earthOrbit.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/orbit", "png")); earthOrbit.Geometry.FirstMaterial.Diffuse.MipFilter = SCNFilterMode.Linear; earthOrbit.Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)); earthOrbit.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting SunNode.AddChildNode(earthOrbit); break; case 4: // Add a halo to the Sun (a simple textured plane that does not write to depth) SunHaloNode = SCNNode.Create(); SunHaloNode.Geometry = SCNPlane.Create(30, 30); SunHaloNode.Rotation = new SCNVector4(1, 0, 0, Pitch * (float)(Math.PI / 180.0f)); SunHaloNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/sun-halo", "png")); SunHaloNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting SunHaloNode.Geometry.FirstMaterial.WritesToDepthBuffer = false; // do not write to depth SunHaloNode.Opacity = 0.2f; SunNode.AddChildNode(SunHaloNode); // Add materials to the stars EarthNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-diffuse-mini", "jpg")); EarthNode.Geometry.FirstMaterial.Emission.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-emissive-mini", "jpg")); EarthNode.Geometry.FirstMaterial.Specular.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-specular-mini", "jpg")); MoonNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/moon", "jpg")); SunNode.Geometry.FirstMaterial.Multiply.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/sun", "jpg")); SunNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/sun", "jpg")); SunNode.Geometry.FirstMaterial.Multiply.Intensity = 0.5f; SunNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; SunNode.Geometry.FirstMaterial.Multiply.WrapS = SunNode.Geometry.FirstMaterial.Diffuse.WrapS = SunNode.Geometry.FirstMaterial.Multiply.WrapT = SunNode.Geometry.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Repeat; EarthNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = MoonNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = SunNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = true; EarthNode.Geometry.FirstMaterial.Shininess = 0.1f; EarthNode.Geometry.FirstMaterial.Specular.Intensity = 0.5f; MoonNode.Geometry.FirstMaterial.Specular.Contents = NSColor.Gray; // Achieve a lava effect by animating textures animation = CABasicAnimation.FromKeyPath("contentsTransform"); animation.Duration = 10.0f; var animationTransform1 = CATransform3D.MakeTranslation(0, 0, 0); animationTransform1 = animationTransform1.Concat(CATransform3D.MakeScale(3, 3, 3)); var animationTransform2 = CATransform3D.MakeTranslation(1, 0, 0); animationTransform2 = animationTransform1.Concat(CATransform3D.MakeScale(3, 3, 3)); animation.From = NSValue.FromCATransform3D(animationTransform1); animation.To = NSValue.FromCATransform3D(animationTransform2); animation.RepeatCount = float.MaxValue; SunNode.Geometry.FirstMaterial.Diffuse.AddAnimation(animation, new NSString("sun-texture")); animation = CABasicAnimation.FromKeyPath("contentsTransform"); animation.Duration = 30.0f; animationTransform1 = CATransform3D.MakeTranslation(0, 0, 0); animationTransform1 = animationTransform1.Concat(CATransform3D.MakeScale(5, 5, 5)); animationTransform2 = CATransform3D.MakeTranslation(1, 0, 0); animationTransform2 = animationTransform1.Concat(CATransform3D.MakeScale(5, 5, 5)); animation.From = NSValue.FromCATransform3D(animationTransform1); animation.To = NSValue.FromCATransform3D(animationTransform2); animation.RepeatCount = float.MaxValue; SunNode.Geometry.FirstMaterial.Multiply.AddAnimation(animation, new NSString("sun-texture2")); break; case 5: // We will turn off all the lights in the scene and add a new light // to give the impression that the Sun lights the scene var lightNode = SCNNode.Create(); lightNode.Light = SCNLight.Create(); lightNode.Light.Color = NSColor.Black; // initially switched off lightNode.Light.LightType = SCNLightType.Omni; SunNode.AddChildNode(lightNode); // Configure attenuation distances because we don't want to light the floor lightNode.Light.SetAttribute(new NSNumber(20), SCNLightAttribute.AttenuationEndKey); lightNode.Light.SetAttribute(new NSNumber(19.5), SCNLightAttribute.AttenuationStartKey); // Animation SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; lightNode.Light.Color = NSColor.White; // switch on presentationViewController.UpdateLightingWithIntensities(new float[] { 0.0f }); //switch off all the other lights SunHaloNode.Opacity = 0.5f; // make the halo stronger 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: // Set the slide's title and subtitle TextManager.SetTitle ("Scene Graph"); TextManager.SetSubtitle ("Summary"); break; case 1: // A node that will help visualize the position of the stars WireframeBoxNode = SCNNode.Create (); WireframeBoxNode.Rotation = new SCNVector4 (0, 1, 0, (float)(Math.PI / 4)); WireframeBoxNode.Geometry = SCNBox.Create (1, 1, 1, 0); WireframeBoxNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("SharedTextures/box_wireframe", "png")); WireframeBoxNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting WireframeBoxNode.Geometry.FirstMaterial.DoubleSided = true; // double sided // Sun SunNode = SCNNode.Create (); SunNode.Position = new SCNVector3 (0, 30, 0); ContentNode.AddChildNode (SunNode); SunNode.AddChildNode ((SCNNode)WireframeBoxNode.Copy ()); // Earth-rotation (center of rotation of the Earth around the Sun) var earthRotationNode = SCNNode.Create (); SunNode.AddChildNode (earthRotationNode); // Earth-group (will contain the Earth, and the Moon) EarthGroupNode = SCNNode.Create (); EarthGroupNode.Position = new SCNVector3 (15, 0, 0); earthRotationNode.AddChildNode (EarthGroupNode); // Earth EarthNode = (SCNNode)WireframeBoxNode.Copy (); EarthNode.Position = new SCNVector3 (0, 0, 0); EarthGroupNode.AddChildNode (EarthNode); // Rotate the Earth around the Sun var animation = CABasicAnimation.FromKeyPath ("rotation"); animation.Duration = 10.0f; animation.To = NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; earthRotationNode.AddAnimation (animation, new NSString ("earth rotation around sun")); // Rotate the Earth animation = CABasicAnimation.FromKeyPath ("rotation"); animation.Duration = 1.0f; animation.From = NSValue.FromVector (new SCNVector4 (0, 1, 0, 0)); animation.To = NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; EarthNode.AddAnimation (animation, new NSString ("earth rotation")); break; case 2: // Moon-rotation (center of rotation of the Moon around the Earth) var moonRotationNode = SCNNode.Create (); EarthGroupNode.AddChildNode (moonRotationNode); // Moon MoonNode = (SCNNode)WireframeBoxNode.Copy (); MoonNode.Position = new SCNVector3 (5, 0, 0); moonRotationNode.AddChildNode (MoonNode); // Rotate the moon around the Earth animation = CABasicAnimation.FromKeyPath ("rotation"); animation.Duration = 1.5f; animation.To = NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; moonRotationNode.AddAnimation (animation, new NSString ("moon rotation around earth")); // Rotate the moon animation = CABasicAnimation.FromKeyPath ("rotation"); animation.Duration = 1.5f; animation.To = NSValue.FromVector (new SCNVector4 (0, 1, 0, (float)(Math.PI * 2))); animation.RepeatCount = float.MaxValue; MoonNode.AddAnimation (animation, new NSString ("moon rotation")); break; case 3: // Add geometries (spheres) to represent the stars SunNode.Geometry = SCNSphere.Create (2.5f); EarthNode.Geometry = SCNSphere.Create (1.5f); MoonNode.Geometry = SCNSphere.Create (0.75f); // Add a textured plane to represent Earth's orbit var earthOrbit = SCNNode.Create (); earthOrbit.Opacity = 0.4f; earthOrbit.Geometry = SCNPlane.Create (31, 31); earthOrbit.Geometry.FirstMaterial.Diffuse.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/orbit", "png")); earthOrbit.Geometry.FirstMaterial.Diffuse.MipFilter = SCNFilterMode.Linear; earthOrbit.Rotation = new SCNVector4 (1, 0, 0, -(float)(Math.PI / 2)); earthOrbit.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting SunNode.AddChildNode (earthOrbit); break; case 4: // Add a halo to the Sun (a simple textured plane that does not write to depth) SunHaloNode = SCNNode.Create (); SunHaloNode.Geometry = SCNPlane.Create (30, 30); SunHaloNode.Rotation = new SCNVector4 (1, 0, 0, Pitch * (float)(Math.PI / 180.0f)); SunHaloNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/sun-halo", "png")); SunHaloNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; // no lighting SunHaloNode.Geometry.FirstMaterial.WritesToDepthBuffer = false; // do not write to depth SunHaloNode.Opacity = 0.2f; SunNode.AddChildNode (SunHaloNode); // Add materials to the stars EarthNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-diffuse-mini", "jpg")); EarthNode.Geometry.FirstMaterial.Emission.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-emissive-mini", "jpg")); EarthNode.Geometry.FirstMaterial.Specular.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-specular-mini", "jpg")); MoonNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/moon", "jpg")); SunNode.Geometry.FirstMaterial.Multiply.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/sun", "jpg")); SunNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/sun", "jpg")); SunNode.Geometry.FirstMaterial.Multiply.Intensity = 0.5f; SunNode.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; SunNode.Geometry.FirstMaterial.Multiply.WrapS = SunNode.Geometry.FirstMaterial.Diffuse.WrapS = SunNode.Geometry.FirstMaterial.Multiply.WrapT = SunNode.Geometry.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Repeat; EarthNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = MoonNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = SunNode.Geometry.FirstMaterial.LocksAmbientWithDiffuse = true; EarthNode.Geometry.FirstMaterial.Shininess = 0.1f; EarthNode.Geometry.FirstMaterial.Specular.Intensity = 0.5f; MoonNode.Geometry.FirstMaterial.Specular.Contents = NSColor.Gray; // Achieve a lava effect by animating textures animation = CABasicAnimation.FromKeyPath ("contentsTransform"); animation.Duration = 10.0f; var animationTransform1 = CATransform3D.MakeTranslation (0, 0, 0); animationTransform1 = animationTransform1.Concat (CATransform3D.MakeScale (3, 3, 3)); var animationTransform2 = CATransform3D.MakeTranslation (1, 0, 0); animationTransform2 = animationTransform1.Concat (CATransform3D.MakeScale (3, 3, 3)); animation.From = NSValue.FromCATransform3D (animationTransform1); animation.To = NSValue.FromCATransform3D (animationTransform2); animation.RepeatCount = float.MaxValue; SunNode.Geometry.FirstMaterial.Diffuse.AddAnimation (animation, new NSString ("sun-texture")); animation = CABasicAnimation.FromKeyPath ("contentsTransform"); animation.Duration = 30.0f; animationTransform1 = CATransform3D.MakeTranslation (0, 0, 0); animationTransform1 = animationTransform1.Concat (CATransform3D.MakeScale (5, 5, 5)); animationTransform2 = CATransform3D.MakeTranslation (1, 0, 0); animationTransform2 = animationTransform1.Concat (CATransform3D.MakeScale (5, 5, 5)); animation.From = NSValue.FromCATransform3D (animationTransform1); animation.To = NSValue.FromCATransform3D (animationTransform2); animation.RepeatCount = float.MaxValue; SunNode.Geometry.FirstMaterial.Multiply.AddAnimation (animation, new NSString ("sun-texture2")); break; case 5: // We will turn off all the lights in the scene and add a new light // to give the impression that the Sun lights the scene var lightNode = SCNNode.Create (); lightNode.Light = SCNLight.Create (); lightNode.Light.Color = NSColor.Black; // initially switched off lightNode.Light.LightType = SCNLightType.Omni; SunNode.AddChildNode (lightNode); // Configure attenuation distances because we don't want to light the floor lightNode.Light.SetAttribute (new NSNumber (20), SCNLightAttribute.AttenuationEndKey); lightNode.Light.SetAttribute (new NSNumber (19.5), SCNLightAttribute.AttenuationStartKey); // Animation SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1; lightNode.Light.Color = NSColor.White; // switch on presentationViewController.UpdateLightingWithIntensities (new float[] { 0.0f }); //switch off all the other lights SunHaloNode.Opacity = 0.5f; // make the halo stronger SCNTransaction.Commit (); break; } }
public override void PresentStep (int index, PresentationViewController presentationViewController) { SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1.0f; switch (index) { case 0: // Set the slide's title and add some code TextManager.SetTitle ("Materials"); TextManager.AddBulletAtLevel ("Diffuse", 0); TextManager.AddBulletAtLevel ("Ambient", 0); TextManager.AddBulletAtLevel ("Specular and shininess", 0); TextManager.AddBulletAtLevel ("Normal", 0); TextManager.AddBulletAtLevel ("Reflective", 0); TextManager.AddBulletAtLevel ("Emission", 0); TextManager.AddBulletAtLevel ("Transparent", 0); TextManager.AddBulletAtLevel ("Multiply", 0); break; case 1: EarthNode.Opacity = 1.0f; presentationViewController.UpdateLightingWithIntensities (new float[] { 1 }); break; case 2: EarthNode.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Blue; TextManager.HighlightBullet (0); ShowCodeExample ("#material.#diffuse.contents# = [NSColor blueColor];#", null, null); break; case 3: EarthNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-diffuse", "jpg")); ShowCodeExample ("#material.#diffuse.contents# =#", "earth-diffuse-mini", "jpg"); break; case 4: EarthNode.Geometry.FirstMaterial.Ambient.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-diffuse", "jpg")); EarthNode.Geometry.FirstMaterial.Ambient.Intensity = 1; TextManager.HighlightBullet (1); ShowCodeExample ("#material.#ambient#.contents =#", "earth-diffuse-mini", "jpg"); presentationViewController.UpdateLightingWithIntensities (LightIntensities); break; case 5: EarthNode.Geometry.FirstMaterial.Shininess = 0.1f; EarthNode.Geometry.FirstMaterial.Specular.Contents = NSColor.White; TextManager.HighlightBullet (2); ShowCodeExample ("#material.#specular#.contents = [NSColor whiteColor];#", null, null); break; case 6: EarthNode.Geometry.FirstMaterial.Specular.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-specular", "jpg")); ShowCodeExample ("#material.#specular#.contents =#", "earth-specular-mini", "jpg"); break; case 7: EarthNode.Geometry.FirstMaterial.Normal.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-bump", "png")); EarthNode.Geometry.FirstMaterial.Normal.Intensity = 1.3f; TextManager.HighlightBullet (3); ShowCodeExample ("#material.#normal#.contents =#", "earth-bump", "png"); break; case 8: EarthNode.Geometry.FirstMaterial.Reflective.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-reflective", "jpg")); EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.7f; EarthNode.Geometry.FirstMaterial.Specular.Intensity = 0.0f; SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 2.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName (CAMediaTimingFunction.EaseInEaseOut); CameraOriginalPosition = presentationViewController.CameraHandle.Position; presentationViewController.CameraHandle.Position = presentationViewController.CameraHandle.ConvertPositionToNode (new SCNVector3 (6, 0, -10.11f), presentationViewController.CameraHandle.ParentNode); SCNTransaction.Commit (); TextManager.HighlightBullet (4); ShowCodeExample ("material.#reflective#.contents =", "earth-reflective", "jpg"); break; case 9: SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName (CAMediaTimingFunction.EaseInEaseOut); presentationViewController.CameraHandle.Position = CameraOriginalPosition; SCNTransaction.Commit (); break; case 10: EarthNode.Geometry.FirstMaterial.Emission.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/earth-emissive", "jpg")); EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f; EarthNode.Geometry.FirstMaterial.Emission.Intensity = 0.5f; TextManager.HighlightBullet (5); ShowCodeExample ("material.#emission#.contents =", "earth-emissive-mini2", "jpg"); break; case 11: EarthNode.Geometry.FirstMaterial.Emission.Intensity = 1.0f; EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.1f; ShowCodeExample (null, null, null); presentationViewController.UpdateLightingWithIntensities (new float[] { 0.01f }); // keeping the intensity non null avoids an unnecessary shader recompilation break; case 12: EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f; presentationViewController.UpdateLightingWithIntensities (LightIntensities); break; case 13: EarthNode.Geometry.FirstMaterial.Emission.Intensity = 0.0f; CloudsNode.Opacity = 0.9f; TextManager.HighlightBullet (6); break; case 14: // This effect can also be achieved with an image with some transparency set as the contents of the 'diffuse' property CloudsNode.Geometry.FirstMaterial.Transparent.Contents = new NSImage (NSBundle.MainBundle.PathForResource ("Scenes/earth/cloudsTransparency", "png")); CloudsNode.Geometry.FirstMaterial.TransparencyMode = SCNTransparencyMode.RgbZero; SCNTransaction.Begin (); SCNTransaction.AnimationDuration = 0; CloudsNode.Geometry.FirstMaterial.Transparency = 0; SCNTransaction.Commit (); CloudsNode.Geometry.FirstMaterial.Transparency = 1; ShowCodeExample ("material.#transparent#.contents =", "cloudsTransparency-mini", "png"); break; case 15: EarthNode.Geometry.FirstMaterial.Multiply.Contents = NSColor.FromDeviceRgba (1.0f, (float)(204 / 255.0), (float)(102 / 255.0), 1); TextManager.HighlightBullet (7); ShowCodeExample ("material.#mutliply#.contents = [NSColor yellowColor];", null, null); break; case 16: EarthNode.Geometry.FirstMaterial.Emission.Intensity = 1.0f; EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.1f; ShowCodeExample (null, null, null); presentationViewController.UpdateLightingWithIntensities (new float[] { 0.01f }); break; case 17: EarthNode.Geometry.FirstMaterial.Emission.Intensity = 0.0f; EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f; presentationViewController.UpdateLightingWithIntensities (LightIntensities); break; } SCNTransaction.Commit (); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; switch (index) { case 0: // Set the slide's title and add some code TextManager.SetTitle("Materials"); TextManager.AddBulletAtLevel("Diffuse", 0); TextManager.AddBulletAtLevel("Ambient", 0); TextManager.AddBulletAtLevel("Specular and shininess", 0); TextManager.AddBulletAtLevel("Normal", 0); TextManager.AddBulletAtLevel("Reflective", 0); TextManager.AddBulletAtLevel("Emission", 0); TextManager.AddBulletAtLevel("Transparent", 0); TextManager.AddBulletAtLevel("Multiply", 0); break; case 1: EarthNode.Opacity = 1.0f; presentationViewController.UpdateLightingWithIntensities(new float[] { 1 }); break; case 2: EarthNode.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Blue; TextManager.HighlightBullet(0); ShowCodeExample("#material.#diffuse.contents# = [NSColor blueColor];#", null, null); break; case 3: EarthNode.Geometry.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-diffuse", "jpg")); ShowCodeExample("#material.#diffuse.contents# =#", "earth-diffuse-mini", "jpg"); break; case 4: EarthNode.Geometry.FirstMaterial.Ambient.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-diffuse", "jpg")); EarthNode.Geometry.FirstMaterial.Ambient.Intensity = 1; TextManager.HighlightBullet(1); ShowCodeExample("#material.#ambient#.contents =#", "earth-diffuse-mini", "jpg"); presentationViewController.UpdateLightingWithIntensities(LightIntensities); break; case 5: EarthNode.Geometry.FirstMaterial.Shininess = 0.1f; EarthNode.Geometry.FirstMaterial.Specular.Contents = NSColor.White; TextManager.HighlightBullet(2); ShowCodeExample("#material.#specular#.contents = [NSColor whiteColor];#", null, null); break; case 6: EarthNode.Geometry.FirstMaterial.Specular.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-specular", "jpg")); ShowCodeExample("#material.#specular#.contents =#", "earth-specular-mini", "jpg"); break; case 7: EarthNode.Geometry.FirstMaterial.Normal.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-bump", "png")); EarthNode.Geometry.FirstMaterial.Normal.Intensity = 1.3f; TextManager.HighlightBullet(3); ShowCodeExample("#material.#normal#.contents =#", "earth-bump", "png"); break; case 8: EarthNode.Geometry.FirstMaterial.Reflective.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-reflective", "jpg")); EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.7f; EarthNode.Geometry.FirstMaterial.Specular.Intensity = 0.0f; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 2.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); CameraOriginalPosition = presentationViewController.CameraHandle.Position; presentationViewController.CameraHandle.Position = presentationViewController.CameraHandle.ConvertPositionToNode(new SCNVector3(6, 0, -10.11f), presentationViewController.CameraHandle.ParentNode); SCNTransaction.Commit(); TextManager.HighlightBullet(4); ShowCodeExample("material.#reflective#.contents =", "earth-reflective", "jpg"); break; case 9: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); presentationViewController.CameraHandle.Position = CameraOriginalPosition; SCNTransaction.Commit(); break; case 10: EarthNode.Geometry.FirstMaterial.Emission.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/earth-emissive", "jpg")); EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f; EarthNode.Geometry.FirstMaterial.Emission.Intensity = 0.5f; TextManager.HighlightBullet(5); ShowCodeExample("material.#emission#.contents =", "earth-emissive-mini2", "jpg"); break; case 11: EarthNode.Geometry.FirstMaterial.Emission.Intensity = 1.0f; EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.1f; ShowCodeExample(null, null, null); presentationViewController.UpdateLightingWithIntensities(new float[] { 0.01f }); // keeping the intensity non null avoids an unnecessary shader recompilation break; case 12: EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f; presentationViewController.UpdateLightingWithIntensities(LightIntensities); break; case 13: EarthNode.Geometry.FirstMaterial.Emission.Intensity = 0.0f; CloudsNode.Opacity = 0.9f; TextManager.HighlightBullet(6); break; case 14: // This effect can also be achieved with an image with some transparency set as the contents of the 'diffuse' property CloudsNode.Geometry.FirstMaterial.Transparent.Contents = new NSImage(NSBundle.MainBundle.PathForResource("Scenes/earth/cloudsTransparency", "png")); CloudsNode.Geometry.FirstMaterial.TransparencyMode = SCNTransparencyMode.RgbZero; SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; CloudsNode.Geometry.FirstMaterial.Transparency = 0; SCNTransaction.Commit(); CloudsNode.Geometry.FirstMaterial.Transparency = 1; ShowCodeExample("material.#transparent#.contents =", "cloudsTransparency-mini", "png"); break; case 15: EarthNode.Geometry.FirstMaterial.Multiply.Contents = NSColor.FromDeviceRgba(1.0f, (float)(204 / 255.0), (float)(102 / 255.0), 1); TextManager.HighlightBullet(7); ShowCodeExample("material.#mutliply#.contents = [NSColor yellowColor];", null, null); break; case 16: EarthNode.Geometry.FirstMaterial.Emission.Intensity = 1.0f; EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.1f; ShowCodeExample(null, null, null); presentationViewController.UpdateLightingWithIntensities(new float[] { 0.01f }); break; case 17: EarthNode.Geometry.FirstMaterial.Emission.Intensity = 0.0f; EarthNode.Geometry.FirstMaterial.Reflective.Intensity = 0.3f; presentationViewController.UpdateLightingWithIntensities(LightIntensities); break; } SCNTransaction.Commit(); }