示例#1
0
        public void CopyNearestNormals(object[] srcMeshes, object[] srcSubmeshes, object[] dstMeshes, object[] dstSubmeshes, sviexParser dstParser, double nearVertexThreshold, bool nearestNormal, bool automatic)
        {
            xxFrame[]           srcMeshArr = Utility.Convert <xxFrame>(srcMeshes);
            double[]            srcSubmeshDoubleIndices = Utility.Convert <double>(srcSubmeshes);
            HashSet <xxSubmesh> srcSubmeshSet           = new HashSet <xxSubmesh>();
            int srcSubmeshIdxIdx  = 0;
            int srcTotalSubmeshes = 0;

            foreach (xxFrame meshFrame in srcMeshArr)
            {
                int numSubmeshes = (int)srcSubmeshDoubleIndices[srcSubmeshIdxIdx++];
                srcTotalSubmeshes += numSubmeshes;
                for (int i = 0; i < numSubmeshes; i++)
                {
                    int srcSubmeshIdx = (int)srcSubmeshDoubleIndices[srcSubmeshIdxIdx++];
                    foreach (sviParser section in SortedParser.sections)
                    {
                        if (section.meshName == meshFrame.Name && section.submeshIdx == srcSubmeshIdx)
                        {
                            xxSubmesh submesh = meshFrame.Mesh.SubmeshList[srcSubmeshIdx];
                            srcSubmeshSet.Add(submesh);
                            break;
                        }
                    }
                }
            }
            if (srcTotalSubmeshes != srcSubmeshSet.Count)
            {
                Report.ReportLog("Not all source submeshes exist in " + SortedParser.Name + ". Using only " + srcSubmeshSet.Count + ".");
            }

            xxFrame[]        dstMeshArr = Utility.Convert <xxFrame>(dstMeshes);
            double[]         dstSubmeshDoubleIndices = Utility.Convert <double>(dstSubmeshes);
            List <xxSubmesh> dstSubmeshList          = new List <xxSubmesh>();
            int dstSubmeshIdxIdx = 0;

            foreach (xxFrame meshFrame in dstMeshArr)
            {
                int numSubmeshes = (int)dstSubmeshDoubleIndices[dstSubmeshIdxIdx++];
                if (numSubmeshes == -1)
                {
                    dstSubmeshList.AddRange(meshFrame.Mesh.SubmeshList);
                }
                else
                {
                    for (int i = 0; i < numSubmeshes; i++)
                    {
                        int       dstSubmeshIdx = (int)dstSubmeshDoubleIndices[dstSubmeshIdxIdx++];
                        xxSubmesh submesh       = meshFrame.Mesh.SubmeshList[dstSubmeshIdx];
                        dstSubmeshList.Add(submesh);
                    }
                }
            }

            sviexParser newParser = new sviexParser();

            foreach (xxFrame dstMeshFrame in dstMeshArr)
            {
                foreach (xxSubmesh dstSubmesh in dstMeshFrame.Mesh.SubmeshList)
                {
                    if (!dstSubmeshList.Contains(dstSubmesh))
                    {
                        continue;
                    }

                    if (progressBar != null)
                    {
                        progressBar.Maximum += dstSubmesh.VertexList.Count;
                    }
                    sviParser newSection = new sviParser();
                    newSection.meshName       = dstMeshFrame.Name;
                    newSection.submeshIdx     = dstMeshFrame.Mesh.SubmeshList.IndexOf(dstSubmesh);
                    newSection.indices        = new ushort[dstSubmesh.VertexList.Count];
                    newSection.normalsPresent = 1;
                    newSection.normals        = new Vector3[dstSubmesh.VertexList.Count];
                    for (ushort i = 0; i < dstSubmesh.VertexList.Count; i++)
                    {
                        xxVertex dstVertex = dstSubmesh.VertexList[i];
                        if (automatic)
                        {
                            nearestNormal = false;
                            for (int j = 0; j < dstSubmesh.VertexList.Count; j++)
                            {
                                if (j != i)
                                {
                                    xxVertex vert       = dstSubmesh.VertexList[j];
                                    double   distSquare = (vert.Position.X - dstVertex.Position.X) * (vert.Position.X - dstVertex.Position.X)
                                                          + (vert.Position.Y - dstVertex.Position.Y) * (vert.Position.Y - dstVertex.Position.Y)
                                                          + (vert.Position.Z - dstVertex.Position.Z) * (vert.Position.Z - dstVertex.Position.Z);
                                    if (distSquare <= nearVertexThreshold)
                                    {
                                        nearestNormal = true;
                                        break;
                                    }
                                }
                            }
                        }

                        Dictionary <xxFrame, Dictionary <xxSubmesh, List <int> > > bestFindings = new Dictionary <xxFrame, Dictionary <xxSubmesh, List <int> > >();
                        int       totalFindings = 0;
                        xxFrame   bestMeshFrame = null;
                        xxSubmesh bestSubmesh   = null;
                        int       bestIdx       = -1;
                        double    bestDist      = double.MaxValue;
                        foreach (xxFrame srcMeshFrame in srcMeshArr)
                        {
                            Dictionary <xxSubmesh, List <int> > bestSubmeshFindings = new Dictionary <xxSubmesh, List <int> >();
                            foreach (xxSubmesh srcSubmesh in srcMeshFrame.Mesh.SubmeshList)
                            {
                                if (!srcSubmeshSet.Contains(srcSubmesh))
                                {
                                    continue;
                                }

                                List <int> bestIndexFindings = new List <int>(srcSubmesh.VertexList.Count);
                                for (int j = 0; j < srcSubmesh.VertexList.Count; j++)
                                {
                                    xxVertex srcVertex  = srcSubmesh.VertexList[j];
                                    double   distSquare = (srcVertex.Position.X - dstVertex.Position.X) * (srcVertex.Position.X - dstVertex.Position.X)
                                                          + (srcVertex.Position.Y - dstVertex.Position.Y) * (srcVertex.Position.Y - dstVertex.Position.Y)
                                                          + (srcVertex.Position.Z - dstVertex.Position.Z) * (srcVertex.Position.Z - dstVertex.Position.Z);
                                    if (distSquare <= nearVertexThreshold)
                                    {
                                        bestIndexFindings.Add(j);
                                        totalFindings++;
                                        continue;
                                    }
                                    if (totalFindings == 0 && distSquare < bestDist)
                                    {
                                        bestMeshFrame = srcMeshFrame;
                                        bestSubmesh   = srcSubmesh;
                                        bestIdx       = j;
                                        bestDist      = distSquare;
                                    }
                                }
                                if (bestIndexFindings.Count > 0)
                                {
                                    bestSubmeshFindings.Add(srcSubmesh, bestIndexFindings);
                                }
                            }
                            if (bestSubmeshFindings.Count > 0)
                            {
                                bestFindings.Add(srcMeshFrame, bestSubmeshFindings);
                            }
                        }
                        if (totalFindings > 0)
                        {
                            Vector3 normalSummed  = new Vector3();
                            Vector3 normalNearest = new Vector3();
                            double  nearestDist   = Double.MaxValue;
                            foreach (var finding in bestFindings)
                            {
                                foreach (sviParser srcSection in SortedParser.sections)
                                {
                                    if (srcSection.meshName == finding.Key.Name)
                                    {
                                        foreach (var submeshFinding in finding.Value)
                                        {
                                            if (srcSection.submeshIdx == finding.Key.Mesh.SubmeshList.IndexOf(submeshFinding.Key))
                                            {
                                                foreach (int j in submeshFinding.Value)
                                                {
                                                    if (nearestNormal)
                                                    {
                                                        double distSquare = (srcSection.normals[j].X - dstVertex.Normal.X) * (srcSection.normals[j].X - dstVertex.Normal.X)
                                                                            + (srcSection.normals[j].Y - dstVertex.Normal.Y) * (srcSection.normals[j].Y - dstVertex.Normal.Y)
                                                                            + (srcSection.normals[j].Z - dstVertex.Normal.Z) * (srcSection.normals[j].Z - dstVertex.Normal.Z);
                                                        if (distSquare < nearestDist)
                                                        {
                                                            normalNearest = srcSection.normals[j];
                                                            nearestDist   = distSquare;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        normalSummed += srcSection.normals[j];
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            if (totalFindings > 1)
                            {
                                normalSummed.Normalize();
                            }

                            newSection.indices[i] = i;
                            newSection.normals[i] = nearestNormal ? normalNearest : normalSummed;
                        }
                        else
                        {
                            int bestSubmeshIdx = bestMeshFrame.Mesh.SubmeshList.IndexOf(bestSubmesh);
                            foreach (sviParser srcSection in SortedParser.sections)
                            {
                                if (srcSection.meshName == bestMeshFrame.Name && srcSection.submeshIdx == bestSubmeshIdx)
                                {
                                    newSection.indices[i] = i;
                                    newSection.normals[i] = srcSection.normals[bestIdx];
                                    break;
                                }
                            }
                        }

                        if (progressBar != null)
                        {
                            progressBar.PerformStep();
                        }
                    }
                    newParser.sections.Add(newSection);
                }
            }

            dstParser.sections = newParser.sections;
        }
示例#2
0
文件: FormSVIEX.cs 项目: kkdevs/sb3u
        private static void SwapNormals(ComboBoxItemXX cbItem, string sviexName)
        {
            Dictionary <xxVertex, Vector3> originalNormals = new Dictionary <xxVertex, Vector3>();
            sviexParser targetParser = PluginsPPD.OpenSVIEX((ppParser)Gui.Scripting.Variables[cbItem.ppForm.ParserVar], sviexName);

            foreach (sviParser section in targetParser.sections)
            {
                bool meshFound = false;
                foreach (ComboBoxItemMesh itemMesh in cbItem.meshes)
                {
                    if (section.meshName == itemMesh.meshFrame.Name)
                    {
                        meshFound = true;
                        xxSubmesh submesh = itemMesh.meshFrame.Mesh.SubmeshList[section.submeshIdx];
                        if (section.indices.Length != submesh.VertexList.Count)
                        {
                            Report.ReportLog("Unmatching SVIEX mesh=" + section.meshName + " submeshIdx=" + section.submeshIdx + " has " + section.indices.Length + " indices.");
                            break;
                        }
                        for (int i = 0; i < section.indices.Length; i++)
                        {
                            ushort   vIdx = section.indices[i];
                            Vector3  norm = section.normals[i];
                            xxVertex vert = submesh.VertexList[vIdx];
                            originalNormals.Add(vert, vert.Normal);
                            vert.Normal = norm;
                        }
                        break;
                    }
                }
                if (!meshFound)
                {
                    Report.ReportLog("SVIEX Normals not copied for " + section.meshName);
                }
            }

            cbItem.xxForm.RecreateRenderObjects();

            foreach (sviParser section in targetParser.sections)
            {
                foreach (ComboBoxItemMesh itemMesh in cbItem.meshes)
                {
                    if (section.meshName == itemMesh.meshFrame.Name)
                    {
                        xxSubmesh submesh = itemMesh.meshFrame.Mesh.SubmeshList[section.submeshIdx];
                        if (section.indices.Length != submesh.VertexList.Count)
                        {
                            break;
                        }
                        for (int i = 0; i < section.indices.Length; i++)
                        {
                            ushort   vIdx = section.indices[i];
                            xxVertex vert = submesh.VertexList[vIdx];
                            Vector3  norm = originalNormals[vert];
                            vert.Normal = norm;
                        }
                        break;
                    }
                }
            }
        }