Humvee in Away3DLite (and PV3D) wheels and steering

May 18, 2010

Intro

In chapter 5 of my book, I discuss how to make a car’s wheels move forwards and backwards and steer. It is actually pretty easy to do in PV3D. But in Away3DLite it is not so obvious. So in the video below I discuss the difference and show you how to get wheel movement and steering working for both PV3D and Awa3DLite.

Video

Driving a Humvee in Away3dLite

Try It Out

Driving a Humvee

Driving a Humvee in Away3DLite

Code

To see the code click the link below:

Read the rest of this entry »


Jiglibflash Pong Game with Levels

June 5, 2009

Intro

Here’s Pong in JiglibFlash and PV3D that I created. It’s fully explained in the book (and the Wii controller is added as well)!

Directions: Click Drag to Move Around the game. Move your mouse up and down to control the game paddle. 21 points and you win the level, get to level six, and you beat the computer. I’ve never made it to level six…

A bounding box had to be created by Hacking the PV3D plugin created by Bartek Drozd…the rest was easy.

Pong in 3D

Pong in 3D

Demo

Source

Of course many thanks to Seb Lee-Delisle, who created a similar game in PV3D, it wasn’t Jiglib and not mutli-level, but it was a good place to start and Seb released it under the Commons license-thanks Seb! And thanks to Barteck Drozd who created the PV3D Jiglib plugin that I hacked to create a Pong Bounding box.

The book is almost done…when it is, I’ll start posting more frequently…sorry about the down time.


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 »


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


Building the Flintstones Car for Papervision3D

March 31, 2009

Intro

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…

Barney Rubble Car in 3DSMax

Barney Rubble Car in 3DSMax

Demo

(Click the screen to activate the car, then control it using your arrow keys-use double arrows left+up to get a continuous left turn…)

Source

YouTube

Discussion

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.

<node id=”CarBody-node” name=”CarBody” type=”NODE”>
<node id=”RRWheel-node” name=”RRWheel” type=”NODE”>
<node id=”RLWheel-node” name=”RLWheel” type=”NODE”>
<node id=”steerFR-node” name=”steerFR” type=”NODE”>
<node id=”FRWheel-node” name=”FRWheel” type=”NODE”>
<node id=”steerFL-node” name=”steerFL” type=”NODE”>
<node id=”FLWheel-node” name=”FLWheel” type=”NODE”>

When importing the “Barney car” Collada file into PV3D, you’ll use these names to control your car.

Grabbing Names from Collada

Your first task, after importing the Collada file into PV3D, is to grab these names from the Collada file so you can use them in your program.

// Steering disc for front wheels
steerFR = collada.getChildByName( “steerFR”, true );
steerFL = collada.getChildByName( “steerFL”, true );
steerFR.rotationX=steerFL.rotationX=-90;

// Rotation of wheels
wheelFR = collada.getChildByName( “FRWheel”, true );
wheelFL = collada.getChildByName( “FLWheel”, true );
wheelRR = collada.getChildByName( “RRWheel”, true );
wheelRL = collada.getChildByName( “RLWheel”, true );

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

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.

steerFR.rotationY = steer;
steerFL.rotationY = steer;

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.

Read the rest of this entry »


Importing Collada into Papervison3D

March 29, 2009

Intro

In PV3D there are two Collada parsers: Collada and DAE. The DAE parser is actually an improved version of Collada parser which includes animation.

When working with Collada files, there are five commonly used scenarios found in PV3D:

  • Single Objects with UVMaps
  • Multiple Objects with UVMaps
  • Single Objects with Multiple Images
  • Interactive Objects (or Vehicles) and Environments
  • Animated Objects

In this post, you learn about Single and Multiple Objects with Simple Images. Click the image below to see a demo:

Moon Orbiting the Earth in 3DSMax

Moon Orbiting the Earth in 3DSMax

Demo

Source

YouTube

Discussion

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.

<geometry id=”earth-mesh” name=”earth”>
<geometry id=”moon-mesh” name=”moon”>

In this case the names are earth and moon.

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.

<image id=”earth.jpg” name=”earth_jpg”>
<init_from>./assets/earth.jpg</init_from>
</image><image id=”moon.jpg” name=”moon_jpg”>
<init_from>./assets/moon.jpg</init_from>
</image>

Once the images are loaded, the onColladaDone method is executed which sets the planets into place and motion.

collada.addEventListener(FileLoadEvent.COLLADA_MATERIALS_DONE, onColladaDone);

To see the rest of the discussion check out Chapter 5 of the book. To see the complete code click the more button below or download the source

Read the rest of this entry »


Papervision3D Pendulums – NKU Seminar #3

February 17, 2009

Papervision3D Pendulums NKU Seminar #3

This is the 3rd in a series of free public seminars held at NKU on Papervision3D and CS4. In this seminar, we take advantage of a number of open source references (given at the end of this post): MIT Open Courseware, Wikipedia, and Wolfram.

(Also in this seminar, Cocomo is tested.)

Please download Flash Player 10 to View all Examples

http://get.adobe.com/flashplayer

Intro

This seminar treats four pendulum types in Papervision3D: Simple , Double , Torsion, and Foucault. In addition, numerical techniques such as Runge-Kutta are discussed and source code demonstrated.

4 Pendulums

4 Pendulums

Source Files

YouTube

Part 1: Simple & Double


Part 2: Torsion & Foucault

Discussion

In each topic, we introduce an important coding concept. By the end of this seminar you should have a knowledge of basic pendulum types, open source resources, encapsulation, pinning, Runge-Kutta, sliders, and environment maps.

A. Simple Pendulum: Encapsulation

Encapsulation is what really separates men from mice when it come to programming in 3D Flash. Dehash on his Blog post a series of Papervision3D examples: http://www.dehash.com/?page_id=212

The example double plane demonstrates how to properly encapsulate elements in Papervision3D. I’ve extended his example to make the planes oscillated: Check it out here (and included in the source code).

Simple Pendulum

Simple Pendulum

Demo

Basically, the overall code is separated into two classes. The main class runs BasicView and is in charge of providing length, pinning, and animation information. The second class holds the elements to be animated.

Two Classes

Two Classes

It’s brilliant (wish I could take credit) and provides the foundations for all types of coolness to be published in future blog posts.

Once the secondary class is imported using

import objects.*;

then you can access all the public classes which let you manipulate the instantiated objects from the sub class, as described in my book.

Of course, the super huge advantage here is that my pendulum elements can be substantiated and pinned as often as needed and used by any number of programs.

B. Double Pendulum: Pinning

The example below demonstrates the importance of pinning. Pinning lets you attach one segment to another.

Double Pendulum

Double Pendulum

Demo

The two elements above were pinned together using:

myPendulum1.rotationZ = Osc;
myPendulum2.rotationZ = Osc*1.721;
myPendulum2.x = myPendulum1.getPin(Osc).x;
myPendulum2.y = myPendulum1.getPin(Osc).y;

where the getPin(Osc) function gives the end point of the first segment and starting point of the second. Its code for the 2D and 3D cases are:

2D Case

public function getPin(myRot:Number):Point
{
var angle:Number = myRot* Math.PI / 180;
var xPos:Number = this.x + Math.sin(angle) * myLength;
var yPos:Number = this.y – Math.cos(angle) * myLength;
return new Point(xPos, yPos);
}

3D pseudo Code (still needs work)

public function getPin(myTheta:Number, myPhi:Number):Vertex3D
{
var angle1:Number = myTheta* Math.PI / 180;
var angle2:Number = myPhi* Math.PI / 180;

var xPos:Number = this.x + Math.cos(angle1) * Math.sin(angle2)*myLength;
var yPos:Number = this.y + Math.cos(angle2) * myLength;
var zPos:Number = this.z + Math.sin(angle1) * Math.sin(angle2)*myLength;

return new Vertex3D(xPos, yPos, zPos);
}

In both cases, pinning is just a trig-calculation of segment ending points.

This example demonstrates one of the normal modes of the double pendulum: with the second pendulum overextending to demonstrate the second degree of freedom. To properly handle this problem one needs to use numerical analysis (such as Runge-Kutta).

C. Numerical Calculations: Runge-Kutta

Though beyond the scope of this seminar, we have include the Flash code of Runge-Kutta 2 (midpoint), and 4 in your source files. This code was developed by Keith Peters in his book Advanced ActionScript 3.0 Animation. It’s a good starting point and will be used in seminars to come. The code is included in the objects folder of your download and is labelled RK2, and RK4.

Keith Peter’s Demo (bouncing ball RK4)

D. Torsion: Sliders

Here we describe the use of sliders. Sliders let you interact with your animations: they add the thrill of interaction. But there is a fundamental decision to be made when using such elements. Should you use Flash components, Flex components, or make your own?

Torsion Pendulum

Torsion Pendulum

Demo

In this seminar, we use Flex components. And since Flex is free for educators, it’s the logical choice (for this seminar). And in addition, by creating a MXML applications your can just drag those components onto the screen where they are supposed to go.

Here’s the steps:

  • Drag your Flex component to the stage and position it
  • Use the Flex Properties Panel to assign min, max, tick, etc…
  • Incorporate your slider using the following code
  • In the HSlider mx tag (which was automatically generated when you dragged the slider to the stage) place a change event: change=”sliderChangeLive2(event);”

<mx:HSlider change=”sliderChangeLive2(event);” x=”10″ y=”67″ value=”6″ maximum=”40″ minimum=”1″ liveDragging=”false” id=”length” enabled=”true” snapInterval=”1″/

  • Create the sliderChangeLive2 function

private function sliderChangeLive2(event:SliderEvent):void {
var currentSlider2:Slider=Slider(event.currentTarget);
mySpConst=currentSlider2.value;
}

  • Place the mySpConst which is generated by your slider into your equations of motion which are located in your animation loop

var Osc1:Number=80*Math.sin(incre*(Math.sqrt(mySpConst)/20));

E. Foucault: Environment Map

Placing an Environment Map on your primitive adds realism to your object as can be shown below. An Environment Map is a Papervision3D shader material, and a great blog to learn more about shader is Jim Foley’s blog MAD VERTICES. He does a super job with primitives, shaders, and more…and has code, video, and demos.

Foucault Pendulum

Foucault Pendulum

Demo

As mentioned earlier an EnvMapMaterial is a shader material. A shader material is a material that uses a light object to determine how it displays. The EnvMapMaterial accepts 4 parameters, the light object, light map bitmapdata, back environment bitmapdata and the ambient light. The EnvMapMaterial displays as though your object is a mirror that is reflecting its environment.

environment = new EnvMapMaterial(light, envMap, envMap, 0×555555)

F. Application: Butterflies

Seb Lee-Delise on his blog http://www.sebleedelisle.com/ gives an example of a butterfly whose wings oscillate like a simple pendulum

http://clockmaker.jp/labs/as3_pv3d_gw_butterfly/reflection.swf

Essentially, two planes are created and positioned with a sine oscillation. The code required to do this is given below:

var leftWing:DisplayObject3D;
var rightWing:DisplayObject3D;
var butterfly:* = new DisplayObject3D();
leftWing = new DisplayObject3D();
rightWing = new DisplayObject3D();
var mat:* = new BitmapFileMaterial(“butterfly_wind.png”);
mat.doubleSided = true;
var leftWingPlane:* = new Plane(mat, 200, 200, 1, 1);
var rightWingPlane:* = new Plane(mat, 200, 200, 1, 1);
leftWingPlane.scaleX = -1;
leftWingPlane.x = -100;
rightWingPlane.x = 100;
leftWing.addChild(leftWingPlane);
rightWing.addChild(rightWingPlane);
butterfly.addChild(leftWing);
butterfly.addChild(rightWing);
addEventListener(Event.ENTER_FRAME,

function (EffectEvent:Event) : void
{
leftWing.rotationY = Math.sin(getTimer() / 200) * 60;
rightWing.rotationY = Math.sin(getTimer() / 200) * -60;
return;
);

To improve the code one would need to use encapsulation and pinning. This is treated in the book.

G. Speeding Things Up

In the book, we show you how to build these pendulums in CS4, which speeds things up by reducing the overhead of Papervision3D.

Resources

The availability of knowledge provided by the internet is changing the face of education. No longer do we need to leave home to gain excess to the reservoirs of knowledge once cloistered in ivory towers. But now at our finger tips, with a simple click ,we gain excess to more than we could ever retain in a lifetime of study.

It’s changing the way we view education and interact with knowledge. From the “small to large” to the “large to small”, knowledge is in an overwhelming abundance and we must now pare it down and interact with what’s pertinent to our assigned task; which really makes the case for 3D data visualization

Simple Pendulum

http://ocw.mit.edu/OcwWeb/web/home/home/index.htm

http://scienceworld.wolfram.com/physics/

http://scienceworld.wolfram.com/physics/Pendulum.html

http://scienceworld.wolfram.com/physics/PendulumSmallOscillations.html

Double Pendulum

http://scienceworld.wolfram.com/physics/DoublePendulum.htm

Torsional Pendulum

http://scienceworld.wolfram.com/physics/TorsionalPendulum.html

Foucault Pendulum

http://en.wikipedia.org/wiki/Foucault_pendulum


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 »


CS4 Second Life Tree Superior to PV3D

January 18, 2009

Intro

When it comes to creating Second Life foliage in Flash 3D, Flash CS4 is far superior in ease of use, code required, and portability.

Creating a Second Life Tree in CS4 Flash

Creating a Second Life Tree in CS4 Flash

To see a demo and grab the source files click the links below:

Source

Demo

Given that I like Papervision3D so much, you’ll find the following analysis very unbiased. But it surprised me, and made me think a little about the direction I’m headed. I’m not giving up Papervision3D, there are too many things that PV3D can do that CS4 can’t. But I’m definitely blending CS4 with Papervision3D whenever a savings like this can be found.

Ease of Use

The steps required to create the Second Life tree graphic for use in the 3D environment for CS4 and PV3D are given below. CS4 requires no programming and PV3D is programming intensive.

CS4, No Programming Required

To create the Second Life Tree in CS4 Flash follow these steps

  1. Import the front and side tree “png” images onto the Flash Stage.
  2. Turn them both into movie clips
  3. Rotate one 90 degrees with the 3D rotation tool and use the 3D translation tool to overlap them at their centers
  4. Turn both into a movie clip and check the linkage of that movie clip for export

PV3D, Programming Intensive

  1. Create a Tree Primitive (see the Post on Second Life Tree)
  2. Import the Tree Primitive into a BasicView wrapper program
  3. Instantiate two BitmapFileMaterials and load your images into them
  4. Create a MaterialList and load your Image materials into it
  5. Load your MaterialList into your Tree Method

Counting lines of code was the real eye opener, it really shows the advantage of having the native z component in Flash 10.

Code Required

All things considered CS4 beats Papervision3D hands down in the number of lines (fewer) required to code the same user experience: 23 to 243, a factor of 10.

Comparision of Lines of Code Required

Comparison of Lines of Code Required

Portability

Like Papervision3D, CS4 runs on Windows, Mac, and Linux. But with CS4 you can run your Second Life tree with Papervision3D, Away3D, Sandy3D, or any other 3D package running in the Flash 10 player.

The code for the CS4 Second Life Tree is given below:

CS4 Code

package {
import flash.display.Sprite;
import flash.display.*;

public class SLTreePackage extends Sprite
{
private var tree:SLTree= new SLTree();
public function SLTreePackage()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
addChild(tree);
tree.x=stage.stageWidth/2;
tree.y=stage.stageHeight/4;
//Start Tree Rotating
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
tree.rotationY+=1;
}
}
}


Follow

Get every new post delivered to your Inbox.