Class for serialising mesh data to/from an OGRE .mesh file.
This class allows exporters to write OGRE .mesh files easily, and allows the OGRE engine to import .mesh files into instatiated OGRE Meshes.

It's important to realize that this exporter uses OGRE terminology. In this context, 'Mesh' means a top-level mesh structure which can actually contain many SubMeshes, each of which has only one Material. Modelling packages may refer to these differently, for example in Milkshape, it says 'Model' instead of 'Mesh' and 'Mesh' instead of 'SubMesh', but the theory is the same.

Inheritance: Serializer
        /// <summary>
        ///		Loads the mesh data.
        /// </summary>
        protected override void LoadImpl()
        {
            // meshLoadMeter.Enter();

            // load this bad boy if it is not to be manually defined
            if (!isManual) {
                // get the resource data from MeshManager
                Stream data = MeshManager.Instance.FindResourceData(name);
                string extension = Path.GetExtension(name);

                // mesh loading stats
                int before, after;

                // get the tick count before loading the mesh
                before = Environment.TickCount;

                if (extension == ".mesh") {
                    // instantiate a mesh reader and pass in the stream data
                    MeshSerializer meshReader = new MeshSerializer();
                    // import the .mesh file
                    meshReader.ImportMesh(data, this);
                } else if (extension == ".xml") {
                    OgreXmlMeshReader meshReader = new OgreXmlMeshReader(data);
                    // import the .xml file
                    meshReader.Import(this);
                } else if (extension == ".dae") {
                    ColladaMeshReader meshReader = new ColladaMeshReader(data, "tmp");
                    // import the .dae file
                    meshReader.Import(this);
                } else {
                    data.Close();
                    throw new AxiomException("Unsupported mesh format '{0}'", extension);
                }

                // 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", this.name, (after - before));

                // close the stream (we don't need to leave it open here)
                data.Close();
            }

            // prepare the mesh for a shadow volume?
            if (MeshManager.Instance.PrepareAllMeshesForShadowVolumes) {
                if (edgeListsBuilt || autoBuildEdgeLists) {
                    PrepareForShadowVolume();
                }
                if (!edgeListsBuilt && autoBuildEdgeLists) {
                    BuildEdgeList();
                }
            }
            // meshLoadMeter.Exit();
        }
Ejemplo n.º 2
0
		//public override void Preload()
		//{
		//    //if (isPreloaded) {
		//    //    return;
		//    //}

		//    // load this bad boy if it is not to be manually defined
		//    if ( !isManuallyDefined )
		//    {
		//        MeshSerializer serializer = new MeshSerializer();

		//        // get the resource data from MeshManager
		//        Stream data = MeshManager.Instance.FindResourceData( name );

		//        string extension = Path.GetExtension( name );

		//        if ( extension != ".mesh" )
		//        {
		//            data.Close();

		//            throw new AxiomException( "Unsupported mesh format '{0}'", extension );
		//        }

		//        // fetch the .mesh dependency info
		//        serializer.GetDependencyInfo( data, this );

		//        // close the stream (we don't need to leave it open here)
		//        data.Close();
		//    }

		//}

		/// <summary>
		///		Loads the mesh data.
		/// </summary>
		protected override void load()
		{
			// unload this first if it is already loaded
			if ( IsLoaded )
			{
				Unload();
			}

			// I should eventually call Preload here, and then use
			// the preloaded data to make future loads faster, but
			// I haven't finished the Preload stuff yet.
			// Preload();

			// load this bad boy if it is not to be manually defined
			if ( !IsManuallyLoaded )
			{
				var serializer = new MeshSerializer();

				// get the resource data from MeshManager
				var data = ResourceGroupManager.Instance.OpenResource( Name, Group, true, this );

				var extension = Path.GetExtension( Name );

				if ( extension != ".mesh" )
				{
					data.Close();

					throw new AxiomException( "Unsupported mesh format '{0}'", extension );
				}

				// import the .mesh file
				serializer.ImportMesh( data, this );

				// close the stream (we don't need to leave it open here)
				data.Close();
			}

			// prepare the mesh for a shadow volume?
			if ( MeshManager.Instance.PrepareAllMeshesForShadowVolumes )
			{
				if ( this._edgeListsBuilt || this._autoBuildEdgeLists )
				{
					PrepareForShadowVolume();
				}
				if ( !this._edgeListsBuilt && this._autoBuildEdgeLists )
				{
					BuildEdgeList();
				}
			}

			// The loading process accesses lod usages directly, so
			// transformation of user values must occur after loading is complete.

			// Transform user lod values
			foreach ( var mlu in this.meshLodUsageList )
			{
				mlu.Value = this._lodStrategy.TransformUserValue( mlu.UserValue );
			}

			// meshLoadMeter.Exit();
		}
 private static Mesh ReadMesh(Matrix4 transform, string srcDir, string meshFile)
 {
     Stream meshData = new FileStream(srcDir + meshFile, FileMode.Open);
     Mesh mesh = new Mesh(meshFile);
     if (meshFile.EndsWith(".mesh", StringComparison.CurrentCultureIgnoreCase)) {
         MeshSerializer meshReader = new MeshSerializer();
         meshReader.ImportMesh(meshData, mesh);
     } else if (meshFile.EndsWith(".mesh.xml", StringComparison.CurrentCultureIgnoreCase)) {
         OgreXmlMeshReader meshReader = new OgreXmlMeshReader(meshData);
         meshReader.Import(mesh);
     } else if (meshFile.EndsWith(".dae", StringComparison.CurrentCultureIgnoreCase)) {
         string extension = Path.GetExtension(meshFile);
         string baseFile = Path.GetFileNameWithoutExtension(meshFile);
         string basename = meshFile.Substring(0, meshFile.Length - extension.Length);
         ColladaMeshReader meshReader = new ColladaMeshReader(meshData, baseFile);
         // import the .dae file
         meshReader.Import(transform, mesh, null, "idle", basename);
         // materialScript = meshReader.MaterialScript;
     } else {
         meshData.Close();
         string extension = Path.GetExtension(meshFile);
         throw new AxiomException("Unsupported mesh format '{0}'", extension);
     }
     meshData.Close();
     return mesh;
 }
Ejemplo n.º 4
0
 private static void Test( string srcDir, string dstDir, string name )
 {
     MeshSerializer meshReader = new MeshSerializer();
     Stream data = new FileStream( srcDir + name, FileMode.Open );
     // import the .mesh file
     Mesh mesh = new Mesh( "testmesh" );
     meshReader.ImportMesh( data, mesh );
     meshReader.ExportMesh( mesh, dstDir + name );
 }
Ejemplo n.º 5
0
        private static void SetupManualLodLevels( string srcDir, string dstDir, string name,
                                                 List<LodEntry> lodEntries )
        {
            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();

            Mesh mesh = ReadMesh( srcDir, dstDir, name );
            if( mesh.LodLevelCount > 1 )
            {
                log.Warn( "Mesh already contains level of detail information" );
                mesh.RemoveLodLevels();
            }
            List<MeshLodUsage> manualLodList = new List<MeshLodUsage>();
            foreach( LodEntry lodEntry in lodEntries )
            {
                Mesh lodMesh = ReadMesh( dstDir, dstDir, lodEntry.meshFile );
                MeshLodUsage lodUsage = new MeshLodUsage();
                lodUsage.fromSquaredDepth = lodEntry.distance * lodEntry.distance;
                lodUsage.manualMesh = lodMesh;
                lodUsage.manualName = lodMesh.Name;
                manualLodList.Add( lodUsage );
            }
            mesh.AddManualLodEntries( manualLodList );

            MeshSerializer meshWriter = new MeshSerializer();
            meshWriter.ExportMesh( mesh, dstDir + name );
        }
Ejemplo n.º 6
0
        private static void GenerateLodLevels( string srcDir, string dstDir, string name,
                                              int lodlevels, float loddist, float lodpercent )
        {
            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 materialScript = null;

            Mesh mesh = ReadMesh( ref materialScript, Matrix4.Identity, srcDir, dstDir, name );
            if( mesh.LodLevelCount > 1 )
            {
                log.Warn( "Mesh already contains level of detail information" );
                mesh.RemoveLodLevels();
            }
            List<float> lodDistanceList = new List<float>();
            for( int i = 0; i < lodlevels; ++i )
                lodDistanceList.Add( loddist * (i + 1) );
            mesh.GenerateLodLevels( lodDistanceList, ProgressiveMesh.VertexReductionQuota.Proportional, lodpercent );

            MeshSerializer meshWriter = new MeshSerializer();
            meshWriter.ExportMesh( mesh, dstDir + name );
        }
Ejemplo n.º 7
0
        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
        }
Ejemplo n.º 8
0
 /// <summary>
 ///   Loads up a mesh and the associated skeleton, and uses the 
 ///   skeleton to create a joint mesh.
 /// </summary>
 /// <param name="dstDir"></param>
 /// <param name="name"></param>
 private static void BuildSkeletonMesh( string dstDir, string name )
 {
     Mesh mesh = MeshManager.Instance.CreateBoneMesh( name );
     string meshFile = name + ".mesh";
     MeshSerializer meshWriter = new MeshSerializer();
     meshWriter.ExportMesh( mesh, dstDir + meshFile );
 }