0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

USDC(Crate) serialization のメモ

Last updated at Posted at 2022-09-10

フォーマットの概要は

自前 AR アプリとかで USDZ を直接読むための USDC file format のメモ
https://qiita.com/syoyo/items/dbfecbc16468e6108d0d

を参照ください.
ここでは serialization のためのメモを残しておきます.

Tokens

シーン(Stage)で使われる全トークンをリストアップし, \0 で繋いで一つのバッファとして LZ4 圧縮かけます.

pxrUSD では Token は一意性を保つために一元管理しているので, そのデータベースを dump して作っているのかと思いきやシーンの Prim をトラバースしてそれぞれ新規に token のデータベースを作っています...

Strings

USDC では String(改行があったりと通常の文字列)も Token にエンコードし, StringIndex でトークンへのインデックスで管理します. なぜかこの StringIndex の配列は LZ4 圧縮はかけません.

これも Prim などをトラバースして収集します.

Paths

Prim や Property のパスリストです.
インデックスベースでの階層構造の情報もここに含みます.

以下の 3 つが含まれます.

  • encodedPaths(Path index. 数はかならずしも総 path 数と同じとは限らない)
  • elementTokens(elementPath 名(Prim や property の名前)のトークンのインデックス)
  • jumps(階層構造のための jump index)

elementToken は Property の場合 negative になります.

jumps は木構造を二重連鎖木で表現のためでしょうか.

詳細はソースコード参照ください.

rel などで指定する絶対パスはそのままのパス文字列情報としては保存されません.
階層構造に分解して implicit に保存(読むときは階層構造を復元しないと絶対パスがわからない)することになります.

また, Prim の階層構造に含まれないパスも考慮して(たとえば rel myrel = </bora/dora> と指定しているが "bora" Prim が無いようなとき)パス階層を作ってあげる必要があります(crate には存在するが, 復元する場合は Prim tree(Spec) には出てこないようなもの).

構造上相対パスは扱いが難しいとおもいましたが, USDC ではやはり相対パスは扱えず, すべて絶対パスとして扱うようです.
USDA で相対パス指定はできるが, 読み込み時に絶対パスに変換される.

def Xform "hello"
(
)
{

    def Sphere "world"
    (
    )
    {
        rel mypath = <../hello>
    }
}

のような場合, 読み込んだ時点で絶対パスへ変換され

def Xform "hello"
(
)
{

    def Sphere "world"
    (
    )
    {
        rel mypath = </hello/hello>
    }
}

パスのリストとしては

/
/hello
/hello/hello
/hello/world

となります.

Fields(ValueRep)

Property など各種データを ValueRep にエンコードが必要になります.
インライン化できるかどうか(単位行列)もここで判定してエンコードしてあげる必要があります.
(シリアライズ側ではインライン化対応は必須というわけではないので, 任意ではあるでしょう)

FieldSet

Prim の情報も Property の情報も FieldSet で一括でまとめ, SpecType でその FieldSet の役割を決める.

  • FieldSet[0] : Xform (SpecType = PseudoRoot)
  • FieldSet[1] : xformOpORder (SpecType = Connection)
  • FieldSet[2] : xformOp:translate (SpecType = Connection)

のような.

Specs, SpecType

Prim の場合は SpecPrim のみっぽい
Property の場合は Attribute か Relationsip のみの模様.
(.connect は Attribute)

Property

rel mytarget みたいに空の rel 定義以外は, アトリビュートの型情報 typeName(token 変数) を持つ. token で文字列なので float, matrix4d などとなる.

Attribute

  • 値を持たない attribute(e.g. float outputs:result など)
  • デフォルト値を持つ attribute(float val = 3.1). default Field がある.
  • TimeSamples attribute*(float val.timesamples = ...). `

Relationship

rel target のように定義だけでターゲットパスが無いもの.

specType = Relationship

field は variability のみのケースが多いと思われる.

  • typeName はなし
  • variability は optional

Connection Target, Relationship Target

connection が存在することをでっち上げるために connectionChildren or targetChildren も追加しておくとよい模様. それぞれ connectionPaths(ListOp), targetPaths(ListOp)に.

connectionChildren : [/path/to/mat]
connectionPaths : explicit list op: [/path/to/mat]

のように2つ定義を FieldSet に入れてあげる.

その他

primChildren(TokenVector) で子ノードの名前のリストがある.
Prim の階層構造は別途エンコードされるが, これは表示時(or トラバース時)の順序を指定するのに利用されます.
たとえばファイル(or C++ 内部)上では

/bora
/dora

のような順序で保存されていたとしても, primChildren = ["dora", "bora"] とあれば,

/dora
/bora

の順で復元します.

properties なども同様の役割を持つ... と思いきや properties は補助的にあるだけで, pxrUSD ではこの順でソートしたりはしませんでした...
`

配列データの圧縮

pxrUSD では, 16 要素以上ある場合に圧縮の試みが行われます.

int, uint, int64, uint64 の配列は Int compress されます.

half, float, double の場合は, すべて int で表現できれば int compress します.
もしくは Lut で表現できれば Lut 化します.

それ以外の型(float3[] など)は圧縮されません.

したがって face indices や, skin weight などの一部が圧縮されるだけで, 頂点座標などは圧縮されないのでどれだけ圧縮効果があるかは不明です.

また, 配列データの圧縮は必須ではないです.
(VRep で isCompressed flag を立たせなければ, 非圧縮でも USDC データとしては合法です)

LZ4 圧縮

0x7E000000(LZ4 の最大サイズ. およそ 2GB)単位で Chunk として圧縮する. 最大 127 chunk まで. したがっておよそ(圧縮して) 200 GB 程度までは一つのバッファとして扱えるようになっている.
chunk の個数は最初の 1 byte.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?