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とつなげる実験開始。