@@ -161,6 +161,79 @@ AActor* WorldSimApi::createNewActor(const FActorSpawnParameters& spawn_params, c
161161 return NewActor;
162162}
163163
164+ bool 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)
165+ {
166+ bool success = false ;
167+ int ncells_x = x_size / res;
168+ int ncells_y = y_size / res;
169+ int ncells_z = z_size / res;
170+
171+ voxel_grid_.resize (ncells_x * ncells_y * ncells_z);
172+
173+ float scale_cm = res * 100 ;
174+ FCollisionQueryParams params;
175+ params.bFindInitialOverlaps = true ;
176+ params.bTraceComplex = false ;
177+ params.TraceTag = " " ;
178+ auto position_in_UE_frame = simmode_->getGlobalNedTransform ().fromGlobalNed (position);
179+ for (float i = 0 ; i < ncells_x; i++) {
180+ for (float k = 0 ; k < ncells_z; k++) {
181+ for (float j = 0 ; j < ncells_y; j++) {
182+ int idx = i + ncells_x * (k + ncells_z * j);
183+ FVector position = FVector ((i - ncells_x /2 ) * scale_cm, (j - ncells_y /2 ) * scale_cm, (k - ncells_z /2 ) * scale_cm) + position_in_UE_frame;
184+ voxel_grid_[idx] = simmode_->GetWorld ()->OverlapBlockingTestByChannel (position, FQuat::Identity, ECollisionChannel::ECC_Pawn, FCollisionShape::MakeBox (FVector (scale_cm /2 )), params);
185+ }
186+ }
187+ }
188+
189+ std::ofstream output (output_file, std::ios::out | std::ios::binary);
190+ if (!output.good ())
191+ {
192+ UE_LOG (LogTemp, Error, TEXT (" Could not open output file to write voxel grid!" ));
193+ return success;
194+ }
195+
196+ // Write the binvox file using run-length encoding
197+ // where each pair of bytes is of the format (run value, run length)
198+ output << " #binvox 1\n " ;
199+ output << " dim " << ncells_x << " " << ncells_z << " " << ncells_y << " \n " ;
200+ output << " translate " << -x_size * 0.5 << " " << -y_size * 0.5 << " " << -z_size * 0.5 << " \n " ;
201+ output << " scale " << 1 .0f /x_size << " \n " ;
202+ output << " data\n " ;
203+ bool run_value = voxel_grid_[0 ];
204+ unsigned int run_length = 0 ;
205+ for (size_t i = 0 ; i < voxel_grid_.size (); ++i)
206+ {
207+ if (voxel_grid_[i] == run_value)
208+ {
209+ // This is a run (repeated bit value)
210+ run_length++;
211+ if (run_length == 255 )
212+ {
213+ output << static_cast <char >(run_value);
214+ output << static_cast <char >(run_length);
215+ run_length = 0 ;
216+ }
217+ }
218+ else
219+ {
220+ // End of a run
221+ output << static_cast <char >(run_value);
222+ output << static_cast <char >(run_length);
223+ run_value = voxel_grid_[i];
224+ run_length = 1 ;
225+ }
226+ }
227+ if (run_length > 0 )
228+ {
229+ output << static_cast <char >(run_value);
230+ output << static_cast <char >(run_length);
231+ }
232+ output.close ();
233+ success = true ;
234+ return success;
235+ }
236+
164237bool WorldSimApi::isPaused () const
165238{
166239 return simmode_->isPaused ();
0 commit comments