Files
planet/ue_client/Source/PlanetClient/GlobeInteractionComponent.cpp
linkong 1e6f4b338b feat: add UE5 LED display client — backend API, C++ source, stereo framework
Backend:
- Add /api/v1/ue/* endpoints (compute-points, cables, landing-points, satellites, status)
  returning flat JSON optimised for UE5 C++ parsing

UE5 client (ue_client/):
- PlanetDataManager: HTTP fetch + local mock JSON loader, spawns ComputePointActors
- ComputePointActor / InteractiveObjectBase: hover/select state, material switching
- GlobeInteractionComponent: drag-to-rotate via CesiumGeoreference origin shift, inertia, zoom
- StereoRenderingManager: runtime SbS/TbB stereo toggle, IPD control (format TBD)
- MotionCaptureInterface: protocol-agnostic gesture/rotate/zoom delegate interface (impl TBD)
- PlanetPlayerController: unified mouse + motion-capture input routing
- PlanetGameMode, Build.cs, Config, mock data

Docs:
- ue5_mvp_fused_plan.md updated to v3.0 for LED display context
- ue_client_setup_guide.md: step-by-step editor setup guide
- ue_todo.md: pending items blocked on vendor answers (stereo format + mocap protocol)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 18:39:05 +08:00

123 lines
4.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "GlobeInteractionComponent.h"
#include "CesiumGeoreference.h"
#include "Engine/World.h"
#include "GameFramework/Pawn.h"
#include "GameFramework/PlayerController.h"
#include "Kismet/GameplayStatics.h"
UGlobeInteractionComponent::UGlobeInteractionComponent()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UGlobeInteractionComponent::BeginPlay()
{
Super::BeginPlay();
FindGeoreference();
}
void UGlobeInteractionComponent::FindGeoreference()
{
Georeference = ACesiumGeoreference::GetDefaultGeoreference(GetWorld());
if (!Georeference)
{
UE_LOG(LogTemp, Error,
TEXT("GlobeInteractionComponent: 场景中没有 CesiumGeoreference请添加一个"));
}
}
// ---------------------------------------------------------------------------
// 旋转
// ---------------------------------------------------------------------------
void UGlobeInteractionComponent::RotateGlobe(float DeltaYaw, float DeltaPitch)
{
if (!Georeference) return;
// 累积惯性速度(本帧的输入叠加到惯性上)
InertiaYaw += DeltaYaw * RotateSensitivity;
InertiaPitch += DeltaPitch * RotateSensitivity;
// 立即应用Tick 里再处理惯性衰减)
double NewLon = Georeference->GetOriginLongitude() - InertiaYaw;
double NewLat = FMath::Clamp(
Georeference->GetOriginLatitude() + InertiaPitch,
-85.0, 85.0
);
Georeference->SetOriginLongitude(NewLon);
Georeference->SetOriginLatitude(NewLat);
// 保持经度在 [-180, 180]
if (NewLon > 180.0) Georeference->SetOriginLongitude(NewLon - 360.0);
if (NewLon < -180.0) Georeference->SetOriginLongitude(NewLon + 360.0);
}
// ---------------------------------------------------------------------------
// 缩放
// ---------------------------------------------------------------------------
void UGlobeInteractionComponent::ZoomGlobe(float Value)
{
if (FMath::IsNearlyZero(Value)) return;
// Value > 0 = 拉近高度减小Value < 0 = 推远(高度增大)
CurrentAltitudeMeters -= Value * ZoomSensitivity;
CurrentAltitudeMeters = FMath::Clamp(CurrentAltitudeMeters,
MinAltitudeMeters,
MaxAltitudeMeters);
ApplyAltitudeToCamera();
}
void UGlobeInteractionComponent::ApplyAltitudeToCamera()
{
if (!Georeference) return;
// 把当前 Origin 经纬度 + 新高度转换为 Unreal 世界坐标,然后移动拥有者 Pawn
AController* Controller = Cast<AController>(GetOwner());
APawn* Pawn = Controller ? Controller->GetPawn() : Cast<APawn>(GetOwner());
if (!Pawn) return;
double Lon = Georeference->GetOriginLongitude();
double Lat = Georeference->GetOriginLatitude();
FVector NewPos = Georeference->TransformLongitudeLatitudeHeightPositionToUnreal(
FVector(Lon, Lat, CurrentAltitudeMeters)
);
Pawn->SetActorLocation(NewPos);
}
// ---------------------------------------------------------------------------
// 惯性 Tick
// ---------------------------------------------------------------------------
void UGlobeInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// 只有惯性速度足够大时才继续转动
if (FMath::IsNearlyZero(InertiaYaw, 0.001f) &&
FMath::IsNearlyZero(InertiaPitch, 0.001f)) return;
if (!Georeference) return;
double NewLon = Georeference->GetOriginLongitude() - InertiaYaw;
double NewLat = FMath::Clamp(
Georeference->GetOriginLatitude() + InertiaPitch,
-85.0, 85.0
);
Georeference->SetOriginLongitude(NewLon);
Georeference->SetOriginLatitude(NewLat);
// 惯性衰减
InertiaYaw *= InertiaDamping;
InertiaPitch *= InertiaDamping;
}
void UGlobeInteractionComponent::StopInertia()
{
InertiaYaw = 0.f;
InertiaPitch = 0.f;
}