3 #define MAX_BUFFER_U16 0xFFFF 6 inline UTexture2D*
Get(TUniquePtr<T>& Dtex) {
return Dtex.Get() ? Dtex.Get()->GetTextureObject() :
nullptr; }
14 return depth.get_depth_scale();
20 ARealSenseInspector::ARealSenseInspector(
const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
24 PrimaryActorTick.bCanEverTick =
true;
26 RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT(
"Root"));
28 PclMesh = CreateDefaultSubobject<URuntimeMeshComponent>(TEXT(
"RuntimeMeshComponent"));
29 PclMesh->SetVisibility(
false);
30 PclMesh->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
31 PclMesh->Mobility = EComponentMobility::Movable;
32 #if ENGINE_MAJOR_VERSION >= 4 && ENGINE_MINOR_VERSION >= 20 33 PclMesh->SetGenerateOverlapEvents(
false);
35 PclMesh->bGenerateOverlapEvents =
false;
37 PclMesh->SetupAttachment(RootComponent);
38 GetDeviceDefaultProfileConfig();
50 REALSENSE_TRACE(TEXT(
"ARealSenseInspector::InitializeDeviceProfile %p"),
this);
56 throw std::runtime_error(
"GetContext failed");
64 throw std::runtime_error(
"No devices available");
71 throw std::runtime_error(
"Device not found");
75 if (depthProfiles.Num() > 0)
77 auto profile = depthProfiles[depthProfiles.Num()-1];
85 if (colorProfiles.Num() > 0)
87 auto profile = colorProfiles[colorProfiles.Num()-1];
100 if (infraredProfiles.Num() > 0)
102 auto profile = infraredProfiles[infraredProfiles.Num()-1];
111 auto what(
uestr(ex.what()));
115 REALSENSE_ERR(TEXT(
"ARealSenseInspector::GetDeviceDefaultProfileConfig exception: %s (FUNC %s ; ARGS %s ; TYPE %d"), *what, *
func, *
args, (
int)ex.
get_type());
117 catch (
const std::exception& ex)
119 REALSENSE_ERR(TEXT(
"ARealSenseInspector::GetDeviceDefaultProfileConfig exception: %s"), ANSI_TO_TCHAR(ex.what()));
122 REALSENSE_TRACE(TEXT(
"ARealSenseInspector::GetDeviceDefaultProfileConfig finished."));
137 throw std::runtime_error(
"Already started");
145 throw std::runtime_error(
"GetContext failed");
155 RsConfig.enable_device_from_file(TCHAR_TO_ANSI(*
CaptureFile));
164 throw std::runtime_error(
"No devices available");
171 throw std::runtime_error(
"Device not found");
247 RsConfig.enable_record_to_file(TCHAR_TO_ANSI(*
CaptureFile));
250 FlushRenderingCommands();
265 FString ThreadName(FString::Printf(TEXT(
"FRealSenseInspectorWorker_%s"), *FGuid::NewGuid().ToString()));
266 Thread.Reset(FRunnableThread::Create(
Worker.Get(), *ThreadName, 0, TPri_Normal));
269 throw std::runtime_error(
"CreateThread failed");
274 auto what(
uestr(ex.what()));
281 catch (
const std::exception& ex)
283 REALSENSE_ERR(TEXT(
"ARealSenseInspector::Start exception: %s"), ANSI_TO_TCHAR(ex.what()));
320 Thread->WaitForCompletion();
337 ENQUEUE_RENDER_COMMAND(FlushCommand)(
338 [](FRHICommandListImmediate& RHICmdList)
340 GRHICommandList.GetImmediateCommandList().ImmediateFlush(EImmediateFlushType::FlushRHIThreadFlushResources);
342 GRHICommandList.GetImmediateCommandList().ImmediateFlush(EImmediateFlushType::FlushRHIThreadFlushResources);
344 FlushRenderingCommands();
362 catch (
const std::exception& ex)
364 REALSENSE_ERR(TEXT(
"ARealSenseInspector::Stop exception: %s"), ANSI_TO_TCHAR(ex.what()));
367 #if defined(PROF_ENABLED) 368 Profiler::GetInstance()->LogSummary();
374 REALSENSE_TRACE(TEXT(
"Enter ARealSenseInspector::ThreadProc %p"),
this);
390 catch (
const std::exception& ex)
392 REALSENSE_ERR(TEXT(
"ARealSenseInspector::ThreadProc exception: %s"), ANSI_TO_TCHAR(ex.what()));
396 REALSENSE_TRACE(TEXT(
"Leave ARealSenseInspector::ThreadProc %p"),
this);
401 const double t0 = FPlatformTime::Seconds();
409 GotFrames =
RsPipeline->poll_for_frames(&Frameset);
413 REALSENSE_TRACE(TEXT(
"poll_for_frames failed: %s"), ANSI_TO_TCHAR(ex.what()));
422 const double t1 = FPlatformTime::Seconds();
423 const double dt = t1 -
t0;
443 REALSENSE_TRACE(TEXT(
"wait_for_frames failed: %s"), ANSI_TO_TCHAR(ex.what()));
526 Super::Tick(DeltaSeconds);
557 const size_t NumPoints =
RsPoints->size();
558 const size_t DensityPoints = (
size_t)FMath::RoundToInt(NumPoints * FMath::Clamp(
PclDensity, 0.0
f, 1.0
f));
559 if (!DensityPoints) {
PclMesh->SetVisibility(
false);
return; }
561 const size_t Step = (
size_t)FMath::RoundToInt(NumPoints / (
float)DensityPoints);
562 if (!Step) {
PclMesh->SetVisibility(
false);
return; }
564 const size_t RenderPoints = (NumPoints / Step);
565 const size_t RenderVertices = RenderPoints * 4;
566 const size_t RenderIndices = RenderPoints * 6;
568 const size_t NumSections = (RenderIndices / MaxBufferIndices) + (RenderIndices % MaxBufferIndices ? 1 : 0);
572 "PCL Id=%zu NumPoints=%zu " 573 "RenderPoints=%zu RenderVertices=%zu RenderIndices=%zu NumSections=%zu " 574 "Density=%.3f Step=%zu"),
576 RenderPoints, RenderVertices, RenderIndices, NumSections,
584 FPointCloudVertex PV[4];
586 size_t SectionId = 0;
590 size_t NumInvalid = 0;
592 while (PointId < NumPoints && SectionId < NumSections)
597 PclMeshData.Add(SectionId, MakeUnique<FMeshSection>());
602 if (!
PclMesh->DoesSectionExist(SectionId))
605 PclMesh->CreateMeshSection(SectionId,
PclMeshData[SectionId]->PclVertices,
PclMeshData[SectionId]->PclIndices,
false, EUpdateFrequency::Frequent);
609 FPointCloudVertex* DstVertices = &(
PclMeshData[SectionId]->PclVertices[0]);
610 int32* DstIndices = &(
PclMeshData[SectionId]->PclIndices[0]);
615 while (PointId < NumPoints && IndexId + 6 <= MaxBufferIndices)
617 const auto V = SrcVertices[PointId];
628 const FVector Pos = FVector(
V.z,
V.x, -
V.y) * 100.0f *
PclScale;
630 PV[0].Position = FVector(Pos.X, Pos.Y - Size, Pos.Z - Size);
631 PV[1].Position = FVector(Pos.X, Pos.Y - Size, Pos.Z + Size);
632 PV[2].Position = FVector(Pos.X, Pos.Y + Size, Pos.Z + Size);
633 PV[3].Position = FVector(Pos.X, Pos.Y + Size, Pos.Z - Size);
635 PV[0].Normal = FVector(-1, 0, 0);
636 PV[1].Normal = FVector(-1, 0, 0);
637 PV[2].Normal = FVector(-1, 0, 0);
638 PV[3].Normal = FVector(-1, 0, 0);
640 PV[0].Tangent = FVector(0, 0, 1);
641 PV[1].Tangent = FVector(0, 0, 1);
642 PV[2].Tangent = FVector(0, 0, 1);
643 PV[3].Tangent = FVector(0, 0, 1);
645 const auto T = SrcTexcoords[PointId];
646 PV[0].UV0 = FVector2D(
T.u,
T.v);
647 PV[1].UV0 = FVector2D(
T.u,
T.v);
648 PV[2].UV0 = FVector2D(
T.u,
T.v);
649 PV[3].UV0 = FVector2D(
T.u,
T.v);
651 DstVertices[0] = PV[0];
652 DstVertices[1] = PV[1];
653 DstVertices[2] = PV[2];
654 DstVertices[3] = PV[3];
656 DstIndices[0] = VertexId + 0;
657 DstIndices[1] = VertexId + 2;
658 DstIndices[2] = VertexId + 1;
659 DstIndices[3] = VertexId + 0;
660 DstIndices[4] = VertexId + 3;
661 DstIndices[5] = VertexId + 2;
673 REALSENSE_TRACE(TEXT(
"section id=%zu points=%zu vert=%zu ind=%zu total=%zu invalid=%zu"),
674 SectionId, VertexId / 4, VertexId, IndexId, PointId, NumInvalid);
678 PclMeshData[SectionId]->PclVertices.SetNumUninitialized(VertexId,
false);
679 PclMeshData[SectionId]->PclIndices.SetNumUninitialized(IndexId,
false);
681 PclMesh->SetMeshSectionVisible(SectionId,
true);
687 const auto NumMeshSections =
PclMesh->GetNumSections();
688 if (NumMeshSections > SectionId)
690 for (
size_t i = SectionId;
i < NumMeshSections; ++
i)
693 PclMesh->SetMeshSectionVisible(
i,
false);
698 PclMesh->SetVisibility(SectionId != 0);
706 for (
auto i = 0;
i <
PclMesh->GetNumSections(); ++
i)
724 throw std::runtime_error(
"Profile not supported");
void EnsureProfileSupported(class URealSenseDevice *Device, ERealSenseStreamType StreamType, ERealSenseFormatType Format, FRealSenseStreamMode Mode)
class URealSenseDevice * GetDeviceById(int Id)
std::vector< sensor > query_sensors() const
ERealSenseStreamType StreamType
static IRealSensePlugin & Get()
UTexture2D * DepthRawTexture
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
TUniquePtr< class FDynamicTexture > DepthColorizedDtex
virtual class URealSenseContext * GetContext()=0
FCriticalSection PointCloudMx
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
ERealSensePipelineMode PipelineMode
virtual void Tick(float DeltaSeconds) override
GLint GLint GLsizei GLsizei GLsizei depth
GLsizei const GLchar *const * string
#define REALSENSE_ERR(Format,...)
TUniquePtr< class rs2::pipeline > RsPipeline
float GetDepthScale(rs2::device dev)
void GetDeviceDefaultProfileConfig()
UTexture2D * DepthColorizedTexture
TMap< int32, TUniquePtr< FMeshSection > > PclMeshData
depth_frame get_depth_frame() const
video_frame get_color_frame() const
const std::string & get_failed_args() const
FRealSenseStreamMode ColorConfig
bool bEnableColorizedDepth
TUniquePtr< class rs2::align > RsAlign
TUniquePtr< class FDynamicTexture > ColorDtex
TUniquePtr< class rs2::pointcloud > RsPointCloud
class URealSenseContext * Context
FRealSenseStreamMode InfraredConfig
void SetPointCloudMaterial(int SectionId, UMaterialInterface *Material)
UTexture2D * Get(TUniquePtr< T > &Dtex)
FRealSenseStreamMode DepthConfig
bool TryLock(FCriticalSection *Mutex)
#define NAMED_PROFILER(name)
void ProcessFrameset(class rs2::frameset *Frameset)
rs2_exception_type get_type() const
ERealSenseDepthColormap DepthColormap
class URuntimeMeshComponent * PclMesh
device get_device() const
UTexture2D * InfraredTexture
TUniquePtr< class FRealSenseInspectorWorker > Worker
TUniquePtr< class FDynamicTexture > InfraredDtex
volatile int PclCalculateFlag
friend class FRealSenseInspectorWorker
TArray< class URealSenseDevice * > Devices
#define REALSENSE_TRACE(Format,...)
class URealSenseDevice * FindDeviceBySerial(FString Serial)
video_frame get_infrared_frame(const size_t index=0) const
FString uestr(const char *str)
TArray< FRealSenseStreamProfile > GetStreamProfiles(ERealSenseStreamType StreamType)
ERealSenseFormatType Format
virtual ~ARealSenseInspector()
void colorize_depth(depth_pixel *dst, const rs2::video_frame &depth, int colormap_id, float depth_min, float depth_max, float depth_units, bool equalize)
class UMaterialInterface * PclMaterial
class URealSenseDevice * ActiveDevice
TUniquePtr< class rs2::points > RsPoints
UTexture2D * ColorTexture
const std::string & get_failed_function() const
volatile int PclReadyFlag
TUniquePtr< class FDynamicTexture > DepthRawDtex
bool SupportsProfile(FRealSenseStreamProfile Profile)
struct rs2_context * GetHandle()