-module(viva_math@vec4). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/viva_math/vec4.gleam"). -export([zero/0, splat/1, add/2, sub/2, scale/2, negate/1, dot/2, length_squared/1, length/1, distance/2, normalize/1, lerp/3, multiply/2, clamp/3, is_close/3]). -export_type([vec4/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " 4-D vector operations.\n" "\n" " Used for RGBA colors, homogeneous coordinates and quaternions (when the\n" " fourth component is treated as w/real).\n" ). -type vec4() :: {vec4, float(), float(), float(), float()}. -file("src/viva_math/vec4.gleam", 13). -spec zero() -> vec4(). zero() -> {vec4, +0.0, +0.0, +0.0, +0.0}. -file("src/viva_math/vec4.gleam", 17). -spec splat(float()) -> vec4(). splat(Value) -> {vec4, Value, Value, Value, Value}. -file("src/viva_math/vec4.gleam", 21). -spec add(vec4(), vec4()) -> vec4(). add(A, B) -> {vec4, erlang:element(2, A) + erlang:element(2, B), erlang:element(3, A) + erlang:element(3, B), erlang:element(4, A) + erlang:element(4, B), erlang:element(5, A) + erlang:element(5, B)}. -file("src/viva_math/vec4.gleam", 25). -spec sub(vec4(), vec4()) -> vec4(). sub(A, B) -> {vec4, erlang:element(2, A) - erlang:element(2, B), erlang:element(3, A) - erlang:element(3, B), erlang:element(4, A) - erlang:element(4, B), erlang:element(5, A) - erlang:element(5, B)}. -file("src/viva_math/vec4.gleam", 29). -spec scale(vec4(), float()) -> vec4(). scale(V, S) -> {vec4, erlang:element(2, V) * S, erlang:element(3, V) * S, erlang:element(4, V) * S, erlang:element(5, V) * S}. -file("src/viva_math/vec4.gleam", 33). -spec negate(vec4()) -> vec4(). negate(V) -> {vec4, +0.0 - erlang:element(2, V), +0.0 - erlang:element(3, V), +0.0 - erlang:element(4, V), +0.0 - erlang:element(5, V)}. -file("src/viva_math/vec4.gleam", 37). -spec dot(vec4(), vec4()) -> float(). dot(A, B) -> (((erlang:element(2, A) * erlang:element(2, B)) + (erlang:element(3, A) * erlang:element( 3, B ))) + (erlang:element(4, A) * erlang:element(4, B))) + (erlang:element(5, A) * erlang:element(5, B)). -file("src/viva_math/vec4.gleam", 41). -spec length_squared(vec4()) -> float(). length_squared(V) -> dot(V, V). -file("src/viva_math/vec4.gleam", 46). ?DOC(" Length using two-level hypot to avoid overflow at extreme scales.\n"). -spec length(vec4()) -> float(). length(V) -> Xy = viva_math@scalar:hypot(erlang:element(2, V), erlang:element(3, V)), Zw = viva_math@scalar:hypot(erlang:element(4, V), erlang:element(5, V)), viva_math@scalar:hypot(Xy, Zw). -file("src/viva_math/vec4.gleam", 52). -spec distance(vec4(), vec4()) -> float(). distance(A, B) -> length(sub(A, B)). -file("src/viva_math/vec4.gleam", 56). -spec normalize(vec4()) -> vec4(). normalize(V) -> L = length(V), case L =:= +0.0 of true -> zero(); false -> {vec4, case L of +0.0 -> +0.0; -0.0 -> -0.0; Gleam@denominator -> erlang:element(2, V) / Gleam@denominator end, case L of +0.0 -> +0.0; -0.0 -> -0.0; Gleam@denominator@1 -> erlang:element(3, V) / Gleam@denominator@1 end, case L of +0.0 -> +0.0; -0.0 -> -0.0; Gleam@denominator@2 -> erlang:element(4, V) / Gleam@denominator@2 end, case L of +0.0 -> +0.0; -0.0 -> -0.0; Gleam@denominator@3 -> erlang:element(5, V) / Gleam@denominator@3 end} end. -file("src/viva_math/vec4.gleam", 64). -spec lerp(vec4(), vec4(), float()) -> vec4(). lerp(A, B, T) -> {vec4, viva_math@scalar:lerp(erlang:element(2, A), erlang:element(2, B), T), viva_math@scalar:lerp(erlang:element(3, A), erlang:element(3, B), T), viva_math@scalar:lerp(erlang:element(4, A), erlang:element(4, B), T), viva_math@scalar:lerp(erlang:element(5, A), erlang:element(5, B), T)}. -file("src/viva_math/vec4.gleam", 74). ?DOC(" Hadamard (component-wise) product.\n"). -spec multiply(vec4(), vec4()) -> vec4(). multiply(A, B) -> {vec4, erlang:element(2, A) * erlang:element(2, B), erlang:element(3, A) * erlang:element(3, B), erlang:element(4, A) * erlang:element(4, B), erlang:element(5, A) * erlang:element(5, B)}. -file("src/viva_math/vec4.gleam", 78). -spec clamp(vec4(), float(), float()) -> vec4(). clamp(V, Lo, Hi) -> {vec4, viva_math@scalar:clamp(erlang:element(2, V), Lo, Hi), viva_math@scalar:clamp(erlang:element(3, V), Lo, Hi), viva_math@scalar:clamp(erlang:element(4, V), Lo, Hi), viva_math@scalar:clamp(erlang:element(5, V), Lo, Hi)}. -file("src/viva_math/vec4.gleam", 87). -spec is_close(vec4(), vec4(), float()) -> boolean(). is_close(A, B, Tol) -> (((gleam@float:absolute_value(erlang:element(2, A) - erlang:element(2, B)) =< Tol) andalso (gleam@float:absolute_value( erlang:element(3, A) - erlang:element(3, B) ) =< Tol)) andalso (gleam@float:absolute_value( erlang:element(4, A) - erlang:element(4, B) ) =< Tol)) andalso (gleam@float:absolute_value( erlang:element(5, A) - erlang:element(5, B) ) =< Tol).