import { LoaderEvent , ColorTransform , Vector3D , Point , AssetLibrary , LoaderContext , URLRequest , RequestAnimationFrame } from "@awayjs/core" ; import { BitmapImage2D , BitmapImageCube , BitmapImageChannel , BlendMode , ImageSampler , ShaderRegisterElement , ShaderRegisterCache , ShaderRegisterData } from "@awayjs/stage" ; import { ShaderBase } from "@awayjs/renderer" ; import { ElementsType } from "@awayjs/graphics" ; import { OrientationMode , AlignmentMode , HoverController , Sprite , Scene , Camera , DisplayObjectContainer , Skybox , Billboard , PrimitiveSpherePrefab } from "@awayjs/scene" ; import { LightingShader , MethodMaterial , SpecularPhongMethod , DiffuseBasicMethod , SpecularBasicMethod , SpecularFresnelMethod , DiffuseCompositeMethod , SpecularCompositeMethod , _Shader_LightingCompositeMethod , _IShader_LightingMethod , ImageTexture2D , PointLight , StaticLightPicker } from "@awayjs/materials" ; import { View } from "@awayjs/view" ; class Intermediate_Globe { private _scene : Scene ; private _root : DisplayObjectContainer ; private _camera : Camera ; private _view : View ; private _cameraController : HoverController ; private _sunMaterial : MethodMaterial ; private _groundMaterial : MethodMaterial ; private _cloudMaterial : MethodMaterial ; private _atmosphereMaterial : MethodMaterial ; private _atmosphereDiffuseMethod : SpecularGlobeMethod ; private _atmosphereSpecularMethod : SpecularGlobeMethod ; private _sun : Billboard ; private _earth : Sprite ; private _clouds : Sprite ; private _atmosphere : Sprite ; private _tiltContainer : DisplayObjectContainer ; private _orbitContainer : DisplayObjectContainer ; private _skyBox : Skybox ; private _light : PointLight ; private _lightPicker : StaticLightPicker ; private _flares : FlareObject [ ] = new Array < FlareObject > ( 12 ) ; private _timer : RequestAnimationFrame ; private _time : number = 0 ; private _move : boolean = false ; private _lastPanAngle : number ; private _lastTiltAngle : number ; private _lastMouseX : number ; private _lastMouseY : number ; private _mouseLockX : number = 0 ; private _mouseLockY : number = 0 ; private _mouseLocked : boolean ; private _flareVisible : boolean ; /**
     * Constructor
     */ constructor ( ) { this . init ( ) ; } /**
     * Global initialise function
     */ private init ( ) { this . initEngine ( ) ; this . initLights ( ) ; this . initMaterials ( ) ; this . initObjects ( ) ; this . initListeners ( ) ; } /**
     * Initialise the engine
     */ private initEngine ( ) { this . _scene = new Scene ( ) ; this . _camera = new Camera ( ) ; this . _camera . projection . far = 100000 ; this . _scene . camera = this . _camera ; this . _view = this . _scene . view ; this . _root = this . _scene . root ; this . _cameraController = new HoverController ( this . _camera , null , 0 , 0 , 600 , - 90 , 90 ) ; this . _cameraController . autoUpdate = false ; this . _cameraController . yFactor = 1 ; } /**
     * Initialise the lights
     */ private initLights ( ) { this . _light = new PointLight ( ) ; this . _light . x = 10000 ; this . _light . ambient = 1 ; this . _light . diffuse = 2 ; this . _lightPicker = new StaticLightPicker ( [ this . _light ] ) ; } /**
     * Initialise the materials
     */ private initMaterials ( ) { var specular = new SpecularFresnelMethod ( true , 1 , 0.1 , new SpecularPhongMethod ( ) ) ; specular . gloss = 5 ; specular . strength = 1 ; this . _sunMaterial = new MethodMaterial ( ) ; this . _sunMaterial . style . sampler = new ImageSampler ( false , true , true ) ; this . _sunMaterial . blendMode = BlendMode . ADD ; this . _groundMaterial = new MethodMaterial ( ) ; this . _groundMaterial . style . sampler = new ImageSampler ( false , true , true ) ; this . _groundMaterial . specularMethod = specular ; this . _groundMaterial . lightPicker = this . _lightPicker ; this . _groundMaterial . ambientMethod . strength = 1 ; this . _groundMaterial . diffuseMethod . multiply = false ; this . _cloudMaterial = new MethodMaterial ( ) ; this . _cloudMaterial . style . sampler = new ImageSampler ( false , true , true ) ; this . _cloudMaterial . alphaBlending = true ; this . _cloudMaterial . lightPicker = this . _lightPicker ; this . _cloudMaterial . style . color = 0x1b2048 ; this . _cloudMaterial . specularMethod . strength = 0 ; this . _cloudMaterial . ambientMethod . strength = 1 ; this . _cloudMaterial . diffuseMethod . multiply = false ; this . _atmosphereMaterial = new MethodMaterial ( ) ; this . _atmosphereMaterial . diffuseMethod = new DiffuseGlobeMethod ( ) ; this . _atmosphereMaterial . specularMethod = new SpecularGlobeMethod ( new SpecularPhongMethod ( ) ) ; this . _atmosphereMaterial . blendMode = BlendMode . ADD ; this . _atmosphereMaterial . lightPicker = this . _lightPicker ; this . _atmosphereMaterial . specularMethod . strength = 0.5 ; this . _atmosphereMaterial . specularMethod . gloss = 5 ; this . _atmosphereMaterial . style . color = 0 ; this . _atmosphereMaterial . diffuseMethod . color = 0x1671cc ; this . _atmosphereMaterial . ambientMethod . strength = 1 ; this . _atmosphereMaterial . diffuseMethod . multiply = false ; } /**
     * Initialise the scene objects
     */ private initObjects ( ) { this . _orbitContainer = new DisplayObjectContainer ( ) ; this . _root . addChild ( this . _orbitContainer ) ; this . _sun = new Billboard ( this . _sunMaterial ) ; this . _sun . width = 3000 ; this . _sun . height = 3000 ; this . _sun . registrationPoint = new Vector3D ( 1500 , 1500 , 0 ) ; this . _sun . orientationMode = OrientationMode . CAMERA_PLANE ; this . _sun . x = 10000 ; this . _orbitContainer . addChild ( this . _sun ) ; this . _earth = < Sprite > new PrimitiveSpherePrefab ( this . _groundMaterial , ElementsType . TRIANGLE , 200 , 200 , 100 ) . getNewObject ( ) ; this . _clouds = < Sprite > new PrimitiveSpherePrefab ( this . _cloudMaterial , ElementsType . TRIANGLE , 202 , 200 , 100 ) . getNewObject ( ) ; this . _atmosphere = < Sprite > new PrimitiveSpherePrefab ( this . _atmosphereMaterial , ElementsType . TRIANGLE , 210 , 200 , 100 ) . getNewObject ( ) ; this . _atmosphere . scaleX = - 1 ; this . _tiltContainer = new DisplayObjectContainer ( ) ; this . _tiltContainer . rotationX = 23 ; this . _tiltContainer . addChild ( this . _earth ) ; this . _tiltContainer . addChild ( this . _clouds ) ; this . _tiltContainer . addChild ( this . _atmosphere ) ; this . _root . addChild ( this . _tiltContainer ) ; this . _cameraController . lookAtObject = this . _tiltContainer ; } /**
     * Initialise the listeners
     */ private initListeners ( ) { window . onresize = ( event ) => this . onResize ( event ) ; document . onmousedown = ( event ) => this . onMouseDown ( event ) ; document . onmouseup = ( event ) => this . onMouseUp ( event ) ; document . onmousemove = ( event ) => this . onMouseMove ( event ) ; document . onwheel = ( event ) => this . onWheel ( event ) ; this . onResize ( ) ; this . _timer = new RequestAnimationFrame ( this . onEnterFrame , this ) ; this . _timer . start ( ) ; AssetLibrary . addEventListener ( LoaderEvent . LOAD_COMPLETE , ( event ) => this . onResourceComplete ( event ) ) ; var loaderContext = new LoaderContext ( ) ; loaderContext . dependencyBaseUrl = "assets/skybox/" ; AssetLibrary . load ( new URLRequest ( "assets/skybox/space_texture.cube" ) , loaderContext ) ; AssetLibrary . load ( new URLRequest ( "assets/globe/cloud_combined_2048.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/globe/earth_specular_2048.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/globe/EarthNormal.png" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/globe/land_lights_16384.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/globe/land_ocean_ice_2048_match.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare2.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare3.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare4.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare6.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare7.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare8.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare10.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare11.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/lensflare/flare12.jpg" ) ) ; } /**
     * Navigation and render loop
     */ private onEnterFrame ( dt ) { this . _time += dt ; this . _earth . rotationY -= 0.2 ; this . _clouds . rotationY -= 0.21 ; this . _orbitContainer . rotationY -= 0.02 ; this . _cameraController . update ( ) ; this . updateFlares ( ) ; this . _scene . render ( ) ; } private updateFlares ( ) { var flareVisibleOld = this . _flareVisible ; var sunScreenPosition = this . _view . project ( this . _sun . scenePosition ) ; var xOffset = sunScreenPosition . x - window . innerWidth / 2 ; var yOffset = sunScreenPosition . y - window . innerHeight / 2 ; var earthScreenPosition = this . _view . project ( this . _earth . scenePosition ) ; var earthRadius = 190 * window . innerHeight / earthScreenPosition . z ; var flareObject ; this . _flareVisible = ( sunScreenPosition . x > 0 && sunScreenPosition . x < window . innerWidth && sunScreenPosition . y > 0 && sunScreenPosition . y < window . innerHeight && sunScreenPosition . z > 0 && Math . sqrt ( xOffset * xOffset + yOffset * yOffset ) > earthRadius ) ; if ( this . _flareVisible != flareVisibleOld ) { for ( var i = 0 ; i < this . _flares . length ; i ++ ) { flareObject = this . _flares [ i ] ; if ( flareObject ) flareObject . billboard . visible = this . _flareVisible ; } } if ( this . _flareVisible ) { var flareDirection = new Point ( xOffset , yOffset ) ; for ( var i = 0 ; i < this . _flares . length ; i ++ ) { flareObject = this . _flares [ i ] ; if ( flareObject ) { var position = this . _view . unproject ( sunScreenPosition . x - flareDirection . x * flareObject . position , sunScreenPosition . y - flareDirection . y * flareObject . position , 100 - i ) ; flareObject . billboard . transform . moveTo ( position . x , position . y , position . z ) ; } } } } /**
     * Listener function for resource complete event on asset library
     */ private onResourceComplete ( event ) { switch ( event . url ) { case 'assets/skybox/space_texture.cube' : this . _skyBox = new Skybox ( < BitmapImageCube > event . assets [ 0 ] ) ; this . _skyBox . style . sampler = new ImageSampler ( false , true ) ; this . _root . addChild ( this . _skyBox ) ; break ; case "assets/globe/cloud_combined_2048.jpg" : var cloudBitmapImage2D = new BitmapImage2D ( 2048 , 1024 , true , 0xFFFFFFFF ) ; cloudBitmapImage2D . copyChannel ( < BitmapImage2D > event . assets [ 0 ] , cloudBitmapImage2D . rect , new Point ( ) , BitmapImageChannel . RED , BitmapImageChannel . ALPHA ) ; this . _cloudMaterial . ambientMethod . texture = new ImageTexture2D ( cloudBitmapImage2D ) ; break ; case "assets/globe/earth_specular_2048.jpg" : var specBitmapImage2D = < BitmapImage2D > event . assets [ 0 ] ; specBitmapImage2D . colorTransform ( specBitmapImage2D . rect , new ColorTransform ( 1 , 1 , 1 , 1 , 64 , 64 , 64 ) ) ; this . _groundMaterial . specularMethod . texture = new ImageTexture2D ( specBitmapImage2D ) ; break ; case "assets/globe/EarthNormal.png" : this . _groundMaterial . normalMethod . texture = new ImageTexture2D ( < BitmapImage2D > event . assets [ 0 ] ) ; break ; case "assets/globe/land_lights_16384.jpg" : this . _groundMaterial . ambientMethod . texture = new ImageTexture2D ( < BitmapImage2D > event . assets [ 0 ] ) ; break ; case "assets/globe/land_ocean_ice_2048_match.jpg" : this . _groundMaterial . diffuseMethod . texture = new ImageTexture2D ( < BitmapImage2D > event . assets [ 0 ] ) ; break ; case "assets/lensflare/flare2.jpg" : this . _flares [ 6 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 1.25 , 1.1 , 48.45 , this . _root ) ; break ; case "assets/lensflare/flare3.jpg" : this . _flares [ 7 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 1.75 , 1.37 , 7.65 , this . _root ) ; break ; case "assets/lensflare/flare4.jpg" : this . _flares [ 8 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 2.75 , 1.85 , 12.75 , this . _root ) ; break ; case "assets/lensflare/flare6.jpg" : this . _flares [ 5 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 1 , 0.68 , 20.4 , this . _root ) ; this . _flares [ 10 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 4 , 2.5 , 10.4 , this . _root ) ; break ; case "assets/lensflare/flare7.jpg" : this . _flares [ 2 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 2 , 0 , 25.5 , this . _root ) ; this . _flares [ 3 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 4 , 0 , 17.85 , this . _root ) ; this . _flares [ 11 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 10 , 2.66 , 50 , this . _root ) ; break ; case "assets/lensflare/flare8.jpg" : this . _flares [ 9 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 0.5 , 2.21 , 33.15 , this . _root ) ; break ; case "assets/lensflare/flare10.jpg" : this . _sunMaterial . ambientMethod . texture = new ImageTexture2D ( < BitmapImage2D > event . assets [ 0 ] ) ; this . _flares [ 0 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 3.2 , - 0.01 , 100 , this . _root ) ; break ; case "assets/lensflare/flare11.jpg" : this . _flares [ 1 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 6 , 0 , 30.6 , this . _root ) ; break ; case "assets/lensflare/flare12.jpg" : this . _flares [ 4 ] = new FlareObject ( < BitmapImage2D > event . assets [ 0 ] , 0.4 , 0.32 , 22.95 , this . _root ) ; break ; } } /**
     * Mouse down listener for navigation
     */ private onMouseDown ( event ) { this . _lastPanAngle = this . _cameraController . panAngle ; this . _lastTiltAngle = this . _cameraController . tiltAngle ; this . _lastMouseX = event . clientX ; this . _lastMouseY = event . clientY ; this . _move = true ; } /**
     * Mouse up listener for navigation
     */ private onMouseUp ( event ) { this . _move = false ; } /**
     * Mouse move listener for mouseLock
     */ private onMouseMove ( event ) { if ( this . _move ) { this . _cameraController . panAngle = 0.3 * ( event . clientX - this . _lastMouseX ) + this . _lastPanAngle ; this . _cameraController . tiltAngle = 0.3 * ( event . clientY - this . _lastMouseY ) + this . _lastTiltAngle ; } } /**
     * Mouse wheel listener for navigation
     */ private onWheel ( event ) { this . _cameraController . distance -= event . deltaY / 2 ; if ( this . _cameraController . distance < 400 ) this . _cameraController . distance = 400 ; else if ( this . _cameraController . distance > 10000 ) this . _cameraController . distance = 10000 ; } /**
     * Key down listener for fullscreen
     */ /**
     * window listener for resize events
     */ private onResize ( event = null ) { this . _view . y = 0 ; this . _view . x = 0 ; this . _view . width = window . innerWidth ; this . _view . height = window . innerHeight ; } } class FlareObject { private flareSize : number = 14.4 ; public billboard : Billboard ; public size : number ; public position : number ; public opacity : number ; /**
     * Constructor
     */ constructor ( bitmapData , size , position , opacity , root ) { var bd = new BitmapImage2D ( bitmapData . width , bitmapData . height , true , 0xFFFFFFFF ) ; bd . copyChannel ( bitmapData , bitmapData . rect , new Point ( ) , BitmapImageChannel . RED , BitmapImageChannel . ALPHA ) ; var billboardMaterial = new MethodMaterial ( bd ) ; billboardMaterial . style . sampler = new ImageSampler ( false , true ) ; billboardMaterial . alpha = opacity / 100 ; billboardMaterial . alphaBlending = true ; this . billboard = new Billboard ( billboardMaterial ) ; this . billboard . width = size * this . flareSize ; this . billboard . height = size * this . flareSize ; this . billboard . registrationPoint = new Vector3D ( size * this . flareSize / 2 , size * this . flareSize / 2 , 0 ) ; this . billboard . orientationMode = OrientationMode . CAMERA_PLANE ; this . billboard . visible = false ; this . size = size ; this . position = position ; this . opacity = opacity ; root . addChild ( this . billboard ) ; } } class DiffuseGlobeMethod extends DiffuseCompositeMethod { public static assetType : string = "[asset DiffuseGlobeMethod]" ; inheritDoc public get assetType ( ) : string { return DiffuseGlobeMethod . assetType ; } } class DiffuseGlobeChunk extends _Shader_LightingCompositeMethod { param levels param baseMethod constructor ( method , shader ) { super ( method , shader ) ; ( < _IShader_LightingMethod > this . _baseChunk ) . _modulateFunction = ( targetReg , registerCache , sharedRegisters ) => this . modulateDiffuseMethod ( targetReg , registerCache , sharedRegisters ) ; } private modulateDiffuseMethod ( targetReg , regCache , sharedRegisters ) { var viewDirFragmentReg = sharedRegisters . viewDirFragment ; var normalFragmentReg = sharedRegisters . normalFragment ; var code = "dp3 " + targetReg + ".w, " + viewDirFragmentReg + ".xyz, " + normalFragmentReg + ".xyz\n" + "mul " + targetReg + ".w, " + targetReg + ".w, " + targetReg + ".w\n" ; return code ; } } class SpecularGlobeMethod extends SpecularCompositeMethod { public static assetType : string = "[asset SpecularGlobeMethod]" ; inheritDoc public get assetType ( ) : string { return SpecularGlobeMethod . assetType ; } } class SpecularGlobeChunk extends _Shader_LightingCompositeMethod { param levels param baseMethod constructor ( method , shader ) { super ( method , shader ) ; ( < _IShader_LightingMethod > this . _baseChunk ) . _modulateFunction = ( targetReg , registerCache , sharedRegisters ) => this . modulateSpecularMethod ( targetReg , registerCache , sharedRegisters ) ; } private modulateSpecularMethod ( targetReg , regCache , sharedRegisters ) { var viewDirFragmentReg = sharedRegisters . viewDirFragment ; var normalFragmentReg = sharedRegisters . normalFragment ; var temp = regCache . getFreeFragmentSingleTemp ( ) ; regCache . addFragmentTempUsages ( temp , 1 ) ; var code = "dp3 " + temp + ", " + viewDirFragmentReg + ".xyz, " + normalFragmentReg + ".xyz\n" + "neg " + temp + ", " + temp + "\n" + "mul " + targetReg + ".w, " + targetReg + ".w, " + temp + "\n" ; regCache . removeFragmentTempUsage ( temp ) ; return code ; } } ShaderBase . registerAbstraction ( DiffuseGlobeChunk , DiffuseGlobeMethod ) ; ShaderBase . registerAbstraction ( SpecularGlobeChunk , SpecularGlobeMethod ) ; window . onload = function ( ) { new Intermediate_Globe ( ) ; } ;