//逐点插入法2 public Edge[] PointByPointInsertion() { EdgeSet sEdgeSet = new EdgeSet(); TriangleSet sTriangleSet = new TriangleSet(); MinBoundRect sMBR = this.mPointSet.MBR; double width = sMBR.MaxX - sMBR.MinX; double height = sMBR.MaxY - sMBR.MinY; double middlePointX = (sMBR.MaxX + sMBR.MinX) / 2; double middlePointY = sMBR.MinY; DataPoint P0 = new DataPoint(-1, "P0", middlePointX - width, middlePointY, 0); DataPoint P1 = new DataPoint(-2, "P1", middlePointX + width, middlePointY, 0); DataPoint P2 = new DataPoint(-3, "P2", middlePointX, middlePointY + 2 * height, 0); Triangle T0 = new Triangle(P0, P1, P2, -1); sTriangleSet.AddTriangle(T0); sEdgeSet.AddEdge(new Edge(P0, P1)); sEdgeSet.AddEdge(new Edge(P1, P2)); sEdgeSet.AddEdge(new Edge(P1, P0)); foreach (var point in mPointSet.PointList) { Triangle CurTri = sTriangleSet.GetPointInsidesTri(point); if (CurTri != null) { } } return(sEdgeSet.EdgeList.ToArray()); }
private void 逐点插入法ToolStripMenuItem_Click(object sender, EventArgs e) { //交互-格网与TIN if (逐点插入法ToolStripMenuItem.Checked == true) { //修改显示 this.UserOperation = UserOperationType.DisplayInTIN; this.ShowTin = true; this.显示隐藏TINToolStripMenuItem.Checked = true; CreateTIN createTin = new CreateTIN(this.mPointSet); Edge[] tinEdges = createTin.PointByPointInsertion2(); Edge[] tinEdges2 = createTin.GeneTIN().ToArray(); TinEdges = tinEdges; TriangleSet triSet = EdgeSet.TopologyGenerateTriangleSet(tinEdges, mPointSet); Triangle[] triList = triSet.TriangleList.ToArray(); TinContourLinePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; agisControl.Refresh(); } else { //修改显示 this.UserOperation = UserOperationType.None; this.ShowTin = false; this.显示隐藏TINToolStripMenuItem.Checked = false; } }
// FUNCTIONS /// <summary> /// Generate triangle array for a standard mesh consisting of rectangular cross sections. /// </summary> /// <param name="numCrossSections">Number of rectangular cross sections "framing" the mesh.</param> /// <returns>Array of integers, each set of 3 representing a triangle in the mesh.</returns> public static int[] getStandardMeshTriangles(int numCrossSections) { int numVertices = numCrossSections * 4; TriangleSet triangleSet = new TriangleSet((numCrossSections - 1) * 8 + 4); // Form appropriate triangles for each set of two cross sections for (int i = 0; i < numCrossSections - 1; i++) { int vOffset = i * 4; // Top triangles triangleSet.pushTriangles(vOffset, vOffset + 4, vOffset + 5, vOffset + 1); // Bottom triangles triangleSet.pushTriangles(vOffset + 2, vOffset + 3, vOffset + 7, vOffset + 6); // Left triangles triangleSet.pushTriangles(vOffset, vOffset + 2, vOffset + 6, vOffset + 4); // Right triangles triangleSet.pushTriangles(vOffset + 1, vOffset + 5, vOffset + 7, vOffset + 3); } // Special case: front triangles on first cross section triangleSet.pushTriangles(0, 1, 3, 2); // Special case: rear triangles on last cross section triangleSet.pushTriangles(numVertices - 4, numVertices - 2, numVertices - 1, numVertices - 3); return(triangleSet.getTrianglePoints()); }
/// <summary> /// Given a Triangle set, write the data to a file. /// </summary> /// <param name="output">The stream to write data to. Will be closed when method completed</param> /// <param name="data">The <TriangleSet> to output </param> public void WriteOutput(Stream output, TriangleSet data) { using (var sw = new StreamWriter(output)) { sw.WriteLine($"{data.EarliestOriginYear},{data.NumberOfDevelopmentYears}"); foreach (var t in data.Triangles) { var stringBuilder = new StringBuilder(t.ProductName); foreach (var year in t.Matrix.Keys) { stringBuilder.Append(",").Append(string.Join(",", t.Matrix[year].Select(x => x.ToString("###0.##")))); } sw.WriteLine(stringBuilder.ToString()); } } }
public void Test_WhenCalculateCalled_ShouldOrWithMembership() { // Arrange FuzzySet antecedentSet = new TriangleSet(.5, .3, .3); antecedentSet.DegreeOfMembership = .7; Term antecedent = new SetProxy(antecedentSet); FuzzySet consequenceSet = new TriangleSet(.5, .3, .3); consequenceSet.DegreeOfMembership = 0; Term consequence = new SetProxy(consequenceSet); Rule rule = new Rule(antecedent, consequence); // Act rule.Calculate(); // Assert Assert.AreEqual(.7, antecedent.Membership, .00001); Assert.AreEqual(.7, consequence.Membership, .00001); }
private void GetTriangleSet_LV3(Vector2 targetPosW, List <PosWeightPair> pairList, PosWeightPair pair1, PosWeightPair pair2, int startIndex, List <TriangleSet> resultTriList) { if (startIndex >= pairList.Count) { return; } PosWeightPair pair3 = null; for (int i = startIndex; i < pairList.Count; i++) { pair3 = pairList[i]; //3개의 포인트가 다 모였다. //targetPosW를 기준으로 삼각형이 되는지 확인하자. bool isTriCondition = false; float angle12 = Vector2.Angle(pair1._posWorld - targetPosW, pair2._posWorld - targetPosW); float angle23 = Vector2.Angle(pair2._posWorld - targetPosW, pair3._posWorld - targetPosW); float angle31 = Vector2.Angle(pair3._posWorld - targetPosW, pair1._posWorld - targetPosW); float angleSum = angle12 + angle23 + angle31; if (Mathf.Abs(angleSum - 360.0f) < 2.0f) { //대략 삼각형 안에 포인트가 있는 듯 하다. isTriCondition = true; } if (!isTriCondition) { continue; } //삼각형 메시를 구했다. TriangleSet newTriSet = new TriangleSet(pair1, pair2, pair3, targetPosW, angle12, angle23, angle31); resultTriList.Add(newTriSet); } }
/// <summary> /// Builds kdtree for specific patch. /// Kdtree is built according to specified positions type and hierarchy level. /// </summary> private static KdIntersectionTree BuildKdTreeForPatch( string patchName, int level, PatchFileInfo info, OpcPaths paths, PositionsType posType, bool saveTriangles = false, bool saveKdTree = true, float maxTriangleSize = float.PositiveInfinity) { var path = Path.Combine(paths.PatchesSubDir, patchName); var patchGeometry = new TriangleSet(); //var patchGeometryTest = new TriangleSet(); if ((maxTriangleSize < float.PositiveInfinity) && (maxTriangleSize > 0.000001f)) { patchGeometry = PatchLoadingStrategy.LoadPatchTriangleSetWithoutOversizedTriangles(info, path, posType, maxTriangleSize); //patchGeometryTest = PatchLoadingStrategy.LoadPatchTriangleSet(info, path, posType); } else { patchGeometry = PatchLoadingStrategy.LoadPatchTriangleSet(info, path, posType); } KdIntersectionTree kdIntTree = new KdIntersectionTree(patchGeometry, KdIntersectionTree.BuildFlags.MediumIntersection | KdIntersectionTree.BuildFlags.Hierarchical); if (!saveTriangles) { kdIntTree.ObjectSet = null; } if (saveKdTree) { var kdTreePath = paths.GetKdTreePath(patchName, level, posType); kdIntTree.Save(kdTreePath); } return(kdIntTree); }
private void 生成等值线ToolStripMenuItem1_Click(object sender, EventArgs e) { this.ShowContourLine = (this.生成等值线ToolStripMenuItem1.Checked == true); if (this.ShowContourLine == false) { this.agisControl.Refresh(); return; } ContourLineSettingForm settingForm = new ContourLineSettingForm(); if (settingForm.ShowDialog(this) == DialogResult.OK) { //生成Tin CreateTIN createTin = new CreateTIN(this.mPointSet); Edge[] tinEdges = createTin.PointByPointInsertion2(); TinEdges = tinEdges; TriangleSet triSet = EdgeSet.TopologyGenerateTriangleSet(tinEdges, mPointSet); Triangle[] triList = triSet.TriangleList.ToArray(); List <Edge> contourLinesList = new List <Edge>(); //计算等值线条数 int lineCount = (int)((settingForm.MaxValue - settingForm.MinValue) / settingForm.IntervalValue); for (int i = 0; i <= lineCount; i++) { for (int j = 0; j < triList.Length; j++) { Edge contourLine = triList[j].GetContourLine(settingForm.MaxValue - i * settingForm.IntervalValue); if (contourLine != null) { contourLinesList.Add(contourLine); } } this.TinContourLineList = contourLinesList.ToArray(); } } TinContourLinePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; agisControl.Refresh(); }
public bool Paste(apMeshGroup meshGroup, List <apModifiedVertexRig> targetModVertRigs) { if (meshGroup == null || targetModVertRigs == null || targetModVertRigs.Count == 0) { return(false); } if (_keyMeshGroup == null || _keyMeshGroup != meshGroup || _posWeightPairs.Count == 0) { return(false); } //Debug.LogError("Paste Start----"); apModifiedVertexRig targetModVertRig = null; Vector2 targetPosW = Vector2.zero; PosWeightPair src = null; Vector2 srcPosW = Vector2.zero; PosWeightPair near_mX = null; PosWeightPair near_pX = null; PosWeightPair near_mY = null; PosWeightPair near_pY = null; float minDst_mX = 0.0f; float minDst_pX = 0.0f; float minDst_mY = 0.0f; float minDst_pY = 0.0f; float dst = 0.0f; //알고리즘 변경 //1. 일단 -X, +X, -Y, +Y 방향으로 가장 가까운 포인트를 찾는다. (축값이 아닌 실제 Dst임) //2. 최대 4개의 포인트에 대하여 "최대 거리"를 구한다 //3. 4개의 포인트를 포함하여 최대 거리 안에 포함된 포인트들을 리스트에 넣는다. //4. 포인트를 3개씩 묶어서 "삼각형"이 되어 이 점을 포함하는지 확인 //5. "삼각형"이 되는 경우, 전체 Dist의 합이 가장 작은 삼각형을 선택한다. //6. 최적화된 삼각형을 찾은 상태에서 Barycentric 방식으로 보간한다. for (int iTarget = 0; iTarget < targetModVertRigs.Count; iTarget++) { targetModVertRig = targetModVertRigs[iTarget]; targetPosW = targetModVertRig._renderVertex._pos_World_NoMod; near_mX = null; near_pX = null; near_mY = null; near_pY = null; minDst_mX = 0.0f; minDst_pX = 0.0f; minDst_mY = 0.0f; minDst_pY = 0.0f; for (int iSrc = 0; iSrc < _posWeightPairs.Count; iSrc++) { src = _posWeightPairs[iSrc]; srcPosW = src._posWorld; dst = Vector2.Distance(srcPosW, targetPosW); if (srcPosW.x < targetPosW.x) { //-X에 대해서 if (dst < minDst_mX || near_mX == null) { near_mX = src; minDst_mX = dst; } } else { //+X에 대해서 if (dst < minDst_pX || near_pX == null) { near_pX = src; minDst_pX = dst; } } if (srcPosW.y < targetPosW.y) { //-Y에 대해서 if (dst < minDst_mY || near_mY == null) { near_mY = src; minDst_mY = dst; } } else { //+Y에 대해서 if (dst < minDst_pY || near_pY == null) { near_pY = src; minDst_pY = dst; } } } //아주 가까운 점이 있다면 그 점을 그대로 대입한다. if (near_mX != null && near_mX.IsApproxPos(targetPosW)) { near_mX.PasteToModVertRig(meshGroup, targetModVertRig); //Debug.Log(">> Case0 : 1개의 겹치는 점 대입"); continue; } if (near_pX != null && near_pX.IsApproxPos(targetPosW)) { near_pX.PasteToModVertRig(meshGroup, targetModVertRig); //Debug.Log(">> Case0 : 1개의 겹치는 점 대입"); continue; } if (near_mY != null && near_mY.IsApproxPos(targetPosW)) { near_mY.PasteToModVertRig(meshGroup, targetModVertRig); //Debug.Log(">> Case0 : 1개의 겹치는 점 대입"); continue; } if (near_pY != null && near_pY.IsApproxPos(targetPosW)) { near_pY.PasteToModVertRig(meshGroup, targetModVertRig); //Debug.Log(">> Case0 : 1개의 겹치는 점 대입"); continue; } //2. 최대 4개의 포인트에 대하여 "최대 거리"를 구한다 //3. 4개의 포인트를 포함하여 최대 거리 안에 포함된 포인트들을 리스트에 넣는다. List <PosWeightPair> pairList = new List <PosWeightPair>(); float maxDist = 0.0f; if (near_mX != null) { pairList.Add(near_mX); maxDist = Mathf.Max(minDst_mX, maxDist); } if (near_pX != null && !pairList.Contains(near_pX)) { pairList.Add(near_pX); maxDist = Mathf.Max(minDst_pX, maxDist); } if (near_mY != null && !pairList.Contains(near_mY)) { pairList.Add(near_mY); maxDist = Mathf.Max(minDst_mY, maxDist); } if (near_pY != null && !pairList.Contains(near_pY)) { pairList.Add(near_pY); maxDist = Mathf.Max(minDst_pY, maxDist); } if (pairList.Count < 3) { maxDist *= 2; } //이제 다시 돌면서 maxDist 거리 안에 있는 모든 포인트를 리스트에 넣는다. for (int iSrc = 0; iSrc < _posWeightPairs.Count; iSrc++) { src = _posWeightPairs[iSrc]; if (pairList.Contains(src)) { //이미 추가되었다. continue; } srcPosW = src._posWorld; dst = Vector2.Distance(srcPosW, targetPosW); if (dst < maxDist) { pairList.Add(src); } } if (pairList.Count == 0) { //1개도 없다면 continue; } if (pairList.Count == 1) { //가까운 점이 1개라면 //그대로 대입 pairList[0].PasteToModVertRig(meshGroup, targetModVertRig); //Debug.Log(">> Case1 : 1개의 점 대입"); continue; } PosWeightPair pairResult = new PosWeightPair(); if (pairList.Count == 2) { //4-1. 가까운 점이 2개라면 //두개의 거리 비로 계산한다. PosWeightPair pairA = pairList[0]; PosWeightPair pairB = pairList[0]; float dstA = Vector2.Distance(pairA._posWorld, targetPosW); float dstB = Vector2.Distance(pairB._posWorld, targetPosW); if (dstA + dstB > 0.0f) { pairResult.Lerp(pairA, pairB, dstA / (dstA + dstB)); } else { pairResult.Lerp(pairA, pairB, 0.5f); } pairResult.PasteToModVertRig(meshGroup, targetModVertRig); //Debug.Log(">> Case2 : 2개의 점 대입"); continue; } //4-2. 포인트를 3개씩 묶어서 "삼각형"이 되어 이 점을 포함하는지 확인 //Recursive 함수를 이용하자 List <TriangleSet> triSet = GetTriangleSet_LV1(targetPosW, pairList, 0); if (triSet.Count == 0) { //삼각형 메시에 포함되지 않았다면, //가장 가까운 3개의 점을 보간하자 pairList.Sort(delegate(PosWeightPair a, PosWeightPair b) { float dstA = Vector2.Distance(a._posWorld, targetPosW); float dstB = Vector2.Distance(b._posWorld, targetPosW); return((int)((dstA - dstB) * 1000.0f)); }); pairResult.Interpolation3_NotTri(pairList[0], pairList[1], pairList[2], targetPosW); pairResult.PasteToModVertRig(meshGroup, targetModVertRig); //Debug.Log(">> Case3 : 삼각형이 안되는 3개의 점 대입"); continue; } //5. "삼각형"이 되는 경우, 전체 Dist의 합이 가장 작은 삼각형을 선택한다. TriangleSet minTriSet = null; float minTriSize = 0.0f; TriangleSet curTriSet = null; for (int iTri = 0; iTri < triSet.Count; iTri++) { curTriSet = triSet[iTri]; if (minTriSet == null || curTriSet._totalDist < minTriSize) { minTriSet = curTriSet; minTriSize = curTriSet._totalDist; } } //6. 최적화된 삼각형을 찾은 상태에서 Barycentric 방식으로 보간한다. minTriSet.CalculateBaryCentricWeights(targetPosW); pairResult.AddPosWeightPair(minTriSet._pair_A, minTriSet._baryCentricWeightA); pairResult.AddPosWeightPair(minTriSet._pair_B, minTriSet._baryCentricWeightB); pairResult.AddPosWeightPair(minTriSet._pair_C, minTriSet._baryCentricWeightC); pairResult.Normalize(); pairResult.PasteToModVertRig(meshGroup, targetModVertRig); //Debug.Log(">> Case4 : 삼각형 보간 대입"); } return(true); }
public static GameObject LoadModel(string fileName) { // If we get here, we're loading a custom model. If it's in the cache, return what's there. if (_cachedModels.ContainsKey(fileName)) { return (GameObject)GameObject.Instantiate(_cachedModels[fileName]); } // If we get here, this is our first request for this filename. Load the mesh. // (We currently only support the Collada format) string meshFileName = CustomContentDirector.GetApplicationDataPath() + fileName; GameObject o = new GameObject(); // This will be the return value Debug.Log("Loading custom model " + meshFileName + "..."); try { // Open a stream to the file using (FileStream fileStream = new FileStream(meshFileName, FileMode.Open)) { // Load the stream into an Xml document parser XmlDocument doc = new XmlDocument(); doc.Load(fileStream); // Now deserialize the document into a XmlCollada.XmlColladaSchema object. While // the naming could be better, this object allows easy access to all the components // in the Collada mesh. XmlCollada.XmlColladaSchema collada = new XmlCollada.XmlColladaSchema(doc); XmlCollada.Scene scene = collada.Scene; XmlCollada.Instance_Visual_Scene instanceVisualScene = scene.InstanceVisualScene; XmlCollada.Visual_Scene visualScene = collada.LibraryVisualScenes.GetVisualScene(instanceVisualScene.URL.Trim('#')); XmlCollada.XmlColladaList geometryNodeList = visualScene.GetInstanceGeometryNodes(); // We don't support these; but when we decide to, these are here for us //XmlCollada.XmlColladaList materialNodeList = collada.LibraryMaterials.Materials; //XmlCollada.XmlColladaList imageNodeList = collada.LibraryImages.Images; // Navigate through the schema to build all geometries for (int i = 0; i < geometryNodeList.Count; i++) { XmlCollada.Node node = (XmlCollada.Node)geometryNodeList.GetAt(i); XmlCollada.XmlColladaList transforms = node.Transforms; XmlCollada.Instance_Geometry instanceGeometry = node.InstanceGeometry; XmlCollada.Geometry geometry = collada.LibraryGeometries.GetGeometry(instanceGeometry.URL.Trim('#')); XmlCollada.Mesh colladaMesh = geometry.Mesh; XmlCollada.XmlColladaList xmlGeometries = colladaMesh.GetXmlGeometries(); // Build a matrix based on all geometry transforms for (int j = 0; j < transforms.Count; j++) { // TODO: Build a matrix based on the transforms } // Now load all the polygon lists for (int j = 0; j < xmlGeometries.Count; j++) { XmlCollada.XmlGeometry xmlGeometry = (XmlCollada.XmlGeometry)xmlGeometries.GetAt(j); XmlCollada.XmlColladaList inputs = xmlGeometry.GetInputs(); TriangleSet triangleSet = new TriangleSet(); // Create one Unity game object per polygon list GameObject unityNode = new GameObject(); Mesh unityMesh = new Mesh(); unityNode.AddComponent<MeshFilter>().mesh = unityMesh; unityNode.AddComponent<MeshRenderer>(); unityNode.transform.parent = o.transform; unityNode.name = node.Name; // Get the material (Currently unsuppoorted) //string instanceMaterialTarget = node.InstanceGeometry.GetBoundMaterialTarget(xmlGeometry.Material); //XmlCollada.Material material = collada.LibraryMaterials.GetMaterial(instanceMaterialTarget.Trim('#')); //XmlCollada.Effect effect = collada.LibraryEffects.GetEffect(material._instanceEffect.URL.Trim('#')); //XmlCollada.XmlShaderElement shader = effect.ProfileCommon.Technique.Shader; // Now load recognized input components for this polygon list Vector3[] vertices = null; Vector3[] normals = null; Vector2[] texcoords = null; int verticesPOffset = -1; int normalsPOffset = -1; int texcoordsPOffset = -1; int maxInputOffset = 0; for (int k = 0; k < inputs.Count; k++) { XmlCollada.Input input = (XmlCollada.Input)inputs.GetAt(k); if (input.Offset > maxInputOffset) { maxInputOffset = input.Offset; } XmlCollada.Source source; if (input.Semantic == "VERTEX") { source = (XmlCollada.Source)colladaMesh.GetSource(colladaMesh.Vertices.Input.Source.Trim('#')); } else { source = (XmlCollada.Source)colladaMesh.GetSource(input.Source.Trim('#')); } XmlCollada.Float_Array floatArray = source.Float_Array; XmlCollada.Technique_Common techniqueCommon = (XmlCollada.Technique_Common)source.Technique_Common; XmlCollada.Accessor accessor = techniqueCommon.Accessor; XmlCollada.XmlColladaList paramsList = accessor.GetParamsList(); // Calculate the number of named parameters int namedParamCount = 0; for (int l = 0; l < paramsList.Count; l++) { XmlCollada.Param param = (XmlCollada.Param)paramsList.GetAt(l); if (param.Name.Length > 0) { namedParamCount++; } } // Build the coordinate list from all the accessor elements float[] floatValues = new float[accessor.Count * namedParamCount]; int curFloatValue = 0; for (int l = 0; l < accessor.Count; l++) { // Do for all parameters int m0 = accessor.Offset + l * accessor.Stride; for (int m = 0; m < paramsList.Count; m++) { XmlCollada.Param param = (XmlCollada.Param)paramsList.GetAt(m); if (param.Name.Length > 0) { floatValues[curFloatValue++] = floatArray.Values[m0 + m]; } } } if (null == vertices && "VERTEX" == input.Semantic.ToUpper()) { vertices = new Vector3[accessor.Count]; for (int l = 0; l < accessor.Count; l++) { vertices[l] = new Vector3(); vertices[l].x = floatValues[l * namedParamCount]; if (namedParamCount > 1) { vertices[l].y = floatValues[l * namedParamCount + 1]; } if (namedParamCount > 2) { vertices[l].z = floatValues[l * namedParamCount + 2]; } } verticesPOffset = input.Offset; } else if (null == normals && "NORMAL" == input.Semantic.ToUpper()) { normals = new Vector3[accessor.Count]; for (int l = 0; l < accessor.Count; l++) { normals[l] = new Vector3(); normals[l].x = floatValues[l * namedParamCount]; if (namedParamCount > 1) { normals[l].y = floatValues[l * namedParamCount + 1]; } if (namedParamCount > 2) { normals[l].z = floatValues[l * namedParamCount + 2]; } } normalsPOffset = input.Offset; } else if (null == texcoords && "TEXCOORD" == input.Semantic.ToUpper()) { texcoords = new Vector2[accessor.Count]; for (int l = 0; l < accessor.Count; l++) { texcoords[l] = new Vector2(); texcoords[l].x = floatValues[l * namedParamCount]; if (namedParamCount > 1) { texcoords[l].y = floatValues[l * namedParamCount + 1]; } } texcoordsPOffset = input.Offset; } } // for (int k = 0; k < inputs.Count; k++) // Now that all the input components (vertex lists) have been loaded, we load the actual face // and index information. Loading is different for polygons and triangles. if (xmlGeometry.root == "polylist" || xmlGeometry.root == "triangles") { // Make a first pass at reading in the polygons. Because there can be a different // number of vertex indices than normal indices than UV indices, we have to create // our own index group based on the unique pairs of those elements. // // Note: The stride of <p> is equal to one more than the highest input offset. // IndexGroupList indexGroupList = new IndexGroupList(); int[] vcounts = xmlGeometry.GetVCount(); int[] p = xmlGeometry.GetP(); int pIndex = 0; // A triangle list is no different than a polygon list where the vcount is undefined. We'll make // it up here and assign three vertices per triangle. if (xmlGeometry.root == "triangles") { vcounts = new int[xmlGeometry.Count]; for (int k=0; k < xmlGeometry.Count; k++) { vcounts[k] = 3; } } // Do for all elements in vcount (one element is one polygon) for (int k = 0; k < vcounts.Length; k++) { int vertexCount = vcounts[k]; int[] polyVertIndices = new int[vertexCount]; int[] polyNormIndices = (normalsPOffset >= 0) ? new int[vertexCount] : null; int[] polyTexIndices = (texcoordsPOffset >= 0) ? new int[vertexCount] : null; // Do for all vertices for this polygon for (int l = 0; l < vertexCount; l++) { polyVertIndices[l] = p[pIndex + verticesPOffset]; if (normalsPOffset >= 0) { polyNormIndices[l] = p[pIndex + normalsPOffset]; } if (texcoordsPOffset >= 0) { polyTexIndices[l] = p[pIndex + texcoordsPOffset]; } pIndex += maxInputOffset + 1; } // At this point we have all our indices; however we still have to deal with the disjointed // nature of the indices (e.g. 8 vertex indices, 24 normal vertices). This is where our index // group list comes in. Add every unique combination of vertex, normal, and uv indices into // a single array, and build our triangle list while we're at it. int[] triangleIndices = new int[(vertexCount - 2) * 3]; for (int l = 0; l < vertexCount - 2; l++) { triangleIndices[l * 3] = indexGroupList.GetGroup(polyVertIndices[0], ((polyNormIndices != null) ? polyNormIndices[0] : -1), ((polyTexIndices != null) ? polyTexIndices[0] : -1)); triangleIndices[l * 3 + 1] = indexGroupList.GetGroup(polyVertIndices[l + 1], ((polyNormIndices != null) ? polyNormIndices[l + 1] : -1), ((polyTexIndices != null) ? polyTexIndices[l + 1] : -1)); triangleIndices[l * 3 + 2] = indexGroupList.GetGroup(polyVertIndices[l + 2], ((polyNormIndices != null) ? polyNormIndices[l + 2] : -1), ((polyTexIndices != null) ? polyTexIndices[l + 2] : -1)); } // Add the triangles to the generic mesh triangleSet.AddIndices(triangleIndices); } // Now we need to assign all the accumulated vertices, normals, and texcoords to the generic mesh Vector3[] v = new Vector3[indexGroupList.Count]; Vector3[] n = (null != normals) ? new Vector3[indexGroupList.Count] : null; Vector2[] uv = (null != texcoords) ? new Vector2[indexGroupList.Count] : null; for (int k = 0; k < indexGroupList.Count; k++) { IndexGroup group = indexGroupList.GetGroup(k); v[k] = vertices[group.vertIndex]; if (null != normals && group.normIndex >= 0) { n[k] = normals[group.normIndex]; } if (null != texcoords && group.texcoordIndex >= 0) { uv[k] = texcoords[group.texcoordIndex]; } } unityMesh.vertices = v; unityMesh.normals = n; unityMesh.uv = uv; unityMesh.triangles = triangleSet.indices; // Assign a default material unityNode.renderer.material = new Material(Shader.Find ("Diffuse")); unityNode.renderer.material.color = new Color(0.3f,0.3f,0.3f,1); // Now add the triangle set to the geometry //genericMeshGeometry.AddTriangleSet(triangleSet); } // if (xmlGeometry.root == "polylist" || xmlGeometry.root == "triangles") //genericMesh.AddGeometry(genericMeshGeometry); } } // for (int i = 0; i < geometryNodeList.Count; i++) } // Now add the mesh to our cache and return it o.name = "prefab_" + fileName; o.SetActiveRecursively(false); DontDestroyOnLoad(o); _cachedModels.Add(fileName, o); } catch (Exception e) { Debug.LogError(e.ToString()); } return (GameObject)GameObject.Instantiate(o); }