feat: saving entities (WIP)

This commit is contained in:
MihailRis
2024-07-05 05:16:31 +03:00
parent 019a88ef84
commit f0270d3391
24 changed files with 290 additions and 101 deletions
+69 -4
View File
@@ -1,5 +1,6 @@
#include "Entities.hpp"
#include "../data/dynamic_util.hpp"
#include "../assets/Assets.hpp"
#include "../world/Level.hpp"
#include "../physics/Hitbox.hpp"
@@ -78,8 +79,7 @@ entityid_t Entities::spawn(
body.triggers[i] = Trigger {
true, TriggerType::AABB, i, id, params, params, {}, {},
create_trigger_callback<scripting::on_trigger_enter>(this),
create_trigger_callback<scripting::on_trigger_exit>(this)
};
create_trigger_callback<scripting::on_trigger_exit>(this)};
}
for (auto& [i, radius] : def.radialTriggers) {
TriggerParams params {};
@@ -87,11 +87,11 @@ entityid_t Entities::spawn(
body.triggers[i] = Trigger {
true, TriggerType::RADIUS, i, id, params, params, {}, {},
create_trigger_callback<scripting::on_trigger_enter>(this),
create_trigger_callback<scripting::on_trigger_exit>(this)
};
create_trigger_callback<scripting::on_trigger_exit>(this)};
}
auto& scripting = registry.emplace<ScriptComponents>(entity);
entities[id] = entity;
uids[entity] = id;
registry.emplace<rigging::Rig>(entity, rig->instance());
for (auto& componentName : def.components) {
auto component = std::make_unique<UserComponent>(
@@ -112,11 +112,59 @@ void Entities::despawn(entityid_t id) {
}
}
dynamic::Value Entities::serialize(const Entity& entity) {
auto root = dynamic::create_map();
auto& eid = entity.getID();
auto& def = eid.def;
root->put("def", def.name);
root->put("uid", eid.uid);
{
auto& transform = entity.getTransform();
auto& tsfmap = root->putMap("transform");
tsfmap.put("pos", dynamic::to_value(transform.pos));
if (transform.size != glm::vec3(1.0f)) {
tsfmap.put("size", dynamic::to_value(transform.size));
}
tsfmap.put("rot", dynamic::to_value(transform.rot));
}
{
auto& rigidbody = entity.getRigidbody();
auto& bodymap = root->putMap("rigidbody");
if (!rigidbody.enabled) {
bodymap.put("enabled", rigidbody.enabled);
}
bodymap.put("vel", dynamic::to_value(rigidbody.hitbox.velocity));
bodymap.put("damping", rigidbody.hitbox.linearDamping);
}
auto& rig = entity.getModeltree();
if (rig.config->getName() != def.rigName) {
root->put("rig", rig.config->getName());
}
if (def.save.rig.pose || def.save.rig.textures) {
auto& rigmap = root->putMap("rig");
if (def.save.rig.textures) {
auto& map = rigmap.putMap("textures");
for (auto& entry : rig.textures) {
map.put(entry.first, entry.second);
}
}
if (def.save.rig.pose) {
auto& list = rigmap.putList("pose");
for (auto& mat : rig.pose.matrices) {
list.put(dynamic::to_value(mat));
}
}
}
return root;
}
void Entities::clean() {
for (auto it = entities.begin(); it != entities.end();) {
if (!registry.get<EntityId>(it->second).destroyFlag) {
++it;
} else {
uids.erase(it->second);
registry.destroy(it->second);
it = entities.erase(it);
}
@@ -249,3 +297,20 @@ void Entities::render(Assets* assets, ModelBatch& batch, const Frustum& frustum)
}
}
}
std::vector<Entity> Entities::getAllInside(AABB aabb) {
std::vector<Entity> collected;
auto view = registry.view<Transform>();
for (auto [entity, transform] : view.each()) {
if (aabb.contains(transform.pos)) {
const auto& found = uids.find(entity);
if (found == uids.end()) {
continue;
}
if (auto entity = get(found->second)) {
collected.push_back(*entity);
}
}
}
return collected;
}
+4
View File
@@ -21,6 +21,7 @@ struct entity_funcs_set {
bool on_fall : 1;
bool on_trigger_enter : 1;
bool on_trigger_exit : 1;
bool on_save : 1;
};
struct EntityDef;
@@ -154,6 +155,7 @@ class Entities {
entt::registry registry;
Level* level;
std::unordered_map<entityid_t, entt::entity> entities;
std::unordered_map<entt::entity, entityid_t> uids;
entityid_t nextID = 1;
void preparePhysics();
@@ -181,7 +183,9 @@ public:
return std::nullopt;
}
std::vector<Entity> getAllInside(AABB aabb);
void despawn(entityid_t id);
dynamic::Value serialize(const Entity& entity);
inline size_t size() const {
return entities.size();
+10 -2
View File
@@ -15,14 +15,22 @@ namespace rigging {
struct EntityDef {
/// @brief Entity string id (with prefix included)
std::string const name;
std::vector<std::string> components;
glm::vec3 hitbox {0.5f};
std::vector<std::pair<size_t, AABB>> boxTriggers {};
std::vector<std::pair<size_t, float>> radialTriggers {};
std::string rigName = name.substr(name.find(":")+1);
struct {
bool enabled = true;
struct {
bool textures = false;
bool pose = false;
} rig;
} save {};
struct {
entityid_t id;
rigging::RigConfig* rig;
+5 -4
View File
@@ -30,8 +30,8 @@ static void get_all_nodes(std::vector<RigNode*>& nodes, RigNode* node) {
}
}
RigConfig::RigConfig(std::unique_ptr<RigNode> root, size_t nodesCount)
: root(std::move(root)), nodes(nodesCount) {
RigConfig::RigConfig(const std::string& name, std::unique_ptr<RigNode> root, size_t nodesCount)
: name(name), root(std::move(root)), nodes(nodesCount) {
get_all_nodes(nodes, this->root.get());
}
@@ -106,7 +106,8 @@ static std::tuple<size_t, std::unique_ptr<RigNode>> read_node(
std::unique_ptr<RigConfig> RigConfig::parse(
std::string_view src,
std::string_view file
std::string_view file,
std::string_view name
) {
auto root = json::parse(file, src);
auto rootNodeMap = root->map("root");
@@ -114,5 +115,5 @@ std::unique_ptr<RigConfig> RigConfig::parse(
throw std::runtime_error("missing 'root' element");
}
auto [count, rootNode] = read_node(rootNodeMap, 0);
return std::make_unique<RigConfig>(std::move(rootNode), count);
return std::make_unique<RigConfig>(std::string(name), std::move(rootNode), count);
}
+9 -2
View File
@@ -68,6 +68,7 @@ namespace rigging {
};
class RigConfig {
std::string name;
std::unique_ptr<RigNode> root;
std::unordered_map<std::string, size_t> indices;
@@ -85,7 +86,8 @@ namespace rigging {
RigNode* node,
glm::mat4 matrix) const;
public:
RigConfig(std::unique_ptr<RigNode> root, size_t nodesCount);
RigConfig(const std::string& name, std::unique_ptr<RigNode> root,
size_t nodesCount);
void update(Rig& rig, glm::mat4 matrix) const;
void setup(const Assets* assets, RigNode* node=nullptr) const;
@@ -103,12 +105,17 @@ namespace rigging {
static std::unique_ptr<RigConfig> parse(
std::string_view src,
std::string_view file
std::string_view file,
std::string_view name
);
const std::vector<RigNode*>& getNodes() const {
return nodes;
}
const std::string& getName() const {
return name;
}
};
};