Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private void ProcessMesh(IOScene scene, IOMesh mesh, HSD_JOBJ rootnode)
        {
            HSD_JOBJ parent = rootnode;

            HashSet <HSD_JOBJ> nodes = new HashSet <HSD_JOBJ>();

            foreach (var j in rootnode.BreathFirstList)
            {
                nodes.Add(j);
            }


            if (mesh.ParentBone != null && _cache.NameToJOBJ.ContainsKey(mesh.ParentBone.Name))
            {
                parent = _cache.NameToJOBJ[mesh.ParentBone.Name];
            }


            HSD_DOBJ root = null;
            HSD_DOBJ prev = null;

            //var skeleton = rootnode.BreathFirstList;
            Console.WriteLine("Processing " + mesh.Name);

            bool singleBinded = mesh.Name.Contains("SINGLE");

            foreach (var poly in mesh.Polygons)
            {
                // Skip Empty Polygon
                if (poly.Indicies.Count == 0)
                {
                    continue;
                }


                // convert to triangles
                poly.ToTriangles(mesh);

                if (poly.PrimitiveType != IOPrimitive.TRIANGLE)
                {
                    continue;
                }


                // Generate DOBJ
                HSD_DOBJ dobj = new HSD_DOBJ();

                if (Settings.ImportMeshNames)
                {
                    dobj.ClassName = mesh.Name;
                }

                if (root == null)
                {
                    root = dobj;
                }
                else
                {
                    prev.Next = dobj;
                }
                prev = dobj;


                // generate material
                var material = scene.Materials.Find(e => e.Name == poly.MaterialName);

                dobj.Mobj = GenerateMaterial(material);


                Console.WriteLine(mesh.Name + " " + material?.Name);


                // reflective mobjs do not use uvs
                var hasReflection = false;

                // bump maps need tangents and bitangents
                var hasBump = false;

                // Assess needed attributes based on the material MOBJ
                if (mesh.Name.Contains("REFLECTIVE"))
                {
                    hasReflection = true;
                }
#if DEBUG
                if (Settings.MetalModel)
                {
                    hasReflection = true;
                }
#endif

                if (mesh.Name.Contains("BUMP"))
                {
                    hasBump = true;
                }

                if (dobj.Mobj.Textures != null)
                {
                    foreach (var t in dobj.Mobj.Textures.List)
                    {
                        if (t.Flags.HasFlag(TOBJ_FLAGS.COORD_REFLECTION))
                        {
                            hasReflection = true;
                        }
                        if (t.Flags.HasFlag(TOBJ_FLAGS.BUMP))
                        {
                            hasBump = true;
                        }
                    }
                }

                // assess attributes
                List <GXAttribName> Attributes = new List <GXAttribName>();

                if (mesh.HasEnvelopes() && Settings.ImportRigging && !singleBinded)
                {
                    Attributes.Add(GXAttribName.GX_VA_PNMTXIDX);

                    if (hasReflection)
                    {
                        Attributes.Add(GXAttribName.GX_VA_TEX0MTXIDX);

                        if (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 1)
                        {
                            Attributes.Add(GXAttribName.GX_VA_TEX1MTXIDX);
                        }

#if DEBUG
                        if (Settings.MetalModel && !Attributes.Contains(GXAttribName.GX_VA_TEX1MTXIDX))
                        {
                            Attributes.Add(GXAttribName.GX_VA_TEX1MTXIDX);
                        }
#endif
                    }
                }


                Attributes.Add(GXAttribName.GX_VA_POS);


                if (hasBump)
                {
                    Attributes.Add(GXAttribName.GX_VA_NBT);
                }
                else
                if (mesh.HasNormals && Settings.ImportNormals)
                {
                    Attributes.Add(GXAttribName.GX_VA_NRM);
                }


                if (mesh.HasColorSet(0) && Settings.ImportVertexColor)
                {
                    Attributes.Add(GXAttribName.GX_VA_CLR0);
                }

                if (mesh.HasColorSet(1) && Settings.ImportVertexColor)
                {
                    Attributes.Add(GXAttribName.GX_VA_CLR1);
                }


                if (mesh.HasUVSet(0) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX0);
                }

                if ((mesh.HasUVSet(1) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 1)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX1);
                }

                if ((mesh.HasUVSet(2) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 2)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX2);
                }

                if ((mesh.HasUVSet(3) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 3)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX3);
                }

                if ((mesh.HasUVSet(4) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 4)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX4);
                }

                if ((mesh.HasUVSet(5) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 5)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX5);
                }

                if ((mesh.HasUVSet(6) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 6)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX6);
                }

                if ((mesh.HasUVSet(7) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 7)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX7);
                }


                var vertices   = new List <GX_Vertex>();
                var jobjList   = new List <HSD_JOBJ[]>();
                var weightList = new List <float[]>();

                foreach (var face in poly.Indicies)
                {
                    var v = mesh.Vertices[face];

                    GX_Vertex vertex = new GX_Vertex();

                    var tkvert  = new Vector3(v.Position.X, v.Position.Y, v.Position.Z);
                    var tknrm   = new Vector3(v.Normal.X, v.Normal.Y, v.Normal.Z);
                    var tktan   = new Vector3(v.Tangent.X, v.Tangent.Y, v.Tangent.Z);
                    var tkbitan = new Vector3(v.Binormal.X, v.Binormal.Y, v.Binormal.Z);

                    var parentTransform = _cache.jobjToWorldTransform[parent].Inverted();

                    if (_cache.jobjToWorldTransform[parent] != Matrix4.Identity)
                    {
                        tkvert  = Vector3.TransformPosition(tkvert, parentTransform);
                        tknrm   = Vector3.TransformNormal(tknrm, parentTransform).Normalized();
                        tktan   = Vector3.TransformNormal(tktan, parentTransform).Normalized();
                        tkbitan = Vector3.TransformNormal(tkbitan, parentTransform).Normalized();
                    }


                    if (mesh.HasEnvelopes() && Settings.ImportRigging)
                    {
                        // create weighting lists
                        List <float>    weight = new List <float>();
                        List <HSD_JOBJ> bones  = new List <HSD_JOBJ>();

                        if (v.Envelope.Weights.Count == 0)
                        {
                            weight.Add(1);
                            bones.Add(rootnode);
                        }

                        if (v.Envelope.Weights.Count > 4)
                        {
                            throw new Exception($"Too many weights! {v.Envelope.Weights.Count} in {mesh.Name}");
                        }

                        foreach (var bw in v.Envelope.Weights)
                        {
                            // check if skeleton actually contains bone
                            if (_cache.NameToJOBJ.ContainsKey(bw.BoneName) && nodes.Contains(_cache.NameToJOBJ[bw.BoneName]))
                            {
                                // add envelope
                                bones.Add(_cache.NameToJOBJ[bw.BoneName]);
                                weight.Add(bw.Weight);

                                // indicate enveloped jobjs
                                if (!_cache.EnvelopedJOBJs.Contains(_cache.NameToJOBJ[bw.BoneName]))
                                {
                                    _cache.EnvelopedJOBJs.Add(_cache.NameToJOBJ[bw.BoneName]);
                                }
                            }
                            else
                            {
                                throw new Exception($"Bone not found \"{bw.BoneName}\" Weight: {bw.Weight} in {mesh.Name}");
                            }
                        }

                        jobjList.Add(bones.ToArray());
                        weightList.Add(weight.ToArray());

                        // invert single binds
                        if (v.Envelope.Weights.Count == 1)
                        {
                            var inv = _cache.jobjToWorldTransform[_cache.NameToJOBJ[v.Envelope.Weights[0].BoneName]].Inverted();
                            tkvert  = Vector3.TransformPosition(tkvert, inv);
                            tknrm   = Vector3.TransformNormal(tknrm, inv).Normalized();
                            tktan   = Vector3.TransformNormal(tknrm, inv).Normalized();
                            tkbitan = Vector3.TransformNormal(tknrm, inv).Normalized();
                        }
                    }

                    vertex.POS   = GXTranslator.fromVector3(tkvert);
                    vertex.NRM   = GXTranslator.fromVector3(tknrm.Normalized());
                    vertex.TAN   = GXTranslator.fromVector3(tktan);
                    vertex.BITAN = GXTranslator.fromVector3(tkbitan);

                    if (Settings.InvertNormals)
                    {
                        vertex.NRM.X   *= -1;
                        vertex.NRM.Y   *= -1;
                        vertex.NRM.Z   *= -1;
                        vertex.TAN.X   *= -1;
                        vertex.TAN.Y   *= -1;
                        vertex.TAN.Z   *= -1;
                        vertex.BITAN.X *= -1;
                        vertex.BITAN.Y *= -1;
                        vertex.BITAN.Z *= -1;
                    }

                    if (mesh.HasUVSet(0))
                    {
                        vertex.TEX0 = new GXVector2(v.UVs[0].X, v.UVs[0].Y);
                    }

                    if (mesh.HasUVSet(1))
                    {
                        vertex.TEX1 = new GXVector2(v.UVs[1].X, v.UVs[1].Y);
                    }

                    if (mesh.HasUVSet(2))
                    {
                        vertex.TEX2 = new GXVector2(v.UVs[2].X, v.UVs[2].Y);
                    }

                    if (mesh.HasUVSet(3))
                    {
                        vertex.TEX3 = new GXVector2(v.UVs[3].X, v.UVs[3].Y);
                    }

                    if (mesh.HasUVSet(4))
                    {
                        vertex.TEX4 = new GXVector2(v.UVs[4].X, v.UVs[4].Y);
                    }

                    if (mesh.HasUVSet(5))
                    {
                        vertex.TEX5 = new GXVector2(v.UVs[5].X, v.UVs[5].Y);
                    }

                    if (mesh.HasUVSet(6))
                    {
                        vertex.TEX6 = new GXVector2(v.UVs[6].X, v.UVs[6].Y);
                    }

                    if (mesh.HasUVSet(7))
                    {
                        vertex.TEX7 = new GXVector2(v.UVs[7].X, v.UVs[7].Y);
                    }

                    if (mesh.HasColorSet(0))
                    {
                        vertex.CLR0 = new GXColor4(
                            v.Colors[0].X * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[0].Y * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[0].Z * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            Settings.ImportVertexAlpha ? v.Colors[0].W : 1);
                    }

                    if (mesh.HasColorSet(1))
                    {
                        vertex.CLR1 = new GXColor4(
                            v.Colors[1].X * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[1].Y * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[1].Z * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            Settings.ImportVertexAlpha ? v.Colors[1].W : 1);
                    }

                    vertices.Add(vertex);
                }


                // generate pobjs
                HSD_POBJ pobj = null;

                if (mesh.HasEnvelopes() && Settings.ImportRigging && !singleBinded)
                {
                    pobj = _cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), jobjList, weightList);
                }
                else
                {
                    pobj = _cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), null);
                }

                if (singleBinded && jobjList.Count > 0 && jobjList[0].Length > 0)
                {
                    parent = jobjList[0][0];
                }

                if (pobj != null)
                {
                    if (dobj.Pobj == null)
                    {
                        dobj.Pobj = pobj;
                    }
                    else
                    {
                        dobj.Pobj.Add(pobj);
                    }
                }
            }

            if (parent.Dobj == null)
            {
                parent.Dobj = root;
            }
            else
            {
                parent.Dobj.Add(root);
            }
        }