// Queries the root node for the expected nodes. internal GameNodes (SCNNode sceneRoot) { Object = sceneRoot.FindChildNode ("teapot", true); if (Object == null) throw new InvalidProgramException (); ObjectMaterial = Object.Geometry?.FirstMaterial; if (ObjectMaterial == null) throw new InvalidProgramException (); Confetti = sceneRoot.FindChildNode ("particles", true); if (Confetti == null) throw new InvalidProgramException (); Camera = sceneRoot.FindChildNode ("camera", true).Camera; if (Camera == null) throw new InvalidProgramException (); CountdownLabel = new SKLabelNode ("Chalkduster") { HorizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Center }; CongratulationsLabel = new SKLabelNode ("Chalkduster") { FontColor = GameColors.DefaultFont, Text = "You Win!", FontSize = 45 }; }
private void AddPlane(string nodeName, SCNNode portalNode, string imageName) { SCNNode child = portalNode.FindChildNode(nodeName, true); child.Geometry.FirstMaterial.Diffuse.Contents = new UIImage(imageName); child.RenderingOrder = 200; }
private void AddCar() { SCNNode pointOfView = sceneView.PointOfView; if (pointOfView == null) { return; } SCNMatrix4 transform = pointOfView.Transform; SCNVector3 orientation = new SCNVector3(-transform.M31, -transform.M32, -transform.M33); SCNVector3 location = new SCNVector3(transform.M41, transform.M42, transform.M43); SCNVector3 currentPositionOfCamera = orientation + location; //TODO 4.2 Creando el coche SCNScene carScene = SCNScene.FromFile("art.scnassets/CarScene.scn"); SCNNode carNode = carScene.RootNode.FindChildNode("frame", false); SCNNode frontLeftWheel = carNode.FindChildNode("frontLeftParent", false); SCNPhysicsVehicleWheel v_frontLeftWheel = SCNPhysicsVehicleWheel.Create(frontLeftWheel); SCNNode frontRightWheel = carNode.FindChildNode("frontRightParent", false); SCNPhysicsVehicleWheel v_frontRightWheel = SCNPhysicsVehicleWheel.Create(frontRightWheel); SCNNode rearLeftWheel = carNode.FindChildNode("rearLeftParent", false); SCNPhysicsVehicleWheel v_rearLeftWheel = SCNPhysicsVehicleWheel.Create(rearLeftWheel); SCNNode rearRightWheel = carNode.FindChildNode("rearRightParent", false); SCNPhysicsVehicleWheel v_rearRightWheel = SCNPhysicsVehicleWheel.Create(rearRightWheel); carNode.Position = currentPositionOfCamera; SCNPhysicsBody body = SCNPhysicsBody.CreateBody(SCNPhysicsBodyType.Dynamic, SCNPhysicsShape.Create(carNode, keepAsCompound: true)); carNode.PhysicsBody = body; PhysicsVehicle = SCNPhysicsVehicle.Create(carNode.PhysicsBody, new SCNPhysicsVehicleWheel[] { v_frontLeftWheel, v_frontRightWheel, v_rearLeftWheel, v_rearRightWheel }); sceneView.Scene.PhysicsWorld.AddBehavior(PhysicsVehicle); sceneView.Scene.RootNode.AddChildNode(carNode); }
private void AddWalls(string nodeName, SCNNode portalNode, string imageName) { SCNNode child = portalNode.FindChildNode(nodeName, true); child.Geometry.FirstMaterial.Diffuse.Contents = new UIImage(imageName); child.RenderingOrder = 200; SCNNode mask = child.FindChildNode("mask", false); if (mask != null) { mask.Geometry.FirstMaterial.Transparency = 0.000001f; } }
// Queries the root node for the expected nodes. internal GameNodes(SCNNode sceneRoot) { Object = sceneRoot.FindChildNode("teapot", true); if (Object == null) { throw new InvalidProgramException(); } ObjectMaterial = Object.Geometry?.FirstMaterial; if (ObjectMaterial == null) { throw new InvalidProgramException(); } Confetti = sceneRoot.FindChildNode("particles", true); if (Confetti == null) { throw new InvalidProgramException(); } Camera = sceneRoot.FindChildNode("camera", true).Camera; if (Camera == null) { throw new InvalidProgramException(); } CountdownLabel = new SKLabelNode("Chalkduster") { HorizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Center }; CongratulationsLabel = new SKLabelNode("Chalkduster") { FontColor = GameColors.DefaultFont, Text = "You Win!", FontSize = 45 }; }
void SetupAutomaticCameraPositions() { SCNNode root = GameView.Scene.RootNode; mainGround = root.FindChildNode("bloc05_collisionMesh_02", true); groundToCameraPosition = new Dictionary <SCNNode, SCNVector3> (); groundToCameraPosition.Add(root.FindChildNode("bloc04_collisionMesh_02", true), new SCNVector3(-0.188683f, 4.719608f, 0f)); groundToCameraPosition.Add(root.FindChildNode("bloc03_collisionMesh", true), new SCNVector3(-0.435909f, 6.297167f, 0f)); groundToCameraPosition.Add(root.FindChildNode("bloc07_collisionMesh", true), new SCNVector3(-0.333663f, 7.868592f, 0f)); groundToCameraPosition.Add(root.FindChildNode("bloc08_collisionMesh", true), new SCNVector3(-0.575011f, 8.739003f, 0f)); groundToCameraPosition.Add(root.FindChildNode("bloc06_collisionMesh", true), new SCNVector3(-1.095519f, 9.425292f, 0f)); groundToCameraPosition.Add(root.FindChildNode("bloc05_collisionMesh_02", true), new SCNVector3(-0.072051f, 8.202264f, 0f)); groundToCameraPosition.Add(root.FindChildNode("bloc05_collisionMesh_01", true), new SCNVector3(-0.072051f, 8.202264f, 0)); }
void AddMonkeyAtPosition(SCNVector3 worldPos, nfloat rotation) { if (Monkeys == null) { Monkeys = new List <MonkeyCharacter> (); } SCNNode palmTree = CreateMonkeyPalmTree(); palmTree.Position = worldPos; palmTree.Rotation = new SCNVector4(0f, 1f, 0f, rotation); RootNode.AddChildNode(palmTree); MonkeyCharacter monkey = (MonkeyCharacter)palmTree.FindChildNode("monkey", true); if (monkey != null) { Monkeys.Add(monkey); } }
public void CreateFlagSimulationFromNode(SCNNode node) { var meshData = new ClothSimMetalNode(this.device, Width, Height); var clothNode = SCNNode.FromGeometry(meshData.Geometry); var flag = node.FindChildNode("flagStaticWave", true); if (flag != null) { var boundingBoxMax = SCNVector3.Zero; var boundingBoxMin = SCNVector3.Zero; flag.GetBoundingBox(ref boundingBoxMin, ref boundingBoxMax); var existingFlagBV = boundingBoxMax - boundingBoxMin; var rescaleToMatchSizeMatrix = SCNMatrix4.Scale(existingFlagBV.X / (float)Width); var rotation = SCNQuaternion.FromAxisAngle(SCNVector3.UnitX, (float)Math.PI / 2f); var localTransform = rescaleToMatchSizeMatrix * SCNMatrix4.Rotate(rotation.ToQuaternion()); localTransform.Transpose(); var currentTransform = SCNMatrix4.Transpose(flag.Transform); var newTransform = currentTransform * localTransform; clothNode.Transform = SCNMatrix4.Transpose(newTransform);// flag.Transform * localTransform; if (clothNode.Geometry != null) { clothNode.Geometry.FirstMaterial = flag.Geometry?.FirstMaterial; if (clothNode.Geometry.FirstMaterial != null) { clothNode.Geometry.FirstMaterial.DoubleSided = true; } } flag.ParentNode.ReplaceChildNode(flag, clothNode); clothNode.Geometry.SetupPaintColorMask("flag_flagA"); clothNode.SetPaintColors(); clothNode.FixNormalMaps(); this.clothData.Add(new ClothData(clothNode, meshData)); } }
public static SCNNode LoadNodeWithName(string name, string path) { var loadingOptions = NSDictionary.FromObjectsAndKeys(new object[] { "YES", SCNSceneSourceLoading.AnimationImportPolicyPlayRepeatedly }, new object[] { SCNSceneSourceLoading.ConvertToYUpKey, SCNSceneSourceLoading.AnimationImportPolicyKey }); string sceneName = new NSUrl(path).LastPathComponent.ToString(); string scenePath = new NSUrl(path).RemoveLastPathComponent().ToString(); SCNScene scene = SCNScene.FromFile(sceneName, scenePath, loadingOptions); SCNNode node = scene.RootNode; // Search for the node named "name" if (!string.IsNullOrEmpty(name)) { node = node.FindChildNode(name, true); } else { node = node.ChildNodes [0]; } return(node); }
public SCNNode CreateLevel () { RootNode = new SCNNode (); // load level dae and add all root children to the scene. var options = new SCNSceneLoadingOptions { ConvertToYUp = true }; SCNScene scene = SCNScene.FromFile ("level", GameSimulation.PathForArtResource ("level/"), options); foreach (SCNNode node in scene.RootNode.ChildNodes) RootNode.AddChildNode (node); // retrieve the main camera Camera = RootNode.FindChildNode ("camera_game", true); // create our path that the player character will follow. CalculatePathPositions (); // Sun/Moon light SunLight = RootNode.FindChildNode ("FDirect001", true); SunLight.EulerAngles = new SCNVector3 (7.1f * (nfloat)Math.PI / 4, (nfloat)Math.PI / 4, 0f); SunLight.Light.ShadowSampleCount = 1; lightOffsetFromCharacter = new SCNVector3 (1500f, 2000f, 1000f); //workaround directional light deserialization issue SunLight.Light.ZNear = 100f; SunLight.Light.ZFar = 5000f; SunLight.Light.OrthographicScale = 1000f; // Torches var torchesPos = new float[] { 0f, -1f, 0.092467f, -1f, -1f, 0.5f, 0.792f, 0.95383f }; for (int i = 0; i < torchesPos.Length; i++) { if (torchesPos [i] != -1) { SCNVector3 location = LocationAlongPath (torchesPos [i]); location.Y += 50; location.Z += 150; SCNNode node = CreateTorchNode (); node.Position = location; RootNode.AddChildNode (node); } } // After load, we add nodes that are dynamic / animated / or otherwise not static. CreateLavaAnimation (); CreateSwingingTorch (); AnimateDynamicNodes (); // Create our player character SCNNode characterRoot = GameSimulation.LoadNodeWithName (string.Empty, "art.scnassets/characters/explorer/explorer_skinned.dae"); PlayerCharacter = new PlayerCharacter (characterRoot); TimeAlongPath = 0; PlayerCharacter.Position = LocationAlongPath (TimeAlongPath); PlayerCharacter.Rotation = GetPlayerDirectionFromCurrentPosition (); RootNode.AddChildNode (PlayerCharacter); // Optimize lighting and shadows // only the charadcter should cast shadows foreach (var child in RootNode.ChildNodes) child.CastsShadow = false; foreach (var child in PlayerCharacter.ChildNodes) child.CastsShadow = true; // Add some monkeys to the scene. AddMonkeyAtPosition (new SCNVector3 (0f, -30f, -400f), 0f); AddMonkeyAtPosition (new SCNVector3 (3211f, 146f, -400f), -(nfloat)Math.PI / 4f); AddMonkeyAtPosition (new SCNVector3 (5200f, 330f, 600f), 0f); // Volcano SCNNode oldVolcano = RootNode.FindChildNode ("volcano", true); string volcanoDaeName = GameSimulation.PathForArtResource ("level/volcano_effects.dae"); SCNNode newVolcano = GameSimulation.LoadNodeWithName ("dummy_master", volcanoDaeName); oldVolcano.AddChildNode (newVolcano); oldVolcano.Geometry = null; oldVolcano = newVolcano.FindChildNode ("volcano", true); oldVolcano = oldVolcano.ChildNodes [0]; // Animate our dynamic volcano node. string shaderCode = "uniform float speed;\n" + "_geometry.color = vec4(a_color.r, a_color.r, a_color.r, a_color.r);\n" + "_geometry.texcoords[0] += (vec2(0.0, 1.0) * 0.05 * u_time);\n"; string fragmentShaderCode = "#pragma transparent\n"; // Dim background SCNNode back = RootNode.FindChildNode ("dumy_rear", true); foreach (var child in back.ChildNodes) { child.CastsShadow = false; if (child.Geometry == null) continue; foreach (SCNMaterial material in child.Geometry.Materials) { material.LightingModelName = SCNLightingModel.Constant; material.Multiply.Contents = AppKit.NSColor.FromDeviceWhite (0.3f, 1f); material.Multiply.Intensity = 1; } } SCNNode backMiddle = RootNode.FindChildNode ("dummy_middle", true); foreach (var child in backMiddle.ChildNodes) { if (child.Geometry == null) continue; foreach (SCNMaterial material in child.Geometry.Materials) material.LightingModelName = SCNLightingModel.Constant; } foreach (var child in newVolcano.ChildNodes) foreach (var volc in child.ChildNodes) { if (volc != oldVolcano && volc.Geometry != null) { volc.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; volc.Geometry.FirstMaterial.Multiply.Contents = AppKit.NSColor.White; volc.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = shaderCode, EntryPointFragment = fragmentShaderCode }; } } Coconuts = new List<Coconut> (); return RootNode; }
public Catapult(SCNNode node, SFXCoordinator sfxCoordinator, int identifier, Dictionary <string, object> gamedefs) : base(node, null, gamedefs, true, false) { this.Base = node; this.audioEnvironment = sfxCoordinator.AudioEnvironment; // Base teamID and name off looking up teamA or teamB folder in the level parents // This won't work on the old levels. this.Team = this.Base.GetTeam(); this.TeamName = this.Team.GetDescription(); // have team id established this.Base.SetPaintColors(); // correct for the pivot point to place catapult flat on ground this.Base.Position = new SCNVector3(this.Base.Position.X, this.Base.Position.Y - 0.13f, this.Base.Position.Z); // highlight setup this.HighlightObject = node.FindChildNode("Highlight", true); if (this.HighlightObject != null) { this.HighlightObject = this.HighlightObject.FindNodeWithGeometry(); } // hide the highlights on load if (this.HighlightObject != null) { this.HighlightObject.Hidden = true; } if (this.HighlightObject?.Geometry?.FirstMaterial?.Diffuse?.Contents is UIColor color) { this.highlightColor = color; } // they should only have y orientation, nothing in x or z // current scene files have the catapults with correct orientation, but the // eulerAngles are different - x and z are both π, y is within epsilon of 0 // That's from bad decomposition of the matrix. Need to restore the eulerAngles from the source. // Especially if we have animations tied to the euler angles. if (Math.Abs(node.EulerAngles.X) > 0.001f || Math.Abs(node.EulerAngles.Z) > 0.001f) { //Console.WriteLine("Catapult can only have y rotation applied"); } // where to place the ball so it sits on the strap this.catapultStrap = this.Base.FindChildNode("catapultStrap", true); if (this.catapultStrap == null) { throw new Exception("No node with name catapultStrap"); } // this only rotates, and represents the center of the catapult through which to fire this.pullOrigin = this.Base.FindChildNode("pullOrigin", true); if (this.pullOrigin == null) { throw new Exception("No node with name pullOrigin"); } // This is a rope simulation meant for a fixed catapult, the catapult rotates. this.rope = new CatapultRope(node); // attach ball to the inactive strap, search for ballOriginInactiveBelow this.ballOriginInactiveBelow = this.Base.FindChildNode("ballOriginInactiveBelow", true); if (this.ballOriginInactiveBelow == null) { throw new Exception("No node with name ballOriginInactiveBelow"); } this.ballOriginInactiveAbove = this.Base.FindChildNode("ballOriginInactiveAbove", true); if (this.ballOriginInactiveAbove == null) { throw new Exception("No node with name ballOriginInactiveAbove"); } // ball will be made visible and drop once projectile is set and cooldown exceeded this.StrapVisible = StrapVisible.Visible; this.CatapultId = identifier; this.Base.SetValueForKey(NSObject.FromObject(this.CatapultId), new NSString(Catapult.CollisionKey)); this.AudioPlayer = new CatapultAudioSampler(this.Base, sfxCoordinator); // use the teamID to set the collision category mask if (this.PhysicsNode?.PhysicsBody != null) { if (this.Team == Team.TeamA) { this.PhysicsNode.PhysicsBody.CategoryBitMask = (int)CollisionMask.CatapultTeamA; var collisionBitMask = (CollisionMask)(int)this.PhysicsNode.PhysicsBody.CollisionBitMask; this.PhysicsNode.PhysicsBody.CollisionBitMask = (nuint)(int)(collisionBitMask | CollisionMask.CatapultTeamB); } else if (this.Team == Team.TeamB) { this.PhysicsNode.PhysicsBody.CategoryBitMask = (int)CollisionMask.CatapultTeamB; var collisionBitMask = (CollisionMask)(int)this.PhysicsNode.PhysicsBody.CollisionBitMask; this.PhysicsNode.PhysicsBody.CollisionBitMask = (nuint)(int)(collisionBitMask | CollisionMask.CatapultTeamA); } } }
public Character() { for (int i = 0; i < StepsSoundCount; i++) { steps [i, (int)FloorMaterial.Grass] = SCNAudioSource.FromFile(string.Format("game.scnassets/sounds/Step_grass_0{0}.mp3", i)); steps [i, (int)FloorMaterial.Grass].Volume = 0.5f; steps [i, (int)FloorMaterial.Rock] = SCNAudioSource.FromFile(string.Format("game.scnassets/sounds/Step_rock_0{0}.mp3", i)); if (i < StepsInWaterSoundCount) { steps [i, (int)FloorMaterial.Water] = SCNAudioSource.FromFile(string.Format("game.scnassets/sounds/Step_splash_0{0}.mp3", i)); steps [i, (int)FloorMaterial.Water].Load(); } else { steps [i, (int)FloorMaterial.Water] = steps [i % StepsInWaterSoundCount, (int)FloorMaterial.Water]; } steps [i, (int)FloorMaterial.Rock].Load(); steps [i, (int)FloorMaterial.Grass].Load(); // Load the character. SCNScene characterScene = SCNScene.FromFile("game.scnassets/panda.scn"); SCNNode characterTopLevelNode = characterScene.RootNode.ChildNodes [0]; Node = SCNNode.Create(); Node.AddChildNode(characterTopLevelNode); // Configure the "idle" animation to repeat forever foreach (var childNode in characterTopLevelNode.ChildNodes) { foreach (var key in childNode.GetAnimationKeys()) { CAAnimation animation = childNode.GetAnimation(key); animation.UsesSceneTimeBase = false; animation.RepeatCount = float.PositiveInfinity; childNode.AddAnimation(animation, key); } } // retrieve some particle systems and save their birth rate fireEmitter = characterTopLevelNode.FindChildNode("fire", true); fireBirthRate = fireEmitter.ParticleSystems [0].BirthRate; fireEmitter.ParticleSystems [0].BirthRate = 0; fireEmitter.Hidden = false; smokeEmitter = characterTopLevelNode.FindChildNode("smoke", true); smokeBirthRate = smokeEmitter.ParticleSystems [0].BirthRate; smokeEmitter.ParticleSystems [0].BirthRate = 0; smokeEmitter.Hidden = false; whiteSmokeEmitter = characterTopLevelNode.FindChildNode("whiteSmoke", true); whiteSmokeBirthRate = whiteSmokeEmitter.ParticleSystems [0].BirthRate; whiteSmokeEmitter.ParticleSystems [0].BirthRate = 0; whiteSmokeEmitter.Hidden = false; SCNVector3 min = SCNVector3.Zero; SCNVector3 max = SCNVector3.Zero; Node.GetBoundingBox(ref min, ref max); float radius = (max.X - min.X) * .4f; float height = (max.Y - min.Y); // Create a kinematic with capsule. SCNNode colliderNode = SCNNode.Create(); colliderNode.Name = "collider"; colliderNode.Position = new SCNVector3(0f, height * .51f, 0f); colliderNode.PhysicsBody = SCNPhysicsBody.CreateBody( SCNPhysicsBodyType.Kinematic, SCNPhysicsShape.Create(SCNCapsule.Create(radius, height)) ); // We want contact notifications with the collectables, enemies and walls. colliderNode.PhysicsBody.ContactTestBitMask = (nuint)(int)(Bitmask.SuperCollectable | Bitmask.Collectable | Bitmask.Collision | Bitmask.Enemy); Node.AddChildNode(colliderNode); walkAnimation = LoadAnimationFromSceneNamed("game.scnassets/walk.scn"); walkAnimation.UsesSceneTimeBase = false; walkAnimation.FadeInDuration = .3f; walkAnimation.FadeOutDuration = .3f; walkAnimation.RepeatCount = float.PositiveInfinity; walkAnimation.Speed = CharacterSpeedFactor; // Play foot steps at specific times in the animation walkAnimation.AnimationEvents = new [] { SCNAnimationEvent.Create(.1f, (animation, animatedObject, playingBackward) => PlayFootStep()), SCNAnimationEvent.Create(.6f, (animation, animatedObject, playingBackward) => PlayFootStep()) }; } }
public SCNNode CreateLevel() { RootNode = new SCNNode(); // load level dae and add all root children to the scene. var options = new SCNSceneLoadingOptions { ConvertToYUp = true }; SCNScene scene = SCNScene.FromFile("level", GameSimulation.PathForArtResource("level/"), options); foreach (SCNNode node in scene.RootNode.ChildNodes) { RootNode.AddChildNode(node); } // retrieve the main camera Camera = RootNode.FindChildNode("camera_game", true); // create our path that the player character will follow. CalculatePathPositions(); // Sun/Moon light SunLight = RootNode.FindChildNode("FDirect001", true); SunLight.EulerAngles = new SCNVector3(7.1f * (nfloat)Math.PI / 4, (nfloat)Math.PI / 4, 0f); SunLight.Light.ShadowSampleCount = 1; lightOffsetFromCharacter = new SCNVector3(1500f, 2000f, 1000f); //workaround directional light deserialization issue SunLight.Light.ZNear = 100f; SunLight.Light.ZFar = 5000f; SunLight.Light.OrthographicScale = 1000f; // Torches var torchesPos = new float[] { 0f, -1f, 0.092467f, -1f, -1f, 0.5f, 0.792f, 0.95383f }; for (int i = 0; i < torchesPos.Length; i++) { if (torchesPos [i] != -1) { SCNVector3 location = LocationAlongPath(torchesPos [i]); location.Y += 50; location.Z += 150; SCNNode node = CreateTorchNode(); node.Position = location; RootNode.AddChildNode(node); } } // After load, we add nodes that are dynamic / animated / or otherwise not static. CreateLavaAnimation(); CreateSwingingTorch(); AnimateDynamicNodes(); // Create our player character SCNNode characterRoot = GameSimulation.LoadNodeWithName(string.Empty, "art.scnassets/characters/explorer/explorer_skinned.dae"); PlayerCharacter = new PlayerCharacter(characterRoot); TimeAlongPath = 0; PlayerCharacter.Position = LocationAlongPath(TimeAlongPath); PlayerCharacter.Rotation = GetPlayerDirectionFromCurrentPosition(); RootNode.AddChildNode(PlayerCharacter); // Optimize lighting and shadows // only the charadcter should cast shadows foreach (var child in RootNode.ChildNodes) { child.CastsShadow = false; } foreach (var child in PlayerCharacter.ChildNodes) { child.CastsShadow = true; } // Add some monkeys to the scene. AddMonkeyAtPosition(new SCNVector3(0f, -30f, -400f), 0f); AddMonkeyAtPosition(new SCNVector3(3211f, 146f, -400f), -(nfloat)Math.PI / 4f); AddMonkeyAtPosition(new SCNVector3(5200f, 330f, 600f), 0f); // Volcano SCNNode oldVolcano = RootNode.FindChildNode("volcano", true); string volcanoDaeName = GameSimulation.PathForArtResource("level/volcano_effects.dae"); SCNNode newVolcano = GameSimulation.LoadNodeWithName("dummy_master", volcanoDaeName); oldVolcano.AddChildNode(newVolcano); oldVolcano.Geometry = null; oldVolcano = newVolcano.FindChildNode("volcano", true); oldVolcano = oldVolcano.ChildNodes [0]; // Animate our dynamic volcano node. string shaderCode = "uniform float speed;\n" + "_geometry.color = vec4(a_color.r, a_color.r, a_color.r, a_color.r);\n" + "_geometry.texcoords[0] += (vec2(0.0, 1.0) * 0.05 * u_time);\n"; string fragmentShaderCode = "#pragma transparent\n"; // Dim background SCNNode back = RootNode.FindChildNode("dumy_rear", true); foreach (var child in back.ChildNodes) { child.CastsShadow = false; if (child.Geometry == null) { continue; } foreach (SCNMaterial material in child.Geometry.Materials) { material.LightingModelName = SCNLightingModel.Constant; material.Multiply.Contents = AppKit.NSColor.FromDeviceWhite(0.3f, 1f); material.Multiply.Intensity = 1; } } SCNNode backMiddle = RootNode.FindChildNode("dummy_middle", true); foreach (var child in backMiddle.ChildNodes) { if (child.Geometry == null) { continue; } foreach (SCNMaterial material in child.Geometry.Materials) { material.LightingModelName = SCNLightingModel.Constant; } } foreach (var child in newVolcano.ChildNodes) { foreach (var volc in child.ChildNodes) { if (volc != oldVolcano && volc.Geometry != null) { volc.Geometry.FirstMaterial.LightingModelName = SCNLightingModel.Constant; volc.Geometry.FirstMaterial.Multiply.Contents = AppKit.NSColor.White; volc.Geometry.ShaderModifiers = new SCNShaderModifiers { EntryPointGeometry = shaderCode, EntryPointFragment = fragmentShaderCode }; } } } Coconuts = new List <Coconut> (); return(RootNode); }