ラベル COLLADA の投稿を表示しています。 すべての投稿を表示
ラベル COLLADA の投稿を表示しています。 すべての投稿を表示

2012年3月19日月曜日

進捗 その2

アニメーションやスキニングをする予定はなかったのだが、一応どんなものか目を通した。
どちらも比較的単純で理解自体は直ぐではあった。
が、やはりデータ構造がしんどいなぁ。



スキン関連だと行列パレット、頂点ウェイトの個数なんかが圧縮されているから
すべて展開しないといけない。
最大10個程度のボーンの影響しかないのに展開前だと85とか総数が記載されてるから。

アニメーションの指定についても
<channel source="#group1_translate-anim-samplerY" target="group1/translate.Y"/>

ターゲットの指定がこれだしなぁ・・・。

colladaを直接扱ってる限りmapの呪縛からは逃れられないってことか。

あとはデータ構造全般として、参照形式で持たせておいたほうが良さそうだ。
同じものを描画する際、<node>だけクローンさせれば無駄がなくなるし。

2012年3月14日水曜日

進捗

問題点ばかりだったので進んでいなかったテクスチャ周辺を改修。
各サンプラにつき2Dテクスチャ1枚という限定はあるが自動読み込み完了。
自動読み込みってなんだって感じだが、今まで非常に残念なことをしていたのだ・・・。
結局デフォルトシェーダも対応しなければいけない方向になってきたがどうしたものか。

あとは、上軸の定義をどうするか。
今の環境ではデフォルトでZ_UPばかり出力されるから、面を反転して描画時に回転を掛けている。
真面目に対応するとあらゆる要素を変換しなければいけないというのが憂鬱。

少し問題点を整理しよう。

[追記]2012/03/15
軸の問題が面倒なので気休めに簡単なトラックボールとズーム機能を追加。

手を抜いていらんだろうとたかをくくっていたが、いざ実装してみると便利なものである。
ただ、数学関連のライブラリが大昔に作ったものを引っ張り出してきたため
行指向・左手座標系とかそういう類のものであったため部分的にOpenGLで利用できるよう
改修中。
列指向・右手座標系はこの世から消えてくれ・・・。

GLSL特化にすれば問題ないといえばそうではあるが・・・一考してみるか。

ズーム機能といえばfreeglutなるもので利用できることを知った。
厳密に言えばホイールイベントの検知ではあるが。
GLUT自体の更新が止まっているためfreeglutなるものが開発されているらしい。

VS2005ユーザとしては悲しいが公式のは利用できなかった。
が、こちらでバイナリを配布しているようで、早速利用させて頂いた。

[追記]2012/03/17
階層構造を実装。
<node>の構築自体は終わっていたが行列関連の整備が進んでいなかったため変換行列周り
に手を付けられていない状態だった。
今回もテスト用モデルを物色しこちらから拝借。
というのもこれまで利用していたモデルは変換行列が不要なものばかりだったので。
右腕が変換を含んでいるみたい。

2012年3月13日火曜日

Metasequoia~Blender~Colladaの罠

ケース1
Metasequoiaで作成した*mqoをBlenderにインポート
*blendで出力
*blendを読み込む
*.mqoでエクスポート
Metasequoiaで読み込む
→ざっくり見た感じ問題ない

ケース2
Metasequoiaで作成した*mqoをBlenderにインポート
*.daeでエクスポート
*.daeをインポート
*.mqoでエクスポート
Metasequoiaで読み込む
→色々アウト。

可逆する必要性はまったくないのでこれ自体は問題ない。

気づいた点が1つ。
Metasequoiaで作成した*mqoをBlenderにインポートし、*daeでエクスポート。
ざっくり見た感じ形状などには問題はない。
が、自己照明(放射光)の値がおかしい。
とある*.daeを読み込んだらやたらと白とびしていたため気がついた。
emissionが(1.0, 1.0, 1.0, 1.0)とかなってるわけ。
単純なレンダリング方程式として見ても、(1.0, 1.0, 1.0, 1.0)とかなってるとトーンマップでも
しない限りemissionを扱っただけで真っ白になるじゃないか!

とりあえず原因を探ってみた。
Metasequoiaのパラメータの扱いが若干特殊なのかも知れない。
というのも自己照明は%表現。
材質パネルの出力イメージで確認するとMetasequoia的には基本色*自己照明となっている。
対してBlenderの*.daeエクスポートを通すと、(自己照明、自己照明、自己照明、1.0)
のようになっている。

Metasequoia側で基本色RGB(255,0,0)として自己照明1.0の出力を行うと
*.daeのマテリアルのemissionが(1.0, 1.0, 1.0, 1.0)となったからだ。

拡散光については想定どおりなんだが。

フリーなので文句は言えないか・・・。

で、渦中の対象モデルは今回こちらから拝借させて頂いた。

中見ると半透明とか使用しているので見た目は結構変わるかも知れない。
emissionについてはどうにもならんので手作業で改変。
フラグメントシェーダはMetasequoia風にアレンジ。


Colladaさん柔軟であるが故に、元が何からエクスポートされたか把握しておかねば
問題点を絞るのが大変だ。

2012年3月11日日曜日

COLLADA (7)プリミティブ

再びジオメトリ周辺。

<p>(インデクス配列)には直前の<input>要素の数だけインデクスが入っている。

<input semantic="VERTEX" source="#vertices" offset="0"/>
<input semantic="NORMAL" source="#normals" offset="1"/>
<input semantic="TEXCOORD" source="#texcoords" offset="2" set="0"/>
<p>0 0 1 1 2 2</p>

位置、法線、座標、位置、法線、座標

なんて具合にインデクスが混在している。
上記は非常に単純な例だが、仕様書には様々なイカレタ例が示されている。
また実際に利用される実数は<p>に依存する。

とあるサンプルファイルの実数配列部は
位置:4122  / 3 = 1374
法線:4122  / 3 = 1374
座標:12904 / 2 = 6452

<p>に基づき展開すると
位置:6318 / 3 = 2106
法線:6318 / 3 = 2106
座標:4212 / 2 = 2106

しかしこれではインデクス化の旨みが0。
OpenGLなら要素毎にプッシュできるので百歩譲って問題ないが・・・。
頂点配列を利用するなら再インデクス化が必要。
この部分だけ見ると強烈にダルいフォーマットだなぁ。

2012年3月7日水曜日

COLLADA (6)マテリアル~エフェクト

これは制限を付けないと収拾が付かない。

今回は下記の制限を付けた。
■<profile_***>
<profile_COMMON>を1つのみ。
仕様書によると固定機能だそうだ。
今時固定機能なんて・・・と思いたいが、シンプルイズベストだ。
将来、いやむしろ今(GLES2.0とか)既にシェーダが基準となっている。
<profile_COMMON>が提供するモデルは、<constant>、<lambert>、<phong>、<blinn>
の4つしかない。
実際これらはシェーダで書いた方が手っ取り早い。
シェーダを準備するのとシェーダ用の窓口を作るのが面倒なだけの単なる怠惰だ。
逆にシェーダ標準で固定機能を切り捨てる設計なら話は早い。
いづれにせよ制限は必要だ。

1つのみとしたことにも理由がある。
仕様書によると<profile_COMMON>以外も0以上で混載できるとある。
何度も引っかかったが、COLLADAはあくまで各種3Dツールの中間フォーマット。
例えばデザイナが試行錯誤しながらモデルを作成している際に、様々なマテリアルを作り
最終的にコレだ!というものを適用する。
適用しなかったものは?
おそらく3Dツールとしては有用な資産として、そうでない場合はゴミとして残る。
デジタルアセットの管理という面では、COLLADAで一元管理(様々なプラットフォーム
データを含む)を行い、そこから必要なものだけ抜き出す感じになるんだろう。


<Sampler***>
<Sampler2D>のみ。
各種要素のテクスチャは1枚のみ。
キューブマップ(6枚指定)とか考えたくない、、、
<Sampler1D>は面白いことができるのでこれはありかもしれない。
この辺は固定機能では面倒となるので、シェーダ標準とするならすべてサポート
という方向でいいかも。

あと気になったことが1点。
現状はv1.4を対象としているが、仕様書が結構手抜きなのでv1.5も併読している。
今回採り上げた周辺の仕様には地味に差があり、一部互換性がないように見える。

2012年3月6日火曜日

COLLADA (5)

頭の片隅に常にあった懸案。
・<scene>内の<instance_visual_scene>の出現回数は0または1
・<library_visual_scenes>内の<visual_scene>の出現回数は1以上
・<instance_node>は<library_nodes>を参照する新たなノード
・<instance_material>と<library_materials>
・<instance_effect>と<library_effects>

・<instance_geometry>と<library_geometries>

原点回帰とでもいうべきか。

インスタンス化と外部参照
注:COLLADA では、インスタンス間のデータ共有の方法を規定していません。データ共有ポリシーはランタイムアプリケーションに任されています。

とある。
様々な凡例やサンプルを調査すると、よほど単純なものでない限りは共有は意識されていない
ように感じる。
マテリアルを例に出すと、Aという基本になるものに差分変更を加えたB、またはCという具合に
実質3種類のマテリアルがあたかも存在することになる。
ご丁寧に<newparam>や<setparam>などで上手い具合にぼかしてある。
メモリー効率面では断然共有化ではあるが、元データの退避や上書きなど処理が煩雑になる。
おまけに差分要素はぴんからきりである。
実行時に毎回セットアップなんてしてられんなぁということで、<instance_***>系列はそのとおり
インスタンス化する方針に変更。
敢えて他の後に記述した<instance_geometry>。
極端な話をしない限りは<instance_geometry>以外はすべてインスタンス化しても大した量には
ならない。

途中経過の自問自答
<instance_geometry>をインスタンス化しなければならないケースは?
なんらかの頂点に対する操作の結果を必要とする場合。
ソフトウェアでスキンニングとかそういった類か。
vertex_shaderを前提とするなら大抵は回避はできるはず。
地形や背景を1つの*.daeで表現なんて絶対しないししてはいけないだろうが
仮にした場合は共通パターンで影響が出る。
これはそもそもがダメなので問題外。
おっと、モーフィングがあったか。
顔の表現時にボーンじゃ上手くいかん!とか言われて顔だけモーフィングしたことあるな・・・。

とりあえず<instance_geometry>以外をインスタンス化することで妥協する方針で。

COLLADA (4)シーングラフ4

ジオメトリを抜き出すのが最終目的なので、 <node>以下の<instance_geometry>は
軽く抜き出すことに止めて置いた。
というのも設計部分で悩んでいる。

<node>におけるもう1つ重要な要素がある。
transformation_elements
変換要素、つまり移動、回転、縮尺など。
これがまたフォーマット観点から見ると非常に素晴らしい表現である。
各子変換要素が出現順で合成されるコンテキストを表します。

COLLADAさん相変わらず柔軟ですね!

本当に壁を殴ってやりたい・・・。
変換要素は
<Lookat>、<matrix>、<rotate>、<scale>、<skew>、<translate>
これらの出現回数は各々0以上。

ジオメトリ特化かつせん断を考慮しなければ
<matrix>、<rotate>、<scale>、<translate>
※<matrix>が微妙な気がするが

つまり、回転→移動→縮尺→移動→回転なんて記述されていれば
すべて順番どおりにジオメトリに適用しないといけないわけだ。

アニメーションを考慮しないなら行列にしてしまえば済む話ではあるが・・・。
見るだけ見てみるか。

2012年3月5日月曜日

COLLADA (4)シーングラフ3

今回は思考中な部分をそのまま記述したので長文となってしまった。
ということで要点だけ。
<library_nodes>には<instance_node>となる<node>が格納されている(はず)。
<visual_scene>内の<node>と同じく、<node>の詳細も記述されている (はず)。
node id は一意になるため、getElement で最初に取得できる要素は必ず指定した<node>
になる(はず)。
<instance_node>とすべきかどうかはアプリケーション依存ではあるが、シーングラフ上で
複数回出現するノードはもれなく<instance_node>となり、<library_nodes>に格納される(はず)。
またその子、孫・・・ももれなく<library_nodes>に格納される(はず)。
とりあえずこれで様子を見よう。

2012年3月4日日曜日

COLLADA (4)シーングラフ2

<node>周辺。

<instance_node>が出現する際に循環参照が生成されることはあるんだろうか。
COLLADA DOMへ独自形式を登録しインポート、エクスポートを行っているなら
責務はCOLLADA DOMとなるが、独自にエクスポートしてる場合はなきにしろあらずか。

コンセプトとして各種デジタルアセットを取り扱う基点となるのが目的だから
文句を言っても仕方ないが<instance_node>の存在が少し厄介。

単純な階層構造の場合、<node>はメッシュそのものになるわけだから、
class Node{
 Node* sibling;
 Node* children;
 Matrix toLocal;
 Matrix toWorld;
 Primitive* prim;
}
みたいな感じとすると、<node>だけで構成される場合は、階層構造を1度トラバースすれば
各toWorldは計算済みとなる。
描画フェーズで階層構造をトラバースしながらtoWorldを利用してプリミティブを描画するだけで
いいこととなる。

仕様書の例を少し改造して
<library_nodes>
 <node id="node2"/>
</library_nodes>
<node id="node0">
 <node id="node1">
  <translate>11.0 12.0 13.0</translate>
  <instance_node url="#node2"/>
 </node>
</node>
<node id="node2">
 <node id="node3">
 </node>
</node>
node1が該当部分となる。
仕様書によると、node1はnode2を少し移動するということだ。
class Nodeの例で<instance_node>への参照を持つと、計算フェーズでtoWorldが
上書きされて残念なことになる。

要素は、COLLADA ノードリソースのインスタンス化を宣言するためのものです。

説明に従ってインスタンス化するのが無難か。
とすると、
node0
 node1
  node2
   node3
node2
 node3

見かけ上のノード数4が実際には6ということになる。
COLLADA DOMのデータベースを介してノードを展開できると後で楽をできそうだがはてさて。

[追記]
ノードが展開できるかはさておき、daeDatabaseの検索が良くできてるな。
domNode* dom_node;
if(dae_db->getElement((daeElement**)&dom_node, 0, "node2", "node") != DAE_OK)
 return NULL;
先の例でこんな感じにすればdomNodeを引っ張ってこれる。
ただ、ここではgetElementの第二引数が0なので<instance_node>の<node>が引っかかる。
常識的に考えると<instance_node>に同じ<node>が存在するはずもないし
それらはただ間接参照するためだけに存在するはずだからid属性しか持っていないはずだ。
また、<library_visual_scenes>内の各<node>のid属性はユニークなはずなので
最大でも2回のクエリで取得できるはずだ。

余談ではあるが、仕様書の<node>の項をよく見ると面白いことが記載されている。
<instance_camera>
<instance_controller>
<instance_geometry>
<instance_light>
<instance_node>
出現回数は0以上。

ということは良し悪しはともかく
・カメラにジオメトリをくっつける
・カメラにライトをくっつける
・ライトにジオメトリをくっつける
なんてことも記載できるわけだ!
改めてこのフォーマットの柔軟性を感じた、今回はいい意味で。

2012年3月1日木曜日

COLLADA (4)シーングラフ

<scene>
 <instance_physics_scene>
 <instance_visual_scene>
 <instance_kinematics_scene>
 <extra>

<instance_visual_scene>
 sid(optional)
 name(optional)
 url
 <extra>
 
<library_visual_scenes>
 id(optional)
 name(optional)
 <asset>
 <visual_scenes>
 <extra>
 
<visual_scene>
 id(optional)
 name(optional)
 <asset>
 <node>
 <evaluate_scene>
 <extra>
 
<node>
 id(optinal)
 name(optinal)
 sid(optinal)
 type(optinal)
 layer
 <asset> 
 transformation_elements
  <Lookat>
  <matrix>
  <rotate>
  <scale>
  <skew>
  <translate>
 <instance_camera>
 <instance_controller>
 <instance_geometry>
 <instance_light>
 <instance_node>
 <node>
 <extra>
 
<library_nodes>
 id(optinal)
 name(optinal)
 <asset>
 <node>
 <extra>


モデルを抜き出すのに必要な箇所だけマーク。
<extra>は実質アプリケーション次第なので無視。
<asset>はこれといって重要なケースが今のところ見つからないので無視。
(optinal)も一部を除いて実質無視。
 

シーングラフの辿り方
(1) <scene>→<instance_visual_scene>::url
(2) <visual_scene>
(3) <node>

階層構造
root:<visual_scene>
他は<node>を入れ子とした親子関係


<node>自体は特に問題ないが<instance_node>に注意。
多分1以上存在していれば<library_nodes>が出現するはず。
エイリアスとなるので生成、破棄はNG。


レイヤー構造
<node>::layer
ケース1:"" ... 空(無所属)
ケース2:"hoge" ... 1グループ(hoge所属)
ケース3:"hoge foo" ... 複数グループ(hogeとfoo所属)

モデラなら必須だが。

その他 
<node>::type
デフォルトは空="NODE"
それ以外は"JOINT"
まだ見てないがスキン関連か?

COLLADA (3)テクスチャマッピング

次に取り掛かるのはテクスチャ周り。
<library_effects>
<library_images>
<library_materials>
このあたり。

その前に避けて通れない画像の読み出しがある。
COLLADAのコンセプトとして多種多様な画像を想定しているわけなので
個々で対応していられない。
ここはオープンソースの享受を受けようというわけでOpenCV
これもいつの間にか色々進化を遂げていて、Win、Linux、Mac、Android!まである。
単体で遊んでも面白そう。
・・・遊びそうになったので我慢してCOLLADAに戻る。

バイナリ配布も行っているようだが、VCに関しては2008(VC9)と2010(VC10)のみ。
当方は2005(VC8)ユーザなのでビルドするしかない。
今時2005なんて使ってる人いるんかと気が引けるが、素敵な情報があった!

ちゃちゃっと環境が整った。

[追記]
collada周りは無視でOpenCVを利用したテクスチャマッピングが正しくできるかのテスト。
モデルを作ろうとしたが、私にとってのBlenderはオーパーツそのものだった。
というわけでメタセコイア→Blender→Colladaのコンボ。
どうせならいい感じのモデルを表示してみたいと物色したら・・・
Paletteというサイトの方のをお借りすることにした。


特に問題なく表示はできているようだ。
OpenCVとOpenGLの相性はかなりいい。
画像ロード~テクスチャバインドまで秒殺できる勢い。

[追記その2]
<library_geometries>から直接辿れる限界がきたようだ。
<library_images>は独立してるからいいとして、
メッシュのプリミティブが参照しているマテリアルを辿るには基本的に
<library_visual_scenes>からでないと無理そう。

<library_visual_scenes>→<node>→<instance_geometry>→<bind_material>
ここから
<library_materials>→<library_effects>

ただ、モデルによっては必ずしも<bind_material>の中身があるわけでもないらしい。
サンプル数が少ないが、上記で辿れない場合は直接
<library_materials>→<library_effects>
か?

また、静的なモデルの最低限の情報は

<library_effects>
<library_images>
<library_materials>
<library_geometries>
<library_visual_scenes>
<scene>

というところか。
作戦の練り直しだな。

2012年2月29日水曜日

COLLADA (2)メッシュ表示

想像以上にイライラするフォーマットという印象。
メッシュの抜き出しに関してはようやく目処がついた。

仕様書にある
(1) <vertices>が存在しないケース
(2) 1つの<source>を全てが間接的に参照しているケース
(3) <vertices>内の<input>が複数あるケース
(4) オフセットの計算(連続する名無し<param>の考慮)
(5) 名無しの<param>
(6) マルチテクスチャ
これらも一応考慮しておいた。

色々考察した結果、エクスポータ依存によるところが非常に大きい。
キチガイ少し風変わりな出力がされている場合、それ即ちヘボいエクスポータということになる。

で、先に進める前に抜き出したメッシュがどんな具合かテストを行うためにOpenGL環境を用意。
メッシュ自体を表示することはできたが、1つ問題が出てきた。

<triangles>にある<p>、つまりインデクス。
当然そのままじゃ使えない。

頂点バッファに押し込みたいので一段噛ます必要があるようだ。



[追記]
と書きつつ気になったので少し古いが資料を発掘。
ディスプレイリストでもいい気がしてきた。
GLES側にはないらしいので、そっちはその時に考えるかな。

[追記その2]
ディスプレイリストで描画。


何の面白みもないただのトーラス。
*.daeが入出力可能かつフリーなソフトがBlenderしか見つけられなかったため。
本当は3DCGといえばティーポットだろうといいたいところだが我慢。
余談ではあるがBlender進化し過ぎ。
10年前くらいは特に見向きもしなかったが何だこれ!?
UIが無駄にかっこいい&操作性がぶっ飛んでいる!!
LightWaveや3DSなら普通に操作できるがこれはちょっと出来ん・・・。

2012年2月27日月曜日

COLLADA (1)準備

ふとCOLLADAでも読んでやるかと思った。XMLパーサ書くの面倒だなと調べたらCOLLADA DOMていう専用のパーサがありましたと。
バカでかいのはこの際いいとしても、初見じゃビルドできないときた。
グーグル先生に聞いたら素敵なサイトを教えてくれた。

v1.5という形式がどうやら最新の形式であることが判明。
というわけでこの環境を構築したわけだが・・・。

試しにネットから拾ってきたCOLLADAファイル(*.dae)をロードしてみる。
すると、ロードエラーで躓くときた。
原因はどうもDOMのバージョンとCOLLADAファイルのバージョンに差異があるということで
これで弾かれているらしい。
なんてこった!

そこでDOMを騙してやる作戦としてCOLLADAファイルのバージョンを変更してみた。
ロードは成功したが、特定のエレメント名に対するオブジェクトが生成されないと警告が出る。

仕方ないのでv1.4の環境を用意することにした・・・。

というのもお手軽にファイルを入手できるGoogle 3Dギャラリーで何ファイルか摘んでみると
どれもv1.4だったからという・・・。

ただ、DOMをv1.4、ファイルをv1.4にしても警告が完全に無くならないファイルもあるわけだが。
見なかったことにしよう。

で、とりあえず見ているわけだが、<geometry><mesh>~</mesh></geometry>内部にある
<source>~</source>
最大でも位置、法線、テクスチャ座標、色が入るということだろう(最低は1)。
疑問点は、
(1)並び順
固定?
数少ないサンプルファイルしか見てないので断定もできない。
ただ、XMLということを考慮すると固定というわけでもない気がするのと
エクスポータ次第な気もするんだけど。

(2)source要素の意味
つまり、取得したsource要素が頂点、法線、テクスチャ座標、色の内どれなのか。
あるファイルには
<source id="***-position">
<source id="***-Position">
<source id="***-Normals">
<source id="***-normal">
<source id="***-UV">
<source id="***-uv">
なんて記述されている。
これも仕様かどうかは調べないといけないが、ハイフン以降で判別自体はできるってことなのか?
では大文字、小文字は百歩譲って、Normalsとnormalの違いってどこから来てるんだろう。
バージョン差異ならまぁいいとしてもエクスポータ次第なら困るとこ。

[追記その1]
COLLADA 1.5.0 Specification in Japanese (Last updated: May 2009) *NEW*
のaccessor項目を見るとどうも違うらしい。
(1) ネーミングが異なる(2) Textureが2個ある

(1)は良く分からんな・・・やっぱりエクスポータ次第か?
とすると、純粋に何かという判別は、各プリミティブにあるsemanticでしか
判別できないということになり、そうすると存在するプリミティブをすべて見ないといけない
ことになる。

(2)はマルチテクスチャを考慮するとテクスチャが複数あるのは自然
だけど、他の要素については重複云々については特に触れていない。
ということは極端な話、POSITIONが複数あってもフォーマット的には問題ないということか。

で、pdfを見ていると分かったことが1つ。
vertices、オフセット、ストライド、最低でもこれらを全て考慮しないといけない。

柔軟にも程がある!

[追記その2]
<mesh>周りのまとめ

<mesh>
<source> ... 出現回数1以上
<vertices>  ... 出現回数1
<lines> ... 出現回数0以上
<linestrips> ... 出現回数0以上
<polygons> ... 出現回数0以上
<polylist> ... 出現回数0以上
<triangles> ... 出現回数0以上
<trifans> ... 出現回数0以上
<tritristrips> ... 出現回数0以上
<extra> ... 出現回数0以上

<vertices>
<input> ... 出現回数1以上
<extra> ... 出現回数0以上

<accessor>のサンプルを見ると<mesh>に<vertices>が存在しないケースがあるが
これは矛盾していないのだろうか?

またその際、<triangles>の<input>のsemanticは"POSITION"。
<vertices>の解説では1つの<input>要素は semantic="POSITIONを指定する必要がある
と明記されている。
この解説が正しいならprimitive_typesの中に出現する<input>のsemanticにはPOSITIONが
出現することはないと思うのだが。


また<vertices>の<input>出現回数が1以上ということは

<vertices id="verts">
  <input semantic=~POSITION" source="#position"/>
</vertices>
<triangles>
   <input semantic=~VERTEX" source="#verts"/ offset=0> 
   <input semantic=~NORMAL" source="#nrms"/ offset=1>
   <input semantic=~TEXCORD" source="#tc/" offset=2>
</triangles>

 と

<vertices id="verts">
  <input semantic=~POSITION" source="#position"/ offset=0>
<input semantic=~NORMAL" source="#nrms"/ offset=1>
  <input semantic=~TEXCORD" source="#tc/" offset=2>

</vertices>
<triangles>
   <input semantic=~VERTEX" source="#verts"/> 
</triangles>


<vertices id="verts">
  <input semantic=~POSITION" source="#position"/>
</vertices> <triangles>
   <input semantic=~VERTEX" source="#verts"/ offset=0> 
<input semantic=~NORMAL" source="#position"/ offset=0>
  <input semantic=~TEXCORD" source="#position/" offset=0>
</triangles> ※最後は各<source>内部でストライドを調整しているケース

同じ意味を指すケースもあるわけだろうか?

・・・ないとは言い切れないだろうなぁ。
あらゆる可能性(仕様の範囲内) を想定して上手くロードすることはできるのだろうか・・・。