Astro15.as (メイン)
package {
    import __AS3__.vec.Vector;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.display.TriangleCulling;
    import flash.events.Event;
    import flash.geom.Matrix3D;
    import flash.geom.Point;
    import flash.geom.Vector3D;
    import flash.geom.PerspectiveProjection;
    import primitives.Sphere;

    [SWF(width="550",height="400",backgroundColor="0x0",frameRate="24")]

    public class Astro15 extends Sprite{
        [(source="assets/panoramic.jpg")]
        private var MoonImage:Class;
        private var _img:Bitmap;
        
        private var _container:Sprite;
        private var _projection:PerspectiveProjection;
        private var _scene:Sprite;
        private var _primitive:Sphere;
        
        //For drawRectangles
        private var _vertices:Vector.<Number>;
        private var _uvtData:Vector.<Number>;
            
        public function Astro15(){
            //canvas
            _container = new Sprite();
            _container.buttonMode = true;
            _container.x = stage.stageWidth/2;
            _container.y = stage.stageHeight/2;
            addChild(_container);
            
            //Projection matrix
            _projection = new PerspectiveProjection();
            _projection.fieldOfView = 60;
            
            //Scene in motion
            _scene = new Sprite();
            _scene.transform.matrix3D = new Matrix3D();
            
            //3D-object
            _primitive = new Sphere(50);
            
            //Texture on the primitive
            _img = Bitmap(new MoonImage());
            
            addEventListener(Event.ENTER_FRAME,renderScene);
        }
        
        private function renderScene(e:Event):void{
            rotate(_scene);
            
            var world:Matrix3D = _scene.transform.matrix3D.clone();
            world.append(_projection.toMatrix3D());
            var projectedVector3D:Vector.<Vector3D> = project3D(_primitive.vertices,world);
            zsort(projectedVector3D,_primitive.uvtData);

            _container.graphics.clear();
            _container.graphics.beginBitmapFill(_img.bitmapData);
            _container.graphics.drawTriangles(_vertices,null,_uvtData,TriangleCulling.POSITIVE);
            _container.graphics.endFill();
        }
        
        private function project3D(vertices:Vector.<Vector3D>,world:Matrix3D):Vector.<Vector3D>{
            var results:Vector.<Vector3D> = new Vector.<Vector3D>();
            for (var i:int=0; i<vertices.length; i++){
                var vertex:Vector3D = vertices[i];
                var v:Vector3D = world.transformVector(vertex);
                results.push(v);
            }
            return results;
        }
        
        private function zsort(vertices:Vector.<Vector3D>,uvtData:Vector.<Number>):void{
            var objects:Array = new Array();
            
            for (var i:int=0; i<vertices.length; i+=3){
                var v0:Vector3D = vertices[i];
                var v1:Vector3D = vertices[i+1];
                var v2:Vector3D = vertices[i+2];
                var avg:Number = (v0.z + v1.z + v2.z)/3;
                
                //arg "uvtData" has data twice as many as "vertices" does.
                var j:int = i*2;
                var uvt0:Point = new Point(uvtData[j],uvtData[j+1]);
                var uvt1:Point = new Point(uvtData[j+2],uvtData[j+3]);
                var uvt2:Point = new Point(uvtData[j+4],uvtData[j+5]);
            
                objects.push({v0:v0,v1:v1,v2:v2,p0:uvt0,p1:uvt1,p2:uvt2,zPos:avg});
            }
            
            objects.sortOn("zPos",Array.DESCENDING | Array.NUMERIC);
            
            _vertices = new Vector.<Number>();
            _uvtData = new Vector.<Number>();
            for each (var obj:Object in objects){
                //Set data for drawRectangles
                _vertices.push(obj.v0.x,obj.v0.y, obj.v1.x,obj.v1.y, obj.v2.x,obj.v2.y);
                _uvtData.push(obj.p0.x,obj.p0.y, obj.p1.x,obj.p1.y, obj.p2.x,obj.p2.y);
            }
        }
        
        private function rotate(target:Sprite):void{
            var dx:Number = (mouseX - stage.stageWidth/2);
            var dy:Number = (mouseY - stage.stageHeight/2);
            target.rotationX = 0.5*dy;
            target.rotationY = -0.8*dx;
        }    
    }
}
Sphere.as (プリミティブ)
package primitives{
    import __AS3__.vec.Vector;
    import flash.geom.Vector3D;
    
    public class Sphere{
        private var _vertices:Vector.<Vector3D>;
        private var _uvtData:Vector.<Number>; 
        
        private const DIF:Number = 10;
        private var tMin:Number = 5;
        private var tMax:Number = 180 - tMin;
        private var pMin:Number = 0;
        private var pMax:Number = 360;
        private var pi:Number = Math.PI;
        
        public function Sphere(r:Number){
            _vertices = new Vector.<Vector3D>();
            _uvtData = new Vector.<Number>();
            
            for (var t:int=tMin; t<tMax; t+=DIF){
                for (var p:int=pMin; p<pMax; p+=DIF){
                    var x1:Number = r*Math.sin(t*pi/180)*Math.cos(p*pi/180);
                    var y1:Number = -r*Math.cos(t*pi/180);
                    var z1:Number = r*Math.sin(t*pi/180)*Math.sin(p*pi/180);
                    var xPos1:Number = (p-pMin)/(pMax-pMin);
                    var yPos1:Number = (t-tMin)/(tMax-tMin);
                    
                    var x2:Number = r*Math.sin((t+DIF)*pi/180)*Math.cos(p*pi/180);
                    var y2:Number = -r*Math.cos((t+DIF)*pi/180);
                    var z2:Number = r*Math.sin((t+DIF)*pi/180)*Math.sin(p*pi/180);
                    var xPos2:Number = (p-pMin)/(pMax-pMin);
                    var yPos2:Number = ((t+DIF)-tMin)/(tMax-tMin);
                    
                    var x3:Number = r*Math.sin(t*pi/180)*Math.cos((p+DIF)*pi/180);
                    var y3:Number = -r*Math.cos(t*pi/180);
                    var z3:Number = r*Math.sin(t*pi/180)*Math.sin((p+DIF)*pi/180);
                    var xPos3:Number = ((p+DIF)-pMin)/(pMax-pMin);
                    var yPos3:Number = (t-tMin)/(tMax-tMin);
                    
                    var x4:Number = r*Math.sin((t+DIF)*pi/180)*Math.cos((p+DIF)*pi/180);
                    var y4:Number = -r*Math.cos((t+DIF)*pi/180);
                    var z4:Number = r*Math.sin((t+DIF)*pi/180)*Math.sin((p+DIF)*pi/180);
                    var xPos4:Number = ((p+DIF)-pMin)/(pMax-pMin);
                    var yPos4:Number = ((t+DIF)-tMin)/(tMax-tMin);
                    
                    var v1:Vector3D = new Vector3D(x1,y1,z1);
                    var v2:Vector3D = new Vector3D(x2,y2,z2);
                    var v3:Vector3D = new Vector3D(x3,y3,z3);
                    var v4:Vector3D = new Vector3D(x4,y4,z4);
                    
                    _vertices.push(v1,v2,v3, v3,v2,v4);
                    _uvtData.push(xPos1,yPos1,xPos2,yPos2,xPos3,yPos3,xPos3,yPos3,xPos2,yPos2,xPos4,yPos4);                
                }
            }    
        }
        
        public function get vertices():Vector.<Vector3D>{
            return _vertices;
        }
        
        public function get uvtData():Vector.<Number>{
            return _uvtData;
        }
    }
}
Powered by blog Boreal Kiss 2008.