77#include " DrawDebugHelpers.h"
88#include " Runtime/Engine/Classes/Components/LineBatchComponent.h"
99#include " Runtime/Engine/Classes/Engine/Engine.h"
10+ #include " Misc/OutputDeviceNull.h"
1011#include " ImageUtils.h"
1112#include < cstdlib>
1213#include < ctime>
14+ #include < algorithm>
1315
1416WorldSimApi::WorldSimApi (ASimModeBase* simmode)
1517 : simmode_(simmode) {}
@@ -83,65 +85,69 @@ bool WorldSimApi::destroyObject(const std::string& object_name)
8385 return result;
8486}
8587
86- std::string WorldSimApi::spawnObject (std::string& object_name, const std::string& load_object, const WorldSimApi::Pose& pose, const WorldSimApi::Vector3r& scale, bool physics_enabled)
88+ std::string WorldSimApi::spawnObject (const std::string& object_name, const std::string& load_object, const WorldSimApi::Pose& pose, const WorldSimApi::Vector3r& scale, bool physics_enabled, bool is_blueprint )
8789{
90+ FString asset_name (load_object.c_str ());
91+ FAssetData* load_asset = simmode_->asset_map .Find (asset_name);
92+
93+ if (!load_asset->IsValid ()) {
94+ throw std::invalid_argument (" There were no objects with name " + load_object + " found in the Registry" );
95+ }
96+
8897 // Create struct for Location and Rotation of actor in Unreal
8998 FTransform actor_transform = simmode_->getGlobalNedTransform ().fromGlobalNed (pose);
9099
91- bool found_object = false , spawned_object = false ;
92- UAirBlueprintLib::RunCommandOnGameThread ([this , load_object, &object_name, &actor_transform, &found_object, &spawned_object, &scale, &physics_enabled]() {
93- FString asset_name = FString (load_object.c_str ());
94- FAssetData* LoadAsset = simmode_->asset_map .Find (asset_name);
95-
96- if (LoadAsset) {
97- found_object = true ;
98- UStaticMesh* LoadObject = dynamic_cast <UStaticMesh*>(LoadAsset->GetAsset ());
99- std::vector<std::string> matching_names = UAirBlueprintLib::ListMatchingActors (simmode_->GetWorld (), " .*" + object_name + " .*" );
100- if (matching_names.size () > 0 ) {
101- size_t greatest_num{ 0 }, result{ 0 };
102- for (auto match : matching_names) {
103- std::string number_extension = match.substr (match.find_last_not_of (" 0123456789" ) + 1 );
104- if (number_extension != " " ) {
105- result = std::stoi (number_extension);
106- greatest_num = greatest_num > result ? greatest_num : result;
107- }
100+ bool spawned_object = false ;
101+ std::string final_object_name = object_name;
102+
103+ UAirBlueprintLib::RunCommandOnGameThread ([this , load_asset, &final_object_name, &spawned_object, &actor_transform, &scale, &physics_enabled, &is_blueprint]() {
104+ // Ensure new non-matching name for the object
105+ std::vector<std::string> matching_names = UAirBlueprintLib::ListMatchingActors (simmode_, " .*" + final_object_name + " .*" );
106+ if (matching_names.size () > 0 ) {
107+ int greatest_num{ 0 };
108+ for (const auto & match : matching_names) {
109+ std::string number_extension = match.substr (match.find_last_not_of (" 0123456789" ) + 1 );
110+ if (number_extension != " " ) {
111+ greatest_num = std::max (greatest_num, std::stoi (number_extension));
108112 }
109- object_name += std::to_string (greatest_num + 1 );
110- }
111- FActorSpawnParameters new_actor_spawn_params;
112- new_actor_spawn_params.Name = FName (object_name.c_str ());
113- // new_actor_spawn_params.NameMode = FActorSpawnParameters::ESpawnActorNameMode::Required_ReturnNull;
114- AActor* NewActor = this ->createNewActor (new_actor_spawn_params, actor_transform, scale, LoadObject);
115-
116- if (NewActor) {
117- spawned_object = true ;
118- simmode_->scene_object_map .Add (FString (object_name.c_str ()), NewActor);
119113 }
114+ final_object_name += std::to_string (greatest_num + 1 );
115+ }
116+
117+ FActorSpawnParameters new_actor_spawn_params;
118+ new_actor_spawn_params.Name = FName (final_object_name.c_str ());
120119
121- UAirBlueprintLib::setSimulatePhysics (NewActor, physics_enabled);
120+ AActor* NewActor;
121+ if (is_blueprint) {
122+ UBlueprint* LoadObject = Cast<UBlueprint>(load_asset->GetAsset ());
123+ NewActor = this ->createNewBPActor (new_actor_spawn_params, actor_transform, scale, LoadObject);
122124 }
123125 else {
124- found_object = false ;
126+ UStaticMesh* LoadObject = dynamic_cast <UStaticMesh*>(load_asset->GetAsset ());
127+ NewActor = this ->createNewStaticMeshActor (new_actor_spawn_params, actor_transform, scale, LoadObject);
125128 }
129+
130+ if (IsValid (NewActor)) {
131+ spawned_object = true ;
132+ simmode_->scene_object_map .Add (FString (final_object_name.c_str ()), NewActor);
133+ }
134+
135+ UAirBlueprintLib::setSimulatePhysics (NewActor, physics_enabled);
126136 },
127137 true );
128138
129- if (!found_object) {
130- throw std::invalid_argument (
131- " There were no objects with name " + load_object + " found in the Registry" );
132- }
133139 if (!spawned_object) {
134140 throw std::invalid_argument (
135141 " Engine could not spawn " + load_object + " because of a stale reference of same name" );
136142 }
137- return object_name ;
143+ return final_object_name ;
138144}
139145
140- AActor* WorldSimApi::createNewActor (const FActorSpawnParameters& spawn_params, const FTransform& actor_transform, const Vector3r& scale, UStaticMesh* static_mesh)
146+ AActor* WorldSimApi::createNewStaticMeshActor (const FActorSpawnParameters& spawn_params, const FTransform& actor_transform, const Vector3r& scale, UStaticMesh* static_mesh)
141147{
142148 AActor* NewActor = simmode_->GetWorld ()->SpawnActor <AActor>(AActor::StaticClass (), FVector::ZeroVector, FRotator::ZeroRotator, spawn_params);
143149
144- if (NewActor) {
150+ if (IsValid ( NewActor) ) {
145151 UStaticMeshComponent* ObjectComponent = NewObject<UStaticMeshComponent>(NewActor);
146152 ObjectComponent->SetStaticMesh (static_mesh);
147153 ObjectComponent->SetRelativeLocation (FVector (0 , 0 , 0 ));
@@ -154,6 +160,33 @@ AActor* WorldSimApi::createNewActor(const FActorSpawnParameters& spawn_params, c
154160 return NewActor;
155161}
156162
163+ AActor* WorldSimApi::createNewBPActor (const FActorSpawnParameters& spawn_params, const FTransform& actor_transform, const Vector3r& scale, UBlueprint* blueprint)
164+ {
165+ UClass* new_bp = static_cast <UClass*>(blueprint->GeneratedClass );
166+ AActor* new_actor = simmode_->GetWorld ()->SpawnActor <AActor>(new_bp, FVector::ZeroVector, FRotator::ZeroRotator, spawn_params);
167+
168+ if (new_actor) {
169+ new_actor->SetActorLocationAndRotation (actor_transform.GetLocation (), actor_transform.GetRotation (), false , nullptr , ETeleportType::TeleportPhysics);
170+ }
171+ return new_actor;
172+ }
173+
174+ bool WorldSimApi::setLightIntensity (const std::string& light_name, float intensity)
175+ {
176+ bool result = false ;
177+ UAirBlueprintLib::RunCommandOnGameThread ([this , &light_name, &intensity, &result]() {
178+ AActor* light_actor = simmode_->scene_object_map .FindRef (FString (light_name.c_str ()));
179+
180+ if (light_actor) {
181+ const FString command = FString::Printf (TEXT (" SetIntensity %f" ), intensity);
182+ FOutputDeviceNull ar;
183+ result = light_actor->CallFunctionByNameWithArguments (*command, ar, nullptr , true );
184+ }
185+ },
186+ true );
187+ return result;
188+ }
189+
157190bool WorldSimApi::createVoxelGrid (const Vector3r& position, const int & x_size, const int & y_size, const int & z_size, const float & res, const std::string& output_file)
158191{
159192 bool success = false ;
0 commit comments