📄 dae.as
字号:
package org.papervision3d.objects.parsers{ import flash.events.Event; import flash.events.ProgressEvent; import flash.utils.ByteArray; import flash.utils.Dictionary; import flash.utils.getTimer; import org.ascollada.ASCollada; import org.ascollada.core.*; import org.ascollada.fx.*; import org.ascollada.io.DaeReader; import org.ascollada.namespaces.*; import org.ascollada.types.*; import org.papervision3d.Papervision3D; import org.papervision3d.core.animation.*; import org.papervision3d.core.animation.channel.*; import org.papervision3d.core.controller.IObjectController; import org.papervision3d.core.controller.SkinController; import org.papervision3d.core.geom.*; import org.papervision3d.core.geom.renderables.*; import org.papervision3d.core.material.AbstractLightShadeMaterial; import org.papervision3d.core.math.*; import org.papervision3d.core.proto.*; import org.papervision3d.core.render.data.RenderSessionData; import org.papervision3d.events.FileLoadEvent; import org.papervision3d.materials.*; import org.papervision3d.materials.shaders.ShadedMaterial; import org.papervision3d.materials.special.*; import org.papervision3d.materials.utils.*; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.special.Skin3D; /** * @author Tim Knip */ public class DAE extends DisplayObject3D implements IAnimationDataProvider, IAnimatable { use namespace collada; /** Default line color for splines. */ public static var DEFAULT_LINE_COLOR:uint = 0xffff00; /** Default line width for splines */ public static var DEFAULT_LINE_WIDTH:Number = 0; /** Alternative file-extension for TGA images. Default is "png". */ public static var DEFAULT_TGA_ALTERNATIVE:String = "png"; /** */ public var COLLADA:XML; /** */ public var filename:String; /** */ public var fileTitle:String; /** */ public var baseUrl:String; /** Path where the textures should be loaded from. */ public var texturePath:String; /** */ public var parser:DaeReader; /** */ public var document:DaeDocument; /** */ public function get yUp():Boolean { if(this.document) return (this.document.asset.yUp == ASCollada.DAE_Y_UP) else return false; } /** * Constructor. * * @param autoPlay Whether to start the animation automatically. * @param name Optional name for the DAE. */ public function DAE(autoPlay:Boolean=true, name:String=null) { super(name); _autoPlay = autoPlay; _rightHanded = Papervision3D.useRIGHTHANDED; } /** * Plays the animation. * * @param clip Optional clip name. */ public function play(clip:String=null):void { _currentFrame = 0; _currentTime = getTimer(); _isPlaying = (_isAnimated && _channels && _channels.length); } /** * Stops the animation. */ public function stop():void { _isPlaying = false; } /** * Gets the default FPS. */ public function get fps():uint { return 20; } /** * Gets a animation channel by its name. * * @param name * * @return the found channel. */ public function getAnimationChannelByName(name:String):AbstractChannel3D { return null; } /** * Gets all animation channels for a target. * <p>NOTE: when target is null, all channels for this object are returned.</p> * * @param target The target to get the channels for. * * @return Array of AnimationChannel3D. */ public function getAnimationChannels(target:DisplayObject3D=null):Array { var channels:Array = new Array(); if(target == null) { for each(var array:Array in _channelsByTarget) channels = channels.concat(array); } else if(_channelsByTarget[target]) { channels = channels.concat(_channelsByTarget[target]); } else return null; return channels; } /** * Gets animation channels by clip name. * * @param name The clip name * * @return Array of AnimationChannel3D. */ public function getAnimationChannelsByClip(name:String):Array { return null; } /** * Loads the COLLADA. * * @param asset The url, an XML object or a ByteArray specifying the COLLADA file. * @param materials An optional materialsList. */ public function load(asset:*, materials:MaterialsList = null):void { this.materials = materials || new MaterialsList(); buildFileInfo(asset); this.parser = new DaeReader(); this.parser.addEventListener(Event.COMPLETE, onParseComplete); this.parser.addEventListener(ProgressEvent.PROGRESS, onParseProgress); if(asset is XML) { this.COLLADA = asset as XML; this.parser.loadDocument(asset); } else if(asset is ByteArray) { this.COLLADA = new XML(ByteArray(asset)); this.parser.loadDocument(asset); } else if(asset is String) { this.filename = String(asset); this.parser.read(this.filename); } else { throw new Error("load : unknown asset type!"); } } /** * Removes a child. * * @param child The child to remove * * @return The removed child */ override public function removeChild(child:DisplayObject3D):DisplayObject3D { var object:DisplayObject3D = getChildByName(child.name, true); if(object) { var parent:DisplayObject3D = DisplayObject3D(object.parent); if(parent) { var removed:DisplayObject3D = parent.removeChild(object); if(removed) return removed; } } return null; } /** * 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) return; if(this.material === existingMaterial) this.material = material; existingMaterial = this.materials.removeMaterial(existingMaterial); 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. * @param existingMaterial Optional existing material to be replaced. */ public function setChildMaterial(child:DisplayObject3D, material:MaterialObject3D, existingMaterial:MaterialObject3D=null):void { if(!child) return; if(!existingMaterial || child.material === existingMaterial) child.material = material; if(child.geometry && child.geometry.faces) { for each( var triangle:Triangle3D in child.geometry.faces ) { if(!existingMaterial || triangle.material === existingMaterial) 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, true), material); } /** * Project. * * @param parent * @param renderSessionData * * @return Number */ public override function project(parent:DisplayObject3D, renderSessionData:RenderSessionData):Number { // update controllers for each(var controller:IObjectController in _controllers) controller.update(); // update animation if(_isPlaying && _channels) { var secs:Number = _currentTime / 1000; var duration:Number = _endTime - _startTime; var elapsed:Number = (getTimer()/1000) - secs; if(elapsed > duration) { _currentTime = getTimer(); secs = _currentTime / 1000; elapsed = 0; } var time:Number = elapsed / duration; for each(var channel:AbstractChannel3D in _channels) { channel.updateToTime(time); } } return super.project(parent, renderSessionData); } /** * Builds a animation channel for an object. * * @param matrixStackChannel the target object's channel * @param target The target object * @param channel The DaeChannel */ private function buildAnimationChannel(target:DisplayObject3D, channel:DaeChannel):MatrixChannel3D { var node:DaeNode = _objectToNode[target]; if(!node) throw new Error("Couldn't find the targeted object!"); var matrixChannel:MatrixChannel3D = new MatrixChannel3D(target, channel.syntax.targetSID); var transform:DaeTransform = node.findMatrixBySID(channel.syntax.targetSID); if(!transform) { Papervision3D.log("Couldn't find the targeted object's transform: " + channel.syntax.targetSID); return null; } var matrix:Matrix3D; var matrixProp:String; var arrayMember:String; var data:Array; var val:Number; var i:int; if(channel.syntax.isArrayAccess) { arrayMember = channel.syntax.arrayMember.join(""); switch(arrayMember) { case "(0)(0)": matrixProp = "n11"; break; case "(1)(0)": matrixProp = "n12"; break; case "(2)(0)": matrixProp = "n13"; break; case "(3)(0)": matrixProp = "n14"; break; case "(0)(1)": matrixProp = "n21"; break; case "(1)(1)": matrixProp = "n22"; break; case "(2)(1)": matrixProp = "n23"; break; case "(3)(1)": matrixProp = "n24"; break; case "(0)(2)": matrixProp = "n31"; break; case "(1)(2)": matrixProp = "n32"; break; case "(2)(2)": matrixProp = "n33"; break; case "(3)(2)": matrixProp = "n34"; break; default: throw new Error(arrayMember); } } switch(transform.type) { case "matrix": if(channel.syntax.isFullAccess) { for(i = 0; i < channel.input.length; i++) { data = channel.output[i]; matrix = new Matrix3D(data); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); } } else if(channel.syntax.isArrayAccess) { matrix = Matrix3D.clone(target.transform); for(i = 0; i < channel.input.length; i++) { matrix[matrixProp] = channel.output[i]; matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); } } else { throw new Error("Don't know how to handle this channel: " + channel.syntax); } break; case "rotate": if(channel.syntax.isFullAccess) { for(i = 0; i < channel.input.length; i++) { data = channel.output[i]; matrix = Matrix3D.rotationMatrix(data[0], data[1], data[2], data[3] * (Math.PI/180)); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); } } else if(channel.syntax.isDotAccess) { switch(channel.syntax.member) { case "ANGLE": for(i = 0; i < channel.input.length; i++) { var angle:Number = channel.output[i] * (Math.PI/180); matrix = Matrix3D.rotationMatrix(transform.values[0], transform.values[1], transform.values[2], angle); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); } break; default: throw new Error("Don't know how to handle this channel: " + channel.syntax); } } else { throw new Error("Don't know how to handle this channel: " + channel.syntax); } break; case "scale": if(channel.syntax.isFullAccess) { for(i = 0; i < channel.input.length; i++) { data = channel.output[i]; matrix = Matrix3D.scaleMatrix(data[0], data[1], data[2]); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); } } else if(channel.syntax.isDotAccess) { for(i = 0; i < channel.input.length; i++) { val = channel.output[i]; switch(channel.syntax.member) { case "X": matrix = Matrix3D.scaleMatrix(val, 0, 0); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); break; case "Y": matrix = Matrix3D.scaleMatrix(0, val, 0); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); break; case "Z": matrix = Matrix3D.scaleMatrix(0, 0, val); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); break; default: break; } } } else { throw new Error("Don't know how to handle this channel: " + channel.syntax); } break; case "translate": if(channel.syntax.isFullAccess) { for(i = 0; i < channel.input.length; i++) { data = channel.output[i]; matrix = Matrix3D.translationMatrix(data[0], data[1], data[2]); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); } } else if(channel.syntax.isDotAccess) { for(i = 0; i < channel.input.length; i++) { val = channel.output[i]; switch(channel.syntax.member) { case "X": matrix = Matrix3D.translationMatrix(val, 0, 0); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); break; case "Y": matrix = Matrix3D.translationMatrix(0, val, 0); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); break; case "Z": matrix = Matrix3D.translationMatrix(0, 0, val); matrixChannel.addKeyFrame(new AnimationKeyFrame3D("keyframe_" + i, channel.input[i], [matrix])); break; default: break; } } } else { throw new Error("Don't know how to handle this channel: " + channel.syntax); } break; default: throw new Error("Unknown transform type!"); } return matrixChannel; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -