📄 dae.as
字号:
/*
* PAPER ON ERVIS NPAPER ISION PE IS ON PERVI IO APER SI PA
* AP VI ONPA RV IO PA SI PA ER SI NP PE ON AP VI ION AP
* PERVI ON PE VISIO APER IONPA RV IO PA RVIS NP PE IS ONPAPE
* ER NPAPER IS PE ON PE ISIO AP IO PA ER SI NP PER
* RV PA RV SI ERVISI NP ER IO PE VISIO AP VISI PA RV3D
* ______________________________________________________________________
* papervision3d.org + blog.papervision3d.org + osflash.org/papervision3d
*
* Copyright 2006 (c) Carlos Ulloa Matesanz, noventaynueve.com.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package org.papervision3d.objects.parsers
{
import flash.display.BitmapData;
import flash.events.*;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.Timer;
import org.papervision3d.materials.shaders.FlatShader;
import org.papervision3d.materials.shaders.GouraudShader;
import org.papervision3d.materials.shaders.LightShader;
import org.papervision3d.materials.shaders.PhongShader;
import org.papervision3d.materials.shaders.ShadedMaterial;
import org.papervision3d.materials.shaders.Shader;
import org.papervision3d.Papervision3D;
import org.ascollada.ASCollada;
import org.ascollada.core.*;
import org.ascollada.fx.*;
import org.ascollada.io.DaeReader;
import org.ascollada.types.*;
import org.ascollada.utils.Logger;
import org.papervision3d.core.*;
import org.papervision3d.core.animation.controllers.*;
import org.papervision3d.core.animation.core.*;
import org.papervision3d.core.geom.*;
import org.papervision3d.core.geom.renderables.*;
import org.papervision3d.core.math.*;
import org.papervision3d.core.proto.*;
import org.papervision3d.events.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.shadematerials.*;
import org.papervision3d.materials.special.*;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.parsers.ascollada.Node3D;
import org.papervision3d.objects.parsers.ascollada.Skin3D;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.objects.parsers.ascollada.*;
import org.papervision3d.lights.PointLight3D;
/**
* @author Tim Knip
*/
public class DAE extends DisplayObject3D
{
/** Default scale, used when no scale was set. */
public static var DEFAULT_SCALE:Number = 100;
/** Full filename. */
public var filename:String;
/** File title. */
public var fileTitle:String;
/** Base url. */
public var baseUrl:String;
/** ASCollada document. @see org.ascollada.core.DaeDocument */
public var document:DaeDocument;
/** Does the collada contain animations? */
public var hasAnimations:Boolean = false;
/** The first skin found in the file. */
public var skin:Skin3D;
/**
*
* @param asset
* @param async
* @return
*/
public function DAE( async:Boolean = false ):void
{
super();
_reader = new DaeReader(async);
this.name = "DAE_" + this.id;
}
/**
* Sets the 3D scale as applied from the registration point of the object.
*/
override public function set scale( scale:Number ):void
{
super.scaleX = scale;
super.scaleY = scale;
super.scaleZ = -scale;
_loadScaleSet = true;
}
/**
* Gets the 3D scale as applied from the registration point of the object.
*/
override public function get scale():Number
{
if( super.scaleX == super.scaleY && super.scaleX == -super.scaleZ )
return super.scaleX;
else
return NaN;
}
/**
* Gets the scale along the local Z axis as applied from the registration point of the object.
*/
override public function get scaleZ():Number
{
return super.scaleZ;
}
/**
* Sets the scale along the local Z axis as applied from the registration point of the object.
*/
override public function set scaleZ( scale:Number ):void
{
super.scaleZ = -scale;
_loadScaleSet = true;
}
/**
* Clones this DAE. NOTE: only works for simple dae's. Skinning, animation, etc. is still unsupported.
*
* @return The clone DAE.
*/
public function clone():DAE
{
var dae:DAE = new DAE();
cloneObj( dae, this._rootNode );
_numClones++;
return dae;
}
/**
* Loads a Collada file from url, xml or bytearray.
*
* @param asset Url, XML or ByteArray
* @param materials Optional MaterialsList.
*/
public function load(asset:*, materials:MaterialsList = null ):void
{
this.materials = materials || new MaterialsList();
this.buildFileInfo(asset);
_asset = asset;
if( _asset is ByteArray || _asset is XML )
{
if( !this._reader.hasEventListener(Event.COMPLETE) )
this._reader.addEventListener(Event.COMPLETE, buildScene);
this._reader.loadDocument(_asset);
}
else
{
doLoad( String(_asset) );
}
}
/**
*
* @param url
* @return
*/
protected function doLoad( url:String ):void
{
this.filename = url;
_reader.addEventListener( Event.COMPLETE, buildScene );
_reader.addEventListener( ProgressEvent.PROGRESS, loadProgressHandler );
_reader.addEventListener( IOErrorEvent.IO_ERROR, handleIOError,false, 0, true );
_reader.read(filename);
}
/**
* Gets a child by name recursively.
*
* @param name
* @return
*/
override public function getChildByName( name:String ):DisplayObject3D
{
return findChildByName(this, name);
}
/**
* Replaces a material by its name.
*
* @param material
* @param name
* @return
*/
public function replaceMaterialByName( material:MaterialObject3D, name:String ):void
{
if( !this.materials )
{
return;
}
var existingMaterial:MaterialObject3D = this.materials.getMaterialByName(name);
if( existingMaterial )
{
if( this.material === existingMaterial )
this.material = material;
existingMaterial = this.materials.removeMaterial(existingMaterial);
existingMaterial.unregisterObject(this);
material = this.materials.addMaterial(material, name);
updateMaterials(this, existingMaterial, material);
}
}
/**
* Bakes all transforms of a joint into single matrices.
*
* @param joint
* @param channels
* @return
*/
private function bakeJointMatrices( joint:Node3D, keys:Array, channels:Array ):Array
{
var matrices:Array = new Array();
for( var i:int = 0; i < keys.length; i++ )
{
var matrix:Matrix3D = Matrix3D.IDENTITY;
for( var j:int = 0; j < joint.transforms.length; j++ )
{
var transform:DaeTransform = joint.transforms[j];
// check for a key at this time
var m:Matrix3D = findChannelMatrix(channels, transform.sid, keys[i]);
if( m )
matrix = Matrix3D.multiply(matrix, m);
else
matrix = Matrix3D.multiply(matrix, new Matrix3D(transform.matrix));
}
matrices.push(matrix);
}
return matrices;
}
/**
*
* @param joint
* @return
*/
private function buildAnimations( node:DisplayObject3D ):void
{
var joint:Node3D = node as Node3D;
var channels:Array = null;
if( joint )
{
channels = findAnimationChannelsByID(joint.daeSID);
if( !channels.length )
channels = findAnimationChannelsByID(joint.daeID);
}
if( channels && channels.length )
{
var keys:Array = buildAnimationKeys(channels);
var baked:Boolean = false;
for( var i:int = 0; i < channels.length; i++ )
{
var channel:DaeChannel = channels[i];
// fetch the transform this channel is targeting
var transform:DaeTransform = findTransformBySID(joint, channel.syntax.targetSID);
if( !transform )
throw new Error( "no transform targeted by channel : " + channel.syntax.targetSID );
// build animation matrices (Array) from channel outputs
var matrices:Array = transform.buildAnimatedMatrices(channel);
// #keys and #matrices *should* be equal
if( matrices.length != channel.input.length )
continue;
//throw new Error( "matrices.length != channel.input.length" );
channel.output = matrices;
if( channels.length == 1 && transform.type == ASCollada.DAE_MATRIX_ELEMENT )
{
// dealing with a matrix node, no need to bake!
try
{
buildAnimationController(joint, keys, matrices);
}
catch( e:Error )
{
Logger.error( "[ERROR] " + joint.name + "\n" + channel.syntax );
}
baked = true;
break;
}
}
if( !baked )
{
// need to bake matrices
var ms:Array = bakeJointMatrices(joint, keys, channels);
joint.copyTransform(ms[0]);
buildAnimationController(joint, keys, ms);
}
}
for each( var child:DisplayObject3D in node.children )
buildAnimations( child );
}
/**
*
* @param joint
* @param keys
* @param matrices
* @return
*/
private function buildAnimationController( joint:Node3D, keys:Array, matrices:Array ):void
{
var mats:Array = new Array(matrices.length);
var ctl:SimpleController = new SimpleController(joint, SimpleController.TRANSFORM);
for(var i:int = 0; i < matrices.length; i++)
{
var j:int = (i+1) % matrices.length;
mats[i] = matrices[i] is Matrix3D ? matrices[i] : new Matrix3D(matrices[i]);
var keyframe0:int = AnimationEngine.secondsToFrame(keys[i]);
var keyframe1:int = AnimationEngine.secondsToFrame(keys[j]);
var duration:uint = j > 0 ? keyframe1 - keyframe0 : 10;
var frame:AnimationFrame = new AnimationFrame(keyframe0, duration, [mats[i]]);
ctl.addFrame(frame);
}
joint.addController(ctl);
}
/**
*
* @param channels
* @return
*/
private function buildAnimationKeys( channels:Array ):Array
{
var keys:Array = new Array();
var tmp:Array = new Array();
var obj:Object = new Object();
var i:int, j:int;
for( i = 0; i < channels.length; i++ )
{
var channel:DaeChannel = channels[i];
for( j = 0; j < channel.input.length; j++ )
{
if( !(obj[ channel.input[j] ]) )
{
obj[ channel.input[j] ] = true;
tmp.push( {time:channel.input[j]} );
}
}
}
tmp.sortOn("time", Array.NUMERIC);
for( i = 0; i < tmp.length; i++ )
keys.push( tmp[i].time );
return keys;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -