レイトレ日記 2022/06/16

今日は,シーン読み込みを実装することに。
毎回どうしようか悩んで,結局間に合わず同じものを使いまわすという過ちを繰り返してきたので,今回はちゃんとやることにした。

理想的にはバイナリ読み込んで,バイナリキャストして,そのまま使える形になるやつが欲しい!
…と思ったら既にありました。

FlatBuffers!!
https://github.com/google/flatbuffers

これよ。これ!欲しかったやつ。
早速試すと,かなり簡単にバイナリフォーマットを定義できる。
最初はstructとtableの違いが判らなかったが,プリミティブ型じゃないものを配列に取る場合はtableにしないとエラーになるので,自前定義のやつを配列で使いたい場合はtableにすればいいみたい。

結構便利なので,メッシュやらテクスチャやらの定義も書きまくる。

struct Vector2
{
    x:float;
    y:float;
}

struct Vector3
{
    x:float;
    y:float;
    z:float;
}

struct Vector4
{
    x:float;
    y:float;
    z:float;
    w:float;
}

struct Matrix3x4
{
    row0:Vector4;
    row1:Vector4;
    row2:Vector4;
}

struct ResVertex
{
    Position:Vector3;
    Normal:Vector3;
    Tangent:Vector3;
    TexCoord:Vector2;
}

table SubResource
{
    Width:uint;
    Height:uint;
    MipIndex:uint;
    Pitch:uint;
    SlicePitch:uint;
    Pixels:[byte];
}

table ResTexture
{
    Dimension:uint;
    Width:uint;
    Height:uint;
    Depth:uint;
    Format:uint;
    MipLevels:uint;
    SurfaceCount:uint;
    Option:uint;
    Resources:[SubResource];
}

struct ResMaterial
{
    BaseColor:uint;
    Normal:uint;
    Orm:uint;
    Emissive:uint;
}

table ResMesh
{
    MateiralId:uint;
    VertexCount:uint;
    IndexCount:uint;
    Vertices:[ResVertex];
    Indices:[uint];
}

struct ResInstance
{
    MeshIndex:uint;
    Transform:Matrix3x4;
}

table ResScene
{
    MeshCount:uint;
    InstanceCount:uint;
    TextureCount:uint;
    MaterialCount:uint;
    IblTexture:ResTexture;
    Meshes:[ResMesh];
    Instances:[ResInstance];
    Textures:[ResTexture];
    Materials:[ResMaterial];
}

root_type ResScene;

お作法的には,スネークケースで書かないと警告が出る。…が,そんな他人のルールなんて知ったこっちゃない。仕事じゃないんで。
自分さえよければいい。それが趣味プログラムの醍醐味!

ランタイム側はファイルを読み込んで,バイナリを

auto resScene = GetResScene(m_pBinary);

と引数で渡してやれば,データにアクセスできるようになる。すごく簡単!
ランタイムの読み込み側は実装したので,あとはシーンエディットと書き出しさえ実装すれば,パストレの実装に集中できそう。
シーンエディタ作るのめんどいなぁ。どうしよ?

残り75日!