mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
model and sprite loaders
This commit is contained in:
@@ -17,6 +17,75 @@ namespace
|
||||
return "model asset loading exception";
|
||||
}
|
||||
};
|
||||
|
||||
const char* model_asset_schema_source = R"json(
|
||||
{
|
||||
"type" : "object",
|
||||
"required" : [ "mesh" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"mesh" : { "$ref": "#/common_definitions/address" },
|
||||
"materials" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref" : "#/common_definitions/address" }
|
||||
}
|
||||
}
|
||||
})json";
|
||||
|
||||
const rapidjson::SchemaDocument& model_asset_schema() {
|
||||
static std::mutex mutex;
|
||||
static std::unique_ptr<rapidjson::SchemaDocument> schema;
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex);
|
||||
if ( !schema ) {
|
||||
rapidjson::Document doc;
|
||||
if ( doc.Parse(model_asset_schema_source).HasParseError() ) {
|
||||
the<debug>().error("ASSETS: Failed to parse model asset schema");
|
||||
throw model_asset_loading_exception();
|
||||
}
|
||||
json_utils::add_common_schema_definitions(doc);
|
||||
schema = std::make_unique<rapidjson::SchemaDocument>(doc);
|
||||
}
|
||||
|
||||
return *schema;
|
||||
}
|
||||
|
||||
stdex::promise<model> parse_model(
|
||||
library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
E2D_ASSERT(root.HasMember("mesh") && root["mesh"].IsString());
|
||||
auto mesh_p = library.load_asset_async<mesh_asset>(
|
||||
path::combine(parent_address, root["mesh"].GetString()));
|
||||
|
||||
vector<stdex::promise<material_asset::load_result>> materials_p;
|
||||
if ( root.HasMember("materials") ) {
|
||||
E2D_ASSERT(root["materials"].IsArray());
|
||||
const auto& materials_json = root["materials"];
|
||||
|
||||
materials_p.reserve(materials_json.Size());
|
||||
for ( rapidjson::SizeType i = 0; i < materials_json.Size(); ++i ) {
|
||||
E2D_ASSERT(materials_json[i].IsString());
|
||||
materials_p.emplace_back(
|
||||
library.load_asset_async<material_asset>(
|
||||
path::combine(parent_address, materials_json[i].GetString())));
|
||||
}
|
||||
}
|
||||
|
||||
return stdex::make_tuple_promise(std::make_tuple(
|
||||
std::move(mesh_p),
|
||||
stdex::make_all_promise(materials_p)))
|
||||
.then([](const std::tuple<
|
||||
mesh_asset::load_result,
|
||||
vector<material_asset::load_result>
|
||||
>& results){
|
||||
model content;
|
||||
content.set_mesh(std::get<0>(results));
|
||||
content.set_materials(std::get<1>(results));
|
||||
return content;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
@@ -25,9 +94,27 @@ namespace e2d
|
||||
library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<json_asset>(address)
|
||||
.then([](const json_asset::load_result& model_data){
|
||||
model mdl;
|
||||
return model_asset::create(std::move(mdl));
|
||||
.then([
|
||||
&library,
|
||||
parent_address = path::parent_path(address)
|
||||
](const json_asset::load_result& model_data){
|
||||
if ( !modules::is_initialized<deferrer>() ) {
|
||||
throw model_asset_loading_exception();
|
||||
}
|
||||
return the<deferrer>().do_in_worker_thread([model_data](){
|
||||
const rapidjson::Document& doc = model_data->content();
|
||||
rapidjson::SchemaValidator validator(model_asset_schema());
|
||||
if ( !doc.Accept(validator) ) {
|
||||
throw model_asset_loading_exception();
|
||||
}
|
||||
})
|
||||
.then([&library, parent_address, model_data](){
|
||||
return parse_model(
|
||||
library, parent_address, model_data->content());
|
||||
})
|
||||
.then([](const model& model){
|
||||
return model_asset::create(model);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,95 @@ namespace
|
||||
return "sprite asset loading exception";
|
||||
}
|
||||
};
|
||||
|
||||
const char* sprite_asset_schema_source = R"json(
|
||||
{
|
||||
"type" : "object",
|
||||
"required" : [ "size", "pivot", "texrect" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"size" : { "$ref": "#/common_definitions/v2" },
|
||||
"pivot" : { "$ref": "#/common_definitions/v2" },
|
||||
"texrect" : { "$ref": "#/common_definitions/b2" },
|
||||
"texture" : { "$ref": "#/common_definitions/address" },
|
||||
"material" : { "$ref": "#/common_definitions/address" }
|
||||
}
|
||||
})json";
|
||||
|
||||
const rapidjson::SchemaDocument& sprite_asset_schema() {
|
||||
static std::mutex mutex;
|
||||
static std::unique_ptr<rapidjson::SchemaDocument> schema;
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex);
|
||||
if ( !schema ) {
|
||||
rapidjson::Document doc;
|
||||
if ( doc.Parse(sprite_asset_schema_source).HasParseError() ) {
|
||||
the<debug>().error("ASSETS: Failed to parse sprite asset schema");
|
||||
throw sprite_asset_loading_exception();
|
||||
}
|
||||
json_utils::add_common_schema_definitions(doc);
|
||||
schema = std::make_unique<rapidjson::SchemaDocument>(doc);
|
||||
}
|
||||
|
||||
return *schema;
|
||||
}
|
||||
|
||||
stdex::promise<sprite> parse_sprite(
|
||||
library& library,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root)
|
||||
{
|
||||
v2f size;
|
||||
E2D_ASSERT(root.HasMember("size"));
|
||||
if ( !json_utils::try_parse_value(root["size"], size) ) {
|
||||
return stdex::make_rejected_promise<sprite>(
|
||||
sprite_asset_loading_exception());
|
||||
}
|
||||
|
||||
v2f 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(root.HasMember("texrect"));
|
||||
if ( !json_utils::try_parse_value(root["texrect"], texrect) ) {
|
||||
return stdex::make_rejected_promise<sprite>(
|
||||
sprite_asset_loading_exception());
|
||||
}
|
||||
|
||||
E2D_ASSERT(!root.HasMember("texture") || root["texture"].IsString());
|
||||
auto texture_p = root.HasMember("texture")
|
||||
? library.load_asset_async<texture_asset>(path::combine(
|
||||
parent_address,
|
||||
root["texture"].GetString()))
|
||||
: stdex::make_resolved_promise(texture_asset::ptr());
|
||||
|
||||
E2D_ASSERT(!root.HasMember("material") || root["material"].IsString());
|
||||
auto material_p = root.HasMember("material")
|
||||
? library.load_asset_async<material_asset>(path::combine(
|
||||
parent_address,
|
||||
root["material"].GetString()))
|
||||
: stdex::make_resolved_promise(material_asset::ptr());
|
||||
|
||||
return stdex::make_tuple_promise(std::make_tuple(
|
||||
std::move(texture_p),
|
||||
std::move(material_p)
|
||||
)).then([size, pivot, texrect](const std::tuple<
|
||||
texture_asset::load_result,
|
||||
material_asset::load_result
|
||||
>& results){
|
||||
sprite content;
|
||||
content.set_size(size);
|
||||
content.set_pivot(pivot);
|
||||
content.set_texrect(texrect);
|
||||
content.set_texture(std::get<0>(results));
|
||||
content.set_material(std::get<1>(results));
|
||||
return content;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
@@ -25,9 +114,27 @@ namespace e2d
|
||||
library& library, str_view address)
|
||||
{
|
||||
return library.load_asset_async<json_asset>(address)
|
||||
.then([](const json_asset::load_result& sprite_data){
|
||||
sprite spr;
|
||||
return sprite_asset::create(std::move(spr));
|
||||
.then([
|
||||
&library,
|
||||
parent_address = path::parent_path(address)
|
||||
](const json_asset::load_result& sprite_data){
|
||||
if ( !modules::is_initialized<deferrer>() ) {
|
||||
throw sprite_asset_loading_exception();
|
||||
}
|
||||
return the<deferrer>().do_in_worker_thread([sprite_data](){
|
||||
const rapidjson::Document& doc = sprite_data->content();
|
||||
rapidjson::SchemaValidator validator(sprite_asset_schema());
|
||||
if ( !doc.Accept(validator) ) {
|
||||
throw sprite_asset_loading_exception();
|
||||
}
|
||||
})
|
||||
.then([&library, parent_address, sprite_data](){
|
||||
return parse_sprite(
|
||||
library, parent_address, sprite_data->content());
|
||||
})
|
||||
.then([](const sprite& sprite){
|
||||
return sprite_asset::create(sprite);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
3
untests/bin/library/mesh.e2d_mesh
Normal file
3
untests/bin/library/mesh.e2d_mesh
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1ab164b79bb190d2ffb325801de93a71b5d7059ad78da21b324532c680029951
|
||||
size 20856
|
||||
6
untests/bin/library/model.json
Normal file
6
untests/bin/library/model.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"mesh" : "mesh.e2d_mesh",
|
||||
"materials" : [
|
||||
"material.json"
|
||||
]
|
||||
}
|
||||
7
untests/bin/library/sprite.json
Normal file
7
untests/bin/library/sprite.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"size" : { "x" : 10, "y" : 20 },
|
||||
"pivot" : { "x" : 0.5, "y" : 0.7 },
|
||||
"texrect" : { "w" : 0.5, "h" : 1 },
|
||||
"texture" : "image.png",
|
||||
"material" : "material.json"
|
||||
}
|
||||
@@ -94,6 +94,23 @@ TEST_CASE("library"){
|
||||
auto texture_res = l.load_asset<texture_asset>("image.png");
|
||||
REQUIRE(texture_res);
|
||||
REQUIRE(texture_res->content());
|
||||
|
||||
auto sprite_res = l.load_asset<sprite_asset>("sprite.json");
|
||||
REQUIRE(sprite_res);
|
||||
REQUIRE(sprite_res->content().size() == v2f(10.f, 20.f));
|
||||
REQUIRE(sprite_res->content().pivot() == v2f(0.5f, 0.7f));
|
||||
REQUIRE(sprite_res->content().texrect() == b2f(0.5f, 1.f));
|
||||
REQUIRE(sprite_res->content().texture());
|
||||
REQUIRE(sprite_res->content().material());
|
||||
|
||||
auto model_res = l.load_asset<model_asset>("model.json");
|
||||
REQUIRE(model_res);
|
||||
REQUIRE(model_res->content().mesh());
|
||||
REQUIRE(model_res->content().material_count() == 1);
|
||||
REQUIRE(model_res->content().material(0));
|
||||
REQUIRE_FALSE(model_res->content().mesh()->content().vertices().empty());
|
||||
REQUIRE(model_res->content().mesh()->content().indices_submesh_count() == 1);
|
||||
REQUIRE_FALSE(model_res->content().mesh()->content().indices(0).empty());
|
||||
}
|
||||
}
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user