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

Alternativa3D Matrix3D interpolation / Zoom to object's face

Alternativa3D 7.6

@author liquid.cow

- testing matrix interpolation for animation
- change the camera position and -target by clicking on an object's face or the stage.
- a bug has been removed, but the transition, well ... sucks
- forked from http://wonderfl.net/c/pNAF
/**
 * Copyright liquid.cow ( http://wonderfl.net/user/liquid.cow )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wERV
 */

// forked from liquid.cow's Alternativa3D / Zoom to object's face
package {
    import alternativ7.engine3d.containers.KDContainer;
    import alternativ7.engine3d.core.Camera3D;
    import alternativ7.engine3d.core.Face;
    import alternativ7.engine3d.core.MouseEvent3D;
    import alternativ7.engine3d.core.Object3D;
    import alternativ7.engine3d.core.RayIntersectionData;
    import alternativ7.engine3d.core.View;
    import alternativ7.engine3d.materials.FillMaterial;
    import alternativ7.engine3d.primitives.Box;

    import gs.*;
    import gs.easing.Cubic;

    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix3D;
    import flash.geom.Vector3D;
    import flash.geom.Point;
    
    /**
     *
     * Alternativa3D 7.6
     *
     * Camera3D, Matrix3D, pointAt
     * @author liquid.cow
     */
    [SWF(backgroundColor="#000000", frameRate="100", width="800", height="600")]
    public class Test6 extends Sprite
    {
        private static const V_CAMERA_INIT : Vector3D = new Vector3D(0, 3000, -4000);
        private static const DEG2RAD       : Number = Math.PI / 180;
        
        private var _container       : KDContainer;
        private var _camera          : Camera3D;
        private var _cameraMatrix    : Matrix3D;
        private var _vMouse3D        : Vector3D;
        private var _clickedFace     : Face;
        private var _targetMatrix    : Matrix3D;
        private var _value           : Number;
        private var _initialMatrix   : Matrix3D;
        
        
        public function Test6() : void {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event=null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            
            _camera = new Camera3D();
            _camera.view = new View(stage.stageWidth, stage.stageHeight);
            addChild(_camera.view);
            
            _camera.x = V_CAMERA_INIT.x;
            _camera.y = V_CAMERA_INIT.y;
            _camera.z = V_CAMERA_INIT.z;

            _targetMatrix = _camera.matrix.clone();
            _targetMatrix.pointAt(new Vector3D(), Vector3D.Z_AXIS, Vector3D.Y_AXIS);
            _camera.matrix = _targetMatrix;
            _cameraMatrix = _targetMatrix.clone();
            _initialMatrix = _targetMatrix.clone();
            
            _container = new KDContainer();
            _container.resolveByAABB = true;
            _container.resolveByOOBB = true;
            _container.addChild(_camera);
        
            _value = 0;
            
            var positions:Vector.<Vector3D> = new Vector.<Vector3D>();
            positions.push(new Vector3D(-500, 0, -500), new Vector3D(-500, -100, 500), new Vector3D(100, -200, -500), new Vector3D(500, -300, 500));
            
            var rotations:Vector.<Number> = new Vector.<Number>();
            rotations.push(45 * DEG2RAD, -45 * DEG2RAD, 0, 25 * DEG2RAD);
            
            var colors:Vector.<uint> = new Vector.<uint>();
            colors.push(0xbf0000, 0xc28a73, 0xeb1e01, 0xba7e47);
            
            for (var i:int = 0; i<4; i++) {
                var material:FillMaterial = new FillMaterial(colors[i], .5, 0, 0x0);
                var box:Box = new Box(200, 100, 300, 1, 1, 1);
                box.x = positions[i].x;
                box.y = positions[i].y;
                box.z = positions[i].z;
                box.rotationY = rotations[i];
                box.setMaterialToAllFaces(material);
                box.addEventListener(MouseEvent3D.CLICK, onClick);
                _container.addChild(box);
            }
            
            _camera.render();
            
            stage.addEventListener(Event.RESIZE, onResize);
            _camera.view.addEventListener(MouseEvent.CLICK, onStageClick);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            addEventListener(Event.ENTER_FRAME, render);
            onResize();
        }
        
        private function onClick(e:MouseEvent3D):void
        {
            var distance:Number = 1100;
            var tempObject:Object3D = e.target as Object3D;
            var vPos:Vector3D = new Vector3D(tempObject.x, tempObject.y, tempObject.z);
            var data:RayIntersectionData = tempObject.intersectRay(e.localOrigin, e.localDirection);
            _clickedFace = data.face;
            
            var v : Vector3D = _clickedFace.normal.clone();
            v.scaleBy(distance);
            v = v.add(new Vector3D(_clickedFace.normal.x * tempObject.boundMaxX, _clickedFace.normal.y * tempObject.boundMaxY, _clickedFace.normal.z * tempObject.boundMaxZ));
            
            var objectTransform:Matrix3D = tempObject.matrix.clone();
            v = objectTransform.transformVector(v);
            
            var m : Matrix3D = new Matrix3D();
            m.appendTranslation(v.x, v.y, v.z);
            
            if (_clickedFace.normal.y != 0) {
                // camera-target-pos is exactly above the object
                var components : Vector.<Vector3D> = m.decompose();
                components[1].x = Math.PI / 2;
                components[1].y = tempObject.rotationY + Math.PI;
                components[1].z = 0;

                m.recompose(components);
            } else {
                m.pointAt(vPos, Vector3D.Z_AXIS, Vector3D.Y_AXIS);
            }

            moveCamera(m);
        }
        
        private function moveCamera(targetMatrix_:Matrix3D) : void 
        {
            _cameraMatrix = _camera.matrix.clone();
            _targetMatrix = targetMatrix_;

            TweenLite.killTweensOf(this);
            _value = 0;
            TweenLite.to(this, 1, {value:1, ease:Cubic.easeInOut});
        }

        private function render( event:Event ) : void 
        {
            _camera.matrix = Matrix3D.interpolate(_cameraMatrix, _targetMatrix, _value);
            _camera.render();
        }
        
        public function onResize(event:Event = null) :void
        {
            _camera.view.width = stage.stageWidth;
            _camera.view.height = stage.stageHeight;
            _camera.fov = 2 * Math.atan2(Math.sqrt(_camera.view.width * _camera.view.width + _camera.view.height * _camera.view.height) / 2, 1100);  
        }
        
        private function onStageClick(event : MouseEvent) : void 
        {
            var a:Array = _camera.view.getObjectsUnderPoint(new Point(_camera.view.mouseX, _camera.view.mouseY));
            if (a.length==0) {
                _clickedFace = null;
                moveCamera(_initialMatrix);
            }
        }
        
        private function onMouseMove(event : MouseEvent) : void {
            if (event.target is Stage) {
                
                var origin:Vector3D = new Vector3D();
                var directionA:Vector3D = new Vector3D();
                var directionB:Vector3D = new Vector3D();
                
                _camera.calculateRay(origin, directionA, _camera.view.width / 2, _camera.view.height / 2);
                _camera.calculateRay(origin, directionB, stage.mouseX, stage.mouseY);
    
                var pos : Vector3D = intersectionPoint(origin, directionB, new Vector3D(0, 0, 0), new Vector3D(0, 1, 0));
                _vMouse3D = new Vector3D(pos.x, pos.y, pos.z);
            }
        }
        
        public static function intersectionPoint(lineStart:Vector3D, lineDirection:Vector3D, planePosition:Vector3D, planeNormal:Vector3D):Vector3D {
            
            var result:Vector3D = new Vector3D();
            var w:Vector3D = lineStart.subtract(planePosition);
            var d:Number = planeNormal.dotProduct(lineDirection);
            var n:Number = -planeNormal.dotProduct(w);
            
            var sI:Number = n / d;
            
            result.x = lineStart.x + (lineDirection.x * sI);
            result.y = lineStart.y + (lineDirection.y * sI);
            result.z = lineStart.z + (lineDirection.z * sI);

            return result;
        }

        public function get value() : Number {
            return _value;
        }

        public function set value(value : Number) : void {
            _value = value;
        }
    }
}