mqoをjsonっぽくするコンバータ
Firefox3.0からOpenGLが使えるらしい
JavaScriptで3D描画―ネットアプリの常識変える?:Firefox 3.0で搭載へ - ZDNet Japan
ということはjavascriptから使える3Dデータフォーマットが必要だと思い、mqoファイルをjsonっぽくするコンバータを作ってみました。
Mayaにもpythonが搭載されたことだし、勉強も兼ねてpythonで。
mqo2json.py
# vim: fileencoding=utf-8 """ mqo > json のコンバータ Objectチャンクのvertexチャンクとfaceチャンクのみ対応 faceにmaterialIndexとかtextureCoordとか入っているけどMaterialチャンクに対応していないので意味無し mqoファイルは綺麗なテキストになってないと上手くコンバートできません BVertexチャンクあるとマズイかも… mqoファイルのフォーマットについては http://www.metaseq.net/ を参照させていただきました """ import re, sys #----------------------------- class Vertex(object): """ Vertexクラス 頂点情報を格納 """ def __init__( self ): self.x = 0.0 self.y = 0.0 self.z = 0.0 def setXYZ( self, x, y, z ): self.x = x self.y = y self.z = z return self def setFromList( self, list ): self.x = list[0] self.y = list[1] self.z = list[2] return self def toList( self ): return [ self.x, self.y, self.z ] def toJsonStr( self ): return '[ ' + str(self.x) + ', ' + str(self.y) + ', ' + str(self.z) + ' ]' #----------------------------- class Face(object): """ Faceクラス 面情報を格納 vertexIndex : 面を形成する頂点のインデックス materialIndex : 面のマテリアルのインデックス textureCoord : テクスチャのUV座標 """ def __init__( self ): self.vertexIndex = None self.materialIndex = -1 self.textureCoord = None def toJsonStr( self ): return '{ "vertexIndex" : [' + ",".join( [str(s) for s in self.vertexIndex] ) + '], "materialIndex" : ' + str(self.materialIndex) + ', "textureCoord" : [' + ",".join( [str(s) for s in self.textureCoord] ) + '] }' #----------------------------- class Mesh(object): """ Meshクラス mqoファイルでいうところのObjectチャンク相当 vertexとfaceしかもっていません """ def __init__( self ): self.vertices = [] self.faces = [] self.name = "unknown" def create( self, chunk ): objNameReg = re.compile(r'"(?P<name>([\w]+))"') m = objNameReg.search( chunk.head ) if m != None: self.name = m.group("name") for child in chunk.children: if child.type == "vertex": self.parseVertexChunk( child ) elif child.type == "face": self.parseFaceChunk( child ) return self def parseVertexChunk( self, chunk ): for d in chunk.data: vtx = Vertex() vtx.setFromList( [ float(s) for s in d.split() ] ) self.vertices.append( vtx ) return self.vertices def parseFaceChunk( self, chunk ): sizeReg = re.compile(r"^(?P<size>([-+]?\d+))") vtxIdxReg = re.compile(r"V\((?P<indices>([^\)]+))\)") matReg = re.compile(r"M\((?P<index>([^\)]+))\)") texCoordReg = re.compile(r"UV\((?P<texCoord>([^\)]+))\)") for d in chunk.data: m = sizeReg.search(d) if m != None: f = Face() m = vtxIdxReg.search(d) if m != None: f.vertexIndex = tuple( [ int(s) for s in m.group("indices").split() ] ) m = matReg.search(d) if m != None: f.materialIndex = int(m.group("index")) m = texCoordReg.search(d) if m != None: f.textureCoord = tuple( [ float(s) for s in m.group("texCoord").split() ] ) self.faces.append(f) return self.faces def toJsonStr( self ): result = '{\n' result += '"name" : "' + self.name + '",\n' result += '"vertex" : [\n' result += ',\n'.join( [ v.toJsonStr() for v in self.vertices ] ) result += '\n],\n' result += '"face" : [\n' result += ',\n'.join( [ f.toJsonStr() for f in self.faces ] ) result += '\n]\n' result += '}' return result #----------------------------- class Chunk(object): """ Chunkクラス mqoファイルのチャンク """ def __init__( self ): self.type = "" self.data = [] self.children = [] self.head = "" self.tail = "" #----------------------------- class MQO(object): """ MQOクラス mqoファイル loadでmqoファイルをロード saveでデータをjson形式でセーブ """ def __init__( self ): self.filepath = "" self.meshes = [] def load( self, path ): self.filepath = path f = open( path ) topLevelChunks = self.parseChunk( f.readlines() ) f.close() for chunk in topLevelChunks: if chunk.type == "Object": m = Mesh() m.create( chunk ) self.meshes.append( m ) def parseChunk( self, lines ): chkStartReg = re.compile(r"(?P<type>(^[\w]+))[^{]+{") chkEndReg = re.compile(r"}$") result = [] stack = [] for l in lines: l = l.strip() sm = chkStartReg.search(l) em = chkEndReg.search(l) if sm != None: chk = Chunk() chk.type = sm.group("type") chk.head = l stack.append(chk) elif em != None: chk = stack.pop() chk.tail = l if len(stack) == 0: result.append(chk) else: stack[-1].children.append(chk) else: if len(stack) != 0: stack[-1].data.append(l) return result def save( self, path, sceneName ): f= open( path, "w" ) jsonStr = sceneName + ' = {\n' jsonStr += '"meshes" : [\n' jsonStr += ',\n'.join( [ m.toJsonStr() for m in self.meshes ] ) jsonStr += '\n]\n' jsonStr += '}' f.write( jsonStr ) f.close() #----------------------------- if __name__ == "__main__": mqo = MQO() mqo.load( sys.argv[1] ) mqo.save( sys.argv[2], sys.argv[3] )
まだまだ勉強不足故に見苦しいコード…
jsonのテキスト作るあたりが特に…
使い方
python mqo2json.py hoge.mqo hoge.js hoge
みたいな感じで使えます。
テスト
ちゃんと出来てるかどうか確かめるために、以前作ったcanvasオブジェクトのヤツをちょろっと書き換え。
元データはhttp://nanoha.kirara.st/3dcg/のアップローダから、はちゅねミクのデータを使わせていただきました。
ポリ数2000ちょいのワイヤーフレーム。
注意:以下のページは自前描画なので激重です(IEだと特に!)
っていうかcolladaでいいんじゃね?
collada(COLLADA Overview - The Khronos Group Inc)ってxmlじゃね?
DOMで使えるんじゃね?
コレ意味なくね?
orz
まぁ、それはそれとして
3DかじってるプログラマとしてはOpenGL搭載は結構楽しみ。
ライティングとかテクスチャマッピングとかできるようになるのかなー。
スキニングとかアニメーションもしたいなー。
プログラマブルシェーダもできるといいなー。
プラグインとスクリプト間の値のやりとりメモ
Photoshopのスクリプトをプラグインのようにパラメータ込みでアクションに記録する方法が分からないので、仕方なくAutomationPluginと組み合わせて力技でアクションに記録できるようにしているのだけど…何かスマートじゃない。
プラグインとスクリプト間の値の受け渡しも、それらしき機構が用意されていないっぽいので仕方なくテンポラリにiniファイルみたいなテキスト形式のフォーマットでっち上げて一時ファイルとして吐かせて読み書きする、という泥臭い状態に…。
せめて値のやり取りだけでもスマートにしたいってことでJSON形式を使ってみることに。
スクリプトはjavascriptだから問題ないけど、プラグイン側はC++なのでパーサ必要だよなーと思って探してみたら結構あった。
とりあえず良さげなやつ2つ。
http://www.codeproject.com/cpp/JSON_Spirit.asp
json-cpp download | SourceForge.net
テキトーにサンプル作って動かしてみたら、期待通りに動いてくれたので、過去に作ったプラグインとかチマチマと修正。
今更canvasオブジェクト
普段はブラウザのjavascriptなんて全く触らないんだけど、もしかしたら少しやることになるかもしれないので必要そうなモノをチマチマと調べてみる。
んで今更ながらcanvasオブジェクトなるものの存在を知ったので、むか〜し作って絶望したヤツをcanvasをIE互換にしてくれるらしいライブラリExplorerCanvas download | SourceForge.netを使ってちょろっと書き直してみた。
http://www.geocities.jp/anderson_luis_de_souza/canvastest/canvastest.html
Firefoxだと思ったより速い。
IEだと妙に遅いけど使い方間違ってるんかな…。
世の中には凄い人もいる。
レイトレ
http://journal.mycom.co.jp/articles/2007/03/19/flog/index.html
ウォークスルー?
Untitled Film Works | Professional Film Makers
テクスチャ付きウォークスルー?
Untitled Film Works | Professional Film Makers
というかブラウザのjavascriptは大変そうだ。
prototypeとかブラウザ依存とか名前汚染とか関数言語的な考え方とか…
C言語脳な俺にはムズカシーorz
PhotoshopのjavascriptでピクセルのRGB値を取得する方法があった
Photoshopのjavascriptには直接ピクセルのRGBを取得できるようなオブジェクトが用意されていないので無理やりやらないといけない。
以下転載。
getColorAt = function(doc, x, y) { function selectBounds(doc, b) { doc.selection.select([[ b[0], b[1] ], [ b[2], b[1] ], [ b[2], b[3] ], [ b[0], b[3] ]]); } function findPV(h) { for (var i = 0; i <= 255; i++ ) { if (h[i]) { return i; } } return 0; } selectBounds(doc, [x, y, x+1, y+1]); var pColour = new SolidColor(); pColour.rgb.red = findPV(doc.channels["Red"].histogram); pColour.rgb.green = findPV(doc.channels["Green"].histogram); pColour.rgb.blue = findPV(doc.channels["Blue"].histogram); doc.selection.deselect(); // or, even better, undo };
転載元はココ。
http://www.ps-scripts.com/bb/viewtopic.php?t=411
Photoshopのjavascriptは便利なんだけど地味に痒いところに手が届いてないので困る。
1ピクセル選択してチャンネルのヒストグラム調べるとかどんだけー
EffectのRenderメソッドをシングルスレッドで実行する方法
public SampleEffect() : base("Text3D", null, "sub menu", PaintDotNet.Effects.EffectDirectives.SingleThreaded, true) { }
派生クラスでベースクラスのコンストラクタを呼ぶときにEffectDirectivesの値をSingleThreadedにすればRenderメソッドがシングルスレッドで呼ばれるっぽい。
当然のことながら重い処理をする場合はレスポンスが悪くなる。
プレビューを自分で組む場合やプレビューしなくてもいい場合はこっちのがいいのかな?
Paint.NETのプラグインを作ってみた
マイクロソフトが開発を支援してるらしきペイントソフト。
ソースが公開されていて、C#メインで作られてる。
従来どおり、この手のソフトはプラグインで機能拡張できるので、とりあえずハイトマップ→ノーマルマップ変換Effectプラグインを作ってみた。
http://www.geocities.jp/anderson_luis_de_souza/
インストールしたディレクトリにあるPaintDotNet.Effects.dllとかが外部公開向けのアセンブリで、こいつらにプラグインの基底クラスが入っている。
それらを派生して実装すればプラグインができる。
プラグイン作成向けのドキュメントが見当たらなかったので、簡単にメモ
- Effectプラグインの本体はPaintDotNet.Effects.Effectを継承して実装。Renderメソッドが肝
- プラグインのパラメータを操作するダイアログはPaintDotNet.Effects.EffectConfigDialogを継承して実装
- プラグインのパラメータはPaintDotNet.Effects.EffectConfigTokenを継承して実装。こいつでダイアログとプラグイン本体間のパラメータのやりとりをする
- PaintDotNet.Effects.Effect.RenderはPaint.NET本体から別スレッドで呼ばれるっぽいのでスレッドセーフにしておかないとダメ
最後のスレッドセーフ云々はRenderArgsのSurfaceを直に弄る分には意識しなくても大丈夫っぽいけど、GDIのGraphics経由で弄るならlock(dstArgs.Graphics)としておかないと実行時に落ちるので注意。
大体こんなところかなー。
はてな開始
自分用のメモをカテゴライズして残しておきたい衝動に駆られたので、はてな開始。
とりあえず使いそうな記法テスト。
小見出し
テキスト
小小見出し
テキスト
ソース
class CTest { public: int _value; };
アマゾン
- 出版社/メーカー: クリプトン・フューチャー・メディア
- 発売日: 2007/08/31
- メディア: CD-ROM
- 購入: 30人 クリック: 4,650回
- この商品を含むブログ (480件) を見る
リンク
Yahoo! JAPAN
引用
グーグル先生
http://www.google.co.jp/webhp?hl=ja