Quiddity.Camera (ExQuiddity v0.1.2)

Copy Markdown View Source

A pinhole camera: where a sensor is, what it looks along, and how wide it sees.

The basis is spelled out rather than inferred — forward, right, up — so a frame's pixel geometry is a property of this struct and nothing has to agree with MuJoCo about which way a camera's own −z points. The defaults are a patch sensor's: 64 × 64 pixels over a 66° field of view, a metre past the part, so a frame rendered here and a frame rendered by a simulator can cover the same solid angle.

Millimetres, everywhere: a STEP file is in millimetres and so is this.

Summary

Functions

The camera's basis and origin as a 4 × 4 matrix, rows first.

The world axis least aligned with a direction — a usable roll reference.

A camera at eye looking at target.

A sensor placed distance mm off a surface, looking straight at it.

The width one pixel covers at distance mm, in millimetres.

A tangent to a surface with normal: the direction a patch's up follows.

The camera as the engine reads it.

Types

t()

@type t() :: %Quiddity.Camera{
  far: float(),
  forward: [float()],
  fov_x: float(),
  height: pos_integer(),
  near: float(),
  origin: [float()],
  right: [float()],
  up: [float()],
  width: pos_integer()
}

Functions

cam_to_world(camera)

@spec cam_to_world(t()) :: [[float()]]

The camera's basis and origin as a 4 × 4 matrix, rows first.

least_aligned_axis(direction)

@spec least_aligned_axis([float()]) :: [float()]

The world axis least aligned with a direction — a usable roll reference.

looking_at(eye, target, options \\ [])

@spec looking_at([float()], [float()], keyword()) ::
  {:ok, t()} | {:error, Quiddity.Error.t()}

A camera at eye looking at target.

Options: :width, :height, :fov_x (radians), :up (the roll reference, defaulting to the world axis least aligned with the view so a straight-down look still has a sensible up), :near and :far.

patch(point, normal, options \\ [])

@spec patch([float()], [float()], keyword()) ::
  {:ok, t()} | {:error, Quiddity.Error.t()}

A sensor placed distance mm off a surface, looking straight at it.

This is the placement a patch camera has on a part: the eye sits on the outward normal, the view runs back down it. The roll reference is a tangent to the surface, so the patch's rows and columns follow the surface rather than the world.

pixel_size(camera, distance)

@spec pixel_size(t(), float()) :: float()

The width one pixel covers at distance mm, in millimetres.

tangent(normal)

@spec tangent([float()]) :: [float()]

A tangent to a surface with normal: the direction a patch's up follows.

The world axis least aligned with the normal is crossed with it, so a part that is not aligned to the world gets a tangent that follows it, and a part that is gets one along its own axes.

to_params(camera)

@spec to_params(t()) :: map()

The camera as the engine reads it.