
An MDI style interface implemented in Flex. It dynamically loads external Flex / Flash programs.
Monthly Archives: September 2007
SVG Path Loader For AS3
[This Code Is Outdated, Click Here To View The Most Recent Updates]
I was looking for a way to design simple vector paths for use in Papervision3D. At first I considered writing an interpreter for a CAD format such as DWG or DXF, but I ultimately decided I didn’t want to invest that much time and chose the XML based SVG format. After putting together a quick XML parser that read path tags and spit out black outlines I scrapped the whole thing in favor of using a regular expression to just pull out the path tags.
|
1 2 3 4 5 6 7 8 9 |
public function SvgPaths(svgData:String) { var pathTagRE:RegExp = /(<path.*?/>)/sig; var pathArray:Array; while(pathArray = pathTagRE.exec(svgData)) { paths.push(new SvgPath(pathArray[1])); } } |
Doing a little more digging I stumbled upon Helen Triolo’s implementation of an SVG reader in AS2. I snagged some code out of her makeDrawCmds function in PathToArray.as file and added support for “t/T” as well as a stub for implementing the elliptical arc path element. Helen’s code for converting cubic bezier curves to quadratic relies upon a recursive function. For a little quicker parsing I substituted Timothee Groleau’s fixed midpoint conversion code.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
static public function cubicBezierToQuadratic(P0:Object, P1:Object, P2:Object, P3:Object):Array { /* A portion of code from Bezier_lib.as by Timothee Groleau */ // calculates the useful base points var PA:Object = getPointOnSegment(P0, P1, 3/4); var PB:Object = getPointOnSegment(P3, P2, 3/4); // get 1/16 of the [P3, P0] segment var dx:Number = (P3.x - P0.x)/16; var dy:Number = (P3.y - P0.y)/16; // calculates control point 1 var Pc_1:Object = getPointOnSegment(P0, P1, 3/8); // calculates control point 2 var Pc_2:Object = getPointOnSegment(PA, PB, 3/8); Pc_2.x -= dx; Pc_2.y -= dy; // calculates control point 3 var Pc_3:Object = getPointOnSegment(PB, PA, 3/8); Pc_3.x += dx; Pc_3.y += dy; // calculates control point 4 var Pc_4:Object = getPointOnSegment(P3, P2, 3/8); // calculates the 3 anchor points var Pa_1:Object = getMiddle(Pc_1, Pc_2); var Pa_2:Object = getMiddle(PA, PB); var Pa_3:Object = getMiddle(Pc_3, Pc_4); // draw the four quadratic subsegments return ([{cx:Pc_1.x, cy:Pc_1.y, ax:Pa_1.x, ay:Pa_1.y}, {cx:Pc_2.x, cy:Pc_2.y, ax:Pa_2.x, ay:Pa_2.y}, {cx:Pc_3.x, cy:Pc_3.y, ax:Pa_3.x, ay:Pa_3.y}, {cx:Pc_4.x, cy:Pc_4.y, ax:P3.x, ay:P3.y}]); } |
To Do:
- Add elliptical arc support
- Add path transformation support
Rippling Flag
I created a basic Plane and applied a BitmapMaterial to it. Before each frame a sine wave is applied to the plane vertices.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
var timeNumber:Number = 0; override public function loop3D(e:Event):void { if (!ready) { return; } var p:Plane = rootNode.getChildByName("plane") as Plane; for(var segW:int = 0; segW <= p.segmentsW; segW++) { var newZ:Number = Math.sin(segW + timeNumber) * rippleHeight; for (var segH:int = 0; segH <= p.segmentsH; segH++) { var currentIndex:int = ((p.segmentsH + 1) * segW) + segH; p.geometry.vertices[currentIndex].z = newZ; } timeNumber += .05; if (timeNumber == 360) { timeNumber = 0; } } rootNode.rotationX = int(-(this.mouseY - (this.height/2))) * 0.5; rootNode.rotationY = int(-(this.mouseX - (this.width/2))) * 0.5; scene3D.renderCamera(camera3D); } |
Papervision3D & SoundMixer

A quick example of direct manipulation of Papervision3D Vertices. It uses the current audio wave or spectrum to set the vertices’s y-axis value.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var bytes:ByteArray; /* Holds the 512 bytes returned by computeSpectrum */ SoundMixer.computeSpectrum(bytes, true 0); /* See the complete source code for the patched ShadedColorMaterial */ var shadedMaterial:ShadedColorMaterial = new ShadedColorMaterial(0xFFFF00); var sphere:Sphere = new Sphere(shadedMaterial, 400, 32, 32); rootNode.addChild(sphere); for(var i:int = 0; i < 512; i++) { sphere.geometry.vertices[i].y = -bytes[i] * 2; } scene3D.renderCamera(camera3D); |
