In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: forked from: (Away3dlite) 지오데식 Sphere

Get Adobe Flash player
by kjkmr 25 Mar 2014
    Embed
/**
 * Copyright kjkmr ( http://wonderfl.net/user/kjkmr )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7bYK
 */

// forked from xzardaz's forked from: (Away3dlite) 지오데식 Sphere 
// forked from jidolstar's (Away3dlite) 지오데식 Sphere 
/**
 * Away3d Lite GeodesicSphere Test
 *
 * 
 * texture http://visibleearth.nasa.gov/
 *
 * @author Yongho, Ji
 * @see http://blog.jidolstar.com/589
 * @see http://blog.jidolstar.com/643
 */
package {
    import com.bit101.components.*;
    
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import flash.text.*;
    import flash.ui.*;
    
    import net.hires.debug.Stats;
    
    [SWF(width=450, height=450, backgroundColor="#000000")]
    public class away3dlite_geodesic_sphere extends Sprite {
        private var _view:SphereView;
        private var _radius:Number=100;
        private var _fractures:Number=5;
        private var _showFrame:Boolean=true;
        
        public function away3dlite_geodesic_sphere() {
            super();
            stage.align=StageAlign.TOP_LEFT;
            stage.scaleMode=StageScaleMode.NO_SCALE;
            stage.frameRate=60;
            createSphereView();
            stage.addChild(new Stats());
        }
        
        private function createSphereView():void {
            var loader:Loader=new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void {
                var texture:BitmapData=Bitmap(loader.contentLoaderInfo.content).bitmapData;
                _view=new SphereView(_radius, _fractures, _showFrame, texture);
                stage.addChild(_view);
                createSphereViewController();
            }); 
            loader.load(new URLRequest("http://assets.wonderfl.net/images/related_images/d/d6/d6ac/d6ac1b471af71d05cd1531d9c4f7f5a7f040afbb"), new LoaderContext(true));
        }
        
        private function createSphereViewController():void {
            var vertexCountLabel:Label=new Label(stage, 100, 86, "");
            var surfaceCountLabel:Label=new Label(stage, 180, 86, "");
            function updateCount():void {
                vertexCountLabel.text="vertex : " + String(_view.getVertexCount());
            }
            new Label(stage, 100, 10, "SHAPE");
            var fractureSlider:HUISlider=new HUISlider(stage, 100, 26, "fractures", function(e:Event):void {
                var fracture:Number=Math.round(e.target.value);
                if (fracture == _fractures)
                    return;
                _fractures=fracture;
                _view.createSphere(_radius, _fractures, _showFrame);
                updateCount();
            });
            var radiusSlider:HUISlider=new HUISlider(stage, 100, 46, "Radius", function(e:Event):void {
                var radius:Number=Math.round(e.target.value);
                if (radius == _radius)
                    return;
                _radius=radius;
                _view.createSphere(_radius, _fractures, _showFrame);
                updateCount();
            });
            var viewFrameCheckBox:CheckBox=new CheckBox(stage, 100, 66, "Show Wire Frame", function(e:Event):void {
                _showFrame=viewFrameCheckBox.selected;
                _view.createSphere(_radius, _fractures, _showFrame);
            });
            viewFrameCheckBox.selected=_showFrame;
            radiusSlider.minimum=10;
            radiusSlider.maximum=800;
            radiusSlider.labelPrecision=0;
            radiusSlider.value=_radius;
            fractureSlider.minimum=0;
            fractureSlider.maximum=10;
            fractureSlider.labelPrecision=0;
            fractureSlider.value=_fractures;
            updateCount();
        }
    }
}

import away3dlite.arcane;
import away3dlite.cameras.*;
import away3dlite.containers.*;
import away3dlite.containers.*;
import away3dlite.core.base.*;
import away3dlite.materials.*;
import away3dlite.primitives.*;

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

use namespace arcane;

/**
 * Sphere를 보여주는 화면
 */
class SphereView extends Sprite {
    //[Embed(source="../assets/earthmap1k.jpg")]
    //private var SKY:Class;    
    private var scene:Scene3D;
    private var camera:Camera3D
    private var view:View3D;
    private var _sphere:GeodesicSphere;
    private var _frameSphere:GeodesicSphere;
    private var _material:BitmapMaterial;
    private var _vx:Number=0;
    private var _vy:Number=0;
    private var rotX:Matrix3D=new Matrix3D();
    private var rotY:Matrix3D=new Matrix3D();
    private var rot:Matrix3D=new Matrix3D();
    
    public function SphereView($radius:Number, $fractures:Number, $viewframe:Boolean, $texture:BitmapData) {
        _material=new BitmapMaterial($texture);
        _material.smooth=true;
        scene=new Scene3D();
        camera=new Camera3D(1,1000);
        view=new View3D(scene, camera);
        addChild(view);
        createSphere($radius, $fractures, $viewframe);
        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }
    
    private function onAddedToStage(event:Event):void {
        addEventListener(Event.ENTER_FRAME, onRenderTick);
        removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        addEventListener(Event.REMOVED_FROM_STAGE, onRemovedToStage);
        view.x=stage.stageWidth / 2;
        view.y=stage.stageHeight / 2;
    }
    
    private function onRemovedToStage($event:Event):void {
        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedToStage);
        removeEventListener(Event.ENTER_FRAME, onRenderTick);
    }
    
    public function createSphere($radius:Number, $fractures:Number, $showFrame:Boolean):void {
        if (_sphere) {
            scene.removeChild(_sphere);
            _sphere = null;
        }
        if (_frameSphere) {
            scene.removeChild(_frameSphere);
            _frameSphere = null;
        }
        _sphere=new GeodesicSphere(_material, $radius, $fractures);
        scene.addChild(_sphere);
        
        if ($showFrame) {
            _frameSphere=new GeodesicSphere(new WireframeMaterial(0xffffff, 0.2), $radius + 1, $fractures);
            scene.addChild(_frameSphere);
        }
    }
    
    protected function onRenderTick($event:Event=null):void {
        _vx+=((mouseY / stage.stageHeight - 0.5) * 5 - _vx) * 0.3;
        _vy+=(-(mouseX / stage.stageWidth - 0.5) * 5 - _vy) * 0.3;
        //http://blog.federicocalvo.com/2009/03/papervision-3d-sphere-globla-axis.html
        var tempMatrix:Matrix3D=_sphere.transform.matrix3D;
        rotX.identity();
        rotX.appendRotation(_vx, Vector3D.X_AXIS);
        rotY.identity();
        rotY.appendRotation(_vy, Vector3D.Y_AXIS);
        rot.identity();
        rot.append(rotX);
        rot.append(rotY);
        tempMatrix.append(rot);
        _sphere.transform.matrix3D=tempMatrix.clone();
        if (_frameSphere) {
            _frameSphere.transform.matrix3D=tempMatrix.clone();
        }
        view.render();
    }
    
    public function getVertexCount():int {
        if (!_sphere)
            return 0;
        return _sphere.vertices.length;
    }
}

/**
 * Creates a 3d Geodesc sphere primitive.
 */
class GeodesicSphere extends AbstractPrimitive {
    private var _radius:Number;
    private var _fractures:Number;
    private var _yUp:Boolean=true;
    
    /**
     * @inheritDoc
     */
    protected override function buildPrimitive():void {
        super.buildPrimitive();
        
        var D2R:Number=Math.PI / 180; //Degree->Radian
        var R2D:Number=180 / Math.PI; //Radian->Degree
        var TPI:Number=Math.PI * 2;
        var PI:Number=Math.PI;
        var HPI:Number=Math.PI / 2;
        var hnLat:int=fractures + 1; //위도 방향 쪼갠수/2
        var nLat:int=2 * hnLat; //위도 방향 쪼갠수 
        var nLon:int; //위도에 대한 경도 방향 쪼갠수 
        var lon:Number; //경도 (단위:라디안)
        var lat:Number; //위도(단위:라디안)
        var dLat:Number=180 / nLat * D2R; //위도 간격(단위:라디안) 
        var dLon:Number; //경도  간격(단위:라디안)
        var i:int;
        var j:int;
        var x:Number;
        var y:Number;
        var z:Number;
        var sinLat:Number;
        var cosLat:Number;
        var sinLon:Number;
        var cosLon:Number;
        var u:Number;
        var v:Number;
        
        ////////////////////////////////
        // Vertex, UVT 데이타 만들기
        ////////////////////////////////    
        
        // latitude -90->0 : 
        x=0;
        y=0;
        z=-_radius;
        _yUp ? _vertices.push(x, -z, y) : _vertices.push(x, y, z);
        _uvtData.push(0, 0, 1);
        for (i=0; i < hnLat; i++) {
            nLon=4 * (i + 1); //경도방향 꼭지점수 4, 8, 12, 16, 20...
            dLon=360 / nLon * D2R;
            lat=-HPI + (i + 1) * dLat;
            v=(HPI + lat) / PI;
            sinLat=Math.sin(lat);
            cosLat=Math.cos(lat);
            z=radius * sinLat;
            for (j=0; j <= nLon; j++) {
                lon=j * dLon;
                sinLon=Math.sin(lon);
                cosLon=Math.cos(lon);
                x=radius * cosLat * cosLon;
                y=radius * cosLat * sinLon;
                u=lon / TPI;
                _yUp ? _vertices.push(x, -z, y) : _vertices.push(x, y, z);
                _uvtData.push(u, v, 1);
            }
        }
        
        //latitude 0 -> 90
        for (i=1; i < hnLat; i++) {
            nLon=4 * (hnLat - i);
            dLon=360 / nLon * D2R;
            lat=dLat * i;
            v=(HPI + lat) / PI;
            sinLat=Math.sin(lat);
            cosLat=Math.cos(lat);
            z=radius * sinLat;
            for (j=0; j <= nLon; j++) {
                lon=j * dLon;
                sinLon=Math.sin(lon);
                cosLon=Math.cos(lon);
                x=radius * cosLat * cosLon;
                y=radius * cosLat * sinLon;
                u=lon / TPI;
                _yUp ? _vertices.push(x, -z, y) : _vertices.push(x, y, z);
                _uvtData.push(u, v, 1);
            }
        }
        x=0;
        y=0;
        z=_radius;
        _yUp ? _vertices.push(x, -z, y) : _vertices.push(x, y, z);
        _uvtData.push(0, 1, 1);
        
        
        ////////////////////////////////
        // Face 만들기 
        ////////////////////////////////        
        var k:int;
        var pt0:int, pt1:int, pt2:int; //하나의 폴리곤을 생성하는 Vertex의 index값 
        var u_idx_start:int, u_idx_end:int, u_idx:int; //상단 index 
        var l_idx_start:int, l_idx_end:int, l_idx:int; //하단 index
        var isUp:int; //지그재그로 컬링 폴리곤을 생성하기 위해 
        var tris:int; //한개 분면에서 해당 적위에 대한 면의 수 
        var triIdx:int; //한개 분면에서 해당 적위에 대한 면의 수만큼 index를 증가하기 위해 사용 
        
        //Latitude -90->0        
        tris=1;
        u_idx_start=0;
        u_idx_end=0;
        for (i=0; i < hnLat; ++i) {
            //위도 간격으로 상하  시작index와 끝 index를 지정 
            l_idx_start=u_idx_start;
            l_idx_end=u_idx_end;
            u_idx_start+=4 * i + 1;
            u_idx_end+=4 * (i + 1) + 1;
            l_idx=l_idx_start;
            u_idx=u_idx_start;
            
            //4분면을 따라 Face를 만들도록 한다. 
            for (k=0; k < 4; ++k) {
                isUp=1;
                //한개 분면에 대한 Face의 index를 만들어준다. 
                for (triIdx=0; triIdx < tris; ++triIdx) {
                    if (isUp === 1) {
                        pt0=l_idx;
                        pt2=u_idx;
                        u_idx++;
                        pt1=u_idx;
                        isUp=0;
                    } else {
                        pt0=u_idx;
                        pt1=l_idx;
                        l_idx++;
                        pt2=l_idx;
                        isUp=1;
                    }
                    _indices.push(pt0, pt1, pt2);
                    //_faceLengths.push(3);
                }
            }
            tris+=2; //한개의 분면에서 해당 적위에 대한 면의 수는 2씩 증가한다. 
        }
        
        //Latitude 0 -> 90         
        for (i=hnLat - 1; i >= 0; i--) {
            l_idx_start=u_idx_start;
            l_idx_end=u_idx_end;
            u_idx_start=u_idx_start + 4 * (i + 1) + 1;
            u_idx_end=u_idx_end + 4 * i + 1;
            tris-=2;
            u_idx=u_idx_start;
            l_idx=l_idx_start;
            for (k=0; k < 4; ++k) {
                isUp=0;
                for (triIdx=0; triIdx < tris; triIdx++) {
                    if (isUp === 1) {
                        pt0=l_idx;
                        pt2=u_idx;
                        u_idx++;
                        pt1=u_idx;
                        isUp=0;
                    } else {
                        pt0=u_idx;
                        pt1=l_idx;
                        l_idx++;
                        pt2=l_idx;
                        isUp=1;
                    }
                    _indices.push(pt0, pt1, pt2);
                    //_faceLengths.push(3);
                }
            }
        }
    }
    
    /**
     * Defines the radius of the sphere. Defaults to 100.
     */
    public function get radius():Number {
        return _radius;
    }
    
    public function set radius(val:Number):void {
        if (_radius == val)
            return;
        
        _radius=val;
        _primitiveDirty=true;
    }
    
    /**
     * Defines the fractures of the sphere. Defaults to 2.
     */
    public function get fractures():Number {
        return _fractures;
    }
    
    public function set fractures(val:Number):void {
        if (_fractures == val)
            return;
        
        _fractures=val;
        _primitiveDirty=true;
    }
    
    /**
     * Defines whether the coordinates of the plane points use a yUp orientation (true) or a zUp orientation (false). Defaults to true.
     */
    public function get yUp():Boolean {
        return _yUp;
    }
    
    public function set yUp(val:Boolean):void {
        if (_yUp == val)
            return;
        
        _yUp=val;
        _primitiveDirty=true;
    }
    
    /**
     * Creates a new <code>GeodesicSphere</code> object.
     */
    public function GeodesicSphere(material:Material=null, radius:Number=100, fractures:int=2, yUp:Boolean=true) {
        super(material);
        
        _radius=radius;
        _fractures=fractures;
        _yUp=yUp;
        bothsides=false;
        
        type="GeodesicSphere";
        url="primitive";
    }
}