package {
import cmodule.FluidSolver.CLibInit;
import com.adobe.viewsource.ViewSource;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.utils.ByteArray;
import flash.utils.getTimer;
import net.hires.debug.Stats;
[SWF(width="512", height="512", frameRate="120")]
public class AlchemySmoke extends Sprite
{
private var _cLib : CLibInit;
private var _cMethods : Object;
private var _width : int = 100,
_height : int = 100;
private var _bitmapData : BitmapData;
private var _bitmap : Bitmap;
private var _destPosition : int;
private var _cRAM : ByteArray;
private var _rect : Rectangle;
private var _prevTime : int;
private var _mouseDown : Boolean;
private var _oldMouseX : Number = -1;
private var _oldMouseY : Number = -1;
private var _textField : TextField;
public function AlchemySmoke()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
ViewSource.addMenuItem(this, "srcview/");
initCLib();
initView();
_prevTime = getTimer();
stage.addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, handleMouseUp);
addEventListener(Event.ENTER_FRAME, handleEnterFrame);
}
private function initCLib() : void
{
var ns : Namespace = new Namespace( "cmodule.FluidSolver");
_cLib = new CLibInit();
_cMethods = _cLib.init();
_cRAM = (ns::gstate).ds;
_destPosition = _cMethods.initBuffers(_width, _height, 0);
_cMethods.setAdvectionProperties(150, 150, 150, 150);
}
/**
* Create view assets
*/
private function initView() : void
{
_bitmapData = new BitmapData(_width, _height, false, 0x000000);
_rect = new Rectangle(0, 0, _width, _height);
_bitmap = new Bitmap(_bitmapData);
_bitmap.scaleY = _bitmap.scaleX = Math.min(stage.stageWidth/_bitmapData.width, stage.stageHeight/_bitmapData.height);
_bitmap.smoothing = true;
addChild(_bitmap);
addChild(new Stats());
_textField = new TextField();
_textField.textColor = 0xffffff;
_textField.multiline = true;
_textField.text = "Mouse down - add smoke\n"+
"Mouse move - move air";
_textField.width = 400;
_textField.height = _textField.textHeight+10;
_textField.y = stage.stageHeight-_textField.textHeight-10;
addChild(_textField);
}
private function handleMouseDown(event : MouseEvent) : void
{
_mouseDown = true;
}
private function handleMouseUp(event : MouseEvent) : void
{
_mouseDown = false;
}
/**
* Calculates time between two frames
*/
private function get timeStep() : Number
{
var dt : Number;
var currentTime : int = getTimer();
dt = (currentTime-_prevTime)/1000;
_prevTime = currentTime;
return dt;
}
private function handleEnterFrame(event : Event) : void
{
var dx : Number, dy : Number;
if (_oldMouseX == -1) _oldMouseX = _bitmap.mouseX;
if (_oldMouseY == -1) _oldMouseY = _bitmap.mouseY;
_cMethods.addForceLine(_oldMouseX, _oldMouseY, _bitmap.mouseX, _bitmap.mouseY, 0.02);
_cMethods.addForceLine(_oldMouseX-1, _oldMouseY, _bitmap.mouseX-1, _bitmap.mouseY, 0.01);
_cMethods.addForceLine(_oldMouseX+1, _oldMouseY, _bitmap.mouseX+1, _bitmap.mouseY, 0.01);
_cMethods.addForceLine(_oldMouseX, _oldMouseY+1, _bitmap.mouseX, _bitmap.mouseY+1, 0.01);
_cMethods.addForceLine(_oldMouseX+1, _oldMouseY+1, _bitmap.mouseX+1, _bitmap.mouseY+1, 0.01);
_cMethods.addForceLine(_oldMouseX-1, _oldMouseY+1, _bitmap.mouseX-1, _bitmap.mouseY+1, 0.01);
_cMethods.addForceLine(_oldMouseX, _oldMouseY-1, _bitmap.mouseX, _bitmap.mouseY-1, 0.01);
_cMethods.addForceLine(_oldMouseX+1, _oldMouseY-1, _bitmap.mouseX+1, _bitmap.mouseY-1, 0.01);
_cMethods.addForceLine(_oldMouseX-1, _oldMouseY-1, _bitmap.mouseX-1, _bitmap.mouseY-1, 0.01);
if (_mouseDown) _cMethods.addInkLine(_oldMouseX, _oldMouseY, _bitmap.mouseX, _bitmap.mouseY, 2);
_oldMouseX = _bitmap.mouseX;
_oldMouseY = _bitmap.mouseY;
_cMethods.updateSimulation(Math.min(timeStep, .025));
_cRAM.position = _destPosition;
_bitmapData.setPixels(_rect, _cRAM);
}
}
}