Предполагая, что x_idx
, y_idx
и z_idx
равны 0
, 4
и 8
, и вас не волнует вся особая обработка неконечных данных и т. Д., Вы можетеупростите внутренний цикл до следующего вида:
void foo(char* data_out, Eigen::Index N, int out_step, const Eigen::Matrix4f& T, const char* data_in, int in_step)
{
for(Eigen::Index i=0; i<N; ++i)
{
Eigen::Vector3f::Map((float*)(data_out + i*out_step)).noalias()
= (T * Eigen::Vector3f::Map((const float*)(data_in + i*in_step)).homogeneous()).head<3>();
}
}
N
будет in.width * in.height
, а out_step
и in_step
будут соответствующими point_step
членами.Незначительное возможное улучшение: вы можете скопировать T
в локальную переменную, чтобы его не нужно было каждый раз загружать из памяти.
Если point_step
кратно sizeof(float)
, вы также можете уменьшить его доодиночное назначение, используя out_stride = out.point_step / sizeof(float)
и т. д. Однако, это обычно генерирует менее эффективный код, чем версия выше (может измениться в будущих версиях Eigen).
void foo2(float* data_out, Eigen::Index N, int out_stride, const Eigen::Matrix4f& T, const float* data_in, int in_stride)
{
Eigen::Matrix3Xf::Map(data_out, 3, N, Eigen::OuterStride<>(out_stride)).noalias()
= (T *
Eigen::Matrix3Xf::Map(data_in, 3, N, Eigen::OuterStride<>(in_stride))
.colwise().homogeneous()
).topRows<3>();
}
Godbolt-Link