Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
BTGraphLayoutEngine.cpp
Go to the documentation of this file.
1// [DEPRECATED - Phase 5 - 2026-03-07]
2// Ce fichier est archivé. Il ne doit plus être inclus ni compilé.
3// Remplacé par : NodeGraph::FromJson + positions JSON sauvegardées (BTGraphDocumentConverter)
4// Voir : Docs/BLUEPRINT-REFACTOR-MARCH-2026.md
5
6/**
7 * @file BTGraphLayoutEngine.cpp
8 * @brief Implementation of graph layout engine for behavior tree visualization
9 */
10
11#include "BTGraphLayoutEngine.h"
12#include "../system/system_utils.h"
13#include <queue>
14#include <algorithm>
15
16namespace Olympe
17{
21
22 std::vector<BTNodeLayout> BTGraphLayoutEngine::ComputeLayout(
24 float nodeSpacingX,
25 float nodeSpacingY,
26 float zoomFactor)
27 {
28 // Suppress unused parameter warnings (fixed grid is used)
29 static_cast<void>(nodeSpacingX);
30 static_cast<void>(nodeSpacingY);
31 static_cast<void>(zoomFactor);
32
33 if (!tree || tree->nodes.empty())
34 {
35 return {};
36 }
37
38 // Clear previous state
39 m_layouts.clear();
40 m_nodeIdToIndex.clear();
41 m_layers.clear();
42 m_parentMap.clear();
43
44 // Phase 1: Assign nodes to layers via BFS
46
47 // Phase 2: Place nodes on fixed 400x200 grid (horizontal layout)
48 // layers become columns (x-axis), order within layer becomes rows (y-axis)
49 const float gridColumnSpacing = 400.0f; // pixels between adjacent layers (columns)
50 const float gridRowSpacing = 200.0f; // pixels between nodes in the same layer (rows)
51
52 for (auto& layout : m_layouts)
53 {
54 layout.position.x = layout.layer * gridColumnSpacing;
55 layout.position.y = layout.orderInLayer * gridRowSpacing;
56 }
57
58 SYSTEM_LOG << "[BTGraphLayout] Layout complete: " << m_layouts.size()
59 << " nodes positioned" << std::endl;
60
61 return m_layouts;
62 }
63
65 {
66 auto it = m_nodeIdToIndex.find(nodeId);
67 if (it != m_nodeIdToIndex.end())
68 {
69 return &m_layouts[it->second];
70 }
71 return nullptr;
72 }
73
75 {
76 auto it = m_nodeIdToIndex.find(nodeId);
77 if (it == m_nodeIdToIndex.end())
78 return false;
79 m_layouts[it->second].position.x = x;
80 m_layouts[it->second].position.y = y;
81 return true;
82 }
83
85 {
86 // BFS from root to assign layers
87 std::queue<std::pair<uint32_t, int>> queue; // (nodeId, layer)
88 std::map<uint32_t, int> visitedLayers;
89
90 queue.push({tree->rootNodeId, 0});
91 visitedLayers[tree->rootNodeId] = 0;
92
93 int maxLayer = 0;
94
95 while (!queue.empty())
96 {
97 std::pair<uint32_t, int> front = queue.front();
98 uint32_t nodeId = front.first;
99 int layer = front.second;
100 queue.pop();
101
102 const BTNode* node = tree->GetNode(nodeId);
103 if (!node)
104 continue;
105
106 // Create layout for this node
108 layout.nodeId = nodeId;
109 layout.layer = layer;
110 layout.orderInLayer = 0; // Will be set below
111
112 size_t idx = m_layouts.size();
113 m_layouts.push_back(layout);
114 m_nodeIdToIndex[nodeId] = idx;
115
116 maxLayer = std::max(maxLayer, layer);
117
118 // Get children and add to queue
119 auto children = GetChildren(node);
120 for (uint32_t childId : children)
121 {
122 // Only visit each node once (shortest path from root)
123 if (visitedLayers.find(childId) == visitedLayers.end())
124 {
125 visitedLayers[childId] = layer + 1;
126 queue.push({childId, layer + 1});
127 }
128 }
129 }
130
131 // Organize nodes into layers and set orderInLayer
132 m_layers.resize(maxLayer + 1);
133 for (const auto& layout : m_layouts)
134 {
135 m_layers[layout.layer].push_back(layout.nodeId);
136 }
137
138 for (size_t layerIdx = 0; layerIdx < m_layers.size(); ++layerIdx)
139 {
140 const auto& layer = m_layers[layerIdx];
141 for (size_t i = 0; i < layer.size(); ++i)
142 {
143 auto it = m_nodeIdToIndex.find(layer[i]);
144 if (it != m_nodeIdToIndex.end())
145 {
146 m_layouts[it->second].orderInLayer = static_cast<int>(i);
147 }
148 }
149 }
150
151 // Build parent map for reference
153 }
154
155 std::vector<uint32_t> BTGraphLayoutEngine::GetChildren(const BTNode* node) const
156 {
157 if (!node)
158 return {};
159
160 std::vector<uint32_t> children;
161
162 // Composite nodes (Selector, Sequence)
163 if (node->type == BTNodeType::Selector || node->type == BTNodeType::Sequence)
164 {
165 children = node->childIds;
166 }
167 // Decorator nodes (Inverter, Repeater)
168 else if (node->type == BTNodeType::Inverter || node->type == BTNodeType::Repeater)
169 {
170 if (node->decoratorChildId != 0)
171 {
172 children.push_back(node->decoratorChildId);
173 }
174 }
175
176 return children;
177 }
178
180 {
181 m_parentMap.clear();
182
183 for (const auto& node : tree->nodes)
184 {
185 auto children = GetChildren(&node);
186 for (uint32_t childId : children)
187 {
188 m_parentMap[childId].push_back(node.id);
189 }
190 }
191 }
192
193} // namespace Olympe
Graph layout engine for behavior tree visualization.
@ Selector
OR node - succeeds if any child succeeds.
@ Sequence
AND node - succeeds if all children succeed.
@ Inverter
Decorator - inverts child result.
@ Repeater
Decorator - repeats child N times.
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
bool UpdateNodePosition(uint32_t nodeId, float x, float y)
Update the stored position for a node (e.g.
const BTNodeLayout * GetNodeLayout(uint32_t nodeId) const
Get computed layout for a specific node.
std::vector< BTNodeLayout > m_layouts
std::vector< uint32_t > GetChildren(const BTNode *node) const
void BuildParentMap(const BehaviorTreeAsset *tree)
std::map< uint32_t, size_t > m_nodeIdToIndex
std::map< uint32_t, std::vector< uint32_t > > m_parentMap
void AssignLayers(const BehaviorTreeAsset *tree)
std::vector< BTNodeLayout > ComputeLayout(const BehaviorTreeAsset *tree, float nodeSpacingX=320.0f, float nodeSpacingY=180.0f, float zoomFactor=1.0f)
Compute layout for a behavior tree.
std::vector< std::vector< uint32_t > > m_layers
float x
Definition vector.h:25
< Provides AssetID and INVALID_ASSET_ID
Represents a single node in a behavior tree.
Layout information for a single behavior tree node.
Vector position
Final position (x, y)
uint32_t nodeId
BT node ID.
#define SYSTEM_LOG