Articles Archive
Articles Search
Director Wiki
 

Wreaking Havok with Physics, Part 1

August 16, 2001
by Darrel Plant

A question on one of the Flash lists the other day got the little grey cells to thinking about a project. I didn't have any particular use for this project, nor was I likely to in the future, but still it seemed a fun thing to investigate.

The question concerned creating a molecule viewer in Flash that would let you view the atoms and links in 3D. An organization named the Research Collaboratory for Structural Bioinformatics (RCSB) has developed something called the Protein Data Bank (PDB) which is, in their words: "the single worldwide repository for the processing and distribution of 3-D biological macromolecular structure data."

The PDB contains many thousands of molecule descriptions in a text file format also known as PDB. This is a portion of a PDB file:

   ...
   ATOM     14  H           1       2.491   0.574   0.546
   ATOM     15  H           1      -2.299   1.616   1.538
   ATOM     16  H           1      -2.069  -1.381  -1.314
   TER   
   CONECT    1    2    6   12    0
   CONECT    2    1    3   15    0
   CONECT    3    2    4   11    0
   ...

This portion of the file bridges the section describing the 3D coordinates for the last three of the 16 atoms in the molecule (all hydrogen molecules) and the connections to the first three atoms (atom 1 is connected to atoms 2, 6, and 12).

There are already good viewers available for PDB files. If you've taken a chemistry course within the past few years, you're probably already familiar with Chime (a PDB viewer Netscape plugin) and RasMol (an open-source standalone application for Unix, Windows, and MacOS). The original question had cited a British Director developer's Shockwave movie that displayed PDBs. So as I learned about the PDB format, I didn't particularly feel the need to build my own viewer.

What I wanted to do was have some fun.

Playing With Your Molecules

Mothers always tell you not to play with your food. They never warn you about splitting atoms, though. I always regretted never getting certified at college to run the little nuclear reactor they had on campus. I'd have to satisfy my atomic urges in some other way.

As I was looking at the structures of various proteins with RasMol, I thought: "I wonder how they'd bounce?" That's right, bounce. Wouldn't it be cool if you could drop the molecule on the floor, fling it against a wall or twirl it around? What if you could add a little physics into the mix?

So I set out to show how, if you were so inclined, you could make a 3D molecule viewer that lets you get your hands on those dirty little atoms. Click here to see the final piece. To get to this movie, I started off by looking at the Springs and Things demo in the Technical Demos section of the Havok Xtra Developer site.

Building the Box

First off, insert an empty Shockwave 3D cast member into a movie and place it on the Stage. Then create a loop script so that the sprite can play uninterrupted.

The movie's Create Scene behavior sets up the scene. This behavior will be applied to the 3D world sprite. If we want to be able to fling the molecule around with impunity, we need more than a floor. We want a box with sides and a top:

on beginSprite me

  s = sprite (me.spriteNum).member

  s.resetWorld ()

  -- create ground
  mr = s.newModelResource ("GroundPlaneRes", #box)
  mr.width = 250
  mr.length = 15
  mr.height = 500
  m = s.newModel ("GroundPlane", mr)
  m.transform.position = vector (0, 250, -150)

   -- create roof
  m = s.newModel ("roof", mr)
  m.transform.position = vector (0, 250, 150)

  -- create walls
  m = s.newModel ("wall1", mr)
  m.transform.position = vector (0, 0, 0)
  m.transform.scale = vector (1, 0.03, 20)

  m = s.newModel ("wall2", mr)
  m.transform.position = vector (125, 250, 0)
  m.transform.scale = vector (0.03, 1, 20)
  m.transform.rotation = vector (0, 0, 180)

  m = s.newModel ("wall3", mr)
  m.transform.position = vector (-125, 250, 0)
  m.transform.scale = vector (0.03, 1, 20)
  m.transform.rotation = vector (0, 0, 180)

This code creates a five-sided box that's missing one of its sides. Each side of the box is a separate model, made from the same modelResource, the box named GroundPlaneRes. The box is scaled and positioned so that the camera can look in from the open side. The top will keep the molecule from being thrown up and out over the box's edge.

Adding a camera and a light will finish the overall environment:

  -- point camera
  c = s.camera[1]
  c.transform.position = vector (0, 600, 0)
  c.pointat (s.model ("GroundPlane").transform.position + vector (0, -100, 50), vector (0, 0, 1))

  c.hither = 1
  c.yon = 1000

  -- add a light
  s.newLight ("light_1", #point)

end

The camera is aimed at a position above the GroundPlane model with the pointAt command, which we'll look at some more later. This command uses two vector values in a list,with the first defining the point the front of the model aims at, and the second defining the side of the object (a camera, in this case) that is the top.

At this point, we've got a well-lit box and nothing more. You can't see the top of the box, but you can look around with the Shockwave3D window's camera controls if you don't believe me.

You've Got Balls

Our next step is to add the spheres that will represent our atoms.

Just like with the walls, we can use a single modelResource as the basis for the three spheres. We can add this to our Create Scene behavior:

-- create balls
  mr = s.newModelResource("Ball1Res", #sphere)
  mr.radius = 10
  m = s.newModel("Ball1", mr)
  m.transform.position = vector (0, 150, -50)

 m.transform.rotation = vector (90, 0, 0)

  m = s.newModel("Ball2", mr)
  m.transform.position = vector (0, 150, -90)

  m = s.newModel("Ball3", mr)
  m.transform.position = vector (0, 150, -130)

The three balls are positioned along a vertical axis, 40 world units apart from each other.

Creating Havok

So far, this scene is static. Our next steps are going to change all of that.

The Havok Xtra is a limited version of a physics engine that's been used in games and 3D applications. It's right there on your Director 8.5 CD-ROM, along with two cast libraries of behaviors to go with it.

The first step to adding physics to our world is to define a Havok type cast member. This is done from the Insert > Media Element menu or by typing new (#havok) in the Message window. Name the new Havok cast member BlankHavok.

To initialize the Havok engine, we need to add one of the behaviors from the Havok > Setup library. Drag the Physics (No HKE) behavior onto the 3D world sprite and accept the defaults in the Parameters dialog. They should look something like this.

In Havok parlance, an HKE is a Havok Export file, created by 3D programs like 3DS Max that support Havok in the modeling application. Since we're going to create everything through Lingo, use the No HKE version of the Physics behavior.

This step associates the Havok physics cast member with the Shockwave 3D world and needs to happen before any other scripts talk to the physics engine. Use the Behavior Inspector to move the Physics behavior before Create World.

Hardbody

Now that we've got physics, we need to tell the objects in our scene how to react, by giving then physical attributes. Add the line in bold at the beginning of the Create World behavior:

on beginSprite me

  s = sprite (me.spriteNum)Member
  hk = member ("BlankHavok")

  s.resetWorld ()

Then, add two lines to each of the definitions of the balls. Use the same code in bold for each ball..

  m = s.newModel("Ball1", mr)
  m.transform.position = vector(0, 150, -50)
  m.transform.rotation = (90, 0, 0)
  m.addModifier (#meshdeform)
  hk.
makeMovableRigidBody (m.name, 10.0)

Adding the #meshdeform modifier to the ball makes it work with the Havok physics engine. The makeMovableRigidBody command creates an object in the physics world that can interact with other objects. Havok supports both moveable and static rigid bodies. Static bodies don't need to check for collisions with each other, cutting down on the amount of processing needed to run the engine.

If you run the movie at this point, the balls will just fall through the floor.

 

To Havok, the floors simply don't exist yet. Gravity exists -- that's what's pulling the balls down -- but the walls haven't been given any physical properties yet. To do that, we'll use the makeFixedRigidBody command. Again, the #meshdeform modifier is added to the model, then it's added to the physics engine. This is how the definition of the ground plane should change.

  -- create ground
  mr = s.newModelResource("GroundPlaneRes", #box)
  mr.width = 250
  mr.length = 15
  mr.height = 500
  m = s.newModel("GroundPlane", mr)
  m.transform.position = vector(0,250,-150)

  m.addModifier (#meshdeform)
  rb = hk.makeFixedRigidBody (m.name)
  rb.friction = 0.5
  rb.restitution = 0

The friction and restitution properties of the model control how other objects slide and bounce off of the surface.

Instead of passing through the floor now, the balls fall slowly onto one another, then the stack tips over and they roll their separate ways (because of a certain amount of randomness built into physics engines, it won't be exactly the same every time). Add the same four lines after each of the wall and roof definitions, and the balls won't roll off the edges..

You can download a Mac or Windows version of the Director 8.5 source file so far.

In our next installment, we'll add some color, link the balls together, make them respond to the mouse, and draw the connecting links.

Darrel Plant is Technical Editor of Director Online. He is the Publisher at Moshofsky/Plant Creative Services in Portland, Oregon, and the author of or contributor to a number of books on Macromedia Director and Flash, including Special Edition Using Flash 5,, Flash 5 Bible, and Director 8.5 Studio..

Copyright 1997-2017, Director Online. Article content copyright by respective authors.