ローカルファイル機能を使った簡単な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>