Implementation of world-space lookAt

transform-matrix
lookat

#1

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 )

  };

}()

#4

Thank you!


#5

thank you!!!


#6

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


#7

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)


#8

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