Spr1の使い方/マニュアル

新しい物理法則エンジンの作成方法について述べる。

  1. PhysicsライブラリでSGBehaviorEngineをスーパークラスとした 新しいクラスを作成(作成は、Physicsライブラリのみですべて行われる)。
    SGBehaviorEngineは<SceneGraph/SGScene.h>で宣言されているため インクルードが必要。

    PHTestEngineクラスを作成すると仮定して話を進める。

    そのクラスの記述すべては、
    namespace Spr{;
    }
    で閉じられる必要がある(インクルードは別でよい)。
    クラスの宣言の場所では、名前を登録するためのマクロが必要であり
    SGOBJECTDEF(PHTestEngine);
    と書けばよい。これは<FileIO/FIDocScene.h>で宣言されているため インクルードが必要。
  2. クラスの.cppファイルの方に派生関係を登録するマクロを記述。
    SGOBJECTIMP(PHTestEngine, SGBehaviorEngine);
  3. PHTestEngineクラスにメンバ関数を作成。最低限必要なものは、 Step(SGScene *s)。
  4. ローダーとセイバーの作成。以下のものが最低限必要な宣言(.cppに書くのが勝手がよい)。
    class PHTestEngineLoader:public FIObjectLoader<PHTestEngine>{
    public:
    	PHTestEngineLoader(){}
    	virtual bool LoadData(FILoadScene* ctx, PHTestEngine* test){}
    };
    class PHTestEngineSaver:public FIObjectSaver<PHTestEngine>{
    	virtual UTString GetType() const{ return "PHTestEngine"; }
    	virtual void SaveData(FISaveScene* ctx, FIDocNodeBase* doc, PHTestEngine* test){}
    };
  5. ローダーとセイバーを登録するマクロをローダーとセイバーの宣言の後に記述。
    DEF_REGISTER_BOTH(PHTestEngine);
    ここの引数を使って登録するため名前は宣言と合わせること。
  6. Xファイルで読み込むデータを定義する(Solidなどのデータに関しては後に述べる)。~定義は次の2つの場合で方法が異なる。
  • Xファイルのデータとクラスで保持するメンバ変数が対になる場合①
  • Xファイルのデータとクラスで保持するメンバ変数が別の形である場合②
    ①の場合、定義は、メンバ変数の前に行う(例えばクラスの宣言の前)。②の場合は ローダーの宣言の前にする。
    DEF_RECORD(XTestEngine,{
            //コードの部分は、~\Microsoft Visual Studio\Common\Tools\GUIDGEN.EXEで作成したコードを記述する。
    	GUID Guid(){ return WBGuid("コード"); } 
    	データの宣言;
    });
    データの宣言では、Xファイルに合わせたデータ型でなければいけないため、
    typedef Vec3f	Vector;
    このように、型を合わせる必要がある。
  1. データの定義をローダーで登録。 登録はローダーのコンストラクタで行う。
    UTRef<FITypeDescDb> db = new FITypeDescDb;
    db->SetPrefix("X");
    db->REG_FIELD(Vector);  //型を合わせたときの宣言型
    db->REG_RECORD_PROTO(XTestEngine); //DEF_RECORDの最初の引数と合わせる
  2. データをメンバ変数に代入。メンバ変数の内容をデータに代入。
    ①の場合、メンバ変数を
    XTestEngine tes;
    このように記述。
    ②の場合、メンバ変数は自分が必要なように記述。
    代入はローダーのメンバ関数LoadData()で行う。 ①の場合、
    virtual bool LoadData(FILoadScene* ctx, PHMTestEngine* test){
    	ctx->docs.Top()->GetWholeData(test->tes);
    	return true;
    }
    逆にデータに代入する場合、
    virtual void SaveData(FISaveScene* ctx, FIDocNodeBase* doc, PHTestEngine* test){
    	doc->SetWholeData(test->tes);
    }
    ②の場合、
    virtual bool LoadData(FILoadScene* ctx, PHMTestEngine* test){
    	XTestEngine tes;
    	ctx->docs.Top()->GetWholeData(tes);
    	自分の考えた形でメンバ変数に代入
    	return true;
    }
    逆にデータに代入する場合、
    virtual void SaveData(FISaveScene* ctx, FIDocNodeBase* doc, PHTestEngine* test){
    	XTestEngine tes;
    	自分の考えた形で上の構造体に代入
    	doc->SetWholeData(tes);
    }
  3. Solidなどの子オブジェクトへの参照をメンバ変数に代入。
    これにはAddChildObject(SGObject* o, SGScene* s)を利用する。
    これはPHTestEngineクラスのメンバ関数として宣言を行う。使用方法は次のようなものである。
    bool PHTestEngine::AddChildObject(SGObject* o, SGScene* s){
    	if(DCAST(PHSolid, o)){
    		solid = (PHSolid*)o;
    		return true;
    	}
    	return false;
    }
    子オブジェクトを持つクラスを保存する場合はSaveData関数は使えない。代わりに Save()を使う。
    virtual void Save(FISaveScene* ctx, SGObject* arg){
    	手動でノードを作成する必要あり
    	PHTestEngine* test = (PHSolid*)arg;
    	FIDocNodeBase* doc = ctx->CreateDocNode("TestEngine", test);
    	ctx->docs.back()->AddChild(doc);
    	XTestEngine tes;
    	自分の考えた形で上の構造体に代入
    	doc->SetWholeData(tes);
    	子オブジェクトへの参照ノードを作成
    	if (test->solid){
    		 doc->AddChild(ctx->CreateDocNode("REF", test->solid));
    	}
    }
  4. 最後にPHRegisterLoader.cppに追加したクラスを登録する(登録の方法は他のクラスと 同じようにすればよい)。