Skip to content

Commit

Permalink
world: add utility functions to traverse the scene graph
Browse files Browse the repository at this point in the history
  • Loading branch information
dbartolini committed Dec 19, 2024
1 parent 963416e commit 4d88530
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Changelog
**Runtime**

* Lua API: 3D Gui will now place objects on the new XY plane (on the "floor") by default.
* Lua API: added ``SceneGraph.owner()``, ``SceneGraph.first_child()`` and ``SceneGraph.next_sibling()``.
* Data Compiler: .mesh resource can now have shared geometries between nodes.

0.53.0 --- 30 Nov 2024
Expand Down
11 changes: 11 additions & 0 deletions docs/lua_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,9 @@ SceneGraph
**instance** (sg, unit) : Id
Returns the ID of the transform owned by the *unit*, or ``nil``.

**owner** (sg, transform) : UnitId
Returns the unit that owns *transform*.

**local_position** (sg, transform) : Vector3
Returns the local position of the *transform*.

Expand Down Expand Up @@ -1272,6 +1275,14 @@ SceneGraph
Unlinks *child* from its parent if it has any. After unlinking, the local
pose of the *child* is set to its previous world pose.

**first_child** (sg, parent) : Id
Returns the first child of the instance *parent* or ``nil``
if *parent* has no children.

**next_sibling** (sg, child) : Id
Returns the next sibling of the instance *child* or ``nil``
if *child* has no sibling.

SoundWorld
===========

Expand Down
24 changes: 24 additions & 0 deletions src/lua/lua_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,12 @@ void load_api(LuaEnvironment &env)
stack.push_nil();
return 1;
});
env.add_module_function("SceneGraph", "owner", [](lua_State *L) {
LuaStack stack(L);
UnitId unit = stack.get_scene_graph(1)->owner(stack.get_transform_instance(2));
stack.push_unit(unit);
return 1;
});
env.add_module_function("SceneGraph", "local_position", [](lua_State *L) {
LuaStack stack(L);
stack.push_vector3(stack.get_scene_graph(1)->local_position(stack.get_transform_instance(2)));
Expand Down Expand Up @@ -1806,6 +1812,24 @@ void load_api(LuaEnvironment &env)
stack.get_scene_graph(1)->unlink(stack.get_transform_instance(2));
return 0;
});
env.add_module_function("SceneGraph", "first_child", [](lua_State *L) {
LuaStack stack(L);
TransformInstance inst = stack.get_scene_graph(1)->first_child(stack.get_transform_instance(2));
if (is_valid(inst))
stack.push_transform(inst);
else
stack.push_nil();
return 1;
});
env.add_module_function("SceneGraph", "next_sibling", [](lua_State *L) {
LuaStack stack(L);
TransformInstance inst = stack.get_scene_graph(1)->next_sibling(stack.get_transform_instance(2));
if (is_valid(inst))
stack.push_transform(inst);
else
stack.push_nil();
return 1;
});

env.add_module_function("UnitManager", "create", [](lua_State *L) {
LuaStack stack(L);
Expand Down
18 changes: 18 additions & 0 deletions src/world/scene_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ TransformInstance SceneGraph::instance(UnitId unit)
return make_instance(hash_map::get(_map, unit, UINT32_MAX));
}

UnitId SceneGraph::owner(TransformInstance transform)
{
CE_ASSERT(transform.i < _data.size, "Index out of bounds");
return _data.unit[transform.i];
}

bool SceneGraph::has(UnitId unit)
{
return hash_map::has(_map, unit);
Expand Down Expand Up @@ -381,6 +387,18 @@ void SceneGraph::unlink(TransformInstance child)
_data.prev_sibling[child.i].i = UINT32_MAX;
}

TransformInstance SceneGraph::first_child(TransformInstance parent)
{
CE_ASSERT(parent.i < _data.size, "Index out of bounds");
return _data.first_child[parent.i];
}

TransformInstance SceneGraph::next_sibling(TransformInstance child)
{
CE_ASSERT(child.i < _data.size, "Index out of bounds");
return _data.next_sibling[child.i];
}

void SceneGraph::clear_changed()
{
for (u32 i = 0; i < _data.size; ++i) {
Expand Down
11 changes: 11 additions & 0 deletions src/world/scene_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ struct SceneGraph
/// Returns the ID of the transform owned by the *unit*.
TransformInstance instance(UnitId unit);

/// Returns the unit that owns @a transform.
UnitId owner(TransformInstance transform);

/// Returns whether the @a unit has a transform.
bool has(UnitId unit);

Expand Down Expand Up @@ -144,6 +147,14 @@ struct SceneGraph
/// pose of the @a child is set to its previous world pose.
void unlink(TransformInstance child);

/// Returns the first child of the instance @a parent or an invalid
/// instance if @a parent has no children.
TransformInstance first_child(TransformInstance parent);

/// Returns the next sibling of the instance @a child or an invalid
/// instance if @a child has no sibling.
TransformInstance next_sibling(TransformInstance child);

void clear_changed();
void get_changed(Array<UnitId> &units, Array<Matrix4x4> &world_poses);
void set_local(TransformInstance transform);
Expand Down

0 comments on commit 4d88530

Please sign in to comment.