示例#1
0
        static void XwParseOpt(OptFile opt, int meshIndex, Face face, out XwVector outNormal, out double outAngle, out double outAngleSum)
        {
            var verticesVertex = new List <XwVector>(face.VerticesCount);
            var verticesLength = new List <double>(face.VerticesCount);
            var verticesAngle  = new List <double>(face.VerticesCount);

            for (int index = 0; index < face.VerticesCount; index++)
            {
                int      index2 = XwOptGetVertexIndex(index + 1, face.VerticesCount);
                XwVector v1     = new XwVector(opt.Meshes[meshIndex].Vertices[face.VerticesIndex.AtIndex(index)]);
                XwVector v0     = new XwVector(opt.Meshes[meshIndex].Vertices[face.VerticesIndex.AtIndex(index2)]);

                XwVector v = XwVector.Substract(v1, v0);

                verticesVertex.Add(v);
                verticesLength.Add(v.Length());
            }

            outAngleSum = 0.0;

            for (int index = 0; index < face.VerticesCount; index++)
            {
                int    index2 = XwOptGetVertexIndex(index - 1, face.VerticesCount);
                double angle  = XwVector.AngleRadianToDegree(XwVector.Angle(verticesVertex[index2], verticesVertex[index]));

                verticesAngle.Add(angle);
                outAngleSum += angle;
            }

            int maxLengthVertexIndex = 0;

            for (int index = 1; index < face.VerticesCount; index++)
            {
                if (verticesLength[maxLengthVertexIndex] < verticesLength[index])
                {
                    maxLengthVertexIndex = index;
                }
            }

            if (verticesLength[XwOptGetVertexIndex(maxLengthVertexIndex - 1, face.VerticesCount)] < verticesLength[XwOptGetVertexIndex(maxLengthVertexIndex + 1, face.VerticesCount)])
            {
                maxLengthVertexIndex = XwOptGetVertexIndex(maxLengthVertexIndex + 1, face.VerticesCount);
            }

            XwVector crossV0 = XwVector.Multiply(verticesVertex[XwOptGetVertexIndex(maxLengthVertexIndex - 1, face.VerticesCount)], -1.0);
            XwVector crossV1 = verticesVertex[maxLengthVertexIndex];
            XwVector normal  = XwVector.NormalizeAndMultiply(XwVector.CrossProduct(crossV0, crossV1), 1.0);

            XwVector ebpC8 = new XwVector(0.0, 0.0, 0.0);
            XwVector ebpD4 = new XwVector(0.0, 0.0, 0.0);
            XwVector ebpE0 = new XwVector(0.0, 0.0, 0.0);
            XwVector ebpEC = new XwVector(0.0, 0.0, 0.0);

            if (face.VerticesCount == 4)
            {
                maxLengthVertexIndex = XwOptGetVertexIndex(maxLengthVertexIndex + 2, face.VerticesCount);
                int index2 = XwOptGetVertexIndex(maxLengthVertexIndex - 1, face.VerticesCount);

                ebpC8 = XwVector.Multiply(verticesVertex[index2], -1.0);
                ebpD4 = verticesVertex[maxLengthVertexIndex];
                ebpE0 = XwVector.NormalizeAndMultiply(XwVector.CrossProduct(ebpC8, ebpD4), 1.0);
                ebpEC = XwVector.NormalizeAndMultiply(XwVector.Add(normal, ebpE0), 1.0);
            }

            outAngle  = XwVector.AngleRadianToDegree(XwVector.Angle(normal, new XwVector(face.Normal)));
            outNormal = normal;
        }
示例#2
0
        static void XwOptComputing(OptFile opt, int selectedMeshIndex, double threshold)
        {
            int meshStart;
            int meshEnd;

            if (selectedMeshIndex < 0)
            {
                meshStart = 0;
                meshEnd   = opt.Meshes.Count;
            }
            else
            {
                meshStart = selectedMeshIndex;
                meshEnd   = meshStart + 1;

                if (meshStart >= opt.Meshes.Count)
                {
                    return;
                }
            }

            var ebp94             = new List <XwVector>();
            var ebp98_vertexIndex = new List <int>();
            var ebp9C_edgesIndex  = new List <Tuple <int, int> >();

            var ebpC8 = new List <List <Tuple <Face, Index, int> > >(); // face, vertexIndex, meshIndex

            int maxLodsCount = opt.Meshes
                               .Skip(meshStart)
                               .Take(meshEnd - meshStart)
                               .Max(t => t.Lods.Count);

            for (int i = 0; i < maxLodsCount; i++)
            {
                ebpC8.Add(new List <Tuple <Face, Index, int> >());
            }

            for (int meshIndex = meshStart; meshIndex < meshEnd; meshIndex++)
            {
                var mesh = opt.Meshes[meshIndex];

                ebp94.Clear();
                ebp98_vertexIndex.Clear();

                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    ebp98_vertexIndex.Add(-1);
                }

                for (int lodIndex = 0; lodIndex < mesh.Lods.Count; lodIndex++)
                {
                    var lod = mesh.Lods[lodIndex];

                    for (int faceGroupIndex = 0; faceGroupIndex < lod.FaceGroups.Count; faceGroupIndex++)
                    {
                        ebp9C_edgesIndex.Clear();

                        var faceGroup = lod.FaceGroups[faceGroupIndex];

                        ebp9C_edgesIndex.Clear();

                        for (int faceIndex = 0; faceIndex < faceGroup.Faces.Count; faceIndex++)
                        {
                            var face = faceGroup.Faces[faceIndex];

                            var faceTuple = Tuple.Create(face, Index.Empty, meshIndex);
                            ebpC8[lodIndex].Add(faceTuple);

                            XwVector normal;
                            double   angle;
                            double   angleSum;
                            XwParseOpt(opt, meshIndex, face, out normal, out angle, out angleSum);

                            // TODO
                            face.Normal = normal.ToOptVector();

                            Index item2 = Index.Empty;
                            Index vertexNormalsIndex = Index.Empty;

                            for (int vertexIndex = 0; vertexIndex < faceTuple.Item1.VerticesCount; vertexIndex++)
                            {
                                int ebp18 = faceTuple.Item1.VerticesIndex.AtIndex(vertexIndex);

                                if (ebp98_vertexIndex[ebp18] == -1)
                                {
                                    ebp98_vertexIndex[ebp18] = XwVectorsFindOrAdd(mesh.Vertices[ebp18], ebp94);
                                }

                                item2 = item2.SetAtIndex(vertexIndex, ebp98_vertexIndex[ebp18]);
                                vertexNormalsIndex = vertexNormalsIndex.SetAtIndex(vertexIndex, -1);
                            }

                            faceTuple = Tuple.Create(faceTuple.Item1, item2, faceTuple.Item3);
                            ebpC8[lodIndex][ebpC8[lodIndex].Count - 1] = faceTuple;

                            faceTuple.Item1.VertexNormalsIndex = vertexNormalsIndex;

                            Index edgesIndex = Index.Empty;

                            for (int vertexIndex = 0; vertexIndex < faceTuple.Item1.VerticesCount; vertexIndex++)
                            {
                                int ebp18;

                                if (faceTuple.Item1.VerticesCount - 1 == vertexIndex)
                                {
                                    ebp18 = 0;
                                }
                                else
                                {
                                    ebp18 = vertexIndex + 1;
                                }

                                Tuple <int, int> ebpDC = Tuple.Create(
                                    faceTuple.Item1.VerticesIndex.AtIndex(vertexIndex),
                                    faceTuple.Item1.VerticesIndex.AtIndex(ebp18));

                                edgesIndex = edgesIndex.SetAtIndex(vertexIndex, XwSetsFindOrAdd(ebpDC, ebp9C_edgesIndex));
                            }

                            faceTuple.Item1.EdgesIndex = edgesIndex;
                        }
                    }
                }

                mesh.VertexNormals.Clear();
            }

            for (int lodIndex = 0; lodIndex < maxLodsCount; lodIndex++)
            {
                for (int faceIndex = 0; faceIndex < ebpC8[lodIndex].Count; faceIndex++)
                {
                    var faceTuple = ebpC8[lodIndex][faceIndex];

                    Index vertexNormalsIndex = Index.Empty;

                    for (int vertexIndex = 0; vertexIndex < faceTuple.Item1.VerticesCount; vertexIndex++)
                    {
                        int index = faceTuple.Item2.AtIndex(vertexIndex);

                        XwVector normalSum = new XwVector(faceTuple.Item1.Normal);

                        for (int faceIndex2 = 0; faceIndex2 < ebpC8[lodIndex].Count; faceIndex2++)
                        {
                            if (faceIndex2 == faceIndex)
                            {
                                continue;
                            }

                            var faceTuple2 = ebpC8[lodIndex][faceIndex2];

                            for (int vertexIndex2 = 0; vertexIndex2 < faceTuple2.Item1.VerticesCount; vertexIndex2++)
                            {
                                if (faceTuple2.Item2.AtIndex(vertexIndex2) == index)
                                {
                                    double angle = XwVector.Angle(new XwVector(faceTuple.Item1.Normal), new XwVector(faceTuple2.Item1.Normal));

                                    if (XwVector.AngleRadianToDegree(angle) <= threshold)
                                    {
                                        normalSum = XwVector.Add(normalSum, new XwVector(faceTuple2.Item1.Normal));
                                    }
                                }
                            }
                        }

                        XwVector normal = XwVector.NormalizeAndMultiply(normalSum, 1.0);
                        vertexNormalsIndex = vertexNormalsIndex.SetAtIndex(vertexIndex, XwVectorsFindOrAdd(normal, opt.Meshes[faceTuple.Item3].VertexNormals));
                    }

                    faceTuple.Item1.VertexNormalsIndex = vertexNormalsIndex;
                }
            }
        }