defmodule Manganese.SerializationKit.Structs.UnityQuaternion do @moduledoc """ A Unity quaternion value with `:x`, `:y`, `:z`, and `w` components. *Note that Unity structs are available in order to process the data in the API server, but most vector calculations occur in the environment simulation service.* This module can be used as an Ecto type for de/serialization when interacting with the database. """ alias Manganese.SerializationKit.Structs @typedoc """ A Unity quaternion. """ @type t :: %Structs.UnityQuaternion{ x: float, y: float, z: float, w: float } defstruct [ :x, :y, :z, :w ] # Utilities @doc """ A quaternion representing no rotation. """ @spec identity :: t def identity, do: %Structs.UnityQuaternion{ x: 0, y: 0, z: 0, w: 1 } # Deserialization @doc """ Deserialize a quaternion from a map. """ @spec from_map(t_external) :: t def from_map(%{ "x" => x, "y" => y, "z" => z, "w" => w }) do %Structs.UnityQuaternion{ x: x, y: y, z: z, w: w } end @doc """ Deserialize a quaternion from a tuple. """ @spec from_tuple(t_internal) :: t def from_tuple({ x, y, z, w }) do %Structs.UnityQuaternion{ x: x, y: y, z: z, w: w } end # Serialization @type t_internal :: { float, float, float, float } @type t_external :: map @doc """ Serialize a quaternion to a map. """ @spec to_map(t) :: t_external def to_map(%Structs.UnityQuaternion{ x: x, y: y, z: z, w: w }) do %{ "x" => x, "y" => y, "z" => z, "w" => w } end @doc """ Serialize a quaternion to a tuple. """ @spec to_tuple(t) :: t_internal def to_tuple(%Structs.UnityQuaternion{ x: x, y: y, z: z, w: w }) do { x, y, z, w } end # Ecto type use Ecto.Type @doc """ The PostgreSQL composite type used to represent a quaternion. """ def type, do: :unity_quaternion # Casting def cast(%Structs.UnityQuaternion{} = unity_quaternion), do: { :ok, unity_quaternion } def cast({ _x, _y, _z, _w } = tuple), do: { :ok, from_tuple tuple } def cast(nil), do: { :ok, nil } def cast(_), do: :error def load({ _x, _y, _z, _w } = tuple), do: { :ok, from_tuple tuple } def dump(%Structs.UnityQuaternion{} = unity_quaternion) do { :ok, to_tuple unity_quaternion } end end