vector_victor/
swizzle.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5/** Rearrange the rows of a matrix by the given row identifiers
6# Arguments
7
8* `mat`: the matrix to manipulate
9* `i...`: variadic comma-seperated list of row selectors. The row selectors are each one of:
10    * const expression representing the row index of the input to copy. eg: `0` or `2`
11    * a letter representing the same. you can use `r,g,b,a` or `x,y,z,w` to represent index 0 through 3,
12      or `u,v` to represent indices 0 through 1.
13    * an expression in curly braces, representing a value to be copied to an entire row of
14      the result, eg: `{1.0}` or `{5}`
15
16  note that the number of selectors doesnt need to match the height of the input!
17
18# Examples
19```
20# use vector_victor::{swizzle, Vector};
21let myvec = Vector::vec([0, 1, 2, 3]);
22
23// each element can be selected with:
24// 0: r, x, u, or 0
25// 1: g, y, v, or 1
26// 2: b, z, or 2
27// 3: a, w, or 3
28// or a result row can be filled by a new value
29
30assert_eq!(swizzle!(myvec, a, z, v, 0, {7}), Vector::vec([3, 2, 1, 0, 7]));
31```
32
33More often you wont mix and match selector "flavors".
34This example unpacks a [DXT5nm](http://wiki.polycount.com/wiki/Normal_Map_Compression) color
35into the red and green channels, with blue filled with 0.
36```
37# use vector_victor::{swizzle, Vector};
38let myvec = Vector::vec([0, 120, 0, 255]);
39assert_eq!(swizzle!(myvec, a, g, {0}), Vector::vec([255, 120, 0]));
40``` */
41#[macro_export]
42macro_rules! swizzle {
43    ($mat: expr, $( $i:tt),+) => {{
44        let mut result = $mat.permute_rows(&$crate::Vector::vec([$( $crate::get!($mat, $i), )+]));
45        let mut _p = 0usize;
46        $(
47            $crate::sub_literal!(result, _p, $i);
48            _p += 1;
49        )+
50        result
51    }};
52}
53
54#[doc(hidden)]
55#[macro_export]
56macro_rules! get {
57    ($mat:expr, x) => {
58        0usize
59    };
60    ($mat:expr, y) => {
61        1usize
62    };
63    ($mat:expr, z) => {
64        2usize
65    };
66    ($mat:expr, w) => {
67        3usize
68    };
69    ($mat:expr, r) => {
70        0usize
71    };
72    ($mat:expr, g) => {
73        1usize
74    };
75    ($mat:expr, b) => {
76        2usize
77    };
78    ($mat:expr, a) => {
79        3usize
80    };
81    ($mat:expr, u) => {
82        0usize
83    };
84    ($mat:expr, v) => {
85        1usize
86    };
87    ($mat:expr, {$i:expr}) => {
88        0usize /* will be replaced later */
89    };
90    ($mat:expr, $i:expr) => {
91        $i
92    };
93}
94
95#[doc(hidden)]
96#[macro_export]
97macro_rules! sub_literal {
98    ($result:expr, $p:expr, {$i:expr}) => {
99        $result.set_row($p, &$crate::Vector::fill($i))
100    };
101    ($result:expr, $p:expr, $i:expr) => {};
102}