Flex 4 (Gumbo) Image Ball – Ouchies!

March 12, 2009

Intro

Flash & Math had created a really cool image ball in Flash, but I needed it in Flex 4 (Gumbo) for a project. So I ported it over. The port was non-trivial so I’ve included it here with its source code. The big thing about having it in Flex (MXML & ActionScript) is that I can now drag the Flex components in and use them to harness data. Click the image below to see the demo.

Flex 4 (Gumbo) Image Ball

Flex 4 (Gumbo) Image Ball

Demo

Code (MXML Flex File Only Images too Large and some Copyrighted)

Discussion

Here are the highlights which got me stuck on the port (got an “Ouchie” from each one) .

Note: the code from Flash & Math is thoroughly documented so make sure you download and go through it to follow along).

Ouchie 1: Not so much of an ouchie if you know this one already (and I did), but you can’t use addChild to add a sprite directly to the stage of a Flex MXML project. So create a canvas and add your sprite to that canvas using rawChildren.

cs4Canvas.rawChildren.addChild(board);

You can even use mutliple canvas components (or other containers) – and I did.

Ouchie 2: Flash & Math pulls their thumb nail image assets from the Flash library using linkage. You can’t do that in Flex, so use the embed tag for the thumb nails (all 46 of them – ouchie, ouchie, ouch).

[Embed(source="thumbs/pic1.jpg")]
private var Small1:Class;

But now the setUpPics() method won’t work, so use the BitmapAsset class in your thumbnail array.

thumbsArray[0]=[new Small1() as BitmapAsset];

And place your embed class in for their movie class.

Ouchie 3: Rewrite the Vector array declarations using a push method to load the vector arrays-their method of loading these arrays doesn’t work in Flex (and figuring that one out was a big ouchie).

thetaStep.push(0,60,36,30,36,60,0);
jLen.push(1,6,10,12,10,6,1);
phiTilt.push(-90,-60,-30,0,30,60,90)

But fortunately, it’s really easy to implement.

Ouchie 4: Just as with a formal class structure, you must make sure that your variables have the private statement in front of them, and that all declarations are contained in a function (within your script tags). In addition, you must create an init() method and call it from your MXML tags (this acts like a constructor function).

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; creationComplete=”init()” layout=”absolute”>

Ouchie 5: I added image forward and backwards buttons to the program so once the user double clicks a thumbnail image, he/she can surf the images without going back and forth between image and image thumbnails (this is a big improvement to the code).

This required that I write a small string routine that extracted the numbers from the image name so I could start at that image and go sequentially

var myStringIs:String = picsArray[i][j];
myStringIs=myStringIs.split(“.”).join();
myStringIs=myStringIs.split(“c”).join();
splitArray=myStringIs.split(“,”);
stringNumIs=Number(splitArray[1].toString());

The move forward and backward code for the buttons is given by

private function moveForward(e:MouseEvent):void {
stringNumIs++;
stringNumIs=stringNumIs%47;
if(stringNumIs==0)stringNumIs=1;
loader.load(new URLRequest(“images/pic”+stringNumIs+”.jpg”));
}

private function moveBackwards(e:MouseEvent):void {
stringNumIs–;
if(stringNumIs==0)stringNumIs=46;
loader.load(new URLRequest(“images/pic”+stringNumIs+”.jpg”));
}

This small routine could definitely be improved upon…but it does the job..

Big Problem
Of course the big problem here is that your images have to be sequentially numbered, that’s a big ouchie, and is unacceptable for future projects: I need descriptive names. I can’t remember which image is which, nor can you…

But my timeframe was so short on this project (of which this was a small piece) that I just had to live with it. But a little recoding is needed here to fix this problem…I would treat it as a particle system.

Conclusion
So the port was a little bit “hurtie…ouch, ouch, ouch.”. It took me about 4 hours to complete, but once completed, it worked great and integrated smoothly into the rest of my application.

Hope this saves you some time…or a few ouchies…

Click the more button below to see all the code and a short tutorial on substrings from flepstudio.

Read the rest of this entry »


Putting Video on a CS4 (Flash 10) Primitive

March 10, 2009

Intro

Get ready to eliminate 1000′s of lines of Papervision3D code. That’s right! By using CS4 you no longer need the Movie Material class, the DisplayObject3D class, the Video Stream Material class, and a plethora of Triangle/UV parsing and math classes. It’s just amazing…in CS4 it’s so simple!

Video on a CS4 Primitive

Video on a CS4 Primitive

Demo

Source

YouTube


Discussion

Note: This discussion uses the code and results of two previous posts:

Adding Video to a Papervision3D Curved Plane

CS4 Super Primitive using Matrix3D

Placing video on the CS4 Super Prim developed in Chapter 3 of the book is very easy and only requires four steps.

  • Step 1: Import the net and media classes in to the Super Prim Class (see the post on CS4 Super Primitive using Matrix3D – this is your starter code)
  • Step 2: Declare the video, net Connection, and net Stream variables.

//net stream assets
private var myConnection : NetConnection;
private var myStream : NetStream;
private var myVideo : Video;

  • Step 3: Incorporate the loadMyVideo() method discussed in the previous post on Adding Video to a Papervision3D Curved Plane
  • Step 4: Create a bitmapData object and in the animation loop draw your video to that bitmapData object and attach the net stream to your video, as shown below:

//Draw Video into Bitmap
bitmapData.draw( this.myVideo);
this.myVideo.attachNetStream ( this.myStream );

The results yield a video being played among the various prims contained in the super prim. At this point you change the video by changing the file name inside your net Stream method (myStream.play(“assets/eternity.flv”)), but the constructor function could be easily changed to receive a video string locater.

A Little Extra

Also in Chapter 4 of the book, we show you how to put your webcam video on a prim. Below is a shot of my Guinea Pig Don Pedro who jumped into the screen to get his web cam video on a sphere.

Pig on a WebCam

Pig on a Web Cam

The code for this is included in the download above. But the explanation is in the book. To see the entire code download the source from the link above, or click the more button below:

Read the rest of this entry »


CS4 Google Maps Project – a money maker!

March 8, 2009

Intro

It seems like most sites like mine give you basic examples of how to do things but never take you to the next level – the level that makes money. This project, though not complete, closed the deal on a contract and is great starter code for any one doing Google maps.

It ‘s an air project, and the code is a little disorganized due to the short time frame. Basically, I had written the same project in Papervision3D but my buttons were off, but in CS4 everything is right on. So in about four hours I transferred this project from Papervision3D to CS4.

Code was flying everywhere and by the end of it I had to spray my keyboard down with liquid nitrogen … it was smok’n red hot …

The contract crew walked into the meeting with a good working prototype, where others were not even close, and guess what … they got funded … and that’s the way to do it. Give your clients something that works (a few bells and whistles) … not just a design … and you’ll win every time (unless the other contractor is the boss’s brother – it happens.).

Landmark Covington

Landmark Covington Air Project

The original Papervision3D code was Wii controlled and I left the Wii code inside the project just in case I needed to reactivate it. Check out my Wii Post to learn how to create a Wii controlled project.

Source 200+ Megs

YouTube

Discussion

Here are the highlights of its development.

1. Use of Flex custom mxml components and Cairngorm to control pop-ups with images and audio

Flex Popup Component

Flex Popup Component

2. removedFromStage trick to close audio after clicking the close button of the maps pop up (same component can be used for video pop-ups as well).

MXML

<mx:Canvas xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; width=”482″ height=”222″ creationComplete=”MyImageBox()” removedFromStage=”leaveStage()” horizontalScrollPolicy=”off” verticalScrollPolicy=”off” fontSize=”12″ backgroundColor=”#FFFFFF” alpha=”1.0″ backgroundAlpha=”0.0″>

ActionScript

private function leaveStage():void{

if(soundChannel){

soundChannel.stop();

SoundBtn.label=”Play Audio”;

}}

3. Primitive swapping using remove and add child

//movieParent.
movieParent.removeChildAt(0);
movieParent.addChild(tunnel);

4. Location navigation using a Combo Box including animated map directions

Navigation Menu

Navigation Menu

5. Application.application.map trick to add Google Maps to Flex

movie.addChild(Application.application.map);

Map in 3D

Map in 3D

6. XML data file to hold pop-up info including audio location.

XML for Marker Pop-up Box

XML for Marker Pop-up Box

I could spend 1 week going through every detail, but the stuff above was the stuff I had to think about! Hope it helps…

Sorry about the messiness of the code. Like I said, it was pretty short order. Once the project was completed, I didn’t have time to rework it. But if you’re working on a project like this one…this code will be very helpful to you. The real key to making this thing work was creating custom Flex components and using Cairngorm to talk to them. Google maps pops them up, and you can put anything in them: audio, video, or 3D.

I’m off to the next job. This coming week one of my programs is being presented in Austria (I haven’t written it yet…of course). But my graphic designers have been working like crazy building the assets for it.

I write about 5000 “working” lines of code a week now (that’s about two projects a day)…but that’s because my code base is growing. The more code I have, the more I can write…that’s right…this number includes cutting and pasting code from one project to another.

Once the Austria project is completed, I’ll post it so you can see how these larger (money making) projects go. Have a great week…


Plotting Equations in 3D – NKU Sem#5 (Links)

March 3, 2009

Plotting in 3D using Papervision3D and CS4.

Seminar #5

Here’s the class links for Plotting Equations in 3D: a free public seminar at NKU.

If you’re an educator or student get Adobe Flex for free at:

http://www.adobe.com/devnet/edu/

A. Resources: Flash & Math (Present Resources)
http://mathdl.maa.org/mathDL/3/?pa=content&sa=viewDocument&nodeId=1598&bodyId=1711

1. Parametric Surfaces in Rectangular Coordinates
2. Parametric Surfaces in Cylindrical Coordinates
3. Parametric Surfaces in Spherical Coordinates
4. Graphing Functions of Two Variables
5. Graphing Functions of Two Variables

B. Flash & Math (Barbara Kaskosz & Doug Ensley)

http://www.flashandmath.com (their book site)

Contour and 3D combined
http://www.flashandmath.com/advanced/contours/index.html

Implicit Plotter
http://www.flashandmath.com/intermediate/implicit/index.html

Simple Graph
http://www.flashandmath.com/basic/simplegraph/index.html

C. How Plotting in 3D is done in Flash
http://www.professionalpapervision.wordpress.com (my book site)

Flash 3D
http://professionalpapervision.wordpress.com/2008/12/11/building-a-3d-flash-engine-in-19-lines-of-code/

Flash & Math (how far can you go)
http://www.flashandmath.com/flashcs4/cs4simple3d/icosa.html

Not to be out done!
http://professionalpapervision.wordpress.com/2009/03/01/cs4-flat-shaded-tie-fighter-drawtriangles/

Note: 2D curves are created by connecting straight lines.

D. Plots in Papervision3D and CS4

Straight lines CS4
http://www.professionalpapervision.com/demos/web/lines3dcs4/

Curves in Papervision3D (straight lines pieced together)
http://www.professionalpapervision.com/demos/web/pendulum/FoucaultPend.html

Molecules
http://professionalpapervision.wordpress.com/2009/02/24/cs4-gumbo-molfile-molecule-viewer-sem4/

Particle Systems

Example 1 low number physics
http://professionalpapervision.wordpress.com/2008/11/21/real-orbiting-3d-particles-taking-out-the-trash/

Example 2 high number – billboarding physics
http://professionalpapervision.wordpress.com/2008/11/02/trilogic-particle-billboarding-flash-source/

Example 3 CS4 Particles
http://professionalpapervision.wordpress.com/2009/01/11/cs4-creating-a-parametric-particle-field/

E. Using the Geometry Trick (Papervision3D

Making Water (Exey Pantelee’s Blog)
http://exey.ru/blog/home/fluid-simulation-pv3d-and-away3d

objectName.geometry.vertices[i].x, y, or z

Sinc Function
http://www.nkuflc.org/sincplot

YouTube:

http://www.youtube.com/watch?v=YlFLT9YA44

Rubrics Cube
http://professionalpapervision.wordpress.com/2008/12/31/setting-up-a-rubiks-cube-in-papevision/

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);
}

F. Parsing – in just 1900 lines of code???
You’ve got to be kidding me – click the more button below to see the code.

G. Where we are going! (3D Plotting Calculator Style)
Bring down the parser to 300 lines…maintainability vs. user experience. Move to IPhone.

Read the rest of this entry »


CS4 Flat Shaded Tie Fighter with drawTriangles

March 1, 2009

Intro

Here’s a CS4 Flat Shaded Tie Fighter. I built the tie fighter in Blender, and used drawTriangles to render the model in CS4. The shaders come directly form Ralph Hauwert’s fast light maps … thanks Ralph. Here I only treat flat shading, but in the book (and its website). I treat the rest of them: cell, gouraud, phong, and envmap.

Since I’ve treated bringing Blender and 3DSMax models into CS4 ad nauseum, I won’t belabor the point. This program culls, has its own light class with brightness (here it alternates in brightness), depth sorts, and displays concavity with no problems.

The perlin noise clouds came from flepstudio … thanks flepstudio!

CS4 Flat Shaded Teifighter drawTriangles

CS4 Flat Shaded Tiefighter using drawTriangles

Source

Demo

YouTube

Discussion

Here’s a brief explanation of flat shading in CS4.

The light class is a point light with brightness (contained in the org/lively3d/lights/ folder of your download). It gives you the position of your light source, brightness, light color, ambient color, and specular level.

Here’s the Hack

The lightColor variable is the color of your light source. The ambientColor variable is not true ambient light. It’s the first and second parameter in a gradient fill (the third one is your light color), and it governs the color that your object will take on. The specularLevel variable adjusts the number of shades between your middle ambient color and light color. And gives the appearance of making your surface shiny at low numbers-hey, it’s a great hack!

Here’s how the gradient fill works:

The beginGradientFill method has several parameters but only the ones used here are listed below: type, color, alphas, ratios, and matrix.
beginGradientFill(type, colors, alphas, ratios, matrix)

They do the following:

  • type-specifies which gradient type to use: linear or radial
  • colors-an array of color values used in the gradient
  • alphas-an array of alpha values corresponding to the colors
  • ratios-defines the percentage of the width where the color is sampled at 100%.
  • matrix- a transformation matrix which controls scale, skewing, and location of your gradient appearance.

Here’s how the light map is implemented:

A bitmapdata object is created named tempmap which is just a simple strip 255 pixels long and 1 pixel wide, the gradient is calculated using the ambient and light colors, and the gradient is drawn into the tempmap and returned.

The process described above is demonstrated in the code below, which comes from Ralph Hauwert’s LightMaps class and is used to create the light maps for flat, cell, phong, and gouraud.

var tempmap:BitmapData = new BitmapData(255,1,false,0);
var s:Sprite = new Sprite();
var m:Matrix = new Matrix();
m.createGradientBox(255,1,0,0,0);
s.graphics.beginGradientFill(GradientType.LINEAR, [ambientColor,ambientColor,lightColor],[1,1,1],[0,255-specularLevel,255],m);
s.graphics.drawRect(0,0,255,1);
s.graphics.endFill();
tempmap.draw(s);
return tempmap;
Now that you understand how a simple light map is created the steps to creating a flat shade are easy:

Step 1: Create your light map

_colors = LightMaps.getFlatMapArray(lightColor, ambientColor, specularLevel );

Step 2: Return a cosine (zd) from the dot product of your light vector with your triangle normal vector. This gives the cosine of the angle of your triangle face normal to your light source. If your light source is at 90 degrees to your object triangle (no light hitting it) then the cosine value (zd) is zero. If your triangle is directly facing the light source then your cosine is 1 (completely lit).

AVect[0]=new Vector3D(dispVec[facesVec[curFace][0]].x,dispVec[facesVec[curFace][0]].y,dispVec[facesVec[curFace][0]].z);
AVect[1]=new Vector3D(dispVec[facesVec[curFace][1]].x,dispVec[facesVec[curFace][1]].y,dispVec[facesVec[curFace][1]].z);
AVect[2]=new Vector3D(dispVec[facesVec[curFace][2]].x,dispVec[facesVec[curFace][2]].y,dispVec[facesVec[curFace][2]].z);

AVect[3]= AVect[0].subtract(AVect[1]);
AVect[4]= AVect[1].subtract(AVect[2]);

AVect[5]=AVect[4].crossProduct(AVect[3]);
AVect[6]=new Vector3D(light.x, light.y, light.z);

var mag1:Number=AVect[5].length;
var mag2:Number=AVect[6].length;

var zd:Number = AVect[6].dotProduct(AVect[5])/(mag1*mag2);

In CS4, you totally eliminate Papervision’s Numbers class since all the calculations provided by that class are now internal to CS4.

So for example a dot product of two matrices in CS4 is given by

var zd:Number = AVect[6].dotProduct(AVect[5])/(mag1*mag2);

Step 3: Calculate the index value from your zd by multiplying it by 255 (hex 0xff) and grab the respective color from your “_colors” array. Essentially as your triangle turns away from your light source the hex value is reduced: effectively darkening your pixels.

zAngle = zd*0xff; //0xff if hex for 255
currentColor = _colors[zAngle];

Step 4: Render your triangle and fill it with your calculated light map color.

spObjImage.graphics.beginFill(currentColor);
spObjImage.graphics.drawTriangles(vertices);

The code above uses drawTriangles exclusively, where PV3D draws individual lines. The big advantage here is that you can make the triangles blow up – can’t wait to show you that!!! And theoretically, it should be faster than PV3D.

Figure 4-4 The Four Steps to Flat Shading

Figure 4-4 The Four Steps to Flat Shading

This probably seems like a lot to absorb, but the good news is that the rest of the shaders follow pretty much of the same process (with the addition of a few matrix methods).

To see the complete code download the source above or click on the more button below:

Read the rest of this entry »


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 »


Creating a Blender Heart NKU Seminar #2

February 9, 2009

Into

This is the second in a series of Papervision3D/CS4 seminars held at NKU which are offered free to the public.

Human Organ Modeling using Blender (February 10):
Create organs using 3D modeling software and learn how to place the models on the web for a truly interactive learning experience.

A Blender Heart

A Blender Heart

Demo

Source

Posted here are the seminar notes, resources, demos, and videos.

Seminar Videos

video 1: http://www.youtube.com/watch?v=ygUCu89sQpw
video 2: http://www.youtube.com/watch?v=sUifORl-faI
video 3: http://www.youtube.com/watch?v=LrkT6BP6SLU
video 4: http://www.youtube.com/watch?v=xlSfyKzOg2M
video 5: http://www.youtube.com/watch?v=AP79nd5XEtQ
video 6: http://www.youtube.com/watch?v=vbHSg1Zffr8
video 7: http://www.y outube.com/watch?v=8fnXbDvRzY4
video 8: http://www.youtube.com/watch?v=qsyFnIDjYJM
video 9: http://www.youtube.com/watch?v=8H7U4t-iASM
video 10: http://www.youtube.com/watch?v=21E_aHuLDR4
video 11:
video 12:

Seminar Modeling Exercises

A. Getting Started

1. Open up house.blend (from the blenderExamples folder) and practice the Mac or Window commands
2. Open up the vein.blend (from the blenderExamples folder) and practice making your own veins (use combo for curved veins), practice dividing and smoothing and pulling off veins

B. Using Reference Images

3. Download Jing, examine reference images and body slices (see links above)
4. Split screen and load front circulation image on right side (from referenceimages folder), top body slice image 1 on left side (from body slices folder) and adjust image
5. View nucleusinc heart video (see link above), and model three primary arteries, use hide elements (use heartcircle.blend starter file)
6. Combine veins and arteries (use a plane reference) to be attached to the heart (start with heartsvcpaarota.blend file)

C. Changing Reference Images

7. Load heart reference image on right side (from referenceimages folder image 1), and body slice image 4, 3, 2 from (from body slices folder) as your model, use hide elements
8. Connect veins to heart, subdivide and smooth (see heartveins.blend, heartveinsSmooth.blend in blenderExamples folder)

D. Texturing Your Heart

9. Demonstrate editing vertices, dividing surfaces, and smoothing .
10. Demonstrate marking seam and unfolding.
11. Demonstrate coloring in gimp & image import/texturizing into photoshop

E. Placing Your Heart on the Web (it’s safer than e-harmony)

12. 11. Load into Papervision3D or CS4 (don’t forget to triangulate), use XML exporter, and place on the web.

Resources: Links (all software listed is free)

Circulatory System:
http://www.rachel-rose.net/bodywork/AP/selftestanswers/Circulation.JPG

Blender Images:

http://www.turbosquid.com/3d-models/3d-heart-opened-closed/428196

Video Example:

http://catalog.nucleusinc.com/

http://catalog.nucleusinc.com/generateexhibit.php?ID=17473&ExhibitKeywordsRaw=&TL=&A=2

Human Medical Slices:
http://vhp.med.umich.edu/browsers/female.html

Image Grabbing Software: Jing from Techsmith
http://www.jingproject.com/

Image Processing Software: Gimp

http://www.gimp.org/

Free 3D modeling Software: Blender (Papermax under Development)

http://www.blender.org/

Free Blender Wiki-book

http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro

Blender XML Exporter

http://flex3cookbook2.googlecode.com/files/exporter-primitive.zip

XML Exporter Blog Post

http://professionalpapervision.wordpress.com/2008/12/09/new-blender-xml-exporterpv3d-xml-primitive/

Papervision3D Download

http://code.google.com/p/papervision3d/downloads/lis

Blender Keyboard Shortcuts

Windows:

Modeling Building
Split Screen: roll over seam, right click, choose split area, click on stage
Background Image: click view and select Background image (view front/top)
x – erase selected item
space bar – add mesh
tab – edit model (dots icons vertices, lines edges, triangle faces)
a – select all/deselect toggle
b – marquee select
b twice – circle rollover select
right click – select
right click+shift – add to selected/toggle
e – extrude
esc – to escape an operation
ctrl-z undo
ctrl-y redo
ctrl+space bar – choose combo edit mechanism/toggle
g – grab
r – rotate (x, y, z to restrict to axis)
s – size (x, y, z to restrict to axis)
f-complete face
space bar +select+edge loop – grab loop
w-merge
h-hide selected
shift+h – hide everything but selected
alt+h – make everything visible
right click object – to select object
m and select layer – to place an object on a different layer

Navigation (touch pad)
ctrl+alt+LMB+mouse slide – zoom
alt+LMB+mouse slide – rotate scene
shift+alt+LMB+mouse slide – pan screen

Navigation (mouse)

roll middle mouse button – zoom
hold middle mouse roller down drag – rotate scene
shift+ hold middle mouse roller down drag – pan

Texturing
ctrl+e mark seam
u – unwrap (must be in UV face select mode)
window type – UV image editor
UVs, Scripts, Save UV Face Layout
Image, Open
Viewport shading, textured
File, Export, XML Exporter
ctrl+t – triangulat

Mac: (typically for Mac the command key is used in place of the right click windows)

Model building
Split Screen: roll over seam, command click, choose split area, click on stage
Background Image: click view and select Background image (view front/top)
x – erase selected item
space bar – add mesh
tab – edit model (dots icons vertices, lines edges, triangle faces)
a – select all/deselect toggle
b – marquee select
b twice – circle rollover select
command click – select
command+shift – add to selected/toggle
e – extrude
esc – to escape an operation
ctrl-z undo
ctrl-y redo
ctrl+space bar – choose combo edit mechanism/toggle
g – grab
r – rotate (x, y, z to restrict to axis)
s – size (x, y, z to restrict to axis)
f-complete face
space bar+select+edge loop – grab loop
w-merge
h-hide selected
shift+h – hide everything but selected
alt+h – make everything visible
command click object – to select object
m and select layer – to place an object on a different layer

Navigation (touch pad)
ctrl+alt+click+mouse slide – zoom
alt+click+mouse slide – rotate scene
shift+alt+click+mouse slide – pan screen

Navigation (mouse)
roll middle mouse button – zoom
hold middle mouse roller down drag – rotate scene
shift+ hold middle mouse roller down drag – pan

Texturing
ctrl+e mark seam
u – unwrap (must be in UV face select mode)
window type – UV image editor
UVs, Scripts, Save UV Face Layout
Image, Open
Viewport shading, textured
File, Export, XML Exporter
ctrl+t – triangulate


New 3DSMax XML Exporter & PV3D XML Primitive

February 4, 2009

Intro

Well it happened again. We built an incredible 3DSMax model (actually 8 of them) to import into Papervision3D for a Google Maps project and we couldn’t get it to work using collada: collada worked in 7 (with a fix), kinda in 8, dead in 9…going going gone. That’s it….we’ve had it!

So as in the Blender case, we built an XML exporter for 3DSMax and Papervision3D XML primitive to suck up the data (We also built an importer for CS4 using drawTriangles). So sure it doesn’t import animation, and guess what…we don’t care! We’re doing all our animation in the Flash engine anyway. And in the book we show you how to build your own data driven animation engine using the Flash10 framework.

3DSMax XML Export

3DSMax XML Expo

YouTube

Demo

Source

Discussion

The exporter is basically a rewrite of the AS3 Geom Class Exporter written by Seraf aka Jerome Birembaut. But as opposed to exporting a class, it exports XML. The exporter is built in Max Script and is run typically as any Max Script is run.

To use the script:

1. In 3DS Max, tools tab, open the maxscript panel and click the “execute script” button.
2. Select the script. It is now displayed in the available scripts list.
3. Select it, a new “XML Exporter” appears.
4. Click the Export XML button.

To learn how to build the house in the demo above view the following Youtube links by Alex Green (one of my designers):

Part 1: http://youtube.com/watch?v=5rf0caQaol8

Part 2: http://youtube.com/watch?v=twZGqvQu3jc

Part 3: http://youtube.com/watch?v=KR7P3tRL72U

Part 4: http://youtube.com/watch?v=EoUzm_x2wP4

Part 5: http://youtube.com/watch?v=51zBUV8Fjn8

Part 6: http://youtube.com/watch?v=y4Fm0u-W88U

To see the 3DSMax Script and XML exporter code, click the more button below.

Read the rest of this entry »


CS4 Animated Shuttle – drawTriangles Blender Parser

January 28, 2009

Intro

There’s been a number of posts speculating whether 3D models could be brought into CS4. The problem has do with properly mapping uv coordinates to the appropriate vertex values. In this post, I’ll demonstrate the development of a very simple parser which allows you to bring Blender models into CS4. It uses the drawTriangles method, the Blender XML Exporter created in a previous post, and a one-to-one mapping scheme of vertex and uv data points.

I’m sure that as time progresses more advanced parsers will be developed, but for our present projects, this one works really well.

Animated Shuttle

Animated Shuttle

Demo

Source

YouTube

Discussion

To create a Blender parser using the drawTriangles method, you’ve got to get your mapping right. It must be one-to-one: each vertex must have one unique uv point. But in modeling software, such as Blender, that’s not true. You can have multiple uv points for one vertex point as shown in the image below

One 3D Point Becomes four in 2D

One 3D Point Becomes four in 2D

So, you can see the problem from the figure above. When you unfold a pyramid, uv mapping of 0ne 3D vertex point becomes four 2D points. In this case, the Blender data will give four uv data points for the apex of your pyramid above (point 4: 0,0,0 -> uv:points: 00, 01, 10, 11). But drawTriangles does not know what to do with this. It wants one uv point for each vertex. The way around this problem is to collect all similar uv data points per vertex and assign a new vertex number for non -unique points. So for example,

(point 4: 0,0,0 -> uv:points: 00, 01, 10, 11

becomes,

point 4: 0,0,0 -> 00
point 5: 0,0,0 -> 01
point 6: 0,0,0 -> 10
point 7: 0,0,0 -> 11

Importantly, points 0-3 are the four base pyramid points which are not unwrapped and as a result don’t need to be assigned new vertex numbers. The new vertex numbers have the same vertex coordinates as shown above – only the point assignment for the triangular fan is changed.

Note: The number of extra points you need to add is entirely dependent on how you unfold your object. If you use the hole punch method, you only need four extra vertices for an entire figure. As in anything, there’s no free lunch. You always give up something to gain something.

Code

The code sorts points into unique vertices and uv numbers (creating a 0ne-to-one mapping). If unique data can not be found new vertices are assigned creating a 0ne-to-one mapping as described in the post on the polar cube.

Blender XML Exporter

The whole process starts by creating a Blender XML file and photoshop image. This is done by using the Blender XML Exporter discussed in an earlier post.

The Blender XML file is imported into the program, parsed, and sorted. Then the sorter code below is used to create the one-to-one mapping scheme discussed above. Here are the steps:

1. The code starts by grabbing the index and vertex data created from the Blender XML export.

for (var i:int = 0; i< myFaceNum; i++) {

//Grab Indices from Blender XML
indices.push(int(mySplitFace[12*i]));
indices.push(int(mySplitFace[12*i+1]));
indices.push(int(mySplitFace[12*i+2]));

//Grab UV Data from Blender XML
myUVDatArray.push(Number(mySplitFace[12*i+3]));
myUVDatArray.push(Number(1-mySplitFace[12*i+4]));

myUVDatArray.push(Number(mySplitFace[12*i+5]));
myUVDatArray.push(Number(1-mySplitFace[12*i+6]));

myUVDatArray.push(Number(mySplitFace[12*i+7]));
myUVDatArray.push(Number(1-mySplitFace[12*i+8]));
}

2. The raw data above is sorted and a one-to-one mapping scheme created.

//Ferts Sorting Program
myFertsNum=indices.length;
myVertsNum=verts.length/3-1;//iteration number

for (var j:int = 0; j< myFertsNum; j++) {
for (var k:int = j+1; k<myFertsNum; k++) {
if (indices[j]==indices[k]) {
if ( (myUVDatArray[2*j]==myUVDatArray[2*k]) && (myUVDatArray[2*j+1]==myUVDatArray[2*k+1]) ) {
} else { verts.push(verts[3*indices[k]],verts[3*indices[k]+1],verts[3*indices[k]+2])
myVertsNum++;
indices[k]=myVertsNum; }}}}

3. And the uvtData is extracted.

//Sort uvtData (verts match uvtData-the golden rule for drawTriangles)
for (var m:int = 0; m<verts.length/3; m++) {
for (var n:int = 0; n<indices.length; n++) {
if (indices[n]==m) {
uvtData.push(myUVDatArray[2*n], myUVDatArray[2*n+1], 0);
break; }}}

Important Note!!!

The resulting parser works really well for convex structures, but has difficulty with concave objects. Due to sorting issues.

Both Flash & Math and Dorking Around 3D in Flash (and in one of my previous post) have suggested individual triangle sorting routines, and Dorking Around 3D in Flash has a working textured convex example using triangle sorting. Further testing and development needs to be done in this area: Individual triangle sorting may handle concave figures without a problem, but at present they do not use the drawTriangles method or an XML importer from Blender, as presented in this post.

Encapsulation

The code is fully encapsulated and closely resembles Papervision3D. A primitive is declared and an animation loop created inside a wrapper file (just as in Papervision3D).

blenderHouse = new BlenderPrim(“assets/data/shuttle.xml”, bmp, 300.0, 300.0, 10);

The parameters of the constructor function above are xml, bitmap, width and height. And the Blender Primitive lives in tbe org/lively3d/objects/primitives folder. This is the same as Papervision3D’s primitive path except for the lively3d part which is used to distinguish the different approaches.

Click the more button below to view the wrapper and Blender Primitive classes.

Read the rest of this entry »


Follow

Get every new post delivered to your Inbox.