Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
UbiAssassin

Using LoaderMax to Load Away3D Content

Recommended Posts

Hello Everyone and Happy New year!

 

I have been fully re-working my website using Greensock (Flash) to leverage the Starling Away3D framework. I have found that many people ask the same questions about how to use the incredible power of the Greensock code to take care of the loading of Starling and Away3D assets:

 

Here are some code examples from the Preloader ClassFile:

 

1. LoaderMax loader that queues and loads a 3DSMax (Obj) model, myModel, for a second Content Classfile:

 

//========================================================
//*** Variable declarations for Main Loader.***
//
//========================================================
		
private var mainQueue:LoaderMax = new LoaderMax({name: "mainQueue", rawProgress: 1, onProgress: ProgressHandler, onComplete: completeHandler});

//==========================================================
//*** LoaderMax Loader.***
//
//==========================================================

LoaderMax.defaultAuditSize = false;
mainQueue.append(myModel);			
mainQueue.load();
mainQueue.addEventListener(LoaderEvent.COMPLETE, completeHandler);
mainQueue.addEventListener(LoaderEvent.PROGRESS, ProgressHandler);
 

2. Here is a close look at the DataLoader Variable that I am using in the Loader above. The DataLoader has the model path (assets/myModel.obj) and the name (SkyScraper) that I am giving the model, so that I can access it in the other class file

 

//=========================================================================
//*** Variable declarations for Away3D Model Preloading.***
//
//=========================================================================
		
private var myModel:DataLoader = new DataLoader("assets/myModel.obj", {name: "SkyScraper", format: "text", rawProgress: 1, autoPlay: false});

This is all that is needed in the preloader class. The 3DSMax model will be loaded by the DataLoader in text format.

 

The next step is important and must be done before testing:

 

1. Open the .obj file in notepad and make sure that the path to the .mtl file is correct. In my example I had to re-write the path from Object: myModel to Object: assets/myModel since the .obj file and its .mtl file were added to the assets folder for my website. If you do not do this, you have the chance of encountering a Network streaming error complaining about the inability to resolve your .mtl file location when testing your flash page.

 

I will now show you how to access the model information that we need in the content class.

 

Here are the code examples from my Content Class File, which needs to access the model data so that it can be shown in the content page:

 

//========================================================
//
//*** DataLoaders for Model Meshes.***
//*** Mesh Variable Declarations.***
//
//========================================================

private var skyScraperModelText:String = LoaderMax.getContent("SkyScraper");
private var modelMesh:Mesh;
In the code chunk above, I have asked to getContent on the name of the DataLoader from the Preloader classfile and that information has been stored in the new string variable skyScraperModelText. I have also declared a new mesh variable "modelMesh" for later usage.

 

//===========================================================
//
//*** Loader for the Portfolio Mesh ***
//
//===========================================================
			
meshLoader = new Loader3D();
meshLoader.loadData(skyScraperModelText);
meshLoader.addEventListener(AssetEvent.ASSET_COMPLETE, modelLoaderHandler);
This chunk of code allows the Loader3D (Away3D) to have access to the Obj model data that we have already pre-loaded using Greensock. The new eventListener will then fire our last chunk of code, which will load the Obj data from the String variable and start applying textures to each 3DsMax model layer that I created when setting the model up:

 

NOTE: Most of the code below is extraneous to the act of loading the model into the content class so that it can be rendered on a webpage. I have left it in so that you can see the process that I am using to dynamically apply my own texture to the mesh layer. There are actually 9 case switches in my real code that apply 8 different textures to the 8 different model layers, but 1 is enough for the example.

 

private function modelLoaderHandler(e:AssetEvent):void
{
        trace("Portfolio Symbol Mesh Loaded!");
			
        //==============================================================
	//
	//*** Set up Away3D Model Textures and Assign the Lights. ***
	//
	//==============================================================
			
	var boxModelCubeTexBase:Texture2DBase = new BitmapTexture(boxModelCube.rawContent.bitmapData);
			
	var boxModelOuterRingTexBase:Texture2DBase = new BitmapTexture(boxModelOuterRing.rawContent.bitmapData);
			
	var boxModelInnerRingTexBase:Texture2DBase = new BitmapTexture(boxModelInnerRing.rawContent.bitmapData);
			
	var boxModelLettersTexBase:Texture2DBase = new BitmapTexture(boxModelLetters.rawContent.bitmapData);
			
	switch (String(profileMeshVar))
		{
		     case "0": 
			runFirstMaterialSwitchPA(); // MaxBody Mesh
			break;
				
		     case "1": 
			meshLoader.removeEventListener(AssetEvent.ASSET_COMPLETE, modelLoaderHandler);
			trace("Profile Model Ready for Render Engine!!!");
			break;
		}
			
		function runFirstMaterialSwitchPA():void
		{
		        trace("Applying First Profile Model Material!")
				
			//========================================================================
			//
			//*** First Material is applied to the Main Box Object ***
			//
			//========================================================================
				
			switch (String(e.asset.assetType))
			{
			   case "mesh": 
				// Assign mesh
				modelMesh = e.asset as Mesh;
						
				// Loop through mesh assigning materials to the sub meshes
			        for each (var m:SubMesh in modelMesh.subMeshes)
				{
				        trace("APPLYING PROFILE MATERIAL TO SURFACE 0!!!!!");
					//=============================================================
					//
					//*** Set up Away3D Model Textures and Assign the Lights. ***
					//
					//=============================================================                                        var cubeMaterial:ColorMaterial = new ColorMaterial(0xffffff);
					cubeMaterial.ambientColor = 0xdd5525;
					cubeMaterial.ambient = 1; //0xdd5525;
					cubeMaterial.specular = .5;
					cubeMaterial.diffuseMethod = new CelDiffuseMethod(3);
					cubeMaterial.specularMethod = new CelSpecularMethod();
					cubeMaterial.addMethod(new OutlineMethod(0x000000, 5, true));
					CelSpecularMethod(cubeMaterial.specularMethod).smoothness = .01;
					CelDiffuseMethod(cubeMaterial.diffuseMethod).smoothness = .01;
					cubeMaterial.normalMap = Cast.bitmapTexture(boxModelCubeTexBase);
					cubeMaterial.repeat = true;
							
					cubeMaterial.lightPicker = lightPicker;
							
					//=============================================================
					//
					//*** Find the Model Assets using the Loader and their Level. *
					//
					//=============================================================
					m.material = cubeMaterial;
					}
					break;
					
					case "material": 
						trace("This is a material and not a model!!!");
						break;
					
					default: 
						trace("UNHANDLED ASSET TYPE: " + e.asset.assetType);
						break;
				}
			}
The true take-away chunk of code from the bit above is part of the first switch statement:

 

switch (String(e.asset.assetType))

{

case "mesh":

// Assign mesh

modelMesh = e.asset as Mesh;

blah blah blah more code

{

The e.asset String is being converted to a mesh and my modelMesh variable is being declared equal to it and therefore now contains the important Obj model asset information. Voila!!!

 

The later code uses switch statements to apply different textures to the different Obj model layers, but that is for another topic ;)

 

I hope that someone else finds this useful and wastes less time searching for answers :D

 

-Cheers

Link to post
Share on other sites

So I thought about this a bit and I think it would be far more useful if I explained my end of project workflow from 3DsMax to Flash and why I felt the need to use switches in the last bit of my code. So I will start with my end of modeling workflow:

 

1. Separate the main mesh into layers using the 3DsMax Layer Tool according to my needs. I might want to animate specific parts of the model in my website code or apply unique textures to each different part of the mesh.

 

2. Go through each mesh layer and make sure that the smoothing groups are set up well and re-build them if they are not.

 

3. Use a checkerboard texture to create good UV maps for all meshes in all layers. I use the checkerboard texture because it is easier to see if the UV's match well across the entire object instead of just mesh by mesh / layer by layer. Easier to create a uniform UV consistency.

 

4. Save the model as myModelA or myModel1 or whatever the next letter or number happens to be in your iterative naming convention.

 

5. Here is where I replace whatever textures that I am using for 3DsMax viewing with just a default standard texture. I make sure that this default is the only texture on all meshes / layers of the model. This is because I like to dynamically apply my textures with code, but you may want to skip this step.

 

6. Select all meshes within all layers of the model, make sure that the model overall is at 0,0,0, Reset X-Form, then convert all meshes back to Edit-able Poly afterward.

 

7. Just as a final check, select all meshes, enter vertex mode and weld to make sure that everything is tight before export.

 

8. Export the model as Obj. Make sure to hide any trash geometry layers or delete them before export.

 

Now you will have an Obj model file and its material file. I have already made a point about adjusting the obj file .mtl path if these assets are placed in a special folder. Failing to do this will spit the dreaded network stream error for the .mtl file.

 

The Two code Switches in my code snippet:

 

1. Switch 1: This switch catches the AssetEvent for each layer in the model. Each event from the DataLoader will be 1 of three things. I only care about the Mesh asset, but it will also provide both the Material and Geometry Assets. This is why I have the first switch. Example:

 

I export a model with 3 layers, my switch will catch three different passes for each layer, so 9 passes. I only care about the Mesh pass, and I push the code that converts the string information to a mesh and then apply my textures accordingly when the Mesh case is true. If I do not detect for the other two cases, however, I will more often than not catch the wrong information and receive a null object error when trying to convert the string to a mesh (in the cases of Material or Geometry). This is the simple and quick explanation for the first switch.

 

2. Switch 2: I am going to use the same example of a 3 layer model and I want a different texture applied to each different layer (mesh section). This is the reason that I use the second switch. You can tell which layer (mesh section) will come in what order by opening your Obj file in notepad and looking at the Object: someName instances. Let's say that my 3 layer model lists the the Object names as follows from top to bottom on the file (Frame, Text, Base). I know what geometry the names link to since they are the layers that I created in 3DsMax ;). Case 0 = Frame, Case 1 = Text and Case 2 = Base. I now know what material to apply in each case instance. Voila!!! I am texturing or animating the correct part of the mesh using a switch statement ;)

 

There are many ways to do this I imagine, and I am the first to admit that I am not an expert. So feel free to get creative with your methods.

Link to post
Share on other sites

Hi UbiAssassin,

 

Thanks for the thorough overview of your process. 

I haven't dabbled with any advanced Stage3D things but I'm sure someone will find this all very useful.

I think it would be great to see a very simple demo or 2 of the output of this code. 

I have looked through your site, but I think a simple "stand alone" demo would be great. 

Feel free to share any links.

 

Thanks again and Happy New Year!

 

Carl

Link to post
Share on other sites

No problem Carl :) I am glad to help when I can! I will put together a small project that preloads a model, then loads it into a content page and finally applies textures dynamically. I will probably have some time this weekend to put it together.

 

-Cheers

Link to post
Share on other sites

Wow thank you so much, I have to animate a 3D earth and I don't want to use three.js

 

Hope this will work.

 

Cheers

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×