loading a .3ds model and textures using materialloader in alternativa7

David Jones
@david3jones
avatar-davidejones

Following on from my previous blog post about loading a .3ds model and texturing i’m going to go over using the MaterialLoader to simplify the process of using textures and materials on your 3d model. If you haven’t already seen the first blog post check it out here Click here to download the .zip file containing the final example First of all here is the full source code below:

package  {
    	import flash.display.MovieClip;
    	import alternativa.engine3d.containers.ConflictContainer;
    	import alternativa.engine3d.controllers.SimpleObjectController;
    	import alternativa.engine3d.core.Camera3D;
    	import alternativa.engine3d.core.View;
    	import alternativa.engine3d.materials.FillMaterial;
    	import alternativa.engine3d.loaders.Parser3DS;
    	import alternativa.engine3d.materials.TextureMaterial;
    	import alternativa.engine3d.objects.Mesh;
    	import alternativa.engine3d.loaders.MaterialLoader;
    	import flash.display.Loader;
    	import flash.utils.ByteArray;
    	import flash.net.URLLoader;
    	import flash.net.URLRequest;
    	import flash.net.URLLoaderDataFormat;
    	import flash.events.Event;
    	import flash.display.Bitmap;
    	import flash.display.BitmapData;
    	public class house extends MovieClip {
    		private var bytes:ByteArray = new ByteArray();
    		private var my3ds:Parser3DS = new Parser3DS();
    		private var container:ConflictContainer = new ConflictContainer();
    		private var controller:SimpleObjectController;
    		private var camera:Camera3D;
    		public function house()
    		{
    			// Camera
    			camera = new Camera3D();
    			camera.view = new View(800, 600);
    			addChild(camera.view);
    			container.addChild(camera);
    			camera.rotationX = -120*Math.PI/180;
    			camera.rotationZ = -10*Math.PI/180;
    			camera.x = -200;
    			camera.y = -1000;
    			camera.z = 400;
    			// Camera controller
    			controller = new SimpleObjectController(stage, camera, 200, 3);
    			// Load 3d Model
    			var ldr:URLLoader = new URLLoader();
    			ldr.dataFormat = URLLoaderDataFormat.BINARY;
    			var req:URLRequest = new URLRequest("model.3ds");
    			ldr.addEventListener(Event.COMPLETE, onComplete);
    			ldr.load(req);
    			// Event Listeners
    			addEventListener(Event.ENTER_FRAME, onEnterFrame);
    			// Initial Render
    			camera.render();
    		}
    		private function onComplete(e:Event=null)
    		{
    			//get the 3d model bytes and parse them
    			bytes=e.target.data;
    			my3ds.parse(bytes);
    			//loop through parsed 3ds and add meshes
    			var i:int = 0;
    			for each(var m:* in my3ds.objects)
    			{
    				if(my3ds.objects[i] is Mesh)
    				{
    					container.addChild(m);
    				}
    				i++;
    			}
    			//load all the textures using material loader
    			var ml:MaterialLoader = new MaterialLoader();
    			ml.addEventListener(Event.COMPLETE, mlComplete);
    			ml.load(my3ds.textureMaterials);
    		}
    		private function mlComplete(e:Event = null):void {
    			var ml:MaterialLoader = MaterialLoader(e.target);
    			trace("done");
    		}
    		public function onEnterFrame(e:Event = null):void {
    			//update controller and camera
    			controller.update();
    			camera.render();
    		}
    	}
}

Now the basic changes are as follows, we no longer need to embed the images into the house.fla file as the materialloader will get them for us. So just make sure the images are in the same directory as the flash file and model.3ds file. Next we need to include and use the materialloader, to do this add the import at the top of the file

import alternativa.engine3d.loaders.MaterialLoader;

Now when the .3ds file is loaded we want to change the oncomplete function to add all the meshes automatically and then to load the materials. This way we won’t have to pick out the meshes and materials and apply them ourselves. To do this i created a loop that will go through each of the objects in the parser3ds instance and check if they are a mesh. If they are a mesh then to add them to the container. After that i created the instance of the material loader and got it to load.

//loop through parsed 3ds and add meshes
var i:int = 0;
for each(var m:* in my3ds.objects)
{
        if(my3ds.objects[i] is Mesh)
        {
    	container.addChild(m);
        }
        i++;
}
//load all the textures using material loader
var ml:MaterialLoader = new MaterialLoader();
ml.addEventListener(Event.COMPLETE, mlComplete);
ml.load(my3ds.textureMaterials);

That is pretty much it, once thats done it will load and add all the meshes and also load and apply the texturematerials assuming you have done everything correctly. Hope it helps

Comments

  • avatar-viking
    # ViKing

    Great script, thanks.

    I’ve a question how can we move the 3ds object into a scene for example ? (specifying x,y,z)

  • avatar-davidejones
    # davidejones

    you can set the 3ds object position by setting the mesh x,y,z

    maybe something like this?

    var i:int = 0; for each(var m:* in my3ds.objects) { if(my3ds.objects[i] is Mesh) { m.x = 0; m.y = 0; m.z = 0; m.rotationX = 0; m.rotationY = 0; m.rotationZ = 0; container.addChild(m); } i++; }

    • avatar-viking
      # ViKing
      Thank you.
  • avatar-cenfee
    # Cenfee
    hello! can u tell how to realize the shadow of buildings, and the mirror effect ? thanks!
  • avatar-davidejones
    # davidejones

    This was done some time ago in v7 but basically the shadows are baked into the textures.

    Alternativa v8 has the ability to cast shadows

Comments are currently closed