// // Created by martin on 26.03.23. // #include "SkinnedMeshResource.h" #include #include "3rdparty/json/json.hpp" inline void to_json(nlohmann::json& j, const SyncTrack& syncTrack) { j["type"] = "SyncTrack"; j["duration"] = syncTrack.m_duration; for (int i = 0; i < syncTrack.m_num_intervals; i++) { j["markers"][i] = syncTrack.m_sync_markers[i]; } } inline void from_json(const nlohmann::json& j, SyncTrack& syncTrack) { if (!j.contains("type") || j["type"] != "SyncTrack") { std::cerr << "Unable to parse SyncTrack: wrong json type!" << std::endl; return; } syncTrack.m_duration = j["duration"]; syncTrack.m_num_intervals = j["markers"].size(); if (syncTrack.m_num_intervals > cSyncTrackMaxIntervals) { std::cerr << "Invalid number of sync intervals: found " << syncTrack.m_num_intervals << " maximum is " << cSyncTrackMaxIntervals << "." << std::endl; syncTrack = SyncTrack(); } for (int i = 0; i < syncTrack.m_num_intervals; i++) { syncTrack.m_sync_markers[i] = j["markers"].at(i); } } inline void to_json(nlohmann::json& j, const SkinnedMeshResource& skinnedMeshResource) { j["type"] = "SkinnedMeshResource"; j["skeleton"]["file"] = skinnedMeshResource.m_skeleton_file; for (int i = 0; i < skinnedMeshResource.m_animation_files.size(); i++) { j["animations"][i]["file"] = skinnedMeshResource.m_animation_files[i]; j["animations"][i]["sync_track"] = skinnedMeshResource.m_sync_tracks[i]; } } inline void from_json(const nlohmann::json& j, SkinnedMeshResource& skinnedMeshResource) { if (!j.contains("type") || j["type"] != "SkinnedMeshResource") { std::cerr << "Unable to parse SkinnedMeshResource: wrong json type!" << std::endl; return; } if (!j.contains("skeleton") || !j["skeleton"].contains("file")) { std::cerr << "Unable to parse SkinnedMeshResource: no skeleton file found!" << std::endl; } skinnedMeshResource.m_skeleton_file = j["skeleton"]["file"]; if (j.contains("animations")) { int num_animations = j["animations"].size(); for (int i = 0; i < num_animations; i++) { if (!j["animations"][i].contains("file") || !j["animations"][i].contains("sync_track")) { std::cerr << "Unable to parse SkinnedMeshResource: invalid animation definition" << std::endl; return; } skinnedMeshResource.m_animation_files.push_back(j["animations"][i]["file"]); skinnedMeshResource.m_sync_tracks.push_back(j["animations"][i]["sync_track"].get()); } } } bool SkinnedMeshResource::saveToFile(const char* filename) const { nlohmann::json j = *this; std::ofstream output_file(filename); output_file << j.dump(4, ' ') << std::endl; output_file.close(); return true; } bool SkinnedMeshResource::loadFromFile(const char* filename) { if (!std::filesystem::exists(filename)) { std::cerr << "Error: file " << filename << " does not exist!" << std::endl; return false; } m_resource_file = filename; std::ifstream input_file; input_file.open(filename); std::stringstream buffer; buffer << input_file.rdbuf(); nlohmann::json j = nlohmann::json::parse(buffer.str(), nullptr, false); *this = j.get(); return true; } void SkinnedMeshResource::createInstance(SkinnedMesh& skinnedMesh) const { skinnedMesh.LoadSkeleton(m_skeleton_file.c_str()); for (int i = 0; i < m_animation_files.size(); i++) { skinnedMesh.LoadAnimation(m_animation_files[i].c_str()); skinnedMesh.m_animation_sync_track.back() = m_sync_tracks[i]; } }