| 155 | } |
| 156 | |
| 157 | void Serializer::serializeMappingOutput(spectacularAI::mapping::MapperOutputPtr mapperOutput) { |
| 158 | std::map<std::string, nlohmann::json> jsonKeyFrames; |
| 159 | std::size_t binaryLength = 0; |
| 160 | |
| 161 | for (auto keyFrameId : mapperOutput->updatedKeyFrames) { |
| 162 | auto search = mapperOutput->map->keyFrames.find(keyFrameId); |
| 163 | if (search == mapperOutput->map->keyFrames.end()) continue; // deleted frame, skip |
| 164 | auto& frameSet = search->second->frameSet; |
| 165 | auto& pointCloud = search->second->pointCloud; |
| 166 | const spectacularAI::Camera &camera = *frameSet->primaryFrame->cameraPose.camera; |
| 167 | const Matrix4d &cameraToWorld = frameSet->primaryFrame->cameraPose.getCameraToWorldMatrix(); |
| 168 | nlohmann::json keyFrameJson; |
| 169 | keyFrameJson["id"] = std::to_string(keyFrameId); |
| 170 | keyFrameJson["frameSet"] = { |
| 171 | {"primaryFrame", { |
| 172 | {"cameraPose", { |
| 173 | {"camera", serializeCamera(camera)}, |
| 174 | {"cameraToWorld", cameraToWorld} |
| 175 | }} |
| 176 | }} |
| 177 | }; |
| 178 | std::size_t points = pointCloud->size(); |
| 179 | if (points > 0) { |
| 180 | keyFrameJson["pointCloud"] = { |
| 181 | {"size", points }, |
| 182 | {"hasNormals", pointCloud->hasNormals() }, |
| 183 | {"hasColors", pointCloud->hasColors() } |
| 184 | }; |
| 185 | binaryLength += points * sizeof(spectacularAI::Vector3f); |
| 186 | if (pointCloud->hasNormals()) binaryLength += points * sizeof(spectacularAI::Vector3f); |
| 187 | if (pointCloud->hasColors()) binaryLength += points * sizeof(std::uint8_t) * 3; |
| 188 | |
| 189 | if (serializedKeyFrameIds.find(keyFrameId) == serializedKeyFrameIds.end()) { |
| 190 | std::stringstream filename; |
| 191 | filename << folder << "/pointCloud" << keyFrameId; |
| 192 | serializedKeyFrameIds.insert(keyFrameId); |
| 193 | serializePointCloud(filename.str(), pointCloud); |
| 194 | } |
| 195 | } |
| 196 | jsonKeyFrames[keyFrameJson["id"]] = keyFrameJson; |
| 197 | } |
| 198 | |
| 199 | nlohmann::json json; |
| 200 | json["updatedKeyFrames"] = mapperOutput->updatedKeyFrames; |
| 201 | json["map"] = {{"keyFrames", jsonKeyFrames}}; |
| 202 | json["finalMap"] = mapperOutput->finalMap; |
| 203 | |
| 204 | std::string jsonStr = json.dump(); |
| 205 | uint32_t jsonLength = jsonStr.length(); |
| 206 | MessageHeader header = { |
| 207 | .magicBytes = MAGIC_BYTES, |
| 208 | .messageId = messageIdCounter, |
| 209 | .jsonSize = jsonLength, |
| 210 | .binarySize = (uint32_t)binaryLength |
| 211 | }; |
| 212 | |
| 213 | std::lock_guard<std::mutex> lock(outputMutex); |
| 214 | outputStream.write(reinterpret_cast<char*>(&header), sizeof(MessageHeader)); |
no test coverage detected