forked from: [Alternativa3D 7.6] test

by erokare forked from [Alternativa3D 7.6] test (diff: 238)
Orbital 1 *
♥0 | Line 172 | Modified 2012-10-23 16:11:48 | MIT License
play

ActionScript3 source code

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

// forked from tencho's [Alternativa3D 7.6] test
/** Orbital 1 * */
package {
    import alternativ7.engine3d.core.Object3D;
    import alternativ7.engine3d.core.Object3DContainer;
    import alternativ7.engine3d.materials.FillMaterial;
    import alternativ7.engine3d.objects.Mesh;
    import alternativ7.engine3d.primitives.Box;    
    
    import flash.display.*;
    import flash.events.*;
    import flash.geom.Vector3D;

    public class Orbital1 extends Sprite {
        
        private var _scene:Scene3D;
        private var _dragger:SphericalDragger;
         
        public function Orbital1() {
            
            _scene = new Scene3D(Scene3D.NOSORT, 465, 465);
            _scene.camera.fov = 75 * Math.PI / 180;
            
            _dragger = new SphericalDragger(_scene.display, 0, 2, 150);
            _dragger.dragEnabled = true;
            _dragger.angle.speed = _dragger.rotation.speed = 0.65;
            _dragger.angle.setLimit(-90, 90);
            _dragger.distance.setLimit(0, 420);
            
            addChild(_scene.display);
            
            var box:Box = new Box(20, 20, 20);
            var modelMaterial:FillMaterial = new FillMaterial(0x00dd66, 1, 1, 0x00ffaa);
            box.setMaterialToAllFaces (modelMaterial);
            _scene.root.addChild(box);  
            
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        /*  */
        private function onEnterFrame(e:Event = null):void {
            var v:Vector3D = _dragger.position;
            _scene.controller.setObjectPosXYZ(v.x, v.y, v.z);
            _scene.controller.lookAtXYZ(0, 0, 0);
            _scene.render();
        }
        
    }
    
}

import alternativ7.engine3d.containers.*;
import alternativ7.engine3d.controllers.SimpleObjectController;
import alternativ7.engine3d.core.*;
import flash.display.*;
import flash.events.*;
import flash.geom.*;

class Scene3D {
    public var display:Sprite = new Sprite();
    public var bg:Sprite = new Sprite();
    public var root:Object3DContainer;
    public var camera:Camera3D;
    public var controller:SimpleObjectController;
    private var _displayRect:Rectangle = new Rectangle();
    
    static public const DISTANCE:String = "distance";
    static public const BSP:String = "bsp";
    static public const KD:String = "kd";
    static public const CONFLICT:String = "conflict";
    static public const NOSORT:String = "nosort";
    
    public function Scene3D(container:String = CONFLICT, width:Number = 465, height:Number = 465, transparent:Boolean = false, bgColor:uint = 0x000000, bgAlpha:Number = 1) {
        switch(container) {
            case DISTANCE: root = new DistanceSortContainer(); break;
            case BSP: root = new BSPContainer(); break;
            case KD: root = new KDContainer(); break;
            case CONFLICT: root = new ConflictContainer(); break;
            case NOSORT: root = new Object3DContainer(); break;
            default: root = new ConflictContainer();
        }
        camera = new Camera3D();
        camera.view = new View(width, height);
        camera.fov = 60 * Math.PI / 180;
        root.addChild(camera);
        display.addChild(bg);
        display.addChild(camera.view);
        display.addEventListener(Event.ADDED_TO_STAGE, onAddedStage);
        controller = new SimpleObjectController(display, camera, 1);
        controller.unbindAll();
        
        setBgColor(transparent, bgColor, bgAlpha);
        setSize(width, height);
    }
    
    public function setSize(width:Number, height:Number):void {
        bg.width = camera.view.width = width;
        bg.height = camera.view.height = height;
    }
    
    public function setBgColor(transparent:Boolean = false, bgColor:uint = 0x000000, bgAlpha:Number = 1):void {
        bg.graphics.beginFill(bgColor, bgAlpha);
        bg.graphics.drawRect(0, 0, 100, 100);
        bg.graphics.endFill();
        bg.visible = !transparent;
    }
    
    private function onAddedStage(e:Event):void {
        display.removeEventListener(Event.ADDED_TO_STAGE, onAddedStage);
        render();
    }
    
    public function render():void {
        if (camera.view.stage) camera.render();
    }
    
}

/***/
class SphericalDragger extends EventDispatcher {
    
    public var distance:Range = new Range();
    public var rotation:Range = new Range();
    public var angle:Range = new Range();
    public var dragEnabled:Boolean = true;
    public var wheelEnabled:Boolean = true;
    
    private var _eventObject:InteractiveObject;
    private var _clickPoint:Point;
    private var _position:Vector3D = new Vector3D();
    private const RADIAN:Number = Math.PI / 180;
    
    public var onMovePosition:Function;
    public function get position():Vector3D { return _position; }
    
    public function SphericalDragger(obj:InteractiveObject, rotation:Number = 0, angle:Number = 30, distance:Number = 1000) {
        this.distance.position = distance;
        this.distance.speed = 1.2;
        this.angle.position = angle;
        this.angle.min = -(this.angle.max = 89);
        this.rotation.position = rotation;
        _eventObject = obj;
        _eventObject.addEventListener(MouseEvent.MOUSE_DOWN, onMsDown);
        _eventObject.addEventListener(MouseEvent.MOUSE_WHEEL, onMsWheel);
        updatePosition();
    }
    
    public function notify():void {
        dispatchEvent(new Event(Event.CHANGE));
        if (onMovePosition != null) onMovePosition(_position);
    }
    
    private function onMsWheel(e:MouseEvent):void {
        if (!dragEnabled || !wheelEnabled) return;
        distance.position *= Math.pow(distance.speed, (e.delta < 0)? 1 : -1);
        distance.checkLimit();
        updatePosition();
    }
    
    private function onMsDown(e:MouseEvent):void {
        if (!dragEnabled) return;
        _eventObject.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMsMove);
        _eventObject.stage.addEventListener(MouseEvent.MOUSE_UP, onMsUp);
        rotation.prev = rotation.position;
        angle.prev = angle.position;
        _clickPoint = new Point(_eventObject.mouseX, _eventObject.mouseY);
    }
    
    private function onMsMove(e:MouseEvent):void {
        if (!dragEnabled) return;
        var dragOffset:Point = new Point(_eventObject.mouseX, _eventObject.mouseY).subtract(_clickPoint);
        rotation.position = rotation.prev - dragOffset.x * rotation.speed;
        rotation.checkLimit();
        angle.position = angle.prev + dragOffset.y * angle.speed;
        angle.checkLimit();
        updatePosition();
    }
    
    private function onMsUp(...rest):void {
        _eventObject.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMsMove);
        _eventObject.stage.removeEventListener(MouseEvent.MOUSE_UP, onMsUp);
        updatePosition();
    }
    
    private function updatePosition():void {
        var per:Number = Math.cos(RADIAN * angle.position);
        var px:Number = Math.cos(RADIAN * rotation.position) * distance.position * per;
        var py:Number = Math.sin(RADIAN * rotation.position) * distance.position * per;
        var pz:Number = Math.sin(RADIAN * angle.position) * distance.position;
        _position = new Vector3D(px, py, pz);
        notify();
    }
    
}

class Range {
    
    public var min:Number = NaN;
    public var max:Number = NaN;
    public var prev:Number = NaN;
    public var speed:Number = 1;
    public var position:Number = 0;
    
    public function Range() {
    }
    
    public function setLimit(min:Number, max:Number):void {
        this.min = min, this.max = max;
    }
    
    public function checkLimit():void {
        if (!isNaN(min) && position < min) position = min;
        else if (!isNaN(max) && position > max) position = max;
    }
    
}