WoW-Engineの学習ログ

参考

Wow-Engineの導入と解説に関してはWOWEngineで、ミクとリンが跳梁跋扈!! – タロタローグ ブログが詳しい。

作業

WoW-Engineの導入

http://seraf.mediabox.fr/wow-engine/as3-3d-physics-engine-wow-engine/のDownloadのver1からZip解凍。flex_sdk_2/frameworks/sourceの中にfrフォルダを入れる。(〜/sourceはflex-config.xmlのsource-pathでパスを通してある)

AS3 Data Structuresの導入

WoW-Engineで使うようなので、http://lab.polygonal.de/ds/のDownload sourceから持ってきて、同じくsrc中のdeフォルダをflex_sdk_2/frameworks/sourceに入れる。

コーディング

activCollisionEventまわりでoverrideがらみのエラーが出て、grepしても使ってる様子がなかったので削除。
上記の参考のページをもとにコーディング。BaundArea内に球体を一個生成するところまで完了。


コードだけ先に乗せておく。

package {
	//Common
	import flash.display.*;
	import flash.events.*;

	//PV3D
	import org.papervision3d.scenes.*;
	import org.papervision3d.objects.*;
	import org.papervision3d.cameras.*;
	import org.papervision3d.materials.*;

	//WoW
	import fr.seraf.wow.constraint.*;
	import fr.seraf.wow.core.*;
	import fr.seraf.wow.core.data.*;
	import fr.seraf.wow.math.*;
	import fr.seraf.wow.primitive.*;
	import fr.seraf.wow.util.*;

	//Class
	public class WoWTest extends Sprite {
		//Common
		private var m_Container	: Sprite;

		//PV3D
		private var m_Scene		: Scene3D;
		private var m_Camera	: Camera3D;
		private var m_RootNode	: DisplayObject3D;
		private var m_BoundArea	: DisplayObject3D;
		private var m_Sphere	: DisplayObject3D;
		private var m_Cube		: DisplayObject3D;

 		//WoW
		private var m_WoWEngine:WOWEngine;
		private var m_BoundArea_WoW:WBoundArea;
		private var m_Sphere_WoW:WSphere;
//		private var m_Cube_WoW:WBox;

		//Param
		private const BOUND_AREA_W:Number = 400;
		private const BOUND_AREA_H:Number = 200;
		private const BOUND_AREA_D:Number = 200;

		private const SPHERE_INIT_X:Number = 0;
		private const SPHERE_INIT_Y:Number = 100;
		private const SPHERE_INIT_Z:Number = -50;

		private const SPHERE_RAD:Number = 10;


		//Constructor
		public function WoWTest():void {
			{//Init Common
				//リサイズ対応
				stage.addEventListener(Event.RESIZE, onStageResize);
	 
				//定期的にupdateを呼ばせる
				addEventListener(Event.ENTER_FRAME, update);
			}

			{//Init PV3D
	 			{//m_Container
					// 表示用の Sprite オブジェクトを生成
					m_Container = new Sprite();
					m_Container.x = 400 / 2; // at center : swf width	= 400
					m_Container.y = 400 / 2; // at center : swf height = 400
					addChild(m_Container);
				}

				{//m_Scene
					// シーンオブジェクトを作る
					m_Scene = new Scene3D(m_Container);
				}

				{//m_Camera
					// カメラオブジェクトを作る
					m_Camera = new Camera3D();
					m_Camera.z = -200;
					m_Camera.focus = 500;
					m_Camera.zoom = 1;
				}

				{//m_RootNode
					// ルートノードを作る
					m_RootNode = new DisplayObject3D();
					m_Scene.addChild(m_RootNode);
				}

				{//m_BoundArea
					m_BoundArea = function():DisplayObject3D
					{
						//BoundAreaを箱として表示
						//内側が映るようにoneSide = false
						//backは透明にして中が見えるように
						var cm:ColorMaterial;
						var material:MaterialsList = new MaterialsList();

						cm = new ColorMaterial(0xDDDDDD);
						cm.oneSide = false;
						material.addMaterial(cm, "front");

						cm = new ColorMaterial(0xFFFFFF, 0.0);
						cm.oneSide = false;
						material.addMaterial(cm, "back");

						cm = new ColorMaterial(0xEEEEEE);
						cm.oneSide = false;
						material.addMaterial(cm, "right");

						cm = new ColorMaterial(0xCCCCCC);
						cm.oneSide = false;
						material.addMaterial(cm, "left");

						cm = new ColorMaterial(0xAAAAAA);
						cm.oneSide = false;
						material.addMaterial(cm, "top");

						cm = new ColorMaterial(0xFFFFFF);
						cm.oneSide = false;
						material.addMaterial(cm, "bottom");

						var cube:Cube = new Cube(material, BOUND_AREA_W, BOUND_AREA_D, BOUND_AREA_H);
						return cube;
					}();

					m_RootNode.addChild(m_BoundArea);
				}

				{//m_Sphere
					m_Sphere = function():DisplayObject3D
					{
						var material:WireframeMaterial = new WireframeMaterial();
						material.oneSide = false;
						material.lineColor = 0xFF0000;
						material.lineAlpha = 1;

						var sphere:DisplayObject3D = new Sphere(material, SPHERE_RAD);
						sphere.x = SPHERE_INIT_X;
						sphere.y = SPHERE_INIT_Y;
						sphere.z = SPHERE_INIT_Z;

						return sphere;
					}();

					m_RootNode.addChild(m_Sphere);
				}

				{//m_Cube
//					m_Cube = createCube();
//					m_RootNode.addChild(m_Cube);
				}
			}

			{//Init WoW
				{//m_WoWEngine
					m_WoWEngine= new WOWEngine();
					m_WoWEngine.collisionResponseMode = m_WoWEngine.SELECTIVE;
					m_WoWEngine.addMasslessForce(new WVector(0.1, -1, 0));//重力っぽいもの
					m_WoWEngine.damping = 1;
				}

				{//m_BoundArea
					m_BoundArea_WoW = new WBoundArea(BOUND_AREA_W, BOUND_AREA_H, BOUND_AREA_D);
					m_BoundArea_WoW.setPosition(0, 0, 0);//中心位置
					m_BoundArea_WoW.elasticity = 1;//弾性
					m_BoundArea_WoW.friction = 0.050;//摩擦
					m_WoWEngine.setBoundArea(m_BoundArea_WoW);
				}

				{//m_Sphere_WoW
					var IsFixed:Boolean = false;
					m_Sphere_WoW = new WSphere(SPHERE_INIT_X, SPHERE_INIT_Y, SPHERE_INIT_Z, SPHERE_RAD, IsFixed, 43, 0.65);
					m_WoWEngine.addParticle(m_Sphere_WoW);
				}

				{//m_Cube_WoW
//					m_Cube_WoW = new WBox();
//					m_WoWEngine.addParticle(m_Cube_WoW);
				}
			}
		}

		private function update( event:Event ):void {
			m_WoWEngine.step();

			m_Sphere.x = m_Sphere_WoW.px;
			m_Sphere.y = m_Sphere_WoW.py;
 
			m_Scene.renderCamera(m_Camera);
		}

		private function onStageResize(event:Event):void {
			m_Container.x = stage.stageWidth	/ 2;
			m_Container.y = stage.stageHeight / 2;
		}
		
	}
}


ちなみに、JS や AS で長い関数をリファクタリングする1手法 - てっく煮ブログ 跡地をもとに、ローカル関数で球体の作成などを行っている。このおかげで、スコープが限定できて精神的に嬉しい。


さらにちなみに、意味のない中括弧はC++の時のコーディングの癖。AS3だと中で宣言した変数が中括弧のスコープからはみ出るので意味なし。


今日の残りでもう少しWoW-Engineについて調べて終了の予定。明日、いよいよWiiFlashとつなげる実験開始。