/* * This file is part of FGGL. * * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any * later version. * * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with FGGL. * If not, see <https://www.gnu.org/licenses/>. */ // // Created by webpigeon on 11/09/22. // #include <cstdlib> #include <iostream> #include <fstream> #include <filesystem> #include <map> #include <yaml-cpp/yaml.h> #include "fggl/data/model.hpp" #include "fggl/data/procedural.hpp" #include "fggl/entity/loader/loader.hpp" #include "binary.hpp" constexpr const char* YAML_PREFAB = "prefabs"; constexpr const char* YAML_COMPONENT = "components"; constexpr uint32_t DEFAULT_STACKS = 16; constexpr uint32_t DEFAULT_SLICES = 16; constexpr const char *SHAPE_SPHERE{"sphere"}; constexpr const char *SHAPE_BOX{"box"}; namespace fggl { static void process_shape(const YAML::Node &node, data::Mesh &mesh) { auto transform = data::OFFSET_NONE; auto offset = node["offset"].as<math::vec3>(math::VEC3_ZERO); transform = glm::translate(transform, offset); auto scale = node["scale"].as<math::vec3>(math::VEC3_ONES); transform = glm::scale(transform, scale); debug::debug("scale: {}, {}, {}", scale.x, scale.y, scale.z); // now the shape itself auto type = node["type"].as<std::string>(); if (type == SHAPE_BOX) { data::make_cube(mesh, transform); } else if (type == SHAPE_SPHERE) { auto stacks = node["stacks"].as<uint32_t>(DEFAULT_STACKS); auto slices = node["slices"].as<uint32_t>(DEFAULT_SLICES); data::make_sphere(mesh, transform, stacks, slices); } else { debug::log(debug::Level::warning, "unknown shape type requested: {}", type); } } static void process_mesh(const YAML::Node& spec, fggl::data::Mesh& mesh) { // process shape structure if (spec["shape"].IsSequence()) { for (const auto &node : spec["shape"]) { process_shape(node, mesh); } } else { process_shape(spec["shape"], mesh); } mesh.removeDups(); } } void write_comp_static_model(FILE* fout, const YAML::Node& config) { // calculate mesh fggl::data::Mesh mesh; fggl::process_mesh( config, mesh); // calculate correct name auto meshName = config["shape_id"]; auto meshNameStr = meshName.as<std::string>(); auto meshGuid = fggl::util::make_guid_rt(meshNameStr); // header data fggl::data::ModelHeader header{ .guid = meshGuid.get(), .type = fggl::data::ModelType::OPENGL, }; // write the mesh to disk fggl::data::write_model( fout, header, mesh ); } int main(int argc, char* argv[]) { auto* packName = argv[1]; std::cout << "generating " << packName << std::endl; std::map< fggl::util::GUID, std::string > guids; // rollball auto rollPath = std::filesystem::current_path() / "rollball.yml"; std::cout << rollPath << std::endl; YAML::Node root = YAML::LoadFile(rollPath); if ( !root ){ return EXIT_FAILURE; } //std::cout << root[ YAML_PREFAB ] << std::endl; std::map<std::string, std::function<void(FILE* fout, const YAML::Node&)>> converters; converters["StaticMesh"] = write_comp_static_model; std::string meshFile = "rollball_models.bin"; FILE* fout = fopen(meshFile.c_str(), "w"); // pack prefabs for (const auto& prefab : root[YAML_PREFAB]) { // name auto name = prefab["name"].as<std::string>(); auto nameRef = fggl::util::make_guid(name.c_str()); guids[nameRef] = name; std::cout << name << std::endl; // parent //auto parentName = prefab["parent"].as<std::string>(); //auto parentGuid = fggl::util::make_guid(parentName.c_str()); // components for( const auto& key : prefab[YAML_COMPONENT] ) { auto compStr = key.first.as<std::string>(); auto compGuid = fggl::util::make_guid_rt(compStr); guids[compGuid] = compStr; // figure out the type auto compWrite = converters.find(compStr); if ( compWrite != converters.end()) { compWrite->second(fout, key.second); } } } fclose(fout); // guid table std::cerr << "GUID Table" << std::endl; std::cerr << "guid,str" << std::endl; for (auto& [guid,str] : guids) { std::cerr << guid.get() << "," << str << std::endl; } return EXIT_SUCCESS; }