var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
addChild(new Bitmap(canvas));
var pix:Vector.<uint> = new Vector.<uint>(canvas.width * canvas.height, true);
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
canvas.lock();
var i:int = pix.length;
while(--i > -1){
var c:uint = uint(Math.random() * 255);
pix[i] = c << 16 | c << 8 | c;
}
canvas.setVector(canvas.rect, pix);
canvas.unlock();
}
This is an easy way to fill a BitmapData Object up with a bunch of TV-style static….
This post is meant to serve as filler while I work to get a good solid SIMPLE fp10, drawing api z-sorting example going… There seem to be 3 main ways of doing z-sorting all of which don’t seem right to me for some reason… they all work… but I have a gut feeling there is a faster way… The winner so far (unexpectedly) is using Array.sortOn
[SWF(backgroundColor=0x000000, width=800, height=600)];
x = stage.stageWidth / 2;
y = stage.stageHeight / 2;
var verts:Vector.<Number> = new Vector.<Number>();
var tVerts:Vector.<Number> = new Vector.<Number>();
var pVerts:Vector.<Number> = new Vector.<Number>();
var uvts:Vector.<Number> = new Vector.<Number>();
var igraph:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
var tVect:Vector3D = new Vector3D();
var m:Matrix3D = new Matrix3D();
for (var i:int = 0; i<300; i++){
for (var j:int = 0; j<3; j++){
tVect.x = Math.random() * 0.15;
m.identity();
m.appendRotation(Math.random()*360, Vector3D.X_AXIS);
m.appendRotation(Math.random()*360, Vector3D.Y_AXIS);
m.appendRotation(Math.random()*360, Vector3D.Z_AXIS);
tVect = m.transformVector(tVect);
verts.push(tVect.x, tVect.y, tVect.z);
}
var stroke:IGraphicsData = new GraphicsStroke();
var col:int = [0xFFFFFF, 0x000000, 0xFFCC00, 0xFF0000][int(Math.random() * 4)];
with (stroke) thickness = (Math.random()*Math.random())*10, fill = new GraphicsSolidFill(col);
var bez:GraphicsPath = new GraphicsPath();
bez.commands = Vector.<int>([1, 3]);
igraph.push(stroke);
igraph.push(bez);
}
var perspective:PerspectiveProjection = new PerspectiveProjection();
perspective.fieldOfView = 45;
var trans:Matrix3D = new Matrix3D();
var proj:Matrix3D = perspective.toMatrix3D();
var dx:Number = 0, dy:Number = 0;
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
dx += (mouseX - dx) / 4;
dy += (mouseY - dy) / 4;
trans.identity();
trans.appendRotation(dy, Vector3D.X_AXIS);
trans.appendRotation(dx, Vector3D.Y_AXIS);
trans.appendTranslation(0,0,0.5);
trans.transformVectors(verts, tVerts);
Utils3D.projectVectors(proj, tVerts, pVerts, uvts);
var inc:int = 0;
for (var i:int = 1; i<igraph.length; i+=2){
GraphicsPath(igraph[i]).data = pVerts.slice(inc, inc + 6);
inc += 6;
}
graphics.clear();
graphics.drawGraphicsData(igraph);
}
After a few hours of trying to get a super optimized fp10 z-sorting demo happening, I gave up (for now) and decided to just let loose with something easy. The result is this 3D Bezier example…
[SWF(frameRate=60, backgroundColor=0x000000, width=500, height=500)]
var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
addChild(new Bitmap(canvas));
var clone:BitmapData = new BitmapData(500,500,false, 0x000000);
var canvasRect:Rectangle = canvas.rect;
var w:int = canvas.width;
var w2:Number = 1/w;
var w10:Number = 1/(w * 80);
var convert:Number = Math.PI/180;
var size:int = canvas.width * canvas.height;
var pix:Vector.<uint> = new Vector.<uint>(size, true);
var gray:ColorMatrixFilter = new ColorMatrixFilter([1, 0.55, 0.55, 0,0,0.55, 0.9, 0.55, 0,0,0.55, 0.55, 0.550,0, 0,0,0,1,0]);
var m:Matrix = new Matrix();
m.scale(1,-1);
m.translate(0,canvas.height);
var sin:Number = 0, cos:Number = 0;
var dx:Number = 0, dy:Number = 0;
var pnt:Point = new Point();
var blur:BlurFilter = new BlurFilter(10,10,1);
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
canvas.lock();
dx += (mouseX * 10 - 3000 - dx) / 8;
dy += (mouseY * 4 - dy) / 8;
for (var i:int = 0; i<size; i++){
var xp:int = i % w;
var yp:int = int(i * w2);
var xp2:int = xp << 1;
var t:Number = (yp * (xp2 + dx) * w10) % 3.14687;
//compute sine
// technique from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
// by Michael Baczynski
if (t<0) {
sin=1.27323954*t+.405284735*t*t;
} else {
sin=1.27323954*t-0.405284735*t*t;
}
// compute cosine
t = (xp2 + dy) * convert % 6.28;
t+=1.57079632;
if (t>3.14159265) {
t-=6.28318531;
}
if (t<0) {
cos=1.27323954*t+0.405284735*t*t;
} else {
cos=1.27323954*t-0.405284735*t*t;
}
var c1:int = 31 * (cos - sin);
if (c1 <0) c1 = 256 - c1;
c1 = (c1 <<2 | c1) ;
pix[i] = c1 <<15 | c1 <<9 | c1;
}
canvas.setVector(canvasRect, pix);
clone.copyPixels(canvas, canvasRect, pnt);
canvas.draw(clone, m, null, BlendMode.SUBTRACT);
clone.copyPixels(canvas, canvasRect, pnt);
clone.applyFilter(clone, canvasRect, pnt, blur);
canvas.draw(clone, null, null, BlendMode.ADD);
canvas.applyFilter(canvas, canvas.rect, new Point(0,0), gray);
canvas.unlock();
}
This snippet creates an interactive animated texture. Originally this texture wasn an unoptimized messy code snippet (see the original post here) – I went through and did a few optimizations to get it running in real-time and this is the result:
Check out the swf over at wonderfl.net…
import com.actionsnippet.qbox.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.Joints.*;
[SWF (backgroundColor=0x000000, width=700, height=600, frameRate=60)]
var sim:QuickBox2D = new QuickBox2D(this, {gravityY:.2});
sim.setDefault({fillColor:0xEFEFEF, fillAlpha:0.5, lineColor:0xFFFFFF});
sim.createStageWalls();
for (var i:int = 0; i<20; i++){
sim.addCircle({x:1+i, y:1, radius:0.2, restitution:1});
}
var head:QuickObject = sim.addCircle({x:0, y:0, radius:0.5});
var neck:QuickObject = sim.addBox({x:0, y:1, width:0.5, height:2});
var top:QuickObject = sim.addGroup({objects:[head, neck], x:10, y:5, fixedRotation:true});
var upperLegA:QuickObject = sim.addBox({x:10, y:7.5, width:0.25, height:1.5,groupIndex:-2});
var lowerLegA:QuickObject = sim.addBox({x:10, y:9, width:0.25, height:1.5,groupIndex:-2});
var upperLegB:QuickObject = sim.addBox({x:10, y:7.5, width:0.25, height:1.5,groupIndex:-2});
var lowerLegB:QuickObject = sim.addBox({x:10, y:9, width:0.25, height:1.5,groupIndex:-2});
var anchor:b2Vec2 = new b2Vec2();
function connect(a:QuickObject, b:QuickObject, lower:Number, upper:Number, offX:Number=0, offY:Number = 0):QuickObject{
var min:Number = Math.min(a.y, b.y);
var max:Number = Math.max(a.y, b.y);
anchor.y = min + (max - min) * 0.5 + offY;
min = Math.min(a.x, b.x);
max = Math.max(a.x, b.x);
anchor.x = min + (max - min) * 0.5 + offX;
return sim.addJoint({a:a.body, b:b.body, x1:anchor.x, y1:anchor.y, lowerAngle:lower, upperAngle:upper});
}
sim.setDefault({type:"revolute", collideConnected:false, enableLimit:true, enableMotor:true, maxMotorTorque:250, lineColor:0xFFFFFF});
var upperLegAJoint:QuickObject = connect(top, upperLegA, -1, 1, 0, 0.8);
var upperLegBJoint:QuickObject = connect(top, upperLegB, -1, 1, 0, 0.8);
var lowerLegAJoint:QuickObject = connect(upperLegA, lowerLegA, -1, 1);
var lowerLegBJoint:QuickObject = connect(upperLegB, lowerLegB, -1, 1);
sim.start();
sim.mouseDrag();
var j:b2RevoluteJoint;
var t:Number = -Math.PI * 0.5;
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
var s1:Number = 1*Math.sin(t);
var s2:Number = 1*Math.sin(t+Math.PI);
t+= 0.05;
top.body.SetAngularVelocity(s1 * 0.25);
j = upperLegAJoint.joint as b2RevoluteJoint;
j.SetMotorSpeed(s1);
j = upperLegBJoint.joint as b2RevoluteJoint;
j.SetMotorSpeed(s2);
j = lowerLegAJoint.joint as b2RevoluteJoint;
j.SetMotorSpeed(-s2);
j = lowerLegBJoint.joint as b2RevoluteJoint;
j.SetMotorSpeed(-s1);
}
Experimenting with primitive robot designs… this was just an improvised design – it looks like it may make sense to break out a pencil and some paper – or my wacom… to get something interesting…
Simple prismatic joint demo. Prismatic joints are odd, it took me awhile to realize how to use them and what they can be used for… Plan on using them in the creation of some Box2D machines in the near futrure…
Check out the swf