[ゲームシステムの全体構成]
図1を参照して、本発明の一実施形態に係るゲーム装置を含むゲームシステム1について説明する。図1は、ゲームシステム1の外観図である。以下、据置型のゲーム装置を一例にして、本実施形態のゲーム装置及びゲームプログラムについて説明する。図1において、ゲームシステム1は、テレビジョン受像器(以下、単に「テレビ」と記載する)2、ゲーム装置3、光ディスク4、入力装置8、及びマーカ部6を含む。本システムは、入力装置8を用いたゲーム操作に基づいてゲーム装置3でゲーム処理を実行するものである。
ゲーム装置3には、当該ゲーム装置3に対して交換可能に用いられる情報記憶媒体の一例である光ディスク4が脱着可能に挿入される。光ディスク4には、ゲーム装置3において実行されるためのゲームプログラムが記憶されている。ゲーム装置3の前面には光ディスク4の挿入口が設けられている。ゲーム装置3は、挿入口に挿入された光ディスク4に記憶されているゲームプログラムを読み出して実行することによってゲーム処理を実行する。
ゲーム装置3には、表示装置の一例であるテレビ2が接続コードを介して接続される。テレビ2は、ゲーム装置3において実行されるゲーム処理の結果得られるゲーム画像を表示する。また、テレビ2の画面の周辺(図1では画面の上側)には、マーカ部6が設置される。マーカ部6は、その両端に2つのマーカ6R及び6Lを備えている。マーカ6R(マーカ6Lも同様)は、具体的には1以上の赤外LEDであり、テレビ2の前方に向かって赤外光を出力する。マーカ部6はゲーム装置3に接続されており、ゲーム装置3はマーカ部6が備える各赤外LEDの点灯を制御することが可能である。
入力装置8は、自機に対して行われた操作の内容を示す操作データをゲーム装置3に与えるものである。本実施形態では、入力装置8はコントローラ5とジャイロセンサユニット7とを含む。詳細は後述するが、入力装置8は、コントローラ5に対してジャイロセンサユニット7が着脱可能に接続されている構成である。コントローラ5とゲーム装置3とは無線通信によって接続される。本実施形態では、コントローラ5とゲーム装置3との間の無線通信には例えばBluetooth(ブルートゥース)(登録商標)の技術が用いられる。なお、他の実施形態においてはコントローラ5とゲーム装置3とは有線で接続されてもよい。
[ゲーム装置3の内部構成]
次に、図2を参照して、ゲーム装置3の内部構成について説明する。図2は、ゲーム装置3の構成を示すブロック図である。ゲーム装置3は、CPU10、システムLSI11、外部メインメモリ12、ROM/RTC13、ディスクドライブ14、及びAV−IC15等を有する。
CPU10は、光ディスク4に記憶されたゲームプログラムを実行することによってゲーム処理を実行するものであり、ゲームプロセッサとして機能する。CPU10は、システムLSI11に接続される。システムLSI11には、CPU10の他、外部メインメモリ12、ROM/RTC13、ディスクドライブ14及びAV−IC15が接続される。システムLSI11は、それに接続される各構成要素間のデータ転送の制御、表示すべき画像の生成、外部装置からのデータの取得等の処理を行う。システムLSI11の内部構成については後述する。揮発性の外部メインメモリ12は、光ディスク4から読み出されたゲームプログラムや、フラッシュメモリ17から読み出されたゲームプログラム等のプログラムを記憶したり、各種データを記憶したりするものであり、CPU10のワーク領域やバッファ領域として用いられる。ROM/RTC13は、ゲーム装置3の起動用のプログラムが組み込まれるROM(いわゆるブートROM)と、時間をカウントするクロック回路(RTC:Real Time Clock)とを有する。ディスクドライブ14は、光ディスク4からプログラムデータやテクスチャデータ等を読み出し、後述する内部メインメモリ11e又は外部メインメモリ12に読み出したデータを書き込む。
また、システムLSI11には、入出力プロセッサ(I/Oプロセッサ)11a、GPU(Graphics Processor Unit)11b、DSP(Digital Signal Processor)11c、VRAM11d、及び内部メインメモリ11eが設けられる。図示は省略するが、これらの構成要素11a〜11eは内部バスによって互いに接続される。
GPU11bは、描画手段の一部を形成し、CPU10からのグラフィクスコマンド(作画命令)に従って画像を生成する。VRAM11dは、GPU11bがグラフィクスコマンドを実行するために必要なデータ(ポリゴンデータやテクスチャデータ等のデータ)を記憶する。画像が生成される際には、GPU11bは、VRAM11dに記憶されたデータを用いて画像データを作成する。
DSP11cは、オーディオプロセッサとして機能し、内部メインメモリ11eや外部メインメモリ12に記憶されるサウンドデータや音波形(音色)データを用いて、音声データを生成する。
上述のように生成された画像データ及び音声データは、AV−IC15によって読み出される。AV−IC15は、読み出した画像データをAVコネクタ16を介してテレビ2に出力するとともに、読み出した音声データを、テレビ2に内蔵されるスピーカ2aに出力する。これによって、画像がテレビ2に表示されるとともに音がスピーカ2aから出力される。
入出力プロセッサ11aは、それに接続される構成要素との間でデータの送受信を実行したり、外部装置からのデータのダウンロードを実行したりする。入出力プロセッサ11aは、フラッシュメモリ17、無線通信モジュール18、無線コントローラモジュール19、拡張コネクタ20、及びメモリカード用コネクタ21に接続される。無線通信モジュール18にはアンテナ22が接続され、無線コントローラモジュール19にはアンテナ23が接続される。
入出力プロセッサ11aは、無線通信モジュール18及びアンテナ22を介してネットワークに接続し、ネットワークに接続される他のゲーム装置や各種サーバと通信することができる。入出力プロセッサ11aは、定期的にフラッシュメモリ17にアクセスし、ネットワークへ送信する必要があるデータの有無を検出し、当該データが有る場合には、無線通信モジュール18及びアンテナ22を介してネットワークに送信する。また、入出力プロセッサ11aは、他のゲーム装置から送信されてくるデータやダウンロードサーバからダウンロードしたデータを、ネットワーク、アンテナ22及び無線通信モジュール18を介して受信し、受信したデータをフラッシュメモリ17に記憶する。CPU10はゲームプログラムを実行することにより、フラッシュメモリ17に記憶されたデータを読み出してゲームプログラムで利用する。フラッシュメモリ17には、ゲーム装置3と他のゲーム装置や各種サーバとの間で送受信されるデータの他、ゲーム装置3を利用してプレイしたゲームのセーブデータ(ゲームの結果データ又は途中データ)が記憶されてもよい。
また、入出力プロセッサ11aは、コントローラ5から送信される操作データをアンテナ23及び無線コントローラモジュール19を介して受信し、内部メインメモリ11e又は外部メインメモリ12のバッファ領域に記憶(一時記憶)する。
さらに、入出力プロセッサ11aには、拡張コネクタ20及びメモリカード用コネクタ21が接続される。拡張コネクタ20は、USBやSCSIのようなインターフェースのためのコネクタであり、外部記憶媒体のようなメディアを接続したり、他のコントローラのような周辺機器を接続したり、有線の通信用コネクタを接続することによって無線通信モジュール18に替えてネットワークとの通信を行ったりすることができる。メモリカード用コネクタ21は、メモリカードのような外部記憶媒体を接続するためのコネクタである。例えば、入出力プロセッサ11aは、拡張コネクタ20やメモリカード用コネクタ21を介して外部記憶媒体にアクセスし、外部記憶媒体にデータを保存したり、外部記憶媒体からデータを読み出したりすることができる。
ゲーム装置3には、電源ボタン24、リセットボタン25、及びイジェクトボタン26が設けられる。電源ボタン24及びリセットボタン25は、システムLSI11に接続される。電源ボタン24がオンされると、ゲーム装置3の各構成要素に対して、図示しないACアダプタを経て電源が供給される。リセットボタン25が押されると、システムLSI11は、ゲーム装置3の起動プログラムを再起動する。イジェクトボタン26は、ディスクドライブ14に接続される。イジェクトボタン26が押されると、ディスクドライブ14から光ディスク4が排出される。
[入力装置8の構成]
次に、図3〜図6を参照して、入力装置8について説明する。図3は、入力装置8の外観構成を示す斜視図である。図4は、コントローラ5の外観構成を示す斜視図である。図3は、コントローラ5の上側後方から見た斜視図であり、図4は、コントローラ5を下側前方から見た斜視図である。
図3及び図4において、コントローラ5は、例えばプラスチック成型によって形成されたハウジング31を有している。ハウジング31は、その前後方向(図3に示すZ軸方向)を長手方向とした略直方体形状を有しており、全体として大人や子供の片手で把持可能な大きさである。プレイヤは、コントローラ5に設けられたボタンを押下すること、及び、コントローラ5自体を動かしてその位置や姿勢を変えることによってゲーム操作を行うことができる。
ハウジング31には、複数の操作ボタンが設けられる。図3に示すように、ハウジング31の上面には、十字ボタン32a、1番ボタン32b、2番ボタン32c、Aボタン32d、マイナスボタン32e、ホームボタン32f、プラスボタン32g、及び電源ボタン32hが設けられる。一方、図4に示すように、ハウジング31の下面には凹部が形成されており、当該凹部の後面側傾斜面にはBボタン32iが設けられる。これらの各操作ボタン32a〜32iには、ゲーム装置3が実行するゲームプログラムに応じた機能が適宜割り当てられる。また、電源ボタン32hは遠隔からゲーム装置3本体の電源をオン/オフするためのものである。ホームボタン32f及び電源ボタン32hは、その上面がハウジング31の上面に埋没している。これによって、プレイヤがホームボタン32f又は電源ボタン32hを誤って押下することを防止することができる。
ハウジング31の後面にはコネクタ33が設けられている。コネクタ33は、コントローラ5に他の機器(例えば、ジャイロセンサユニット7や他のコントローラ)を接続するために利用される。また、ハウジング31の後面におけるコネクタ33の両側には、上記他の機器が容易に離脱することを防止するために係止穴33aが設けられている。
ハウジング31上面の後方には複数(図3では4つ)のLED34a〜34dが設けられる。ここで、コントローラ5には、他のメインコントローラと区別するためにコントローラ種別(番号)が付与される。各LED34a〜34dは、コントローラ5に現在設定されている上記コントローラ種別をプレイヤに通知したり、コントローラ5の電池残量をプレイヤに通知したりする等の目的で用いられる。具体的には、コントローラ5を用いてゲーム操作が行われる際、上記コントローラ種別に応じて複数のLED34a〜34dのいずれか1つが点灯する。
また、コントローラ5は撮像情報演算部35(図7)を有しており、図4に示すように、ハウジング31前面には撮像情報演算部35の光入射面35aが設けられる。光入射面35aは、マーカ6R及び6Lからの赤外光を少なくとも透過する材質で構成される。
ハウジング31上面における1番ボタン32bとホームボタン32fとの間には、コントローラ5に内蔵されるスピーカ49(図5)からの音を外部に放出するための音抜き孔31aが形成されている。
次に、図5及び図6を参照して、コントローラ5の内部構造について説明する。図5及び図6は、コントローラ5の内部構造を示す図である。なお、図5は、コントローラ5の上筐体(ハウジング31の一部)を外した状態を示す斜視図である。図6は、コントローラ5の下筐体(ハウジング31の一部)を外した状態を示す斜視図である。図6に示す斜視図は、図5に示す基板30を裏面から見た斜視図となっている。
図5において、ハウジング31の内部には基板30が固設されており、当該基板30の上主面上に各操作ボタン32a〜32h、各LED34a〜34d、加速度センサ37、アンテナ45、及びスピーカ49等が設けられる。これらは、基板30等に形成された配線(図示せず)によってマイクロコンピュータ(Micro Computer:マイコン)42(図6参照)に接続される。本実施形態では、加速度センサ37は、X軸方向に関してコントローラ5の中心からずれた位置に配置されている。これによって、コントローラ5をZ軸回りに回転させたときのコントローラ5の動きが算出しやすくなる。また、加速度センサ37は、長手方向(Z軸方向)に関してコントローラ5の中心よりも前方に配置されている。また、無線モジュール44(図7)及びアンテナ45によって、コントローラ5がワイヤレスコントローラとして機能する。
一方、図6において、基板30の下主面上の前端縁に撮像情報演算部35が設けられる。撮像情報演算部35は、コントローラ5の前方から順に赤外線フィルタ38、レンズ39、撮像素子40、及び画像処理回路41を備えている。これらの部材38〜41はそれぞれ基板30の下主面に取り付けられる。
さらに、基板30の下主面上には、上記マイコン42及びバイブレータ48が設けられている。バイブレータ48は、例えば振動モータやソレノイドであり、基板30等に形成された配線によってマイコン42と接続される。マイコン42の指示によりバイブレータ48が作動することによってコントローラ5に振動が発生する。これによって、コントローラ5を把持しているプレイヤの手にその振動が伝達される、いわゆる振動対応ゲームを実現することができる。本実施形態では、バイブレータ48は、ハウジング31のやや前方寄りに配置される。つまり、バイブレータ48がコントローラ5の中心よりも端側に配置することによって、バイブレータ48の振動によりコントローラ5全体を大きく振動させることができる。また、コネクタ33は、基板30の下主面上の後端縁に取り付けられる。なお、図5及び図6に示す他、コントローラ5は、マイコン42の基本クロックを生成する水晶振動子、スピーカ49に音声信号を出力するアンプ等を備えている。
また、ジャイロセンサユニット7は、3軸回りの角速度を検知するジャイロセンサ(図7に示すジャイロセンサ55及び56)を有する。ジャイロセンサユニット7は、コントローラ5のコネクタ33に着脱可能に装着される。ジャイロセンサユニット7の前端(図3に示すZ軸正方向側の端部)には、コネクタ33に接続可能なプラグ(図7に示すプラグ53)が設けられる。さらに、プラグ53の両側にはフック(図示せず)が設けられる。ジャイロセンサユニット7がコントローラ5に対して装着される状態では、プラグ53がコネクタ33に接続されるとともに、上記フックがコントローラ5の係止穴33aに係止する。これによって、コントローラ5とジャイロセンサユニット7とがしっかりと固定される。また、ジャイロセンサユニット7は側面(図3に示すX軸方向の面)にボタン51を有している。ボタン51は、それを押下すれば上記フックの係止穴33aに対する係止状態を解除することができるように構成されている。したがって、ボタン51を押下しながらプラグ53をコネクタ33から抜くことによって、ジャイロセンサユニット7をコントローラ5から離脱することができる。
また、ジャイロセンサユニット7の後端には、上記コネクタ33と同形状のコネクタが設けられる。したがって、コントローラ5(のコネクタ33)に対して装着可能な他の機器は、ジャイロセンサユニット7のコネクタに対しても装着可能である。なお、図3においては、当該コネクタに対してカバー52が着脱可能に装着されている。
なお、図3〜図6に示したコントローラ5及びジャイロセンサユニット7の形状や、各操作ボタンの形状、加速度センサやバイブレータの数及び設置位置等は単なる一例に過ぎず、他の形状、数、及び設置位置であってもよい。また、本実施形態では、撮像手段による撮像方向はZ軸正方向であるが、撮像方向はいずれの方向であってもよい。すなわち、コントローラ5における撮像情報演算部35の位置(撮像情報演算部35の光入射面35a)は、ハウジング31の前面でなくてもよく、ハウジング31の外部から光を取り入れることができれば他の面に設けられてもかまわない。
図7は、入力装置8(コントローラ5及びジャイロセンサユニット7)の構成を示すブロック図である。コントローラ5は、操作部32(各操作ボタン32a〜32i)、コネクタ33、撮像情報演算部35、通信部36、及び加速度センサ37を備えている。コントローラ5は、自機に対して行われた操作内容を示すデータを操作データとしてゲーム装置3へ送信するものである。
操作部32は、上述した各操作ボタン32a〜32iを含み、各操作ボタン32a〜32iに対する入力状態(各操作ボタン32a〜32iが押下されたか否か)を示す操作ボタンデータを通信部36のマイコン42へ出力する。
撮像情報演算部35は、撮像手段が撮像した画像データを解析してその中で輝度が高い領域を判別してその領域の重心位置やサイズなどを算出するためのシステムである。撮像情報演算部35は、例えば最大200フレーム/秒程度のサンプリング周期を有するので、比較的高速なコントローラ5の動きでも追跡して解析することができる。
撮像情報演算部35は、赤外線フィルタ38、レンズ39、撮像素子40、及び画像処理回路41を含んでいる。赤外線フィルタ38は、コントローラ5の前方から入射する光から赤外線のみを通過させる。レンズ39は、赤外線フィルタ38を透過した赤外線を集光して撮像素子40へ入射させる。撮像素子40は、例えばCMOSセンサやあるいはCCDセンサのような固体撮像素子であり、レンズ39が集光した赤外線を受光して画像信号を出力する。ここで、テレビ2の表示画面近傍に配置されるマーカ部6のマーカ6R及び6Lは、テレビ2の前方に向かって赤外光を出力する赤外LEDで構成される。したがって、赤外線フィルタ38を設けることによって、撮像素子40は、赤外線フィルタ38を通過した赤外線だけを受光して画像データを生成するので、マーカ6R及び6Lの画像をより正確に撮像することができる。以下では、撮像素子40によって撮像された画像を撮像画像と呼ぶ。撮像素子40によって生成された画像データは、画像処理回路41で処理される。画像処理回路41は、撮像画像内における撮像対象(マーカ6R及び6L)の位置を算出する。画像処理回路41は、算出された位置を示す座標を通信部36のマイコン42へ出力する。この座標のデータは、マイコン42によって操作データとしてゲーム装置3に送信される。以下では、上記座標を「マーカ座標」と呼ぶ。マーカ座標はコントローラ5自体の向き(傾斜角度)や位置に対応して変化するので、ゲーム装置3はこのマーカ座標を用いてコントローラ5の向きや位置を算出することができる。
なお、他の実施形態においては、コントローラ5は画像処理回路41を備えていない構成であってもよく、撮像画像自体がコントローラ5からゲーム装置3へ送信されてもよい。このとき、ゲーム装置3は、画像処理回路41と同様の機能を有する回路あるいはプログラムを有しており、上記マーカ座標を算出するようにしてもよい。
加速度センサ37は、コントローラ5の加速度(重力加速度を含む)を検出する、すなわち、コントローラ5に加わる力(重力を含む)を検出する。加速度センサ37は、当該加速度センサ37の検出部に加わっている加速度のうち、センシング軸方向に沿った直線方向の加速度(直線加速度)の値を検出する。例えば、2軸以上の多軸加速度センサの場合には、加速度センサの検出部に加わっている加速度として、各軸に沿った成分の加速度をそれぞれ検出する。例えば、3軸又は2軸の加速度センサは、アナログ・デバイセズ株式会社(Analog Devices, Inc.)又はSTマイクロエレクトロニクス社(STMicroelectronics N.V.)から入手可能である種類のものでもよい。なお、加速度センサ37は、例えば静電容量式の加速度センサであるとするが、他の方式の加速度センサを用いるようにしてもよい。
本実施形態では、加速度センサ37は、コントローラ5を基準とした上下方向(図3に示すY軸方向)、左右方向(図3に示すX軸方向)及び前後方向(図3に示すZ軸方向)の3軸方向に関してそれぞれ直線加速度を検出する。加速度センサ37は、各軸に沿った直線方向に関する加速度を検出するものであるため、加速度センサ37からの出力は3軸それぞれの直線加速度の値を表すものとなる。すなわち、検出された加速度は、入力装置8(コントローラ5)を基準に設定されるXYZ座標系(コントローラ座標系)における3次元のベクトル(ax,ay,az)として表される。以下では、加速度センサ37によって検出される3軸に関する各加速度値を各成分とするベクトルを加速度ベクトルと呼ぶ。
加速度センサ37が検出した加速度を示すデータ(加速度データ)は、通信部36へ出力される。なお、加速度センサ37が検出した加速度は、コントローラ5自体の向き(傾斜角度)や動きに対応して変化するので、ゲーム装置3は加速度データを用いてコントローラ5の向きや動きを算出することができる。本実施形態では、ゲーム装置3は、加速度データ及び後述する角速度データに基づいて入力装置8(コントローラ5)の姿勢を判断する。入力装置8の姿勢は、例えば、入力装置8が存在する空間の所定位置を基準としたxyz座標系の座標値によって表される。ここでは、図1に示されるように、xyz座標系は、入力装置8がマーカ部6の正面に位置することを前提とし、入力装置8の位置からマーカ部6を向く方向をz軸正方向とし、鉛直上向き(重力方向の逆方向)をy軸正方向とし、入力装置8の位置からマーカ部6を見た場合の左方向をx軸正方向とした座標系であるとする。また、ここでは、入力装置8(コントローラ5)を基準としたX軸、Y軸、Z軸が、それぞれx軸、y軸、z軸の向きと一致するときの入力装置8の姿勢を基準姿勢と呼ぶことにする。入力装置8の姿勢は、基準姿勢からZ軸方向を基準としてロール方向(Z軸周り)、ピッチ方向(X軸周り)、ヨー方向(Y軸周り)にそれぞれ入力装置8を回転させた場合のxyz座標系における姿勢である。当該姿勢は、後述する回転行列Mによって表現される。
加速度センサ37が検出した加速度(加速度ベクトル)を示すデータ(加速度データ)は、通信部36へ出力される。
なお、加速度センサ37から出力される加速度の信号に基づいて、ゲーム装置3のプロセッサ(例えばCPU10)又はコントローラ5のプロセッサ(例えばマイコン42)等のコンピュータが処理を行うことによって、コントローラ5に関するさらなる情報を推測又は算出(判定)することができることは、当業者であれば本明細書の説明から容易に理解できるであろう。例えば、加速度センサ37を搭載するコントローラ5が静止状態であることを前提としてコンピュータ側の処理が実行される場合(すなわち、加速度センサによって検出される加速度が重力加速度のみであるとして処理が実行される場合)、コントローラ5が現実に静止状態であれば、検出された加速度に基づいてコントローラ5の姿勢が重力方向に対して傾いているか否か又はどの程度傾いているかを知ることができる。具体的には、加速度センサ37の検出軸が鉛直下方向を向いている状態を基準としたとき、1G(重力加速度)がかかっているか否かによって、コントローラ5が基準に対して傾いているか否かを知ることができるし、その大きさによって基準に対してどの程度傾いているかも知ることができる。また、多軸の加速度センサ37の場合には、さらに各軸の加速度の信号に対して処理を施すことによって、重力方向に対してコントローラ5がどの程度傾いているかをより詳細に知ることができる。この場合において、プロセッサは、加速度センサ37からの出力に基づいてコントローラ5の傾斜角度を算出してもよいし、当該傾斜角度を算出せずに、コントローラ5の傾斜方向を算出するようにしてもよい。このように、加速度センサ37をプロセッサと組み合わせて用いることによって、コントローラ5の傾斜角度又は姿勢を判定することができる。
一方、コントローラ5が動的な状態(コントローラ5が動かされている状態)であることを前提とする場合には、加速度センサ37は重力加速度に加えてコントローラ5の動きに応じた加速度を検出するので、検出された加速度から重力加速度の成分を所定の処理により除去することによってコントローラ5の動き方向を知ることができる。また、コントローラ5が動的な状態であることを前提とする場合であっても、検出された加速度から、加速度センサの動きに応じた加速度の成分を所定の処理により除去することによって、重力方向に対するコントローラ5の傾きを知ることが可能である。なお、他の実施例では、加速度センサ37は、内蔵の加速度検出手段で検出された加速度信号をマイコン42に出力する前に当該加速度信号に対して所定の処理を行うための、組込み式の処理装置又は他の種類の専用の処理装置を備えていてもよい。組込み式又は専用の処理装置は、例えば、加速度センサ37が静的な加速度(例えば、重力加速度)を検出するために用いられる場合、加速度信号を傾斜角(あるいは、他の好ましいパラメータ)に変換するものであってもよい。
通信部36は、マイコン42、メモリ43、無線モジュール44、及びアンテナ45を含んでいる。マイコン42は、処理を行う際にメモリ43を記憶領域として用いながら、マイコン42が取得したデータをゲーム装置3へ無線送信する無線モジュール44を制御する。また、マイコン42はコネクタ33に接続されている。ジャイロセンサユニット7から送信されてくるデータは、コネクタ33を介してマイコン42に入力される。以下、ジャイロセンサユニット7の構成について説明する。
ジャイロセンサユニット7は、プラグ53、マイコン54、2軸ジャイロセンサ55、及び1軸ジャイロセンサ56を備えている。上述のように、ジャイロセンサユニット7は、3軸(本実施形態では、XYZ軸)周りの角速度を検出し、検出した角速度を示すデータ(角速度データ)をコントローラ5へ送信する。
2軸ジャイロセンサ55は、X軸周りの角速度及びY軸周りの(単位時間あたりの)角速度を検出する。また、1軸ジャイロセンサ56は、Z軸周りの(単位時間あたりの)角速度を検出する。なお、本明細書では、コントローラ5の撮像方向(Z軸正方向)を基準として、Z軸周り、X軸周り、Y軸周りの回転方向を、それぞれ、ロール方向、ピッチ方向、ヨー方向と呼ぶ。すなわち、2軸ジャイロセンサ55は、ピッチ方向(X軸周りの回転方向)及びヨー方向(Y軸周りの回転方向)の角速度を検出し、1軸ジャイロセンサ56は、ロール方向(Z軸周りの回転方向)の角速度を検出する。
なお、本実施形態では、3軸回りの角速度を検出するために、2軸ジャイロセンサ55と1軸ジャイロセンサ56とを用いる構成としたが、他の実施形態においては、3軸回りの角速度を検出することができればよく、用いるジャイロセンサの数及び組み合わせはどのようなものであってもよい。
また、本実施形態では、各ジャイロセンサ55及び56が角速度を検出する3つの軸は、加速度センサ37が加速度を検出する3つの軸(XYZ軸)と一致するように設定される。ただし、他の実施形態においては、各ジャイロセンサ55及び56が角速度を検出する3つの軸と、加速度センサ37が加速度を検出する3つの軸とは一致しなくてもよい。
ジャイロセンサ55及び56で検出された角速度を示すデータは、マイコン54に出力される。したがって、マイコン54には、XYZ軸の3軸回りの角度速度を示すデータが入力されることになる。マイコン54は、上記3軸回りの角速度を示すデータを角速度データとしてプラグ53を介してコントローラ5へ送信する。なお、マイコン54からコントローラ5への送信は所定の周期毎に逐次行われるが、ゲームの処理は1/60秒を単位として(1フレーム時間として)行われることが一般的であるので、この時間以下の周期で送信を行うことが好ましい。
コントローラ5の説明に戻り、操作部32、撮像情報演算部35、及び加速度センサ37からマイコン42へ出力されたデータ、ならびに、ジャイロセンサユニット7からマイコン42へ送信されてきたデータは、一時的にメモリ43に格納される。これらのデータは、上記操作データとしてゲーム装置3へ送信される。すなわち、マイコン42は、ゲーム装置3の無線コントローラモジュール19への送信タイミングが到来すると、メモリ43に格納されている操作データを無線モジュール44へ出力する。無線モジュール44は、例えばBluetooth(ブルートゥース)(登録商標)の技術を用いて、所定周波数の搬送波を操作データで変調し、その微弱電波信号をアンテナ45から放射する。つまり、操作データは、無線モジュール44で微弱電波信号に変調されてコントローラ5から送信される。微弱電波信号はゲーム装置3側の無線コントローラモジュール19で受信される。受信された微弱電波信号について復調や復号を行うことによって、ゲーム装置3は操作データを取得することができる。そして、ゲーム装置3のCPU10は、取得した操作データとゲームプログラムとに基づいて、ゲーム処理を行う。なお、通信部36から無線コントローラモジュール19への無線送信は所定の周期毎に逐次行われるが、ゲームの処理は1/60秒を単位として(1フレーム時間として)行われることが一般的であるので、この時間以下の周期で送信を行うことが好ましい。コントローラ5の通信部36は、例えば1/200秒に1回の割合で各操作データをゲーム装置3の無線コントローラモジュール19へ出力する。
上記コントローラ5を用いることによって、プレイヤは、各操作ボタンを押下する従来の一般的なゲーム操作に加えて、コントローラ5を任意の傾斜角度に傾ける操作を行うことができる。その他、上記コントローラ5によれば、プレイヤは、コントローラ5によって画面上の任意の位置を指示する操作、及び、コントローラ5自体を動かす操作を行うこともできる。
[ゲーム処理の概要]
次に、図8〜図10Cを参照して、上記ゲームシステム1において実行されるゲームの概要について説明する。
本実施形態において実行されるゲームでは、プレイヤによる操作に応じて、仮想空間に配置されたキャラクタオブジェクトが水上オートバイを操縦する。プレイヤは、図8に示されるように入力装置8を両手で把持し、当該入力装置8を左右に傾けることによって、水上オートバイの進行方向を制御することができる。図9は、ゲームの実行中にテレビ2の画面に表示されるゲーム画像の一例を示している。テレビ2の画面には、仮想空間に配置された仮想カメラから見たキャラクタオブジェクトの姿が表示される。
図10A〜図10Cは、入力装置8を両手で把持しているプレイヤ側から当該入力装置8を水平方向に見た場合の入力装置8の様子を示している。本実施形態では、水上オートバイの進行方向は、一例として、入力装置8のロール方向に関する姿勢に応じて決定される。例えば、図10Aのように、入力装置8の長手方向が水平になっている場合には、水上オートバイは直進する。そして、図10Bのように、入力装置8の前端(撮像情報演算部35が設けられている端部)が後端(ジャイロセンサユニット7が設けられている端部)よりも上方になっている場合には、水上オートバイは右旋回する。そして、図10Cのように、入力装置8の前端が後端よりも下方になっている場合には、水上オートバイは左旋回する。なお、前述のように、入力装置8の姿勢は、ジャイロセンサユニット7から出力される角速度データ、もしくは加速度センサ37から出力される加速度データに基づいて計算することもできる。さらには、ジャイロセンサユニット7から出力される角速度データと加速度センサ37から出力される加速度データの両方を考慮して入力装置8の姿勢を計算することもできる。
仮想空間におけるキャラクタオブジェクトの姿勢は、ゲーム状況に応じて様々に変化する。
例えば、入力装置8のロール方向の姿勢に応じてキャラクタオブジェクトの腰の位置を変化させてもよい。図11Aは、入力装置8が図10Aの状態のときのキャラクタオブジェクトの姿勢を示している。図11Bは、入力装置8が図10Bの状態のときのキャラクタオブジェクトの姿勢を示している。図11Cは、入力装置8が図10Cの状態のときのキャラクタオブジェクトの姿勢を示している。図11A〜図11Cにおいて、キャラクタオブジェクトの両足の位置と両手の位置は水上オートバイに対して固定されているが、キャラクタオブジェクト腰の位置は入力装置8の姿勢に応じて移動している。
他の例として、キャラクタオブジェクトの両手の位置を、水上オートバイのハンドルの長さに応じて変化させてもよい。例えば、図12の例では、図11Aの水上オートバイと比較してハンドルが長いので、それに応じてキャラクタオブジェクトの両手の距離も広がっている。
さらに他の例として、キャラクタオブジェクトの左手の位置を、水上オートバイのハンドル以外のオブジェクトに固定してもよい。例えば、図13の例では、キャラクタオブジェクトの位置が、水面に飛び出した柱に固定されている。
本実施形態では、上記のようなキャラクタオブジェクトの姿勢制御を、少ない計算量で、かつ自然な姿勢となるように制御する。以下、本実施形態におけるキャラクタオブジェクトの姿勢制御の概要を説明する。
[キャラクタオブジェクトの構造]
本実施形態では、キャラクタオブジェクトは複数のノードで構成される関節構造体として定義されている。ここで、「ノード」とは、関節のみを指すものではなく、末端をも指すものとする。
図14は、キャラクタオブジェクトの外観を示しており、図15は、図14に示したキャラクタオブジェクトに対応するノード構造を示している。図14において、白丸および黒丸は、キャラクタオブジェクトを構成するノードを表しており、ノード間を結ぶ矢印は、ノードの階層構造を表している。矢印の始点に位置するノードは、矢印の終点に位置するノードに対して上位のノードであり、本明細書では、矢印の始点に位置するノードのことを、矢印の終点に位置するノードの「親」(もしくは「親ノード」)と称す。逆に、矢印の終点に位置するノードのことを、矢印の始点に位置するノードの「子」(もしくは「子ノード」)と称す。
本実施形態では、キャラクタオブジェクトを構成する複数のノードを、メインノードとサブノードに分類して、それぞれ異なる方法によって、まずメインノードの位置及び向きを決定した後で、サブノードの位置及び向きを決定する。本実施形態では、一例として、図15に黒丸で示しているキャラクタオブジェクトの右手ノード、首ノード、左手ノード、胸ノード、腰ノード、右足ノード、左足ノードの7つのノードをメインノードとして扱い、白丸で示している残りのノード(左指ノード、左肘ノード、左肩ノード、左足付け根ノード、左膝ノードなど)を「サブノード」として扱う。なお、本実施形態では胸ノードの位置と腰ノードの位置は同一位置に定義されているため、図15においてはこれらの胸ノードと腰ノードが重なって表示されている。
図16A〜図16Cは、キャラクタオブジェクトの右手ノードの向きを変化させたときのキャラクタオブジェクトの姿勢の変化の様子を示している。図16A〜図16Cにおける各矢印は、右手ノードのローカル座標のx軸,y軸,z軸の向きをそれぞれ示している。右手ノードの向き(すなわち、仮想空間における右手ノードのローカル座標のx軸,y軸,z軸の向き)が変化すると、キャラクタオブジェクトの右手(すなわちキャラクタオブジェクトの右手首から先の部分)の姿勢が変化する。また、図17A〜図17Cは、キャラクタオブジェクトの胸ノードの向きを変化させたときのキャラクタオブジェクトの姿勢の変化の様子を示している。図17A〜図17Cにおける各矢印は、胸ノードのローカル座標のx軸,y軸,z軸の向きをそれぞれ示している。胸ノードの向き(すなわち、仮想空間における胸ノードのローカル座標のx軸,y軸,z軸の向き)が変化すると、キャラクタオブジェクトの上半身(すなわちキャラクタオブジェクトの腰から上の部分)の姿勢が変化する。すなわち、あるノードの位置や向きが変化すると、通常、そのノードの下位の階層に位置するノードの位置や向きにも影響が及ぶ。
ところで、図11A〜図11Cに示したように、キャラクタオブジェクトの両足と両手を水上オートバイの特定位置に固定した状態で、入力装置8の姿勢に応じてキャラクタオブジェクトの腰の位置を変化させたい場合、本実施形態では、まず、キャラクタオブジェクトの左足ノードの位置と向き、右足ノードの位置と向き、左手ノードの位置と向き、右足ノードの位置と向きを、それぞれ所定の値に設定するとともに、腰ノードの位置に、入力装置8の姿勢に応じた値を設定する。そして、これらの値と、予め用意された「基準姿勢」とに基づいて、残りのノードの位置と向きを決定する。以下、「基準姿勢」について説明する。
[基準姿勢]
図18は、図11A〜図13のようなキャラクタオブジェクトの姿勢制御を行うときに用いられる「基準姿勢」の一例である。「基準姿勢」は、具体的には、図19に示すような複数のノード(図15に示した複数のノードにそれぞれ対応)の位置と向きによって定義されている。本実施形態では、詳細は後述するが、仮想空間におけるキャラクタオブジェクトの一部のノードの位置や向きが設定されたとき、残りのノードの位置や向きは、仮想空間におけるキャラクタオブジェクトの姿勢が全体的に基準姿勢に近い見た目になるように、基準姿勢に基づいて算出される。したがって、各関節の可動範囲等のパラメータを特に設定しなくても、仮想空間におけるキャラクタオブジェクトの各関節が不自然な方向に曲がることはなく、仮想空間におけるキャラクタオブジェクトの姿勢は見た目に自然となる。
なお、仮想空間におけるキャラクタオブジェクトの姿勢制御に用いる基準姿勢は、フレーム毎に変更してもよい。図20は、時間経過に応じて基準姿勢を変化させる例を示している。この例では、基準姿勢を1フレーム毎に少しずつ変化させ、キャラクタオブジェクトが一度かがんでから元の姿勢に戻るまでの期間を1サイクルとして、周期的に基準姿勢を変化させる例である。図20のような基準姿勢を用いてキャラクタオブジェクトの姿勢制御を行った場合、仮想空間において水上オートバイに乗っているキャラクタオブジェクトの上半身が周期的に上下に揺れるようなゲーム画像を生成することができる。なお、図20のように基準姿勢を変化させる場合、各フレームの基準姿勢を全て予め用意する必要はなく、例えば、2つの基準姿勢だけを予め用意しておき、その2つの基準姿勢に基づく補間処理等によって、これらの2つの基準姿勢とは異なる基準姿勢をリアルタイムに生成するようにしてもよい。
図21および図22は、ゲーム状況に応じて基準姿勢を変化させる例を示している。図21は、キャラクタオブジェクトが水上オートバイを発進させる前の、スタンバイしている状況で用いられる基準姿勢の一例を示している。図22は、キャラクタオブジェクトが水上バイクから放り出されそうになっている状況で用いられる基準姿勢の一例を示している。
[メインノードの位置および向きの制御]
本実施形態では、仮想空間においてキャラクタオブジェクトの一部のメインノードの位置や向きが変化したときに、それに連動して残りのメインノードの位置や向きを変化させるために、図23に示すような6つの仮想的なバネを導入し、各メインノードの位置および向きの算出に利用する。
各バネは、仮想空間においてバネによって接続された2つのメインノードのうちの一方のメインノード(以下、ノードBと称す)に対する他方のメインノード(以下、ノードAと称す)の相対位置および相対向きを、基準姿勢におけるノードAに対するノードBの相対位置(以下、基準相対位置と称す)および相対向き(以下、基準相対向きと称す)に近づけるように作用する。
図24は、基準姿勢におけるノードAとノードBのそれぞれの位置と向きを示している。図中の黒丸が各ノードの位置を表しており、矢印が各ノードの向き(例えば、各ノードの向きを表すローカル座標系のy軸)を表している。
仮想空間におけるノードAとノードBのそれぞれの位置と向きが図25Aに示すようなものであった場合、仮想空間におけるノードBに対するノードAの相対位置が、図24に示した基準姿勢におけるノードBに対するノードAの相対位置(基準相対位置)からずれている。よって、バネは、仮想空間におけるノードBに対するノードAの相対位置を、基準相対位置に近づけるように、ノードAとノードBに対して図に示すような互いに反対方向の力を与える。なお、バネによってノードAとノードBに与えられる力の大きさは、仮想空間におけるノードBに対するノードAの相対位置と、基準姿勢におけるノードBに対するノードAの相対位置(基準相対位置)のずれの大きさに応じて(例えば、ずれの大きさに比例して)大きくなる。よって、仮想空間におけるノードAとノードBのそれぞれの位置と向きが図25Bに示すようなものであった場合、バネによってノードAとノードBに図25Aの場合よりも大きな力が与えられる。
仮想空間におけるノードAとノードBのそれぞれの位置と向きが図26Aに示すようなものであった場合、仮想空間におけるノードBに対するノードAの相対向きが、図24に示した基準姿勢におけるノードBに対するノードAの相対向き(基準相対向き)からずれている。よって、バネは、仮想空間におけるノードBに対するノードAの相対向きを、基準相対向きに近づけるように、ノードAとノードBに対して図に示すような互いに反対方向のトルクを与える。なお、バネによってノードAとノードBに与えられるトルクの大きさは、仮想空間におけるノードBに対するノードAの相対向きと、基準姿勢におけるノードBに対するノードAの相対向き(基準相対向き)のずれの大きさに応じて(例えば、ずれの大きさに比例して)大きくなる。よって、仮想空間におけるノードAとノードBのそれぞれの位置と向きが図26Bに示すようなものであった場合、バネによってノードAとノードBに図26Aの場合よりも大きなトルクが与えられる。
仮想空間におけるノードAとノードBのそれぞれの位置と向きが図27に示すようなものであった場合、仮想空間におけるノードBに対するノードAの相対位置が、図24に示した基準姿勢におけるノードBに対するノードAの相対位置(基準相対位置)からずれていると同時に、仮想空間におけるノードBに対するノードAの相対向きが、図24に示した基準姿勢におけるノードBに対するノードAの相対向き(基準相対向き)からずれている。よって、バネは、仮想空間におけるノードBに対するノードAの相対位置を、基準相対位置に近づけるように、ノードAとノードBに対して図に示すような互いに反対方向の力を与えると同時に、仮想空間におけるノードBに対するノードAの相対向きを、基準相対向きに近づけるように、ノードAとノードBに対して図に示すような互いに反対方向のトルクを与える。
上記のようにして各メインノードに与えられる力とトルクが計算されると、当該力とトルクに基づいて、仮想空間における各メインノードの位置と向きが決定される。
仮想空間における各メインノードの位置および向きが決定されると、その後、必要に応じてメインノードの位置および向きが補正される。この補正処理については後述する。
[サブノードの位置および向きの制御]
仮想空間における各メインノードの位置および向きが確定すると、続いて、サブノードの位置と向きが決定される。サブノードの位置と向きは、すでに確定しているメインノードの位置および向きと、基準姿勢とに基づいて一意に決定される。
本実施形態では、予め定められた一部のサブノード(以下、「第1タイプサブノード」と称す)の仮想空間における位置および向きは、当該第1タイプサブノードに接続された1つ以上のノードのうちの予め定められた1つの特定のノード(以下、関連ノードと称す)の仮想空間における位置および向きと、基準姿勢とに基づいて、一意に決定される。また、予め定められた一部のサブノード(以下、「第2タイプサブノード」と称す)の仮想空間における位置および向きは、当該第2タイプサブノードに接続された2つのノード(親ノードおよび子ノード)の仮想空間における位置および向きと、基準姿勢とに基づいて、一意に決定される。
具体的には、仮想空間における第1タイプサブノードの位置および向きは、仮想空間における関連ノードの位置および向きに対する当該第1タイプサブノードの相対位置および相対向きが、基準姿勢における関連ノードの位置および向きに対する当該第1タイプサブノードの相対位置(基準相対位置)および相対向き(基準相対向き)に一致するように決定される。例えば、仮想空間における左指ノードの位置および向きは、仮想空間における左手ノード(左指ノードの親ノード)に対する当該左指ノードの相対位置および相対向きが、基準姿勢における左手ノードに対する左指ノードの相対位置(基準相対位置)および相対向き(基準相対向き)に一致するように決定される。また例えば、仮想空間における左足付け根ノードの位置および向きは、仮想空間における腰ノード(左足付け根ノードの親ノード)に対する当該左足付け根ノードの相対位置および相対向きが、基準姿勢における腰ノードに対する左足付け根ノードの相対位置(基準相対位置)および相対向き(基準相対向き)に一致するように決定される。なお、ここでは仮想空間における親ノードの位置および向きと基準姿勢とに基づいて第1タイプサブノードの位置および向きを決定する例を説明したが、子ノードの位置および向きと基準姿勢とに基づいて第1タイプサブノードの位置および向きを決定するようにしても構わない。
次に、図28〜図29Dを参照して、仮想空間における第2タイプサブノードの位置および向きの決定方法について説明する。ここでは一具体例として、右膝ノードの位置および向きを決定する方法について説明する。
図28は、キャラクタオブジェクトの基準姿勢を示している。図中の白丸および黒丸は、各ノードの位置を示しており、矢印は各ノードの向き(例えば、各ノードの向きを表すローカル座標系のy軸)を表している。
右足ノードはメインノードであり、右足付け根ノードは第1タイプサブノードである。本実施形態では、メインノードの位置および向きと、第1タイプサブノードの位置および向きが全て決定された後に、第2タイプサブノードの位置および向きが決定される。したがって、ここでは、右足ノードの位置および向きと、右足付け根ノードの位置および向きは、すでに決定済みであるとする。
まず、仮想空間における右膝ノードの位置を決定するために、図29Aに示すように、仮想空間における右足付け根ノードを中心とした球Aと、右足ノードを中心とした球Bを求める。球Aの半径は、基準姿勢における右足付け根ノードと右膝ノードの間の距離と等しくなるように設定される。すなわち、球Aの表面は、右足付け根ノードを基準としたときの右膝ノードの候補位置を示している。また、球Bの半径は、基準姿勢における右足ノードと右膝ノードの間の距離と等しくなるように設定される。すなわち、球Bの表面は、右足ノードを基準としたときの右膝ノードの候補位置を示している。
球Aおよび球Bを上記のように設定すると、図29Bに示すような球Aの表面と球Bの表面の交線上の各点が、仮想空間における右膝ノードの候補位置となる。ただし、この段階では右膝ノードの候補位置が複数(無数に)存在するので、本実施形態では、基準姿勢を参照することによって、これらの複数の候補位置から右膝ノードの位置を一意に決定する。具体的には、右足付け根ノードと右足ノードとを結ぶ直線を中心として、右膝がいずれの方向に突き出るべきかを、基準姿勢データを参照して決定する。そして、右膝の突き出し方向が求まれば、図29Cに示すように、右足付け根ノードと右足ノードとを結ぶ直線を基準として右膝の突き出し方向に位置する球Aの表面と球Bの表面の交線上の一点が、右膝ノードの位置として決定される。
右膝ノードの位置が決定されると、例えば、仮想空間における右膝ノードと右足ノードの位置関係等に基づいて、右膝ノードの向きが適宜に決定される(図29D)。なお、ここで説明した第2タイプサブノードの決定方法は単なる一例に過ぎない。
[ゲーム処理の詳細]
次に、光ディスク4に記憶されたゲームプログラムに基づいてCPU10によって実行されるゲーム処理の詳細を説明する。
図30は、上記ゲーム処理の実行中に外部メインメモリ12に格納されるプログラムおよびデータの一部を示している。外部メインメモリ12には、光ディスク4から読み出されたゲームプログラム61、入力装置8から受信した操作データ62、キャラクタオブジェクトを構成する複数のノードに関するデータの集合であるノードデータ63、ノードの階層構造(親子関係)を規定した階層構造情報64、基準姿勢における各ノードの位置および向きを規定した基準姿勢情報65、メインノード間を結ぶ仮想的な各バネに関するデータの集合であるバネ情報66、キャラクタオブジェクトや水上オートバイ等の仮想空間における各オブジェクトの配置位置を示すオブジェクト位置座標67、仮想空間における各オブジェクトの外観形状を表すポリゴンデータ68、仮想空間における各オブジェクトの表面の模様を示すテクスチャデータ69等が格納される。なお、これらのプログラムやデータの一部もしくは全部は、例えば内部メインメモリ11eなど、外部メインメモリ12以外の記憶領域に格納されても構わない。
操作データ62には、コントローラ5に設けられた各種スイッチの状態を示すボタンデータ、コントローラ5に装着されたジャイロセンサユニット7から出力された角速度データ、コントローラ5内の加速度センサ37から出力された加速度データ、コントローラ5内の画像処理回路41から出力されたマーカ座標データが含まれている。
ノードデータ63には、各メインノードに関するデータの集合であるメインノードデータと、各サブノードに関するデータの集合であるサブノードデータが含まれている。
図31は、メインノードデータの詳細を示す図である。メインノードデータには、各メインノード毎に複数のパラメータ(すなわち、ノード番号、位置、向き、速度、角速度、力、トルク、位置の属性、向きの属性、補正用パラメータ)が含まれている。
・「ノード番号」は、キャラクタオブジェクトを構成する複数のノードを識別するための番号である。
・「位置」(pos)は、仮想空間における当該メインノードの絶対位置を示すパラメータであり、例えば3次元ベクトルで表される。
・「向き」(rot)は、仮想空間における当該メインノードの絶対向きを示すパラメータ、例えばクォータニオンで表される。
・「速度」(vel)は、仮想空間における当該メインノードの絶対速度を示すパラメータ、例えば3次元ベクトルで表される。
・「角速度」(omega)は、仮想空間における当該メインノードの絶対角速度を示すパラメータ、例えば3次元ベクトルで表される。
・「力」(force)は、当該メインノードに作用する仮想空間における絶対力を示すパラメータ、例えば3次元ベクトルで表される。
・「トルク」(torque)は、当該メインノードに作用する仮想空間における絶対トルクを示すパラメータ、例えば3次元ベクトルで表される。
・「位置の属性」(attr_pos)は、当該メインノードの「位置」の属性を示すパラメータ、「制御」または「自由」のいずれかを表している。
・「向きの属性」(attr_rot)は、当該メインノードの「向き」の属性を示すパラメータ、「制御」または「自由」のいずれかを表している。
・「補正用パラメータ」(Tmin,Tmax,Fmin,Fmax)は、後述する補正処理の際に利用されるパラメータである。
なお、「制御」の属性を有するメインノードの「位置」には、任意の値を直接設定することができる。一方、「自由」の属性を有するメインノードの「位置」は、前述の仮想的なバネを用いた演算によって、その値が決定される。したがって、例えば図11A〜図11Cのように、キャラクタオブジェクトの両手と両足を水上オートバイに固定した状態で、プレイヤの入力操作に応じてキャラクタオブジェクトの腰の位置を移動させたい場合には、左手ノード、右手ノード、左足ノード、右足ノード、腰ノードのそれぞれの「位置の属性」を「制御」に設定し、残りのメインノードの「位置の属性」を「自由」に設定すればよい。「向きの属性」に関しても同様である。なお、各メインノードの「位置の属性」および「向きの属性」は、ゲーム状況に応じて変化させてもよい。
図32は、サブノードデータの詳細を示す図である。サブノードデータには、各サブノード毎に複数のパラメータ(すなわち、ノード番号、位置、向き)が含まれている。
・「ノード番号」は、キャラクタオブジェクトを構成する複数のノードを識別するための番号である。メインノードに割り当てられるノード番号とサブノードに割り当てられるノード番号は重複しないものとする。
・「位置」(pos)は、仮想空間における当該サブノードの絶対位置を示すパラメータであり、例えば3次元ベクトルで表される。
・「向き」(rot)は、仮想空間における当該サブノードの絶対向きを示すパラメータ、例えばクォータニオンで表される。
図33は、基準姿勢情報65の詳細を示す図である。基準姿勢情報65には、メインノードとサブノードを含む全ノードに関して、各ノード毎に複数のパラメータ(すなわち、ノード番号、位置、向き、親ノードに対する相対位置、親ノードに対する相対向き)が含まれている。
・「ノード番号」は、キャラクタオブジェクトを構成する複数のノードを識別するための番号である。
・「位置」(pos)は、基準姿勢における当該ノードの絶対位置を示すパラメータであり、例えば3次元ベクトルで表される。
・「向き」(rot)は、基準姿勢における当該ノードの絶対向きを示すパラメータであり、例えばクォータニオンで表される。
・「親ノードに対する相対位置」(pos_local)は、親ノードに対する当該ノードの相対位置を示すパラメータであり、例えば3次元ベクトルで表される。
・「親ノードに対する相対向き」(rot_local)は、親ノードに対する当該ノードの相対向きを示すパラメータであり、例えばクォータニオンで表される。
なお、基準姿勢情報65における各ノードの「親ノードに対する相対位置」と「親ノードに対する相対向き」の値は、階層構造情報64と、基準姿勢情報65に含まれる各ノードの「位置」および「向き」とに基づいて、必要に応じてリアルタイムに算出することもできる。
なお、前述したように基準姿勢を時間やゲーム状況に応じて変化させる場合には、例えば、基準姿勢情報に含まれる各パラメータをリアルタイムに変更したり、予め用意した複数の基準姿勢情報セットの中からゲーム状況に応じて1つの基準姿勢情報セットを選択したりすればよい。
図34は、バネ情報66の詳細を示す図である。バネ情報66には、例えば図23に示したようなメインノード間を結ぶ仮想的な各バネに関して、各バネ毎に複数のパラメータ(すなわち、ノードAのノード番号、ノードBのノード番号、ノードAの仮想空間における基準位置、ノードAの仮想空間における基準向き、前回位置ずれ、前回x軸向きずれ、前回y軸向きずれ、前回z軸向きずれ、変位に関する硬さ係数、変位に関する減衰係数、回転に関する硬さ係数、回転に関する減衰係数)が含まれている。
・「ノードAのノード番号」は、当該バネによって接続される2つのメインノードのうちの一方のメインノード(以下、ノードAと称す)のノード番号である。
・「ノードBのノード番号」は、当該バネによって接続される2つのメインノードのうちの他方のメインノード(以下、ノードBと称す)のノード番号である。
・「ノードAの仮想空間における基準位置」(posA)は、基準姿勢におけるノードBに対するノードAの相対位置(基準相対位置)を、仮想空間におけるノードBの絶対位置および絶対向きを基準として、仮想空間における絶対位置に変換した結果の値を示すパラメータであり、例えば3次元ベクトルで表される。
・「ノードAの仮想空間における基準向き」(rotA)は、基準姿勢におけるノードBに対するノードAの相対向き(基準相対向き)を、仮想空間におけるノードBの絶対向きを基準として、仮想空間における絶対向きに変換した結果の値を示すパラメータであり、例えば3次元ベクトルで表される。
・「前回位置ずれ」(length_pos)は、過去に計算した、ノードAの仮想空間における基準位置と現在の位置の間のずれの大きさの計算結果(スカラー)のうち、最新のものを保存しておくためのパラメータである。
・「前回x向きずれ」(length_x)は、過去に計算した、ノードAの仮想空間における基準向きと現在の向きの間のずれ(ノードAの向きを表すローカル座標系のx軸の向きのずれ)の大きさの計算結果(スカラー)のうち、最新のものを保存しておくためのパラメータである。
・「前回y向きずれ」(length_y)は、過去に計算した、ノードAの仮想空間における基準向きと現在の向きの間のずれ(ノードAの向きを表すローカル座標系のy軸の向きのずれ)の大きさの計算結果(スカラー)のうち、最新のものを保存しておくためのパラメータである。
・「前回z向きずれ」(length_z)は、過去に計算した、ノードAの仮想空間における基準向きと現在の向きの間のずれ(ノードAの向きを表すローカル座標系のz軸の向きのずれ)の大きさの計算結果(スカラー)のうち、最新のものを保存しておくためのパラメータである。
・「変位に関する硬さ係数」(Sp)は、バネの変位に関する硬さ係数である。
・「変位に関する減衰係数」(Spd)は、バネの変位に関する減衰係数である。
・「回転に関する硬さ係数」(Sr)は、バネの回転に関する硬さ係数である。
・「回転に関する減衰係数」(Srd)は、バネの回転に関する減衰係数である。
[ゲーム処理の流れ]
次に、図35〜図41のフローチャートを参照して、光ディスク4に記憶されたゲームプログラム61に基づいてCPU10によって実行されるゲーム処理の流れを説明する。なお、以下で説明するゲーム処理の一部は、CPU10の指示によってGPU11bなどの他のプロセッサによって実行されても構わない。
ゲームプログラム61の実行が開始されると、ステップS10においてCPU10は、初期処理を行う。初期処理には、ゲーム処理に利用される各種変数に初期値を入力したり、仮想空間にキャラクタオブジェクトや水上オートバイ等のオブジェクトを初期位置に配置したり、仮想カメラを初期位置に配置したりする処理が含まれる。
ステップS11においてCPU10は、必要に応じて、キャラクタオブジェクトの基準姿勢を更新する。これは、図20〜図22に示したように、キャラクタオブジェクトの基準姿勢を時間やゲーム状況に応じて適宜に変化させるための処理である。
ステップS12においてCPU10は、必要に応じて、各メインノードの「位置の属性」および「向きの属性」を更新する。前述のように、各メインノードの「位置の属性」および「向きの属性」は、「制御」か「自由」のいずれかに設定されており、ここでは、ゲーム状況に応じてこれらの値を適宜に更新する。なお、以下の説明では、「制御」の属性を有するメインノードの「位置」および「向き」のことを、それぞれ「位置(制御)」および「向き(制御)」と称し、「自由」の属性を有するメインノードの「位置」および「向き」のことを、それぞれ「位置(自由)」および「向き(自由)」と称する。
ステップS13においてCPU10は、入力装置8から操作データ62を取得して外部メインメモリ12に格納する。
ステップS14においてCPU10は、操作データ62に基づいて仮想空間における水上オートバイの移動制御(図10A〜図10Cを参照して説明した旋回制御を含む)を行い、仮想空間におけるキャラクタオブジェクトおよび水上オートバイの配置位置(オブジェクト位置座標67)を更新する。
ステップS15においてCPU10は、姿勢制御処理(キャラクタオブジェクトの姿勢を更新するための処理)を実行する。姿勢制御処理の詳細については後述する。
ステップS16においてCPU10は、ステップS14で更新されたキャラクタオブジェクトおよび水上オートバイの配置位置と、ステップS15で更新されたキャラクタオブジェクトの姿勢に基づいて、ポリゴンデータ68およびテクスチャデータ69を用いて、仮想カメラから見たキャラクタオブジェクトの様子を示すゲーム画像を生成する。
ステップS17においてCPU10は、ゲームが終了したか否かを判断し、ゲームが終了した場合はゲームプログラム61の実行を終了する。ゲームが終了していない場合には、処理はステップS11に戻る。
以上のステップS11〜ステップS17の処理は、テレビ2の画面の更新周期に同期して、繰り返し実行される。こうして、テレビ2の画面には、キャラクタオブジェクトが水上オートバイを操縦している様子が表示される。
[姿勢制御処理の詳細]
次に、図36を参照して、図35のステップS15の姿勢制御処理の詳細を説明する。
ステップS20においてCPU10は、メインノード処理(各メインノードの「位置」と「向き」を決定するための処理)を実行する。メインノード処理の詳細については後述する。
ステップS21においてCPU10は、サブノード処理(各サブノードの「位置」と「向き」を決定するための処理)を実行する。サブノード処理の詳細については後述する。
[メインノード処理の詳細]
次に、図37を参照して、図36のステップS20のメインノード処理の詳細を説明する。
ステップS30においてCPU10は、「制御」の属性が設定されているメインノードの「位置(制御)」と「向き(制御)」を決定する。具体的には、「位置の属性」が「制御」に設定されているメインノードの「位置」のパラメータに、所望の値を代入するとともに、「向きの属性」が「制御」に設定されているメインノードの「向き」のパラメータに、所望の値を代入する。この処理は、例えば図11A〜図11Cの例において、キャラクタオブジェクトの両足や両手を水上オートバイに固定したり、キャラクタオブジェクトの腰の位置を入力装置8の姿勢に応じた位置に移動したりするためのものである。
ステップS31においてCPU10は、「自由」の属性が設定されているメインノードの「位置(自由)」と「向き(自由)」に仮の値を設定する。以下、「位置(自由)」に設定される仮の値のことを「仮位置」と称し、「向き(自由)」設定される仮の値のことを「仮向き」と称する。ここで設定される仮位置および仮向きは、直前のフレームの処理で決定された「位置(自由)」と「向き(自由)」の値を、そのまま仮位置、仮向きとして利用してもよいし、基準姿勢に基づいて仮位置、仮向きを設定してもよいし、予め定められた所定値を仮位置、仮向きとして設定してもよい。
ステップS32においてCPU10は、バネ演算処理(各メインノードの「位置(自由)」と「向き(自由)」を決定するための処理)を実行する。バネ演算処理の詳細については後述する。
ステップS33においてCPU10は、補正処理(各メインノードの「位置(自由)」と「向き(自由)」を必要に応じて補正するための処理)を実行する。補正処理の詳細については後述する。
[バネ演算処理の詳細]
次に、図38を参照して、図37のステップS32のバネ演算処理の詳細を説明する。
ステップS40においてCPU10は、各メインノードの「力」と「トルク」を0にリセットする。
ステップS41においてCPU10は、バネ情報66に規定されている複数のバネの中から、未選択のバネを1つ選択する。以下のステップS42〜ステップS49の説明において、単に「バネ」と記載した場合には、当該ステップS41で選択されたバネを指すものとする。
ステップS42においてCPU10は、基準姿勢情報65に基づいて、バネで接続された一対のメインノードのうちの一方のメインノード(以下、「ノードB」と称する)に対する他方のメインノード(以下、「ノードA」と称する)の基準相対位置を計算する。前述のように、ノードBに対するノードAの「基準相対位置」とは、基準姿勢におけるノードBに対するノードAの相対位置を意味する。
ステップS43においてCPU10は、「ノードAの仮想空間における基準位置」の値を計算して、外部メインメモリ12に格納する。「ノードAの仮想空間における基準位置」の値は、前述のように、ノードBに対するノードAの基準相対位置を、仮想空間におけるノードBの絶対位置および絶対向きを基準として、仮想空間における絶対位置に変換することによって計算される。
ステップS44においてCPU10は、仮想空間におけるノードAの現在の位置と基準位置のずれ(変位)を計算し、当該ずれに基づいて、バネがノードAとノードBに及ぼす力(3次元ベクトル)を計算する。バネがノードAに及ぼす力をF(3次元ベクトル)とすると、バネがノードBに及ぼす力は-F(3次元ベクトル)となる。Fの値は、例えば以下のようなプログラムコードによって計算される。
length = | S< Jc[ A ], Jc[ B ] >.posA - Jc[ A ].pos |
dir = ( S< Jc[ A ], Jc[ B ] >.posA - Jc[ A ].pos ) / length
F = ( Sp * length - Spd * | S< Jc[ A ], Jc[ B ]>.length_pos - length | ) * dir
S< Jc[ A ], Jc[ B ] >.length_pos = length (更新)
上記プログラムコードにおいて、「length」は仮想空間におけるノードAの現在の位置と基準位置のずれの大きさを示しており、「dir」は当該ずれの向きを示している。「Jc[ A ]」は、複数のメインノードのうちの特定のメインノード(ノードA)を表している。また、「S< Jc[ A ], Jc[ B ] >.posA」は、ノードAとノードBを結ぶバネのパラメータ「posA」を示しており、「Jc[ A ].pos」は、ノードAのパラメータ「pos」を示している。また、「Sp」は「変位に関する硬さ係数」であり、「Spd」は「変位に関する減衰係数」である。「Sp」および「Spd」の値はバネ毎に異なるように設定されてもよい。「Sp」の値が相対的に大きいバネほど、そのバネによって接続される2つのメインノードの位置関係が、基準姿勢におけるそれらの位置関係に相対的に近いものになり、逆に「Sp」の値が相対的に小さいバネほど、そのバネによって接続される2つのメインノードの位置関係が、基準姿勢におけるそれらの位置関係から相対的に遠いものになる。例えば、腰ノードと胸ノードを結ぶバネの「Sp」の値は、右手ノードと胸ノードを結ぶバネの「Sp」に対して10倍程度の値を設定するようにしてもよい。
ステップS45においてCPU10は、ステップS44で算出されたFに基づいて、ノードAとノードBの「力」(force)を更新する。ノードAの「力」(Jc[ A ].force)およびノードBの「力」(Jc[ B ].force)は、例えば以下のようなプログラムコードによって計算される。
Jc[ A ].force = Jc[ A ].force + F
Jc[ B ].force = Jc[ B ].force - F
ステップS46においてCPU10は、基準姿勢情報65に基づいて、ノードBに対するノードAの基準相対向きを計算する。前述のように、ノードBに対するノードAの「基準相対向き」とは、基準姿勢におけるノードBに対するノードAの相対向きを意味する。
ステップS47においてCPU10は、「ノードAの仮想空間における基準向き」の値を計算して、外部メインメモリ12に格納する。「ノードAの仮想空間における基準向き」の値は、前述のように、ノードBに対するノードAの基準相対向きを、仮想空間におけるノードBの絶対向きを基準として、仮想空間における絶対向きに変換することによって計算される。
ステップS48においてCPU10は、仮想空間におけるノードAの現在の向きと基準向きのずれを計算し、当該ずれに基づいて、バネがノードAとノードBに及ぼすトルクを計算する。本実施形態では、一例として、バネがノードAに及ぼすトルクを、バネがノードAの向きを示すローカル座標の各軸(x軸,y軸,z軸)に及ぼすトルク(Tx, Ty, Tz)として算出する(図42B参照)。なお、図42Aは、仮想空間におけるノードAの基準向きを示しており、図42Bは仮想空間におけるノードAの現在の向きを示している。バネがノードBの向きを示すローカル座標軸の各軸(x軸,y軸,z軸)に及ぼすトルクは、それぞれ、-Tx, -Ty, -Tzとなる。Txの値は、例えば以下のようなプログラムコードによって計算される。
length = | Xaxis( S< Jc[ A ], Jc[ B ] >.rotA ) - Xaxis( Jc[ A ].rot ) |
dir = ( Xaxis( S< Jc[ A ], Jc[ B ] >.rotA ) - Xaxis( Jc[ A ].rot ) ) / length
Tx = ( Sr * length - Srd * | S< Jc[ A ], Jc[ B ] >.length_x - length | ) * dir
S< Jc[ A ], Jc[ B ] >.length_x = length (更新)
上記プログラムコードにおいて、「length」は仮想空間におけるノードA(ノードAの向きを示すローカル座標のx軸)の現在の向きと基準向きのずれの大きさを示しており、「dir」は当該ずれの向きを示している。「Xaxis( rot )」は、向き(rot)を示すローカル座標のx軸を示している。後述するYaxis, Zaxisも同様である。また、「Sr」は「回転に関する硬さ係数」であり、「Srd」は「回転に関する減衰係数」である。「Sr」および「Srd」の値はバネ毎に異なるように設定されてもよい。
Ty,Tzについても、Txと同様にして計算される。
ステップS49においてCPU10は、ステップS44で算出されたTx,Ty,Tzに基づいて、ノードAとノードBの「トルク」(torque)を更新する。ノードAの「トルク」(Jc[ A ].torque)およびノードBの「トルク」(Jc[ B ].torque)は、例えば以下のようなプログラムコードによって計算される。なお、「×」は外積記号である。
Jc[ A ].torque = Jc[ A ].torque + Xaxis( Jc[ A ].rot ) × Tx + Yaxis( Jc[ A ].rot ) × Ty + Zaxis( Jc[ A ].rot ) × Tz
Jc[ B ].torque = Jc[ B ].torque - Xaxis( Jc[ B ].rot ) × Tx - Yaxis( Jc[ B ].rot ) × Ty - Zaxis( Jc[ B ].rot ) × Tz
ステップS50においてCPU10は、バネ情報66に規定されている全てのバネがすでに選択されたかどうかを判断する。そして、全てのバネがすでに選択されている場合には処理はステップS51に進み、まだ選択されていないバネが存在する場合には処理はステップS41に戻る。
ステップS51においてCPU10は、各メインノードの「力」と「トルク」に基づいて、各メインノードの「位置(自由)」と「向き(自由)」を更新する。なお、ここで用いる各メインノードの「力」と「トルク」は、各メインノードに接続されている1以上のバネから受ける力とトルクを合計したものとなっている。各メインノードの「位置(自由)」(Jc.pos)と「向き(自由)」(Jc.rot)は、例えば以下のようなプログラムコードによって計算される。
Jc.vel = Jc.vel * Dp + Jc.force
Jc.pos = Jc.pos + Jc.vel
Jc.omega = Jc.omega * Dr + Jc.torque
Jc.rot = [ 1.0, Jc.omega * 0.5 ] * Jc.rot
「[ 1.0, Jc.omega * 0.5 ]」は、角速度に基づいて向きを変化させるためのクォータニオンである。また、「Dp」は仮想空間における変位に関する減衰係数であり、「Dr」は仮想空間における回転に関する減衰係数である。「Dp」および「Dr」は、それぞれ、0 < Dp < 1, 0 < Dr < 1 を満たすような所定の値が設定される。
ステップS52においてCPU10は、上記ステップS40〜ステップS51の一連の処理を所定回数(例えば4回)繰り返したかどうか判断する。そして、ステップS40〜ステップS51の一連の処理を所定回数繰り返した場合には、バネ演算処理を終了し、そうでない場合には、処理はステップS40に戻る。なお、ステップS40〜ステップS51の一連の処理は、必ずしも複数回繰り返す必要は無いが、この一連の処理を繰り返すほど、仮想空間におけるキャラクタオブジェクトの姿勢が安定し、より自然な姿勢となることが期待できる。
[補正処理の詳細]
次に、図39を参照して、図37のステップS33の補正処理の詳細を説明する。
前述のバネ演算処理では、基準姿勢に基づいてメインノードの位置および向きが決定されるが、各メインノードの距離に対する制限を一切考慮していないため、「制御」の属性を有するメインノードの「位置」や「向き」の値によっては、バネで接続されているメインノード間の距離が、不自然な値に設定されてしまう可能性がある。例えば、腰ノードと右足ノードの間の距離は、キャラクタオブジェクトの腰の位置から右足首までの最大長を超えるべきではないが、前述のバネ演算処理だけでは、腰ノードと右足ノードの間の距離は、キャラクタオブジェクトの腰の位置から右足首までの最大長を超えてしまい、ゲーム画像中のキャラクタオブジェクトの腰のパーツと足のパーツが離れて見えてしまう可能性がある。例えば、図43Aのようにキャラクタオブジェクトの右足ノードと左足ノードの「位置」および「向き」が固定されている状態から、左手ノードを図の矢印方向に移動させると、図43Bのように、キャラクタオブジェクトの腕などに隙間が生じる可能性がある。そこで、補正処理では、バネで接続されているメインノード間の距離が、予め定めた制限距離を超えている場合に、その距離が制限距離に収まるように、各メインノードの位置や向きを補正する。
ステップS60においてCPU10は、各メインノードの「補正用パラメータ」(Tmin,Tmax,Fmin,Fmax)を0にリセットする。
ステップS61においてCPU10は、バネ情報66に規定されている複数のバネの中から、未選択のバネを1つ選択する。以下のステップS62〜ステップS64の説明において、単に「バネ」と記載した場合には、当該ステップS61で選択されたバネを指すものとする。
ステップS62においてCPU10は、バネで接続されている2つのメインノード(ノードAおよびノードB)の間の距離が制限距離を超えているかどうかを判断し、制限距離を超えている場合には処理はステップS63に進み、制限距離を超えていない場合には処理はステップS65に進む。なお、制限距離は、各バネ毎に予め定められているものとする。
ステップS63においてCPU10は、ノードAとノードBの間の距離が制限距離となるようにするために必要となるノードAの移動距離および移動方向を示すベクトル(当該ベクトルは、あたかもノードAとノードBの間に働く引力を示すベクトルに似ているため、以下、引力ベクトルと称す)を計算する。例えば、引力ベクトル(modifyAB)は、例えば以下のようなプログラムコードによって計算される。
modifyAB = ( C.length - lengthAB ) * ( Jc[ A ].pos - Jc[ B ].pos ) / lengthAB
なお、上記プログラムコードにおいて、「C.length」はノードAとノードBの間の制限距離を示しており、「lengthAB」はノードAとノードBの間の距離を示している。
ステップS64においてCPU10は、引力ベクトルに基づいて、ノードAとノードBの「補正用パラメータ」(Tmin, Tmax, Fmin, Fmax)を更新する。ノードAの「補正用パラメータ」(JcExA.Tmin, JcExA.Tmax, JcExA.Fmin, JcExA.Fmax)およびノードBの「補正用パラメータ」(JcExB.Tmin, JcExB.Tmax, JcExB.Fmin, JcExB.Fmax)は、例えば以下のようなプログラムコードによって計算される。
F = Cp * modifyAB
T = Cr * modifyAB
JcExA.Fmin = Min( F, JcExA.Fmin )
JcExA.Fmax = Max( F, JcExA.Fmax )
JcExA.Tmin = Min( T, JcExA.Tmin )
JcExA.Tmax = Max( T, JcExA.Tmax )
JcExB.Fmin = Min( -F, JcExB.Fmin )
JcExB.Fmax = Max( -F, JcExB.Fmax )
JcExB.Tmin = Min( -T, JcExB.Tmin )
JcExB.Tmax = Max( -T, JcExB.Tmax )
なお、上記プログラムコードにおいて、「Cp」は戻し幅係数を示しており、「Cr」は向きの補正量を示している。また、「Min」は、複数の3次元ベクトルから、各成分(x成分、y成分、z成分)毎に最小値を選択して新たな3次元ベクトルを得る演算子であり、「Max」は、複数の3次元ベクトルから、各成分(x成分、y成分、z成分)毎に最大値を選択して新たな3次元ベクトルを得る演算子である。
ステップS65においてCPU10は、バネ情報66に規定されている全てのバネがすでに選択されたかどうかを判断する。そして、全てのバネがすでに選択されている場合には処理はステップS66に進み、まだ選択されていないバネが存在する場合には処理はステップS61に戻る。
ステップS66においてCPU10は、「補正用パラメータ」の値に基づいて、各メインノードの「位置(自由)」および「向き(自由)」を更新する。ただし、全てのバネについてステップS62の判断結果が否定であった場合には、当該ステップS66の処理を省略してもよい。各メインノードの「位置(自由)」および「向き(自由)」は、各メインノードの補正用パラメータ(JcEx.Tmin,JcEx.Tmax,JcEx.Fmin,JcEx.Fmax)を用いて、例えば以下のようなプログラムコードによって計算される。
Jc.pos = Jc.pos + ( JcEx.Fmin + JcEx.Fmax )
Jc.rot = [ 1.0, (JcEx.Tmin + JcEx.Tmax ) * 0.5 ] * Jc.rot
なお、上記プログラムコードにおける「JcEx.Fmin + JcEx.Fmax」で示される3次元ベクトルは、後述の「修正ベクトル」に相当する。
なお、本実施形態では上記のように、メインノードの「位置」を補正する際に、同時に「向き」も補正しているが、これは、それらの間の距離が制限距離を超えるような2つのメインノードが存在しているときには、メインノードの「位置」を補正するだけでなく、「向き」も補正した方が、適切な状態に補正しやすく、キャラクタオブジェクトの見た目もより自然になるからである。例えば、図43Bの状態から補正処理によって左腕の隙間を埋める場合、図43Cに示すように、胸ノードの向き(例えば、胸ノードの向きを表すローカル座標系のy軸)を左手ノードの方向へ近づけるように補正することによって、キャラクタオブジェクトの姿勢をより自然なものにすることができる。
ステップS67においてCPU10は、補正処理の終了条件を満たしたかどうかを判断し、終了条件を満たした場合には補正処理を終了し、そうでない場合には処理はステップS60に戻る。本実施形態では、一例として、下記の2つの条件(条件1および条件2)のうちのいずれか一方を満たした場合に、終了条件を満たしたと判断する。
(条件1)
ステップS63において算出された各バネに関する引力ベクトルの大きさの合計値が、予め定めた閾値以下になったこと。
(条件2)
ステップS60〜ステップS66の一連の処理を所定回数繰り返したこと。
上記条件1を設けることにより、補正の必要性がない、もしくはステップS60〜ステップS66の一連の処理を何回か繰り返した結果、補正の効果が十分に得られたときに、補正処理をすぐに終了させることができ、余計な処理負担を回避することができる。また、上記条件1に加えて上記条件2を設けることにより、例えばステップS60〜ステップS66の一連の処理を無限に繰り返したとしても補正の効果が十分に得られないようなケースにおいて、補正処理を無駄に継続してしまうことを回避することができる。
次に、上記補正処理の原理について、図44A〜図46Bを参照してより分かりやすく説明する。
説明を理解しやすくするために、図44Aに示すように、第1接続ノード,第2接続ノードおよび第3接続ノードの3つのノードに接続されたノード(注目ノードと称す)の位置を制御する場合を例として説明する。
図44Aにおいて、第1目標位置は、注目ノードと第1接続ノードの位置関係に基づいて決定される、当該注目ノードの目標位置を示している。例えば、前述のように、バネで接続された2つのメインノードの間の距離が予め定められた制限距離を超えている場合に、当該2つのメインノードを近づける必要がある。第1ベクトルは、注目ノードを第1目標位置に近づけるための当該注目ノードの目標移動方向(第1目標移動方向)と目標移動量(第1目標移動量)を示すベクトルである。第1ベクトルの大きさは、例えば、注目ベクトルと第1目標位置の間の距離に応じて(例えば、注目ベクトルと第1目標位置の間の距離に比例するように)決定されるものとする。第1ベクトルは、注目ノードが第1接続ノードに引き寄せられる方向を示すベクトルであることから、注目ノードと第1接続ノードの間に生じる「引力」を表していると言うことができる。第2ベクトルおよび第3ベクトルについても同様である。
なお、オブジェクトの或るパーツが別のパーツにめり込んで表示されるのを防止するために、バネで接続された2つのメインノードの間の距離が予め定められた必要距離を下回っている場合に、当該2つのメインノードを遠ざけたい場合がある。図44Bでは、注目ノードと第2接続ノードの間の距離が必要距離を下回っているために、注目オブジェクトから見て第2接続ノードから遠ざかる方向に第2目標位置が存在している。図44Bにおける第2ベクトルは、注目ノードが第2接続ノードから遠ざけられる方向を示すベクトルであることから、注目ノードと第2接続ノードの間に生じる「斥力」を表していると言うことができる。
ところで、図44Aにおいて、第1ベクトル〜第3ベクトルは、それぞれ異なる方向及び大きさを有している。このような状況において、注目ノードの位置をどのように移動させるかは、最終的に得られるゲーム画像におけるキャラクタオブジェクトの見た目の自然さに大きく影響する。容易に思いつく方法としては、第1ベクトル〜第3ベクトルを全て加算し、加算した結果として得られるベクトルに従って注目ノードの位置を移動させる方法がある。しかしながら、当該方法を採用すると、図45に示すような例において、注目ノードと第2〜第6目標位置の間の距離はいずれも近づく一方で、注目ノードと第1目標位置の間の距離だけが大きく離れてしまうことになり、その結果、キャラクタオブジェクトの特定部分だけが際だって不自然に見えてしまうことになる。
以下、図46Aおよび図46Bを参照して、本実施形態における注目ノードの位置の制御方法を説明する。なお、図46Aおよび図46Bは、図44Aの例に対応している。
本実施形態では、第1ベクトル〜第3ベクトルの3つのベクトルを対象として、各成分(X成分,Y成分,Z成分)毎に最大値および最小値を求め、こうして求めた6つの値(X成分の最大値(Xmax),X成分の最小値(Xmin),Y成分の最大値(Ymax),Y成分の最小値(Ymin),Z成分の最大値(Zmax),Z成分の最小値(Zmin))に基づいて、注目ノードを制御するための修正ベクトルを決定し、当該修正ベクトルに基づいて注目ノードの位置を更新する。
図46Aおよび図46Bの例では、第1ベクトル〜第3ベクトルのうち、X成分の大きさが最も大きいのは第3ベクトルである。したがって、第3ベクトルのX成分の値がXmaxとなる。同様に、第1ベクトル〜第3ベクトルのうち、X成分の大きさが最も小さいのは第1ベクトルである。したがって、第1ベクトルのX成分の値がXminとなる。Y成分およびZ成分についても同様である。
Xmax,Xmin,Ymax,Ymin,Zmax,Zmin の6つの値から修正ベクトルを求める方法としては、種々の方法が考えられる。ここでは、2つの代表的な方法について説明する。
第1の方法は、( Xmax+Xmin, Ymax+Ymin, Zmax+Zmin )を修正ベクトルとして利用する方法である。すなわち、第1の方法では、各成分の最大値と最小値の合計値を、修正ベクトルにおける対応する成分の値として利用する。図46Aは、当該第1の方法で決定された修正ベクトルを示している。
第2の方法は、(( Xmax + Xmin ) / 2, ( Ymax + Ymin ) / 2, ( Zmax + Zmin ) / 2))を修正ベクトルとして利用する方法である。すなわち、第2の方法では、各成分の最大値と最小値の平均値を、修正ベクトルにおける対応する成分の値として利用する。図46Bは、当該第2の方法で決定された修正ベクトルを示している。
なお、第1の方法で決定した修正ベクトルは、第2の方法で決定した修正ベクトルに対して、方向が同じで、大きさのみが2倍となる。したがって、例えば、修正ベクトルの大きさに比例した距離だけ移動させるように注目ノードの位置を補正すると仮定した場合には、第1の方法で決定した修正ベクトルを持いて補正する方が、第2の方法で決定した修正ベクトルを用いて補正する場合と比較して、注目ベクトルの補正量は2倍になり、補正の効果が大きくなる。
なお、第1の方法では、各成分の最大値と最小値の合計値を、修正ベクトルにおける対応する成分の値として利用しているが、これに替えて、各成分の最大値と最小値の合計値に所定の係数を乗じた合成値を、修正ベクトルにおける対応する成分の値として利用してもよい。当該所定の係数として例えば「0.5」を用いる場合には、第2の方法で決定した修正ベクトルと同じ修正ベクトルを得ることができる。
図45の例において、上記のような第1の方法や第2の方法で修正ベクトルを決定すると、修正ベクトルの大きさはほぼ0になる。したがって、前述した例(第1ベクトル〜第3ベクトルを全て加算た結果として得られるベクトルに従って注目ノードの位置を移動させる例)のようにキャラクタオブジェクトの特定部分だけが際だって不自然に見えてしまうような不具合は生じない。
[サブノード処理の詳細]
次に、図40を参照して、図36のステップS21のサブノード処理の詳細を説明する。
本実施形態において、各サブノードは、第1タイプサブノードまたは第2タイプサブノードのいずれか一方に予め分類されている。各サブノードが第1タイプサブノードと第2タイプサブノードのどちらに分類されているのかは、サブノード毎に予め定義されているものとする。
ステップS70においてCPU10は、各第1タイプサブノードの「位置」および「向き」を決定する。仮想空間における第1タイプサブノードの位置および向きは、当該第1タイプサブノードに接続された1つ以上のノードのうちの予め定められた1つの特定のノード(本実施形態では親ノードとする)の仮想空間における位置および向きと、基準姿勢とに基づいて、一意に決定される。第1タイプサブノードの「位置」(Jnc.pos)および「向き」(Jnc.rot)は、例えば以下のようなプログラムコードによって計算される。
Jnc.pos = Parent( Jnc ).rot * Ja.pos_local + Parent( Jnc ).pos
Jnc.rot = Parent( Jnc ).rot * Ja.rot_local
上記プログラムコードにおいて、「Parent( Jnc ).pos」および「Parent( Jnc ).rot」は、親ノードの「位置」および「向き」をそれぞれ示している。また、「Ja.pos_local」および「Ja.rot_local」は、基準姿勢情報における当該第1タイプサブノードの「親ノードに対する相対位置」および「親ノードに対する相対向き」をそれぞれ示している。
ステップS71においてCPU10は、第2タイプサブノード処理を実行する。第2タイプサブノード処理は、各第2タイプサブノードの「位置」および「向き」を決定するための処理である。仮想空間における第2タイプサブノードの位置および向きは、当該第2タイプサブノードに接続された親ノードおよび子ノードの仮想空間における位置および向きと、基準姿勢とに基づいて、一意に決定される。第2タイプサブノードに接続された親ノードおよび子ノードの仮想空間における位置および向きは、前述のメインノード処理または上記ステップS70の処理によってすでに決定されているものとする。以下、図41を参照して、当該第2タイプサブノード処理の詳細を説明する。
[第2タイプサブノード処理の詳細]
ステップS80においてCPU10は、第2タイプサブノードの中から、未選択の第2タイプサブノード(すなわち、「位置」と「向き」が未決定の第2タイプサブノード)を1つ選択する。以下のステップS81〜ステップS85の説明において、単に「第2タイプサブノード」と記載した場合には、当該ステップS80で選択された第2タイプサブノードを指すものとする。
ステップS81においてCPU10は、第2タイプサブノードと親ノードの間の基準距離(Lp)と、第2タイプサブノードと子ノードの間の基準距離(Lc)と、仮想空間における親ノードと子ノードの間の距離(Lpc)を計算する。Lp, Lc, Lpcは、例えば以下のようなプログラムコードによって計算される。
Lp = | Ja.pos - Parent( Ja ).pos |
Lc = | Ja.pos - Child( Ja ).pos |
Lpc = | Parent( Jnc ).pos - Child( Jnc ).pos |
上記プログラムコードにおいて、「Ja.pos」は、基準姿勢における第2タイプサブノードの位置を示しており、「Parent( Ja ).pos」および「Child( Ja ).pos」は、基準姿勢における親ノードおよび子ノードの位置をそれぞれ示している。また、「Parent( Jnc ).pos」および「Child( Jnc ).pos」は、仮想空間における親ノードおよび子ノードの位置をそれぞれ示している。
ステップS82においてCPU10は、仮想空間における第2タイプサブノードの「仮の向き」(rot')を計算する。当該「仮の向き」(rot')は、仮想空間における親の向きと、基準姿勢における親の向きに対する処理対象ノードの相対向きとから仮に求めた、仮想空間における処理対象ノードの向きである。「仮の向き」(rot')は、例えば以下のようなプログラムコードによって計算される。
rot’ = Parent( Jnc ).rot * Ja.rot
上記プログラムコードにおいて、「Parent( Jnc ).rot」は、仮想空間における親ノードの向きを示しており、「Ja.rot」は、基準姿勢における第2タイプサブノードの向きを示している。
ステップS83においてCPU10は、親ノードと子ノードを結ぶ直線に対する第2タイプサブノードの突き出し方向を計算する。具体的には、子ノードから親ノードに向かうベクトル(pc)と、ステップS82で計算した「仮の向き」(rot’)に基づいて、第2タイプサブノードの突き出し方向を計算する。第2タイプサブノードの突き出し方向は、第2タイプサブノードが表している間接の回転軸に対して直交する方向である。第2タイプサブノードが表している間接の回転軸は、第2タイプサブノード毎に予め定義されているものとする。例えば、図47の例では、右膝ノードの回転軸は、右膝ノードの向きを表すローカル座標系のx軸である。このように、第2タイプサブノードの向きを表すローカル座標系のx軸が、当該第2タイプサブノードの回転軸として定義されている場合には、第2タイプサブノードの突き出し方向(v)は、例えば以下のようなプログラムコードによって計算される。
v = Xaxis( rot’ ) × pc / | pc |
ステップS84においてCPU10は、親ノードと子ノードを結ぶ直線に対する第2タイプサブノードの突き出し長さを計算する。突き出し長さ(Lv)は、Lp,Lc,Lpcを用いて、例えば以下のようなプログラムコードによって計算される(図47参照)。
p = ( Lc * Lc - Lp * Lp + Lpc * Lpc ) / ( 2 * Lpc )
Lv = ( Lc * Lc - p * p ) ^ 0.5
ステップS85においてCPU10は、仮想空間における第2タイプサブノードの「位置」と「向き」を決定する。仮想空間における第2タイプサブノードの「位置」(Jnc.pos)は、例えば以下のようなプログラムコードによって計算される。
Jnc.pos = Child( Jnc ).pos + p * pc / | pc | + Lv * v
仮想空間における第2タイプサブノードの「向き」(Jnc.rot)は、第2タイプサブノードの「位置」と、親ノードもしくは子ノードの「位置」等を考慮して、適切な向きを設定する。
ステップS86においてCPU10は、全ての第2タイプサブノードがすでに選択されたかどうか(すなわち、全ての第2タイプサブノードの「位置」と「向き」がすでに決定されたかどうか)を判断する。そして、全ての第2タイプサブノードがすでに選択されている場合には第2タイプサブノード処理を終了し、まだ選択されていない第2タイプサブノードが存在する場合には処理はステップS80に戻る。
上記のような処理により、複数のノードで構成されるキャラクタオブジェクトの姿勢が、基準姿勢に基づいて、自然な姿勢となるように制御される。
特に、仮想空間における一部のメインノードの位置または向きを指定したときに、残りのメインノードの位置および向きが基準姿勢に基づくバネ演算処理によって計算されるため、各関節の可動範囲等のパラメータを特に設定しなくても、仮想空間におけるキャラクタオブジェクトの姿勢は見た目に自然となる。
また、仮想空間におけるサブノードの位置および向きについても基準姿勢に基づいて決定されるため、各関節の可動範囲等のパラメータを特に設定しなくても、仮想空間におけるキャラクタオブジェクトの姿勢は見た目に自然となる。
また、キャラクタオブジェクトを構成する全ノードのうちの一部のノード(メインノード)のみを対象としてバネ演算処理を行っているので、全ノードを対象としてバネ演算処理を行う場合と比較して、全体的な処理負荷を低減することができる。
なお、本実施形態では、人間を模したキャラクタオブジェクトの姿勢を制御する例を説明したが、本発明はこれに限らず、複数のノードで構成される任意のオブジェクトの姿勢の制御に利用することができる。
また、本実施形態では、3次元の仮想空間に配置された3次元のオブジェクトの姿勢を制御する例を説明したが、本発明はこれに限らず、2次元のオブジェクトの姿勢の制御にも利用することができる。
また、本発明は、仮想空間に存在するオブジェクトをプレイヤがインタラクティブに操作するものに限定されるものではなく、例えば、仮想空間においてコンピュータによって自動的に移動制御されるオブジェクト(例えば犬など)を、プレイヤが画面上で単に観察するようなものにも適用できる。この場合、入力装置は必ずしも必要ない。
また、本実施形態では、据置型のゲーム装置に本発明を適用した例を説明したが、本発明は、携帯型ゲーム装置や、携帯電話や、一般的なパーソナルコンピュータ等の任意の情報処理装置に適用することができる。
また、本実施形態では、各ノードの位置および向きの両方を制御する例を説明したが、位置または向きのいずれか一方を固定とし、残りの一方のみを制御するようにしても構わない。
また、本実施形態では、バネ演算処理において、図38のステップS40〜ステップS51の一連の処理を所定回数繰り返す例を説明したが、本発明はこれに限らず、ステップS40〜ステップS51の一連の処理を繰り返すことなく(すなわち、1度だけ実行して)、バネ演算処理を終了するようにしても構わない。
また、本実施形態では、補正処理において、図39のステップS60〜ステップS66の一連の処理を所定回数繰り返す例を説明したが、本発明はこれに限らず、ステップS60〜ステップS66の一連の処理を繰り返すことなく(すなわち、1度だけ実行して)、補正処理を終了するようにしても構わない。
また、本実施形態では、キャラクタオブジェクトを構成する全ノードをメインノードとサブノードに分類し、それぞれ異なる方法で位置と向きを決定しているが、本発明はこれに限らず、全ノードに対してメインノード処理またはサブノード処理のいずれか一方だけを共通に実行して、各ノードの位置および向きを決定するようにしてもよい。
また、本実施形態では、バネ演算処理によってメインノードの位置および向きを決定した後に、補正処理によって、これらのメインノードの位置および向きを必要に応じて補正しているが、当該補正処理は、任意の手法によって決定されたノードの位置および向きを補正する手法として汎用的に利用することができる。