package {
import AS3s.Terrain2;
import away3d.animators.PathAnimator;
import away3d.animators.data.Path;
import away3d.cameras.*;
import away3d.cameras.lenses.SphericalLens;
import away3d.containers.*;
import away3d.core.base.Mesh;
import away3d.core.base.Object3D;
import away3d.core.filter.FogFilter;
import away3d.core.math.*;
import away3d.core.render.*;
import away3d.core.utils.*;
import away3d.extrusions.*;
import away3d.materials.*;
import away3d.primitives.*;
import caurina.transitions.Tweener;
import com.adobe.viewsource.ViewSource;
import com.as3dmod.ModifierStack;
import com.as3dmod.modifiers.*;
import com.as3dmod.plugins.away3d.LibraryAway3d;
import com.as3dmod.util.ModConstant;
import flash.display.*;
import flash.events.*;
import flash.filters.ColorMatrixFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.ui.Keyboard;
import flash.utils.*;
[SWF(backgroundColor="#000000", frameRate="30", quality="LOW", width="800", height="600")]
public class TFO3D_Flash extends Sprite
{
[Embed(source="../assets/terrainTexture2.jpg")]
public static var TerrainTexture:Class;
[Embed(source="../assets/terrainHeightmap2.png")]
public static var TerrainHeightmap:Class;
[Embed(source="../assets/sky.jpg")]
private var Sky:Class;
[Embed(source="../assets/signature.swf", symbol="Signature")]
public static var SignatureSwf:Class;
[Embed(source="../assets/slides.swf", mimeType="application/octet-stream")]
public static var Slides:Class;
private var factorW:Number = 20; private var factorH:Number = 20; private var factorD:Number = 10; private var precisionX:Number = 15; private var precisionY:Number = 15;
protected var backCamera:Camera3D;
protected var cameraObject:Object3D;
protected var targetObject:Object3D;
protected var backCameraContainer:ObjectContainer3D;
protected var foreCamera:Camera3D;
protected var backView:View3D;
protected var foreView:View3D;
private var Signature:Sprite;
private var SignatureBitmap:Bitmap;
protected var prevCarousel:ObjectContainer3D;
protected var prevSlideMaterial:MovieMaterial;
protected var prevSlideFilter:ColorMatrixFilter;
protected var prevSlide:Plane;
protected var nextCarousel:ObjectContainer3D;
protected var nextSlideMaterial:MovieMaterial;
protected var nextSlideFilter:ColorMatrixFilter;
protected var nextSlide:Plane;
private var prevStack:ModifierStack;
private var prevPaperMod:Bend;
private var nextStack:ModifierStack;
private var nextPaperMod:Bend;
private var skyMaterial:BitmapMaterial;
private var elevationBitmap:BitmapData;
private var elevationReader:ElevationReader;
private var colorBitmap:BitmapData;
private var terrainMaterial:BitmapMaterial;
protected var background:Scene3D;
protected var foreground:Scene3D;
private var skinExtrude:Mesh;
private var path:Path;
private var targetAnimator:PathAnimator;
private var cameraAnimator:PathAnimator;
public var cameraPosition:Number = 0;
public var targetPosition:Number = 0;
private var skysphere:Sphere;
private var zero:Number3D = new Number3D();
protected var slidesArray:Array = new Array();
protected var slidesLoader:Loader = new Loader();
private var renderFlag:Boolean = true;
private var active:Boolean = true;
private var currentSlideIndex:int = 0;
public function TFO3D_Flash()
{
super();
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.fullScreenSourceRect = new Rectangle(0,0,800,600);
stage.stageFocusRect = false;
ViewSource.addMenuItem(this, "srcview/index.html")
slidesLoader.contentLoaderInfo.addEventListener(Event.INIT, onSlidesReady);
slidesLoader.loadBytes(new Slides());
}
private function onSlidesReady(event:Event):void
{
var index:Number = 1;
var symbol:Class;
var symbolInstance:MovieClip;
try {
while (symbol = (slidesLoader.contentLoaderInfo.applicationDomain.getDefinition("Slide" + String(index++)) as Class))
{
symbolInstance = new symbol() as MovieClip;
symbolInstance.stop();
slidesArray.push(symbolInstance);
}
} catch (error:Error) {
setupScene();
}
}
public function setupScene():void
{
backCamera = new Camera3D({zoom:7, focus:200, z:-1000, lens:new SphericalLens()});
foreCamera = new Camera3D({zoom:3, focus:200, z:-1000});
elevationBitmap = Cast.bitmap(TerrainHeightmap);
colorBitmap = Cast.bitmap(TerrainTexture);
var fogBitmap:BitmapData = new BitmapData(colorBitmap.width, colorBitmap.height);
var fogShape:Shape = new Shape();
var fogMatrix:Matrix = new Matrix();
fogMatrix.createGradientBox(2048, 2048, 0, 0, 0);
var colArray:Array = [0xB6D1FE, 0xB6D1FE, 0xB6D1FE];
var alphaArray:Array = [0, 0, 0.3];
var pointArray:Array = [0, 128, 255];
fogShape.graphics.beginGradientFill(GradientType.RADIAL, colArray, alphaArray, pointArray, fogMatrix);
fogShape.graphics.drawRect(0, 0, 2048, 2048);
colorBitmap.draw(fogShape);
elevationReader = new ElevationReader();
var levelsBitmap:BitmapData = new BitmapData(colorBitmap.width, colorBitmap.height);
levelsBitmap.draw(elevationBitmap, new Matrix(4, 0, 0, 4), new ColorTransform(3, 3, 3, 1, 20, 20, 20, 0));
elevationReader.traceLevels(levelsBitmap, "av", precisionX, precisionY, factorW, factorH, factorD);
elevationReader.applyHeightGradient(colorBitmap, 0xFFFFFFFF, true, "normal");
terrainMaterial = new BitmapMaterial(colorBitmap);
skyMaterial = new BitmapMaterial( Cast.bitmap(Sky) );
background = new Scene3D();
var fogMaterial:ColorMaterial = new ColorMaterial(0x66FFFFFF, {alpha:0.5});
var fog:FogFilter = new FogFilter({material:fogMaterial, minZ:1000, maxZ:6000});
backView = new View3D({camera:backCamera, scene:background});
backView.clipping.minZ = 150;
addChild(backView);
Signature = Sprite(new SignatureSwf());
SignatureBitmap = new Bitmap(new BitmapData(Signature.width, Signature.height, true, 0));
stage.quality = StageQuality.HIGH;
SignatureBitmap.bitmapData.draw(Signature);
stage.quality = StageQuality.LOW;
addChild(SignatureBitmap);
var elevate:Elevation = new Elevation();
var points:Array = elevate.generate(elevationBitmap, "av", precisionX, precisionY, factorW, factorH, factorD);
skinExtrude = (new Terrain2({material:terrainMaterial})).meshes[0];
skinExtrude.material = terrainMaterial;
skinExtrude.moveTo(0, -1500, 0);
skinExtrude.pushback = true;
var aPath:Array = [new Number3D(3104.8101,342.4314,-5934.6686),new Number3D(4980.6329,37.0196,-5816.8588),new Number3D(6597.7215,46.2745,-5551.7867),new Number3D(6597.7215,46.2745,-5551.7867),
new Number3D(8279.4937,157.3333,-5139.4524),new Number3D(9702.5316,397.9608,-4756.5706),new Number3D(9702.5316,397.9608,-4756.5706),
new Number3D(10672.7848,869.9608,-4196.9741),new Number3D(10996.2025,1702.9020,-3549.0202),new Number3D(10996.2025,1702.9020,-3549.0202),
new Number3D(10737.4684,2156.3922,-2959.9712),new Number3D(10414.0506,2193.4118,-2429.8271),new Number3D(10414.0506,2193.4118,-2429.8271),
new Number3D(10284.6835,1665.8824,-1752.4207),new Number3D(10220.0000,981.0196,-1016.1095),new Number3D(10220.0000,981.0196,-1016.1095),
new Number3D(10155.3165,768.1569,-279.7983),new Number3D(9379.1139,1027.2941,368.1556),new Number3D(9379.1139,1027.2941,368.1556),
new Number3D(8214.8101,1416.0000,839.3948),new Number3D(6985.8228,1499.2941,1192.8242),new Number3D(6985.8228,1499.2941,1192.8242),
new Number3D(5886.2025,1656.6275,1664.0634),new Number3D(5304.0506,1999.0588,2370.9222),new Number3D(5304.0506,1999.0588,2370.9222),
new Number3D(5045.3165,1610.3529,3077.7810),new Number3D(4269.1139,1369.7255,3755.1873),new Number3D(4269.1139,1369.7255,3755.1873),
new Number3D(3104.8101,1018.0392,4167.5216),new Number3D(1746.4557,351.6863,4579.8559),new Number3D(1746.4557,351.6863,4579.8559),
new Number3D(582.1519,27.7647,5110.0000),new Number3D(-840.8861,9.2549,5581.2392),new Number3D(-840.8861,9.2549,5581.2392),
new Number3D(-2263.9241,175.8431,5905.2161),new Number3D(-4010.3797,777.4118,5934.6686),new Number3D(-4010.3797,777.4118,5934.6686),
new Number3D(-5562.7848,1749.1765,5816.8588),new Number3D(-6727.0886,2063.8431,5080.5476),new Number3D(-6727.0886,2063.8431,5080.5476),
new Number3D(-7050.5063,897.7255,4314.7839),new Number3D(-7244.5570,138.8235,3549.0202),new Number3D(-7244.5570,138.8235,3549.0202),
new Number3D(-6921.1392,37.0196,2783.2565),new Number3D(-6144.9367,46.2745,2017.4928),new Number3D(-6144.9367,46.2745,2017.4928),
new Number3D(-5433.4177,166.5882,1340.0865),new Number3D(-4592.5316,175.8431,662.6801),new Number3D(-4592.5316,175.8431,662.6801),
new Number3D(-3492.9114,342.4314,44.1787),new Number3D(-2846.0759,388.7059,-633.2277),new Number3D(-2846.0759,388.7059,-633.2277),
new Number3D(-2587.3418,610.8235,-1340.0865),new Number3D(-2587.3418,990.2745,-2046.9452),new Number3D(-2587.3418,990.2745,-2046.9452),
new Number3D(-3363.5443,1508.5490,-2812.7089),new Number3D(-4398.4810,1536.3137,-3342.8530),new Number3D(-4398.4810,1536.3137,-3342.8530),
new Number3D(-5756.8354,1147.6078,-3696.2824),new Number3D(-7244.5570,916.2353,-3872.9971),new Number3D(-7244.5570,916.2353,-3872.9971),
new Number3D(-8861.6456,934.7451,-3755.1873),new Number3D(-10155.3165,1184.6275,-3283.9481),new Number3D(-10155.3165,1184.6275,-3283.9481),
new Number3D(-10866.8354,1776.9412,-2606.5418),new Number3D(-10996.2025,1749.1765,-1811.3256),new Number3D(-10996.2025,1749.1765,-1811.3256),
new Number3D(-10672.7848,1166.1176,-1104.4669),new Number3D(-10025.9494,666.3529,-456.5130),new Number3D(-10025.9494,666.3529,-456.5130),
new Number3D(-9379.1139,175.8431,368.1556),new Number3D(-8861.6456,0.0000,1104.4669)];
cameraObject = new Object3D();
targetObject = new Object3D();
backCameraContainer = new ObjectContainer3D();
backCameraContainer.scaleY = 1;
backCameraContainer.scaleX = -0.3;
backCameraContainer.scaleZ = 0.74;
backCameraContainer.rotationY = 180;
backCameraContainer.y = -2000;
backCameraContainer.z = 420;
backCameraContainer.addChild(cameraObject);
backCameraContainer.addChild(targetObject);
background.addChild(backCameraContainer);
targetPosition = (currentSlideIndex+1)/(slidesArray.length);
path = new Path(aPath);
path.smoothPath();
cameraAnimator = new PathAnimator(path, cameraObject);
targetAnimator = new PathAnimator(path, targetObject);
background.addChild(skinExtrude);
skysphere = new Sphere({material:skyMaterial, radius:50000, rotationX:180, segmentsW:10, segmentsH:12});
skysphere.scale(-1);
background.addChild( skysphere );
prevSlideMaterial = new MovieMaterial(slidesArray[0], {precision:2.5});
prevSlideFilter = new ColorMatrixFilter();
prevSlide = new Plane({ownCanvas:true, filters:[prevSlideFilter], material:prevSlideMaterial, z:-9600, width:800, height:600, segmentsW:10, segmentsH:10, bothsides:true, yUp:false});
prevCarousel = new ObjectContainer3D({z:9000}, prevSlide);
nextSlideMaterial = new MovieMaterial(slidesArray[1], {precision:2.5});
nextSlideFilter = new ColorMatrixFilter();
nextSlide = new Plane({ownCanvas:true, filters:[nextSlideFilter], material:nextSlideMaterial, width:800, height:600, segmentsW:10, segmentsH:10, bothsides:true, yUp:false});
nextCarousel = new ObjectContainer3D({z:9000}, nextSlide);
foreground = new Scene3D(prevCarousel, nextCarousel);
foreView = new View3D({camera:foreCamera, scene:foreground, renderer:new BasicRenderer()});
addChild(foreView);
prevStack = new ModifierStack(new LibraryAway3d(), prevSlide);
prevPaperMod = new Bend(0, .2, .4);
prevPaperMod.constraint = ModConstant.LEFT;
prevStack.addModifier(prevPaperMod);
nextStack = new ModifierStack(new LibraryAway3d(), nextSlide);
nextPaperMod = new Bend(0, .2, .4);
nextPaperMod.constraint = ModConstant.LEFT;
nextStack.addModifier(nextPaperMod);
stage.addEventListener(MouseEvent.MOUSE_OVER, onActivate);
stage.addEventListener(Event.MOUSE_LEAVE, onDeactivate);
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(Event.RESIZE, onResize);
onResize(null);
}
private function onActivate(event:Event):void
{
active = true;
}
private function onDeactivate(event:Event):void
{
active = false;
}
private function onKeyDown(event:KeyboardEvent):void
{
if (!active)
return;
switch (event.keyCode)
{
case Keyboard.ENTER:
if (stage.displayState == StageDisplayState.FULL_SCREEN)
stage.displayState =StageDisplayState.NORMAL;
else
stage.displayState =StageDisplayState.FULL_SCREEN;
break;
case Keyboard.LEFT:
onPrevSlide();
break;
case Keyboard.RIGHT:
onNextSlide();
break;
case Keyboard.DOWN:
(slidesArray[currentSlideIndex] as MovieClip).nextFrame();
break;
case Keyboard.UP:
(slidesArray[currentSlideIndex] as MovieClip).prevFrame();
break;
default:
if (event.keyCode > 48 && event.keyCode < 59) {
clearAll();
currentSlideIndex = event.keyCode - 49;
prevSlideMaterial.movie = slidesArray[currentSlideIndex];
nextSlideMaterial.movie = slidesArray[currentSlideIndex];
prevSlideMaterial.interactive = true;
nextSlideMaterial.interactive = true;
}
}
}
public function clearAll():void
{
Tweener.removeAllTweens();
}
public function onNextSlide():void
{
if (currentSlideIndex >= slidesArray.length - 1)
return;
clearAll();
currentSlideIndex++;
renderFlag = true;
prevSlideMaterial.interactive = false;
nextSlideMaterial.interactive = false;
prevSlideMaterial.movie = slidesArray[currentSlideIndex-1]
prevSlide.z = -9600;
prevSlide.rotationX = 0;
prevSlide.rotationY = 0;
prevCarousel.rotationY = 0;
prevPaperMod.force = 0;
nextSlideMaterial.movie = slidesArray[currentSlideIndex]
nextSlide.z = -2000;
nextSlide.rotationX = 0;
nextSlide.rotationY = 0;
nextCarousel.rotationY = -45;
nextPaperMod.force = 1;
Tweener.addTween(prevCarousel, {rotationY:45, time:1.5, transition:"easeinquad"});
Tweener.addTween(prevSlide, {z:-2000, rotationX:360, rotationY:360, time:1.5, transition:"easeinquad"});
Tweener.addTween(nextCarousel, {rotationY:0, time:1.5, delay:1, transition:"easeoutquad"});
Tweener.addTween(nextSlide, {z:-9600, rotationX:360, rotationY:360, time:1.5, delay:1, transition:"easeoutquad", onComplete:setTimeout, onCompleteParams:[disableRenderNext, 200]});
Tweener.addTween(this, {cameraPosition:currentSlideIndex/slidesArray.length, time:2.5, transition:"linear"});
Tweener.addTween(this, {targetPosition:(currentSlideIndex+1)/slidesArray.length, time:2.5, transition:"linear"});
Tweener.addTween(prevPaperMod, {force:1, time:1.5, transition:"easeoutquad"});
Tweener.addTween(nextPaperMod, {force:0, time:1.4, delay:1, transition:"easeinquad"});
}
public function onPrevSlide():void
{
if (currentSlideIndex <= 0)
return;
clearAll();
currentSlideIndex--;
renderFlag = true;
prevSlideMaterial.interactive = false;
nextSlideMaterial.interactive = false;
prevSlideMaterial.movie = slidesArray[currentSlideIndex]
prevSlide.z = -2000;
prevSlide.rotationX = 0;
prevSlide.rotationY = 0;
prevCarousel.rotationY = 45;
prevPaperMod.force = 1;
nextSlideMaterial.movie = slidesArray[currentSlideIndex+1]
nextSlide.z = -9600;
nextSlide.rotationX = 0;
nextSlide.rotationY = 0;
nextCarousel.rotationY = 0;
nextPaperMod.force = 0;
Tweener.addTween(nextCarousel, {rotationY:-45, time:1.5, transition:"easeinquad"});
Tweener.addTween(nextSlide, {z:-2000, rotationX:360, rotationY:360, time:1.5, transition:"easeinquad"});
Tweener.addTween(prevCarousel, {rotationY:0, time:1.5, delay:1, transition:"easeoutquad"});
Tweener.addTween(prevSlide, {z:-9600, rotationX:360, rotationY:360, time:1.5, delay:1, transition:"easeoutquad", onComplete:setTimeout, onCompleteParams:[disableRenderPrev, 200]});
Tweener.addTween(this, {cameraPosition:currentSlideIndex/slidesArray.length, time:2.5, transition:"linear"});
Tweener.addTween(this, {targetPosition:(currentSlideIndex+1)/slidesArray.length, time:2.5, transition:"linear"});
Tweener.addTween(nextPaperMod, {force:1, time:1.5, transition:"easeoutquad"});
Tweener.addTween(prevPaperMod, {force:0, time:1.5, delay:1, transition:"easeinquad"});
}
public function disableRenderPrev():void
{
renderFlag = false;
prevSlideMaterial.interactive = true;
nextSlideMaterial.interactive = false;
prevStack.mesh.resetGeometry();
nextStack.mesh.resetGeometry();
foreView.render();
}
public function disableRenderNext():void
{
renderFlag = false;
prevSlideMaterial.interactive = false;
nextSlideMaterial.interactive = true;
prevStack.mesh.resetGeometry();
nextStack.mesh.resetGeometry();
foreView.render();
}
internal var tintR:int = 255;
internal var tintG:int = 255;
internal var tintB:int = 255;
public function onEnterFrame(event:Event):void
{
if (!active)
return;
var prevFraction:Number = (-2000 - prevSlide.z)/7600;
prevSlideFilter.matrix = [1, 0, 0, 0, tintR*(1-prevFraction),
0, 1, 0, 0, tintG*(1-prevFraction),
0, 0, 1, 0, tintB*(1-prevFraction),
0, 0, 0, prevFraction, 0]
var nextFraction:Number = (-2000 - nextSlide.z)/7600;
nextSlideFilter.matrix = [1, 0, 0, 0, tintR*(1-nextFraction),
0, 1, 0, 0, tintG*(1-nextFraction),
0, 0, 1, 0, tintB*(1-nextFraction),
0, 0, 0, nextFraction, 0]
foreView.render();
if (!renderFlag && currentSlideIndex)
return;
cameraAnimator.update(cameraPosition);
targetAnimator.update(targetPosition);
backCamera.position = cameraObject.scenePosition;
backCamera.lookAt(targetObject.scenePosition);
skysphere.rotationY += 0.05;
prevStack.apply();
nextStack.apply();
backView.render();
}
private function onResize(event:Event):void
{
foreView.x = backView.x = stage.stageWidth / 2;
foreView.y = backView.y = stage.stageHeight / 2;
foreView.scaleX = stage.stageWidth/800;
foreView.scaleY = stage.stageHeight/600;
if (SignatureBitmap)
SignatureBitmap.y = stage.stageHeight - Signature.height;
}
}
}