예제 #1
0
        public void ImportModel()
        {
            OpenFileDialog dlg = new OpenFileDialog()
            {
                DefaultExt = "sa1mdl", Filter = "Model Files|*.sa1mdl;*.obj;*.objf", RestoreDirectory = true
            };

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                switch (Path.GetExtension(dlg.FileName).ToLowerInvariant())
                {
                case ".obj":
                case ".fbx":
                case ".dae":
                case ".objf":
                    Assimp.AssimpContext context = new Assimp.AssimpContext();
                    context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
                    Assimp.Scene scene    = context.ImportFile(dlg.FileName, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs);
                    NJS_OBJECT   newmodel = SAEditorCommon.Import.AssimpStuff.AssimpImport(scene, scene.RootNode, ModelFormat.BasicDX, LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray(), true);
                    Model.Attach = newmodel.Attach;
                    Model.ProcessVertexData();
                    Mesh = Model.Attach.CreateD3DMesh();
                    break;

                case ".sa1mdl":
                    ModelFile mf = new ModelFile(dlg.FileName);
                    Model.Attach = mf.Model.Attach;
                    Model.ProcessVertexData();
                    Mesh = Model.Attach.CreateD3DMesh();
                    break;
                }
            }
        }
예제 #2
0
        private bool loadFile(string path)
        {
            Assimp.AssimpContext importer = new Assimp.AssimpContext();
            importer.SetConfig(new NormalSmoothingAngleConfig(66f));
            //TODO check which other post processes we need
            m_scene = importer.ImportFile(path,
                                          Assimp.PostProcessSteps.CalculateTangentSpace
                                          | Assimp.PostProcessSteps.GenerateNormals
                                          | Assimp.PostProcessSteps.Triangulate
                                          | Assimp.PostProcessSteps.JoinIdenticalVertices
                                          | Assimp.PostProcessSteps.OptimizeMeshes);

            //failed loading :(
            if (!m_scene.HasMeshes)
            {
                textBoxInfo.Text = "No Valid Meshes found.";
                return(false);
            }

            //display some info
            string msg = "Mesh Count: " + m_scene.MeshCount.ToString()
                         + Environment.NewLine + "Material count: " + m_scene.MaterialCount.ToString()
                         + " (Maximum material count is 32)";

            textBoxInfo.Text = msg;

            buttonSave.Enabled = (m_scene.MeshCount > 0 && m_scene.MaterialCount <= maxMaterials);

            return(true);
        }
예제 #3
0
        public void ShowSelectFileDialog()
        {
            using (var ofd = new OpenFileDialog())
            {
                ofd.Filter = "Mesh files (*.dae, *.obj, *.stl)|*.dae;*.obj;*.stl|Wavefront (*.obj)|*.obj|Collada (*.dae)|*.dae|STL (*.stl)|*.stl|All files (*.*)|*.*";
                if (!string.IsNullOrEmpty(browseTextBox1.Value))
                {
                    ofd.FileName = browseTextBox1.Value;
                }

                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        browseTextBox1.Value = ofd.FileName;
                        SceneToImport        = AssimpContext.ImportFile(ofd.FileName,
                                                                        Assimp.PostProcessSteps.Triangulate |
                                                                        Assimp.PostProcessSteps.GenerateNormals |
                                                                        Assimp.PostProcessSteps.FlipUVs);

                        FillModelsGridView();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Could not import file!");
                    }
                }
            }
        }
예제 #4
0
        private LoadedModel LoadModelOfd()
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (ofd.CheckFileExists)
                {
                    string dirName = Path.GetDirectoryName(ofd.FileName);
                    try
                    {
                        using (Assimp.AssimpContext importer = new Assimp.AssimpContext())
                        {
                            importer.SetConfig(new NormalSmoothingAngleConfig(66.0f));
                            Assimp.Scene model       = importer.ImportFile(ofd.FileName, Assimp.PostProcessPreset.TargetRealTimeMaximumQuality);
                            LoadedModel  loadedModel = new LoadedModel(model, dirName);
                            loadedModel.Name = Path.GetFileName(ofd.FileName);
                            return(loadedModel);
                        }
                    }
                    catch
                    {
                        System.Windows.MessageBox.Show("Unsupported file type.", "Error");
                    }
                }
            }
            return(null);
        }
예제 #5
0
        public void ImportModel(string filePath, bool legacyImport = false)
        {
            NJS_OBJECT newmodel;

            // Old OBJ import (with vcolor face) for NodeTable and legacy import
            if (legacyImport)
            {
                newmodel = new NJS_OBJECT
                {
                    Attach = SAModel.Direct3D.Extensions.obj2nj(filePath, LevelData.TextureBitmaps != null ? LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray() : null),
                };
                COL.Model.Attach = newmodel.Attach;
                COL.Model.ProcessVertexData();
                Visible = true;
                Solid   = true;
                mesh    = COL.Model.Attach.CreateD3DMesh();
                return;
            }
            Assimp.AssimpContext context = new Assimp.AssimpContext();
            context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
            Assimp.Scene scene = context.ImportFile(filePath, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs);
            newmodel         = SAEditorCommon.Import.AssimpStuff.AssimpImport(scene, scene.RootNode, ModelFormat.BasicDX, LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray(), true);
            COL.Model.Attach = newmodel.Attach;
            COL.Model.ProcessVertexData();
            Visible = true;
            Solid   = true;
            mesh    = COL.Model.Attach.CreateD3DMesh();
        }
예제 #6
0
        static Assimp.Scene LoadAssimpScene(string fileName)
        {
            Assimp.AssimpContext cont = new Assimp.AssimpContext();

            // AssImp adds dummy nodes for pivots from FBX, so we'll force them off
            cont.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
            cont.ZAxisRotation = -90.0f;
            return(cont.ImportFile(fileName, Assimp.PostProcessSteps.Triangulate));
        }
예제 #7
0
        public void Load()
        {
            BoneAnimations = new List <BoneAnimation>();

            var importer = new Assimp.AssimpContext();
            var aScene   = importer.ImportFile(FilePath, Assimp.PostProcessPreset.TargetRealTimeMaximumQuality);

            RootBoneAnimation = LoadBoneAnimation(aScene, aScene.RootNode, null);
        }
예제 #8
0
        public DeviceModelCollection LoadModel(string filePath)
        {
            var context = new Assimp.AssimpContext();

            var pp    = Assimp.PostProcessSteps.FindInvalidData | Assimp.PostProcessSteps.OptimizeGraph;
            var scene = context.ImportFile(filePath, pp);

            return(ReadModel(scene));
        }
예제 #9
0
 public void SetUp()
 {
     var assimpNetimporter = new Assimp.AssimpContext();
     Assimp.LogStream.IsVerboseLoggingEnabled = true;
     var logger = new Assimp.ConsoleLogStream();
     logger.Attach();
     assimpNetScene = assimpNetimporter.ImportFile(filename);
     logger.Detach();
     var assimpSharpImporter = new AssimpSharp.FBX.FBXImporter();
     assimpSharpScene = new AssimpSharp.Scene();
     assimpSharpScene = assimpSharpImporter.ReadFile(filename);
 }
예제 #10
0
파일: Program.cs 프로젝트: thamstras/OpenKh
        public static MeshGroup FromFbx(string filePath)
        {
            const float Scale        = 1.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            TexList     = new List <string>();
            TextureData = new List <Tm2>();

            foreach (Assimp.Material mat in scene.Materials)
            {
                TexList.Add(Path.GetFileName(mat.TextureDiffuse.FilePath));
                Stream str = File.OpenRead(TexList[TexList.Count - 1]);

                PngImage png     = new PngImage(str);
                Tm2      tmImage = Tm2.Create(png);
                TextureData.Add(tmImage);
            }

            int childCount = scene.RootNode.ChildCount;

            return(new MeshGroup()
            {
                MeshDescriptors = scene.Meshes
                                  .Select(x =>
                {
                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var i = 0; i < vertices.Length; i++)
                    {
                        vertices[i].X = x.Vertices[i].X * Scale;
                        vertices[i].Y = x.Vertices[i].Y * Scale;
                        vertices[i].Z = x.Vertices[i].Z * Scale;
                        vertices[i].Tu = x.TextureCoordinateChannels[0][i].X;
                        vertices[i].Tv = 1.0f - x.TextureCoordinateChannels[0][i].Y;
                        vertices[i].R = 1.0f;
                        vertices[i].G = 1.0f;
                        vertices[i].B = 1.0f;
                        vertices[i].A = 1.0f;
                    }

                    return new MeshDescriptor
                    {
                        Vertices = vertices,
                        Indices = x.GetIndices(),
                        IsOpaque = true,
                        TextureIndex = x.MaterialIndex
                    };
                }).ToList()
            });
        }
예제 #11
0
        public static void AssimpPRMConvert(string initialFilePath, string finalFilePath)
        {
            Assimp.AssimpContext context = new Assimp.AssimpContext();
            context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
            Assimp.Scene aiScene = context.ImportFile(initialFilePath, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs);

            PRMModel prm = new PRMModel();

            int totalVerts = 0;

            //Iterate through and combine meshes. PRMs can only have a single mesh
            IterateAiNodesPRM(prm, ref totalVerts, aiScene, aiScene.RootNode, Matrix4x4.Transpose(GetMat4FromAssimpMat4(aiScene.RootNode.Transform)));
            AquaUtil.WritePRMToFile(prm, finalFilePath, 4);
        }
예제 #12
0
 public static Assimp.Scene ImportScene(string path, bool allowWeights)
 {
     using (var aiContext = new Assimp.AssimpContext())
     {
         aiContext.SetConfig(new Assimp.Configs.VertexBoneWeightLimitConfig(allowWeights ? 3 : 1));
         aiContext.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
         return(aiContext.ImportFile(path,
                                     Assimp.PostProcessSteps.FindDegenerates | Assimp.PostProcessSteps.FindInvalidData |
                                     Assimp.PostProcessSteps.FlipUVs | Assimp.PostProcessSteps.ImproveCacheLocality |
                                     Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.LimitBoneWeights |
                                     Assimp.PostProcessSteps.SplitByBoneCount | Assimp.PostProcessSteps.Triangulate |
                                     Assimp.PostProcessSteps.ValidateDataStructure | Assimp.PostProcessSteps.GenerateUVCoords));
     }
 }
예제 #13
0
 public override Assimp.Scene Import(string filename, ContentImporterContext context)
 {
     if (dllLoadExc != null)
     {
         context.RaiseBuildMessage("FBXIMPORT", dllLoadExc.Message, BuildMessageEventArgs.BuildMessageType.Error);
     }
     try
     {
         Assimp.AssimpContext c = new Assimp.AssimpContext();
         return(c.ImportFile(filename, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.OptimizeMeshes | Assimp.PostProcessSteps.OptimizeGraph));
     }
     catch (Exception ex)
     {
         context.RaiseBuildMessage(filename, ex.Message, BuildMessageEventArgs.BuildMessageType.Error);
     }
     return(null);
 }
        internal static Engine_MeshInfo LoadFilePro(string _fileName)
        {
            var a = new Assimp.AssimpContext();
            var s = a.ImportFile(_fileName);

            Engine_MeshInfo obj = new Engine_MeshInfo();

            obj.vertices = new List <Engine_Vertex>();
            obj.indices  = new List <ushort>();
            foreach (var mesh in s.Meshes)
            {
                for (int i = 0; i < mesh.VertexCount; i++)
                {
                    obj.vertices.Add(new Engine_Vertex(
                                         mesh.Vertices[i].X,
                                         mesh.Vertices[i].Y,
                                         mesh.Vertices[i].Z,
                                         mesh.TextureCoordinateChannels[0][i].X,
                                         mesh.TextureCoordinateChannels[0][i].Y,
                                         mesh.Normals[i].X,
                                         mesh.Normals[i].Y,
                                         mesh.Normals[i].Z));
                }

                foreach (var item in mesh.Faces)
                {
                    var rangeIndices = new ushort[] {
                        (ushort)(item.Indices[0]),
                        (ushort)(item.Indices[1]),
                        (ushort)(item.Indices[2])
                    };
                    obj.indices.AddRange(rangeIndices);
                    if (item.IndexCount == 4)
                    {
                        rangeIndices = new ushort[] {
                            (ushort)(item.Indices[0]),
                            (ushort)(item.Indices[2]),
                            (ushort)(item.Indices[3])
                        };
                        obj.indices.AddRange(rangeIndices);
                    }
                }
            }

            return(obj);
        }
예제 #15
0
        public static MeshGroup FromFbx(GraphicsDevice graphics, string filePath)
        {
            const float Scale        = 96.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            return(new MeshGroup()
            {
                MeshDescriptors = scene.Meshes
                                  .Select(x =>
                {
                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var i = 0; i < vertices.Length; i++)
                    {
                        vertices[i].X = x.Vertices[i].X * Scale;
                        vertices[i].Y = x.Vertices[i].Y * Scale;
                        vertices[i].Z = x.Vertices[i].Z * Scale;
                        vertices[i].Tu = x.TextureCoordinateChannels[0][i].X;
                        vertices[i].Tv = 1.0f - x.TextureCoordinateChannels[0][i].Y;
                        vertices[i].R = 0xFF;
                        vertices[i].G = 0xFF;
                        vertices[i].B = 0xFF;
                        vertices[i].A = 0xFF;
                    }

                    return new MeshDescriptor
                    {
                        Vertices = vertices,
                        Indices = x.Faces.SelectMany(f => f.Indices).ToArray(),
                        IsOpaque = true,
                        TextureIndex = x.MaterialIndex
                    };
                }).ToList(),
                Textures = scene.Materials.Select(x =>
                {
                    var path = Path.Join(baseFilePath, $"{x.Name}.png");
                    return new PngKingdomTexture(path, graphics);
                }).ToArray(),
            });
        }
예제 #16
0
파일: AssimpIO.cs 프로젝트: ubisoft/vrtist
        private async Task <Assimp.Scene> ImportAssimpFile(string fileName)
        {
            Assimp.Scene aScene = null;
            await Task <Assimp.Scene> .Run(() =>
            {
                try
                {
                    Assimp.AssimpContext ctx = new Assimp.AssimpContext();
                    aScene = ctx.ImportFile(fileName,
                                            Assimp.PostProcessSteps.Triangulate |
                                            Assimp.PostProcessSteps.GenerateNormals |
                                            Assimp.PostProcessSteps.GenerateUVCoords);
                }
                catch (Assimp.AssimpException e)
                {
                    Debug.LogError(e.Message);
                    aScene = null;
                }
            });

            return(aScene);
        }
예제 #17
0
파일: AssimpIO.cs 프로젝트: ubisoft/vrtist
 public void Import(string fileName, Transform root, bool synchronous = false)
 {
     blocking = synchronous;
     if (synchronous)
     {
         Assimp.AssimpContext ctx = new Assimp.AssimpContext();
         var aScene = ctx.ImportFile(fileName,
                                     Assimp.PostProcessSteps.Triangulate |
                                     Assimp.PostProcessSteps.GenerateNormals |
                                     Assimp.PostProcessSteps.GenerateUVCoords);
         CreateUnityDataFromAssimp(fileName, aScene, root).MoveNext();
         Clear();
         progress = 1.0f;
     }
     else
     {
         unityDataInCoroutineCreated = false;
         ImportTaskData d = new ImportTaskData();
         d.fileName = fileName;
         d.root     = root;
         taskData.Add(d);
     }
 }
예제 #18
0
        public static RwAnimationNode FromAssimpScene(RwNode parent, RwFrameListNode frameList, string path)
        {
            var             aiContext   = new Assimp.AssimpContext();
            var             aiScene     = aiContext.ImportFile(path);
            var             aiAnimation = aiScene.Animations.FirstOrDefault();
            RwAnimationNode animationNode;

            if (aiAnimation != null)
            {
                animationNode = new RwAnimationNode(parent, RwKeyFrameType.Uncompressed, ( float )(aiAnimation.DurationInTicks / aiAnimation.TicksPerSecond));
                var nodeNameToHAnimId = aiAnimation.NodeAnimationChannels.ToDictionary(x => x.NodeName, x => frameList.GetNameIdByName(x.NodeName));
                var nodeKeyframeTimes = aiAnimation.NodeAnimationChannels.SelectMany(x => x.PositionKeys)
                                        .Select(x => x.Time)
                                        .Concat(aiAnimation.NodeAnimationChannels.SelectMany(x => x.RotationKeys.Select(y => y.Time)))
                                        .Distinct()
                                        .OrderBy(x => x)
                                        .ToList();

                var previousKeyFrames = new Dictionary <int, RwKeyFrame>();
                var nodeKeyFrames     = new Dictionary <int, List <RwKeyFrame> >();

                // Add initial pose
                foreach (var hierarchyNode in frameList.AnimationRootNode.HAnimFrameExtensionNode.Hierarchy.Nodes)
                {
                    var frame            = frameList[frameList.GetFrameIndexByNameId(hierarchyNode.NodeId)];
                    var firstRotation    = Quaternion.CreateFromRotationMatrix(frame.Transform);
                    var firstTranslation = frame.Transform.Translation;

                    var channel = aiAnimation.NodeAnimationChannels.FirstOrDefault(x => nodeNameToHAnimId[x.NodeName] == hierarchyNode.NodeId);
                    if (channel != null)
                    {
                        if (channel.HasRotationKeys)
                        {
                            firstRotation = ToQuaternion(channel.RotationKeys.First().Value);
                        }

                        if (channel.HasPositionKeys)
                        {
                            firstTranslation = ToVector3(channel.PositionKeys.First().Value);
                        }
                    }

                    var keyFrame = new RwKeyFrame(0, firstRotation, firstTranslation, null);
                    animationNode.KeyFrames.Add(keyFrame);

                    previousKeyFrames[hierarchyNode.NodeId] = keyFrame;
                    nodeKeyFrames[hierarchyNode.NodeId]     = new List <RwKeyFrame>();
                }

                foreach (var keyFrameTime in nodeKeyframeTimes)
                {
                    if (keyFrameTime == 0.0f)
                    {
                        continue;
                    }

                    foreach (var channel in aiAnimation.NodeAnimationChannels)
                    {
                        if (!channel.HasPositionKeys && !channel.HasRotationKeys)
                        {
                            continue;
                        }

                        if (!channel.RotationKeys.Any(x => x.Time == keyFrameTime) || !channel.PositionKeys.Any(x => x.Time == keyFrameTime))
                        {
                            continue;
                        }

                        var hierarchAnimNodeId = nodeNameToHAnimId[channel.NodeName];
                        var previousKeyFrame   = previousKeyFrames[hierarchAnimNodeId];
                        var rotation           = previousKeyFrame.Rotation;
                        var translation        = previousKeyFrame.Translation;

                        var rotationKeys = channel.RotationKeys.Where(x => x.Time == keyFrameTime);
                        if (rotationKeys.Any())
                        {
                            var aiRotation = rotationKeys.First().Value;
                            rotation = new Quaternion(aiRotation.X, aiRotation.Y, aiRotation.Z, aiRotation.W);
                        }

                        var translationKeys = channel.PositionKeys.Where(x => x.Time == keyFrameTime);
                        if (translationKeys.Any())
                        {
                            var aiTranslation = translationKeys.First().Value;
                            translation = new Vector3(aiTranslation.X, aiTranslation.Y, aiTranslation.Z);
                        }

                        var keyFrame = new RwKeyFrame(( float )(keyFrameTime / aiAnimation.TicksPerSecond), rotation, translation, previousKeyFrame);
                        nodeKeyFrames[hierarchAnimNodeId].Add(keyFrame);
                        previousKeyFrames[hierarchAnimNodeId] = keyFrame;
                    }
                }

                while (!nodeKeyFrames.All(x => x.Value.Count == 0))
                {
                    foreach (var kvp in nodeKeyFrames)
                    {
                        if (animationNode.KeyFrames.Count == 0)
                        {
                            continue;
                        }

                        var keyFrame = kvp.Value.First();
                        animationNode.KeyFrames.Add(keyFrame);
                        kvp.Value.Remove(keyFrame);

                        if (animationNode.KeyFrames.Count == 0)
                        {
                            var previousKeyFrame = previousKeyFrames[kvp.Key];
                            if (previousKeyFrame.Time != animationNode.Duration)
                            {
                                var lastRotation    = previousKeyFrame.Rotation;
                                var lastTranslation = previousKeyFrame.Translation;
                                var channel         = aiAnimation.NodeAnimationChannels.SingleOrDefault(x => nodeNameToHAnimId[x.NodeName] == kvp.Key);
                                if (channel != null)
                                {
                                    if (channel.HasRotationKeys)
                                    {
                                        lastRotation = ToQuaternion(channel.RotationKeys.Last().Value);
                                    }

                                    if (channel.HasPositionKeys)
                                    {
                                        lastTranslation = ToVector3(channel.PositionKeys.Last().Value);
                                    }
                                }

                                animationNode.KeyFrames.Add(new RwKeyFrame(animationNode.Duration, lastRotation, lastTranslation, previousKeyFrame));
                            }
                        }
                    }
                }
            }
            else
            {
                animationNode = new RwAnimationNode(null, RwKeyFrameType.Uncompressed, 0f);
            }

            return(animationNode);
        }
예제 #19
0
 void LoadAssimpNetScene(string file)
 {
     var importer = new Assimp.AssimpContext();
     var assimpNetScene = importer.ImportFile(file);
 }
예제 #20
0
 private static void ImportDAEFile(ResourceWrapper res, string path)
 {
     var ctx = new Assimp.AssimpContext();
     res.WrappedObject = new RWScene(ctx.ImportFile(path));
 }
예제 #21
0
        public static void AssimpAQMConvert(string initialFilePath, bool playerExport, bool useScaleFrames, float scaleFactor)
        {
            float baseScale = 1f / 100f * scaleFactor; //We assume that this will be 100x the true scale because 1 unit to 1 meter isn't the norm

            Assimp.AssimpContext context = new Assimp.AssimpContext();
            context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
            Assimp.Scene aiScene = context.ImportFile(initialFilePath, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs);

            string                        inputFilename = Path.GetFileNameWithoutExtension(initialFilePath);
            List <string>                 aqmNames      = new List <string>(); //Leave off extensions in case we want this to be .trm later
            List <AquaMotion>             aqmList       = new List <AquaMotion>();
            Dictionary <int, Assimp.Node> aiNodes       = GetAnimatedNodes(aiScene);
            var nodeKeys = aiNodes.Keys.ToList();

            nodeKeys.Sort();
            int      animatedNodeCount = nodeKeys.Last() + 1;
            AquaUtil aqua = new AquaUtil();

            for (int i = 0; i < aiScene.Animations.Count; i++)
            {
                if (aiScene.Animations[i] == null)
                {
                    continue;
                }
                AquaMotion aqm          = new AquaMotion();
                var        anim         = aiScene.Animations[i];
                int        animEndFrame = 0; //We'll fill this later. Assumes frame 0 to be the start

                if (anim.Name != null && anim.Name != "")
                {
                    //Make sure we're not overwriting anims that somehow have duplicate names
                    if (aqmNames.Contains(anim.Name))
                    {
                        aqmNames.Add($"Anim_{i}_" + anim.Name + ".aqm");
                    }
                    else
                    {
                        aqmNames.Add(anim.Name + ".aqm");
                    }
                }
                else
                {
                    aqmNames.Add($"Anim_{i}_" + inputFilename + ".aqm");
                }

                aqm.moHeader = new AquaMotion.MOHeader();

                //Get anim fps
                if (anim.TicksPerSecond == 0)
                {
                    //Default to 30
                    aqm.moHeader.frameSpeed = 30;
                }
                else
                {
                    aqm.moHeader.frameSpeed = (float)anim.TicksPerSecond;
                }

                aqm.moHeader.unkInt0 = 2;   //Always, always 2 for NIFL
                aqm.moHeader.variant = 0x2; //These are flags for the animation to tell the game what type it is. Since this is a skeletal animation, we always put 2 here.
                //If it's a player one specifically, the game generally adds 0x10 to this.
                aqm.moHeader.nodeCount = animatedNodeCount;
                if (playerExport)
                {
                    aqm.moHeader.variant += 0x10;
                    aqm.moHeader.nodeCount++; //Add an extra for the nodeTreeFlag 'node'
                }
                aqm.moHeader.testString.SetString("test");

                //Set this ahead of time in case these are out of order
                aqm.motionKeys = new List <AquaMotion.KeyData>(new AquaMotion.KeyData[aqm.moHeader.nodeCount]);

                //Nodes
                foreach (var animNode in anim.NodeAnimationChannels)
                {
                    if (animNode == null)
                    {
                        continue;
                    }

                    int id = GetNodeNumber(animNode.NodeName);

                    var node = aqm.motionKeys[id] = new AquaMotion.KeyData();

                    node.mseg.nodeName.SetString(animNode.NodeName);
                    node.mseg.nodeId        = id;
                    node.mseg.nodeType      = 2;
                    node.mseg.nodeDataCount = useScaleFrames ? 3 : 2;

                    if (animNode.HasPositionKeys)
                    {
                        AquaMotion.MKEY posKeys = new AquaMotion.MKEY();
                        posKeys.keyType  = 1;
                        posKeys.dataType = 1;
                        var first = true;
                        foreach (var pos in animNode.PositionKeys)
                        {
                            posKeys.vector4Keys.Add(new Vector4(pos.Value.X * baseScale, pos.Value.Y * baseScale, pos.Value.Z * baseScale, 0));

                            //Account for first frame difference
                            if (first)
                            {
                                posKeys.frameTimings.Add(1);
                                first = false;
                            }
                            else
                            {
                                posKeys.frameTimings.Add((ushort)(pos.Time * 0x10));
                            }
                            posKeys.keyCount++;
                        }
                        posKeys.frameTimings[posKeys.keyCount - 1] += 2; //Account for final frame bitflags

                        animEndFrame = Math.Max(animEndFrame, posKeys.keyCount);
                        node.keyData.Add(posKeys);
                    }

                    if (animNode.HasRotationKeys)
                    {
                        AquaMotion.MKEY rotKeys = new AquaMotion.MKEY();
                        rotKeys.keyType  = 2;
                        rotKeys.dataType = 3;
                        var first = true;
                        foreach (var rot in animNode.RotationKeys)
                        {
                            rotKeys.vector4Keys.Add(new Vector4(rot.Value.X, rot.Value.Y, rot.Value.Z, rot.Value.W));

                            //Account for first frame difference
                            if (first)
                            {
                                rotKeys.frameTimings.Add(1);
                                first = false;
                            }
                            else
                            {
                                rotKeys.frameTimings.Add((ushort)(rot.Time * 0x10));
                            }
                            rotKeys.keyCount++;
                        }
                        rotKeys.frameTimings[rotKeys.keyCount - 1] += 2; //Account for final frame bitflags

                        animEndFrame = Math.Max(animEndFrame, rotKeys.keyCount);
                        node.keyData.Add(rotKeys);
                    }

                    if (animNode.HasScalingKeys)
                    {
                        AquaMotion.MKEY sclKeys = new AquaMotion.MKEY();
                        sclKeys.keyType  = 2;
                        sclKeys.dataType = 3;
                        var first = true;
                        foreach (var scl in animNode.ScalingKeys)
                        {
                            sclKeys.vector4Keys.Add(new Vector4(scl.Value.X, scl.Value.Y, scl.Value.Z, 0));

                            //Account for first frame difference
                            if (first)
                            {
                                sclKeys.frameTimings.Add(1);
                                first = false;
                            }
                            else
                            {
                                sclKeys.frameTimings.Add((ushort)(scl.Time * 0x10));
                            }
                            sclKeys.keyCount++;
                        }
                        sclKeys.frameTimings[sclKeys.keyCount - 1] += 2; //Account for final frame bitflags

                        animEndFrame = Math.Max(animEndFrame, sclKeys.keyCount);
                        node.keyData.Add(sclKeys);
                    }
                }

                //NodeTreeFlag
                if (playerExport)
                {
                    var node = aqm.motionKeys[aqm.motionKeys.Count - 1] = new AquaMotion.KeyData();
                    node.mseg.nodeName.SetString("__NodeTreeFlag__");
                    node.mseg.nodeId        = aqm.motionKeys.Count - 1;
                    node.mseg.nodeType      = 0x10;
                    node.mseg.nodeDataCount = useScaleFrames ? 3 : 2;

                    //Position
                    AquaMotion.MKEY posKeys = new AquaMotion.MKEY();
                    posKeys.keyType  = 0x10;
                    posKeys.dataType = 5;
                    posKeys.keyCount = animEndFrame + 1;
                    for (int frame = 0; frame < posKeys.keyCount; frame++)
                    {
                        if (frame == 0)
                        {
                            posKeys.frameTimings.Add(0x9);
                        }
                        else if (frame == posKeys.keyCount - 1)
                        {
                            posKeys.frameTimings.Add((ushort)((frame * 0x10) + 0xA));
                        }
                        else
                        {
                            posKeys.frameTimings.Add((ushort)((frame * 0x10) + 0x8));
                        }
                        posKeys.intKeys.Add(0x31);
                    }
                    node.keyData.Add(posKeys);

                    //Rotation
                    AquaMotion.MKEY rotKeys = new AquaMotion.MKEY();
                    rotKeys.keyType  = 0x11;
                    rotKeys.dataType = 5;
                    rotKeys.keyCount = animEndFrame + 1;
                    for (int frame = 0; frame < rotKeys.keyCount; frame++)
                    {
                        if (frame == 0)
                        {
                            rotKeys.frameTimings.Add(0x9);
                        }
                        else if (frame == rotKeys.keyCount - 1)
                        {
                            rotKeys.frameTimings.Add((ushort)((frame * 0x10) + 0xA));
                        }
                        else
                        {
                            rotKeys.frameTimings.Add((ushort)((frame * 0x10) + 0x8));
                        }
                        rotKeys.intKeys.Add(0x31);
                    }
                    node.keyData.Add(rotKeys);

                    //Scale
                    if (useScaleFrames)
                    {
                        AquaMotion.MKEY sclKeys = new AquaMotion.MKEY();
                        sclKeys.keyType  = 0x12;
                        sclKeys.dataType = 5;
                        sclKeys.keyCount = animEndFrame + 1;
                        for (int frame = 0; frame < sclKeys.keyCount; frame++)
                        {
                            if (frame == 0)
                            {
                                sclKeys.frameTimings.Add(0x9);
                            }
                            else if (frame == sclKeys.keyCount - 1)
                            {
                                sclKeys.frameTimings.Add((ushort)((frame * 0x10) + 0xA));
                            }
                            else
                            {
                                sclKeys.frameTimings.Add((ushort)((frame * 0x10) + 0x8));
                            }
                            sclKeys.intKeys.Add(0x31);
                        }
                        node.keyData.Add(sclKeys);
                    }
                }

                //Sanity check
                foreach (var aiPair in aiNodes)
                {
                    var node   = aqm.motionKeys[aiPair.Key];
                    var aiNode = aiPair.Value;
                    if (node == null)
                    {
                        node = aqm.motionKeys[aiPair.Key] = new AquaMotion.KeyData();

                        node.mseg.nodeName.SetString(aiNode.Name);
                        node.mseg.nodeId        = aiPair.Key;
                        node.mseg.nodeType      = 2;
                        node.mseg.nodeDataCount = useScaleFrames ? 3 : 2;

                        //Position
                        AddOnePosFrame(node, aiNode, baseScale);

                        //Rotation
                        AddOneRotFrame(node, aiNode);

                        //Scale
                        AddOneScaleFrame(useScaleFrames, node);
                    }
                    else
                    {
                        if (node.keyData[0].vector4Keys.Count < 1)
                        {
                            AddOnePosFrame(node, aiNode, baseScale);
                        }

                        if (node.keyData[1].vector4Keys.Count < 1)
                        {
                            AddOneRotFrame(node, aiNode);
                        }

                        if (useScaleFrames && node.keyData[2].vector4Keys.Count < 1)
                        {
                            AddOneScaleFrame(useScaleFrames, node, aiNode);
                        }
                    }
                }

                aqmList.Add(aqm);
            }

            for (int i = 0; i < aqmList.Count; i++)
            {
                var aqm = aqmList[i];
                AquaUtil.AnimSet set = new AquaUtil.AnimSet();
                set.anims.Add(aqm);
                aqua.aquaMotions.Add(set);
                aqua.WriteNIFLMotion(initialFilePath + "_" + aqmNames[i]);

                aqua.aquaMotions.Clear();
            }
        }
예제 #22
0
        /// <summary>
        /// Converts a given .GR2 file to a .dae file for rendering and further conversion.
        /// </summary>
        /// <param name="filename">The file name.</param>
        /// <returns>The .dae converted model file.</returns>
        private static HelixToolkitScene LoadFile(string filename)
        {
            var dae = $"{filename}.dae";

            if (!File.Exists(dae))
            {
                GeneralHelper.WriteToConsole($"Converting model to .dae for rendering...\n");
                var divine    = $" -g \"bg3\" --action \"convert-model\" --output-format \"dae\" --source \"\\\\?\\{filename}.GR2\" --destination \"\\\\?\\{dae}\" -l \"all\"";
                var process   = new Process();
                var startInfo = new ProcessStartInfo
                {
                    FileName               = Properties.Settings.Default.divineExe,
                    Arguments              = divine,
                    WindowStyle            = ProcessWindowStyle.Hidden,
                    CreateNoWindow         = true,
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true
                };
                process.StartInfo = startInfo;
                process.Start();
                process.WaitForExit();
                GeneralHelper.WriteToConsole(process.StandardOutput.ReadToEnd());
                GeneralHelper.WriteToConsole(process.StandardError.ReadToEnd());
            }
            try
            {
                var importer = new Importer();
                // Update material here?
                var file = importer.Load(dae);
                if (file == null && File.Exists(dae))
                {
                    GeneralHelper.WriteToConsole("Fixing vertices...\n");
                    try
                    {
                        var xml          = XDocument.Load(dae);
                        var geometryList = xml.Descendants().Where(x => x.Name.LocalName == "geometry").ToList();
                        foreach (var lod in geometryList)
                        {
                            var vertexId = lod.Descendants().Where(x => x.Name.LocalName == "vertices").Select(x => x.Attribute("id").Value).First();
                            var vertex   = lod.Descendants().Single(x => x.Name.LocalName == "input" && x.Attribute("semantic").Value == "VERTEX");
                            vertex.Attribute("source").Value = $"#{vertexId}";
                        }
                        xml.Save(dae);
                        GeneralHelper.WriteToConsole("Model conversion complete!\n");
                        file = importer.Load(dae);
                    }
                    catch (Exception ex)
                    {
                        // in use by another process
                        GeneralHelper.WriteToConsole($"Error : {ex.Message}\n");
                    }
                }

                if (!File.Exists($"{filename}.fbx"))
                {
                    var converter     = new Assimp.AssimpContext();
                    var exportFormats = converter.GetSupportedExportFormats().Select(e => e.FormatId);
                    var importFormats = converter.GetSupportedImportFormats();
                    var imported      = converter.ImportFile(dae);
                    converter.ExportFile(imported, $"{filename}.fbx", "fbx");
                }
                importer.Dispose();
                return(file);
            }
            catch (Exception ex)
            {
                GeneralHelper.WriteToConsole($"Error loading .dae: {ex.Message}. Inner exception: {ex.InnerException?.Message}\n");
            }
            return(null);
        }
예제 #23
0
        protected unsafe override bool OnLoad(Model model, File stream)
        {
            var filePath = FileUtil.StandardlizeFile(stream.Name);

            filePath = FileUtil.GetPath(stream.Name);
            FileSystem.AddResourceDir(filePath);
            FileSystem.AddResourceDir(filePath + "textures");

            var    ctx = new Assimp.AssimpContext();
            string ext = FileUtil.GetExtension(loadingFile);

            if (!ctx.IsImportFormatSupported(ext))
            {
                ctx.Dispose();
                return(false);
            }

            //Assimp.Scene scene = ctx.ImportFileFromStream(stream, assimpFlags, ext);
            Assimp.Scene scene = ctx.ImportFile(stream.Name, assimpFlags);

            BoundingBox boundingBox = new BoundingBox();

            string path = FileUtil.GetPath(loadingFile);

            model.VertexBuffers = new List <Buffer>();
            model.IndexBuffers  = new List <Buffer>();

            vertexBuffer.Clear();
            indexBuffer.Clear();
            vertexOffset = 0;
            indexOffset  = 0;
            VertexLayout    vertexLayout = new VertexLayout(vertexComponents);
            List <Geometry> geoList      = new List <Geometry>();

            // Iterate through all meshes in the file and extract the vertex components
            for (int m = 0; m < scene.MeshCount; m++)
            {
                Assimp.Mesh mesh = scene.Meshes[m];
                if (mesh.MaterialIndex >= 0 && mesh.MaterialIndex < scene.MaterialCount)
                {
                    Material mat = ConvertMaterial(path, scene.Materials[mesh.MaterialIndex], mesh.HasTangentBasis);
                    if (mat == null)
                    {
                        continue;
                    }

                    model.Materials.Add(mat);
                }
                else
                {
                    Log.Error("No material : " + mesh.Name);
                }

                var geometry = ConvertGeometry(mesh, scale, vertexLayout, vertexComponents, combineVB, combineIB, out var meshBoundingBox);
                geoList.Add(geometry);

                if (geometry.VertexBuffer != null)
                {
                    model.VertexBuffers.Add(geometry.VertexBuffer);
                }

                if (geometry.IndexBuffer != null)
                {
                    model.IndexBuffers.Add(geometry.IndexBuffer);
                }

                model.Geometries.Add(new [] { geometry });
                model.GeometryCenters.Add(meshBoundingBox.Center);

                boundingBox.Merge(meshBoundingBox);
            }

            if (combineVB)
            {
                var vb = Buffer.Create(VkBufferUsageFlags.VertexBuffer, false, sizeof(float), vertexBuffer.Count, vertexBuffer.Data);
                model.VertexBuffers.Add(vb);

                foreach (var geo in geoList)
                {
                    geo.VertexBuffer = vb;
                }
            }

            if (combineIB)
            {
                var ib = Buffer.Create(VkBufferUsageFlags.IndexBuffer, false, sizeof(uint), indexBuffer.Count, indexBuffer.Data);
                model.IndexBuffers.Add(ib);
                foreach (var geo in geoList)
                {
                    geo.IndexBuffer = ib;
                }
            }

            model.BoundingBox = boundingBox;

            ctx.Dispose();

            FileSystem.RemoveResourceDir(filePath);
            FileSystem.RemoveResourceDir(filePath + "textures");
            return(true);
        }
예제 #24
0
        private void FrmGenNormal_Load(object sender, EventArgs e)
        {
            context3D = new Context3D();

            System.Drawing.Bitmap bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            RenderTargetAdapter renderBufferAdapter = new RenderTargetAdapter(bitmap, pictureBox1);

            context3D.configureBackBuffer(pictureBox1.Width, pictureBox1.Height, renderBufferAdapter);
            pictureBox1.BackgroundImage = bitmap;


            System.Drawing.Bitmap debuglayer      = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            RenderTargetAdapter   debuggerAdapter = new RenderTargetAdapter(debuglayer, pictureBox1);

            pictureBox1.Image           = debuglayer;
            context3D.debugLayerAdapter = debuggerAdapter;


            Assimp.AssimpContext importer = new Assimp.AssimpContext();
            Assimp.Scene         scene
                = importer.ImportFile("../../../models/Quad.fbx",
                                      Assimp.PostProcessSteps.MakeLeftHanded
                                      |
                                      Assimp.PostProcessSteps.CalculateTangentSpace
                                      );

            lst_indexList = new List <IndexBuffer3D>();
            lst_vertexes  = new List <VertexBuffer3D>();

            texsize = new float2(1.0f / 2, 1.0f / 2);

            var texture = MiniRender.textures.Texture.white;

            texture.AutoGenMipMap();
            context3D.setTextureAt(0, texture);
            context3D.setSamplerStateAt(0, Context3DWrapMode.REPEAT, Context3DTextureFilter.LINEAR, Context3DMipFilter.MIPNONE);

            for (int k = 0; k < scene.MeshCount; k++)
            {
                var mesh    = scene.Meshes[k];
                var vs      = mesh.Vertices;
                var indices = mesh.GetUnsignedIndices();



                var normals  = mesh.Normals;
                var tangents = mesh.Tangents;
                var coords   = mesh.TextureCoordinateChannels[0];

                var indexList = context3D.createIndexBuffer(indices.Length);
                indexList.uploadFromVector(indices);

                lst_indexList.Add(indexList);

                List <Vertex> vertices = new List <Vertex>();
                for (int i = 0; i < vs.Count; i++)
                {
                    vertices.Add(
                        new Vertex()
                    {
                        vertex = new float3(vs[i].X, vs[i].Y, vs[i].Z)
                    }
                        );
                }

                if (mesh.HasNormals)
                {
                    for (int i = 0; i < vs.Count; i++)
                    {
                        vertices[i].normal = (new float3(normals[i].X, normals[i].Y, normals[i].Z));
                    }
                }

                if (mesh.HasTangentBasis)
                {
                    for (int i = 0; i < vs.Count; i++)
                    {
                        vertices[i].tangent = new float3(tangents[i].X, tangents[i].Y, tangents[i].Z);
                    }
                }

                if (mesh.HasTextureCoords(0))
                {
                    for (int i = 0; i < vs.Count; i++)
                    {
                        vertices[i].uv = new float3(coords[i].X, coords[i].Y, coords[i].Z);
                    }
                }

                if (mesh.HasVertexColors(0))
                {
                    var color = mesh.VertexColorChannels[0];
                    for (int i = 0; i < vs.Count; i++)
                    {
                        vertices[i].color = new float4(color[i].R, color[i].G, color[i].B, color[i].A);
                    }
                }
                var vertexes = context3D.createVertexBuffer(vertices.Count);
                vertexes.uploadFromVector(vertices.ToArray());

                lst_vertexes.Add(vertexes);
            }



            var program3d = context3D.createProgram();

            program3d.upload(new VShader(),
                             new FShader()
                             );

            context3D.setProgram(program3d);

            //refreshCtl();

            //render();
        }
예제 #25
0
        private void Form1_Load(object sender, EventArgs e)
        {
            context3D = new Context3D();

            System.Drawing.Bitmap bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            RenderTargetAdapter renderBufferAdapter = new RenderTargetAdapter(bitmap, pictureBox1);

            context3D.configureBackBuffer(pictureBox1.Width, pictureBox1.Height, renderBufferAdapter);
            pictureBox1.BackgroundImage = bitmap;


            System.Drawing.Bitmap debuglayer      = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            RenderTargetAdapter   debuggerAdapter = new RenderTargetAdapter(debuglayer, pictureBox1);

            pictureBox1.Image           = debuglayer;
            context3D.debugLayerAdapter = debuggerAdapter;


            Assimp.AssimpContext importer = new Assimp.AssimpContext();

            scene = importer.ImportFile("../../../models/cube.fbx",
                                        Assimp.PostProcessSteps.MakeLeftHanded
                                        | Assimp.PostProcessSteps.Triangulate
                                        //| Assimp.PostProcessSteps.GenerateSmoothNormals
                                        | Assimp.PostProcessSteps.CalculateTangentSpace
                                        //| Assimp.PostProcessSteps.PreTransformVertices
                                        );

            lst_indexList = new List <IndexBuffer3D>();
            lst_vertexes  = new List <VertexBuffer3D>();


            //var texture = context3D.createTexture(474, 474);
            //texture.uploadFromByteArray(SceneUtils.LoadBitmapData("../../../models/texs/th.jpg"), 0);
            var texture = MiniRender.textures.Texture.white;

            //SceneUtils.MakeAndUploadTexture(context3D, "../../../models/texs/duckCM.bmp");
            texture.AutoGenMipMap();
            context3D.setTextureAt(0, texture);
            context3D.setSamplerStateAt(0, Context3DWrapMode.REPEAT, Context3DTextureFilter.LINEAR, Context3DMipFilter.MIPLINEAR);

            //设置matcap
            var matcap = SceneUtils.MakeAndUploadTexture(context3D, "../../../models/texs/MaCrea_3.png");

            matcap.AutoGenMipMap();
            context3D.setTextureAt(1, matcap);
            context3D.setSamplerStateAt(1, Context3DWrapMode.CLAMP, Context3DTextureFilter.LINEAR, Context3DMipFilter.MIPLINEAR);

            //设置法线
            var normalmap = MiniRender.textures.Texture.planeNormal;

            //SceneUtils.MakeAndUploadTexture(context3D, "../../../models/texs/Robot_Normal.png");
            normalmap.AutoGenMipMap();
            context3D.setTextureAt(2, normalmap);
            context3D.setSamplerStateAt(2, Context3DWrapMode.REPEAT, Context3DTextureFilter.LINEAR, Context3DMipFilter.MIPNEAREST);

            //设置粗糙度与金属性贴图
            var metallic =
                SceneUtils.MakeAndUploadTexture(context3D, "../../../models/texs/jian_2_m.png");

            metallic.AutoGenMipMap();
            context3D.setTextureAt(3, metallic);
            context3D.setSamplerStateAt(3, Context3DWrapMode.REPEAT, Context3DTextureFilter.LINEAR, Context3DMipFilter.MIPNEAREST);

            for (int k = 0; k < scene.MeshCount; k++)
            {
                var mesh    = scene.Meshes[k];
                var vs      = mesh.Vertices;
                var indices = mesh.GetUnsignedIndices();

                var normals  = mesh.Normals;
                var tangents = mesh.Tangents;
                var coords   = mesh.TextureCoordinateChannels[0];

                var indexList = context3D.createIndexBuffer(indices.Length);
                indexList.uploadFromVector(indices);

                lst_indexList.Add(indexList);

                List <Vertex> vertices = new List <Vertex>();
                for (int i = 0; i < vs.Count; i++)
                {
                    vertices.Add(
                        new Vertex()
                    {
                        vertex = new float3(vs[i].X, vs[i].Y, vs[i].Z) * 3
                    }
                        );
                }

                if (mesh.HasNormals)
                {
                    for (int i = 0; i < vs.Count; i++)
                    {
                        vertices[i].normal = (new float3(normals[i].X, normals[i].Y, normals[i].Z));
                    }
                }

                if (mesh.HasTangentBasis)
                {
                    for (int i = 0; i < vs.Count; i++)
                    {
                        vertices[i].tangent = new float3(tangents[i].X, tangents[i].Y, tangents[i].Z);
                    }
                }

                if (mesh.HasTextureCoords(0))
                {
                    for (int i = 0; i < vs.Count; i++)
                    {
                        vertices[i].uv = new float3(coords[i].X, coords[i].Y, coords[i].Z);
                    }
                }

                if (mesh.HasVertexColors(0))
                {
                    var color = mesh.VertexColorChannels[0];
                    for (int i = 0; i < vs.Count; i++)
                    {
                        vertices[i].color = new float4(color[i].R, color[i].G, color[i].B, color[i].A);
                    }
                }



                var vertexes = context3D.createVertexBuffer(vertices.Count);
                vertexes.uploadFromVector(vertices.ToArray());

                lst_vertexes.Add(vertexes);
            }



            var program3d = context3D.createProgram();

            fShader = new programs.test3.FShader_Metallic();
            program3d.upload(new programs.test4.VShader_Bump(),
                             new programs.test4.FShader_Bump()
                             //fShader
                             );

            context3D.setProgram(program3d);
        }
예제 #26
0
        public static MeshGroup FromFbx(string filePath)
        {
            const float Scale        = 1.0f;
            var         assimp       = new Assimp.AssimpContext();
            var         scene        = assimp.ImportFile(filePath, Assimp.PostProcessSteps.PreTransformVertices);
            var         BoneScene    = assimp.ImportFile(filePath);
            var         baseFilePath = Path.GetDirectoryName(filePath);

            TexList     = new List <string>();
            TextureData = new List <Tm2>();
            BoneData    = new List <Assimp.Bone>();
            NodeData    = new List <Assimp.Node>();

            foreach (Assimp.Material mat in scene.Materials)
            {
                Stream str  = null;
                var    name = Path.GetFileName(mat.TextureDiffuse.FilePath);
                if (name != "" || name != null)
                {
                    str = File.OpenRead(name);
                }

                if (str != null)
                {
                    TexList.Add(Path.GetFileName(mat.TextureDiffuse.FilePath));
                    PngImage png     = new PngImage(str);
                    Tm2      tmImage = Tm2.Create(png);
                    TextureData.Add(tmImage);
                }
            }

            Assimp.Bone rBone = new Assimp.Bone();
            foreach (var m in BoneScene.Meshes)
            {
                foreach (var bn in m.Bones)
                {
                    if (!BoneData.Contains(bn))
                    {
                        BoneData.Add(bn);
                    }
                }
            }

            NodeData.AddRange(BoneScene.RootNode.Children.ToList());

            return(new MeshGroup()
            {
                MeshDescriptors = scene.Meshes
                                  .Select(x =>
                {
                    var vertices = new PositionColoredTextured[x.Vertices.Count];
                    for (var i = 0; i < vertices.Length; i++)
                    {
                        vertices[i].X = x.Vertices[i].X * Scale;
                        vertices[i].Y = x.Vertices[i].Y * Scale;
                        vertices[i].Z = x.Vertices[i].Z * Scale;
                        vertices[i].Tu = x.TextureCoordinateChannels[0][i].X;
                        vertices[i].Tv = 1.0f - x.TextureCoordinateChannels[0][i].Y;
                        vertices[i].R = x.VertexColorChannels[0][i].R;
                        vertices[i].G = x.VertexColorChannels[0][i].G;
                        vertices[i].B = x.VertexColorChannels[0][i].B;
                        vertices[i].A = x.VertexColorChannels[0][i].A;
                    }

                    return new MeshDescriptor
                    {
                        Vertices = vertices,
                        Indices = x.GetIndices(),
                        IsOpaque = true,
                        TextureIndex = x.MaterialIndex
                    };
                }).ToList()
            });
        }
예제 #27
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("No arguments!");
            }

            var objectFile = args[0];

            Console.WriteLine("Loading mesh...");

            Geometry.Geometry geo;
            if (Path.GetExtension(objectFile) == ".hfe")
            {
                // Loading an hfe file
                geo = Geometry.Geometry.LoadFromBinary(objectFile);
            }
            else if (Path.GetExtension(objectFile) == ".json")
            {
                // Loading geometry from json
                geo = Geometry.Geometry.LoadFromJson(objectFile);
            }
            else
            {
                // Loading an external file format
                var importer = new Assimp.AssimpContext();
                importer.SetConfig(new Assimp.Configs.NormalSmoothingAngleConfig(66.0f));
                var scene = importer.ImportFile(objectFile, Assimp.PostProcessPreset.TargetRealTimeMaximumQuality);

                if (!scene.HasMeshes)
                {
                    Console.WriteLine("Scene has no meshes!");
                    return;
                }

                Console.WriteLine("Processing mesh...");
                geo = Geometry.Geometry.FromAssimp(scene.Meshes[0], true, true);
                scene.Clear();
                importer.Dispose();
            }

            bool bUseSymmetricLaplacian = false;
            var  indx = Array.FindIndex(args, t => t == "-sym");

            if (indx != -1)
            {
                Console.WriteLine("Using symmetric laplacian...");
                bUseSymmetricLaplacian = true;
            }

            indx = Array.FindIndex(args, t => t == "-lapout");
            if (indx != -1)
            {
                Console.WriteLine("Creating differential structure...");
                var diff = new DifferentialStructure(geo);

                Console.WriteLine("Writing mesh laplacian to file...");
                var outputFile = args[indx + 1];

                if (bUseSymmetricLaplacian)
                {
                    DifferentialStructure.WriteSparseMatrix(diff.InteriorSymmetrizedLaplacian, outputFile);
                }
                else
                {
                    DifferentialStructure.WriteSparseMatrix(diff.InteriorLaplacian, outputFile);
                }
            }

            indx = Array.FindIndex(args, t => t == "-modesin");
            Mat modes = null;
            Vec spec  = null;
            GeometryVisualMode visMode = GeometryVisualMode.ViewMesh;

            if (indx != -1)
            {
                Console.WriteLine("Reading mode data...");
                var inputFile = args[indx + 1];
                DifferentialStructure.ReadModeData(inputFile, out modes, out spec);

                var diff = new DifferentialStructure(geo);
                if (bUseSymmetricLaplacian)
                {
                    modes = diff.HalfInverseMassMatrix * modes;
                }

                if (geo.HasBoundary)
                {
                    modes = diff.InteriorToClosureMap * modes;
                }

                visMode = GeometryVisualMode.ViewModes;
            }

            indx = Array.FindIndex(args, t => t == "-funcin");
            if (indx != -1)
            {
                Console.WriteLine("Reading function data...");
                var inputFile = args[indx + 1];
                DifferentialStructure.ReadFunctionData(inputFile, out modes);

                var diff = new DifferentialStructure(geo);
                if (geo.HasBoundary)
                {
                    modes = diff.InteriorToClosureMap * modes;
                }

                visMode = GeometryVisualMode.ViewModes;
                spec    = Vec.Build.Dense(modes.RowCount, 0d);
            }

            indx = Array.FindIndex(args, t => t == "-viewmass");
            if (indx != -1)
            {
                visMode = GeometryVisualMode.ViewDegreeVector;
            }

            indx = Array.FindIndex(args, t => t == "-viewlapdiag");
            if (indx != -1)
            {
                visMode = GeometryVisualMode.ViewLapDiagonal;
            }

            indx = Array.FindIndex(args, t => t == "-meshout");
            if (indx != -1)
            {
                Console.WriteLine("Saving processed mesh...");
                var path = args[indx + 1];
                if (Path.GetExtension(path) == ".hfe")
                {
                    geo.SaveToBinary(path);
                }
                else if (Path.GetExtension(path) == ".json")
                {
                    geo.SaveToJson(path);
                }
                else
                {
                    Console.WriteLine("Unrecognized meshout file extension!");
                }
            }

            indx = Array.FindIndex(args, t => t == "-noview");
            if (indx != -1)
            {
                return;
            }

            using (var window = new GeometryDisplayWindow(geo))
            {
                window.VisualMode        = visMode;
                window.ObjectModes       = modes;
                window.ObjectEigenvalues = spec;
                window.Run();
            }
        }
예제 #28
0
        //Takes in an Assimp model and generates a full PSO2 model and skeleton from it.
        public static AquaObject AssimpAquaConvertFull(string initialFilePath, float scaleFactor, bool preAssignNodeIds, bool isNGS)
        {
            AquaUtil aquaUtil  = new AquaUtil();
            float    baseScale = 1f / 100f * scaleFactor; //We assume that this will be 100x the true scale because 1 unit to 1 meter isn't the norm

            Assimp.AssimpContext context = new Assimp.AssimpContext();
            context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false));
            Assimp.Scene aiScene = context.ImportFile(initialFilePath, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs);

            AquaObject aqp;
            AquaNode   aqn = new AquaNode();

            if (isNGS)
            {
                aqp = new NGSAquaObject();
            }
            else
            {
                aqp = new ClassicAquaObject();
            }

            //Construct Materials
            Dictionary <string, int> matNameTracker = new Dictionary <string, int>();

            foreach (var aiMat in aiScene.Materials)
            {
                string name;
                if (matNameTracker.ContainsKey(aiMat.Name))
                {
                    name = $"{aiMat.Name} ({matNameTracker[aiMat.Name]})";
                    matNameTracker[aiMat.Name] += 1;
                }
                else
                {
                    name = aiMat.Name;
                    matNameTracker.Add(aiMat.Name, 1);
                }

                AquaObject.GenericMaterial genMat = new AquaObject.GenericMaterial();
                List <string> shaderList          = new List <string>();
                AquaObjectMethods.GetMaterialNameData(ref name, shaderList, out string alphaType, out string playerFlag);
                genMat.matName     = name;
                genMat.shaderNames = shaderList;
                genMat.blendType   = alphaType;
                genMat.specialType = playerFlag;
                genMat.texNames    = new List <string>();
                genMat.texUVSets   = new List <int>();

                //Texture assignments. Since we can't rely on these to export properly, we dummy them or just put diffuse if a playerFlag isn't defined.
                //We'll have the user set these later if needed.
                if (genMat.specialType != null)
                {
                    AquaObjectMethods.GenerateSpecialMaterialParameters(genMat);
                }
                else if (aiMat.TextureDiffuse.FilePath != null)
                {
                    genMat.texNames.Add(Path.GetFileName(aiMat.TextureDiffuse.FilePath));
                }
                else
                {
                    genMat.texNames.Add("tex0_d.dds");
                }
                genMat.texUVSets.Add(0);

                AquaObjectMethods.GenerateMaterial(aqp, genMat, true);
            }

            //Default to this so ids can be assigned by order if needed
            Dictionary <string, int> boneDict = new Dictionary <string, int>();

            if (aiScene.RootNode.Name == null || !aiScene.RootNode.Name.Contains("(") || preAssignNodeIds == true)
            {
                int nodeCounter = 0;
                BuildAiNodeDictionary(aiScene.RootNode, ref nodeCounter, boneDict);
            }

            IterateAiNodesAQP(aqp, aqn, aiScene, aiScene.RootNode, Matrix4x4.Transpose(GetMat4FromAssimpMat4(aiScene.RootNode.Transform)), baseScale);

            //Assimp data is gathered, proceed to processing model data for PSO2
            AquaUtil.ModelSet set = new AquaUtil.ModelSet();
            set.models.Add(aqp);
            aquaUtil.aquaModels.Add(set);
            aquaUtil.ConvertToNGSPSO2Mesh(false, false, false, true, false, false, true);

            //AQPs created this way will require more processing to finish.
            //-Texture lists in particular, MUST be generated as what exists is not valid without serious errors
            return(aqp);
        }
예제 #29
0
        public static List <Item> ImportFromFile(string filePath, EditorCamera camera, out bool errorFlag, out string errorMsg, EditorItemSelection selectionManager, OnScreenDisplay osd, bool multiple = false)
        {
            List <Item> createdItems = new List <Item>();

            if (!File.Exists(filePath))
            {
                errorFlag = true;
                errorMsg  = "File does not exist!";
                return(null);
            }

            DirectoryInfo filePathInfo = new DirectoryInfo(filePath);

            bool    importError    = false;
            string  importErrorMsg = "";
            Vector3 pos            = camera.Position + (-20 * camera.Look);

            switch (filePathInfo.Extension)
            {
            case ".sa1mdl":
                ModelFile  mf   = new ModelFile(filePath);
                NJS_OBJECT objm = mf.Model;
                osd.ClearMessageList();
                osd.AddMessage("Importing models, please wait...", 3000);
                osd.ClearMessageList();
                createdItems.AddRange(ImportFromHierarchy(objm, selectionManager, osd, multiple));
                osd.AddMessage("Stage import complete!", 100);
                break;

            case ".obj":
            case ".objf":
                LevelItem item = new LevelItem(filePath, new Vertex(pos.X, pos.Y, pos.Z), new Rotation(), levelItems.Count, selectionManager)
                {
                    Visible = true
                };

                createdItems.Add(item);
                break;

            case ".txt":
                NodeTable.ImportFromFile(filePath, out importError, out importErrorMsg, selectionManager);
                break;

            case ".dae":
            case ".fbx":
                Assimp.AssimpContext context = new Assimp.AssimpContext();
                Assimp.Configs.FBXPreservePivotsConfig conf = new Assimp.Configs.FBXPreservePivotsConfig(false);
                context.SetConfig(conf);
                Assimp.Scene scene = context.ImportFile(filePath, Assimp.PostProcessSteps.Triangulate);
                for (int i = 0; i < scene.RootNode.ChildCount; i++)
                {
                    osd.ClearMessageList();
                    osd.AddMessage("Importing model " + i.ToString() + " of " + scene.RootNode.ChildCount.ToString() + "...", 3000);
                    Assimp.Node        child  = scene.RootNode.Children[i];
                    List <Assimp.Mesh> meshes = new List <Assimp.Mesh>();
                    foreach (int j in child.MeshIndices)
                    {
                        meshes.Add(scene.Meshes[j]);
                    }
                    bool isVisible = true;
                    for (int j = 0; j < child.MeshCount; j++)
                    {
                        if (scene.Materials[meshes[j].MaterialIndex].Name.Contains("Collision"))
                        {
                            isVisible = false;
                            break;
                        }
                    }
                    ModelFormat mfmt = ModelFormat.Basic;
                    if (isVisible)
                    {
                        switch (geo.Format)
                        {
                        case LandTableFormat.SA2:
                            mfmt = ModelFormat.Chunk;
                            break;

                        case LandTableFormat.SA2B:
                            mfmt = ModelFormat.GC;
                            break;
                        }
                    }
                    NJS_OBJECT obj = AssimpStuff.AssimpImport(scene, child, mfmt, TextureBitmaps[leveltexs].Select(a => a.Name).ToArray(), !multiple);
                    {
                        //sa2 collision patch
                        if (obj.Attach.GetType() == typeof(BasicAttach))
                        {
                            BasicAttach ba = obj.Attach as BasicAttach;
                            foreach (NJS_MATERIAL mats in ba.Material)
                            {
                                mats.DoubleSided = true;
                            }
                        }
                        //cant check for transparent texture so i gotta force alpha for now, temporary
                        else if (obj.Attach.GetType() == typeof(ChunkAttach))
                        {
                            ChunkAttach ca = obj.Attach as ChunkAttach;
                            foreach (PolyChunk polys in ca.Poly)
                            {
                                if (polys.GetType() == typeof(PolyChunkMaterial))
                                {
                                    PolyChunkMaterial mat = polys as PolyChunkMaterial;
                                    mat.SourceAlpha      = AlphaInstruction.SourceAlpha;
                                    mat.DestinationAlpha = AlphaInstruction.InverseSourceAlpha;
                                }
                                else if (polys.GetType() == typeof(PolyChunkStrip))
                                {
                                    PolyChunkStrip str = polys as PolyChunkStrip;
                                    //str.UseAlpha = true;
                                }
                            }
                        }
                    }
                    obj.Attach.ProcessVertexData();
                    LevelItem newLevelItem = new LevelItem(obj.Attach, new Vertex(obj.Position.X + pos.X, obj.Position.Y + pos.Y, obj.Position.Z + pos.Z), obj.Rotation, levelItems.Count, selectionManager)
                    {
                        Visible = isVisible
                    };
                    createdItems.Add(newLevelItem);
                }
                osd.ClearMessageList();
                osd.AddMessage("Stage import complete!", 100);
                break;

            default:
                errorFlag = true;
                errorMsg  = "Invalid file format!";
                return(null);
            }

            StateChanged();

            errorFlag = importError;
            errorMsg  = importErrorMsg;

            return(createdItems);
        }
예제 #30
0
        private Scene LoadScene()
        {
            //var mesh2 = new MeshGeometry3D
            //{
            //    Positions = new FreezableCollection<Point3D>
            //    {
            //        (0, 0, 0), (100, 0, 0), (100, 100, 0), (0, 100, 0)
            //    },
            //    Indices = new FreezableCollection<uint>
            //    {
            //        0, 1, 2, 2, 3, 0
            //    }
            //};
            var dstScene = new Scene();

#if false
            var bitmap = BitmapDecoder.Create(File.OpenRead(Path.Combine(@"Content\", "heart.png")));
            var frame  = bitmap.Frames[0];
            var brush  = new ImageBrush {
                Source = frame
            };
            for (int i = 0; i < 5; i++)
            {
                dstScene.Add(new Visual3D
                {
                    Geometry = new BoxGeometry3D {
                        Width = 10, Height = 2, Depth = 20
                    },
                    Material = new Material <StandardShaderParameters>
                    {
                        Shader     = new StandardShadersGroup(),
                        Parameters = new StandardShaderParameters
                        {
                            MainTexture = brush
                        }
                    }
                });
            }
#else
            var context = new Assimp.AssimpContext();
            var scene   = context.ImportFile(@"Content\Reimu\reimu_Sheep3D_0.957.fbx", Assimp.PostProcessSteps.GenerateSmoothNormals | Assimp.PostProcessSteps.GenerateUVCoords);
            foreach (var src in scene.Meshes)
            {
                var mesh = new MeshGeometry3D
                {
                    Positions = new FreezableCollection <Point3D>(from v in src.Vertices
                                                                  select new Point3D(v.X, v.Y, v.Z)),
                    Normals = new FreezableCollection <Vector3>(from v in src.Normals
                                                                select new Vector3(v.X, v.Y, v.Z)),
                    TextureCoordinates = new FreezableCollection <Point>(from v in src.TextureCoordinateChannels[0]
                                                                         select new Point(v.X, v.Y)),
                    Indices = new FreezableCollection <uint>(from f in src.Faces
                                                             from i in f.Indices
                                                             select(uint) i)
                };
                var   srcMaterial = scene.Materials[src.MaterialIndex];
                Brush mainTexture;
                if (srcMaterial.HasTextureDiffuse)
                {
                    var bitmap = BitmapDecoder.Create(File.OpenRead(Path.Combine(@"Content\Reimu\", srcMaterial.TextureDiffuse.FilePath)));
                    var frame  = bitmap.Frames[0];
                    mainTexture = new ImageBrush {
                        Source = frame
                    };
                }
                else
                {
                    mainTexture = new SolidColorBrush {
                        Color = Colors.Black
                    }
                };
                var visual = new Visual3D
                {
                    Geometry = mesh,
                    Material = new Material <StandardShaderParameters>
                    {
                        Shader     = new StandardShadersGroup(),
                        Parameters = new StandardShaderParameters
                        {
                            MainTexture = mainTexture
                        }
                    }
                };
                dstScene.Add(visual);
            }
#endif

            //Console.WriteLine($"Total Vertex Count: { dstScene.Sum(o => ((MeshGeometry3D)o.Geometry).Positions.Count) }");
            return(dstScene);
        }
예제 #31
0
        private void ConvertModelIntoMapModel(string modelFile, MapGenConfig config)
        {
            logger.Debug($"Loading 3D model file \"{modelFile}\" using Assimp.");

            var assimp = new Assimp.AssimpContext();
            var scene  = assimp.ImportFile(modelFile, Assimp.PostProcessSteps.PreTransformVertices);

            bigMeshContainer = new BigMeshContainer();

            var scale = config.scale;

            Matrix4x4 matrix = Matrix4x4.Identity;

            if (config.applyMatrix != null)
            {
                var m = config.applyMatrix;

                if (m.Length == 16)
                {
                    matrix = new Matrix4x4(
                        m[0], m[1], m[2], m[3],
                        m[4], m[5], m[6], m[7],
                        m[8], m[9], m[10], m[11],
                        m[12], m[13], m[14], m[15]
                        );

                    logger.Debug($"Apply matrix: {matrix}");
                }
            }
            else
            {
                matrix *= scale;
            }

            logger.Debug($"Starting triangle strip conversion for {scene.Meshes.Count} meshes.");

            foreach (var inputMesh in scene.Meshes)
            {
                logger.Debug($"Mesh: {inputMesh.Name} ({inputMesh.FaceCount:#,##0} faces, {inputMesh.VertexCount:#,##0} vertices)");

                var modelMat = scene.Materials[inputMesh.MaterialIndex];

                var matDef = config.FindMaterial(modelMat.Name ?? "default") ?? MaterialDef.CreateFallbackFor(modelMat.Name);
                if (matDef.ignore)
                {
                    logger.Info($"This mesh \"{inputMesh.Name}\" is not rendered due to ignore flag of material \"{modelMat.Name}\".");
                    continue;
                }

                var kh2Mesh = bigMeshContainer.AllocateBigMeshForMaterial(matDef);

                var diffuseTextureFile = modelMat.TextureDiffuse.FilePath;
                if (!string.IsNullOrEmpty(diffuseTextureFile))
                {
                    if (config.reuseImd)
                    {
                        logger.Debug($"The mesh \"{inputMesh.Name}\" material \"{matDef.name}\" has filepath \"{diffuseTextureFile}\" for diffuse texture. It will be associated with material's fromFile3. Setting preferable imd file to fromFile2 due to reuseImd flag.");

                        matDef.fromFile2 = Path.ChangeExtension(diffuseTextureFile, ".imd");
                        matDef.fromFile3 = diffuseTextureFile;
                    }
                    else
                    {
                        logger.Debug($"The mesh \"{inputMesh.Name}\" material \"{matDef.name}\" has filepath \"{diffuseTextureFile}\" for diffuse texture. It will be associated with material's fromFile2.");

                        matDef.fromFile3 = diffuseTextureFile;
                    }
                }

                var kh2BaseVert = kh2Mesh.vertexList.Count;

                List <int> vertexToLocal = new List <int>();

                foreach (var inputVertex in inputMesh.Vertices)
                {
                    var vertex = Vector3.Transform(
                        new Vector3(inputVertex.X, inputVertex.Y, inputVertex.Z),
                        matrix
                        );

                    var index = kh2Mesh.vertexList.IndexOf(vertex);
                    if (index < 0)
                    {
                        index = kh2Mesh.vertexList.Count;
                        kh2Mesh.vertexList.Add(vertex);
                    }

                    vertexToLocal.Add(index);
                }

                var localFaces = inputMesh.Faces
                                 .Select(
                    set => set.Indices
                    .Select(index => new VertPair {
                    uvColorIndex = index, vertexIndex = vertexToLocal[index]
                })
                    .ToArray()
                    )
                                 .ToArray();

                var inputTexCoords       = inputMesh.TextureCoordinateChannels.First();
                var inputVertexColorList = inputMesh.VertexColorChannels.First();

                var hasVertexColor = inputMesh.VertexColorChannelCount >= 1;

                var maxIntensity = matDef.maxColorIntensity
                                   ?? config.maxColorIntensity
                                   ?? 128;
                var maxAlpha = matDef.maxAlpha
                               ?? config.maxAlpha
                               ?? 128;

                var triConverter =
                    config.disableTriangleStripsOptimization
                    ? (TriangleFansToTriangleStripsConverter)TriangleFansToTriangleStripsNoOpts
                    : (TriangleFansToTriangleStripsConverter)TriangleFansToTriangleStripsOptimized;

                foreach (var triStripInput in triConverter(localFaces))
                {
                    var triStripOut = new BigMesh.TriangleStrip();

                    foreach (var vertPair in triStripInput)
                    {
                        triStripOut.vertexIndices.Add(kh2BaseVert + vertPair.vertexIndex);

                        triStripOut.uvList.Add(Get2DCoord(inputTexCoords[vertPair.uvColorIndex]));

                        if (hasVertexColor)
                        {
                            triStripOut.vertexColorList.Add(ConvertVertexColor(inputVertexColorList[vertPair.uvColorIndex], maxIntensity, maxAlpha));
                        }
                        else
                        {
                            triStripOut.vertexColorList.Add(new Color(maxIntensity, maxIntensity, maxIntensity, maxAlpha));
                        }
                    }

                    kh2Mesh.triangleStripList.Add(triStripOut);
                }

                logger.Debug($"Output: {kh2Mesh.vertexList.Count:#,##0} vertices, {kh2Mesh.triangleStripList.Count:#,##0} triangle strips.");
            }

            logger.Debug($"The conversion has done.");

            logger.Debug($"Starting mesh splitter and vif packets builder.");

            mapModel = new Mdlx.M4
            {
                VifPackets = new List <Mdlx.VifPacketDescriptor>(),
            };

            foreach (var bigMesh in bigMeshContainer.MeshList
                     .Where(it => it.textureIndex != -1)
                     )
            {
                foreach (var smallMesh in BigMeshSplitter.Split(bigMesh))
                {
                    var dmaPack = new MapVifPacketBuilder(smallMesh);

                    smallMeshList.Add(smallMesh);

                    bigMesh.vifPacketIndices.Add(Convert.ToUInt16(mapModel.VifPackets.Count));
                    smallMesh.vifPacketIndices.Add(Convert.ToUInt16(mapModel.VifPackets.Count));

                    mapModel.VifPackets.Add(
                        new Mdlx.VifPacketDescriptor
                    {
                        VifPacket = dmaPack.vifPacket.ToArray(),
                        TextureId = smallMesh.textureIndex,
                        DmaPerVif = new ushort[] {
                            dmaPack.firstVifPacketQwc,
                            0,
                        },
                        IsTransparentFlag = smallMesh.matDef.transparentFlag ?? 0,
                    }
                        );
                }
            }

            logger.Debug($"Output: {mapModel.VifPackets.Count:#,##0} vif packets.");

            logger.Debug($"The builder has done.");

            logger.Debug($"Starting vifPacketRenderingGroup builder.");

            // first group: render all

            mapModel.vifPacketRenderingGroup = new List <ushort[]>(
                new ushort[][] {
                Enumerable.Range(0, mapModel.VifPackets.Count)
                .Select(it => Convert.ToUInt16(it))
                .ToArray()
            }
                );

            logger.Debug($"Output: {mapModel.vifPacketRenderingGroup.Count:#,##0} groups.");

            mapModel.DmaChainIndexRemapTable = new List <ushort>(
                Enumerable.Range(0, mapModel.VifPackets.Count)
                .Select(it => Convert.ToUInt16(it))
                .ToArray()
                );
        }
예제 #32
0
        public override IDisposable Load(Type resourceType, string identifier)
        {
            using (var assimpContext = new Assimp.AssimpContext())
            {
                var scene = assimpContext.ImportFile(identifier);
                var meshes = new List<Graphics.Mesh>();

                foreach (var mesh in scene.Meshes)
                {
                    var bytesPerVertex = 12;

                    if (mesh.HasNormals)
                    {
                        bytesPerVertex += 12;
                    }

                    if (mesh.HasTextureCoords(0))
                    {
                        bytesPerVertex += 8;
                    }

                    var vertexCount = mesh.VertexCount;
                    var meshSizeInBytes = vertexCount * bytesPerVertex;

                    using (var stream = new SlimDX.DataStream(meshSizeInBytes, true, true))
                    {
                        for (var i = 0; i < vertexCount; ++i)
                        {
                            stream.Write(mesh.Vertices[i]);

                            if (mesh.HasNormals)
                            {
                                stream.Write(mesh.Normals[i]);
                            }

                            if (mesh.HasTextureCoords(0))
                            {
                                stream.Write(mesh.TextureCoordinateChannels[0][i].X);
                                stream.Write(mesh.TextureCoordinateChannels[0][i].Y);
                            }
                        }

                        var vertexBuffer = new Graphics.VertexBuffer(device.Handle, stream, bytesPerVertex, vertexCount, SlimDX.Direct3D11.PrimitiveTopology.TriangleList);
                        var indices = mesh.GetIndices();

                        if (indices != null && indices.Count() > 0)
                        {
                            var indexBuffer = new Graphics.IndexBuffer(device.Handle, indices);

                            return new Graphics.Mesh(vertexBuffer, indexBuffer);
                        }

                        var result = new Graphics.Mesh(vertexBuffer);

                        if (resourceType.Equals(typeof(Graphics.Mesh)))
                        {
                            return result;
                        }
                        else
                        {
                            meshes.Add(result);
                        }
                    }
                }

                if (meshes.Count > 0)
                {
                    return new Graphics.MeshGroup(meshes);
                }
                else
                {
                    throw new KeyNotFoundException("Failed to load mesh: " + identifier);
                }
            }
        }