Пример #1
0
def matrix_to_quat(m):
    if not _ek.is_matrix_v(m):
        raise Exception('Unsupported type!')

    name = _ek.detail.array_name('Quaternion', m.Type, [4], m.IsScalar)
    module = _modules.get(m.__module__)
    Quat4f = getattr(module, name)

    o = 1.0
    t0 = o + m[0, 0] - m[1, 1] - m[2, 2]
    q0 = Quat4f(t0, m[1, 0] + m[0, 1], m[0, 2] + m[2, 0], m[2, 1] - m[1, 2])

    t1 = o - m[0, 0] + m[1, 1] - m[2, 2]
    q1 = Quat4f(m[1, 0] + m[0, 1], t1, m[2, 1] + m[1, 2], m[0, 2] - m[2, 0])

    t2 = o - m[0, 0] - m[1, 1] + m[2, 2]
    q2 = Quat4f(m[0, 2] + m[2, 0], m[2, 1] + m[1, 2], t2, m[1, 0] - m[0, 1])

    t3 = o + m[0, 0] + m[1, 1] + m[2, 2]
    q3 = Quat4f(m[2, 1] - m[1, 2], m[0, 2] - m[2, 0], m[1, 0] - m[0, 1], t3)

    mask0 = m[0, 0] > m[1, 1]
    t01 = _ek.select(mask0, t0, t1)
    q01 = _ek.select(mask0, q0, q1)

    mask1 = m[0, 0] < -m[1, 1]
    t23 = _ek.select(mask1, t2, t3)
    q23 = _ek.select(mask1, q2, q3)

    mask2 = m[2, 2] < 0.0
    t0123 = _ek.select(mask2, t01, t23)
    q0123 = _ek.select(mask2, q01, q23)

    return q0123 * (_ek.rsqrt(t0123) * 0.5)
Пример #2
0
def trace(a):
    if not _ek.is_matrix_v(a):
        raise Exception('Unsupported type!')
    result = a[0, 0]
    for i in range(1, a.Size):
        result += a[i, i]
    return result
Пример #3
0
def frob(a):
    if not _ek.is_matrix_v(a):
        raise Exception('Unsupported type!')

    result = _ek.sqr(a[0])
    for i in range(1, a.Size):
        value = a[i]
        result = _ek.fmadd(value, value, result)
    return _ek.hsum(result)
Пример #4
0
def transpose(a):
    if not _ek.is_matrix_v(a):
        raise Exception("Unsupported target type!")

    result = type(a)()
    for i in range(a.Size):
        for j in range(a.Size):
            result[j, i] = a[i, j]
    return result
Пример #5
0
def transform_compose(s, q, t):
    if not _ek.is_matrix_v(s) or not _ek.is_quaternion_v(q):
        raise Exception('Unsupported type!')

    name = _ek.detail.array_name('Matrix', q.Type, (4, 4), q.IsScalar)
    module = _modules.get(q.__module__)
    Matrix4f = getattr(module, name)

    result = Matrix4f(quat_to_matrix(q, 3) @ s)
    result[3] = [t[0], t[1], t[2], 1.0]

    return result
Пример #6
0
def diag(a):
    if _ek.is_matrix_v(a):
        result = a.Value()
        for i in range(a.Size):
            result[i] = a[i, i]
        return result
    elif _ek.is_static_array_v(a):
        name = _ek.detail.array_name('Matrix', a.Type, (a.Size, *a.Shape),
                                     a.IsScalar)
        module = _modules.get(a.__module__)
        cls = getattr(module, name)
        result = _ek.zero(cls)
        for i in range(a.Size):
            result[i, i] = a[i]
        return result
    else:
        raise Exception('Unsupported type!')
Пример #7
0
def transform_decompose(a, it=10):
    if not _ek.is_matrix_v(a):
        raise Exception('Unsupported type!')

    name = _ek.detail.array_name('Array', a.Type, [3], a.IsScalar)
    module = _modules.get(a.__module__)
    Array3f = getattr(module, name)

    name = _ek.detail.array_name('Matrix', a.Type, (3, 3), a.IsScalar)
    Matrix3f = getattr(module, name)

    Q, P = polar_decomp(Matrix3f(a), it)

    sign_q = det(Q)
    Q = _ek.mulsign(Q, sign_q)
    P = _ek.mulsign(P, sign_q)

    return P, matrix_to_quat(Q), Array3f(a[3][0], a[3][1], a[3][2])
Пример #8
0
def det(m):
    if not _ek.is_matrix_v(m):
        raise Exception("Unsupported target type!")

    if m.Size == 1:
        return m[0, 0]
    elif m.Size == 2:
        return _ek.fmsub(m[0, 0], m[1, 1], m[0, 1] * m[1, 0])
    elif m.Size == 3:
        return _ek.dot(m[0], _ek.cross(m[1], m[2]))
    elif m.Size == 4:
        col0, col1, col2, col3 = m

        col1 = _ek.shuffle((2, 3, 0, 1), col1)
        col3 = _ek.shuffle((2, 3, 0, 1), col3)

        temp = _ek.shuffle((1, 0, 3, 2), col2 * col3)
        row0 = col1 * temp
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fmsub(col1, temp, row0)

        temp = _ek.shuffle((1, 0, 3, 2), col1 * col2)
        row0 = _ek.fmadd(col3, temp, row0)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fnmadd(col3, temp, row0)

        col1 = _ek.shuffle((2, 3, 0, 1), col1)
        col2 = _ek.shuffle((2, 3, 0, 1), col2)
        temp = _ek.shuffle((1, 0, 3, 2), col1 * col3)
        row0 = _ek.fmadd(col2, temp, row0)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fnmadd(col2, temp, row0)

        return _ek.dot(col0, row0)
    else:
        raise Exception('Unsupported array size!')
Пример #9
0
def inverse_transpose(m):
    if not _ek.is_matrix_v(m):
        raise Exception("Unsupported target type!")

    t = type(m)
    if m.Size == 1:
        return t(_ek.rcp(m[0, 0]))
    elif m.Size == 2:
        inv_det = _ek.rcp(_ek.fmsub(m[0, 0], m[1, 1], m[0, 1] * m[1, 0]))
        return t(m[1, 1] * inv_det, -m[1, 0] * inv_det, -m[0, 1] * inv_det,
                 m[0, 0] * inv_det)
    elif m.Size == 3:
        col0, col1, col2 = m
        row0 = _ek.cross(col1, col2)
        row1 = _ek.cross(col2, col0)
        row2 = _ek.cross(col0, col1)
        inv_det = _ek.rcp(_ek.dot(col0, row0))

        return t(row0 * inv_det, row1 * inv_det, row2 * inv_det)

    elif m.Size == 4:
        col0, col1, col2, col3 = m

        col1 = _ek.shuffle((2, 3, 0, 1), col1)
        col3 = _ek.shuffle((2, 3, 0, 1), col3)

        temp = _ek.shuffle((1, 0, 3, 2), col2 * col3)
        row0 = col1 * temp
        row1 = col0 * temp
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fmsub(col1, temp, row0)
        row1 = _ek.shuffle((2, 3, 0, 1), _ek.fmsub(col0, temp, row1))

        temp = _ek.shuffle((1, 0, 3, 2), col1 * col2)
        row0 = _ek.fmadd(col3, temp, row0)
        row3 = col0 * temp
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fnmadd(col3, temp, row0)
        row3 = _ek.shuffle((2, 3, 0, 1), _ek.fmsub(col0, temp, row3))

        temp = _ek.shuffle((1, 0, 3, 2),
                           _ek.shuffle((2, 3, 0, 1), col1) * col3)
        col2 = _ek.shuffle((2, 3, 0, 1), col2)
        row0 = _ek.fmadd(col2, temp, row0)
        row2 = col0 * temp
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row0 = _ek.fnmadd(col2, temp, row0)
        row2 = _ek.shuffle((2, 3, 0, 1), _ek.fmsub(col0, temp, row2))

        temp = _ek.shuffle((1, 0, 3, 2), col0 * col1)
        row2 = _ek.fmadd(col3, temp, row2)
        row3 = _ek.fmsub(col2, temp, row3)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row2 = _ek.fmsub(col3, temp, row2)
        row3 = _ek.fnmadd(col2, temp, row3)

        temp = _ek.shuffle((1, 0, 3, 2), col0 * col3)
        row1 = _ek.fnmadd(col2, temp, row1)
        row2 = _ek.fmadd(col1, temp, row2)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row1 = _ek.fmadd(col2, temp, row1)
        row2 = _ek.fnmadd(col1, temp, row2)

        temp = _ek.shuffle((1, 0, 3, 2), col0 * col2)
        row1 = _ek.fmadd(col3, temp, row1)
        row3 = _ek.fnmadd(col1, temp, row3)
        temp = _ek.shuffle((2, 3, 0, 1), temp)
        row1 = _ek.fnmadd(col3, temp, row1)
        row3 = _ek.fmadd(col1, temp, row3)

        inv_det = _ek.rcp(_ek.dot(col0, row0))

        return t(row0 * inv_det, row1 * inv_det, row2 * inv_det,
                 row3 * inv_det)
    else:
        raise Exception('Unsupported array size!')