import { LoaderEvent , TimerEvent , Vector3D , ColorTransform , AssetLibrary , IAsset , URLRequest , RequestAnimationFrame , Timer } from "@awayjs/core" ; import { BitmapImage2D , ImageSampler , BlendMode } from "@awayjs/stage" ; import { ElementsType , Graphics , ParticleAnimationSet , ParticleAnimator , ParticleProperties , ParticlePropertiesMode , ParticleBillboardNode , ParticleScaleNode , ParticleVelocityNode , ParticleColorNode , ParticleGraphicsHelper } from "@awayjs/graphics" ; import { HoverController , Sprite , Scene , Camera , PrimitivePlanePrefab } from "@awayjs/scene" ; import { MethodMaterial , MethodMaterialMode , PointLight , DirectionalLight , StaticLightPicker , ImageTexture2D } from "@awayjs/materials" ; import { View } from "@awayjs/view" ; class Basic_Fire { private static NUM_FIRES : number = 10 ; private _scene : Scene ; private _camera : Camera ; private _cameraController : HoverController ; private _planeMaterial : MethodMaterial ; private _particleMaterial : MethodMaterial ; private _directionalLight : DirectionalLight ; private _lightPicker : StaticLightPicker ; private _fireAnimationSet : ParticleAnimationSet ; private _particleSprite : Sprite ; private _fireTimer : Timer ; private _plane : Sprite ; private _fireObjects : Array < FireVO > = new Array < FireVO > ( ) ; private _timer : RequestAnimationFrame ; private _time : number = 0 ; private _move : boolean = false ; private _lastPanAngle : number ; private _lastTiltAngle : number ; private _lastMouseX : number ; private _lastMouseY : number ; /**
     * Constructor
     */ constructor ( ) { this . init ( ) ; } /**
     * Global initialise function
     */ private init ( ) { this . initEngine ( ) ; this . initLights ( ) ; this . initMaterials ( ) ; this . initParticles ( ) ; this . initObjects ( ) ; this . initListeners ( ) ; } /**
     * Initialise the engine
     */ private initEngine ( ) { this . _scene = new Scene ( ) ; this . _camera = new Camera ( ) ; this . _scene . camera = this . _camera ; this . _cameraController = new HoverController ( this . _camera ) ; this . _cameraController . distance = 1000 ; this . _cameraController . minTiltAngle = 0 ; this . _cameraController . maxTiltAngle = 90 ; this . _cameraController . panAngle = 45 ; this . _cameraController . tiltAngle = 20 ; } /**
     * Initialise the lights
     */ private initLights ( ) { this . _directionalLight = new DirectionalLight ( new Vector3D ( 0 , - 1 , 0 ) ) ; this . _directionalLight . color = 0xeedddd ; this . _directionalLight . diffuse = .5 ; this . _directionalLight . ambient = .5 ; this . _directionalLight . specular = 0 ; this . _directionalLight . ambientColor = 0x808090 ; this . _lightPicker = new StaticLightPicker ( [ this . _directionalLight ] ) ; } /**
     * Initialise the materials
     */ private initMaterials ( ) { this . _planeMaterial = new MethodMaterial ( ) ; this . _planeMaterial . mode = MethodMaterialMode . MULTI_PASS ; this . _planeMaterial . lightPicker = this . _lightPicker ; this . _planeMaterial . style . sampler = new ImageSampler ( true , true , false ) ; this . _planeMaterial . specularMethod . strength = 10 ; this . _particleMaterial = new MethodMaterial ( ) ; this . _particleMaterial . blendMode = BlendMode . ADD ; } /**
     * Initialise the particles
     */ private initParticles ( ) { this . _fireAnimationSet = new ParticleAnimationSet ( true , true ) ; this . _fireAnimationSet . addAnimation ( new ParticleBillboardNode ( ) ) ; this . _fireAnimationSet . addAnimation ( new ParticleScaleNode ( ParticlePropertiesMode . GLOBAL , false , false , 2.5 , 0.5 ) ) ; this . _fireAnimationSet . addAnimation ( new ParticleVelocityNode ( ParticlePropertiesMode . GLOBAL , new Vector3D ( 0 , 80 , 0 ) ) ) ; this . _fireAnimationSet . addAnimation ( new ParticleColorNode ( ParticlePropertiesMode . GLOBAL , true , true , false , false , new ColorTransform ( 0 , 0 , 0 , 1 , 0xFF , 0x33 , 0x01 ) , new ColorTransform ( 0 , 0 , 0 , 1 , 0x99 ) ) ) ; this . _fireAnimationSet . addAnimation ( new ParticleVelocityNode ( ParticlePropertiesMode . LOCAL_STATIC ) ) ; this . _fireAnimationSet . initParticleFunc = this . initParticleFunc ; var particle = < Sprite > ( new PrimitivePlanePrefab ( null , ElementsType . TRIANGLE , 10 , 10 , 1 , 1 , false ) ) . getNewObject ( ) ; var graphicsSet = new Array < Graphics > ( ) ; for ( var i = 0 ; i < 500 ; i ++ ) graphicsSet . push ( particle . graphics ) ; this . _particleSprite = new Sprite ( null , this . _particleMaterial ) ; ParticleGraphicsHelper . generateGraphics ( this . _particleSprite . graphics , graphicsSet ) ; } /**
     * Initialise the scene objects
     */ private initObjects ( ) { this . _plane = < Sprite > new PrimitivePlanePrefab ( this . _planeMaterial , ElementsType . TRIANGLE , 1000 , 1000 ) . getNewObject ( ) ; this . _plane . material = this . _planeMaterial ; this . _plane . graphics . scaleUV ( 2 , 2 ) ; this . _plane . y = - 20 ; this . _scene . root . addChild ( this . _plane ) ; for ( var i = 0 ; i < Basic_Fire . NUM_FIRES ; i ++ ) { var particleSprite = this . _particleSprite . clone ( ) ; var animator = new ParticleAnimator ( this . _fireAnimationSet ) ; particleSprite . animator = animator ; var degree = i / Basic_Fire . NUM_FIRES * Math . PI * 2 ; particleSprite . x = Math . sin ( degree ) * 400 ; particleSprite . z = Math . cos ( degree ) * 400 ; particleSprite . y = 5 ; this . _fireObjects . push ( new FireVO ( particleSprite , animator ) ) ; this . _scene . root . addChild ( particleSprite ) ; } this . _fireTimer = new Timer ( 1000 , this . _fireObjects . length ) ; this . _fireTimer . addEventListener ( TimerEvent . TIMER , ( event ) => this . onTimer ( event ) ) ; this . _fireTimer . start ( ) ; } /**
     * 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 . _timer = new RequestAnimationFrame ( this . onEnterFrame , this ) ; this . _timer . start ( ) ; AssetLibrary . addEventListener ( LoaderEvent . LOAD_COMPLETE , ( event ) => this . onResourceComplete ( event ) ) ; AssetLibrary . load ( new URLRequest ( "assets/floor_diffuse.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/floor_normal.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/floor_specular.jpg" ) ) ; AssetLibrary . load ( new URLRequest ( "assets/blue.png" ) ) ; } /**
     * Initialiser for particle properties
     */ private initParticleFunc ( prop ) { prop . startTime = Math . random ( ) * 5 ; prop . duration = Math . random ( ) * 4 + 0.1 ; var degree1 = Math . random ( ) * Math . PI * 2 ; var degree2 = Math . random ( ) * Math . PI * 2 ; var r = 15 ; prop [ ParticleVelocityNode . VELOCITY_VECTOR3D ] = new Vector3D ( r * Math . sin ( degree1 ) * Math . cos ( degree2 ) , r * Math . cos ( degree1 ) * Math . cos ( degree2 ) , r * Math . sin ( degree2 ) ) ; } /**
     * Returns an array of active lights in the scene
     */ private getAllLights ( ) { var lights = new Array < any > ( ) ; lights . push ( this . _directionalLight ) ; var fireVO ; for ( var i = 0 ; i < this . _fireObjects . length ; i ++ ) { fireVO = this . _fireObjects [ i ] ; if ( fireVO . light ) lights . push ( fireVO . light ) ; } return lights ; } /**
     * Timer event handler
     */ private onTimer ( event ) { var fireObject = this . _fireObjects [ this . _fireTimer . currentCount - 1 ] ; fireObject . animator . start ( ) ; var light = new PointLight ( ) ; light . color = 0xFF3301 ; light . diffuse = 0 ; light . specular = 0 ; light . transform . moveTo ( fireObject . sprite . x , fireObject . sprite . y , fireObject . sprite . z ) ; fireObject . light = light ; this . _lightPicker . lights = this . getAllLights ( ) ; } /**
     * Navigation and render loop
     */ private onEnterFrame ( dt ) { this . _time += dt ; var fireVO ; for ( var i = 0 ; i < this . _fireObjects . length ; i ++ ) { fireVO = this . _fireObjects [ i ] ; var light = fireVO . light ; if ( ! light ) continue ; if ( fireVO . strength < 1 ) fireVO . strength += 0.1 ; light . fallOff = 380 + Math . random ( ) * 20 ; light . radius = 200 + Math . random ( ) * 30 ; light . diffuse = light . specular = fireVO . strength + Math . random ( ) * .2 ; } this . _scene . render ( ) ; } /**
     * Listener function for resource complete event on asset library
     */ private onResourceComplete ( event ) { var assets = event . assets ; var length = assets . length ; for ( var c = 0 ; c < length ; c ++ ) { var asset = assets [ c ] ; console . log ( asset . name , event . url ) ; switch ( event . url ) { case "assets/floor_diffuse.jpg" : this . _planeMaterial . ambientMethod . texture = new ImageTexture2D ( < BitmapImage2D > asset ) ; break ; case "assets/floor_normal.jpg" : this . _planeMaterial . normalMethod . texture = new ImageTexture2D ( < BitmapImage2D > asset ) ; break ; case "assets/floor_specular.jpg" : this . _planeMaterial . specularMethod . texture = new ImageTexture2D ( < BitmapImage2D > asset ) ; break ; case "assets/blue.png" : this . _particleMaterial . ambientMethod . texture = new ImageTexture2D ( < BitmapImage2D > asset ) ; 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 ; } 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 ; } } /**
     * stage listener for resize events
     */ private onResize ( event = null ) { this . _scene . view . y = 0 ; this . _scene . view . x = 0 ; this . _scene . view . width = window . innerWidth ; this . _scene . view . height = window . innerHeight ; } } /**
* Data class for the fire objects
*/ class FireVO { public sprite : Sprite ; public animator : ParticleAnimator ; public light : PointLight ; public strength : number = 0 ; constructor ( sprite , animator ) { this . sprite = sprite ; this . animator = animator ; } } window . onload = function ( ) { new Basic_Fire ( ) ; } ;