载入中...
搜索中...
未找到
CameraController.cpp
浏览该文件的文档.
2
4
5#include <simplesquirrel/simplesquirrel.hpp>
6
7#include <algorithm>
8#include <cmath>
9
10namespace eve::camera {
11
13
15
17
19
20void CameraController::setTarget(float x, float y, float z) {
21 target_ = glm::vec3(x, y, z);
22}
23
24float CameraController::getTargetX() const { return target_.x; }
25float CameraController::getTargetY() const { return target_.y; }
26float CameraController::getTargetZ() const { return target_.z; }
27
28void CameraController::setOffset(float x, float y, float z) {
29 offset_ = glm::vec3(x, y, z);
30}
31
32void CameraController::setLookAhead(float x, float y, float z) {
33 lookAhead_ = glm::vec3(x, y, z);
34}
35
36void CameraController::setMode(const std::string &mode) { mode_ = mode; }
37
38std::string CameraController::getMode() const { return mode_; }
39
40void CameraController::setRadius(float r) { radius_ = r; }
41void CameraController::setAzimuth(float deg) { azimuthDeg_ = deg; }
42void CameraController::setElevation(float deg) { elevationDeg_ = deg; }
43void CameraController::setOrbitSpeed(float degPerSec) { orbitSpeedDeg_ = degPerSec; }
44
45void CameraController::setYaw(float deg) { yawDeg_ = deg; }
46void CameraController::setPitch(float deg) { pitchDeg_ = deg; }
47
48void CameraController::setSmooth(float damping) { smooth_ = std::max(0.f, damping); }
49
50void CameraController::setMaxSpeed(float unitsPerSec) { maxSpeed_ = std::max(0.f, unitsPerSec); }
51
52void CameraController::addView(const std::string &name, float ex, float ey, float ez,
53 float tx, float ty, float tz) {
54 View v;
55 v.name = name;
56 v.eye = glm::vec3(ex, ey, ez);
57 v.target = glm::vec3(tx, ty, tz);
58 views_.push_back(v);
59}
60
61bool CameraController::switchTo(const std::string &name, float blendTime) {
62 int idx = -1;
63 for (int i = 0; i < static_cast<int>(views_.size()); ++i) {
64 if (views_[i].name == name) {
65 idx = i;
66 break;
67 }
68 }
69 if (idx < 0) return false;
70
71 if (viewIndex_ >= 0 && viewIndex_ < static_cast<int>(views_.size())) {
72 blendFrom_ = views_[viewIndex_];
73 } else {
74 blendFrom_ = cur_;
75 }
76 blendTo_ = views_[idx];
77 viewIndex_ = idx;
78
79 if (blendTime > 0.f) {
80 blending_ = true;
81 blendDur_ = blendTime;
82 blendT_ = 0.f;
83 } else {
84 blending_ = false;
85 blendDur_ = 1.f;
86 blendT_ = 0.f;
87 }
88 return true;
89}
90
91void CameraController::playSequence(float stepTime) {
92 playing_ = true;
93 stepTime_ = stepTime > 0.f ? stepTime : 1.f;
94 timer_ = 0.f;
95 if (!blending_ && views_.empty()) return;
96 if (viewIndex_ < 0 || viewIndex_ >= static_cast<int>(views_.size())) {
97 switchTo(views_.front().name, 0.f);
98 }
99}
100
101void CameraController::stopSequence() { playing_ = false; }
102
103bool CameraController::isPlaying() const { return playing_; }
104
105CameraController::View CameraController::desired() const {
106 View v;
107 if (mode_ == "orbit") {
108 const float az = glm::radians(azimuthDeg_);
109 const float el = glm::radians(elevationDeg_);
110 glm::vec3 dir(std::cos(el) * std::sin(az), std::sin(el), std::cos(el) * std::cos(az));
111 v.eye = target_ + dir * radius_;
112 v.target = target_;
113 } else if (mode_ == "topdown") {
114 v.eye = target_ + glm::vec3(0.f, radius_, 0.f);
115 v.target = target_;
116 } else if (mode_ == "firstperson") {
117 v.eye = target_;
118 const float yaw = glm::radians(yawDeg_);
119 const float pitch = glm::radians(pitchDeg_);
120 glm::vec3 dir(std::cos(pitch) * std::sin(yaw), std::sin(pitch), std::cos(pitch) * std::cos(yaw));
121 v.target = v.eye + dir * 100.f;
122 } else if (mode_ == "cinematic") {
123 if (blending_ && viewIndex_ >= 0) {
124 float t = blendDur_ > 0.f ? glm::clamp(blendT_ / blendDur_, 0.f, 1.f) : 1.f;
125 t = t * t * (3.f - 2.f * t); // smoothstep
126 v.eye = glm::mix(blendFrom_.eye, blendTo_.eye, t);
127 v.target = glm::mix(blendFrom_.target, blendTo_.target, t);
128 } else if (viewIndex_ >= 0 && viewIndex_ < static_cast<int>(views_.size())) {
129 v = views_[viewIndex_];
130 } else {
131 v.target = target_ + lookAhead_;
132 v.eye = v.target + offset_;
133 }
134 } else { // follow (默认)
135 v.target = target_ + lookAhead_;
136 v.eye = v.target + offset_;
137 }
138 return v;
139}
140
141void CameraController::applyView(const View &v) {
142 if (!cam_) return;
143 cam_->setEye(v.eye.x, v.eye.y, v.eye.z);
144 cam_->setTarget(v.target.x, v.target.y, v.target.z);
145}
146
147void CameraController::easeToward(const View &v, float dt) {
148 const float k = 1.f - std::exp(-smooth_ * dt);
149 glm::vec3 deye = (v.eye - cur_.eye) * k;
150 glm::vec3 dtgt = (v.target - cur_.target) * k;
151 if (maxSpeed_ > 0.f && dt > 0.f) {
152 const float maxStep = maxSpeed_ * dt;
153 const float le = glm::length(deye);
154 if (le > maxStep && le > 1e-6f) deye *= maxStep / le;
155 const float lt = glm::length(dtgt);
156 if (lt > maxStep && lt > 1e-6f) dtgt *= maxStep / lt;
157 }
158 cur_.eye += deye;
159 cur_.target += dtgt;
160}
161
163 cur_ = desired();
164 initialized_ = true;
165 applyView(cur_);
166}
167
169 if (!cam_) return;
170
171 if (mode_ == "cinematic" && playing_ && !views_.empty()) {
172 timer_ += dt;
173 if (!blending_ && timer_ >= stepTime_) {
174 const int next = (viewIndex_ + 1) % static_cast<int>(views_.size());
175 switchTo(views_[next].name, blendDur_);
176 timer_ = 0.f;
177 }
178 }
179
180 if (blending_) {
181 blendT_ += dt;
182 if (blendT_ >= blendDur_) {
183 blending_ = false;
184 blendT_ = blendDur_;
185 }
186 }
187
188 // orbit 自动盘旋:不断累积方位角
189 if (mode_ == "orbit") {
190 azimuthDeg_ += orbitSpeedDeg_ * dt;
191 }
192
193 const View d = desired();
194
195 if (!initialized_) {
196 cur_ = d;
197 initialized_ = true;
198 }
199 easeToward(d, dt);
200 applyView(cur_);
201}
202
203void Camera::expose(ssq::Class &cls) {
204 // 模块级方法(如需要可在此添加);当前只通过 eve.CameraController 暴露控制器。
205}
206
207void Camera::expose(ssq::Table &table) {
208 auto cls = table.addClass(name, Camera::create, false);
209 expose(cls);
210
211 auto cc = table.addClass<CameraController>(
212 "CameraController",
213 std::function<CameraController *()>([]() { return new CameraController(); }), true);
214
215 cc.addFunc("setCamera", &CameraController::setCamera);
216 cc.addFunc("getCamera", &CameraController::getCamera);
217
218 cc.addFunc("setTarget", &CameraController::setTarget);
219 cc.addFunc("getTargetX", &CameraController::getTargetX);
220 cc.addFunc("getTargetY", &CameraController::getTargetY);
221 cc.addFunc("getTargetZ", &CameraController::getTargetZ);
222 cc.addFunc("setOffset", &CameraController::setOffset);
223 cc.addFunc("setLookAhead", &CameraController::setLookAhead);
224
225 cc.addFunc("setMode", &CameraController::setMode);
226 cc.addFunc("getMode", &CameraController::getMode);
227
228 cc.addFunc("setRadius", &CameraController::setRadius);
229 cc.addFunc("setAzimuth", &CameraController::setAzimuth);
230 cc.addFunc("setElevation", &CameraController::setElevation);
231 cc.addFunc("setOrbitSpeed", &CameraController::setOrbitSpeed);
232
233 cc.addFunc("setYaw", &CameraController::setYaw);
234 cc.addFunc("setPitch", &CameraController::setPitch);
235
236 cc.addFunc("setSmooth", &CameraController::setSmooth);
237 cc.addFunc("setMaxSpeed", &CameraController::setMaxSpeed);
238 cc.addFunc("snap", &CameraController::snap);
239
240 cc.addFunc("addView", &CameraController::addView);
241 cc.addFunc("switchTo", &CameraController::switchTo);
242 cc.addFunc("playSequence", &CameraController::playSequence);
243 cc.addFunc("stopSequence", &CameraController::stopSequence);
244 cc.addFunc("isPlaying", &CameraController::isPlaying);
245
246 cc.addFunc("update", &CameraController::update);
247}
248
249} // namespace eve::camera
HSQOBJECT cls
Definition ECS.cpp:21
int y
Definition Grass.cpp:135
int z
Definition Grass.cpp:135
int x
Definition Grass.cpp:135
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:24
int idx
const char * name
Definition RockMesh.cpp:21
int d
int v
V3 dir
Definition TreeMesh.cpp:121
void addView(const std::string &name, float ex, float ey, float ez, float tx, float ty, float tz)
void setTarget(float x, float y, float z)
void setCamera(graphics::Camera3D *cam)
graphics::Camera3D * getCamera() const
void playSequence(float stepTime)
void setLookAhead(float x, float y, float z)
follow:额外的视线前移点(可让镜头看向玩家前方)。
void setMode(const std::string &mode)
void setMaxSpeed(float unitsPerSec)
bool switchTo(const std::string &name, float blendTime)
void setOffset(float x, float y, float z)
follow:摄像机相对 target 的偏移(默认 (0, 2, 6))。
void setOrbitSpeed(float degPerSec)
摄像机模块命名空间(eve.Camera)。主要职责是把 CameraController 绑定进脚本。
void setTarget(float x, float y, float z)
void setEye(float x, float y, float z)