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.