📄 sketchupcollada.as
字号:
package org.papervision3d.objects.parsers{ import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.SecurityErrorEvent; import flash.net.URLLoader; import flash.net.URLRequest; import org.papervision3d.Papervision3D; import org.papervision3d.core.geom.TriangleMesh3D; import org.papervision3d.core.geom.renderables.Triangle3D; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.core.math.Matrix3D; import org.papervision3d.core.math.NumberUV; import org.papervision3d.core.proto.DisplayObjectContainer3D; import org.papervision3d.core.proto.GeometryObject3D; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.events.FileLoadEvent; import org.papervision3d.materials.BitmapFileMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.DisplayObject3D; /** * The Collada class lets you load and parse Collada scenes. * <p/> * Recommended DCC Settings: * <ul><li><b>Maya</b>: * <ul><li>General Export Options * <ul><li>Relative Paths, Triangulate.</li></ul> * <li>Filter Export * <ul><li>Polygon meshes, Normals, Texture Coordinates.</li></ul> * </li></ul> * <li><b>3DS Max</b>: * <ul><li>Standard Options * <ul><li>Relative Paths.</li></ul> * <li>Geometry * <ul><li>Normals, Triangulate.</li></ul> * </li></ul> */ public class SketchupCollada extends DisplayObject3D { /** * Default scaling value for constructor. */ static public var DEFAULT_SCALING :Number = 1; /** * Internal scaling value. */ static private var INTERNAL_SCALING :Number = 100; /** * Whether or not the scene has been loaded. */ public var loaded :Boolean; public var materialsToLoad:int =0; // ___________________________________________________________________________________________________ // N E W // NN NN EEEEEE WW WW // NNN NN EE WW WW WW // NNNNNN EEEE WWWWWWWW // NN NNN EE WWW WWW // NN NN EEEEEE WW WW /** * Creates a new Collada object. * <p/> * The Collada class lets you load and parse a Collada scene. * <p/> * COLLADA is a COLLAborative Design Activity for establishing an interchange file format for interactive 3D applications. * <p/> * COLLADA defines an open standard XML schema for exchanging digital assets among various container software applications that might otherwise store their assets in incompatible formats. * <p/> * COLLADA documents that describe digital assets are XML files, usually identified with a .dae (digital asset exchange) filename extension. * <p/> * @param COLLADA An XML COLLADA object or the filename of the .dae scene to load. * <p/> * @param materials A MaterialsList object. * <p/> * @param scale Scaling factor. * <p/> */ public function SketchupCollada( COLLADA :*, materials :MaterialsList=null, scale :Number=1, initObject :Object=null ) { super(null, null, initObject); this._materials = materials || new MaterialsList(); this._container = this; this.loaded = false; this._scaling = scale || DEFAULT_SCALING; this._scaling *= INTERNAL_SCALING; this._geometries = new Object(); if( COLLADA is XML ) { this.COLLADA = COLLADA; this._filename = ""; buildCollada(); } else if( COLLADA is String ) { this._filename = COLLADA; loadCollada(); } } // _______________________________________________________________________ PRIVATE private function loadCollada():void { this._loader = new URLLoader(); this._loader.addEventListener( Event.COMPLETE, onComplete ); this._loader.addEventListener(IOErrorEvent.IO_ERROR, handleIOError); this._loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleSecurityLoadError); this._loader.addEventListener( ProgressEvent.PROGRESS, handleLoadProgress ); this._loader.load( new URLRequest( this._filename ) ); } private function handleLoadProgress( e:ProgressEvent ):void { var progressEvent:FileLoadEvent = new FileLoadEvent( FileLoadEvent.LOAD_PROGRESS, this._filename, e.bytesLoaded, e.bytesTotal); dispatchEvent( progressEvent ); } private function handleIOError(e:IOErrorEvent):void { trace("COLLADA file load error", e.text); dispatchEvent(new FileLoadEvent(FileLoadEvent.LOAD_ERROR,this._filename,0,0,e.text)); } private function handleSecurityLoadError(e:SecurityErrorEvent):void { trace("COLLADA file security load error", e.text); dispatchEvent(new FileLoadEvent(FileLoadEvent.SECURITY_LOAD_ERROR,this._filename, 0, 0, e.text)); } private function onComplete(evt:Event):void { this.COLLADA = new XML( this._loader.data ); buildCollada(); } // _______________________________________________________________________ private function buildCollada():void { //Reset the number of materials to load. materialsToLoad = 0; default xml namespace = COLLADA.namespace(); // Get up axis this._yUp = (COLLADA.asset.up_axis == "Y_UP"); // Parse first scene var sceneId:String = getId( COLLADA.scene.instance_visual_scene.@url ); var scene:XML = COLLADA.library_visual_scenes.visual_scene.(@id == sceneId)[0]; parseScene( scene ); var fileEvent:FileLoadEvent = new FileLoadEvent( FileLoadEvent.LOAD_COMPLETE, _filename ); this.dispatchEvent( fileEvent ); this.loaded = true; } // _______________________________________________________________________ parseScene private function parseScene( scene:XML ):void { for each( var node:XML in scene.node ) parseNode( node, this._container ); } // _______________________________________________________________________ parseNode private function parseNode( node:XML, parent:DisplayObjectContainer3D ):void { var matrix :Matrix3D = Matrix3D.IDENTITY; //if( ! this._yUp && parent == this._container ) //{ //matrix = Matrix3D.rotationX( Math.PI/2 ); //matrix = Matrix3D.multiply( matrix, Matrix3D.rotationZ( Math.PI ) ); //} var newNode:DisplayObject3D; if( String( node.instance_geometry ) == "" ) newNode = new DisplayObject3D( node.@name ); else newNode = new TriangleMesh3D( null, null, null, node.@name ); var instance :DisplayObject3D = parent.addChild( newNode, node.@name ); var children :XMLList = node.children(); var totalChildren :int = children.length(); for( var i:int = 0; i < totalChildren; i++ ) { var child:XML = children[i]; switch( child.name().localName ) { case "translate": matrix = Matrix3D.multiply( matrix, translateMatrix( getArray( child ) ) ); break; case "rotate": matrix = Matrix3D.multiply( matrix, rotateMatrix( getArray( child ) ) ); break; case "scale": matrix = Matrix3D.multiply( matrix, scaleMatrix( getArray( child ) ) ); break; // Baked transform matrix case "matrix": matrix = Matrix3D.multiply( matrix, bakedMatrix( new Matrix3D( getArray( child ) ) ) ); break; case "node": if(String(child).indexOf("ForegroundColor")==-1) parseNode( child, instance ); //•••••••••••••••••••••••••••••••••••••••••••••• break; case "instance_geometry": // Instance materials if(String(child).indexOf("lines")==-1) { //•••••••••••••••••••••••••••••••••••••• var bindMaterial:Object = new Object(); for each( var instance_material:XML in child..instance_material ) { bindMaterial[ instance_material.@symbol ] = instance_material.@target.split("#")[1]; } // Instance geometry for each( var geometry:XML in child ) { var geoId:String = getId( geometry.@url ); var geo:XML = COLLADA.library_geometries.geometry.(@id == geoId)[0]; parseGeometry( geo, instance, Matrix3D.clone( matrix ), bindMaterial ); } } //••• break; } } instance.copyTransform( matrix ); } // _______________________________________________________________________ parseGeometry private function parseGeometry( geometry:XML, instance:DisplayObject3D, matrix2:Matrix3D=null, bindMaterial:Object=null ):void { var matrix:Matrix3D = Matrix3D.clone( matrix2 ) || Matrix3D.IDENTITY; // TODO: Cleanup // DEBUG //trace( "parseGeometry: " + geometry.@id ); // DEBUG // Semantics var semantics :Object = new Object(); semantics.name = geometry.@id; var faces:Array = semantics.triangles = new Array(); // Multi material var multiMaterial:Boolean = (geometry.mesh.triangles.length() > 1); // Triangles for each( var triangles:XML in geometry.mesh.triangles ) { // Input var field:Array = new Array(); for each( var input:XML in triangles.input ) { semantics[ input.@semantic ] = deserialize( input, geometry ); field.push( input.@semantic ); } var data :Array = triangles.p.split(' '); var len :Number = triangles.@count; var material :String = triangles.@material; // DEBUG //trace( "triangles: " + len ); if(material != "FrontColorNoCulling") addMaterial( instance, material, bindMaterial ); // •••••••••••••••••••••••••••••••••• for( var j:Number = 0; j < len; j++ ) { var t:Object = new Object(); for( var v:Number = 0; v < 3; v++ ) { var fld:String; for( var k:Number = 0; fld = field[k]; k++ ) { if( ! t[ fld ] ) t[ fld ] = new Array(); t[ fld ].push( Number( data.shift() ) ); } t["material"] = material; //multiMaterial? material : null; } faces.push( t ); } } buildObject( semantics, instance, matrix ); } // _______________________________________________________________________ buildObject private function buildObject( semantics:Object, instance:DisplayObject3D, matrix:Matrix3D=null ):void { matrix = matrix || Matrix3D.IDENTITY; // var mesh :Mesh3D = new Mesh3D( null, new Array(), new Array() ) instance.addGeometry( new GeometryObject3D() ); // Vertices var vertices :Array = instance.geometry.vertices = new Array(); var scaling :Number = this._scaling; var accVerts :Number = vertices.length; var semVertices :Array = semantics.VERTEX; var len:Number = semVertices.length; // DEBUG //trace( "Vertices: " + len );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -