mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
100.75k stars 35.22k forks source link

Firstpersoncontrols target (lookAt) position #974

Closed flyingdeath closed 12 years ago

flyingdeath commented 12 years ago

Hi,

How do change the Firstpersoncontrols's camera's target (lookAt) position while still using the Firstpersoncontrols model?

From what I can see the function update, creates projection sphere that the mouse's position gets translated on to then rotates the camera with.

targetPosition: Only gets used a container to load the x,y,z into the camera's lookat position.

lon and lat: They seem like right the starting point for the sphere. But I don't understand the correct form to change it.

Thanks, Brian.


  this.update = function() {

    var now = new Date().getTime();
    this.tdiff = ( now - this.lastUpdate ) / 1000;
    this.lastUpdate = now;

    if ( !this.freeze ) {

      if ( this.heightSpeed ) {

        var y = clamp( this.object.position.y, this.heightMin, this.heightMax );
        var delta = y - this.heightMin;

        this.autoSpeedFactor = this.tdiff * ( delta * this.heightCoef );

      } else {

        this.autoSpeedFactor = 0.0;

      }

      var actualMoveSpeed = this.tdiff * this.movementSpeed;

      if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
      if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );

      if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed );
      if ( this.moveRight ) this.object.translateX( actualMoveSpeed );

      if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
      if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );

      var actualLookSpeed = this.tdiff * this.lookSpeed;

      if ( !this.activeLook ) {

        actualLookSpeed = 0;

      }

      this.lon += this.mouseX * actualLookSpeed;
      if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed;

      this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
      this.phi = ( 90 - this.lat ) * Math.PI / 180;
      this.theta = this.lon * Math.PI / 180;

      var targetPosition = this.target,
      position = this.object.position;

      targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
      targetPosition.y = position.y + 100 * Math.cos( this.phi );
      targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );

      var verticalLookRatio = 1;

      if ( this.constrainVertical ) {

        verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );

      }

      this.lon += this.mouseX * actualLookSpeed;
      if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;

      this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
      this.phi = ( 90 - this.lat ) * Math.PI / 180;

      this.theta = this.lon * Math.PI / 180;

      if ( this.constrainVertical ) {

        this.phi = map_linear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax );

      }

      var targetPosition = this.target,
      position = this.object.position;

      targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
      targetPosition.y = position.y + 100 * Math.cos( this.phi );
      targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );

      this.object.lookAt( targetPosition );

    }

  };
mrdoob commented 12 years ago

Maybe you can apply the FirstPersonControls into a dummy object which then, in every frame you copy the position of that dummy object into your camera. That way you have full control of the .lookAt()

flyingdeath commented 12 years ago

I don't think that'll work. If I understand you correctly I believe you mean to use a buffer to store each position of first person controls and then change the buffer when needed but how would I realign first person controls to the buffer after I'm done setting the it

mrdoob commented 12 years ago

What I mean is this:

camera.position.copy( dummy_with_controls.position );
flyingdeath commented 12 years ago

HI,

Ok I understand that part, But does that mean


camera.position.copy( dummy_with_controls.position );

// so dump camera position then what I wish to change the lookat position

dummy_with_controls.lookat.position.x = 25
dummy_with_controls.lookat.position.y = 25
dummy_with_controls.lookat.position.z = 25

true == (camera.lookat.position.x == dummy_with_controls.lookat.position.x ||
            camera.lookat.position.y == dummy_with_controls.lookat.position.y ||
            camera.lookat.position.z == dummy_with_controls.lookat.position.z)

// or ....

true == (fps.camera.lookat.position.x == dummy_with_controls.lookat.position.x ||
            fps.camera.lookat.position.y == dummy_with_controls.lookat.position.y ||
            fps.camera.lookat.position.z == dummy_with_controls.lookat.position.z)
flyingdeath commented 12 years ago

Hi,

ok how do you mean???

camera.position.copy( dummy_with_controls.position );

camera.position copy into dummy_with_controls.position

or dummy_with_controls.position copy into camera.position

flyingdeath commented 12 years ago

Hi,

So camera.position.copy( dummy_with_controls.position );

Copies dummy_with_controls.position into camera.position

Which doesn't help.

I don't understand, Please help??

Thanks, Brian.

mrdoob commented 12 years ago

It doesn't? What are you trying to do then?

flyingdeath commented 12 years ago

Hi,

camera.position.copy( dummy_with_controls.position );

Is 'dummy_with_controls' another Firstpersoncontrols class instance or A camera instance or is it something else?

camera.position is the position of the camera.

camera.lookAt is a function to set the lookAt position.

If there a camera.lookAtPosition propriety then which is it?

I'm try to set the lookAt position through the Firstpersoncontrols class which seems doable.

If you are thinking of a different way of doing this please code it out.

I think it'll be too difficult to supply small bits code to spec this out.

Thanks, Brian.

mrdoob commented 12 years ago

Sorry, that didn't reply my question...

So, as far as I understand. What you want to do is having a 3d character moving around a world with the camera behind it. Is that correct?

flyingdeath commented 12 years ago

I would basically would like a regular first person "shooter" controls and the ability to set the current position of the camera and what it looks at.

position of camera set here


  this.translate = function(pos){
    this.object.translateZ(pos.z);
    this.object.translateX(pos.x);
    this.object.translateY(pos.y);
  }

  this.setCamera = function(position){
    this.object.position.copy(position);
  }

I'm trying to set the lookAt position through the Firstpersoncontrols class which seems doable.

Position of what the camera looks at:


TODO:

If you wish to fix this a didfferent way please do so.

mrdoob commented 12 years ago

I wonder if this works...

controls.lat = 0;
controls.lon = 0;
controls.phi = 0;
controls.theta = 0;
controls.target = object_you_want_to_look_at.position;
flyingdeath commented 12 years ago

That won't work when you return to normal control latitude and longtitude will be zeroed out and point off to space adjusting any of the other properties will just resolve in being overwritten.

Please let me know if you need any more help?

mrdoob commented 12 years ago

Well, I guess you'll need to code your custom FirstPersonControls class then :)

flyingdeath commented 12 years ago

Then can you help with the math then?

Who coded the class if not you?

And can we still talk to them?

Thanks, Brian.

flyingdeath commented 12 years ago

Ok I've got it. :)

But I don't know what you'll want in the final code if any at all. Please let me know if need any help understanding this stuff.

Now on the next thing, making the camera move like a human

:)


  this.translate = function(pos){
    this.object.translateZ(pos.z);
    this.object.translateX(pos.x);
    this.object.translateY(pos.y);
  }

  this.cloneCamera = function(){
   return owl.deepCopy(this.object);
  }

  this.setCamera = function(position){
    this.object.position.copy(position);
  }

   /*********************************************************************************************/
  this.updateCords = function(pos, dif){
   this.dif = dif
    var camPos = owl.deepCopy(this.object.position);
    var ver  = new THREE.Vector3(pos.x, pos.y, pos.z); 
    ver   = ver.sub(ver, camPos);

    var r = this.getRadius(ver)
    var p = 100;

    var tmpGeo         = this.getGeoCords(ver,r);
    var tmpSpherical   = this.getSpherical(tmpGeo[0],tmpGeo[1]);
    var targetPosition = this.getCartesian(tmpSpherical[0], tmpSpherical[1], r);
    targetPosition     = new THREE.Vector3(0, 0, 0).add(targetPosition, camPos);

    this.lon   = tmpGeo[0];
    this.lat   = tmpGeo[1];

    this.object.lookAt( targetPosition );
    this.ext_update = true;

 //   this.d.output("("+ this.lon + ","+ this.lat + "),<br/>"+
 //                 "("+ this.phi +","+this.theta+"," +dif+")<br/>" +
 //                 "("+ targetPosition.x+ ","+ targetPosition.y+ ","+targetPosition.z+"),<br/>" +
 //                  "("+ pos.x+ ","+ pos.y+ ","+pos.z+")," 
 //                 );
 }

 this.getRadius = function(pos){
   var r = Math.sqrt(Math.pow(pos.x,2) + Math.pow(pos.y,2) + Math.pow(pos.z,2));
   return r;
 }
  /*********************************************************************************************/

 this.getGeoCords = function(pos,r){
   var lon = -1*((90 + (Math.atan2(pos.x , pos.z)) * 180 / Math.PI) % 360) -180;
   var lat = 90 - (Math.acos(pos.y / r)) * 180 / Math.PI;

  //  this.lat = Math.max( - 85, Math.min( 85, this.lat ) );

   return [lon,lat];
 }
  /*********************************************************************************************/

 this.getGeoCordsSpherical = function(phi, theta){
    var lon = theta * (180/Math.PI);
    var lat = (90 + phi) * (180/Math.PI);
   return [lon, lat];
 }
  /*********************************************************************************************/

 this.getSpherical = function(lon, lat){
   var theta = lon * Math.PI / 180;
   var phi   = ( 90 - lat) * Math.PI / 180;
   return [phi, theta];
 }
  /*********************************************************************************************/

 this.getCartesian = function(phi, theta, p){
   var targetPosition =  new THREE.Vector3(0, 0, 0);
   targetPosition.x = p * Math.sin( phi ) * Math.cos( theta );
   targetPosition.y = p * Math.cos( phi );
   targetPosition.z = p * Math.sin( phi ) * Math.sin( theta );
   return targetPosition;
 }
  /*********************************************************************************************/
flyingdeath commented 12 years ago

Research

current Cartesian to lat and lon conversion http://stackoverflow.com/questions/5674149/3d-coordinates-on-a-sphere-to-latitude-and-longitude

current Spherical conversion back Cartesian http://www.math.montana.edu/frankw/ccp/multiworld/multipleIVP/spherical/body.htm

more research http://board.flashkit.com/board/archive/index.php/t-666832.html http://en.wikipedia.org/wiki/Geographic_coordinate_system http://mathworld.wolfram.com/SphericalCoordinates.html http://en.wikipedia.org/wiki/Spherical_coordinate_system http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node179.html http://www.actionscript.org/forums/showthread.php3?t=164956 http://www.math.montana.edu/frankw/ccp/cases/Global-Positioning/spherical-coordinates/learn.htm http://www.colorado.edu/geography/gcraft/notes/coordsys/coordsys.html http://www.physicsforums.com/showthread.php?t=21892 http://www.physicsforums.com/showthread.php?t=281447 http://www.engin.brown.edu/courses/en3/Notes/Vector_Web2/Vectors6a/Vectors6a.htm http://www.johndcook.com/python_longitude_latitude.html http://rbrundritt.wordpress.com/2008/10/14/conversion-between-spherical-and-cartesian-coordinates-systems/ http://answers.unity3d.com/questions/189724/polar-spherical-coordinates-to-xyz-and-vice-versa.html http://gis.stackexchange.com/ http://stackoverflow.com/questions/5674149/3d-coordinates-on-a-sphere-to-latitude-and-longitude

wcoebergh commented 6 years ago

flyingdeath's code works for me, thanks!