Ejemplo n.º 1
0
        static void ConvertDLPToOBJ(DLPFile dlp)
        {
            if (dlp == null)
            {
                throw new InvalidOperationException("Cannot convert a null DLP object to OBJ!");
            }

            var rootDir = Path.GetFullPath($"{Path.GetDirectoryName(dlp.FileName)}.\\..\\");

            var objPath = Path.ChangeExtension(dlp.FileName, ".obj");
            var mtlPath = Path.ChangeExtension(dlp.FileName, ".mtl");

            var obj = new StringBuilder();
            var mtl = new StringBuilder();

            obj.AppendLine($"# DLP converted to OBJ using ARTS Manager");
            obj.AppendLine($"# Source: {dlp.FileName}");
            obj.AppendLine();

            obj.AppendLine($"# Vertices: {dlp.Vertices.Count}");
            obj.AppendLine($"# Patches: {dlp.Patches.Count}");
            obj.AppendLine($"# Groups: {dlp.Groups.Count}");
            obj.AppendLine();

            obj.AppendLine($"mtllib {Path.GetFileName(mtlPath)}");
            obj.AppendLine();

            mtl.AppendLine($"# DLP7 materials");
            mtl.AppendLine();

            var vxIndex  = 0; // increases when we add a new vertex
            var minIndex = 0; // for normals/uvs

            var materialLookup = new Dictionary <string, ObjMaterial>();
            var materials      = new Dictionary <string, ObjMaterial>();

            foreach (var group in dlp.Groups)
            {
                var objF = new StringBuilder();

                var objVx = new StringBuilder();
                var objVn = new StringBuilder();
                var objVt = new StringBuilder();

                var vBuf = new Dictionary <int, int>();

                var curMtl = 0;
                var curTex = 0;

                foreach (var p in group.Patches)
                {
                    var patch = dlp.Patches[p];

                    if (patch.Stride != 1)
                    {
                        continue;
                    }
                    if ((patch.Resolution < 3) || (patch.Resolution > 4))
                    {
                        continue;
                    }

                    if ((patch.Material != curMtl) || (patch.Texture != curTex))
                    {
                        curMtl = patch.Material;
                        curTex = patch.Texture;

                        var mat = (curMtl != 0) ? dlp.Materials[curMtl - 1] : null;
                        var tex = (curTex != 0) ? dlp.Textures[curTex - 1] : null;

                        var materialName = "";

                        if ((mat != null) && (tex != null))
                        {
                            materialName = $"{mat.Name}|{tex.Name}";
                        }
                        else
                        {
                            materialName = (mat != null) ? mat.Name : (tex != null) ? tex.Name : "";
                        }

                        if (String.IsNullOrEmpty(materialName))
                        {
                            throw new InvalidOperationException("apparently this patch doesn't have any clothes on...");
                        }

                        if (!materialLookup.ContainsKey(materialName))
                        {
                            var material = new ObjMaterial(materialName);
                            var texture  = (tex != null) ? tex.Name : null;

                            var hasAlpha = false;

                            if (texture != null)
                            {
                                var tex16OPath = Path.Combine(rootDir, $"TEX16O\\{texture}.DDS");
                                var tex16APath = Path.Combine(rootDir, $"TEX16A\\{texture}.DDS");

                                var hasTex16O = File.Exists(tex16OPath);
                                var hasTex16A = File.Exists(tex16APath);

                                texture = (hasTex16O) ? tex16OPath : ((hasAlpha = hasTex16A)) ? tex16APath : $"{texture}.DDS";
                            }

                            if (mat != null)
                            {
                                material.SetComponentColor(ComponentType.Ambient, mat.Ambient);
                                material.SetComponentColor(ComponentType.Diffuse, mat.Diffuse);
                                material.SetComponentColor(ComponentType.Specular, mat.Specular);

                                //material.Specularity = mat.Shininess;
                            }

                            if (tex != null)
                            {
                                // maybe have a thing that checks if its 3ds max?
                                //material.SetComponentMap(ComponentType.Ambient, texture);
                                material.SetComponentMap(ComponentType.Diffuse, texture);

                                if (hasAlpha)
                                {
                                    material.Properties["d"]     = "0.0000";
                                    material.Properties["map_d"] = texture;
                                }
                            }

                            // compile
                            material.Save(mtl);

                            materialLookup.Add(materialName, material);
                            materials.Add(materialName, material);
                        }

                        objF.AppendLine($"usemtl {materialLookup[materialName].Name}");
                    }

                    // open face
                    objF.Append("f ");

                    for (int i = 0; i < patch.Resolution; i++)
                    {
                        var v = patch.Vertices[i];

                        int vx = v.Vertex;

                        var vt1 = v.SMap;
                        var vt2 = (-v.TMap - 1);

                        var vn = v.Normals;

                        if (!vBuf.ContainsKey(vx))
                        {
                            var vertex = dlp.Vertices[vx];

                            objVx.AppendLine($"v {vertex.X:F6} {vertex.Y:F6} {vertex.Z:F6}");

                            vBuf.Add(vx, vxIndex++);
                        }

                        // translate to index in buffer
                        vx = vBuf[vx];

                        objVt.AppendLine($"vt {vt1:F6} {vt2:F6} 1.000000");
                        objVn.AppendLine($"vn {vn.X:F6} {vn.Y:F6} {vn.Z:F6}");

                        // append face
                        objF.AppendFormat("{0}/{1}/{1} ", (vx + 1), (i + minIndex + 1));
                    }

                    minIndex += patch.Resolution;

                    // move to next face
                    objF.AppendLine();
                }

                // commit changes, move along
                obj.AppendLine($"o {group.Name}");
                obj.AppendLine(objVx.ToString());
                obj.AppendLine(objVn.ToString());
                obj.AppendLine(objVt.ToString());

                obj.AppendLine($"g {group.Name}");
                obj.AppendLine(objF.ToString());
            }

            File.WriteAllText(objPath, obj.ToString());
            File.WriteAllText(mtlPath, mtl.ToString());
        }