import { AssetEvent , LoaderEvent , URLLoaderEvent , Vector3D , AssetLibrary , LoaderContext , URLRequest , URLLoader , URLLoaderDataFormat , RequestAnimationFrame , ParserUtils } from "@awayjs/core" ; import { SpecularImage2D , ImageSampler , ImageUtils } from "@awayjs/stage" ; import { HoverController , Sprite , Scene , Camera , DisplayObjectContainer } from "@awayjs/scene" ; import { ImageTexture2D , MethodMaterial , MethodMaterialMode , SpecularFresnelMethod , ShadowSoftMethod , PointLight , DirectionalLight , StaticLightPicker , DirectionalShadowMapper } from "@awayjs/materials" ; import { AWDParser } from "@awayjs/parsers" ; import { View } from "@awayjs/view" ; class Intermediate_MonsterHeadShading { private _textureStrings : Array < string > = Array < string > ( "monsterhead_diffuse.jpg" , "monsterhead_specular.jpg" , "monsterhead_normals.jpg" ) ; private _textureDictionary : Object = new Object ( ) ; private _scene : Scene ; private _camera : Camera ; private _view : View ; private _root : DisplayObjectContainer ; private _cameraController : HoverController ; private _headMaterial : MethodMaterial ; private _softShadowMethod : ShadowSoftMethod ; private _fresnelMethod : SpecularFresnelMethod ; private _blueLight : PointLight ; private _redLight : PointLight ; private _directionalLight : DirectionalLight ; private _lightPicker : StaticLightPicker ; private _headModel : Sprite ; private _advancedMethod : Boolean = true ; private _numTextures : number = 0 ; private _currentTexture : number = 0 ; private _n : number = 0 ; private _loadingText : string ; private _assetsRoot : string = "assets/monsterhead/" ; private _move : Boolean = false ; private _lastPanAngle : number ; private _lastTiltAngle : number ; private _lastMouseX : number ; private _lastMouseY : number ; private timer : RequestAnimationFrame ; private time : number = 0 ; private parseAWDDelegate : ( event : URLLoaderEvent ) => void ; private parseBitmapDelegate : ( event : URLLoaderEvent ) => void ; private loadProgressDelegate : ( event : URLLoaderEvent ) => void ; private onBitmapCompleteDelegate : ( event : Event ) => void ; private onAssetCompleteDelegate : ( event : AssetEvent ) => void ; private onResourceCompleteDelegate : ( event : LoaderEvent ) => void ; private _shadowRange : number = 3 ; private _lightDirection : number = 120 * Math . PI / 180 ; private _lightElevation : number = 30 * Math . PI / 180 ; /**
     * Constructor
     */ public constructor ( ) { this . init ( ) ; } /**
     * Global initialise function
     */ private init ( ) { this . initEngine ( ) ; this . initLights ( ) ; this . initListeners ( ) ; this . _n = 0 ; this . _numTextures = this . _textureStrings . length ; this . load ( this . _textureStrings [ this . _n ] ) ; } /**
     * Initialise the engine
     */ private initEngine ( ) { this . _scene = new Scene ( ) ; this . _camera = this . _scene . camera ; this . _camera . projection . near = 20 ; this . _camera . projection . far = 1000 ; this . _cameraController = new HoverController ( this . _camera , null , 225 , 10 , 800 ) ; this . _cameraController . yFactor = 1 ; this . _view = this . _scene . view ; this . _root = this . _scene . root ; } /**
     * Initialise the lights in a scene
     */ private initLights ( ) { var x = Math . sin ( this . _lightElevation ) * Math . cos ( this . _lightDirection ) ; var y = - Math . cos ( this . _lightElevation ) ; var z = Math . sin ( this . _lightElevation ) * Math . sin ( this . _lightDirection ) ; this . _directionalLight = new DirectionalLight ( new Vector3D ( x , y , z ) ) ; this . _directionalLight . color = 0xffeedd ; this . _directionalLight . ambient = 1 ; this . _directionalLight . specular = .3 ; this . _directionalLight . ambientColor = 0x101025 ; this . _directionalLight . shadowsEnabled = true ; this . _directionalLight . shadowMapper . epsilon = 0.2 ; ( < DirectionalShadowMapper > this . _directionalLight . shadowMapper ) . lightOffset = 1000 ; this . _blueLight = new PointLight ( ) ; this . _blueLight . color = 0x4080ff ; this . _blueLight . x = 3000 ; this . _blueLight . z = 700 ; this . _blueLight . y = 20 ; this . _redLight = new PointLight ( ) ; this . _redLight . color = 0x802010 ; this . _redLight . x = - 2000 ; this . _redLight . z = 800 ; this . _redLight . y = - 400 ; this . _lightPicker = new StaticLightPicker ( [ this . _directionalLight , this . _blueLight , this . _redLight ] ) ; } /**
     * 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 ) ; this . onResize ( ) ; this . parseAWDDelegate = ( event ) => this . parseAWD ( event ) ; this . parseBitmapDelegate = ( event ) => this . parseBitmap ( event ) ; this . loadProgressDelegate = ( event ) => this . loadProgress ( event ) ; this . onBitmapCompleteDelegate = ( event ) => this . onBitmapComplete ( event ) ; this . onAssetCompleteDelegate = ( event ) => this . onAssetComplete ( event ) ; this . onResourceCompleteDelegate = ( event ) => this . onResourceComplete ( event ) ; this . timer = new RequestAnimationFrame ( this . onEnterFrame , this ) ; this . timer . start ( ) ; } /**
     * Updates the direction of the directional lightsource
     */ private updateDirection ( ) { this . _directionalLight . direction = new Vector3D ( Math . sin ( this . _lightElevation ) * Math . cos ( this . _lightDirection ) , - Math . cos ( this . _lightElevation ) , Math . sin ( this . _lightElevation ) * Math . sin ( this . _lightDirection ) ) ; } private updateRange ( ) { this . _softShadowMethod . range = this . _shadowRange ; } /**
     * Global binary file loader
     */ private load ( url ) { var loader = new URLLoader ( ) ; switch ( url . substring ( url . length - 3 ) ) { case "AWD" : case "awd" : loader . dataFormat = URLLoaderDataFormat . ARRAY_BUFFER ; this . _loadingText = "Loading Model" ; loader . addEventListener ( URLLoaderEvent . LOAD_COMPLETE , this . parseAWDDelegate ) ; break ; case "png" : case "jpg" : loader . dataFormat = URLLoaderDataFormat . BLOB ; this . _currentTexture ++ ; this . _loadingText = "Loading Textures" ; loader . addEventListener ( URLLoaderEvent . LOAD_COMPLETE , this . parseBitmapDelegate ) ; break ; } loader . addEventListener ( URLLoaderEvent . LOAD_PROGRESS , this . loadProgressDelegate ) ; loader . load ( new URLRequest ( this . _assetsRoot + url ) ) ; } /**
     * Display current load
     */ private loadProgress ( event ) { var P = Math . floor ( event [ "bytesLoaded" ] / event [ "bytesTotal" ] * 100 ) ; if ( P != 100 ) { console . log ( this . _loadingText + '\n' + ( ( this . _loadingText == "Loading Model" ) ? Math . floor ( ( event [ "bytesLoaded" ] / 1024 ) << 0 ) + 'kb | ' + Math . floor ( ( event [ "bytesTotal" ] / 1024 ) << 0 ) + 'kb' : this . _currentTexture + ' | ' + this . _numTextures ) ) ; } } /**
     * Parses the Bitmap file
     */ private parseBitmap ( event ) { var urlLoader = < URLLoader > event . target ; var image = ParserUtils . blobToImage ( urlLoader . data ) ; image . onload = this . onBitmapCompleteDelegate ; urlLoader . removeEventListener ( URLLoaderEvent . LOAD_COMPLETE , this . parseBitmapDelegate ) ; urlLoader . removeEventListener ( URLLoaderEvent . LOAD_PROGRESS , this . loadProgressDelegate ) ; urlLoader = null ; } /**
     * Parses the AWD file
     */ private parseAWD ( event ) { console . log ( "Parsing Data" ) ; var urlLoader = < URLLoader > event . target ; AssetLibrary . addEventListener ( AssetEvent . ASSET_COMPLETE , this . onAssetCompleteDelegate ) ; AssetLibrary . addEventListener ( LoaderEvent . LOAD_COMPLETE , this . onResourceCompleteDelegate ) ; AssetLibrary . loadData ( urlLoader . data , new LoaderContext ( false ) , null , new AWDParser ( ) ) ; urlLoader . removeEventListener ( URLLoaderEvent . LOAD_PROGRESS , this . loadProgressDelegate ) ; urlLoader . removeEventListener ( URLLoaderEvent . LOAD_COMPLETE , this . parseAWDDelegate ) ; urlLoader = null ; } /**
     * Listener for bitmap complete event on loader
     */ private onBitmapComplete ( event ) { var image = < HTMLImageElement > event . target ; image . onload = null ; if ( ! this . _textureDictionary [ this . _textureStrings [ this . _n ] ] ) this . _textureDictionary [ this . _textureStrings [ this . _n ] ] = new ImageTexture2D ( ( this . _n == 1 ) ? new SpecularImage2D ( ImageUtils . imageToBitmapImage2D ( image ) ) : ImageUtils . imageToBitmapImage2D ( image ) ) ; this . _n ++ ; if ( this . _n < this . _textureStrings . length ) { this . load ( this . _textureStrings [ this . _n ] ) ; } else { this . load ( "MonsterHead.awd" ) ; } } /**
     * Navigation and render loop
     */ private onEnterFrame ( dt ) { this . _scene . render ( ) ; } /**
     * Listener for asset complete event on loader
     */ private onAssetComplete ( event ) { if ( event . asset . isAsset ( Sprite ) ) { this . _headModel = < Sprite > event . asset ; this . _headModel . graphics . scale ( 4 ) ; this . _headModel . y = - 20 ; this . _root . addChild ( this . _headModel ) ; } } /**
     * Triggered once all resources are loaded
     */ private onResourceComplete ( e ) { AssetLibrary . removeEventListener ( AssetEvent . ASSET_COMPLETE , this . onAssetCompleteDelegate ) ; AssetLibrary . removeEventListener ( LoaderEvent . LOAD_COMPLETE , this . onResourceCompleteDelegate ) ; var material = new MethodMaterial ( this . _textureDictionary [ "monsterhead_diffuse.jpg" ] ) ; material . shadowMethod = new ShadowSoftMethod ( this . _directionalLight , 10 , 5 ) ; material . lightPicker = this . _lightPicker ; material . specularMethod . gloss = 30 ; material . specularMethod . strength = 1 ; material . style . color = 0x303040 ; material . ambientMethod . strength = 1 ; this . _headMaterial = new MethodMaterial ( ) ; this . _headMaterial . ambientMethod . texture = this . _textureDictionary [ "monsterhead_diffuse.jpg" ] ; this . _headMaterial . mode = MethodMaterialMode . MULTI_PASS ; this . _headMaterial . style . sampler = new ImageSampler ( true , true ) ; this . _headMaterial . normalMethod . texture = this . _textureDictionary [ "monsterhead_normals.jpg" ] ; this . _headMaterial . lightPicker = this . _lightPicker ; this . _headMaterial . style . color = 0x303040 ; this . _headMaterial . diffuseMethod . multiply = false ; this . _softShadowMethod = new ShadowSoftMethod ( this . _directionalLight , 20 ) ; this . _softShadowMethod . range = this . _shadowRange ; this . _headMaterial . shadowMethod = this . _softShadowMethod ; this . _fresnelMethod = new SpecularFresnelMethod ( true ) ; this . _fresnelMethod . fresnelPower = 3 ; this . _headMaterial . specularMethod = this . _fresnelMethod ; this . _headMaterial . specularMethod . texture = this . _textureDictionary [ "monsterhead_specular.jpg" ] ; this . _headMaterial . specularMethod . strength = 3 ; this . _headMaterial . specularMethod . gloss = 10 ; var len = this . _headModel . graphics . count ; for ( var i = 0 ; i < len ; i ++ ) this . _headModel . graphics . getShapeAt ( i ) . material = this . _headMaterial ; AssetLibrary . addEventListener ( LoaderEvent . LOAD_COMPLETE , ( event ) => this . onExtraResourceComplete ( event ) ) ; AssetLibrary . load ( new URLRequest ( "assets/diffuseGradient.jpg" ) ) ; } /**
     * Triggered once extra resources are loaded
     */ private onExtraResourceComplete ( event ) { switch ( event . url ) { case "assets/diffuseGradient.jpg" : 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 ; } } /**
     * 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 ; } } window . onload = function ( ) { new Intermediate_MonsterHeadShading ( ) ; } ;