gl-matrix icon indicating copy to clipboard operation
gl-matrix copied to clipboard

What happened to vec3.unproject?

Open mattdesl opened this issue 11 years ago • 5 comments

I noticed it was in earlier versions, but can't see it on master or dev branches. Was it removed intentionally?

mattdesl avatar Dec 03 '13 03:12 mattdesl

For reference to anyone who stumbles on this later, here is how I've implemented it in my own library.

/**
 * Multiplies this Vector3 by the specified matrix, 
 * applying a W divide. This is useful for projection,
 * e.g. unprojecting a 2D point into 3D space.
 *
 * @method  prj
 * @param {Matrix4} the 4x4 matrix to multiply with 
 * @return {Vector3} this object for chaining
 */
vec3.project = function(mat) {
    var x = this.x,
        y = this.y,
        z = this.z,
        m = mat.val,
        a00 = m[0], a01 = m[1], a02 = m[2], a03 = m[3],
        a10 = m[4], a11 = m[5], a12 = m[6], a13 = m[7],
        a20 = m[8], a21 = m[9], a22 = m[10], a23 = m[11],
        a30 = m[12], a31 = m[13], a32 = m[14], a33 = m[15];

    var l_w = 1 / (x * a03 + y * a13 + z * a23 + a33);

    this.x = (x * a00 + y * a10 + z * a20 + a30) * l_w; 
    this.y = (x * a01 + y * a11 + z * a21 + a31) * l_w; 
    this.z = (x * a02 + y * a12 + z * a22 + a32) * l_w;
    return this;
};

/**
 * Unproject this point from 2D space to 3D space.
 * The point should have its x and y properties set to
 * 2D screen space, and the z either at 0 (near plane)
 * or 1 (far plane). The provided matrix is assumed to already
 * be combined, i.e. projection * view * model.
 *
 * After this operation, this vector's (x, y, z) components will
 * represent the unprojected 3D coordinate.
 * 
 * @param  {Vector4} viewport          screen x, y, width and height in pixels
 * @param  {Matrix4} invProjectionView combined projection and view matrix
 * @return {Vector3}                   this object, for chaining
 */
vec3.unproject = function(viewport, invProjectionView) {
    var viewX = viewport.x,
        viewY = viewport.y,
        viewWidth = viewport.z,
        viewHeight = viewport.w;

    var x = this.x, 
        y = this.y,
        z = this.z;

    x = x - viewX;
    y = viewHeight - y - 1;
    y = y - viewY;

    this.x = (2 * x) / viewWidth - 1;
    this.y = (2 * y) / viewHeight - 1;
    this.z = 2 * z - 1;

    return this.project(invProjectionView);
};

mattdesl avatar Mar 18 '14 18:03 mattdesl

Also very curious about the rationale behind this - was there an API change?

sgrove avatar Jul 30 '14 19:07 sgrove

Sorry to bump, but curious to know if this was out of scope, incompatible with the API, or would be accepted in a new patch?

sgrove avatar Aug 14 '14 18:08 sgrove

Modified the method by @mattdesl to work with the latest version, sorry for ES syntax but you get the idea:

vec3.project = function (out, vector, projection) {
  let x = vector[0]
  let y = vector[1]
  let z = vector[2]
  let m = projection
  let a00 = m[0]
  let a01 = m[1]
  let a02 = m[2]
  let a03 = m[3]
  let a10 = m[4]
  let a11 = m[5]
  let a12 = m[6]
  let a13 = m[7]
  let a20 = m[8]
  let a21 = m[9]
  let a22 = m[10]
  let a23 = m[11]
  let a30 = m[12]
  let a31 = m[13]
  let a32 = m[14]
  let a33 = m[15]

  let lw = 1 / (x * a03 + y * a13 + z * a23 + a33)

  vec3.set(
    out,
    (x * a00 + y * a10 + z * a20 + a30) * lw,
    (x * a01 + y * a11 + z * a21 + a31) * lw,
    (x * a02 + y * a12 + z * a22 + a32) * lw
  )
  return out
}

I didn't need unproject but it can be updated similarly.

RanzQ avatar Jun 29 '16 14:06 RanzQ

Bump, why was this removed?

tVoss avatar Sep 27 '21 02:09 tVoss