📄 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.events.*; import flash.utils.ByteArray; import flash.utils.Dictionary; 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.Papervision3D; 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.*; /** * @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; /** Path where the textures should be loaded from. */ public var texturePath:String; /** ASCollada document. @see org.ascollada.core.DaeDocument */ public var document:DaeDocument; /** Does the collada contain animations? */ public var hasAnimations:Boolean = false; /** An Array of Skin3D. */ public var skins:Array; /** */ public var animate:Boolean; /** */ public function get yUp() : Boolean { return _yUp; } /** * * @param asset * @param async * @return */ public function DAE( async:Boolean = false, animate:Boolean = true ):void { super(); this.animate = animate; _reader = new DaeReader(async); this.name = "DAE_" + this.id; } /** * Clones this DAE. * * @return The clone DAE. */ public function clone():DAE { var dae:DAE = new DAE(); cloneObj( dae, this ); dae.skins = new Array(); for each(var skin:Skin3D in this.skins) { // verify the skin was cloned OK... var clonedSkin:Skin3D = dae.getChildByName(skin.name) as Skin3D; if(!clonedSkin) throw new Error("Clone error! Could not find the cloned skin..."); clonedSkin.joints = new Array(); clonedSkin.skeletons = new Array(); clonedSkin.addController(new SkinController(clonedSkin, _yUp)); dae.skins.push(clonedSkin); clonedSkin.geometry.dirty = true; // verify all joints where cloned OK... for each(var joint:Node3D in skin.joints) { var clonedJoint:Node3D = dae.getChildByName(joint.name) as Node3D; if(!clonedJoint) throw new Error("Clone error! Could not find the cloned joint..."); for each(var ctl:AbstractController in joint.controllers) { if(ctl is SimpleController) { var prop:String = SimpleController(ctl).property; var cctl:SimpleController = new SimpleController(clonedJoint, prop); for(var i:int = 0; i < ctl.frames.length; i++) { var frame:AnimationFrame = ctl.frames[i]; var m:Matrix3D = frame.values[0] as Matrix3D; var frm:AnimationFrame = new AnimationFrame(frame.frame, frame.duration, [Matrix3D.clone(m)], ""); cctl.addFrame(frame); } clonedJoint.addController(cctl); } } clonedSkin.joints.push(clonedJoint); } // verify all skeleton where cloned OK... for each(var skeleton:DisplayObject3D in skin.skeletons) { var clonedSkeleton:DisplayObject3D = dae.getChildByName(skeleton.name); if(!clonedSkeleton) throw new Error("Clone error! Could not find the cloned skeleton..."); clonedSkin.skeletons.push(clonedSkeleton); } } var rootNode:DisplayObject3D = dae.getChildByName("COLLADA_root"); if(rootNode) rootNode.scaleX = -rootNode.scaleX; dae.copyTransform(this.transform); 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); } } /** * Sets the material for a child DisplayObject3D. * * @param child A child DisplayObject3D of this DAE. * @param material The new material for the child. */ public function setChildMaterial( child : DisplayObject3D, material : MaterialObject3D ) : void { if( !child ) return; child.material = material; if(child.geometry && child.geometry.faces) { for each( var triangle:Triangle3D in child.geometry.faces ) triangle.material = material; } } /** * Sets the material for a child DisplayObject3D by the child's name. * * @param childName The name of the DisplayObject3D. * @param material The new material for the child. */ public function setChildMaterialByName( childName : String, material : MaterialObject3D ) : void { setChildMaterial(getChildByName(childName), material); } /**vo * 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 ) { Papervision3D.log("[WARNING] no transform targeted by channel : " + channel.syntax.targetSID); continue; //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); } /** *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -