载入中...
搜索中...
未找到
CameraController.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
6#include "common/Module.h"
7#include "common/Result.h"
9
10#include <glm/glm.hpp>
11
12#include <string>
13#include <cstdint>
14#include <deque>
15#include <vector>
16
17namespace eve::graphics {
18class Camera3D;
19}
20namespace eve::platform_event {
21class PlatformEvent;
22}
23namespace eve::scene {
24class SceneNodeRef;
25}
26
27namespace eve::camera {
28
31 float postFxExposure = 13.5f;
32 int64_t postFxExposureMode = 0;
33 bool depthOfFieldActive = true;
35 float focusDistance = 100.f;
36 float aperture = 16.f;
37 float focalLength = 50.f;
38 int64_t kernelSize = 1;
39 int64_t savedFocusMode = 0;
40 int64_t focusModeHdrp = 0;
41 int64_t focusModeUrp = 0;
42 int64_t qualityHdrp = 1;
43 float nearBlurStart = 0.f;
44 float nearBlurEnd = 0.1f;
45 float farBlurStart = 200.f;
46 float farBlurEnd = 2000.f;
47 float blurStartUrp = 2.f;
48 float blurEndUrp = 1000.f;
49 float maximumBlurRadius = 1.f;
50 bool highQualityUrp = false;
51};
52
68public:
72 ~CameraController() override;
73
75 void setActionCuesEnabled(bool enabled);
77 [[nodiscard]] bool getActionCuesEnabled() const;
79 [[nodiscard]] bool supports(const LogicalId& cue) const noexcept override;
81 [[nodiscard]] Result<void> trigger(const action::ActionCameraCueBinding& binding,
82 const action::ActionNotifyContext& context) override;
83
84 // --- 绑定要驱动的摄像机 ---
86 void setCamera(graphics::Camera3D* cam);
88 graphics::Camera3D* getCamera() const;
89
90 // --- 目标 / 观察锚点 ---
92 void setTarget(float x, float y, float z);
94 void setTargetNode(scene::SceneNodeRef* node);
96 float getTargetX() const;
98 float getTargetY() const;
100 float getTargetZ() const;
102 void setOffset(float x, float y, float z);
104 void setLookAhead(float x, float y, float z);
109 void setSecondaryTarget(float x, float y, float z);
111 void clearSecondaryTarget();
113 [[nodiscard]] bool hasSecondaryTarget() const noexcept { return hasSecondaryTarget_; }
114 float getSecondaryTargetX() const;
116 float getSecondaryTargetY() const;
118 float getSecondaryTargetZ() const;
119
120 // --- 视角模式 ---
122 void setMode(const std::string& mode);
124 std::string getMode() const;
125
126 // --- orbit / topdown 参数 ---
128 void setRadius(float r); // orbit 半径 / topdown 高度
float getRadius() const { return radius_; }
131 [[nodiscard]] Result<void> setRadiusLimits(float minimum, float maximum);
float getMinimumRadius() const { return minimumRadius_; } float getMaximumRadius() const { return maximumRadius_; }
135 void setAzimuth(float deg); // orbit 方位角
137 void setElevation(float deg); // orbit 仰角
139 void setOrbitSpeed(float degPerSec); // 自动盘旋转速
140
141 // --- firstperson 参数 ---
143 void setYaw(float deg);
145 void setPitch(float deg);
147 void addInput(float yawDeltaDeg, float pitchDeltaDeg, float zoomDelta);
148
150 void setPhotoModeAuthority(bool enabled);
152 bool getPhotoModeAuthority() const noexcept{return photoModeAuthority_;}
154 PhotoModeFieldAcceptance acceptsPhotoModeField(const PhotoModeAssignment& assignment) const noexcept override;
156 [[nodiscard]] Result<void> applyPhotoModeField(const PhotoModeAssignment& assignment) override;
158 [[nodiscard]] Result<void> setCameraRoll(float degrees);
160 float getCameraRoll() const noexcept{return cameraRollDeg_;}
162 float getPcgCullingDistance() const noexcept{return pcgCullingDistance_;}
164 const PcgPhotoModePostFxState& getPcgPostFxState() const noexcept{return pcgPostFxState_;}
165 // --- framing / lens ---
167 void setComposition(float screenX, float screenY);
169 void setDeadZone(float radius);
171 void setFov(float degrees);
173 float getFov() const;
174
175 // --- 平滑 ---
177 void setSmooth(float damping); // 每秒指数阻尼,越大越跟手
179 void setPositionSmooth(float damping);
181 void setTargetSmooth(float damping);
183 void setMaxSpeed(float unitsPerSec); // 0 = 不限速
185 void snap(); // 立即应用当前目标视角
186
187 // --- obstruction / collision ---
189 void setCollisionEnabled(bool enabled);
191 void setCollisionRadius(float radius);
193 void setCollisionRecovery(float damping);
195 void setCollisionMask(uint64_t maskBits);
197 void setCollisionIgnoredBody(int bodyId);
199 void clearCollisionBoxes();
201 void addCollisionBox(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);
203 bool isObstructed() const;
205 int getCollisionBodyId() const;
206
207 // --- camera rigs / director ---
209 bool addRig(const std::string& name, const std::string& mode, int priority);
211 bool removeRig(const std::string& name);
213 bool setRigPriority(const std::string& name, int priority);
215 bool setRigEnabled(const std::string& name, bool enabled);
217 bool saveRigState(const std::string& name);
219 bool activateRig(const std::string& name, float blendTime);
221 std::string getActiveRig() const;
222
223 // --- additive modifiers ---
225 void addImpulse(float positionAmplitude, float rotationAmplitude, float duration, unsigned int seed = 0);
227 void addFovImpulse(float degrees, float duration);
229 void clearImpulses();
230
231 // --- cinematic / 自动切换视角 ---
233 void addView(const std::string& name, float ex, float ey, float ez, float tx, float ty, float tz);
235 bool switchTo(const std::string& name, float blendTime);
237 void playSequence(float stepTime); // 每隔 stepTime 秒切换到下一个 View
239 void stopSequence();
241 bool isPlaying() const;
242
243 // --- timeline / events ---
245 void clearTimeline();
247 bool addTimelineCut(float time, const std::string& rigName, float blendTime);
249 bool addTimelineEvent(float time, const std::string& name, const std::string& data);
251 bool addTimelineFloat(float time, const std::string& property, float value);
253 void setEventSink(platform_event::PlatformEvent* sink);
255 void playTimeline(bool loop);
257 void pauseTimeline();
259 void stopTimeline();
261 void seekTimeline(float time, bool fireEvents = false);
263 bool isTimelinePlaying() const;
265 float getTimelineTime() const;
267 std::string consumeTimelineEvent();
269 std::string getTimelineEventData() const;
271 int getPendingTimelineEventCount() const;
273 float getTimelineDuration() const;
275 int getRigCount() const;
277 std::string serializeAsset() const;
279 bool deserializeAsset(const std::string& json);
280
281 // --- 每帧驱动 ---
283 void update(float dt);
284
285private:
286 struct View {
287 std::string name;
288 glm::vec3 eye{0.f};
289 glm::vec3 target{0.f};
290 float fov = 60.f;
291 };
292
293 struct Rig {
294 std::string name;
295 std::string mode;
296 int priority = 0;
297 bool enabled = true;
298 glm::vec3 target{0.f};
299 glm::vec3 offset{0.f, 2.f, 6.f};
300 glm::vec3 lookAhead{0.f};
301 glm::vec2 composition{0.f};
302 float radius = 10.f;
303 float azimuth = 45.f;
304 float elevation = 30.f;
305 float yaw = 0.f;
306 float pitch = 0.f;
307 float fov = 60.f;
308 float smooth = 6.f;
309 float maxSpeed = 0.f;
310 };
311
312 struct CollisionBox {
313 glm::vec3 min{0.f};
314 glm::vec3 max{0.f};
315 };
316 struct Impulse {
317 float positionAmplitude = 0.f;
318 float rotationAmplitude = 0.f;
319 float duration = 0.f;
320 float age = 0.f;
321 unsigned int seed = 0;
322 float fovAmplitude = 0.f;
323 };
324 struct TimelineCut {
325 float time = 0.f;
326 std::string rig;
327 float blend = 0.f;
328 bool fired = false;
329 };
330 struct TimelineEvent {
331 float time = 0.f;
332 std::string name;
333 std::string data;
334 bool fired = false;
335 };
336 struct TimelineFloat {
337 float time = 0.f;
338 std::string property;
339 float value = 0.f;
340 };
341
342 View desired() const;
343 void applyView(const View& v);
344 void easeToward(const View& v, float dt);
345 void updateTrackedTarget();
346 void updateDirector();
347 void applyCollision(View& v, float dt);
348 void applyModifiers(View& v, float dt);
349 void updateTimeline(float dt);
350 void evaluateTimelineFloats();
351 void emitTimelineEvent(const TimelineEvent& marker);
352 static bool validMode(const std::string& mode);
353 [[nodiscard]] Result<void> applyPcgPostFx(const PhotoModeAssignment& assignment);
354 void projectPcgPostFx();
355
356 graphics::Camera3D* cam_ = nullptr;
357 bool photoModeAuthority_ = false;
358 float cameraRollDeg_ = 0.f;
359 float pcgCullingDistance_ = 0.f;
360 PcgPhotoModePostFxState pcgPostFxState_{};
361
362 std::string mode_ = "follow";
363
364 glm::vec3 target_{0.f, 0.f, 0.f};
365 std::string targetNodeHost_;
366 std::string targetNodeId_;
367 glm::vec3 offset_{0.f, 2.f, 6.f};
368 glm::vec3 lookAhead_{0.f, 0.f, 0.f};
369 glm::vec3 secondaryTarget_{0.f};
370 bool hasSecondaryTarget_ = false;
371
372 float radius_ = 10.f;
373 float minimumRadius_ = 0.01f;
374 float maximumRadius_ = 100000.f;
375 float azimuthDeg_ = 45.f;
376 float elevationDeg_ = 30.f;
377 float orbitSpeedDeg_ = 20.f;
378
379 float yawDeg_ = 0.f;
380 float pitchDeg_ = 0.f;
381 glm::vec2 composition_{0.f};
382 float deadZone_ = 0.f;
383 glm::vec3 deadZoneTarget_{0.f};
384 bool deadZoneInitialized_ = false;
385 float fovDeg_ = 60.f;
386
387 float smooth_ = 6.f;
388 float positionSmooth_ = 6.f;
389 float targetSmooth_ = 6.f;
390 float maxSpeed_ = 0.f;
391 bool initialized_ = false;
392 View cur_{};
393
394 bool collisionEnabled_ = false;
395 float collisionRadius_ = 0.25f;
396 float collisionRecovery_ = 4.f;
397 float collisionDistance_ = -1.f;
398 bool obstructed_ = false;
399 uint64_t collisionMask_ = UINT64_MAX;
400 int collisionIgnoredBody_ = -1;
401 int collisionBodyId_ = -1;
402 std::vector<CollisionBox> collisionBoxes_;
403
404 std::vector<Rig> rigs_;
405 std::string activeRig_;
406 bool directorEnabled_ = false;
407 std::vector<Impulse> impulses_;
408
409 // cinematic
410 std::vector<View> views_;
411 int viewIndex_ = -1;
412 bool playing_ = false;
413 float stepTime_ = 3.f;
414 float timer_ = 0.f;
415 bool blending_ = false;
416 View blendFrom_{};
417 View blendTo_{};
418 float blendT_ = 0.f;
419 float blendDur_ = 1.f;
420
421 std::vector<TimelineCut> timelineCuts_;
422 std::vector<TimelineEvent> timelineEvents_;
423 std::vector<TimelineFloat> timelineFloats_;
424 platform_event::PlatformEvent* eventSink_ = nullptr;
425 float timelineTime_ = 0.f;
426 float timelineDuration_ = 0.f;
427 bool timelinePlaying_ = false;
428 bool timelineLoop_ = false;
429 std::deque<std::pair<std::string, std::string>> pendingTimelineEvents_;
430 std::string consumedTimelineEventData_;
431};
432
436class Camera : public Module {
437public:
440 Camera() = default;
442 ~Camera() override = default;
443};
444
445} // namespace eve::camera
Typed camera-cue action block contract.
LogicalId target
double value
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
float duration
int priority
float degrees
Definition CardTypes.cpp:35
#define EVENGINE_API_WORLD
Definition Export.h:109
float maximum[3]
float minimum[3]
double r
float v
float elevation
float blend
size_t offset
std::string name
eve::action::ActionVfxBinding binding
float radius
std::uint32_t seed
Definition PointSet.cpp:807
glm::vec3 eye
Move-only, checked operation results for the common layer.
const RoadNode * node
const VegetationPresetContext & context
IPhotoModeFieldSink public API.
Human-readable, scoped identifier in the form namespace:name.
Definition Identity.h:411
EVENGINE_API_FOUNDATION public API.
Definition Module.h:46
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Optional open target for instantaneous action camera cues.
3D 摄像机控制器(eve.Camera / eve.CameraController)。
bool hasSecondaryTarget() const noexcept
Return whether a lock-on look target is currently stored.
CameraController()
Camera controller.
const PcgPhotoModePostFxState & getPcgPostFxState() const noexcept
Return the complete retained Pcg post-processing state.
float getPcgCullingDistance() const noexcept
Return Pcg's signed culling-distance adjustment.
float getCameraRoll() const noexcept
Return current camera roll in degrees.
bool getPhotoModeAuthority() const noexcept
Return whether this controller currently publishes photo-mode camera fields.
摄像机模块命名空间(eve.Camera)。主要职责是把 CameraController 绑定进脚本。
Camera()=default
Constructs a Camera.
~Camera() override=default
Releases Camera resources.
EVENGINE_API_BACKENDS public API.
EVENGINE_API_FOUNDATION public API.
Script handle to a scene node (hostName + nodeId). Deliberately holds strings rather than arena point...
卡牌游戏 UI 工具模块:工厂 + 脚本绑定入口。 功能参考 ycarowr/UiCard:扇形手牌布局、抽牌/洗牌、悬浮放大、拖拽到落牌区、 敌方手牌(背面/偷看)、费用不足置灰,以及可实时调节的布局...
Definition Animation.h:25
PhotoModeFieldAcceptance
Capability implemented by the composition root that routes assignments to domain owners.
bool enabled
One reversible field assignment in a photo-mode transaction.
Owning validated camera impulse shared by action runtime and camera targets.
Context linking a routed event to its action execution.
Complete Pcg photo-mode post-processing state retained across render-pipeline projections.