Tag Archives: fp10

Fp10 3d Logo

Actionscript:
  1. var container:Sprite = new Sprite();
  2. container.x = stage.stageWidth / 2;
  3. container.y = stage.stageHeight / 2;
  4. addChild(container);
  5.  
  6. var redBox:Sprite = new Sprite();
  7. redBox.graphics.beginFill(0xFF0000);
  8. redBox.graphics.drawRect(-50,-250,100,500);
  9. redBox.rotationZ = 10;
  10. container.addChild(redBox);
  11.  
  12. var logos:Array = []
  13. var elements:Array = [];
  14. elements.push({element:redBox, z:0});
  15.  
  16. // add the logos
  17. for (var i:int = 0; i<6; i++){
  18.     var logoContainer:MovieClip = new MovieClip();
  19.     var logoText:TextField = new TextField();
  20.     logoText.defaultTextFormat = new TextFormat("_sans", 50);
  21.     logoText.text = "LOGO";
  22.     logoText.autoSize = "left";
  23.     logoText.selectable= false;
  24.    
  25.     logoText.x = -logoText.width / 2;
  26.     logoText.y = -logoText.height / 2;
  27.     logoContainer.addChild(logoText);
  28.     logoText.backgroundColor = 0xFFFFFF;
  29.    
  30.     container.addChild(logoContainer);
  31.     logos.push(logoContainer);
  32.     elements.push({element:logoContainer, z:0});
  33. }
  34.  
  35. var ang:Number = -Math.PI / 2;
  36. var rotationSpeed:Number = 0.05;
  37. addEventListener(Event.ENTER_FRAME, onLoop);
  38. function onLoop(evt:Event):void {
  39.    
  40.      var dx:Number = (mouseY - stage.stageHeight / 2) / 10;
  41.      var dy:Number = (mouseX - stage.stageWidth / 2) / 10;
  42.      container.rotationX += (dx - container.rotationX) / 4;
  43.      container.rotationY += (dy - container.rotationY) / 4;
  44.      
  45.      ang += rotationSpeed;
  46.      for (var i:int = 0; i<logos.length; i++){
  47.          var logo:Sprite = logos[i];
  48.          logo.x = 150 * Math.cos(ang + i);
  49.          logo.z = 150 * Math.sin(ang + i);
  50.          logo.alpha = 1 - logo.z / 200;
  51.          logo.rotationY = -Math.atan2(logo.z, logo.x)  / Math.PI * 180  - 90;
  52.      }
  53.      
  54.      // z-sort
  55.      for (i = 0; i<elements.length; i++){
  56.           elements[i].z = elements[i].element.transform.getRelativeMatrix3D(this).position.z;
  57.      }
  58.      
  59.     elements.sortOn("z", Array.NUMERIC | Array.DESCENDING);
  60.     for (i = 0; i<elements.length; i++) {
  61.         container.addChild(elements[i].element);
  62.     }
  63. }

A student of mine was having trouble creating a 3D logo for a client. I created this snippet to help explain how some of the fp10 3D stuff works.... z-sorting etc... The code could be optimized a bit... but it works nicely...


Have a look at the swf...

Posted in 3D, misc, motion | Also tagged , , | 2 Comments

QuickBox2D 3D

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2. [SWF(width = 800, height=600, backgroundColor=0x000000, frameRate = 60)]
  3.  
  4. var main:MovieClip = MovieClip(addChild(new MovieClip()));
  5. main.z = 500;
  6. main.rotationX = -40;
  7.  
  8. var sim:QuickBox2D = new QuickBox2D(main);
  9.  
  10. sim.createStageWalls({fillColor:0x1133CC});
  11. sim.setDefault({lineColor:0xFFFFFF, fillColor:0x113355});
  12.  
  13. for (var i:int = 0; i<30; i++){
  14.     var b:QuickObject = sim.addBox({x:Math.random()*10 + 3, y:Math.random()*10 + 3,
  15.                                     width:0.25 + Math.random()*2, height:0.25 + Math.random()*2});
  16. }
  17.  
  18. sim.start();
  19. sim.mouseDrag();

This demo shows how you can render your QuickBox2D simulation to somewhere other than the main timeline. In this case, I render to a MovieClip that has altered z and and rotationX properties.


Have a look at the swf...

Posted in 3D, Box2D, QuickBox2D | Also tagged , , , , | 2 Comments

Fake Light w/ UV & Quads

Actionscript:
  1. [SWF(width = 500, height=500, backgroundColor = 0x000000)]
  2. x = stage.stageWidth / 2;
  3. y = stage.stageHeight / 2;
  4. var quadNum:int = 2200;
  5. // standard Vectors for using drawTriangles
  6. var verts:Vector.<Number> = new Vector.<Number>();
  7. var pVerts:Vector.<Number>;
  8. var uvts:Vector.<Number> = new Vector.<Number>();
  9. var indices:Vector.<int> = new Vector.<int>();
  10. // needed for z-sorting
  11. var sortedIndices:Vector.<int>;
  12. var faces:Array = [];
  13. // we'll use this for tranforming points
  14. // and as the transformation matrix for our render
  15. var m:Matrix3D = new Matrix3D();
  16. // plot a quad
  17. var quad:Vector.<Number>;
  18. quad = Vector.<Number>([-10, -10, 0,
  19.                         10, -10, 0,
  20.                         -10, 10, 0,
  21.                         10, 10, 0]);
  22. // temp vect for any transformed quads
  23. var transQuad:Vector.<Number> = new Vector.<Number>();
  24. var i:int;
  25. var inc:int = 0;
  26. for (i = 0; i<quadNum; i++){
  27.     m.identity();
  28.     var s:Number = (int(Math.random()*50) == 1) ? 2 + Math.random()*2 : .1 + Math.random() * 2;
  29.     m.appendScale(s, s, 1);
  30.     m.appendRotation(90, Vector3D.Y_AXIS);
  31.     var mult:Number = 100 + Math.random()*200;
  32.     m.appendTranslation(mult, 0, 0);
  33.     m.appendRotation(Math.random()*360, Vector3D.X_AXIS);
  34.     m.appendRotation(Math.random()*360, Vector3D.Y_AXIS);
  35.     m.appendRotation(Math.random()*360, Vector3D.Z_AXIS);
  36.     m.transformVectors(quad, transQuad);
  37.     verts = verts.concat(transQuad);
  38.     faces.push(new Vector3D());
  39.     faces.push(new Vector3D());
  40.     var i4:int = i * 4;
  41.     indices.push(0 + i4, 1 + i4, 2 + i4,
  42.                  1 + i4, 3 + i4, 2 + i4);
  43.     mult /= 300;
  44.     uvts.push(mult,mult,0,
  45.               mult+.1,mult,0,
  46.               mult,mult - .1,0,
  47.               mult + .1,mult + .1,0);
  48. }
  49. sortedIndices = new Vector.<int>(indices.length, true);
  50. // create texture
  51. var tex:BitmapData = new BitmapData(400,400,false, 0x000000);
  52. var grad:Shape = new Shape();
  53. var mat:Matrix = new Matrix();
  54. mat.createGradientBox(400,400,0,0,0);
  55. with (grad.graphics){
  56.     beginGradientFill(GradientType.LINEAR, [0xFFFFFF,0x002244], [1, 1], [100, 255], mat);
  57.     drawRect(0,0,400,400);
  58. }
  59. tex.draw(grad);
  60. // create background
  61. mat.createGradientBox(1600,1200,0,-550, 0);
  62. with (grad.graphics){
  63.     beginGradientFill(GradientType.RADIAL, [0x000000, 0x001133], [1, 1], [0, 255], mat);
  64.     drawRect(0,0,500,500);
  65. }
  66. grad.x = -stage.stageWidth/2
  67. grad.y = -stage.stageHeight/2;
  68. addChild(grad);
  69. // triangles will be drawn to this
  70. var render:Shape = Shape(addChild(new Shape()));
  71. // fix all vector lengths
  72. verts.fixed = true, uvts.fixed = true, indices.fixed = true
  73. pVerts = new Vector.<Number>(verts.length/3 * 2, true);
  74. // we need these if we want perspective
  75. var persp:PerspectiveProjection = new PerspectiveProjection();
  76. persp.fieldOfView = 45;
  77. // projection matrix
  78. var proj:Matrix3D = persp.toMatrix3D();
  79. var dx:Number = 0, dy:Number = 0;
  80. addEventListener(Event.ENTER_FRAME, onLoop);
  81. function onLoop(evt:Event):void {
  82.     dx += (mouseX - dx) / 4;
  83.     dy += (mouseY - dy) / 4;
  84.     m.identity();
  85.     m.appendRotation(dy, Vector3D.X_AXIS);
  86.     m.appendRotation(dx, Vector3D.Y_AXIS);
  87.     m.appendTranslation(0,0,800);
  88.     m.append(proj);
  89.     Utils3D.projectVectors(m, verts, pVerts, uvts);
  90.     var face:Vector3D;
  91.     inc = 0;
  92.     for (var i:int = 0; i<indices.length; i+=3){
  93.         face = faces[inc];
  94.         face.x = indices[i];
  95.         face.y = indices[int(i + 1)];
  96.         face.z = indices[int(i + 2)];
  97.         var i3:int = i * 3;
  98.         face.w = (uvts[int(face.x*3 + 2)] + uvts[int(face.y*3 + 2)] + uvts[int(face.z*3 + 2)]) * 0.333333;
  99.         inc++;
  100.     }
  101.     faces.sortOn("w", Array.NUMERIC);
  102.     inc = 0;
  103.     for each (face in faces){
  104.         sortedIndices[inc++] = face.x;
  105.         sortedIndices[inc++] = face.y;
  106.         sortedIndices[inc++] = face.z;
  107.     }
  108.     render.graphics.clear();
  109.     render.graphics.beginBitmapFill(tex, null, false, false);
  110.     render.graphics.drawTriangles(pVerts, sortedIndices, uvts, TriangleCulling.NEGATIVE);
  111. }

Expanding again on the z-sorting demos from the last few days - this snippet uses UV coords and a gradient to create something that vaguely resembles a light. Unlike the previous demos, the 3D cluster in this snippet is made up of quads - requiring a slight adjustment to the depth calculation.


Have a look at the swf...

I also posted the code over at wonderfl.net...

Posted in 3D, Graphics, Vector, matrix, misc, sortOn | Also tagged , , | 2 Comments

3D Bezier

Actionscript:
  1. [SWF(backgroundColor=0x000000, width=800, height=600)];
  2. x = stage.stageWidth / 2;
  3. y = stage.stageHeight / 2;
  4. var verts:Vector.<Number>  = new Vector.<Number>();
  5. var tVerts:Vector.<Number> = new Vector.<Number>();
  6. var pVerts:Vector.<Number> = new Vector.<Number>();
  7. var uvts:Vector.<Number> = new Vector.<Number>();
  8.  
  9. var igraph:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
  10.  
  11. var tVect:Vector3D = new Vector3D();
  12. var m:Matrix3D = new Matrix3D();
  13. for (var i:int = 0; i<300; i++){
  14.     for (var j:int = 0; j<3; j++){
  15.         tVect.x = Math.random() * 0.15;
  16.         m.identity();
  17.         m.appendRotation(Math.random()*360, Vector3D.X_AXIS);
  18.         m.appendRotation(Math.random()*360, Vector3D.Y_AXIS);
  19.         m.appendRotation(Math.random()*360, Vector3D.Z_AXIS);
  20.         tVect = m.transformVector(tVect);
  21.         verts.push(tVect.x, tVect.y, tVect.z);
  22.     }
  23.    
  24.      
  25.     var stroke:IGraphicsData = new GraphicsStroke();
  26.    
  27.     var col:int = [0xFFFFFF, 0x000000, 0xFFCC00, 0xFF0000][int(Math.random() * 4)];
  28.     with (stroke) thickness = (Math.random()*Math.random())*10, fill = new GraphicsSolidFill(col);
  29.  
  30.     var bez:GraphicsPath = new GraphicsPath();
  31.     bez.commands = Vector.<int>([1, 3]);
  32.     igraph.push(stroke);
  33.     igraph.push(bez);
  34. }
  35.  
  36. var perspective:PerspectiveProjection = new PerspectiveProjection();
  37. perspective.fieldOfView = 45;
  38. var trans:Matrix3D = new Matrix3D();
  39. var proj:Matrix3D = perspective.toMatrix3D();
  40. var dx:Number = 0, dy:Number = 0;
  41.  
  42. addEventListener(Event.ENTER_FRAME, onLoop);
  43. function onLoop(evt:Event):void {
  44.     dx += (mouseX - dx) / 4;
  45.     dy += (mouseY - dy) / 4;
  46.        
  47.     trans.identity();
  48.     trans.appendRotation(dy, Vector3D.X_AXIS);
  49.     trans.appendRotation(dx, Vector3D.Y_AXIS);
  50.     trans.appendTranslation(0,0,0.5);
  51.     trans.transformVectors(verts, tVerts);
  52.     Utils3D.projectVectors(proj, tVerts, pVerts, uvts);
  53.    
  54.     var inc:int = 0;
  55.     for (var i:int = 1; i<igraph.length; i+=2){
  56.         GraphicsPath(igraph[i]).data = pVerts.slice(inc, inc + 6);
  57.         inc += 6;
  58.     }
  59.      
  60.     graphics.clear();
  61.     graphics.drawGraphicsData(igraph);
  62. }

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...


Check out the swf...

Posted in 3D, Graphics, bezier | Also tagged , , | 3 Comments

Sphere of Squares

Actionscript:
  1. [SWF(width = 600, height = 600, backgroundColor=0x000000)]
  2. var squareNum:int  = 1000;
  3. var hw:Number = stage.stageWidth / 2;
  4. var hh:Number = stage.stageHeight / 2;
  5. // verts defines a single square
  6. var verts:Vector.<Number> = Vector.<Number>([-20, 0, 0, 20, 0, 0, 20, 0, 40, -20, 0, 40, -20, 0, 0]);
  7. var cmds:Vector.<int> = Vector.<int>([1,2,2,2,2]);
  8. var tempVerts:Vector.<Number> = new Vector.<Number>();
  9. var newVerts:Vector.<Number> = new Vector.<Number>();
  10. var pVerts:Vector.<Number> = new Vector.<Number>(10 * squareNum);
  11. var uv:Vector.<Number> = new Vector.<Number>(15 * squareNum);
  12. var vectors:Shape = new Shape();
  13. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0x000000);
  14. addChild(new Bitmap(canvas));
  15. var blurred:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0x000000);
  16. var blur:BlurFilter = new BlurFilter(20,20,1);
  17.  
  18. var m:Matrix3D = new Matrix3D();
  19.  
  20. var radius:Number = 200;
  21. // duplicate the verts array a bunch of times
  22. // each time moving the square to a random place on the
  23. // circumference of a sphere
  24. for (var i:int = 0; i<squareNum; i++){
  25.     m.identity();
  26.     var s:Number = Math.random()*.5 + .5;
  27.     m.appendScale(s, s, s);
  28.     m.appendRotation(90,Vector3D.X_AXIS);
  29.     m.appendTranslation(0, 0, radius);
  30.     m.appendRotation(Math.random()*360,Vector3D.X_AXIS);
  31.     m.appendRotation(Math.random()*360,Vector3D.Y_AXIS);
  32.     m.appendRotation(Math.random()*360,Vector3D.Z_AXIS);
  33.     m.transformVectors(verts,tempVerts);
  34.     newVerts = newVerts.concat(tempVerts);
  35.     cmds = cmds.concat(Vector.<int>([1,2,2,2,2]));
  36. }
  37. newVerts.fixed = pVerts.fixed = uv.fixed = true;
  38. var dx:Number = 0, dy:Number = 0;
  39. var pnt:Point = new Point();
  40. addEventListener(Event.ENTER_FRAME, onLoop);
  41. function onLoop(evt:Event):void {
  42.        dx += (mouseX - dx) / 4;
  43.        dy += (mouseY - dy) / 4;
  44.        m.identity();
  45.        m.appendRotation(dx,Vector3D.Z_AXIS);
  46.        m.appendRotation(dy,Vector3D.X_AXIS);
  47.        m.appendTranslation(hw,hh, 0);
  48.        Utils3D.projectVectors(m, newVerts, pVerts, uv);
  49.        with(vectors.graphics){
  50.            clear();
  51.            beginFill(0xFFFFFF);
  52.            drawCircle(hw, hh, radius+10);
  53.            beginFill(0x000000);
  54.            drawPath(cmds, pVerts, GraphicsPathWinding.NON_ZERO);
  55.        }
  56.        canvas.fillRect(canvas.rect, 0x000000);
  57.        canvas.draw(vectors);
  58.        blurred.copyPixels(canvas, canvas.rect, pnt);
  59.        blurred.applyFilter(blurred,blurred.rect, pnt, blur);
  60.        canvas.draw(blurred, null, null, BlendMode.SCREEN);
  61. }

This snippet is similar to yesterdays post but the visual result is rather different. This one does a little more Matrix3D stuff resulting in a sphere made up entirely of squares. This is obscured by the size of the squares and the fact that they overlap and cut each other up. BitmapData a BlurFilter and a BlendMode give the entire thing a slight glow...


Have a look at the swf here...

Posted in 3D, BitmapData, Vector | Also tagged , , | 12 Comments

Bresenham’s Circle and setVector()

Actionscript:
  1. var canvasSize:int = 400;
  2. var canvas:BitmapData = new BitmapData(canvasSize, canvasSize, false, 0xFFFFFF);
  3. addChild(new Bitmap(canvas));
  4. var size:int = canvas.width * canvas.height;
  5. var pixels:Vector.<uint> = canvas.getVector(canvas.rect);
  6.  
  7. addEventListener(Event.ENTER_FRAME, onLoop);
  8. function onLoop(evt:Event):void {
  9.      for (var i:int = 0; i<500; i++){
  10.       fillCircle(int(Math.random() * canvasSize),
  11.                       int(Math.random() * canvasSize),
  12.                       int(Math.random() * 5 + 3),
  13.                       uint(Math.random() * 0xFFFF));
  14.      }
  15.      canvas.lock();
  16.      canvas.setVector(canvas.rect, pixels);
  17.      canvas.unlock();
  18. }
  19.  
  20. function fillCircle(xp:int,yp:int, radius:int, col:uint = 0x000000):void {
  21.     var xoff:int =0;
  22.     var yoff:int = radius;
  23.     var balance:int = -radius;
  24.     while (xoff <= yoff) {
  25.          var p0:int = xp - xoff;
  26.          var p1:int = xp - yoff;
  27.          var w0:int = xoff + xoff;
  28.          var w1:int = yoff + yoff;
  29.          hLine(p0, yp + yoff, w0, col);
  30.          hLine(p0, yp - yoff, w0, col);
  31.          hLine(p1, yp + xoff, w1, col);
  32.          hLine(p1, yp - xoff, w1, col);
  33.         if ((balance += xoff++ + xoff)>= 0) {
  34.             balance-=--yoff+yoff;
  35.         }
  36.     }
  37. }
  38. function hLine(xp:int, yp:int, w:int, col:uint):void {
  39.     var index:int = xp + yp * canvasSize;
  40.     for (var i:int = 0; i <w; i++){
  41.         index++;
  42.         if (index> -1 && index <size){
  43.           pixels[index] = col;
  44.         }
  45.     }
  46. }

In the past I've posted examples of Bresenham's Circle (here and here). Both of those examples make use of setPixel(). Today's snippet demos a version of Bresenham's Circle that works with setVector().

Posted in BitmapData, graphics algorithms, pixel manipulation, setPixel | Also tagged , , | Leave a comment