Implementation of world-space lookAt

Hello, all, here’s a simple way to implement true lookAt which does not require elements to have non-transformed parents.

Implementation

In the following example, both objectAnywhereInTheSceneGraph and otherObjectAnywhereInTheSceneGraph can be anywhere in the scene graph, and can have unlimited number of transformed parents.

// use this new lookAt in onBeforeRender:
objectAnywhereInTheSceneGraph.onBeforeRender = () => {
  lookAt( objectAnywhereInTheSceneGraph, otherObjectAnywhereInTheSceneGraph )
}


var lookAt = function() {

  // based on the one from Three.js, but for use on world matrices.

  var m1 = new THREE.Matrix4();

  var sourcePosition = new THREE.Vector3()
  var sourceQuaternion = new THREE.Quaternion()
  var sourceScale = new THREE.Vector3()

  var targetPosition = new THREE.Vector3()
  var targetQuaternion = new THREE.Quaternion()
  var targetScale = new THREE.Vector3()

  // sourceObject will look at targetObject
  return function lookAt( sourceObject, targetObject ) {

    sourceObject.matrixWorld.decompose( sourcePosition, sourceQuaternion, sourceScale )
    targetObject.matrixWorld.decompose( targetPosition, targetQuaternion, targetScale )

    if ( sourceObject.isCamera ) {

      m1.lookAt( sourcePosition, targetPosition, sourceObject.up );

    } else {

      m1.lookAt( targetPosition, sourcePosition, sourceObject.up );

    }

    sourceQuaternion.setFromRotationMatrix( m1 );

    sourceObject.matrixWorld.compose( sourcePosition, sourceQuaternion, sourceScale )

  };

}()

Thank you!

1 Like

thank you!!!

1 Like

Since three.js R96 Object3D.lookAt() supports transformed parents:

2 Likes

That PR looks more complicated. What use cases does it cover that mine doesn’t? (I’m not criticizing it, just genuinely curious for learning)

Your code does not ensure that the world matrices of the parent objects are actually up to date.

1 Like

That’s easy to add. :smiley: