0

I googled far and wide but I haven't found the solution to what I think to actually be a pretty common situation. Say I have a THREE.PerspectiveCamera initialized to look at a certain point in space:

var camera = new THREE.PerspectiveCamera(45, 2, 0.1, 100);
var target = new THREE.Vector3(1, 2, 3);
camera.lookAt(target);

Now, later on in the code I'd like to be able to find out the coordinates of target by simply querying camera.
I tried what suggested in this question, adapting it to my own scenario:

var vector = new THREE.Vector3();
vector.applyQuaternion(camera.quaternion);
console.log(vector);

But it logs a vector of coordinates (0, 0, 0) instead of the correct coordinates (which, in my example, should be (1, 2, 3)).
Any insights? Cheers.

EDIT:
Ok so I'm going to try to contextualize here, so as to justify why MrTrustworthy's solution is unfortunately not applicable in my scenario. I'm trying to tweak the THREE.OrbitControls library for my purposes, since I noticed that when using it, it overrides whichever position the camera was looking at originally. This has also been reported here. Basically, on line 36 of OrbitControls.js (I'm using the version which can be found here) this.target is initialized to a new THREE.Vector3(); I found out that if I manually set it to equal the same vector I use as argument of camera.lookAt() everything works just fine: I can start panning, orbiting and zooming the scene from the same POV I would see the scene from if I didn't apply the controls. Of course, I cannot hard-code this information into OrbitControls.js because it would require me to change it every time I want to change the initial "lookAt" of my camera; and if I were to follow MrTrustworthy's suggestion I would have to change line 36 of OrbitControls.js to read like this: this.target = object.targetRef (or this.target = object.targetRef || new THREE.Vecotr3()), which is also too "opinionated" (it would always require object to have a targetRef property, whereas I'm trying to stick to using only three.js's existing object properties and methods). Hope this helps get a better understanding of my case. Cheers.

Community
  • 1
  • 1
Andrea Aloi
  • 971
  • 1
  • 17
  • 37
  • Quaternions only model rotations, so if your camera is not at the origin then you'll also need to compensate for its translation. I expect you'll also need to invert the camera's quaternion. – Drew Noakes Oct 24 '14 at 22:34
  • Also note that there are infinite solutions to the problem. Technically the camera is looking at any point along its central axis. – Drew Noakes Oct 24 '14 at 22:35
  • Also, the answer in the SO post you linked to said to do this: `var vector = new THREE.Vector3( 0, 0, -1 );` – WestLangley Oct 25 '14 at 02:08
  • @DrewNoakes, you have a point (actually, you have infinite points! ;)), I could settle for one point thought; if my camera is in `(1, 1, 0)` and was originally looking at `(1, 0, 0)` (straight down along y-axis), the algorithm I'm looking for could as well provide me with point `(1, -1, 0)` for all I care, since setting `camera.lookAt(new THREE.Vector3(1, -1, 0))` would have the same effect as `camera.lookAt(new THREE.Vector3(1, 0, 0))`, right? – Andrea Aloi Oct 25 '14 at 16:38
  • @WestLangley, it seems to me that using `THREE.Vector3(0, 0, -1)` requires some previous knowledge of where the camera *should* be looking at, whereas in my case (see edits) the library which receives the camera object knows nothing about the vector originally passed to `camera.lookAt()` (and shouldn't be fed any additional information which is not deducible simply from the camera itself). Anyhow, for the sake of it I tried using `var vector = new THREE.Vector3(0, 0, -1)` but still no dice: after applying the camera's quaternion to it, it points to the origin rather than the point `(1, 2, 3)`. – Andrea Aloi Oct 25 '14 at 16:43
  • For one thing, use http://threejs.org/examples/js/controls/OrbitControls.js, and when learning or debugging, use the un-minified version http://threejs.org/build/three.js. – WestLangley Oct 25 '14 at 18:45
  • @WestLangley thanks for the heads up on `OrbitControls.js`, I've downloaded the version you linked; as for three.js, I was already using the un-minified version. Still not working though: if I have a camera looking at a certain point in space, as soon as I add orbit controls to it (due to automatic update upon construction: `OrbitControls.js:654`) the camera's target gets reset to `(0, 0, 0)`. Kinda silly, if you ask me, to have `this.object.lookAt(this.target)` (`OrbitControls.js:292`) where `this.target = new THREE.Vector3()` (`OrbitControls.js:36`) instead of deducing point from object. – Andrea Aloi Oct 26 '14 at 14:10
  • Btw, re-edited my previous edit now that I changed version of `OrbitControls.js` as per @WestLangley's comment. – Andrea Aloi Oct 26 '14 at 14:58
  • `controls = new THREE.OrbitControls(...); controls.target.copy( target );` or `controls.target.set( x, y, z );`. – WestLangley Oct 26 '14 at 16:11

3 Answers3

1

If your only usecase is "I want to be able to access the camera-targets position via the camera object", you could just put a reference into the camera object.

var camera = new THREE.PerspectiveCamera(45, 2, 0.1, 100);
var target = new THREE.Vector3(1, 2, 3);
camera.lookAt(target);
camera.targetRef = target;

//access it
var iNeedThisNow = camera.targetRef;
MrTrustworthy
  • 416
  • 1
  • 4
  • 14
1

I figured it out and wrote my solution here. Since the issue affects both THREE.TrackballControls and THREE.OrbitControls, the solution involves applying a slight change to both those files. I wonder if it can be considered a valid change and make its way to rev. 70; I will issue a PR on github just for the sake of it :)
Thanks to all those who pitched in.

Community
  • 1
  • 1
Andrea Aloi
  • 971
  • 1
  • 17
  • 37
1

well you could put the object in parent, have parent lookat, and have the child object rotated 180 degrees. That's the quick noob solution

Jack Franzen
  • 768
  • 7
  • 21