ローカルファイル機能を使った簡単な3Dビューワー
Flash10での機能のローカルファイルへのFileReference機能を使った簡単な3Dビューワーを作成しました。
こんな感じ
http://moeten.info/flex/20081016_fp10Test2/bin-release/test21.html
メタセコイアとcollada形式に対応しています。
テクスチャは対応してません汗
こちらの3Dデーターを使用してみてください。
http://moeten.info/flex/20081016_fp10Test2/bin-release/miku01.zip
簡単な動作ムービーはこちら
ソースはこちら
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="ColladaView()" width="800" height="800" backgroundGradientColors="[0xffffff,0xcccccc]" viewSourceURL="srcview/index.html"> <mx:Script> <![CDATA[ import flash.display.*; import flash.events.*; import org.papervision3d.objects.parsers.Collada; import org.papervision3d.scenes.*; import org.papervision3d.objects.*; import org.papervision3d.cameras.*; import org.papervision3d.materials.*; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.view.Viewport3D; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.materials.special.LineMaterial; import org.papervision3d.core.geom.Lines3D; import org.papervision3d.core.geom.renderables.Line3D; import org.libspark.pv3d.Metasequoia; private var container : Sprite; private var scene : Scene3D; private var camera : Camera3D; private var cameraTarget : DisplayObject3D; private var renderer : BasicRenderEngine; private var viewport : Viewport3D; private var valx : Number = 0; private var valy : Number = 0; private var col : Collada; public function ColladaView():void{ init3D(); addEventListener(Event.ENTER_FRAME, loop3D); addEventListener(Event.RESIZE, onStageResize); addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelHandler); } private function onMouseWheelHandler(evt:MouseEvent):void{ // カメラの前後移動 distance += -10*evt.delta; } private function init3D():void{ //シーン生成 viewport = new Viewport3D( myUI.width , myUI.height , true , false , true , true ); myUI.addChildAt(viewport , 0); renderer = new BasicRenderEngine(); scene = new Scene3D(); //カメラ設定 cameraTarget = new DisplayObject3D(); camera = new Camera3D(); camera.z = - 100; camera.y = 10; setupLine(); } //xyz作成 private function setupLine():void{ var lines:Lines3D = new Lines3D(); var size:int = 50; lines.addLine( new Line3D( lines , new LineMaterial(0xff0000,1) , 1 , new Vertex3D(0,0,-size),new Vertex3D( 0,0,size ) ) ); lines.addLine( new Line3D( lines , new LineMaterial(0x00ff00,1) , 1 , new Vertex3D(0,-size,0),new Vertex3D(0,size,0 ) ) ); lines.addLine( new Line3D( lines , new LineMaterial(0x0000ff,1) , 1 , new Vertex3D(-size,0,0),new Vertex3D(size,0,0 ) ) ); scene.addChild( lines ); } private var distance:Number = 1; private function loop3D( event:Event ):void{ var reach:Number = 0.01; var ease:Number = 0.1; var cameraDistance:Number = distance; camera.x += (Math.sin(mouseX * reach) * cameraDistance - camera.x) * ease; camera.z += (Math.cos(mouseX * reach) * - cameraDistance - camera.z) * ease; camera.y += (Math.sin(mouseY * reach) * cameraDistance - camera.y) * ease; camera.lookAt(cameraTarget); //レンダリング renderer.renderScene(scene, camera, viewport); } private var fr:FileReference; private function onOpen():void{ fr = new FileReference(); var docFilter:FileFilter = new FileFilter("3D Format(.mqo .dae)", "*.mqo;*.dae"); var imagesFilter:FileFilter = new FileFilter("Images (動かないよ!)", "*.jpg;*.gif;*.png"); fr.browse([docFilter,imagesFilter]); fr.addEventListener(Event.SELECT , onSelect ); } private function onSelect(e:Event):void{ txtName.text = "" + fr.name; txtSize.text = "" + fr.size; txtCreationDate.text = "" + fr.creationDate; txtCreator.text = "" + fr.creator; txtModifcationDate.text = "" + fr.modificationDate; txtTtype.text = "" + fr.type; // イベントリスナーを追加 fr.addEventListener(ProgressEvent.PROGRESS,onProgress); fr.addEventListener(Event.COMPLETE,onComplete); fr.load(); // 読み込み処理を開始 } private function onProgress(e:ProgressEvent):void{ trace("読み込んだバイト数:" + e.bytesLoaded + "、 全体のバイト数:" + e.bytesTotal); } private function onComplete(e:Event):void{ scene.removeChildByName("myObject"); var mat:WireframeMaterial = new WireframeMaterial( 0xff0000 ,1,2); if( fr.type == ".mqo" ){ var byteArray:ByteArray = ByteArray( fr.data); var metaseq:Metasequoia = new Metasequoia(); metaseq.buildMetasequoia( byteArray.readMultiByte( byteArray.length ,"shift-jis") , fr.name) ; metaseq.material = mat; scene.addChild( metaseq , "myObject" ); }else if( fr.type == ".dae" ){ var col:Collada = new Collada(XML(fr.data)); col.material = mat scene.addChild( col , "myObject"); } } private function onStageResize(event:Event):void{ } ]]> </mx:Script> <mx:Style> .myTitle{ backgroundColor:#D9D9D9; paddingLeft:5px; } .myTitle2{ color:#ffffff; backgroundColor:#333333; } GridItem{ borderColor:#000000; borderStyle:solid; borderThickness:1; } </mx:Style> <mx:UIComponent id="myUI" width="100%" height="100%"/> <mx:Button click="onOpen()" width="217" height="42" x="10" y="10" label="ファイル選択(.mqo .dae)"/> <mx:Grid x="10" y="60" > <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" styleName="myTitle2"> <mx:Label text="name"/> </mx:GridItem> <mx:GridItem width="100%" height="100%"> <mx:Label id="txtName"/> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" styleName="myTitle2"> <mx:Label text="size"/> </mx:GridItem> <mx:GridItem width="100%" height="100%"> <mx:Label id="txtSize"/> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" styleName="myTitle2"> <mx:Label text="creationDate"/> </mx:GridItem> <mx:GridItem width="100%" height="100%"> <mx:Label id="txtCreationDate"/> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" styleName="myTitle2"> <mx:Label text="creator"/> </mx:GridItem> <mx:GridItem width="100%" height="100%"> <mx:Label id="txtCreator"/> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" styleName="myTitle2"> <mx:Label text="modificationDate"/> </mx:GridItem> <mx:GridItem width="100%" height="100%"> <mx:Label id="txtModifcationDate"/> </mx:GridItem> </mx:GridRow> <mx:GridRow width="100%" height="100%"> <mx:GridItem width="100%" height="100%" styleName="myTitle2"> <mx:Label text="type"/> </mx:GridItem> <mx:GridItem width="100%" height="100%"> <mx:Label id="txtTtype"/> </mx:GridItem> </mx:GridRow> </mx:Grid> </mx:Application>