25 std::ifstream f(jsonPath);
32 throw Core::CoriError(std::format(
"Failed to open json file {}", jsonPath.string()));
35 json data = json::parse(f);
37 const json& framesObject = data[
"frames"];
38 const glm::u16vec2 frameResolution = {framesObject.items().begin().value()[
"frame"][
"w"], framesObject.items().begin().value()[
"frame"][
"h"]};
40 const std::filesystem::path atlasPath = jsonPath.parent_path() / data[
"meta"][
"image"];
42 if (!image->GetSuccessStatus()) {
43 throw Core::CoriError(std::format(
"Failed to load image: {}", atlasPath.string()));
46 const glm::uvec2 initialImageResolution = { image->GetWidth(), image->GetHeight() };
49 if (!atlas->GetSuccessStatus()) {
50 throw Core::CoriError(std::format(
"Failed to load Sprite Atlas from: {}", atlasPath.string()));
53 std::vector<std::pair<uint32_t, json>> sortedFrameItems;
55 for (
const auto& [key, frameData] : framesObject.items()) {
56 int32_t frameNum = ExtractFrameNumber(key);
58 sortedFrameItems.emplace_back( frameNum, frameData );
65 std::ranges::sort(sortedFrameItems, [](
const auto& a,
const auto& b) {
66 return a.first < b.first;
69 std::vector<Internal::AnimationFrame> frames;
70 std::vector<Internal::AnimationData> animations;
71 animations.reserve(initialImageResolution.y / frameResolution.y);
74 glm::uvec2 pos{ 0.0f, 0.0f };
76 for (
const auto& [frameIndex, frameData] : sortedFrameItems) {
77 glm::u16vec2 currentFrameResolution = { frameData[
"frame"][
"w"], frameData[
"frame"][
"h"] };
78 if (frameResolution != currentFrameResolution) {
79 throw Core::CoriError(std::format(
"All animation frames should have the same resolution. Mismatch between frame '0' resolution: ({}, {}), and frame '{}' resolution: ({}, {})", frameResolution.x, frameResolution.y, frameIndex, currentFrameResolution.x, currentFrameResolution.y));
83 pos = { frameData[
"frame"][
"x"], frameData[
"frame"][
"y"] };
84 if (pos.y - oldPos.y == frameResolution.y) {
86 animations.push_back(anim);
90 uint32_t col = pos.x / frameResolution.x;
91 uint32_t row = pos.y / frameResolution.y;
95 frame.
m_UVs = atlas->GetSpriteUVsAtPosition({col, row});
96 frame.
m_TickDuration = std::round(
static_cast<float>(frameData[
"duration"]) / (timeStep * 1000.0f));
98 frames.push_back(frame);
100 if (frameIndex + 1 == sortedFrameItems.size()) {
102 animations.push_back(anim);
107 return std::shared_ptr<AnimationPack>(
new AnimationPack(animations, atlas, name, type));
109 catch (std::exception& e) {
111 return std::shared_ptr<AnimationPack>(
new AnimationPack());
118 throw Core::CoriError(std::format(
"Failed to open json file {}", jsonPath.string()));
121 json data = json::parse(f);
123 const json& meta = data[
"meta"];
124 const glm::u16vec2 frameResolution = {meta[
"frameSizeX"], meta[
"frameSizeY"]};
125 const std::string& textureFile = meta[
"textureFile"];
126 const std::filesystem::path atlasPath = jsonPath.parent_path() / textureFile;
129 if (!image->GetSuccessStatus()) {
130 throw Core::CoriError(std::format(
"Failed to load image: {}", atlasPath.string()));
134 if (!atlas->GetSuccessStatus()) {
135 throw Core::CoriError(std::format(
"Failed to load Sprite Atlas from: {}", atlasPath.string()));
138 std::vector<Internal::AnimationData> animations;
139 const json& animationsArray = data[
"animations"];
141 for (
const auto& animJson : animationsArray) {
142 std::vector<Internal::AnimationFrame> frames;
143 const json& framesArray = animJson[
"frames"];
145 for (
const auto& frameJson : framesArray) {
146 const glm::uvec2 pos = {frameJson[
"x"], frameJson[
"y"]};
148 const uint32_t col = pos.x / frameResolution.x;
149 const uint32_t row = pos.y / frameResolution.y;
152 frame.
m_UVs = atlas->GetSpriteUVsAtPosition({col, row});
153 frame.
m_TickDuration = std::round(
static_cast<float>(frameJson[
"ms"]) / (timeStep * 1000.0f));
154 frames.push_back(frame);
156 animations.emplace_back(frameResolution, frames);
160 return std::shared_ptr<AnimationPack>(
new AnimationPack(animations, atlas, name, type));
162 catch (std::exception& e) {
164 return std::shared_ptr<AnimationPack>(
new AnimationPack());
172 throw Core::CoriError(std::format(
"Failed to open json file {}", jsonPath.string()));
175 json data = json::parse(f);
177 const json& meta = data[
"meta"];
178 const std::string& textureFile = meta[
"textureFile"];
179 const std::filesystem::path atlasPath = jsonPath.parent_path() / textureFile;
182 if (!image->GetSuccessStatus()) {
183 throw Core::CoriError(std::format(
"Failed to load image: {}", atlasPath.string()));
187 glm::vec2 atlasSize = { atlas->GetWidth(), atlas->GetHeight() };
189 std::vector<Internal::AnimationData> animations;
190 const json& animationsArray = data[
"animations"];
192 for (
const auto& animJson : animationsArray) {
193 std::vector<Internal::AnimationFrame> frames;
194 const json& framesArray = animJson[
"frames"];
195 const glm::u16vec2 frameResolution = {animJson[
"frameSizeX"], animJson[
"frameSizeY"]};
197 for (
const auto& frameJson : framesArray) {
198 const glm::vec2 pos = {frameJson[
"x"], frameJson[
"y"]};
201 const glm::vec2 UVmin = pos / atlasSize;
202 const glm::vec2 UVmax = (pos + glm::vec2(frameResolution)) / atlasSize;
203 frame.
m_UVs = { UVmin, UVmax };
204 frame.
m_TickDuration = std::round(
static_cast<float>(frameJson[
"ms"]) / (timeStep * 1000.0f));
205 frames.push_back(frame);
207 animations.emplace_back(frameResolution, frames);
211 return std::shared_ptr<AnimationPack>(
new AnimationPack(animations, atlas, name, type));
213 catch (std::exception& e) {
215 return std::shared_ptr<AnimationPack>(
new AnimationPack());
219 return std::shared_ptr<AnimationPack>(
new AnimationPack());
static std::shared_ptr< Texture2D > Create(const std::shared_ptr< Image > &image)
Creates a Texture2D from the Image.