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) { TextManager.SetTitle("Shader Modifiers"); TextManager.AddBulletAtLevel("Inject custom GLSL code", 0); TextManager.AddBulletAtLevel("Combines with Scene Kit’s shaders", 0); TextManager.AddBulletAtLevel("Inject at specific stages", 0); TextManager.AddEmptyLine(); TextManager.AddCode("#aMaterial.#shaderModifiers# = @{ <Entry Point> : <GLSL Code> };#"); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Portability", 0); TextManager.AddBulletAtLevel("Performance", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); break; } }
public override void SetupSlide(PresentationViewController presentationViewController) { TextManager.SetTitle("More Information"); TextManager.AddTextAtLevel("Allan Schaffer", 0); TextManager.AddTextAtLevel("Graphics and Game Technologies Evangelist", 1); TextManager.AddTextAtLevel("*****@*****.**", 2); TextManager.AddEmptyLine(); TextManager.AddTextAtLevel("Documentation", 0); TextManager.AddTextAtLevel("Scene Kit Programming Guide", 1); TextManager.AddTextAtLevel("http://developer.apple.com", 2); TextManager.AddEmptyLine(); TextManager.AddTextAtLevel("Apple Developer Forums", 0); TextManager.AddTextAtLevel("http://devforums.apple.com", 2); TextManager.AddEmptyLine(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.5f; var cameraNode = presentationViewController.CameraNode; switch (index) { case 0: break; case 1: // Add a code snippet TextManager.AddCode("#aCamera.#FocalDistance# = 16.0f; \n" + "aCamera.#FocalBlurRadius# = 8.0f;#"); break; case 2: // Turn on DOF to illustrate the code snippet cameraNode.Camera.FocalDistance = 16; cameraNode.Camera.FocalSize = 1.5f; cameraNode.Camera.Aperture = 0.3f; cameraNode.Camera.FocalBlurRadius = 8; break; case 3: // Focus far away cameraNode.Camera.FocalDistance = 35; cameraNode.Camera.FocalSize = 4; cameraNode.Camera.Aperture = 0.1f; // and update the code snippet TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.AddEmptyLine(); TextManager.AddCode("#aCamera.#FocalDistance# = #35.0f#; \n" + "aCamera.#FocalBlurRadius# = 8.0f;#"); break; } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Javascript code example", 0); TextManager.AddCode("#\n#//allocate a node#\n" + "var aNode = SCNNode.Create ();\n\n" + "#//change opacity#\n" + "aNode.Opacity = 0.5f;\n\n" + "#//remove from parent#\n" + "aNode.RemoveFromParentNode ();\n\n" + "#//animate implicitly#\n" + "SCNTransaction.Begin ();\n" + "SCNTransaction.AnimationDuration = 1.0f;\n" + "aNode.Scale = new SCNVector3 (2, 2, 2);\n" + "SCNTransaction.Commit ();#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 2: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.AddBulletAtLevel("Tools", 0); TextManager.AddBulletAtLevel("Debugging", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.AddBulletAtLevel("Image", 0); TextManager.AddBulletAtLevel("Name / Path / URL", 1); TextManager.AddBulletAtLevel("NSImage / UIImage / NSData", 1); TextManager.AddBulletAtLevel("SKTexture", 1); TextManager.FlipInText(SlideTextManager.TextType.Bullet); var code = TextManager.AddCode("#material.diffuse.contents = #@\"slate.jpg\"#;#"); code.Position = new SCNVector3(code.Position.X + 6, code.Position.Y - 6.5f, code.Position.Z); Material.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/slate", "jpg")); Material.Normal.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/slate-bump", "png")); Material.Normal.Intensity = 0; break; case 2: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; Material.Normal.Intensity = 5.0f; Material.Specular.Contents = NSColor.Gray; SCNTransaction.Commit(); code = TextManager.AddCode("#material.normal.contents = #[SKTexture textureByGeneratingNormalMap]#;#"); code.Position = new SCNVector3(code.Position.X + 2, code.Position.Y - 6.5f, code.Position.Z); break; case 3: TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Live contents", 0); TextManager.AddBulletAtLevel("CALayer tree", 1); TextManager.AddBulletAtLevel("SKScene (new)", 1); TextManager.FlipInText(SlideTextManager.TextType.Bullet); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; Material.Normal.Intensity = 2.0f; SCNTransaction.Commit(); PlayerLayer1 = ConfigurePlayer(NSBundle.MainBundle.PathForResource("Movies/movie1", "mov"), "material-cube"); break; case 4: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Cube map", 0); TextManager.AddBulletAtLevel("NSArray of 6 items", 1); TextManager.FlipInText(SlideTextManager.TextType.Bullet); code = TextManager.AddCode("#material.reflective.contents = #@[aright.png, left.png ... front.png]#;#"); code.Position = new SCNVector3(code.Position.X, code.Position.Y - 9.5f, code.Position.Z); var image = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/cubemap", "png"), 12, false); image.Position = new SCNVector3(-10, 9, 0); image.Opacity = 0; ContentNode.AddChildNode(image); Object.Geometry = SCNTorus.Create(W * 0.5f, W * 0.2f); Material = Object.Geometry.FirstMaterial; Object.Rotation = new SCNVector4(1, 0, 0, (float)Math.PI / 2); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; var right = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/right", "tga")); var left = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/left", "tga")); var top = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/top", "tga")); var bottom = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/bottom", "tga")); var back = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/back", "tga")); var front = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/front", "tga")); var materialContents = new NSMutableArray(); materialContents.AddObjects(new NSObject[] { right, left, top, bottom, back, front }); Material.Reflective.Contents = materialContents; Material.Diffuse.Contents = NSColor.Red; image.Opacity = 1.0f; SCNTransaction.Commit(); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); switch (index) { case 0: // Set the slide's title and subtitle and add some text TextManager.SetTitle("Node Attributes"); TextManager.SetSubtitle("Camera"); TextManager.AddBulletAtLevel("Point of view for renderers", 0); // Start with the "sign" model hidden var group = ContentNode.FindChildNode("group", true); group.Scale = new SCNVector3(0, 0, 0); group.Hidden = true; break; case 1: // Reveal the model (unhide then scale) group = ContentNode.FindChildNode("group", true); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; group.Hidden = false; SCNTransaction.Commit(); SCNTransaction.AnimationDuration = 1.0f; group.Scale = new SCNVector3(1, 1, 1); break; case 2: TextManager.AddCode("#aNode.#Camera# = #SCNCamera#.Create (); \naView.#PointOfView# = aNode;#"); break; case 3: // Switch to camera1 SCNTransaction.AnimationDuration = 2.0f; ((SCNView)presentationViewController.View).PointOfView = ContentNode.FindChildNode("camera1", true); break; case 4: // Switch to camera2 SCNTransaction.AnimationDuration = 2.0f; ((SCNView)presentationViewController.View).PointOfView = ContentNode.FindChildNode("camera2", true); break; case 5: // On completion add some code SCNTransaction.SetCompletionBlock(() => { TextManager.FadesIn = true; TextManager.AddEmptyLine(); TextManager.AddCode("#aNode.#Camera#.XFov = angleInDegrees;#"); }); // Switch back to the default camera SCNTransaction.AnimationDuration = 1.0f; ((SCNView)presentationViewController.View).PointOfView = presentationViewController.CameraNode; break; case 6: // Switch to camera 3 SCNTransaction.AnimationDuration = 1.0f; var target = ContentNode.FindChildNode("camera3", true); // Don't let the default transition animate the FOV (we will animate the FOV separately) var wantedFOV = target.Camera.XFov; target.Camera.XFov = ((SCNView)presentationViewController.View).PointOfView.Camera.XFov; // Animate point of view with an ease-in/ease-out function SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); ((SCNView)presentationViewController.View).PointOfView = target; SCNTransaction.Commit(); // Animate the FOV with the default timing function (for a better looking transition) SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; ((SCNView)presentationViewController.View).PointOfView.Camera.XFov = wantedFOV; SCNTransaction.Commit(); break; case 7: // Switch to camera 4 var cameraNode = ContentNode.FindChildNode("camera4", true); // Don't let the default transition animate the FOV (we will animate the FOV separately) wantedFOV = cameraNode.Camera.XFov; cameraNode.Camera.XFov = ((SCNView)presentationViewController.View).PointOfView.Camera.XFov; // Animate point of view with the default timing function SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; ((SCNView)presentationViewController.View).PointOfView = cameraNode; SCNTransaction.Commit(); // Animate the FOV with an ease-in/ease-out function SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.0f; SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); ((SCNView)presentationViewController.View).PointOfView.Camera.XFov = wantedFOV; SCNTransaction.Commit(); break; case 8: // Quickly switch back to the default camera SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; ((SCNView)presentationViewController.View).PointOfView = presentationViewController.CameraNode; SCNTransaction.Commit(); break; } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case (int)ParticleSteps.Fire: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Particle Image", 0); TextManager.AddBulletAtLevel("Color over life duration", 0); TextManager.AddBulletAtLevel("Size over life duration", 0); TextManager.AddBulletAtLevel("Several blend modes", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); var hole = SCNNode.Create(); hole.Geometry = SCNTube.Create(1.7f, 1.9f, 1.5f); hole.Position = new SCNVector3(0, 0, HOLE_Z); hole.Scale = new SCNVector3(1, 0, 1); GroundNode.AddChildNode(hole); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5f; hole.Scale = new SCNVector3(1, 1, 1); SCNTransaction.Commit(); var ps = SCNParticleSystem.Create("fire", "Particles"); hole.AddParticleSystem(ps); Hole = hole; break; case (int)ParticleSteps.FireScreen: ps = Hole.ParticleSystems [0]; ps.BlendMode = SCNParticleBlendMode.Screen; break; case (int)ParticleSteps.Local: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Local vs Global", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); Hole.RemoveAllParticleSystems(); Hole2 = Hole.Clone(); Hole2.Geometry = (SCNGeometry)Hole.Geometry.Copy(); Hole2.Position = new SCNVector3(0, -2, HOLE_Z - 4); GroundNode.AddChildNode(Hole2); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5; Hole2.Position = new SCNVector3(0, 0, HOLE_Z - 4); SCNTransaction.Commit(); ps = SCNParticleSystem.Create("reactor", "Particles"); ps.ParticleColorVariation = new SCNVector4(0, 0, 0.5f, 0); Hole.AddParticleSystem(ps); var localPs = (SCNParticleSystem)ps.Copy(); localPs.ParticleImage = ps.ParticleImage; localPs.Local = true; Hole2.AddParticleSystem(localPs); var animation = CABasicAnimation.FromKeyPath("position"); animation.From = NSValue.FromVector(new SCNVector3(7, 0, HOLE_Z)); animation.To = NSValue.FromVector(new SCNVector3(-7, 0, HOLE_Z)); animation.BeginTime = CAAnimation.CurrentMediaTime() + 0.75; animation.Duration = 8; animation.AutoReverses = true; animation.RepeatCount = float.MaxValue; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimeOffset = animation.Duration / 2; Hole.AddAnimation(animation, new NSString("animateHole")); animation = CABasicAnimation.FromKeyPath("position"); animation.From = NSValue.FromVector(new SCNVector3(-7, 0, HOLE_Z - 4)); animation.To = NSValue.FromVector(new SCNVector3(7, 0, HOLE_Z - 4)); animation.BeginTime = CAAnimation.CurrentMediaTime() + 0.75; animation.Duration = 8; animation.AutoReverses = true; animation.RepeatCount = float.MaxValue; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimeOffset = animation.Duration / 2; Hole2.AddAnimation(animation, new NSString("animateHole")); break; case (int)ParticleSteps.Gravity: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Affected by gravity", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); Hole2.RemoveAllParticleSystems(); Hole2.RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.ScaleTo(0, 0.5), SCNAction.RemoveFromParentNode() })); Hole.RemoveAllParticleSystems(); Hole.RemoveAnimation(new NSString("animateHole"), 0.5f); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5; var tube = (SCNTube)Hole.Geometry; tube.InnerRadius = 0.3f; tube.OuterRadius = 0.4f; tube.Height = 1.0f; SCNTransaction.Commit(); ps = SCNParticleSystem.Create("sparks", "Particles"); Hole.RemoveAllParticleSystems(); Hole.AddParticleSystem(ps); foreach (var child in ((SCNView)presentationViewController.View).Scene.RootNode.ChildNodes) { if (child.Geometry != null) { if (child.Geometry.GetType() == typeof(SCNFloor)) { FloorNode = child; } } } /*FloorNode = ((SCNView)presentationViewController.View).Scene.RootNode.FindNodes ((SCNNode child, out bool stop) => { * stop = false; * if (child.Geometry != null) * stop = (child.Geometry.GetType () == typeof(SCNFloor)); * return stop; * });*/ /*FloorNode = [presentationViewController.view.scene.rootNode childNodesPassingTest:^BOOL(SCNNode *child, BOOL *stop) { * return [child.geometry isKindOfClass:[SCNFloor class]]; * }][0];*/ ps.ColliderNodes = new SCNNode[] { FloorNode }; break; case (int)ParticleSteps.Collider: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Affected by colliders", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); var boxNode = SCNNode.Create(); boxNode.Geometry = SCNBox.Create(5, 0.2f, 5, 0); boxNode.Position = new SCNVector3(0, 7, HOLE_Z); boxNode.Geometry.FirstMaterial.Emission.Contents = NSColor.DarkGray; GroundNode.AddChildNode(boxNode); ps = Hole.ParticleSystems [0]; ps.ColliderNodes = new SCNNode[] { FloorNode, boxNode }; animation = CABasicAnimation.FromKeyPath("eulerAngles"); animation.From = NSValue.FromVector(new SCNVector3(0, 0, NMath.PI / 4 * 1.7f)); animation.To = NSValue.FromVector(new SCNVector3(0, 0, -NMath.PI / 4 * 1.7f)); animation.BeginTime = CAAnimation.CurrentMediaTime() + 0.5; animation.Duration = 2; animation.AutoReverses = true; animation.RepeatCount = float.MaxValue; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimeOffset = animation.Duration / 2; boxNode.AddAnimation(animation, new NSString("animateHole")); BoxNode = boxNode; break; case (int)ParticleSteps.Fields: Hole.RemoveAllParticleSystems(); Hole.RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.ScaleTo(0, 0.75), SCNAction.RemoveFromParentNode() })); BoxNode.RunAction(SCNAction.Sequence(new SCNAction[] { SCNAction.MoveBy(0, 15, 0, 1.0), SCNAction.RemoveFromParentNode() })); var particleHolder = SCNNode.Create(); particleHolder.Position = new SCNVector3(0, 20, HOLE_Z); GroundNode.AddChildNode(particleHolder); ParticleHolder = particleHolder; TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Affected by physics fields", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); ps = SCNParticleSystem.Create("snow", "Particles"); ps.AffectedByPhysicsFields = true; ParticleHolder.AddParticleSystem(ps); Snow = ps; //physics field var field = SCNPhysicsField.CreateTurbulenceField(50, 1); field.HalfExtent = new SCNVector3(20, 20, 20); field.Strength = 4.0f; var fieldOwner = SCNNode.Create(); fieldOwner.Position = new SCNVector3(0, 5, HOLE_Z); GroundNode.AddChildNode(fieldOwner); fieldOwner.PhysicsField = field; FieldOwner = fieldOwner; ps.ColliderNodes = new SCNNode[] { FloorNode }; break; case (int)ParticleSteps.FieldsVortex: VortexFieldOwner = SCNNode.Create(); VortexFieldOwner.Position = new SCNVector3(0, 5, HOLE_Z); GroundNode.AddChildNode(VortexFieldOwner); //tornado var worldOrigin = new SCNVector3(FieldOwner.WorldTransform.M41, FieldOwner.WorldTransform.M42, FieldOwner.WorldTransform.M43); var worldAxis = new SCNVector3(0, 1, 0); var vortex = SCNPhysicsField.CustomField((SCNVector3 position, SCNVector3 velocity, float mass, float charge, double timeInSeconds) => { var l = new SCNVector3(); l.X = worldOrigin.X - position.X; l.Z = worldOrigin.Z - position.Z; SCNVector3 t = Cross(worldAxis, l); var d2 = (l.X * l.X + l.Z * l.Z); var vs = (nfloat)(VS / Math.Sqrt(d2)); var fy = (nfloat)(1.0 - (Math.Min(1.0, (position.Y / 15.0)))); return(new SCNVector3(t.X * vs + l.X * (nfloat)VW * fy, 0, t.Z * vs + l.Z * (nfloat)VW * fy)); }); vortex.HalfExtent = new SCNVector3(100, 100, 100); VortexFieldOwner.PhysicsField = vortex; break; case (int)ParticleSteps.SubSystems: FieldOwner.RemoveFromParentNode(); ParticleHolder.RemoveAllParticleSystems(); Snow.DampingFactor = -1; TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Sub-particle system on collision", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); ps = SCNParticleSystem.Create("rain", "Particles"); var pss = SCNParticleSystem.Create("plok", "Particles"); pss.IdleDuration = 0; pss.Loops = false; ps.SystemSpawnedOnCollision = pss; ParticleHolder.AddParticleSystem(ps); ps.ColliderNodes = new SCNNode[] { FloorNode }; break; case (int)ParticleSteps.Confetti: ParticleHolder.RemoveAllParticleSystems(); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Custom blocks", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); ps = SCNParticleSystem.Create(); ps.EmitterShape = SCNBox.Create(20, 9, 5, 0); ps.BirthRate = 100; ps.ParticleLifeSpan = 10; ps.ParticleLifeSpanVariation = 0; ps.SpreadingAngle = 20; ps.ParticleSize = 0.25f; ps.ParticleVelocity = 10; ps.ParticleVelocityVariation = 19; ps.BirthDirection = SCNParticleBirthDirection.Constant; ps.EmittingDirection = new SCNVector3(0, -1, 0); ps.BirthLocation = SCNParticleBirthLocation.Volume; ps.ParticleImage = new NSImage(NSBundle.MainBundle.PathForResource("Particles/confetti", "png")); ps.LightingEnabled = true; ps.OrientationMode = SCNParticleOrientationMode.Free; ps.SortingMode = SCNParticleSortingMode.Distance; ps.ParticleAngleVariation = 180; ps.ParticleAngularVelocity = 200; ps.ParticleAngularVelocityVariation = 400; ps.ParticleColor = NSColor.Green; ps.ParticleColorVariation = new SCNVector4(0.2f, 0.1f, 0.1f, 0); ps.ParticleBounce = 0; ps.ParticleFriction = 0.6f; ps.ColliderNodes = new SCNNode[] { FloorNode }; ps.BlendMode = SCNParticleBlendMode.Alpha; var floatAnimation = CAKeyFrameAnimation.FromKeyPath(""); floatAnimation.Values = new NSNumber[] { 1, 1, 0 }; floatAnimation.KeyTimes = new NSNumber[] { 0, 0.9f, 1 }; floatAnimation.Duration = 1.0f; floatAnimation.Additive = false; //ps.PropertyControllers = @{ SCNParticlePropertyOpacity: [SCNParticlePropertyController controllerWithAnimation:floatAnimation] }; //ps.HandleEvent (SCNParticleEvent.Birth, /*[ps handleEvent:SCNParticleEventBirth forProperties:@[SCNParticlePropertyColor] withBlock:^(void **data, size_t *dataStride, uint32_t *indices , NSInteger count) { * * for (int i = 0; i < count; ++i) { * var col = (float *)((char *)data[0] + dataStride[0] * i); * if (rand() & 0x1) { // swith green for red * col[0] = col[1]; * col[1] = 0; * } * * } * }];*/ /*[ps handleEvent:SCNParticleEventCollision forProperties:@[SCNParticlePropertyAngle, SCNParticlePropertyRotationAxis, SCNParticlePropertyAngularVelocity, SCNParticlePropertyVelocity, SCNParticlePropertyContactNormal] withBlock:^(void **data, size_t *dataStride, uint32_t *indices , NSInteger count) { * * for (NSInteger i = 0; i < count; ++i) { * // fix orientation * float *angle = (float *)((char *)data[0] + dataStride[0] * indices[i]); * float *axis = (float *)((char *)data[1] + dataStride[1] * indices[i]); * * float *colNrm = (float *)((char *)data[4] + dataStride[4] * indices[i]); * SCNVector3 collisionNormal = {colNrm[0], colNrm[1], colNrm[2]}; * SCNVector3 cp = SCNVector3CrossProduct(collisionNormal, SCNVector3Make(0, 0, 1)); * CGFloat cpLen = SCNVector3Length(cp); * angle[0] = asin(cpLen); * * axis[0] = cp.x / cpLen; * axis[1] = cp.y / cpLen; * axis[2] = cp.z / cpLen; * * // kill angular rotation * float *angVel = (float *)((char *)data[2] + dataStride[2] * indices[i]); * angVel[0] = 0; * * if (colNrm[1] > 0.4) { * float *vel = (float *)((char *)data[3] + dataStride[3] * indices[i]); * vel[0] = 0; * vel[1] = 0; * vel[2] = 0; * } * } * }];*/ ParticleHolder.AddParticleSystem(ps); break; case (int)ParticleSteps.EmitterCube: ParticleHolder.RemoveAllParticleSystems(); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Emitter shape", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); ParticleHolder.RemoveFromParentNode(); ps = SCNParticleSystem.Create("emitters", "Particles"); ps.Local = true; ParticleHolder.AddParticleSystem(ps); var node = SCNNode.Create(); node.Position = new SCNVector3(3, 6, HOLE_Z); node.RunAction(SCNAction.RepeatActionForever(SCNAction.RotateBy(NMath.PI * 2, new SCNVector3(0.3f, 1, 0), 8))); GroundNode.AddChildNode(node); Bokeh = ps; node.AddParticleSystem(ps); break; case (int)ParticleSteps.EmitterSphere: Bokeh.EmitterShape = SCNSphere.Create(5); break; case (int)ParticleSteps.EmitterTorus: Bokeh.EmitterShape = SCNTorus.Create(5, 1); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case (int)TechniqueSteps.Intro: break; case (int)TechniqueSteps.Code: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); PlistGroup.RemoveFromParentNode(); TextManager.AddEmptyLine(); TextManager.AddCode("#// Load a technique\nSCNTechnique *technique = [SCNTechnique #techniqueWithDictionary#:aDictionary];\n\n\n" + "// Chain techniques\ntechnique = [SCNTechnique #techniqueBySequencingTechniques#:@[t1, t2 ...];\n\n\n\t\t\t\t\t" + "// Set a technique\naSCNView.#technique# = technique;#"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case (int)TechniqueSteps.Files: Pass2.RemoveFromParentNode(); TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddBulletAtLevel("Load from Plist", 0); TextManager.FlipInText(SlideTextManager.TextType.Code); PlistGroup = SCNNode.Create(); ContentNode.AddChildNode(PlistGroup); //add plist icon var node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/plist", "png"), 8, true); node.Position = new SCNVector3(0, 3.7f, 10); PlistGroup.AddChildNode(node); //add plist icon node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/vsh", "png"), 3, true); for (var i = 0; i < 5; i++) { node = node.Clone(); node.Position = new SCNVector3(6, 1.4f, 10 - i); PlistGroup.AddChildNode(node); } node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/fsh", "png"), 3, true); for (var i = 0; i < 5; i++) { node = node.Clone(); node.Position = new SCNVector3(9, 1.4f, 10 - i); PlistGroup.AddChildNode(node); } break; case (int)TechniqueSteps.Plist: //add plist icon node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique", "png"), 9, true); node.Position = new SCNVector3(0, 3.5f, 10.1f); node.Opacity = 0.0f; PlistGroup.AddChildNode(node); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; node.Position = new SCNVector3(0, 3.5f, 11); node.Opacity = 1.0f; SCNTransaction.Commit(); break; case (int)TechniqueSteps.Pass1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass1", "png"), 15, true); node.Position = new SCNVector3(0, 3.5f, 10.1f); node.Opacity = 0.0f; ContentNode.AddChildNode(node); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; node.Position = new SCNVector3(0, 3.5f, 11); node.Opacity = 1.0f; SCNTransaction.Commit(); Pass1 = node; break; case (int)TechniqueSteps.Passes3: Pass1.RemoveFromParentNode(); Pass2 = SCNNode.Create(); Pass2.Opacity = 0.0f; Pass2.Position = new SCNVector3(0, 3.5f, 6); node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass2", "png"), 8, true); node.Position = new SCNVector3(-8, 0, 0); Pass2.AddChildNode(node); node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass3", "png"), 8, true); node.Position = new SCNVector3(0, 0, 0); Pass2.AddChildNode(node); node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass4", "png"), 8, true); node.Position = new SCNVector3(8, 0, 0); Pass2.AddChildNode(node); ContentNode.AddChildNode(Pass2); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; Pass2.Position = new SCNVector3(0, 3.5f, 9); Pass2.Opacity = 1.0f; SCNTransaction.Commit(); break; case (int)TechniqueSteps.Passes3Connected: TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Connect pass inputs / outputs", 0); node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/link", "png"), 8.75f, true); node.Position = new SCNVector3(0.01f, -2, 0); node.Opacity = 0.0f; Pass2.AddChildNode(node); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; var n = Pass2.ChildNodes [0]; n.Position = new SCNVector3(-7.5f, -0.015f, 0); n = Pass2.ChildNodes [2]; n.Position = new SCNVector3(7.5f, 0.02f, 0); node.Opacity = 1.0f; SCNTransaction.Commit(); break; case (int)TechniqueSteps.Sample: TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("Example: simple depth of field"); TextManager.FlipInText(SlideTextManager.TextType.Code); Pass3 = SCNNode.Create(); node = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/pass5", "png"), 15, true); node.Position = new SCNVector3(-3, 5, 10.1f); node.Opacity = 0.0f; Pass3.AddChildNode(node); var t0 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique0", "png"), 4, false); t0.Position = new SCNVector3(-8.5f, 1.5f, 10.1f); t0.Opacity = 0.0f; Pass3.AddChildNode(t0); var t1 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique1", "png"), 4, false); t1.Position = new SCNVector3(-3.6f, 1.5f, 10.1f); t1.Opacity = 0.0f; Pass3.AddChildNode(t1); var t2 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique2", "png"), 4, false); t2.Position = new SCNVector3(1.4f, 1.5f, 10.1f); t2.Opacity = 0.0f; Pass3.AddChildNode(t2); var t3 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/technique/technique3", "png"), 8, false); t3.Position = new SCNVector3(8, 5, 10.1f); t3.Opacity = 0.0f; Pass3.AddChildNode(t3); ContentNode.AddChildNode(Pass3); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; node.Opacity = 1.0f; t0.Opacity = 1.0f; t1.Opacity = 1.0f; t2.Opacity = 1.0f; t3.Opacity = 1.0f; SCNTransaction.Commit(); break; } }
public override void PresentStep(int index, PresentationViewController presentationViewController) { // Animate by default SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; switch (index) { case 0: TextManager.FlipInText(SlideTextManager.TextType.Bullet); break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddCode("#// Rotate forever\n" + "[aNode #runAction:#\n" + " [SCNAction repeatActionForever:\n" + " [SCNAction rotateByX:0 y:M_PI*2 z:0 duration:5.0]]];#"); TextManager.FlipInText(SlideTextManager.TextType.Code); break; case 2: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Code); TextManager.AddBulletAtLevel("Move", 0); TextManager.AddBulletAtLevel("Rotate", 0); TextManager.AddBulletAtLevel("Scale", 0); TextManager.AddBulletAtLevel("Opacity", 0); TextManager.AddBulletAtLevel("Remove", 0); TextManager.AddBulletAtLevel("Wait", 0); TextManager.AddBulletAtLevel("Custom block", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); break; case 3: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Directly targets the render tree", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); break; case 4: TextManager.AddBulletAtLevel("node.position / node.presentationNode.position", 0); //labels var label1 = TextManager.AddTextAtLevel("Action", 0); label1.Position = new SCNVector3(-15, 3, 0); var label2 = TextManager.AddTextAtLevel("Animation", 0); label2.Position = new SCNVector3(-15, -2, 0); //animation var animNode = SCNNode.Create(); var cubeSize = 4.0f; animNode.Position = new SCNVector3(-5, cubeSize / 2, 0); var cube = SCNBox.Create(cubeSize, cubeSize, cubeSize, 0.05f * cubeSize); cube.FirstMaterial.Diffuse.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/texture", "png")); cube.FirstMaterial.Diffuse.MipFilter = SCNFilterMode.Linear; cube.FirstMaterial.Diffuse.WrapS = SCNWrapMode.Repeat; cube.FirstMaterial.Diffuse.WrapT = SCNWrapMode.Repeat; animNode.Geometry = cube; ContentNode.AddChildNode(animNode); SCNTransaction.Begin(); SCNNode animPosIndicator = null; SCNAnimationEvent startEvt = SCNAnimationEvent.Create(0, (CAAnimation animation, NSObject animatedObject, bool playingBackward) => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; animPosIndicator.Position = new SCNVector3(10, animPosIndicator.Position.Y, animPosIndicator.Position.Z); SCNTransaction.Commit(); }); SCNAnimationEvent endEvt = SCNAnimationEvent.Create(1, (CAAnimation animation, NSObject animatedObject, bool playingBackward) => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0; animPosIndicator.Position = new SCNVector3(-5, animPosIndicator.Position.Y, animPosIndicator.Position.Z); SCNTransaction.Commit(); }); var anim = CABasicAnimation.FromKeyPath("position.x"); anim.Duration = 3; anim.From = new NSNumber(0.0); anim.To = new NSNumber(15.0); anim.Additive = true; anim.AutoReverses = true; anim.AnimationEvents = new SCNAnimationEvent[] { startEvt, endEvt }; anim.RepeatCount = float.MaxValue; animNode.AddAnimation(anim, new NSString("cubeAnimation")); //action var actionNode = SCNNode.Create(); actionNode.Position = new SCNVector3(-5, cubeSize * 1.5f + 1, 0); actionNode.Geometry = cube; ContentNode.AddChildNode(actionNode); var mv = SCNAction.MoveBy(15, 0, 0, 3); actionNode.RunAction(SCNAction.RepeatActionForever(SCNAction.Sequence(new SCNAction[] { mv, mv.ReversedAction() }))); //position indicator var positionIndicator = SCNNode.Create(); positionIndicator.Geometry = SCNCylinder.Create(0.5f, 0.01f); positionIndicator.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Red; positionIndicator.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; positionIndicator.EulerAngles = new SCNVector3(NMath.PI / 2, 0, 0); positionIndicator.Position = new SCNVector3(0, 0, cubeSize * 0.5f); actionNode.AddChildNode(positionIndicator); //anim pos indicator animPosIndicator = positionIndicator.Clone(); animPosIndicator.Position = new SCNVector3(5, cubeSize / 2, cubeSize * 0.5f); ContentNode.AddChildNode(animPosIndicator); SCNTransaction.Commit(); break; } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1.5f; var cameraNode = presentationViewController.CameraNode; switch (index) { case 0: break; case 1: // Add a code snippet TextManager.AddCode("#aCamera.#FocalDistance# = 16.0f; \n" + "aCamera.#FocalBlurRadius# = 8.0f;#"); break; case 2: // Turn on DOF to illustrate the code snippet cameraNode.Camera.FocalDistance = 16; cameraNode.Camera.FocalSize = 1.5f; cameraNode.Camera.Aperture = 0.3f; cameraNode.Camera.FocalBlurRadius = 8; break; case 3: // Focus far away cameraNode.Camera.FocalDistance = 35; cameraNode.Camera.FocalSize = 4; cameraNode.Camera.Aperture = 0.1f; // and update the code snippet TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.AddEmptyLine(); TextManager.AddCode("#aCamera.#FocalDistance# = #35.0f#; \n" + "aCamera.#FocalBlurRadius# = 8.0f;#"); break; case 4: // Remove the code TextManager.FadeOutText(SlideTextManager.TextType.Subtitle); TextManager.FadeOutText(SlideTextManager.TextType.Code); // Move the camera and adjust tje focal distance presentationViewController.CameraHandle.Position = presentationViewController.CameraHandle.ConvertPositionToNode(new SCNVector3(0, -3, -6), presentationViewController.CameraHandle.ParentNode); cameraNode.Camera.FocalDistance = 27; // Move the light back a little presentationViewController.MainLight.Position = presentationViewController.MainLight.ConvertPositionToNode(new SCNVector3(0, 3, 6), presentationViewController.MainLight.ParentNode); break; case 5: // Focus near cameraNode.Camera.FocalDistance = 10; cameraNode.Camera.FocalSize = 1; cameraNode.Camera.Aperture = 0.3f; break; } SCNTransaction.Commit(); }
public override void PresentStep(int index, PresentationViewController presentationViewController) { switch (index) { case 0: break; case 1: TextManager.HighlightBullet(0); StaticShadowNode.Opacity = 1; var node = TextManager.AddCode("#aMaterial.#multiply#.contents = aShadowMap;#"); node.Position = new SCNVector3(node.Position.X, node.Position.Y - 4, node.Position.Z); foreach (var child in node.ChildNodes) { child.RenderingOrder = 1; foreach (var m in child.Geometry.Materials) { m.ReadsFromDepthBuffer = false; } } break; case 2: //move the tree PalmTree.RunAction(SCNAction.RotateBy(0, NMath.PI * 4, 0, 8)); break; case 3: TextManager.FadesIn = true; TextManager.FadeOutText(SlideTextManager.TextType.Code); TextManager.AddEmptyLine(); node = TextManager.AddCode("#aLight.#castsShadow# = YES;#"); foreach (SCNNode child in node.ChildNodes) { child.RenderingOrder = 1; foreach (SCNMaterial m in child.Geometry.Materials) { m.ReadsFromDepthBuffer = false; m.WritesToDepthBuffer = false; } } node.Position = new SCNVector3(node.Position.X, node.Position.Y - 6, node.Position.Z); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; var spot = presentationViewController.SpotLight; OldSpotShadowColor = spot.Light.ShadowColor; spot.Light.ShadowColor = NSColor.Black; spot.Light.ShadowRadius = 3; var tp = TextManager.TextNode.Position; var superNode = presentationViewController.CameraNode.ParentNode.ParentNode; var p0 = GroundNode.ConvertPositionToNode(SCNVector3.Zero, null); var p1 = GroundNode.ConvertPositionToNode(new SCNVector3(20, 0, 0), null); var tr = new SCNVector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); var p = superNode.Position; p.X += tr.X; p.Y += tr.Y; p.Z += tr.Z; tp.X += 20; tp.Y += 0; tp.Z += 0; superNode.Position = p; TextManager.TextNode.Position = tp; SCNTransaction.Commit(); TextManager.HighlightBullet(1); break; case 4: //move the light var lightPivot = SCNNode.Create(); lightPivot.Position = Character.Position; GroundNode.AddChildNode(lightPivot); spot = presentationViewController.SpotLight; OldSpotPosition = spot.Position; OldSpotParent = spot.ParentNode; OldSpotZNear = spot.Light.ZNear; spot.Light.ZNear = 20; spot.Position = lightPivot.ConvertPositionFromNode(spot.Position, spot.ParentNode); lightPivot.AddChildNode(spot); //add an object to represent the light var lightModel = SCNNode.Create(); var lightHandle = SCNNode.Create(); var cone = SCNCone.Create(0, 0.5f, 1); cone.RadialSegmentCount = 10; cone.HeightSegmentCount = 5; lightModel.Geometry = cone; lightModel.Geometry.FirstMaterial.Emission.Contents = NSColor.Yellow; lightHandle.Position = new SCNVector3(spot.Position.X * DIST, spot.Position.Y * DIST, spot.Position.Z * DIST); lightModel.CastsShadow = false; lightModel.EulerAngles = new SCNVector3(NMath.PI / 2, 0, 0); lightHandle.AddChildNode(lightModel); lightHandle.Constraints = new SCNConstraint[] { SCNLookAtConstraint.Create(Character) }; lightPivot.AddChildNode(lightHandle); LightHandle = lightHandle; var animation = CABasicAnimation.FromKeyPath("eulerAngles.z"); animation.From = new NSNumber((nfloat)(Math.PI / 4) * 1.7f); animation.To = new NSNumber((nfloat)(-Math.PI / 4) * 0.3f); animation.Duration = 4; animation.AutoReverses = true; animation.RepeatCount = float.MaxValue; animation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut); animation.TimeOffset = animation.Duration / 2; lightPivot.AddAnimation(animation, new NSString("lightAnim")); break; case 5: TextManager.FadeOutText(SlideTextManager.TextType.Code); var text = TextManager.AddCode("#aLight.#shadowMode# =\n#SCNShadowModeModulated#;\naLight.#gobo# = anImage;#"); text.Position = new SCNVector3(text.Position.X, text.Position.Y - 6, text.Position.Z); text.EnumerateChildNodes((SCNNode child, out bool stop) => { stop = false; child.RenderingOrder = 1; foreach (var m in child.Geometry.Materials) { m.ReadsFromDepthBuffer = false; m.WritesToDepthBuffer = false; } return(stop); }); LightHandle.RemoveFromParentNode(); RestoreSpotPosition(presentationViewController); TextManager.HighlightBullet(2); spot = presentationViewController.SpotLight; spot.Light.CastsShadow = false; var head = Character.FindChildNode("Bip001_Pelvis", true); node = SCNNode.Create(); node.Light = SCNLight.Create(); node.Light.LightType = SCNLightType.Spot; node.Light.SpotOuterAngle = 30; node.Constraints = new SCNConstraint[] { SCNLookAtConstraint.Create(head) }; node.Position = new SCNVector3(0, 220, 0); node.Light.ZNear = 10; node.Light.ZFar = 1000; node.Light.Gobo.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/blobShadow", "jpg")); node.Light.Gobo.Intensity = 0.65f; node.Light.ShadowMode = SCNShadowMode.Modulated; //exclude character from shadow node.Light.CategoryBitMask = 0x1; Character.FindNodes((SCNNode child, out bool stop) => { stop = false; child.CategoryBitMask = 0x2; return(stop); }); Projector = node; Character.AddChildNode(node); break; } }
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("Copying"); TextManager.AddBulletAtLevel("Attributes are shared by default", 0); TextManager.AddBulletAtLevel("Unshare if needed", 0); TextManager.AddBulletAtLevel("Copying geometries is cheap", 0); break; case 1: // New "Node B" box var nodeB = Utils.SCBoxNode("Node B", new CGRect(-55, -36, 110, 50), GreenColor, 10, true); nodeB.Name = "nodeB"; nodeB.Position = new SCNVector3(140, 0, 0); nodeB.Opacity = 0; var nodeA = ContentNode.FindChildNode("nodeA", true); nodeA.AddChildNode(nodeB); // Arrow from "Root Node" to "Node B" var arrowNode = SCNNode.Create(); arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(140, 3), new CGSize(10, 14), 4, true), 0); arrowNode.Position = new SCNVector3(-130, 60, 0); arrowNode.Rotation = new SCNVector4(0, 0, 1, -(float)(Math.PI * 0.12f)); arrowNode.Geometry.FirstMaterial.Diffuse.Contents = GreenColor; nodeB.AddChildNode(arrowNode); // Arrow from "Node B" to the shared geometry arrowNode = SCNNode.Create(); arrowNode.Name = "arrow-shared-geometry"; arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(140, 3), new CGSize(10, 14), 4, false), 0); arrowNode.Position = new SCNVector3(0, -28, 0); arrowNode.Rotation = new SCNVector4(0, 0, 1, (float)(Math.PI * 1.12f)); arrowNode.Geometry.FirstMaterial.Diffuse.Contents = PurpleColor; nodeB.AddChildNode(arrowNode); // Reveal SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; nodeB.Opacity = 1.0f; // Show the related code TextManager.AddCode("#// Copy a node \n" + "var nodeB = nodeA.#Copy# ();#"); SCNTransaction.Commit(); break; case 2: var geometryNodeA = ContentNode.FindChildNode("geometry", true); var oldArrowNode = ContentNode.FindChildNode("arrow-shared-geometry", true); // New "Geometry" box var geometryNodeB = Utils.SCBoxNode("Geometry", new CGRect(-55, -20, 110, 40), PurpleColor, 10, true); geometryNodeB.Position = new SCNVector3(140, 0, 0); geometryNodeB.Opacity = 0; geometryNodeA.AddChildNode(geometryNodeB); // Arrow from "Node B" to the new geometry arrowNode = SCNNode.Create(); arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(55, 3), new CGSize(10, 14), 4, false), 0); arrowNode.Position = new SCNVector3(0, 75, 0); arrowNode.Rotation = new SCNVector4(0, 0, 1, -(float)(Math.PI * 0.5f)); arrowNode.Geometry.FirstMaterial.Diffuse.Contents = PurpleColor; geometryNodeB.AddChildNode(arrowNode); // Arrow from the new geometry to "Material" arrowNode = SCNNode.Create(); arrowNode.Name = "arrow-shared-material"; arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(140, 3), new CGSize(10, 14), 4, true), 0); arrowNode.Position = new SCNVector3(-130, -80, 0); arrowNode.Rotation = new SCNVector4(0, 0, 1, (float)(Math.PI * 0.12f)); arrowNode.Geometry.FirstMaterial.Diffuse.Contents = RedColor; geometryNodeB.AddChildNode(arrowNode); // Reveal SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; geometryNodeB.Opacity = 1.0f; oldArrowNode.Opacity = 0.0f; // Show the related code TextManager.AddEmptyLine(); TextManager.AddCode("#// Unshare geometry \n" + "nodeB.Geometry = nodeB.Geometry.#Copy# ();#"); SCNTransaction.Commit(); break; case 3: var materialANode = ContentNode.FindChildNode("material", true); oldArrowNode = ContentNode.FindChildNode("arrow-shared-material", true); // New "Material" box var materialBNode = Utils.SCBoxNode("Material", new CGRect(-55, -20, 110, 40), NSColor.Orange, 10, true); materialBNode.Position = new SCNVector3(140, 0, 0); materialBNode.Opacity = 0; materialANode.AddChildNode(materialBNode); // Arrow from the unshared geometry to the new material arrowNode = SCNNode.Create(); arrowNode.Geometry = SCNShape.Create(Utils.SCArrowBezierPath(new CGSize(55, 3), new CGSize(10, 14), 4, false), 0); arrowNode.Position = new SCNVector3(0, 75, 0); arrowNode.Rotation = new SCNVector4(0, 0, 1, -(float)(Math.PI * 0.5f)); arrowNode.Geometry.FirstMaterial.Diffuse.Contents = NSColor.Orange; materialBNode.AddChildNode(arrowNode); // Reveal SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 1; materialBNode.Opacity = 1.0f; oldArrowNode.Opacity = 0.0f; SCNTransaction.Commit(); break; } }
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) { float delay = 0; switch (index) { case 0: break; case 1: TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.AddEmptyLine(); TextManager.AddBulletAtLevel("Available on OS X 10.8+ and iOS 8.0", 0); TextManager.FlipInText(SlideTextManager.TextType.Bullet); //show some nice icons Icon1 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/Badge_X", "png"), 7, false); Icon1.Position = new SCNVector3(-20, 3.5f, 5); GroundNode.AddChildNode(Icon1); Icon2 = Utils.SCPlaneNode(NSBundle.MainBundle.PathForResource("Images/Badge_iOS", "png"), 7, false); Icon2.Position = new SCNVector3(20, 3.5f, 5); GroundNode.AddChildNode(Icon2); SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; Icon1.Position = new SCNVector3(-6, 3.5f, 5); Icon2.Position = new SCNVector3(6, 3.5f, 5); SCNTransaction.Commit(); break; case 2: SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.75f; Icon1.Position = new SCNVector3(-6, 3.5f, -5); Icon2.Position = new SCNVector3(6, 3.5f, -5); Icon1.Opacity = 0.0f; Icon2.Opacity = 0.0f; SCNTransaction.Commit(); foreach (var node in Boxes) { var popTime = new DispatchTime(DispatchTime.Now, (Int64)(delay * Utils.NSEC_PER_SEC)); DispatchQueue.MainQueue.DispatchAfter(popTime, () => { SCNTransaction.Begin(); SCNTransaction.AnimationDuration = 0.5f; node.Rotation = new SCNVector4(1, 0, 0, 0); node.Scale = new SCNVector3(0.02f, 0.02f, 0.02f); node.Opacity = 1.0f; SCNTransaction.Commit(); }); delay += 0.05f; } TextManager.FlipOutText(SlideTextManager.TextType.Bullet); TextManager.FlipOutText(SlideTextManager.TextType.Subtitle); TextManager.SetSubtitle("Graphic Frameworks"); TextManager.FlipInText(SlideTextManager.TextType.Bullet); TextManager.FlipInText(SlideTextManager.TextType.Subtitle); break; } }