[{"name":"Camera3d","comment":" A `Camera3d` is a perspective or orthographic camera in 3D space. This module contains functions\nfor:\n\n  - Constructing cameras in various ways\n  - Extracting properties such as the view direction and view plane of the camera\n  - Constructing 3D 'pick rays' based on a given camera and 2D click position\n\n@docs Camera3d, Projection, FieldOfView, angle, height\n\n\n# Constructors\n\n@docs lookAt, orbit, orbitZ, isometric, isometricElevation, with\n\n\n# Properties\n\n@docs eyePoint, viewDirection, viewPlane, frame, focalDistance, projection, fovAngle, fovHeight\n\n\n# Ray casting\n\n@docs ray\n\n\n# Advanced\n\n@docs frustumSlope\n\n","unions":[{"name":"Camera3d","comment":" A camera in 3D space, using particular units\n(usually [meters](https://package.elm-lang.org/packages/ianmackenzie/elm-units/latest/Length#Meters))\nwithin a particular [coordinate system](https://github.com/ianmackenzie/elm-geometry#coordinate-systems)\n(generally a user-defined type like `WorldCoordinates`).\n","args":["units","coordinates"],"cases":[]},{"name":"FieldOfView","comment":" Defines the vertical [field of view](https://en.wikipedia.org/wiki/Field_of_view) of a camera.\nStrictly speaking, for a perspective camera the field of view should be defined as an angle and\nfor an orthographic camera it should be defined as a height. Practically speaking, however, it is\nusually possible (and often useful) to convert between the two.\n\nGiven a focal distance it is possible (with a bit of trigonometry) to compute the field of view\nangle from the field of view height, or vice versa:\n\n![Field of view](https://ianmackenzie.github.io/elm-3d-camera/4.0.0/fov.png)\n\nAll the camera construction functions in this module either compute the focal distance\nautomatically (e.g. as the distance from an eye point to a focal point), or (in the case of the\n[`with`](#with) constructor) require you to provide one explicitly.\n\nAs a result, this module allows you to specify field of view as either an angle or a height for\neither perspective or orthographic cameras, and any necessary conversions will be done\nautomatically.\n\n","args":["units"],"cases":[]},{"name":"Projection","comment":" Defines whether a camera uses [perspective or orthographic projection](https://en.wikipedia.org/wiki/3D_projection).\n","args":[],"cases":[["Perspective",[]],["Orthographic",[]]]}],"aliases":[],"values":[{"name":"angle","comment":" Specify vertical field of view as an angle. For an orthographic camera, this will be converted\nto a height at the camera's focal distance.\n","type":"Angle.Angle -> Camera3d.FieldOfView units"},{"name":"eyePoint","comment":" Get the location of a camera.\n","type":"Camera3d.Camera3d units coordinates -> Point3d.Point3d units coordinates"},{"name":"focalDistance","comment":" The focal distance of the camera is used to convert between angle-based and height-based field\nof view. This generally corresponds to the distance from the camera to the object currently being\nlooked at/focused on (which is often also the center of rotation/orbit point for the camera).\n","type":"Camera3d.Camera3d units coordinates -> Quantity.Quantity Basics.Float units"},{"name":"fovAngle","comment":" Get a camera's vertical field of view as an angle. If necessary, this will be computed from a\nheight-based field of view using the camera's focal distance.\n","type":"Camera3d.Camera3d units coordinates -> Angle.Angle"},{"name":"fovHeight","comment":" Get a camera's vertical field of view as a height. If necessary, this will be computed from an\nangle-based field of view using the camera's focal distance.\n","type":"Camera3d.Camera3d units coordinates -> Quantity.Quantity Basics.Float units"},{"name":"frame","comment":" The frame of a camera is a `Frame3d` where:\n\n  - The origin point of the frame is the eye point of the camera\n  - The X direction of the frame points to the left\n  - The Y direction of the frame points up\n  - The Z direction of the frame points out of the screen\n\n","type":"Camera3d.Camera3d units coordinates -> Frame3d.Frame3d units coordinates defines"},{"name":"frustumSlope","comment":" Half the [`fovAngle`](#fovAngle), expressed as a slope instead of an angle. This is useful for\nvarious low-level camera operations such as computing projection matrices.\n","type":"Camera3d.Camera3d units coordinates -> Basics.Float"},{"name":"height","comment":" Specify vertical field of view as a height. For a perspective camera, this will be converted to\nan angle at the camera's focal distance.\n","type":"Quantity.Quantity Basics.Float units -> Camera3d.FieldOfView units"},{"name":"isometric","comment":" Construct a camera looking at the given focal point, the given distance\naway, such that a set of XYZ axes at that point will appear to have:\n\n  - Z straight up\n  - X pointing to the left and 30 degrees down\n  - Y pointing to the right and 30 degrees down\n\n","type":"{ focalPoint : Point3d.Point3d units coordinates, distance : Quantity.Quantity Basics.Float units, projection : Camera3d.Projection, fov : Camera3d.FieldOfView units } -> Camera3d.Camera3d units coordinates"},{"name":"isometricElevation","comment":" Not actually a constructor, but a useful value (approximately 35.26 degrees)\nto use when constructing cameras using `orbit` or `orbitZ`: using this as the\n`elevation` value will result in an [isometric](#isometric) camera if\n`azimuth` is set to 45 degrees. Said another way, this is the elevation angle of\na vector with components (1, 1, 1).\n","type":"Angle.Angle"},{"name":"lookAt","comment":" Construct a `Camera3d` at the given eye point looking towards the given\nfocal point, with the given global up direction (which will typically be\n`Direction3d.positiveZ` or `Direction3d.positiveY`). The focal distance will\nbe computed as the distance from the eye point to the focal point. For\nexample, to construct a camera at the point (10, 0, 5) looking towards the\norigin:\n\n    camera =\n        Camera3d.lookAt\n            { eyePoint = Point3d.meters 10 0 5\n            , focalPoint = Point3d.origin\n            , upDirection = Direction3d.positiveZ\n            , projection = Camera3d.Perspective\n            , fov = Camera3d.angle (Angle.degrees 30)\n            }\n\n    Camera3d.eyePoint camera\n    --> Point3d.meters 10 0 5\n\n    Camera3d.viewDirection camera\n    --> Direction3d.xz (Angle.degrees -153.43)\n\nThat is likely all you need to know but if you are interested in the details and\ncorner cases, read on!\n\nThe view direction of the returned camera will point from the eye point to\nthe focal point. The Y direction will be chosen to be as close to the global up\ndirection as possible (the camera will not have any 'roll') and the X\ndirection will point to the right.\n\nIf the direction from the eye point to the focal point is parallel to the global\nup direction (that is, the camera represents looking straight up or straight\ndown) then the X and Y directions will be chosen arbitrarily.\n\nIf the given eye point and focal point are coincident (so that there is no well-\ndefined view direction), then the returned camera will have its Y direction set\nto the global up direction and its X and view directions will be chosen\narbitrarily.\n\n","type":"{ eyePoint : Point3d.Point3d units coordinates, focalPoint : Point3d.Point3d units coordinates, upDirection : Direction3d.Direction3d coordinates, projection : Camera3d.Projection, fov : Camera3d.FieldOfView units } -> Camera3d.Camera3d units coordinates"},{"name":"orbit","comment":" Construct a `Camera3d` looking at the given focal point, the given\ndistance away. The direction from the focal point to the eye point is defined by\nthe given azimuth and elevation angles, which are with respect to the given\nground plane (the position of the ground plane does not matter, only its\norientation). For example,\n\n    Camera3d.orbit\n        { focalPoint = Point3d.meters 0 0 1\n        , groundPlane = SketchPlane3d.xy\n        , azimuth = Angle.degrees 0\n        , elevation = Angle.degrees 45\n        , distance = Length.meters 10\n        , projection = Camera3d.Perspective\n        , fov = Camera3d.angle (Angle.degrees 30)\n        }\n\nis equivalent to\n\n    Camera3d.lookAt\n        { focalPoint = Point3d.meters 0 0 1\n        , eyePoint = Point3d.meters 7.071 0 7.071\n        , upDirection = Direction3d.z\n        , projection = Camera3d.Perspective\n        , fov = Camera3d.angle (Angle.degrees 30)\n        }\n\nAs the name suggests, `Camera3d.orbit` is useful for making orbiting cameras;\nyou can orbit around the focal point by changing just the azimuth, and rotate\nup and down by changing just the elevation.\n\n","type":"{ focalPoint : Point3d.Point3d units coordinates, groundPlane : SketchPlane3d.SketchPlane3d units coordinates defines, azimuth : Angle.Angle, elevation : Angle.Angle, distance : Quantity.Quantity Basics.Float units, projection : Camera3d.Projection, fov : Camera3d.FieldOfView units } -> Camera3d.Camera3d units coordinates"},{"name":"orbitZ","comment":" A special case of `orbit` for orbiting around a Z axis through the given\nfocal point. This corresponds to setting `groundPlane` to `SketchPlane3d.xy`,\nso azimuth is measured from the X axis towards the Y axis and elevation is\nmeasured up from the XY plane. Not related to the [classic soft drink](https://en.wikipedia.org/wiki/Orbitz_%28drink%29).\n","type":"{ focalPoint : Point3d.Point3d units coordinates, azimuth : Angle.Angle, elevation : Angle.Angle, distance : Quantity.Quantity Basics.Float units, projection : Camera3d.Projection, fov : Camera3d.FieldOfView units } -> Camera3d.Camera3d units coordinates"},{"name":"projection","comment":" Get the projection type of a camera.\n","type":"Camera3d.Camera3d units coordinates -> Camera3d.Projection"},{"name":"ray","comment":" Given a camera, [a rectangle defining the shape and size of a screen](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-camera/latest/#projection-to-screen-space),\nand a 2D point within that screen, calculate the corresponding 3D ray as an `Axis3d`.\nConceptually, the ray will pass through the given point on the screen and will\nhave direction equal to the viewing direction at that point.\n\nFor a perspective camera, the origin of the ray will be constant (always equal\nto the camera's eye point) and the direction will vary depending on the 2D\nscreen point. For an orthographic camera, the direction of the ray will be\nconstant (the view direction of the camera) but the origin will vary depending\non the 2D screen point.\n\n","type":"Camera3d.Camera3d units coordinates -> Rectangle2d.Rectangle2d screenUnits screenCoordinates -> Point2d.Point2d screenUnits screenCoordinates -> Axis3d.Axis3d units coordinates"},{"name":"viewDirection","comment":" Get the direction that a camera is looking in (the direction 'into the screen').\n","type":"Camera3d.Camera3d units coordinates -> Direction3d.Direction3d coordinates"},{"name":"viewPlane","comment":" The view plane of a camera is a `SketchPlane3d` where:\n\n  - The origin point of the sketch plane is the eye point of the camera\n  - The X direction of the sketch plane points to the left\n  - The Y direction of the sketch plane points up\n  - The normal direction of the sketch plane points out of the screen\n\n","type":"Camera3d.Camera3d units coordinates -> SketchPlane3d.SketchPlane3d units coordinates defines"},{"name":"with","comment":" Construct a camera directly from:\n\n  - Its view plane, which is a `SketchPlane3d` conceptually [aligned with the screen](#viewPlane)\n  - The focal distance of the camera (used to convert between angle-based and height-based field of\n    view as necessary). This is generally the distance from the camera's eye point to the object\n    being focused on (which is also often the center of rotation for the camera).\n  - What kind of projection the camera should use\n  - What field of view the camera should use\n\nThis corresponds most directly to the internal representation of a `Camera3d` and is the most\nflexible, but usually also the most akward to use.\n\n","type":"{ viewPlane : SketchPlane3d.SketchPlane3d units coordinates defines, focalDistance : Quantity.Quantity Basics.Float units, projection : Camera3d.Projection, fov : Camera3d.FieldOfView units } -> Camera3d.Camera3d units coordinates"}],"binops":[]},{"name":"LineSegment3d.Projection","comment":"\n\n@docs toScreenSpace\n\n","unions":[],"aliases":[],"values":[{"name":"toScreenSpace","comment":" Project a line segment from 3D world to 2D screen coordinates. Equivalent\nto calling [`Point3d.toScreenSpace`](Point3d-Projection#toScreenSpace) on the\ntwo endpoints of the line segment.\n","type":"Camera3d.Camera3d worldUnits worldCoordinates -> Rectangle2d.Rectangle2d screenUnits screenCoordinates -> LineSegment3d.LineSegment3d worldUnits worldCoordinates -> LineSegment2d.LineSegment2d screenUnits screenCoordinates"}],"binops":[]},{"name":"Point3d.Projection","comment":"\n\n@docs depth, toScreenSpace\n\n","unions":[],"aliases":[],"values":[{"name":"depth","comment":" Find the 'depth' of a point relative to a camera. This is the signed\ndistance of the point from a plane with:\n\n  - origin point equal to the camera's eye point\n  - normal direction equal to the camera's viewing direction\n\nThe returned depth is positive for points in front of the camera and negative\nfor points behind.\n\n","type":"Camera3d.Camera3d units coordinates -> Point3d.Point3d units coordinates -> Quantity.Quantity Basics.Float units"},{"name":"toScreenSpace","comment":" Project a point from 3D world to 2D screen coordinates, by supplying\n[a rectangle defining the shape and size of a screen](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-camera/latest/#projection-to-screen-space).\nPoints directly ahead of the camera will end up in the center of the given screen rectangle.\n\nNote that the projected 2D point may be outside the given rectangle, if the\ngiven 3D point is outside the field of view of the given camera.\n\n","type":"Camera3d.Camera3d worldUnits worldCoordinates -> Rectangle2d.Rectangle2d screenUnits screenCoordinates -> Point3d.Point3d worldUnits worldCoordinates -> Point2d.Point2d screenUnits screenCoordinates"}],"binops":[]},{"name":"Triangle3d.Projection","comment":"\n\n@docs toScreenSpace, isFrontFacing\n\n","unions":[],"aliases":[],"values":[{"name":"isFrontFacing","comment":" Check if a given triangle is front facing with respect to the given camera.\nA 'front facing' triangle has a normal direction towards the camera instead of\naway. This also means that when projected into 2D, the vertices of the triangle\nwill be in counterclockwise order.\n","type":"Camera3d.Camera3d units coordinates -> Triangle3d.Triangle3d units coordinates -> Basics.Bool"},{"name":"toScreenSpace","comment":" Project a triangle from 3D world to 2D screen coordinates. Equivalent\nto calling [`Point3d.toScreenSpace`](Point3d-Projection#toScreenSpace) on the\nthree vertices of the triangle.\n","type":"Camera3d.Camera3d worldUnits worldCoordinates -> Rectangle2d.Rectangle2d screenUnits screenCoordinates -> Triangle3d.Triangle3d worldUnits worldCoordinates -> Triangle2d.Triangle2d screenUnits screenCoordinates"}],"binops":[]},{"name":"WebGL.Matrices","comment":" These matrices can be used for rendering 3D [WebGL](https://package.elm-lang.org/packages/elm-explorations/webgl/latest/)\nscenes. For in-depth explanations of how they are used, check out:\n\n  - <https://learnopengl.com/Getting-started/Coordinate-Systems>\n  - <http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/>\n  - <http://www.songho.ca/opengl/gl_transform.html>\n\n\n# Individual matrices\n\n@docs modelMatrix, viewMatrix, projectionMatrix\n\n\n# Combined matrices\n\n@docs modelViewMatrix, viewProjectionMatrix, modelViewProjectionMatrix\n\n","unions":[],"aliases":[],"values":[{"name":"modelMatrix","comment":" Construct a WebGL model matrix given a `Frame3d` that defines the position\nand orientation of an object. Multiplying by this matrix transforms from local\nobject coordinates (coordinates relative to the given frame) to world\ncoordinates.\n\n(This is an alias of [`Frame3d.toMat4`](https://package.elm-lang.org/packages/ianmackenzie/elm-geometry-linear-algebra-interop/latest/Geometry-Interop-LinearAlgebra-Frame3d#toMat4),\nprovided here for consistency/convenience.)\n\n","type":"Frame3d.Frame3d units coordinates defines -> Math.Matrix4.Mat4"},{"name":"modelViewMatrix","comment":" Construct a WebGL model-view matrix given a camera and a `Frame3d` that\ndefines the position and orientation of an object.\n\nMultiplying by this matrix transforms from local object coordinates (coordinates\nrelative to the given frame) directly to view (eye) coordinates without first\ntransforming to world coordinates. Avoiding this intermediate conversion to\nworld coordinates improves accuracy, especially if both the object and camera\nare far from the world origin point.\n\n","type":"Frame3d.Frame3d units coordinates defines -> Camera3d.Camera3d units coordinates -> Math.Matrix4.Mat4"},{"name":"modelViewProjectionMatrix","comment":" Construct a WebGL model-view-projection matrix for a given camera; this is\nthe product of the projection and model-view matrices. Multiplying by this\nmatrix converts from local object coordinates to clip coordinates.\n","type":"Frame3d.Frame3d units coordinates defines -> Camera3d.Camera3d units coordinates -> { nearClipDepth : Quantity.Quantity Basics.Float units, farClipDepth : Quantity.Quantity Basics.Float units, aspectRatio : Basics.Float } -> Math.Matrix4.Mat4"},{"name":"projectionMatrix","comment":" Construct a WebGL projection matrix for a given camera, by supplying near\nand far clip depths as well as the aspect ratio (width over height) of the WebGL\nwindow being rendered to. Multiplying by this matrix converts from view\ncoordinates to [clip coordinates](https://en.wikipedia.org/wiki/Clip_coordinates).\n\nUsing a value of [`Quantity.positiveInfinity`](https://package.elm-lang.org/packages/ianmackenzie/elm-units/latest/Quantity#positiveInfinity)\nfor `farClipDepth` is supported, and this often works well for perspective\ncameras. However, for orthographic cameras, an infinite far clip depth means\nthat depth testing will not work. For things like line drawings this might be\nfine, but if you are depending on closer objects being reliably drawn in front\nof further-away objects (at least when using an orthographic camera) then you\nwill have to specify a finite far clip depth.\n\n","type":"Camera3d.Camera3d units coordinates -> { nearClipDepth : Quantity.Quantity Basics.Float units, farClipDepth : Quantity.Quantity Basics.Float units, aspectRatio : Basics.Float } -> Math.Matrix4.Mat4"},{"name":"viewMatrix","comment":" Construct a WebGL view matrix for a given camera. Multiplying by this\nmatrix transforms from world coordinates to view (eye) coordinates.\n\nNote that to avoid accuracy/roundoff issues (especially if both the camera\nand rendered objects are far from the world origin point), it is often better to\nuse [`modelViewMatrix`](#modelViewMatrix) instead of calling `modelMatrix` and\n`viewMatrix` separately.\n\n","type":"Camera3d.Camera3d units coordinates -> Math.Matrix4.Mat4"},{"name":"viewProjectionMatrix","comment":" Construct a WebGL view-projection matrix for a given camera; this is the\nproduct of the projection and view matrices. Multiplying by this matrix\nconverts from world coordinates to clip coordinates.\n","type":"Camera3d.Camera3d units coordinates -> { nearClipDepth : Quantity.Quantity Basics.Float units, farClipDepth : Quantity.Quantity Basics.Float units, aspectRatio : Basics.Float } -> Math.Matrix4.Mat4"}],"binops":[]}]