Unravel Engine C++ Reference
Loading...
Searching...
No Matches
transform_component_bindings.cpp
Go to the documentation of this file.
2#include "script_bindings.h"
3
4#include "../script_interop.h"
5
9
10namespace unravel
11{
12namespace
13{
14
15
16//-------------------------------------------------------------------------
17/*
18
19 _______ _____ _ _ _____ ______ ____ _____ __ __
20 |__ __| __ \ /\ | \ | |/ ____| ____/ __ \| __ \| \/ |
21 | | | |__) | / \ | \| | (___ | |__ | | | | |__) | \ / |
22 | | | _ / / /\ \ | . ` |\___ \| __|| | | | _ /| |\/| |
23 | | | | \ \ / ____ \| |\ |____) | | | |__| | | \ \| | | |
24 |_| |_| \_\/_/ \_\_| \_|_____/|_| \____/|_| \_\_| |_|
25
26
27*/
28//-------------------------------------------------------------------------
29auto internal_m2n_get_children(entt::entity id) -> hpp::small_vector<entt::entity>
30{
32 {
33 const auto& children = comp->get_children();
34 hpp::small_vector<entt::entity> children_id;
35 children_id.reserve(children.size());
36 for(const auto& child : children)
37 {
38 children_id.emplace_back(child.entity());
39 }
40 return children_id;
41 }
42
43 return {};
44}
45
46// Helper structure carrying an entity and the count of path segments matched so far.
47struct node_candidate
48{
49 entt::entity entity;
50 size_t matched_index{}; // number of path segments matched so far
51};
52
53auto internal_m2n_get_child(entt::entity id, const std::string& path, bool recursive) -> entt::entity
54{
55 auto root = get_entity_from_id(id);
56 if(!root || path.empty())
57 return entt::null;
58
59 // Tokenize the path once.
60 const auto parts = string_utils::tokenize(path, "/");
61 if(parts.empty())
62 return entt::null;
63
64 // Use a vector as a queue to reduce dynamic allocations.
65 hpp::small_vector<node_candidate> queue;
66 queue.reserve(4); // Reserve a reasonable number based on expected hierarchy size.
67 queue.push_back({root, 0});
68
69 // Process the vector as a queue.
70 for(size_t idx = 0; idx < queue.size(); ++idx)
71 {
72 auto candidate = queue[idx];
73 bool advanced = false;
74
75 // Try matching current candidate.
76 if(candidate.matched_index < parts.size())
77 {
78 if(auto tag_comp = safe_get_component<tag_component>(candidate.entity))
79 {
80 if(tag_comp->name == parts[candidate.matched_index])
81 {
82 candidate.matched_index++;
83 advanced = true;
84 if(candidate.matched_index == parts.size())
85 {
86 return candidate.entity;
87 }
88 }
89 }
90 }
91
92 // Determine if we should enqueue children.
93 // For recursive mode: allow children if no match yet or just advanced.
94 // For non-recursive mode: allow children only if no match has started.
95 bool should_enqueue = recursive ? (candidate.matched_index == 0 || advanced) : (candidate.matched_index == 0);
96
97 if(should_enqueue)
98 {
99 if(auto trans_comp = safe_get_component<transform_component>(candidate.entity))
100 {
101 for(const auto& child : trans_comp->get_children())
102 {
103 queue.push_back({child.entity(), candidate.matched_index});
104 }
105 }
106 }
107 }
108 // No matching entity found.
109 return entt::null;
110}
111
112auto internal_m2n_get_parent(entt::entity id) -> entt::entity
113{
115 {
116 return comp->get_parent().entity();
117 }
118
119 return {};
120}
121
122void internal_m2n_set_parent(entt::entity id, entt::entity new_parent, bool global_stays)
123{
125 {
126 auto parent = get_entity_from_id(new_parent);
127 comp->set_parent(parent, global_stays);
128 }
129}
130
131auto internal_m2n_get_position_global(entt::entity id) -> math::vec3
132{
134 {
135 return comp->get_position_global();
136 }
137
138 return {};
139}
140
141void internal_m2n_set_position_global(entt::entity id, const math::vec3& value)
142{
144 {
145 comp->set_position_global(value);
146 }
147}
148
149void internal_m2n_move_by_global(entt::entity id, const math::vec3& value)
150{
152 {
153 comp->move_by_global(value);
154 }
155}
156
157auto internal_m2n_get_position_local(entt::entity id) -> math::vec3
158{
160 {
161 return comp->get_position_local();
162 }
163
164 return {};
165}
166
167void internal_m2n_set_position_local(entt::entity id, const math::vec3& value)
168{
170 {
171 comp->set_position_local(value);
172 }
173}
174
175void internal_m2n_move_by_local(entt::entity id, const math::vec3& value)
176{
178 {
179 comp->move_by_local(value);
180 }
181}
182
183//--------------------------------------------------
184auto internal_m2n_get_rotation_euler_global(entt::entity id) -> math::vec3
185{
187 {
188 return comp->get_rotation_euler_global();
189 }
190
191 return {};
192}
193
194void internal_m2n_rotate_by_euler_global(entt::entity id, const math::vec3& amount)
195{
197 {
198 comp->rotate_by_euler_global(amount);
199 }
200}
201
202void internal_m2n_rotate_axis_global(entt::entity id, float degrees, const math::vec3& axis)
203{
205 {
206 comp->rotate_axis_global(degrees, axis);
207 }
208}
209
210auto internal_m2n_transform_vector_global(entt::entity id, const math::vec3& coord) -> math::vec3
211{
213 {
214 const auto& global = comp->get_transform_global();
215 return global.transform_coord(coord);
216 }
217
218 return {};
219}
220
221auto internal_m2n_inverse_transform_vector_global(entt::entity id, const math::vec3& coord) -> math::vec3
222{
224 {
225 const auto& global = comp->get_transform_global();
226 return global.inverse_transform_coord(coord);
227 }
228
229 return {};
230}
231
232auto internal_m2n_transform_direction_global(entt::entity id, const math::vec3& direction) -> math::vec3
233{
235 {
236 const auto& global = comp->get_transform_global();
237 return global.transform_normal(direction);
238 }
239
240 return {};
241}
242
243auto internal_m2n_inverse_transform_direction_global(entt::entity id, const math::vec3& direction) -> math::vec3
244{
246 {
247 const auto& global = comp->get_transform_global();
248 return global.inverse_transform_normal(direction);
249 }
250
251 return {};
252}
253
254void internal_m2n_look_at(entt::entity id, const math::vec3& point, const math::vec3& up)
255{
257 {
258 comp->look_at(point, up);
259 }
260}
261
262void internal_m2n_set_rotation_euler_global(entt::entity id, const math::vec3& value)
263{
265 {
266 comp->set_rotation_euler_global(value);
267 }
268}
269
270auto internal_m2n_get_rotation_euler_local(entt::entity id) -> math::vec3
271{
273 {
274 return comp->get_rotation_euler_local();
275 }
276
277 return {};
278}
279
280void internal_m2n_set_rotation_euler_local(entt::entity id, const math::vec3& value)
281{
283 {
284 comp->set_rotation_euler_local(value);
285 }
286}
287
288void internal_m2n_rotate_by_euler_local(entt::entity id, const math::vec3& amount)
289{
291 {
292 comp->rotate_by_euler_local(amount);
293 }
294}
295
296auto internal_m2n_get_rotation_global(entt::entity id) -> math::quat
297{
299 {
300 return comp->get_rotation_global();
301 }
302
303 return {};
304}
305
306void internal_m2n_set_rotation_global(entt::entity id, const math::quat& value)
307{
309 {
310 comp->set_rotation_global(value);
311 }
312}
313
314void internal_m2n_rotate_by_global(entt::entity id, const math::quat& amount)
315{
317 {
318 comp->rotate_by_global(amount);
319 }
320}
321
322auto internal_m2n_get_rotation_local(entt::entity id) -> math::quat
323{
325 {
326 return comp->get_rotation_local();
327 }
328
329 return {};
330}
331
332void internal_m2n_set_rotation_local(entt::entity id, const math::quat& value)
333{
335 {
336 comp->set_rotation_local(value);
337 }
338}
339
340void internal_m2n_rotate_by_local(entt::entity id, const math::quat& amount)
341{
343 {
344 comp->rotate_by_local(amount);
345 }
346}
347
348//--------------------------------------------------
349auto internal_m2n_get_scale_global(entt::entity id) -> math::vec3
350{
352 {
353 return comp->get_scale_global();
354 }
355
356 return {};
357}
358
359void internal_m2n_set_scale_global(entt::entity id, const math::vec3& value)
360{
362 {
363 comp->set_scale_global(value);
364 }
365}
366
367void internal_m2n_scale_by_global(entt::entity id, const math::vec3& amount)
368{
370 {
371 comp->scale_by_global(amount);
372 }
373}
374
375auto internal_m2n_get_scale_local(entt::entity id) -> math::vec3
376{
378 {
379 return comp->get_scale_local();
380 }
381
382 return {};
383}
384
385void internal_m2n_set_scale_local(entt::entity id, const math::vec3& value)
386{
388 {
389 comp->set_scale_local(value);
390 }
391}
392
393void internal_m2n_scale_by_local(entt::entity id, const math::vec3& amount)
394{
396 {
397 comp->scale_by_local(amount);
398 }
399}
400
401//--------------------------------------------------
402auto internal_m2n_get_skew_global(entt::entity id) -> math::vec3
403{
405 {
406 return comp->get_skew_global();
407 }
408
409 return {};
410}
411
412void internal_m2n_setl_skew_globa(entt::entity id, const math::vec3& value)
413{
415 {
416 comp->set_skew_global(value);
417 }
418}
419
420auto internal_m2n_get_skew_local(entt::entity id) -> math::vec3
421{
423 {
424 return comp->get_skew_local();
425 }
426
427 return {};
428}
429
430void internal_m2n_set_skew_local(entt::entity id, const math::vec3& value)
431{
433 {
434 comp->set_skew_local(value);
435 }
436}
437
438} // namespace
439
441{
442 APPLOG_TRACE("{}", __func__);
443
444 auto reg = dotnet::internal_call_registry("Unravel.Core.TransformComponent");
445 reg.add_internal_call("internal_m2n_get_children", dotnet_internal_call(internal_m2n_get_children));
446 reg.add_internal_call("internal_m2n_get_child", dotnet_internal_call(internal_m2n_get_child));
447 reg.add_internal_call("internal_m2n_get_parent", dotnet_internal_call(internal_m2n_get_parent));
448 reg.add_internal_call("internal_m2n_set_parent", dotnet_internal_call(internal_m2n_set_parent));
449
450 reg.add_internal_call("internal_m2n_get_position_global", dotnet_internal_call(internal_m2n_get_position_global));
451 reg.add_internal_call("internal_m2n_set_position_global", dotnet_internal_call(internal_m2n_set_position_global));
452 reg.add_internal_call("internal_m2n_move_by_global", dotnet_internal_call(internal_m2n_move_by_global));
453
454 reg.add_internal_call("internal_m2n_get_position_local", dotnet_internal_call(internal_m2n_get_position_local));
455 reg.add_internal_call("internal_m2n_set_position_local", dotnet_internal_call(internal_m2n_set_position_local));
456 reg.add_internal_call("internal_m2n_move_by_local", dotnet_internal_call(internal_m2n_move_by_local));
457
458 // Euler
459 reg.add_internal_call("internal_m2n_get_rotation_euler_global",
460 dotnet_internal_call(internal_m2n_get_rotation_euler_global));
461 reg.add_internal_call("internal_m2n_set_rotation_euler_global",
462 dotnet_internal_call(internal_m2n_set_rotation_euler_global));
463 reg.add_internal_call("internal_m2n_rotate_by_euler_global",
464 dotnet_internal_call(internal_m2n_rotate_by_euler_global));
465
466 reg.add_internal_call("internal_m2n_get_rotation_euler_local",
467 dotnet_internal_call(internal_m2n_get_rotation_euler_local));
468 reg.add_internal_call("internal_m2n_set_rotation_euler_local",
469 dotnet_internal_call(internal_m2n_set_rotation_euler_local));
470 reg.add_internal_call("internal_m2n_rotate_by_euler_local", dotnet_internal_call(internal_m2n_rotate_by_euler_local));
471
472 // Quat
473 reg.add_internal_call("internal_m2n_get_rotation_global", dotnet_internal_call(internal_m2n_get_rotation_global));
474 reg.add_internal_call("internal_m2n_set_rotation_global", dotnet_internal_call(internal_m2n_set_rotation_global));
475 reg.add_internal_call("internal_m2n_rotate_by_global", dotnet_internal_call(internal_m2n_rotate_by_global));
476
477 reg.add_internal_call("internal_m2n_get_rotation_local", dotnet_internal_call(internal_m2n_get_rotation_local));
478 reg.add_internal_call("internal_m2n_set_rotation_local", dotnet_internal_call(internal_m2n_set_rotation_local));
479 reg.add_internal_call("internal_m2n_rotate_by_local", dotnet_internal_call(internal_m2n_rotate_by_local));
480
481 // Other
482 reg.add_internal_call("internal_m2n_rotate_axis_global", dotnet_internal_call(internal_m2n_rotate_axis_global));
483 reg.add_internal_call("internal_m2n_look_at", dotnet_internal_call(internal_m2n_look_at));
484 reg.add_internal_call("internal_m2n_transform_vector_global",
485 dotnet_internal_call(internal_m2n_transform_vector_global));
486 reg.add_internal_call("internal_m2n_inverse_transform_vector_global",
487 dotnet_internal_call(internal_m2n_inverse_transform_vector_global));
488
489 reg.add_internal_call("internal_m2n_transform_direction_global",
490 dotnet_internal_call(internal_m2n_transform_direction_global));
491 reg.add_internal_call("internal_m2n_inverse_transform_direction_global",
492 dotnet_internal_call(internal_m2n_inverse_transform_direction_global));
493
494 // Scale
495 reg.add_internal_call("internal_m2n_get_scale_global", dotnet_internal_call(internal_m2n_get_scale_global));
496 reg.add_internal_call("internal_m2n_set_scale_global", dotnet_internal_call(internal_m2n_set_scale_global));
497 reg.add_internal_call("internal_m2n_scale_by_global", dotnet_internal_call(internal_m2n_scale_by_local));
498
499 reg.add_internal_call("internal_m2n_get_scale_local", dotnet_internal_call(internal_m2n_get_scale_local));
500 reg.add_internal_call("internal_m2n_set_scale_local", dotnet_internal_call(internal_m2n_set_scale_local));
501 reg.add_internal_call("internal_m2n_scale_by_local", dotnet_internal_call(internal_m2n_scale_by_local));
502
503 // Skew
504 reg.add_internal_call("internal_m2n_get_skew_global", dotnet_internal_call(internal_m2n_get_skew_global));
505 reg.add_internal_call("internal_m2n_set_skew_globa", dotnet_internal_call(internal_m2n_setl_skew_globa));
506 reg.add_internal_call("internal_m2n_get_skew_local", dotnet_internal_call(internal_m2n_get_skew_local));
507 reg.add_internal_call("internal_m2n_set_skew_local", dotnet_internal_call(internal_m2n_set_skew_local));
508}
509
510} // namespace unravel
std::vector< render_pass_node > children
#define APPLOG_TRACE(...)
Definition logging.h:17
auto queue(seq_action action, const seq_scope_policy &scope_policy, hpp::source_location location) -> seq_id_t
Queues a new action.
Definition seq.cpp:14
auto tokenize(const std::string &str, const std::string &delimiters) -> string_tokens_t
Definition utils.cpp:153
void register_transform_component_script_bindings()
auto get_entity_from_id(entt::entity id) -> entt::handle
auto safe_get_component(entt::entity id) -> T *
entt::handle entity