Cylinder構文のオブジェクトにテクスチャを貼る方法
2012/9/9

円柱、円錐型のオブジェクト制作には頂点を手入力するより、Cylinder構文を使うと非常に手間が省けます。とはいえ、BVE公式サイトの解説にはCylinderにテクスチャを貼る方法については書かれておらず、「テクスチャを貼るときには頂点打ちをしなくてはいけない」というのが通説になっていました。

ところが、BVE飯田保線区さんのところで、「Cylinderにもテクスチャが貼れる」という記述がありました。どうやら座標の割り当てがわかってしまえば良い、というような内容でしたが、具体的なことはわからなかったので試しにオブジェクトを制作して実験してみました。

ストラクチャファイルの構文を一通り扱えることを前提に話を進めていきますので、不明な点があれば公式サイト等で確認して下さい(無責任)。




ご存じの通り、テクスチャを貼る際には、LoadTextureでテクスチャを指定、SetTextureCoordinatesでテクスチャのマッピング設定を行います。通常の頂点打ちによるオブジェクトであれば、AddVertexで指定した座標に上から0,1,2,3,・・・とインデックスが割り当てられますから、これを指定するわけですが、Cylinderを使った場合は座標の入力などしていないのでこの場合、マッピング指定ができないという問題があります。

しかし、どうやら内部的には座標のマッピング番号は振られているようで、一定のポリシーに沿ってこれが決められていることがわかりました。構文の実態は座標と面の作成を自動的に行うものであると考えらます。




とりあえず解説用にテクスチャを作りました。テクスチャの上下左右が明確にわかることが望ましいので今回はこれを使います。


左のはWeb掲載の都合上GIF画像なのでこのまま使うことはできません。実験をやってみたい方はこちらからダウンロードしてください。



まずは最小限の構成を作ります。
色は便宜的なもので、この後不要になりますから入力しなくて問題ありません。

CreateMeshBuilder
Cylinder,8,1,1,3
GenerateNormals
SetColor,255,255,255

分割数=8つまり8角形の円柱を作ります。


ここで、おおよそ予測を立ててテクスチャを貼りつけてみました。頂点打ちの時に私が使っている方法で、上底を上から見て時計回りに一周、下底も同様い一週という順番に配置するというもの。






右のビューアを見ると明らかにおかしいです。

回転させながらよく見ると上にくるはずの色が下にあったり、その逆だったりしていることから、"前半が上側、後半が下側の頂点になっている"わけではないとわかります。




LoadTexture,texture_test.bmp
SetTextureCoordinates,0,1,0,
SetTextureCoordinates,1,1,0.25,
SetTextureCoordinates,2,1,0.5,
SetTextureCoordinates,3,1,0.75,
SetTextureCoordinates,4,1,1,
SetTextureCoordinates,5,1,0.75,
SetTextureCoordinates,6,1,0.5,
SetTextureCoordinates,7,1,0.25,
SetTextureCoordinates,8,0,0,
SetTextureCoordinates,9,0,0.25,
SetTextureCoordinates,10,0,0.5,
SetTextureCoordinates,11,0,0.75,
SetTextureCoordinates,12,0,1,
SetTextureCoordinates,13,0,0.75,
SetTextureCoordinates,14,0,0.5,
SetTextureCoordinates,15,0,0.25,




この構文をいじって、頂点を探していきます。具体的には1カ所だけ変更してストラクチャビューアで確認。変更した部分には変化があるはずなのでそれを書き取り、さらに別な場所を書き換えて…という作業を繰り返します。


試した結果、偶数番が上底、奇数番が下底に割り当てられているということがわかりました。インデックス番号0が上底、その真下の下底の頂点が1、0から上から見て反時計回りに一つ隣の頂点が2でその真下が3、という具体に上下が対応していて上から見て反時計回りに一週する形であることがわかりました。

右の図のような感じで、上、下、そこから左回りに上、下、…となる感じ。




とりあえず順番がわかったのでテクスチャを貼ってみます。14、15から0、1に戻ってくる形になるので一枚のテクスチャで一周させる貼り方はできず、左右反転した2枚で一周という形にします。

SetTextureCoordinates,0,0,0,
SetTextureCoordinates,1,1,0,
SetTextureCoordinates,2,0,0.25,
SetTextureCoordinates,3,1,0.25,
SetTextureCoordinates,4,0,0.5,
SetTextureCoordinates,5,1,0.5,
SetTextureCoordinates,6,0,0.75,
SetTextureCoordinates,7,1,0.75,
SetTextureCoordinates,8,0,1,
SetTextureCoordinates,9,1,1,
SetTextureCoordinates,10,0,0.75,
SetTextureCoordinates,11,1,0.75,
SetTextureCoordinates,12,0,0.5,
SetTextureCoordinates,13,1,0.5,
SetTextureCoordinates,14,0,0.25,
SetTextureCoordinates,15,1,0.25,

テクスチャから判断して赤い→で示したところが0に当たる頂点です。回転させていない状態ですので、どうやら正面から見て右端からスタートして、左回りであることがわかります。





※底面はおかしなことになりますが、これはどうにもなりませんでした(汗)


わかりにくいので図で解説します。

座標は必ず一番右側に当たる頂点から順に割振られます、
この場合は12、13の頂点が正面になり、右端に当たるのは2つ隣の頂点です。そこから、先ほどの解説通り左回りで一周する形になります。

※なお、この図は説明のため若干回転させてあります。

今回は8角形だったのですが、6角形だとどうなるかというとこんな感じ。

この場合も必ず右側からスタートになるのは変わりません。


やはり底面はおかしなことになります。上下1ドットを透過させると底面が透過されるので、どうやら上下の1ドットを使っているようなのですが、形状はめちゃくちゃでどうにもなりません。透過させればこれを消すことはできますが、そうすると筒状の形にしかならなくなります。


拙い説明で理解しづらい部分がありましたら、申し訳ありません。個別のサポートができる余裕がありませんので、実験用のファイルを使って同様の実験をしてご理解いただければ幸いです。
また、ここでの解説は独自研究によるものであり内容の信憑性について保証できるものではありません。間違い等があればご指摘いただければ幸いです。苦情はご勘弁を。

実験に使ったファイルがほしい方はこちらからダウンロードしてください。
実験用ファイル

底面がきれいに処理できないので用途を選びますが、工夫次第で手間が削減できるので活用できるところには今後使っていきたいと思っています。やっぱり頂点の計算は面倒なので。
ちなみにちらっと書きましたが、座標も自動作成されているのでAddFaceを使って面を追加することもできます。あんまり使い道はないかもしれませんが。



戻る