pex-gl / pex-cam

Cameras models and controllers for 3D rendering in PEX.
MIT License
2 stars 3 forks source link

Add getWorldRay #4

Closed vorg closed 6 years ago

vorg commented 6 years ago
const Vec3 = require('pex-math/Vec3')
const Mat4 = require('pex-math/Mat4')

module.exports = function getWorldRay (camera, x, y, windowWidth, windowHeight) {
  if (camera.frustum) {
    x += camera.frustum.offset[0]
    y += camera.frustum.offset[1]
    windowWidth = camera.frustum.totalSize[0]
    windowHeight = camera.frustum.totalSize[1]
  }
  let nx = 2 * x / windowWidth - 1
  let ny = 1 - 2 * y / windowHeight

  // view ray
  let hNear = 2 * Math.tan(camera.fov / 2) * camera.near
  let wNear = hNear * camera.aspect

  nx *= (wNear * 0.5)
  ny *= (hNear * 0.5)

  let origin = [0, 0, 0]
  let direction = Vec3.normalize([nx, ny, -camera.near])
  let ray = [origin, direction]

  let invViewMatrix = Mat4.invert(Mat4.copy(camera.viewMatrix))

  Vec3.multMat4(origin, invViewMatrix)
  Vec3.multMat4(direction, invViewMatrix)
  Vec3.normalize(Vec3.sub(direction, origin))

  return ray
}