mirror of
https://github.com/enduro2d/enduro2d.git
synced 2026-01-05 01:51:02 +07:00
add nested atlas sprites and load these from flipbook
This commit is contained in:
@@ -13,18 +13,6 @@
|
||||
namespace e2d
|
||||
{
|
||||
class atlas final {
|
||||
public:
|
||||
struct region {
|
||||
str_hash name;
|
||||
v2f pivot;
|
||||
b2f texrect;
|
||||
};
|
||||
|
||||
struct shape_region {
|
||||
str_hash name;
|
||||
v2f pivot;
|
||||
vector<v2f> points;
|
||||
};
|
||||
public:
|
||||
atlas();
|
||||
~atlas() noexcept;
|
||||
@@ -43,31 +31,11 @@ namespace e2d
|
||||
|
||||
atlas& set_texture(const texture_asset::ptr& texture) noexcept;
|
||||
const texture_asset::ptr& texture() const noexcept;
|
||||
|
||||
atlas& set_regions(vector<region>&& regions) noexcept;
|
||||
atlas& set_regions(const vector<region>& regions);
|
||||
const vector<region>& regions() const noexcept;
|
||||
const region* find_region(str_hash name) const noexcept;
|
||||
|
||||
atlas& set_shape_regions(vector<shape_region>&& regions) noexcept;
|
||||
atlas& set_shape_regions(const vector<shape_region>& regions);
|
||||
const vector<shape_region>& shape_regions() const noexcept;
|
||||
const shape_region* find_shape_region(str_hash name) const noexcept;
|
||||
private:
|
||||
texture_asset::ptr texture_;
|
||||
vector<region> regions_;
|
||||
vector<shape_region> shape_regions_;
|
||||
};
|
||||
|
||||
void swap(atlas& l, atlas& r) noexcept;
|
||||
bool operator==(const atlas& l, const atlas& r) noexcept;
|
||||
bool operator!=(const atlas& l, const atlas& r) noexcept;
|
||||
|
||||
void swap(atlas::region& l, atlas::region& r) noexcept;
|
||||
bool operator==(const atlas::region& l, const atlas::region& r) noexcept;
|
||||
bool operator!=(const atlas::region& l, const atlas::region& r) noexcept;
|
||||
|
||||
void swap(atlas::shape_region& l, atlas::shape_region& r) noexcept;
|
||||
bool operator==(const atlas::shape_region& l, const atlas::shape_region& r) noexcept;
|
||||
bool operator!=(const atlas::shape_region& l, const atlas::shape_region& r) noexcept;
|
||||
}
|
||||
|
||||
@@ -8,16 +8,14 @@
|
||||
|
||||
#include "_high.hpp"
|
||||
|
||||
#include "assets/texture_asset.hpp"
|
||||
#include "assets/sprite_asset.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
class flipbook final {
|
||||
public:
|
||||
struct frame {
|
||||
v2f pivot;
|
||||
b2f texrect;
|
||||
texture_asset::ptr texture;
|
||||
sprite_asset::ptr sprite;
|
||||
};
|
||||
|
||||
struct sequence {
|
||||
@@ -43,11 +41,13 @@ namespace e2d
|
||||
|
||||
flipbook& set_frames(vector<frame>&& frames) noexcept;
|
||||
flipbook& set_frames(const vector<frame>& frames);
|
||||
|
||||
const vector<frame>& frames() const noexcept;
|
||||
const frame* find_frame(std::size_t index) const noexcept;
|
||||
|
||||
flipbook& set_sequences(vector<sequence>&& sequences) noexcept;
|
||||
flipbook& set_sequences(const vector<sequence>& sequences);
|
||||
|
||||
const vector<sequence>& sequences() const noexcept;
|
||||
const sequence* find_sequence(str_hash name) const noexcept;
|
||||
private:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"atlas" : {
|
||||
"atlas" : "ships_atlas.json",
|
||||
"region" : "ship (2).png"
|
||||
}
|
||||
"texture" : "ships.png",
|
||||
"pivot" : { "x" : 441, "y" : 340 },
|
||||
"texrect" : { "x" : 408, "y" : 284, "w" : 66, "h" : 113 }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"texture" : "ships.png",
|
||||
"regions" : [{
|
||||
"sprites" : [{
|
||||
"name" : "ship (1).png",
|
||||
"pivot" : { "x" : 441, "y" : 455 },
|
||||
"texrect" : { "x" : 408, "y" : 399, "w" : 66, "h" : 113 }
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <enduro2d/high/assets/atlas_asset.hpp>
|
||||
|
||||
#include "json_asset.hpp"
|
||||
#include <enduro2d/high/assets/sprite_asset.cpp>
|
||||
#include <enduro2d/high/assets/texture_asset.cpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -25,15 +27,14 @@ namespace
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"texture" : { "$ref": "#/common_definitions/address" },
|
||||
"regions" : { "$ref": "#/definitions/regions" },
|
||||
"shape_regions" : { "$ref": "#/definitions/shape_regions" }
|
||||
"sprites" : { "$ref": "#/definitions/sprites" }
|
||||
},
|
||||
"definitions" : {
|
||||
"regions" : {
|
||||
"sprites" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/region" }
|
||||
"items" : { "$ref": "#/definitions/sprite" }
|
||||
},
|
||||
"region" : {
|
||||
"sprite" : {
|
||||
"type" : "object",
|
||||
"required" : [ "name", "pivot", "texrect" ],
|
||||
"additionalProperties" : false,
|
||||
@@ -42,24 +43,6 @@ namespace
|
||||
"pivot" : { "$ref": "#/common_definitions/v2" },
|
||||
"texrect" : { "$ref": "#/common_definitions/b2" }
|
||||
}
|
||||
},
|
||||
"shape_regions" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/shape_region" }
|
||||
},
|
||||
"shape_region" : {
|
||||
"type" : "object",
|
||||
"required" : [ "name", "pivot", "points" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"name" : { "$ref": "#/common_definitions/name" },
|
||||
"pivot" : { "$ref": "#/common_definitions/v2" },
|
||||
"points" : {
|
||||
"type" : "array",
|
||||
"minItems" : 3,
|
||||
"items" : { "$ref": "#/common_definitions/v2" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})json";
|
||||
@@ -82,69 +65,45 @@ namespace
|
||||
return *schema;
|
||||
}
|
||||
|
||||
bool parse_regions(
|
||||
struct sprite_desc {
|
||||
str_hash name;
|
||||
v2f pivot;
|
||||
b2f texrect;
|
||||
};
|
||||
|
||||
bool parse_sprites(
|
||||
const rapidjson::Value& root,
|
||||
vector<atlas::region>& regions)
|
||||
vector<sprite_desc>& sprite_descs)
|
||||
{
|
||||
E2D_ASSERT(root.IsArray());
|
||||
vector<atlas::region> tregions(root.Size());
|
||||
vector<sprite_desc> tsprite_descs(root.Size());
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < root.Size(); ++i ) {
|
||||
E2D_ASSERT(root[i].IsObject());
|
||||
const auto& region_json = root[i];
|
||||
const auto& sprite_json = root[i];
|
||||
|
||||
E2D_ASSERT(region_json.HasMember("name"));
|
||||
if ( !json_utils::try_parse_value(region_json["name"], tregions[i].name) ) {
|
||||
E2D_ASSERT(sprite_json.HasMember("name"));
|
||||
if ( !json_utils::try_parse_value(sprite_json["name"], tsprite_descs[i].name) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
E2D_ASSERT(region_json.HasMember("pivot"));
|
||||
if ( !json_utils::try_parse_value(region_json["pivot"], tregions[i].pivot) ) {
|
||||
E2D_ASSERT(sprite_json.HasMember("pivot"));
|
||||
if ( !json_utils::try_parse_value(sprite_json["pivot"], tsprite_descs[i].pivot) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
E2D_ASSERT(region_json.HasMember("texrect"));
|
||||
if ( !json_utils::try_parse_value(region_json["texrect"], tregions[i].texrect) ) {
|
||||
E2D_ASSERT(sprite_json.HasMember("texrect"));
|
||||
if ( !json_utils::try_parse_value(sprite_json["texrect"], tsprite_descs[i].texrect) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
regions = std::move(tregions);
|
||||
sprite_descs = std::move(tsprite_descs);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_shape_regions(
|
||||
const rapidjson::Value& root,
|
||||
vector<atlas::shape_region>& regions)
|
||||
{
|
||||
E2D_ASSERT(root.IsArray());
|
||||
vector<atlas::shape_region> tregions(root.Size());
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < root.Size(); ++i ) {
|
||||
E2D_ASSERT(root[i].IsObject());
|
||||
const auto& region_json = root[i];
|
||||
|
||||
E2D_ASSERT(region_json.HasMember("name"));
|
||||
if ( !json_utils::try_parse_value(region_json["name"], tregions[i].name) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
E2D_ASSERT(region_json.HasMember("pivot"));
|
||||
if ( !json_utils::try_parse_value(region_json["pivot"], tregions[i].pivot) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
E2D_ASSERT(region_json.HasMember("points"));
|
||||
if ( !json_utils::try_parse_values(region_json["points"], tregions[i].points) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
regions = std::move(tregions);
|
||||
return true;
|
||||
}
|
||||
|
||||
stdex::promise<atlas> parse_atlas(
|
||||
using parse_atlas_result = std::tuple<atlas, nested_content>;
|
||||
stdex::promise<parse_atlas_result> parse_atlas(
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
@@ -153,33 +112,31 @@ namespace
|
||||
auto texture_p = library.load_asset_async<texture_asset>(
|
||||
path::combine(parent_address, root["texture"].GetString()));
|
||||
|
||||
vector<atlas::region> regions;
|
||||
if ( root.HasMember("regions") ) {
|
||||
const auto& regions_json = root["regions"];
|
||||
if ( !parse_regions(regions_json, regions) ) {
|
||||
return stdex::make_rejected_promise<atlas>(
|
||||
atlas_asset_loading_exception());
|
||||
}
|
||||
}
|
||||
|
||||
vector<atlas::shape_region> shape_regions;
|
||||
if ( root.HasMember("shape_regions") ) {
|
||||
const auto& shape_regions_json = root["shape_regions"];
|
||||
if ( !parse_shape_regions(shape_regions_json, shape_regions) ) {
|
||||
return stdex::make_rejected_promise<atlas>(
|
||||
vector<sprite_desc> sprite_descs;
|
||||
if ( root.HasMember("sprites") ) {
|
||||
const auto& sprites_json = root["sprites"];
|
||||
if ( !parse_sprites(sprites_json, sprite_descs) ) {
|
||||
return stdex::make_rejected_promise<parse_atlas_result>(
|
||||
atlas_asset_loading_exception());
|
||||
}
|
||||
}
|
||||
|
||||
return texture_p.then([
|
||||
regions = std::move(regions),
|
||||
shape_regions = std::move(shape_regions)
|
||||
sprite_descs = std::move(sprite_descs)
|
||||
](const texture_asset::load_result& texture) mutable {
|
||||
atlas content;
|
||||
content.set_texture(texture);
|
||||
content.set_regions(std::move(regions));
|
||||
content.set_shape_regions(std::move(shape_regions));
|
||||
return content;
|
||||
|
||||
nested_content ncontent;
|
||||
for ( const sprite_desc& desc : sprite_descs ) {
|
||||
sprite spr;
|
||||
spr.set_pivot(desc.pivot);
|
||||
spr.set_texrect(desc.texrect);
|
||||
spr.set_texture(texture);
|
||||
ncontent.insert(std::make_pair(desc.name, sprite_asset::create(std::move(spr))));
|
||||
}
|
||||
|
||||
return std::make_tuple(std::move(content), std::move(ncontent));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -205,9 +162,10 @@ namespace e2d
|
||||
return parse_atlas(
|
||||
library, parent_address, atlas_data->content());
|
||||
})
|
||||
.then([](auto&& content){
|
||||
.then([](const parse_atlas_result& result){
|
||||
return atlas_asset::create(
|
||||
std::forward<decltype(content)>(content));
|
||||
std::get<0>(result),
|
||||
std::get<1>(result));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "json_asset.hpp"
|
||||
#include <enduro2d/high/assets/atlas_asset.hpp>
|
||||
#include <enduro2d/high/assets/sprite_asset.cpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -38,35 +39,16 @@ namespace
|
||||
"required" : [ "atlas" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"atlas" : { "$ref": "#/definitions/atlas_frame" }
|
||||
"atlas" : { "$ref": "#/common_definitions/address" }
|
||||
}
|
||||
}, {
|
||||
"required" : [ "texture" ],
|
||||
"required" : [ "sprite" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"texture" : { "$ref": "#/definitions/texture_frame" }
|
||||
"sprite" : { "$ref": "#/common_definitions/address" }
|
||||
}
|
||||
}]
|
||||
},
|
||||
"atlas_frame" : {
|
||||
"type" : "object",
|
||||
"required" : [ "atlas", "region" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"atlas" : { "$ref": "#/common_definitions/address" },
|
||||
"region" : { "$ref": "#/common_definitions/name" }
|
||||
}
|
||||
},
|
||||
"texture_frame" : {
|
||||
"type" : "object",
|
||||
"required" : [ "texture", "pivot", "texrect" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"texture" : { "$ref": "#/common_definitions/address" },
|
||||
"pivot" : { "$ref": "#/common_definitions/v2" },
|
||||
"texrect" : { "$ref": "#/common_definitions/b2" }
|
||||
}
|
||||
},
|
||||
"sequences" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/sequence" }
|
||||
@@ -105,84 +87,31 @@ namespace
|
||||
return *schema;
|
||||
}
|
||||
|
||||
stdex::promise<flipbook::frame> parse_flipbook_atlas_frame(
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
E2D_ASSERT(root.HasMember("atlas") && root["atlas"].IsString());
|
||||
auto atlas_p = library.load_asset_async<atlas_asset>(
|
||||
path::combine(parent_address, root["atlas"].GetString()));
|
||||
|
||||
str_hash region_hash;
|
||||
if ( !json_utils::try_parse_value(root["region"], region_hash) ) {
|
||||
return stdex::make_rejected_promise<flipbook::frame>(
|
||||
flipbook_asset_loading_exception());
|
||||
}
|
||||
|
||||
return atlas_p.then([region_hash](const atlas_asset::load_result& atlas){
|
||||
const texture_asset::ptr& texture = atlas->content().texture();
|
||||
const atlas::region* region = atlas->content().find_region(region_hash);
|
||||
|
||||
if ( !texture || !region ) {
|
||||
throw flipbook_asset_loading_exception();
|
||||
}
|
||||
|
||||
flipbook::frame content;
|
||||
content.pivot = region->pivot;
|
||||
content.texrect = region->texrect;
|
||||
content.texture = texture;
|
||||
return content;
|
||||
});
|
||||
}
|
||||
|
||||
stdex::promise<flipbook::frame> parse_flipbook_texture_frame(
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
E2D_ASSERT(root.IsObject());
|
||||
|
||||
E2D_ASSERT(root.HasMember("texture") && root["texture"].IsString());
|
||||
auto texture_p = library.load_asset_async<texture_asset>(
|
||||
path::combine(parent_address, root["texture"].GetString()));
|
||||
|
||||
v2f pivot;
|
||||
E2D_ASSERT(root.HasMember("pivot"));
|
||||
if ( !json_utils::try_parse_value(root["pivot"], pivot) ) {
|
||||
return stdex::make_rejected_promise<flipbook::frame>(
|
||||
flipbook_asset_loading_exception());
|
||||
}
|
||||
|
||||
b2f texrect;
|
||||
E2D_ASSERT(root.HasMember("texrect"));
|
||||
if ( !json_utils::try_parse_value(root["texrect"], texrect) ) {
|
||||
return stdex::make_rejected_promise<flipbook::frame>(
|
||||
flipbook_asset_loading_exception());
|
||||
}
|
||||
|
||||
return texture_p.then([pivot, texrect](const texture_asset::load_result& texture){
|
||||
flipbook::frame content;
|
||||
content.pivot = pivot;
|
||||
content.texrect = texrect;
|
||||
content.texture = texture;
|
||||
return content;
|
||||
});
|
||||
}
|
||||
|
||||
stdex::promise<flipbook::frame> parse_flipbook_frame(
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
if ( root.HasMember("atlas") ) {
|
||||
return parse_flipbook_atlas_frame(library, parent_address, root["atlas"]);
|
||||
E2D_ASSERT(root["atlas"].IsString());
|
||||
return library.load_asset_async<atlas_asset, sprite_asset>(
|
||||
path::combine(parent_address, root["atlas"].GetString()))
|
||||
.then([](const sprite_asset::load_result& sprite){
|
||||
flipbook::frame frame;
|
||||
frame.sprite = sprite;
|
||||
return frame;
|
||||
});
|
||||
}
|
||||
|
||||
if ( root.HasMember("texture") ) {
|
||||
return parse_flipbook_texture_frame(library, parent_address, root["texture"]);
|
||||
if ( root.HasMember("sprite") ) {
|
||||
E2D_ASSERT(root["sprite"].IsString());
|
||||
return library.load_asset_async<sprite_asset>(
|
||||
path::combine(parent_address, root["sprite"].GetString()))
|
||||
.then([](const sprite_asset::load_result& sprite){
|
||||
flipbook::frame frame;
|
||||
frame.sprite = sprite;
|
||||
return frame;
|
||||
});
|
||||
}
|
||||
|
||||
return stdex::make_rejected_promise<flipbook::frame>(
|
||||
@@ -198,8 +127,8 @@ namespace
|
||||
vector<stdex::promise<flipbook::frame>> frames_p;
|
||||
frames_p.reserve(root.Size());
|
||||
for ( rapidjson::SizeType i = 0; i < root.Size(); ++i ) {
|
||||
auto frame_p = parse_flipbook_frame(library, parent_address, root[i]);
|
||||
frames_p.push_back(frame_p);
|
||||
frames_p.push_back(
|
||||
parse_flipbook_frame(library, parent_address, root[i]));
|
||||
}
|
||||
return stdex::make_all_promise(frames_p);
|
||||
}
|
||||
@@ -237,7 +166,7 @@ namespace
|
||||
sequence.fps = fps;
|
||||
sequence.name = name_hash;
|
||||
sequence.frames = std::move(frames);
|
||||
sequences.push_back(sequence);
|
||||
sequences.push_back(std::move(sequence));
|
||||
}
|
||||
|
||||
return stdex::make_resolved_promise(sequences);
|
||||
@@ -263,12 +192,9 @@ namespace
|
||||
vector<flipbook::frame>,
|
||||
vector<flipbook::sequence>
|
||||
>& results){
|
||||
const vector<flipbook::frame>& frames = std::get<0>(results);
|
||||
const vector<flipbook::sequence>& sequences = std::get<1>(results);
|
||||
|
||||
flipbook content;
|
||||
content.set_frames(frames);
|
||||
content.set_sequences(sequences);
|
||||
content.set_frames(std::get<0>(results));
|
||||
content.set_sequences(std::get<1>(results));
|
||||
return content;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "json_asset.hpp"
|
||||
#include <enduro2d/high/assets/atlas_asset.hpp>
|
||||
#include <enduro2d/high/assets/texture_asset.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -21,39 +22,12 @@ namespace
|
||||
|
||||
const char* sprite_asset_schema_source = R"json({
|
||||
"type" : "object",
|
||||
"oneOf" : [{
|
||||
"required" : [ "atlas" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"atlas" : { "$ref": "#/definitions/atlas" }
|
||||
}
|
||||
}, {
|
||||
"required" : [ "texture" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"texture" : { "$ref": "#/definitions/texture" }
|
||||
}
|
||||
}],
|
||||
"definitions" : {
|
||||
"atlas" : {
|
||||
"type" : "object",
|
||||
"required" : [ "atlas", "region" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"atlas" : { "$ref": "#/common_definitions/address" },
|
||||
"region" : { "$ref": "#/common_definitions/name" }
|
||||
}
|
||||
},
|
||||
"texture" : {
|
||||
"type" : "object",
|
||||
"required" : [ "texture", "pivot", "texrect" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"texture" : { "$ref": "#/common_definitions/address" },
|
||||
"pivot" : { "$ref": "#/common_definitions/v2" },
|
||||
"texrect" : { "$ref": "#/common_definitions/b2" }
|
||||
}
|
||||
}
|
||||
"required" : [ "texture", "pivot", "texrect" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"texture" : { "$ref": "#/common_definitions/address" },
|
||||
"pivot" : { "$ref": "#/common_definitions/v2" },
|
||||
"texrect" : { "$ref": "#/common_definitions/b2" }
|
||||
}
|
||||
})json";
|
||||
|
||||
@@ -75,64 +49,25 @@ namespace
|
||||
return *schema;
|
||||
}
|
||||
|
||||
stdex::promise<sprite> parse_sprite_with_atlas(
|
||||
stdex::promise<sprite> parse_sprite(
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
E2D_ASSERT(root.HasMember("atlas") && root["atlas"].IsObject());
|
||||
const auto& atlas_root_json = root["atlas"];
|
||||
|
||||
E2D_ASSERT(atlas_root_json.HasMember("atlas") && atlas_root_json["atlas"].IsString());
|
||||
auto atlas_p = library.load_asset_async<atlas_asset>(
|
||||
path::combine(parent_address, atlas_root_json["atlas"].GetString()));
|
||||
|
||||
str_hash region_hash;
|
||||
if ( !json_utils::try_parse_value(atlas_root_json["region"], region_hash) ) {
|
||||
return stdex::make_rejected_promise<sprite>(
|
||||
sprite_asset_loading_exception());
|
||||
}
|
||||
|
||||
return atlas_p.then([
|
||||
region_hash
|
||||
](const atlas_asset::load_result& atlas){
|
||||
const texture_asset::ptr& texture = atlas->content().texture();
|
||||
const atlas::region* region = atlas->content().find_region(region_hash);
|
||||
|
||||
if ( !texture || !region ) {
|
||||
throw sprite_asset_loading_exception();
|
||||
}
|
||||
|
||||
sprite content;
|
||||
content.set_pivot(region->pivot);
|
||||
content.set_texrect(region->texrect);
|
||||
content.set_texture(texture);
|
||||
return content;
|
||||
});
|
||||
}
|
||||
|
||||
stdex::promise<sprite> parse_sprite_with_texture(
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
E2D_ASSERT(root.HasMember("texture") && root["texture"].IsObject());
|
||||
const auto& texture_root_json = root["texture"];
|
||||
|
||||
E2D_ASSERT(texture_root_json.HasMember("texture") && texture_root_json["texture"].IsString());
|
||||
E2D_ASSERT(root.HasMember("texture") && root["texture"].IsString());
|
||||
auto texture_p = library.load_asset_async<texture_asset>(
|
||||
path::combine(parent_address, texture_root_json["texture"].GetString()));
|
||||
path::combine(parent_address, root["texture"].GetString()));
|
||||
|
||||
v2f pivot;
|
||||
E2D_ASSERT(texture_root_json.HasMember("pivot"));
|
||||
if ( !json_utils::try_parse_value(texture_root_json["pivot"], pivot) ) {
|
||||
E2D_ASSERT(root.HasMember("pivot"));
|
||||
if ( !json_utils::try_parse_value(root["pivot"], pivot) ) {
|
||||
return stdex::make_rejected_promise<sprite>(
|
||||
sprite_asset_loading_exception());
|
||||
}
|
||||
|
||||
b2f texrect;
|
||||
E2D_ASSERT(texture_root_json.HasMember("texrect"));
|
||||
if ( !json_utils::try_parse_value(texture_root_json["texrect"], texrect) ) {
|
||||
E2D_ASSERT(root.HasMember("texrect"));
|
||||
if ( !json_utils::try_parse_value(root["texrect"], texrect) ) {
|
||||
return stdex::make_rejected_promise<sprite>(
|
||||
sprite_asset_loading_exception());
|
||||
}
|
||||
@@ -148,23 +83,6 @@ namespace
|
||||
return content;
|
||||
});
|
||||
}
|
||||
|
||||
stdex::promise<sprite> parse_sprite(
|
||||
const library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
if ( root.HasMember("atlas") ) {
|
||||
return parse_sprite_with_atlas(library, parent_address, root);
|
||||
}
|
||||
|
||||
if ( root.HasMember("texture") ) {
|
||||
return parse_sprite_with_texture(library, parent_address, root);
|
||||
}
|
||||
|
||||
return stdex::make_rejected_promise<sprite>(
|
||||
sprite_asset_loading_exception());
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
|
||||
@@ -29,15 +29,11 @@ namespace e2d
|
||||
|
||||
void atlas::clear() noexcept {
|
||||
texture_.reset();
|
||||
regions_.clear();
|
||||
shape_regions_.clear();
|
||||
}
|
||||
|
||||
void atlas::swap(atlas& other) noexcept {
|
||||
using std::swap;
|
||||
swap(texture_, other.texture_);
|
||||
swap(regions_, other.regions_);
|
||||
swap(shape_regions_, other.shape_regions_);
|
||||
}
|
||||
|
||||
atlas& atlas::assign(atlas&& other) noexcept {
|
||||
@@ -52,8 +48,6 @@ namespace e2d
|
||||
if ( this != &other ) {
|
||||
atlas s;
|
||||
s.texture_ = other.texture_;
|
||||
s.regions_ = other.regions_;
|
||||
s.shape_regions_ = other.shape_regions_;
|
||||
swap(s);
|
||||
}
|
||||
return *this;
|
||||
@@ -67,64 +61,6 @@ namespace e2d
|
||||
const texture_asset::ptr& atlas::texture() const noexcept {
|
||||
return texture_;
|
||||
}
|
||||
|
||||
atlas& atlas::set_regions(vector<region>&& regions) noexcept {
|
||||
regions_ = std::move(regions);
|
||||
std::sort(
|
||||
regions_.begin(), regions_.end(),
|
||||
[](const atlas::region& l, const atlas::region& r) noexcept {
|
||||
return l.name < r.name;
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
|
||||
atlas& atlas::set_regions(const vector<region>& regions) {
|
||||
return set_regions(vector<region>(regions));
|
||||
}
|
||||
|
||||
const vector<atlas::region>& atlas::regions() const noexcept {
|
||||
return regions_;
|
||||
}
|
||||
|
||||
const atlas::region* atlas::find_region(str_hash name) const noexcept {
|
||||
const auto iter = std::lower_bound(
|
||||
regions_.begin(), regions_.end(), name,
|
||||
[](const atlas::region& l, str_hash r) noexcept {
|
||||
return l.name < r;
|
||||
});
|
||||
return iter != regions_.end() && iter->name == name
|
||||
? &*iter
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
atlas& atlas::set_shape_regions(vector<shape_region>&& regions) noexcept {
|
||||
shape_regions_ = std::move(regions);
|
||||
std::sort(
|
||||
shape_regions_.begin(), shape_regions_.end(),
|
||||
[](const atlas::shape_region& l, const atlas::shape_region& r) noexcept {
|
||||
return l.name < r.name;
|
||||
});
|
||||
return *this;
|
||||
}
|
||||
|
||||
atlas& atlas::set_shape_regions(const vector<shape_region>& regions) {
|
||||
return set_shape_regions(vector<shape_region>(regions));
|
||||
}
|
||||
|
||||
const vector<atlas::shape_region>& atlas::shape_regions() const noexcept {
|
||||
return shape_regions_;
|
||||
}
|
||||
|
||||
const atlas::shape_region* atlas::find_shape_region(str_hash name) const noexcept {
|
||||
const auto iter = std::lower_bound(
|
||||
shape_regions_.begin(), shape_regions_.end(), name,
|
||||
[](const atlas::shape_region& l, str_hash r) noexcept {
|
||||
return l.name < r;
|
||||
});
|
||||
return iter != shape_regions_.end() && iter->name == name
|
||||
? &*iter
|
||||
: nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
@@ -134,46 +70,10 @@ namespace e2d
|
||||
}
|
||||
|
||||
bool operator==(const atlas& l, const atlas& r) noexcept {
|
||||
return l.texture() == r.texture()
|
||||
&& l.regions() == r.regions()
|
||||
&& l.shape_regions() == r.shape_regions();
|
||||
return l.texture() == r.texture();
|
||||
}
|
||||
|
||||
bool operator!=(const atlas& l, const atlas& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
void swap(atlas::region& l, atlas::region& r) noexcept {
|
||||
using std::swap;
|
||||
swap(l.name, r.name);
|
||||
swap(l.pivot, r.pivot);
|
||||
swap(l.texrect, r.texrect);
|
||||
}
|
||||
|
||||
bool operator==(const atlas::region& l, const atlas::region& r) noexcept {
|
||||
return l.name == r.name
|
||||
&& l.pivot == r.pivot
|
||||
&& l.texrect == r.texrect;
|
||||
}
|
||||
|
||||
bool operator!=(const atlas::region& l, const atlas::region& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
void swap(atlas::shape_region& l, atlas::shape_region& r) noexcept {
|
||||
using std::swap;
|
||||
swap(l.name, r.name);
|
||||
swap(l.pivot, r.pivot);
|
||||
swap(l.points, r.points);
|
||||
}
|
||||
|
||||
bool operator==(const atlas::shape_region& l, const atlas::shape_region& r) noexcept {
|
||||
return l.name == r.name
|
||||
&& l.pivot == r.pivot
|
||||
&& l.points == r.points;
|
||||
}
|
||||
|
||||
bool operator!=(const atlas::shape_region& l, const atlas::shape_region& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,15 +128,11 @@ namespace e2d
|
||||
|
||||
void swap(flipbook::frame& l, flipbook::frame& r) noexcept {
|
||||
using std::swap;
|
||||
swap(l.pivot, r.pivot);
|
||||
swap(l.texrect, r.texrect);
|
||||
swap(l.texture, r.texture);
|
||||
swap(l.sprite, r.sprite);
|
||||
}
|
||||
|
||||
bool operator==(const flipbook::frame& l, const flipbook::frame& r) noexcept {
|
||||
return l.pivot == r.pivot
|
||||
&& l.texrect == r.texrect
|
||||
&& l.texture == r.texture;
|
||||
return l.sprite == r.sprite;
|
||||
}
|
||||
|
||||
bool operator!=(const flipbook::frame& l, const flipbook::frame& r) noexcept {
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
{
|
||||
"texture" : "image.png",
|
||||
"regions" : [{
|
||||
"sprites" : [{
|
||||
"name" : "sprite",
|
||||
"pivot" : { "x" : 1, "y" : 2 },
|
||||
"texrect" : { "x" : 5, "y" : 6, "w" : 7, "h" : 8 }
|
||||
}],
|
||||
"shape_regions" : [{
|
||||
"name" : "shape_sprite",
|
||||
"pivot" : { "x" : 3, "y" : 4 },
|
||||
"points" : [
|
||||
{ "x" : 1, "y" : 2 },
|
||||
{ "x" : 3, "y" : 4 },
|
||||
{ "x" : 5, "y" : 6 }]
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
{
|
||||
"frames" : [{
|
||||
"atlas" : {
|
||||
"atlas" : "atlas.json",
|
||||
"region" : "sprite"
|
||||
}
|
||||
}, {
|
||||
"texture" : {
|
||||
"texture" : "image.png",
|
||||
"pivot" : { "x" : 1, "y" : 2 },
|
||||
"texrect" : { "x" : 5, "y" : 6, "w" : 7, "h" : 8 }
|
||||
}
|
||||
}],
|
||||
"frames" : [
|
||||
{ "atlas" : "atlas.json:/sprite" },
|
||||
{ "sprite" : "sprite.json" }
|
||||
],
|
||||
"sequences" : [{
|
||||
"fps" : 24,
|
||||
"name" : "sequence_0",
|
||||
|
||||
5
untests/bin/library/sprite.json
Normal file
5
untests/bin/library/sprite.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"texture" : "image.png",
|
||||
"pivot" : { "x" : 1, "y" : 2 },
|
||||
"texrect" : { "x" : 5, "y" : 6, "w" : 7, "h" : 8 }
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"atlas" : {
|
||||
"atlas" : "atlas.json",
|
||||
"region" : "sprite"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"texture" : {
|
||||
"texture" : "image.png",
|
||||
"pivot" : { "x" : 1, "y" : 2 },
|
||||
"texrect" : { "x" : 5, "y" : 6, "w" : 7, "h" : 8 }
|
||||
}
|
||||
}
|
||||
@@ -104,39 +104,18 @@ TEST_CASE("library"){
|
||||
REQUIRE(atlas_res);
|
||||
|
||||
REQUIRE(atlas_res->content().texture() == texture_res);
|
||||
REQUIRE(atlas_res->content().regions().size() == 1);
|
||||
REQUIRE(atlas_res->content().shape_regions().size() == 1);
|
||||
|
||||
const atlas::region* region = atlas_res->content().find_region("sprite");
|
||||
REQUIRE(region);
|
||||
REQUIRE(region->name == make_hash("sprite"));
|
||||
REQUIRE(region->pivot == v2f(1.f,2.f));
|
||||
REQUIRE(region->texrect == b2f(5.f,6.f,7.f,8.f));
|
||||
REQUIRE(atlas_res->find_nested_asset("sprite"));
|
||||
|
||||
const atlas::shape_region* shape_region = atlas_res->content().find_shape_region("shape_sprite");
|
||||
REQUIRE(shape_region);
|
||||
REQUIRE(shape_region->name == make_hash("shape_sprite"));
|
||||
REQUIRE(shape_region->pivot == v2f(3.f,4.f));
|
||||
REQUIRE(shape_region->points == vector<v2f>{
|
||||
{1.f, 2.f},
|
||||
{3.f, 4.f},
|
||||
{5.f, 6.f}
|
||||
});
|
||||
|
||||
REQUIRE_FALSE(atlas_res->content().find_region("sprite2"));
|
||||
REQUIRE_FALSE(atlas_res->content().find_shape_region("shape_sprite2"));
|
||||
sprite_asset::ptr spr = atlas_res->find_nested_asset<sprite_asset>("sprite");
|
||||
REQUIRE(spr);
|
||||
REQUIRE(spr->content().pivot() == v2f(1.f,2.f));
|
||||
REQUIRE(spr->content().texrect() == b2f(5.f,6.f,7.f,8.f));
|
||||
REQUIRE(spr->content().texture()== texture_res);
|
||||
}
|
||||
|
||||
{
|
||||
auto sprite_res = l.load_asset<sprite_asset>("sprite_a.json");
|
||||
REQUIRE(sprite_res);
|
||||
REQUIRE(sprite_res->content().pivot() == v2f(1.f, 2.f));
|
||||
REQUIRE(sprite_res->content().texrect() == b2f(5.f, 6.f, 7.f, 8.f));
|
||||
REQUIRE(sprite_res->content().texture() == texture_res);
|
||||
}
|
||||
|
||||
{
|
||||
auto sprite_res = l.load_asset<sprite_asset>("sprite_t.json");
|
||||
auto sprite_res = l.load_asset<sprite_asset>("sprite.json");
|
||||
REQUIRE(sprite_res);
|
||||
REQUIRE(sprite_res->content().pivot() == v2f(1.f, 2.f));
|
||||
REQUIRE(sprite_res->content().texrect() == b2f(5.f, 6.f, 7.f, 8.f));
|
||||
@@ -152,15 +131,13 @@ TEST_CASE("library"){
|
||||
|
||||
const flipbook::frame* frame_0 = flipbook_res->content().find_frame(0);
|
||||
REQUIRE(frame_0);
|
||||
REQUIRE(frame_0->texture == texture_res);
|
||||
REQUIRE(frame_0->pivot == v2f(1.f,2.f));
|
||||
REQUIRE(frame_0->texrect == b2f(5.f, 6.f, 7.f, 8.f));
|
||||
REQUIRE(frame_0->sprite);
|
||||
REQUIRE(frame_0->sprite == l.load_asset<atlas_asset, sprite_asset>("atlas.json:/sprite"));
|
||||
|
||||
const flipbook::frame* frame_1 = flipbook_res->content().find_frame(1);
|
||||
REQUIRE(frame_1);
|
||||
REQUIRE(frame_1->texture == texture_res);
|
||||
REQUIRE(frame_1->pivot == v2f(1.f, 2.f));
|
||||
REQUIRE(frame_1->texrect == b2f(5.f, 6.f, 7.f, 8.f));
|
||||
REQUIRE(frame_1->sprite);
|
||||
REQUIRE(frame_1->sprite == l.load_asset<sprite_asset>("sprite.json"));
|
||||
|
||||
const flipbook::sequence* sequence_0 = flipbook_res->content().find_sequence("sequence_0");
|
||||
REQUIRE(sequence_0);
|
||||
|
||||
Reference in New Issue
Block a user