public void TestImportFromFile() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\sphere.obj"); AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(55.0f)); importer.Scale = .5f; importer.XAxisRotation = 25.0f; importer.YAxisRotation = 50.0f; LogStream.IsVerboseLoggingEnabled = true; Assert.IsTrue(importer.ContainsConfig(NormalSmoothingAngleConfig.NormalSmoothingAngleConfigName)); importer.RemoveConfigs(); Assert.IsFalse(importer.ContainsConfig(NormalSmoothingAngleConfig.NormalSmoothingAngleConfigName)); importer.SetConfig(new NormalSmoothingAngleConfig(65.0f)); importer.SetConfig(new NormalSmoothingAngleConfig(22.5f)); importer.RemoveConfig(NormalSmoothingAngleConfig.NormalSmoothingAngleConfigName); Assert.IsFalse(importer.ContainsConfig(NormalSmoothingAngleConfig.NormalSmoothingAngleConfigName)); importer.SetConfig(new NormalSmoothingAngleConfig(65.0f)); Scene scene = importer.ImportFile(path, PostProcessPreset.TargetRealTimeMaximumQuality); Assert.IsNotNull(scene); Assert.IsTrue((scene.SceneFlags & SceneFlags.Incomplete) != SceneFlags.Incomplete); }
/// <summary> /// Imports an Assimp scene with default settings. /// </summary> /// <param name="path"></param> /// <returns></returns> public static Scene ImportScene(string path) { using (var aiContext = new AssimpContext()) { aiContext.SetConfig(new Assimp.Configs.VertexBoneWeightLimitConfig(4)); aiContext.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false)); return(aiContext.ImportFile(path, PostProcessSteps.FindDegenerates | PostProcessSteps.FindInvalidData | PostProcessSteps.FlipUVs | PostProcessSteps.ImproveCacheLocality | PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.LimitBoneWeights | PostProcessSteps.SplitByBoneCount | PostProcessSteps.Triangulate | PostProcessSteps.ValidateDataStructure | PostProcessSteps.GenerateUVCoords | PostProcessSteps.GenerateSmoothNormals)); } }
private void LoadModel(string fileName) { string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets", fileName); using (AssimpContext importer = new AssimpContext()) { try { importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); Scene scene = importer.ImportFile(path, PostProcessPreset.TargetRealTimeQuality | PostProcessSteps.FlipWindingOrder); if (scene != null && scene.HasMeshes) { Console.WriteLine($"Loading {fileName}"); } else { Console.WriteLine($"ERROR: Failed to load {fileName}"); return; } ProcessNode(scene.RootNode, scene); JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize; settings.Formatting = Formatting.Indented; string modelData = JsonConvert.SerializeObject(meshes, settings); System.IO.File.WriteAllText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets", fileName + ".json"), modelData); Console.WriteLine($"Finished loading {fileName}"); } catch (Exception e) { Console.WriteLine($"ERROR: Somthing went wrong while loading the mesh {fileName}. " + e.Message); } } }
public ModelObject(string tag, string fileName, string shaderType) { m_ShaderType = shaderType; m_Tag = tag; Scene model; AssimpContext importer = new AssimpContext(); importer.SetConfig(new Assimp.Configs.NormalSmoothingAngleConfig(66.0f)); model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality); m_Geometry = new Geometry[model.MeshCount]; m_NumberOfMeshes = m_Geometry.Length; int count = 0; foreach (var item in model.Meshes) { List <Vector3D[]> vertList = new List <Vector3D[]> { item.Vertices.ToArray(), item.TextureCoordinateChannels[0].ToArray(), item.Normals.ToArray(), item.BiTangents.ToArray(), item.Tangents.ToArray() }; m_Geometry[count] = new Geometry(vertList, item.GetIndices(), item.VertexCount); count++; } }
/// <summary> /// Loads an Assimp Scene from Stream /// </summary> /// <param name="s">Stream</param> /// <param name="hint">File extension(obj, fbx, ...)</param> /// <returns></returns> internal static Scene LoadInternalAssimpScene(Stream s, string hint = "") { AssimpContext context = new AssimpContext(); context.SetConfig(new NormalSmoothingAngleConfig(66)); return(context.ImportFileFromStream(s, hint)); }
public Model LoadFromFile(string path) { AssimpContext Importer = new AssimpContext(); Importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); String fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), path); modelDirPath = Path.GetDirectoryName(fileName); //Scene scene = Importer.ImportFileFromStream(stream); Assimp.Scene scene = Importer.ImportFile( fileName, PostProcessSteps.FindDegenerates | PostProcessSteps.FindInvalidData | PostProcessSteps.FlipUVs | // Required for Direct3D PostProcessSteps.FlipWindingOrder | // Required for Direct3D PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.ImproveCacheLocality | PostProcessSteps.OptimizeMeshes | PostProcessSteps.Triangulate ); _meshes = new List <Mesh>(); ProcessNode(scene.RootNode, scene); return(new Model(path, ref _meshes)); }
protected bool CreateMesh(string sFullPath) { // Console.WriteLine("Create MEsh:" + sFullPath); AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(35.0f)); try { Scene _modelScene = importer.ImportFile(sFullPath, PostProcessSteps.Triangulate); processNode(_modelScene.RootNode, _modelScene, this); //ComputeBoundingBox(); ComputeBoundingBox(_modelScene); BoundingBox.P1 = m_sceneMin; BoundingBox.P2 = m_sceneMax; } catch (Exception e) { Globals.Log(this, e.Message); Console.WriteLine(e.Message); if (e.InnerException != null) { Console.WriteLine(e.InnerException.Message); } return(false); } return(true); }
/// <summary> /// Loads a model with assimp /// </summary> /// <param name="stream">the input stream for assimp</param> /// <returns></returns> internal static List <Mesh> LoadModel(Stream stream) { AssimpContext context = new AssimpContext(); context.SetConfig(new NormalSmoothingAngleConfig(66)); return(LoadAssimpScene(context.ImportFileFromStream(stream), "")); }
public void Load(string sPath) { Filename = sPath; string sFullPath = Path.Combine(Globals.ResourcePath, sPath); //string sFullPath = sPath; if (!File.Exists(sFullPath)) { Console.WriteLine("File:" + sFullPath + " not found"); return; } AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); try { _modelScene = importer.ImportFile(sFullPath); processNode(_modelScene.RootNode, _modelScene, this); ComputeBoundingBox(); } catch (Exception e) { Globals.Log(this, e.Message); Console.WriteLine(e.Message); if (e.InnerException != null) { Console.WriteLine(e.InnerException.Message); } } }
private AssimpContext GetImporter() { AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); return(importer); }
private void ConvertSceneC() { Console.WriteLine("Thread C: Starting convert."); AssimpContext importer = new AssimpContext(); String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); String outputPath = Path.Combine(TestHelper.RootPath, "TestFiles\\duck2.obj"); new ConsoleLogStream("Thread C:").Attach(); importer.SetConfig(new NormalSmoothingAngleConfig(55.0f)); importer.SetConfig(new FavorSpeedConfig(true)); Console.WriteLine("Thread C: Converting"); ExportDataBlob blob = importer.ConvertFromFileToBlob(path, "obj"); Console.WriteLine("Thread C: Done converting"); }
public Task <MeshData <VertexPositionNormal> > Import(Stream assetData) { var importer = new AssimpContext(); importer.SetConfig(new SortByPrimitiveTypeConfig(PrimitiveType.Polygon | PrimitiveType.Line)); _scene = importer.ImportFileFromStream(assetData, PostProcessSteps); ComputeBoundingBox(); var vertices = new List <IVertexBufferDescription>(); var indices = new List <ushort>(); foreach (var mesh in _scene.Meshes) { vertices.AddRange(mesh.Vertices.Select((vertex, i) => new VertexPositionNormal(FromVector(vertex), FromVector(mesh.Normals[i])) as IVertexBufferDescription)); indices.AddRange(mesh.GetUnsignedIndices().Cast <ushort>()); } var meshData = new MeshData <VertexPositionNormal>( _scene.RootNode.Name, new VertexBuffer <VertexPositionNormal>(vertices.ToArray(), indices.ToArray())); return(Task.FromResult(meshData)); }
public static Assimp.Scene Load(string fileName) { Assimp.AssimpContext importer = new AssimpContext(); importer.SetConfig(new Assimp.Configs.NormalSmoothingAngleConfig(0.66f)); Scene model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality); return(model); }
static void Main(string[] args) { AssimpContext c = new AssimpContext(); c.SetConfig(new NormalSmoothingAngleConfig(66)); Scene s = c.ImportFile("test.fbx"); Console.WriteLine("Hello World!"); }
public Model(string path) { var importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); var scene = importer.ImportFile(path, PostProcessSteps.Triangulate | PostProcessSteps.FlipUVs); processNode(scene.RootNode, scene); }
public SimpleOpenGLSample() : base() { Title = "Quack! - AssimpNet Simple OpenGL Sample"; String fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "duck.dae"); AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); m_model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality); ComputeBoundingBox(); }
public Scene LoadModel(byte[] data, string ext) { if (ext == null || ext == "") { ext = "obj"; } using (AssimpContext ACont = new AssimpContext()) { ACont.SetConfig(new NormalSmoothingAngleConfig(66f)); return(ACont.ImportFileFromStream(new DataStream(data), PostProcessSteps.Triangulate, ext)); } }
public AssimpModelBuilder(IOpenGLObjectFactory openGLFactory, Stream filestream) { _openGLFactory = openGLFactory; AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); _assimpmodel = importer.ImportFileFromStream(filestream, flags); Matrix4x4 identity = Matrix4x4.Identity; CreateBuffers(_assimpmodel.RootNode, null, ref identity); }
void CopyFileForResources(string pathOrigin) { if (File.Exists(pathOrigin)) { //string pathResources = Application.streamingAssetsPath; string pathResources = @"C:\git\poc-tcc\augmented-reality\Assets\MarkerBasedARExample\Resources\Gift3.fbx"; File.Copy(pathOrigin, pathResources, true); PropertiesModel.NameObjectSelected = pathOrigin; //string url = $"file:///{pathOrigin}"; using (AssimpContext assimp = new AssimpContext()) { assimp.SetConfig(new Assimp.Configs.MeshVertexLimitConfig(60000)); assimp.SetConfig(new Assimp.Configs.MeshTriangleLimitConfig(60000)); assimp.SetConfig(new Assimp.Configs.RemoveDegeneratePrimitivesConfig(true)); assimp.SetConfig(new Assimp.Configs.SortByPrimitiveTypeConfig(Assimp.PrimitiveType.Line | Assimp.PrimitiveType.Point)); PostProcessSteps postProcessSteps = PostProcessSteps.SplitLargeMeshes | PostProcessSteps.OptimizeGraph | PostProcessSteps.OptimizeMeshes | PostProcessSteps.Triangulate | PostProcessSteps.SortByPrimitiveType | PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessSteps.FlipWindingOrder; Assimp.Scene scene = assimp.ImportFile(pathOrigin, postProcessSteps); print("rootNode name: " + scene.RootNode.Name); MainNodeFBX mainNodeFBX = new MainNodeFBX(); PropertiesModel.ImportedExternalObject = new GameObject(scene.RootNode.Name); ImportNode(scene.RootNode, mainNodeFBX, scene, PropertiesModel.ImportedExternalObject); DontDestroyOnLoad(PropertiesModel.ImportedExternalObject); SceneManager.LoadScene("ObjectSelectMarkerLessScene"); } } }
public FileMeshRenderObject(string filePath) { this.filePath = filePath; using (var importer = new AssimpContext()) { importer.SetConfig(new NoSkeletonMeshesConfig(true)); var model = importer.ImportFile(filePath, PostProcessPreset.TargetRealTimeMaximumQuality); foreach (var mesh in model.Meshes) { SetupMesh(mesh); } } }
private void LoadSceneB() { Console.WriteLine("Thread B: Starting import."); AssimpContext importer = new AssimpContext(); String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); new ConsoleLogStream("Thread B:").Attach(); importer.SetConfig(new NormalSmoothingAngleConfig(55.0f)); Console.WriteLine("Thread B: Importing"); Scene scene = importer.ImportFile(path); Console.WriteLine("Thread B: Done importing"); }
private ContentCompilerResult CompileFromFileInternal(string fileName, ModelCompilerOptions compilerOptions) { logger = new Logger(); var result = new ContentCompilerResult() { Logger = logger }; modelFilePath = fileName; modelDirectory = Path.GetDirectoryName(modelFilePath); // Preload AssimpLibrary if not already loaded if (!AssimpLibrary.Instance.IsLibraryLoaded) { var rootPath = Path.GetDirectoryName(typeof(AssimpLibrary).Assembly.Location); AssimpLibrary.Instance.LoadLibrary(Path.Combine(rootPath, AssimpLibrary.Instance.DefaultLibraryPath32Bit), Path.Combine(rootPath, AssimpLibrary.Instance.DefaultLibraryPath64Bit)); } var importer = new AssimpContext(); importer.SetConfig(new Assimp.Configs.MaxBoneCountConfig(72)); //importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); // Steps for Direct3D Right-Handed, should we make this configurable? var steps = PostProcessSteps.FlipUVs | PostProcessSteps.FlipWindingOrder | PostProcessSteps.LimitBoneWeights | PostProcessSteps.SplitByBoneCount; // Setup quality switch (compilerOptions.Quality) { case ModelRealTimeQuality.Low: steps |= PostProcessPreset.TargetRealTimeFast; break; case ModelRealTimeQuality.Maximum: steps |= PostProcessPreset.TargetRealTimeMaximumQuality; break; default: steps |= PostProcessPreset.TargetRealTimeQuality; break; } scene = importer.ImportFile(fileName, steps); model = new ModelData(); ProcessScene(); result.IsContentGenerated = true; result.ModelData = model; return(result); }
/* * Interpretes file at 'filepath' using Assimp and converts it to a equivalent Structure class. */ public Structure Interpret(string filepath) { var context = new AssimpContext(); Scene scene; try{ NormalSmoothingAngleConfig smoothingConfig = new NormalSmoothingAngleConfig(0.0f); SortByPrimitiveTypeConfig removeConfig = new SortByPrimitiveTypeConfig(PrimitiveType.Point | PrimitiveType.Line); context.SetConfig(smoothingConfig); context.SetConfig(removeConfig); scene = context.ImportFile(filepath, PostProcessSteps.Triangulate | PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals | PostProcessSteps.FindDegenerates | PostProcessSteps.SortByPrimitiveType | PostProcessSteps.FixInFacingNormals); }catch (FileNotFoundException e) { throw new FileNotFoundException("Unexpected error: Filepath into DataInterpreter not valid. {" + filepath + "}", e); }catch { throw new IOException("Error when importing file: " + filepath.ToString()); } // For every mesh create a equivalent component. foreach (Mesh mesh in scene.Meshes) { int compIndex = _structure.addComponent(new Component()); Dictionary <(double, double, double), int> dict = PreprocessVertices(compIndex, mesh.Vertices); // For every face, lookup each of the three vertex indices using dict and their coordinates. Then create the face in component with // the indices we just got. foreach (var face in mesh.Faces) { int[] vertices = new int[3]; vertices[0] = dict[(mesh.Vertices[face.Indices[0]].X, mesh.Vertices[face.Indices[0]].Y, mesh.Vertices[face.Indices[0]].Z)];
public override bool ExportToFile(IOModel model, string filename) { var tempFile = Path.Combine(Path.GetDirectoryName(filename), "_proxy.obj"); var tempMtlFile = Path.Combine(Path.GetDirectoryName(filename), "_proxy.mtl"); var objExporter = new ObjExporter(_settings, _callback); var objData = objExporter.ExportToFile(model, tempFile); AssimpContext context = new AssimpContext(); context.SetConfig(new NormalSmoothingAngleConfig(90.0f)); Scene scene = context.ImportFile(tempFile); switch (_exporter) { case Exporter.Collada: { context.ExportFile(scene, filename, "collada"); // Open up exported collada file and fix all texture filenames to relative XDocument exported = XDocument.Load(filename); foreach (var node in exported.Root.DescendantNodes()) { if (node is XElement) { var element = (XElement)node; if (element.Name.LocalName == "init_from" && element.Value.EndsWith(".png")) { element.Value = Path.GetFileName(element.Value); } } } exported.Save(filename); } break; case Exporter.GLTF2: context.ExportFile(scene, filename, "gltf2"); break; case Exporter.X3d: context.ExportFile(scene, filename, "x3d"); break; } File.Delete(tempFile); File.Delete(tempMtlFile); return(true); }
/// <summary> /// Loads a Assimp Model From File /// </summary> /// <param name="filename">The path to the file</param> /// <returns>The loaded AssimpModel</returns> private static List <Mesh> LoadModel(string path) { if (!File.Exists(path)) { Logger.Crash(new InvalidFolderPathException(path), true); return(new List <Mesh> { Mesh.DefaultMesh }); } AssimpContext context = new AssimpContext(); context.SetConfig(new NormalSmoothingAngleConfig(66)); return(LoadAssimpScene(context.ImportFile(path), path)); }
/* 函数 */ void loadModel(string path) { AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); Scene scene = importer.ImportFile(path, PostProcessSteps.Triangulate | PostProcessSteps.FlipUVs); if (scene == null || (scene.SceneFlags & SceneFlags.Incomplete) != 0 || scene.RootNode == null) { Console.WriteLine($"ERROR::ASSIMP:: import"); return; } directory = Path.GetDirectoryName(path); processNode(scene.RootNode, scene); }
/// <summary> /// Loads the model using Assimp. (Throws on failure.) /// </summary> /// <param name="fileName">The absolute path and name of the model.</param> /// <returns>The Assimp scene.</returns> private static Assimp.Scene LoadAssimp(string fileName) { using (var importer = new AssimpContext()) { importer.SetConfig(new Assimp.Configs.RemoveDegeneratePrimitivesConfig(true)); return(importer.ImportFile(fileName, PostProcessSteps.FindDegenerates | PostProcessSteps.FindInvalidData | PostProcessSteps.FlipUVs | // Required for Direct3D PostProcessSteps.FlipWindingOrder | // Required for Direct3D PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.ImproveCacheLocality | PostProcessSteps.OptimizeMeshes | PostProcessSteps.Triangulate)); } }
// -------------------------------------------------------------------- private void LoadModel(string path) { textBoxPath.Text = path; mCurrentPath = path; //https://github.com/assimp/assimp-net/blob/master/AssimpNet.Sample/SimpleOpenGLSample.cs AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); mCurrentModel = importer.ImportFile(path, PostProcessPreset.TargetRealTimeMaximumQuality); ReloadSupportFile(); buttonImport.Enabled = true; ShowPreview(); }
public SimpleOpenGLSample() : base() { Title = "AssimpNet OpenGL Game"; String fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "blade_runner_police_spinner_blue.rot.4.obj"); //"blade_runner_police_spinner_blue.obj"); //"Center_City_Sci-Fi.obj"); //"blade_runner_police_spinner_blue.obj"); //"duck.dae"); AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(42.0f)); m_model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality); ComputeBoundingBox(); }
static void Main(string[] args) { //Simple test to make sure the non-net standard legacy target functions (unit tests all run with the net standard dll) String fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets", "duck.dae"); AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); Scene scene = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeQuality | PostProcessSteps.FlipWindingOrder); if (scene != null && scene.HasMeshes) { Console.WriteLine("Import SUCCESSFUL!"); } else { Console.WriteLine("Import FAILED!"); } }
static void ExportFile(string fileName, string destFolder) { String targetMeshFile = Path.GetFileNameWithoutExtension(fileName) + ".mesh"; String targetAnimFile = Path.GetFileNameWithoutExtension(fileName) + ".anim"; Console.WriteLine("Exporting " + targetMeshFile + "..."); AssimpContext importer = new AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); importer.SetConfig(new VertexBoneWeightLimitConfig(4)); Scene scene = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessSteps.FlipUVs); System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone(); customCulture.NumberFormat.NumberDecimalSeparator = "."; System.Threading.Thread.CurrentThread.CurrentCulture = customCulture; FileStream fs = new FileStream(Path.Combine(destFolder, targetMeshFile), FileMode.Create); BinaryWriter dest = new BinaryWriter(fs); MeshBlock meshBlock = new MeshBlock(dest, "MX3D"); List<MeshNode> nodes = new List<MeshNode>(); addNodes(nodes, scene.RootNode, scene.Meshes[0]); for (int j = 0; j < 1; j++) { MeshBlock groupBlock = new MeshBlock(dest, "XGRP"); exportGroup(dest, scene.Meshes[j], scene, nodes); groupBlock.EndBlock(dest); } MeshBlock skeletonDataBlock; skeletonDataBlock = new MeshBlock(dest, "XSKL"); UInt32 boneCount = (UInt32)nodes.Count; dest.Write(boneCount); for (int j = 0; j < nodes.Count; j++) { exportBone(dest, nodes[j], scene, j); } skeletonDataBlock.EndBlock(dest); meshBlock.EndBlock(dest); dest.Close(); fs.Close(); for (int i = 0; i < scene.AnimationCount; i++) { Animation animation = scene.Animations[i]; String name = animation.Name; if (name.Length <= 0) { name = Path.GetFileNameWithoutExtension(targetAnimFile); int p = name.LastIndexOf("@"); if (p >= 0) { name = name.Substring(p + 1); } } Console.WriteLine("Exporting " + name + " animation..."); fs = new FileStream(Path.Combine(destFolder, targetAnimFile), FileMode.Create); dest = new BinaryWriter(fs); byte[] tagData = Encoding.ASCII.GetBytes("ANIM"); dest.Write(tagData); float FPS = (float)animation.TicksPerSecond; dest.Write(FPS); byte loop = 1; dest.Write(loop); float loopPoint = 0.0f; dest.Write(loopPoint); float animSpeed = 1.0f; dest.Write(animSpeed); String nextAnim = ""; exportString(dest, nextAnim); UInt32 channelCount = (UInt32)animation.NodeAnimationChannelCount; dest.Write(channelCount); for (int j = 0; j < channelCount; j++) { NodeAnimationChannel channel = animation.NodeAnimationChannels[j]; exportString(dest, channel.NodeName); UInt32 posCount = (UInt32)channel.PositionKeyCount; dest.Write(posCount); for (int k = 0; k < posCount; k++) { float t = (float)channel.PositionKeys[k].Time; float x = channel.PositionKeys[k].Value.X; float y = channel.PositionKeys[k].Value.Y; float z = channel.PositionKeys[k].Value.Z; float w = 1.0f; dest.Write(t); dest.Write(x); dest.Write(y); dest.Write(z); dest.Write(w); } UInt32 rotCount = (UInt32)channel.RotationKeyCount; dest.Write(rotCount); for (int k = 0; k < rotCount; k++) { float t = (float)channel.RotationKeys[k].Time; float x = channel.RotationKeys[k].Value.X; float y = channel.RotationKeys[k].Value.Y; float z = channel.RotationKeys[k].Value.Z; float w = channel.RotationKeys[k].Value.W; dest.Write(t); dest.Write(x); dest.Write(y); dest.Write(z); dest.Write(w); } UInt32 scaleCount = (UInt32)channel.ScalingKeyCount; dest.Write(scaleCount); for (int k = 0; k < scaleCount; k++) { float t = (float)channel.ScalingKeys[k].Time; float x = channel.ScalingKeys[k].Value.X; float y = channel.ScalingKeys[k].Value.Y; float z = channel.ScalingKeys[k].Value.Z; float w = 1.0f; dest.Write(t); dest.Write(x); dest.Write(y); dest.Write(z); dest.Write(w); } } dest.Close(); fs.Close(); } }