/// <summary> /// Generic load, called by SkeletonManager. /// </summary> protected override void load() { if ( IsLoaded ) { return; } LogManager.Instance.Write( "Skeleton: Loading '{0}'...", Name ); // load the skeleton file var data = ResourceGroupManager.Instance.OpenResource( Name, Group, true, this ); // instantiate a new skeleton reader var reader = new OgreSkeletonSerializer(); reader.ImportSkeleton( data, this ); var extension = Path.GetExtension( Name ); //TODO: Load any linked skeletons //LinkedSkeletonAnimSourceList::iterator i; //for (i = mLinkedSkeletonAnimSourceList.begin(); // i != mLinkedSkeletonAnimSourceList.end(); ++i) //{ // i->pSkeleton = SkeletonManager::getSingleton().load( // i->skeletonName, mGroup); //} }
/// <summary> /// Loads the mesh data. /// </summary> /// <summary> /// Generic load, called by SkeletonManager. /// </summary> public override void Load() { if (isLoaded) { Unload(); isLoaded = false; } skeletonLoadMeter.Enter(); LogManager.Instance.Write("Skeleton: Loading '{0}'...", name); // load the skeleton file Stream data = SkeletonManager.Instance.FindResourceData(name); string extension = Path.GetExtension(name); if (extension == ".skeleton") { // instantiate a new skeleton reader OgreSkeletonSerializer reader = new OgreSkeletonSerializer(); reader.ImportSkeleton(data, this); } else if (extension == ".xml") { // instantiate a new skeleton reader OgreXmlSkeletonReader reader = new OgreXmlSkeletonReader(data); reader.Import(this); } else { data.Close(); throw new Exception("Unsupported skeleton file format '" + extension + "'"); } data.Close(); isLoaded = true; skeletonLoadMeter.Exit(); }
/// <summary> /// Utility method to merge animations from other files into a single skeleton /// </summary> /// <param name="srcDir">the directory from which the new animations will be loaded</param> /// <param name="dstDir">the directory to which the modified skeleton will be saved</param> /// <param name="skelFile">the name of the file to which the modified skeleton will be written</param> /// <param name="transform">the transform to apply to the skeleton and animations</param> /// <param name="skeleton">the original skeleton</param> /// <param name="animations">the list of animations</param> private static void AddAnimations( string srcDir, string dstDir, string skelFile, Matrix4 transform, Skeleton skeleton, List<AnimationEntry> animations ) { // mesh loading stats int before, after; // get the tick count before loading the mesh before = Environment.TickCount; foreach( AnimationEntry entry in animations ) { Mesh mesh = new Mesh( "Mesh" ); Stream data = new FileStream( srcDir + entry.animation_file, FileMode.Open ); ColladaMeshReader meshReader = new ColladaMeshReader( data, null ); // import the .dae file meshReader.Import( transform, mesh, skeleton, entry.animation_name, null ); // close the stream (we don't need to leave it open here) data.Close(); } // get the tick count after loading the mesh after = Environment.TickCount; // record the time elapsed while loading the mesh log.InfoFormat( "Mesh: took {0}ms", (after - before) ); //// prepare the mesh for a shadow volume? //if (MeshManager.Instance.PrepareAllMeshesForShadowVolumes) { // if (edgeListsBuilt || autoBuildEdgeLists) { // PrepareForShadowVolume(); // } // if (!edgeListsBuilt && autoBuildEdgeLists) { // BuildEdgeList(); // } //} OgreSkeletonSerializer skelWriter = new OgreSkeletonSerializer(); skelWriter.ExportSkeleton( skeleton, dstDir + skelFile ); }
private static Skeleton ReadSkeleton( Matrix4 transform, string srcDir, string skelFile ) { Stream skelData = new FileStream( srcDir + skelFile, FileMode.Open ); Skeleton skeleton = new Skeleton( skelFile ); if( skelFile.EndsWith( ".skeleton" ) ) { OgreSkeletonSerializer skelReader = new OgreSkeletonSerializer(); skelReader.ImportSkeleton( skelData, skeleton ); } else if( skelFile.EndsWith( ".skeleton.xml" ) ) { OgreXmlSkeletonReader skelReader = new OgreXmlSkeletonReader( skelData ); skelReader.Import( skeleton ); } else { skelData.Close(); string extension = Path.GetExtension( skelFile ); throw new AxiomException( "Unsupported skeleton format '{0}'", extension ); } skelData.Close(); return skeleton; }
private static void ConvertFile( string srcDir, string dstDir, string name, Matrix4 transform, bool build_tangents, bool extract_collision_volumes, bool optimize_mesh, string skeleton_file ) { if( String.IsNullOrEmpty( name ) ) { // TODO: It would be better to catch this while parsing command args, but // that's a bit too hairy for now. This will at least inform the user. throw new ArgumentException( "No file named for conversion" ); } string dir = string.Empty; string path = string.Empty; SplitPath( ref dir, ref path, name ); if( srcDir == string.Empty ) srcDir = dir; if( dstDir == string.Empty ) dstDir = dir; name = path; // get the resource data from MeshManager string extension = Path.GetExtension( name ).ToLower(); string baseFile = Path.GetFileNameWithoutExtension( name ); if( baseFile.EndsWith( ".mesh" ) ) baseFile = baseFile.Substring( 0, baseFile.Length - 5 ); string baseSkeletonName = null; if( skeleton_file != null ) baseSkeletonName = Path.GetFileName( skeleton_file ); // mesh loading stats int before, after; // get the tick count before loading the mesh before = Environment.TickCount; string materialScript = null; Mesh mesh = ReadMesh( ref materialScript, transform, srcDir, dstDir, name ); if( optimize_mesh ) mesh = MeshUtility.CopyMesh( mesh ); // get the tick count after loading the mesh after = Environment.TickCount; // record the time elapsed while loading the mesh log.InfoFormat( "Mesh: Loaded '{0}', took {1}ms", mesh.Name, (after - before) ); // Build tangent vectors if( build_tangents ) { log.Info( "Building tangent vectors from uv map" ); MeshHelper.BuildTangentVectors( mesh ); } if( extract_collision_volumes ) { log.InfoFormat( "Extracting collision volumes from '{0}'", mesh.Name ); CVExtractor.ExtractCollisionShapes( mesh, dstDir + baseFile ); } //// prepare the mesh for a shadow volume? //if (MeshManager.Instance.PrepareAllMeshesForShadowVolumes) { // if (edgeListsBuilt || autoBuildEdgeLists) { // PrepareForShadowVolume(); // } // if (!edgeListsBuilt && autoBuildEdgeLists) { // BuildEdgeList(); // } //} // Allow them to override the skeleton reference of the mesh if( baseSkeletonName != null ) mesh.SkeletonName = baseSkeletonName; string meshFile = baseFile + ".mesh"; MeshSerializer meshWriter = new MeshSerializer(); meshWriter.ExportMesh( mesh, dstDir + meshFile ); // If it was a .dae file, we will need to export the material and skeleton as well if( extension != ".dae" && extension != ".kmz" ) return; if( materialScript != null ) { string materialFile = baseFile + ".material"; Stream materialData = new FileStream( dstDir + materialFile, FileMode.Create ); StreamWriter materialWriter = new StreamWriter( materialData ); materialWriter.Write( materialScript ); materialWriter.Close(); } if( mesh.Skeleton == null ) return; #if USE_XML string skelFile = baseFile + ".skeleton.xml"; Stream skelData = new FileStream(dstDir + skelFile, FileMode.Create); OgreXmlSkeletonWriter skelWriter = new OgreXmlSkeletonWriter(skelData); skelWriter.Export(mesh.Skeleton); skelData.Close(); #else // DEBUG foreach( AttachmentPoint socket in mesh.Skeleton.AttachmentPoints ) { log.InfoFormat( "Created attachment point with parent {0}", socket.ParentBone ); log.InfoFormat( " Relative Position: {0}", socket.Position ); log.InfoFormat( " Relative Up: {0}", socket.Orientation * Vector3.UnitZ ); Bone bone = mesh.Skeleton.GetBone( socket.ParentBone ); Vector3 derivedPos = bone.DerivedPosition + socket.Position; Vector3 derivedUp = socket.Orientation * bone.DerivedOrientation * Vector3.UnitZ; log.InfoFormat( " Absolute Position: {0}", derivedPos ); log.InfoFormat( " Absolute Up: {0}", derivedUp ); } string skelFile = baseFile + ".skeleton"; OgreSkeletonSerializer skelWriter = new OgreSkeletonSerializer(); skelWriter.ExportSkeleton( mesh.Skeleton, dstDir + skelFile ); #endif }
/// <summary> /// Utility method to add attachment points to an existing skeleton /// </summary> /// <param name="dstDir">the directory to which the modified skeleton will be saved</param> /// <param name="skelFile">the name of the file to which the modified skeleton will be written</param> /// <param name="skeleton">the original skeleton</param> /// <param name="attachPoints">the list of attachment points</param> private static void AddAttachments( string dstDir, string skelFile, Skeleton skeleton, List<AttachmentPointNode> attachPoints ) { if( skeleton.AttachmentPoints.Count > 0 && attachPoints.Count != skeleton.AttachmentPoints.Count ) log.WarnFormat( "Skeleton attachment points count ({0}) does not match new count ({1})", skeleton.AttachmentPoints.Count, attachPoints.Count ); foreach( AttachmentPointNode attachPoint in attachPoints ) { Quaternion rotate; Vector3 translate, scale; Matrix4 transform = attachPoint.Transform; Matrix4.DecomposeMatrix( ref transform, out translate, out rotate, out scale ); Bone parentBone = skeleton.GetBone( attachPoint.ParentBone ); bool isDup = false; foreach( AttachmentPoint tmp in skeleton.AttachmentPoints ) if( tmp.Name == attachPoint.Name ) isDup = true; if( isDup ) continue; skeleton.CreateAttachmentPoint( attachPoint.Name, parentBone.Handle, rotate, translate ); } OgreSkeletonSerializer skelWriter = new OgreSkeletonSerializer(); skelWriter.ExportSkeleton( skeleton, dstDir + skelFile ); }
/// <summary> /// Generic load, called by SkeletonManager. /// </summary> protected override void LoadImpl() { LogManager.Instance.Write("Skeleton: Loading '{0}'...", name); skeletonLoadMeter.Enter(); // load the skeleton file Stream data = SkeletonManager.Instance.FindResourceData(name); OgreSkeletonSerializer reader = new OgreSkeletonSerializer(); reader.ImportSkeleton(data, this); // TODO: linkedSkeletonAnimSourceList data.Close(); skeletonLoadMeter.Exit(); }