質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

1回答

1274閲覧

戦車の砲台のように回転させたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2020/09/25 00:28

編集2022/01/12 10:55

左に回転させたあと右側に回転させるとその場所に瞬間移動ようにな形で回転してしまうのですが自分は左に回転して右側に回転したらそのまま
一定の速度で回転したいのですがどうすればいいのでしょうか?

**例「戦車の砲台で前を見ていて後ろに砲台を向けようとして左キーを押したらその瞬間後ろに向いてしまう」**現象の解決法が知りたです。

イメージ説明
イメージ説明

cpp

1 2 3//回転行列を設定 4void Game::Set_rotate(float xx,float yy,float zz,float r) 5{ 6 glm::quat someQuat = glm::angleAxis(r,glm::vec3(xx,yy,zz)); 7 glm::mat4 ro = glm::toMat4(someQuat); 8 9 memcpy(rotate, glm::value_ptr(ro), sizeof(float) * 16); 10 11} 12 13 14//アップデート 15void Game::Update() 16{ 17 if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(Window) != GL_FALSE) 18 { 19 mIsRunLoop = false; 20 } 21 22 23 24 25 26 if (glfwGetKey(Window, GLFW_KEY_F1) == GLFW_PRESS) 27 { 28 if (keyMode != KeyState::Move) 29 { 30 keyMode = KeyState::Move; 31 printf(" MODE: 移動\n"); 32 } 33 34 }else if (glfwGetKey(Window, GLFW_KEY_F2) == GLFW_PRESS) 35 { 36 if (keyMode != KeyState::Rotate) 37 { 38 keyMode = KeyState::Rotate; 39 printf(" MODE: 回転\n"); 40 } 41 42 } 43 44 45 46 47 //モード切り替え 48 switch ( keyMode ) 49 { 50 51 case KeyState::Move: 52 { 53 ///////////////左右上下移動 54 if (glfwGetKey(Window, GLFW_KEY_LEFT) == GLFW_PRESS) 55 { 56 pos.x -= 0.03f; 57 pos.z = -5; 58 59 Set_move(pos.x, pos.y, pos.z); 60 printf("LEFT %.2f\n",pos.x); 61 } 62 else if (glfwGetKey(Window, GLFW_KEY_RIGHT) == GLFW_PRESS) 63 { 64 65 pos.x += 0.03f; 66 pos.z = -5; 67 68 Set_move(pos.x, pos.y, pos.z); 69 70 printf("RIGHT %.2f\n",pos.x); 71 } 72 73 if (glfwGetKey(Window, GLFW_KEY_UP) == GLFW_PRESS) 74 { 75 76 // pos.x -= 0.0f; 77 pos.y += 0.3f; 78 // pos.z -= 0.0f; 79 80 Set_move(pos.x, pos.y, pos.z); 81 82 printf("UP\n"); 83 84 } 85 else if (glfwGetKey(Window, GLFW_KEY_DOWN) == GLFW_PRESS) 86 { 87 // pos.x -= 0.0f; 88 pos.y -= 0.3f; 89 // pos.z -= 0.0f; 90 91 Set_move(pos.x, pos.y, pos.z); 92 printf("DOWN\n"); 93 } 94 95 //Z軸移動 96 if (glfwGetKey(Window, GLFW_KEY_Z) == GLFW_PRESS) 97 { 98 99 // pos.x -= 0.0f; 100 // pos.y -= 0.0f; 101 pos.z -= 0.03f; 102 103 104 Set_move(pos.x, pos.y, pos.z); 105 printf("Z: %.2f\n", pos.z); 106 } 107 else if (glfwGetKey(Window, GLFW_KEY_X) == GLFW_PRESS) 108 { 109 110 // pos.x += 0.0f; 111 // pos.y += 0.0f; 112 pos.z += 0.03f; 113 114 Set_move(pos.x, pos.y, pos.z); 115 printf("X: %.2f\n", pos.z); 116 } 117 } 118 break; 119 120 121 //--------------------------------------------------回転 122 case KeyState::Rotate: 123 { 124 //const float speed = 0.03; 125 const float speed = 1.0f; 126 127 if (glfwGetKey(Window, GLFW_KEY_LEFT) == GLFW_PRESS)//left 128 { 129 //回転単位ベクトル 130 move_rotate.x = 0; 131 move_rotate.y = -speed; 132 move_rotate.z = 0; 133 134 135 r += glm::radians(1.0f); 136 137 Set_rotate(move_rotate.x, move_rotate.y, move_rotate.z, r); 138 139 key = KeyState::Left; 140 printf("LEFT\n"); 141 } 142 else if (glfwGetKey(Window, GLFW_KEY_RIGHT) == GLFW_PRESS) 143 { 144 //回転単位ベクトル 145 146 move_rotate.x = 0; 147 move_rotate.y = -speed; 148 move_rotate.z = 0; 149 150 151 r -= glm::radians(1.0f); 152 153 Set_rotate(move_rotate.x, move_rotate.y, move_rotate.z, r); 154 155 key = KeyState::Right; 156 printf("RIGHT\n"); 157 } 158 159 if (glfwGetKey(Window, GLFW_KEY_UP) == GLFW_PRESS) 160 { 161 //回転単位ベクトル 162 move_rotate.x = speed; 163 move_rotate.y = 0; 164 move_rotate.z = 0; 165 166 167 r += glm::radians(1.0f); 168 169 170 171 172 173 Set_rotate(move_rotate.x, move_rotate.y, move_rotate.z, r); 174 175 176 printf("UP\n"); 177 178 } 179 else if (glfwGetKey(Window, GLFW_KEY_DOWN) == GLFW_PRESS) 180 { 181 182 //回転単位ベクトル 183 move_rotate.x = -speed; 184 move_rotate.y = 0; 185 move_rotate.z = 0; 186 187 188 r -= glm::radians(1.0f); 189 190 Set_rotate(move_rotate.x, move_rotate.y, move_rotate.z, r); 191 192 193 printf("DOWN\n"); 194 } 195 196 //Z軸移動 197 if (glfwGetKey(Window, GLFW_KEY_Z) == GLFW_PRESS) 198 { 199 200 201 202 Set_move(move_rotate.x, move_rotate.y, move_rotate.z); 203 printf("Z: %.2f\n", move_rotate.z); 204 } 205 else if (glfwGetKey(Window, GLFW_KEY_X) == GLFW_PRESS) 206 { 207 208 209 210 Set_move(move_rotate.x, move_rotate.y, move_rotate.z); 211 printf("X: %.2f\n", move_rotate.z); 212 } 213 } 214 break; 215 //-------------------------------------------------- 216 } 217 218} 219 220 221//描画アップデート 222void Game::GenerateOutput() 223{ 224 225 glClearColor(1.0f, 0.0f, 0.0f, 1.0f); 226 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 227 228 //ワールド行列を再計算 229 CreateWorldMatrix(); 230 231 232 233 234 235 //透視射形行列を再計算 236 glm::mat4 v = glm::perspective(glm::radians(90.f), (640.0f / 400.0f), 0.1f, 100.0f); 237 238 //カメラ 239 glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 0), glm::vec3(0,0,-1), glm::vec3(0, 1, 0)); 240 glm::mat4 r = view * v; 241 memcpy(viewMatrix, &r, sizeof(float) * 16); 242 243 244 245 //シェーダープログラムをアクティブ 246 glUseProgram(ShaderProgram); 247 248 //Uniformリソースをプログラムに設定 249 glUniformMatrix4fv(glGetUniformLocation(ShaderProgram, "worldMatrix"), 1, GL_FALSE, wordlMatrix); 250 glUniformMatrix4fv(glGetUniformLocation(ShaderProgram, "viewMatrix"), 1, GL_FALSE, viewMatrix); 251 252 253 254 // 頂点リソースを設定 255 glBindVertexArray(vao); 256 257 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 258 259 260 glDrawElements(GL_TRIANGLES, std::size(index), GL_UNSIGNED_INT,0); 261 262 263 264 265 glViewport(0, 0, WIDTH, HEIGHT); 266 glfwSwapBuffers(Window); 267 glfwPollEvents(); 268 269}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/25 01:33

文章とタイトルを編集しました。
退会済みユーザー

退会済みユーザー

2020/09/26 02:07

質問とタイトルを編集しました。
txty

2020/09/27 09:58 編集

テクスチャの貼りつけができてるみたいですが、質問もされていたようなので、何が原因だったか書いてください。
guest

回答1

0

ひょっとして,

新しい回転行列 = さらなる回転のための回転行列 * いままでの回転のための回転行列

とかして更新すれば良いのでは……みたいな話だったりしますか?

投稿2020/09/25 04:09

fana

総合スコア11632

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

txty

2020/09/25 05:13 編集

私が仮に書いた内積の引数は間違いでしたか。その回答を私のページにも貼っていいでしょうか。
fana

2020/09/25 07:23 編集

? (全てが突然すぎて,何の話かもわからない)
退会済みユーザー

退会済みユーザー

2020/09/25 07:41

例えばフィギュアを斜めから見たいからちょっと傾けてその場でその斜めを維持したまま横に回転させて横からその斜めにしたフィギュアを色んな角度からみたいっていうやつですねw
txty

2020/09/25 08:48 編集

>fanaさん私はスレッドをたて4*4行列の計算を内積(内積の計算が合ってないようだが)解こうとしたんですが、A*B not B*A で AとBに何をいれるのか分かりませんでした。で、提示コメントにある 新しい回転行列 = さらなる回転のための回転行列 * いままでの回転のための回転行列が正しいとおもったのですが、内積の計算次第でもある気がしたので、分からない状態のままにしておこうと新たに考えました。 コメントは人様のスレッドなのでこれぐらいにしときます。
fana

2020/09/25 08:18 編集

回転Aと回転Bとの合成を考える場合, 合成結果 = A * B とするか 合成結果 = B * A とするか,という話であるならば,それは単に考えやすい(扱いやすい)方を使えばいい. Aが既存の回転で,Bがさらなる追加の回転である場合, 合成結果 = A * B の側を用いるならば, 合成結果*v = (A*B)*v = A*( B*v ) であり,その意味は, 「vがあらかじめBによって回転した結果に,Aによる回転を施す」だ. 例えば,戦車の砲のようなものについて考える.この砲には狙いを定めやすいようにカメラがくくりつけられているとしよう. (カメラ映像のど真ん中に標的を捉えて撃つような用途だ) 砲塔の旋回と砲の仰角が共に既に(ある基準の姿勢から)何らかの角度に変更された後の状態において,何故かこのカメラに砲身の方向を回転軸とした回転(要はroll)をさせたいのだとしよう. この追加の回転の回転軸を 「砲塔の旋回と砲の仰角が共に既に何らかの角度に変更された結果の上での」値として考えるのはわりと面倒だ. しかし,見方を変えて, 「カメラがあらかじめRollした後に,砲塔の旋回と砲の仰角の変更が行われた」と考えるならば,このRollの回転軸を考えるのは楽になるであろう. 何をどのような順序で「やったことにすれば」所望の結果が得られるかを考えたときに,複数のやり方があるならば,その中で自分が最も楽に扱える方法を採ればいい. ※この回答の趣旨は「今の回転を捨てるのではなく,新しい回転と合成すれば良い」というところにあり, その合成順序までを指定する意図はない.
退会済みユーザー

退会済みユーザー

2020/09/26 02:59 編集

質問内容をわかりやすく編集しました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問