





















































This article covers the following:
Let's start off by having a look at some general practices to keep in mind when modeling for Papervision3D.
In this section, we will discuss several techniques that relate to modeling for Papervision3D. As Papervision3D is commonly used for web-based projects, modeling requires a different mindset than modeling for an animated movie, visualization, or game. Most of the techniques discussed relate to improving performance. This section is especially useful for modelers who need to create models for Papervision3D.
Papervision3D Previewer
Papervision3D Previewer is a small program that should be part of every modeller's toolbox. This tool comes in handy for testing purposes. It allows a modeler to render an exported model in Papervision3D, and it displays some statistics that show how the model performs. At the time of writing, this tool was not compatible with Papervision3D 2.1, which could result in small problems when loading external models.
Papervision3D Previewer can be downloaded from http://code.google.com/p/mrdoob/wiki/pv3dpreviewer
Papervision3D is a cutting edge technology that brings 3D to the Flash Player. It does this at an amazing speed relative to the capabilities of the Flash player. However, performance of Papervision3D is just a fraction of the performance that can be achieved with hardware-accelerated engines such as used by console games. Even with hardware-accelerated games there is a limit to the number of polygons that can be rendered, meaning there is always a compromise between detail and performance. This counts even more for Papervision3D, so always try to model using as few polygons as possible.
Papervision3D users often wonder what the maximum number of triangles is that the Flash player can handle. There is no generic answer to this question, as performance depends on more factors than just the number of triangles. On average, the total triangle count should be no more than 3000, which equals 1500 polygons (remember that one polygon is made of two triangles).
Unlike most 3D modeling programs, Papervision3D is triangle based and not polygon based.
Although this seems to contradict the previous suggestion to keep your polygon count low, sometimes you need more polygons to get rid of texture distortion or to reduce z-sorting artifacts. z-sorting artifacts will often occur in areas where objects intersect or closely intersect each other. Subdividing polygons in those areas can make z-sorting more accurate. Often this needs to be done by creating new polygons for the intersecting triangles of approximately the same size.
There are several approaches to prevent z-sorting problems. Depending on the object you're using, it can be very time consuming to tweak and find the optimal amount and location of polygons. The amount of polygons you add in order to solve the problem should still be kept as low as possible. Finding the optimal values for your model will often result in switching a lot between Papervision3D and the 3D modeling program.
Textures used in the 3D modeling tool can be exported along with the model to a format that is readable for Papervision3D. This is a valuable feature as the texture will automatically be loaded by Papervision3D. However, the image, which was defined in the 3D authoring tool, will be used exactly as provided by Papervision3D. If you choose a 1024 by 1024 pixels image as the texture, for example the wheels of a car, Papervision3D loads the entire image and draws it on the wheel of a car that appears on screen at a size of 50 by 50 pixels for example. There are several problems related to this:
Always choose texture dimensions that make sense for the application using it, and keep in mind that they have to be power of two. This will enable mipmapping and smoothing, which come without extra performance costs.
3D modeling programs usually read a variety of image sources. Some even support reading Adobe Photoshop's native file-format PSD. Flash can load only GIF, JPG, or PNG files at run time. Therefore, stick to these formats in your model so that you do not have to convert the textures when the model needs to be exported to Papervision3D.
If your model is made up of several objects and textures, it's a good idea to use UV mapping, which is the process of unwrapping the model and defining all its textures into one single image. This way we can speed up initial loading of an application by making one request from Flash to load this image instead of loading dozens of images. UV mapping can also be used to tile or reuse parts of the image. The more parts of the UV-mapped image you can reuse, the more bandwidth you'll save. Always try to keep your UV-mapped image as small as possible, just as with keeping your normal textures small. In case you have a lot of objects sharing the same UV map and you need a large canvas to unwrap the UV map, be aware of the fact that the maximum image size supported by Flash Player 9 is 2880x2880 pixels. With the benefits of power of two textures in mind, the maximum width and height is 2048x2048 pixels.
Baking textures is the process of integrating shadows, lighting, reflection, or entire 3D objects into a single image. Most 3D modeling tools support this.
This contradicts what has been said about tiling images in UV maps, as baking results in images that usually can only be used once because of the baked information on the texture. However, it can increase the level of realism of your application, just like shading does, but without the loss of performance caused by calculating shading in real time.
Never use them in combination with a tiling image, as repeated shading, for instance, will result in unnatural looking renders. Therefore, each texture needs to be unique, which will cause longer loading times before you can show a scene.
It is always a good convention to use recognizable names for all your objects. This counts for the classes, methods, and properties in your code, and also for the names of the 3D objects in your modeling tool.
Always think twice before renaming an object that is used by an application. The application might use the name of an object as the identifier to do something with it—for example, making it clickable. When working in a team of modelers and programmers, you really need to make this clear to the modelers as changing the name of an object can easily break your application.
Maintaining the same relative size for your modeled objects, as you would use for instantiating primitives in your scene, is a good convention. Although you could always adjust the scale property of a loaded 3D model, it is very convenient when both Papervision3D and your modeling tool use the same scale.
Remember that Papervision3D doesn't have a metric system defining units of a certain value such as meters, yards, pixels, and so on. It just uses units.
Another convention is to position your object or objects at the origin of the 3D space in the modeling tool. Especially when exporting a single object from a 3D modeling tool, it is really helpful if it is located at a position of 0 on all axes. This way you can position the 3D object in Papervision3D by using absolute values, without needing to take the offset into account. You can compare this with adding movie clips to your library in Flash. In most cases, it is pretty useful when the elements of a movie clip are centered on their registration point.
For each project you should try to find the balance between lightweight modeling and quality. Because each project is different in requirements, scale, and quality, there is no rule that applies for all. Keep the tips mentioned in the previous sections in mind and try to be creative with them. If you see a way to optimize your model, then do not hesitate to use it.
Before we have a look at how to create and export models for Papervision3D, we will create a basic application for this purpose.
In order to show an imported 3D model using Papervision3D, we will create a basic application.
Based on the orbit example (code bundle-chapter 6, click the following link to download: http://www.packtpub.com/files/code/5722_Code.zip) we create the following class. Each time we load a new model we just have to alter the init() method. First, have a look at the following base code for this example:
package {
import flash.events.Event;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.view.BasicView;
public class ExternalModelsExample extends BasicView
{
private var model:DisplayObject3D;
private var rotX:Number = 0.1;
private var rotY:Number = 0.1;
private var camPitch:Number = 90;
private var camYaw:Number = 270;
private var easeOut:Number = 0.1;
public function ExternalModelsExample()
{
stage.frameRate = 40;
init();
startRendering();
}
private function init():void
{
model = new Plane();
scene.addChild(model);
}
private function modelLoaded(e:FileLoadEvent):void
{
//To be added
}
override protected function onRenderTick(e:Event=null):void
{
var xDist:Number = mouseX - stage.stageWidth * 0.5;
var yDist:Number = mouseY - stage.stageHeight * 0.5;
camPitch += ((yDist * rotX) - camPitch + 90)
* easeOut;
camYaw += ((xDist * rotY) - camYaw + 270) * easeOut;
camera.orbit(camPitch, camYaw);
super.onRenderTick();
}
}
}
We have created a new plane using a wireframe as its material. The plane is assigned to a class property named model, which is of the DisplayObject3D type. In fact, any external model is a do3D. No matter what type of model we load in the following examples, we can always assign it to the model property. The classes that we'll use for loading 3D models all inherit from DisplayObject3D.
Now that we have created a default application, we are ready to create our first model in 3D Studio Max, export it, and then import it into Papervison3D.
Autodesk 3ds Max (also known as 3D Studio Max or 3ds Max) is one of the widely-known commercial 3D modeling and animation programs. This is a good authoring tool to start with, as it can save to two of the file formats Papervision3D can handle. These are:
As of 3ds Max version 9, there is a built-in exporter plugin available that supports exporting to COLLADA. However, you should avoid using this, as at the time of writing, the models it exports are not suitable for Papervision3D.
Don't have a license of 3ds Max and want to get along with the following examples? Go to www.autodesk.com to download a 30-day trial.
An exporter that does support COLLADA files suitable for Papervision3D is called COLLADA Max. This is a free and open source exporter that works with all versions of 3ds Max 7 and higher.
Installing this exporter is easy. Just follow the steps mentioned below:
If the only COLLADA export option is Autodesk Collada, then something went wrong during the installation of COLLADA Max, as this is not the exporter that works with Papervision3D.
Now that 3ds Max is configured correctly for exporting a file format that can be read by Papervision3D, we will have a look at how to create a basic textured model in 3ds Max and export it to Papervision3D.
If you already know how to work with 3ds Max, this step is quite easy. All we need to do is create the Utah teapot, add UV mapping, add a material to it, and export it as COLLADA. However, if you are new to 3ds Max, the following steps needs to be clarified.
UV mapping is also known as UVW mapping. Some call it UV mapping and others call it UVW mapping. 3ds Max uses the term UVW mapping.
Save the model in the default 3ds Max file format (.max) somewhere on your local disk, so we can use it later when discussing other ways to export this model to Papervision3D.
The model that we have created and exported is now ready to be imported by Papervision3D. Let's take a look at how this works.
To work with the exported Utah teapot, we will use the ExternalModelsExample project that we created previously in this article.
Browse to the folder inside your project where you have saved your document class. Create a new folder called assets and copy to this folder, the created COLLADA file along with the image used as the material of the teapot.
The class used to load an external COLLADA file is called DAE, so let's import it.
import org.papervision3d.objects.parsers.DAE;
This type of class is also known as a parser, as it parses the model from a loaded file.
When you have a closer look at the source files of Papervision3D and its model parsers, you will probably find out about the Collada class. This might be a little confusing as we use the DAE parser to load a COLLADA file and we do not use the Collada parser. Although you could use either, this article uses the DAE parser exclusively, as it is a more recent class, supporting more features such as animation. There is no feature that is supported by the Collada parser, and is not supported by the DAE parser.
Replace all code inside the init() method with the following code that loads a COLLADA file:
model = new DAE();
model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);
DAE(model).load("assets/teapot.DAE");
Because model is defined as a DisplayObject3D class type, we need to cast it to DAE to make use of its methods so that we can call the load() method.
An event listener is defined, waiting for the model to be completely loaded and parsed. Once it is loaded, the modelLoaded() method will be triggered. It is a good convention to add models only to the scene once the model is completely loaded. Add the following line of code to the modelLoaded() method:
scene.addChild(model);
COLLADA Utah Teapot Example
Publishing this code will result in the teapot with the texture as created in 3ds Max.
In real-world applications it is good practice to keep your models in one folder and your textures in another. You might want to organize the files similar to the following structure:
By default, textures are loaded from the same folder as the model is loaded from, or optionally from the location as specified in the COLLADA file. To include the /assets/textures/ folder we can add a file search path, which defines to have a look in the specified folder, to see if the file is located there, in case none can be found on the default paths. This can be defined as follows:
daeModel.addFileSearchPath("assets/textures");
You can call this method multiple times, in order to have multiple folders defined. Internally, in Papervision3D, it will loop through an array of file paths.
Now that we have seen how to get an object from 3ds Max into a Papervision3D project, we have a look at another format that is supported by both 3ds Max and Papervision3D. This format is called 3D Studio, using a 3ds extension. It is one of the established 3D file formats that are supported by most 3D modeling tools.
Exporting and importing is very similar to COLLADA. Let's first export the file to the 3D Studio format.
You can close this warning, but you need to be aware of the output message. It says that the bitmap filename is a non-8.3 filename, that is, a maximum amount of 8 characters for the filename and a 3-character extension. The 3D Studio file is an old format, released at the time when there was a DOS version of 3ds Max. Back then it was an OS naming convention to use short filenames, known as 8.3 filenames. This convention still applies to the 3D Studio format, for the sake of backward compatibility. Therefore, the reference to the bitmap has been renamed inside the exported 3D Studio file.
As you can see, it is very easy to export a model from 3ds Max to a format Papervision3D can read. Modeling the 3D object is definitely the hardest and most time consuming part, simply because creating models takes a lot of time. Loading the model into Papervision3D is just as easy as exporting it.
First, copy the 3D Studio file plus the renamed image to the assets folder of your project. We can then alter the document class in order to load the 3ds file. The class that is used to parse a 3D Studio file is called Max3DS and needs to be imported.
import org.papervision3d.objects.parsers.Max3DS;
In the init() method you should replace or comment the code that loads the COLLADA model from our previous example, with the following:
model = new Max3DS();
model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);
Max3DS(model).load("assets/teapot.3ds", null, "./assets/");
As the first parameter of the load method, we pass a file reference to the model we want to load. The second parameter defines a materials list, which we will not use for this example. The third and final parameter defines the texture folder. This folder is relative to the location of the published SWF. Note that this works slightly different than the DAE parser, which loads referenced images from the path relative to the folder in which the COLLADA file is located or loads images as specified by the addFileSearchPath() method.
ExternalModelsExample
Publish the code and you'll see the same teapot. However, this time it's using the 3D Studio file format as its source.
The teapot is a static model that we exported from a 3D program and loaded into Papervision3D. It is also possible to load animated models, which contain one or multiple animations. 3ds Max is one of the programs in which you can create an animation for use in Papervision3D. Animating doesn't require any additional steps. You can just create the animation and export it. This also goes for other modeling tools that support exporting animations to COLLADA.
For the sake of simplicity, this example will make use of a model that is already animated in 3ds Max. The model contains two animations, which together make up one long animation on a shared timeline. We will export this model and its animation to COLLADA, load it into Papervision3D, and play the two animations.
By completing these steps you have successfully exported an animation in the COLLADA format for Papervision3D. Now, have a look at how we can load the animated model into Papervision3D.
First, you need to copy the exported COLLADA and the applied material—Blades.jpg, House.jpg, and Stand.jpg—to the assets folder of your project.
To load an animated COLLADA, we can use the DAE class again. We only need to define some parameters at instantiation, so the animation will loop.
model = new DAE(true,null,true);
model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);
DAE(model).load("assets/animatedMill.dae");
Take a look at what these parameters stand for.