package away3d.loaders
{
import away3d.containers.*;
import away3d.arcane;
import away3d.core.base.*;
import away3d.core.utils.*;
import away3d.events.LoaderEvent;
import away3d.loaders.data.*;
import away3d.loaders.utils.*;
import away3d.materials.*;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.events.Event;
import flash.utils.ByteArray;
import nochump.util.zip.*;
use namespace arcane;
/**
* File loader for the KMZ 4 file format (exported from Google Sketchup).
*/
public class Kmz extends AbstractParser
{
private var collada:XML;
private var _materialData:MaterialData;
private var _face:Face;
private var kmzFile:ZipFile;
private function parseKmz(datastream:ByteArray, init:Object):void
{
kmzFile = new ZipFile(datastream);
var totalMaterials:int = kmzFile.entries.join("@").split(".jpg").length;
for(var i:int = 0; i < kmzFile.entries.length; i++) {
var entry:ZipEntry = kmzFile.entries[i];
var data:ByteArray = kmzFile.getInput(entry);
if(entry.name.indexOf(".dae")>-1 && entry.name.indexOf("models/")>-1) {
collada = new XML(data.toString());
container = Collada.parse(collada, init);
if (container is Object3DLoader) {
(container as Object3DLoader).parser.container.materialLibrary.loadRequired = false;
(container as Object3DLoader).addOnSuccess(onParseGeometry);
} else {
parseImages();
}
}
}
}
private function onParseGeometry(event:LoaderEvent):void
{
container = event.loader.handle;
parseImages();
}
private function parseImages():void
{
materialLibrary = container.materialLibrary;
materialLibrary.loadRequired = false;
var totalMaterials:int = kmzFile.entries.join("@").split(".jpg").length;
for(var i:int = 0; i < kmzFile.entries.length; i++) {
var entry:ZipEntry = kmzFile.entries[i];
var data:ByteArray = kmzFile.getInput(entry);
if((entry.name.indexOf(".jpg")>-1 || entry.name.indexOf(".png")>-1) && entry.name.indexOf("images/")>-1) {
var _loader:Loader = new Loader();
_loader.name = "../" + entry;
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadBitmapCompleteHandler);
_loader.loadBytes(data);
}
}
}
private function loadBitmapCompleteHandler(e:Event):void {
var loader:Loader = Loader(e.target.loader);
//pass material instance to correct materialData
for each (_materialData in materialLibrary) {
if (_materialData.textureFileName == loader.name) {
_materialData.textureBitmap = Bitmap(loader.content).bitmapData;
_materialData.material = new BitmapMaterial(_materialData.textureBitmap);
for each(_face in _materialData.elements)
_face.material = _materialData.material as ITriangleMaterial;
}
}
}
/**
* Reference container for all materials used in the kmz scene.
*/
public var materialLibrary:MaterialLibrary;
/**
* Container data object used for storing the parsed kmz data structure.
*/
public var containerData:ContainerData;
/**
* Creates a new Kmz object. Not intended for direct use, use the static parse or load methods.
* This loader is only compatible with the kmz 4 googleearth format that is exported from Google Sketchup.
*
* @param datastream The binary zip data of a loaded file.
* @param init [optional] An initialisation object for specifying default instance properties.
*
* @see away3d.loaders.Kmz#parse()
* @see away3d.loaders.Kmz#load()
*/
public function Kmz(data:*, init:Object = null)
{
parseKmz(Cast.bytearray(data), init);
}
/**
* Creates a 3d container object from the raw binary data of a kmz file.
*
* @param data The birnay zip data of a loaded file.
* @param init [optional] An initialisation object for specifying default instance properties.
* @param loader [optional] Not intended for direct use.
*
* @return A 3d container object representation of the kmz file.
*/
public static function parse(data:*, init:Object = null, loader:Object3DLoader = null):ObjectContainer3D
{
return Object3DLoader.parseGeometry(data, Kmz, init).handle as ObjectContainer3D;
}
/**
* Loads and parses a kmz file into a 3d container object.
*
* @param url The url location of the file to load.
* @param init [optional] An initialisation object for specifying default instance properties.
* @return A 3d loader object that can be used as a placeholder in a scene while the file is loading.
*/
public static function load(url:String, init:Object = null):Object3DLoader
{
return Object3DLoader.loadGeometry(url, Kmz, true, init);
}
public override function parseNext():void
{
notifySuccess();
}
}
}