[[Spr1の使い方/マニュアル]]
新しい物理法則エンジンの作成方法について述べる。~
+PhysicsライブラリでSGBehaviorEngineをスーパークラスとした
新しいクラスを作成(作成は、Physicsライブラリのみですべて行われる)。~
SGBehaviorEngineは<SceneGraph/SGScene.h>で宣言されているため
インクルードが必要。~
~
PHTestEngineクラスを作成すると仮定して話を進める。~
~
そのクラスの記述すべては、
namespace Spr{;
}
で閉じられる必要がある(インクルードは別でよい)。~
クラスの宣言の場所では、名前を登録するためのマクロが必要であり
SGOBJECTDEF(PHTestEngine);
と書けばよい。これは<FileIO/FIDocScene.h>で宣言されているため
インクルードが必要。
+クラスの.cppファイルの方に派生関係を登録するマクロを記述。
SGOBJECTIMP(PHTestEngine, SGBehaviorEngine);
+PHTestEngineクラスにメンバ関数を作成。最低限必要なものは、
Step(SGScene *s)。~
+ローダーとセイバーの作成。以下のものが最低限必要な宣言(.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){}
};
+ローダーとセイバーを登録するマクロをローダーとセイバーの宣言の後に記述。~
DEF_REGISTER_BOTH(PHTestEngine);
ここの引数を使って登録するため名前は宣言と合わせること。
+Xファイルで読み込むデータを定義する(Solidなどのデータに関しては後に述べる)。~定義は次の2つの場合で方法が異なる。
-Xファイルのデータとクラスで保持するメンバ変数が対になる場合①
-Xファイルのデータとクラスで保持するメンバ変数が別の形である場合②~
①の場合、定義は、メンバ変数の前に行う(例えばクラスの宣言の前)。②の場合は
ローダーの宣言の前にする。
DEF_RECORD(XTestEngine,{
//コードの部分は、~\Microsoft Visual Studio\Common\Tools\GUIDGEN.EXEで作成したコードを記述する。
GUID Guid(){ return WBGuid("コード"); }
データの宣言;
});
データの宣言では、Xファイルに合わせたデータ型でなければいけないため、
typedef Vec3f Vector;
このように、型を合わせる必要がある。
+データの定義をローダーで登録。
登録はローダーのコンストラクタで行う。
UTRef<FITypeDescDb> db = new FITypeDescDb;
db->SetPrefix("X");
db->REG_FIELD(Vector); //型を合わせたときの宣言型
db->REG_RECORD_PROTO(XTestEngine); //DEF_RECORDの最初の引数と合わせる
+データをメンバ変数に代入。メンバ変数の内容をデータに代入。~
①の場合、メンバ変数を
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);
}
+Solidなどの子オブジェクトへの参照をメンバ変数に代入。~
これにはAddChildObject(SGObject* o, SGScene* s)を利用する。~
これはPHTestEngineクラスのメンバ関数として宣言を行う。使用方法は次のようなものである。
// if (DCAST([データのクラス名], o)){
// [上のクラス型のメンバ変数].push_back((PHSolid*)o);
// return true;
// }
// return false;
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));
}
}
+最後にPHRegisterLoader.cppに追加したクラスを登録する(登録の方法は他のクラスと
同じようにすればよい)。