📄 dae.as
字号:
instance = new TriangleMesh3D(null, [], [], node.name); // add all COLLADA geometries to the TriangleMesh3D for each(var geom:DaeInstanceGeometry in node.geometries) { var geometry:GeometryObject3D = _geometries[ geom.url ]; if(!geometry) continue; if(_geometries[ geom.url ] is Lines3D) { instance.addChild(_geometries[ geom.url ]); continue; } var materialInstances:Array = new Array(); if(geom.materials) { for each(var instanceMaterial:DaeInstanceMaterial in geom.materials) { material = this.materials.getMaterialByName(instanceMaterial.symbol); if(material) { // register shaded materials with its object if(material is AbstractLightShadeMaterial || material is ShadedMaterial) material.registerObject(instance); materialInstances.push(material); } } } mergeGeometries(instance.geometry, geometry.clone(instance), materialInstances); } } else { // no geometry, simply create a Joint3D instance = new DisplayObject3D(node.name); } // recurse node instances for(i = 0; i < node.instance_nodes.length; i++) { var dae_node:DaeNode = document.getDaeNodeById(node.instance_nodes[i].url); buildNode(dae_node, instance); } // setup the initial transform instance.copyTransform(buildMatrix(node)); // recurse node children for(i = 0; i < node.nodes.length; i++) buildNode(node.nodes[i], instance); // save COLLADA id, sid _colladaID[instance] = node.id; _colladaSID[instance] = node.sid; _colladaIDToObject[node.id] = instance; _colladaSIDToObject[node.sid] = instance; _objectToNode[instance] = node; instance.flipLightDirection = true; parent.addChild(instance); } /** * Builds the scene. */ private function buildScene():void { if(this.parser.hasEventListener(Event.COMPLETE)) this.parser.removeEventListener(Event.COMPLETE, onParseComplete); if(this.parser.hasEventListener(ProgressEvent.PROGRESS)) this.parser.removeEventListener(ProgressEvent.PROGRESS, onParseProgress); _controllers = new Array(); buildGeometries(); _rootNode = new DisplayObject3D("COLLADA_Scene"); for(var i:int = 0; i < this.document.vscene.nodes.length; i++) { buildNode(this.document.vscene.nodes[i], _rootNode); } // link the skins linkSkins(); this.addChild(_rootNode); if(this.yUp) { } else { _rootNode.rotationX = 90; _rootNode.rotationY = 180; } if(!_rightHanded) _rootNode.scaleX = -_rootNode.scaleX; // animation stuff _currentFrame = 0; _totalFrames = 0; _startTime = _endTime = 0; _channels = new Array(); _isAnimated = false; _isPlaying = false; // may have animations to be parsed. if(document.numQueuedAnimations) { _isAnimated = true; this.parser.addEventListener(Event.COMPLETE, onParseAnimationsComplete); this.parser.addEventListener(ProgressEvent.PROGRESS, onParseAnimationsProgress); this.parser.readAnimations(); } dispatchEvent(new FileLoadEvent(FileLoadEvent.LOAD_COMPLETE, this.filename)); } /** * Builds a skin. * * @param instance * @param colladaSkin * @param skeletons */ private function buildSkin(instance:Skin3D, colladaSkin:DaeSkin, skeletons:Array, node:DaeNode):void { var skin:GeometryObject3D = _geometries[ colladaSkin.source ]; if(!skin) { // geometry can be inside a morph controller var morphController:DaeController = this.document.controllers[colladaSkin.source]; if(morphController && morphController.morph) { var morph:DaeMorph = morphController.morph; // fetch geometry skin = _geometries[morph.source]; // fetch target geometries for(var j:int = 0; j < morph.targets.length; j++) { var targetGeometry:GeometryObject3D = _geometries[morph.targets[j]]; } } if(!skin) throw new Error("no geometry for source: " + colladaSkin.source); } mergeGeometries(instance.geometry, skin.clone(instance)); _skins[ instance ] = colladaSkin; } /** * Builds vertices from a COLLADA mesh. * * @param mesh The COLLADA mesh. @see org.ascollada.core.DaeMesh * * @return Array of Vertex3D */ private function buildVertices(mesh:DaeMesh):Array { var vertices:Array = new Array(); for( var i:int = 0; i < mesh.vertices.length; i++ ) vertices.push(new Vertex3D(mesh.vertices[i][0], mesh.vertices[i][1], mesh.vertices[i][2])); return vertices; } /** * Recursively finds a child by its COLLADA is. * * @param id * @param parent * * @return The found child. */ private function findChildByID(id:String, parent:DisplayObject3D = null):DisplayObject3D { parent = parent || this; if(_colladaID[parent] == id) return parent; for each(var child:DisplayObject3D in parent.children) { var obj:DisplayObject3D = findChildByID(id, child); if(obj) return obj; } return null } /** * Recursively finds a child by its SID. * * @param name * @param parent * * @return The found child. */ private function findChildBySID(sid:String, parent:DisplayObject3D = null):DisplayObject3D { parent = parent || this; if(_colladaSID[parent] == sid) return parent; for each(var child:DisplayObject3D in parent.children) { var obj:DisplayObject3D = findChildBySID(sid, child); if(obj) return obj; } return null } /** * Tests whether a node has a baked transform * * @param node */ private function isBakedMatrix(node:DaeNode):Boolean { if(!node.transforms.length || node.transforms.length > 1) return false; var transform:DaeTransform = node.transforms[0]; return (transform.type == ASCollada.DAE_MATERIAL_ELEMENT); } /** * Setup the skin controllers. */ private function linkSkin(instance:DisplayObject3D, skin:DaeSkin):void { var i:int; var found:Object = new Object(); var controller:SkinController = new SkinController(instance as Skin3D); controller.bindShapeMatrix = new Matrix3D(skin.bind_shape_matrix); controller.joints = new Array(); controller.vertexWeights = new Array(); controller.invBindMatrices = new Array(); for(i = 0; i < skin.joints.length; i++) { var jointId:String = skin.joints[i]; if(found[jointId]) continue; var joint:DisplayObject3D = _colladaIDToObject[jointId]; if(!joint) joint = _colladaSIDToObject[jointId]; if(!joint) throw new Error("Couldn't find the joint id = " + jointId); var vertexWeights:Array = skin.findJointVertexWeightsByIDOrSID(jointId); if(!vertexWeights) throw new Error("Could not find vertex weights for joint with id = " + jointId); var bindMatrix:Array = skin.findJointBindMatrix2(jointId); if(!bindMatrix || bindMatrix.length != 16) throw new Error("Could not find inverse bind matrix for joint with id = " + jointId); controller.joints.push(joint); controller.invBindMatrices.push(new Matrix3D(bindMatrix)); controller.vertexWeights.push(vertexWeights); found[jointId] = true; } _controllers.push(controller); } /** * Setup the skin controllers. */ private function linkSkins():void { _numSkins = 0; for(var object:* in _skins) { var instance:TriangleMesh3D = object as TriangleMesh3D; if(!instance) throw new Error("Not a Skin3D?"); linkSkin(instance, _skins[object]); _numSkins++; } } /** * Loads the next material. * * @param event */ private function loadNextMaterial(event:FileLoadEvent=null):void { if(event) { var previous:BitmapFileMaterial = event.target as BitmapFileMaterial; if(_rightHanded && previous) BitmapMaterialTools.mirrorBitmapX(previous.bitmap); } if(_queuedMaterials.length) { var data:Object = _queuedMaterials.shift(); var url:String = data.url; var symbol:String = data.symbol; url = url.replace(/\.tga/i, "."+DEFAULT_TGA_ALTERNATIVE); var material:BitmapFileMaterial = data.material; material.addEventListener(FileLoadEvent.LOAD_COMPLETE, loadNextMaterial); material.addEventListener(FileLoadEvent.LOAD_ERROR, onMaterialError); material.name = symbol; material.texture = url + "?nc=" + Math.random(); this.materials.addMaterial(material, symbol); } else { dispatchEvent(new FileLoadEvent(FileLoadEvent.COLLADA_MATERIALS_DONE, this.filename)); buildScene(); } } /** * Merge geometries. * * @param target The target geometry to merge to. * @param source The source geometry * @param material Optional material for triangles, only used when a triangle has no material. */ private function mergeGeometries(target:GeometryObject3D, source:GeometryObject3D, materialInstances:Array=null):void { if(materialInstances && materialInstances.length) { var firstMaterial:MaterialObject3D = materialInstances[0]; for each(var triangle:Triangle3D in source.faces) { var correctMaterial:Boolean = false; for each(var material:MaterialObject3D in materialInstances) { if(material === triangle.material) { correctMaterial = true; break; } } triangle.material = correctMaterial ? triangle.material : firstMaterial; } } target.vertices = target.vertices.concat(source.vertices); target.faces = target.faces.concat(source.faces); target.ready = true; } /** * Called when a BitmapMaterial failed to load. * * @param event */ private function onMaterialError(event:Event):void { loadNextMaterial(); } /** * Called when the parser completed parsing animations. * * @param event */ private function onParseAnimationsComplete(event:Event):void { buildAnimationChannels(); _channels = this.getAnimationChannels() || new Array(); _currentFrame = _totalFrames = 0; _startTime = _endTime = 0; for each(var channel:AbstractChannel3D in _channels) { _totalFrames = Math.max(_totalFrames, channel.keyFrames.length); _startTime = Math.min(_startTime, channel.startTime); _endTime = Math.max(_endTime, channel.endTime); } trace( "animations COMPLETE (#channels: " + _channels.length + " #frames: " + _totalFrames + ", startTime: " + _startTime + " endTime: " + _endTime+ ")"); dispatchEvent(new FileLoadEvent(FileLoadEvent.ANIMATIONS_COMPLETE, this.filename)); if(_autoPlay) play(); } /** * Called on parse animations progress. * * @param event */ private function onParseAnimationsProgress(event:ProgressEvent):void { trace( "animations #" + event.bytesLoaded + " of " + event.bytesTotal); } /** * Called when the DaeReader completed parsing. * * @param event */ private function onParseComplete(event:Event):void { var reader:DaeReader = event.target as DaeReader; this.document = reader.document; _textureSets = new Object(); _colladaID = new Dictionary(true); _colladaSID = new Dictionary(true); _colladaIDToObject = new Object(); _colladaSIDToObject = new Object(); _objectToNode = new Object(); _skins = new Dictionary(true); buildMaterials(); loadNextMaterial(); } /** * Called on parsing progress. * * @param event */ private function onParseProgress(event:ProgressEvent):void { } /** * * @param do3d * @param existingMaterial * @param newMaterial */ private function updateMaterials(do3d:DisplayObject3D, existingMaterial:MaterialObject3D, newMaterial:MaterialObject3D):void { existingMaterial.unregisterObject(do3d); // register shaded materials with its object if(newMaterial is AbstractLightShadeMaterial || newMaterial is ShadedMaterial) { newMaterial.registerObject(do3d); } if( do3d.material === existingMaterial ) do3d.material = newMaterial; if( do3d.geometry && do3d.geometry.faces && do3d.geometry.faces.length ) { for each( var triangle:Triangle3D in do3d.geometry.faces ) { if( triangle.material === existingMaterial ) triangle.material = newMaterial; } } for each(var child:DisplayObject3D in do3d.children) updateMaterials(child, existingMaterial, newMaterial); } /** */ private var _colladaID:Dictionary; /** */ private var _colladaSID:Dictionary; /** */ private var _colladaIDToObject:Object; /** */ private var _colladaSIDToObject:Object; /** */ private var _objectToNode:Object; /** */ private var _channelsByTarget:Dictionary; /** */ private var _geometries:Object; /** */ private var _queuedMaterials:Array; /** */ private var _textureSets:Object; /** */ private var _channels:Array; /** */ private var _skins:Dictionary; /** */ private var _numSkins:uint; /** */ private var _rootNode:DisplayObject3D; /** */ private var _currentFrame:int = 0; /** */ private var _currentTime:int; /** */ private var _totalFrames:int = 0; /** */ private var _startTime:Number; /** */ private var _endTime:Number; /** */ private var _isAnimated:Boolean = false; /** */ private var _isPlaying:Boolean = false; /** */ private var _autoPlay:Boolean; /** */ private var _rightHanded:Boolean; /** */ private var _controllers:Array; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -