webgl-3d-animation
Version:
Interactive 3D animation using WebGL showing a 2D predator prey ecology on a grid which is real-time mapped onto the surface of a 3D torus. node.js server side gives access to WAV format files which are rendered using Web Audio API
887 lines • 338 kB
JavaScript
(function ($hx_exports) { "use strict";
$hx_exports.lime = $hx_exports.lime || {};
var console = (1,eval)('this').console || {log:function(){}};
var $hxClasses = {},$estr = function() { return js.Boot.__string_rec(this,''); };
function $extend(from, fields) {
function Inherit() {} Inherit.prototype = from; var proto = new Inherit();
for (var name in fields) proto[name] = fields[name];
if( fields.toString !== Object.prototype.toString ) proto.toString = fields.toString;
return proto;
}
var ApplicationMain = function() { };
$hxClasses["ApplicationMain"] = ApplicationMain;
ApplicationMain.__name__ = true;
ApplicationMain.create = function() {
ApplicationMain.preloader = new lime.app.Preloader();
ApplicationMain.preloader.onComplete = ApplicationMain.start;
ApplicationMain.preloader.create(ApplicationMain.config);
var urls = [];
var types = [];
ApplicationMain.preloader.load(urls,types);
};
ApplicationMain.main = function() {
ApplicationMain.config = { antialiasing : 0, background : 16777215, borderless : false, depthBuffer : false, fps : 0, fullscreen : false, height : 0, orientation : "", resizable : true, stencilBuffer : false, title : "WebGL Fluid Experiment", vsync : true, width : 0};
};
ApplicationMain.start = function() {
ApplicationMain.app = new Main();
ApplicationMain.app.create(ApplicationMain.config);
var result = ApplicationMain.app.exec();
};
var lime = {};
lime.AssetLibrary = function() {
};
$hxClasses["lime.AssetLibrary"] = lime.AssetLibrary;
lime.AssetLibrary.__name__ = true;
lime.AssetLibrary.prototype = {
exists: function(id,type) {
return false;
}
,getAudioBuffer: function(id) {
return null;
}
,getBytes: function(id) {
return null;
}
,getFont: function(id) {
return null;
}
,getImage: function(id) {
return null;
}
,getPath: function(id) {
return null;
}
,getText: function(id) {
var bytes = this.getBytes(id);
if(bytes == null) return null; else return bytes.readUTFBytes(bytes.length);
}
,isLocal: function(id,type) {
return true;
}
,list: function(type) {
return null;
}
,load: function(handler) {
handler(this);
}
,loadAudioBuffer: function(id,handler) {
handler(this.getAudioBuffer(id));
}
,loadBytes: function(id,handler) {
handler(this.getBytes(id));
}
,loadFont: function(id,handler) {
handler(this.getFont(id));
}
,loadImage: function(id,handler) {
handler(this.getImage(id));
}
,loadText: function(id,handler) {
var callback = function(bytes) {
if(bytes == null) handler(null); else handler(bytes.readUTFBytes(bytes.length));
};
this.loadBytes(id,callback);
}
,__class__: lime.AssetLibrary
};
var DefaultAssetLibrary = function() {
this.type = new haxe.ds.StringMap();
this.path = new haxe.ds.StringMap();
this.className = new haxe.ds.StringMap();
lime.AssetLibrary.call(this);
var id;
};
$hxClasses["DefaultAssetLibrary"] = DefaultAssetLibrary;
DefaultAssetLibrary.__name__ = true;
DefaultAssetLibrary.__super__ = lime.AssetLibrary;
DefaultAssetLibrary.prototype = $extend(lime.AssetLibrary.prototype,{
exists: function(id,type) {
var requestedType;
if(type != null) requestedType = js.Boot.__cast(type , String); else requestedType = null;
var assetType = this.type.get(id);
if(assetType != null) {
if(assetType == requestedType || (requestedType == "SOUND" || requestedType == "MUSIC") && (assetType == "MUSIC" || assetType == "SOUND")) return true;
if(requestedType == "BINARY" || requestedType == null || assetType == "BINARY" && requestedType == "TEXT") return true;
}
return false;
}
,getAudioBuffer: function(id) {
return null;
}
,getBytes: function(id) {
var bytes = null;
var data;
data = ((function($this) {
var $r;
var key = $this.path.get(id);
$r = lime.app.Preloader.loaders.get(key);
return $r;
}(this))).data;
if(typeof(data) == "string") {
bytes = new lime.utils.ByteArray();
bytes.writeUTFBytes(data);
} else if(js.Boot.__instanceof(data,lime.utils.ByteArray)) bytes = data; else bytes = null;
if(bytes != null) {
bytes.position = 0;
return bytes;
} else return null;
}
,getFont: function(id) {
return null;
}
,getImage: function(id) {
return lime.graphics.Image.fromImageElement((function($this) {
var $r;
var key = $this.path.get(id);
$r = lime.app.Preloader.images.get(key);
return $r;
}(this)));
}
,getPath: function(id) {
return this.path.get(id);
}
,getText: function(id) {
var bytes = null;
var data;
data = ((function($this) {
var $r;
var key = $this.path.get(id);
$r = lime.app.Preloader.loaders.get(key);
return $r;
}(this))).data;
if(typeof(data) == "string") return data; else if(js.Boot.__instanceof(data,lime.utils.ByteArray)) bytes = data; else bytes = null;
if(bytes != null) {
bytes.position = 0;
return bytes.readUTFBytes(bytes.length);
} else return null;
}
,isLocal: function(id,type) {
var requestedType;
if(type != null) requestedType = js.Boot.__cast(type , String); else requestedType = null;
return true;
}
,list: function(type) {
var requestedType;
if(type != null) requestedType = js.Boot.__cast(type , String); else requestedType = null;
var items = [];
var $it0 = this.type.keys();
while( $it0.hasNext() ) {
var id = $it0.next();
if(requestedType == null || this.exists(id,type)) items.push(id);
}
return items;
}
,loadAudioBuffer: function(id,handler) {
handler(this.getAudioBuffer(id));
}
,loadBytes: function(id,handler) {
handler(this.getBytes(id));
}
,loadImage: function(id,handler) {
handler(this.getImage(id));
}
,loadText: function(id,handler) {
var callback = function(bytes) {
if(bytes == null) handler(null); else handler(bytes.readUTFBytes(bytes.length));
};
this.loadBytes(id,callback);
}
,__class__: DefaultAssetLibrary
});
var EReg = function(r,opt) {
opt = opt.split("u").join("");
this.r = new RegExp(r,opt);
};
$hxClasses["EReg"] = EReg;
EReg.__name__ = true;
EReg.prototype = {
match: function(s) {
if(this.r.global) this.r.lastIndex = 0;
this.r.m = this.r.exec(s);
this.r.s = s;
return this.r.m != null;
}
,__class__: EReg
};
var GPUFluid = function(gl,width,height,cellSize,solverIterations) {
if(solverIterations == null) solverIterations = 18;
if(cellSize == null) cellSize = 8;
this.pressureGradientSubstractShader = new PressureGradientSubstract();
this.pressureSolveShader = new PressureSolve();
this.divergenceShader = new Divergence();
this.advectShader = new Advect();
this.gl = gl;
this.width = width;
this.height = height;
this.solverIterations = solverIterations;
this.aspectRatio = this.width / this.height;
this.cellSize = cellSize;
this.advectShader.rdx.set(1 / this.cellSize);
this.divergenceShader.halfrdx.set(0.5 * (1 / this.cellSize));
this.pressureGradientSubstractShader.halfrdx.set(0.5 * (1 / this.cellSize));
this.pressureSolveShader.alpha.set(-this.cellSize * this.cellSize);
this.cellSize;
var texture_float_linear_supported = true;
if(gl.getExtension("OES_texture_float_linear") == null) texture_float_linear_supported = false;
if(gl.getExtension("OES_texture_float") == null) null;
this.textureQuad = gltoolbox.GeometryTools.getCachedTextureQuad();
var nearestFactory = gltoolbox.TextureTools.createTextureFactory(gl.RGBA,gl.FLOAT,gl.NEAREST,null);
this.velocityRenderTarget = new gltoolbox.render.RenderTarget2Phase(width,height,nearestFactory);
this.pressureRenderTarget = new gltoolbox.render.RenderTarget2Phase(width,height,nearestFactory);
this.divergenceRenderTarget = new gltoolbox.render.RenderTarget(width,height,nearestFactory);
this.dyeRenderTarget = new gltoolbox.render.RenderTarget2Phase(width,height,gltoolbox.TextureTools.createTextureFactory(gl.RGB,gl.FLOAT,texture_float_linear_supported?gl.LINEAR:gl.NEAREST,null));
this.updateCoreShaderUniforms(this.advectShader);
this.updateCoreShaderUniforms(this.divergenceShader);
this.updateCoreShaderUniforms(this.pressureSolveShader);
this.updateCoreShaderUniforms(this.pressureGradientSubstractShader);
};
$hxClasses["GPUFluid"] = GPUFluid;
GPUFluid.__name__ = true;
GPUFluid.prototype = {
step: function(dt) {
this.gl.viewport(0,0,this.width,this.height);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.textureQuad);
this.advect(this.velocityRenderTarget,dt);
if(this.applyForcesShader == null) null; else {
this.applyForcesShader.dt.set(dt);
this.applyForcesShader.velocity.set(this.velocityRenderTarget.readFromTexture);
this.renderShaderTo(this.applyForcesShader,this.velocityRenderTarget);
this.velocityRenderTarget.swap();
}
this.divergenceShader.velocity.set(this.velocityRenderTarget.readFromTexture);
this.renderShaderTo(this.divergenceShader,this.divergenceRenderTarget);
this.solvePressure();
this.pressureGradientSubstractShader.pressure.set(this.pressureRenderTarget.readFromTexture);
this.pressureGradientSubstractShader.velocity.set(this.velocityRenderTarget.readFromTexture);
this.renderShaderTo(this.pressureGradientSubstractShader,this.velocityRenderTarget);
this.velocityRenderTarget.swap();
if(this.updateDyeShader == null) null; else {
this.updateDyeShader.dt.set(dt);
this.updateDyeShader.dye.set(this.dyeRenderTarget.readFromTexture);
this.renderShaderTo(this.updateDyeShader,this.dyeRenderTarget);
this.dyeRenderTarget.swap();
}
this.advect(this.dyeRenderTarget,dt);
}
,resize: function(width,height) {
this.velocityRenderTarget.resize(width,height);
this.pressureRenderTarget.resize(width,height);
this.divergenceRenderTarget.resize(width,height);
this.dyeRenderTarget.resize(width,height);
this.width = width;
this.height = height;
}
,clear: function() {
this.velocityRenderTarget.clear(this.gl.COLOR_BUFFER_BIT);
this.pressureRenderTarget.clear(this.gl.COLOR_BUFFER_BIT);
this.dyeRenderTarget.clear(this.gl.COLOR_BUFFER_BIT);
}
,simToClipSpaceX: function(simX) {
return simX / (this.cellSize * this.aspectRatio);
}
,simToClipSpaceY: function(simY) {
return simY / this.cellSize;
}
,advect: function(target,dt) {
this.advectShader.dt.set(dt);
this.advectShader.target.set(target.readFromTexture);
this.advectShader.velocity.set(this.velocityRenderTarget.readFromTexture);
this.renderShaderTo(this.advectShader,target);
target.tmpFBO = target.writeFrameBufferObject;
target.writeFrameBufferObject = target.readFrameBufferObject;
target.readFrameBufferObject = target.tmpFBO;
target.tmpTex = target.writeToTexture;
target.writeToTexture = target.readFromTexture;
target.readFromTexture = target.tmpTex;
}
,applyForces: function(dt) {
if(this.applyForcesShader == null) return;
this.applyForcesShader.dt.set(dt);
this.applyForcesShader.velocity.set(this.velocityRenderTarget.readFromTexture);
this.renderShaderTo(this.applyForcesShader,this.velocityRenderTarget);
this.velocityRenderTarget.swap();
}
,computeDivergence: function() {
this.divergenceShader.velocity.set(this.velocityRenderTarget.readFromTexture);
this.renderShaderTo(this.divergenceShader,this.divergenceRenderTarget);
}
,solvePressure: function() {
this.pressureSolveShader.divergence.set(this.divergenceRenderTarget.texture);
this.pressureSolveShader.activate(true,true);
var _g1 = 0;
var _g = this.solverIterations;
while(_g1 < _g) {
var i = _g1++;
this.pressureSolveShader.pressure.set(this.pressureRenderTarget.readFromTexture);
this.pressureSolveShader.setUniforms();
lime.graphics.opengl.GL.context.bindFramebuffer(36160,this.pressureRenderTarget.writeFrameBufferObject);
this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);
this.pressureRenderTarget.swap();
}
this.pressureSolveShader.deactivate();
}
,subtractPressureGradient: function() {
this.pressureGradientSubstractShader.pressure.set(this.pressureRenderTarget.readFromTexture);
this.pressureGradientSubstractShader.velocity.set(this.velocityRenderTarget.readFromTexture);
this.renderShaderTo(this.pressureGradientSubstractShader,this.velocityRenderTarget);
this.velocityRenderTarget.swap();
}
,updateDye: function(dt) {
if(this.updateDyeShader == null) return;
this.updateDyeShader.dt.set(dt);
this.updateDyeShader.dye.set(this.dyeRenderTarget.readFromTexture);
this.renderShaderTo(this.updateDyeShader,this.dyeRenderTarget);
this.dyeRenderTarget.swap();
}
,renderShaderTo: function(shader,target) {
if(shader.active) {
shader.setUniforms();
shader.setAttributes();
null;
} else {
if(!shader.ready) shader.create();
lime.graphics.opengl.GL.context.useProgram(shader.prog);
shader.setUniforms();
shader.setAttributes();
shader.active = true;
}
target.activate();
this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);
shader.deactivate();
}
,updateCoreShaderUniforms: function(shader) {
if(shader == null) return;
shader.aspectRatio.set(this.aspectRatio);
shader.invresolution.data.x = 1 / this.width;
shader.invresolution.data.y = 1 / this.height;
}
,set_applyForcesShader: function(v) {
this.applyForcesShader = v;
this.applyForcesShader.dx.set_data(this.cellSize);
this.updateCoreShaderUniforms(this.applyForcesShader);
return this.applyForcesShader;
}
,set_updateDyeShader: function(v) {
this.updateDyeShader = v;
this.updateDyeShader.dx.set_data(this.cellSize);
this.updateCoreShaderUniforms(this.updateDyeShader);
return this.updateDyeShader;
}
,set_cellSize: function(v) {
this.cellSize = v;
this.advectShader.rdx.set(1 / this.cellSize);
this.divergenceShader.halfrdx.set(0.5 * (1 / this.cellSize));
this.pressureGradientSubstractShader.halfrdx.set(0.5 * (1 / this.cellSize));
this.pressureSolveShader.alpha.set(-this.cellSize * this.cellSize);
return this.cellSize;
}
,__class__: GPUFluid
};
var shaderblox = {};
shaderblox.ShaderBase = function() {
this.textures = [];
this.uniforms = [];
this.attributes = [];
this.name = ("" + Std.string(Type.getClass(this))).split(".").pop();
this.createProperties();
};
$hxClasses["shaderblox.ShaderBase"] = shaderblox.ShaderBase;
shaderblox.ShaderBase.__name__ = true;
shaderblox.ShaderBase.prototype = {
createProperties: function() {
}
,create: function() {
}
,destroy: function() {
haxe.Log.trace("Destroying " + Std.string(this),{ fileName : "ShaderBase.hx", lineNumber : 51, className : "shaderblox.ShaderBase", methodName : "destroy"});
lime.graphics.opengl.GL.context.deleteShader(this.vert);
lime.graphics.opengl.GL.context.deleteShader(this.frag);
lime.graphics.opengl.GL.context.deleteProgram(this.prog);
this.prog = null;
this.vert = null;
this.frag = null;
this.ready = false;
}
,initFromSource: function(vertSource,fragSource) {
var vertexShader = lime.graphics.opengl.GL.context.createShader(35633);
lime.graphics.opengl.GL.context.shaderSource(vertexShader,vertSource);
lime.graphics.opengl.GL.context.compileShader(vertexShader);
if(lime.graphics.opengl.GL.context.getShaderParameter(vertexShader,35713) == 0) {
haxe.Log.trace("Error compiling vertex shader: " + lime.graphics.opengl.GL.context.getShaderInfoLog(vertexShader),{ fileName : "ShaderBase.hx", lineNumber : 67, className : "shaderblox.ShaderBase", methodName : "initFromSource"});
haxe.Log.trace("\n" + vertSource,{ fileName : "ShaderBase.hx", lineNumber : 68, className : "shaderblox.ShaderBase", methodName : "initFromSource"});
throw "Error compiling vertex shader";
}
var fragmentShader = lime.graphics.opengl.GL.context.createShader(35632);
lime.graphics.opengl.GL.context.shaderSource(fragmentShader,fragSource);
lime.graphics.opengl.GL.context.compileShader(fragmentShader);
if(lime.graphics.opengl.GL.context.getShaderParameter(fragmentShader,35713) == 0) {
haxe.Log.trace("Error compiling fragment shader: " + lime.graphics.opengl.GL.context.getShaderInfoLog(fragmentShader) + "\n",{ fileName : "ShaderBase.hx", lineNumber : 77, className : "shaderblox.ShaderBase", methodName : "initFromSource"});
var lines = fragSource.split("\n");
var i = 0;
var _g = 0;
while(_g < lines.length) {
var l = lines[_g];
++_g;
haxe.Log.trace(i++ + " - " + l,{ fileName : "ShaderBase.hx", lineNumber : 81, className : "shaderblox.ShaderBase", methodName : "initFromSource"});
}
throw "Error compiling fragment shader";
}
var shaderProgram = lime.graphics.opengl.GL.context.createProgram();
lime.graphics.opengl.GL.context.attachShader(shaderProgram,vertexShader);
lime.graphics.opengl.GL.context.attachShader(shaderProgram,fragmentShader);
lime.graphics.opengl.GL.context.linkProgram(shaderProgram);
if(lime.graphics.opengl.GL.context.getProgramParameter(shaderProgram,35714) == 0) throw "Unable to initialize the shader program.\n" + lime.graphics.opengl.GL.context.getProgramInfoLog(shaderProgram);
var numUniforms = lime.graphics.opengl.GL.context.getProgramParameter(shaderProgram,35718);
var uniformLocations = new haxe.ds.StringMap();
while(numUniforms-- > 0) {
var uInfo = lime.graphics.opengl.GL.context.getActiveUniform(shaderProgram,numUniforms);
var loc = lime.graphics.opengl.GL.context.getUniformLocation(shaderProgram,uInfo.name);
uniformLocations.set(uInfo.name,loc);
loc;
}
var numAttributes = lime.graphics.opengl.GL.context.getProgramParameter(shaderProgram,35721);
var attributeLocations = new haxe.ds.StringMap();
while(numAttributes-- > 0) {
var aInfo = lime.graphics.opengl.GL.context.getActiveAttrib(shaderProgram,numAttributes);
var loc1 = lime.graphics.opengl.GL.context.getAttribLocation(shaderProgram,aInfo.name);
attributeLocations.set(aInfo.name,loc1);
loc1;
}
this.vert = vertexShader;
this.frag = fragmentShader;
this.prog = shaderProgram;
var count = this.uniforms.length;
var removeList = [];
this.numTextures = 0;
this.textures = [];
var _g1 = 0;
var _g11 = this.uniforms;
while(_g1 < _g11.length) {
var u = _g11[_g1];
++_g1;
var loc2 = uniformLocations.get(u.name);
if(js.Boot.__instanceof(u,shaderblox.uniforms.UTexture)) {
var t = u;
t.samplerIndex = this.numTextures++;
this.textures[t.samplerIndex] = t;
}
if(loc2 != null) u.location = loc2; else removeList.push(u);
}
while(removeList.length > 0) {
var x = removeList.pop();
HxOverrides.remove(this.uniforms,x);
}
var _g2 = 0;
var _g12 = this.attributes;
while(_g2 < _g12.length) {
var a = _g12[_g2];
++_g2;
var loc3 = attributeLocations.get(a.name);
if(loc3 == null) a.location = -1; else a.location = loc3;
}
}
,activate: function(initUniforms,initAttribs) {
if(initAttribs == null) initAttribs = false;
if(initUniforms == null) initUniforms = true;
if(this.active) {
if(initUniforms) this.setUniforms();
if(initAttribs) this.setAttributes();
return;
}
if(!this.ready) this.create();
lime.graphics.opengl.GL.context.useProgram(this.prog);
if(initUniforms) this.setUniforms();
if(initAttribs) this.setAttributes();
this.active = true;
}
,deactivate: function() {
if(!this.active) return;
this.active = false;
this.disableAttributes();
}
,setUniforms: function() {
var _g = 0;
var _g1 = this.uniforms;
while(_g < _g1.length) {
var u = _g1[_g];
++_g;
u.apply();
}
}
,setAttributes: function() {
var offset = 0;
var _g1 = 0;
var _g = this.attributes.length;
while(_g1 < _g) {
var i = _g1++;
var att = this.attributes[i];
var location = att.location;
if(location != -1) {
lime.graphics.opengl.GL.context.enableVertexAttribArray(location);
lime.graphics.opengl.GL.context.vertexAttribPointer(location,att.itemCount,att.type,false,this.aStride,offset);
}
offset += att.byteSize;
}
}
,disableAttributes: function() {
var _g1 = 0;
var _g = this.attributes.length;
while(_g1 < _g) {
var i = _g1++;
var idx = this.attributes[i].location;
if(idx == -1) continue;
lime.graphics.opengl.GL.context.disableVertexAttribArray(idx);
}
}
,toString: function() {
return "[Shader(" + this.name + ", attributes:" + this.attributes.length + ", uniforms:" + this.uniforms.length + ")]";
}
,__class__: shaderblox.ShaderBase
};
var FluidBase = function() {
shaderblox.ShaderBase.call(this);
};
$hxClasses["FluidBase"] = FluidBase;
FluidBase.__name__ = true;
FluidBase.__super__ = shaderblox.ShaderBase;
FluidBase.prototype = $extend(shaderblox.ShaderBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n \r\nattribute vec2 vertexPosition;\r\n\r\nuniform float aspectRatio;\r\n\r\nvarying vec2 texelCoord;\r\n\r\n\r\nvarying vec2 p;\r\n\r\nvoid main() {\r\n\ttexelCoord = vertexPosition;\r\n\t\r\n\tvec2 clipSpace = 2.0*texelCoord - 1.0;\t\n\t\r\n\tp = vec2(clipSpace.x * aspectRatio, clipSpace.y);\r\n\r\n\tgl_Position = vec4(clipSpace, 0.0, 1.0 );\t\r\n}\r\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n#define PRESSURE_BOUNDARY\n#define VELOCITY_BOUNDARY\n\nuniform vec2 invresolution;\nuniform float aspectRatio;\n\nvec2 clipToSimSpace(vec2 clipSpace){\n return vec2(clipSpace.x * aspectRatio, clipSpace.y);\n}\n\nvec2 simToTexelSpace(vec2 simSpace){\n return vec2(simSpace.x / aspectRatio + 1.0 , simSpace.y + 1.0)*.5;\n}\n\n\nfloat samplePressue(sampler2D pressure, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n\n \n \n \n #ifdef PRESSURE_BOUNDARY\n if(coord.x < 0.0) cellOffset.x = 1.0;\n else if(coord.x > 1.0) cellOffset.x = -1.0;\n if(coord.y < 0.0) cellOffset.y = 1.0;\n else if(coord.y > 1.0) cellOffset.y = -1.0;\n #endif\n\n return texture2D(pressure, coord + cellOffset * invresolution).x;\n}\n\n\nvec2 sampleVelocity(sampler2D velocity, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n vec2 multiplier = vec2(1.0, 1.0);\n\n \n \n \n #ifdef VELOCITY_BOUNDARY\n if(coord.x<0.0){\n cellOffset.x = 1.0;\n multiplier.x = -1.0;\n }else if(coord.x>1.0){\n cellOffset.x = -1.0;\n multiplier.x = -1.0;\n }\n if(coord.y<0.0){\n cellOffset.y = 1.0;\n multiplier.y = -1.0;\n }else if(coord.y>1.0){\n cellOffset.y = -1.0;\n multiplier.y = -1.0;\n }\n #endif\n\n return multiplier * texture2D(velocity, coord + cellOffset * invresolution).xy;\n}\n");
this.ready = true;
}
,createProperties: function() {
shaderblox.ShaderBase.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["aspectRatio",-1]);
this.aspectRatio = instance;
this.uniforms.push(instance);
var instance1 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UVec2"),["invresolution",-1]);
this.invresolution = instance1;
this.uniforms.push(instance1);
var instance2 = Type.createInstance(Type.resolveClass("shaderblox.attributes.FloatAttribute"),["vertexPosition",0,2]);
this.vertexPosition = instance2;
this.attributes.push(instance2);
this.aStride += 8;
}
,__class__: FluidBase
});
var Advect = function() {
FluidBase.call(this);
};
$hxClasses["Advect"] = Advect;
Advect.__name__ = true;
Advect.__super__ = FluidBase;
Advect.prototype = $extend(FluidBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n \r\nattribute vec2 vertexPosition;\r\n\r\nuniform float aspectRatio;\r\n\r\nvarying vec2 texelCoord;\r\n\r\n\r\nvarying vec2 p;\r\n\r\nvoid main() {\r\n\ttexelCoord = vertexPosition;\r\n\t\r\n\tvec2 clipSpace = 2.0*texelCoord - 1.0;\t\n\t\r\n\tp = vec2(clipSpace.x * aspectRatio, clipSpace.y);\r\n\r\n\tgl_Position = vec4(clipSpace, 0.0, 1.0 );\t\r\n}\r\n\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n#define PRESSURE_BOUNDARY\n#define VELOCITY_BOUNDARY\n\nuniform vec2 invresolution;\nuniform float aspectRatio;\n\nvec2 clipToSimSpace(vec2 clipSpace){\n return vec2(clipSpace.x * aspectRatio, clipSpace.y);\n}\n\nvec2 simToTexelSpace(vec2 simSpace){\n return vec2(simSpace.x / aspectRatio + 1.0 , simSpace.y + 1.0)*.5;\n}\n\n\nfloat samplePressue(sampler2D pressure, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n\n \n \n \n #ifdef PRESSURE_BOUNDARY\n if(coord.x < 0.0) cellOffset.x = 1.0;\n else if(coord.x > 1.0) cellOffset.x = -1.0;\n if(coord.y < 0.0) cellOffset.y = 1.0;\n else if(coord.y > 1.0) cellOffset.y = -1.0;\n #endif\n\n return texture2D(pressure, coord + cellOffset * invresolution).x;\n}\n\n\nvec2 sampleVelocity(sampler2D velocity, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n vec2 multiplier = vec2(1.0, 1.0);\n\n \n \n \n #ifdef VELOCITY_BOUNDARY\n if(coord.x<0.0){\n cellOffset.x = 1.0;\n multiplier.x = -1.0;\n }else if(coord.x>1.0){\n cellOffset.x = -1.0;\n multiplier.x = -1.0;\n }\n if(coord.y<0.0){\n cellOffset.y = 1.0;\n multiplier.y = -1.0;\n }else if(coord.y>1.0){\n cellOffset.y = -1.0;\n multiplier.y = -1.0;\n }\n #endif\n\n return multiplier * texture2D(velocity, coord + cellOffset * invresolution).xy;\n}\n\nuniform sampler2D velocity;\nuniform sampler2D target;\nuniform float dt;\nuniform float rdx; \n\nvarying vec2 texelCoord;\nvarying vec2 p;\n\nvoid main(void){\n \n \n vec2 tracedPos = p - dt * rdx * texture2D(velocity, texelCoord ).xy;\n\n \n tracedPos = simToTexelSpace(tracedPos)/invresolution; \n \n vec4 st;\n st.xy = floor(tracedPos-.5)+.5; \n st.zw = st.xy+1.; \n\n vec2 t = tracedPos - st.xy;\n\n st*=invresolution.xyxy; \n \n vec4 tex11 = texture2D(target, st.xy );\n vec4 tex21 = texture2D(target, st.zy );\n vec4 tex12 = texture2D(target, st.xw );\n vec4 tex22 = texture2D(target, st.zw );\n\n \n gl_FragColor = mix(mix(tex11, tex21, t.x), mix(tex12, tex22, t.x), t.y);\n}\n");
this.ready = true;
}
,createProperties: function() {
FluidBase.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["velocity",-1,false]);
this.velocity = instance;
this.uniforms.push(instance);
var instance1 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["target",-1,false]);
this.target = instance1;
this.uniforms.push(instance1);
var instance2 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["dt",-1]);
this.dt = instance2;
this.uniforms.push(instance2);
var instance3 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["rdx",-1]);
this.rdx = instance3;
this.uniforms.push(instance3);
this.aStride += 0;
}
,__class__: Advect
});
var Divergence = function() {
FluidBase.call(this);
};
$hxClasses["Divergence"] = Divergence;
Divergence.__name__ = true;
Divergence.__super__ = FluidBase;
Divergence.prototype = $extend(FluidBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n \r\nattribute vec2 vertexPosition;\r\n\r\nuniform float aspectRatio;\r\n\r\nvarying vec2 texelCoord;\r\n\r\n\r\nvarying vec2 p;\r\n\r\nvoid main() {\r\n\ttexelCoord = vertexPosition;\r\n\t\r\n\tvec2 clipSpace = 2.0*texelCoord - 1.0;\t\n\t\r\n\tp = vec2(clipSpace.x * aspectRatio, clipSpace.y);\r\n\r\n\tgl_Position = vec4(clipSpace, 0.0, 1.0 );\t\r\n}\r\n\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n#define PRESSURE_BOUNDARY\n#define VELOCITY_BOUNDARY\n\nuniform vec2 invresolution;\nuniform float aspectRatio;\n\nvec2 clipToSimSpace(vec2 clipSpace){\n return vec2(clipSpace.x * aspectRatio, clipSpace.y);\n}\n\nvec2 simToTexelSpace(vec2 simSpace){\n return vec2(simSpace.x / aspectRatio + 1.0 , simSpace.y + 1.0)*.5;\n}\n\n\nfloat samplePressue(sampler2D pressure, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n\n \n \n \n #ifdef PRESSURE_BOUNDARY\n if(coord.x < 0.0) cellOffset.x = 1.0;\n else if(coord.x > 1.0) cellOffset.x = -1.0;\n if(coord.y < 0.0) cellOffset.y = 1.0;\n else if(coord.y > 1.0) cellOffset.y = -1.0;\n #endif\n\n return texture2D(pressure, coord + cellOffset * invresolution).x;\n}\n\n\nvec2 sampleVelocity(sampler2D velocity, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n vec2 multiplier = vec2(1.0, 1.0);\n\n \n \n \n #ifdef VELOCITY_BOUNDARY\n if(coord.x<0.0){\n cellOffset.x = 1.0;\n multiplier.x = -1.0;\n }else if(coord.x>1.0){\n cellOffset.x = -1.0;\n multiplier.x = -1.0;\n }\n if(coord.y<0.0){\n cellOffset.y = 1.0;\n multiplier.y = -1.0;\n }else if(coord.y>1.0){\n cellOffset.y = -1.0;\n multiplier.y = -1.0;\n }\n #endif\n\n return multiplier * texture2D(velocity, coord + cellOffset * invresolution).xy;\n}\n\nuniform sampler2D velocity;\t\nuniform float halfrdx;\t\n\r\nvarying vec2 texelCoord;\r\n\r\n\r\nvoid main(void){\r\n\t\n \t\n\tvec2 L = sampleVelocity(velocity, texelCoord - vec2(invresolution.x, 0));\r\n\tvec2 R = sampleVelocity(velocity, texelCoord + vec2(invresolution.x, 0));\r\n\tvec2 B = sampleVelocity(velocity, texelCoord - vec2(0, invresolution.y));\r\n\tvec2 T = sampleVelocity(velocity, texelCoord + vec2(0, invresolution.y));\r\n\r\n\tgl_FragColor = vec4( halfrdx * ((R.x - L.x) + (T.y - B.y)), 0, 0, 1);\r\n}\r\n\n");
this.ready = true;
}
,createProperties: function() {
FluidBase.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["velocity",-1,false]);
this.velocity = instance;
this.uniforms.push(instance);
var instance1 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["halfrdx",-1]);
this.halfrdx = instance1;
this.uniforms.push(instance1);
this.aStride += 0;
}
,__class__: Divergence
});
var PressureSolve = function() {
FluidBase.call(this);
};
$hxClasses["PressureSolve"] = PressureSolve;
PressureSolve.__name__ = true;
PressureSolve.__super__ = FluidBase;
PressureSolve.prototype = $extend(FluidBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n \r\nattribute vec2 vertexPosition;\r\n\r\nuniform float aspectRatio;\r\n\r\nvarying vec2 texelCoord;\r\n\r\n\r\nvarying vec2 p;\r\n\r\nvoid main() {\r\n\ttexelCoord = vertexPosition;\r\n\t\r\n\tvec2 clipSpace = 2.0*texelCoord - 1.0;\t\n\t\r\n\tp = vec2(clipSpace.x * aspectRatio, clipSpace.y);\r\n\r\n\tgl_Position = vec4(clipSpace, 0.0, 1.0 );\t\r\n}\r\n\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n#define PRESSURE_BOUNDARY\n#define VELOCITY_BOUNDARY\n\nuniform vec2 invresolution;\nuniform float aspectRatio;\n\nvec2 clipToSimSpace(vec2 clipSpace){\n return vec2(clipSpace.x * aspectRatio, clipSpace.y);\n}\n\nvec2 simToTexelSpace(vec2 simSpace){\n return vec2(simSpace.x / aspectRatio + 1.0 , simSpace.y + 1.0)*.5;\n}\n\n\nfloat samplePressue(sampler2D pressure, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n\n \n \n \n #ifdef PRESSURE_BOUNDARY\n if(coord.x < 0.0) cellOffset.x = 1.0;\n else if(coord.x > 1.0) cellOffset.x = -1.0;\n if(coord.y < 0.0) cellOffset.y = 1.0;\n else if(coord.y > 1.0) cellOffset.y = -1.0;\n #endif\n\n return texture2D(pressure, coord + cellOffset * invresolution).x;\n}\n\n\nvec2 sampleVelocity(sampler2D velocity, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n vec2 multiplier = vec2(1.0, 1.0);\n\n \n \n \n #ifdef VELOCITY_BOUNDARY\n if(coord.x<0.0){\n cellOffset.x = 1.0;\n multiplier.x = -1.0;\n }else if(coord.x>1.0){\n cellOffset.x = -1.0;\n multiplier.x = -1.0;\n }\n if(coord.y<0.0){\n cellOffset.y = 1.0;\n multiplier.y = -1.0;\n }else if(coord.y>1.0){\n cellOffset.y = -1.0;\n multiplier.y = -1.0;\n }\n #endif\n\n return multiplier * texture2D(velocity, coord + cellOffset * invresolution).xy;\n}\n\nuniform sampler2D pressure;\nuniform sampler2D divergence;\nuniform float alpha;\n\nvarying vec2 texelCoord;\n\nvoid main(void){\n \n \n float L = samplePressue(pressure, texelCoord - vec2(invresolution.x, 0));\n float R = samplePressue(pressure, texelCoord + vec2(invresolution.x, 0));\n float B = samplePressue(pressure, texelCoord - vec2(0, invresolution.y));\n float T = samplePressue(pressure, texelCoord + vec2(0, invresolution.y));\n\n float bC = texture2D(divergence, texelCoord).x;\n\n gl_FragColor = vec4( (L + R + B + T + alpha * bC) * .25, 0, 0, 1 );\n}\n");
this.ready = true;
}
,createProperties: function() {
FluidBase.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["pressure",-1,false]);
this.pressure = instance;
this.uniforms.push(instance);
var instance1 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["divergence",-1,false]);
this.divergence = instance1;
this.uniforms.push(instance1);
var instance2 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["alpha",-1]);
this.alpha = instance2;
this.uniforms.push(instance2);
this.aStride += 0;
}
,__class__: PressureSolve
});
var PressureGradientSubstract = function() {
FluidBase.call(this);
};
$hxClasses["PressureGradientSubstract"] = PressureGradientSubstract;
PressureGradientSubstract.__name__ = true;
PressureGradientSubstract.__super__ = FluidBase;
PressureGradientSubstract.prototype = $extend(FluidBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n \r\nattribute vec2 vertexPosition;\r\n\r\nuniform float aspectRatio;\r\n\r\nvarying vec2 texelCoord;\r\n\r\n\r\nvarying vec2 p;\r\n\r\nvoid main() {\r\n\ttexelCoord = vertexPosition;\r\n\t\r\n\tvec2 clipSpace = 2.0*texelCoord - 1.0;\t\n\t\r\n\tp = vec2(clipSpace.x * aspectRatio, clipSpace.y);\r\n\r\n\tgl_Position = vec4(clipSpace, 0.0, 1.0 );\t\r\n}\r\n\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n#define PRESSURE_BOUNDARY\n#define VELOCITY_BOUNDARY\n\nuniform vec2 invresolution;\nuniform float aspectRatio;\n\nvec2 clipToSimSpace(vec2 clipSpace){\n return vec2(clipSpace.x * aspectRatio, clipSpace.y);\n}\n\nvec2 simToTexelSpace(vec2 simSpace){\n return vec2(simSpace.x / aspectRatio + 1.0 , simSpace.y + 1.0)*.5;\n}\n\n\nfloat samplePressue(sampler2D pressure, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n\n \n \n \n #ifdef PRESSURE_BOUNDARY\n if(coord.x < 0.0) cellOffset.x = 1.0;\n else if(coord.x > 1.0) cellOffset.x = -1.0;\n if(coord.y < 0.0) cellOffset.y = 1.0;\n else if(coord.y > 1.0) cellOffset.y = -1.0;\n #endif\n\n return texture2D(pressure, coord + cellOffset * invresolution).x;\n}\n\n\nvec2 sampleVelocity(sampler2D velocity, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n vec2 multiplier = vec2(1.0, 1.0);\n\n \n \n \n #ifdef VELOCITY_BOUNDARY\n if(coord.x<0.0){\n cellOffset.x = 1.0;\n multiplier.x = -1.0;\n }else if(coord.x>1.0){\n cellOffset.x = -1.0;\n multiplier.x = -1.0;\n }\n if(coord.y<0.0){\n cellOffset.y = 1.0;\n multiplier.y = -1.0;\n }else if(coord.y>1.0){\n cellOffset.y = -1.0;\n multiplier.y = -1.0;\n }\n #endif\n\n return multiplier * texture2D(velocity, coord + cellOffset * invresolution).xy;\n}\n\nuniform sampler2D pressure;\r\nuniform sampler2D velocity;\r\nuniform float halfrdx;\r\n\r\nvarying vec2 texelCoord;\r\n\r\nvoid main(void){\r\n float L = samplePressue(pressure, texelCoord - vec2(invresolution.x, 0));\r\n float R = samplePressue(pressure, texelCoord + vec2(invresolution.x, 0));\r\n float B = samplePressue(pressure, texelCoord - vec2(0, invresolution.y));\r\n float T = samplePressue(pressure, texelCoord + vec2(0, invresolution.y));\r\n\r\n vec2 v = texture2D(velocity, texelCoord).xy;\r\n\r\n gl_FragColor = vec4(v - halfrdx*vec2(R-L, T-B), 0, 1);\r\n}\r\n\r\n\n");
this.ready = true;
}
,createProperties: function() {
FluidBase.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["pressure",-1,false]);
this.pressure = instance;
this.uniforms.push(instance);
var instance1 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["velocity",-1,false]);
this.velocity = instance1;
this.uniforms.push(instance1);
var instance2 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["halfrdx",-1]);
this.halfrdx = instance2;
this.uniforms.push(instance2);
this.aStride += 0;
}
,__class__: PressureGradientSubstract
});
var ApplyForces = function() {
FluidBase.call(this);
};
$hxClasses["ApplyForces"] = ApplyForces;
ApplyForces.__name__ = true;
ApplyForces.__super__ = FluidBase;
ApplyForces.prototype = $extend(FluidBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n \r\nattribute vec2 vertexPosition;\r\n\r\nuniform float aspectRatio;\r\n\r\nvarying vec2 texelCoord;\r\n\r\n\r\nvarying vec2 p;\r\n\r\nvoid main() {\r\n\ttexelCoord = vertexPosition;\r\n\t\r\n\tvec2 clipSpace = 2.0*texelCoord - 1.0;\t\n\t\r\n\tp = vec2(clipSpace.x * aspectRatio, clipSpace.y);\r\n\r\n\tgl_Position = vec4(clipSpace, 0.0, 1.0 );\t\r\n}\r\n\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n#define PRESSURE_BOUNDARY\n#define VELOCITY_BOUNDARY\n\nuniform vec2 invresolution;\nuniform float aspectRatio;\n\nvec2 clipToSimSpace(vec2 clipSpace){\n return vec2(clipSpace.x * aspectRatio, clipSpace.y);\n}\n\nvec2 simToTexelSpace(vec2 simSpace){\n return vec2(simSpace.x / aspectRatio + 1.0 , simSpace.y + 1.0)*.5;\n}\n\n\nfloat samplePressue(sampler2D pressure, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n\n \n \n \n #ifdef PRESSURE_BOUNDARY\n if(coord.x < 0.0) cellOffset.x = 1.0;\n else if(coord.x > 1.0) cellOffset.x = -1.0;\n if(coord.y < 0.0) cellOffset.y = 1.0;\n else if(coord.y > 1.0) cellOffset.y = -1.0;\n #endif\n\n return texture2D(pressure, coord + cellOffset * invresolution).x;\n}\n\n\nvec2 sampleVelocity(sampler2D velocity, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n vec2 multiplier = vec2(1.0, 1.0);\n\n \n \n \n #ifdef VELOCITY_BOUNDARY\n if(coord.x<0.0){\n cellOffset.x = 1.0;\n multiplier.x = -1.0;\n }else if(coord.x>1.0){\n cellOffset.x = -1.0;\n multiplier.x = -1.0;\n }\n if(coord.y<0.0){\n cellOffset.y = 1.0;\n multiplier.y = -1.0;\n }else if(coord.y>1.0){\n cellOffset.y = -1.0;\n multiplier.y = -1.0;\n }\n #endif\n\n return multiplier * texture2D(velocity, coord + cellOffset * invresolution).xy;\n}\n\nuniform sampler2D velocity;\n\tuniform float dt;\n\tuniform float dx;\n\tvarying vec2 texelCoord;\n\tvarying vec2 p;\n");
this.ready = true;
}
,createProperties: function() {
FluidBase.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["velocity",-1,false]);
this.velocity = instance;
this.uniforms.push(instance);
var instance1 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["dt",-1]);
this.dt = instance1;
this.uniforms.push(instance1);
var instance2 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["dx",-1]);
this.dx = instance2;
this.uniforms.push(instance2);
this.aStride += 0;
}
,__class__: ApplyForces
});
var UpdateDye = function() {
FluidBase.call(this);
};
$hxClasses["UpdateDye"] = UpdateDye;
UpdateDye.__name__ = true;
UpdateDye.__super__ = FluidBase;
UpdateDye.prototype = $extend(FluidBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n \r\nattribute vec2 vertexPosition;\r\n\r\nuniform float aspectRatio;\r\n\r\nvarying vec2 texelCoord;\r\n\r\n\r\nvarying vec2 p;\r\n\r\nvoid main() {\r\n\ttexelCoord = vertexPosition;\r\n\t\r\n\tvec2 clipSpace = 2.0*texelCoord - 1.0;\t\n\t\r\n\tp = vec2(clipSpace.x * aspectRatio, clipSpace.y);\r\n\r\n\tgl_Position = vec4(clipSpace, 0.0, 1.0 );\t\r\n}\r\n\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n#define PRESSURE_BOUNDARY\n#define VELOCITY_BOUNDARY\n\nuniform vec2 invresolution;\nuniform float aspectRatio;\n\nvec2 clipToSimSpace(vec2 clipSpace){\n return vec2(clipSpace.x * aspectRatio, clipSpace.y);\n}\n\nvec2 simToTexelSpace(vec2 simSpace){\n return vec2(simSpace.x / aspectRatio + 1.0 , simSpace.y + 1.0)*.5;\n}\n\n\nfloat samplePressue(sampler2D pressure, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n\n \n \n \n #ifdef PRESSURE_BOUNDARY\n if(coord.x < 0.0) cellOffset.x = 1.0;\n else if(coord.x > 1.0) cellOffset.x = -1.0;\n if(coord.y < 0.0) cellOffset.y = 1.0;\n else if(coord.y > 1.0) cellOffset.y = -1.0;\n #endif\n\n return texture2D(pressure, coord + cellOffset * invresolution).x;\n}\n\n\nvec2 sampleVelocity(sampler2D velocity, vec2 coord){\n vec2 cellOffset = vec2(0.0, 0.0);\n vec2 multiplier = vec2(1.0, 1.0);\n\n \n \n \n #ifdef VELOCITY_BOUNDARY\n if(coord.x<0.0){\n cellOffset.x = 1.0;\n multiplier.x = -1.0;\n }else if(coord.x>1.0){\n cellOffset.x = -1.0;\n multiplier.x = -1.0;\n }\n if(coord.y<0.0){\n cellOffset.y = 1.0;\n multiplier.y = -1.0;\n }else if(coord.y>1.0){\n cellOffset.y = -1.0;\n multiplier.y = -1.0;\n }\n #endif\n\n return multiplier * texture2D(velocity, coord + cellOffset * invresolution).xy;\n}\n\nuniform sampler2D dye;\n\tuniform float dt;\n\tuniform float dx;\n\tvarying vec2 texelCoord;\n\tvarying vec2 p;\n");
this.ready = true;
}
,createProperties: function() {
FluidBase.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["dye",-1,false]);
this.dye = instance;
this.uniforms.push(instance);
var instance1 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["dt",-1]);
this.dt = instance1;
this.uniforms.push(instance1);
var instance2 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["dx",-1]);
this.dx = instance2;
this.uniforms.push(instance2);
this.aStride += 0;
}
,__class__: UpdateDye
});
var GPUParticles = function(gl,count) {
if(count == null) count = 524288;
this.gl = gl;
gl.getExtension("OES_texture_float");
this.textureQuad = gltoolbox.GeometryTools.getCachedTextureQuad();
this.inititalConditionsShader = new InitialConditions();
this.stepParticlesShader = new StepParticles();
this.stepParticlesShader.dragCoefficient.set_data(1);
this.stepParticlesShader.flowScale.data.x = 1;
this.stepParticlesShader.flowScale.data.y = 1;
this.setCount(count);
this.renderShaderTo(this.inititalConditionsShader,this.particleData);
};
$hxClasses["GPUParticles"] = GPUParticles;
GPUParticles.__name__ = true;
GPUParticles.prototype = {
step: function(dt) {
this.stepParticlesShader.dt.set_data(dt);
this.stepParticlesShader.particleData.set_data(this.particleData.readFromTexture);
this.renderShaderTo(this.stepParticlesShader,this.particleData);
}
,reset: function() {
this.renderShaderTo(this.inititalConditionsShader,this.particleData);
}
,setCount: function(newCount) {
var dataWidth = Math.ceil(Math.sqrt(newCount));
var dataHeight = dataWidth;
if(this.particleData != null) this.particleData.resize(dataWidth,dataHeight); else this.particleData = new gltoolbox.render.RenderTarget2Phase(dataWidth,dataHeight,gltoolbox.TextureTools.floatTextureFactoryRGBA);
if(this.particleUVs != null) this.gl.deleteBuffer(this.particleUVs);
this.particleUVs = this.gl.createBuffer();
var arrayUVs = new Array();
var _g = 0;
while(_g < dataWidth) {
var i = _g++;
var _g1 = 0;
while(_g1 < dataHeight) {
var j = _g1++;
arrayUVs.push(i / dataWidth);
arrayUVs.push(j / dataHeight);
}
}
this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.particleUVs);
this.gl.bufferData(this.gl.ARRAY_BUFFER,new Float32Array(arrayUVs),this.gl.STATIC_DRAW);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);
return this.count = newCount;
}
,renderShaderTo: function(shader,target) {
this.gl.viewport(0,0,target.width,target.height);
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,target.writeFrameBufferObject);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.textureQuad);
if(shader.active) {
shader.setUniforms();
shader.setAttributes();
null;
} else {
if(!shader.ready) shader.create();
lime.graphics.opengl.GL.context.useProgram(shader.prog);
shader.setUniforms();
shader.setAttributes();
shader.active = true;
}
this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);
shader.deactivate();
target.tmpFBO = target.writeFrameBufferObject;
target.writeFrameBufferObject = target.readFrameBufferObject;
target.readFrameBufferObject = target.tmpFBO;
target.tmpTex = target.writeToTexture;
target.writeToTexture = target.readFromTexture;
target.readFromTexture = target.tmpTex;
}
,get_dragCoefficient: function() {
return this.stepParticlesShader.dragCoefficient.data;
}
,get_flowScaleX: function() {
return this.stepParticlesShader.flowScale.data.x;
}
,get_flowScaleY: function() {
return this.stepParticlesShader.flowScale.data.y;
}
,get_flowVelocityField: function() {
return this.stepParticlesShader.flowVelocityField.data;
}
,set_dragCoefficient: function(v) {
return this.stepParticlesShader.dragCoefficient.set_data(v);
}
,set_flowScaleX: function(v) {
return this.stepParticlesShader.flowScale.data.x = v;
}
,set_flowScaleY: function(v) {
return this.stepParticlesShader.flowScale.data.y = v;
}
,set_flowVelocityField: function(v) {
return this.stepParticlesShader.flowVelocityField.set_data(v);
}
,__class__: GPUParticles
};
var PlaneTexture = function() {
shaderblox.ShaderBase.call(this);
};
$hxClasses["PlaneTexture"] = PlaneTexture;
PlaneTexture.__name__ = true;
PlaneTexture.__super__ = shaderblox.ShaderBase;
PlaneTexture.prototype = $extend(shaderblox.ShaderBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nattribute vec2 vertexPosition;\n\tvarying vec2 texelCoord;\n\tvoid main(){\n\t\ttexelCoord = vertexPosition;\n\t\tgl_Position = vec4(vertexPosition*2.0 - vec2(1.0, 1.0), 0.0, 1.0 );\n\t}\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nvarying vec2 texelCoord;\n");
this.ready = true;
}
,createProperties: function() {
shaderblox.ShaderBase.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.attributes.FloatAttribute"),["vertexPosition",0,2]);
this.vertexPosition = instance;
this.attributes.push(instance);
this.aStride += 8;
}
,__class__: PlaneTexture
});
var InitialConditions = function() {
PlaneTexture.call(this);
};
$hxClasses["InitialConditions"] = InitialConditions;
InitialConditions.__name__ = true;
InitialConditions.__super__ = PlaneTexture;
InitialConditions.prototype = $extend(PlaneTexture.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nattribute vec2 vertexPosition;\n\tvarying vec2 texelCoord;\n\tvoid main(){\n\t\ttexelCoord = vertexPosition;\n\t\tgl_Position = vec4(vertexPosition*2.0 - vec2(1.0, 1.0), 0.0, 1.0 );\n\t}\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nvarying vec2 texelCoord;\n\nvoid main(){\n\t\tvec2 ip = vec2((texelCoord.x), (texelCoord.y)) * 2.0 - 1.0;\n\t\tvec2 iv = vec2(0,0);\n\t\tgl_FragColor = vec4(ip, iv);\n\t}\n");
this.ready = true;
}
,createProperties: function() {
PlaneTexture.prototype.createProperties.call(this);
this.aStride += 0;
}
,__class__: InitialConditions
});
var ParticleBase = function() {
PlaneTexture.call(this);
};
$hxClasses["ParticleBase"] = ParticleBase;
ParticleBase.__name__ = true;
ParticleBase.__super__ = PlaneTexture;
ParticleBase.prototype = $extend(PlaneTexture.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nattribute vec2 vertexPosition;\n\tvarying vec2 texelCoord;\n\tvoid main(){\n\t\ttexelCoord = vertexPosition;\n\t\tgl_Position = vec4(vertexPosition*2.0 - vec2(1.0, 1.0), 0.0, 1.0 );\n\t}\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nvarying vec2 texelCoord;\n\nuniform float dt;\n\tuniform sampler2D particleData;\n");
this.ready = true;
}
,createProperties: function() {
PlaneTexture.prototype.createProperties.call(this);
var instance = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UFloat"),["dt",-1]);
this.dt = instance;
this.uniforms.push(instance);
var instance1 = Type.createInstance(Type.resolveClass("shaderblox.uniforms.UTexture"),["particleData",-1,false]);
this.particleData = instance1;
this.uniforms.push(instance1);
this.aStride += 0;
}
,__class__: ParticleBase
});
var StepParticles = function() {
ParticleBase.call(this);
};
$hxClasses["StepParticles"] = StepParticles;
StepParticles.__name__ = true;
StepParticles.__super__ = ParticleBase;
StepParticles.prototype = $extend(ParticleBase.prototype,{
create: function() {
this.initFromSource("\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nattribute vec2 vertexPosition;\n\tvarying vec2 texelCoord;\n\tvoid main(){\n\t\ttexelCoord = vertexPosition;\n\t\tgl_Position = vec4(vertexPosition*2.0 - vec2(1.0, 1.0), 0.0, 1.0 );\n\t}\n\n\n\n\n","\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nvarying vec2 texelCoord;\n\nuniform float dt;\n\tuniform sampler2D particleData;\n\nuniform float dragCoefficient;\n\tuniform vec2 flowScale;\n\tuniform sampler2D flowVelocityField;\n\tvoid main(){\n\t\tvec2 p = texture2D(particleData, texelCoord).xy;\n\t\tvec2 v = texture2D(particleData, texelCoord).zw;\n\t\tvec2 vf = texture2D(flowVelocityField, (p+1.)*.5).xy * flowScale;\n\t\tv += (vf - v) * dragCoeffi