Despite that Alternativa3D lets you to build geometry "by hands", it is hard to create complex models by programming methods. So, we can import models in 3DS format, and that is what this tutorial about.
First, load tutorial source code. It has main project class file, 3DS file and two textures. We will look through different parts of the code and get them together at the end.
Loader3DS class
Class alternativa.engine3d.loaders.Loader3DS is made for loading models in 3DS format. Every object from this file is being made using this algorithm:
- Vertices and faces are being created;
- Surfaces are being created using groups of faces with the same material. Every surface gets it's own material. If material from file has a link to diffuse texture, TextureMaterial instantiated based on texture file. If diffuse texture is not set, FillMaterial instance is being created, using corresponding color. If object has no materials assigned, all it's faces are being added to a single surface. This surface gets WireMaterial with black lines.
After loading objects form the same hierarchy as in the source 3DS-file. Unsupported objects are being represented with Object3D class instances.
Before loading a file you can set values for some class properties, to apply them to creating objects:
- For textured materials:
- repeat – repeating texture while filling polygons;
- smooth – smoothing for upscaled textures;
- blendMode – color blending mode. Value – any constant from flash.display.BlendMode class. It is set to BlendMode.NORMAL by default;
- precision – texture material perspective correction precision rate. You can set any of alternativa.engine3d.materials.TextureMaterialPrecision values here. Default is TextureMaterialPrecision.MEDIUM;
- For 3D-objects you can set mobility values.
3DS stores sizes in inches. To convert them, it is necessary to set units property, which is a coefficient for conversion. For convenience there are following class constants:
- INCHES
- FEET
- MILES
- MILLIMETERS
- CENTIMETERS
- METERS
- KILOMETERS
The units property is set to 1 (INCHES) by default.
// Create loader and set parameters loader = new Loader3DS(); loader.smooth = true; loader.precision = TextureMaterialPrecision.HIGH;
After all necessary loader parameters are set, we can call load() method to import model. We have to set URL of a file as a parameter. All used textures have to lie in the same location as the model. If loader will miss texture file, it will replace it with a stub one and throw exception.
After loading is complete, Event.COMPLETE is being dispatched and content property will contain alternativa.engine3d.core.Object3D class instance, which is a container for all loaded from the file objects.
loader.load("resource/house.3ds");
loader.addEventListener(Event.COMPLETE, onLoadingComplete);
Optimizing loaded objects
Having all the objects loaded from 3DS file, we'll not hurry to put them on the scene. The point is that we can reduce a number of vertices and faces, in order to improve performance. We have some special methods of alternativa.utils.MeshUtils class:
- autoWeldVertices(mesh:Mesh, threshold:Number = 0) – welds vertices with same coordinates (using given threshold);
- autoWeldFaces(mesh:Mesh, angleThreshold:Number = 0, uvThreshold:Number = 0) – unites adjacent faces, if they're co-planar and form convex n-gon. Faces are being united only if they belong to same object surface, and common vertices UV-coordinates are within given threshold. Co-planar criteria is an angle between faces' normals, which has to be within given threshold too.
You can see the process of uniting vertices and faces:



Let's write a code to optimize loaded objects and to put them on the scene:
// Optimizing object geometry private function weldVerticesAndFaces(object:Object3D):void { if (object is Mesh) { MeshUtils.autoWeldVertices(Mesh(object), 0.01); MeshUtils.autoWeldFaces(Mesh(object), 0.01, 0.001); } // Launching procedure for object's children for (var key:* in object.children) { weldVerticesAndFaces(key); } } // Make optimization and add to scene every object in loader.content private function onLoadingComplete(e:Event):void { for (var o:* in loader.content.children) { var object:Object3D = o; weldVerticesAndFaces(object); scene.root.addChild(object); } }
Result
Get all the code in methods and put it in our main class. Compile project, put SWF and resources (model and textures) at the correct locations, launch:
