i need focus node, example pyramid. apply distance camera, move camera based on user click. approach :
import scenekit class gameviewcontroller: uiviewcontroller { let scene = scnscene() override func viewdidload() { super.viewdidload() let camera = scncamera() camera.usesorthographicprojection = true camera.orthographicscale = 4 camera.znear = 1 camera.zfar = 100 let cameranode = scnnode() cameranode.position = scnvector3(x: 0, y: 0, z: 6) cameranode.camera = camera let cameraorbit = scnnode() cameraorbit.name = "orbit" cameraorbit.addchildnode(cameranode) scene.rootnode.addchildnode(cameraorbit) let py = scnpyramid(width: 2, height: 3, length: 2) py.firstmaterial?.diffuse.contents = uicolor.purple() let p = scnnode(geometry: py) p.position = scnvector3(x:0,y:0,z:2) //see note scene.rootnode.addchildnode(p) /* n o t e : position of pyramid must not changed intention rotate camera not pyramid node repeat, don't want rotate pyramid */ let scnview = self.view as! scnview scnview.scene = scene scnview.allowscameracontrol = false scnview.backgroundcolor = uicolor.black() // user rotates camera tapping let tapgesture = uitapgesturerecognizer(target: self, action: #selector(handletap(_:))) scnview.addgesturerecognizer(tapgesture) } //the function camera rotation : func handletap(_ gesturerecognize: uigesturerecognizer) { //i guess solution around here //like modify cameraorbit.position ? //or cameranode.position ? //tried both doesn't work //or used them wrong let cameraorbit = scene.rootnode.childnode(withname: "orbit", recursively: true)! scntransaction.begin() scntransaction.animationduration = 2 cameraorbit.eulerangles.z += float(m_pi_2) //see below scntransaction.commit() /* realise performing rotation on camera (the camera position unchanged) works z rotation, not want. want solution, works eulerangles.x , eulerangles.y. used eulerangles.z example since it's easier observe. guess true solution involves moving camera specific trajectory, not rotation of "anchored" camera. */ } //... }
the result :
what want achieve make rotation relative centre :
my question is, how adjust pivot can achieve rotation relative pyramid's centre?
note : don't want rotate pyramid.
i found solution, can't explain why. please comment if can explain.
the camera orbit position must set match object's location (in case, pyramid). so
cameraorbit.position = p.position
then here comes mystery solution, add cameraorbit.position.y half of pi :
cameraorbit.position.y += float(m_pi_2) //therefore have final cameraorbit.position (0, pi/2, 2)
tested , works cameraorbit.eulerangles. don't have clue why works. if pi/2 coming projection thingy, why it's tucked on y only? mean, when of cameraorbit.eulerangles, don't need assign pi/2 either x or z.
here complete code
import scenekit class gameviewcontroller: uiviewcontroller { let scene = scnscene() override func viewdidload() { super.viewdidload() let camera = scncamera() camera.usesorthographicprojection = true camera.orthographicscale = 4 camera.znear = 1 camera.zfar = 100 let cameranode = scnnode() cameranode.position = scnvector3(x: 0, y: 0, z: 6) cameranode.camera = camera let cameraorbit = scnnode() cameraorbit.name = "orbit" cameraorbit.addchildnode(cameranode) scene.rootnode.addchildnode(cameraorbit) let py = scnpyramid(width: 2, height: 3, length: 2) py.firstmaterial?.diffuse.contents = uicolor.purple() let p = scnnode(geometry: py) p.position = scnvector3(x:0,y:0,z:2) scene.rootnode.addchildnode(p) // s o l u t o n : cameraorbit.position = p.position cameraorbit.position.y += float(m_pi_2) //therefore have final cameraorbit.position (0, pi/2, 2) let scnview = self.view as! scnview scnview.scene = scene scnview.allowscameracontrol = false scnview.backgroundcolor = uicolor.black() // user rotates camera tapping let tapgesture = uitapgesturerecognizer(target: self, action: #selector(handletap(_:))) scnview.addgesturerecognizer(tapgesture) } //the function camera rotation : func handletap(_ gesturerecognize: uigesturerecognizer) { //i wrong, solution not here let cameraorbit = scene.rootnode.childnode(withname: "orbit", recursively: true)! scntransaction.begin() scntransaction.animationduration = 2 cameraorbit.eulerangles.z += float(m_pi_2) //works x , y scntransaction.commit() } ... }
Comments
Post a Comment