ios - SCNCamera moving camera's pivot -


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 :

the triangle rotates around point below apex

what want achieve make rotation relative centre :

like this

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