| 549 | } |
| 550 | |
| 551 | void AMjArticulation::PostSetup(mjModel* Model, mjData* Data) |
| 552 | { |
| 553 | m_model = Model; |
| 554 | m_data = Data; |
| 555 | |
| 556 | TArray<UMjComponent*> AllMjComponents; |
| 557 | GetRuntimeComponents<UMjComponent>(AllMjComponents); |
| 558 | |
| 559 | UE_LOG(LogURLab, Log, TEXT("AMjArticulation::PostSetup - Found %d runtime MjComponents for articulation '%s'"), AllMjComponents.Num(), *GetName()); |
| 560 | for (UMjComponent* MjComp : AllMjComponents) |
| 561 | { |
| 562 | if (MjComp) |
| 563 | MjComp->Bind(Model, Data, m_prefix); |
| 564 | } |
| 565 | |
| 566 | // Build component-name maps for Blueprint API (O(1) look up by name) |
| 567 | // We use the MuJoCo-side name (GetMjName()) as the key for consistency with UI/data. |
| 568 | ActuatorComponentMap.Empty(); |
| 569 | JointComponentMap.Empty(); |
| 570 | SensorComponentMap.Empty(); |
| 571 | BodyComponentMap.Empty(); |
| 572 | TendonComponentMap.Empty(); |
| 573 | EqualityComponentMap.Empty(); |
| 574 | KeyframeComponentMap.Empty(); |
| 575 | |
| 576 | for (UMjComponent* MjComp : AllMjComponents) |
| 577 | { |
| 578 | FString UE_Name = MjComp->GetName(); |
| 579 | FString MJ_Name = MjComp->GetMjName(); |
| 580 | |
| 581 | auto AddToMap = [&](auto& Map, auto* Comp) { |
| 582 | if (!UE_Name.IsEmpty()) |
| 583 | Map.Add(UE_Name, Comp); |
| 584 | if (!MJ_Name.IsEmpty() && MJ_Name != UE_Name) |
| 585 | Map.Add(MJ_Name, Comp); |
| 586 | }; |
| 587 | |
| 588 | if (UMjActuator* A = Cast<UMjActuator>(MjComp)) |
| 589 | AddToMap(ActuatorComponentMap, A); |
| 590 | else if (UMjJoint* J = Cast<UMjJoint>(MjComp)) |
| 591 | AddToMap(JointComponentMap, J); |
| 592 | else if (UMjSensor* S = Cast<UMjSensor>(MjComp)) |
| 593 | AddToMap(SensorComponentMap, S); |
| 594 | else if (UMjBody* B = Cast<UMjBody>(MjComp)) |
| 595 | AddToMap(BodyComponentMap, B); |
| 596 | else if (UMjTendon* T = Cast<UMjTendon>(MjComp)) |
| 597 | AddToMap(TendonComponentMap, T); |
| 598 | else if (UMjEquality* E = Cast<UMjEquality>(MjComp)) |
| 599 | AddToMap(EqualityComponentMap, E); |
| 600 | else if (UMjKeyframe* K = Cast<UMjKeyframe>(MjComp)) |
| 601 | AddToMap(KeyframeComponentMap, K); |
| 602 | } |
| 603 | |
| 604 | UE_LOG(LogURLab, Log, TEXT("AMjArticulation::PostSetup - %s maps (using prefix '%s'): %d actuators, %d joints, %d sensors, %d bodies, %d tendons"), |
| 605 | *GetName(), *m_prefix, ActuatorComponentMap.Num(), JointComponentMap.Num(), SensorComponentMap.Num(), BodyComponentMap.Num(), TendonComponentMap.Num()); |
| 606 | |
| 607 | // Build MuJoCo ID maps (O(1) resolve from ID to Component) |
| 608 | BodyIdMap.Empty(); |
no test coverage detected