1. Code
  2. Game Development

View 3DS Models With Away3D 4.0 Beta

Scroll to top
7 min read

In this tutorial we’ll learn how to load and display a 3DS model file in Flash, using Away3D 4.0 beta and Stage3D's GPU hardware acceleration.


Final Result Preview

Let's take a look at the final result we will be working towards:

Click to download the demo files.


Introduction

To use this tutorial you will need to have a 3D model (exported as a .3ds file) and its texture (as an image file).

I created a simple 3D model of a teapot in Autodesk 3DS Max, and exported it to a file named Teapot.3DS along with its separate texture file, teapot.jpg. You can find both files in the source download.

You will need to download a package SWC of Away3D 4.0.0 beta (you can also find this SWC in the source files).

And you need to know that Away3D 4.0.0 beta version uses the new Stage3D features of Adobe Flash, meaning it can use the GPU for 3D graphics acceleration.

We are going to build this demo using pure AS3, compiled in FlashDevelop (read more about it here). FlashDevelop is a free AS3 IDE, although it is Windows only. If you prefer to use another IDE, you will still be able to follow this tutorial.


Step 1: Create a New Project

If you don’t already have it, be sure to download and install FlashDevelop. Open it and start a new AS3 Project.

Create a New Project in FlashDevelopCreate a New Project in FlashDevelopCreate a New Project in FlashDevelop

FlashDevelop will create a blank AS3 template project for you. We'll use the Main class for all our code.


Step 2: Compiler Options

Go into the Project menu, choose Properties and change a few options:

  1. Set the target platform to Flash Player 11.1.
  2. Change the SWF size to 550x400px.
  3. Set the background color to black.
  4. Change the FPS to 40.
Target Flash 11Target Flash 11Target Flash 11

If we want to run this tutorial from the HTML embed code, we have to include the parameter wmode=direct in the parameters of the Flash object in the HTML file. It'll look like this:

1
2
<object width="550" height="400" data="3DViewer.swf" type="application/x-shockwave-flash" wmode="direct">
3
<param name="src" value="3DViewer.swf" />
4
<param name="wmode" value="direct" />
5
</object>

In this tutorial we'll load the 3DS file from local storage (rather than from a web server), so we must change some settings in the Compiler Options tab. Set Use Network Services to False.

Local file loadLocal file loadLocal file load


Step 3: Add Away3D Library

Get away3d-core-fp11_4_0_0_beta.swc from the source files, or download it from Away3D’s site.

Copy that file to your project's lib directory.

In FlashDevelop, right-click the SWC file, and choose Add to Library.

Add Away3D Library


Step 4: Imports

Now let’s start coding with our Main.as file. To begin, we have to import the necessary library files for program to setup the Away3D engine and the Flash components. There are quite a few, so let's get them out of the way:

1
2
// 3DS Model Viewer Tutorial

3
// by Vu Hoang Minh - www.3dgameflash.com

4
// Created for active.tutsplus.com

5
 
6
package
7
{
8
	//Away3D classes

9
	import away3d.cameras.lenses.PerspectiveLens;
10
	import away3d.containers.ObjectContainer3D;
11
	import away3d.containers.View3D;
12
	import away3d.entities.Mesh;
13
	import away3d.events.LoaderEvent;
14
	import away3d.loaders.Loader3D;
15
	import away3d.loaders.parsers.Max3DSParser;
16
	import away3d.materials.TextureMaterial;
17
	import away3d.textures.BitmapTexture;
18
19
	//General Flash classes for display and interaction

20
	import flash.display.Bitmap;
21
	import flash.display.MovieClip;
22
	import flash.display.Shape;
23
	import flash.display.Sprite;
24
	import flash.events.Event;
25
	import flash.events.MouseEvent;
26
	import flash.geom.Vector3D;
27
	import flash.text.TextField; 
28
29
	//Classes for loading the 3DS file from the hard drive 

30
	import flash.display.SimpleButton;
31
	import flash.events.IOErrorEvent;
32
	import flash.net.FileFilter;
33
	import flash.net.FileReference;
34
	import flash.net.URLRequest;
35
	import flash.system.Security;

Step 5: Initialize Program

Let's get started. We'll declare the variables that we're going to need, initialise the 3D engine, and set up the "Browse" button and debug output text field.

1
2
	public class Main extends Sprite
3
	{		
4
		private var file:FileReference;
5
		private var view3d:View3D;
6
		private var loader:Loader3D;
7
		private var labelDebug:TextField;
8
		private var object3d:Mesh;
9
		
10
		public function Main():void
11
		{
12
			//boilerplate loading code

13
			if (stage)
14
				init();
15
			else
16
				addEventListener(Event.ADDED_TO_STAGE, init);
17
		}
18
		
19
		private function init(e:Event = null):void
20
		{
21
			//allow us to load a local file

22
			Security.allowDomain("*");
23
            
24
			removeEventListener(Event.ADDED_TO_STAGE, init);
25
            
26
			//init 3D engine

27
			view3d = new View3D();
28
			view3d.camera.lens = new PerspectiveLens();
29
			view3d.camera.z = 100;
30
			addChild(view3d);
31
			
32
			//3D loader

33
			initLoader();
34
			
35
			//Button to open file browser

36
			var mcBrowse:MovieClip = new MovieClip();
37
			mcBrowse.graphics.beginFill(0xeeeeee);
38
			mcBrowse.graphics.drawRoundRect(1, 2, 100, 25, 7, 7);
39
			mcBrowse.graphics.endFill();
40
			var labelBrowse:TextField = new TextField();
41
			labelBrowse.text = "Browse";
42
			mcBrowse.addChild(labelBrowse);
43
			mcBrowse.mouseChildren = false;
44
			mcBrowse.buttonMode = true;
45
			labelBrowse.x = 25;
46
			mcBrowse.addEventListener(MouseEvent.CLICK, onClick_mcBrowse);
47
			addChild(mcBrowse);
48
			
49
			//debug output

50
			labelDebug = new TextField();
51
			labelDebug.text = "...";
52
			labelDebug.textColor = 0xff0000;
53
			labelDebug.selectable = false;
54
			labelDebug.y = mcBrowse.height / 2;
55
			labelDebug.width = 600;
56
			addChild(labelDebug);
57
			
58
			//file

59
			file = new FileReference();
60
		}

In lines 25-29, we initialise the Away3D graphics components. We create a new View3D (a container that stores the camera and objects), configure its lens and camera, and add it to the display list.

After that we make a Browse button: we draw its background, add its label, configure it, and add it to the display list.

To make it easy to keep track of the 3DS loading state, we make a debug label, which is a simple text field.

Finally, we initialise a FileReference instance to handle browsing for the 3DS file.


Step 6: Initialise 3D Loader

The next important thing we must do is create a 3D model loader.

1
2
	private function initLoader():void
3
	{
4
		//clear all

5
		removeEventListener(Event.ENTER_FRAME, onEnterFrame);			
6
		while (view3d.scene.numChildren > 0)
7
		{
8
			view3d.scene.removeChild(view3d.scene.getChildAt(0));
9
		}		
10
            	
11
		//init new 3D loader

12
        	Loader3D.enableParser(Max3DSParser);
13
		loader = new Loader3D();
14
		loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onComplete_loader);
15
		loader.addEventListener(LoaderEvent.LOAD_ERROR, onError_loader);
16
		view3d.scene.addChild(loader);
17
            
18
   		//config camera

19
		view3d.camera.lookAt(loader.position);
20
	}

This function has three sections:

  1. First, we clear everything out, in case our program has run before.
  2. After that, we initialise a new Loader3D instance, and add listeners to it which trigger when it fires an Error when a 3D file has completely loaded. To make it visible, we add it to the View3D's scene.
  3. To ensure that we can actually see the object once it has loaded, we tell the camera to look at it.

Step 7: Handle All Events

Next, we'll add all the event handler functions, which all have something to do with loading the 3DS file.

1
2
		private function onClick_mcBrowse(e:MouseEvent):void
3
		{
4
			file.browse([new FileFilter("3DS", "*.3ds")]);
5
			file.addEventListener(Event.SELECT, onFileSelected);
6
			file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
7
			file.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
8
		}
9
		
10
		private function onSecurityError(e:Event):void 
11
		{
12
			labelDebug.text += ".Security Error!";
13
		}
14
		
15
		private function onIOError(e:IOErrorEvent):void 
16
		{
17
			labelDebug.text += ".File not found Error!";
18
		}
19
		
20
		private function onFileSelected(e:Event):void
21
		{
22
			labelDebug.text = "File :" + file.name;
23
			file.removeEventListener(Event.SELECT, onFileSelected);
24
			file.addEventListener(Event.COMPLETE, onFileLoaded);
25
			file.load();
26
		}
27
		
28
		private function onFileLoaded(e:Event):void
29
		{
30
			file.removeEventListener(Event.COMPLETE, onFileLoaded);
31
			initLoader();
32
			loader.loadData(e.target.data);
33
		}
34
		
35
		private function onError_loader(e:LoaderEvent):void
36
		{
37
			trace("Error loading File...");
38
			labelDebug.text += " .Loading Error";
39
		}
40
		
41
		private function onComplete_loader(e:LoaderEvent):void
42
		{
43
			trace("3D File loaded");
44
			labelDebug.text += " .Complete.Rendering...";
45
			loader.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, onComplete_loader);
46
			loader.removeEventListener(LoaderEvent.LOAD_ERROR, onError_loader);
47
			object3d = Mesh(loader.getChildAt(0));
48
			view3d.scene.addChild(object3d);
49
			loader.dispose();
50
			loader = null;
51
			
52
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
53
		}

When the user clicks the Browse button, we display the File Browse Dialog, which uses a FileFilter to restrict the files shown to those with a .3ds extension. We add several event listeners to this dialog, so that we can detect when a file is detected or if an error occurs.

After a file has been selected, we load it to the FileReference instance that we initialised earlier. Once it has loaded, we call the initLoader() function that we defined in the previous step, which loads our 3D model.

At this time, there are two possible states we can catch:

  • One is the "error" state, which implies that our program cannot load the 3D model file (perhaps the path is incorrect, or the map texture file is wrong...).
  • The other is the "loaded successfully" event, upon which we cast the loaded file to a Mesh and add it to the scene of View3D.

To free up our memory and reuse it later, we should dispose of our loader.

At the end of above code (assuming the file loaded) we add an ENTER_FRAME event, which we'll use to render the object. We'll write that handler now.


Step 8: Start the Render Loop

Now that everything has been initialized, we are ready to render it all. Every frame, we'll make the 3D object yaw (rotate) and call the render() function of View3D to update the display.

1
2
		private function onEnterFrame(e:Event):void
3
		{
4
			object3d.yaw(1);  //yaw by one unit

5
			view3d.render();
6
		}

Step 9: Compile and Run!

Almost done! Compile your SWF with F5, and see your final result. So interesting, right?

You can do than just rotate the object - try calling object3d.moveFoward(10) or object3d.pitch(1). You could even do this in response to a mouse movement or a key press.

Just for reference, and to ensure that you've used the correct filenames and locations for everything, here is what your FlashDevelop project should look like:

Just for reference, and to ensure that you've used the correct filenames and locations for everything

Conclusion

We have finished first basic 3D tutorial on newest 3d Accelarate function of Adobe. I warmly welcome all readers to get in touch with me via the comments, or through my website, any time. Thanks for reading. See you next time. Good luck and HAVE FUN!