public void TestConvertFromStream() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); String outputPath = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.obj"); String outputPath2 = Path.Combine(TestHelper.RootPath, "TestFiles\\duck-fromBlob.obj"); FileStream fs = File.OpenRead(path); AssimpImporter importer = new AssimpImporter(); importer.AttachLogStream(new ConsoleLogStream()); importer.ConvertFromStreamToFile(fs, ".dae", outputPath, "obj"); fs.Position = 0; ExportDataBlob blob = importer.ConvertFromStreamToBlob(fs, ".dae", "collada"); fs.Close(); //Take ExportDataBlob's data, write it to a memory stream and export that back to an obj and write it MemoryStream memStream = new MemoryStream(); memStream.Write(blob.Data, 0, blob.Data.Length); memStream.Position = 0; importer.ConvertFromStreamToFile(memStream, ".dae", outputPath2, "obj"); memStream.Close(); }
public ModelLoader(Device device, TextureLoadHandler textureLoadHandler) { _device = device; _textureLoadHandler = textureLoadHandler; _importer = new AssimpImporter(); _importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); }
public void TestToStream() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); AssimpImporter importer = new AssimpImporter(); ExportDataBlob blob = importer.ConvertFromFileToBlob(path, "obj"); Assert.IsNotNull(blob); MemoryStream stream = new MemoryStream(); blob.ToStream(stream); Assert.IsTrue(stream.Length != 0); stream.Position = 0; ExportDataBlob blob2 = ExportDataBlob.FromStream(stream); Assert.IsNotNull(blob2); Assert.IsTrue(blob.Data.Length == blob.Data.Length); if(blob.NextBlob != null) { Assert.IsTrue(blob2.NextBlob != null); Assert.IsTrue(blob2.NextBlob.Name.Equals(blob.NextBlob.Name)); Assert.IsTrue(blob2.NextBlob.Data.Length == blob.NextBlob.Data.Length); } }
public void importmodel() { //string fileName = "F:/UNITY stuff/FlexHub/FlexHub_parts/FBX-Parts_FlexHub/Part_72.fbx"; allnodes.Clear(); //Create a new importer importer = new AssimpImporter(); // create an importer instance //importer.SetConfig (new con) model = importer.ImportFile(filetoImport //import the specified file //PostProcessSteps.JoinIdenticalVertices | //PostProcessSteps.FindInvalidData | //PostProcessSteps.RemoveRedundantMaterials | //PostProcessSteps.FixInFacingNormals ); Debug.Log(model.RootNode.Name + "\n" + "-----------------------------"); // get the root node name MasterNode = model.RootNode; // get the master node of the scene meshesinmodel = model.Meshes; GameObject gobject = convertNodes(MasterNode); // call the function and pass the resulting GO to a new GO importer.Dispose(); // diacard the importer when importing is done }
public void importmodel() { //string fileName = "F:/UNITY stuff/FlexHub/FlexHub_parts/FBX-Parts_FlexHub/Part_72.fbx"; allnodes.Clear(); //Create a new importer AssimpImporter importer = new AssimpImporter(); // create an importer instance //importer.SetConfig (new con) Scene model = importer.ImportFile(filetoImport, //import hte specified file PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.FindInvalidData | PostProcessSteps.RemoveRedundantMaterials | PostProcessSteps.FixInFacingNormals ); Debug.Log(model.RootNode.Name + "\n" + "-----------------------------"); // get the root node name MasterNode = model.RootNode; // get the master node of the scene GameObject gobject = convertNodes(MasterNode); // call the function and pass the resulting GO to a new GO //int count = gobject.transform.childCount; //for(int i = 0; i < count; i++) //{ // Transform obj = gobject.transform.GetChild(i); // Debug.Log(obj.name); //} importer.Dispose(); // diacard the importer when importing is done }
public AssimpModelLoader(string modelFilePath, SkeletonPerVertexBoneInfluenceType skeletonType = SkeletonPerVertexBoneInfluenceType.ThreeBones) { m_skeletonType = skeletonType; var importer = new AssimpImporter(); m_scene = importer.ImportFile(modelFilePath, PostProcessSteps.FlipUVs | PostProcessSteps.CalculateTangentSpace); }
/// <summary> /// Loads the model. /// </summary> protected override void Load(AssetLoadContext context, Stream stream, string extensionHint) { using (var importer = new AssimpImporter()) { var scene = importer.ImportFileFromStream(stream, postProcessing, extensionHint); this.Load(context, scene); } }
/// <summary> /// Loads a model file into the model. /// </summary> /// <param name="assetManager">AssetManager that provides texture assets</param> /// <param name="fileName">File name of the model.</param> public void Load(AssetManager assetManager, string fileName) { using (var importer = new AssimpImporter()) { var scene = importer.ImportFile(fileName, postProcessing); this.Load(new AssetLoadContext(assetManager, Path.GetFileNameWithoutExtension(fileName), "."), scene); } }
public void importmodel() { //string fileName = "F:/UNITY stuff/FlexHub/FlexHub_parts/FBX-Parts_FlexHub/Part_72.fbx"; allnodes.Clear(); //Create a new importer importer = new AssimpImporter(); // create an importer instance //importer.SetConfig (new con) model = importer.ImportFile(filetoImport, //import the specified file //PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.Triangulate | //very important PostProcessSteps.FindInvalidData | PostProcessSteps.RemoveRedundantMaterials ); Debug.Log(model.RootNode.Name + "\n" + "-----------------------------"); // get the root node name MasterNode = model.RootNode; // get the master node of the scene //meshesinmodel = model.Meshes; Debug.Log("No.Of Meshes in the model : " + model.MeshCount + "\n" + "-----------------------------"); //foreach (Assimp.Mesh m in meshesinmodel) //{ // Debug.Log("Polygon type: " +m.PrimitiveType); // /*************************************************************************************/ // Debug.Log("No. Vertices in this mesh: " +m.VertexCount); // verticesinmesh = m.Vertices; // for (int y = 0; y < verticesinmesh.Length; ++y) // { // Debug.Log ("vertex " + (y+1) + " is " + verticesinmesh[y]); // } // Debug.Log("No.Vertices detected in this mesh: " +verticesinmesh.Length); // /*************************************************************************************/ // Debug.Log("Faces in this mesh: " + m.FaceCount); // facesinmesh = m.Faces; // foreach (Assimp.Face f in facesinmesh) // { // faceindices = f.Indices; // for (int x = 0; x < faceindices.Length; ++x) // { // Debug.Log(faceindices[x]); // } // Debug.Log("Length of the face indeces array: "+faceindices.Length); // } // Debug.Log("No.Faces detected in this mesh: " + facesinmesh.Length); //} GameObject gobject = convertNodes(MasterNode); // call the function and pass the resulting GO to a new GO importer.Dispose(); // diacard the importer when importing is done }
public void Construct(Stream stream, Action <Vector3, Vector3, Vector2> appendVertex, Action <Int3> appendIndex, int index, string formatHint) { Assimp.AssimpImporter importer = new AssimpImporter(); Scene scene = importer.ImportFileFromStream(stream, PostProcessPreset.ConvertToLeftHanded | PostProcessPreset.TargetRealTimeQuality, formatHint); Assimp.Mesh mesh = scene.Meshes[index % scene.MeshCount]; int offset = 0; Construct(mesh, appendVertex, appendIndex, ref offset); }
public override SceneContent Import(FileStream stream, ContentManager manager) { AssimpImporter importer = new AssimpImporter(); Scene scene = importer.ImportFileFromStream(stream, PostProcessPreset.TargetRealTimeMaximumQuality, Path.GetExtension(stream.Name)); return(new SceneContent(scene) { Name = stream.Name }); }
public SimpleOpenGLSample() : base() { Title = "Quack! - Assimp.NET Simple OpenGL Sample"; String fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "duck.dae"); AssimpImporter importer = new AssimpImporter(); importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); m_model = importer.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality); ComputeBoundingBox(); }
public void TestConvertFromFile() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\Bob.md5mesh"); String outputPath = Path.Combine(TestHelper.RootPath, "TestFiles\\Bob.dae"); AssimpImporter importer = new AssimpImporter(); importer.ConvertFromFileToFile(path, outputPath, "collada"); ExportDataBlob blob = importer.ConvertFromFileToBlob(path, "collada"); }
public AssimpModel(RenderContext context, string fileName) { this.FileName = Path.GetFileName(fileName); this.context = context; loader = new BasicSubresourceLoader(Path.GetDirectoryName(fileName)); AssimpImporter importer = new AssimpImporter(); modelScene = importer.ImportFile(fileName, PostProcessSteps.Triangulate | PostProcessSteps.GenerateSmoothNormals); Visibility = true; Initialize(); }
public void TestObjLoad() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\sphere.obj"); AssimpImporter importer = new AssimpImporter(); Scene scene = importer.ImportFile(path); Assert.IsNotNull(scene); Assert.IsNotNull(scene.RootNode); Assert.IsTrue(scene.RootNode.Name.Equals("sphere.obj")); }
private Scene LoadDaeScene(String path) { Scene scene; using (var importer = new AssimpImporter()) { importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); scene = importer.ImportFile(path, PostProcessPreset.TargetRealTimeMaximumQuality); } return(scene); }
public void ConstructAll(string path, Action <Vector3, Vector3, Vector2> appendVertex, Action <Int3> appendIndex) { Assimp.AssimpImporter importer = new AssimpImporter(); Scene scene = importer.ImportFile(path, PostProcessPreset.ConvertToLeftHanded | PostProcessPreset.TargetRealTimeQuality); int offset = 0; foreach (Assimp.Mesh m in scene.Meshes) { Construct(m, appendVertex, appendIndex, ref offset); } }
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.LibraryLoaded) { 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 AssimpImporter(); 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); }
public void LoadScene() { AssimpImporter importer = new AssimpImporter(); LogStream logstream = new LogStream(delegate(String msg, String userData) { Console.WriteLine(msg); }); importer.AttachLogStream(logstream); m_scene = importer.ImportFile(Path.Combine(m_scenePath, m_sceneFileName)); // Oslobadjanje resursa koriscenih za ucitavanje podataka o sceni. importer.Dispose(); }
protected override void LoadContent() { // Importer for many models var importer = new AssimpImporter(); // Load a specific model //string fileName = System.IO.Path.GetFullPath(Content.RootDirectory + "/tower.3ds"); //Scene scene = importer.ImportFile(fileName, PostProcessSteps.MakeLeftHanded); //m_model = new Model(scene, GraphicsDevice, Content); // Load shader EffectCompilerFlags compilerFlags = EffectCompilerFlags.None; EffectCompiler compiler = new EffectCompiler(); #if DEBUG compilerFlags |= EffectCompilerFlags.Debug; #endif var simpleShaderCompileResult = compiler.CompileFromFile(Content.RootDirectory + "/pointlight.fx", compilerFlags); if (simpleShaderCompileResult.HasErrors) { System.Console.WriteLine(simpleShaderCompileResult.Logger.Messages); System.Diagnostics.Debugger.Break(); } m_simpleEffect = new SharpDX.Toolkit.Graphics.Effect(GraphicsDevice, simpleShaderCompileResult.EffectData); m_simpleEffect.Parameters["diffuseSampler"].SetResource(m_linearSamplerState); base.LoadContent(); map = new Map(@"Content\map.PNG", new Size2(20, 20)); map.LoadContent(GraphicsDevice, Content); player = new Player(new Vector3(0.0f, 10.0f, 0.0f), GraphicsDevice); player.Map = map; spritebatch = new SpriteBatch(GraphicsDevice, 2048); compass = Content.Load <Texture2D>("compass.png"); torch = Content.Load <Texture2D>("torchPlaceholder.png"); compassNeedle = Content.Load <Texture2D>("needle.png"); particle = Content.Load <Texture2D>("particle.png"); gameOver = Content.Load <Texture2D>("gameover.png"); emitter.position = new Vector2(width - torch.Width / 3, height - torch.Height / 3); }
/// <summary> /// Ucitavanje podataka o sceni iz odgovarajuceg fajla. /// </summary> public void LoadScene() { // Instanciranje klase za ucitavanje podataka o sceni. AssimpImporter importer = new AssimpImporter(); // Definisanje callback delegata za belezenje poruka u toku ucitavanja podataka o sceni. LogStream logstream = new LogStream(delegate(String msg, String userData) { Console.WriteLine(msg); }); importer.AttachLogStream(logstream); // Ucitavanje podataka o sceni iz odgovarajuceg fajla. m_scene = importer.ImportFile(Path.Combine(m_scenePath, m_sceneFileName)); // Oslobadjanje resursa koriscenih za ucitavanje podataka o sceni. importer.Dispose(); }
public List <DX11IndexedGeometry> LoadModelsFromFile(string path, AssimpLoadInformation loadInfo) { Assimp.AssimpImporter importer = new AssimpImporter(); Scene scene = importer.ImportFile(path, PostProcessPreset.ConvertToLeftHanded | PostProcessPreset.TargetRealTimeQuality); List <DX11IndexedGeometry> result = new List <DX11IndexedGeometry>(); for (int j = 0; j < scene.MeshCount; j++) { Assimp.Mesh mesh = scene.Meshes[j]; if (mesh.HasFaces && mesh.HasVertices) { result.Add(this.LoadFromMesh(mesh, loadInfo)); } } return(result); }
private static IModel LoadModelFromAssimp <VertexFormat, IndexFormat>(FileInfo fi, string modelName, Device device) where VertexFormat : IModelMeshComponents, new() where IndexFormat : struct { //Get Assimp Scene Scene scene; using (AssimpImporter importer = new AssimpImporter()) { //is imported, loaded into managed memory. Then the unmanaged memory is released, and everything is reset. scene = importer.ImportFile(fi.FullName, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessPreset.ConvertToLeftHanded); } //Get components var components = ((IModelMeshComponents) new VertexFormat()).Components; //Build custom buffer format from passed in components bool isP = (components & ModelMesh.ModelMesh.ModelMeshComponents.P) == ModelMesh.ModelMesh.ModelMeshComponents.P; bool isN = (components & ModelMesh.ModelMesh.ModelMeshComponents.N) == ModelMesh.ModelMesh.ModelMeshComponents.N; bool isT = (components & ModelMesh.ModelMesh.ModelMeshComponents.T) == ModelMesh.ModelMesh.ModelMeshComponents.T; bool isC = (components & ModelMesh.ModelMesh.ModelMeshComponents.C) == ModelMesh.ModelMesh.ModelMeshComponents.C; //index Format TypeCode typeCode = Type.GetTypeCode(typeof(IndexFormat)); IModel model = null; if (isP && !(isN || isT || isC)) { if (typeCode == TypeCode.UInt16) { model = Generate_P_UINT16(scene, device); } if (typeCode == TypeCode.UInt32) { model = Generate_P_UINT32(scene, device); } } if (isP && isC && !(isN || isT)) { if (typeCode == TypeCode.UInt16) { model = Generate_PC_UINT16(scene, device); } if (typeCode == TypeCode.UInt32) { model = Generate_PC_UINT32(scene, device); } } if (isP && isN && !(isT || isC)) { if (typeCode == TypeCode.UInt16) { model = Generate_PN_UINT16(scene, device); } if (typeCode == TypeCode.UInt32) { model = Generate_PN_UINT32(scene, device); } } if (isP && isN && isC && !(isT)) { if (typeCode == TypeCode.UInt16) { model = Generate_PNC_UINT16(scene, device); } if (typeCode == TypeCode.UInt32) { model = Generate_PNC_UINT32(scene, device); } } if (isP && isN && isT && isC) { if (typeCode == TypeCode.UInt16) { model = Generate_PNTC_UINT16(scene, device); } if (typeCode == TypeCode.UInt32) { model = Generate_PNTC_UINT32(scene, device); } } if (model == null) { return(null); } model.ModelFilePath = fi.FullName; model.Name = modelName; return(model); }
public void TestSupportedFormats() { AssimpImporter importer = new AssimpImporter(); ExportFormatDescription[] exportDescs = importer.GetSupportedExportFormats(); String[] importFormats = importer.GetSupportedImportFormats(); Assert.IsNotNull(exportDescs); Assert.IsNotNull(importFormats); Assert.IsTrue(exportDescs.Length >= 1); Assert.IsTrue(importFormats.Length >= 1); Assert.IsTrue(importer.IsExportFormatSupported(exportDescs[0].FileExtension)); Assert.IsTrue(importer.IsImportFormatSupported(importFormats[0])); }
private void ConvertSceneC() { Console.WriteLine("Thread C: Starting convert."); AssimpImporter importer = new AssimpImporter(); String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); String outputPath = Path.Combine(TestHelper.RootPath, "TestFiles\\duck2.obj"); importer.AttachLogStream(new ConsoleLogStream("Thread C:")); importer.SetConfig(new NormalSmoothingAngleConfig(55.0f)); importer.SetConfig(new FavorSpeedConfig(true)); importer.VerboseLoggingEnabled = true; Console.WriteLine("Thread C: Converting"); ExportDataBlob blob = importer.ConvertFromFileToBlob(path, "obj"); Console.WriteLine("Thread C: Done converting"); }
private void objPath_TextChanged(object sender, TextChangedEventArgs e) { string file = objPath.Text; if (file != null && file != "" && File.Exists(file)) { this.file = file; //objPath.Text = file; new Thread(() => { try { this.texturepossible = false; int minx = 1000000, maxx = -1000000, miny = 1000000, maxy = -1000000, minz = 1000000, maxz = -1000000; Scene scene = new AssimpImporter().ImportFile(file); foreach (Mesh m in scene.Meshes) { if (m.TextureCoordsChannelCount > 0) { this.texturepossible = true; } foreach (Assimp.Vector3D p in m.Vertices) { if (p.X < minx) { minx = (int)p.X; } else if (p.X > maxx) { maxx = (int)p.X; } if (p.Y < miny) { miny = (int)p.Y; } else if (p.Y > maxy) { maxy = (int)p.Y; } if (p.Z < minz) { minz = (int)p.Z; } else if (p.Z > maxz) { maxz = (int)p.Z; } } } this.Dispatcher.Invoke((Action)(() => { BoundsBox.Content = @"(" + (maxx - minx) + "x" + (maxy - miny) + "x" + (maxz - minz) + ")"; })); } catch (Exception ex) { System.Windows.MessageBox.Show(ex.Message, "Couldn't load mesh file"); this.file = null; } }).Start(); } }
private void Convertobj(object sender, DoWorkEventArgs e) { Scene scene = new AssimpImporter().ImportFile(file, PostProcessSteps.Triangulate); //List<Triangle> splittriangles = new List<Triangle>(); pointlist = new HashSet <Point3D>(); //pointlist.ToDictionary<> int progress = 0; int total = 0; try { foreach (Mesh m in scene.Meshes) { foreach (Face face in m.Faces) { total++; } } foreach (Mesh m in scene.Meshes) { foreach (Face face in m.Faces) { IList <Point3D> vertices = new List <Point3D>(); foreach (uint i in face.Indices) { double x = m.Vertices[i].X * scale; double y = m.Vertices[i].Y * scale; double z = m.Vertices[i].Z * scale; Point3D point; if (flipyz) { if (flipxz) { point = new Point3D(y, z, flipz * x); } else { point = new Point3D(x, z, flipz * y); } } else { if (flipxz) { point = new Point3D(z, y, flipz * x); } else { point = new Point3D(x, y, flipz * z); } } vertices.Add(point); pointlist.Add(new Point3D((int)Math.Floor(point.X), (int)Math.Floor(point.Y), (int)Math.Floor(point.Z))); } if (vertices.Count == 3) { Triangle triangle = new Triangle(vertices); if (!triangle.BoundsSmallerThan(bounds)) { Splittriangles(triangle); } } else { } progress++; backgroundWorker.ReportProgress((progress * 100) / total); if (backgroundWorker.CancellationPending) { e.Cancel = true; } } } } catch (Exception ex) { if (!(ex is OperationCanceledException)) { System.Windows.MessageBox.Show(ex.Message, "Something went wrong converting the obj"); } else { e.Cancel = true; } } try { if (backgroundWorker.CancellationPending) { throw new OperationCanceledException(); } dynamic blueprint = new JObject(); try { blueprint = BlueprintOptimizer.CreateBlueprintFromPoints(pointlist); } catch (Exception bpex) { System.Windows.MessageBox.Show(bpex.Message, "Something went wrong building the blueprint"); } int amountgenerated = blueprint.bodies[0].childs.Count; string message = "converted obj to blueprint with " + amountgenerated + " blocks !"; //MessageBox.Show(message+"\n\nOptimized to: "+count+" shapes"); Random r = new Random(); string blueprintpath = Database.User_ + "\\Blueprints\\Generatedblueprintobj-" + r.Next() + r.Next(); dynamic description = new JObject(); description.description = "generated obj blueprint with " + amountgenerated + " block"; description.name = "generated blueprint" + r.Next(); description.type = "Blueprint"; description.version = 0; new Task(() => { System.Windows.MessageBox.Show(message + "\nPLEASE WAIT for the rendering to complete"); }).Start(); if (BP.Blueprintpath == null) {//no blueprint exists, initialize new one new BP(blueprintpath, blueprint, description); } else {//overwrite current blueprint BP.setblueprint(blueprint); BP.Description.description += message; } } catch (Exception exc) { System.Windows.MessageBox.Show(exc.Message, "error"); } }
private void Convertobjwtexture(object sender, DoWorkEventArgs e) { try { Scene scene = new AssimpImporter().ImportFile(file, PostProcessSteps.Triangulate); coloredpoints = new Dictionary <Point3D, Point3D>(); //List<Triangle> splittriangles = new List<Triangle>(); //pointlist = new HashSet<Point3D>(); //pointlist.ToDictionary<> int progress = 0; int total = 0; foreach (Mesh m in scene.Meshes) { foreach (Face face in m.Faces) { total++; } } foreach (Mesh m in scene.Meshes) { var texturecoords = m.GetTextureCoords(0); foreach (Face face in m.Faces) { IList <Point3D> vertices = new List <Point3D>(); IList <Point3D> texturepoints = new List <Point3D>(); foreach (uint i in face.Indices) { double x = m.Vertices[i].X * scale; double y = m.Vertices[i].Y * scale; double z = m.Vertices[i].Z * scale; Point3D point; Assimp.Vector3D texturep = texturecoords[i]; Point3D texturepoint = new Point3D(texturep.X, 1 - texturep.Y, texturep.Z); if (flipyz) { if (flipxz) { point = new Point3D(y, z, flipz * x); } else { point = new Point3D(x, z, flipz * y); } } else { if (flipxz) { point = new Point3D(z, y, flipz * x); } else { point = new Point3D(x, y, flipz * z); } } vertices.Add(point); texturepoints.Add(texturepoint); Point3D flooredpoint = new Point3D((int)Math.Floor(point.X), (int)Math.Floor(point.Y), (int)Math.Floor(point.Z)); if (!coloredpoints.ContainsKey(flooredpoint)) { coloredpoints.Add(flooredpoint, texturepoint); } } if (vertices.Count == 3) { ColorTriangle triangle = new ColorTriangle(vertices, texturepoints); if (!triangle.BoundsSmallerThan(bounds)) { Splitcolortriangles(triangle); } } else { } progress++; backgroundWorker.ReportProgress((progress * 100) / total); if (backgroundWorker.CancellationPending) { e.Cancel = true; } } } } catch (Exception ex) { if (!(ex is OperationCanceledException)) { System.Windows.MessageBox.Show(ex.Message, "Something went wrong converting the obj+texture"); } else { e.Cancel = true; } } try { if (backgroundWorker.CancellationPending) { throw new OperationCanceledException(); } dynamic blueprint = new JObject(); try { Bitmap texturemap = new Bitmap(this.texture); HashSet <Tuple <Point3D, string> > pointswithcolor = new HashSet <Tuple <Point3D, string> >(); int width = texturemap.Width; int height = texturemap.Height; foreach (var pair in coloredpoints) { int x = (int)(pair.Value.X * width); int y = (int)(pair.Value.Y * height); if (pair.Value.Y > 1) { } while (y < 0) { y++; } while (x < 0) { x++; } if (Math.Abs(x) > width / 2) { } while (x >= width) { x -= width; } while (y >= height) { y -= height; } System.Drawing.Color color = texturemap.GetPixel(x, y); string c = color.Name.Substring(2); pointswithcolor.Add(new Tuple <Point3D, string>(pair.Key, c)); } coloredpoints.Clear(); blueprint = BlueprintOptimizer.CreateBlueprintFromPointsAndColor(pointswithcolor); } catch (Exception bpex) { System.Windows.MessageBox.Show(bpex.Message, "Something went wrong building the blueprint"); } int amountgenerated = blueprint.bodies[0].childs.Count; string message = "converted obj to blueprint with " + amountgenerated + " blocks !"; //MessageBox.Show(message+"\n\nOptimized to: "+count+" shapes"); Random r = new Random(); string blueprintpath = Database.User_ + "\\Blueprints\\Generatedblueprintobj-" + r.Next() + r.Next(); dynamic description = new JObject(); description.description = "generated obj blueprint with " + amountgenerated + " block"; description.name = "generated blueprint" + r.Next(); description.type = "Blueprint"; description.version = 0; new Task(() => { System.Windows.MessageBox.Show(message + "\nPLEASE WAIT for the rendering to complete"); }).Start(); if (BP.Blueprintpath == null) {//no blueprint exists, initialize new one new BP(blueprintpath, blueprint, description); } else {//overwrite current blueprint BP.setblueprint(blueprint); BP.Description.description += message; } } catch (Exception exc) { System.Windows.MessageBox.Show(exc.Message, "error"); } }
private void LoadSceneA() { Console.WriteLine("Thread A: Starting import."); AssimpImporter importer = new AssimpImporter(); String path = Path.Combine(TestHelper.RootPath, "TestFiles\\Bob.md5mesh"); importer.AttachLogStream(new ConsoleLogStream("Thread A:")); Console.WriteLine("Thread A: Importing"); Scene scene = importer.ImportFile(path); Console.WriteLine("Thread A: Done importing"); }
public BasicModel(Device device, TextureManager texMgr, string filename, string texturePath, bool flipUV = false) { var importer = new AssimpImporter(); if (!importer.IsImportFormatSupported(Path.GetExtension(filename))) { throw new ArgumentException("Model format " + Path.GetExtension(filename) + " is not supported! Cannot load {1}", "filename"); } #if DEBUG importer.AttachLogStream(new ConsoleLogStream()); importer.VerboseLoggingEnabled = true; #endif var postProcessFlags = PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace; if (flipUV) { postProcessFlags |= PostProcessSteps.FlipUVs; } var model = importer.ImportFile(filename, postProcessFlags); var min = new Vector3(float.MaxValue); var max = new Vector3(float.MinValue); foreach (var mesh in model.Meshes) { var verts = new List <PosNormalTexTan>(); var subset = new MeshGeometry.Subset { VertexCount = mesh.VertexCount, VertexStart = Vertices.Count, FaceStart = Indices.Count / 3, FaceCount = mesh.FaceCount }; Subsets.Add(subset); // bounding box corners for (var i = 0; i < mesh.VertexCount; i++) { var pos = mesh.HasVertices ? mesh.Vertices[i].ToVector3() : new Vector3(); min = Vector3.Minimize(min, pos); max = Vector3.Maximize(max, pos); var norm = mesh.HasNormals ? mesh.Normals[i] : new Vector3D(); var texC = mesh.HasTextureCoords(0) ? mesh.GetTextureCoords(0)[i] : new Vector3D(); var tan = mesh.HasTangentBasis ? mesh.Tangents[i] : new Vector3D(); var v = new PosNormalTexTan(pos, norm.ToVector3(), texC.ToVector2(), tan.ToVector3()); verts.Add(v); } Vertices.AddRange(verts); var indices = mesh.GetIndices().Select(i => (short)(i + (uint)subset.VertexStart)).ToList(); Indices.AddRange(indices); var mat = model.Materials[mesh.MaterialIndex]; var material = mat.ToMaterial(); Materials.Add(material); var diffusePath = mat.GetTexture(TextureType.Diffuse, 0).FilePath; if (Path.GetExtension(diffusePath) == ".tga") { // DirectX doesn't like to load tgas, so you will need to convert them to pngs yourself with an image editor diffusePath = diffusePath.Replace(".tga", ".png"); } if (!string.IsNullOrEmpty(diffusePath)) { DiffuseMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, diffusePath))); } var normalPath = mat.GetTexture(TextureType.Normals, 0).FilePath; if (!string.IsNullOrEmpty(normalPath)) { NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath))); } else { var normalExt = Path.GetExtension(diffusePath); normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt; NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath))); } } BoundingBox = new BoundingBox(min, max); ModelMesh.SetSubsetTable(Subsets); ModelMesh.SetVertices(device, Vertices); ModelMesh.SetIndices(device, Indices); }
private void LoadSceneB() { Console.WriteLine("Thread B: Starting import."); AssimpImporter importer = new AssimpImporter(); String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); importer.AttachLogStream(new ConsoleLogStream("Thread B:")); importer.SetConfig(new NormalSmoothingAngleConfig(55.0f)); Console.WriteLine("Thread B: Importing"); Scene scene = importer.ImportFile(path); Console.WriteLine("Thread B: Done importing"); }
public ModelLoader(Device device) { m_device = device; m_importer = new AssimpImporter(); m_importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); }
public SkinnedModel(Device device, TextureManager texMgr, string filename, string texturePath, bool flipTexY = false) { var importer = new AssimpImporter(); #if DEBUG importer.AttachLogStream(new ConsoleLogStream()); importer.VerboseLoggingEnabled = true; #endif var model = importer.ImportFile(filename, PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.CalculateTangentSpace); // Load animation data Animator = new SceneAnimator(); Animator.Init(model); // create our vertex-to-boneweights lookup var vertToBoneWeight = new Dictionary <uint, List <VertexWeight> >(); // create bounding box extents _min = new Vector3(float.MaxValue); _max = new Vector3(float.MinValue); foreach (var mesh in model.Meshes) { ExtractBoneWeightsFromMesh(mesh, vertToBoneWeight); var subset = new MeshGeometry.Subset { VertexCount = mesh.VertexCount, VertexStart = Vertices.Count, FaceStart = Indices.Count / 3, FaceCount = mesh.FaceCount }; Subsets.Add(subset); var verts = ExtractVertices(mesh, vertToBoneWeight, flipTexY); Vertices.AddRange(verts); // extract indices and shift them to the proper offset into the combined vertex buffer var indices = mesh.GetIndices().Select(i => (short)(i + (uint)subset.VertexStart)).ToList(); Indices.AddRange(indices); // extract materials var mat = model.Materials[mesh.MaterialIndex]; var material = mat.ToMaterial(); Materials.Add(material); // extract material textures var diffusePath = mat.GetTexture(TextureType.Diffuse, 0).FilePath; if (!string.IsNullOrEmpty(diffusePath)) { DiffuseMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, diffusePath))); } var normalPath = mat.GetTexture(TextureType.Normals, 0).FilePath; if (!string.IsNullOrEmpty(normalPath)) { NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath))); } else { // for models created without a normal map baked, we'll check for a texture with the same // filename as the diffure texture, and _nmap suffixed // this lets us add our own normal maps easily var normalExt = Path.GetExtension(diffusePath); normalPath = Path.GetFileNameWithoutExtension(diffusePath) + "_nmap" + normalExt; if (File.Exists(Path.Combine(texturePath, normalPath))) { NormalMapSRV.Add(texMgr.CreateTexture(Path.Combine(texturePath, normalPath))); } } } BoundingBox = new BoundingBox(_min, _max); ModelMesh.SetSubsetTable(Subsets); ModelMesh.SetVertices(device, Vertices); ModelMesh.SetIndices(device, Indices); }
public void TestImportFromStream() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); FileStream fs = File.OpenRead(path); AssimpImporter importer = new AssimpImporter(); importer.VerboseLoggingEnabled = true; LogStream logstream = new LogStream(delegate(String msg, String userData) { Console.WriteLine(msg); }); importer.AttachLogStream(logstream); Scene scene = importer.ImportFileFromStream(fs, ".dae"); fs.Close(); Assert.IsNotNull(scene); Assert.IsTrue((scene.SceneFlags & SceneFlags.Incomplete) != SceneFlags.Incomplete); }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: ModelCompiler.exe model.dae"); return; } foreach (string filename in args) { AssimpImporter importer = new AssimpImporter(); PostProcessSteps steps = PostProcessPreset.TargetRealTimeMaximumQuality; steps |= PostProcessSteps.OptimizeMeshes | PostProcessSteps.SplitLargeMeshes | PostProcessSteps.Triangulate | PostProcessSteps.FlipUVs | PostProcessSteps.LimitBoneWeights; importer.SetConfig(new VertexBoneWeightLimitConfig(2)); Scene scene = importer.ImportFile(filename, steps); Vector3D bbMin = new Vector3D(float.MaxValue, float.MaxValue, float.MaxValue); Vector3D bbMax = new Vector3D(float.MinValue, float.MinValue, float.MinValue); Node meshNode = scene.RootNode; while (!meshNode.HasMeshes) { meshNode = meshNode.Children[0]; } Mesh nodeGeometry = scene.Meshes[meshNode.MeshIndices[0]]; List <Vector3D> transformedVertices = new List <Vector3D>(); foreach (Vector3D vertex in nodeGeometry.Vertices) { Vector4 tempv = new Vector4(vertex.X, vertex.Y, vertex.Z, 1.0f); Matrix tempm = Matrix.Scaling(0.1f) * Matrix.RotationYawPitchRoll(((float)Math.PI / 2.0f), ((float)Math.PI / 2.0f), 0.0f) * new Matrix(meshNode.Transform.A1, meshNode.Transform.A2, meshNode.Transform.A3, meshNode.Transform.A3, meshNode.Transform.B1, meshNode.Transform.B2, meshNode.Transform.B3, meshNode.Transform.B3, meshNode.Transform.C1, meshNode.Transform.C2, meshNode.Transform.C3, meshNode.Transform.C3, meshNode.Transform.D1, meshNode.Transform.D2, meshNode.Transform.D3, meshNode.Transform.D3); Vector4 finalvec = Vector4.Transform(tempv, tempm); transformedVertices.Add(new Vector3D(finalvec.X, finalvec.Y, finalvec.Z)); } using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(filename + ".mdl"))) { foreach (Vector3D vector in transformedVertices) { bbMin.X = Math.Min(vector.X, bbMin.X); bbMin.Y = Math.Min(vector.Y, bbMin.Y); bbMin.Z = Math.Min(vector.Z, bbMin.Z); bbMax.X = Math.Max(vector.X, bbMax.X); bbMax.Y = Math.Max(vector.Y, bbMax.Y); bbMax.Z = Math.Max(vector.Z, bbMax.Z); } writer.Write(bbMin.X); writer.Write(bbMin.Y); writer.Write(bbMin.Z); writer.Write(bbMax.X); writer.Write(bbMax.Y); writer.Write(bbMax.Z); //writer.Write(scene.Meshes.Length); writer.Write(1); Mesh currentMesh = nodeGeometry; if (!currentMesh.HasTextureCoords(0)) { Console.WriteLine("ERROR: model must have texture coordinates"); return; } Vector3D[] texCoords = currentMesh.GetTextureCoords(0); writer.Write(currentMesh.VertexCount); for (int j = 0; j < currentMesh.VertexCount; j++) { writer.Write(transformedVertices[j].X); writer.Write(transformedVertices[j].Y); writer.Write(transformedVertices[j].Z); writer.Write(texCoords[j].X); writer.Write(texCoords[j].Y); } writer.Write(currentMesh.Faces.Length * 3); for (int j = 0; j < currentMesh.Faces.Length; j++) { Face currentFace = currentMesh.Faces[j]; if (currentFace.IndexCount != 3) { Console.WriteLine("ERROR: non-triangle found!"); Console.ReadKey(); return; } foreach (uint index in currentFace.Indices) { writer.Write((int)index); } } //writer.Write(currentMesh.Faces.Length * 3); //for (int j = 0; j < currentMesh.Faces.Length; j++) //{ // Face currentFace = currentMesh.Faces[j]; // if (currentFace.IndexCount != 3) // { // Console.WriteLine("ERROR: non-triangle found!"); // Console.ReadKey(); // return; // } // foreach (uint index in currentFace.Indices) // { // writer.Write(transformedVertices[(int)index].X); // writer.Write(transformedVertices[(int)index].Y); // writer.Write(transformedVertices[(int)index].Z); // writer.Write(texCoords[index].X); // writer.Write(texCoords[index].Y); // } //} } } }
public static void MeshToStaticModel(string file) { AssimpImporter importer = new AssimpImporter(); try { Scene scene = importer.ImportFile(file, PostProcessSteps.Triangulate); if (scene.MeshCount == 1) { Vector3D[] vertices = scene.Meshes[0].Vertices; Vector3D[] uvCoords = scene.Meshes[0].GetTextureCoords(0); Vector3D[] normals = null; short[] indices = scene.Meshes[0].GetShortIndices(); if (!scene.Meshes[0].HasNormals) { MessageBox.Show("Mesh doesn't have normals. Check if the mesh has been exported correctly.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); } normals = scene.Meshes[0].Normals; // 4 byte floats * 3 dimensions byte[] vertexData = new byte[12 * vertices.Length]; // 4 byte floats * 2 dimensions byte[] uvData = new byte[8 * uvCoords.Length]; // 4 byte normals * 3 dimensions byte[] normalData = new byte[12 * normals.Length]; int vertexOffset = 0, uvOffset = 0, normalOffset = 0; // Extract vertex data for (int i = 0; i < vertices.Length; ++i) { byte[] x, y, z; x = BitConverter.GetBytes(vertices[i].X); y = BitConverter.GetBytes(vertices[i].Y); z = BitConverter.GetBytes(vertices[i].Z); Buffer.BlockCopy(x, 0, vertexData, vertexOffset, 4); Buffer.BlockCopy(y, 0, vertexData, vertexOffset + 4, 4); Buffer.BlockCopy(z, 0, vertexData, vertexOffset + 8, 4); vertexOffset += 12; } // Extract UV coordinates data for (int i = 0; i < uvCoords.Length; ++i) { byte[] s, t; s = BitConverter.GetBytes(uvCoords[i].X); t = BitConverter.GetBytes(uvCoords[i].Y); Buffer.BlockCopy(s, 0, uvData, uvOffset, 4); Buffer.BlockCopy(t, 0, uvData, uvOffset + 4, 4); uvOffset += 8; } // Extract normal data for (int i = 0; i < normals.Length; ++i) { byte[] x, y, z; x = BitConverter.GetBytes(normals[i].X); y = BitConverter.GetBytes(normals[i].Y); z = BitConverter.GetBytes(normals[i].Z); Buffer.BlockCopy(x, 0, normalData, normalOffset, 4); Buffer.BlockCopy(y, 0, normalData, normalOffset + 4, 4); Buffer.BlockCopy(z, 0, normalData, normalOffset + 8, 4); normalOffset += 12; } // Save the raw mesh file byte[] binary = new byte[MESH_HEADER_LENGTH + vertexData.Length + uvData.Length + normalData.Length + 2 * indices.Length]; // Set the vertex count binary[0] = BitConverter.GetBytes((UInt16)vertices.Length)[0]; binary[1] = BitConverter.GetBytes((UInt16)vertices.Length)[1]; // Copy the vertices Buffer.BlockCopy(vertexData, 0, binary, MESH_HEADER_LENGTH, vertexData.Length); // Copy the UV coordinates Buffer.BlockCopy(uvData, 0, binary, MESH_HEADER_LENGTH + vertexData.Length, uvData.Length); // Copy the normals Buffer.BlockCopy(normalData, 0, binary, MESH_HEADER_LENGTH + vertexData.Length + uvData.Length, normalData.Length); // Copy the indices Buffer.BlockCopy(indices, 0, binary, MESH_HEADER_LENGTH + vertexData.Length + uvData.Length + normalData.Length, 2 * indices.Length); // Save the converted file File.WriteAllBytes(file.Split('.')[0] + ".mesh", binary); } else { MessageBox.Show("Model has " + scene.MeshCount + " submeshes. Only models with one submesh can be processed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (AssimpException assExp) { MessageBox.Show(assExp.Message, "Error converting mesh", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public override NodeContent Import(string filename, ContentImporterContext context) { var identity = new ContentIdentity(filename, GetType().Name); var importer = new AssimpImporter(); importer.AttachLogStream(new LogStream((msg, userData) => context.Logger.LogMessage(msg))); var scene = importer.ImportFile(filename, PostProcessSteps.FlipUVs | // So far appears necessary PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.Triangulate | PostProcessSteps.SortByPrimitiveType | PostProcessSteps.FindInvalidData ); var rootNode = new NodeContent { Name = scene.RootNode.Name, Identity = identity, Transform = ToXna(scene.RootNode.Transform) }; // TODO: Materials var materials = new List <MaterialContent>(); foreach (var sceneMaterial in scene.Materials) { var diffuse = sceneMaterial.GetTexture(TextureType.Diffuse, 0); materials.Add(new BasicMaterialContent() { Name = sceneMaterial.Name, Identity = identity, Texture = new ExternalReference <TextureContent>(diffuse.FilePath, identity) }); } // Meshes var meshes = new Dictionary <Mesh, MeshContent>(); foreach (var sceneMesh in scene.Meshes) { if (!sceneMesh.HasVertices) { continue; } var mesh = new MeshContent { Name = sceneMesh.Name }; // Position vertices are shared at the mesh level foreach (var vert in sceneMesh.Vertices) { mesh.Positions.Add(new Vector3(vert.X, vert.Y, vert.Z)); } var geom = new GeometryContent { Name = string.Empty, //Material = materials[sceneMesh.MaterialIndex] }; // Geometry vertices reference 1:1 with the MeshContent parent, // no indirection is necessary. geom.Vertices.Positions.AddRange(mesh.Positions); geom.Vertices.AddRange(Enumerable.Range(0, sceneMesh.VertexCount)); geom.Indices.AddRange(sceneMesh.GetIntIndices()); // Individual channels go here if (sceneMesh.HasNormals) { geom.Vertices.Channels.Add(VertexChannelNames.Normal(), ToXna(sceneMesh.Normals)); } for (var i = 0; i < sceneMesh.TextureCoordsChannelCount; i++) { geom.Vertices.Channels.Add(VertexChannelNames.TextureCoordinate(i), ToXnaVector2(sceneMesh.GetTextureCoords(i))); } mesh.Geometry.Add(geom); rootNode.Children.Add(mesh); meshes.Add(sceneMesh, mesh); } // Bones var bones = new Dictionary <Node, BoneContent>(); var hierarchyNodes = scene.RootNode.Children.SelectDeep(n => n.Children).ToList(); foreach (var node in hierarchyNodes) { var bone = new BoneContent { Name = node.Name, Transform = Matrix.Transpose(ToXna(node.Transform)) }; if (node.Parent == scene.RootNode) { rootNode.Children.Add(bone); } else { var parent = bones[node.Parent]; parent.Children.Add(bone); } // Copy the bone's name to the MeshContent - this appears to be // the way it comes out of XNA's FBXImporter. foreach (var meshIndex in node.MeshIndices) { meshes[scene.Meshes[meshIndex]].Name = node.Name; } bones.Add(node, bone); } return(rootNode); }
public void TestImportFromFile() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\sphere.obj"); AssimpImporter importer = new AssimpImporter(); importer.SetConfig(new NormalSmoothingAngleConfig(55.0f)); importer.Scale = .5f; importer.XAxisRotation = 25.0f; importer.YAxisRotation = 50.0f; importer.VerboseLoggingEnabled = 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); }
protected override void Initialize() { AddExportHandler <ObjectSet>(filePath => { if (filePath.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase)) { Data.TryFixParentBoneInfos(SourceConfiguration?.BoneDatabase); FbxExporter.ExportToFile(Data, filePath); } else { var configuration = ConfigurationList.Instance.CurrentConfiguration; var objectDatabase = configuration?.ObjectDatabase; var textureDatabase = configuration?.TextureDatabase; var boneDatabase = configuration?.BoneDatabase; Data.Save(filePath, objectDatabase, textureDatabase, boneDatabase); } }); AddExportHandler <Scene>(filePath => { Data.TryFixParentBoneInfos(SourceConfiguration?.BoneDatabase); AssimpExporter.ExportToFile(Data, filePath); }); AddReplaceHandler <ObjectSet>(filePath => { var configuration = ConfigurationList.Instance.CurrentConfiguration; var objectDatabase = configuration?.ObjectDatabase; var textureDatabase = configuration?.TextureDatabase; var objectSet = new ObjectSet(); objectSet.Load(filePath, objectDatabase, textureDatabase); return(objectSet); }); AddReplaceHandler <Scene>(filePath => { if (Data.Objects.Count > 1) { return(AssimpImporter.ImportFromFile(filePath)); } return(AssimpImporter.ImportFromFileWithSingleObject(filePath)); }); AddCustomHandler("Copy object set info to clipboard", () => { uint objectSetId = 39; uint objectId = 0xFFFFFFFF; var objectDatabase = ConfigurationList.Instance.CurrentConfiguration?.ObjectDatabase; if (objectDatabase != null && objectDatabase.ObjectSets.Count > 0) { objectSetId = objectDatabase.ObjectSets.Max(x => x.Id) + 1; objectId = objectDatabase.ObjectSets.SelectMany(x => x.Objects).Max(x => x.Id) + 1; } else { using (var inputDialog = new InputDialog { WindowTitle = "Enter base id for objects", Input = Math.Max(0, Data.Objects.Max(x => x.Id) + 1).ToString() }) { while (inputDialog.ShowDialog() == DialogResult.OK) { bool result = uint.TryParse(inputDialog.Input, out objectId); if (!result || objectId == 0xFFFFFFFF) { MessageBox.Show("Please enter a correct id number.", Program.Name, MessageBoxButtons.OK, MessageBoxIcon.Error); } else { break; } } } } if (objectId == 0xFFFFFFFF) { return; } string baseName = Path.ChangeExtension(Name, null); if (Data.Format.IsClassic() && baseName.EndsWith("_obj", StringComparison.OrdinalIgnoreCase)) { baseName = baseName.Substring(0, baseName.Length - 4); } var objectSetInfo = new ObjectSetInfo { Name = baseName.ToUpperInvariant(), Id = objectSetId, FileName = Name, TextureFileName = baseName + (Data.Format.IsClassic() ? "_tex.bin" : ".txd"), ArchiveFileName = Parent is FarcArchiveNode ? Parent.Name : baseName + ".farc" }; foreach (var obj in Data.Objects) { objectSetInfo.Objects.Add(new ObjectInfo { Id = objectId++, Name = obj.Name.ToUpperInvariant() }); } using (var stringWriter = new StringWriter()) using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true })) { sObjectSetInfoSerializer.Serialize(xmlWriter, objectSetInfo, new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty })); Clipboard.SetText(stringWriter.ToString()); } }); AddCustomHandlerSeparator(); AddDirtyCustomHandler("Combine all objects into one", () => { if (Data.Objects.Count <= 1) { return(false); } var combinedObject = new Object { Name = "Combined object" }; var indexMap = new Dictionary <int, int>(); foreach (var obj in Data.Objects) { if (obj.Skin != null) { if (combinedObject.Skin == null) { combinedObject.Skin = new Skin(); combinedObject.Skin.Bones.AddRange(obj.Skin.Bones); } else { for (int i = 0; i < obj.Skin.Bones.Count; i++) { var bone = obj.Skin.Bones[i]; int boneIndex = combinedObject.Skin.Bones.FindIndex( x => x.Name.Equals(bone.Name, StringComparison.OrdinalIgnoreCase)); if (boneIndex == -1) { indexMap[i] = combinedObject.Skin.Bones.Count; combinedObject.Skin.Bones.Add(bone); } else { indexMap[i] = boneIndex; } } foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes)) { if (subMesh.BoneIndices?.Length >= 1) { for (int i = 0; i < subMesh.BoneIndices.Length; i++) { subMesh.BoneIndices[i] = ( ushort )indexMap[subMesh.BoneIndices[i]]; } } } } combinedObject.Skin.Blocks.AddRange(obj.Skin.Blocks); } foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes)) { subMesh.MaterialIndex += ( uint )combinedObject.Materials.Count; } combinedObject.Meshes.AddRange(obj.Meshes); combinedObject.Materials.AddRange(obj.Materials); } Data.Objects.Clear(); Data.Objects.Add(combinedObject); return(true); }, Keys.None, CustomHandlerFlags.Repopulate | CustomHandlerFlags.ClearMementos); AddCustomHandlerSeparator(); AddDirtyCustomHandler("Convert all bones to osage", () => { foreach (var obj in Data.Objects) { var movingBone = obj.Skin?.Bones.FirstOrDefault(x => x.Name == "kl_mune_b_wj"); if (movingBone == null) { continue; } var nameMap = new Dictionary <string, string>(); var stringBuilder = new StringBuilder(); foreach (var bone in obj.Skin.Bones) { // Ignore bones if they are already OSG or EXP. // Also ignore the moving bone and its parents. // Ignore j_kao_wj for now because it f***s miku's headphones up if (bone.Name == "j_kao_wj") { continue; } var boneToCompare = movingBone; do { if (boneToCompare == bone) { break; } boneToCompare = boneToCompare.Parent; } while (boneToCompare != null); if (boneToCompare == bone) { continue; } if (obj.Skin.Blocks.Any(x => { switch (x) { case OsageBlock osgBlock: return(osgBlock.Nodes.Any(y => y.Name == bone.Name)); case ExpressionBlock expBlock: return(expBlock.Name == bone.Name); default: return(false); } })) { continue; } if (bone.Parent == null) { bone.Parent = movingBone; } Matrix4x4.Invert(bone.InverseBindPoseMatrix, out var bindPoseMatrix); var matrix = Matrix4x4.Multiply(bindPoseMatrix, bone.Parent.InverseBindPoseMatrix); Matrix4x4.Decompose(matrix, out var scale, out var rotation, out var translation); rotation = Quaternion.Normalize(rotation); string newName = bone.Name; if (newName.EndsWith("_wj", StringComparison.OrdinalIgnoreCase)) { newName = newName.Remove(newName.Length - 3); } newName += "_ragdoll"; nameMap.Add(bone.Name, newName); bone.Name = newName; string baseName = newName; var osageBlock = new OsageBlock { ExternalName = $"c_{baseName}_osg", Name = $"e_{baseName}", ParentName = bone.Parent.Name, Position = translation, Rotation = rotation.ToEulerAngles(), Scale = scale }; osageBlock.Nodes.Add(new OsageNode { Name = bone.Name, Length = 0.08f }); obj.Skin.Blocks.Add(osageBlock); stringBuilder.AppendFormat( "{0}.node.0.coli_r=0.030000\r\n" + "{0}.node.0.hinge_ymax=179.000000\r\n" + "{0}.node.0.hinge_ymin=-179.000000\r\n" + "{0}.node.0.hinge_zmax=179.000000\r\n" + "{0}.node.0.hinge_zmin=-179.000000\r\n" + "{0}.node.0.inertial_cancel=1.000000\r\n" + "{0}.node.0.weight=3.000000\r\n" + "{0}.node.length=1\r\n" + "{0}.root.force=0.010000\r\n" + "{0}.root.force_gain=0.300000\r\n" + "{0}.root.friction=1.000000\r\n" + "{0}.root.init_rot_y=0.000000\r\n" + "{0}.root.init_rot_z=0.000000\r\n" + "{0}.root.rot_y=0.000000\r\n" + "{0}.root.rot_z=0.000000\r\n" + "{0}.root.stiffness=0.100000\r\n" + "{0}.root.wind_afc=0.500000\r\n", osageBlock.ExternalName); }
private static void BuildMesh(D3D10.Device d, string meshArgs) { string name = meshArgs.Split(',')[0]; InputElement[] layout = (InputElement[])typeof(MeshInputElements10).GetField(meshArgs.Split(',')[1]).GetValue(typeof(MeshInputElements10)); string fileName = ConfigurationSettings.AppSettings["ExportsFolder"] + name; AssimpImporter importer = new AssimpImporter(); LogStream logstream = new LogStream(delegate(String msg, String userData) { Console.WriteLine(msg); }); importer.AttachLogStream(logstream); importer.Scale = 0; importer.XAxisRotation = 0; importer.YAxisRotation = 0; importer.ZAxisRotation = 0; importer.VerboseLoggingEnabled = true; importer.RemoveConfigs(); Scene model = importer.ImportFile(fileName, PostProcessSteps.CalculateTangentSpace // calculate tangents and bitangents if possible | PostProcessSteps.JoinIdenticalVertices // join identical vertices/ optimize indexing CAUSES A PROBLEM //| PostProcessSteps.ValidateDataStructure // perform a full validation of the loader's output | PostProcessSteps.ImproveCacheLocality // improve the cache locality of the output vertices | PostProcessSteps.RemoveRedundantMaterials // remove redundant materials //| PostProcessSteps.FindDegenerates // remove degenerated polygons from the import CAUSES A PROBLEM //| PostProcessSteps.FindInvalidData // detect invalid model data, such as invalid normal vectors | PostProcessSteps.GenerateUVCoords // convert spherical, cylindrical, box and planar mapping to proper UVs | PostProcessSteps.TransformUVCoords // preprocess UV transformations (scaling, translation ...) //| PostProcessSteps.FindInstances // search for instanced meshes and remove them by references to one master //| PostProcessSteps.LimitBoneWeights // limit bone weights to 4 per vertex | PostProcessSteps.OptimizeMeshes // join small meshes, if possible; | PostProcessSteps.GenerateSmoothNormals // generate smooth normal vectors if not existing | PostProcessSteps.Triangulate // triangulate polygons with more than 3 edges | PostProcessSteps.SortByPrimitiveType // make 'clean' meshes which consist of a single typ of primitives | PostProcessSteps.FlipUVs // common DirectX issue (Xna also) | PostProcessSteps.FixInFacingNormals | PostProcessSteps.MakeLeftHanded | PostProcessSteps.FlipWindingOrder ); MeshHelper.BuildMeshTextures(d, model); Mesh3D m = MeshHelper.LoadFromFile(d, model, layout); importer.Dispose(); Stream stream = File.Open(ConfigurationSettings.AppSettings["ExportsFolder"] + name.Replace(".X", ".mesh"), FileMode.Create); BinaryFormatter bFormatter = new BinaryFormatter(); if (m != null) { bFormatter.Serialize(stream, m); } stream.Close(); }