2008年11月アーカイブ

MouseWheelイベントでトラップに引っかってしもーた\(^o^)/


MouseWheelがどっちにスクロールしたかなんてのは、
MouseEvent#deltaの32ビット目を見ればわかると思って



イベントハンドラの中で、こんな風にロジック書いちゃった

if(event.delta < 0) {
     ・
     ・
     ・
} else {
     ・
     ・
     ・
}


Windows+マウスでテストしたら、ゼンゼンOKだったんだけど、

MacBookで試してみたら罠が待ち受けてた!!


MouseWheelイベントだから、当然上か下かにスクロールされたときに発生するはずじゃん



つまり、delta=0なんてありえないじゃん!!



プログラム
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" mouseWheel="trace(event.delta)">
	
</mx:WindowedApplication>


タッチパッドに指を2本添えて(←ココ重要)、適当に前後に動かす。


結果
-2
-2
0
0
0
-6
0
0
4
0
0
0
0
-5
0
0

0とかまじ自重しろ!!!


イベントハンドラの先頭に、


if(event.delta==0) return



を加えるとマウスのと同じ動きをしてくれるようになりました。






Flat Shadingっていうので、面を描画してみたよ!!



Flat Shadingっていうは、面が光源の方を向いていれば明るく、そうでなければ暗い色で塗りつぶす手法。


まず、光源は常識的に考えて、上から下に向かって光っているから、

(0, -1, 0)っていうベクトル。


一応、単位ベクトル(x^2+y^2+z^2=1)になるようにとる。



んで、面が光源の方を向いているかは、

その面の法線ベクトルと光源ベクトルと内積をとればおk

このとき、2つのベクトルが単位業行列であれば、内積はcosθになるので、2つのベクトルの角度が求まる。


とか書くと、日本語でおkとか言われそうなので、



簡単に説明・・・




って思ったら、id:nitoyonさんのてっく煮の方が絵とかあって分かりやすそうだからそっち見てね!!


↓要FlashPlayer10 クリックすると動くよ!!




次は、Gouraud Shadingで滑らかにしたいな




前の[3D][Astro] .obj形式のファイルを読み込んで、ユタ・ティーポットを表示してみたをちょっと修正した版

修正点
・.objファイルの差し替え。
・GPUを使う。
・getGeometryMatrixメソッドをUIComponent3Dクラスに移動。
・三角形の描画にmoveTo、lineToではなく、drawTrianglesを使う。



・.objファイルの差し替え。
前回のでは、四角形データを三角形+法線と勘違いしていて、4つ目の点を使ってなかったので、
もう三角形だけで構成された.objを作成。

ついでに、分割数を4に減らして頂点数ダイエット!!

ついでに回転の中心をポッドの真ん中にした。



・GPUを使う。
HTMLのFlashを呼ぶところにwmode=gpuを追加



・getGeometryMatrixメソッドをUIComponent3Dクラスに移動。
_xとか_rotateXとかが親クラスにあるのに、getGeometryMatrixがサブクラスとか変だし使い回したいからUIComponent3Dに移動



・三角形の描画にmoveTo、lineToではなく、drawTrianglesを使う。
FlashPlayer10からGraphicsクラスにメソッドが増えました!!
詳しくは、ここに書いてあるよ!!

今回は、この
drawTriangles(vertices:Vector.<Number>, indices:Vector.<int> = null, uvtData:Vector.<Number> = null, culling:String = "none"):void

を使ってみた


これできっと軽くなる!!


って思ったけど、世の中そんなに甘くなかったT T


Windingとかは、Shade書く時に使えそう!!


さっきのブログのサンプル見ると

graphics.drawTriangles(
    Vector.<Number>([10,10, 100,10, 10,100, 100,100]),
    Vector.<int>([0,1,2, 1,3,2]));


って書くと、

点0(10, 10) 点1(100, 10) 点2(10, 100)
点1(100, 10) 点3(100, 100) 点2(10, 100)
を結んだ2個の三角形を書いてくれるみたい。

第2引数を与えなかったら、前から順に3つずつとかになるっぽい。



軽くなった気がしないけど、修正版↓(要FlashPlayer10)



Adobe AIRでファイル名に&を含むものを.airファイルに含めると、

.airファイルをダブルクリックしてインストールしようとすると、


エラーが発生しました。

AIR ファイルが破損しているためアプリケーションをインストールできませんでした。アプリケーション作成者に問い合わせて、新しい AIR ファイルを入手してください。


ってでる。




再現の仕方

1. FlexBulderでAIRのプロジェクトを作る。

2. プロジェクト直下に"bin-release"フォルダを作成。

3. bin-release内にファイル名に&を含むものを作成。

4. リリースビルド

5. 作成された.airファイルをダブルクリック


ピクチャ 1.png


いろいろ試せば&以外でも起るかもね。

とりあえず、テキトーにぐぐっても情報出てこなかったから、日本語でこのバグの情報が出回るのこれが初めてかもね。


taiga.jpによると、Adobeにバグを報告するとTシャツが貰えるらしいので報告しとこうかな。

四面体は全部の頂点をつなげばおkなのですっごい楽なんだけど、


やっぱポリゴン表示したいよね!!



3Dでポリゴンと言えば、



ユタ・ティーポッド!!!

ポケモンのポリゴンじゃないよ!!!



ユタ・ティーポッドとか有名過ぎて、

DirectXだとMesh.Teapot()で作れちゃうらしいよ!!
そのうちTetris()っていうメソッドでテトリスが生成できるようになるっていう噂だよ!!笑



なんか、3Dソフトだと、だいたい標準でついてるっぽいので、.objでexport〜♪



そしたら、fとかvとか数字がいっぱいなファイルをげっと


↓こんなの
v 0 0.00528 -0.07404
v -0.01215 0.00528 -0.073085
v -0.02362 0.00528 -0.07032
v -0.03428 0.00528 -0.065885
v -0.043975 0.00528 -0.05992
・
・
・
f 1461 1 379 1156
f 1460 1461 1156 1157
f 1459 1460 1157 1158
f 1458 1459 1158 1159
f 1457 1458 1159 1160
・
・
・


これが軽く見積もっても2836行くらい続いてた。

この数字を、どんだけ目を見開いてみても、どんな角度から見ても、

ティーポッド見えなかった(´・ω・`)



だから、グーグルに.obj フォーマットとかで尋ねてみたら、


GoogleのPageRankとかなんとかの計算によると、OBJファイルフォーマットっていうのが、一番オススメらしい



そこを見ると、


1つ目の点が
(x, y, z) = (0, 0.00528, -0.07404)で

2つ目の点が
(x, y, z) = (-0.01215, 0.00528, -0.073085)で



1つ目の面が
点1461と点1と点379で構成されてて、その法線ベクトルは1156だよってことらしい。
面は三角形じゃなくて、四角形っぽい。
点1461、点1、点379、点1156を頂点とする四角形だったよ!!




読み方が分かったところで、もう一度objファイルを見たけど、やっぱ数字にしか見えないから、

行列ちゃんを使って線にしてみたよ!!!





(要:FlashPlayer10)





やべぇwwww重すぎwww


今回はマウスとかで操作はつけてないよ。

べ、べつに手を抜いたわけじゃないからね!!!

仕方なかったんだよ・・・


お布団が呼んでたから、仕方なかったんだよ!!!!




数字を線に変えるのに使った呪文は、


for(i=0; i<lines.length; i++) {
	line = (lines[i] as String).split(/ /);
	// 点
	if(line[0] == "v") {
		points.push(new Vector3D(line[1]*1000, line[2]*1000, line[3]*1000, 1));
	}
	// 面
	else if(line[0] == "f") {
		faces.push(new Face(parseInt(line[1])-1, parseInt(line[2])-1, parseInt(line[3])-1, parseInt(line[4])-1));
	}
}

ぁ、作った.objの値が小さすぎて、顕微鏡使わないと見れそうになかったから、

テキトーに1000倍してみたよ!!



と、あと、Faceっていうのが、
class Face {
	
	public function Face(v1:int, v2:int, v3:int, n:int):void {
		this.v1 = v1;
		this.v2 = v2;
		this.v3 = v3;
		this.n = n;
	}
	
	// 頂点
	public var v1:int;
	public var v2:int;
	public var v3:int;
	// 法線ベクトル
	public var n:int;
}


あと、これを保存するリストだけど、VectorクラスがArrayクラスのシャア専用仕様らしいから、

Vector使ってみたよ!!!


宣言の仕方は、
private var points:Vector.<vector3d> = new Vector.<vector3d>();


これできっとArrayより3倍くらい速くなるんじゃないかな


あとは、[3D][Astro] 3Dの移動/回転を行列(Matrix3D)を使ってやるとかでやった、座標変換行列を掛けてやって、

面に従って、線を引いて行けば表示できるよ!!!


ぁ、for eachよりfor文の方が速いから怠けずにfor文で書くといいよ!!



あとは、右クリック -> ソースの表示とかで見てねー


UIComponent3Dは、変数をオーバライドして、親には渡さないようにしてるよ!!


せっかく自分で行列書いたんだから、デフォルトの計算されたら悔しいもんね!!!



そんな反抗期なクラスちゃんだよヾ(・ω・`)

一昨日の[3D][Astro] 3Dの移動/回転を行列(Matrix3D)を使ってやるで、HSliderのthumbDragイベントによって、updateDisplayListが実行されてるはずなのに表示が更新されてない(´・ω・`)

まじ意味わかんねーヾ(〃>_<;〃)ノ


って思ってたら、liveDraggingっていうプロパティがあるみたい


APIリファレンスによるとー



スライダのライブドラッグを有効にするかどうかを指定します。 false の場合は、value プロパティと values プロパティが設定され、ユーザーがスライダサムのドラッグを停止したときchange イベントが送出されます。 true の場合は、value プロパティと values プロパティが設定され、ユーザーがサムを移動しているときに change イベントが継続的に送出されます。



なんでこんなプロパティあるんだろうー(´・ε・`)

停止したとき = CHANGE、移動中 = thumbDragとかでいいのに。


でも、おかげで、これをtrueにしたら、描画が反映されました。


id:keiichic++


なんでこんなの知ってるんだろう?(゜_。)?(。_゜)?
Flash Player 10 (コードネーム Astro)でzパラメータやrotationX, rotationY, rotationZが追加されて、
LabelとかImageとかなら、めーーーっっっ  ちゃ簡単に3次元表示できるようになって、今更こんなことしても意味ないじゃん!!って思われがちだけど、そこはスルーしつつ、基礎を学ぼうってことで


今回は最初だからとりあえず表示するのが目標なので、ポリゴンとか遠近とか光源とかテクスチャとか・・・もはや、なにそれおいしいの???笑


id:nitoyonさんのてっく煮 ブログAS3.0 で 3D プログラミングを1から勉強するシリーズが参考になるよー。




まず、回転について、(構成は最初に数学的な説明で、あとでMatrix3Dクラスの使い方)


rotationZ = 30とかってやると、点(1, 0, 0)が、点(0, 1, 0)に移るわけだけど、なかで回転行列使ってるわけね。回転行列知らない人はグーグル先生に聞いてみるといいよ!!!
ぁ、ハチロク世代以前な人には残念なお知らせなんだけど、ゆとりっ子は、高校で習うよ!!数Cだよ!!!

↓みたいな式で、θだけ反時計回りに回転するよ!!!

matrix.png



で、今は、3次元について考えてるから、これの3次元バージョン

・X軸について回転
matrixX.png


・Y軸について回転
matrixY.png


・Z軸について回転
matrixZ.png



・使い方(X軸回転)

matrix2.png



んで、回転行列とかアフィン変換とか3Dとかでググると、↓こんなの出てくる時もあるけど、
matrix3.png

これは、座標系が左手系で、行優先のベクトルを使ってるからで、
DirectXがこの左手系らしく、ぐぐるといっぱいでてくる。

ゆとりでも知ってるように、行列の乗算は交換法則が成り立たないからA*BとB*Aはまったくばつものだよ!!

OpenGLとかASのMatrix3Dクラスは列優先っぽいので、DirectXとか爆発すればいいお^^




んで、行列を使うメリットは、これってこれをまとめれること。

てっく煮でも説明があるけど、

ある点Pを回転させる時に、PをまずX軸で回転して、次にY軸で回転して・・・ってやると、
回転させる点が1つとかだと別にいいんだけど、ポリゴンはフツーいっぱい点をもってて、
  ポリゴンを回転させる = すべての点を回転させる
だから、めっちゃ計算大変なのね。

もうCPUが暖房器具になれるよ!!


行列は、交換法則は成り立たないけど、結合法則は成り立つ!!
だから、先にX軸回転とY軸回転とZ軸回転の行列を掛けておいて、
その結果1つを、各頂点に書ければとってもえころじー

たぶん文字でみてもわかんないから、下に書くASのソースみると分かりやすいかも



んで、今まで全力でスルーしてきたけど、

3次元をやってるのに行列は4*4になってる!!!


4*4にしたのは、回転に加えて平行移動も一緒にやっちゃうから
x軸方向にtx、y軸方向にty、z軸方向にtz平行移動させる時に、
for each(point in polygon) {
  p.x += tx;
  p.y += ty;
  p.z += tz;
}
なんてやらなくても、今までのように、

matrix4.png

ってやればok


んで、そろそろ数学飽きてきたからこれをActionScriptに翻訳するよ!!




まず、Matrix3Dクラスは、引数なしでnewすると4*4の単位行列が生成されます。

んで、行列の掛け算ってめっちゃめんどいんだけど、メソッドが用意されているので使うんだけど、

行列は、A*BとB*Aが違うから、自分より前に掛けるか後ろに掛けるかで2種類用意されてます。

それが、append〜系とprepend〜系のメソッド。

A.append(B)の場合、B*A
A.prepend(B)の場合、A*B

となるらしいです。


んで、回転させるのに、↑のsinとかcosとかめんどくさいよー><って思ってたら
めっちゃ簡単だったww

あるMatrix3DのインスタンスにX軸回転の回転行列を掛けるとき、
Matrix3D#appendRotate(rotateX, Vector3D.X_AXIS)とかやると、行列にrotateX度回転する機能を付与してくれるよ!!
んで、実際の点を移動させるのは、Matrix3D#transformVector(Vector3D):void!!

残りは、説明しないけど、空気を読めばわかるはず!!



んで、上で説明した。行列だと計算回数が減ってhappyっていう話は、


ってやると、for文の中がいっぱい処理があって大変だけど、

って言う風に、最初に座標変換行列を用意しておいて、それを掛けるだけにするととっても楽ですよ。みたいな


んで、動くもの。(FlashPlayer10が必要)




3Dを2Dに変換するとこの投影変換は、並行投影を使うということで、Z座標を無視して表示しただけwww


ってか、HSliderをドラッグした時にすぐに描画されないのはなぜ??updateDisplayListは走ってるはずなんだけどなぁー
ソースは右クリックで


11/17 追記
HSliderのlivedraggingプロパティをtrueにしたら反映されるようになりました。
3Dグラフィックスとかで、テクスチャを貼ったりする時とかに使われる、スーパーサンプリングについて

Wikipediaのアンチエイリアスの項によると、

スーパーサンプリング
表示する画像解像度より高解像度に描画しておき、描画終了時に高解像度画像を表示解像度に変換してから表示する

とのこと。

百聞は一見に如かずってことで動くもの↓




サンプリングの方法はめっちゃ簡単で、
1x1.png 1*1でかいオリジナルテクスチャの対応するエリアの、真ん中の色を取る方法。
1x2.png 1*2対応するエリアの、真ん中の上から25%, 75%に位置する色の平均を取る方法。
2x2.png2*2Grid対応するエリアの、4分割した時の各真ん中の色の平均を取る方法。
2x2RGSS.png 2*2RGSS対応するエリアの、16分割した時の図の位置の色を取の平均る方法。
4x4Grid.png 4*4Grid対応するエリアの、16分割した時の真ん中の色を取の平均る方法。



他にもいっぱいあるけど、めんどくさいからこのくらいでー



ハチロク世代のtopcoder部で、カレーを食べてtopcoderをやる会に参加しました。

詳しくは、id:suztmoたんのブログでー


んで、その時に、id:nishiohirokazuたんが、「みんなのグラフ並べて比べれるといいよねー」みたいなことを言っていたので、


作ってみましたー。





あれ?下から数えて2番目だ涙

このアーカイブについて

このページには、2008年11月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2008年10月です。

次のアーカイブは2008年12月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

Powered by Movable Type 5.0