User:Kisaragi marine/brson

From Resonite Wiki
Revision as of 08:04, 1 December 2024 by Kisaragi marine (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

注意: このページはbrsonの内部構成を記述しており、その内容は時とともに変化することがある。その場合でも、泣き言を言わないこと。

ライセンス上の問題を生じるため、このページをKisaragi marine以外が編集することは禁止します。追加するべきことがある場合は議論ページでお声がけ下さい
このページの利用または二次利用にかかる利用許諾についてはResonite Wiki:Copyrightsに従うものとする。

以下は、クリエイティブ・コモンズ 表示-継承 4.0 国際のリーガルコード (日本語版) によって要求される利用条件を緩和する追加条項である:

  • OGPなど、システムの自動的な引用によって本コンテンツまたはその一部が「従の部分」として単語の順序を入れ替えることなく表示される場合、その部分が表示される親コンテキストの内容はリーガルコード第1条第a項によって定義された「翻案物」としてみなさない。
  • SNSなどで本コンテンツ、本コンテンツの「翻案物」、またはその一部を共有する際に本ページへのリンクを含めた場合、リーガルコード第3条第a項の条件は全て満たしているとみなす。


概要

Resoniteはbrson7zbsonlz4bsonと呼ばれる形式でアセットを保存したりエクスポートしたりすることができる。

ただし、それらの形式によってエクスポートされた形式は少しばかり複雑である。 以下に、スキーマを示す。

  1. そのアセットが「レガシーモード」ではなく、Resoniteでエンコードされた場合はヘッダー
  2. ヘッダーの圧縮アーカイブの種別フィールドによってその形式が識別される、圧縮されているかもしれないBSON

ヘッダー

  1. \x46\x72\x44\x54 (ASCIIでFrDT)
  2. \x00\x00\x00\x00 (予約済みと思われる)。
  3. Variable Byte codeでエンコードされた圧縮アーカイブの種別

圧縮アーカイブの種別

圧縮アーカイブの種別を示す。

  1. 0x00=予約済み?
  2. 0x01=LZ4 frame mode
  3. 0x02=LZMA
  4. 0x03=Brotli

参照グラフ

圧縮アーカイブを解凍すると、BSONでエンコードされたアセットが見られる。説明のため、これを「参照ルート」と呼ぶ。

参照グラフのルートはオブジェクトになっており、そのフィールドは次の通り。

  • VersionNumber: このバイナリがエクスポートされたバージョンを示す。
  • FeatureFlags: フィーチャーフラグを定義する。
    • ColorManagement: ???
    • ResetGUID: ???
    • ProtoFlux: ???
    • TEXTURE_QUALITY: ???
    • TypeManagement: ???
  • Types: 使われているコンポーネントの型を文字列で列挙する。
    • (items): 「共通言語基盤における型の正準名」
  • TypeVersions: 型のバージョン。全てのコンポーネントが含まれているとは限らない。
    • (key): Typesに含まれている文字列。
    • (value): 数値。
  • Object: エンコードされたSlot
  • Asset: エンコードされたIAssetProviderの配列。
    • (value): IComponent: エンコードされたの配列。

ここで、「共通言語基盤における型の正準名」は型が所属する「アセンブリ」の名前を半角角括弧で括った文字列の直後に型の完全修飾名を結合し、存在するならその直後に型引数のアリティ及び型パラメータをコンマ区切りでさらに結合したものである。例えば VRIKAvatarなら[FrooxEngine]FrooxEngine.FinalIK.VRIKAvatar など。

スキーマ定義

説明用: PackageNodeIdentifier

PackageNodeIdentifier は本体に存在するノードに割り振られることがある不透明な識別子である。パッケージの全てのノードの中で一意であることが保証される。

説明用: UniquePtr

スキーマ UniquePtrを次のように定義する。

  • 型変数 T を受けとり、以下のスキーマを返す:
    • ID: PackageNodeIdentifier
    • Data: T

説明用: WorldElementRef

スキーマ WorldElementRefUniquePtr(PackageNodeIdentifier) のエイリアスとして定義する。

WorldElementRef は マッチする PackageNodeIdentifier のノードを指す値として解決されなければならない。

説明用: ComponentTableIndex

スキーマ ComponentTableIndex は、自身の値をインデックスとして Types フィールドで宣言された型の要素を参照する非負整数である。

例えばComponentTableIndexが42であれば、型を解決するためには Types[42]を参照する必要がある。

Slot

本体のObjectは常にSlotから始まる。Slotが必要なコンポーネントを保持し、コンポーネントがドライブ先やアセットの参照、あるいは値を保持するいつもの構造と同型であることに気がつくだろう。

  • ID: PackageNodeIdentifier
  • Components: UniquePtr(Array(IComponent))
  • ParentReference: PackageNodeIdentifier
  • Children: Array(Slot)
  • Slotと同じフィールド:
    • Name (string)
    • Tag (string?)
    • Position (float3)
    • Rotation (floatQ)
    • Scale (float3)
    • OrderOffset (long)

IComponent

  • Type: ComponentTableIndex
  • Data: コンポーネントに依存するデータ

詳しいことは各コンポーネントのドキュメントを参照せよ。

ただし、一部の型については読み替えが必要である。

  • Sync<T>と書いてあった場合はT型として解決できるWorldElementRef
  • SyncList<T>と書いてあった場合はArray(T)型として解決できるWorldElementRef
  • SyncRef<T>と書いてあった場合はT型に解決できるWorldElementRef
  • インターフェイス型が代入されていた場合はもともとの型 (として解決できるWorldElementRef)

また、[NameOverride(string)]属性がついている場合、フィールドはその名前で出力される。さらに、[NonPersistent]がついているフィールドはシリアライズから除外される。

例えば、Rig ([FrooxEngine]FrooxEngine.Rig) の Bones フィールドは「*list* of Slot」という定義だが、これはSyncList<Slot>にほかならない。そのため、各要素はSlotとしてデコードできるWorldElementRefとしてエンコードされている。

頻出のコンポーネントを利便性のために示す。