forked from: 3d study

by yd_niku forked from 3d study (diff: 15)
♥0 | Line 118 | Modified 2010-08-01 19:36:27 | MIT License | (replaced)
play

ActionScript3 source code

/**
 * Copyright yd_niku ( http://wonderfl.net/user/yd_niku )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/iXj2
 */

// forked from yd_niku's 3d study
package {
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    public class FlashTest extends Sprite {
        public var world:Matrix3D = new Matrix3D();
        public var view:Matrix3D = new Matrix3D();
        public var projection:PerspectiveProjection = new PerspectiveProjection();
        
        public var niku:DisplayObject3D;
        
        public function FlashTest() {
            x = y = 232;
            
            projection.fieldOfView = 60;
            
            niku = new DisplayObject3D( new NikuModel() );
            
            view.appendTranslation(0,0,-500);
            //world.appendRotation( 180, Vector3D.X_AXIS );
            
            var resource:BitmapDataResource = new BitmapDataResource(ResourceMap.IMG);
            resource.addEventListener( Event.COMPLETE, onLoadTexture );
            resource.load();
        }
        public var texture:BitmapData;
        private function onLoadTexture( e:Event ):void {
            texture = BitmapDataResource.getResource(ResourceMap.IMG);
            
            niku.texture = texture;
            //niku.model.transform.appendTranslation( 0, 0, 100 );
            
            addEventListener( Event.ENTER_FRAME, render )
        }
        public function render(e:Event = null ):void{
            //view.appendRotation( 1, Vector3D.X_AXIS );
            niku.model.transform.appendRotation(3, Vector3D.Y_AXIS);
            
            var mat:Matrix3D = world.clone();
            mat.append( view );
            mat.append( projection.toMatrix3D() );
            
            graphics.clear();
            niku.render( graphics, mat );
        }
    }
}

import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.net.*;
import flash.utils.*;
import flash.system.*;

// この辺の構造は psyarkさんのコードを大いに参考にさせてもらってます。
// モデルとテクスチャを持ったレンダリング用オブジェクト
class DisplayObject3D {
    public var model:Model3D;
    public var texture:BitmapData;
    
    public function DisplayObject3D( model:Model3D=null, texture:BitmapData = null ) {
        this.model = model || new Model3D();
        this.texture = texture;
    }
    
    public function render( graphics:Graphics, projection:Matrix3D ):void {
        // グローバル座標に変換されたメッシュオブジェクト(のコピー)を取得
        var geo:Geometory3D = model.getGeometory();
        
        // 演算用にコピーしてProjection用のMatrixでスクリーン投影
        var trianglePath:GraphicsTrianglePath = new GraphicsTrianglePath();
        trianglePath.vertices = new Vector.<Number>;
        trianglePath.indices   = geo.indices.slice();
        trianglePath.uvtData = geo.uvData.slice();
        trianglePath.culling = TriangleCulling.POSITIVE;
        Utils3D.projectVectors( projection, geo.vertices, trianglePath.vertices, trianglePath.uvtData );
        
        //trace( trianglePath.vertices );
        //trace( trianglePath.uvtData );
        // テクスチャとあわせて描画
        var data:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
        data[0] = new GraphicsBitmapFill( texture, null, false, true);
        data[1] = trianglePath;
        graphics.drawGraphicsData( data );
    }
    
}

// メッシュと回転情報をもったモデル
class Model3D {
     public var mesh:Geometory3D = new Geometory3D();
     public var transform:Matrix3D = new Matrix3D();
     public function Model3D() {
     }
     // オリジナルのメッシュをコピーして(非破壊)回転を反映させてたメッシュを返す
     public function getGeometory():Geometory3D {
         var result:Geometory3D = new Geometory3D();
         result.vertices = new Vector.<Number>();
         transform.transformVectors( mesh.vertices, result.vertices );
         result.indices= mesh.indices.slice();
         result.uvData= mesh.uvData.slice();
         return result;
     }
}

// メッシュ単体
class Geometory3D{
     public var vertices:Vector.<Number> = new Vector.<Number>(0, false);
     public var indices:Vector.<int> = new Vector.<int>(0, false);
     public var uvData:Vector.<Number> = new Vector.<Number>(0, false);
     
     public function Geometory3D(){
     }
}

class NikuModel extends Model3D{
     public function NikuModel():void {
        mesh.vertices.push( -50, -50, 0);
        mesh.vertices.push(  50, -50, 0);
        mesh.vertices.push( -50,  50, 0);
        mesh.vertices.push(  50,  50, 0);
            
        mesh.indices.push( 0, 1, 2 );
        mesh.indices.push( 2, 1, 3 );
        
        mesh.uvData.push( 0,0,0, 1,0,0, 0,1,0, 1,1,0 );  
     }
}


internal class ResourceMap {
    public static const IMG:String = "http://assets.wonderfl.net/images/related_images/7/74/741f/741fc0b9afc2ddb3db777a9d2c3c4705dc064054";
}

internal class BitmapDataResource extends EventDispatcher {
        private static var _resources:Dictionary = new Dictionary();
        
        private var _key: String;
        public function BitmapDataResource ( key:String ) {
            _key = key;
        }
        public function load():void {
            var req:URLRequest = new URLRequest(_key);
            
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onLoadComplete );
            loader.load( req, new LoaderContext(true) );
        }
        private function onLoadComplete(e:Event):void {
            var loaderInfo :LoaderInfo = e.target as LoaderInfo;
            var content:Bitmap = Loader( loaderInfo.loader ).content as Bitmap;
            _resources[ _key ] = content.bitmapData;
            
            dispatchEvent( new Event(Event.COMPLETE) );
        }
        
        public static function getResource( key:String ) :*{
            return _resources[ key ] as BitmapData;
        }
}