📄 collada.as.svn-base
字号:
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 Collada 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 Collada( 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":
parseNode( child, instance );
break;
case "instance_geometry":
// Instance materials
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 );
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;
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 );
var i:int;
for( i=0; i < len; i++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -