📄 dae.as
字号:
material.registerObject(instance); } mergeGeometries(instance.geometry, geometry.clone(instance), material); } } else { // no geometry, simply create a Joint3D instance = new Joint3D(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; 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); buildGeometries(); _rootNode = this.addChild(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); // may have animations to be parsed. if(document.numQueuedAnimations) { 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 * @param reverseFaces */ private function buildSkin(instance:Skin3D, colladaSkin:DaeSkin, skeletons:Array, reverseFaces:Boolean=true):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); } if(reverseFaces) { for each(var triangle:Triangle3D in skin.faces) { var tmp:Vertex3D = triangle.v0; triangle.v0 = triangle.v2; triangle.v2 = tmp; triangle.uv = [triangle.uv2, triangle.uv1, triangle.uv0]; } } mergeGeometries(instance.geometry, skin.clone(instance)); var yUp:Boolean = (this.document.asset.yUp == ASCollada.DAE_Y_UP); instance.joints = new Array(); instance.skeletons = new Array(); for each(var skeletonId:String in skeletons) instance.skeletons.push(skeletonId) for(var i:int = 0; i < colladaSkin.joints.length; i++) instance.joints.push(colladaSkin.joints[i]); _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:Skin3D, skin:DaeSkin):void { var i:int; var found:Object = new Object(); for(i = 0; i < instance.joints.length; i++) { var jointId:String = instance.joints[i]; if(found[jointId]) continue; var joint:Joint3D = _colladaIDToObject[jointId]; if(!joint) joint = _colladaSIDToObject[jointId]; if(!joint) throw new Error("Couldn't find the joint id = " + jointId); joint = this.getChildByName(joint.name, true) as Joint3D; var vertexWeights:Array = skin.findJointVertexWeightsByIDOrSID(jointId); if(!vertexWeights) throw new Error("Could not find vertex weights for joint with id = " + jointId); joint.vertexWeights = vertexWeights; 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); joint.inverseBindMatrix = new Matrix3D(bindMatrix); instance.joints[i] = joint; found[jointId] = true; } var remove:Array = new Array(); for(i = 0; i < instance.skeletons.length; i++) { var skeletonId:String = instance.skeletons[i]; var skeleton:Joint3D = _colladaIDToObject[skeletonId]; if(!skeleton) skeleton = _colladaSIDToObject[skeletonId]; if(!skeleton) throw new Error("Couldn't find the skeleton with id = " + skeletonId); skeleton = this.getChildByName(skeleton.name, true) as Joint3D; if(!skeleton) throw new Error("Couldn't find the skeleton with id = " + skeletonId); instance.skeletons[i] = skeleton; remove.push(skeleton); } // remove the joints from the scenegraph! for each(var jnt:Joint3D in remove) this.removeChild(skeleton); instance.bindShapeMatrix = new Matrix3D(skin.bind_shape_matrix); } /** * Setup the skin controllers. */ private function linkSkins():void { for(var object:* in _skins) { var instance:Skin3D = object as Skin3D; if(!instance) throw new Error("Not a Skin3D?"); linkSkin(instance, _skins[object]); } } /** * Loads the next material. * * @param event */ private function loadNextMaterial(event:FileLoadEvent=null):void { if(_queuedMaterials.length) { var data:Object = _queuedMaterials.shift(); var url:String = data.url; var symbol:String = data.symbol; var material:BitmapFileMaterial = new BitmapFileMaterial(); material.addEventListener(FileLoadEvent.LOAD_COMPLETE, loadNextMaterial); material.addEventListener(FileLoadEvent.LOAD_ERROR, onMaterialError); material.texture = url; this.materials.addMaterial(material, symbol); } else { dispatchEvent(new FileLoadEvent(FileLoadEvent.COLLADA_MATERIALS_DONE, this.filename)); trace("materials complete!"); buildScene(); } } private function mergeGeometries(target:GeometryObject3D, source:GeometryObject3D, material:MaterialObject3D=null):void { if(material) { for each(var triangle:Triangle3D in source.faces) triangle.material = material; } target.vertices = target.vertices.concat(source.vertices); target.faces = target.faces.concat(source.faces); } /** * 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 { trace( "animations COMPLETE"); buildAnimationChannels(); dispatchEvent(new FileLoadEvent(FileLoadEvent.ANIMATIONS_COMPLETE, this.filename)); } /** * 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); 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 _rootNode:DisplayObject3D; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -