package
{
import away3d.containers.View3D;
import away3d.core.math.Number3D;
import away3d.events.MouseEvent3D;
import away3d.materials.BitmapMaterial;
import away3d.primitives.Sphere;
import away3d.debug.AwayStats;
import away3d.core.utils.Cast;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BitmapFilter;
import flash.filters.DropShadowFilter;
import flash.geom.Matrix;
import flash.display.*;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFormat;
/**
* ...
* @author Tony Lukasavage - SavageLook.com
*/
[SWF("#000000", height="600", width="800", frameRate="60")]
public class reflect_away3d extends Sprite
{
private var _view:View3D;
private var _matrix:Matrix = new Matrix();
private var _bitmapReflect:Bitmap = new Bitmap();
private var _bitmapReflectGradient:Sprite = new Sprite();
private var _bmd:BitmapData;
private var _sphere:Sphere;
private var _titleText:TextField;
private var _drawn:DisplayObject;
private var _bounds:Rectangle;
private var _yscale:Number = 1;
private var _xscale:Number = 1;
private var _rotX:Number = 0;
private var _rotY:Number = 0;
private var _overSphere:Boolean = false;
private var _distance:Number = 92;
[Embed( "earth.jpg")] private var earthImage:Class;
public function reflect_away3d():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;
stage.quality = StageQuality.HIGH;
_view = new View3D();
_view.x = stage.stageWidth / 2;
_view.y = stage.stageHeight / 2;
_view.camera.position = new Number3D(0, 0, -1000);
_view.camera.lookAt(new Number3D(0, 0, 0));
_sphere = new Sphere( { material:new BitmapMaterial(Cast.bitmap(earthImage), { smooth:true } ),
segmentsH:20, segmentsW:20 } );
_sphere.useHandCursor = true;
_view.scene.addChild(_sphere);
_bitmapReflectGradient.cacheAsBitmap = true;
_bitmapReflect.cacheAsBitmap = true;
_bitmapReflect.mask = _bitmapReflectGradient;
_titleText = new TextField();
_titleText.text = "SavageLook.com -- Reflection in Away3D";
_titleText.setTextFormat(new TextFormat("arial", 14, 0xffffff, false, false, false, "https://savagelook.com/blog/away3d/reflection-in-away3d"));
_titleText.x = 10;
_titleText.y = stage.stageHeight - 30;
_titleText.width = _titleText.textWidth * 1.1;
_titleText.filters = [new DropShadowFilter(3,45,0xffffff,1,4,4)];
this.addChild(_view);
this.addChild(new AwayStats());
this.addChild(_bitmapReflect);
this.addChild(_bitmapReflectGradient);
this.addChild(_titleText);
this.addEventListener(Event.ENTER_FRAME, _onEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_MOVE, _onMouseMove);
stage.addEventListener(MouseEvent.MOUSE_UP, function(e:MouseEvent):void { _overSphere = false; } );
_sphere.addEventListener(MouseEvent3D.MOUSE_DOWN, function(e:MouseEvent3D):void { _overSphere = true; } );
}
private function _onMouseMove(e:MouseEvent):void {
if (!e.buttonDown) {
_rotX = ((stage.stageWidth / 2) - e.stageX) / (stage.stageWidth / 8);
_rotY = ((stage.stageHeight / 2) - e.stageY) / (stage.stageHeight / 8);
} else {
if (_overSphere) {
_rotX = 0;
_rotY = 0;
if (e.stageX > _distance && e.stageX < stage.stageWidth - _distance) {
_view.x = e.stageX;
}
if (e.stageY < stage.stageHeight / 2 && e.stageY > _distance) {
_view.y = e.stageY;
}
}
}
}
private function _onEnterFrame(e:Event):void {
_sphere.rotationX -= _rotY;
_sphere.rotationY += _rotX;
_sphere.applyRotations();
_xscale = _yscale = 1 - ((300 - _view.y) / 600);
_view.render();
_drawn = (_view.session.getContainer(_view) as DisplayObjectContainer).getChildAt(0);
_bounds = _drawn.getRect(this);
_bmd = new BitmapData(_drawn.width, _drawn.height, true, 0x00ffffff);
_matrix.createBox(_xscale, -_yscale, 0, _drawn.width/2, _drawn.height * _yscale / 2);
_bmd.draw(_drawn, _matrix);
_bitmapReflect.bitmapData = _bmd;
_bitmapReflect.x = _bounds.x;
_bitmapReflect.y = stage.stageHeight / 2 + _distance;
_matrix.createGradientBox(_bitmapReflect.width, _bitmapReflect.height * _yscale / 2, Math.PI / 2, 0, 0);
_bitmapReflectGradient.graphics.clear();
_bitmapReflectGradient.graphics.beginGradientFill("linear", [0xffffff, 0xffffff], [0.9, 0], [0, 255], _matrix);
_bitmapReflectGradient.graphics.drawRect(0, 0, _bitmapReflect.width, _bitmapReflect.height);
_bitmapReflectGradient.graphics.endFill();
_bitmapReflectGradient.x = _bitmapReflect.x;
_bitmapReflectGradient.y = _bitmapReflect.y;
}
}
}