Esempio n. 1
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();
            }
        }
        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;
                }
            }
        }
        public static void Unserialize(GR2Reader reader, Vertex v)
        {
            var d = v.Format;

            if (d.HasPosition)
            {
                v.Position = ReadVector3(reader);
            }

            if (d.HasBoneWeights)
            {
                if (d.NumBoneInfluences == 2)
                {
                    v.BoneWeights = ReadInfluences2(reader);
                    v.BoneIndices = ReadInfluences2(reader);
                }
                else
                {
                    v.BoneWeights = ReadInfluences(reader);
                    v.BoneIndices = ReadInfluences(reader);
                }
            }

            switch (d.NormalType)
            {
            case NormalType.None: break;

            case NormalType.Float3: v.Normal = ReadVector3(reader); break;

            case NormalType.Half4: v.Normal = ReadHalfVector4As3(reader); break;

            case NormalType.QTangent:
            {
                var qTangent = ReadQTangent(reader);
                v.Normal   = qTangent.Row2;
                v.Tangent  = qTangent.Row1;
                v.Binormal = qTangent.Row0;
                break;
            }
            }

            switch (d.TangentType)
            {
            case NormalType.None: break;

            case NormalType.Float3: v.Tangent = ReadVector3(reader); break;

            case NormalType.Half4: v.Tangent = ReadHalfVector4As3(reader); break;

            case NormalType.QTangent: break;     // Tangent read from QTangent
            }

            switch (d.BinormalType)
            {
            case NormalType.None: break;

            case NormalType.Float3: v.Binormal = ReadVector3(reader); break;

            case NormalType.Half4: v.Binormal = ReadHalfVector4As3(reader); break;

            case NormalType.QTangent: break;     // Binormal read from QTangent
            }

            if (d.ColorMaps > 0)
            {
                for (var i = 0; i < d.ColorMaps; i++)
                {
                    Vector4 color;
                    switch (d.ColorMapType)
                    {
                    case ColorMapType.Float4: color = ReadVector4(reader); break;

                    case ColorMapType.Byte4: color = ReadNormalByteVector4(reader); break;

                    default: throw new Exception($"Cannot unserialize color map: Unsupported format {d.ColorMapType}");
                    }

                    v.SetColor(i, color);
                }
            }

            if (d.TextureCoordinates > 0)
            {
                for (var i = 0; i < d.TextureCoordinates; i++)
                {
                    Vector2 uv;
                    switch (d.TextureCoordinateType)
                    {
                    case TextureCoordinateType.Float2: uv = ReadVector2(reader); break;

                    case TextureCoordinateType.Half2: uv = ReadHalfVector2(reader); break;

                    default: throw new Exception($"Cannot unserialize UV map: Unsupported format {d.TextureCoordinateType}");
                    }

                    v.SetUV(i, uv);
                }
            }
        }