public PresentationViewController(string path) { // Load the presentation settings from the plist file var settingsPath = NSBundle.MainBundle.PathForResource(path, "xml"); SlideSettings = JsonConvert.DeserializeObject <Settings> (File.ReadAllText(settingsPath)); SlideCache = new Dictionary <string, Slide> (); // Create a new empty scene Scene = new SCNScene(); // Create and add a camera to the scene // We create three separate nodes to ease the manipulation of the global position, pitch (ie. orientation around the x axis) and relative position // - cameraHandle is used to control the global position in world space // - cameraPitch is used to rotate the position around the x axis // - cameraNode is sometimes manipulated by slides to move the camera relatively to the global position (cameraHandle). But this node is supposed to always be repositioned at (0, 0, 0) in the end of a slide. CameraHandle = SCNNode.Create(); CameraHandle.Name = "cameraHandle"; Scene.RootNode.AddChildNode(CameraHandle); CameraPitch = SCNNode.Create(); CameraPitch.Name = "cameraPitch"; CameraHandle.AddChildNode(CameraPitch); CameraNode = SCNNode.Create(); CameraNode.Name = "cameraNode"; CameraNode.Camera = new SCNCamera(); // Set the default field of view to 70 degrees (a relatively strong perspective) CameraNode.Camera.XFov = 70.0; CameraNode.Camera.YFov = 42.0; CameraPitch.AddChildNode(CameraNode); // Setup the different lights InitLighting(); // Create and add a reflective floor to the scene var floorMaterial = new SCNMaterial(); floorMaterial.Ambient.Contents = NSColor.Black; floorMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/floor", "png")); floorMaterial.Diffuse.ContentsTransform = SCNMatrix4.CreateFromAxisAngle(new SCNVector3(0, 0, 1), NMath.PI / 4); floorMaterial.Specular.WrapS = floorMaterial.Specular.WrapT = floorMaterial.Diffuse.WrapS = floorMaterial.Diffuse.WrapT = SCNWrapMode.Mirror; Floor = SCNFloor.Create(); Floor.ReflectionFalloffEnd = 3.0f; Floor.FirstMaterial = floorMaterial; var floorNode = SCNNode.Create(); floorNode.Geometry = Floor; Scene.RootNode.AddChildNode(floorNode); floorNode.PhysicsBody = SCNPhysicsBody.CreateStaticBody(); //make floor dynamic for physics slides Scene.PhysicsWorld.Speed = 0; //pause physics to avoid continuous drawing // Use a shader modifier to support a secondary texture for some slides var shaderFile = NSBundle.MainBundle.PathForResource("Shaders/floor", "shader"); var surfaceModifier = File.ReadAllText(shaderFile); floorMaterial.ShaderModifiers = new SCNShaderModifiers { EntryPointSurface = surfaceModifier }; // Set the scene to the view View = new SCNView(CGRect.Empty); ((SCNView)View).Scene = Scene; ((SCNView)View).BackgroundColor = NSColor.Black; // black fog Scene.FogColor = NSColor.FromCalibratedWhite(0, 1); Scene.FogEndDistance = 45; Scene.FogStartDistance = 40; // Turn on jittering for better anti-aliasing when the scene is still ((SCNView)View).JitteringEnabled = true; // Start the presentation GoToSlide(0); }
public void InitLighting() { // Omni light (main light of the scene) Lights [(int)Light.Main] = new SCNNode { Name = "omni", Position = new SCNVector3(0, 3, -13) }; Lights [(int)Light.Main].Light = new SCNLight { LightType = SCNLightType.Omni, AttenuationStartDistance = 10, AttenuationEndDistance = 50, Color = NSColor.Black }; CameraHandle.AddChildNode(Lights [(int)Light.Main]); //make all lights relative to the camera node // Front light Lights [(int)Light.Front] = new SCNNode { Name = "front light", Position = new SCNVector3(0, 0, 0) }; Lights [(int)Light.Front].Light = new SCNLight { LightType = SCNLightType.Directional, Color = NSColor.Black }; CameraHandle.AddChildNode(Lights [(int)Light.Front]); // Spot light Lights [(int)Light.Spot] = new SCNNode { Name = "spot light", Transform = SCNMatrix4.Mult(SCNMatrix4.CreateFromAxisAngle(new SCNVector3(1, 0, 0), -(nfloat)(Math.PI / 2) * 0.8f), SCNMatrix4.CreateFromAxisAngle(new SCNVector3(0, 0, 1), -0.3f)), Position = new SCNVector3(0, 30, -19), Rotation = new SCNVector4(1, 0, 0, -(float)(Math.PI / 2)) }; Lights [(int)Light.Spot].Light = new SCNLight { LightType = SCNLightType.Spot, ShadowRadius = 3, ZNear = 20, ZFar = 100, Color = NSColor.Black, CastsShadow = true }; NarrowSpotlight(false); CameraHandle.AddChildNode(Lights [(int)Light.Spot]); // Left light Lights [(int)Light.Left] = new SCNNode { Name = "left light", Position = new SCNVector3(-20, 10, -20), Rotation = new SCNVector4(0, 1, 0, (float)(Math.PI / 2)) }; Lights [(int)Light.Left].Light = new SCNLight { LightType = SCNLightType.Omni, AttenuationStartDistance = 30, AttenuationEndDistance = 80, Color = NSColor.Black }; CameraHandle.AddChildNode(Lights [(int)Light.Left]); // Right light Lights [(int)Light.Right] = new SCNNode { Name = "right light", Position = new SCNVector3(20, 10, -20) }; Lights [(int)Light.Right].Light = new SCNLight { LightType = SCNLightType.Omni, AttenuationStartDistance = 30, AttenuationEndDistance = 80, Color = NSColor.Black }; CameraHandle.AddChildNode(Lights [(int)Light.Right]); // Ambient light Lights [(int)Light.Ambient] = new SCNNode { Name = "ambient light" }; Lights [(int)Light.Ambient].Light = new SCNLight { LightType = SCNLightType.Ambient, Color = NSColor.FromCalibratedWhite(0.0f, 1.0f) }; Scene.RootNode.AddChildNode(Lights [(int)Light.Ambient]); }
public void InitLighting() { // Omni light (main light of the scene) Lights [(int)Light.Main] = new SCNNode { Name = "omni", Position = new SCNVector3(0, 3, -13) }; Lights [(int)Light.Main].Light = new SCNLight { LightType = SCNLightType.Omni }; Lights [(int)Light.Main].Light.SetAttribute(new NSNumber(10), SCNLightAttribute.AttenuationStartKey); Lights [(int)Light.Main].Light.SetAttribute(new NSNumber(50), SCNLightAttribute.AttenuationEndKey); CameraHandle.AddChildNode(Lights [(int)Light.Main]); //make all lights relative to the camera node // Front light Lights [(int)Light.Front] = new SCNNode { Name = "front light", Position = new SCNVector3(0, 0, 0) }; Lights [(int)Light.Front].Light = new SCNLight { LightType = SCNLightType.Directional }; CameraHandle.AddChildNode(Lights [(int)Light.Front]); // Spot light Lights [(int)Light.Spot] = new SCNNode { Name = "spot light", Position = new SCNVector3(0, 30, -19), Rotation = new SCNVector4(1, 0, 0, (float)-(Math.PI / 2)) }; Lights [(int)Light.Spot].Light = new SCNLight { LightType = SCNLightType.Spot, ShadowRadius = 10 }; Lights [(int)Light.Spot].Light.SetAttribute(new NSNumber(30), SCNLightAttribute.ShadowNearClippingKey); Lights [(int)Light.Spot].Light.SetAttribute(new NSNumber(50), SCNLightAttribute.ShadowFarClippingKey); Lights [(int)Light.Spot].Light.SetAttribute(new NSNumber(10), SCNLightAttribute.SpotInnerAngleKey); Lights [(int)Light.Spot].Light.SetAttribute(new NSNumber(45), SCNLightAttribute.SpotOuterAngleKey); CameraHandle.AddChildNode(Lights [(int)Light.Spot]); // Left light Lights [(int)Light.Left] = new SCNNode { Name = "left light", Position = new SCNVector3(-20, 10, -5) }; Lights [(int)Light.Left].Light = new SCNLight { LightType = SCNLightType.Omni }; Lights [(int)Light.Left].Light.SetAttribute(new NSNumber(30), SCNLightAttribute.AttenuationStartKey); Lights [(int)Light.Left].Light.SetAttribute(new NSNumber(80), SCNLightAttribute.AttenuationEndKey); CameraHandle.AddChildNode(Lights [(int)Light.Left]); // Right light Lights [(int)Light.Right] = new SCNNode { Name = "right light", Position = new SCNVector3(20, 10, -5) }; Lights [(int)Light.Right].Light = new SCNLight { LightType = SCNLightType.Omni }; Lights [(int)Light.Right].Light.SetAttribute(new NSNumber(30), SCNLightAttribute.AttenuationStartKey); Lights [(int)Light.Right].Light.SetAttribute(new NSNumber(80), SCNLightAttribute.AttenuationEndKey); CameraHandle.AddChildNode(Lights [(int)Light.Right]); // Ambient light Lights [(int)Light.Ambient] = new SCNNode { Name = "ambient light" }; Lights [(int)Light.Ambient].Light = new SCNLight { LightType = SCNLightType.Ambient }; Scene.RootNode.AddChildNode(Lights [(int)Light.Ambient]); // Switch off all the lights for (int i = 0; i < (int)Light.Count; i++) { Lights [i].Light.Color = NSColor.Black; } }