[SCE CONFIDENTIAL DOCUMENT]

PlayStation(R)Edge 1.2.0

                  Copyright (C) 2007 Sony Computer Entertainment Inc.

                                                 All Rights Reserved.



Edge アニメーションライブラリを使用して複数のロコモーションキャラクターを

アニメーション化するサンプル



<サンプルプログラムのポイント>



本サンプルは、anim-sample の拡張版であり、Edge Animation コードには修正を

加えずユーザーコードのみを使用し、「ロコモーション処理」（ルートトランス

レーションの取り出し）を行う方法を示します。ループするアニメーションが

存在するため、ブレンドツリー内で各アニメーションインスタンス毎にコンテク

ストを管理する必要があります。ロコモーション処理の実装時、または

edgeAnimProcessBlendTree() コールバックの高度な使用方法の例として参照して

ください。



<サンプルプログラム解説>



ロコモーションアニメーションにおいては、ブレンディングの際にルートジョイ

ントの"デルタ値"を使用する必要があります。この"デルタ値"とは、発生したル

ーピングを考慮したあるフレーム値と最後のフレーム値との差異のことです。

これは、評価後およびブレンディング前にアニメーションのルートジョイントを

修正できるようにするリーフコールバックを使用して実現します。このデルタ値

を計算するには、さらに別の情報を必要とします。特に、以前のルート値および

最後の評価時からアニメーションがループした回数に関する情報が必要です。

このステートは、アニメーションのインスタンス毎にストアされ、コールバック

によってアップロードされます。各パイプラインステージ毎に呼び出されるため、

コールバック側ではこのデータをプリフェッチすることができ、ストールを最小限

に留めることができます。



ブレンドツリー処理の終了後、ブレンドしたルートジョイントの最終のデルタ値

を使って、キャラクターのワールド位置を更新します。



以下に、重要なメイン関数に関する詳細を示します（以下に記載されていない

コード部分については、anim-sample を参照してください）。



SampleApp::onInit()



    1つのスケルトンと2つのアニメーション（walk と jog）を読み込み、各アニ

　　メーションのルートエンドのデルタ値を計算します。コールバック関数は、

　　フレーム毎のデルタ値を計算する際、この値を使ってルーピングを考慮しま

　　す。

　　キャラクターのグリッドの初期化は、各自のアニメーションロコモーション

　　ステートによって行われます。



SampleApp::onUpdate()



    各キャラクターは、y 軸を中心にわずかに回転します。アニメーションによ

    って動作するモーションと組み合わせると、各キャラクターが円形のパスを

    辿ります。

    各キャラクターのアニメーション時間を進め、最後の更新からアニメーション　　で発生したループ数をループカウントとして設定します。



SampleApp::runAnimJobs()



    各キャラクターに対し、シンプルなブレンドツリーを構築し、

　　createAnimJob() を呼び出してアニメーションジョブを作成します。

    EdgeAnimBlendLeaf の 'userVal' メンバーをロコモーションステートのアド

    レスに設定します。この値がリーフコールバックに渡されると、ステートデ

    ータにアクセスできるようになります。



SampleApp::createAnimJob()



    anim-sample とほぼ同じです。このジョブは、ルートジョイントをアップデ

    ートします。このジョブ用に出力バッファ中にスペースが割り当てられ、実効

　　アドレスは追加パラメータとして渡されます。



cellSpursJobMain2()



    ジョブのエントリポイントです。anim-sample とほぼ同じです。

    processBlendTree() は、ジョブが DMA 転送するルートジョイントを更新し

    ます。



processBlendTree()



    リーフコールバックをセットアップします。ユーザーコールバックバッファの

　　サイズは、edgeAnimSpuInitialize() のコール内で指定します。このバッファ

    はロコモーションステートへの DMA 転送で使用するため、LocomotionState 

    構造体のサイズに設定します。実際のコールバック関数 LeafCallback() は、

    edgeAnimProcessBlendTree() へのコール内で指定します。ブレンドツリー処理    の後、通常通りローカル空間ジョイントをワールド空間マトリックスに変換

　　します。尚、この更新されたルートジョイント変換は、ワールドジョイント

　　配列内の最初のエントリから得ることができます。





LeafCallback()



    ブレンドツリー内の各ロコモーションアニメーションに対しデルタ値を計算

　　します。

    パイプラインステージ -1では、ロコモーションステートをユーザーバッファ

　　へプリフェッチします。

    パイプラインステージ 0 では、以下のようにデルタ値を計算し、現在のポー

　　ズのルートジョイントを上書きします。



            ルートのデルタ値 = (現在評価されているルート - 最後に評価され

　　　　　　たルート) + ループ数 * ループエンドのデルタ値



    最後に、ロコモーションステートを更新し、メインメモリにDMA転送します。





<ファイル>

spu/process_blend_tree.cpp	: メインのアニメーション処理関数（スプリッ

			　　　　　トして SPU ジョブまたは PC/win32 版のい

				  ずれかから呼び出す

spu/process_blend_tree.h	: 上記関数のヘッダ

spu/job_anim.cpp		: アニメーションジョブ

spu/job_anim.mk			: アニメーションジョブの makefile

 

<プログラムの実行方法>

    - ファイルサービングのルートを self ディレクトリに設定します。

    - プログラムを実行します。

