Flash CS4 Planetarium in 49 Lines

April 22, 2009

Intro

In Chapter 7 of the book I change the  Planetarium example (shown in a previous post) so that it only uses XML (threw out Cairngorm). And in the process I thought, hey this should be easy to do in CS4. And it was! Check it out below…a planetarium (with real star data) in 49 lines of code…including comments.

Flash CS4 Planetarium in 49 Lines

Flash CS4 Planetarium in 49 Lines

Demo

Source

Disucssion

There are two main steps in getting this to go:

Step 1: Get a star object into your library so you can instantiate it onto the stage like you would your particles class – this step saves you tons of code: var myStar = new Star();

Star in the Library for Instantiation

Star in the Library for Instantiation

Step 2: Treat your stars like a particle system. This lets your stuff then into an updatable array so you can rotate them:

The rest of this stuff you’ve seen before, and I go through the discussion in the book and in the YouTube video above so I just show the code below: myParticles[j]

Sample Star Data (CSV)

AND, 2.065, 42.316, 0,
AND, 1.161, 35.616, 1,
AND, 0.655, 30.85, 1,
AND, 0.139, 29.083, 1,

CS4 Planetarium in 49 lines

import flash.events.*;
import flash.display.*;

//Create star parameters
var myStar:Star;
var skyRadius:Number = 240;
var myOsc:int=0;
var starHolder:MovieClip= new MovieClip();

//Create a star array to hold CSVdata and particle array
var starArray:Array=new Array();
var myParticles = new Array();

//XML Statements used to bring in XML data
var urlRequest:URLRequest = new URLRequest(“data/starData.xml”);
var xmlLoader:URLLoader = new URLLoader(urlRequest);
xmlLoader.addEventListener(“complete”, readXml);

//XML parser and CSV splitter
function readXml(event:Event):void{
var markersXML:XML = new XML(event.target.data);
starArray=markersXML.myStars.split(“,”);

//Set the initial star system in place and add to a Movie holder
for(var i:uint = 0; i < starArray.length/4; i++){

//Instantiate stars and place them in a particle array
var myStar = new Star();
myParticles.push(myStar);
starHolder.addChild(myStar);

//Position stars (x, y, z) on stage
myStar.x=skyRadius*(Math.cos(2*Math.PI*starArray[4*i+1]/24)*Math.sin((90-starArray[4*i+2])*Math.PI/180));
myStar.z=-skyRadius*(Math.sin(2*Math.PI*starArray[4*i+1]/24)*Math.sin((90-starArray[4*i+2])*Math.PI/180));
myStar.y=skyRadius*Math.cos((90-starArray[4*i+2])*Math.PI/180);

//Scale stars according to magnitude and give a rand rotation
myStar.scaleX=myStar.scaleY=(1/9)*(3-starArray[(4*i+3)]);
myStar.rotation=180*Math.random();
}

//Add stars to star holder and position the holder
addChild(starHolder);
starHolder.x=400;
starHolder.y=300;

//Create your animation loop using an Enter Frame Listener
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

function onEnterFrame(event:Event):void{
//Increment oscillation parameter and iterate over stars
myOsc++;
for(var j:uint = 0; j < starArray.length/4; j++){

//Set new x, y, z for your stars as they rotate
myParticles[j].x=skyRadius*(Math.cos(2*Math.PI*starArray[4*j+1]/24+myOsc/180)*Math.sin((90-starArray[4*j+2])*Math.PI/180));
myParticles[j].z=-skyRadius*(Math.sin(2*Math.PI*starArray[4*j+1]/24+myOsc/180)*Math.sin((90-starArray[4*j+2])*Math.PI/180));
myParticles[j].y=skyRadius*Math.cos((90-starArray[4*j+2])*Math.PI/180);
}}


2 and 3D FLINT Particle (Gumbo) Viewers

April 17, 2009

Intro

I used to have an old truck, that I payed way too much for, and on its sixth repair trip … the mechanic said there had been too many hands in it. What did that mean? And then it just died and nobody knew why. It’s true for software as well – too many people working on a project can kill it … you just need a few bright folks. And with Flint, there was just one, Richard Lord. It demonstrates how powerful just one guy can be.

In chapter 6 of the book, we cover Richard’s incredible FLINT particle system and its use in PV3D … super job Richard Lord!!! This guy must have a cranium cavity the size of the grand canyon.

However, in the prep for the particle chapter I really got tired of having to wait for his different example apps to come up, so I created 2 and 3D fast particle viewers (in Flex 4 Gumbo) . You can view the apps below and download the source code as well. They work very similarly to the MD2 viewer posted earlier, so I won’t cover how they were made here.

Download Source for both Apps here

2D Viewer Demo (click this link or image below)

Flint 2D Particle System

Flint 2D Particle Viewer

3D Viewer Demo (click this link or image below)

3D Particle Viewer

Flint 3D Particle Viewer


Flash CS4 Exploding House of Cards (3D Particle Class)

April 15, 2009

Intro

Exploding an object is serious gaming fun. There’s just something about the human psyche that loves to see things blow up. In this post, we show you how to create a card house in Flash CS4 and then how to blow it up by treating the cards as particles.

Exploding House of Cards

Exploding House of Cards

Demo

Source: http://flex3cookbook3.googlecode.com/files/blowitUp3D.zip


YouTube Video 1: Building a House of Cards in CS4 (Part 1)

YouTube Video 2: Building a House of Cards in CS4 (Part 2)

YouTube Video 3: Making Your CS4 Card House Explode (Part 3)

Discussion

The first step in making things explode is to add a spin (x, y, z) property to your Particle3D class (developed in the book).

You can accomplish this in the following three steps:

Exploding an object is serious gaming fun. There’s just something about the human psyche that loves to see things blow up. The first step in making things explode is to add a spin (x, y, z) property to your Particle3D class. You can accomplish this in the following three steps:

Step 1: To keep things straight rename your Particle3D (developed in the book) class to ParticleBlowUp and add a spin (x, y, z) property

public var spinX:Number;
public var spinY:Number;
public var spinZ:Number;

Step 2: In the constructor function, set the spin (x, y, z) equal to zero.

spinX = 0;
spinY = 0;
spinZ = 0;

Step 3: And in your animation method “myLoop” update the rotation of the particle by iterating the spin (x, y, z) amount.

this.rotationX += spinX;
this.rotationY += spinY;
this.rotationZ += spinZ;

And that’s all you have to do to your Particle3D (now named ParticleBlowUp) class. See the book for more details…

You’re Only Half Way

But to get your particle system to explode you want to transfer a multi-part movie clip into your Particle class (using polymorphism). Then iterate over the elements of that movie clip, so you can spin those elements off into space in different directions, simulating an explosion.

To do this, make the following changes to your Particle3D class shown below:

1. Remove the “extends Sprite” statement from your ParticleBlowUp class; this allows you to bring in an object into your ParticleBlowUp class.

2. Create a public property “obj” and data type it as a Display Object:

public var obj:DisplayObject

3. Add “obj” to your constructor method, declare “obj” as an object in your constructor method.
4. Finally, change all the “this” keywords to object so that the transformations are applied to the object passed in through the constructor.

To see the rest of the discussion click the link below:

Read the rest of this entry »


Hacking Plugin Media and PV3D.org

April 11, 2009

Intro

Seb Lee-Delisle is the technical director at Plug-in media and is famous world wide for his particle effects and his very entertaining presentations. During the Christmas season Seb usually releases a snow particle system to the open source community. You can download Seb’s snow systems and more from his blog at www.sebleedelisle.com.

In this post, you’ll take Seb’s snow-storm particle effect and combine it with another great blog release found on John Lindquist’s site at www.pv3d.org. John also releases tons of great PV3D examples and you should take the time to visit his site as well.

You’ll combine Seb and John’s work to produce a reflecting snowy Christmas scene shown below. This is a great example of hacking two different software apps to produce a superior one.

IT'S A SNOWY CHRISTMAS

IT'S A SNOWY CHRISTMAS

Demo

Download

YouTube

Discussion

If you haven’t guessed it yet, hacking in the open source community is a good thing, and the book emphasizes going beyond the surface of PV3D and making it better (or hacking the heck out of it)!

Making it Snow for Christmas

You’ll want to start by either going to Seb and John’s blogs and downloading the corresponding snow storm and Flint Christmas scene, or by downloading the Merry Christmas code from the book’s chapter code (or link above).

John uses this Christmas scene as an example of Flint particles. The problem is that his snow is just 2D and does not interact with the reflective surface. Seb has 3D snow that will interact with the surface. So you’re going to delete the FLINT particle snow system (you’ll learn about FLINT in a later post) and add Seb’s snow.

Here are the steps:

1. Delete the Flint Particle system from John’s code.
2. And import Seb’s snow storm package into to John’s code and instantiate it using the following code:

snowStorm=new SnowStorm(100, .4,2000);
// Also, make sure that you update the snow in your animation loop (enterFrameHandler) or it willnot show up.
snowStorm.update();

3. John uses planes for Christmas ornaments, you can “snaz” this up a bit by replacing the planes with spheres, and by reducing the segments to 2×2 you make your ornaments look like crystals.

for(var i:int = 0; i < total; i++)
{
var material:ColorMaterial;
if((i & 1) == 0) material = new ColorMaterial(0xaa0000);
else material = new ColorMaterial(0x00aa00);
material.doubleSided = true;
//Add a sphere instead
var sphere:Sphere = new Sphere(material, 10, 2,2);
sphere.x = Math.cos(i) * (radius – i * 3);
sphere.z = Math.sin(i) * (radius – i * 3);
sphere.y = i / total * height;

myHolder.addChild(sphere);

}

4. You now have 3D snow and cool looking ornaments, but the snow is out of wrack and at this point you’ll need to adjust a few parameters to make it look just right. In this case, we want the falling snow to disappear just as it touches the reflective surface . To accomplish this adjust the following parameters

snowStorm=new SnowStorm(100, .4,2000);
myHolder.addChild(snowStorm);
//Pull the snow up so it disappears when it hits the reflective surface
snowStorm.y=1000;

In addition to changing your particle parameters you raise your snow’s y-position so it just touches the reflective surface before being recycled. Next you have to go into the snow class itself and adjust the particle ratio. In the SnowStorm class in the update method make the following change:

if(particles.length/10 < maxFlakes)

This is what I call emotional (or intuitive) programming. You might not know completely how the code works but by changing a few parameters you bring everything into agreement. This can be both dangerous and fun! So make sure you keep back up copies in case you really mess something up.

This causes your particles to be regenerated more rapidly and close the gap that appears due to particle lag. Now matter what you create, you’ll always need to make adjustments. Get used to going down to sub classes and changing parameters.

Flex is a great tool for surfing logically to classes that you need to modify. Just roll over a method and hold down the command key (MAC) or alt key (PC) and when you do the method, class, or property will underscore and when you click on it you will automatically navigate to that method even if it is in another class.

5. Finally you want to change the words from MERRY CHRISTMAS to IT’S A SNOWY CHRISTMAS. You’ll need to play around with the spacing of the words a little to get it right (this is where a little knowledge of trig is helpful).

//IT’S A
var itsaMaterial:Letter3DMaterial = new Letter3DMaterial(0x00cc00);
var itsa:Text3D = new Text3D(“IT’S A”, rockwell, itsaMaterial);
//SNOWY
var snowyMaterial:Letter3DMaterial = new Letter3DMaterial(0xcc0000);
var snowy:Text3D = new Text3D(“SNOWY”, rockwell, snowyMaterial);
//CHRISTMAS
var christmasMaterial:Letter3DMaterial = new Letter3DMaterial(0x00cc00);
var christmas:Text3D = new Text3D(“CHRISTMAS”, rockwell, christmasMaterial);

The final results are shown below in the figure above. To see the entire code download it from the source or click the more button below:

Read the rest of this entry »


Slicing Images in 3D and Adding Interactivity

April 5, 2009

Intro

One of the things I really hate about slicing up images … is slicing them. It’s just so time intensive in Photoshop, Illustrator, or Gimp and then I never get it right or the site specs change and I have to re-slice (and God forbid re-program). So I’ve developed a method for slicing them programmatically – no more hand made clothes, all made by machine! Let me show you how it works.

Click the image below to see the demo (click on the slices to rotate them, or you can drag them as well):

Split Image and Interactivity

Split Image and Interactivity

Demo

Note: You must use the Flash 10 player. I built this in Gumbo as an ActionScript project.

Source

YouTube Demo


Discussion

In this post we actually handle three important concepts

  1. Slicing an Image
  2. Polymorphism & Encapsulation
  3. Static Properties/Methods & Interactivity

These concepts are key OOP principles briefly discussed below, but are given much more detail in the book. And are essential in understanding PV3D.

Slicing an Image

Slicing an image is pretty easy using copyPixels. You just bring in your image and copy the portion of the image that is your split as shown below:

// loop through all pieces
for(var x:uint=0;x<6;x++) {
for (var y:uint=0;y<4;y++) {

// create new map piece bitmap
var newmapPieceBitmap:Bitmap = new Bitmap(new BitmapData(pieceWidth,pieceHeight));
newmapPieceBitmap.bitmapData.copyPixels(image.bitmapData,new Rectangle(x*pieceWidth,y*pieceHeight,pieceWidth,pieceHeight),new Point(0,0));

// create new sprite and add bitmap data to it
var newmapPiece:Sprite = new Sprite();
newmapPiece.addChild(newmapPieceBitmap);
mapPiece=new MapPiece(newmapPiece,x,y);
DragDropStatic.DragDrop(mapPiece);

// set location
mapPiece.x = x*(pieceWidth+5)+20;
mapPiece.y = y*(pieceHeight+5)+20;
mapPiece.addEventListener(MouseEvent.CLICK,clickmapPiece);

// add to stage
movie.addChild(mapPiece);

}
}

You’ve got to loop twice to get both column and row as you use copyPixels to grab your slice. If you check out Gary Rosenzweig’s book ActionScript 3.0 Game Programming University you’ll find that he uses a similar slicing technique. But in addition to Gary’s approach, we use Polymorphism & Encapsulation typically found in PV3D. Their use is briefly discussed below, but is treated in greater detail in the book.

Polymorphism & Encapsulation

The heart of PV3D is encapsulation and by using polymorphism we can create a MapPiece class that enables us to easily work with the map pieces. Polymorphism is used to grab the map pieces and treat them as instantiated objects as shown in the MapPiece class below:

package objects.primitives
{
import flash.display.Sprite;

public class MapPiece extends Sprite
{
private var mapPiece:Sprite;
private var locX:uint;
private var locY:uint;
private var myXPos:Number;
private var myYPos:Number;

public function MapPiece(mapPiece:Sprite,locX:uint,locY:uint)
{
this.mapPiece=mapPiece;
this.locX=locX;
this.locY=locY;
addChild(mapPiece);
}

Interactivity

Interactivity is accomplished in two ways: (1) by adding a listener, and (2) using Static Properties and Methods.

Listener

The instantiated map piece has a mouse click listener added to each map piece using the code below:

mapPiece.addEventListener(MouseEvent.CLICK,clickmapPiece);

Static Properties and Methods

By creating a static properties and methods class you can create reusable code. This is done for the drag and drop class shown below.

package utils
{
import flash.display.Sprite;
import flash.events.MouseEvent;

public class DragDropStatic
{
public function DragDropStatic()
{

}

public static function DragDrop(mySprite:Sprite):void
{
mySprite.addEventListener(MouseEvent.MOUSE_DOWN, dragMe);
mySprite.addEventListener(MouseEvent.MOUSE_UP, dropMe);
function dragMe(event:MouseEvent):void
{
mySprite.startDrag();
}
function dropMe(event:MouseEvent):void
{
mySprite.stopDrag();

}}}}

Once the class is created then it’s easily executed using

DragDropStatic.DragDrop(mapPiece);

All of this is handled in greater detail in Chapter 6 of the book.

Check out the source code by downloading it from the link above or clicking below.

Read the rest of this entry »


Gaming Seminar at NKU (Notes and Links)

March 31, 2009

Intro

Here’s a few notes and links for the Gaming Seminar:

Three Types of Games

  • Simulators
  • Board Games
  • Environment Game

Particle systems are at the heart of games.

Augmented Reality

Seb Delise

Augment Example 1

Augment Example 2

Example WebCam Experiment

http://woveninteractive.com/dev/nascar/flartoolkit-nascar.html

Making Games

In Making games there are three important areas:

  • Pedagogy…game play, genre (need a design doc – I don’t know what you are thinking)
  • Graphics and Models
  • Programming

Seb Delise Pong Example

3D Pong Example

Barney Car Modeling


CS4 (Gumbo) Molfile Molecule Viewer Sem#4

February 24, 2009

Intro

This is seminar #4, of a series of free seminars given this semester at NKU on Papervision3D and CS4. It demonstrates how to create a molfile molecule viewer in CS4 (Gumbo). Click the image below to see a demo.

CS4 Molecule for a Molfile

CS4 Molecule from a Molfile

Source

Demo

YouTube

Discussion

This is now my second version of a 3D molecule viewer. The first version was written in Papervision3D and was about 1400 lines of code and required that you rewrite the molfile into xml, and didn’t show bonds. This version is in CS4 (Gumbo or Flex 4) and is only about 350 lines of code, has bonds (single, double, triple, aromatic) and parses the molfile directly.

It took me a day to write this application(from 4 to 11), and that was with breaks: playing with the kids, gym, Shakespeare club, an ice cream float party, and several episodes of Hawaii-5-0 and Enterprise. Yeah, this is the life!

Molfile Parser

Parsing the Molefile was much easier than I thought it was going to be. Here is how you do it:

  • You just bring the molfile into Flex 4 using http services command (just as you would an XML file but with no e4x format)

<mx:HTTPService id=”molService” url=”assets/0420.mol”
result=”initMoleFile(event)” />

  • Then you convert it to a string, take out the special characters, split the contents, stuff it into an array, and remove all empty array elements.

// Convert to string
myString=molService.lastResult.toString();

//Remove special characters
myString = myString.split(“\n”).join(” “);
myString = myString.split(“\r”).join(” “);

//Stuff into an Array
myArray = myString.split(/ /);

//Filter out bland array elements
myArray = myArray.filter(filterMe);
function filterMe(element:String, index:int, array:Array):Boolean{
return (element != “” ); }

  • After you’ve stuffed your molefile into an array, you need to know where to go in that array so you can start counting off the data elements.Where do you go? Go to the version number of the molfile. So run a forEach and grab it’s index value.

myArray.forEach(myStart);

function myStart(element:String, index:int, array:Array):void{
if(element == “V2000″||element == “V3000″){
myStartVert=index;}

The index value of the version number is the heart of your molfile parser. Above we allow for versions V2000 or V3000. This index value will take you to any piece of data that you need in order to display your molecule. From this point on, its just a big counting game, everything is referenced to your version index value.

Atom File

To display your model you need an atom shape that can change size, color, and fill based upon the atom type.

The atom color, type, and radius were previously handled in an earlier version of the molecule viewer, created in Papervision3D (video, source).

And the atom shape and fill were handled in a previous post in this blog on 3D Lines in CS4 using drawPath.

By combining these two programs you can come up with a suitable atom. To do this:

  • Place the atom switch case from the PV3D Viewer into the Ball class created in the 3D Lines post, then change the ball class to Atom along with its constructor and class names.
  • In the switch case change the myColor value from grabbing a jpg to equaling a color value for all possible atoms:

case “H”:
//myColor = “colors/white.jpg”;
myColor = 0xffffff;
radius = 25;

  • In the Constructor function change it to receive only one parameter type, which is the letter of your atom: H, C, O…

public function init(type:String):void{…

  • Finally, change the fill method to gradient fill so your atoms looks cool.

graphics.beginGradientFill(myType, [myColor, 0x000022],[1,1], [1, 40]);

Now that your atom subclass is completed, it’s time to start building molecules.

Creating Molecules and Bonds

There are two parts to creating molecules: placing atoms in 3D, and creating their bonds. The first part of a molfile gives you the atom position values, and the second part give the bond relationships (which atoms are connected to which) and types.

Placing Atoms

Essentially all you have to do is replace the random placement of circles from the post on drawPaths to the atomic positions found in your molfile.

atom.xpos = myArray[myStartVert+1 +j*16] * myScale – offsetx;
atom.ypos = myArray[myStartVert+2 +j*16] * myScale – offsety;
atom.zpos = myArray[myStartVert+3 +j*16] * myScale – offsetz;

myHolder.addChild(atom);

You get to those positions by counting 1 position forward for x, 2 for y, and 3 for z, from the version number index, as shown above.

The offset is just an average of the molecular positions and gives you the ability to spin your molecule around its center. Everything else pretty much follows what was done in the drawPaths post.

Creating Bonds

Creating bonds is easy as well, with one big conceptual change from the drawPaths post. Double processing is eliminated by just duplicating the atom and placing it into a marks array. The lines follow the duplicated atom in the marks array and the other atom which exist in the atoms array are used for sorting.

atoms.push(atom);
marks.push(atom);

The big problem (in creating bonds) was figuring out how to create double, triple, and aromatic bonds. And it turns out to be just a big counting game, coupled with offsetting lines. It starts with figuring out what type of bond you have and using that information in a switch case.

The information for what type of bond you have is carried in the second part of your molfile which starts at

startBondArray=myStartVert+myNumAtoms*16+1

Adding 2 to this number gives you the bond type location (OK once again it’s a big counting game – check out the molfile description under the read more button to see the molfile structure – I know it well).

So, each time you create a double, triple, or aromatic bond you have to keep track of where all the data is in your array. This was accomplished by adding the following counting tracker to your command and data arrays:

commands[2*k+2*dB+4*tB+2*aB]

mydata[4*k+4*dB+8*tB+4*aB]

which are needed to for the drawPath command shown below

myHolder.graphics.drawPath(commands, mydata);

The variables dB, tB, and aB are iterated (by one) each time you create a double, triple, or aromatic bond respectively. These values are then zeroed after each molecular drawing iteration and the process is restarted on each onEnterFrame tick.

Creating the bond offsets was not very sophisticated as shown below:

mydata[4*k+4*dB+8*tB+4*aB] = marks[myArray[startBondArray+7*k]-1].x-bond2Sep;
mydata[4*k+1+4*dB+8*tB+4*aB] = marks[myArray[startBondArray+7*k]-1].y-bond2Sep;

mydata[4*k+4+4*dB+8*tB+4*aB] = marks[myArray[startBondArray+7*k]-1].x+bond2Sep;
mydata[4*k+5+4*dB+8*tB+4*aB] = marks[myArray[startBondArray+7*k]-1].y+bond2Sep;

You just subtract or add an offset value (bond2Sep) as shown above for the double bond case.

Which Way Should We Go!

In going through this, I found some molfiles on the web that were not well formed and would not work with this parser. That’s always the problem with parsers. The errors were easy to fix and many times just meant adding or subtracting an extra zero. But your end user can’t do that…

I really think XML is the best way to go. That way you can target nodes and forget about counting. You can go even a step farther with XML and include chemical bonding information which would enable you to run chemical simulations. Wouldn’t that be cool!

To see all the code, download it from the source link above or click the button below:

Read the rest of this entry »


3D Lines in CS4 using drawPath

February 19, 2009

Intro

In the previous post on Pendulums, Papervision’s line3D class was used to plot the orbit of a Foucault Pendulum in a rotated plane. But there was a problem – adding more line segments slowed the processor and as result line segments had to be removed. Aha! You just thought I had created some really cool effect by erasing the end of my line while making the front. No, without erasing, everything would eventually slow down to a stand still.

Let’s speed things up a little by using CS4′s drawPath method. Click on the image below to see the demo.

3D Lines in CS4

3D Lines in CS4

Source

Demo

YouTube


Discussion: Drawing Points and Lines

Keith Peters in his book does a similar example using CS3 line functions, but he doesn’t sort his filled circles. His circles are black, and when you run his demo it appears as if the application is z-sorting-but it isn’t. If you try to applying his zSort algorithm the connecting lines go hay-wire. They don’t know where to go and try to follow his black circles as they rapidly sort.

Here’s the Trick

Commonly when we run into such issues in Papervision3D we create dummy graphics for our wayward objects to follow. So in this case you create dummy graphics under your circles for your lines to follow. Thus, separating the zSortng of the circles from the positions of your lines.

There ‘s a little bit of double processing here, but it’s worth it. And it’s very typical of solving problems of this type. In the code below, you see the parallel creation of the circle (or ball) and the dummy marker (or mark).

var ball:BallCS4 = new BallCS4(10, 0);
var mark:MarkCS4 = new MarkCS4(0, 0);
marks.push(ball);
balls.push(ball);
mark.xpos = ball.xpos = Math.random() * 200 – 100;
mark.ypos = ball.ypos = Math.random() * 200 – 100;
mark.zpos = ball.zpos = Math.random() * 200 – 100;
myHolder.addChild(ball);
myHolder.addChild(mark);

The MarkCS4 class is your dummy marker and is an object of zero pixel size – how do like that one! The BallCS4 class is similar to the MarkCS4 class. But draws a circle instead of a zero pixel line.

BallCS4 uses the drawPath method to create its circle in CS4. Since there are no drawCircles methods in CS4 you have to create one. I used four radial curves (created by the CURVE_TO method), which looks fine for small circles, but you’ll need to add eight for larger circles. The radius parameter (below) determines the size of your filled circle.

commands.push(GraphicsPathCommand.MOVE_TO);
data.push(-radius/1.9, radius/1.9);

data.push(0, radius);
data.push(radius/1.9, radius/1.9);

data.push(radius, 0);
data.push(radius/1.9, -radius/1.9);

data.push(0, -radius);
data.push(-radius/1.9, -radius/1.9);

data.push(-radius, 0);
data.push(-radius/1.9, radius/1.9);

commands.push(GraphicsPathCommand.CURVE_TO);
commands.push(GraphicsPathCommand.CURVE_TO);
commands.push(GraphicsPathCommand.CURVE_TO);
commands.push(GraphicsPathCommand.CURVE_TO);

graphics.lineStyle(0);
graphics.beginFill(0×800000);
graphics.drawPath(commands, data);

Extra Reading

A great article which explains this in more detail can be found on Senocular’s blog. Once you’ve got your “commands” and “data” Vectors loaded, you throw them into the drawPath function…and TaDah – sphere (or in this case filled circle)! Instantiate it as many times as you want.

zSort

Now that you’ve decoupled the spheres from the lines using the marker graphics you can now use Keith’s zSort method.

private function sortZ():void
{
balls.sortOn(“zpos”, Array.NUMERIC | Array.DESCENDING );
for(var i:uint = 0; i < numBalls; i++)
{
var ball:BallCS4 = balls[i];
myHolder.addChild(ball as Sprite);
}
}

The Big Limitation

The big limitation is that drawPath only draws in x and y – hey where’s the z Adobe? So to get around that limitation you have to use perspective scaling given in the code below:

var scale:Number = fl / (fl + ball.zpos);
ball.scaleX = ball.scaleY = scale;
ball.x = ball.xpos*scale;
ball.y = ball.ypos*scale;

That’s it, you’re ready to start using 3D lines in CS4. In an upcoming post, we will treat Creating 3D Springs and Making a Node Garden. And my favorite, 3D spring data visualization which I can’t wait to release. I’ve been working on this one for a while.

To see the entire code download the source above or click on the more button below.

Read the rest of this entry »


CS4 Creating a Parametric Particle Field

January 11, 2009

Intro

In the previous section of the book, you learned how to get a single element orbiting a torus using the parametric equations of a torus. Here you’ll multiply that single element by 100 and create a parametric particle system, which orbits your torus. Click the image below to see the torus worm in action.

Torus Worm (Parametric Particle System)

Torus Worm (Parametric Particle System)

You’ll get a more formal treatment of particles in the gaming section of the book. But for the most part, anything with more than one element can be treated as a particle system. Treating elements as particles has a number of advantages. Primarily, particles are more easily handled mathematically. You’ll use particle systems extensively throughout the book.

Web Stuff

1. Demo
2. Source

3. YouTube (Below)

Coming Soon!

Discussion

Building a particle system in Flash is relatively easy. And in this section, you’ll cover the basics. To build the orbiting worm around a torus (parametric particle system), follow the steps below:

1. Declare the number of particles to be created and create an array to place your particles in. This is the key to working with particles. Using an array (particles_ary) you’ll be able to control position, color, and alpha of each particle.

var numOfParticles:uint = 100;
var particles_ary:Array = [];

2. Use a for loop to run the updateStage() function which creates your particles. Once the particles are created run the addEventListener method which starts the updating loop for each particle on every on enter frame event.

for(var i:uint = 0; i < numOfParticles; i++)
{
updateStage();
numVar++;
//Start Looping
if(numVar==numOfParticles){
addEventListener(Event.ENTER_FRAME, myonEnterFrame);}
}

3. Draw your balls (particles) to the stage and place them in a particle array. A random color is assigned to each ball using the Math.random()*0xffffff method.

//Draw a Ball
var ball:Sprite = new Sprite
//Assign a random ball color
ball.graphics.beginFill(Math.random()*0xffffff);
//draws your ball at 0,0
ball.graphics.drawCircle(0, 0, ballRadius);
ball.graphics.endFill();//ends the fill
//Add ball to the stage
addChild(ball);
//Push the ball into a particle array
particles_ary.push(ball);

4. With each onEnterFrame loop update all your particle positions using myAngle+i/20 that separates the different particles in angle by the ratio of i/20. This causes your particles to line up on the torus and move across its surface as the myAngle variable is iterated. Use the particles_ary[i].alpha method to change the alpha of each particle based on their ith position. Center the particle system on the stage by adding CenterX, and CenterY to the particle x, y positions.

for(var i:uint = 0; i < particles_ary.length; i++)
{
//ball parametric orbit x
var newAngle:Number=myAngle+i/20;
particles_ary[i].alpha=1/(i+1)+.2;
particles_ary[i].x = (100+60*Math.cos(2*newAngle))*Math.cos(newAngle/4)+CenterX;
//ball parametric orbit y
particles_ary[i].y = (100+60*Math.cos(2*newAngle))*Math.sin(newAngle/4)+CenterY;
//ball parametric orbit z
particles_ary[i].z = 60*Math.sin(2*newAngle);
}

The result is a worm-like entity orbiting a torus. The key to creating particle systems and controlling them is to stuff the individual particles into an array upon creation. And then iterate over each particle during the frame loop of the animation sequence.

The master of building particle systems in Papervision3D is Seb Lee-Delisle: with numerous examples of Flash 9 particles systems on his blog at http://www.sebleedelisle.com. In addition, flint-particle-system, a very robust Google Code project, works very well with Papervision3D.

Although in CS4, with native 3D and pixel bender, the process of building particle systems becomes greatly simplified as shown in the code above.

Click the more button to see the entire code:

Read the rest of this entry »


Setting up a Rubik’s Cube in Papervision

December 31, 2008

Intro

Well it’s Christmas, and you’re right, one of the kids got a Rubik’s cube. And we’ve spent the entire break figuring it out – right down to the smallest child, even baby Na. It was a Rubik’s Cube free-for-all. And if that wasn’t enough, we had to make it virtual.

In this post, we’re going to show you a trick you can use to set up a Rubik’s Cube in just 8 lines of code. It uses the same trick that Mr. Doob uses on his blog – geometry.vertices. Below is an image of the cube you will make. Click on it to run the application.

Rubik's Cube (set up in 8 lines of code)

Rubik's Cube (set up in 8 lines of code)

Web Stuff

Demo

Download Source

YouTube Video – Coming!

Discussion

Essentially what you want to do is create a single large cube and use its vertices to anchor the smaller cubes to create the Rubik’s cube .

Using geometry.vertices to add cubes

Using geometry.vertices to add cubes

Large Cube

Segmenting the large cube with 2, 2, 2 (as shown in the image above)creates the coordinates of the Rubik’s cube

cubeGrid = new Cube(myMaterialsList1, mySize, mySize, mySize,2,2,2);

Placing small cubes at each vertex of the large cube is done using the geometry.vertices method.

Small Cubes

The geometry.vertices method gives you the position of each large cube vertex which is stored in the vertices array and accessed using the geometry.vertices method as shown below:

for(var i:int = 0; i<cubeGrid.geometry.vertices.length; i++)
{
var myPart:Cube = new Cube(materialArray[i], mySize/2.1,mySize/2.1,mySize/2.1,2,2,2);

myPart.x=cubeGrid.geometry.vertices[i].x;
myPart.y=cubeGrid.geometry.vertices[i].y;
myPart.z=cubeGrid.geometry.vertices[i].z;

particleArray.push(myPart);
myGraphicsHolder.addChild(myPart);
}

That’s really all there is to it, the only other thing you need to do is to set the faces of the small cubes to the appropriate Rubiks’s Cube colors using a materials list array (materialArray). Just click the more button below to see the complete code listing.

Note: This only sets the cube up. In the book, I show you how to program a fully functioning Rubik’s Cube.

Read the rest of this entry »


Follow

Get every new post delivered to your Inbox.