To this point, I’ve been putting Google Maps into Air applications due to the Flash Sandbox issue encountered in PV3D (discussed in a previous post). But in CS4, guess what, it’s not an issue. They go right on the web as you can see from the demo below:
Now here is how you do it, and it’s so simple you will not believe it. Use the code below to put your map into a movie where it’s free to move freely in 3D.
movie.addChild(map);
Placing a Google Map on a CS4 Plane is easier in Flex 4 (Gumbo) than it is in PV3D. All you do is throw your map into a movie clip using the code below, and then center it to get your map pivot right. The code snippet below sets your map in a movie clip, centers its pivot, sets map controls, places your movie in a Flex canvas, and centers your movie on the stage.
//Place your map in a movie so you can position its pivot
movie.addChild(map);
//Set your map pivot
map.x=-map.width/2;
map.y=-map.height/2;
//Put your movie in a Flex Canvas
mapHolder.rawChildren.addChild(movie);
//Center your Movie
movie.z=0;
movie.x=450;
movie.y=300;
The map also has two additional Flex components; a button, which stops it from spinning and a slider, which adjusts its speed and direction of rotation.
This is the great power of CS4 over PV3D. You can now bring native Flex components into your 3D environment in conjunction with your 3D objects. Bringing Flex components into PV3D is a difficult task and requires the use of the draw BitmapData feature. But with CS4 it occurs natively, and those components can be manipulated in 3D as well.
Hey that’s it, how crazy can that be! And all the controls and buttons are fully functional and in the right place.
Note: You could have just rotated the map directly, but you put it in a movie to control positioning and its pivot point.
The rest of the code is shown in the link below and discussed in greater detail in Chapter 7 of the book.
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.
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(0×00aa00);
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(0×00cc00);
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(0×00cc00);
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:
Carlos Ulloa, with his brainchild Papervision3D, released a cool looking sports car a while back and John Lindquist picked it up on his site and released the code. But what was not released was how to create such a car and export it as a controllable Collada file for use in PV3D. So, I built the Flintstones “Barney Rubble Car” below to illustrate the process.
In this post, we will show you how to create a controllable vehicle and more…
The video above walks you through the creation of the car. So I won’t go through that. We will start with once your Collada file is exported.
After Creating Your Barney Car
Just as you would put a model together, as you create the different parts in 3DSMax, you just place them together. The important part is that you give each one of them a name so you can control them with ActionScript. In this particular example the following naming convention was used:
CarBody-your “Barney Log” car body
FRWheel-your front right wheel which links to your steerFR (disk brake)
FLWheel-your front left wheel
steerFR-your front right disc brake which acts as the linkage container for your FRWheel
steerFL-your front left disc brake which acts as the linkage container for your FLWheel
RRWheel-your rear right wheel
RLWheel-your rear left wheel
So after creating and naming all the elements of your “Barney car” in 3DSMax (for example), export your car as a Collada file.
When you look at a Collada file for the first time you might be shocked. It looks somewhat horrific at first. But actually Collada files are very simple. They are organized into libraries. Each library typically contains some important aspect of 3D, such as lights, cameras, geometry, animation, physics, and so on…
In the case of the “Barney car” above, you’re interested in examining the visual_scenes library. Collada files can be opened in Dreamweaver or Flex. When examining the visual_scenes library nodes you’ll find all the elements created by our 3DSMAX.
These names are stored in appropriate variables and used to control your car. You’ll first investigate the steering mechanism.
Creating a Steering Mechanism
Key to creating a steering mechanism is using linking. The steering mechanism is created in 3DSMax by linking the front wheels to their corresponding disc brakes. Since the tires are children of the disc brakes, when the disc brakes are rotated the tires rotate with them. And when the car is moved forward all the tires rotate together in sequence.
Wheel Linkage
Putting this all together in the code below illustrates how the car’s wheels are maneuvered in PV3D. The steering code is surprisingly simple and consists of only two lines of code.
So as the steering parameter is changed the rotationY for your disc is changed, thus changing the angle of your wheel. Next you’ll learn to make your wheels roll.
Rolling Wheels and Moving Car
As the speed of you car is increased the wheel yaw is also increased making the wheels turn.
var roll :Number = speed*.4;
wheelFR.yaw( roll );
wheelFL.yaw( roll );
wheelRL.yaw( roll );
wheelRR.yaw( roll );
// Turn your car
car.yaw( speed * steer / 500 );
// Move car forward
car.moveLeft( speed )
Finally, the car itself is turned using the yaw command and moved forward (or backwards) using moveLeft, where the parameter in the move method is the distance to move in pixels. Now you might have been expecting moveForward to be used, and in other cases it is. It just depends on your geometry of how your car was created in 3DSMax, and in this case moveLeft actually took you forward.
To see all the car code click below or download the source above.
Single and Multiple Objects with Simple Images are obviously the simplest of all the scenarios in PV3D. In the example above of the moon orbiting the earth, 3DSMax is used to do the modeling. But the procedure presented in this post is similar for other modeling software packages as well.
This is how you do it!
An object is created by a modeling program, such as 3DSMax, and a simple image is placed on that object. In 3DSMax this is done using the material editor. Each material and object is given a name so that it can be controlled by the PV3D program once the Collada file, created by your modeling program, is imported into PV3D.
Once the Collada file is exported from 3DSMax and brought into PV3D, the created objects can be easily manipulated by referring to the object names contained in the exported Collada file. If you forget what you called them during the modeling process, these names can be viewed by opening the Collada file in an editor such as Dreamweaver or Flex and navigating to the geometries library and geometry tags.
Manipulating objects in a Collada file using AS3 is key to creating dynamic game content and use this procedure often. Importing a Collada file into PV3D is an easy 3 step process:
Importing Collada files into PV3D
Step 1: Import the Collada parser
import org.papervision3d.objects.parsers.Collada;
Step 2: Declare collada var and datatype it to Collada
private var collada:Collada;
Step 3: Instantiate the Collada class and fill in the appropriate parameters
collada = new Collada(“MoonEarth.DAE”,null,.1);
In this case, the material parameter of the Collada parser is set to null since the material is imported from the reference inside of the Collada file, found in the images library, as shown below.
OK, after the last post on MD2, if I don’t show you how to create your own MD2 models I haven’t done my job…so let’s do it!
Making your own Quake 2 (MD2) models is a must if you are going to be successful. The process described here will work for both 3DSMax and Maya, but there are similar procedures for other modeling applications. There is both good and bad news here.
So we will not repeat all that info, but just create a very simple model to demonstrate the process. Import to the process is to make sure you hit the 7 key to keep those polygons down as you build.
Watch Your Polygons
Step 2: Texture and Export Your Model
It’s actually simpler to put a texture on a model in Blender. So here’s an outline of how it’s done in 3DSMax (make sure you watch the video below as well)
After creating your model in 3DS Max, add the Unwrap UVW modifier
After selecting your model, select Face from the Unwrap UVW modifier
From the parameters menu (of Unwrap UVW modifier) select Edit
From the UVWs menu (pop up) select mapping and select flatten mapping and click OK (presets should be fine)
You should now be able to see the different sections of your house, then click on tools and select Render UVW Template
In the Render UVs popup change the dimension appropriately (for mitmapped textures 256 or below you get hardware acceleration, but you give up resolution – so it’s a trade off – just use resolution when you need it)
Then from the Mode drop down menu choose solid and then click Render UV Template
Your Render Map should pop up, click on the disk icon to save this map to your hardrive for editing in Photoshop, Gimp, or your favorite image editor (defaults should be OK when saving image to hardrive)
After editing your texture map and saving it (in this instance I saved it as a png since that format works well in Flex), from the Edit UVWs popup choose Pick Texture from the UV drop down box and the Material/Map Browser popup will appear.
From the Material/Map Browser select Bitmap and navigate to and select your image. Your image should appear in the Edit UVWs window overlay (as in Blender use this window to edit your image position).
Now place your texture on your house by hitting the m-key, select the first sphere, click the button next to the diffuse label. And your Material/Map Browser will popup, choose bitmap and navigate to and select your image. That image will now appear on your sphere.
Drag the image from the sphere to your house. Click the “Show Standard Map in Viewport” button to see the uv map on your house (or do a quick render to see it).
Click the export button from the file menu and choose the 3D Studio (*.3DS) format , name your file, and click save
Choose Preserve MAX’s Texture Coordinates and Click OK.
Step 3: Prepare Your Model in MilkShape
You can download MilkShape 3D and a MD2 Viewer from
The steps for creating a MD2 model for PV3D starting with 3DSMax (or Maya) are as follows:
After creating your model in 3DSMax (or Maya)
Export it as a 3ds file (fdx file)
Import this file into MilkShape by choosing Autodesk 3DS… (or Maya)
Click the model tab, then the joint button and insert a joint by clicking on a vertex of your model
Select all vertices (control a)
Go to the joints tab and click assign
Check to make sure animation is correct (single frame for no animation)
Export as an MD2 file (ignore the no md3.qc warning not loading into quake)
Check it out using the MD2 model viewer found on the MilkShape site or the PV3D viewer provided on the book’s website.
Step 4: Export to PV3D Model Viewer
After exporting to the MD2 format, change the markers XML data to include the pertinent resources, and upload those resources (xml data, MD2, image, and zip file) to your server. In an upcoming chapter, we will show you how to create an Air viewer.
we demonstrated a Papervision3D Viewer. You’ll now load that viewer with the model you created previously.
You made it! Lots of steps, but the process is pretty fast. I can get through it in about 30 minutes, but my designers take a couple of hours. Of course, that’s why their designs rock!!!
One of the things which I abhor about modeling in Papervision3D is texture baking. And if you’ve been in the business as long as I have you know why…it’s a labor intensive nightmare…and you can’t ever get it right. But with pixel bender you don’t have to bake your textures anymore and you can adjust your parameters dynamically using ActionScript.
To create a dynamic light baker filter the simple light filter was modified by throwing out all the pow and exponent methods. The big trick is that exponential behavior can be mimicked by using inverse of distance –now that’s a processor saver. The final algorithm use is shown below:
lively3d Light Source for Texture Baking
The pixel bender algorithm is easily implemented using the code below:
In addition to the modification mentioned above the alpha component is split off and set to one. This keeps the images from losing its alpha as you reduce brightness.
Step 2: Next you must create a Pixel Bender Bitmap File Material Class. This is simply done by making a copy of PV3D’s BitmapFileMaterial class and renaming it BitmapBendMaterial class and after changing the constructor and class names extend this class by the BitmapPixelMaterial class.
BitmapBendMaterial extends BitmapPixelMaterial
You’ll now create the BitmapPixelMaterial class.
Step 3: Make a copy of the PV3D BitmapMaterial class and name it BitmapPixelMaterial. Add the appropriate import statements and the pbj and image embed methods and create a shader as shown below:
[Embed (source="filters/livelyLight.pbj",
mimeType="application/octet-stream")]
private var ShaderClass:Class;
[Embed (source="assets/images/gainesHouse512.jpg")]
private var myImage:Class;
private var shader:Shader
Next incorporate the code to get your shader and image working together:
Our group just finished the first part of the Beverly Hills Supper Club project. I realize that this is a sensitive area and lives were lost. The completed site will be a memorial to those loved ones that were lost in this tragic fire.
Here I demonstrated playing the Supper Club fire video on the Blender building skin. To see the demo just click the image below (drag the building with the mouse to rotate it and click the play video button to get the video to play):
Another trick is handling rotations correctly. To do this you need to use subtraction of your previous position from you present position (since you are appending rotation in this example). So if you are rotating forward the difference is positive and if backwards the difference is negative.
private function boardMove(e:MouseEvent):void {
var locX:Number=prevX;
var locY:Number=prevY;
if(doRotate){
prevX=spBoard.mouseX;
prevY=spBoard.mouseY;
rotateObj(prevY-locY,-(prevX-locX),0);
e.updateAfterEvent();
}
Once you “get this in your head” you’ll undertstand “append” rotation in CS4 – otherwise it’s uncontrollably wild.
Now there’s on more “Super trick”. This application was originally created for an Adobe Air and was run on the desktop. So when you put it on the web the video will not work since it uses
But this time we don’t have indices and uv data … shouldn’t we just give up or get some expert to tell us what to do…nah, just replace indices and uv data with null and it works…please don’t ask me why. Remember, I said this was a trick.
The full project will allow site visitors to leave messages in supper club rooms…building a flexpress flat-file data base to handle these messages is part of the TEI project… The advantage of the flat-file data base is that you can drop the program onto any server – hassle free and it works – no fancy install!
To see the entire code click the more button below:
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!
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 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).
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.
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
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:
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.
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)
//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).
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:
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.
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:
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: