Unravel Engine C++ Reference
Loading...
Searching...
No Matches
entity_inspect.cpp
Go to the documentation of this file.
1#include "entity_inspect.h"
2
9#include <hpp/utility.hpp>
10#include <math/math.h>
11#include <uuid/uuid.h>
12
13#include <logging/logging.h>
14#include <sstream>
15
16namespace unravel
17{
18namespace
19{
20
21auto json_escape(const std::string& value) -> std::string
22{
23 std::string out;
24 out.reserve(value.size() + 8);
25 for(char c : value)
26 {
27 switch(c)
28 {
29 case '\\':
30 out += "\\\\";
31 break;
32 case '"':
33 out += "\\\"";
34 break;
35 case '\b':
36 out += "\\b";
37 break;
38 case '\f':
39 out += "\\f";
40 break;
41 case '\n':
42 out += "\\n";
43 break;
44 case '\r':
45 out += "\\r";
46 break;
47 case '\t':
48 out += "\\t";
49 break;
50 default:
51 out += c;
52 break;
53 }
54 }
55 return out;
56}
57
58auto make_json_string(const std::string& value) -> std::string
59{
60 return "\"" + json_escape(value) + "\"";
61}
62
63} // namespace
64
65auto find_entity_by_id(scene& scn, const std::string& id) -> entt::handle
66{
67 if(id.empty() || !scn.registry)
68 {
69 return {};
70 }
71 if(auto uuid = hpp::uuid::from_string(id))
72 {
73 auto handle = scn.find_entity_by_uuid(*uuid);
74 if(handle)
75 {
76 return handle;
77 }
78 }
79 try
80 {
81 const auto integral = static_cast<entt::entity>(std::stoul(id));
82 if(scn.registry->valid(integral))
83 {
84 return entt::handle(*scn.registry, integral);
85 }
86 }
87 catch(...)
88 {
89 }
90 return {};
91}
92
93auto entity_id_string(entt::handle entity) -> std::string
94{
95 if(!entity)
96 {
97 return {};
98 }
99 if(auto* id = entity.try_get<id_component>())
100 {
101 return hpp::to_string(id->id);
102 }
103 return std::to_string(entt::to_integral(entity.entity()));
104}
105
106auto collect_component_pretty_names(entt::handle entity) -> std::vector<std::string>
107{
108 std::vector<std::string> names;
109 if(!entity)
110 {
111 return names;
112 }
113 hpp::for_each_tuple_type<all_inspectable_components>(
114 [&](auto index)
115 {
116 using ctype = std::tuple_element_t<decltype(index)::value, all_inspectable_components>;
117 if(entity.all_of<ctype>())
118 {
119 auto type = entt::resolve<ctype>();
120 names.emplace_back(entt::get_pretty_name(type));
121 }
122 });
123 if(entity.all_of<script_component>())
124 {
125 auto type = entt::resolve<script_component>();
126 names.emplace_back(entt::get_pretty_name(type));
127 }
128 return names;
129}
130
131auto entity_to_summary_json(entt::handle entity, int depth, int max_depth) -> std::string
132{
133 if(!entity)
134 {
135 return "null";
136 }
137 std::string name;
138 std::string tag;
139 if(auto* tag_comp = entity.try_get<tag_component>())
140 {
141 name = tag_comp->name;
142 tag = tag_comp->tag;
143 }
144 std::string parent_id;
145 bool active = true;
146 math::vec3 position_world{0.0f};
147 math::vec3 rotation_world{0.0f};
148 math::vec3 scale_world{1.0f};
149 math::vec3 position_local{0.0f};
150 math::vec3 rotation_local{0.0f};
151 math::vec3 scale_local{1.0f};
152 if(auto* transform = entity.try_get<transform_component>())
153 {
154 active = transform->is_active();
155 position_world = transform->get_position_global();
156 rotation_world = transform->get_rotation_euler_global();
157 scale_world = transform->get_scale_global();
158 position_local = transform->get_position_local();
159 rotation_local = transform->get_rotation_euler_local();
160 scale_local = transform->get_scale_local();
161 if(auto parent = transform->get_parent())
162 {
163 parent_id = entity_id_string(parent);
164 }
165 }
166 auto components = collect_component_pretty_names(entity);
167 std::string components_json = "[";
168 for(size_t i = 0; i < components.size(); ++i)
169 {
170 if(i > 0)
171 {
172 components_json += ",";
173 }
174 components_json += make_json_string(components[i]);
175 }
176 components_json += "]";
177 std::string children_json = "[]";
178 if(depth < max_depth)
179 {
180 if(auto* transform = entity.try_get<transform_component>())
181 {
182 children_json = "[";
183 const auto& children = transform->get_children();
184 for(size_t i = 0; i < children.size(); ++i)
185 {
186 if(i > 0)
187 {
188 children_json += ",";
189 }
190 children_json += entity_to_summary_json(children[i], depth + 1, max_depth);
191 }
192 children_json += "]";
193 }
194 }
195 return fmt::format(
196 R"({{"id":{},"name":{},"tag":{},"active":{},"parent_id":{},"position":[{:.6g},{:.6g},{:.6g}],"rotation_euler":[{:.6g},{:.6g},{:.6g}],"scale":[{:.6g},{:.6g},{:.6g}],"position_local":[{:.6g},{:.6g},{:.6g}],"rotation_euler_local":[{:.6g},{:.6g},{:.6g}],"scale_local":[{:.6g},{:.6g},{:.6g}],"components":{},"children":{}}})",
197 make_json_string(entity_id_string(entity)),
198 make_json_string(name),
199 make_json_string(tag),
200 active ? "true" : "false",
201 parent_id.empty() ? "null" : make_json_string(parent_id),
202 position_world.x,
203 position_world.y,
204 position_world.z,
205 rotation_world.x,
206 rotation_world.y,
207 rotation_world.z,
208 scale_world.x,
209 scale_world.y,
210 scale_world.z,
211 position_local.x,
212 position_local.y,
213 position_local.z,
214 rotation_local.x,
215 rotation_local.y,
216 rotation_local.z,
217 scale_local.x,
218 scale_local.y,
219 scale_local.z,
220 components_json,
221 children_json);
222}
223
224auto entity_components_serialized(entt::handle entity) -> std::string
225{
226 if(!entity)
227 {
228 return {};
229 }
230 std::stringstream stream;
231 save_to_stream(stream, entt::const_handle{entity});
232 return stream.str();
233}
234
235} // namespace unravel
Class that contains core data for audio listeners. There can only be one instance of it per scene.
Component that handles transformations (position, rotation, scale, etc.) in the ACE framework.
const char * id
uint16_t index
std::vector< render_pass_node > children
std::string name
Definition hub.cpp:33
std::string tag
Definition hub.cpp:32
std::string parent_id
texture_job_type type
auto get_pretty_name(const meta_type &t) -> std::string
auto make_json_string(const std::string &value) -> std::string
auto json_escape(const std::string &value) -> std::string
auto entity_id_string(entt::handle entity) -> std::string
Stable id string for MCP/editor tooling (UUID preferred).
auto find_entity_by_id(scene &scn, const std::string &id) -> entt::handle
Resolve an entity by UUID string or integral entt id.
auto collect_component_pretty_names(entt::handle entity) -> std::vector< std::string >
Component pretty-names present on the entity (inspectable + Script).
auto entity_components_serialized(entt::handle entity) -> std::string
Full associative serialization of serializeable components (scene-file format).
std::tuple< id_component, tag_component, layer_component, prefab_component, prefab_id_component, transform_component, test_component, model_component, animation_component, bone_component, submesh_component, camera_component, volume_component, auto_exposure_component, tonemapping_component, assao_component, bloom_component, fxaa_component, taa_component, ssr_component, ssil_component, light_component, skylight_component, reflection_probe_component, physics_component, character_controller_component, audio_source_component, audio_listener_component, text_component, particle_emitter_component, ui_document_component > all_inspectable_components
auto save_to_stream(std::ostream &stream, entt::const_handle e, const script_component::script_object &obj) -> bool
auto entity_to_summary_json(entt::handle entity, int depth, int max_depth) -> std::string
JSON summary: transform, component pretty-names, optional children.
entt::handle entity
Component that provides a unique identifier (UUID) for an entity.
Represents a scene in the ACE framework, managing entities and their relationships.
Definition scene.h:70
Component that provides a tag (name or label) for an entity.
gfx::uniform_handle handle
Definition uniform.cpp:9