ThumbWorks / AugmentedSolarSystem

An Augmented reality experience to explore planets in our Solar System
71 stars 25 forks source link

Add all of the moons #41

Open rodericj opened 6 years ago

rodericj commented 6 years ago

A little bit of issue with the initial tries on this. Should be able to use SwiftAA.

johndpope commented 6 years ago

for consideration - the way this project is structured - https://github.com/johndpope/PhysicsTest/blob/master/PhysicsTest/ViewController.swift

when the planets are added - they have a physical body + orbit + moons. this may help organize adding *all the moons. credits @henkvanderspek


           let moon = Moon(body: PhyiscalBody.moon, orbit: Orbit.moon)
            let earth = Planet(body: PhyiscalBody.earth, orbit: Orbit.earth, moons: [moon])

struct PhyiscalBody {
    let radius: Float
    let color: Color
    var diamater: Float {
        return radius * 2
    }
}

struct Orbit {
    let duration: TimeInterval
    let axis: Float
    let distance: Float
}

struct Color {
    let red: Float
    let green: Float
    let blue: Float
}

struct Planet {
    let body: PhyiscalBody
    let orbit: Orbit
    let moons: [Moon]
}

struct Moon {
    let body: PhyiscalBody
    let orbit: Orbit
}

struct SolarSystem {
    var planets: [Planet]
}

private extension SCNNode {
    func runOrbit(_ orbit: Orbit) {
        if orbit.duration <= 0 { return }
        if orbit.distance <= 0 { return }
        let degrees = Float(360.0/orbit.duration)
        let angle = CGFloat(GLKMathDegreesToRadians(degrees))
        let rotate = SCNAction.rotateBy(x: 0, y: angle, z: 0, duration: 1.0)
        let forever = SCNAction.repeatForever(rotate)
        runAction(forever, forKey: nil)
    }
}

private extension PhyiscalBody {
    var node: SCNNode {
        let geometry = SCNSphere(radius: CGFloat(radius))
        geometry.firstMaterial?.diffuse.contents = UIColor(color: color)
        geometry.isGeodesic = true
        return SCNNode(geometry: geometry)
    }
}

private extension Planet {
    var node: SCNNode {
        let bnode = body.node
        bnode.position = SCNVector3Make(0, 0, orbit.distance)
        let center = SCNNode()
        center.rotation = SCNVector4Make(0, 0, 1, GLKMathDegreesToRadians(orbit.axis))
        center.addChildNode(bnode)
        center.runOrbit(orbit)
        for moon in moons {
            let n = moon.node
            center.addChildNode(n)
        }
        return center
    }
}

private extension Moon {
    var node: SCNNode {
        // Merge with duplicate stuff from above
        let bnode = body.node
        bnode.position = SCNVector3Make(0, 0, orbit.distance)
        let center = SCNNode()
        center.rotation = SCNVector4Make(0, 0, 1, GLKMathDegreesToRadians(orbit.axis))
        center.addChildNode(bnode)
        center.runOrbit(orbit)
        return center
    }
}

extension SolarSystem {
    var scene: SCNScene {
        let scene = SCNScene()
        let camera = SCNNode.camera()
        let sun = SCNNode.sun()
        camera.addChildNode(sun)
        scene.rootNode.addChildNode(camera)
        let center = SCNNode()
        for planet in planets {
            center.addChildNode(planet.node)
        }
        scene.rootNode.addChildNode(center)
        return scene
    }
}