public void ReadMorph( MorphController controller, XmlNode node, ColladaMeshInfo meshInfo ) { string morphSource = node.Attributes[ "source" ].Value; if( morphSource.StartsWith( "#" ) ) // strip off the leading '#' morphSource = morphSource.Substring( 1 ); else log.InfoFormat( "Morph source {0} does not start with '#'", morphSource ); if( controller.Target != null ) { string msg = string.Format( "Duplicate morph for controller {0}", controller.Name ); throw new Exception( msg ); } controller.Target = meshInfo.Geometries[ morphSource ]; #if SET_BASE_GEOMETRY controller.Target.BaseGeometrySet = meshInfo.geometries[ morphSource ]; #endif foreach( XmlNode childNode in node.ChildNodes ) { switch( childNode.Name ) { case "source": ReadSource( controller, childNode, meshInfo ); break; case "targets": ReadTargets( controller, childNode, meshInfo ); break; default: DebugMessage( childNode ); break; } } }
public void ReadTargets( MorphController morphController, XmlNode node, ColladaMeshInfo meshInfo ) { foreach( XmlNode childNode in node.ChildNodes ) { switch( childNode.Name ) { case "input": ReadInput( morphController.InputSources, null, childNode, meshInfo ); break; default: DebugMessage( childNode ); break; } } }
// In Collada 1.4, skins have targets (source attribute), but // controllers do not public override void ReadController( XmlNode node, ColladaMeshInfo meshInfo ) { // Set up the current geometry name string controllerName = node.Attributes[ "id" ].Value; // string target = node.Attributes["target"].Value; foreach( XmlNode childNode in node.ChildNodes ) { switch( childNode.Name ) { case "skin": SkinController skinController = new SkinController( controllerName ); // skinController.Target = meshInfo.geometries[target]; meshInfo.Controllers[ controllerName ] = skinController; ReadSkin( skinController, childNode, meshInfo ); break; case "morph": string method = "NORMALIZED"; if( childNode.Attributes[ "method" ] != null ) method = childNode.Attributes[ "method" ].Value; MorphController morphController = new MorphController( controllerName, method ); // morphController.Target = meshInfo.geometries[target]; meshInfo.Controllers[ controllerName ] = morphController; ReadMorph( morphController, childNode, meshInfo ); break; default: DebugMessage( childNode ); break; } } }
protected void BuildInitialPoseInfo( Dictionary<MeshGeometry, List<PoseRef>> initialPoses, Dictionary<MeshGeometry, VertexAnimationTrack> tracks, Animation anim, MorphController morphController ) { InputSource morphTargetSource = morphController.GetInputSourceBySemantic( "MORPH_TARGET" ); InputSource morphWeightSource = morphController.GetInputSourceBySemantic( "MORPH_WEIGHT" ); List<MeshGeometry> initialGeometries = morphController.Target; for( int geoIndex = 0; geoIndex < initialGeometries.Count; ++geoIndex ) { MeshGeometry geometry = initialGeometries[ geoIndex ]; // These geometry.Id are the submesh names (e.g. head01-mesh.0) for( ushort i = 0; i < m_AxiomMesh.SubMeshCount; ++i ) { SubMesh subMesh = m_AxiomMesh.GetSubMesh( i ); if( subMesh.Name != geometry.Id ) continue; VertexData vData = null; ushort target; if( subMesh.useSharedVertices ) { target = 0; vData = m_AxiomMesh.SharedVertexData; } else { target = (ushort) (i + 1); vData = subMesh.vertexData; } VertexAnimationTrack track = anim.CreateVertexTrack( target, vData, VertexAnimationType.Pose ); tracks[ geometry ] = track; // This is the initial set of influences on the geometry List<PoseRef> initialPoseInfo = new List<PoseRef>(); initialPoses[ geometry ] = initialPoseInfo; for( int k = 0; k < morphTargetSource.Accessor.Count; ++k ) { // morphTargetName is the id of the mesh we are blending in (e.g. head02-mesh) string morphTargetName = (string) morphTargetSource.Accessor.GetParam( "MORPH_TARGET", k ); float influence = (float) morphWeightSource.Accessor.GetParam( "MORPH_WEIGHT", k ); GeometrySet morphDest = Geometries[ morphTargetName ]; // Get the pose index for the target submesh // First find the PoseInfo object that is about this combination PoseInfo poseInfo = GetPoseInfo( morphController.Target, morphDest ); // Now that I have the pose info for this combination, // I still need to find the pose index for the portion // that is associated with my MeshGeometry (instead of // the GeometrySet). Since I added these in order, I // should be able to retrieve it in order as well. ushort poseIndex = (ushort) poseInfo.poseIndices[ geoIndex ]; initialPoseInfo.Add( new PoseRef( poseIndex, influence ) ); } } } }