public AssimpImporter() { var importer = new AssimpContext(); AvaliableFormats = importer.GetSupportedImportFormats(); importer.Dispose(); }
public static string[] GetSupportedImportFormats() { Assimp.AssimpContext C = new AssimpContext(); string[] _Formats = C.GetSupportedImportFormats(); C.Dispose(); return(_Formats); }
private void button1_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.Cancel) { return; } // Получаем выбранный файл string filename = openFileDialog1.FileName; textBox1.AppendText(String.Format("Load: {0} {1}", filename, Environment.NewLine)); // Включим логи для импортера LogStream logstream = new LogStream(delegate(String msg, String userData) { textBox1.AppendText(msg + Environment.NewLine); }); logstream.Attach(); // Импортиуем UVCoords = new List <Vector3D>(); // Координаты UVVertex = new HashSet <Vector3D>(); // Точки AssimpContext importer = new AssimpContext(); Scene scene = importer.ImportFile(filename, PostProcessSteps.ValidateDataStructure); // (PostProcessSteps.FindInstances | PostProcessSteps.ValidateDataStructure) if (scene.Meshes.Count > 0) { Mesh mesh = scene.Meshes[0]; if (mesh.TextureCoordinateChannelCount > 0) { UVCoords = mesh.TextureCoordinateChannels[0]; foreach (Vector3D uv in UVCoords) { UVVertex.Add(uv); } } } DrawImage(); importer.Dispose(); Refresh(); }
/// <summary> /// /// </summary> /// <param name="filePath"></param> /// <param name="rootJOBJ"></param> public static void ExportFile(string filePath, HSD_JOBJ rootJOBJ, ModelExportSettings settings = null, Dictionary <int, string> boneLabels = null) { ModelExporter mex = new ModelExporter(); AssimpContext importer = new AssimpContext(); Dictionary <string, string> extToId = new Dictionary <string, string>(); foreach (var v in importer.GetSupportedExportFormats()) { if (!extToId.ContainsKey("." + v.FileExtension)) { extToId.Add("." + v.FileExtension, v.FormatId); } } PostProcessSteps postProcess = PostProcessSteps.FlipWindingOrder; if (settings.Optimize) { postProcess |= PostProcessSteps.JoinIdenticalVertices; } if (settings.FlipUVs) { postProcess |= PostProcessSteps.FlipUVs; } settings.Directory = System.IO.Path.GetDirectoryName(filePath) + "\\"; if (System.IO.Path.GetExtension(filePath).ToLower() == ".dae") { var sc = mex.WriteRootNode(rootJOBJ, settings, boneLabels); /*var scn = Scene.ToUnmanagedScene(sc); * scn = AssimpLibrary.Instance.ApplyPostProcessing(scn, postProcess); * var scene = Scene.FromUnmanagedScene(scn); * Scene.FreeUnmanagedScene(scn);*/ ExportCustomDAE(filePath, sc, settings); } else { importer.ExportFile(mex.WriteRootNode(rootJOBJ, settings, boneLabels), filePath, extToId[System.IO.Path.GetExtension(filePath)], postProcess); } importer.Dispose(); }
public void TestLoadFreeLibrary() { if (AssimpLibrary.Instance.IsLibraryLoaded) { AssimpLibrary.Instance.FreeLibrary(); } AssimpLibrary.Instance.LoadLibrary(); String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); AssimpContext importer = new AssimpContext(); importer.ImportFile(path); importer.Dispose(); AssimpLibrary.Instance.FreeLibrary(); }
protected override void Dispose(bool disposing) { // Dispose(bool disposing) executes in two distinct scenarios. // If disposing equals true, the method has been called directly // or indirectly by a user's code. Managed and unmanaged resources // can be disposed. // If disposing equals false, the method has been called by the // runtime from inside the finalizer and you should not reference // other objects. Only unmanaged resources can be disposed. // // from: https://docs.microsoft.com/en-us/dotnet/api/system.idisposable.dispose?view=netcore-3.1 // finalizer is the destructor, now even though OpenGL's resources // are unmanaged, we can safely only access our fields if disposing = true if (disposing) { Scene.ForEach(m => m.Unassign()); IZBRenderer.Unassign(); AssimpContext.Dispose(); } base.Dispose(disposing); }
public static void LoadSource(this RMesh rmesh, string filename) { AssimpContext context = new AssimpContext(); context.SetConfig(new Assimp.Configs.FBXImportAllMaterialsConfig(true)); context.SetConfig(new Assimp.Configs.FBXImportAllGeometryLayersConfig(true)); context.SetConfig(new Assimp.Configs.MultithreadingConfig(2)); context.SetConfig(new Assimp.Configs.FBXStrictModeConfig(false)); if (!context.IsImportFormatSupported(Path.GetExtension(filename))) { throw new ReactorException("Attempted to load a model that Assimp doesn't know how to load"); } LogStream log = new LogStream((msg, user) => { RLog.Info(msg.Remove(msg.Length - 2)); }); log.Attach(); int platform = (int)Environment.OSVersion.Platform; Scene scene = context.ImportFile(filename, PostProcessSteps.FindInvalidData | PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.Triangulate | PostProcessSteps.GenerateUVCoords | PostProcessSteps.CalculateTangentSpace | PostProcessSteps.PreTransformVertices); if (scene.HasMeshes) { foreach (Mesh mesh in scene.Meshes) { if (!mesh.HasVertices) { continue; } RMeshPart rmeshpart = RMeshPart.Create <RMeshPart> (); RVertexData [] data = new RVertexData [mesh.VertexCount]; List <int> indicesList = new List <int> (); if (mesh.HasFaces) { foreach (Face face in mesh.Faces) { indicesList.AddRange(face.Indices.ToArray()); foreach (int index in face.Indices) { Vector3D p = mesh.Vertices [index]; data [index].Position = new Vector3(p.X, p.Y, p.Z); if (mesh.HasTextureCoords(0)) { Vector3D t = mesh.TextureCoordinateChannels [0] [index]; data [index].TexCoord = new Vector2(t.X, -t.Y); } if (mesh.HasNormals) { Vector3D n = mesh.Normals [index]; data [index].Normal = new Vector3(n.X, n.Y, n.Z); } if (mesh.HasTangentBasis) { Vector3D b = mesh.BiTangents [index]; Vector3D t = mesh.Tangents [index]; data [index].Bitangent = new Vector3(b.X, b.Y, b.Z); data [index].Tangent = new Vector3(t.X, t.Y, t.Z); } } } } RVertexBuffer vbuffer = new RVertexBuffer(typeof(RVertexData), mesh.VertexCount, RBufferUsage.WriteOnly, true); RIndexBuffer ibuffer = new RIndexBuffer(typeof(int), indicesList.Count, RBufferUsage.WriteOnly); ibuffer.SetData(indicesList.ToArray()); vbuffer.SetData <RVertexData> (data); #if WINDOWS var separator = "\\"; #else var separator = "/"; #endif rmeshpart.VertexBuffer = vbuffer; rmeshpart.IndexBuffer = ibuffer; RMaterial material = new RMaterial(rmesh.Name + ":Material"); if (scene.HasMaterials) { Material mat = scene.Materials[mesh.MaterialIndex]; material.Shininess = mat.Shininess; material.SetColor(RMaterialColor.DIFFUSE, new RColor(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A)); if (mat.HasTextureDiffuse) { var texFileName = Path.GetFileName(mat.TextureDiffuse.FilePath.Replace("\\", separator).Replace("/", separator)); RTexture2D tex = (RTexture2D)RTextures.Instance.CreateTexture <RTexture2D>(texFileName, "/textures/" + texFileName.ToLower()); tex.Bind(); tex.GenerateMipmaps(); tex.SetTextureMagFilter(RTextureMagFilter.Linear); tex.SetTextureMinFilter(RTextureMinFilter.LinearMipmapLinear); tex.SetTextureWrapMode(RTextureWrapMode.Repeat, RTextureWrapMode.Repeat); tex.Unbind(); material.SetTexture(RTextureLayer.DIFFUSE, tex); } if (mat.HasTextureNormal) { var texFileName = Path.GetFileName(mat.TextureNormal.FilePath.Replace("\\", separator).Replace("/", separator)); RTexture2D tex = (RTexture2D)RTextures.Instance.CreateTexture <RTexture2D>(texFileName, "/textures/" + texFileName.ToLower()); tex.Bind(); tex.GenerateMipmaps(); tex.SetTextureMagFilter(RTextureMagFilter.Linear); tex.SetTextureMinFilter(RTextureMinFilter.LinearMipmapLinear); tex.SetTextureWrapMode(RTextureWrapMode.Repeat, RTextureWrapMode.Repeat); tex.Unbind(); material.SetTexture(RTextureLayer.NORMAL, tex); } if (mat.HasTextureAmbient) { var texFileName = Path.GetFileName(mat.TextureAmbient.FilePath.Replace("\\", separator).Replace("/", separator)); RTexture2D tex = (RTexture2D)RTextures.Instance.CreateTexture <RTexture2D>(texFileName, "/textures/" + texFileName.ToLower()); tex.SetTextureMagFilter(RTextureMagFilter.Linear); tex.SetTextureMinFilter(RTextureMinFilter.LinearMipmapLinear); tex.SetTextureWrapMode(RTextureWrapMode.Repeat, RTextureWrapMode.Repeat); material.SetTexture(RTextureLayer.AMBIENT, tex); } if (mat.HasTextureHeight) { var texFileName = Path.GetFileName(mat.TextureHeight.FilePath.Replace("\\", separator).Replace("/", separator)); RTexture2D tex = (RTexture2D)RTextures.Instance.CreateTexture <RTexture2D>(texFileName, "/textures/" + texFileName.ToLower()); tex.SetTextureMagFilter(RTextureMagFilter.Linear); tex.SetTextureMinFilter(RTextureMinFilter.LinearMipmapLinear); tex.SetTextureWrapMode(RTextureWrapMode.Repeat, RTextureWrapMode.Repeat); material.SetTexture(RTextureLayer.HEIGHT, tex); } if (mat.HasTextureEmissive) { var texFileName = Path.GetFileName(mat.TextureEmissive.FilePath.Replace("\\", separator).Replace("/", separator)); RTexture2D tex = (RTexture2D)RTextures.Instance.CreateTexture <RTexture2D>(texFileName, "/textures/" + texFileName.ToLower()); tex.SetTextureMagFilter(RTextureMagFilter.Linear); tex.SetTextureMinFilter(RTextureMinFilter.LinearMipmapLinear); tex.SetTextureWrapMode(RTextureWrapMode.Repeat, RTextureWrapMode.Repeat); material.SetTexture(RTextureLayer.GLOW, tex); } if (mat.HasTextureSpecular) { var texFileName = Path.GetFileName(mat.TextureSpecular.FilePath.Replace("\\", separator).Replace("/", separator)); RTexture2D tex = (RTexture2D)RTextures.Instance.CreateTexture <RTexture2D>(texFileName, "/textures/" + texFileName.ToLower()); tex.SetTextureMagFilter(RTextureMagFilter.Linear); tex.SetTextureMinFilter(RTextureMinFilter.LinearMipmapLinear); tex.SetTextureWrapMode(RTextureWrapMode.Repeat, RTextureWrapMode.Repeat); material.SetTexture(RTextureLayer.SPECULAR, tex); } } rmeshpart.Material = material; rmesh.Parts.Add(rmeshpart); } //return rmesh; } //return null; if (rmesh.Parts.Count == 0) { throw new ReactorException("Attempted to load a model when Assimp couldn't find any verticies!"); } context.Dispose(); }
public async Task <JobResult> UploadJob(IFormFile file, [FromForm] string fScriptParams, [FromForm] string scriptFilename, [FromForm] string outputFileFormat = "1") { //Result of the job JobResult res = new JobResult(); if (String.IsNullOrEmpty(outputFileFormat)) { outputFileFormat = "1"; //Standard OBJ } try { List <ScriptParameterFilter> filterScriptParams = new List <ScriptParameterFilter>(); //Deserialize parameters for the script if (fScriptParams != null) { filterScriptParams = JsonConvert.DeserializeObject <List <ScriptParameterFilter> >(fScriptParams); } string folderName = _appSettings.UploadDirectoryName; string webRootPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); string newPath = Path.Combine(webRootPath, folderName); if (!Directory.Exists(newPath)) { try { //Create direcotry if it doesn't exits Directory.CreateDirectory(newPath); } catch (Exception e) { res.ResultCode = new JobResultCode() { Message = e.ToString(), Number = JobResultNumber.OtherError }; } } if (file.Length > 0) //Check if filelength greater than zero { //Remove apostroph string fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.ToString().Trim('"'); string fullPath = Path.Combine(newPath, fileName); try { using (var stream = new FileStream(fullPath, FileMode.Create)) { file.CopyTo(stream); } } catch (Exception e) { res.ResultCode = new JobResultCode() { Message = e.ToString(), Number = JobResultNumber.OtherError }; } //Generates a ramdom job ID string jobId = Guid.NewGuid().ToString("N"); res.JobId = jobId; string pathToWorkJob = Path.Combine(_appSettings.WorkingDirectory, jobId); try { Directory.CreateDirectory(pathToWorkJob); } catch (Exception e) { res.ResultCode = new JobResultCode() { Message = e.ToString(), Number = JobResultNumber.OtherError }; return(res); } var workJobFileInput = Path.Combine(pathToWorkJob, CorrectFileName(fileName)); FFile.Copy(fullPath, workJobFileInput); string workJobScript = Path.Combine(pathToWorkJob, scriptFilename); FFile.Copy(Path.Combine(_appSettings.ScriptDirectory, scriptFilename), workJobScript); FilterScriptService fManager = new FilterScriptService(); var fScript = fManager.ReadFilterScript(workJobScript); foreach (var filter in filterScriptParams) { var filterScriptXml = fScript.Items.FirstOrDefault(a => a.GetType() == typeof(FilterScriptXmlfilter) && ((FilterScriptXmlfilter)a).name == filter.FilterName); var filterScript = fScript.Items.FirstOrDefault(a => a.GetType() == typeof(FilterScriptFilter) && ((FilterScriptFilter)a).name == filter.FilterName); if (filterScript != null) { foreach (var filterParameter in filter.FilterParameter) { var param = ((FilterScriptFilter)filterScript).Param?.ToList().FirstOrDefault(a => a.name == filterParameter.Key); if (param != null) { param.value = filterParameter.Value; } } } if (filterScriptXml != null) { foreach (var filterParameter in filter.FilterParameter) { var param = ((FilterScriptXmlfilter)filterScriptXml).xmlparam?.ToList().FirstOrDefault(a => a.name == filterParameter.Key); if (param != null) { param.value = filterParameter.Value; } } } } fManager.WriteFilterScript(workJobScript, fScript); var index = CheckFileExtension(workJobFileInput); if (index < 0) //Filetype is not supported { res.ResultCode = new JobResultCode() { Message = "Filetype is not supported. See supported filetypes.", Number = JobResultNumber.FiletypeNotSupported }; return(res); } var oFileF = int.Parse(outputFileFormat); //If gltf, do job with obj an then convert it to gltf if (outputFileFormat == "5") { oFileF = 1; } string jobResultFilename = $"{workJobFileInput.Substring(0, index)}{_appSettings.ResultFileNameEnding}.{ParameterController.LstSupportedExportFormats.FirstOrDefault(a => a.Id == oFileF).Extension}"; var outputFile = Path.Combine(pathToWorkJob, jobResultFilename); string filterOutputFile = Path.Combine(pathToWorkJob, $"{_appSettings.FilterOutputFilename}.txt"); MeshLabService mService = new MeshLabService(); try { mService.StartJob(filterOutputFile, workJobFileInput, workJobScript, outputFile, pathToWorkJob, true, _appSettings.MeshLabDirectory); } catch (Exception e) { res.ResultCode = new JobResultCode() { Number = JobResultNumber.JobFailed, Message = e.ToString() }; return(res); } if (!FFile.Exists(outputFile)) { res.ResultCode = new JobResultCode() { Number = JobResultNumber.JobFailed, Message = FFile.ReadAllText(filterOutputFile) }; return(res); } if (outputFileFormat == "5") { try { using (AssimpContext cont = new AssimpContext()) { var tmpDir = Path.Combine(pathToWorkJob, "output"); Directory.CreateDirectory(tmpDir); var x = cont.ConvertFromFileToFile(jobResultFilename, Path.Combine(tmpDir, "output.gltf"), "gltf2"); } } catch (Exception) {} } res.FileResultName = Path.GetFileName(jobResultFilename); var hausdorff = -1.0; MeshInfo meshInfo = null; if (FFile.Exists(filterOutputFile)) { var foFile = FFile.ReadAllText(filterOutputFile); hausdorff = mService.ParseHausdorff(foFile); meshInfo = mService.ParseMeshInfo(foFile); } FileInfo fiResult = new FileInfo(outputFile); FileInfo fiOriginal = new FileInfo(workJobFileInput); res.AdditionalData = new Dictionary <string, string>(); if (hausdorff > 0) { res.AdditionalData.Add("Hausdorff", hausdorff.ToString(CultureInfo.InvariantCulture)); } try { using (AssimpContext importer = new AssimpContext()) { var model = importer.ImportFile(workJobFileInput); long cntVertex = 0; long cntFaces = 0; foreach (var modelMesh in model.Meshes) { cntVertex += modelMesh.VertexCount; cntFaces += modelMesh.FaceCount; } res.AdditionalData.Add("Number of Vertices of original model", cntVertex.ToString("N0")); res.AdditionalData.Add("Number of Faces of original model", cntFaces.ToString("N0")); importer.Dispose(); } } catch (Exception) {} try { using (AssimpContext importer = new AssimpContext()) { var model = importer.ImportFile(outputFile); long cntVertex = 0; long cntFaces = 0; foreach (var modelMesh in model.Meshes) { cntVertex += modelMesh.VertexCount; cntFaces += modelMesh.FaceCount; } res.AdditionalData.Add("Number of Vertices of result model", cntVertex.ToString("N0")); res.AdditionalData.Add("Number of Faces of result model", cntFaces.ToString("N0")); importer.Dispose(); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } res.FileInputSize = GetFileSizeInBytes(fiOriginal.Length); if (outputFileFormat == "5") { try { using (AssimpContext cont = new AssimpContext()) { var tmpDir = Path.Combine(pathToWorkJob, "output"); ZipFile.CreateFromDirectory(tmpDir, Path.Combine(pathToWorkJob, "output.zip")); jobResultFilename = Path.Combine(pathToWorkJob, "output.zip"); res.FileResultName = "output.zip"; DirectoryInfo info = new DirectoryInfo(tmpDir); long totalSize = info.EnumerateFiles().Sum(f => f.Length); res.FileResultSize = GetFileSizeInBytes(totalSize); res.ReducedBy = (100.0 - (double)totalSize / fiOriginal.Length * 100.0).ToString("F") + "%"; } } catch (Exception) { } } else { res.FileResultSize = GetFileSizeInBytes(fiResult.Length); res.ReducedBy = (100.0 - (double)fiResult.Length / fiOriginal.Length * 100.0).ToString("F") + "%"; } res.ReducedBy = (100.0 - (double)fiResult.Length / fiOriginal.Length * 100.0).ToString("F") + "%"; res.ResultCode = new JobResultCode() { Message = "Success", Number = JobResultNumber.Success }; return(res); } else { res.ResultCode = new JobResultCode() { Number = JobResultNumber.FileRequired, Message = "File is required!" }; return(res); } } catch (Exception ex) { res.ResultCode = new JobResultCode() { Number = JobResultNumber.OtherError, Message = ex.ToString() }; return(res); } }
public void loadMeshFromFile(String filename) { //Filepath to our model String fileName = FileManager.getMediaFile(filename); //Create a new importer AssimpContext importer = new AssimpContext(); ////This is how we add a logging callback //LogStream logstream = new LogStream(delegate (String msg, String userData) //{ // Console.WriteLine(msg); //}); //logstream.Attach(); //Import the model. The model is imported, loaded into managed memory. // Then the unmanaged memory is released, and everything is reset. Scene model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality); // Load the model data into our own structures for (var i = 0; i < model.MeshCount; i++) { // Vertices for (var currentVertex = 0; currentVertex < model.Meshes[i].VertexCount; currentVertex++) { Vector3D vector = model.Meshes[i].Vertices[currentVertex]; vertices.Add(new Vector3(vector.X, vector.Y, vector.Z)); colorData.Add(new Vector3(0.5f, 0.5f, 0.5f)); } // Normals for (var currentNormal = 0; currentNormal < model.Meshes[i].Normals.Count; currentNormal++) { Vector3D normal = model.Meshes[i].Normals[currentNormal]; normals.Add(new Vector3(normal.X, normal.Y, normal.Z)); } // Material if (model.Materials[0].HasTextureDiffuse == true) { isTextured = true; textureCoordinates.Capacity = model.Meshes[0].TextureCoordinateChannels[0].Count; foreach (Assimp.Vector3D element in model.Meshes[0].TextureCoordinateChannels[0]) { textureCoordinates.Add(new Vector2(element.X, element.Y)); } textureID = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, textureID); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); // Use anisotropic Filtering if available var extensions = GL.GetString(StringName.Extensions).Split(' '); if (extensions.Contains("GL_EXT_texture_filter_anisotropic")) { int max_aniso = GL.GetInteger((GetPName)ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt); GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, max_aniso); } Bitmap bmp = new Bitmap(FileManager.getMediaFile("textures/" + model.Materials[0].TextureDiffuse.FilePath)); BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0); bmp.UnlockBits(bmp_data); // Generate MipMaps (especially to get rid of texture flickering) GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } GL.BindTexture(TextureTarget.Texture2D, -1); // Indices indices.AddRange(model.Meshes[i].GetIndices()); } //End of example importer.Dispose(); // Generate the buffers generateBuffers(); }
public void ReadFromFile(string filename) { var file = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), filename); //Create new importer var importer = new AssimpContext(); //Check if model is supported if (!importer.IsImportFormatSupported(Path.GetExtension(file))) { throw new ArgumentException("Model format " + Path.GetExtension(file) + " is not supported! Cannot load {1}", "filename"); } //Configs importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); var model = importer.ImportFile(file, PostProcessPreset.TargetRealTimeMaximumQuality); importer.Dispose(); MeshData = new MeshData(); AnimationData = new AnimationData(); foreach (var mesh in model.Meshes) { MeshData.Indices = mesh.GetIndices().ToList(); MeshData.IndexCount = MeshData.Indices.Count; MeshData.Name = mesh.Name; MeshData.VertexCount = mesh.VertexCount; foreach (var v in mesh.Vertices) { MeshData.VertexPositions.Add(new Vector3(v.X, v.Y, v.Z)); } foreach (var v in mesh.Normals) { MeshData.VertexNormals.Add(new Vector3(v.X, v.Y, v.Z)); } foreach (var v in mesh.TextureCoordinateChannels[0]) { MeshData.VertexTextureCoordinates.Add(new Vector2(v.X, v.Y)); } AnimationData.BoneCount = mesh.BoneCount; foreach (var b in mesh.Bones) { var j = new AnimationJoint(); j.Name = b.Name; //j.OffsetMatrix = b.OffsetMatrix; AnimationData.Bones.Add(j); } } return; //TO DO STILL BONES ARE DONE IN A DIFFERENT WAY AnimationData.HasAnimations = model.HasAnimations; foreach (var a in model.Animations) { //Clip var clip = new AnimationClip() { Name = a.Name, Duration = (float)a.DurationInTicks, TicksPerSecond = (float)a.TicksPerSecond }; //KeyFrames foreach (var m in a.NodeAnimationChannels) { var key = new AnimationKey(); for (var i = 0; i < m.PositionKeyCount; ++i) { var time = m.PositionKeys[i].Time; var pos = m.PositionKeys[i].Value.ToVector3(); var rot = m.RotationKeys[i].Value; var s = m.ScalingKeys[i].Value.ToVector3(); } //clip.Keys.Add(key); } } // AnimationData.Animations.Add(clip); //} }
public void Dispose() { context?.Dispose(); }
public void TestLoadFreeLibrary() { if(AssimpLibrary.Instance.IsLibraryLoaded) AssimpLibrary.Instance.FreeLibrary(); AssimpLibrary.Instance.LoadLibrary(); String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); AssimpContext importer = new AssimpContext(); importer.ImportFile(path); importer.Dispose(); AssimpLibrary.Instance.FreeLibrary(); }
public void ExportMesh(GameObject go, string path) { Vector3 lastPos = go.transform.position; go.transform.position = Vector3.zero; Scene scene = new Scene(); List <string> sameNames = new List <string>(); List <Transform> children = new List <Transform>(); Dictionary <Transform, Node> nodesByTransform = new Dictionary <Transform, Node>(); GetAllChildren(children, go.transform); foreach (Transform child in children) { string nname = child.name; if (sameNames.Contains(nname)) { nname += "_"; } else { sameNames.Add(nname); } Node node = new Node(nname); UnityEngine.Matrix4x4 m = child.localToWorldMatrix.inverse; node.Transform = new Assimp.Matrix4x4( m.m00, m.m01, m.m02, m.m03, m.m10, m.m11, m.m12, m.m13, m.m20, m.m21, m.m22, m.m23, m.m30, m.m31, m.m32, m.m33 ); nodesByTransform.Add(child, node); if (child == go.transform) { Node rootNode = new Node(Path.GetFileNameWithoutExtension(path)); rootNode.Children.Add(node); scene.RootNode = rootNode; } } foreach (Transform child in children) { foreach (Transform c in child) { if (child == go.transform) { scene.RootNode.Children.Add(nodesByTransform[c]); } else { nodesByTransform[child].Children.Add(nodesByTransform[c]); } } } sameNames.Clear(); MeshFilter[] mfs = go.GetComponentsInChildren <MeshFilter>(); SkinnedMeshRenderer[] smrs = go.GetComponentsInChildren <SkinnedMeshRenderer>(); int meshIndex = 0; foreach (var mf in mfs) { PdxShape shape = mf.GetComponent <PdxShape>(); Assimp.Material mat = new Assimp.Material(); mat.Name = shape.shader; TextureSlot diff = new TextureSlot(); diff.FilePath = shape.diffuse; diff.TextureType = TextureType.Diffuse; diff.UVIndex = 0; //mat.TextureDiffuse = diff; mat.AddMaterialTexture(ref diff); TextureSlot norm = new TextureSlot(); norm.FilePath = shape.normal; norm.TextureType = TextureType.Normals; norm.UVIndex = 0; //mat.TextureNormal = norm; mat.AddMaterialTexture(ref norm); TextureSlot spec = new TextureSlot(); spec.FilePath = shape.specular; spec.TextureType = TextureType.Specular; spec.UVIndex = 0; //mat.TextureSpecular = spec; mat.AddMaterialTexture(ref spec); scene.Materials.Add(mat); Assimp.Mesh am = null; am = FromUnityMesh(mf.mesh, "pShape" + meshIndex, go.transform); if (sameNames.Contains(am.Name)) { am.Name += "_"; } else { sameNames.Add(am.Name); } am.MaterialIndex = meshIndex; scene.Meshes.Add(am); nodesByTransform[mf.transform].MeshIndices.Add(meshIndex); meshIndex++; } foreach (var smr in smrs) { PdxShape shape = smr.GetComponent <PdxShape>(); Assimp.Material mat = new Assimp.Material(); mat.Name = shape.shader; TextureSlot diff = new TextureSlot(); diff.FilePath = shape.diffuse; diff.TextureType = TextureType.Diffuse; diff.UVIndex = 0; //mat.TextureDiffuse = diff; mat.AddMaterialTexture(ref diff); TextureSlot norm = new TextureSlot(); norm.FilePath = shape.normal; norm.TextureType = TextureType.Normals; norm.UVIndex = 0; //mat.TextureNormal = norm; mat.AddMaterialTexture(ref norm); TextureSlot spec = new TextureSlot(); spec.FilePath = shape.specular; spec.TextureType = TextureType.Specular; spec.UVIndex = 0; //mat.TextureSpecular = spec; mat.AddMaterialTexture(ref spec); scene.Materials.Add(mat); Assimp.Mesh am = null; UnityEngine.Mesh baked = new UnityEngine.Mesh(); smr.BakeMesh(baked); am = FromUnityMesh(baked /*smr.sharedMesh*/, "pShape" + meshIndex, go.transform); if (sameNames.Contains(am.Name)) { am.Name += "_"; } else { sameNames.Add(am.Name); } am.MaterialIndex = meshIndex; scene.Meshes.Add(am); nodesByTransform[smr.transform].MeshIndices.Add(meshIndex); meshIndex++; } AssimpContext context = new AssimpContext(); bool result = context.ExportFile(scene, path, "obj", PostProcessSteps.MakeLeftHanded | PostProcessSteps.FlipWindingOrder); context.Dispose(); go.transform.position = lastPos; if (result) { EditorController.instance.Status("Object saved as " + path); } else { EditorController.instance.Status("Export failed :(", 2); } }
public static void Init() { AssimpContext importer = new AssimpContext(); NormalSmoothingAngleConfig config = new NormalSmoothingAngleConfig(66.0f); importer.SetConfig(config); LogStream logStream = new LogStream(delegate(string msg, string userData) { Console.WriteLine(msg); }); logStream.Attach(); Scene scene = importer.ImportFile(@"resources/icosphere.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Icosphere = scene.Meshes[0]; scene = importer.ImportFile(@"resources/icosphereHigh.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.IcosphereHigh = scene.Meshes[0]; scene = importer.ImportFile(@"resources/asteroid.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Asteroid = scene.Meshes[0]; scene = importer.ImportFile(@"resources/point.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Point = scene.Meshes[0]; scene = importer.ImportFile(@"resources/cube.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Cube = scene.Meshes[0]; scene = importer.ImportFile(@"resources/camera.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Camera = scene.Meshes[0]; scene = importer.ImportFile(@"resources/skybox.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.SkyboxFront = scene.Meshes[0]; Mesh.SkyboxBack = scene.Meshes[1]; Mesh.SkyboxRight = scene.Meshes[2]; Mesh.SkyboxLeft = scene.Meshes[3]; Mesh.SkyboxTop = scene.Meshes[4]; Mesh.SkyboxBottom = scene.Meshes[5]; scene = importer.ImportFile(@"resources/gizmoPosX.ply", PostProcessPreset.TargetRealTimeQuality); Mesh.GizmoXPos = scene.Meshes[0]; scene = importer.ImportFile(@"resources/gizmoPosY.ply", PostProcessPreset.TargetRealTimeQuality); Mesh.GizmoYPos = scene.Meshes[0]; scene = importer.ImportFile(@"resources/gizmoPosZ.ply", PostProcessPreset.TargetRealTimeQuality); Mesh.GizmoZPos = scene.Meshes[0]; scene = importer.ImportFile(@"resources/gizmoRotX.ply", PostProcessPreset.TargetRealTimeQuality); Mesh.GizmoXRot = scene.Meshes[0]; scene = importer.ImportFile(@"resources/gizmoRotY.ply", PostProcessPreset.TargetRealTimeQuality); Mesh.GizmoYRot = scene.Meshes[0]; scene = importer.ImportFile(@"resources/gizmoRotZ.ply", PostProcessPreset.TargetRealTimeQuality); Mesh.GizmoZRot = scene.Meshes[0]; scene = importer.ImportFile(@"resources/text000.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Text000 = scene.Meshes[0]; scene = importer.ImportFile(@"resources/text090.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Text090 = scene.Meshes[0]; scene = importer.ImportFile(@"resources/text180.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Text180 = scene.Meshes[0]; scene = importer.ImportFile(@"resources/text270.obj", PostProcessPreset.TargetRealTimeQuality); Mesh.Text270 = scene.Meshes[0]; importer.Dispose(); logStream.Detach(); }
public GameObject LoadMesh(string path) { AssimpContext context = new AssimpContext(); Scene scene = context.ImportFile(path, PostProcessSteps.MakeLeftHanded | PostProcessSteps.FlipWindingOrder); if (!scene.HasMeshes) { return(null); } List <UnityEngine.Material> snow = new List <UnityEngine.Material>(); List <UnityEngine.Material> color = new List <UnityEngine.Material>(); List <UnityEngine.Material> atlas = new List <UnityEngine.Material>(); Dictionary <string, Transform> bonesByName = new Dictionary <string, Transform>(); GameObject goRoot = new GameObject(Path.GetFileName(path)); float min = 0; int idx = 0; foreach (Assimp.Mesh sceneMesh in scene.Meshes) { GameObject go = new GameObject("pShape" + idx); go.tag = "Shape"; bool skinned = false; UnityEngine.Mesh mesh = new UnityEngine.Mesh(); mesh.name = "pMeshShape" + idx; idx++; List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uv = new List <Vector2>(); List <Vector2> uv2 = null; List <BoneWeight> boneWeights = new List <BoneWeight>(); Transform[] bones = null; foreach (var sceneVertex in sceneMesh.Vertices) { vertices.Add(new Vector3(sceneVertex.X, sceneVertex.Y, sceneVertex.Z)); } foreach (var sceneNormal in sceneMesh.Normals) { normals.Add(new Vector3(sceneNormal.X, sceneNormal.Y, sceneNormal.Z)); } foreach (var sceneUV in sceneMesh.TextureCoordinateChannels[0]) { uv.Add(new Vector2(sceneUV.X, 1f - sceneUV.Y)); } if (sceneMesh.TextureCoordinateChannelCount > 1) { uv2 = new List <Vector2>(); foreach (var sceneUV2 in sceneMesh.TextureCoordinateChannels[1]) { uv2.Add(new Vector2(sceneUV2.X, 1f - sceneUV2.Y)); } } Transform rootBone = null; if (sceneMesh.HasBones) { for (int j = 0; j < sceneMesh.VertexCount; j++) { boneWeights.Add(new BoneWeight()); } skinned = true; bones = new Transform[sceneMesh.BoneCount]; int boneIndex = 0; foreach (var sceneBone in sceneMesh.Bones) { GameObject bone = new GameObject(sceneBone.Name); bone.tag = "Bone"; UnityEngine.Matrix4x4 matrix = new UnityEngine.Matrix4x4(); matrix.SetRow(0, new Vector4(sceneBone.OffsetMatrix.A1, sceneBone.OffsetMatrix.A2, sceneBone.OffsetMatrix.A3, sceneBone.OffsetMatrix.A4)); matrix.SetRow(1, new Vector4(sceneBone.OffsetMatrix.B1, sceneBone.OffsetMatrix.B2, sceneBone.OffsetMatrix.B3, sceneBone.OffsetMatrix.B4)); matrix.SetRow(2, new Vector4(sceneBone.OffsetMatrix.C1, sceneBone.OffsetMatrix.C2, sceneBone.OffsetMatrix.C3, sceneBone.OffsetMatrix.C4)); matrix.SetRow(3, new Vector4(sceneBone.OffsetMatrix.D1, sceneBone.OffsetMatrix.D2, sceneBone.OffsetMatrix.D3, sceneBone.OffsetMatrix.D4)); bone.transform.FromMatrix(matrix.inverse); bonesByName[bone.name] = bone.transform; bones[boneIndex] = bone.transform; if (sceneBone.HasVertexWeights) { for (int i = 0; i < sceneBone.VertexWeights.Count; i++) { BoneWeight bw = boneWeights[sceneBone.VertexWeights[i].VertexID]; if (bw.boneIndex0 == 0 && bw.weight0 == 0) { bw.boneIndex0 = boneIndex; bw.weight0 = sceneBone.VertexWeights[i].Weight; } else if (bw.boneIndex1 == 0 && bw.weight1 == 0) { bw.boneIndex1 = boneIndex; bw.weight1 = sceneBone.VertexWeights[i].Weight; } else if (bw.boneIndex2 == 0 && bw.weight2 == 0) { bw.boneIndex2 = boneIndex; bw.weight2 = sceneBone.VertexWeights[i].Weight; } else if (bw.boneIndex3 == 0 && bw.weight3 == 0) { bw.boneIndex3 = boneIndex; bw.weight3 = sceneBone.VertexWeights[i].Weight; } /*if (bw.weight0 < 0.0011f) bw.weight0 = 0f; * if (bw.weight1 < 0.0011f) bw.weight1 = 0f; * if (bw.weight2 < 0.0011f) bw.weight2 = 0f; * if (bw.weight3 < 0.0011f) bw.weight3 = 0f;*/ boneWeights[sceneBone.VertexWeights[i].VertexID] = bw; } } boneIndex++; } foreach (var bone in bonesByName) { if (bone.Key.ToLower().Equals("root")) { rootBone = bone.Value; } string parent = ""; FindParentInHierarchy(bone.Key, scene.RootNode, out parent); if (parent.Length > 0 && bonesByName.ContainsKey(parent)) { bone.Value.SetParent(bonesByName[parent]); } else { bone.Value.SetParent(goRoot.transform); } } } UnityEngine.Matrix4x4[] bindposes = null; if (bones != null) { bindposes = new UnityEngine.Matrix4x4[bones.Length]; for (int b = 0; b < bones.Length; b++) { bindposes[b] = bones[b].worldToLocalMatrix * go.transform.localToWorldMatrix; } } mesh.vertices = vertices.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = sceneMesh.GetIndices(); mesh.uv = uv.ToArray(); mesh.RecalculateBounds(); mesh.RecalculateTangents(); if (min < mesh.bounds.max.z) { min = mesh.bounds.max.z; } //print(mesh.bounds.min.ToString()); //print(mesh.bounds.max.ToString()); PdxShape shape = go.AddComponent <PdxShape>(); Assimp.Material _mat = scene.Materials[sceneMesh.MaterialIndex]; //print(_mat.Name); Shader shader = Shader.Find("PDX/" + _mat.Name); shape.shader = _mat.Name; if (shader == null) { shader = Shader.Find("PDX/PdxMeshStandard"); shape.shader = "PdxMeshStandard"; } UnityEngine.Material mat = new UnityEngine.Material(shader); bool collision = false; switch (shape.shader) { case "Collision": collision = true; break; case "PdxMeshSnow": snow.Add(mat); break; case "PdxMeshColor": color.Add(mat); break; case "PdxMeshTextureAtlas": atlas.Add(mat); mat.SetTexture("_Atlas", atlasExample); break; } if (_mat.HasTextureDiffuse) { if (_mat.TextureDiffuse.FilePath.EndsWith(".dds")) { string texPath = _mat.TextureDiffuse.FilePath; if (texPath[1] != ':') { texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureDiffuse.FilePath; } if (File.Exists(texPath)) { shape.diffuse = texPath; Texture2D tex = PdxLoader.LoadDDS(texPath); tex.name = Path.GetFileName(texPath); mat.SetTexture("_Diffuse", tex); } } } if (_mat.HasTextureHeight) { if (_mat.TextureHeight.FilePath.EndsWith(".dds")) { string texPath = _mat.TextureHeight.FilePath; if (texPath[1] != ':') { texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureHeight.FilePath; } if (File.Exists(texPath)) { shape.normal = texPath; Texture2D tex = PdxLoader.LoadDDS(texPath); tex.name = Path.GetFileName(texPath); mat.SetTexture("_Normal", tex); } } } if (_mat.HasTextureSpecular) { if (_mat.TextureSpecular.FilePath.EndsWith(".dds")) { string texPath = _mat.TextureSpecular.FilePath; if (texPath[1] != ':') { texPath = Path.GetDirectoryName(path) + Path.DirectorySeparatorChar + _mat.TextureSpecular.FilePath; } if (File.Exists(texPath)) { shape.specular = texPath; Texture2D tex = PdxLoader.LoadDDS(texPath); tex.name = Path.GetFileName(texPath); mat.SetTexture("_Specular", tex); } } } if (skinned) { SkinnedMeshRenderer smr = go.AddComponent <SkinnedMeshRenderer>(); smr.bones = bones; smr.rootBone = rootBone; mesh.bindposes = bindposes; mesh.boneWeights = boneWeights.ToArray(); smr.sharedMesh = mesh; if (collision) { smr.sharedMaterial = mat; } else { smr.sharedMaterials = new UnityEngine.Material[] { mat, highlightMaterial } }; shape.smr = smr; } else { MeshFilter mf = go.AddComponent <MeshFilter>(); mf.mesh = mesh; MeshRenderer mr = go.AddComponent <MeshRenderer>(); if (collision) { mr.sharedMaterial = mat; } else { mr.sharedMaterials = new UnityEngine.Material[] { mat, highlightMaterial } }; shape.mr = mr; } go.transform.SetParent(goRoot.transform); } #region import animation foreach (var a in scene.Animations) { if ((int)a.TicksPerSecond == 1) { EditorController.instance.Status("Can't load animation with custom frame rate", 1); break; } bool resampled = false; if (a.HasNodeAnimations) { PdxDataService.AnimationData adata = new PdxDataService.AnimationData(); #if UNITY_EDITOR print("fps: " + a.TicksPerSecond + ", duration: " + a.DurationInTicks); #endif adata.fps = 15;// (float)a.TicksPerSecond; adata.sampleCount = (int)a.DurationInTicks; adata.length = adata.sampleCount / adata.fps; foreach (var nac in a.NodeAnimationChannels) { resampled = nac.PositionKeyCount == adata.sampleCount + 1 || nac.RotationKeyCount == adata.sampleCount + 1 || nac.ScalingKeyCount == adata.sampleCount + 1; if (resampled) { break; } } #if UNITY_EDITOR print("resampled " + resampled); #endif foreach (var nac in a.NodeAnimationChannels) { if (!bonesByName.ContainsKey(nac.NodeName)) { continue; } var animation = new PdxDataService.AnimationData.Animation(); animation.name = nac.NodeName; animation.parent = bonesByName[nac.NodeName]; animation.keys = new List <PdxDataService.AnimationData.Key>(); for (int i = 0; i < adata.sampleCount + 1; i++) { animation.keys.Add(new PdxDataService.AnimationData.Key()); } animation.keys[0].pos = animation.parent.transform.localPosition; animation.keys[0].rot = animation.parent.transform.localRotation; animation.keys[0].scl = animation.parent.transform.localScale; //animation.sampleT = true; // or joint mistmatch error if (nac.HasPositionKeys) { if (resampled) { foreach (var pk in nac.PositionKeys) { int i = (int)pk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].pos = new Vector3(pk.Value.X, pk.Value.Y, pk.Value.Z); animation.keys[i].time = (float)pk.Time / (float)adata.fps; } } else { List <VectorKey> posKeys = nac.PositionKeys; if (ListVectorKey(ref posKeys, adata.sampleCount)) { animation.sampleT = true; foreach (var pk in posKeys) { int i = (int)pk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].pos = new Vector3(pk.Value.X, pk.Value.Y, pk.Value.Z); animation.keys[i].time = (float)pk.Time / (float)adata.fps; } } } } if (nac.HasRotationKeys) { if (resampled) { foreach (var rk in nac.RotationKeys) { int i = (int)rk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].rot = new UnityEngine.Quaternion(rk.Value.X, rk.Value.Y, rk.Value.Z, rk.Value.W); animation.keys[i].time = (float)rk.Time / (float)adata.fps; } } else { List <QuaternionKey> rotKeys = nac.RotationKeys; if (ListQuaternionKey(ref rotKeys, adata.sampleCount)) { animation.sampleQ = true; foreach (var rk in rotKeys) { int i = (int)rk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].rot = new UnityEngine.Quaternion(rk.Value.X, rk.Value.Y, rk.Value.Z, rk.Value.W); animation.keys[i].time = (float)rk.Time / (float)adata.fps; } } } } if (nac.HasScalingKeys) { if (resampled) { foreach (var sk in nac.ScalingKeys) { int i = (int)sk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].scl = new Vector3(sk.Value.X, sk.Value.Y, sk.Value.Z); animation.keys[i].time = (float)sk.Time / (float)adata.fps; } } else { List <VectorKey> sclKeys = nac.ScalingKeys; if (ListVectorKey(ref sclKeys, adata.sampleCount)) { animation.sampleS = true; foreach (var sk in sclKeys) { int i = (int)sk.Time + 1; if (i >= animation.keys.Count) { break; } animation.keys[i].scl = new Vector3(sk.Value.X, sk.Value.Y, sk.Value.Z); animation.keys[i].time = (float)sk.Time / (float)adata.fps; } } } } adata.hierarchy.Add(animation); } var player = goRoot.AddComponent <PdxAnimationPlayer>(); adata.Fix(); player.animationData = adata; } } #endregion EditorController.instance.SceneHasSnowMaterial(snow.Count > 0 ? snow.ToArray() : null); EditorController.instance.SceneHasColorMaterial(color.Count > 0 ? color.ToArray() : null); EditorController.instance.SceneHasAtlasMaterial(atlas.Count > 0 ? atlas.ToArray() : null); if (!path.ToLower().EndsWith(".obj")) { goRoot.transform.Translate(0, min, 0, Space.World); goRoot.transform.rotation = UnityEngine.Quaternion.Euler(90, 0, 0); } context.Dispose(); return(goRoot); }
static int nullBonesC = 0; //TODO remove this counter public static void Main(string[] args) { //Dir if (Directory.Exists("./obj")) { Console.WriteLine("Directory Found"); } else { printError("Creating Dir"); Directory.CreateDirectory("./obj"); } //File Input string fileName = "./obj/" + getUserInput("File name"); if (fileName == "./obj/") { string[] possibleFiles = Directory.GetFiles("./obj"); foreach (string currFileName in possibleFiles) { if (!currFileName.EndsWith(".txt") && !currFileName.EndsWith(".js")) { fileName = currFileName; break; } } } else { string[] possibleFiles = Directory.GetFiles("./obj"); foreach (string currFileName in possibleFiles) { if (!currFileName.Contains("fileName")) { fileName = currFileName; break; } } } Console.WriteLine("Files found, starting to read them"); try { File.Delete("./obj/output.txt"); } catch (Exception e) { printError("No file to delete, ignore this error" + e); } //Create a new importer AssimpContext importer = new AssimpContext(); importer.SetConfig(new IFCUseCustomTriangulationConfig(true)); importer.SetConfig(new SortByPrimitiveTypeConfig(PrimitiveType.Line | PrimitiveType.Point)); importer.SetConfig(new VertexBoneWeightLimitConfig(4)); //This is how we add a configuration (each config is its own class) //NormalSmoothingAngleConfig config = new NormalSmoothingAngleConfig(66.0f); //importer.SetConfig(config); //This is how we add a logging callback LogStream logstream = new LogStream(delegate(String msg, String userData) { Console.WriteLine(msg); }); logstream.Attach(); //Import the model. All configs are set. The model //is imported, loaded into managed memory. Then the unmanaged memory is released, and everything is reset. //Triangulating is already being done //TODO aiProcess_JoinIdenticalVertices (Index buffer objects) scene = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessSteps.FlipUVs | PostProcessSteps.OptimizeMeshes | PostProcessSteps.OptimizeGraph | PostProcessSteps.SortByPrimitiveType | PostProcessSteps.LimitBoneWeights); extractBones(scene.RootNode); createBoneTree(scene.RootNode, -1, Matrix4x4.Identity); parseNode(scene.RootNode); //End of example importer.Dispose(); adjVert = (Lookup <Vector3D, triAndVertIndex>)toLookup.ToLookup((item) => item.Key, (item) => item.Value); //First 3 => Point, Second 3 => Line //TODO Make this a bit better //For each triangle, store some bary coords Bary[] bary = new Bary[normals.Count]; //Filled with: default( int ) //Edit #region Bary coords and bones //Lines: for (int j = 0; j < toLookup.Count; j += 3) { Vector3D v0 = toLookup[j + 2].Key - toLookup[j + 1].Key; Vector3D v1 = toLookup[j + 2].Key - toLookup[j].Key; Vector3D v2 = toLookup[j + 1].Key - toLookup[j].Key; double area = Math.Abs(Vector3D.Cross(v1, v2).Length()) / 2; //Determinant of a 2D matrix, used to calculate the area of a parallelogram IEnumerable <triAndVertIndex> matchingVertices0 = adjVert[toLookup[j].Key]; IEnumerable <triAndVertIndex> matchingVertices1 = adjVert[toLookup[j + 1].Key]; IEnumerable <triAndVertIndex> matchingVertices2 = adjVert[toLookup[j + 2].Key]; //2 Matching points //TriIndex = triangle index of the adjacent triangle foreach (triAndVertIndex index in matchingVertices0) { //Oh, yeah! It's working! (Magic!) //TODO turn this into a function as well foreach (triAndVertIndex otherIndex in matchingVertices1) { //If it is part of the same line if (otherIndex.triIndex == index.triIndex) { double angleBetweenTriangles = (Vector3D.Dot(faceNormals[j / 3], faceNormals[otherIndex.triIndex])); if (angleBetweenTriangles < THRESHOLD) { //area = 1/2*base*height //2*area / base = height /* * dist = vec3(area / v0.Length(), 0, 0); * gl_Position = gl_PositionIn[0]; * EmitVertex(); * dist = vec3(0, area / v1.Length(), 0); * gl_Position = gl_PositionIn[1]; * EmitVertex(); * dist = vec3(0, 0, area / v2.Length()); * gl_Position = gl_PositionIn[2]; * EmitVertex();*/ bary[j / 3].l2 = area / v2.Length(); // 1;// angleBetweenTriangles + addTo; } //If we found the adjacent triangle, we can go to the next one break; } } } foreach (triAndVertIndex index in matchingVertices1) { foreach (triAndVertIndex otherIndex in matchingVertices2) { if (otherIndex.triIndex == index.triIndex) { double angleBetweenTriangles = (Vector3D.Dot(faceNormals[j / 3], faceNormals[otherIndex.triIndex])); if (angleBetweenTriangles < THRESHOLD) { bary[j / 3].l0 = area / v0.Length(); // TODO angleBetweenTriangles + addTo; } break; } } } foreach (triAndVertIndex index in matchingVertices2) { foreach (triAndVertIndex otherIndex in matchingVertices0) { if (otherIndex.triIndex == index.triIndex) { double angleBetweenTriangles = (Vector3D.Dot(faceNormals[j / 3], faceNormals[otherIndex.triIndex])); if (angleBetweenTriangles < THRESHOLD) { bary[j / 3].l1 = area / v1.Length(); // TODO angleBetweenTriangles + addTo; } break; } } } } //Draw the points as well for (int j = 0; j < toLookup.Count; j += 3) { Vector3D v0 = toLookup[j + 2].Key - toLookup[j + 1].Key; Vector3D v1 = toLookup[j + 2].Key - toLookup[j].Key; Vector3D v2 = toLookup[j + 1].Key - toLookup[j].Key; double area = Math.Abs(Vector3D.Cross(v1, v2).Length()) / 2; //Determinant of a 2D matrix, used to calculate the area of a parallelogram IEnumerable <triAndVertIndex> matchingVertices0 = adjVert[toLookup[j].Key]; IEnumerable <triAndVertIndex> matchingVertices1 = adjVert[toLookup[j + 1].Key]; IEnumerable <triAndVertIndex> matchingVertices2 = adjVert[toLookup[j + 2].Key]; /*int numberOfAdjBary = 0; * * //Index of the adjacent triangle * foreach (triAndVertIndex index in matchingVertices0) * { * //TODO turn this into a function as well * if ((bary[index.triIndex], ((index.vertIndex + 1) % 3) + 3] > 0 || bary[index.triIndex, ((index.vertIndex + 2) % 3) + 3] > 0) * && index.triIndex != j / 3) * { * numberOfAdjBary++; * } * } * //Every line is actually 2 lines * if (numberOfAdjBary >= 4) * { * //Now, we need to do the point calculations * double dist0 = area / v0.Length(); * //bary[j / 3, 0] = ; * } * numberOfAdjBary = 0; * foreach (triAndVertIndex index in matchingVertices1) * { * if ((bary[index.triIndex, ((index.vertIndex + 1) % 3) + 3] > 0 || bary[index.triIndex, ((index.vertIndex + 2) % 3) + 3] > 0) * && index.triIndex != j / 3) * { * numberOfAdjBary++; * } * } * if (numberOfAdjBary >= 4) * { * bary[j / 3, 1] = area / v1.Length(); * } * numberOfAdjBary = 0; * foreach (triAndVertIndex index in matchingVertices2) * { * if ((bary[index.triIndex, ((index.vertIndex + 1) % 3) + 3] > 0 || bary[index.triIndex, ((index.vertIndex + 2) % 3) + 3] > 0) * && index.triIndex != j / 3) * { * numberOfAdjBary++; * } * } * if (numberOfAdjBary >= 4) * { * bary[j / 3, 2] = area / v2.Length(); * }***/ } #endregion #if true //Create the output file StreamWriter JSONFile = File.CreateText("./obj/output.txt"); //Write to file JSONFile.Write("model = ["); bool firstTime = true; for (int j = 0, texCount = 0; j < vertices.Count; j++) { var index = j - texCount; Vector3D[] currVert = Program.vertices[j]; if (currVert.Length == 1) { if (firstTime) { JSONFile.Write("{"); firstTime = false; } else { JSONFile.Write("]},\n{"); } JSONFile.Write("name:\"" + texNames[(int)currVert[0].X] + "\",model:["); Console.Write(texNames[(int)currVert[0].X] + "---"); texCount++; } else { //Edit string[] baryCoordsOfTri = toBary(bary[index]); //Triangle for (int i = 0; i < 3; i++) { JSONFile.Write(Vec3DToString(currVert[i])); JSONFile.Write(UVToString(uvs[index][i])); JSONFile.Write(Vec3DToString(normals[index][i])); JSONFile.Write(baryCoordsOfTri[i]); bones[index][i].Weights[1] = 0; if (bones[index][i].BoneIDs[1] == -1) { bones[index][i].Weights[0] = 1; } if (bones[index][i].Weights[0] == 0.5) { bones[index][i].Weights[0] = 0.49f; } JSONFile.Write((bones[index][i].BoneIDs[0] + 0.5) + "," + (bones[index][i].BoneIDs[1] + 0.5) + "," + bones[index][i].Weights[0] + ","); if (bones[index][i].Weights[0] > 0.45 && bones[index][i].Weights[0] < 0.55) { //printError("W1: " + string.Join(",.,", bones[index][i].Weights)); } if (bones[index][i].Weights[0] > 0.9) { //printError("W1: " + string.Join(",.,", bones[index][i].Weights)); } } } } JSONFile.Write("]}];"); JSONFile.Close(); #endif StreamWriter bonesFile = File.CreateText("./obj/outputBones.txt"); //You are going to have to reorder the parts manually bonesFile.Write("bones = ["); foreach (BoneInfo boneNode in boneNodesList) { //TODO Number of bones (To nearest power of 2) //TODO Max number of influencing bones per vertex Quaternion rot, offsetRot; Vector3D translation, offsetTranslation; Vector3D scale, offsetScale; boneNode.localMat.Decompose(out scale, out rot, out translation); boneNode.BoneOffsetMatrix.Decompose(out offsetScale, out offsetRot, out offsetTranslation); //Console.WriteLine(QuaternionToString(rot) + "->\n" + MatToString1(rot.GetMatrix())); //Console.WriteLine(QuaternionToString(rot) + "->\n" + Matrix4x4.FromTranslation(translation)); //Don't use .ToString(), use a custom function! bonesFile.WriteLine( "{name:\"" + boneNode.Name + "\",parent:" + boneNode.Parent + ",pos:[" + Vec3DToString(translation, false) + "],qRot:[" + QuaternionToString(rot) + "],offsetPos:[" + Vec3DToString(offsetTranslation, false) + "],offsetRot:[" + QuaternionToString(offsetRot) + "]},"); } bonesFile.Write("];"); bonesFile.WriteLine("\nvar animations = [];"); bonesFile.Close(); try { File.Delete("./obj/output.js"); } catch (Exception) { }; try { File.Delete("./obj/outputBones.js"); } catch (Exception) { }; try { File.Move("./obj/output.txt", Path.ChangeExtension("./obj/output.txt", ".js")); } catch (Exception) { }; try { File.Move("./obj/outputBones.txt", Path.ChangeExtension("./obj/outputBones.txt", ".js")); } catch (Exception) { }; Console.WriteLine("Info: {0} Bones {1} vertices without bones", boneNodesList.Count, nullBonesC); Console.WriteLine("DONE!"); Console.Read(); }
public void Dispose() { m_importer.Dispose(); }
static public AssimpVolume LoadFromFile(string filename) { string path = Path.Combine("Assets", "Models", filename); AssimpContext importer = new AssimpContext(); NormalSmoothingAngleConfig normalSmoothing = new NormalSmoothingAngleConfig(66.0f); importer.SetConfig(normalSmoothing); LogStream logStream = new LogStream ( delegate(string message, string userData) { Console.Write(message); } ); logStream.Attach(); Scene model = importer.ImportFile(path, PostProcessPreset.TargetRealTimeMaximumQuality); Mesh mesh = model.Meshes[0]; AssimpVolume v = new AssimpVolume(); List <Vector3> newVertices = new List <Vector3>(); foreach (Assimp.Vector3D vert in mesh.Vertices) { newVertices.Add(new Vector3(vert.X, vert.Y, vert.Z)); } v.vertices = newVertices.ToArray(); v.indices = mesh.GetIndices(); if (mesh.HasNormals) { v.generateNormals = false; List <Vector3> newNormals = new List <Vector3>(); foreach (Assimp.Vector3D n in mesh.Normals) { newNormals.Add(new Vector3(n.X, n.Y, n.Z)); } v.normals = newNormals.ToArray(); } if (mesh.HasTextureCoords(0)) { List <Vector2> newTextureCoords = new List <Vector2>(); foreach (Assimp.Vector3D tc in mesh.TextureCoordinateChannels[0]) { newTextureCoords.Add(new Vector2(tc.X, tc.Y)); } v.textureCoords = newTextureCoords.ToArray(); } if (mesh.HasVertexColors(0)) { List <Vector3> newColors = new List <Vector3>(); foreach (Assimp.Color4D c in mesh.VertexColorChannels[0]) { newColors.Add(new Vector3(c.R, c.G, c.B)); } v.colors = newColors.ToArray(); } importer.Dispose(); return(v); }
public override List <Containers.Mesh> Parse(string path) { List <Containers.Mesh> meshes = new List <Containers.Mesh>(); AssimpContext ctx = new AssimpContext(); var scene = ctx.ImportFile(path, PostProcessSteps.Triangulate); if (scene.HasMeshes) { foreach (Assimp.Mesh m in scene.Meshes) { if (m.HasNormals && m.HasTextureCoords(0) && m.HasVertices) { Containers.Mesh ms = new Containers.Mesh(); foreach (Vector3D v in m.Normals) { ms.normals.Add(new OpenTK.Vector3(v.X, v.Y, v.Z)); //we also add placeholders for tangents ms.tangents.Add(new OpenTK.Vector4(0, 0, 0, 1)); } foreach (Vector3D v in m.Vertices) { ms.vertices.Add(new OpenTK.Vector3(v.X, v.Y, v.Z)); } foreach (Vector3D v in m.TextureCoordinateChannels[0]) { ms.uv.Add(new OpenTK.Vector2(v.X, v.Y)); } ms.indices = new List <int>(m.GetIndices()); //store faces for use with Mikktspace generation //and for displaying UVs foreach (Face f in m.Faces) { if (f.IndexCount == 3) { Triangle t = new Triangle(); t.n0 = t.v0 = t.u0 = f.Indices[0]; t.n1 = t.v1 = t.u1 = f.Indices[1]; t.n2 = t.v2 = t.u2 = f.Indices[2]; ms.AddTriangle(t); } } //generate tangents using mikktspace Mikkt.GenTangents(ms); meshes.Add(ms); } } } ctx.Dispose(); return(meshes); }