60 std::vector<std::string> messageLog;
68 void addGroup(Group mGroup)
override {
69 Entity::addGroup(mGroup);
70 manager.AddToGroup(
this, mGroup);
77 void update(
float deltaTime)
81 Entity::update(deltaTime);
84 void updatePorts(
float deltaTime)
override {
90 glm::vec3 m_position = glm::vec3(-tr->size.x / 2, 0.0f, 0.0f);
92 if (children[NodePorts::LEFT]) {
94 children[NodePorts::LEFT]->update(deltaTime);
95 for (
auto& portSlots : children[NodePorts::LEFT]->GetComponent<
PortComponent>().portSlots) {
96 portSlots->update(deltaTime);
100 m_position = glm::vec3(tr->size.x / 2, 0.0f, 0.0f);
102 if (children[NodePorts::RIGHT]) {
104 children[NodePorts::RIGHT]->update(deltaTime);
105 for (
auto& portSlots : children[NodePorts::RIGHT]->GetComponent<
PortComponent>().portSlots) {
106 portSlots->update(deltaTime);
110 m_position = glm::vec3(0.0f, -tr->size.y / 2.0f, 0.0f);
112 if (children[NodePorts::TOP]) {
114 children[NodePorts::TOP]->update(deltaTime);
115 for (
auto& portSlots : children[NodePorts::TOP]->GetComponent<
PortComponent>().portSlots) {
116 portSlots->update(deltaTime);
120 m_position = glm::vec3(0.0f, tr->size.y / 2.0f, 0.0f);
122 if (children[NodePorts::BOTTOM]) {
123 children[NodePorts::BOTTOM]->GetComponent<
TransformComponent>().position = m_position;
124 children[NodePorts::BOTTOM]->update(deltaTime);
125 for (
auto& portSlots : children[NodePorts::BOTTOM]->GetComponent<
PortComponent>().portSlots) {
126 portSlots->update(deltaTime);
131 void cellUpdate()
override{
132 if (this->ownerCell) {
135 Cell* newCell = manager.grid->getCell(*
this, manager.grid->getGridLevel());
136 if (newCell != this->ownerCell) {
137 std::scoped_lock lock(manager.movedNodesMutex);
139 manager.grid->addNode(
this, newCell);
141 manager.movedNodes.push_back(
this);
143 for (
auto& link : inLinks) {
144 link->updateArrowHeads();
146 for (
auto& link : outLinks) {
147 link->updateArrowHeads();
152 void addMessage(std::string mMessage)
override{
153 messageLog.push_back(mMessage);
156 void imgui_print()
override {
157 glm::vec2 position = this->GetComponent<TransformComponent>().getPosition();
158 ImGui::Text(
"Position: (%.2f, %.2f)", position.x, position.y);
161 if (ImGui::BeginTable(
"GroupsTable", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
162 ImGui::TableSetupColumn(
"Message Log", ImGuiTableColumnFlags_WidthStretch);
164 ImGui::TableHeadersRow();
165 for (
auto str : messageLog) {
166 ImGui::TableNextRow();
167 ImGui::TableSetColumnIndex(0);
168 ImGui::Text(
"%s", str.c_str());
176 void imgui_display()
override {
177 ImGui::Text(
"Display Info Here Node");
182 manager.aboutTo_updateActiveEntities();
186 bool hasChildren = std::all_of(children.begin(), children.end(),
187 [](
auto* c) { return c != nullptr; });
190 TazGraphEngine::ConsoleLogger::error(
"Node already has 4 children!");
196 auto& leftPort = getManager()->addEntityNoId<
Empty>();
197 leftPort.addGroup(Manager::groupPorts);
198 glm::vec3 m_position = glm::vec3(-tr->size.x / 2, 0.0f, 0.0f);
200 children[NodePorts::LEFT] = &leftPort;
201 children[NodePorts::LEFT]->setParentEntity(
this);
202 children[NodePorts::LEFT]->GetComponent<
TransformComponent>().bodyCenter = tr->bodyCenter + m_position;
203 children[NodePorts::LEFT]->addComponent<
PortComponent>(
true);
205 auto& rightPort = getManager()->addEntityNoId<
Empty>();
206 rightPort.addGroup(Manager::groupPorts);
207 m_position = glm::vec3(tr->size.x / 2 , 0.0f, 0.0f);
209 children[NodePorts::RIGHT] = &rightPort;
210 children[NodePorts::RIGHT]->setParentEntity(
this);
211 children[NodePorts::RIGHT]->GetComponent<
TransformComponent>().bodyCenter = tr->bodyCenter + m_position;
212 children[NodePorts::RIGHT]->addComponent<
PortComponent>(
true);
215 auto& topPort = getManager()->addEntityNoId<
Empty>();
216 topPort.addGroup(Manager::groupPorts);
217 m_position = glm::vec3(0.0f, -tr->size.y / 2.0f, 0.0f);
219 children[NodePorts::TOP] = &topPort;
220 children[NodePorts::TOP]->setParentEntity(
this);
221 children[NodePorts::TOP]->GetComponent<
TransformComponent>().bodyCenter = tr->bodyCenter + m_position;
222 children[NodePorts::TOP]->addComponent<
PortComponent>(
false);
225 auto& bottomPort = getManager()->addEntityNoId<
Empty>();
226 bottomPort.addGroup(Manager::groupPorts);
227 m_position = glm::vec3(0.0f, tr->size.y / 2.0f, 0.0f);
229 children[NodePorts::BOTTOM] = &bottomPort;
230 children[NodePorts::BOTTOM]->setParentEntity(
this);
231 children[NodePorts::BOTTOM]->GetComponent<
TransformComponent>().bodyCenter = tr->bodyCenter + m_position;
232 children[NodePorts::BOTTOM]->addComponent<
PortComponent>(
false);
246 void removePorts()
override {
247 for (
auto portName : { NodePorts::LEFT, NodePorts::RIGHT, NodePorts::TOP, NodePorts::BOTTOM }) {
248 if (children[portName]) {
249 children[portName]->destroy();
250 for (
auto slot : children[portName]->GetComponent<
PortComponent>().portSlots)
254 children[portName]->GetComponent<
PortComponent>().portSlots.clear();
255 children[portName] =
nullptr;
260 void removeSlots()
override {
261 for (
auto portName : { NodePorts::LEFT, NodePorts::RIGHT, NodePorts::TOP, NodePorts::BOTTOM }) {
262 if (children[portName]) {
263 for (
auto slot : children[portName]->GetComponent<
PortComponent>().portSlots)
267 children[portName]->GetComponent<
PortComponent>().portSlots.clear();
288 Link(
Manager& mManager,
unsigned int mfromId,
unsigned int mtoId)
291 from =
dynamic_cast<NodeEntity*
>(mManager.getEntityFromId(fromId));
292 from->addOutLink(
this);
293 to =
dynamic_cast<NodeEntity*
>(mManager.getEntityFromId(toId));
302 fromId = from->getId();
311 fromId = from->getId();
316 unsigned int mfromId,
unsigned int mtoId,
329 int m_fromPort,
int m_toPort,
int m_fromSlot,
int m_toSlot
333 m_fromPort, m_toPort,
334 m_fromSlot, m_toSlot)
339 void addGroup(Group mGroup)
override {
340 Entity::addGroup(mGroup);
341 manager.AddLinkToGroup(
this, mGroup);
348 void update(
float deltaTime)
override
350 Entity::update(deltaTime);
355 void cellUpdate()
override {
358 if (!ownerCells.empty()) {
359 auto level = manager.grid->getGridLevel();
360 const auto& fromCell = manager.grid->getCell(*getFromNode(), level);
361 const auto& toCell = manager.grid->getCell(*getToNode(), level);
363 const auto& ownerFront = ownerCells.front();
364 const auto& ownerBack = ownerCells.back();
366 if (fromCell != ownerFront
367 || toCell != ownerBack)
371 manager.grid->addLink(
this, manager.grid->getGridLevel());
377 void updateArrowHeads()
override {
378 if (children[LinkPorts::ARROWHEAD]) {
381 children[LinkPorts::ARROWHEAD]->update(0.0f);
389 glm::vec3 direction = toPortTR->getCenterTransform() - fromPortTR->getCenterTransform();
391 glm::vec3 unitDirection = glm::normalize(direction);
392 float offset = 10.0f;
394 glm::vec3 arrowHeadPos = toPortTR->getCenterTransform() - unitDirection * offset;
397 float angleRadians = -atan2(direction.y, direction.x);
398 float angleDegrees = glm::degrees(angleRadians);
400 glm::ivec3 arrowSize(10, 20, 0);
401 glm::vec3 farrowSize(10.0f, 20.0f, 0.0f);
403 glm::vec3 newArrowHeadPosition = arrowHeadPos - (farrowSize / 2.0f);
404 children[LinkPorts::ARROWHEAD]->GetComponent<
TransformComponent>().position = newArrowHeadPosition;
406 children[LinkPorts::ARROWHEAD]->GetComponent<
TransformComponent>().setRotation(glm::vec3(0.0f, 0.0f, angleRadians + glm::half_pi<float>()));
410 void updateConnectedPorts()
override{
414 int newFromPort = getBestPortForConnection(fromTR->getCenterTransform(), toTR->getCenterTransform());
415 int newToPort = getBestPortForConnection(toTR->getCenterTransform(), fromTR->getCenterTransform());
417 fromSlotIndex = assignSlotIndex(from, newFromPort, fromPort, fromSlotIndex);
418 toSlotIndex = assignSlotIndex(to, newToPort, toPort, toSlotIndex);
420 fromPort = newFromPort;
424 void addArrowHead()
override {
428 fromPort = getBestPortForConnection(fromTR->getCenterTransform(), toTR->getCenterTransform());
429 toPort = getBestPortForConnection(toTR->getCenterTransform(), fromTR->getCenterTransform());
434 glm::vec3 direction = toPortTR->getCenterTransform() - fromPortTR->getCenterTransform();
436 glm::vec3 unitDirection = glm::normalize(direction);
437 float offset = 10.0f;
439 glm::vec3 arrowHeadPos = toPortTR->getCenterTransform() - unitDirection * offset;
441 auto& temp_arrowHead = getManager()->addEntityNoId<
Empty>();
444 float angleRadians = -atan2(direction.y, direction.x);
445 float angleDegrees = glm::degrees(angleRadians);
447 glm::vec3 farrowSize(10.0f, 20.0f, 0.0f);
449 temp_arrowHead.addComponent<
TransformComponent>(arrowHeadPos - (farrowSize /2.0f), farrowSize, 1);
453 temp_arrowHead.GetComponent<
TransformComponent>().setRotation(glm::vec3(0.0f, 0.0f, angleRadians + glm::half_pi<float>()));
455 temp_arrowHead.addGroup(Manager::groupArrowHeads_0);
457 temp_arrowHead.setParentEntity(
this);
459 manager.grid->addEmpty(&temp_arrowHead, manager.grid->getGridLevel());
461 children[LinkPorts::ARROWHEAD] = &temp_arrowHead;
464 void removeArrowHead()
override {
465 if (children[LinkPorts::ARROWHEAD]) {
466 children[LinkPorts::ARROWHEAD]->removeFromCell();
467 children[LinkPorts::ARROWHEAD]->destroy();
468 children[LinkPorts::ARROWHEAD] =
nullptr;
472 void resetPorts()
override {
477 int getBestPortForConnection(
const glm::vec3& fromPos,
const glm::vec3& toPos) {
479 float deltaX = toPos.x - fromPos.x;
480 float deltaY = toPos.y - fromPos.y;
482 if (abs(deltaX) > abs(deltaY)) {
483 return deltaX > 0 ? NodePorts::RIGHT : NodePorts::LEFT;
486 return deltaY > 0 ? NodePorts::BOTTOM : NodePorts::TOP;
490 int assignSlotIndex(
NodeEntity* node,
int newPort,
int oldPort,
int oldSlotIndex) {
492 if (oldPort != -1 && oldPort != newPort && oldPort < (
int)node->children.size()) {
493 Entity* oldPortEntity = node->children[oldPort];
494 if (oldPortEntity && oldPortEntity->hasComponent<
PortComponent>()) {
495 auto& oldSlots = oldPortEntity->GetComponent<
PortComponent>().portSlots;
497 if (oldSlotIndex >= 0 && oldSlotIndex < (
int)oldSlots.size()) {
498 EmptyEntity* slotToRemove = oldSlots[oldSlotIndex];
500 oldSlots.erase(oldSlots.begin() + oldSlotIndex);
501 slotToRemove->destroy();
503 updateLinksSlotIndices(node, oldPort, oldSlotIndex);
508 if (oldPort != newPort) {
509 if (newPort < 0 || newPort >= (
int)node->children.size()) {
513 Entity* newPortEntity = node->children[newPort];
514 if (!newPortEntity || !newPortEntity->hasComponent<
PortComponent>()) {
518 auto& newSlots = newPortEntity->GetComponent<
PortComponent>().portSlots;
520 auto& newSlot = node->getManager()->addEntityNoId<
Empty>();
521 newSlot.addGroup(Manager::groupPortSlots);
524 portTransform.bodyCenter,
533 newSlot.setParentEntity(newPortEntity);
534 newSlots.push_back(&newSlot);
536 return static_cast<int>(newSlots.size() - 1);
542 void updateLinksSlotIndices(
NodeEntity* node,
int portIndex,
int removedSlotIndex) {
543 for (
auto& linkEntity : node->getOutLinks()) {
545 if (linkEntity->fromPort == portIndex &&
546 linkEntity->fromSlotIndex > removedSlotIndex) {
547 linkEntity->fromSlotIndex--;
551 for (
auto& linkEntity : node->getInLinks()) {
553 if (linkEntity->toPort == portIndex &&
554 linkEntity->toSlotIndex > removedSlotIndex) {
555 linkEntity->toSlotIndex--;
560 void imgui_print()
override {
561 glm::vec2 fromNodePosition = this->getFromNode()->GetComponent<
TransformComponent>().getCenterTransform();
562 glm::vec2 toNodePosition = this->getToNode()->GetComponent<
TransformComponent>().getCenterTransform();
564 ImGui::Text(
"From Node Position: (%.2f, %.2f)", fromNodePosition.x, fromNodePosition.y);
565 ImGui::Text(
"To Node Position: (%.2f, %.2f)", toNodePosition.x, toNodePosition.y);
567 ImGui::Text(
"Bounding boxes of intercepted cells:");
569 for (
auto cell : ownerCells) {
570 ImGui::Text(
"- %.2f , %.2f , %.2f", cell->boundingBox_origin.x, cell->boundingBox_origin.y, cell->boundingBox_origin.z);
574 void imgui_display()
override {
575 ImGui::Text(
"Display Info Here Link");
581 if (children[LinkPorts::ARROWHEAD]) {
582 children[LinkPorts::ARROWHEAD]->destroy();
585 manager.aboutTo_updateActiveEntities();