GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
dxlib_camera.cpp
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
8#include "dxlib_camera.h"
9
10#include <cmath>
11
12#include <Dxlib.h>
13
14#include "cassert_define.h"
15#include "math_util.h"
16#include "dxlib_util.h"
17#include "graphic_const.h"
18
19
20namespace designlab
21{
22
24 kDefaultCameraFrontVec{ Vector3::GetFrontVec() },
25 kDefaultCameraUpVec{ Vector3::GetUpVec() },
26 camera_view_mode_(enums::CameraViewMode::kTopView),
27 free_controlled_target_pos_{},
28 now_camera_state_{},
29 goal_camera_state_{}
30{
31 SetCameraViewMode(enums::CameraViewMode::kTopView); // カメラの初期位置をセットする.
32
33 SetCameraPosAndRot(); // カメラ位置をセットする.
34
35 InitCameraTargetLength(); // カメラの距離を初期化する.
36
37 now_camera_state_.camera_quat =
40}
41
42
44{
45 // カメラの距離を目標値に近づける.
46 now_camera_state_.length_camera_to_target = math_util::ApproachTarget(
47 now_camera_state_.length_camera_to_target,
48 goal_camera_state_.length_camera_to_target,
49 0.1f);
50
51 // カメラの回転を目標値に近づける.
52 now_camera_state_.camera_quat = SlerpQuaternion(
53 now_camera_state_.camera_quat,
54 goal_camera_state_.camera_quat,
55 0.1f);
56
57 now_camera_state_.camera_quat = now_camera_state_.camera_quat.GetNormalized();
58
59
60 // カメラの注視点を目標値に近づける.
62 {
63 now_camera_state_.target_pos = math_util::ApproachTarget(
64 now_camera_state_.target_pos,
65 goal_camera_state_.target_pos,
66 0.1f);
67 }
68 else
69 {
70 now_camera_state_.target_pos = math_util::ApproachTarget(
71 now_camera_state_.target_pos,
72 free_controlled_target_pos_,
73 0.1f);
74 }
75
76
77 // カメラ位置をセットする.
78 SetCameraPosAndRot();
79
80 if (kOutputDebugLog)
81 {
82 printfDx("cameraの姿勢(クォータニオン) w = %f, v= { %f, %f, %f }\n",
83 now_camera_state_.camera_quat.w,
84 now_camera_state_.camera_quat.v.x,
85 now_camera_state_.camera_quat.v.y,
86 now_camera_state_.camera_quat.v.z);
87
88 printfDx("cameraの注視点 x = %f, y = %f, z = %f\n",
89 now_camera_state_.target_pos.x,
90 now_camera_state_.target_pos.y,
91 now_camera_state_.target_pos.z);
92
93 printfDx("cameraの距離 %f\n", now_camera_state_.length_camera_to_target);
94 }
95}
96
97
99{
100 camera_view_mode_ = mode;
101
102 // ゴール座標を更新する.
103 switch (mode)
104 {
106 {
107 goal_camera_state_.camera_quat =
109 return;
110 }
111
113 {
114 goal_camera_state_.camera_quat =
116 return;
117 }
118
120 {
123
126
127 goal_camera_state_.camera_quat = quat1 * quat2;
128
129 return;
130 }
131
133 {
134 goal_camera_state_.camera_quat =
136 return;
137 }
138
140 {
141 goal_camera_state_.camera_quat =
143 return;
144 }
145
147 {
148 return;
149 }
150
152 {
153 free_controlled_target_pos_ = goal_camera_state_.target_pos;
154 return;
155 }
156
157 default:
158 assert(false); // ここに来ることはない.
159 break;
160 }
161}
162
163
165{
166 // 最大と最小の中間値を初期値とする.
167 goal_camera_state_.length_camera_to_target = kDefaultCameraZoom;
168}
169
170
171void DxlibCamera::AddCameraToTargetLength(const float length_dif)
172{
173 goal_camera_state_.length_camera_to_target += length_dif;
174
175 // カメラの距離が最大値を超えたら最大値にする.
176 if (GraphicConst::kCameraToTargetMax < goal_camera_state_.length_camera_to_target)
177 {
178 goal_camera_state_.length_camera_to_target = GraphicConst::kCameraToTargetMax;
179 }
180
181 // カメラの距離が最小値を下回ったら最小値にする.
182 if (goal_camera_state_.length_camera_to_target < GraphicConst::kCameraToTargetMin)
183 {
184 goal_camera_state_.length_camera_to_target = GraphicConst::kCameraToTargetMin;
185 }
186}
187
188
189void DxlibCamera::SetCameraPosAndRot()
190{
191 // カメラの位置をセットする.クォータニオンを用いて回転させ,
192 // Vector3 から dxlib::VECTOR に変換する.
193
194 Vector3 camera_target_dif =
195 RotateVector3(kDefaultCameraFrontVec, now_camera_state_.camera_quat) *
196 now_camera_state_.length_camera_to_target;
197
198 VECTOR camera_pos =
199 dxlib_util::ConvertToDxlibVec(camera_target_dif + now_camera_state_.target_pos);
200
201 VECTOR camera_upvec =
203 RotateVector3(kDefaultCameraUpVec, now_camera_state_.camera_quat));
204
205 SetCameraPositionAndTargetAndUpVec(
206 camera_pos,
207 dxlib_util::ConvertToDxlibVec(now_camera_state_.target_pos),
208 camera_upvec);
209
210 // ChangeLightTypeDirを使っているので,カメラ向きに合わせてライトの向きも変更する.
211 VECTOR light_dir =
213 -RotateVector3(kDefaultCameraFrontVec, now_camera_state_.camera_quat));
214
215 ChangeLightTypeDir(light_dir);
216}
217
218} // namespace designlab
void AddCameraToTargetLength(float length_dif)
カメラの注視する目標の座標からカメラまでの距離を増やす.
void InitCameraTargetLength()
カメラと注視点との距離を初期化する.
void Update()
カメラの位置などの更新を行う.毎フレーム実行すること.
void SetCameraViewMode(enums::CameraViewMode mode)
カメラのモードをセットする.同時にカメラの目標回転角度などを設定する.
static const float kCameraToTargetMax
カメラと注視目標の最大距離.
static const float kCameraToTargetMin
カメラと注視目標の最小距離.
VECTOR ConvertToDxlibVec(const Vector3 &vec)
Dxlibの座標を示すVECTORと,このプログラムで使用しているVectorを変換する. ロボット座標系は右手座標系, Dxlibは左手座標系(工学は右手・ゲームライブラリは左手が多い)なのでyを...
Definition dxlib_util.h:35
CameraViewMode
カメラの視点を表す列挙体.
@ kFreeControlledAndMovableTarget
自由に操作可能かつ注視点を設定可能.
@ kLeftSideView
右から真横の視点.
@ kTopView
上からの見下ろし視点.
@ kRightSideView
右から真横の視点.
@ kBackView
背面からの視点.
@ kFrontView
正面からの視点.
@ kFreeControlled
自由に操作可能.
T ApproachTarget(const T &current, const T &target, float rate)
目標値に値を近づける関数. 描画用なので,線形でなく,適当に値を近づける. そのため,計算に使いたいなら作り直すこと.
Definition math_util.h:85
constexpr T ConvertDegToRad(const T deg) noexcept
角度を [deg] から [rad] に変換する関数.
Definition math_util.h:126
Vector3 RotateVector3(const Vector3 &vec, const EulerXYZ &rot)
回転させたベクトルを返す.三角関数の処理が多く重たいので注意.
Quaternion SlerpQuaternion(const Quaternion &q1, const Quaternion &q2, const float t)
球面線形補間を行う.
クォータニオンを表す構造体.
static Quaternion MakeByAngleAxis(float rad_angle, const Vector3 &axis)
回転軸と回転角からクォータニオンを作成する. q = cos(θ/2) * w + sin(θ/2) * { v.x + v.y + v.z } となる. ノルムは必ず1になる.
3次元の位置ベクトルを表す構造体.
static constexpr Vector3 GetUpVec() noexcept
上に進む単位ベクトルを返す. 静的な関数なので,Vector3::GetUpVec() と呼び出せる.
static constexpr Vector3 GetFrontVec() noexcept
正面に進む単位ベクトルを返す. 静的な関数なので,Vector3::GetFrontVec() と呼び出せる.
static constexpr Vector3 GetLeftVec() noexcept
左に進む単位ベクトルを返す. 静的な関数なので,Vector3::GetLeftVec() と呼び出せる.