
- 2024年10月
- 2021年5月
- 2020年8月
- 2020年6月
- 2020年5月
- 2019年1月
- 2018年8月
- 2018年6月
- 2018年5月
- 2018年3月
- 2018年1月
- 2017年12月
- 2017年11月
- 2017年10月
- 2017年9月
- 2017年8月
- 2017年7月
- 2017年6月
- 2016年11月
- 2013年9月
- 2013年8月
- 2013年6月
- 2013年5月
- 2013年4月
- 2013年3月
- 2013年2月
- 2013年1月
- 2012年12月
- 2012年11月
- 2012年10月
- 2012年9月
- 2012年6月
- 2012年5月
- 2012年4月
- 2012年2月
- 2011年7月
- 2011年5月
- 2011年4月
- 2011年2月
- 2010年12月
- 2010年11月
- 2010年10月
- 2010年9月
- 2010年8月
- 2010年7月
- 2010年6月
- 2010年5月
- 2010年4月
- 2010年3月
- 2010年2月
- 2010年1月
- 2009年12月
- 2008年2月
- 2008年1月
- 2007年12月
- 2007年5月
- 2007年4月
- 2007年3月
- 2007年2月
scnファイルのデータ構造 / magicien
JSceneKitを実装する上で難しかった点の一つは、scnファイルの解析である。とはいえ、pmmファイルの解析で鍛えられたバイナリ読解力を以ってすれば造作もない。試しに ship.scn をバイナリエディタで開いてみると、"bplist00" という文字列が最初に入っていることがわかる。
これは、binary property list形式ということなので、plutilコマンドで中身を見ることができる。
$ plutil -p ship.scn
実行結果はこんな感じ。
{ "$version" => 100000 "$objects" => [ 0 => "$null" (中略) 81 => { "$classname" => "SCNScene" "$classes" => [ 0 => "SCNScene" 1 => "NSObject" ] } ] "$archiver" => "NSKeyedArchiver" "$top" => { "root" => <CFKeyedArchiverUID 0x7f90efd00480 [0x7fffbe406da0]>{value = 1} }
JSONのような形式で内容が表示されるので、これを元にどこにどのデータが入っているかを解析する。
すると、ファイルの末尾26バイトにパースに必要なデータが入っていることがわかる。
- オフセットデータのサイズ:unsigned byte
- オブジェクトのindexのサイズ:unsigned byte
- オブジェクト数:unsigned long long
- 最初のオブジェクトのindex:unsigned long long
- オブジェクトデータの場所:unsigned long long
最初に読み込むべきオブジェクトは、「最初のオブジェクトのindex」で与えられている。
各オブジェクトデータの先頭1バイトに、データの種類が格納されている。
0x00 なら null、0x08 なら false、 0x09 なら true、0x10〜0x1F なら整数、等。
最初のオブジェクトは、$version、$objects、$archiver、$top というデータの入ったDictionary型になっている。
次に読み込むべきオブジェクトは、$objects[$top.root] のオブジェクト。このオブジェクトが本当に必要なデータということになる。
オブジェクトが何らかのインスタンスである場合は、Dictionary型になっていて、"$class" にどのクラスのデータかが記録されている。
scnファイルの場合は、$class.$classname が SCNScene となっているはず。
Dictionary内の残りのデータはクラスによって異なるので、どれをどう読み込むかはクラス毎に実装が必要。
インスタンスのデータ全てが出力されているかといえばそういうわけではなく、デフォルト値と同じ場合は出力されていないこともある。
文字で書くと意味不明ですね。OmniGraffleの試用期間が終わったので製品版買おうかと思ったけど、Standardでも思ったより値が張るなぁ。
タグ:
この記事のURL: https://darkhorse2.0spec.jp/223/
2017/06/28(Wed) 04:03:27