Exemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        private List <Node> ProcessModel(IOModel model)
        {
            List <Node> nodes = new List <Node>();

            // bones
            foreach (var root in model.Skeleton.RootBones)
            {
                nodes.Add(ProcessSkeleton(root));
            }

            // get root bone
            IOBone rootBone = null;

            if (model.Skeleton != null && model.Skeleton.RootBones.Count > 0)
            {
                rootBone = model.Skeleton.RootBones[0];
            }

            // mesh
            foreach (var mesh in model.Meshes)
            {
                nodes.Add(ProcessMesh(mesh, model, rootBone));
            }

            return(nodes);
        }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            ADAM6KReqService ADAM6KReqService = new ADAM6KReqService();

            DeviceModel Device = new DeviceModel()
            {
                IPAddress = "172.18.3.241"
            };

            if (ADAM6KReqService.OpenCOM(Device.IPAddress))
            {
                Device = ADAM6KReqService.GetDevice();
                string typ = ADAM6KReqService.GetDevRng(Device.ModuleType);
                Console.WriteLine("Get range code is [%s].", typ);


                IOModel IOitem = new IOModel()
                {
                    Id   = 40,
                    Ch   = 0,
                    cRng = 251,
                };
                ADAM6KReqService.UpdateIOConfig(IOitem);
                Console.WriteLine("Change range code is [%s].", IOitem.cRng);
            }



            Console.ReadKey();
        }
Exemplo n.º 3
0
        static void Main(string[] args)
        {
            ADAM6KReqService ADAM6KReqService = new ADAM6KReqService();

            DeviceModel Device = new DeviceModel()
            {
                IPAddress = "172.18.3.241"
            };

            if (ADAM6KReqService.OpenCOM(Device.IPAddress))
            {
                Device = ADAM6KReqService.GetDevice();

                IOModel IOitem = new IOModel()
                {
                    Id  = 0,
                    Ch  = 0,
                    cEn = 0,
                };
                ADAM6KReqService.UpdateIOConfig(IOitem);
                Console.WriteLine("Change channel mask is disable.");
            }



            Console.ReadKey();
        }
Exemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public IOScene GetScene(string filePath)
        {
            FbxHelper helper = new FbxHelper(FbxIO.ReadBinary(filePath));


            //TODO: FBX Version 2006-2010 unupported. (Anything < 7100 works. But textures aren't grabbed)
            //FBX Version 2011-2020 <-- Tested & Supported!
            //FBX Version 2011-2020 currently supported
            if (helper.Version < 7100)
            {
                throw new NotSupportedException($"FBX Version {helper.Version} not supported");
            }

            IOScene scene = new IOScene();

            IOModel model = new IOModel();

            model.Skeleton = helper.GetSkeleton();
            scene.Models.Add(model);

            model.Meshes.AddRange(helper.ExtractMesh());

            scene.Materials.AddRange(helper.GetMaterials());

            return(scene);
        }
Exemplo n.º 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mesh"></param>
        /// <returns></returns>
        private Node ProcessMesh(IOMesh mesh, IOModel model)
        {
            Node n = new Node()
            {
                Name = mesh.Name,
                sID  = mesh.Name,
                ID   = mesh.Name,
                Type = Node_Type.NODE
            };

            var materials = mesh.Polygons.Select(e => e.MaterialName).Distinct();

            if (mesh.HasEnvelopes())
            {
                var geom = new Instance_Controller();

                geom.URL = "#" + GenerateGeometryController(mesh, model.Skeleton);

                n.Instance_Controller = new Instance_Controller[] { geom };

                n.Instance_Controller[0].Bind_Material = new IONET.Collada.FX.Materials.Bind_Material[]
                {
                    new Bind_Material()
                    {
                        Technique_Common = new FX.Technique_Common.Technique_Common_Bind_Material()
                        {
                            Instance_Material = materials.Select(e => new Instance_Material_Geometry()
                            {
                                Symbol = e, Target = "#" + e
                            }).ToArray()
                        }
                    }
                };
            }
            else
            {
                var geom = new Instance_Geometry();

                geom.URL = "#" + GenerateGeometry(mesh);

                n.Instance_Geometry = new Instance_Geometry[] { geom };

                n.Instance_Geometry[0].Bind_Material = new IONET.Collada.FX.Materials.Bind_Material[]
                {
                    new Bind_Material()
                    {
                        Technique_Common = new FX.Technique_Common.Technique_Common_Bind_Material()
                        {
                            Instance_Material = materials.Select(e => new Instance_Material_Geometry()
                            {
                                Symbol = e, Target = "#" + e
                            }).ToArray()
                        }
                    }
                };
            }

            return(n);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Gets the model information in this scene as an IO Model
        /// </summary>
        /// <returns></returns>
        public override IOModel GetIOModel()
        {
            IOModel iomodel = new IOModel();

            iomodel.Skeleton = (SBSkeleton)Skeleton;

            foreach (var mesh in Model.Meshes)
            {
                var iomesh = new IOMesh();
                iomesh.Name = mesh.Name;
                iomodel.Meshes.Add(iomesh);

                iomesh.HasPositions = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.Position0);
                iomesh.HasNormals   = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.Normal0);
                iomesh.HasUV0       = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.map1);
                iomesh.HasUV1       = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.uvSet);
                iomesh.HasUV2       = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.uvSet1);
                iomesh.HasUV3       = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.uvSet2);
                iomesh.HasColor     = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.colorSet1);

                iomesh.HasBoneWeights = true;

                iomesh.Indices.AddRange(mesh.Indices);

                foreach (var vertex in mesh.Vertices)
                {
                    var iovertex = new IOVertex();

                    iovertex.Position    = vertex.Position0;
                    iovertex.Normal      = vertex.Normal0;
                    iovertex.Tangent     = vertex.Tangent0;
                    iovertex.UV0         = vertex.Map1;
                    iovertex.UV1         = vertex.UvSet;
                    iovertex.UV2         = vertex.UvSet1;
                    iovertex.Color       = vertex.ColorSet1;
                    iovertex.BoneIndices = new Vector4(vertex.BoneIndices.X, vertex.BoneIndices.Y, vertex.BoneIndices.Z, vertex.BoneIndices.W);
                    iovertex.BoneWeights = vertex.BoneWeights;

                    // single bind fix
                    if (mesh.ParentBone != "" && Skeleton != null)
                    {
                        var parentBone = Skeleton[mesh.ParentBone];
                        if (parentBone != null)
                        {
                            iovertex.Position    = Vector3.TransformPosition(vertex.Position0, parentBone.WorldTransform);
                            iovertex.Normal      = Vector3.TransformNormal(vertex.Normal0, parentBone.WorldTransform);
                            iovertex.BoneIndices = new Vector4(Skeleton.IndexOfBone(parentBone), 0, 0, 0);
                            iovertex.BoneWeights = new Vector4(1, 0, 0, 0);
                        }
                    }

                    iomesh.Vertices.Add(iovertex);
                }
            }

            return(iomodel);
        }
Exemplo n.º 7
0
        static void Main(string[] args)
        {
            ADAM6KReqService ADAM6KReqService = new ADAM6KReqService();

            DeviceModel Device = new DeviceModel()
            {
                IPAddress = "172.18.3.188"
            };

            if (ADAM6KReqService.OpenCOM(Device.IPAddress))
            {
                Device = ADAM6KReqService.GetDevice();
                List <IOModel> IO_Data = (List <IOModel>)ADAM6KReqService.GetListOfIOItems("");

                //
                IOModel IOitem = new IOModel();//need to get twice.
                foreach (var item in (List <IOModel>)ADAM6KReqService.GetListOfIOItems(""))
                {
                    if (item.Id == 0 && item.Ch == 0)
                    {
                        IOitem = new IOModel()
                        {
                            Id  = item.Id,
                            Ch  = item.Ch,
                            Tag = item.Tag,
                            Val = item.Val,
                            En  = item.En,
                            //DI
                            Md    = item.Md,
                            Inv   = item.Inv,
                            Fltr  = item.Fltr,
                            FtLo  = item.FtLo,
                            FtHi  = item.FtHi,
                            FqT   = item.FqT,
                            FqP   = item.FqP,
                            CntIV = item.CntIV,
                            CntKp = item.CntKp,
                            OvLch = item.OvLch,
                        };
                    }
                }
                IOitem.Md = 2; IOitem.Inv = 0; IOitem.Fltr = 1;
                //    IOModel IOitem = new IOModel()
                //{
                //    Id = 0,
                //    Ch = 0,
                //    cEn = 0,
                //};
                ADAM6KReqService.UpdateIOConfig(IOitem);
                Console.WriteLine("Change channel mask is disable.");
            }



            Console.ReadKey();
        }
Exemplo n.º 8
0
        public static void ExportIOModelAsSMD(string FileName, IOModel Model)
        {
            SMD file = new SMD();

            if (Model.HasSkeleton)
            {
                var bonelist = new List <SBBone>(Model.Skeleton.Bones);
                var frame    = new SMDSkeletonFrame();
                file.skeleton.Add(frame);
                frame.time = 0;
                foreach (var bone in bonelist)
                {
                    file.nodes.Add(new SMDNode()
                    {
                        Name = bone.Name, ID = bonelist.IndexOf(bone), ParentID = bonelist.IndexOf(bone.Parent)
                    });
                    frame.skeletons.Add(new SMDSkeleton()
                    {
                        BoneID = bonelist.IndexOf(bone), Position = bone.Translation, Rotation = bone.RotationEuler
                    });
                }
            }

            if (Model.HasMeshes)
            {
                Dictionary <string, int> UniqueMeshNames = new Dictionary <string, int>();

                foreach (var mesh in Model.Meshes)
                {
                    if (!UniqueMeshNames.ContainsKey(mesh.Name))
                    {
                        UniqueMeshNames.Add(mesh.Name, 0);
                    }

                    string Name = mesh.Name + (UniqueMeshNames[mesh.Name] == 0 ? "" : "_" + UniqueMeshNames[mesh.Name]);
                    UniqueMeshNames[mesh.Name]++;

                    for (int i = 0; i < mesh.Indices.Count; i += 3)
                    {
                        var triangle = new SMDTriangle();
                        triangle.Material = Name;
                        triangle.vertex1  = IOVertexToSMDVertex(mesh.Vertices[(int)mesh.Indices[i + 0]]);
                        triangle.vertex2  = IOVertexToSMDVertex(mesh.Vertices[(int)mesh.Indices[i + 1]]);
                        triangle.vertex3  = IOVertexToSMDVertex(mesh.Vertices[(int)mesh.Indices[i + 2]]);
                        file.triangles.Add(triangle);
                    }
                }
            }

            file.Save(FileName);
        }
Exemplo n.º 9
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="model"></param>
 private static void InvertSingleBinds(IOModel model)
 {
     foreach (var m in model.Meshes)
     {
         foreach (var v in m.Vertices)
         {
             if (v.Envelope.Weights.Count > 0 && v.Envelope.Weights[0].Weight == 1)
             {
                 System.Numerics.Matrix4x4.Invert(model.Skeleton.GetBoneByName(v.Envelope.Weights[0].BoneName).WorldTransform, out System.Numerics.Matrix4x4 inv);
                 v.Transform(inv);
             }
         }
     }
 }
Exemplo n.º 10
0
        public override bool ExportToFile(IOModel model, string filename)
        {
            var tempFile    = Path.Combine(Path.GetDirectoryName(filename), "_proxy.obj");
            var tempMtlFile = Path.Combine(Path.GetDirectoryName(filename), "_proxy.mtl");
            var objExporter = new ObjExporter(_settings, _callback);
            var objData     = objExporter.ExportToFile(model, tempFile);

            AssimpContext context = new AssimpContext();

            context.SetConfig(new NormalSmoothingAngleConfig(90.0f));
            Scene scene = context.ImportFile(tempFile);

            switch (_exporter)
            {
            case Exporter.Collada:
            {
                context.ExportFile(scene, filename, "collada");

                // Open up exported collada file and fix all texture filenames to relative
                XDocument exported = XDocument.Load(filename);
                foreach (var node in exported.Root.DescendantNodes())
                {
                    if (node is XElement)
                    {
                        var element = (XElement)node;
                        if (element.Name.LocalName == "init_from" && element.Value.EndsWith(".png"))
                        {
                            element.Value = Path.GetFileName(element.Value);
                        }
                    }
                }
                exported.Save(filename);
            }
            break;

            case Exporter.GLTF2:
                context.ExportFile(scene, filename, "gltf2");
                break;

            case Exporter.X3d:
                context.ExportFile(scene, filename, "x3d");
                break;
            }

            File.Delete(tempFile);
            File.Delete(tempMtlFile);

            return(true);
        }
Exemplo n.º 11
0
        public override void FromIOModel(IOModel iomodel)
        {
            //System.Windows.Forms.MessageBox.Show("Importing Model to DAT not supported");

            // use the existing skeleton always
            iomodel.ConvertToSkeleton((SBSkeleton)Skeleton);

            // single bound vertices are stored in inverse transform positions
            iomodel.InvertSingleBinds();

            // dobjs to import to
            var dobjs = GetMeshObjects();

            foreach (SBHsdMesh m in GetMeshObjects())
            {
                m.DOBJ.Pobj = null;
            }

            var attributeGroup       = MakeRiggedAttributes();
            var singleAttributeGroup = MakeSingleAttributes();

            // get a compressor ready
            // the compressor will handle making the compressed attribute buffers
            POBJ_Generator compressor = new POBJ_Generator();

            // import the iomeshes into their respective dobjs
            foreach (var iomesh in iomodel.Meshes)
            {
                int dobjId = -1;
                int.TryParse(iomesh.Name.Replace("DOBJ_", ""), out dobjId);

                SBConsole.WriteLine(iomesh.Name + " imported:" + (dobjId != -1));

                if (dobjId != -1)
                {
                    var dobj = (SBHsdMesh)dobjs[dobjId];
                    dobj.ImportPOBJs(iomesh, (SBSkeleton)Skeleton, compressor, dobj.ParentBone == "JOBJ_0" ? attributeGroup : singleAttributeGroup);
                }
            }

            // finalizes and remakes the buffer
            compressor.SaveChanges();

            // refresh everything
            RefreshRendering();
        }
Exemplo n.º 12
0
        /// <summary>
        /// Imports information into this scene from an IO Model
        /// </summary>
        public override void FromIOModel(IOModel iomodel)
        {
            // copy skeleton
            Skeleton = iomodel.Skeleton;

            // make temp material
            UltimateMaterial material = new UltimateMaterial();

            material.Name  = "SFX_PBS_0100080008008269_opaque";
            material.Label = "skin_sonic_001";

            //TODO more elegant material management
            Materials.Add(material);

            // convert meshes
            SBUltimateModel model = new SBUltimateModel();

            foreach (var iomesh in iomodel.Meshes)
            {
                SBUltimateMesh <UltimateVertex> mesh = new SBUltimateMesh <UltimateVertex>();
                mesh.Name       = iomesh.Name;
                mesh.ParentBone = "";
                mesh.Material   = material;

                model.Meshes.Add(mesh);

                mesh.Indices = iomesh.Indices;

                iomesh.GenerateTangentsAndBitangents();

                foreach (var vertex in iomesh.Vertices)
                {
                    mesh.Vertices.Add(IOToUltimateVertex(vertex));
                }

                //TODO: make more customizable through import settings
                mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.Position0);
                mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.Normal0);
                mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.Tangent0);
                mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.map1);
                mesh.ExportAttributes.Add(SSBHLib.Tools.MESHAttribute.colorSet1);
            }

            Model = model;
        }
Exemplo n.º 13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        private List <Node> ProcessModel(IOModel model)
        {
            List <Node> nodes = new List <Node>();

            // bones
            foreach (var root in model.Skeleton.RootBones)
            {
                nodes.Add(ProcessSkeleton(root));
            }

            // mesh
            foreach (var mesh in model.Meshes)
            {
                nodes.Add(ProcessMesh(mesh, model));
            }

            return(nodes);
        }
Exemplo n.º 14
0
        public void ExportIOModel(string FileName, IOModel model)
        {
            StringBuilder o = new StringBuilder();

            // keep track of used names so we don't have name overlap
            Dictionary <string, int> UsedNames = new Dictionary <string, int>();

            // uuuggh
            int VertexCount = 1;

            foreach (IOMesh mesh in model.Meshes)
            {
                // append the index number for this mesh name
                string Meshname = mesh.Name;
                if (UsedNames.ContainsKey(mesh.Name))
                {
                    UsedNames[mesh.Name] += 1;
                    o.AppendLine($"g _{UsedNames[mesh.Name]}");
                }
                else
                {
                    UsedNames.Add(mesh.Name, 0);
                    o.AppendLine($"o {Meshname}");
                    o.AppendLine($"g _{UsedNames[mesh.Name]}");
                }

                foreach (IOVertex v in mesh.Vertices)
                {
                    o.AppendLine($"v {v.Position.X} {v.Position.Y} {v.Position.Z}");
                    o.AppendLine($"vn {v.Normal.X} {v.Normal.Y} {v.Normal.Z}");
                    o.AppendLine($"vt {v.UV0.X} {v.UV0.Y}");
                }
                for (int i = 0; i < mesh.Indices.Count; i += 3)
                {
                    o.AppendLine($"f {VertexCount + mesh.Indices[i]}/{VertexCount + mesh.Indices[i]}/{VertexCount + mesh.Indices[i]}" +
                                 $" {VertexCount + mesh.Indices[i + 1]}/{VertexCount + mesh.Indices[i + 1]}/{VertexCount + mesh.Indices[i + 1]}" +
                                 $" {VertexCount + mesh.Indices[i + 2]}/{VertexCount + mesh.Indices[i + 2]}/{VertexCount + mesh.Indices[i + 2]}");
                }
                VertexCount += mesh.Vertices.Count;
            }

            System.IO.File.WriteAllText(FileName, o.ToString());
        }
Exemplo n.º 15
0
        internal static IOModel IOModelFactory(IOType ioType, string args, ProcessWrapper.ProcessControlHandler handler)
        {
            IOModel outModel = null;

            switch (ioType)
            {
            case IOType.StdIO: outModel = new StdIOModel(); break;

            case IOType.PIPES: outModel = new PipeIOModel(); break;

            case IOType.QUEUES: outModel = new QueueIOModel(); break;
            }
            if (outModel != null)
            {
                outModel.BaseInit(args);
                outModel.SetReadHandler(handler);
            }
            return(outModel);
        }
Exemplo n.º 16
0
    double AIRead()//unit: V
    {
        IOModel DevIO = new IOModel();

        foreach (var item in ADAM6KReqService.GetListOfIOItems(""))
        {
            var readInfo = (IOModel)item;
            if (readInfo.Id.Equals(ai_id_offset + Ref_IO_Mod.Ch))
            {
                DevIO = readInfo;
                break;
            }
        }
        double rData = 0.0;

        //判斷輸出的數值單位
        if (//Uni-polar
            DevIO.Rng == (int)ValueRange.mV_0To150 || DevIO.Rng == (int)ValueRange.mV_0To500
            //Bi-polar
            || DevIO.Rng == (int)ValueRange.mV_Neg15To15 || DevIO.Rng == (int)ValueRange.mV_Neg50To50 ||
            DevIO.Rng == (int)ValueRange.mV_Neg100To100 || DevIO.Rng == (int)ValueRange.mV_Neg150To150 ||
            DevIO.Rng == (int)ValueRange.mV_Neg500To500)
        {
            rData = (double)DevIO.Val / 1000000;
        }
        else if (DevIO.Rng == (int)ValueRange.Jtype_0To760C || DevIO.Rng == (int)ValueRange.Ktype_0To1370C ||
                 DevIO.Rng == (int)ValueRange.Ttype_Neg100To400C || DevIO.Rng == (int)ValueRange.Etype_0To1000C ||
                 DevIO.Rng == (int)ValueRange.Rtype_500To1750C || DevIO.Rng == (int)ValueRange.Stype_500To1750C ||
                 DevIO.Rng == (int)ValueRange.Btype_500To1800C)
        {
            rData = (double)DevIO.Val;
        }
        else
        {
            rData = (double)DevIO.Val / 1000;
        }

        return(rData);
    }
Exemplo n.º 17
0
        public void ExportIOModel(string FileName, IOModel model)
        {
            DialogResult UV1dialog = MessageBox.Show("Export UV1?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (UV1dialog == DialogResult.Yes)
            {
                ExportUV1 = true;
            }

            DialogResult UV2dialog = MessageBox.Show("Export UV2?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (UV2dialog == DialogResult.Yes)
            {
                ExportUV2 = true;
            }

            DialogResult UV3dialog = MessageBox.Show("Export UV3?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (UV3dialog == DialogResult.Yes)
            {
                ExportUV3 = true;
            }

            DialogResult Bonedialog = MessageBox.Show("Export Bone weights?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (Bonedialog == DialogResult.Yes)
            {
                ExportBoneWeights = true;
            }

            StringBuilder csv = new StringBuilder();

            if (model.HasMeshes)
            {
                foreach (IOMesh mesh in model.Meshes)
                {
                    UVNum = 1;

                    if (ExportUV1 == true)
                    {
                        UVNum++;
                    }
                    if (ExportUV2 == true)
                    {
                        UVNum++;
                    }
                    if (ExportUV3 == true)
                    {
                        UVNum++;
                    }

                    csv.Append($"Obj Name:{mesh.Name}\n");
                    if (ExportBoneWeights == true)
                    {
                        if (mesh.HasBoneWeights)
                        {
                            csv.Append("Bone_Suport\n");
                        }
                    }
                    csv.Append($"UV_Num:{UVNum}\n");
                    csv.Append("vert_Array\n");

                    foreach (IOVertex v in mesh.Vertices)
                    {
                        csv.Append($"{v.Position.X},{v.Position.Y},{v.Position.Z}\n");

                        if (mesh.HasNormals)
                        {
                            csv.Append($"{v.Normal.X},{v.Normal.Y},{v.Normal.Z}\n");
                        }
                        else
                        {
                            csv.Append("0.000000,0.000000,1.000000\n");
                        }

                        if (mesh.HasColor)
                        {
                            //Let's convert these floats to byte range with this dirty trick
                            csv.Append($"{v.Color.X * 255 % 256},{v.Color.Y * 255 % 256},{v.Color.Z * 255 % 256},{v.Color.W * 255 % 256}\n");
                        }
                        else
                        {
                            csv.Append("127,127,127,255\n");
                        }

                        if (mesh.HasUV0)
                        {
                            csv.Append($"{v.UV0.X},{v.UV0.Y}\n");
                        }
                        else
                        {
                            csv.Append("0.000000,0.000000\n");
                        }


                        if (ExportUV1 == true)
                        {
                            if (mesh.HasUV1)
                            {
                                csv.Append($"{v.UV1.X},{v.UV1.Y}\n");
                            }
                            else
                            {
                                csv.Append("0.000000,0.000000\n");
                            }
                        }

                        if (ExportUV2 == true)
                        {
                            if (mesh.HasUV2)
                            {
                                csv.Append($"{v.UV2.X},{v.UV2.Y}\n");
                            }
                            else
                            {
                                csv.Append("0.000000,0.000000\n");
                            }
                        }

                        if (ExportUV3 == true)
                        {
                            if (mesh.HasUV3)
                            {
                                csv.Append($"{v.UV3.X},{v.UV3.Y}\n");
                            }
                            else
                            {
                                csv.Append("0.000000,0.000000\n");
                            }
                        }
                    }

                    csv.Append("face_Array\n");

                    for (int i = 0; i < mesh.Indices.Count; i += 3)
                    {
                        csv.Append($"{mesh.Indices[i] + 1},{mesh.Indices[i + 1] + 1},{mesh.Indices[i + 2] + 1}\n");
                    }

                    if (ExportBoneWeights == true)
                    {
                        csv.Append("bone_Array\n");

                        foreach (var v in mesh.Vertices)
                        {
                            if (v.BoneWeights[0] != 0)
                            {
                                csv.Append($"{model.Skeleton.Bones[(int)v.BoneIndices.X].Name},{v.BoneWeights[0]},");
                            }
                            if (v.BoneWeights[1] != 0)
                            {
                                csv.Append($"{model.Skeleton.Bones[(int)v.BoneIndices.Y].Name},{v.BoneWeights[1]},");
                            }
                            if (v.BoneWeights[2] != 0)
                            {
                                csv.Append($"{model.Skeleton.Bones[(int)v.BoneIndices.Z].Name},{v.BoneWeights[2]},");
                            }
                            if (v.BoneWeights[3] != 0)
                            {
                                csv.Append($"{model.Skeleton.Bones[(int)v.BoneIndices.W].Name},{v.BoneWeights[3]},");
                            }

                            csv.Append("\n");
                        }
                    }
                }
            }
            File.WriteAllText(FileName, csv.ToString());
        }
Exemplo n.º 18
0
    //============================================//

    void GetDeviceItems(int id)
    {
        //var obj = ADAM6KReqService.GetListOfIOItems("");
        bool           flg     = false;
        List <IOModel> IO_Data = (List <IOModel>)ADAM6KReqService.GetListOfIOItems("");

        if (id >= di_id_offset)
        {
            foreach (var item in IO_Data)
            {
                if (item.Id == id && item.Ch == id - di_id_offset)
                {
                    IOitem = new IOModel()
                    {
                        Id  = item.Id,
                        Ch  = item.Ch,
                        Tag = item.Tag,
                        Val = item.Val,
                        //AI
                        En     = item.En,
                        Rng    = item.Rng,
                        Evt    = item.Evt,
                        LoA    = item.LoA,
                        HiA    = item.HiA,
                        Eg     = item.Eg,
                        EgF    = item.EgF,
                        Val_Eg = item.Val_Eg,
                        cEn    = item.cEn,
                        cRng   = item.cRng,
                        EnLA   = item.EnLA,
                        EnHA   = item.EnHA,
                        LAMd   = item.LAMd,
                        HAMd   = item.HAMd,
                        cLoA   = item.cLoA,
                        cHiA   = item.cHiA,
                        LoS    = item.LoS,
                        HiS    = item.HiS,
                        // add basic
                        Res  = item.Res,
                        EnB  = item.EnB,
                        BMd  = item.BMd,
                        AiT  = item.AiT,
                        Smp  = item.Smp,
                        AvgM = item.AvgM,
                        //DI
                        Md    = item.Md,
                        Inv   = item.Inv,
                        Fltr  = item.Fltr,
                        FtLo  = item.FtLo,
                        FtHi  = item.FtHi,
                        FqT   = item.FqT,
                        FqP   = item.FqP,
                        CntIV = item.CntIV,
                        CntKp = item.CntKp,
                        OvLch = item.OvLch,
                        //DO
                        FSV  = item.FSV,
                        PsLo = item.PsLo,
                        PsHi = item.PsHi,
                        HDT  = item.HDT,
                        LDT  = item.LDT,
                        ACh  = item.ACh,
                        AMd  = item.AMd,
                    };
                }
            }
        }
        //if (id >= ai_id_offset)
        {
            //ViewData = IOitem;
            chiTxtbox.Text = (id - di_id_offset).ToString();
            //return true;
        }
        //else if (id >= do_id_offset) { mod = DOitem; }

        flg = true;
    }
Exemplo n.º 19
0
 /// <summary>
 /// Imports an IO model into the scene
 /// </summary>
 /// <param name="iomodel"></param>
 public virtual void FromIOModel(IOModel iomodel)
 {
 }
Exemplo n.º 20
0
        public IOModel GetIOModel()
        {
            IOModel outModel = new IOModel();

            Mesh meshFile     = null;
            Matl materialFile = null;

            foreach (FileNode n in Parent.Nodes)
            {
                if (n.Text.Equals(model.MeshString))
                {
                    meshFile = ((NumsbhNode)n).mesh;
                }
                if (n.Text.Equals(model.SkeletonFileName))
                {
                    outModel.Skeleton = (RSkeleton)((SkelNode)n).GetRenderableNode();
                }
                if (n.Text.Equals(model.MaterialFileNames[0].MaterialFileName))
                {
                    materialFile = ((MatlNode)n).Material;
                }
            }

            Dictionary <string, int> indexByBoneName = new Dictionary <string, int>();

            if (outModel.Skeleton != null)
            {
                for (int i = 0; i < outModel.Skeleton.Bones.Count; i++)
                {
                    indexByBoneName.Add(outModel.Skeleton.Bones[i].Name, i);
                }
            }

            Dictionary <string, int> materialNameToIndex = new Dictionary <string, int>();

            if (materialFile != null)
            {
                int materialIndex = 0;
                foreach (var entry in materialFile.Entries)
                {
                    materialNameToIndex.Add(entry.ShaderLabel, materialIndex++);
                    IOMaterial material = new IOMaterial
                    {
                        Name = entry.ShaderLabel
                    };
                    outModel.Materials.Add(material);

                    foreach (var attr in entry.Attributes)
                    {
                        if (attr.ParamId == MatlEnums.ParamId.Texture0)
                        {
                            IOTexture dif = new IOTexture
                            {
                                Name = attr.DataObject.ToString()
                            };
                            material.DiffuseTexture = dif;
                        }
                    }
                }
            }

            if (meshFile != null)
            {
                SsbhVertexAccessor vertexAccessor = new SsbhVertexAccessor(meshFile);
                {
                    SsbhRiggingAccessor riggingAccessor = new SsbhRiggingAccessor(meshFile);
                    foreach (MeshObject obj in meshFile.Objects)
                    {
                        IOMesh outMesh = new IOMesh()
                        {
                            Name = obj.Name,
                        };
                        outModel.Meshes.Add(outMesh);

                        // get material
                        if (materialFile != null)
                        {
                            foreach (var entry in model.ModelEntries)
                            {
                                if (entry.MeshName.Equals(obj.Name) && entry.SubIndex == obj.SubMeshIndex)
                                {
                                    outMesh.MaterialIndex = materialNameToIndex[entry.MaterialLabel];
                                    break;
                                }
                            }
                        }

                        IOVertex[] vertices = new IOVertex[obj.VertexCount];
                        for (int i = 0; i < vertices.Length; i++)
                        {
                            vertices[i] = new IOVertex();
                        }

                        foreach (MeshAttribute attr in obj.Attributes)
                        {
                            SsbhVertexAttribute[] values = vertexAccessor.ReadAttribute(attr.AttributeStrings[0].Name, 0, obj.VertexCount, obj);

                            if (attr.AttributeStrings[0].Name.Equals("Position0"))
                            {
                                outMesh.HasPositions = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Position = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("Normal0"))
                            {
                                outMesh.HasNormals = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Normal = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }

                            // Flip UVs vertically for export.
                            if (attr.AttributeStrings[0].Name.Equals("map1"))
                            {
                                outMesh.HasUV0 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV0 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet"))
                            {
                                outMesh.HasUV1 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV1 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet1"))
                            {
                                outMesh.HasUV2 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV2 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet2"))
                            {
                                outMesh.HasUV3 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV3 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("colorSet1"))
                            {
                                outMesh.HasColor = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Color = new OpenTK.Vector4(values[i].X, values[i].Y, values[i].Z, values[i].W) / 127f;
                                }
                            }
                        }

                        // Fix SingleBinds
                        if (outModel.Skeleton != null && !obj.ParentBoneName.Equals(""))
                        {
                            int parentIndex = outModel.Skeleton.GetBoneIndex(obj.ParentBoneName);
                            if (parentIndex != -1)
                            {
                                for (int i = 0; i < vertices.Length; i++)
                                {
                                    vertices[i].Position      = OpenTK.Vector3.TransformPosition(vertices[i].Position, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].Normal        = OpenTK.Vector3.TransformNormal(vertices[i].Normal, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].BoneIndices.X = indexByBoneName[obj.ParentBoneName];
                                    vertices[i].BoneWeights.X = 1;
                                    outMesh.HasBoneWeights    = true;
                                }
                            }
                        }

                        // Apply Rigging
                        SsbhVertexInfluence[] influences = riggingAccessor.ReadRiggingBuffer(obj.Name, (int)obj.SubMeshIndex);

                        foreach (SsbhVertexInfluence influence in influences)
                        {
                            outMesh.HasBoneWeights = true;

                            // Some influences refer to bones that don't exist in the skeleton.
                            // _eff bones?
                            if (!indexByBoneName.ContainsKey(influence.BoneName))
                            {
                                continue;
                            }

                            if (vertices[influence.VertexIndex].BoneWeights.X == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.X = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.X = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Y == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Y = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Y = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Z == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Z = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Z = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.W == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.W = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.W = influence.Weight;
                            }
                        }

                        outMesh.Vertices.AddRange(vertices);
                        outMesh.Indices.AddRange(vertexAccessor.ReadIndices(0, obj.IndexCount, obj));
                    }
                }
            }


            return(outModel);
        }
Exemplo n.º 21
0
        public void ExportIOModel(string FileName, IOModel model)
        {
            using (StudioSB.GUI.SBCustomDialog d = new GUI.SBCustomDialog(ExportSettings))
            {
                if (d.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }
            }

            using (DAEWriter writer = new DAEWriter(FileName, false))
            {
                writer.WriteAsset();

                // Material IO needs big rework
                if (model.HasMaterials && ExportSettings.ExportTextures)
                {
                    List <string> TextureNames = new List <string>();
                    var           png          = false;
                    foreach (var tex in model.Textures)
                    {
                        var filePath = System.IO.Path.GetDirectoryName(FileName) + "\\" + tex.Name;

                        TextureNames.Add(tex.Name);
                        if (tex.InternalFormat == OpenTK.Graphics.OpenGL.InternalFormat.Rgba)
                        {
                            png = true;

                            Tools.FileTools.WriteBitmapFile(filePath + ".png", tex.Width, tex.Height, tex.Arrays[0].Mipmaps[0]);
                        }
                        else
                        {
                            IO_DDS.Export(filePath + ".dds", tex);
                        }
                    }
                    writer.WriteLibraryImages(TextureNames.ToArray(), png ? ".png" : ".dds");

                    writer.StartMaterialSection();
                    foreach (var mat in model.Materials)
                    {
                        writer.WriteMaterial(mat.Name);
                    }
                    writer.EndMaterialSection();

                    writer.StartEffectSection();
                    foreach (var mat in model.Materials)
                    {
                        writer.WriteEffect(mat.Name, mat.DiffuseTexture);
                    }
                    writer.EndEffectSection();
                }
                else
                {
                    writer.WriteLibraryImages();
                }

                if (model.HasSkeleton)
                {
                    foreach (var bone in model.Skeleton.Bones)
                    {
                        float[] Transform = new float[] { bone.Transform.M11, bone.Transform.M21, bone.Transform.M31, bone.Transform.M41,
                                                          bone.Transform.M12, bone.Transform.M22, bone.Transform.M32, bone.Transform.M42,
                                                          bone.Transform.M13, bone.Transform.M23, bone.Transform.M33, bone.Transform.M43,
                                                          bone.Transform.M14, bone.Transform.M24, bone.Transform.M34, bone.Transform.M44 };
                        float[] InvTransform = new float[] { bone.InvWorldTransform.M11, bone.InvWorldTransform.M21, bone.InvWorldTransform.M31, bone.InvWorldTransform.M41,
                                                             bone.InvWorldTransform.M12, bone.InvWorldTransform.M22, bone.InvWorldTransform.M32, bone.InvWorldTransform.M42,
                                                             bone.InvWorldTransform.M13, bone.InvWorldTransform.M23, bone.InvWorldTransform.M33, bone.InvWorldTransform.M43,
                                                             bone.InvWorldTransform.M14, bone.InvWorldTransform.M24, bone.InvWorldTransform.M34, bone.InvWorldTransform.M44 };
                        writer.AddJoint(bone.Name, bone.Parent == null ? "" : bone.Parent.Name, Transform, InvTransform);
                    }
                }

                writer.StartGeometrySection();
                foreach (var mesh in model.Meshes)
                {
                    writer.StartGeometryMesh(mesh.Name);

                    if (mesh.MaterialIndex != -1)
                    {
                        writer.CurrentMaterial = model.Materials[mesh.MaterialIndex].Name;
                    }

                    // collect sources
                    List <float>   Position    = new List <float>();
                    List <float>   Normal      = new List <float>();
                    List <float>   UV0         = new List <float>();
                    List <float>   UV1         = new List <float>();
                    List <float>   UV2         = new List <float>();
                    List <float>   UV3         = new List <float>();
                    List <float>   Color       = new List <float>();
                    List <int[]>   BoneIndices = new List <int[]>();
                    List <float[]> BoneWeights = new List <float[]>();

                    foreach (var vertex in mesh.Vertices)
                    {
                        Position.Add(vertex.Position.X); Position.Add(vertex.Position.Y); Position.Add(vertex.Position.Z);
                        Normal.Add(vertex.Normal.X); Normal.Add(vertex.Normal.Y); Normal.Add(vertex.Normal.Z);
                        UV0.Add(vertex.UV0.X); UV0.Add(vertex.UV0.Y);
                        UV1.Add(vertex.UV1.X); UV1.Add(vertex.UV1.Y);
                        UV2.Add(vertex.UV2.X); UV2.Add(vertex.UV2.Y);
                        UV3.Add(vertex.UV3.X); UV3.Add(vertex.UV3.Y);
                        Color.AddRange(new float[] { vertex.Color.X, vertex.Color.Y, vertex.Color.Z, vertex.Color.W });

                        List <int>   bIndices = new List <int>();
                        List <float> bWeights = new List <float>();
                        if (vertex.BoneWeights.X > 0)
                        {
                            bIndices.Add((int)vertex.BoneIndices.X);
                            bWeights.Add(vertex.BoneWeights.X);
                        }
                        if (vertex.BoneWeights.Y > 0)
                        {
                            bIndices.Add((int)vertex.BoneIndices.Y);
                            bWeights.Add(vertex.BoneWeights.Y);
                        }
                        if (vertex.BoneWeights.Z > 0)
                        {
                            bIndices.Add((int)vertex.BoneIndices.Z);
                            bWeights.Add(vertex.BoneWeights.Z);
                        }
                        if (vertex.BoneWeights.W > 0)
                        {
                            bIndices.Add((int)vertex.BoneIndices.W);
                            bWeights.Add(vertex.BoneWeights.W);
                        }
                        BoneIndices.Add(bIndices.ToArray());
                        BoneWeights.Add(bWeights.ToArray());
                    }

                    // write sources
                    if (mesh.HasPositions)
                    {
                        writer.WriteGeometrySource(mesh.Name, DAEWriter.VERTEX_SEMANTIC.POSITION, Position.ToArray(), mesh.Indices.ToArray());
                    }

                    if (mesh.HasNormals)
                    {
                        writer.WriteGeometrySource(mesh.Name, DAEWriter.VERTEX_SEMANTIC.NORMAL, Normal.ToArray(), mesh.Indices.ToArray());
                    }

                    if (mesh.HasColor)
                    {
                        writer.WriteGeometrySource(mesh.Name, DAEWriter.VERTEX_SEMANTIC.COLOR, Color.ToArray(), mesh.Indices.ToArray());
                    }

                    if (mesh.HasUV0)
                    {
                        writer.WriteGeometrySource(mesh.Name, DAEWriter.VERTEX_SEMANTIC.TEXCOORD, UV0.ToArray(), mesh.Indices.ToArray(), 0);
                    }

                    if (mesh.HasUV1)
                    {
                        writer.WriteGeometrySource(mesh.Name, DAEWriter.VERTEX_SEMANTIC.TEXCOORD, UV1.ToArray(), mesh.Indices.ToArray(), 1);
                    }

                    if (mesh.HasUV2)
                    {
                        writer.WriteGeometrySource(mesh.Name, DAEWriter.VERTEX_SEMANTIC.TEXCOORD, UV2.ToArray(), mesh.Indices.ToArray(), 2);
                    }

                    if (mesh.HasUV3)
                    {
                        writer.WriteGeometrySource(mesh.Name, DAEWriter.VERTEX_SEMANTIC.TEXCOORD, UV3.ToArray(), mesh.Indices.ToArray(), 3);
                    }


                    if (mesh.HasBoneWeights)
                    {
                        writer.AttachGeometryController(BoneIndices, BoneWeights);
                    }

                    writer.EndGeometryMesh();
                }
                writer.EndGeometrySection();
            }
        }
Exemplo n.º 22
0
        public void ExportIOModel(string FileName, IOModel model)
        {
            int    num      = 0;
            string filepath = Path.GetDirectoryName(FileName);
            string filename = Path.GetFileNameWithoutExtension(FileName);

            if (model.HasMeshes)
            {
                //.ply only support a sigle mesh, So export each mesh as a seperate file
                foreach (IOMesh mesh in model.Meshes)
                {
                    StringBuilder o = new StringBuilder();

                    //Using \n instead of AppendLine because it adds a white space, no text editor can see.
                    //No idea why. Opening it in a hex editor shows 0D
                    //.ply doesn't support white spaces unless it's a comment

                    o.Append("ply\n");
                    o.Append("format ascii 1.0\n");
                    o.Append("comment Created by CrossMod: https://github.com/Ploaj/CrossMod/ \n");
                    o.Append($"element vertex {mesh.Vertices.Count}\n");

                    o.Append("property float x\n" +
                             "property float y\n" +
                             "property float z\n");

                    if (mesh.HasNormals)
                    {
                        o.Append("property float nx\n" +
                                 "property float ny\n" +
                                 "property float nz\n");
                    }
                    if (mesh.HasUV0)
                    {
                        o.Append("property float s\n" +
                                 "property float t\n");
                    }
                    if (mesh.HasColor)
                    {
                        o.Append("property uchar red\n" +
                                 "property uchar green\n" +
                                 "property uchar blue\n" +
                                 "property uchar alpha\n");
                    }

                    //Divide vertex count by 3 to get triangle count
                    o.Append($"element face {mesh.Indices.Count / 3}\n");
                    o.Append("property list uchar uint vertex_indices\n");
                    o.Append("end_header\n");

                    foreach (IOVertex v in mesh.Vertices)
                    {
                        o.Append($"{v.Position.X} {v.Position.Y} {v.Position.Z}");

                        if (mesh.HasNormals)
                        {
                            o.Append($" {v.Normal.X} {v.Normal.Y} {v.Normal.Z}");
                        }

                        if (mesh.HasUV0)
                        {
                            o.Append($" {v.UV0.X} {v.UV0.Y}");
                        }

                        if (mesh.HasColor)
                        {
                            o.Append($" {v.Color.X} {v.Color.Y} {v.Color.Z} {v.Color.W}");
                        }

                        o.Append("\n");
                    }

                    for (int i = 0; i < mesh.Indices.Count; i += 3)
                    {
                        o.Append($"3 {mesh.Indices[i]} {mesh.Indices[i + 1]} {mesh.Indices[i + 2]}\n");
                    }

                    File.WriteAllText($"{filepath}\\{filename}_{num++}.ply", o.ToString());
                }
            }
        }
Exemplo n.º 23
0
        public override IOModel ImportFromFile(string filename)
        {
            var model     = new IOModel();
            var materials = new List <string>();
            var positions = new List <Vector3>();
            var textures  = new Dictionary <int, Texture>();

            using (var reader = new StreamReader(File.OpenRead(filename)))
            {
                var line = reader.ReadLine();
                if (line.Trim() != "Metasequoia Document")
                {
                    logger.Error("Not a valid Metasequoia file");
                    return(null);
                }

                while (!reader.EndOfStream)
                {
                    line = reader.ReadLine().Trim();
                    if (line == "" || line == "}")
                    {
                        continue;
                    }

                    // Parse chunks
                    var chunk = line.Split(' ')[0];
                    if (chunk == "Format")
                    {
                    }
                    else if (chunk == "Thumbnail")
                    {
                        IgnoreChunk(reader);
                    }
                    else if (chunk == "Scene")
                    {
                        IgnoreChunk(reader);
                    }
                    else if (chunk == "Material")
                    {
                        var numMaterials = int.Parse(line.Split(' ')[1]);
                        if (numMaterials == 0)
                        {
                            return(null);
                        }
                        for (var i = 0; i < numMaterials; i++)
                        {
                            var materialString = reader.ReadLine().Trim();
                            var tokensMaterial = materialString.Split(' ');
                            var material       = new IOMaterial(tokensMaterial[0]);

                            for (var j = 0; j < tokensMaterial.Length; j++)
                            {
                                var texturePath = "";
                                if (tokensMaterial[j].StartsWith("tex"))
                                {
                                    texturePath = tokensMaterial[j].Substring(5, tokensMaterial[j].Length - 7);
                                    if (texturePath != "")
                                    {
                                        string basePath = Path.GetDirectoryName(filename);
                                        if (!File.Exists(Path.Combine(basePath, texturePath)))
                                        {
                                            basePath = Path.Combine(Path.GetDirectoryName(filename), "Texture");
                                        }
                                        if (!File.Exists(Path.Combine(basePath, texturePath)))
                                        {
                                            throw new FileNotFoundException("Texture " + texturePath + " could not be found");
                                        }

                                        textures.Add(i, GetTexture(basePath, texturePath));
                                    }

                                    material.Texture = textures[i];
                                    break;
                                }
                            }

                            model.Materials.Add(material);
                        }
                    }
                    else if (chunk == "Object")
                    {
                        var name       = line.Split(' ')[1];
                        var mesh       = new IOMesh(name.Replace("\"", ""));
                        var tokensName = mesh.Name.Split('_');
                        positions = new List <Vector3>();

                        if (name.Contains("TeRoom_"))
                        {
                            model.HasMultipleRooms = true;
                        }

                        var lastVertex  = 0;
                        var translation = Vector3.Zero;

                        while (!reader.EndOfStream)
                        {
                            line = reader.ReadLine().Trim();
                            var tokens = line.Split(' ');

                            if (tokens[0] == "translation" && model.HasMultipleRooms)
                            {
                                translation = ApplyAxesTransforms(new Vector3(ParseFloatCultureInvariant(tokens[1]),
                                                                              ParseFloatCultureInvariant(tokens[2]),
                                                                              ParseFloatCultureInvariant(tokens[3])));
                            }
                            else if (tokens[0] == "vertex")
                            {
                                var numVertices = int.Parse(tokens[1]);
                                for (var i = 0; i < numVertices; i++)
                                {
                                    var tokensPosition = reader.ReadLine().Trim().Split(' ');
                                    var newPos         = ApplyAxesTransforms(new Vector3(ParseFloatCultureInvariant(tokensPosition[0]),
                                                                                         ParseFloatCultureInvariant(tokensPosition[1]),
                                                                                         ParseFloatCultureInvariant(tokensPosition[2]))
                                                                             );
                                    positions.Add(newPos);
                                }
                                line = reader.ReadLine().Trim();
                            }
                            else if (tokens[0] == "face")
                            {
                                var numFaces = int.Parse(tokens[1]);
                                for (var i = 0; i < numFaces; i++)
                                {
                                    line = reader.ReadLine().Trim();

                                    var numVerticesInFace = int.Parse(line.Substring(0, line.IndexOf(' ')));
                                    var poly = new IOPolygon(numVerticesInFace == 3 ? IOPolygonShape.Triangle : IOPolygonShape.Quad);

                                    // We MUST have vertices
                                    var stringVertices = GetSubBlock(line, "V");
                                    if (stringVertices == "")
                                    {
                                        return(null);
                                    }
                                    var tokensVertices = stringVertices.Split(' ');
                                    for (var k = 0; k < numVerticesInFace; k++)
                                    {
                                        var index = int.Parse(tokensVertices[k]);
                                        mesh.Positions.Add(positions[index]);
                                        poly.Indices.Add(lastVertex);
                                        lastVertex++;
                                    }

                                    // Change vertex winding
                                    if (_settings.InvertFaces)
                                    {
                                        poly.Indices.Reverse();
                                    }

                                    // UV
                                    var stringUV = GetSubBlock(line, "UV");
                                    if (stringUV != "")
                                    {
                                        var tokensUV = stringUV.Split(' ');
                                        for (var k = 0; k < numVerticesInFace; k++)
                                        {
                                            var uv = ApplyUVTransform(new Vector2(ParseFloatCultureInvariant(tokensUV[2 * k]),
                                                                                  ParseFloatCultureInvariant(tokensUV[2 * k + 1])),
                                                                      textures[0].Image.Width,
                                                                      textures[0].Image.Height);
                                            mesh.UV.Add(uv);
                                        }
                                    }

                                    // Colors
                                    var stringColor = GetSubBlock(line, "COL");
                                    if (stringColor != "")
                                    {
                                        var tokensColor = stringColor.Split(' ');
                                        for (var k = 0; k < numVerticesInFace; k++)
                                        {
                                            var color = ApplyColorTransform(GetColor(long.Parse(tokensColor[k])));
                                            mesh.Colors.Add(color);
                                        }
                                    }
                                    else
                                    {
                                        for (var k = 0; k < numVerticesInFace; k++)
                                        {
                                            var color = ApplyColorTransform(Vector4.One);
                                            mesh.Colors.Add(color);
                                        }
                                    }

                                    // Material index
                                    var stringMaterialIndex = GetSubBlock(line, "M");
                                    var materialIndex       = 0;
                                    if (stringMaterialIndex != "")
                                    {
                                        materialIndex = int.Parse(stringMaterialIndex);
                                    }

                                    // Add polygon to the submesh (and add submesh if not existing yet)
                                    var material = model.Materials[materialIndex];
                                    if (!mesh.Submeshes.ContainsKey(material))
                                    {
                                        mesh.Submeshes.Add(material, new IOSubmesh(material));
                                    }

                                    mesh.Submeshes[material].Polygons.Add(poly);
                                }
                                line = reader.ReadLine().Trim();
                            }
                            else if (tokens[0] == "vertexattr")
                            {
                                // section to ignore
                                IgnoreChunk(reader);
                            }
                            else if (tokens[0] == "}")
                            {
                                break;
                            }
                        }

                        model.Meshes.Add(mesh);
                    }
                }
            }

            CalculateNormals(model);

            return(model);
        }
Exemplo n.º 24
0
        public static WadAnimation ImportAnimationFromModel(WadToolClass tool, IWin32Window owner, int nodeCount, string fileName)
        {
            IOModel tmpModel = null;

            // Import the model
            try
            {
                var settings = new IOGeometrySettings()
                {
                    ProcessAnimations = true, ProcessGeometry = false
                };
                using (var form = new GeometryIOSettingsDialog(settings))
                {
                    form.AddPreset(IOSettingsPresets.AnimationSettingsPresets);
                    string resultingExtension = Path.GetExtension(fileName).ToLowerInvariant();

                    if (resultingExtension.Equals(".fbx"))
                    {
                        form.SelectPreset("3dsmax Filmbox (FBX)");
                    }
                    else if (resultingExtension.Equals(".dae"))
                    {
                        form.SelectPreset("3dsmax COLLADA");
                    }

                    if (form.ShowDialog(owner) != DialogResult.OK)
                    {
                        return(null);
                    }

                    var importer = BaseGeometryImporter.CreateForFile(fileName, settings, null);
                    tmpModel = importer.ImportFromFile(fileName);

                    // We don't support animation importing from custom-written mqo importer yet...
                    if (importer is MetasequoiaImporter)
                    {
                        tool.SendMessage("Metasequoia importer isn't currently supported.", PopupType.Error);
                        return(null);
                    }

                    // If no animations, return null
                    if (tmpModel.Animations.Count == 0)
                    {
                        tool.SendMessage("Selected file has no supported animations!", PopupType.Error);
                        return(null);
                    }
                }
            }
            catch (Exception ex)
            {
                tool.SendMessage("Unknown error while importing animation. \n" + ex?.Message, PopupType.Error);
                logger.Warn(ex, "'ImportAnimationFromModel' failed.");
                return(null);
            }

            IOAnimation animToImport;

            if (tmpModel.Animations.Count > 1)
            {
                using (var dialog = new AnimationImportDialog(tmpModel.Animations.Select(o => o.Name).ToList()))
                {
                    dialog.ShowDialog(owner);
                    if (dialog.DialogResult == DialogResult.Cancel)
                    {
                        return(null);
                    }
                    else
                    {
                        animToImport = tmpModel.Animations[dialog.AnimationToImport];
                    }
                }
            }
            else
            {
                animToImport = tmpModel.Animations[0];
            }


            // Integrity check, for cases when something totally went wrong with assimp
            if (animToImport == null)
            {
                tool.SendMessage("Animation importer encountered serious error. No animation imported.", PopupType.Error);
                return(null);
            }

            // Integrity check, is there any valid frames?
            if (animToImport.Frames.Count <= 0)
            {
                tool.SendMessage("Selected animation has no frames!", PopupType.Error);
                return(null);
            }

            // Integrity check, number of bones = number of nodes?
            if (animToImport.NumNodes != nodeCount)
            {
                tool.SendMessage("Selected animation has different number of bones!", PopupType.Error);
                return(null);
            }

            WadAnimation animation = new WadAnimation();

            animation.Name = animToImport.Name;

            foreach (var frame in animToImport.Frames)
            {
                var keyFrame = new WadKeyFrame();
                keyFrame.Offset = frame.Offset;
                frame.Angles.ForEach(angle => keyFrame.Angles.Add(new WadKeyFrameRotation()
                {
                    Rotations = angle
                }));

                animation.KeyFrames.Add(keyFrame);
            }

            animation.EndFrame = (ushort)(animToImport.Frames.Count - 1);

            return(animation);
        }
Exemplo n.º 25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="n"></param>
        /// <param name="bones"></param>
        private IOBone LoadNodes(Node n, IOBone parent, IOModel model, List <string> skeletonIds)
        {
            // create bone to represent node
            IOBone bone = new IOBone()
            {
                Name  = n.Name,
                AltID = n.sID
            };

            // load matrix
            if (n.Matrix != null && n.Matrix.Length >= 0)
            {
                bone.LocalTransform = n.Matrix[0].ToMatrix();
            }
            else
            {
                // or segmented transform
                Vector3 scale    = Vector3.One;
                Vector3 position = Vector3.Zero;
                Vector4 rx       = Vector4.UnitX;
                Vector4 ry       = Vector4.UnitY;
                Vector4 rz       = Vector4.UnitZ;

                if (n.Scale != null && n.Scale.Length > 0)
                {
                    var val = n.Scale[0].GetValues();
                    scale = new Vector3(val[0], val[1], val[2]);
                }

                if (n.Translate != null && n.Translate.Length > 0)
                {
                    var val = n.Translate[0].GetValues();
                    position = new Vector3(val[0], val[1], val[2]);
                }

                if (n.Rotate != null && n.Rotate.Length > 0)
                {
                    foreach (var r in n.Rotate)
                    {
                        var val = r.GetValues();
                        switch (r.sID)
                        {
                        case "rotationX":
                            rx = new Vector4(val[0], val[1], val[2], val[3]);
                            break;

                        case "rotationY":
                            ry = new Vector4(val[0], val[1], val[2], val[3]);
                            break;

                        case "rotationZ":
                            rz = new Vector4(val[0], val[1], val[2], val[3]);
                            break;
                        }
                    }
                }

                // create transform
                bone.LocalTransform = Matrix4x4.CreateTranslation(position) *
                                      Matrix4x4.CreateFromAxisAngle(new Vector3(rz.X, rz.Y, rz.Z), rz.W) *
                                      Matrix4x4.CreateFromAxisAngle(new Vector3(ry.X, ry.Y, ry.Z), ry.W) *
                                      Matrix4x4.CreateFromAxisAngle(new Vector3(rx.X, rx.Y, rx.Z), rx.W) *
                                      Matrix4x4.CreateScale(scale);
            }


            // add this node to parent
            if (parent != null)
            {
                parent.AddChild(bone);
            }

            // load children
            if (n.node != null)
            {
                foreach (var v in n.node)
                {
                    LoadNodes(v, bone, model, skeletonIds);
                }
            }


            // load instanced geometry
            if (n.Instance_Geometry != null)
            {
                foreach (var g in n.Instance_Geometry)
                {
                    var geom = LoadGeometryFromID(n, g.URL);
                    geom.TransformVertices(bone.WorldTransform);
                    geom.ParentBone = bone;
                    model.Meshes.Add(geom);
                }
            }

            // load instanced geometry controllers
            if (n.Instance_Controller != null)
            {
                foreach (var c in n.Instance_Controller)
                {
                    var geom = LoadGeometryControllerFromID(n, c.URL);
                    geom.TransformVertices(bone.WorldTransform);
                    geom.ParentBone = bone;
                    model.Meshes.Add(geom);
                }
            }

            // detect skeleton
            if ((!string.IsNullOrEmpty(bone.Name) && skeletonIds.Contains(bone.Name)) ||
                (n.Type == Node_Type.JOINT && parent == null) ||
                (n.Instance_Camera == null &&
                 n.Instance_Controller == null &&
                 n.Instance_Geometry == null &&
                 n.Instance_Light == null &&
                 n.Instance_Node == null &&
                 parent == null &&
                 n.node != null &&
                 n.node.Length > 0))
            {
                model.Skeleton.RootBones.Add(bone);
            }

            // complete
            return(bone);
        }
Exemplo n.º 26
0
        public override IOModel GetIOModel()
        {
            var iomodel = new IOModel();

            iomodel.Skeleton = (SBSkeleton)Skeleton;

            List <SBHsdBone> bones = new List <SBHsdBone>();

            foreach (SBHsdBone bone in Skeleton.Bones)
            {
                bones.Add(bone);
            }

            Dictionary <HSDStruct, string> tobjToName = new Dictionary <HSDStruct, string>();

            foreach (var tex in tobjToSurface)
            {
                tex.Value.Name = $"TOBJ_{iomodel.Textures.Count}";
                tobjToName.Add(tex.Key, tex.Value.Name);
                iomodel.Textures.Add(tex.Value);
            }

            foreach (SBHsdMesh me in GetMeshObjects())
            {
                var dobj = me.DOBJ;

                var parent = Skeleton.Bones[0];
                foreach (var b in Skeleton.Bones)
                {
                    if (b is SBHsdBone bone)
                    {
                        if (bone.GetJOBJ().Dobj != null)
                        {
                            if (bone.GetJOBJ().Dobj.List.Contains(dobj))
                            {
                                parent = b;
                                break;
                            }
                        }
                    }
                }

                var iomesh = new IOMesh();
                iomesh.Name = me.Name;
                iomodel.Meshes.Add(iomesh);

                iomesh.HasPositions   = true;
                iomesh.HasColor       = true;
                iomesh.HasNormals     = true;
                iomesh.HasBoneWeights = true;
                iomesh.HasUV0         = true;

                if (dobj.Pobj != null)
                {
                    foreach (var pobj in dobj.Pobj.List)
                    {
                        var dl       = pobj.ToDisplayList();
                        var vertices = GX_VertexAccessor.GetDecodedVertices(dl, pobj);

                        HSD_Envelope[] bindGroups = null;;
                        if (pobj.EnvelopeWeights != null)
                        {
                            bindGroups = pobj.EnvelopeWeights;
                        }

                        var offset = 0;
                        foreach (var v in dl.Primitives)
                        {
                            List <GX_Vertex> strip = new List <GX_Vertex>();
                            for (int i = 0; i < v.Count; i++)
                            {
                                strip.Add(vertices[offset + i]);
                            }
                            offset += v.Count;
                            iomesh.Vertices.AddRange(ConvertGXDLtoTriangleList(v.PrimitiveType, SBHsdMesh.GXVertexToHsdVertex(strip, bones, bindGroups), (SBHsdBone)parent));
                        }
                    }
                }


                iomesh.Optimize();

                // flip faces
                var temp = iomesh.Indices.ToArray();
                iomesh.Indices.Clear();
                for (int i = 0; i < temp.Length; i += 3)
                {
                    if (i + 2 < temp.Length)
                    {
                        iomesh.Indices.Add(temp[i + 2]);
                        iomesh.Indices.Add(temp[i + 1]);
                        iomesh.Indices.Add(temp[i]);
                    }
                    else
                    {
                        break;
                    }
                }

                iomesh.MaterialIndex = iomodel.Materials.Count;

                IOMaterialPhong mat = new IOMaterialPhong();
                mat.Name = iomesh.Name + "_material";
                if (dobj.Mobj.Material != null)
                {
                    mat.DiffuseColor  = dobj.Mobj.Material.DiffuseColor;
                    mat.SpecularColor = dobj.Mobj.Material.SpecularColor;
                    mat.AmbientColor  = dobj.Mobj.Material.AmbientColor;
                }
                if (dobj.Mobj.Textures != null)
                {
                    mat.DiffuseTexture = tobjToName[dobj.Mobj.Textures._s];
                }
                iomodel.Materials.Add(mat);
            }

            return(iomodel);
        }
Exemplo n.º 27
0
        public IOModel GetIOModel()
        {
            IOModel outModel = new IOModel();

            MESH meshFile = null;

            foreach (FileNode n in Parent.Nodes)
            {
                if (n.Text.Equals(_model.MeshString))
                {
                    meshFile = ((NUMSHB_Node)n).mesh;
                }
                if (n.Text.Equals(_model.SkeletonFileName))
                {
                    outModel.Skeleton = (RSkeleton)((SKEL_Node)n).GetRenderableNode();
                }
            }

            Dictionary <string, int> indexByBoneName = new Dictionary <string, int>();

            if (outModel.Skeleton != null)
            {
                for (int i = 0; i < outModel.Skeleton.Bones.Count; i++)
                {
                    indexByBoneName.Add(outModel.Skeleton.Bones[i].Name, i);
                }
            }

            if (meshFile != null)
            {
                using (SSBHVertexAccessor vertexAccessor = new SSBHVertexAccessor(meshFile))
                {
                    SSBHRiggingAccessor riggingAccessor = new SSBHRiggingAccessor(meshFile);
                    foreach (MeshObject obj in meshFile.Objects)
                    {
                        IOMesh outMesh = new IOMesh()
                        {
                            Name = obj.Name,
                        };
                        outModel.Meshes.Add(outMesh);

                        IOVertex[] vertices = new IOVertex[obj.VertexCount];
                        for (int i = 0; i < vertices.Length; i++)
                        {
                            vertices[i] = new IOVertex();
                        }

                        foreach (MeshAttribute attr in obj.Attributes)
                        {
                            SSBHVertexAttribute[] values = vertexAccessor.ReadAttribute(attr.AttributeStrings[0].Name, 0, obj.VertexCount, obj);

                            if (attr.AttributeStrings[0].Name.Equals("Position0"))
                            {
                                outMesh.HasPositions = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Position = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("Normal0"))
                            {
                                outMesh.HasNormals = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Normal = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("map1"))
                            {
                                outMesh.HasUV0 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV0 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet"))
                            {
                                outMesh.HasUV1 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV1 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet1"))
                            {
                                outMesh.HasUV2 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV2 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet2"))
                            {
                                outMesh.HasUV3 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV3 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("colorSet1"))
                            {
                                outMesh.HasColor = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Color = new OpenTK.Vector4(values[i].X, values[i].Y, values[i].Z, values[i].W);
                                }
                            }
                        }

                        // Fix SingleBinds
                        if (outModel.Skeleton != null && !obj.ParentBoneName.Equals(""))
                        {
                            int parentIndex = outModel.Skeleton.GetBoneIndex(obj.ParentBoneName);
                            if (parentIndex != -1)
                            {
                                for (int i = 0; i < vertices.Length; i++)
                                {
                                    vertices[i].Position      = OpenTK.Vector3.TransformPosition(vertices[i].Position, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].Normal        = OpenTK.Vector3.TransformNormal(vertices[i].Normal, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].BoneIndices.X = indexByBoneName[obj.ParentBoneName];
                                    vertices[i].BoneWeights.X = 1;
                                }
                            }
                        }

                        // Apply Rigging
                        SSBHVertexInfluence[] influences = riggingAccessor.ReadRiggingBuffer(obj.Name, (int)obj.SubMeshIndex);

                        foreach (SSBHVertexInfluence influence in influences)
                        {
                            // Some influences refer to bones that don't exist in the skeleton.
                            // _eff bones?
                            if (!indexByBoneName.ContainsKey(influence.BoneName))
                            {
                                continue;
                            }

                            if (vertices[influence.VertexIndex].BoneWeights.X == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.X = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.X = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Y == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Y = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Y = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Z == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Z = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Z = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.W == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.W = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.W = influence.Weight;
                            }
                        }

                        outMesh.Vertices.AddRange(vertices);
                        outMesh.Indices.AddRange(vertexAccessor.ReadIndices(0, obj.IndexCount, obj));
                    }
                }
            }


            return(outModel);
        }
Exemplo n.º 28
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public IOScene GetScene(string filePath)
        {
            IOScene scene = new IOScene();

            IOModel model = new IOModel();

            scene.Models.Add(model);

            using (FileStream stream = new FileStream(filePath, FileMode.Open))
                using (StreamReader r = new StreamReader(stream))
                {
                    Dictionary <string, IOMesh> nameToMesh  = new Dictionary <string, IOMesh>();
                    HashSet <IOBone>            meshBones   = new HashSet <IOBone>();
                    Dictionary <int, IOBone>    idxToBone   = new Dictionary <int, IOBone>();
                    Dictionary <int, int>       idxToParent = new Dictionary <int, int>();

                    string mode = "";
                    int    time = 0;

                    while (!r.EndOfStream)
                    {
                        // read and clean line args
                        var line = r.ReadLine().Trim();
                        var args = Regex.Replace(line, @"\s+", " ").Split(' ');

                        // check for grouping
                        switch (args[0])
                        {
                        case "nodes":
                        case "skeleton":
                        case "triangles":
                        case "end":
                            mode = args[0];
                            break;
                        }

                        switch (mode)
                        {
                        case "nodes":
                            if (args.Length >= 3)
                            {
                                args = line.Split('"');

                                var index       = int.Parse(args[0].Trim());
                                var name        = args[1];
                                var parentIndex = int.Parse(args[2].Trim());

                                IOBone bone = new IOBone()
                                {
                                    Name = name
                                };

                                idxToBone.Add(index, bone);
                                idxToParent.Add(index, parentIndex);
                            }
                            break;

                        case "skeleton":
                            if (args.Length == 2 && args[0] == "time")
                            {
                                int.TryParse(args[1], out time);
                            }
                            if (args.Length == 7)
                            {
                                var index = int.Parse(args[0]);

                                if (time == 0)
                                {
                                    idxToBone[index].Translation   = new System.Numerics.Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
                                    idxToBone[index].RotationEuler = new System.Numerics.Vector3(float.Parse(args[4]), float.Parse(args[5]), float.Parse(args[6]));
                                }
                            }
                            break;

                        case "triangles":
                        {
                            if (args.Length > 0 && args.Length < 9 && args[0] != "triangles")
                            {
                                var material = string.Join(" ", args);

                                var v1 = ParseVertex(r.ReadLine(), idxToBone, out IOBone parent);
                                var v2 = ParseVertex(r.ReadLine(), idxToBone, out parent);
                                var v3 = ParseVertex(r.ReadLine(), idxToBone, out parent);

                                var meshName = parent.Name + material;

                                if (!meshBones.Contains(parent))
                                {
                                    meshBones.Add(parent);
                                }

                                meshName = Regex.Replace(meshName.Trim(), @"\s+", "_").Replace("#", "");

                                if (!nameToMesh.ContainsKey(meshName))
                                {
                                    // create and load material
                                    IOMaterial mat = new IOMaterial()
                                    {
                                        Name = material
                                    };
                                    scene.Materials.Add(mat);

                                    // create io mesh
                                    var iomesh = new IOMesh()
                                    {
                                        Name = meshName
                                    };

                                    // create triangle polygon
                                    iomesh.Polygons.Add(new IOPolygon()
                                        {
                                            MaterialName  = material,
                                            PrimitiveType = IOPrimitive.TRIANGLE
                                        });

                                    nameToMesh.Add(meshName, iomesh);
                                }

                                var mesh = nameToMesh[meshName];
                                mesh.Polygons[0].Indicies.Add(mesh.Vertices.Count);
                                mesh.Polygons[0].Indicies.Add(mesh.Vertices.Count + 1);
                                mesh.Polygons[0].Indicies.Add(mesh.Vertices.Count + 2);
                                mesh.Vertices.Add(v1);
                                mesh.Vertices.Add(v2);
                                mesh.Vertices.Add(v3);
                            }
                        }
                        break;
                        }
                    }

                    // create skeleton hierarchy
                    foreach (var bone in idxToBone)
                    {
                        var parent = idxToParent[bone.Key];

                        if (parent == -1)
                        {
                            if (meshBones.Count > 1 && meshBones.Contains(bone.Value))
                            {
                                continue;
                            }
                            else
                            {
                                model.Skeleton.RootBones.Add(bone.Value);
                            }
                        }
                        else
                        {
                            idxToBone[parent].AddChild(bone.Value);
                        }
                    }

                    // dump mesh
                    model.Meshes.AddRange(nameToMesh.Values);
                }

            return(scene);
        }
Exemplo n.º 29
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public IOScene GetScene(string filePath)
        {
            // generate a new scene
            IOScene scene = new IOScene();


            // load collada file
            _collada = Collada.LoadFromFile(filePath);

            // failed to load collada file
            if (_collada == null)
            {
                return(scene);
            }

            // load material library's to scene
            if (_collada.Library_Materials != null)
            {
                foreach (var mat in _collada.Library_Materials.Material)
                {
                    scene.Materials.Add(LoadMaterial(mat));
                }
            }


            // look through all visual scene
            foreach (var colscene in _collada.Library_Visual_Scene.Visual_Scene)
            {
                // treat each scene as a "model"
                IOModel model = new IOModel()
                {
                    Name = colscene.Name
                };

                // scan skeletons
                List <string> skelIDs = new List <string>();
                foreach (var v in colscene.Node)
                {
                    if (GetSkeletonReferences(v, out List <string> joints))
                    {
                        foreach (var j in joints)
                        {
                            if (!skelIDs.Contains(j))
                            {
                                skelIDs.Add(j);
                            }
                        }
                    }
                }

                // load nodes
                foreach (var v in colscene.Node)
                {
                    LoadNodes(v, null, model, skelIDs);
                }

                // add model
                scene.Models.Add(model);
            }


            // cleanup
            _collada = null;


            // done
            return(scene);
        }
Exemplo n.º 30
0
        public override bool ExportToFile(IOModel model, string filename)
        {
            var path         = Path.GetDirectoryName(filename);
            var materialPath = path + "\\" + Path.GetFileNameWithoutExtension(filename) + ".mtl";

            using (var writer = new StreamWriter(filename, false))
            {
                writer.WriteLine("# Exported by Tomb Editor " + Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\n");
                writer.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(filename) + ".mtl" + "\n");

                // Optimize all data
                var poscol        = new List <Vector3[]>();
                var poscolIndices = new Dictionary <int, int>();

                var normals       = new List <Vector3>();
                var normalIndices = new Dictionary <int, int>();

                var uvs       = new List <Vector2>();
                var uvIndices = new Dictionary <int, int>();

                // Pack positions and colours
                int meshCount = 0;
                foreach (var mesh in model.Meshes)
                {
                    if (mesh.Positions.Count == 0)
                    {
                        continue;
                    }

                    for (int i = 0; i < mesh.Positions.Count; i++)
                    {
                        var position = ApplyAxesTransforms(mesh.Positions[i]);
                        var colour   = ApplyColorTransform(mesh.Colors.Count > i ? mesh.Colors[i] : new Vector4(2)).To3();

                        int found = -1;
                        for (int j = 0; j < poscol.Count; j++)
                        {
                            if (poscol[j][0] == position &&
                                poscol[j][1] == colour)
                            {
                                found = j;
                                break;
                            }
                        }

                        if (found == -1)
                        {
                            found = poscol.Count;
                            poscol.Add(new Vector3[2] {
                                position, colour
                            });
                        }

                        poscolIndices.Add(i + meshCount, found);
                    }
                    meshCount += mesh.Positions.Count;
                }

                // Pack normals
                meshCount = 0;
                foreach (var mesh in model.Meshes)
                {
                    if (mesh.Normals.Count == 0)
                    {
                        mesh.CalculateNormals();
                    }

                    for (int i = 0; i < mesh.Normals.Count; i++)
                    {
                        var normal = mesh.Normals[i];
                        int found  = -1;
                        for (int j = 0; j < normals.Count; j++)
                        {
                            if (normals[j] == normal)
                            {
                                found = j;
                                break;
                            }
                        }

                        if (found == -1)
                        {
                            found = normals.Count;
                            normals.Add(normal);
                        }

                        normalIndices.Add(i + meshCount, found);
                    }
                    meshCount += mesh.Normals.Count;
                }

                // Pack UV coords
                meshCount = 0;
                foreach (var mesh in model.Meshes)
                {
                    if (mesh.UV.Count == 0)
                    {
                        continue;
                    }

                    for (int i = 0; i < mesh.UV.Count; i++)
                    {
                        var uv    = mesh.UV[i];
                        int found = -1;
                        for (int j = 0; j < uvs.Count; j++)
                        {
                            if (uvs[j] == uv)
                            {
                                found = j;
                                break;
                            }
                        }

                        if (found == -1)
                        {
                            found = uvs.Count;
                            uvs.Add(uv);
                        }

                        uvIndices.Add(i + meshCount, found);
                    }
                    meshCount += mesh.UV.Count;
                }

                // Save vertices
                if (!_settings.UseVertexColor)
                {
                    foreach (var pc in poscol)
                    {
                        writer.WriteLine("v " + pc[0].X.ToString(CultureInfo.InvariantCulture) + " " +
                                         pc[0].Y.ToString(CultureInfo.InvariantCulture) + " " +
                                         pc[0].Z.ToString(CultureInfo.InvariantCulture));
                    }
                }
                else
                {
                    // Include vertex colour, it may be parsed correctly by some software, e.g. MeshMixer and MeshLab.
                    foreach (var pc in poscol)
                    {
                        writer.WriteLine("v " + pc[0].X.ToString(CultureInfo.InvariantCulture) + " " +
                                         pc[0].Y.ToString(CultureInfo.InvariantCulture) + " " +
                                         pc[0].Z.ToString(CultureInfo.InvariantCulture) + " " +
                                         pc[1].X.ToString(CultureInfo.InvariantCulture) + " " +
                                         pc[1].Y.ToString(CultureInfo.InvariantCulture) + " " +
                                         pc[1].Z.ToString(CultureInfo.InvariantCulture));
                    }
                }
                writer.WriteLine("# " + poscol.Count + " vertices total.\n");

                // Save normals
                foreach (var normal in normals)
                {
                    writer.WriteLine("vn " + normal.X.ToString(CultureInfo.InvariantCulture) + " " +
                                     normal.Y.ToString(CultureInfo.InvariantCulture) + " " +
                                     normal.Z.ToString(CultureInfo.InvariantCulture));
                }
                writer.WriteLine("# " + normals.Count + " normals total.\n");

                // Save UVs
                foreach (var uv in uvs)
                {
                    writer.WriteLine("vt " + uv.X.ToString(CultureInfo.InvariantCulture) + " " +
                                     (1.0f - uv.Y).ToString(CultureInfo.InvariantCulture) + " 0.000");
                }
                writer.WriteLine("# " + uvs.Count + " UVs total.\n");

                int pCount = 0;
                int uCount = 0;
                int nCount = 0;

                foreach (var mesh in model.Meshes)
                {
                    writer.WriteLine("o " + mesh.Name + "\n");

                    // Save faces
                    IOMaterial lastMaterial = null;
                    int        faceCount    = 0;

                    foreach (var submesh in mesh.Submeshes)
                    {
                        if (submesh.Value.Polygons.Count == 0)
                        {
                            continue;
                        }

                        if (lastMaterial == null || lastMaterial != submesh.Key)
                        {
                            lastMaterial = submesh.Key;
                            writer.WriteLine("\n" + "usemtl " + lastMaterial.Name.ToString());
                        }

                        foreach (var poly in submesh.Value.Polygons)
                        {
                            var indices = new List <int>();
                            indices.Add(poly.Indices[0]);
                            indices.Add(poly.Indices[1]);
                            indices.Add(poly.Indices[2]);
                            if (poly.Shape == IOPolygonShape.Quad)
                            {
                                indices.Add(poly.Indices[3]);
                            }

                            // Change vertex winding
                            if (_settings.InvertFaces)
                            {
                                indices.Reverse();
                            }

                            var v1 = indices[0];
                            var v2 = indices[1];
                            var v3 = indices[2];
                            var v4 = (poly.Shape == IOPolygonShape.Quad ? indices[3] : 0);

                            if (poly.Shape == IOPolygonShape.Triangle)
                            {
                                writer.WriteLine("f  " + (poscolIndices[v1 + pCount] + 1) + "/"
                                                 + (uvIndices    [v1 + uCount] + 1) + "/"
                                                 + (normalIndices[v1 + nCount] + 1) + " "
                                                 + (poscolIndices[v2 + pCount] + 1) + "/"
                                                 + (uvIndices    [v2 + uCount] + 1) + "/"
                                                 + (normalIndices[v2 + nCount] + 1) + " "
                                                 + (poscolIndices[v3 + pCount] + 1) + "/"
                                                 + (uvIndices    [v3 + uCount] + 1) + "/"
                                                 + (normalIndices[v3 + nCount] + 1));
                            }
                            else
                            {
                                writer.WriteLine("f  " + (poscolIndices[v1 + pCount] + 1) + "/"
                                                 + (uvIndices    [v1 + uCount] + 1) + "/"
                                                 + (normalIndices[v1 + nCount] + 1) + " "
                                                 + (poscolIndices[v2 + pCount] + 1) + "/"
                                                 + (uvIndices    [v2 + uCount] + 1) + "/"
                                                 + (normalIndices[v2 + nCount] + 1) + " "
                                                 + (poscolIndices[v3 + pCount] + 1) + "/"
                                                 + (uvIndices    [v3 + uCount] + 1) + "/"
                                                 + (normalIndices[v3 + nCount] + 1) + " "
                                                 + (poscolIndices[v4 + pCount] + 1) + "/"
                                                 + (uvIndices    [v4 + uCount] + 1) + "/"
                                                 + (normalIndices[v4 + nCount] + 1));
                            }
                            faceCount++;
                        }
                    }
                    pCount += mesh.Positions.Count;
                    uCount += mesh.UV.Count;
                    nCount += mesh.Normals.Count;

                    writer.WriteLine("# " + faceCount + " faces total.\n");
                }
            }

            using (var writer = new StreamWriter(materialPath, false))
            {
                writer.WriteLine("# Exported by Tomb Editor " +
                                 Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\n");

                foreach (var material in model.UsedMaterials)
                {
                    writer.WriteLine("newmtl " + material.Name);
                    writer.WriteLine("    Ka 1.000000 1.000000 1.000000");
                    writer.WriteLine("    Kd 1.000000 1.000000 1.000000");
                    writer.WriteLine("    Ni 1.000000");
                    writer.WriteLine("    Ns 10.000000");
                    writer.WriteLine("    d " + (material.AdditiveBlending ? "0.500000" : "1.000000"));
                    writer.WriteLine("    illum 2");
                    writer.WriteLine("    map_Ka " + material.TexturePath);
                    writer.WriteLine("    map_Kd " + material.TexturePath);
                    writer.WriteLine("\n");
                }
            }

            return(true);
        }