Exemplo n.º 1
0
        private void SaveDAE(Root root, ExporterOptions options)
        {
            var exporter = new ColladaExporter();

            exporter.Options = options;
            exporter.Export(root, options.OutputPath);
        }
Exemplo n.º 2
0
        private void Save(Root root, ExporterOptions options)
        {
            switch (options.OutputFormat)
            {
            case ExportFormat.GR2:
                FileManager.TryToCreateDirectory(options.OutputPath);
                SaveGR2(options.OutputPath, root);
                break;

            case ExportFormat.DAE:
                SaveDAE(root, options);
                break;

            default:
                throw new NotImplementedException("Unsupported output format");
            }
        }
Exemplo n.º 3
0
        public mesh ExportToCollada(ExporterOptions options)
        {
            // TODO: model transform/inverse transform?

            source vertexSource = null;
            var    sources      = new List <source>();
            ulong  inputOffset  = 0;
            var    inputs       = new List <InputLocal>();
            var    inputOffsets = new List <InputLocalOffset>();

            foreach (var component in PrimaryVertexData.VertexComponentNames)
            {
                var    input  = new InputLocal();
                source source = null;
                switch (component.String)
                {
                case "Position":
                {
                    source         = PrimaryVertexData.MakeColladaPositions(Name);
                    vertexSource   = source;
                    input.semantic = "POSITION";

                    var vertexInputOff = new InputLocalOffset();
                    vertexInputOff.semantic = "VERTEX";
                    vertexInputOff.source   = "#" + source.id;
                    vertexInputOff.offset   = inputOffset++;
                    inputOffsets.Add(vertexInputOff);
                    break;
                }

                case "Normal":
                {
                    if (options.ExportNormals)
                    {
                        source         = PrimaryVertexData.MakeColladaNormals(Name);
                        input.semantic = "NORMAL";
                    }
                    break;
                }

                case "Tangent":
                {
                    if (options.ExportTangents)
                    {
                        source         = PrimaryVertexData.MakeColladaTangents(Name);
                        input.semantic = "TANGENT";
                    }
                    break;
                }

                case "Binormal":
                {
                    if (options.ExportTangents)
                    {
                        source         = PrimaryVertexData.MakeColladaBinormals(Name);
                        input.semantic = "BINORMAL";
                    }
                    break;
                }

                case "MaxChannel_1":
                case "MaxChannel_2":
                case "UVChannel_1":
                case "UVChannel_2":
                {
                    if (options.ExportUVs)
                    {
                        int uvIndex = Int32.Parse(component.String.Substring(11)) - 1;
                        source = PrimaryVertexData.MakeColladaUVs(Name, uvIndex);

                        var texInputOff = new InputLocalOffset();
                        texInputOff.semantic = "TEXCOORD";
                        texInputOff.source   = "#" + source.id;
                        texInputOff.offset   = inputOffset++;
                        inputOffsets.Add(texInputOff);
                    }
                    break;
                }

                case "BoneWeights":
                case "BoneIndices":
                    // These are handled in ExportSkin()
                    break;

                case "DiffuseColor0":
                case "map1":     // Possibly bogus D:OS name for DiffuseColor0
                    // TODO: This is not exported at the moment.
                    break;

                default:
                    throw new NotImplementedException("Vertex component not supported: " + component.String);
                }

                if (source != null)
                {
                    sources.Add(source);
                }

                if (input.semantic != null)
                {
                    input.source = "#" + source.id;
                    inputs.Add(input);
                }
            }

            var triangles = PrimaryTopology.MakeColladaTriangles(
                inputOffsets.ToArray(),
                PrimaryVertexData.Deduplicator.VertexDeduplicationMap,
                PrimaryVertexData.Deduplicator.UVDeduplicationMaps
                );

            var colladaMesh = new mesh();

            colladaMesh.vertices       = new vertices();
            colladaMesh.vertices.id    = Name + "-vertices";
            colladaMesh.vertices.input = inputs.ToArray();
            colladaMesh.source         = sources.ToArray();
            colladaMesh.Items          = new object[] { triangles };

            return(colladaMesh);
        }
Exemplo n.º 4
0
        public void ImportFromCollada(mesh mesh, VertexDescriptor vertexFormat, bool isSkinned, ExporterOptions options)
        {
            Options = options;
            Mesh    = mesh;
            ImportSources();
            ImportFaces();

            if (vertexFormat == null)
            {
                vertexFormat = FindVertexFormat(isSkinned);
            }

            InputVertexType  = vertexFormat;
            OutputVertexType = new VertexDescriptor
            {
                HasPosition           = InputVertexType.HasPosition,
                HasBoneWeights        = InputVertexType.HasBoneWeights,
                NumBoneInfluences     = InputVertexType.NumBoneInfluences,
                NormalType            = InputVertexType.NormalType,
                TangentType           = InputVertexType.TangentType,
                BinormalType          = InputVertexType.BinormalType,
                ColorMapType          = InputVertexType.ColorMapType,
                ColorMaps             = InputVertexType.ColorMaps,
                TextureCoordinateType = InputVertexType.TextureCoordinateType,
                TextureCoordinates    = InputVertexType.TextureCoordinates
            };

            ImportVertices();

            // TODO: This should be done before deduplication!
            // TODO: Move this to somewhere else ... ?
            if (!HasNormals || Options.RecalculateNormals)
            {
                if (!HasNormals)
                {
                    Utils.Info(String.Format("Channel 'NORMAL' not found, will rebuild vertex normals after import."));
                }

                HasNormals = true;
                OutputVertexType.NormalType = NormalType.Float3;
                computeNormals();
            }

            ImportColors();
            ImportUVs();

            if (UVInputIndices.Count() > 0 || ColorInputIndices.Count() > 0 ||
                NormalsInputIndex != -1 || TangentsInputIndex != -1 || BinormalsInputIndex != -1)
            {
                var outVertexIndices = new Dictionary <int[], int>(new VertexIndexComparer());
                ConsolidatedIndices  = new List <int>(TriangleCount * 3);
                ConsolidatedVertices = new List <Vertex>(Vertices.Count);
                OriginalToConsolidatedVertexIndexMap = new Dictionary <int, List <int> >();
                for (var vert = 0; vert < TriangleCount * 3; vert++)
                {
                    var index = new int[InputOffsetCount];
                    for (var i = 0; i < InputOffsetCount; i++)
                    {
                        index[i] = Indices[vert * InputOffsetCount + i];
                    }

                    int consolidatedIndex;
                    if (!outVertexIndices.TryGetValue(index, out consolidatedIndex))
                    {
                        var vertexIndex = index[VertexInputIndex];
                        consolidatedIndex = ConsolidatedVertices.Count;
                        Vertex vertex = Vertices[vertexIndex].Clone();
                        if (NormalsInputIndex != -1)
                        {
                            vertex.Normal = Normals[index[NormalsInputIndex]];
                        }
                        if (TangentsInputIndex != -1)
                        {
                            vertex.Tangent = Tangents[index[TangentsInputIndex]];
                        }
                        if (BinormalsInputIndex != -1)
                        {
                            vertex.Binormal = Binormals[index[BinormalsInputIndex]];
                        }
                        for (int uv = 0; uv < UVInputIndices.Count(); uv++)
                        {
                            vertex.SetUV(uv, UVs[uv][index[UVInputIndices[uv]]]);
                        }
                        for (int color = 0; color < ColorInputIndices.Count(); color++)
                        {
                            vertex.SetColor(color, Colors[color][index[ColorInputIndices[color]]]);
                        }
                        outVertexIndices.Add(index, consolidatedIndex);
                        ConsolidatedVertices.Add(vertex);

                        List <int> mappedIndices = null;
                        if (!OriginalToConsolidatedVertexIndexMap.TryGetValue(vertexIndex, out mappedIndices))
                        {
                            mappedIndices = new List <int>();
                            OriginalToConsolidatedVertexIndexMap.Add(vertexIndex, mappedIndices);
                        }

                        mappedIndices.Add(consolidatedIndex);
                    }

                    ConsolidatedIndices.Add(consolidatedIndex);
                }

                Utils.Info(String.Format("Merged {0} vertices into {1} output vertices", Vertices.Count, ConsolidatedVertices.Count));
            }
            else
            {
                Utils.Info(String.Format("Mesh has no separate normals, colors or UV map, vertex consolidation step skipped."));

                ConsolidatedVertices = Vertices;

                ConsolidatedIndices = new List <int>(TriangleCount * 3);
                for (var vert = 0; vert < TriangleCount * 3; vert++)
                {
                    ConsolidatedIndices.Add(VertexIndex(vert));
                }

                OriginalToConsolidatedVertexIndexMap = new Dictionary <int, List <int> >();
                for (var i = 0; i < Vertices.Count; i++)
                {
                    OriginalToConsolidatedVertexIndexMap.Add(i, new List <int> {
                        i
                    });
                }
            }

            if ((InputVertexType.TangentType == NormalType.None ||
                 InputVertexType.BinormalType == NormalType.None) &&
                ((!HasTangents && UVs.Count > 0) || Options.RecalculateTangents))
            {
                if (!HasTangents)
                {
                    Utils.Info(String.Format("Channel 'TANGENT'/'BINROMAL' not found, will rebuild vertex tangents after import."));
                }

                OutputVertexType.TangentType  = NormalType.Float3;
                OutputVertexType.BinormalType = NormalType.Float3;
                HasTangents = true;
                computeTangents();
            }

            // Use optimized tangent, texture map and color map format when exporting for D:OS 2
            if ((Options.ModelInfoFormat == DivinityModelInfoFormat.LSMv0 ||
                 Options.ModelInfoFormat == DivinityModelInfoFormat.LSMv1) &&
                HasNormals &&
                HasTangents)
            {
                OutputVertexType.NormalType   = NormalType.QTangent;
                OutputVertexType.TangentType  = NormalType.QTangent;
                OutputVertexType.BinormalType = NormalType.QTangent;

                if (OutputVertexType.TextureCoordinateType == TextureCoordinateType.Float2)
                {
                    OutputVertexType.TextureCoordinateType = TextureCoordinateType.Half2;
                }

                if (OutputVertexType.ColorMapType == ColorMapType.Float4)
                {
                    OutputVertexType.ColorMapType = ColorMapType.Byte4;
                }
            }
        }
Exemplo n.º 5
0
        public void ImportFromCollada(mesh mesh, string vertexFormat, bool isSkinned, ExporterOptions options)
        {
            Options = options;
            Mesh    = mesh;
            ImportSources();
            ImportFaces();

            if (vertexFormat == null)
            {
                vertexFormat = FindVertexFormat(isSkinned);
            }

            VertexType = VertexFormatRegistry.Resolve(vertexFormat);
            ImportVertices();

            // TODO: This should be done before deduplication!
            // TODO: Move this to somewhere else ... ?
            if (!HasNormals || Options.RecalculateNormals)
            {
                if (!HasNormals)
                {
                    Utils.Info(String.Format("Channel 'NORMAL' not found, will rebuild vertex normals after import."));
                }
                computeNormals();
            }

            ImportColors();
            ImportUVs();
            if (UVInputIndices.Count() > 0 || ColorInputIndices.Count() > 0)
            {
                var outVertexIndices = new Dictionary <int[], int>(new VertexIndexComparer());
                ConsolidatedIndices  = new List <int>(TriangleCount * 3);
                ConsolidatedVertices = new List <Vertex>(Vertices.Count);
                OriginalToConsolidatedVertexIndexMap = new Dictionary <int, List <int> >();
                for (var vert = 0; vert < TriangleCount * 3; vert++)
                {
                    var index = new int[InputOffsetCount];
                    for (var i = 0; i < InputOffsetCount; i++)
                    {
                        index[i] = Indices[vert * InputOffsetCount + i];
                    }

                    int consolidatedIndex;
                    if (!outVertexIndices.TryGetValue(index, out consolidatedIndex))
                    {
                        var vertexIndex = index[VertexInputIndex];
                        consolidatedIndex = ConsolidatedVertices.Count;
                        Vertex vertex = Vertices[vertexIndex].Clone();
                        for (int uv = 0; uv < UVInputIndices.Count(); uv++)
                        {
                            vertex.SetUV(uv, UVs[uv][index[UVInputIndices[uv]]]);
                        }
                        for (int color = 0; color < ColorInputIndices.Count(); color++)
                        {
                            vertex.SetColor(color, Colors[color][index[ColorInputIndices[color]]]);
                        }
                        outVertexIndices.Add(index, consolidatedIndex);
                        ConsolidatedVertices.Add(vertex);

                        List <int> mappedIndices = null;
                        if (!OriginalToConsolidatedVertexIndexMap.TryGetValue(vertexIndex, out mappedIndices))
                        {
                            mappedIndices = new List <int>();
                            OriginalToConsolidatedVertexIndexMap.Add(vertexIndex, mappedIndices);
                        }

                        mappedIndices.Add(consolidatedIndex);
                    }

                    ConsolidatedIndices.Add(consolidatedIndex);
                }

                Utils.Info(String.Format("Merged {0} vertices into {1} output vertices", Vertices.Count, ConsolidatedVertices.Count));
            }
            else
            {
                Utils.Info(String.Format("Mesh has no UV map, vertex consolidation step skipped."));

                ConsolidatedVertices = Vertices;

                ConsolidatedIndices = new List <int>(TriangleCount * 3);
                for (var vert = 0; vert < TriangleCount * 3; vert++)
                {
                    ConsolidatedIndices.Add(VertexIndex(vert));
                }

                OriginalToConsolidatedVertexIndexMap = new Dictionary <int, List <int> >();
                for (var i = 0; i < Vertices.Count; i++)
                {
                    OriginalToConsolidatedVertexIndexMap.Add(i, new List <int> {
                        i
                    });
                }
            }

            var description = Vertex.Description(VertexType);

            if ((description.Tangent && description.Binormal) && (!HasTangents || Options.RecalculateTangents))
            {
                if (!HasTangents)
                {
                    Utils.Info(String.Format("Channel 'TANGENT'/'BINROMAL' not found, will rebuild vertex tangents after import."));
                }
                computeTangents();
            }
        }
Exemplo n.º 6
0
 public ColladaMeshExporter(Mesh mesh, ExporterOptions options)
 {
     ExportedMesh = mesh;
     Options      = options;
 }
Exemplo n.º 7
0
        private void UpdateCommonExporterSettings(ExporterOptions settings)
        {
            var game = GetGame();
            if (game == DivGame.DOS)
            {
                settings.Is64Bit = false;
                settings.AlternateSignature = false;
                settings.VersionTag = Header.Tag_DOS;
            }
            else
            {
                settings.Is64Bit = true;
                settings.AlternateSignature = true;
                settings.VersionTag = Header.Tag_DOSEE;
            }

            settings.ExportNormals = exportNormals.Checked;
            settings.ExportTangents = exportTangents.Checked;
            settings.ExportUVs = exportUVs.Checked;
            settings.RecalculateNormals = recalculateNormals.Checked;
            settings.RecalculateTangents = recalculateTangents.Checked;
            settings.RecalculateIWT = recalculateJointIWT.Checked;
            settings.BuildDummySkeleton = buildDummySkeleton.Checked;
            settings.CompactIndices = use16bitIndex.Checked;
            settings.DeduplicateVertices = deduplicateVertices.Checked;
            settings.DeduplicateUVs = filterUVs.Checked;
            settings.ApplyBasisTransforms = applyBasisTransforms.Checked;
            settings.UseObsoleteVersionTag = forceLegacyVersion.Checked;

            if (conformToOriginal.Checked && conformantGR2Path.Text.Length > 0)
            {
                settings.ConformGR2Path = conformantGR2Path.Text;
            }
            else
            {
                settings.ConformGR2Path = null;
            }
        }
Exemplo n.º 8
0
        private void UpdateExporterSettings(ExporterOptions settings)
        {
            UpdateCommonExporterSettings(settings);

            settings.InputPath = inputPath.Text;
            if (settings.InputPath.Substring(settings.InputPath.Length - 4).ToLower() == ".gr2")
            {
                settings.InputFormat = ExportFormat.GR2;
            }
            else
            {
                settings.InputFormat = ExportFormat.DAE;
            }

            settings.OutputPath = outputPath.Text;
            if (settings.OutputPath.Substring(settings.OutputPath.Length - 4).ToLower() == ".gr2")
            {
                settings.OutputFormat = ExportFormat.GR2;
            }
            else
            {
                settings.OutputFormat = ExportFormat.DAE;
            }

            foreach (var item in resourceFormats.Items)
            {
                var setting = item as ListViewItem;
                var name = setting.SubItems[0].Text;
                var type = setting.SubItems[1].Text;
                var value = setting.SubItems[2].Text;
                if (type == "Mesh" && value != "Automatic")
                {
                    settings.VertexFormats.Add(name, value);
                }
            }
        }