feat: saving entities (WIP)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user