注意: このページはbrsonの内部構成を記述しており、その内容は時とともに変化することがある。その場合でも、泣き言を言わないこと。
概要
Resoniteはbrson、7zbson、lz4bsonと呼ばれる形式でアセットを保存したりエクスポートしたりすることができる。
ただし、それらの形式によってエクスポートされた形式は少しばかり複雑である。 以下に、スキーマを示す。
- そのアセットが「レガシーモード」ではなく、Resoniteでエンコードされた場合はヘッダー。
- ヘッダーの圧縮アーカイブの種別フィールドによってその形式が識別される、圧縮されているかもしれないBSON。
ヘッダー
\x46\x72\x44\x54
(ASCIIでFrDT
)\x00\x00\x00\x00
(予約済みと思われる)。- Variable Byte codeでエンコードされた圧縮アーカイブの種別。
圧縮アーカイブの種別
圧縮アーカイブの種別を示す。
- 0x00=予約済み?
- 0x01=LZ4 frame mode
- 0x02=LZMA
- 0x03=Brotli
参照グラフ
圧縮アーカイブを解凍すると、BSONでエンコードされたアセットが見られる。説明のため、これを「参照ルート」と呼ぶ。
参照グラフのルートはオブジェクトになっており、そのフィールドは次の通り。
VersionNumber
: このバイナリがエクスポートされたバージョンを示す。FeatureFlags
: フィーチャーフラグを定義する。ColorManagement
: ???ResetGUID
: ???ProtoFlux
: ???TEXTURE_QUALITY
: ???TypeManagement
: ???
Types
: 使われているコンポーネントの型を文字列で列挙する。- (items): 「共通言語基盤における型の正準名」
TypeVersions
: 型のバージョン。全てのコンポーネントが含まれているとは限らない。- (key):
Types
に含まれている文字列。 - (value): 数値。
- (key):
Object
: エンコードされたSlot。Asset
: エンコードされたIAssetProviderの配列。- (value): IComponent: エンコードされたの配列。
ここで、「共通言語基盤における型の正準名」は型が所属する「アセンブリ」の名前を半角角括弧で括った文字列の直後に型の完全修飾名を結合し、存在するならその直後に型引数のアリティ及び型パラメータをコンマ区切りでさらに結合したものである。例えば VRIKAvatarなら[FrooxEngine]FrooxEngine.FinalIK.VRIKAvatar
など。
スキーマ定義
説明用: PackageNodeIdentifier
PackageNodeIdentifier
は本体に存在するノードに割り振られることがある不透明な識別子である。パッケージの全てのノードの中で一意であることが保証される。
説明用: UniquePtr
スキーマ UniquePtr
を次のように定義する。
- 型変数
T
を受けとり、以下のスキーマを返す:ID
:PackageNodeIdentifier
Data
: T
説明用: WorldElementRef
スキーマ WorldElementRef
を UniquePtr(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
: ComponentTableIndexData
: コンポーネントに依存するデータ
詳しいことは各コンポーネントのドキュメントを参照せよ。
ただし、一部の型については読み替えが必要である。
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
としてエンコードされている。
頻出のコンポーネントを利便性のために示す。