GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
camera_dragger.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 "camera_dragger.h"
9
10#include "cassert_define.h"
11#include "dxlib_util.h"
12
13
14namespace designlab
15{
16
17CameraDragger::CameraDragger(const std::shared_ptr<DxlibCamera> camera) :
18 camera_ptr_(camera)
19{
20 assert(camera_ptr_ != nullptr);
21}
22
23void CameraDragger::DraggedAction(const int cursor_dif_x, const int cursor_dif_y,
24 const unsigned int mouse_key_bit)
25{
27
28 assert(camera_ptr_ != nullptr);
29
30 // カーソルが動いていたら,カメラの回転を変更する.
31 if ((mouse_key_bit & MOUSE_INPUT_LEFT) && (mouse_key_bit & MOUSE_INPUT_RIGHT))
32 {
33 if (abs(cursor_dif_x) > abs(cursor_dif_y))
34 {
35 // カメラの回転をマウスの横移動量に合わせて変更.
36 Quaternion move_quaternion_x = { 0, 0, 0, 0 };
37
38 move_quaternion_x = Quaternion::MakeByAngleAxis(
39 cursor_dif_x * kCameraMoveSpeed * -1, { 0, 0, 1 });
40
41 Quaternion res = camera_ptr_->GetCameraQuat() * move_quaternion_x;
42
43 res = res.GetNormalized();
44
45 camera_ptr_->SetCameraQuat(res);
46 }
47 else
48 {
49 // カメラの回転をマウスの縦移動量に合わせて変更.
50 Quaternion move_quaternion_y = Quaternion::MakeByAngleAxis(
51 cursor_dif_y * kCameraMoveSpeed * -1, { 0, 1, 0 });
52
53 Quaternion res = camera_ptr_->GetCameraQuat() * move_quaternion_y;
54
55 res = res.GetNormalized();
56
57 camera_ptr_->SetCameraQuat(res);
58 }
59 }
60 else if (mouse_key_bit & MOUSE_INPUT_MIDDLE)
61 {
62 // ホイールクリックをしていたらカメラを回転させる.
63 // XとYのどちらかの移動量が大きい方を処理する.
64
65 if (abs(cursor_dif_x) > 0)
66 {
67 // カメラの回転をマウスの横移動量に合わせて変更.
68 Quaternion move_quaternion_x = { 0, 0, 0, 0 };
69
70 move_quaternion_x = Quaternion::MakeByAngleAxis(
71 cursor_dif_x * kCameraMoveSpeed * -1, { 0, 0, 1 });
72
73 Quaternion res = camera_ptr_->GetCameraQuat() * move_quaternion_x;
74
75 res = res.GetNormalized();
76
77 camera_ptr_->SetCameraQuat(res);
78 }
79
80 if (abs(cursor_dif_y) > 0)
81 {
82 // カメラの回転をマウスの縦移動量に合わせて変更.
83 Quaternion move_quaternion_y = Quaternion::MakeByAngleAxis(
84 cursor_dif_y * kCameraMoveSpeed * -1, { 0, 1, 0 });
85
86 Quaternion res = camera_ptr_->GetCameraQuat() * move_quaternion_y;
87
88 res = res.GetNormalized();
89
90 camera_ptr_->SetCameraQuat(res);
91 }
92 }
93 else if (mouse_key_bit & MOUSE_INPUT_LEFT)
94 {
95 // 左クリックしていたらカメラのビュー視点の中心軸を回転軸とした回転.
96 const int mouse_move =
97 abs(cursor_dif_x) > abs(cursor_dif_y) ? cursor_dif_x : cursor_dif_y;
98
99 if (mouse_move != 0)
100 {
101 const Quaternion move_quaternion = Quaternion::MakeByAngleAxis(
102 mouse_move * kCameraMoveSpeed * -1.0f, { 1, 0, 0 });
103
104 const Quaternion res =
105 (camera_ptr_->GetCameraQuat() * move_quaternion).GetNormalized();
106
107 camera_ptr_->SetCameraQuat(res);
108 }
109 }
110 else if (
111 mouse_key_bit & MOUSE_INPUT_RIGHT &&
112 Squared(cursor_dif_x) + Squared(cursor_dif_y) > Squared(kMouseMoveMargin))
113 {
114 // 右クリックしていたらカメラの平行移動.
115 if (camera_ptr_->GetCameraViewMode() !=
117 {
118 // 表示モードを注視点を自由に動かせるモードに変更.
119 camera_ptr_->SetCameraViewMode(
121 }
122
123
124 Vector3 move_vec_x = { 0, 0, 0 };
125
126 if (abs(cursor_dif_x) > 0)
127 {
128 move_vec_x = { 0, cursor_dif_x * kCameraTargetMoveSpeed * -1, 0 };
129
130 move_vec_x = RotateVector3(move_vec_x, camera_ptr_->GetCameraQuat());
131 }
132
133 Vector3 move_vec_y = { 0, 0, 0 };
134
135 if (abs(cursor_dif_y) > 0)
136 {
137 move_vec_y = { 0, 0, cursor_dif_y * kCameraTargetMoveSpeed };
138
139 move_vec_y = RotateVector3(move_vec_y, camera_ptr_->GetCameraQuat());
140 }
141
142 // 現在のターゲット座標を取得.
143 Vector3 now_target_pos = camera_ptr_->GetFreeTargetPos();
144
145 now_target_pos = now_target_pos + move_vec_x + move_vec_y; // 移動量を加算.
146
147 camera_ptr_->SetFreeTargetPos(now_target_pos); // ターゲット座標を更新.
148 }
149}
150
151void CameraDragger::RotMouseWheel(const int rot) const
152{
153 camera_ptr_->AddCameraToTargetLength(kCameraZoomSpeed * rot * -1);
154}
155
156} // namespace designlab
CameraDragger(const std::shared_ptr< DxlibCamera > camera)
void DraggedAction(int cursor_dif_x, int cursor_dif_y, unsigned int mouse_key_bit) override
ドラッグ中の処理を行う. カーソルは上にあるけど,ドラッグ中ではない場合でも呼び出される.
void RotMouseWheel(int rot) const override
マウスホイールが回転したときの処理を行う. マウスホイールが回転したときに呼び出される.
@ kFreeControlledAndMovableTarget
自由に操作可能かつ注視点を設定可能.
constexpr T Squared(const T num) noexcept
2乗した値を返す関数.
Definition math_util.h:59
Vector3 RotateVector3(const Vector3 &vec, const EulerXYZ &rot)
回転させたベクトルを返す.三角関数の処理が多く重たいので注意.
クォータニオンを表す構造体.
Quaternion GetNormalized() const noexcept
正規化したクォータニオンを返す. クォータニオンの正規化とは,ノルムを1にすることを表す. クォータニオンqの正規化は,q / |q| で求められる.
static Quaternion MakeByAngleAxis(float rad_angle, const Vector3 &axis)
回転軸と回転角からクォータニオンを作成する. q = cos(θ/2) * w + sin(θ/2) * { v.x + v.y + v.z } となる. ノルムは必ず1になる.
3次元の位置ベクトルを表す構造体.