All Projects → ianmackenzie → elm-3d-camera

ianmackenzie / elm-3d-camera

Licence: MPL-2.0 license
Camera type for doing 3D rendering in Elm

Programming Languages

elm
856 projects

Projects that are alternatives of or similar to elm-3d-camera

Sharpmath
A small .NET math library.
Stars: ✭ 36 (+200%)
Mutual labels:  vector, matrix
Numphp
Mathematical PHP library for scientific computing
Stars: ✭ 120 (+900%)
Mutual labels:  vector, matrix
Matrix Puppet Hangouts
Matrix bridge for Google Hangouts
Stars: ✭ 42 (+250%)
Mutual labels:  vector, matrix
Cgmath
A linear algebra and mathematics library for computer graphics.
Stars: ✭ 773 (+6341.67%)
Mutual labels:  vector, matrix
PyGLM
Fast OpenGL Mathematics (GLM) for Python
Stars: ✭ 167 (+1291.67%)
Mutual labels:  vector, matrix
Fmatvec
A fast vector/matrix library
Stars: ✭ 5 (-58.33%)
Mutual labels:  vector, matrix
Lacaml
OCaml bindings for BLAS/LAPACK (high-performance linear algebra Fortran libraries)
Stars: ✭ 101 (+741.67%)
Mutual labels:  vector, matrix
Libxsmm
Library for specialized dense and sparse matrix operations, and deep learning primitives.
Stars: ✭ 518 (+4216.67%)
Mutual labels:  vector, matrix
Hlslpp
Math library using hlsl syntax with SSE/NEON support
Stars: ✭ 153 (+1175%)
Mutual labels:  vector, matrix
Matrixstats
R package: Methods that Apply to Rows and Columns of Matrices (and to Vectors)
Stars: ✭ 151 (+1158.33%)
Mutual labels:  vector, matrix
Vectorious
Linear algebra in TypeScript.
Stars: ✭ 616 (+5033.33%)
Mutual labels:  vector, matrix
Blasjs
Pure Javascript manually written 👌 implementation of BLAS, Many numerical software applications use BLAS computations, including Armadillo, LAPACK, LINPACK, GNU Octave, Mathematica, MATLAB, NumPy, R, and Julia.
Stars: ✭ 241 (+1908.33%)
Mutual labels:  vector, matrix
Mathsharp
A vector and matrix library written in C# using hardware intrinsics
Stars: ✭ 616 (+5033.33%)
Mutual labels:  vector, matrix
Cglm
📽 Highly Optimized Graphics Math (glm) for C
Stars: ✭ 887 (+7291.67%)
Mutual labels:  vector, matrix
Tensor Sensor
The goal of this library is to generate more helpful exception messages for numpy/pytorch matrix algebra expressions.
Stars: ✭ 532 (+4333.33%)
Mutual labels:  vector, matrix
Algebra
means completeness and balancing, from the Arabic word الجبر
Stars: ✭ 92 (+666.67%)
Mutual labels:  vector, matrix
Armadillo Code
Armadillo: fast C++ library for linear algebra & scientific computing - http://arma.sourceforge.net
Stars: ✭ 388 (+3133.33%)
Mutual labels:  vector, matrix
Joml
A Java math library for OpenGL rendering calculations
Stars: ✭ 479 (+3891.67%)
Mutual labels:  vector, matrix
Node Sylvester
🐱 Sylvester is a vector, matrix, and geometry library for JavaScript, that runs in the browser and on the server.
Stars: ✭ 144 (+1100%)
Mutual labels:  vector, matrix
Math Php
Powerful modern math library for PHP: Features descriptive statistics and regressions; Continuous and discrete probability distributions; Linear algebra with matrices and vectors, Numerical analysis; special mathematical functions; Algebra
Stars: ✭ 2,009 (+16641.67%)
Mutual labels:  vector, matrix

elm-3d-camera

This package provides convenient ways to define and use perspective and orthographic cameras in 3D. It is based on elm-geometry and is used heavily by elm-3d-scene. It can also be used standalone to:

  • Construct WebGL model/view/projection matrices in a way that is more intuitive than using elm-explorations/linear-algebra directly
  • Perform 3D-to-2D projection of various elm-geometry values (points, line segments, triangles). This in turn allows you to do things like render simple 3D shapes by projecting them into 2D so that they can be drawn with SVG instead of WebGL.

Defining cameras

The functions in this package let you construct perspective or orthographic cameras in various different ways, for example:

import Angle
import Camera3d
import Length
import Point3d

perspectiveCamera =
    Camera3d.lookAt
        { eyePoint = Point3d.meters 4 0 3
        , focalPoint = Point3d.origin
        , upDirection = Direction3d.positiveZ
        , projection = Camera3d.Perspective
        , fov = Camera3d.angle (Angle.degrees 30)
        }

Note that there are no functions for transforming (translating, rotating etc.) cameras - cameras are intended to be 'throwaway' values that you would construct on the fly when doing some rendering. For example, if in the above code you wanted to have an animated camera that tracked some moving object, you might store the camera and object positions in your model as Point3d values but then recreate the actual Camera3d value every frame.

WebGL rendering

Once you have a camera, you can use it to get WebGL view and projection matrices:

import WebGL.Matrices as WebGL

viewMatrix =
    WebGL.viewMatrix camera

projectionMatrix =
    WebGL.projectionMatrix camera
        { nearClipDepth = Length.meters 0.1
        , farClipDepth = Length.meters 100
        , aspectRatio = 16 / 9
        }

Projection to screen space

You can also use a Camera3d to project points, lines, and triangles from 3D to 2D. This allows you to, for example, do a perspective projection of 3D points and lines into 2D so that those points and lines can be rendered with SVG (taking advantage of SVG features like perfect circles and dashed lines which are difficult to do with WebGL):

Perspective projection

First, you must define the dimensions of the screen you want to project to; this should generally be of the form

screen =
    Rectangle2d.from bottomLeftCorner topRightCorner

Note that if you want browser DOM coordinates directly, you'll probably want to use something like

scree =
    Rectangle2d.from
        (Point2d.pixels 0 clientHeight)
        (Point2d.pixels clientWidth 0)

since in HTML 0 is the top and positive Y is down. I personally generally prefer working in 2D coordinate systems where positive Y is up (converting to DOM coordinates at the last possible moment), so my code that projects from 3D to 2D looks like this:

import Point3d.Projection as Point3d
import LineSegment3d.Projection as LineSegment3d

screen =
    Rectangle2d.from Point2d.origin
        (Point2d.pixels 800 600)

point2d =
    point3d |> Point3d.toScreenSpace camera screen

lineSegment2d =
    lineSegment3d
        |> LineSegment3d.toScreenSpace camera screen

(The Overlay.elm example uses an under-development Drawing2d module which works in a coordinate system where positive Y is up, converting to Y-down coordinates only when actually rendering to SVG internally.)

Roadmap

A few more features are planned:

  • More 3D-to-2D projections (directions, axes)
  • Construction of 3D cut planes from 2D on-screen lines

Questions? Comments?

Please open a new issue if you run into a bug, if any documentation is missing/incorrect/confusing, or if there's a new feature that you would find useful. For general questions about using elm-3d-camera, try:

  • Joining the #geometry or #webgl channels on the Elm Slack, or sending me (@ianmackenzie) a message - even if you don't have any particular questions right now, it would be great to know what you're hoping to do with the package! - Posting to the Elm Discourse forums

You can also find me on Twitter (@ianemackenzie), where I occasionally post elm-geometry-related stuff like demos or new releases. Have fun, and don't be afraid to ask for help!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].