Everything so far
This commit is contained in:
		
							parent
							
								
									1b4a17dc20
								
							
						
					
					
						commit
						18a92331c9
					
				
					 4 changed files with 83 additions and 21 deletions
				
			
		|  | @ -9,21 +9,35 @@ | |||
| import SceneKit | ||||
| import QuartzCore | ||||
| 
 | ||||
| class GameViewController: NSViewController { | ||||
|      | ||||
| class GameViewController: NSViewController, SCNSceneRendererDelegate { | ||||
|     static let numberOfBallsPerSide = 41 | ||||
| 
 | ||||
|     private var balls = [SCNNode]() | ||||
| 
 | ||||
|     override func viewDidLoad() { | ||||
|         super.viewDidLoad() | ||||
|          | ||||
| 
 | ||||
|         guard let sceneView = view as? SCNView else { | ||||
|             fatalError("My view isn't a SCNView!") | ||||
|         } | ||||
|         sceneView.delegate = self | ||||
|         sceneView.rendersContinuously = true | ||||
|         sceneView.preferredFramesPerSecond = 30 | ||||
| 
 | ||||
|         // create a new scene | ||||
|         let scene = SCNScene(named: "art.scnassets/ship.scn")! | ||||
|         let scene = SCNScene(named: "art.scnassets/blank.scn")! | ||||
|          | ||||
|         // create and add a camera to the scene | ||||
|         let cameraNode = SCNNode() | ||||
|         cameraNode.camera = SCNCamera() | ||||
|         let camera = SCNCamera() | ||||
|         cameraNode.camera = camera | ||||
|         scene.rootNode.addChildNode(cameraNode) | ||||
|          | ||||
|         // place the camera | ||||
|         cameraNode.position = SCNVector3(x: 0, y: 0, z: 15) | ||||
|         cameraNode.position = SCNVector3(x: CGFloat(GameViewController.numberOfBallsPerSide / 7), | ||||
|                                          y: 1.5, | ||||
|                                          z: CGFloat(GameViewController.numberOfBallsPerSide / 3)) | ||||
|         cameraNode.look(at: SCNVector3()) | ||||
|          | ||||
|         // create and add a light to the scene | ||||
|         let lightNode = SCNNode() | ||||
|  | @ -38,33 +52,44 @@ class GameViewController: NSViewController { | |||
|         ambientLightNode.light!.type = .ambient | ||||
|         ambientLightNode.light!.color = NSColor.darkGray | ||||
|         scene.rootNode.addChildNode(ambientLightNode) | ||||
|          | ||||
|         // retrieve the ship node | ||||
|         let ship = scene.rootNode.childNode(withName: "ship", recursively: true)! | ||||
|          | ||||
|         // animate the 3d object | ||||
|         ship.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: 2, z: 0, duration: 1))) | ||||
|          | ||||
|         // retrieve the SCNView | ||||
|         let scnView = self.view as! SCNView | ||||
| 
 | ||||
|         let sphereContainer = SCNNode() | ||||
|         scene.rootNode.addChildNode(sphereContainer) | ||||
| 
 | ||||
|         if let sphere = scene.rootNode.childNode(withName: "sphere", recursively: false) { | ||||
|             // Remove it. We're going to copy it all over the place. | ||||
|             sphere.removeFromParentNode() | ||||
|             for i in 0..<GameViewController.numberOfBallsPerSide { | ||||
|                 for j in 0..<GameViewController.numberOfBallsPerSide { | ||||
|                     let ijSphere = sphere.clone() | ||||
|                     balls.append(ijSphere) | ||||
|                     ijSphere.worldPosition = SCNVector3(x: CGFloat(-GameViewController.numberOfBallsPerSide / 2) + CGFloat(i), | ||||
|                                                         y: 0.0, | ||||
|                                                         z: CGFloat(-GameViewController.numberOfBallsPerSide / 2) + CGFloat(j)) | ||||
|                     sphereContainer.addChildNode(ijSphere) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         sphereContainer.runAction(SCNAction.repeatForever(SCNAction.rotate(by: CGFloat.pi, around: SCNVector3(0, 1, 0), duration: 40.0))) | ||||
|          | ||||
|         // set the scene to the view | ||||
|         scnView.scene = scene | ||||
|         sceneView.scene = scene | ||||
|          | ||||
|         // allows the user to manipulate the camera | ||||
|         scnView.allowsCameraControl = true | ||||
|         sceneView.allowsCameraControl = false | ||||
|          | ||||
|         // show statistics such as fps and timing information | ||||
|         scnView.showsStatistics = true | ||||
|         sceneView.showsStatistics = true | ||||
|          | ||||
|         // configure the view | ||||
|         scnView.backgroundColor = NSColor.black | ||||
|         sceneView.backgroundColor = NSColor.black | ||||
|          | ||||
|         // Add a click gesture recognizer | ||||
|         let clickGesture = NSClickGestureRecognizer(target: self, action: #selector(handleClick(_:))) | ||||
|         var gestureRecognizers = scnView.gestureRecognizers | ||||
|         var gestureRecognizers = sceneView.gestureRecognizers | ||||
|         gestureRecognizers.insert(clickGesture, at: 0) | ||||
|         scnView.gestureRecognizers = gestureRecognizers | ||||
|         sceneView.gestureRecognizers = gestureRecognizers | ||||
|     } | ||||
|      | ||||
|     @objc | ||||
|  | @ -102,4 +127,41 @@ class GameViewController: NSViewController { | |||
|             SCNTransaction.commit() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     func delayForSphereAt(x: Int, y: Int) -> Double { | ||||
|         return 0.05 * Double(x) + 0.03 * Double(y) | ||||
|     } | ||||
| 
 | ||||
|     // MARK: - SCNRendererDelegate | ||||
| 
 | ||||
|     static let numberOfSteps = 100 | ||||
|     var step = 0 | ||||
|     var maxY = 0.0 | ||||
|     var minY = 0.0 | ||||
| 
 | ||||
|     func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { | ||||
|         for z in 0..<GameViewController.numberOfBallsPerSide { | ||||
|             for x in 0..<GameViewController.numberOfBallsPerSide { | ||||
|                 let idx = z * GameViewController.numberOfBallsPerSide + x | ||||
|                 let node = balls[idx] | ||||
|                 let delay = delayForSphereAt(x: x, y: z) | ||||
|                 //let inputX = 2.0 * Double.pi * Double(step) / Double(GameViewController.numberOfSteps) + delay | ||||
| 
 | ||||
|                 let inputX = 2.0 / 3.0 * time + delay | ||||
|                 let y = sin(inputX) + sin(2.0 * inputX) + sin(4.0 * inputX) + sin(8.0 * inputX) | ||||
| 
 | ||||
|                 node.worldPosition.y = CGFloat(y) | ||||
| 
 | ||||
|                 maxY = max(y, maxY) | ||||
|                 minY = min(y, minY) | ||||
|                 let scale = CGFloat(map(y, inMin: minY, inMax: maxY, outMin: 0.0, outMax: 1.0)) | ||||
|                 node.scale = SCNVector3(x: scale, y: scale, z: scale) | ||||
|             } | ||||
|         } | ||||
|         step = (step + 1) % GameViewController.numberOfSteps | ||||
|     } | ||||
| 
 | ||||
|     func map(_ x: Double, inMin: Double, inMax: Double, outMin: Double, outMax: Double) -> Double { | ||||
|         return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin; | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								Waveform/art.scnassets/blank.scn
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Waveform/art.scnassets/blank.scn
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 342 KiB | 
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue