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 ) );
             }
         }
     }
 }