545 lines
16 KiB
C++
545 lines
16 KiB
C++
#pragma once
|
|
|
|
#include "diffvg.h"
|
|
#include "vector.h"
|
|
#include <iostream>
|
|
|
|
template <typename T>
|
|
struct TMatrix3x3 {
|
|
DEVICE
|
|
TMatrix3x3() {
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
data[i][j] = T(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename T2>
|
|
DEVICE
|
|
TMatrix3x3(T2 *arr) {
|
|
data[0][0] = arr[0];
|
|
data[0][1] = arr[1];
|
|
data[0][2] = arr[2];
|
|
data[1][0] = arr[3];
|
|
data[1][1] = arr[4];
|
|
data[1][2] = arr[5];
|
|
data[2][0] = arr[6];
|
|
data[2][1] = arr[7];
|
|
data[2][2] = arr[8];
|
|
}
|
|
DEVICE
|
|
TMatrix3x3(T v00, T v01, T v02,
|
|
T v10, T v11, T v12,
|
|
T v20, T v21, T v22) {
|
|
data[0][0] = v00;
|
|
data[0][1] = v01;
|
|
data[0][2] = v02;
|
|
data[1][0] = v10;
|
|
data[1][1] = v11;
|
|
data[1][2] = v12;
|
|
data[2][0] = v20;
|
|
data[2][1] = v21;
|
|
data[2][2] = v22;
|
|
}
|
|
|
|
DEVICE
|
|
const T& operator()(int i, int j) const {
|
|
return data[i][j];
|
|
}
|
|
DEVICE
|
|
T& operator()(int i, int j) {
|
|
return data[i][j];
|
|
}
|
|
DEVICE
|
|
static TMatrix3x3<T> identity() {
|
|
TMatrix3x3<T> m(1, 0, 0,
|
|
0, 1, 0,
|
|
0, 0, 1);
|
|
return m;
|
|
}
|
|
|
|
T data[3][3];
|
|
};
|
|
|
|
using Matrix3x3 = TMatrix3x3<Real>;
|
|
using Matrix3x3f = TMatrix3x3<float>;
|
|
|
|
template <typename T>
|
|
struct TMatrix4x4 {
|
|
DEVICE TMatrix4x4() {
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
data[i][j] = T(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename T2>
|
|
DEVICE TMatrix4x4(const T2 *arr) {
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
data[i][j] = (T)arr[i * 4 + j];
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename T2>
|
|
DEVICE TMatrix4x4(const TMatrix4x4<T2> &m) {
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
data[i][j] = T(m.data[i][j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename T2>
|
|
DEVICE TMatrix4x4(T2 v00, T2 v01, T2 v02, T2 v03,
|
|
T2 v10, T2 v11, T2 v12, T2 v13,
|
|
T2 v20, T2 v21, T2 v22, T2 v23,
|
|
T2 v30, T2 v31, T2 v32, T2 v33) {
|
|
data[0][0] = (T)v00;
|
|
data[0][1] = (T)v01;
|
|
data[0][2] = (T)v02;
|
|
data[0][3] = (T)v03;
|
|
data[1][0] = (T)v10;
|
|
data[1][1] = (T)v11;
|
|
data[1][2] = (T)v12;
|
|
data[1][3] = (T)v13;
|
|
data[2][0] = (T)v20;
|
|
data[2][1] = (T)v21;
|
|
data[2][2] = (T)v22;
|
|
data[2][3] = (T)v23;
|
|
data[3][0] = (T)v30;
|
|
data[3][1] = (T)v31;
|
|
data[3][2] = (T)v32;
|
|
data[3][3] = (T)v33;
|
|
}
|
|
|
|
DEVICE
|
|
const T& operator()(int i, int j) const {
|
|
return data[i][j];
|
|
}
|
|
|
|
DEVICE
|
|
T& operator()(int i, int j) {
|
|
return data[i][j];
|
|
}
|
|
|
|
DEVICE
|
|
static TMatrix4x4<T> identity() {
|
|
TMatrix4x4<T> m(1, 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1);
|
|
return m;
|
|
}
|
|
|
|
T data[4][4];
|
|
};
|
|
|
|
using Matrix4x4 = TMatrix4x4<Real>;
|
|
using Matrix4x4f = TMatrix4x4<float>;
|
|
|
|
template <typename T0, typename T1>
|
|
DEVICE
|
|
inline auto operator+(const TMatrix3x3<T0> &m0, const TMatrix3x3<T1> &m1) -> TMatrix3x3<decltype(m0(0, 0) + m1(0, 0))> {
|
|
TMatrix3x3<decltype(m0(0, 0) + m1(0, 0))> m;
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
m(i, j) = m0(i, j) + m1(i, j);
|
|
}
|
|
}
|
|
return m;
|
|
}
|
|
|
|
template <typename T0, typename T1>
|
|
DEVICE
|
|
inline auto operator-(const TMatrix3x3<T0> &m0, const TMatrix3x3<T1> &m1) -> TMatrix3x3<decltype(m0(0, 0) - m1(0, 0))> {
|
|
TMatrix3x3<decltype(m0(0, 0) - m1(0, 0))> m;
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
m(i, j) = m0(i, j) - m1(i, j);
|
|
}
|
|
}
|
|
return m;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline auto operator*(const TMatrix3x3<T> &m0, const TMatrix3x3<T> &m1) -> TMatrix3x3<T> {
|
|
TMatrix3x3<T> ret;
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
ret(i, j) = T(0);
|
|
for (int k = 0; k < 3; k++) {
|
|
ret(i, j) += m0(i, k) * m1(k, j);
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline auto operator*(const TVector3<T> &v, const TMatrix3x3<T> &m) -> TVector3<T> {
|
|
TVector3<T> ret;
|
|
for (int i = 0; i < 3; i++) {
|
|
ret[i] = T(0);
|
|
for (int j = 0; j < 3; j++) {
|
|
ret[i] += v[j] * m(j, i);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline auto operator*(const TMatrix3x3<T> &m, const TVector3<T> &v) -> TVector3<T> {
|
|
TVector3<T> ret;
|
|
for (int i = 0; i < 3; i++) {
|
|
ret[i] = 0.f;
|
|
for (int j = 0; j < 3; j++) {
|
|
ret[i] += m(i, j) * v[j];
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline auto inverse(const TMatrix3x3<T> &m) -> TMatrix3x3<T> {
|
|
// computes the inverse of a matrix m
|
|
auto det = m(0, 0) * (m(1, 1) * m(2, 2) - m(2, 1) * m(1, 2)) -
|
|
m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) +
|
|
m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0));
|
|
|
|
auto invdet = 1 / det;
|
|
|
|
auto m_inv = TMatrix3x3<T>{};
|
|
m_inv(0, 0) = (m(1, 1) * m(2, 2) - m(2, 1) * m(1, 2)) * invdet;
|
|
m_inv(0, 1) = (m(0, 2) * m(2, 1) - m(0, 1) * m(2, 2)) * invdet;
|
|
m_inv(0, 2) = (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * invdet;
|
|
m_inv(1, 0) = (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) * invdet;
|
|
m_inv(1, 1) = (m(0, 0) * m(2, 2) - m(0, 2) * m(2, 0)) * invdet;
|
|
m_inv(1, 2) = (m(1, 0) * m(0, 2) - m(0, 0) * m(1, 2)) * invdet;
|
|
m_inv(2, 0) = (m(1, 0) * m(2, 1) - m(2, 0) * m(1, 1)) * invdet;
|
|
m_inv(2, 1) = (m(2, 0) * m(0, 1) - m(0, 0) * m(2, 1)) * invdet;
|
|
m_inv(2, 2) = (m(0, 0) * m(1, 1) - m(1, 0) * m(0, 1)) * invdet;
|
|
return m_inv;
|
|
}
|
|
|
|
template <typename T0, typename T1>
|
|
DEVICE
|
|
inline auto operator+(const TMatrix4x4<T0> &m0, const TMatrix4x4<T1> &m1) -> TMatrix4x4<decltype(m0(0, 0) + m1(0, 0))> {
|
|
TMatrix4x4<decltype(m0(0, 0) + m1(0, 0))> m;
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
m(i, j) = m0(i, j) + m1(i, j);
|
|
}
|
|
}
|
|
return m;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
TMatrix3x3<T> transpose(const TMatrix3x3<T> &m) {
|
|
return TMatrix3x3<T>(m(0, 0), m(1, 0), m(2, 0),
|
|
m(0, 1), m(1, 1), m(2, 1),
|
|
m(0, 2), m(1, 2), m(2, 2));
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
TMatrix4x4<T> transpose(const TMatrix4x4<T> &m) {
|
|
return TMatrix4x4<T>(m(0, 0), m(1, 0), m(2, 0), m(3, 0),
|
|
m(0, 1), m(1, 1), m(2, 1), m(3, 1),
|
|
m(0, 2), m(1, 2), m(2, 2), m(3, 2),
|
|
m(0, 3), m(1, 3), m(2, 3), m(3, 3));
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline TMatrix3x3<T> operator-(const TMatrix3x3<T> &m0) {
|
|
TMatrix3x3<T> m;
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
m(i, j) = -m0(i, j);
|
|
}
|
|
}
|
|
return m;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline TMatrix4x4<T> operator-(const TMatrix4x4<T> &m0) {
|
|
TMatrix4x4<T> m;
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
m(i, j) = -m0(i, j);
|
|
}
|
|
}
|
|
return m;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline TMatrix4x4<T> operator-(const TMatrix4x4<T> &m0, const TMatrix4x4<T> &m1) {
|
|
TMatrix4x4<T> m;
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
m(i, j) = m0(i, j) - m1(i, j);
|
|
}
|
|
}
|
|
return m;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline TMatrix3x3<T>& operator+=(TMatrix3x3<T> &m0, const TMatrix3x3<T> &m1) {
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
m0(i, j) += m1(i, j);
|
|
}
|
|
}
|
|
return m0;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline TMatrix4x4<T>& operator+=(TMatrix4x4<T> &m0, const TMatrix4x4<T> &m1) {
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
m0(i, j) += m1(i, j);
|
|
}
|
|
}
|
|
return m0;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline TMatrix4x4<T>& operator-=(TMatrix4x4<T> &m0, const TMatrix4x4<T> &m1) {
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
m0(i, j) -= m1(i, j);
|
|
}
|
|
}
|
|
return m0;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
inline TMatrix4x4<T> operator*(const TMatrix4x4<T> &m0, const TMatrix4x4<T> &m1) {
|
|
TMatrix4x4<T> m;
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
for (int k = 0; k < 4; k++) {
|
|
m(i, j) += m0(i, k) * m1(k, j);
|
|
}
|
|
}
|
|
}
|
|
return m;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
TMatrix4x4<T> inverse(const TMatrix4x4<T> &m) {
|
|
// https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
|
|
TMatrix4x4<T> inv;
|
|
|
|
inv(0, 0) = m(1, 1) * m(2, 2) * m(3, 3) -
|
|
m(1, 1) * m(2, 3) * m(3, 2) -
|
|
m(2, 1) * m(1, 2) * m(3, 3) +
|
|
m(2, 1) * m(1, 3) * m(3, 2) +
|
|
m(3, 1) * m(1, 2) * m(2, 3) -
|
|
m(3, 1) * m(1, 3) * m(2, 2);
|
|
|
|
inv(1, 0) = -m(1, 0) * m(2, 2) * m(3, 3) +
|
|
m(1, 0) * m(2, 3) * m(3, 2) +
|
|
m(2, 0) * m(1, 2) * m(3, 3) -
|
|
m(2, 0) * m(1, 3) * m(3, 2) -
|
|
m(3, 0) * m(1, 2) * m(2, 3) +
|
|
m(3, 0) * m(1, 3) * m(2, 2);
|
|
|
|
inv(2, 0) = m(1, 0) * m(2, 1) * m(3, 3) -
|
|
m(1, 0) * m(2, 3) * m(3, 1) -
|
|
m(2, 0) * m(1, 1) * m(3, 3) +
|
|
m(2, 0) * m(1, 3) * m(3, 1) +
|
|
m(3, 0) * m(1, 1) * m(2, 3) -
|
|
m(3, 0) * m(1, 3) * m(2, 1);
|
|
|
|
inv(3, 0) = -m(1, 0) * m(2, 1) * m(3, 2) +
|
|
m(1, 0) * m(2, 2) * m(3, 1) +
|
|
m(2, 0) * m(1, 1) * m(3, 2) -
|
|
m(2, 0) * m(1, 2) * m(3, 1) -
|
|
m(3, 0) * m(1, 1) * m(2, 2) +
|
|
m(3, 0) * m(1, 2) * m(2, 1);
|
|
|
|
inv(0, 1) = -m(0, 1) * m(2, 2) * m(3, 3) +
|
|
m(0, 1) * m(2, 3) * m(3, 2) +
|
|
m(2, 1) * m(0, 2) * m(3, 3) -
|
|
m(2, 1) * m(0, 3) * m(3, 2) -
|
|
m(3, 1) * m(0, 2) * m(2, 3) +
|
|
m(3, 1) * m(0, 3) * m(2, 2);
|
|
|
|
inv(1, 1) = m(0, 0) * m(2, 2) * m(3, 3) -
|
|
m(0, 0) * m(2, 3) * m(3, 2) -
|
|
m(2, 0) * m(0, 2) * m(3, 3) +
|
|
m(2, 0) * m(0, 3) * m(3, 2) +
|
|
m(3, 0) * m(0, 2) * m(2, 3) -
|
|
m(3, 0) * m(0, 3) * m(2, 2);
|
|
|
|
inv(2, 1) = -m(0, 0) * m(2, 1) * m(3, 3) +
|
|
m(0, 0) * m(2, 3) * m(3, 1) +
|
|
m(2, 0) * m(0, 1) * m(3, 3) -
|
|
m(2, 0) * m(0, 3) * m(3, 1) -
|
|
m(3, 0) * m(0, 1) * m(2, 3) +
|
|
m(3, 0) * m(0, 3) * m(2, 1);
|
|
|
|
inv(3, 1) = m(0, 0) * m(2, 1) * m(3, 2) -
|
|
m(0, 0) * m(2, 2) * m(3, 1) -
|
|
m(2, 0) * m(0, 1) * m(3, 2) +
|
|
m(2, 0) * m(0, 2) * m(3, 1) +
|
|
m(3, 0) * m(0, 1) * m(2, 2) -
|
|
m(3, 0) * m(0, 2) * m(2, 1);
|
|
|
|
inv(0, 2) = m(0, 1) * m(1, 2) * m(3, 3) -
|
|
m(0, 1) * m(1, 3) * m(3, 2) -
|
|
m(1, 1) * m(0, 2) * m(3, 3) +
|
|
m(1, 1) * m(0, 3) * m(3, 2) +
|
|
m(3, 1) * m(0, 2) * m(1, 3) -
|
|
m(3, 1) * m(0, 3) * m(1, 2);
|
|
|
|
inv(1, 2) = -m(0, 0) * m(1, 2) * m(3, 3) +
|
|
m(0, 0) * m(1, 3) * m(3, 2) +
|
|
m(1, 0) * m(0, 2) * m(3, 3) -
|
|
m(1, 0) * m(0, 3) * m(3, 2) -
|
|
m(3, 0) * m(0, 2) * m(1, 3) +
|
|
m(3, 0) * m(0, 3) * m(1, 2);
|
|
|
|
inv(2, 2) = m(0, 0) * m(1, 1) * m(3, 3) -
|
|
m(0, 0) * m(1, 3) * m(3, 1) -
|
|
m(1, 0) * m(0, 1) * m(3, 3) +
|
|
m(1, 0) * m(0, 3) * m(3, 1) +
|
|
m(3, 0) * m(0, 1) * m(1, 3) -
|
|
m(3, 0) * m(0, 3) * m(1, 1);
|
|
|
|
inv(3, 2) = -m(0, 0) * m(1, 1) * m(3, 2) +
|
|
m(0, 0) * m(1, 2) * m(3, 1) +
|
|
m(1, 0) * m(0, 1) * m(3, 2) -
|
|
m(1, 0) * m(0, 2) * m(3, 1) -
|
|
m(3, 0) * m(0, 1) * m(1, 2) +
|
|
m(3, 0) * m(0, 2) * m(1, 1);
|
|
|
|
inv(0, 3) = -m(0, 1) * m(1, 2) * m(2, 3) +
|
|
m(0, 1) * m(1, 3) * m(2, 2) +
|
|
m(1, 1) * m(0, 2) * m(2, 3) -
|
|
m(1, 1) * m(0, 3) * m(2, 2) -
|
|
m(2, 1) * m(0, 2) * m(1, 3) +
|
|
m(2, 1) * m(0, 3) * m(1, 2);
|
|
|
|
inv(1, 3) = m(0, 0) * m(1, 2) * m(2, 3) -
|
|
m(0, 0) * m(1, 3) * m(2, 2) -
|
|
m(1, 0) * m(0, 2) * m(2, 3) +
|
|
m(1, 0) * m(0, 3) * m(2, 2) +
|
|
m(2, 0) * m(0, 2) * m(1, 3) -
|
|
m(2, 0) * m(0, 3) * m(1, 2);
|
|
|
|
inv(2, 3) = -m(0, 0) * m(1, 1) * m(2, 3) +
|
|
m(0, 0) * m(1, 3) * m(2, 1) +
|
|
m(1, 0) * m(0, 1) * m(2, 3) -
|
|
m(1, 0) * m(0, 3) * m(2, 1) -
|
|
m(2, 0) * m(0, 1) * m(1, 3) +
|
|
m(2, 0) * m(0, 3) * m(1, 1);
|
|
|
|
inv(3, 3) = m(0, 0) * m(1, 1) * m(2, 2) -
|
|
m(0, 0) * m(1, 2) * m(2, 1) -
|
|
m(1, 0) * m(0, 1) * m(2, 2) +
|
|
m(1, 0) * m(0, 2) * m(2, 1) +
|
|
m(2, 0) * m(0, 1) * m(1, 2) -
|
|
m(2, 0) * m(0, 2) * m(1, 1);
|
|
|
|
auto det = m(0, 0) * inv(0, 0) +
|
|
m(0, 1) * inv(1, 0) +
|
|
m(0, 2) * inv(2, 0) +
|
|
m(0, 3) * inv(3, 0);
|
|
|
|
if (det == 0) {
|
|
return TMatrix4x4<T>{};
|
|
}
|
|
|
|
auto inv_det = 1.0 / det;
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
inv(i, j) *= inv_det;
|
|
}
|
|
}
|
|
|
|
return inv;
|
|
}
|
|
|
|
template <typename T>
|
|
inline std::ostream& operator<<(std::ostream &os, const TMatrix3x3<T> &m) {
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
os << m(i, j) << " ";
|
|
}
|
|
os << std::endl;
|
|
}
|
|
return os;
|
|
}
|
|
|
|
template <typename T>
|
|
inline std::ostream& operator<<(std::ostream &os, const TMatrix4x4<T> &m) {
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int j = 0; j < 4; j++) {
|
|
os << m(i, j) << " ";
|
|
}
|
|
os << std::endl;
|
|
}
|
|
return os;
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
TVector2<T> xform_pt(const TMatrix3x3<T> &m, const TVector2<T> &pt) {
|
|
TVector3<T> t{m(0, 0) * pt[0] + m(0, 1) * pt[1] + m(0, 2),
|
|
m(1, 0) * pt[0] + m(1, 1) * pt[1] + m(1, 2),
|
|
m(2, 0) * pt[0] + m(2, 1) * pt[1] + m(2, 2)};
|
|
return TVector2<T>{t[0] / t[2], t[1] / t[2]};
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
void d_xform_pt(const TMatrix3x3<T> &m, const TVector2<T> &pt,
|
|
const TVector2<T> &d_out,
|
|
TMatrix3x3<T> &d_m,
|
|
TVector2<T> &d_pt) {
|
|
TVector3<T> t{m(0, 0) * pt[0] + m(0, 1) * pt[1] + m(0, 2),
|
|
m(1, 0) * pt[0] + m(1, 1) * pt[1] + m(1, 2),
|
|
m(2, 0) * pt[0] + m(2, 1) * pt[1] + m(2, 2)};
|
|
auto out = TVector2<T>{t[0] / t[2], t[1] / t[2]};
|
|
TVector3<T> d_t{d_out[0] / t[2],
|
|
d_out[1] / t[2],
|
|
-(d_out[0] * out[0] + d_out[1] * out[1]) / t[2]};
|
|
d_m(0, 0) += d_t[0] * pt[0];
|
|
d_m(0, 1) += d_t[0] * pt[1];
|
|
d_m(0, 2) += d_t[0];
|
|
d_m(1, 0) += d_t[1] * pt[0];
|
|
d_m(1, 1) += d_t[1] * pt[1];
|
|
d_m(1, 2) += d_t[1];
|
|
d_m(2, 0) += d_t[2] * pt[0];
|
|
d_m(2, 1) += d_t[2] * pt[1];
|
|
d_m(2, 2) += d_t[2];
|
|
d_pt[0] += d_t[0] * m(0, 0) + d_t[1] * m(1, 0) + d_t[2] * m(2, 0);
|
|
d_pt[1] += d_t[0] * m(0, 1) + d_t[1] * m(1, 1) + d_t[2] * m(2, 1);
|
|
}
|
|
|
|
template <typename T>
|
|
DEVICE
|
|
TVector2<T> xform_normal(const TMatrix3x3<T> &m_inv, const TVector2<T> &n) {
|
|
return normalize(TVector2<T>{m_inv(0, 0) * n[0] + m_inv(1, 0) * n[1],
|
|
m_inv(0, 1) * n[0] + m_inv(1, 1) * n[1]});
|
|
}
|