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>
151 lines
5.6 KiB
C++
151 lines
5.6 KiB
C++
#pragma once
|
||
|
||
#include "CoreMinimal.h"
|
||
#include "UObject/Interface.h"
|
||
#include "MotionCaptureInterface.generated.h"
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 动捕事件 —— 供应商中间件触发这些事件,UE5 侧响应
|
||
// ---------------------------------------------------------------------------
|
||
|
||
/**
|
||
* 手势类型枚举
|
||
*
|
||
* TODO(等动捕供应商确认手势集合后补充):
|
||
* 当前列出的是推测的基本手势,以实际交付为准。
|
||
*/
|
||
UENUM(BlueprintType)
|
||
enum class EMotionGesture : uint8
|
||
{
|
||
None UMETA(DisplayName="无"),
|
||
SwipeLeft UMETA(DisplayName="向左划"), // 地球向左转
|
||
SwipeRight UMETA(DisplayName="向右划"), // 地球向右转
|
||
SwipeUp UMETA(DisplayName="向上划"), // 地球向上转
|
||
SwipeDown UMETA(DisplayName="向下划"), // 地球向下转
|
||
PinchIn UMETA(DisplayName="捏合(缩小)"),// 缩放
|
||
PinchOut UMETA(DisplayName="展开(放大)"),// 缩放
|
||
Point UMETA(DisplayName="指向"), // 悬停选中
|
||
Confirm UMETA(DisplayName="确认"), // 点击选中
|
||
Dismiss UMETA(DisplayName="挥手取消"), // 关闭信息卡
|
||
};
|
||
|
||
// 动捕系统触发某个离散手势时广播
|
||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGestureDetected, EMotionGesture, Gesture);
|
||
|
||
// 动捕系统持续输出指向方向时广播(用于悬停高亮)
|
||
// Direction: 归一化方向向量,由动捕系统解算后传入
|
||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPointingDirectionChanged, FVector, Direction);
|
||
|
||
// 动捕系统输出旋转增量时广播(用于连续拖拽旋转地球)
|
||
// DeltaYaw/DeltaPitch: 单帧内的角度增量(度)
|
||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnRotateDelta, float, DeltaYaw, float, DeltaPitch);
|
||
|
||
// 动捕系统输出缩放增量时广播
|
||
// DeltaScale: > 0 放大,< 0 缩小
|
||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnZoomDelta, float, DeltaScale);
|
||
|
||
|
||
/**
|
||
* UMotionCaptureReceiver
|
||
*
|
||
* 动捕接收器基类。根据供应商协议,创建对应的子类实现:
|
||
*
|
||
* - LiveLink 协议 → UMotionCaptureReceiverLiveLink (TODO)
|
||
* - OSC/UDP 协议 → UMotionCaptureReceiverOSC (TODO)
|
||
*
|
||
* 子类负责接收数据并调用 BroadcastXxx() 方法,
|
||
* PlanetPlayerController 订阅这些委托即可,不关心底层协议。
|
||
*
|
||
* TODO(等动捕供应商回复后):
|
||
* 1. 确认协议(Live Link / OSC / 私有 SDK)
|
||
* 2. 在对应子类里实现连接和数据接收
|
||
* 3. 把子类拖进场景,在 PlanetDataManager / PlayerController 里引用它
|
||
*/
|
||
UCLASS(Abstract, BlueprintType, Blueprintable)
|
||
class PLANETCLIENT_API UMotionCaptureReceiver : public UObject
|
||
{
|
||
GENERATED_BODY()
|
||
|
||
public:
|
||
// -----------------------------------------------------------------------
|
||
// 外部订阅这些委托
|
||
// -----------------------------------------------------------------------
|
||
UPROPERTY(BlueprintAssignable, Category="Planet|MotionCapture")
|
||
FOnGestureDetected OnGestureDetected;
|
||
|
||
UPROPERTY(BlueprintAssignable, Category="Planet|MotionCapture")
|
||
FOnPointingDirectionChanged OnPointingDirectionChanged;
|
||
|
||
UPROPERTY(BlueprintAssignable, Category="Planet|MotionCapture")
|
||
FOnRotateDelta OnRotateDelta;
|
||
|
||
UPROPERTY(BlueprintAssignable, Category="Planet|MotionCapture")
|
||
FOnZoomDelta OnZoomDelta;
|
||
|
||
// 连接到动捕中间件(子类实现)
|
||
UFUNCTION(BlueprintCallable, Category="Planet|MotionCapture")
|
||
virtual void Connect() {}
|
||
|
||
// 断开连接(子类实现)
|
||
UFUNCTION(BlueprintCallable, Category="Planet|MotionCapture")
|
||
virtual void Disconnect() {}
|
||
|
||
UFUNCTION(BlueprintPure, Category="Planet|MotionCapture")
|
||
virtual bool IsConnected() const { return false; }
|
||
|
||
protected:
|
||
// 子类解析到数据后调用这些方法广播
|
||
void BroadcastGesture(EMotionGesture Gesture)
|
||
{
|
||
OnGestureDetected.Broadcast(Gesture);
|
||
}
|
||
|
||
void BroadcastPointing(const FVector& Direction)
|
||
{
|
||
OnPointingDirectionChanged.Broadcast(Direction);
|
||
}
|
||
|
||
void BroadcastRotateDelta(float DeltaYaw, float DeltaPitch)
|
||
{
|
||
OnRotateDelta.Broadcast(DeltaYaw, DeltaPitch);
|
||
}
|
||
|
||
void BroadcastZoomDelta(float DeltaScale)
|
||
{
|
||
OnZoomDelta.Broadcast(DeltaScale);
|
||
}
|
||
};
|
||
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 动作映射配置
|
||
//
|
||
// 把动捕手势映射到具体的 UE 操作,在 Details 面板里可以改。
|
||
// 这样不用改代码就能重新映射手势。
|
||
// ---------------------------------------------------------------------------
|
||
USTRUCT(BlueprintType)
|
||
struct FMotionActionMapping
|
||
{
|
||
GENERATED_BODY()
|
||
|
||
// 触发"旋转地球"的手势(持续输出增量)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|MotionCapture")
|
||
EMotionGesture RotateGlobe = EMotionGesture::None; // TODO: 填入供应商手势名
|
||
|
||
// 触发"放大"的手势
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|MotionCapture")
|
||
EMotionGesture ZoomIn = EMotionGesture::PinchOut;
|
||
|
||
// 触发"缩小"的手势
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|MotionCapture")
|
||
EMotionGesture ZoomOut = EMotionGesture::PinchIn;
|
||
|
||
// 触发"选中数据点"的手势
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|MotionCapture")
|
||
EMotionGesture SelectPoint = EMotionGesture::Confirm;
|
||
|
||
// 触发"关闭信息卡"的手势
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Planet|MotionCapture")
|
||
EMotionGesture DismissInfoCard = EMotionGesture::Dismiss;
|
||
};
|