diff --git a/ar.md b/ar.md new file mode 100644 index 0000000000000000000000000000000000000000..81fab2113a8106c6d598b5cdcff3e0f8528d1ec2 --- /dev/null +++ b/ar.md @@ -0,0 +1,209 @@ + + +# Beginning ARKit +[Beginning ARKit](https://www.raywenderlich.com/737368-beginning-arkit/) from [https://raywenderlich.com](https://raywenderlich.com). + +## Git rid of "SpaceShip", and draw first object + +- In viewDidLoad: delete everything after showsStatistics +- In viewDidLoad: + +```swift + sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints] + sceneView.autoenablesDefaultLighting = true +``` + +- create new func after viewWillDisappear: + +```swift + func drawSphereAtOrigin() { + let sphere = SCNNode(geometry: SCNSphere(radius: 0.05)) // (all objects are nodes) + sphere.geometry?.firstMaterial?.diffuse.contents = UIColor.blue + sphere.position = SCNVector3(0,0,0) + sceneView.scene.rootNode.addChildNode(sphere) + } +``` + +- call drawSphereAtOrigin() at end of viewWillAppear() + +See: +- axis (red is X, blue Z, yellow Y) at origin +- yellow dots are "feature points" (points that are probably part of a surface, but not a plane) + +## Modifying the sphere + +Colors that we see are *reflected* light. +- Matte surfaces give off "diffuse" reflection (sent in all directions), also called "color intensity". +- *Specular* reflection is that which bounces right back, the "shiny highlights". + + +Create an orange square at 12 o'clock position, a bit higher and +behind origin (20 cm above origin, 30 cm behind, 10 cm in +size). Orange w/ white highlights: + +```swift + func drawBox() { + let box = SCNNode(geometry: SCNBox(width: 0.1, height: 0.1 , length: 0.1, chamferRadius: 0.0)) + box.position = SCNVector3(0, 0.2, -0.3) + box.geometry?.firstMaterial?.diffuse.contents = UIColor.orange + box.geometry?.firstMaterial?.specular.contents = UIColor.white + sceneView.scene.rootNode.addChildNode(box) + } +``` + +Notes: +- *chamfer radius* is roundness of corners. +- source of virtual light is phone + +## A Pyramid + +30 cm in front, 20 below, 10 cm all dimensions, green w/ red highlights: + +```swift + func drawPyramidAt600Low() { + let pyr = SCNNode(geometry: SCNPyramid(width: 0.1, height: 0.1, length: 0.1)) + pyr.geometry?.firstMaterial?.diffuse.contents = UIColor.green + pyr.geometry?.firstMaterial?.specular.contents = UIColor.red + pyr.position = SCNVector3(0, -0.2, 0.3) + sceneView.scene.rootNode.addChildNode(pyr) + } +``` + +# Draw a cat + +- use images instead of flat +- add cat, earth picture assets +- define the following at bottom of file: +- 10 cm plane at 9 o'clock +- 20 cm left +- painted w/ cat + +```swift + func drawCat() { + let cat = SCNNode(geometry: SCNPlane(width: 0.1, height: 0.1)) + cat.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "cat") + cat.geometry?.firstMaterial?.isDoubleSided = true + cat.position = SCNVector3(-0.2, 0, 0) + sceneView.scene.rootNode.addChildNode(cat) + } +``` + +and then + +```swift + cat.geometry?.firstMaterial?.isDoubleSided = true +``` + +Use euler angles: +- rotation around x axis ("pitch") +- rotation around y axis ("yaw") +- rotation around z axis ("roll") + + +Convention is that positive rotation is counter-clockwise +- and in radians +- rotate 45 clockwise around x, 20 counter y, 45 countercl z + +```swift +extension Int { + func degRadians() -> CGFloat { + return CGFloat(self) * CGFloat.pi / 180 + } +} +``` + +And then: +```swift + cat.eulerAngles = SCNVector3(-45.degreesToRadians(), 20.degreesToRadians(), 45.degreesToRadians()) +``` + +- repaint earth to look like sphere, give it yellow highlights + +```swift + func drawSphereAtOrigin() { + let sphere = SCNNode(geometry: SCNSphere(radius: 0.05)) + sphere.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "earth") + sphere.geometry?.firstMaterial?.specular.contents = UIColor.yellow + sphere.position = SCNVector3(0,0,0) + sceneView.scene.rootNode.addChildNode(sphere) + } +``` + + +Add torus at 3 o'clock, red, w/ white highlights +- a large ring, pipe encircles ("ring radius", "pipe radius") + +```swift + func drawDonut() { + let donut = SCNNode(geometry: SCNTorus(ringRadius: 0.05, pipeRadius: 0.03)) + donut.geometry?.firstMaterial?.diffuse.contents = UIColor.red + donut.geometry?.firstMaterial?.specular.contents = UIColor.white + donut.position = SCNVector3(0.2,0,0) + donut.eulerAngles = SCNVector3(0,0,45.degRadians()) + sceneView.scene.rootNode.addChildNode(donut) + } +``` + +## Actions + +"actions" are objects you can use to make changes to scenekit objects + - rotating, growing/shrinking + +```swift + let rotate = SCNAction.rotate(by: 360.degreesToRadians(), around: SCNVector3(0,1,0), duration: 8) + sphere.runAction(rotate) +``` + +can affect other actions: +- multiple in parallel +- sequence +- repeat *n* times +- repeat indefinitely + + +### Spin Earth + +```swift + let rotate = SCNAction.rotate(by: 360.degreesToRadians(), around: SCNVector3(0,1,0), duration: 8) + let rotateForever = SCNAction.repeatForever(rotate) +``` + +## The "SpaceShip" + +The ARkit's *scene object*: + - virtual world overlaying real world + - we have been adding objects by adding them to the scene in the ar scenekit view + - "there is another" + +Another scene: "art.ship": +- originally loaded into the scene object of the ar scenekitview at the beginning + +We can add it to ours by extracting it from a scene file and adding to the scene object of AR scenekit view +- load into placeholder scene object, +- use childNode (withName) recursively to find it + + +Use by: +- make the `sphere` variable global to the view: + - `var sphere = SCNNode()` before ViewDidLoad +- remove "let" of sphere property in the func + +## The "SpaceShip" Orbits +- get the scene containing the ship +- splat it 1 meter right of origin by adding to Earth +- scale down to 1/3 size + +```swift + func drawShip() { + let scene = SCNScene(named: "art.scnassets/ship.scn")! + let ship = (scene.rootNode.childNode(withName: "ship", recursively: false))! + ship.position = SCNVector3(1, 0, 0) + ship.scale = SCNVector3(0.3, 0.3, 0.3) + ship.eulerAngles = SCNVector3(0, 180.degreesToRadians(), 0) + sphere.addChildNode(ship) + } +``` + +Use Euler angles to make it face forwards. + + diff --git a/arActions.png b/arActions.png new file mode 100644 index 0000000000000000000000000000000000000000..97995af513aea6490912ca26025fe44ff08dc4c4 Binary files /dev/null and b/arActions.png differ diff --git a/arDiffuseVsSpecular.png b/arDiffuseVsSpecular.png new file mode 100644 index 0000000000000000000000000000000000000000..ab91dc5b69e3ff9f5a4ebb232c7e5c078a7fddb6 Binary files /dev/null and b/arDiffuseVsSpecular.png differ diff --git a/arRotationAngles.png b/arRotationAngles.png new file mode 100644 index 0000000000000000000000000000000000000000..6b095913ce1adc1f80b54de81e018f2915ca989f Binary files /dev/null and b/arRotationAngles.png differ diff --git a/assign5/.DS_Store b/assign5/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..668dbd009fc09dfbbc09226b242ea293f1a927be Binary files /dev/null and b/assign5/.DS_Store differ