<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>MOROCOSHI:BLOG</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/" />
    <link rel="self" type="application/atom+xml" href="http://www.morocoshi.net/blog/atom.xml" />
    <id>tag:www.morocoshi.net,2009-09-01:/blog//3</id>
    <updated>2011-10-30T00:00:00Z</updated>
    <subtitle>フリーダムに生きてゆきます</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.261</generator>

<entry>
    <title>A3D8.17.0でパーティクルの実験</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2011/10/a3d8170.html" />
    <id>tag:www.morocoshi.net,2011:/blog//3.47</id>

    <published>2011-10-30T00:00:00Z</published>
    <updated>2011-10-30T00:00:00Z</updated>

    <summary> Flashはアルファを含んだ画像やシェイプを重ねすぎると表示がおかしくなったり...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[<a href="http://www.morocoshi.net/blog/material/swf/particles/particles.swf" onclick="javascript:openswf(this.href, 600, 500, '11.0'); return false;" target="_blank" class="openswf">
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="barusan.jpg" src="http://www.morocoshi.net/blog/material/img/barusan.jpg" class="mt-image-none" style="" height="305" width="400" /></span></a>
<br />Flashはアルファを含んだ画像やシェイプを重ねすぎると表示がおかしくなったり極端に重くなったりするので、拡大縮小回転しつつたくさん重ねる場合は処理の重いBitmapData.draw()を使うしかなかったんですが、FP11のStage3Dではそんな心配もいらないみたいです。<br /><br />上のデモは透過画像を重ねまくる事になる煙パーティクルの負荷テストです。例によって3Dライブラリを作れるスキルはないので、Alternativa3Dにお世話になりました。煙画像のSprite3Dをぶわーって吐きだしてるだけです。<br />自分の環境ではパーティクル数1300でギリギリ60fpsくらい。もっと表示できると思ってたんだけど、これはSprite3Dに割り当てた透過画像が重いって事なのかな。それでも以前は100個くらいが限界だったので大分軽くなってると思うけど。<br /><br /><h3>完全に忘れてた</h3>そういえば以前PV3Dで某エースコンバット的なものを作ろうとしてて・・・というかほぼできてたんだけど、これは雲とか3DモデルのほとんどをBitmapData.draw()で描画してました。雲の塊用ビューポートを空にたくさん浮かべて、カメラからの距離で雲の解像度とレンダリング頻度を調節したりと結構めんどい処理をしていたわりに速度が出なくて悲しかった。。。これA3D8で作り直したいな。<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="flight002.jpg" src="http://www.morocoshi.net/blog/material/img/flight002.jpg" class="mt-image-none" style="" height="343" width="400" /></span><br /><br /><div><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="flight001.jpg" src="http://www.morocoshi.net/blog/material/img/flight001.jpg" class="mt-image-none" style="" height="320" width="400" /></span></div><div><br /></div>]]>
        <![CDATA[<br />]]>
    </content>
</entry>

<entry>
    <title>A3D7.7: COLLADAからユーザー定義プロパティを取り出す</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2011/04/userdataparser.html" />
    <id>tag:www.morocoshi.net,2011:/blog//3.45</id>

    <published>2011-04-16T00:00:00Z</published>
    <updated>2011-10-11T00:00:00Z</updated>

    <summary>OpenCOLLADAで書き出すCOLLADAファイルにはオブジェクトごとに設定...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[OpenCOLLADAで書き出すCOLLADAファイルにはオブジェクトごとに設定したユーザー定義プロパティを含める事ができます。<br /><br />ユーザー定義プロパティっていうのは、モデリングソフト等で↓こんな感じにオブジェクトごとに自由に設定できるデータで、自分はA3D+Jiglibでコリジョン設定をする際に剛体のパラメータに使おうかなって思ってました。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="userdefwin.png" src="http://www.morocoshi.net/blog/material/img/userdefwin.png" class="mt-image-none" style="" width="417" height="187" /></span><br /><br />※書き出し時に赤枠の所にチェックを入れるとユーザー定義データが含められる<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="userprop.png" src="http://www.morocoshi.net/blog/material/img/userprop.png" class="mt-image-none" style="" width="423" height="287" /></span><br /><br />ただ、Alternativa3D7.7がユーザー定義データをパースしてくれているかがちょっとわからなくて。Object3Dにそれっぽいパラメータが見当たらなかったから多分パースしてないのかな？<br /><br />よくわからないので、ユーザー定義プロパティだけをパースするクラスを作ってみました。<br /><br />]]>
        <![CDATA[<h3>色々と自信のないソース</h3>
<pre class="brush: as3;">package {
	
	import alternativa.engine3d.core.Object3D;
	import flash.utils.Dictionary;
	
	/**
	 * OpenCOLLADAで書き出したデータからユーザー定義プロパティをパースする
	 */
	public class UserDataParser {
		
		private var _data:Dictionary = new Dictionary();
		
		public function UserDataParser() {
		}
		
		/**
		 * ユーザー定義プロパティをパース
		 * @param	xml	COLLADAデータ
		 * @param	objects	ParserColladaでパースしたObject3Dの配列
		 */
		public function parse(xml:XML, objects:Vector.&lt;Object3D&gt;):void {
			var ns:Namespace = xml.namespace();
			var users:Array = [];
			for each(var item:XML in xml..ns::library_visual_scenes.ns::visual_scene.ns::node) {
				var user:Object = { };
				users.push(user);
				var userProp:String = item..ns::technique.(@profile == "OpenCOLLADA").ns::user_properties;
				if (!userProp) continue;
				var params:Array = userProp.replace(/\r\n|\n/g, "\r").split("\r");
				for each(var p:String in params) {
					var match:Array = p.match(/^(.*)=(.*)$/);
					if (!match) continue;
					var atr:String = trim(match[1]);
					if (!atr) continue;
					user[atr] = scanValue(match[2]);
				}
			}
			for (var i:int = 0; i &lt; objects.length; i++) {
				_data[objects[i]] = users[i];
			}
		}
		
		/**
		 * 文字列をNumber,String,Array,Booleanに変換する
		 * @param	str
		 * @return
		 */
		public function scanValue(str:String):* {
			str = trim(str);
			if (!str) return null;
			var s0:String = str.substr(0, 1);
			var s1:String = str.substr(-1, 1);
			
			var value:*;
			if ((s0 == '"' &amp;&amp; s1 == '"') || (s0 == "'" &amp;&amp; s1 == "'")) {
				value = str.substr(1, str.length-2);
			} else if (str == "true" || str == "false") {
				value = str == "true";
			} else if (s0 == '[' &amp;&amp; s1 == ']') {
				value = scanArray(str.substr(1, str.length - 2));
			} else {
				value = Number(str);
			}
			
			return value;
		}
		
		private function scanArray(str:String):Array {
			var values:Array = [];
			str = trim(str);
			if (!str) return values;
			
			var buffer:String = "";
			var qt:String = "";
			var cnt:int = 0;
			var isString:Boolean = false;
			var strings:Array = str.split("");
			for each(var s:String in strings) {
				if (!isString &amp;&amp; s == "," &amp;&amp; !cnt) {
					values.push(scanValue(buffer));
					buffer = "";
				} else {
					if (!isString &amp;&amp; (s == '"' || s == "'")) {
						isString = true;
						qt = s;
					} else if (isString &amp;&amp; s == qt) {
						isString = false;
					}
					if (!isString) {
						if (s == "[") cnt++;
						if (s == "]") cnt--;
					}
					buffer += s;
				}
			}
			values.push(scanValue(buffer));
			
			return values;
		}
		
		private function trim(str:String):String {
			return str.replace(/^\s+|\s+$/g, "");
		}
		
		/**
		 * ユーザー定義プロパティを取得
		 * @param	obj
		 * @return
		 */
		public function getData(obj:Object3D):Object {
			return _data[obj];
		}
		
	}

}</pre>

<br />このパーサはXMLからユーザー定義プロパティだけをパースするだけなので、COLLADAモデルは別にParserColladaでパースしておく必要があります。<br /><br /><em>（2011/4/30追記）親子関係のリンクがあった時の処理を組んでいなかったので、子以下のオブジェクトのプロパティが取れないかもしれません。</em><br /><br /><h3>使い方</h3>
<pre class="brush: as3;">//COLLADAデータ
var xml:XML = &lt;COLLADA&gt;～&lt;/COLLADA&gt;;

//COLLADAをパース
var parser:ParserCollada = new ParserCollada();
parser.parse(xml);

//XMLとParserCollada.objectsを渡してユーザー定義プロパティをパース
var user:UserDataParser = new UserDataParser();
user.parse(xml, parser.objects);

//名前がmojaのオブジェクトを取得
var moja:Object3D = parser.getObjectByName("moja");

//mojaのユーザー定義データを取得
var data:Object = user.getData(moja);

//mojaにtype="hoge"ってユーザー定義データがある場合、hogeがトレースされる
trace(data.type);
</pre><h3>

モデリングソフトで設定するユーザー定義プロパティの書式</h3>(例)<br /><blockquote>hoge = "moja"<br />foo=123.4<br />test = [3, "@", -0.5, ["xxx","yyy"], false]<br />flag=true<br /></blockquote><br /><ul><li>変数=値（セミコロンはつけない）</li><li>イコール前後や配列内のスペースはあってもなくてもいい<br /></li><li>値が数値、文字列、配列、ブーリアンならパースできる</li><li>配列は入れ子になっていても大丈夫</li><li>「"」か「'」で囲うと文字列になる</li></ul><br />]]>
    </content>
</entry>

<entry>
    <title>3dsMaxで書き出したCOLLADAをAlternativa3D7.7でうまくパースできない場合</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2011/04/alternativa3dcollada.html" />
    <id>tag:www.morocoshi.net,2011:/blog//3.44</id>

    <published>2011-04-11T00:00:00Z</published>
    <updated>2011-10-11T00:00:00Z</updated>

    <summary> 3dsMaxでモデリングしたものをOpenCOLLADAで書き出して、A3D7...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="3dsMax" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[ 3dsMaxでモデリングしたものを<a target="_blank" href="http://www.opencollada.org/download.html">OpenCOLLADA</a>で書き出して、A3D7.7のCOLLADAパーサで表示すると、時々モデルの大きさや位置がおかしくなっている事があります。<br /><br />最初はOpenCOLLADA側のバグかなと思っていたんですが、書き出したDAEファイルをPV3Dでは問題なく表示できていたので、A3DのCOLLADAパーサ側の不具合かもしれません。（PV3DのCOLLADAパーサにも一部不具合があるようだけど）<br /><br />モデルのパースがうまくいかない原因ははっきりしていないんですが、なんとなくスケールや回転を何度か弄ったり、基点を動かしたりするとうまくいかない気がします。<br /><br /><h3>とりあえずの対処法</h3>うまくパースできなかったモデルの基点をリセットしてみる<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="parseerror1.png" src="http://www.morocoshi.net/blog/material/img/parseerror1.png" class="mt-image-none" style="" height="373" width="177" /></span><br /><br /><h3>それでも駄目だった場合もしくは基点をリセットしたくない場合<br /></h3><br /><ol><li>適当なオブジェクト（以下 T）を作る。Boxとか。</li><li>Tを編集可能ポリゴンに変換</li><li>Tを位置合わせ機能でうまくパース出来ないモデル（以下A）と同じ位置にする</li><li>必要なら回転も合わせる</li><li>TにAをアタッチする（AがTの一部になる感じ）</li><li>Tだけを選択して削除</li></ol>これでだいたいうまくいくはず・・・たぶん。編集可能ポリゴンにアタッチするのでAがモディファイヤを色々適用してた場合は全部統合されちゃうけどね。<br />]]>
        
    </content>
</entry>

<entry>
    <title>3dsMaxでのOpenCOLLADA+A3D書き出し時のエラーの原因</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2011/04/colladaerror.html" />
    <id>tag:www.morocoshi.net,2011:/blog//3.43</id>

    <published>2011-04-11T00:00:00Z</published>
    <updated>2011-04-15T00:00:00Z</updated>

    <summary> 最近は3dsMax2010で作ったモデルをA3DプラグインでCOLLADA書き...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="3dsMax" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[ 最近は3dsMax2010で作ったモデルをA3DプラグインでCOLLADA書き出しする事が多いんですが、書き出し時にエラーが出てMaxが落ちてしまう事が時々あって困っていました。<br /><br />色々と調べていくつか原因が特定できたので書いておきます。<br />※あくまで自分の環境で発生したものです。<br /><br /><ul><li>同じシェルマテリアルを複数のオブジェクトに貼っているとエラー</li><li>デイライトでサンライトをmr Sunに設定したものをシーンに配置しているとエラー<br /></li></ul><br />シェルマテリアルは<a href="http://www.morocoshi.net/blog/2011/04/a3dwt3.html" target="_self">レンダーベイキングの記事</a>で説明したマテリアルです。シェルマテリアルを複数モデルで共有する事ってあまりなさそうですが、モデルの一部をデタッチしてわけたりすると2つのモデルに貼っている事になってしまうかもしれません。一応これはシェルマテリアルを複製して貼り直す事で解決できます。<br /><br />デイライトの方は非表示にしたりして書き出し対象になっていなくてもエラーが出てしまうので、サンライトパラメータでmr Sunを選ばないようにするか、書き出す時に一時的にシーンから削除するしかないのかな？他にいい方法が見つかったら追記します。]]>
        
    </content>
</entry>

<entry>
    <title>Alternativa3Dでウォークスルー #3 レンダーベイキング</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2011/04/a3dwt3.html" />
    <id>tag:www.morocoshi.net,2011:/blog//3.40</id>

    <published>2011-04-10T00:00:00Z</published>
    <updated>2011-04-15T00:00:00Z</updated>

    <summary>前回はキャラクタ用コリジョンを作って部屋の中を歩き回るデモを作りました。その部屋...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[<a target="_self" href="http://www.morocoshi.net/blog/2011/04/a3dwt2.html">前回</a>はキャラクタ用コリジョンを作って部屋の中を歩き回るデモを作りました。その部屋の中の見た目がやわらかい感じになっていますが、あれはモデリングソフトでオブジェクトに落ちる影や光をテクスチャに焼きつけているからです。一般的にはレンダーベイキングって言うのかな。今回は3dsMax2010を使って前回のシーンのようなテクスチャに影をベイクしたものを書き出すまでの手順を書いておきます。丁度今作っているモデルがあるので説明にはそれを使って行きます。<br /><br /><h3>使った物</h3>モデリングソフトには3dsMax2010を使いました。<a target="_blank" href="http://alternativaplatform.com/en/alternativa3d/">Alternativa3D(A3D)の3dsMax用プラグイン</a>が出ているのでCOLLADAの書き出しにはそれを使います。このプラグインを入れると、A3D専用オブジェクト（Sprite3DとLOD）が生成できるようになって、オブジェクトごとにA3D用プロパティ（ソート形式や透明度等）を設定してDAEファイルにそれらを含めて書き出せるようになります。<br /><br />]]>
        <![CDATA[<h3>1. モデルを用意する</h3>まずは3dsMaxで適当にモデリング、ライティングします。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="maxmodeling.jpg" src="http://www.morocoshi.net/blog/material/img/maxmodeling.jpg" class="mt-image-none" style="" height="294" width="400" /></span><br /><br />一番重要なテクスチャまで適当になっちゃいましたが・・・。引き出しの取っ手の部分はA3Dプラグインによって作れるようになったSprite3Dオブジェクトです。これは常にカメラの方を向いてくれるPlaneのようなもので、Maxのビューポート上でも機能してくれます。<br /><br /><h3>2. レンダリングして確認</h3>実際どんな感じの見た目になるか、レンダリングして確認します。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="maxrendering.jpg" src="http://www.morocoshi.net/blog/material/img/maxrendering.jpg" class="mt-image-none" style="" height="283" width="400" /></span><br /><br />レンダラーにはmental rayを使いました。ファイナルギャザー(FG)とグローバルイルミネーション(GI)を有効にしたので影がいい感じになってます。FGもGIもパラメータが多すぎてややこしいよ。取っ手部分はA3D用のSprite3Dにしているせいかレンダリングでは表示されないようです。花瓶の影が落ちていないのは後で説明します。<br /><br />ただ、このままCOLLADAに書き出しても当然A3Dでは影は表示されないのでのっぺりとした見た目になってしまいます。そこで3dsMaxの「テクスチャレンダリング」機能を使って、光や影をテクスチャにベイクしてA3D上でもレンダリング結果に近い見た目にしていきます。<br /><br /><h3>3. UVWを設定する</h3>テクスチャレンダリングは全オブジェクトに設定したいんですが、まずは椅子のモデルだけにテクスチャレンダリングする手順を書いていきます。<br /><br />テクスチャレンダリングをさせるには、そのモデルにテクスチャ座標が設定されている必要があるので、ベイクしたいオブジェクトに「UVW アンラップ」モディファイヤを適用しておきます。<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="modeledit.jpg" src="http://www.morocoshi.net/blog/material/img/modeledit.jpg" class="mt-image-none" style="" height="233" width="177" /></span><br /><br />適用したらUVWアンラップのサブオブジェクトレベルを面にして全選択し、「編集」を押して「UVWを編集」ウィンドウを開きます。そして[マッピング]→[フラッテンマッピング]を実行します。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="uvwedit.jpg" src="http://www.morocoshi.net/blog/material/img/uvwedit.jpg" class="mt-image-none" style="" height="549" width="454" /></span><br /><br />うまくいけば上のような感じになります。テクスチャをベイクする際に気を付ける事は、生成したテクスチャ座標の複数の面が重なっているとベイク結果がおかしくなってしまうので、上のように全ての面が重なっていない状態にする必要があります。例えばキューブの6面全てが同じイメージだからといって6面全てを重ねてしまうとまずい事になります。<br /><br /><h3>4. テクスチャレンダリング</h3>UVWの設定ができたら、[レンダリング]→[テクスチャ レンダリング]でウィンドウを開きます。<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="texturerender1.png" src="http://www.morocoshi.net/blog/material/img/texturerender1.png" class="mt-image-none" style="" height="720" width="366" /></span><br /><br /><ol><li>テクスチャレンダリングによって生成される新しいベイク画像の保存先の基本パスをここで設定できる。必須ではないが設定しておくとベイクするオブジェクトが多い時に楽になる。</li><li>ビューポートで選択されているオブジェクトがここに表示される。選択したオブジェクトにベイクしたいのでビューポートで椅子を選択しておく。</li><li>ベイク画像を生成する際に使うマッピング座標。UVWアンラップを設定しているのでここでは「既存チャンネルを使用」を選ぶ。</li><li>今回は選択した椅子だけにベイクの設定をしたいので「選択オブジェクト」を選ぶ。</li></ol><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="texturerender2.png" src="http://www.morocoshi.net/blog/material/img/texturerender2.png" class="mt-image-none" style="" height="844" width="366" /></span><br /><br /><ol start="5"><li>最初はこのボタンの上のリストに何もないはずなので、「追加」を押してウィンドウを開いて</li><li>CompleteMapを選んで「要素を追加」する。</li><li>ここで保存するベイク画像のファイル名と種類を決めておく。1のフォルダと同じならファイル名だけでいいし、フルパスにすれば違う場所にも保存できる。</li><li>ベイク後に生成した画像をマテリアルのどこに適用するか。見た目のイメージを変更したいので「拡散反射光カラー」を選ぶ。</li><li>ベイク画像の大きさを設定。</li><li>「シェルを新規作成～」を選び、「新規ベイクを作成」で「標準:(B)ブリン」を選ぶ。これでベイク後にシェルマテリアルが設定される。</li><li>後は「レンダリング」を押してベイク画像が生成されるのを待つ。<br /></li></ol><br />これが完成したベイク画像。ちょっとわかりにくいけど、影が焼きこまれて単色ではなくなっています。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="bakedimage.jpg" src="http://www.morocoshi.net/blog/material/img/bakedimage.jpg" class="mt-image-none" style="" height="261" width="253" /></span><br /><br />これでテクスチャレンダリングの作業は終わりです。<br /><br /><h3>5. シェルマテリアル</h3>テクスチャレンダリングが終わった後、椅子のマテリアルをスポイトで取ってみるとシェルマテリアルが適用されている事がわかります。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="shellmaterial.jpg" src="http://www.morocoshi.net/blog/material/img/shellmaterial.jpg" class="mt-image-none" style="" height="511" width="598" /></span><br /><br />これは「テクスチャのレンダリング」ウィンドウの10で自動設定されたもので、ビューポート上に表示されるマテリアルとレンダリングに使われるマテリアルを切り替える事ができるマテリアルです。上の図の場合は、レンダリング時には元々貼ってあった「wood ( Arch &amp; Design (mi) )」が使われて、ビューポート上の表示にはベイク済みの「baked_wood ( Standard )」が使われます。COLLADA書き出しをするとビューポート上の設定がそのまま使われるようで、このまま書き出せばベイクされたテクスチャが使われる事になります。<br /><br />ここで椅子のテクスチャをベイク済みのものにするだけならベイク済みテクスチャを直接椅子に貼ってしまえばいいのですが、その状態で再度テクスチャレンダリングを実行すると、ベイク画像の上に更に新しい影がベイクされてしまいどんどん影が濃くなってしまいます。後でシーンのライティングやオブジェクトの位置を変更する可能性のある場合はシェルマテリアルを使っておいた方が安全かもしれません。<br /><br />後は、椅子以外の全てのオブジェクトにもテクスチャレンダリングの作業をしていきます。<br /><br /><h3>6. COLLADA書き出し</h3>ベイク作業が終わったら、「OpenCOLLADA + A3D」で書き出します。DAEが3つもあって間違えそう・・・<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="exportdae.png" src="http://www.morocoshi.net/blog/material/img/exportdae.png" class="mt-image-none" style="" height="143" width="393" /></span><br /><br />書き出しオプションはOpenCOLLADAと同じっぽいです。<br /><div><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="opencollada.png" src="http://www.morocoshi.net/blog/material/img/opencollada.png" class="mt-image-none" style="" height="287" width="423" /></span><br /><br />※<a href="http://www.morocoshi.net/blog/2011/04/colladaerror.html">書き出し時にエラーが出る場合</a><br /><br /><h3>7. A3DでCOLLADAを読み込み</h3>実際にA3Dに読み込むとこんな感じです。（動かせるデモは部屋全体ができてからにします）<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="a3drender.jpg" src="http://www.morocoshi.net/blog/material/img/a3drender.jpg" class="mt-image-none" style="" height="302" width="400" /></span><br /></div><div><br />テクスチャレンダリングによってオブジェクトの影がテクスチャに直接焼きこまれてしまうので、オブジェクトの位置を移動させたりすると当然おかしな事になってしまいます。なのでA3D上で動かす予定のモデルはしかたなく影を落とさない設定にしました。花瓶の影が落ちていないのはそのせいです。影がないせいでちょっと浮いた感じになってますが・・・。それと引き出しは開閉させたかったので、<br /><br /><ul><li>引き出しのテクスチャは自分だけ開けた状態でベイク</li><li>床のテクスチャは引き出しを全部閉めた状態でベイク</li></ul>としています。引き出し部分はなんとかこれで誤魔化せたけど、ものによってはどうしてもおかしくなってしまうし、テクスチャレンダリングは使いどころが難しいね。<br /></div>]]>
    </content>
</entry>

<entry>
    <title>Alternativa3Dでウォークスルー #2 キャラクタ用コリジョン</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2011/04/a3dwt2.html" />
    <id>tag:www.morocoshi.net,2011:/blog//3.38</id>

    <published>2011-04-07T00:00:00Z</published>
    <updated>2011-10-11T00:00:00Z</updated>

    <summary>前回Alternativa3D(A3D7.7)でJiglibFlashを使えると...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[<a target="_self" href="http://www.morocoshi.net/blog/2011/04/a3dwt1.html">前回</a>Alternativa3D(A3D7.7)でJiglibFlashを使えるところまで行ったので、今回はキャラクタ用コリジョンを作ってみます。<br /><br />最初に考えていたのは、回転しないようにした縦長のカプセルコリジョンを作って歩く方向に力を加えていくものだったんですが、実際やってみると設定が悪いせいか動くカプセルの衝突判定がなんだかおかしい。他のボックス・球・カプセルとぶつかった時にピクピクしたり簡単にすり抜けたり。設定で何とかならないか色々試してみたもののなかなか改善できなかったので、結局動くカプセルはなるべく使わないようにする事にしました。カプセル以外のコリジョンが動かないカプセルにぶつかったときは問題なかったんだけどね。<br /><br />色々と試行錯誤しつつ決めたキャラクタの処理<br /><br /><ul><li>回転しない球体コリジョンを用意する。</li><li>必要ならキャラクタのメッシュと連携させる。一人称視点ならコリジョンだけで。</li><li>キー入力で前後左右に移動。ジャンプもできるようにする。</li><li>必要ならマウスドラッグで視点を動かす。</li><li>キャラクタの視線ベクトルと垂直ベクトルの外積で水平横方向のベクトルを作り、そこから水平前方向のベクトルも作って前後左右の移動処理に使う。</li><li>視線が真上か真下を向いていると上記の計算ができなくなるので角度は制限する。</li><li>自分のコリジョンが周囲のコリジョンとぶつかっているか、どの角度で触れているかをチェックして、ジャンプできるか判定する。（空中や絶壁でのジャンプをさせないため）</li><li>摩擦があると壁に接触した状態でのジャンプが難しいため0にする。その代わり毎フレーム水平方向のみ移動量を減退させて摩擦っぽくさせる。</li><li>摩擦を0にした事でちょっとした坂もずるずる滑ってしまう為、足元がゆるい傾斜+接地中のみ無重力にして滑らないようにする。</li></ul><br /><br />]]>
        <![CDATA[<h3>つくってみた</h3>移動　　：WSAD か 矢印キー<br />ジャンプ：SPACE<br />視点移動：マウスドラッグ<br /><br />

<a href="http://www.morocoshi.net/blog/material/swf/jiglibtest2/JiglibTest2.swf" onclick="javascript:openswf(this.href, 550, 400, 10.1); return false;" target="_blank" class="openswf"><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="jiglibtest2.jpg" src="http://www.morocoshi.net/blog/material/img/jiglibtest2.jpg" class="mt-image-none" style="" height="293" width="400" /></span></a><br /><a target="_blank" href="http://www.morocoshi.net/blog/material/as/JiglibTest2.zip">ソース</a><b>（2011/4/13修正）</b><br /><br />net.morocoshi.jiglib.a3d.A3dWalker.asを作って上にリストアップした処理をまとめたクラスにしました。ソースにはそれ以外の細々したクラスも入ってるけど。<br /><br />一人称視点でカメラの向き＝キャラクタの向きになってます。なんとなくそれっぽく動けてはいるんですが、接地中は無重力にしているせいかゆるい坂を少し上ってすぐ止まると勢いで一瞬浮き上がった感じになります。あと、どうしても動くオブジェクトがいろんな所にめり込んでしまって、最悪埋まったままになることも。。。でもこれはしかたないのかな。長時間めり込んでいたら位置をリセットするような処理が組めればなんとかなりそうだけど。<br /><br /><h3>JiglibFlashでわかった事色々</h3><ul><li>動くオブジェクトで回転だけさせたくない場合はRigidBody.maxRotVelocities = 0<br /></li><li>オブジェクトを動かすにはRigidBody.addWorldForce(力ベクトル,加える位置)</li><li>addWorldForceの第二引数の座標は、RigidBodyと同じ座標にすればスピンしない</li><li>オブジェクトの現在位置はRigidBody.currentState.positionで取れる</li><li>オブジェクトに力を加えて動く距離は、シミュレーション速度に影響されるっぽい</li><li>なので毎回同じ高さにジャンプさせたい場合はAbstractPhysics.step()ではなくAbstractPhysics.engine.integrate(～)を使った方がいい？</li><li>特定のRigidBodyだけ無重力にするには毎フレーム重力ベクトルを－RigidBody.mass倍したものを加えればいい</li><li>現在の重力ベクトルはPhysicsSystem.getInstance().gravityでどこからでも取得できる</li><li>オブジェクトの減速はRigidBody.currentState.linVelocityを弄ればいい<br /></li></ul><br /><h3>コリジョン用モデル</h3>今回のステージは単純な形状ではあるけど、それでも複数のコリジョンを組み合わせる必要があったので、見た目のモデルとコリジョン用のモデルを分けている部分があります。<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="jiglibmesh.jpg" src="http://www.morocoshi.net/blog/material/img/jiglibmesh.jpg" class="mt-image-none" style="" height="338" width="400" /></span><br /><a href="http://www.morocoshi.net/blog/material/swf/jiglibtest2/JiglibTest2.swf" onclick="javascript:openswf(this.href, 550, 400, 10.1); return false;" target="_blank" class="openswf"></a><div>こっちが表示用メッシュで<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="jiglibcollisionmesh.jpg" src="http://www.morocoshi.net/blog/material/img/jiglibcollisionmesh.jpg" class="mt-image-none" style="" height="339" width="400" /></span><br /></div><div>こっちがコリジョン用のメッシュ。<br /><br />これを同じファイルでレイヤを分けて管理しています。いくつか見た目とコリジョンが一致しているものがあって、ボールとか上下するリフトとかは表示用メッシュのをそのままコリジョンにしてます。<br /><br /><h3>オブジェクトごとのプロパティ</h3>どれがどんな形状のコリジョンだとか、動くオブジェクトなのか固定オブジェクトなのか、他にも色々とオブジェクトごとにパラメータを持たせたいのに、今のところオブジェクトの名前につけた記号だけで管理している状態でそろそろ厳しくなってきました。名前はA3Dで参照を取得するのにも使うので極力余計なものはつけたくないし。<br /><br />一応OpenCOLLADAではオブジェクトごとに設定したユーザー定義プロパティも書き出せるようになっているのでそれを利用したいんですが、A3D側でそのプロパティを取得する方法がちょっと分からなくて。もしA3DのCOLLADAパーサがパースしていないようだったら、ユーザー定義プロパティを抜き出す為だけのパーサを自作する必要があるのかな。仮にパースできるようになったとしても、3dsMax上でモデルごとにユーザー定義プロパティを設定したり確認するのが結構面倒なので、パラメータを簡易設定できるMaxスクリプトも作りたいし。色々大変そうだ・・・。<br /><br /></div>]]>
    </content>
</entry>

<entry>
    <title>Alternativa3Dでウォークスルー #1 JiglibFlash</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2011/04/a3dwt1.html" />
    <id>tag:www.morocoshi.net,2011:/blog//3.37</id>

    <published>2011-04-06T00:00:00Z</published>
    <updated>2011-10-11T00:00:00Z</updated>

    <summary> Alternativa3D(A3D7.7)でウォークスルーしてみようと思います...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[ <a target="_blank" href="http://alternativaplatform.com/en/">Alternativa3D</a>(A3D7.7)でウォークスルーしてみようと思います。3Dな地形の中をキャラクターが歩き回るあれです。<br /><br />昔PV3Dで作ろうとしていて記事もいくつか書いてたんですが、当たり判定難しいとか、PV3Dのポリゴンソート的に厳しいとかで、1年以上放置してました・・・。今回は当たり判定に物理エンジンライブラリを使ってみる事にします。<br /><br />ここ最近は出来あがった作品をwonderflに投稿するだけだったので、久しぶりに制作過程をメモしていこうと思います。ただ、Alternativa3Dの基本的な使い方までは解説しないので、そっちを知りたい方はnarutohyperさんのサイトが詳しいのでそちらをお勧めします。<br /><a target="_blank" href="http://marubayashi.net/alternativa3d7/index.html">東京てらこ がっつり３D スライド資料 | Alternativa3D7 | 丸林商店</a><br /><br />これから作っていくもののソースコードですが、ちょっとしたサンプルは公開できるかもしれないけど、作りこんでくると公開が難しくなるので、あまり期待しない方がいいかも。<br />]]>
        <![CDATA[<h3>JiglibFlash</h3>ウォークスルーさせるには地形とキャラクターとの当たり判定を計算する必要があって、今回は<a target="_blank" href="http://www.jiglibflash.com/blog/">JiglibFlash</a>を利用しようと思います。JiglibFlashの存在は前から知っていたんですが、実際使った事はなかったので色々調べてみました。<br /><br />JiglibFlashについて<br /><br /><ul><li>AS3用の3D物理エンジンライブラリ</li><li>Jiglib本体は位置とか回転とかの見えないデータをもじゃもじゃしてる</li><li>Jiglibが計算したデータを3Dメッシュモデルに適用する必要がある<br />
</li><li>いくつかプラグインが用意されていて、PV3Dとかのモデルには簡単に適用できる<br />
</li><li>A3D用のプラグインは今のところ同封されていない</li></ul>JiglibFlashで扱えるコリジョン（※確認できたもの）<br /><br /><ul><li>直方体（JBox）</li><li>球（JSphere）</li><li>カプセル（JCapsule）</li><li>無限に広がる平面（JPlane）</li><li>地形（JTerrain）</li></ul><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="primitives.png" src="http://www.morocoshi.net/blog/material/img/primitives.png" class="mt-image-none" style="" height="151" width="499" /></span><br /><br />カプセルは最初円柱と勘違いしてました。実際は円柱の両サイドに半球がくっついた感じです。JiglibFlash + 
PV3Dのサンプルに円柱がありますが、あれは見た目だけでコリジョンはカプセルになってました。地形は上下方向に頂点を移動させた凸凹な地形を作れる感じなのかな？<br /><br />カプセルが円柱じゃないのはわかったけど、もしかして円柱は作れない？他にも三角錐とか円錐とか、複雑な形状のモデルとかは
無理なんでしょうか。地形が作れるのなら頑張ればどんな形状でもいけるんじゃ・・・と思って中を覗いたけど、よくわからなかった。。細長い棒とかならカプセルで代用できるけど、薄い円形の板とかはどうすればいいんだろう。<br /><br />このままだと作れる地形が限定されてしまいそうで不安ですが、きっと誰かが他の形状にも対応させてくれてるはず・・・と他人任せにしつつ、とりあえず今は用意されてるものだけでなんとかしてみます。<br /><br /><h3>A3DでJiglibFlashを使う</h3><div>さっそくA3DでJiglibしたいところなんですが、A3D用メッシュとJiglibコリジョンをくっつける為のプラグインは同封されていないので用意
する必要があります。PV3D用プラグインを見る限りでは、基本的にスクリプトでメッシュとコリジョンを生成して2つを関連付けている感じでした。自分はモデリングソフトでステージを作って、そのモデルデータをFlashで使う事が多いので、スクリプトでメッシュとコリジョンを生成する機能だけだと困る事
があります。<br /><br />例えばこんなステージを3dsMaxで作って、スクリプトでこのステージの形状に合わせたコリジョンを座標を調べつつ入力していくのはかなり骨が折れます。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="teststage.jpg" src="http://www.morocoshi.net/blog/material/img/teststage.jpg" class="mt-image-none" style="" height="309" width="400" /></span><br /><br />そこで、こんな感じにコリジョン用モデルも一緒に用意しておいて、各モデルの位置・サイズ・回転を元にコリジョンを自動生成するようにできればよさそうです。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="testcollision.jpg" src="http://www.morocoshi.net/blog/material/img/testcollision.jpg" class="mt-image-none" style="" height="277" width="400" /></span><br /></div><div><br /><br /><h3>つくってみた</h3>PV3D用のプラグインを参考にしつつ、メッシュを渡すだけでコリジョンを生成して関連付けてくれるものを用意してみました。ボックス・球・カプセル・無限平面に対応しています。地形はまだ対応できてません。<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://www.morocoshi.net/blog/material/swf/jiglibtest1/JiglibTest1.swf" onclick="javascript:openswf(this.href, 465, 465, 10.1); return false;" target="_blank" class="openswf"><img alt="jiglibtest.png" src="http://www.morocoshi.net/blog/material/img/jiglibtest.png" class="mt-image-none" style="" height="397" width="400" /></a></span><br /></div><div><a target="_blank" href="http://www.morocoshi.net/blog/material/as/JiglibTest1.zip">ソース</a><br /><br />3dsMaxで適当に配置したプリミティブをCOLLADA形式で書き出して、A3D7.7で読み込んでJiglibのコリジョンを半自動で設定しています。せっかくなので新機能のライトとかも使ってみました。使い方があってるかは自信ないです。<br /><br />今回作ったJiglib関係のクラスは<br /><ul><li>net.morocoshi.jiglib.a3d.A3dPhysics.as</li><li>net.morocoshi.jiglib.a3d.A3dMesh.as</li></ul>の2つだけです。net.morocoshiパッケージ以下に上記以外のクラスも入ってるけど、A3Dのカメラやコンテナをまとめたクラスと、カメラをぐるぐるするのに必要なクラスなのでJiglibとは関係ないです。<br /><br />使い方を簡単に説明すると、<br />
<pre class="brush: as3;">_sim = new A3dPhysics(5, 0, 0, -20);</pre>
まず最初にA3dPhysicsクラスをnewします。第一引数は速度で、それ以降は重力の大きさ(XYZ成分)<br />
<pre class="brush: as3;">_sim.addBox(mesh1, true);
_sim.addSphere(mesh2, true);
_sim.addCapsule(mesh3, "z", true);
_sim.addPlane(mesh4, true);</pre>次に、A3dPhysicsオブジェクトでadd～()します。第一引数はコリジョンを生成したいメッシュです。addBox()すれば渡したメッシュでボックスコリジョンが生成されて、addSphere()すれば球のコリジョンが生成されます。コリジョンの大きさはメッシュから自動判別されます。カプセルを生成する時だけ、第二引数でカプセルがどの軸に沿って伸びているかをxyzから指定する必要があります。<br /><br />ただ、どのメッシュがどんな形なのかまでは判別してくれないので、どの形状のコリジョンにするかはモデル名で形が分かるようにしておくなどの工夫が必要になります。サンプルではメッシュモデルの名前に_RB_がついていたらボックス、_RS_なら球という感じで判別しています。（Max側では[RB]ってつけてるんだけど、書き出すとアンダースコアになっちゃうから）<br /><pre class="brush: as3;">_sim.step();</pre>後は毎フレームstep()してシミュレーションを進めるだけ。A3dPhysics.step()はフレーム経過にかかった時間を元にシミュレーション速度を調節していて、フレームレートに依存しないようになっているみたいです。これはこれで便利なんですが、FPSが極端に落ちてしまうと計算がアバウトになるせいか壁をすり抜けたり衝突判定がおかしくなってしまう事があります。その場合はstep()は使わずに、</div><div><pre class="brush: as3;">_sim.engine.integrate(0.2);</pre>こうするとシミュレーション速度がFPSに依存するようになります。（integrateの引数はシミュレーション速度）ちなみにA3dPhysicsクラスのコンストラクタで設定した速度はstep()の方にしか影響しません。<br /><br /><h3>コリジョンの自動判定について</h3>メッシュを渡した時のコリジョンの判定方法は形状によって違うんですが、ボックスとカプセルは、バウンディングボックスとXYZスケールと回転の情報だけで判定しています。例えばモデリングソフトでボックスを生成した後に適当に回転させて、ローカルXYZ軸に沿ってスケーリングした後、内部の全頂点を平行移動・・・までなら問題ないのですが、まずいのが内部の全頂点を回転してしまう事で、見た目のボックスとバウンディングボックスがずれてしまうので正しい判定ができなくなります。<br /><br />それとJiglibでメッシュとコリジョンをくっつける際に、メッシュの基点がオブジェクトの中央である必要があるので、メッシュの基点が中央にない場合は自動で全頂点を平行移動させて合わせるようにしています。コリジョン適用前と適用後で座標が変化している場合があるのはそのためです。頂点を動かした分、モデルを逆にずらしているから見た目は変わらないはずだけど。<br /><br /><h3>A3D7.7のCOLLADAパーサ</h3>A3D7.7のCOLLADAパーサには現時点で一部不具合があるようで、モデリングソフト側でスケーリングや回転を組み合わせているとうまくパースできずに位置がずれてしまうケースがあるようなので、Jiglibを適用する前に表示がおかしくないかチェックした方がいいと思います。<br /><br /><br />では今回はこのくらいで。続きはそのうち・・・<br /></div>]]>
    </content>
</entry>

<entry>
    <title>今後の事とかAlternativa3Dの事とか</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2011/03/alternativa3d.html" />
    <id>tag:www.morocoshi.net,2011:/blog//3.34</id>

    <published>2011-03-30T00:00:00Z</published>
    <updated>2011-03-30T00:00:00Z</updated>

    <summary>更新。。。久々。。。Papervision3Dに感動して毎日弄っていたり、ウォー...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Blog" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[更新。。。久々。。。<br />Papervision3Dに感動して毎日弄っていたり、ウォークスルーコンテンツ作ろうとしていたあの頃が懐かしいです。<br /><br />ここのブログを放置している間にXREAの有料期間が過ぎてしまって、広告が表示されるようになったり、ディスク容量が減ったりしてしまいました。容量が減った影響でいくつかファイルを削除したので、見れないものがあるかもしれません。<br /><br />お金を払えばまた元に戻せるんですが、以前からXREAのサーバー障害が頻繁に発生していた事もあって、せっかくなので別のサーバーに移転しようか迷っています。震災の影響なのか、どこのサービスも障害だらけで、いいところが見つかっていませんが。。<br /><br />そうそう最近はFlashでの3D表現にAlternativa3D(A3D)を主に使っています。前回の記事でちょっとA3Dについて触れたけど、あれからバージョンが上がって一部不具合が修正されて、ロゴも簡単に消せるようになって、3dsMax用プラグインも出ています。A3D関係の記事も増やしていきたいなあ。]]>
        
    </content>
</entry>

<entry>
    <title>Alternativa3D7.5を使ってみた</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2010/10/alternativa3d75.html" />
    <id>tag:www.morocoshi.net,2010:/blog//3.33</id>

    <published>2010-10-02T00:00:00Z</published>
    <updated>2010-10-04T00:00:00Z</updated>

    <summary> Alternativa3Dで3Dデモを作ったよ。バージョンは最近出た7.5。な...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Alternativa3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[<form class="mt-enclosure mt-enclosure-image" style="display: inline;" contenteditable="false">
<a href="http://www.morocoshi.net/blog/material/swf/alt3dtest/alt3dtest.swf" onclick="javascript:openswf(this.href, 650, 450, 10.1); return false;" target="_blank" class="openswf"><img alt="alt3dtest.jpg" src="http://www.morocoshi.net/blog/material/img/alt3dtest.jpg" class="mt-image-none" style="" height="350" width="500" /></a></form><br /><a target="_blank" href="http://alternativaplatform.com/en/">Alternativa3D</a>で3Dデモを作ったよ。バージョンは最近出た7.5。<br />なんだかゲームが始まりそうな雰囲気ですが、残念ながら眺めるだけです。(CAMERAをDRAGにすると画面ドラッグで動かせる)]]>
        <![CDATA[<h3>参考にしたサイト</h3>今回Alternativa3Dを初めて触ってみたんですが、どうやら今回の7.5のバージョンアップでクラス構成が大幅に変更されているようで、7.5以前のTIPSだけで勉強するのはちょっと厳しかったです。<br /><br />自分がこのデモを作る際に参考にしたサイトやソース<br /><a target="_blank" href="http://clockmaker.jp/blog/2010/09/alternativa3d-7-5-first-impression/">Flashの3Dエンジン「Alternativa3D 7.5」を試してみた | ClockMaker Blog</a><br /><a target="_blank" href="http://wonderfl.net/c/10hP">Altanativa3D 7.5 test | wonderfl</a><br /><br /><strike>今回のデモを作る際に自作ライブラリをいくつか使ってしまってソースコードが公開できなくなってしまいました。</strike><br />自作ライブラリを使わないバージョンをWonderflに<a target="_blank" href="http://wonderfl.net/c/eZbi">投稿しました。</a>やっている事はColladaモデルを読み込んで、テクスチャを読み込ませて、カメラを動かしているだけです。シェーダっぽく見えるのは全てレンダーベイキングだし、床の反射も床の下に反射用モデルを置いてそれっぽく見せているだけだったりします。<br /><br /><h3>はまったリスト</h3><ul><li>3dsMAXから書き出したcolladaモデルがうまくパースされないケースがある(リサイズしてるとまずい気がする)</li><li>colladaモデルの構成とカメラの位置によっては何故かエラーが出まくる</li><li>BSPソート(PV3DでいうQuadrantRenderEngine)がcolladaモデルによってはうまく機能しない場合がある</li><li>ロゴの上にスプライトがちょっとでも重なるとビューポート全体が見えなくなるようになってる(仕様)</li></ul><h3>よかったリスト</h3><ul><li>テクスチャが歪まない</li><li>ソート順を保ったまま3Dオブジェクト単位でフィルタやブレンドモードが設定できる(デモでは床と光の筋に設定してる)</li><li>colladaのボーンアニメーションでモーションブレンドが使える</li><li>ボーンアニメーションの再生速度を変更できる</li></ul>]]>
    </content>
</entry>

<entry>
    <title>記事内のFlashが一部見れなくなってました</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2010/07/loader-trouble.html" />
    <id>tag:www.morocoshi.net,2010:/blog//3.30</id>

    <published>2010-07-03T00:00:00Z</published>
    <updated>2011-04-15T00:00:00Z</updated>

    <summary>お久しぶりです。久々すぎて、MovableTypeの使い方分からなくなってる。。...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="ActionScript3" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[お久しぶりです。<br />久々すぎて、MovableTypeの使い方分からなくなってる。。<br />少し前からwonderflで<a target="_blank" href="http://wonderfl.net/user/tencho/codes">コード</a>書いてたんだけどね。<br />それを記事にしようとすると結構面倒くさくて、、まとめるのムズカシイ<br /><br />そうそうタイトルの件です。いつのまにか昔の記事のFlashが見れなくなってたっていう。見れないっていうかくるくる回るローディングが途中で止まってました。以前は見れたのに。<br /><br />それでしばらく調べてわかったこと。<br />結論から言うと、どうも<em>Firefoxの一部のバージョン(1.5、2.0、3.6.4、3.6.6)でhtmlに埋め込んだFlashを再生するとLoader.load()で空文字や半角スペースのパスをロードした時にエラーイベントも完了イベントも発生しない</em>というのが原因だったらしい。<br /><br />そんなルールあったんだ・・・<br />]]>
        <![CDATA[<br />問題があったFlashではローディング画面でPapervision3D用のテクスチャ画像とDAEモデルを読み込んでいるんだけど、DAEモデルを読み込む部分で先に進まなくなってたんです。それでDAEクラス内の動きを調べたら、テクスチャ画像を読み込む部分のLoaderクラスの処理で毎回止まってました。どうやらLoader.load(new 
URLRequest(画像パス))って処理のところで、画像パスが空文字だった時にLoaderがエラーイベントを返さなくなっていたらしい。そのせいでDAEクラスもイベントを返せなくなっていた・・・多分そんな感じ。<br /><br /><h3>確認用Flash</h3>
<a href="http://www.morocoshi.net/debug/loadertest/bin/" onclick="javascript:openPage(this.href, 400, 300); return false;" target="_blank" class="openpage">loadertest.swf</a>（<a target="_blank" href="http://www.morocoshi.net/debug/loadertest/src/LoaderTest.as">ソース</a>）<br />一応置いときます。空文字のパスをロードした時のエラーイベント発生状況を調べた時に作ったやつです。ボタンを押すとラベル名をURLとしてLoader.load()します。一番左が問題の空文字。全部存在しないファイルとかなんで、クリックして赤いエラーメッセージが出ればOKです。<br /><br />Windows7+FlashPlayer10.1の環境で、IE、Safari、Chrome、Operaに関しては最新版しかチェックしてないけど、これらのブラウザでLoader.load(new 
URLRequest(""))をやるとちゃんとエラーイベントが返ってきました。でもFirefoxは最近でた3.6.4と3.6.6、あと昔の1.5と2.0のバージョンで再生すると何故かエラーイベントが発生しなかった・・・<br /><a target="_blank" href="http://www.morocoshi.net/debug/loadertest/bin/loadertest.swf">SWFを埋め込まずに再生</a>するとまた結果が違ってくるらしく、こっちはFirefox3.6.6でもエラーが発生してくれました。<br /><br /><h3>空文字の原因</h3>そもそもなんで空文字のパスでLoader.load(new 
URLRequest(""))とかしてるの？って話なんだけど、元々ステージモデルとかのdaeファイル内にはテクスチャの設定がしてあって、テクスチャの画像パスなんかも含まれてました。DAEクラスは自動でテクスチャ画像を読み込んでくれる機能もあるんだけど、何故かこれがうまくいかなかくて、、それで諦めて、事前に別処理で読み込んでおいた画像をマテリアルリストとしてDAE.load()時に渡す方法にしてたんです。マテリアルリストを渡す場合はDAEクラスによる外部テクスチャ画像の読み込みは不要になるので、じゃ画像パスはいらないよね！ってdaeファイル内のテクスチャ画像パスを全部削ったのがいけなかった。<br /><br />↓問題のあったdaeファイル内のテクスチャ画像パスが記述されていた部分
<pre class="brush: as3;">&lt;library_images&gt;
	&lt;image id="face"&gt;
		&lt;init_from&gt;ここにあった画像パスを消していた&lt;/init_from&gt;
	&lt;/image&gt;
	&lt;image id="foot"&gt;
		&lt;init_from&gt;ここにあった画像パスを消していた&lt;/init_from&gt;
	&lt;/image&gt;
	&lt;image id="hand"&gt;
		&lt;init_from&gt;ここにあった画像パスを消していた&lt;/init_from&gt;
	&lt;/image&gt;
&lt;/library_images&gt;</pre>
DAEクラスはマテリアルリストを渡されても一応daeファイル内の上記の画像パスは読み込もうとはするらしい。パスを消していたもんだから空文字になってしまって、それで今回の問題が発生してしまった・・・んだと思う。<br /><br />本当はマテリアルリストを渡す場合はここのテクスチャの読み込み処理が発生しないようにするべきなんだろうけど、ひとまず#を入れてエラーが出るようにしておきました。空文字とか半角スペースだけとかを避ければエラーになってくれるはず。<br /><br />
↓応急処置後
<pre class="brush: as3;">&lt;library_images&gt;
	&lt;image id="face"&gt;
		&lt;init_from&gt;#&lt;/init_from&gt;
	&lt;/image&gt;
	&lt;image id="foot"&gt;
		&lt;init_from&gt;#&lt;/init_from&gt;
	&lt;/image&gt;
	&lt;image id="hand"&gt;
		&lt;init_from&gt;#&lt;/init_from&gt;
	&lt;/image&gt;
&lt;/library_images&gt;
</pre>こんな感じでとりあえずFirefox3.6.6でも見れるようになった・・・めでたしめでたし。ちなみにこれは間違ってdaeファイル内の画像パスを消しちゃった場合の対処法ね。そんな人他にもいるのか疑問だけど。。<br /><br /><h3>結局</h3>Loaderクラスで外部画像を読み込む時、事前にＵＲＬが決まっている場合は今回みたいな事にはならないけど、ＵＲＬを動的に生成するケースでは何かの原因で空文字が指定される事もあるかもしれない。そうなると読み込みが完了するか、エラーが出るまで待機するような設計だった場合ブラウザによっては先に進めなくなってしまうから、どんなパスが指定されるか予測できない時は読み込む前にＵＲＬをチェックして処理を分岐させる必要があるって事なのかな。とりあえず空文字と半角スペース1個にはならないようにしとこう。<br /><br /><h3>DAEクラスでテクスチャがうまく読み込めない原因</h3>マテリアルリストを渡すはめになった「daeファイルで指定したテクスチャが読み込めない現象」は、<a target="_blank" href="http://www.ahiru.org/archives/92">ここの記事</a>に解決策が書いてありました。これでなんとかなりそうな気がします。<br />]]>
    </content>
</entry>

<entry>
    <title>ふんふん</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2009/11/post.html" />
    <id>tag:www.morocoshi.net,2009:/blog//3.26</id>

    <published>2009-11-22T00:00:00Z</published>
    <updated>2011-04-15T00:00:00Z</updated>

    <summary>最近ちょっと更新が滞ってます。バンドの手伝いとか、手伝いじゃないのとか、色々もさ...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Blog" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[最近ちょっと更新が滞ってます。<br />バンドの手伝いとか、手伝いじゃないのとか、色々もさもさしてて。<br /><br />久しぶりに記事みなおしてみると色々直したいとこがあるなあ。。<br />とりあえず気になったのは、<a href="http://www.morocoshi.net/blog/2009/10/pv3d21.html">レンズフレア</a>の記事で<br />もしかして黒に塗ってる意味ない？とか、<br />記事ではチャンネルコピーしてるけど<br />画像そのままコピーしてぼかしてアルファ値調べればいいだけ？とか・・・<br />負荷はあまり変わらないのかもしれないけどね。<br />落ち着いたら修正するかもしれません。<br />]]>
        
    </content>
</entry>

<entry>
    <title>wmodeを指定するとMOUSE_LEAVEが効かない場合がある？</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2009/11/wmodetran.html" />
    <id>tag:www.morocoshi.net,2009:/blog//3.25</id>

    <published>2009-11-11T00:00:00Z</published>
    <updated>2011-04-13T00:00:00Z</updated>

    <summary>Flashコンテンツ(AS3)のステージ内でマウスを押した(MouseEvent...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="ActionScript3" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[Flashコンテンツ(AS3)のステージ内でマウスを押した(MouseEvent.MOUSE_DOWN)ままFlashの領域外までドラッグした時、そのままではマウスを離したイベント(MouseEvent.MOUSE_UP)を検出できないんだけど、マウスがFlash領域から出た時を検出できるEvent.MOUSE_LEAVEを使うとマウスダウン→領域外までドラッグ→マウスアップのタイミングでもイベントが取れるのでこれを利用してボタンの表示を元に戻したりドラッグ処理を停止したりできます。<br /><br />ただ、swfをhtmlに埋め込む時にwmodeを指定していると環境によってはEvent.MOUSE_LEAVEイベントが発生しない事があるっぽい。。。<br /><br />そこで、検証用にサンプルを用意してちょっと実験してみました。全てWindowsXP、FlashPlayer10でテストしてます。真ん中の黒いボックスがボタンになっていて、マウスを押すとオレンジに、離すと青に変化するようになってます。<br /><br />]]>
        <![CDATA[「ボタン上でマウスダウン→Flash領域外までドラッグ→マウスを離す」とやって、オレンジ→青と変われば成功ね。<br /><br />
<h3>wmode指定なし</h3>
<div id="swf1"></div><br />
IE8・Firefox3.0・Opera10・Safari4・Chrome5で全て問題なし。<br /><br />
<script type="text/javascript">
swfobject.embedSWF("http://www.morocoshi.net/blog/material/swf/mouseleave.swf", "swf1", 250, 200, "9", "", {}, {});
</script>
<h3>wmode=transparent</h3>
<div id="swf2"></div><br /><ul><li>Chrome5</li></ul><blockquote>問題なし<br /></blockquote><ul><li>Firefox3.0・Opera10・Safari4</li></ul><blockquote>Flash領域外ドラッグでEvent.MOUSE_LEAVEが発生しない。<br /></blockquote><ul><li>IE8</li></ul><blockquote>Flash領域外(ブラウザ内)でマウスを離すとstageのMouseEvent.MOUSE_UPが発生し、<br />その後マウスを動かすとEvent.MOUSE_LEAVEが発生した。<br />ドラッグしてブラウザの外で離すとすぐにEvent.MOUSE_LEAVEが発生。<br /></blockquote><br />
<script type="text/javascript">
swfobject.embedSWF("http://www.morocoshi.net/blog/material/swf/mouseleave.swf", "swf2", 250, 200, "9", "", {}, {wmode: "transparent"});
</script>
<h3>wmode=opaque</h3>
<div id="swf3"></div><br />
transparentと同じ結果。<br /><br />
<script type="text/javascript">
swfobject.embedSWF("http://www.morocoshi.net/blog/material/swf/mouseleave.swf", "swf3", 250, 200, "9", "", {}, {wmode: "opaque"}); </script><br /><h3>結局</h3>Event.MOUSE_LEAVEを判定したい時はwmodeは指定すると駄目って事なのかな。<br />見にくいけどサンプルのソースは<a target="_blank" href="http://www.morocoshi.net/blog/material/as/MouseLeaveTest.as">これ</a>です<br />]]>
    </content>
</entry>

<entry>
    <title>PV3D2.1: FrustumClipping使用時のポリゴン欠け</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2009/11/pv3d21-frustumclipping.html" />
    <id>tag:www.morocoshi.net,2009:/blog//3.24</id>

    <published>2009-11-09T00:00:00Z</published>
    <updated>2010-04-05T00:00:00Z</updated>

    <summary>renderer.clipping = new FrustumClipping(...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="Papervision3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[renderer.clipping = new FrustumClipping(～);<br />とかやっていると、<br />カメラを高速で回転した時とかに画面の端でポリゴンが<br />一瞬カリングされてしまう謎の現象があったんだけど<br /><a target="_blank" href="http://ferv.jp/blog/2009/06/04/frustumclipping_camera3dtarget/">jp.ferv.blogさんの記事</a>でやっと対処法がわかりました。<br /><br />FrustumClippingを使うときはCamera3D.targetは使わず<br />代わりにCamera.lookAt()を使えば解決するようです。<br /><br />で、これでめでたしめでたしと思いきや何故か上手くいかなくて、<br />結構長い間フガフガしてたんだけど<br />BasicViewクラスを使う時に<br /><b>new BasicView(640, 480, false, false);</b><br />って第五引数を省略してたせいで<br />カメラタイプがデフォルトの"Target"になってしまってて<br />コンストラクタで<b>camera.target = DisplayObject3D.ZERO;</b>されてたのが原因だった。。<br />いつも省略してたから全然気付かなかったよ・・・<br /><br /><b>new BasicView(640, 480, false, false, CameraType.FREE);</b><br />こんな風に第五引数を"Free"にして解決。<br />]]>
        
    </content>
</entry>

<entry>
    <title>PV3D2.1: レンズフレア</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2009/10/pv3d21.html" />
    <id>tag:www.morocoshi.net,2009:/blog//3.23</id>

    <published>2009-10-26T00:00:00Z</published>
    <updated>2010-07-08T00:00:00Z</updated>

    <summary>Papervision3Dでウォークスルーの実験中。レンズフレアエフェクトをつけ...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="PV3Dでウォークスルー" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Papervision3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[Papervision3Dでウォークスルーの実験中。<br /><a href="http://www.morocoshi.net/blog/material/swf/walk5/walkthrough5.swf" onclick="javascript:openswf(this.href, 600, 400, 10); return false;" target="_blank" class="openswf"><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="walkthrough5.jpg" src="http://www.morocoshi.net/blog/material/img/walkthrough5.jpg" class="mt-image-none" style="" height="261" width="400" /></span></a><br />レンズフレアエフェクトをつけてみました。<br />海面のウネウネはなんか失敗。キラキラさせたかったんだけど・・・<br /><br />太陽の部分は3dsMaxのレンズエフェクトでレンダリングしたもので、<br />画面全体にかかる光の輪はFlashの放射グラデーションです。<br />レンズフレアの仕組みはよくわかってないんだけど、<br />光の輪が複数個あって、それが画面中央の座標と光源を結ぶ直線上に並んでるって<br />イメージはあったのでそんな感じで表現してます。

]]>
        <![CDATA[<br /><h3>太陽のスクリーン座標</h3>3D空間内にあるオブジェクトの基点の2D画面上での位置はDisplayObject3D.screenで簡単に調べられるのでそれを利用します。<br />
<pre class="brush: as3;">	var sun:DisplayObject3D = new DisplayObject3D();
	scene.addChild(sun);
	sun.autoCalcScreenCoords = true;
	sun.position = new Number3D(100000, 20000, 0);
</pre>
まず太陽の位置を知るためにダミーのDisplayObject3Dを生成して、シーンに追加しておきます。autoCalcScreenCoords=trueしているのはシーンがレンダリングされる度に自動でスクリーン座標を計算させる為です。後は毎フレームスクリーン座標を調べてその位置に太陽の画像を移動させるだけ。<br />
<pre class="brush: as3;">	//最初に実行しておく処理
	//ビューポートサイズ
	var viewRect:Rectangle = new Rectangle(0, 0, viewport.width, viewport.height);
	//ビューポートの中央座標
	var centerX:Number = viewport.width/2;
	var centerY:Number = viewport.height/2;
	
	//毎フレーム実行する処理
	var isShow:Boolean = (sun.screen.z &gt; 0 &amp;&amp; viewRect.contains(sun.screen.x + centerX, sun.screen.y + centerY));
	//sunMc, ring1Mc, ring2Mcはそれぞれ太陽と光の輪のムービークリップ
	sunMc.visible = isShow;
	ring1Mc.visible = isShow;
	ring2Mc.visible = isShow;
	if (isShow) {
		sunMc.x = sun.screen.x + centerX;
		sunMc.y = sun.screen.y + centerY;
		ring1Mc.x = sun.screen.x * 0.5 + centerX;
		ring1Mc.y = sun.screen.y * 0.5 + centerY;
		ring2Mc.x = sun.screen.x * -1.0 + centerX;
		ring2Mc.y = sun.screen.y * -1.0 + centerY;
	}
</pre>
このコードでいうとsun.screenがスクリーン座標になります。screen.xとscreen.yがビューポートの真ん中を(0, 0)としたスクリーン座標でscreen.zはオブジェクトのカメラからの距離かな？（自信ない）<br />カメラの前に太陽があるのか、後ろにあるのかを判定するのにscreen.zを使ってます。screen.z&lt;0だったら太陽がカメラの後ろにあるので表示を消して、太陽がビューポートの外にあった時も消しています。<br /><br />※DisplayObject3D.screenはシーンをレンダリングした後でアクセスしないと最新の座標が取れないようです。<br /><br /><h3>太陽を遮るオブジェクトの判定</h3>太陽が画面内にあっても、それを遮るオブジェクトがあった場合消す必要があります。以前Shockwave3D時代にやっていた方法は、カメラの位置から太陽の方向にレイを飛ばして地形モデルと交差したかどうかで判定していたんだけど、交差判定が重くなりそうだったので今回は別の方法にしてみました。<br /><br /><em>※以前ここで紹介した方法がかなり重かったので、もっと軽い方法での判定に変えました。</em><br /><br />今回シーン内に空用モデルを配置していないので、レンダリング結果を表示するビューポート画面で空の部分は描画するものが何もない・・・つまり透明になっているという事になります。なので太陽位置の透明度を調べれば遮蔽物があるかどうかがわかります。<br /><br />大ざっぱな手順は<br /><br /><ol><li>ビューポートに映っている画像をBitmapDataで取得する</li><li>取得したBitmapData上の太陽位置のピクセル情報を調べる</li><li>取得したピクセルの透明度を調べて、透明だったら遮蔽物がない事にする<br /></li></ol>こんな感じです。<br />1のビューポート画像をBitmapDataで取得する方法ですが、いつもVireport3Dクラスを使うところをBitmapVireport3Dクラスにすると、BitmapVireport3D.bitmapDataにアクセスするだけでビューポートに映っている画像がそのままBitmapDataとして拾えます。<br />
<br />
遮蔽物判定部分のコードは抜粋になっちゃうけど以下のような感じ。<br />・はじめに用意しておくもの
<pre class="brush: as3;">	//BitmapViewport3Dオブジェクトを生成（第4引数をtrueにして背景を透過させる）
	var viewport:BitmapViewport3D = new BitmapViewport3D(600, 400, false, true, 0x000000);
</pre>
・以下のコードは毎フレーム、シーンのレンダリング直後に実行。
<pre class="brush: as3;">	//ピクセルカラーを取得(※px, pyは太陽のスクリーン座標)
	var argb:uint = viewport.bitmapData.getPixel(px, py);
	//透明度の割合を取得
	var per:Number = 1 - (argb  &gt;&gt;&gt; 24) / 0xFF;
</pre>
perが透明度の割合（0～1）なので、この数値で太陽のスケールとかアルファとかを変化させるだけです。最後の行の「ARGBカラー値 &gt;&gt;&gt; 24」はアルファチャンネルの値を抜き出すビット演算です。<br /><br /><div><h3>太陽が半分隠れていた時の処理</h3>上記の処理だけでもいいんだけど、太陽が半分隠れていた時に少し弱まる感じを再現したいので、その処理も考えてみます。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="lensflare2.jpg" src="http://www.morocoshi.net/blog/material/img/lensflare2.jpg" class="mt-image-none" style="" height="115" width="500" /></span></div><br />最初ここで紹介していた方法が、ビューポート画像をBitmapDataで取得した後、そのアルファチャンネル画像をぼかして空と遮蔽物の境界部分をなめらかにする方法でした。実際はもっと回りくどかったけど・・・<br /><br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="omoiyatu.jpg" src="http://www.morocoshi.net/blog/material/img/omoiyatu.jpg" class="mt-image-none" style="" height="103" width="600" /></span><br /><br />こうすると太陽が半分隠れる境界部分で徐々に透明度が変化してくれるので、それっぽい表現ができたんだけど・・・毎フレーム画像を複製してぼかしていたので、物凄く重かった。（全体をぼかす必要はなかったんだけど・・・）<br /><br />そこでぼかすのをやめて、太陽の周囲のピクセルも調べてそれらの透明度の平均値を求める方法に変えてみました。太陽位置のピクセルを中心に、上下左右数ピクセルの矩形範囲の透明度を全て加算して、それを矩形範囲のピクセル数で割るだけです。<br /><br />

・はじめに用意しておくもの
<pre class="brush: as3;">	//BitmapViewport3Dオブジェクトを生成（第4引数をtrueにして背景を透過させる）
	var viewport:BitmapViewport3D = new BitmapViewport3D(600, 400, false, true, 0x000000);
	//上下左右に何ピクセルまで調べるか（padding&gt;=0）
	var padding:int = 2;
	//調べるピクセルの総数
	var pixelNum:int = (padding * 2 + 1) * (padding * 2 + 1);
</pre>
・以下のコードは毎フレーム、シーンのレンダリング直後に実行。
<pre class="brush: as3;">	var perTotal:int = 0;
	for (var ix:int = -padding; ix &lt;= padding; ix++) {
		for (var iy:int = -padding; iy &lt;= padding; iy++) {
			//(px, py)は太陽のスクリーン座標
			perTotal += viewport.bitmapData.getPixel32(px + ix, py + iy) &gt;&gt;&gt; 24;
		}
	}
	//アルファ値の平均値を求める
	var per:Number = 1 - perTotal / pixelNum / 0xFF;
</pre>
あとはperの割合（0～1）で太陽の強さを変化させるだけです。<br /><br />
<h3>Wonderflのサンプル</h3>この方法で組んだレンズフレアのサンプルをWonderflに投稿してあるので動くコードが見たい人は下のリンクからどうぞ。コードは色々と酷いけど気にしないでね。。。<br />
<div style="text-align: center; width: 465px;"><iframe title="レンズフレア - wonderfl build flash online" src="http://wonderfl.net/blogparts/i0dL" style="border: 1px solid black;" scrolling="no" height="490" width="465"></iframe><a href="http://wonderfl.net/c/i0dL" title="レンズフレア - wonderfl build flash online">レンズフレア - wonderfl build flash online</a></div>
<a href="editor-content.html?cs=UTF-8" onclick="javascript:openWonderfl('i0dL', 'レンズフレア'); return false;" target="_blank" class="openswf"><br /></a>]]>
    </content>
</entry>

<entry>
    <title>PV3D2.1: 背景と高さ判定</title>
    <link rel="alternate" type="text/html" href="http://www.morocoshi.net/blog/2009/10/pv3d21-7.html" />
    <id>tag:www.morocoshi.net,2009:/blog//3.21</id>

    <published>2009-10-17T00:00:00Z</published>
    <updated>2010-07-04T00:00:00Z</updated>

    <summary>Papervision3Dでウォークスルーの実験中。 背景をつけてみました。大き...</summary>
    <author>
        <name>てんちょ</name>
        <uri>http://www.morocoshi.net/blog/</uri>
    </author>
    
        <category term="PV3Dでウォークスルー" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Papervision3D" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="pv3d21920" label="PV3D2.1.920" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.morocoshi.net/blog/">
        <![CDATA[Papervision3Dでウォークスルーの実験中。<br /><a href="http://www.morocoshi.net/blog/material/swf/walk4/walkthrough4.swf" onclick="javascript:openswf(this.href, 600, 400, 9); return false;" target="_blank" class="openswf"><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="walkthrough4.jpg" src="http://www.morocoshi.net/blog/material/img/walkthrough4.jpg" class="mt-image-none" style="" height="244" width="400" /></span></a><a href="http://www.morocoshi.net/blog/material/swf/walk3/walkthrough3.swf" onclick="javascript:openswf(this.href, 600, 400, 9); return false;" target="_blank" class="openswf"> <br /></a>背景をつけてみました。<br />大きい一枚の画像をカメラの角度に合わせて上下左右にスクロールさせてます。<br />あと、高さ判定処理を組みなおして少しそれっぽく動けるようにしました。<br />高い所のモデルの下をくぐったり、高い所から落ちたりできます。]]>
        <![CDATA[<br /><h3>背景の追加<br /></h3><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="walk4sky.jpg" src="http://www.morocoshi.net/blog/material/img/walk4sky.jpg" class="mt-image-none" style="" height="100" width="600" /></span><br />背景に使った空画像の全体図はこんな感じ。<br />手前のくっきりしてる雲だけ<a target="_blank" href="http://www.planetside.co.uk/content/view/15/27/">Terragen2</a>でレンダリング・・・というか知らない間に2出てたんだね。<br />
カメラは横に0～360°しか動かないのでその角度と画像のX座標をリンクさせているだけです。<br />実際は端が切れないように画像を横方向に多めにループさせてます。<br />横方向は簡単だったんですが、縦方向がカメラから水平線の位置を割り出す必要があって、<br />今はまだ目分量による簡単な位置合わせしかしていないので正確ではないです。<br /><br />ちゃんとした水平線の高さの割り出し方を調べるのがベストだと思うんだけど、<br />物凄い遠くに配置したダミーのDisplayObject3Dが常にカメラの正面(高さは海面)にくるようにして<br />そのダミーオブジェクトの座標を調べるって方法でもいける気がします。試してないけど・・・<br />Papervision3DではDisplayObject3D.autoCalcScreenCoords = trueしてから<br />DisplayObject3D.screenを調べれば基点のスクリーン座標が簡単に調べられるようです。<br /><br /><h3>高さの判定</h3>今までは単純にキャラ上空から真下に飛ばしたレイと地形モデルの最初の交点にキャラを移動させていただけで<br />モデルの下をくぐったりできなかったんですが、<br />今回は交差する全ての点の中から次に進める高さを調べているのでそれっぽく動けるようになりました。<br />(斜面を滑り落ちるような処理は高さ判定の処理とは別物です)<br />やっている事はだいたいこんな感じです。<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="heightcheck.png" src="http://www.morocoshi.net/blog/material/img/heightcheck.png" class="mt-image-none" style="" height="518" width="422" /></span><br />基本的にキャラクターの移動前の高さと移動後の高さを比べて<br />先に進めるか進めないかの判定くらいしかしていません。<br />先に進めなかったら移動前の位置に戻しています。<br />高さ判定のコードがそれ以外の処理に混ざってしまっているのでコードは割愛しますが<br />内容はほとんど上の図そのままです。if文だらけになるのはしょうがないのかな。。<br />こんなに条件が多くなってしまったのは高いところから落下する処理があった為で、<br />常に足が地面に接地しているだけなら<br /><ul><li>一番近い高さに移動させる</li><li>高さが違いすぎたら元に戻す</li></ul>この処理だけでもなんとかなりそうな気がします。<br /><br />
条件分岐が多いとはいえ交差判定は今まで通り1回だけで済んでいるので<br />
処理はたいして重くならずに済みました。<br />
ただ高さだけで判定していて正面に壁があるかどうかはまったく調べていないので、<br />
ゲームでよくある壁に沿って滑るような動きができないし、<br />
キャラクタ―が壁に半分めり込んだりします。<br />複雑な地形での壁の判定はどうしようかな・・・<br />]]>
    </content>
</entry>

</feed>

