将json数组解析为QMatrix4x4

时间:2018-08-16 10:49:09

标签: json qt

我有一个像json-object这样的数组:

{
"id":"1",
 "Matrix":
 [
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12],
    [13,14,15,16]
 ]
}

有了QJsonDocumentQJsonObject我已经可以解析数组,但是如何将其转换为QMatrix4x4

数组的内容如下:

QJsonArray jsonArray = jsonObject["Matrix"].toArray();

Matrix:  QJsonArray([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])

1 个答案:

答案 0 :(得分:1)

QMatrix4x4有两个合适的构造函数:

  • QMatrix4x4(const float *values)

    要使用此构造函数,您需要将QJsonArray转换为提供C兼容浮点数组的数据结构:

    auto jsonDoc = QJsonDocument::fromJson(jsonData);
    QJsonArray jsonArr = jsonDoc.object()["Matrix"].toArray();
    std::array<float, 16> myArr;
    for (std::size_t i = 0; i < 16; i++)
      myArr[i] =
          static_cast<float>(jsonArr.at(i / 4).toArray().at(i % 4).toDouble());
    
    QMatrix4x4 mat(myArr.data());
    
  • QMatrix4x4(float m11, float m12, ...)

    要使用此构造函数,您需要将QJsonArray中的元素作为单独的参数传递给构造函数。您可以手动执行此操作,也可以利用一些模板元编程技巧来使编译器为您生成该代码:

    template <std::size_t... indexes>
    QMatrix4x4 jsonArrayToQMatrix4x4Impl(const QJsonArray &jsonArray,
                                         std::index_sequence<indexes...>) {
      return QMatrix4x4(static_cast<float>(
          jsonArray.at(indexes / 4).toArray().at(indexes % 4).toDouble())...);
    }
    
    QMatrix4x4 jsonArrayToQMatrix4x4(const QJsonArray &jsonArray) {
      return jsonArrayToQMatrix4x4Impl(jsonArray, std::make_index_sequence<16>{});
    }
    
    //usage:
    QJsonArray jsonArr = jsonDoc.object()["Matrix"].toArray();
    QMatrix4x4 mat = jsonArrayToQMatrix4x4(jsonArr);
    

如果要处理不同的QMatrix大小,则可能要使用此通用适配器:

template <typename QMatrixType, std::size_t cols, std::size_t... indexes>
QMatrixType jsonArrayToQMatrixImpl(const QJsonArray &jsonArray,
                                   std::index_sequence<indexes...> seq) {
  const std::array<float, seq.size()> array{static_cast<float>(
      jsonArray.at(indexes / cols).toArray().at(indexes % cols).toDouble())...};
  return QMatrixType(array.data());
}

template <std::size_t cols, std::size_t rows,
          typename QMatrixType = QGenericMatrix<cols, rows, float>>
QMatrixType jsonArrayToQMatrix(const QJsonArray &jsonArray) {
  return jsonArrayToQMatrixImpl<QMatrixType, cols>(
      jsonArray, std::make_index_sequence<rows * cols>{});
}

//usage:
QJsonArray jsonArr = jsonDoc.object()["Matrix"].toArray();
QMatrix4x4 mat = jsonArrayToQMatrix<4, 4, QMatrix4x4>(jsonArr);
QMatrix4x3 mat2 = jsonArrayToQMatrix<4, 3>(jsonArr);

请注意,以上示例在转换前未检查输入QJsonArray的有效大小。当QJsonArray的元素数少于要求的数量时,结果QMatrix的缺失元素应为0。