// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

part of vector_math_64;

/// Constructs a rotation matrix in [rotationMatrix].
///
/// Sets [rotationMatrix] to a rotation matrix built from
/// [forwardDirection] and [upDirection]. The right direction is
/// constructed to be orthogonal to [forwardDirection] and
/// [upDirection].
///
/// [forwardDirection] specifies the direction of the forward vector.
/// [upDirection] specifies the direction of the up vector.
///
/// Use case is to build the per-model rotation matrix from vectors
/// [forwardDirection] and [upDirection]. See sample code below for
/// a context.
///
///     class Model {
///       Vector3 _center = new Vector3.zero();        // per-model translation
///       Vector3 _scale = new Vector3(1.0, 1.0, 1.0); // per-model scaling
///       Matrix4 _rotation = new Matrix4.identity();  // per-model rotation
///       Matrix4 _MV = new Matrix4.identity();        // per-model model-view
///
///       void updateModelViewUniform(RenderingContext gl, UniformLocation u_MV,
///         Vector3 camPosition, camFocusPosition, camUpDirection) {
///
///         // V = View (inverse of camera)
///         // T = Translation
///         // R = Rotation
///         // S = Scaling
///         setViewMatrix(_MV, camPosition, camFocusPosition, camUpDirection); // MV = V
///         _MV.translate(_center); // MV = V*T
///         _MV.multiply(_rotation); // MV = V*T*R
///         // _rotation is updated with setRotationMatrix(_rotation, forward, up);
///         _MV.scale(_scale); // MV = V*T*R*S
///
///         gl.uniformMatrix4fv(u_MV, false, _MV.storage);
///       }
///     }
void setRotationMatrix(
    Matrix4 rotationMatrix, Vector3 forwardDirection, Vector3 upDirection) {
  setModelMatrix(rotationMatrix, forwardDirection, upDirection, 0.0, 0.0, 0.0);
}

/// Constructs an OpenGL model matrix in [modelMatrix].
/// Model transformation is the inverse of the view transformation.
/// Model transformation is also known as "camera" transformation.
/// Model matrix is commonly used to compute a object location/orientation into
/// the full model-view stack.
///
/// [forwardDirection] specifies the direction of the forward vector.
/// [upDirection] specifies the direction of the up vector.
/// [tx],[ty],[tz] specifies the position of the object.
void setModelMatrix(Matrix4 modelMatrix, Vector3 forwardDirection,
    Vector3 upDirection, double tx, double ty, double tz) {
  final Vector3 right = forwardDirection.cross(upDirection)..normalize();
  final Vector3 c1 = right;
  final Vector3 c2 = upDirection;
  final Vector3 c3 = -forwardDirection;
  modelMatrix.setValues(c1[0], c1[1], c1[2], 0.0, c2[0], c2[1], c2[2], 0.0,
      c3[0], c3[1], c3[2], 0.0, tx, ty, tz, 1.0);
}

/// Constructs an OpenGL view matrix in [viewMatrix].
/// View transformation is the inverse of the model transformation.
/// View matrix is commonly used to compute the camera location/orientation into
/// the full model-view stack.
///
/// [cameraPosition] specifies the position of the camera.
/// [cameraFocusPosition] specifies the position the camera is focused on.
/// [upDirection] specifies the direction of the up vector (usually, +Y).
void setViewMatrix(Matrix4 viewMatrix, Vector3 cameraPosition,
    Vector3 cameraFocusPosition, Vector3 upDirection) {
  final Vector3 z = (cameraPosition - cameraFocusPosition)..normalize();
  final Vector3 x = upDirection.cross(z)..normalize();
  final Vector3 y = z.cross(x)..normalize();

  final double rotatedEyeX = -x.dot(cameraPosition);
  final double rotatedEyeY = -y.dot(cameraPosition);
  final double rotatedEyeZ = -z.dot(cameraPosition);

  viewMatrix.setValues(x[0], y[0], z[0], 0.0, x[1], y[1], z[1], 0.0, x[2], y[2],
      z[2], 0.0, rotatedEyeX, rotatedEyeY, rotatedEyeZ, 1.0);
}

/// Constructs a new OpenGL view matrix.
///
/// [cameraPosition] specifies the position of the camera.
/// [cameraFocusPosition] specifies the position the camera is focused on.
/// [upDirection] specifies the direction of the up vector (usually, +Y).
Matrix4 makeViewMatrix(
    Vector3 cameraPosition, Vector3 cameraFocusPosition, Vector3 upDirection) {
  final Matrix4 r = Matrix4.zero();
  setViewMatrix(r, cameraPosition, cameraFocusPosition, upDirection);
  return r;
}

/// Constructs an OpenGL perspective projection matrix in [perspectiveMatrix].
///
/// [fovYRadians] specifies the field of view angle, in radians, in the y
/// direction.
/// [aspectRatio] specifies the aspect ratio that determines the field of view
/// in the x direction. The aspect ratio of x (width) to y (height).
/// [zNear] specifies the distance from the viewer to the near plane
/// (always positive).
/// [zFar] specifies the distance from the viewer to the far plane
/// (always positive).
void setPerspectiveMatrix(Matrix4 perspectiveMatrix, double fovYRadians,
    double aspectRatio, double zNear, double zFar) {
  final double height = math.tan(fovYRadians * 0.5);
  final double width = height * aspectRatio;
  final double near_minus_far = zNear - zFar;

  perspectiveMatrix
    ..setZero()
    ..setEntry(0, 0, 1.0 / width)
    ..setEntry(1, 1, 1.0 / height)
    ..setEntry(2, 2, (zFar + zNear) / near_minus_far)
    ..setEntry(3, 2, -1.0)
    ..setEntry(2, 3, (2.0 * zNear * zFar) / near_minus_far);
}

/// Constructs a new OpenGL perspective projection matrix.
///
/// [fovYRadians] specifies the field of view angle, in radians, in the y
/// direction.
/// [aspectRatio] specifies the aspect ratio that determines the field of view
/// in the x direction. The aspect ratio of x (width) to y (height).
/// [zNear] specifies the distance from the viewer to the near plane
/// (always positive).
/// [zFar] specifies the distance from the viewer to the far plane
/// (always positive).
Matrix4 makePerspectiveMatrix(
    double fovYRadians, double aspectRatio, double zNear, double zFar) {
  final Matrix4 r = Matrix4.zero();
  setPerspectiveMatrix(r, fovYRadians, aspectRatio, zNear, zFar);
  return r;
}

/// Constructs an OpenGL infinite projection matrix in [infiniteMatrix].
/// [fovYRadians] specifies the field of view angle, in radians, in the y
/// direction.
/// [aspectRatio] specifies the aspect ratio that determines the field of view
/// in the x direction. The aspect ratio of x (width) to y (height).
/// [zNear] specifies the distance from the viewer to the near plane
/// (always positive).
void setInfiniteMatrix(Matrix4 infiniteMatrix, double fovYRadians,
    double aspectRatio, double zNear) {
  final double height = math.tan(fovYRadians * 0.5);
  final double width = height * aspectRatio;

  infiniteMatrix
    ..setZero()
    ..setEntry(0, 0, 1.0 / width)
    ..setEntry(1, 1, 1.0 / height)
    ..setEntry(2, 2, -1.0)
    ..setEntry(3, 2, -1.0)
    ..setEntry(2, 3, -2.0 * zNear);
}

/// Constructs a new OpenGL infinite projection matrix.
///
/// [fovYRadians] specifies the field of view angle, in radians, in the y
/// direction.
/// [aspectRatio] specifies the aspect ratio that determines the field of view
/// in the x direction. The aspect ratio of x (width) to y (height).
/// [zNear] specifies the distance from the viewer to the near plane
/// (always positive).
Matrix4 makeInfiniteMatrix(
    double fovYRadians, double aspectRatio, double zNear) {
  final Matrix4 r = Matrix4.zero();
  setInfiniteMatrix(r, fovYRadians, aspectRatio, zNear);
  return r;
}

/// Constructs an OpenGL perspective projection matrix in [perspectiveMatrix].
///
/// [left], [right] specify the coordinates for the left and right vertical
/// clipping planes.
/// [bottom], [top] specify the coordinates for the bottom and top horizontal
/// clipping planes.
/// [near], [far] specify the coordinates to the near and far depth clipping
/// planes.
void setFrustumMatrix(Matrix4 perspectiveMatrix, double left, double right,
    double bottom, double top, double near, double far) {
  final double two_near = 2.0 * near;
  final double right_minus_left = right - left;
  final double top_minus_bottom = top - bottom;
  final double far_minus_near = far - near;
  perspectiveMatrix
    ..setZero()
    ..setEntry(0, 0, two_near / right_minus_left)
    ..setEntry(1, 1, two_near / top_minus_bottom)
    ..setEntry(0, 2, (right + left) / right_minus_left)
    ..setEntry(1, 2, (top + bottom) / top_minus_bottom)
    ..setEntry(2, 2, -(far + near) / far_minus_near)
    ..setEntry(3, 2, -1.0)
    ..setEntry(2, 3, -(two_near * far) / far_minus_near);
}

/// Constructs a new OpenGL perspective projection matrix.
///
/// [left], [right] specify the coordinates for the left and right vertical
/// clipping planes.
/// [bottom], [top] specify the coordinates for the bottom and top horizontal
/// clipping planes.
/// [near], [far] specify the coordinates to the near and far depth clipping
/// planes.
Matrix4 makeFrustumMatrix(double left, double right, double bottom, double top,
    double near, double far) {
  final Matrix4 view = Matrix4.zero();
  setFrustumMatrix(view, left, right, bottom, top, near, far);
  return view;
}

/// Constructs an OpenGL orthographic projection matrix in [orthographicMatrix].
///
/// [left], [right] specify the coordinates for the left and right vertical
/// clipping planes.
/// [bottom], [top] specify the coordinates for the bottom and top horizontal
/// clipping planes.
/// [near], [far] specify the coordinates to the near and far depth clipping
/// planes.
void setOrthographicMatrix(Matrix4 orthographicMatrix, double left,
    double right, double bottom, double top, double near, double far) {
  final double rml = right - left;
  final double rpl = right + left;
  final double tmb = top - bottom;
  final double tpb = top + bottom;
  final double fmn = far - near;
  final double fpn = far + near;
  orthographicMatrix
    ..setZero()
    ..setEntry(0, 0, 2.0 / rml)
    ..setEntry(1, 1, 2.0 / tmb)
    ..setEntry(2, 2, -2.0 / fmn)
    ..setEntry(0, 3, -rpl / rml)
    ..setEntry(1, 3, -tpb / tmb)
    ..setEntry(2, 3, -fpn / fmn)
    ..setEntry(3, 3, 1.0);
}

/// Constructs a new OpenGL orthographic projection matrix.
///
/// [left], [right] specify the coordinates for the left and right vertical
/// clipping planes.
/// [bottom], [top] specify the coordinates for the bottom and top horizontal
/// clipping planes.
/// [near], [far] specify the coordinates to the near and far depth clipping
/// planes.
Matrix4 makeOrthographicMatrix(double left, double right, double bottom,
    double top, double near, double far) {
  final Matrix4 r = Matrix4.zero();
  setOrthographicMatrix(r, left, right, bottom, top, near, far);
  return r;
}

/// Returns a transformation matrix that transforms points onto
/// the plane specified with [planeNormal] and [planePoint].
Matrix4 makePlaneProjection(Vector3 planeNormal, Vector3 planePoint) {
  final Vector4 v = Vector4(planeNormal.storage[0], planeNormal.storage[1],
      planeNormal.storage[2], 0.0);
  final Matrix4 outer = Matrix4.outer(v, v);
  var r = Matrix4.zero();
  r = r - outer;
  final Vector3 scaledNormal =
      planeNormal.scaled(dot3(planePoint, planeNormal));
  final Vector4 T = Vector4(scaledNormal.storage[0], scaledNormal.storage[1],
      scaledNormal.storage[2], 1.0);
  r.setColumn(3, T);
  return r;
}

/// Returns a transformation matrix that transforms points by reflecting
/// them through the plane specified with [planeNormal] and [planePoint].
Matrix4 makePlaneReflection(Vector3 planeNormal, Vector3 planePoint) {
  final Vector4 v = Vector4(planeNormal.storage[0], planeNormal.storage[1],
      planeNormal.storage[2], 0.0);
  final Matrix4 outer = Matrix4.outer(v, v)..scale(2.0);
  var r = Matrix4.zero();
  r = r - outer;
  final double scale = 2.0 * planePoint.dot(planeNormal);
  final Vector3 scaledNormal = planeNormal.scaled(scale);
  final Vector4 T = Vector4(scaledNormal.storage[0], scaledNormal.storage[1],
      scaledNormal.storage[2], 1.0);
  r.setColumn(3, T);
  return r;
}

/// On success, Sets [pickWorld] to be the world space position of
/// the screen space [pickX], [pickY], and [pickZ].
///
/// The viewport is specified by ([viewportX], [viewportWidth]) and
/// ([viewportY], [viewportHeight]).
///
/// [cameraMatrix] includes both the projection and view transforms.
///
/// [pickZ] is typically either 0.0 (near plane) or 1.0 (far plane).
///
/// Returns false on error, for example, the mouse is not in the viewport
bool unproject(
    Matrix4 cameraMatrix,
    num viewportX,
    num viewportWidth,
    num viewportY,
    num viewportHeight,
    num pickX,
    num pickY,
    num pickZ,
    Vector3 pickWorld) {
  viewportX = viewportX.toDouble();
  viewportWidth = viewportWidth.toDouble();
  viewportY = viewportY.toDouble();
  viewportHeight = viewportHeight.toDouble();
  pickX = pickX.toDouble();
  pickY = pickY.toDouble();
  pickX = pickX - viewportX;
  pickY = pickY - viewportY;
  pickX = (2.0 * pickX / viewportWidth) - 1.0;
  pickY = (2.0 * pickY / viewportHeight) - 1.0;
  pickZ = (2.0 * pickZ) - 1.0;

  // Check if pick point is inside unit cube
  if (pickX < -1.0 ||
      pickY < -1.0 ||
      pickX > 1.0 ||
      pickY > 1.0 ||
      pickZ < -1.0 ||
      pickZ > 1.0) {
    return false;
  }

  // Copy camera matrix.
  final Matrix4 invertedCameraMatrix = Matrix4.copy(cameraMatrix);
  // Invert the camera matrix.
  invertedCameraMatrix.invert();
  // Determine intersection point.
  final Vector4 v =
      Vector4(pickX.toDouble(), pickY.toDouble(), pickZ.toDouble(), 1.0);
  invertedCameraMatrix.transform(v);
  if (v.w == 0.0) {
    return false;
  }
  final double invW = 1.0 / v.w;
  pickWorld
    ..x = v.x * invW
    ..y = v.y * invW
    ..z = v.z * invW;

  return true;
}

/// On success, [rayNear] and [rayFar] are the points where
/// the screen space [pickX], [pickY] intersect with the near and far
/// planes respectively.
///
/// The viewport is specified by ([viewportX], [viewportWidth]) and
/// ([viewportY], [viewportHeight]).
///
/// [cameraMatrix] includes both the projection and view transforms.
///
/// Returns false on error, for example, the mouse is not in the viewport.
bool pickRay(
    Matrix4 cameraMatrix,
    num viewportX,
    num viewportWidth,
    num viewportY,
    num viewportHeight,
    num pickX,
    num pickY,
    Vector3 rayNear,
    Vector3 rayFar) {
  bool r;

  r = unproject(cameraMatrix, viewportX, viewportWidth, viewportY,
      viewportHeight, pickX, viewportHeight - pickY, 0.0, rayNear);
  if (!r) {
    return false;
  }

  return unproject(cameraMatrix, viewportX, viewportWidth, viewportY,
      viewportHeight, pickX, viewportHeight - pickY, 1.0, rayFar);
}
