プロジェクト演習III,V <インタラクティブ・ゲーム制作> プログラミングコース 第8回 ゲームで使えるベクトル演算
今日の資料構成 ベクトルの基礎についてはPDFを参照 それをゲーム的にどう使うかをPPTで解説
今日の知識でできること ベクトルが表しているものの区別 距離による判定 角度による判定 真横の方向をゲットできる
まず押さえたいこと ベクトルの演算規則 三角関数の存在 スカラー積・和・差 長さ(ノルム) 内積 外積 射影 これはちょっと上級編 三角関数の存在 さすったりこすったりは要りません
ごっちゃにしてませんか? ベクトルは時と場合によって、 「座標」を表したり「方向」を表したり「移動量」を表したりと、 その意味合いが変化します fk_Modelのメンバ関数もごっちゃになる人が多いので、もう一度整理しましょう
fk_Modelで扱う ベクトルの意味一覧表 とりあえずグローバル座標版のみ ローカル座標はまた後ほど getVec()、getUpvec()で得られる方向ベクトルは 常に長さが1である 正規化済み 方向が重要なので 長さは無意味 関数名 動作 得る物・与える物 getPosition() 取得 座標 getVec() 方向(モデルの-z方向) getUpvec() getVec()との垂直方向 (モデルの+y方向) glRotate() 設定 軸を通る座標 glRotatewithVec() 軸を構成する座標 glTranslate() 移動量付きの方向 glMoveTo() glFocus() 注視する座標 glVec() 方向 glUpvec() glVec()との垂直方向
意味ごとの ベクトル演算結果一覧表 今回の資料と合わせてよく確認しておくこと 位置+位置はありえない ただし、tA+(1-t)Bの形式で表した式は線分上の任意の点を表す これは次回以降取り扱う 計算式 得られる物 位置+位置 Perdon? 位置A-位置B BからAへの方向 位置A+方向B AからB進んだ位置 位置A-方向B AからB戻った位置 方向A+方向B 合成された方向 方向A-方向B 位置*実数 方向*実数 長さを実数倍した方向
ローカル座標版について ローカル座標とは モデルのいる位置を原点とし、モデルに取っての前方向を(0,0,-1)、上方向を(0,1,0)とする座標系 神の手が「動かす」のではなく、自分で「動く」処理を行う際に便利 関数名 動作 得る物・与える物 loRotate 設定 軸を通るL座標 loRotateWithVec() 軸を構成するL座標 loTranslate() L座標系での移動量 loFocus() L座標系で(0,0,-1)に したい方向 loUpvec() L座標系で(0,1,0)に したい方向
距離判定 もはや言うまでもあるまい 位置Aー位置Bで得られたベクトルの長さを求めて、条件判定に利用できる fk_Vectorではdist()関数が利用できる fk_Vector vecAB = posB – posA; double distance = vecAB.dist(); こんな裏技もあるよ (posB-posA).dist();
角度判定 プレイヤーモデルの位置(posP)と、 敵モデルの位置(posE)と方向(vecE)から 「一定の角度内にプレイヤーが入ると追いかけてくる敵の動き」が実現できる 敵モデルから見たプレイヤーモデルへの方向を求める(vecEP = posP-posE) それを正規化して(vecEP.normalize())、 vecEとの内積を取る 得られたcosθの値を使って条件判定
外積の使い方 前述した角度判定の結果が「左右どっち側に何度なのか」を調べるのに利用 真横の方向をゲット 実演します glVec()^glUpvec()で右方向のベクトルが 得られる
今日の課題 一定距離内に一定の角度で近づいた場合、 プレイヤーモデル(キー操作可能なモデル)を追跡してくる動きを実現しよう 上下左右キーによる移動方向がカメラの向きと連動するようにしてみよう