topical media & game development
student-ar-org-papervision3d-core-effects-BitmapFireEffect.ax
student-ar-org-papervision3d-core-effects-BitmapFireEffect.ax
[swf]
[flash]
flex
...
author: Default
version: 0.1
package org.papervision3d.core.effects {
import org.papervision3d.view.layer.BitmapEffectLayer;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.filters.DisplacementMapFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
public class @ax-student-ar-org-papervision3d-core-effects-BitmapFireEffect extends AbstractEffect{
private var layer:BitmapEffectLayer;
private var _fadeRate:Number=0.4;
private var _distortionScale:Number=0.4;
private var _distortion:Number=0.5;
private var _flameHeight:Number=0.3;
private var _flameSpread:Number=0.3;
private var _blueFlame:Boolean = false;
private var _smoke:Number = 0;
// private properties:
// display elements:
private var displayBmp:BitmapData;
private var scratchBmp:BitmapData;
private var perlinBmp:BitmapData;
// geom:
private var mtx:Matrix;
private var pnt:Point;
private var drawColorTransform:ColorTransform;
// filters:
private var fireCMF:ColorMatrixFilter;
private var dispMapF:DisplacementMapFilter;
private var blurF:BlurFilter;
// other
private var endCount:Number;
private var bmpsValid:Boolean=false;
private var perlinValid:Boolean=false;
private var filtersValid:Boolean=false;
private var _target:DisplayObject;
public function @ax-student-ar-org-papervision3d-core-effects-BitmapFireEffect(r:Number = 1, g:Number = 1, b:Number = 1, a:Number= 1){
mtx = new Matrix();
pnt = new Point();
}
public override function attachEffect(layer:BitmapEffectLayer):void{
this.layer = BitmapEffectLayer(layer);
target = layer.drawLayer;
}
public override function postRender():void{
doFire();
//layer.canvas.applyFilter(layer.canvas, layer.canvas.rect, new Point(), fade);
}
public function set width(value:Number):void {
//layer.canvas.width;
}
public function get width():Number {
return layer.canvas.width;
}
public function set height(value:Number):void {
;
}
public function get height():Number {
return layer.canvas.height;
}
[Inspectable(defaultValue=0.4,name='fadeRate (0-1)')]
Sets the rate that flames fade as they move up. 0 is slowest, 1 is fastest.
@default 0.4
public function set fadeRate(value:Number):void {
filtersValid &&= (value == _fadeRate);
_fadeRate = value;
}
public function get fadeRate():Number {
return _fadeRate;
}
[Inspectable(defaultValue=0.4,name='distortionScale (0-1)')]
Sets the scale of flame distortion. 0.1 is tiny and chaotic, 1 is large and smooth.
@default 0.4
public function set distortionScale(value:Number):void {
perlinValid &&= (value == _distortionScale);
_distortionScale = value;
}
public function get distortionScale():Number {
return _distortionScale;
}
[Inspectable(defaultValue=0.4,name='distortion (0-1)')]
Sets the amount of distortion. 0.1 is little, 1 is chaotic.
@default 0.4
public function set distortion(value:Number):void {
filtersValid &&= (value == _fadeRate);
_distortion = value;
}
public function get distortion():Number {
return _distortion;
}
[Inspectable(defaultValue=0.3,name='flameHeight (0-1)')]
Sets the how high the flame will burn. 0 is zero gravity, 1 is a bonfire.
@default 0.3
public function set flameHeight(value:Number):void {
perlinValid &&= (value == _flameHeight);
_flameHeight = value;
}
public function get flameHeight():Number {
return _flameHeight;
}
[Inspectable(defaultValue=0.3,name='flameSpread (0-1)')]
Sets the how much the fire will spread out around the target. 0 is no spread, 1 is a lot.
@default 0.3
public function set flameSpread(value:Number):void {
filtersValid &&= (value == _flameSpread);
_flameSpread = value;
}
public function get flameSpread():Number {
return _flameSpread;
}
[Inspectable(defaultValue=false,name='blueFlame')]
Indicates whether it should use a blue or red flame.
@default false
public function set blueFlame(value:Boolean):void {
filtersValid &&= (value == _blueFlame);
_blueFlame = value;
}
public function get blueFlame():Boolean {
return _blueFlame;
}
[Inspectable(defaultValue=0,name='smoke (0-1)')]
Sets the amount of smoke. 0 little, 1 lots.
@default 0
public function set smoke(value:Number):void {
filtersValid &&= (value == _smoke);
_smoke = value;
}
public function get smoke():Number {
return _smoke;
}
[Inspectable(defaultValue='',name='target')]
Sets the amount of smoke. 0 little, 1 lots.
@default
public function set targetName(value:String):void {
}
Defines the shape of the fire. The fire will burn upwards, so it should be near the bottom, and centered in the FireFX component.
@default
public function set target(value:DisplayObject):void {
_target = value;
clear();
}
public function get target():DisplayObject {
return _target;
}
Clears the fire.
public function clear():void {
if (displayBmp) {
displayBmp.fillRect(displayBmp.rect,0);
}
}
public function stopFire():void {
// let the fire burn down for 20 frames:
if (endCount == 0) { endCount = 20; }
}
private function updateBitmaps():void {
if (displayBmp) {
displayBmp.dispose();
displayBmp = null;
scratchBmp.dispose();
scratchBmp = null;
perlinBmp.dispose();
perlinBmp = null;
}
displayBmp = layer.canvas;
scratchBmp = displayBmp.clone();
perlinBmp = new BitmapData(width*3, height*3, false, 0);
updatePerlin();
updateFilters();
bmpsValid = true;
}
private function updatePerlin():void {
perlinBmp.perlinNoise(30*_distortionScale,20*_distortionScale,1,-Math.random()*1000|0,false,true,1|2,false);
perlinBmp.colorTransform(perlinBmp.rect,new ColorTransform(1, 1-_flameHeight*0.5 ,1,1,0,0,0,0));
perlinValid = true;
}
private function updateFilters():void {
if (_blueFlame) {
fireCMF = new ColorMatrixFilter([0.8-0.55*_fadeRate,0,0,0,0,
0,0.93-0.48*_fadeRate,0,0,0,
0,0.1,0.96-0.35*_fadeRate,0,0,
0,0.1,0,1,-25+_smoke*24]);
drawColorTransform = new ColorTransform(0,0,0,1,210,240,255,0);
} else {
fireCMF = new ColorMatrixFilter([0.96-0.35*_fadeRate,0.1,0,0,-1,
0,0.9-0.45*_fadeRate,0,0,0,
0,0,0.8-0.55*_fadeRate,0,0,
0,0.1,0,1,-25+_smoke*24]);
drawColorTransform = new ColorTransform(0,0,0,1,255,255,210,0);
}
dispMapF = new DisplacementMapFilter(perlinBmp,pnt,1,2,14*_distortion,-30,"clamp");
blurF = new BlurFilter(32*_flameSpread,32*_flameSpread,1);
filtersValid = true;
}
private function startFire():void {
endCount = 0;
}
private function doFire():void {
if (_target == null) { return; }
if (!bmpsValid) { updateBitmaps(); }
if (!perlinValid) { updatePerlin(); }
if (!filtersValid) { updateFilters(); }
if (endCount == 0) {
var drawMtx:Matrix = _target.transform.matrix;
scratchBmp.fillRect(scratchBmp.rect,0);
drawColorTransform.alphaOffset = -Math.random()*200|0;
scratchBmp.draw(_target,drawMtx,drawColorTransform,"add");
scratchBmp.applyFilter(scratchBmp,scratchBmp.rect,pnt,blurF);
displayBmp.draw(scratchBmp,mtx,null,"add");
}
dispMapF.mapPoint = new Point( -Math.random()*(perlinBmp.width-displayBmp.width)|0, -Math.random()*(perlinBmp.height-displayBmp.height)|0 );
displayBmp.applyFilter(displayBmp,displayBmp.rect,pnt,dispMapF);
displayBmp.applyFilter(displayBmp,displayBmp.rect,pnt,fireCMF);
//if (endCount != 0 && --endCount == 0) {
// removeEventListener(Event.ENTER_FRAME,doFire);
}
}
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.