Войти
ПрограммированиеФорумОбщее

GLM Row Major (3 стр)

Страницы: 1 2 3 4 5 Следующая »
#30
20:42, 20 янв 2018

Эта, вы что.
Обе матрицы,

(1 0 0 1)
(0 1 0 2)
(0 0 1 3)
(0 0 0 1)
и
(1 0 0 0)
(0 1 0 0)
(0 0 1 0)
(1 2 3 1)

могут быть как row-major, так и column-major. Как вы приставляете к ней вектор - это ж просто вопрос нотации. Ну любит академия писать v' = M * v, ну не стрелять же их за это.
А мажористость говорит, к примеру, в каком байте начинается элемент первой строки третьего столбца (байты 8-11 или байты 32-35).

Кстати, вот это все помнят? Попробуйте перевернуть нотацию.

#31
18:42, 21 янв 2018

Wraith
> Эта, вы что.
> Обе матрицы,
> (1 0 0 1)
> (0 1 0 2)
> (0 0 1 3)
> (0 0 0 1)
> и
> (1 0 0 0)
> (0 1 0 0)
> (0 0 1 0)
> (1 2 3 1)
Блин. Ну я же уже объяснил что значит col major. Вот берешь ты glm, и с помощью библиотеки получаешь translate матрицу от вектора (1,2,3). И если glm тебе возвращает
(1 0 0 1)
(0 1 0 2)
(0 0 1 3)
(0 0 0 1)
То это col major. Теперь чтобы получить перенос при умножении матрицы на вектор тебе вектор надо ставить справа. v' = M × v. Не, ты конечно можешь поставить его слева, но это будет хрень, а не перенос. И совершенно по барабану в каких байтах хранит glm матрицы. Главное как glm трактует их при умножении. Вот вектор переноса будет храниться в столбце при получении матрицы переноса средствами glm.
Вся col или row мажористость находится внутри функций вида:
GetTranslateMatrix
GetRotateMatrix
GetViewMatrix
GetperspectiveMatrix
и т. п.
Достаточно переписать их, чтобы вся glm библиотека стала row major. Так хоть понятно теперь?

#32
22:56, 21 янв 2018

MrShoor
>(1 0 0 1)
>(0 1 0 2)
>(0 0 1 3)
>(0 0 0 1)
>Блин. Ну я же уже объяснил что значит col major.
...
>И совершенно по барабану в каких байтах хранит glm матрицы. Главное как glm трактует их при умножении.

Самое смешное, что если ты просто перевернешь нотацию той гл-матрицы, и приставишь вектор слева, то получишь аккурат row-major матрицу из D3D (где в памяти элементы лежат _11, _12, _13, _14, _21, ...).

Самое главное - это как раз как байты в памяти лежат. Типичный интерес - чтобы матрица 3х4 лежала в структуре, которую я мог бы сразу залить как константный буфер, где она объявлена как vec4 matrix[3]; потому что этот долбаный глсл не дает объявлять матрицы 3x4.

Нотация - субъективная вкусовщина, лейаут в памяти - объективная реальность.

#33
2:24, 22 янв 2018

Wraith
> Самое смешное, что если ты просто перевернешь нотацию той гл-матрицы, и
> приставишь вектор слева, то получишь аккурат row-major матрицу
Как бы логично, что если я на каком-то одном этапе добавлю операцию траспонирования (а перевернешь нотацию - и есть операция транспонирования), то из col major матрицы она станет row major. Но все равно спасибо, кэп.

Wraith
> Самое главное - это как раз как байты в памяти лежат.
Вообще пофигу. Реально. Кто мне мешает поменять местами скажем вторую и третью строку, но так, чтобы все операции учитывали это изменение? И вот байты лежат уже совсем по другому, а все работает. В памяти можешь делать вообще что угодно, хоть на 45 градусов поворачивай:
(1 0 0 1)
(0 1 0 2)
(0 0 1 3)
(0 0 0 1)
оп:
(1)
(0 2)
(0 0 3)
(1 1 1 1)
(0 0 0)
(0 0)
(0)
Главное лишь то, как ты напишешь операции с этой матрицей. В матеамтике принято, что строка умножается на столбец. Поэтому если мы множим v' = M * v, чтобы получить нашу трансформацию, то базис в M хранится в стоблцах. И вот наши столбцы:
cols | GLM Row Major

Wraith
> Нотация - субъективная вкусовщина
Прости, но нет. Об этой субъективной вкусовщине договорились уже давно. Строка множимой матрицы умножается на столбец множителя, а не наоборот: https://ru.wikipedia.org/wiki/Умножение_матриц
Если для трансформации вектора тебе приходится делать v' = M * v, то значит это col major. Если v' = v * M - это row major. И не важно где ты это делаешь. В коде, на бумажке или в уме. И это будет всегда так, до тех пор, пока ты следуешь правилам умножения матриц, и множишь строку на столбец.

#34
9:48, 22 янв 2018

MrShoor
> Как пользоваться column major матрицами я знаю. Но хочется пользоваться row
> major чтобы например писать:
> v = v * m1 * m2 * m3;
> а не:
> v = (m3 * (m2 * (m1 * v)));
> ну и слева направо приятнее опять же читать.

странно, мне приятнее читать как в универе было

#35
7:58, 23 янв 2018

MrShoor
>> Самое смешное, что если ты просто перевернешь нотацию той гл-матрицы, и
>> приставишь вектор слева, то получишь аккурат row-major матрицу
>Как бы логично, что если я на каком-то одном этапе добавлю операцию траспонирования (а перевернешь нотацию - и есть операция транспонирования), то из col major матрицы она станет row major. Но все равно спасибо, кэп.

>> Самое главное - это как раз как байты в памяти лежат.
>Вообще пофигу. Реально. Кто мне мешает поменять местами скажем вторую и третью строку, но так, чтобы все операции учитывали это изменение? И вот байты лежат уже совсем по другому, а все работает. В памяти можешь делать вообще что угодно, хоть на 45 градусов поворачивай:

>>Если для трансформации вектора тебе приходится делать v' = M * v, то значит это col major. Если v' = v * M - это row major. И не важно где ты это делаешь. В коде, на бумажке или в уме.

Да откуда это?

Ты видел хоть одну научную работу с линейной алгеброй, где упоминается row-major или column-major по отношению к чему-то иному, чем представление матриц в памяти при вычислениях?

#36
9:04, 23 янв 2018

Wraith
> Ты видел хоть одну научную работу с линейной алгеброй, где упоминается
> row-major или column-major по отношению к чему-то иному, чем представление
> матриц в памяти при вычислениях?
Не в курсе есть такие работы или нет, но в математике базис в матрице перехода принято хранить в столбцах. В математике он по умолчанию col major. Пруф:
https://en.wikipedia.org/wiki/Transformation_matrix
Прям в первых же предложениях.
И умножают обычно во всех научных работах на вектор справа:
v' = M * v
А если ты видишь в научной работе умножение:
v' = v * M
то значит вектор представлен строкой, и базис в матрице соотвественно тоже строкой (но так не принято, и я ни разу не видел, чтобы в формулах писали вектор слева от матрицы).

#37
12:21, 23 янв 2018

Wraith
> Ты видел хоть одну научную работу с линейной алгеброй, где упоминается
> row-major или column-major по отношению к чему-то иному, чем представление
> матриц в памяти при вычислениях?
Не знаю про научные работы, но row-major и column-major также являются соглашением на тему того, как интерпретировать данные матрицы, разве нет? Так что библиотека, способная к композиции и декомпозиции матриц, может быть RM или CM.

#38
7:45, 24 янв 2018

MrShoor
> В математике он по умолчанию col major.
Да нет же. Понятие мажористости применимо только к компьютерным вычислениям. И заметь, что в статье, на которую ты ссылаешься, нигде column-major не упоминается.

-Eugene-
> Не знаю про научные работы, но row-major и column-major также являются
> соглашением на тему того, как интерпретировать данные матрицы, разве нет? Так
> что библиотека, способная к композиции и декомпозиции матриц, может быть RM или
> CM.

Вот допустим есть у нас есть функция:

struct float4 { float x,y,z,w; };
float4 transform( float4 v, float4 m[4] )
{
    float4 result;
    result.x = dot4( m[0], v );
    result.y = dot4( m[1], v );
    result.z = dot4( m[2], v );
    result.w = dot4( m[3], v );
    return result;
}

Она применяет матрицу трансформации к вектору. Вопрос: она для row-major, или для column-major матриц?

#39
8:11, 24 янв 2018

Wraith
> И заметь, что в статье, на которую ты ссылаешься, нигде column-major не
> упоминается.
Теперь кажется я тебя понял. col major ты рассматриваешь как сугубо лейаут матрицы в памяти. Я же в данном случае рассматриваю его как нотацию. Короче да, я опять вывернул на изнанку терминологию. Основной вопрос темы - как заставить glm поддерживать нотацию вектор-строка (потому что мне так удобнее). Так пойдет?

#40
9:14, 24 янв 2018

Wraith vs MrShoor счёт 1:0

#41
9:39, 24 янв 2018

MrShoor
Так а ты приглядись к функции в №39. И сразу найдешь ответ на свой вопрос. :)

Могу такую подсказку еще добавить:

// см. №39
void multiply( float4 q[4], float4 a[4], float4 b[4] )
{
    q[0] = transform( a[0], b );
    q[1] = transform( a[1], b );
    q[2] = transform( a[2], b );
    q[3] = transform( a[3], b );
}

А эта функция для row-major или column-major матриц?

template <typename T, precision P>
GLM_FUNC_QUALIFIER tmat4x4<T, P> translate(tmat4x4<T, P> const & m, tvec3<T, P> const & v)
{
    tmat4x4<T, P> Result(m);
    Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
    return Result;
}

А эта?


innuendo
Выйди вон уже.

#42
11:30, 24 янв 2018

Wraith
> Вопрос: она для row-major, или для column-major матриц?
Вопрос в поставленной формулировке не имеет смысла.
Встречный вопрос: как правильно написать трансформацию вектора матрицей переноса?
vec * translate(position) или translate(position) * vec?
Или, например, в чем разница между translate(position) * scale(size) и scale(size) * translate(position)?
Я понимаю, что тут есть некоторая подмена понятий.
Библиотеки с вектор-строками row-major-ные, а с вектор-столбцами - column-major-ные. Соответственно, это кореллирует с лейаутом в памяти, когда мы определяем матрицу как matrix4x4 = vector4[4].

#43
21:57, 24 янв 2018

Wraith
> А эта функция для row-major или column-major матриц?
Я думал, что мы уже определились в терменологии. Я же уже сказал, что хочу поменять нотацию glm библиотеки.
Я хочу чтобы пренос осущетсвлялся вот таким умножением:
vec * translate(position)
А в glm сейчас оно работает только так:
translate(position) * vec

#44
9:50, 25 янв 2018

-Eugene-
"Садись, двойка."

Приведенная функция работает для случая когда row-major матрицы и вектор-столбец справа, а также в случае когда column-major матрицы и вектор-строка слева.

            [ m0.x | m1.x | m2.x | m3.x ]
[x y z w] x [ m0.y | m1.y | m2.y | m3.y ] = [ v*m0, v*m1, v*m2, v*m3 ]
            [ m0.z | m1.z | m2.z | m3.z ]
            [ m0.w | m1.w | m2.w | m3.w ]

         
[ m0.x | m0.y | m0.z | m0.w ]   [x]   [v*m0]
[ m1.x | m1.y | m1.z | m1.w ] x [y] = [v*m1]
[ m2.x | m2.y | m2.z | m2.w ]   [z]   [v*m2]
[ m3.x | m3.y | m3.z | m3.w ]   [w]   [v*m3]


MrShoor
/me sighs
Ну так просто поменяй местами аргументы в operator*() для матриц и векторов...

Страницы: 1 2 3 4 5 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.