On this page

Обзор

VEX имеет тип массив. Это полезно в некоторых местах:

  • Поддержка параметра ramp.

  • Чтение данных с нод поверхностей с помощью функции import().

  • Общее программирование, где бы массивы ни были полезны.

Note

В настоящее время VEX не поддерживает многомерные массивы.

В этом примере показаны некоторые из сумасшедших вещей, которые вы можете делать с массивами:

surface
crazy(
      string maps[] = { "Mandril.rat", "default.pic" };
      export float alength = 0;
      )
{
    vector texclr, av[];

    texclr = texture(maps[s+t > 1], s, t);
    av = array( {1,0,0}, vector(nrandom()), t, texclr, {.5,0,0});

    if (fit(noise(s*8), 0, 1, .3, .7) > t)
        av = array(1, {0,1,0}, 0);

    Cf = spline("linear", s, av);
    alength = len(av);
}

Объявление типов массивов

Общий вид для объявления переменной массива тип_членов имя_переменной[]:

// my_array - это массив чисел с плавающей запятой
float   my_array[];

// v - это один вектор, а vector_array - это массив векторов
vector  v, vector_array[];

// str_array - это массив строк
string  str_array[];

По желанию вы можете установить размер массива внутри квадратных скобок, но компилятор VEX в настоящее время игнорирует его.

Чтобы объявить функцию, возвращающую массив:

// Функция, которая возвращает массив векторов
vector[] rgb_array()
{
...
};    

Чтобы объявить вложенную функцию, возвращающую массив:

// Функция, которая возвращает массив векторов
cvex
foo()
{
    // Используйте необязательное ключевое слово «function», чтобы избежать неоднозначности типа
    function vector[] rgb_array()
    {
    ...
    };    
}

Используйте фигурные скобки, чтобы указать литеральный массив, а элементы разделяйте запятыми:

vector an_array[] = { {1, 2, 3}, {2, 3, 4}, {4, 5, 6} };

vector[] rgb_array()
{
    return { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} };
}

Если вы укажете скаляр там, где ожидается вектор, компилятор автоматически присвоит данное скалярное значение всем элементам вектора:

vector an_array[] = { 1, 2, 3};
// an_array[] == { {1, 1, 1}, {2, 2, 2}, {3, 3, 3} }

Функция array() создает массив из своих аргументов.

int my_array[] = array(1, 2, 3, 4, 5);

Вы можете использовать array() для создания массива любого типа. Чтобы заставить array() сгенерировать векторы, например:

vector (array (значение1, значение2, ...) );

Доступ и установка значений массива

Используйте конструкцию имямассива[индекс] для получения значения по позиции в массиве.

vector bw[] = { 0, 1 };
// bw[] == { {0, 0, 0}, {1, 1, 1} }
Cf = bw[index];

Границы массива проверяются во время выполнения. Чтение за пределами массива вернет 0 или "". Это может привести к возникновению предупреждения или ошибке исполнения (run-time error) в будущем. Запись за конец массива изменит размер массива, чтобы включить в него указанный индекс. Новые записи будут иметь значение 0 или "".

Используется индексирование в стиле языка Python. Это означает, что отрицательные индексы относятся к позициям с конца массива.

int nums[] = { 0, 1, 2, 3, 4, 5 };
int n = nums[10];  // Вернет 0
int b = nums[-2];  // Вернет 4

string strs[] = { };
string s = strs[20];  // Вернет ""

Вы также можете присваивать значения с помощью обозначения квадратных скобок.

float nums[] = { };
nums[0] = 3.14;

(Функции getcomp и setcomp являются эквивалентами для использования обозначения квадратных скобок.)

Note

Получение доступа к элементам по их позиции посредством квадратных скобок также работает для векторов. Вы также можете использовать их для матриц, используя пару скобок: float a = m3[0][1];

Срезы массивов

Квадратные скобки могут использоваться для извлечения подмассивов с использованием обозначений для срезов из языка Python.

int nums[] = { 0, 1, 2, 3, 4, 5 };
int start[] = nums[0:2];  // { 0, 1 }
int end[] = nums[-2:];  // { 4, 5 }
int rev[] = nums[::-1];  // { 5, 4, 3, 2, 1, 0 }
int odd[] = nums[1::2]; // { 1, 3, 5 }

Функция slice является эквивалентом использования обозначения среза в квадратных скобках.

Копирование между массивами и векторами/матрицами

Оператор присваивания поддерживает возможность назначения значений массивов чисел с плавающей точкой в векторы и наоборот:

float x[];
// Cf и P векторы

x = set(P);   // Присваивание значений вектора P соответствующим 
              // элементам массива x

Cf = set(x);  // Присваивание первых трех элементов массива x в качестве
              // элементов вектора Cf

Если массив не имеет достаточного количества элементов, чтобы заполнить вектор/матрицу, последний элемент повторяется столько раз, сколько необходимо для заполнения.

float x[] = {1, 2} // Недостаточно, чтобы заполнить вектор
Cf = set(x);  // Cf == {1, 2, 2}

Вы также можете проводить присваивание между типами матриц и массивов vector2/vector/vector4:

vector2     v2[];
vector      v[];
vector4     v4[];
matrix2     m2 = 1;
matrix3     m3 = 1;
matrix      m4 = 1;

v = set(m3);   // Каждая строка матрицы 3x3 помещается в вектор
m3 = set(v);   // Копирует векторы в строки матрицы
v4 = set(m4);  // Извлекает строки матрицы в массив векторов (vector4)
m4 = set(v4);  // Создает матрицу с использованием вектора (vector4)

В итоге:

Левая сторона = Правая сторона Заметки
vector2 float[] Например vector2 v = {1,2}
vector float[] Например vector v = {1,2,3}
vector4 float[] Например vector4 v = {1,2,3,4};
matrix2 float[] Например matrix2 m = {1,2,3,4};
matrix2 vector2[] Например matrix2 m = { {1,2}, {4,5} };
matrix3 float[] Например matrix3 m = {1,2,3,4,5,6,7,8,9};
matrix3 vector[] Например matrix3 m = { {1,2,3}, {4,5,6}, {7,8,9}};
matrix float[] Например matrix m = {1,2,3,4,5,6,7,8,9.., 16};
matrix vector4[] Например matrix m = { {1,2,3,4}, {5,6,7,8}, ... {13,14,15,16}};
float[] vector2 Создаст массив с двумя float значениями из элементов vector2
float[] vector Создаст массив с тремя float значениями из элементов vector
float[] vector4 Создаст массив с четырьмя float значениями из элементов vector4
float[] matrix2 Создаст массив с четырьмя float значениями из элементов matrix2
vector2[] matrix2 Создаст массив с двумя vector2 значениями из элементов matrix2
float[] matrix3 Создаст массив с девятью float значениями из элементов matrix3
vector[] matrix3 Создаст массив с тремя vector значениями из элементов matrix3
float[] matrix4 Создаст массив с шестнадцатью float значениями
vector4[] matrix4 Создаст массив с четырьмя vector4.

Перебор элементов массива

Смотрите foreach.

Работа с массивами

Следующие функции позволят вам всячески манипулировать массивами.

resize

Устанавливает длину массива. Если массив был увеличен, промежуточные значения будут заполнены 0 или "".

len

Возвращает длину массива.

pop

Удаляет последний элемент из массива (уменьшая размер массива на 1) и возвращает удаленный элемент.

push

Добавляет элемент в конец массива (увеличивая размер массива на 1).

getcomp

Возвращает значение компонента массива, то же, что array[num].

setcomp

Устанавливает значение компонента массива, то же, что и array[num] = value.

array

Эффективно создает массив из своих аргументов.

serialize

Превращает массив векторов или матриц в массив float значений.

unserialize

Обращает эффект serialize: собирает плоский массив float значений в массив векторов или матриц.

neighbours

Основанная на массиве замена комбинации neighbourcount/neighbour. Возвращает массив номеров точек соседних с данной точкой.

Следующие функции также работают с массивами:

Псевдокомментарии компилятора VCC (Pragmas)

Псевдокомментарий ramp позволяет указать пользовательский интерфейс "ramp" для набора параметров.

#pragma ramp <ramp_parm> <basis_parm> <keys_parm> <values_parm>

Смотрите псевдокомментарии компилятора VCC для получения дополнительной информации.

Ограничения

  • В настоящее время VEX не поддерживает многомерные массивы.

  • Массивы не могут передаваться между шейдерами (через simport, и т.д.).

  • Массивы не могут быть записаны в изображения.

VEX

Язык

Следующие шаги

Справочная информация