private float CalcRadius(NiTriShapeData data) { float num1 = float.MinValue; for (int index = 0; index < (int)data.GetNumVertices(); ++index) { Vector3 vector3_1 = data.GetVertices()[index]; Vector3 vector3_2 = data.GetCenter() - vector3_1; float num2 = (float)((double)vector3_2[0] * (double)vector3_2[0] + (double)vector3_2[1] * (double)vector3_2[1] + (double)vector3_2[2] * (double)vector3_2[2]); if ((double)num2 > (double)num1) num1 = num2; } return (float)Math.Sqrt((double)num1); }
private void MergeNodes(List<ShapeDesc> shapes) { int count = shapes.Count; Dictionary<string, List<ShapeDesc>> dictionary = new Dictionary<string, List<ShapeDesc>>(); for (int index = 0; index < shapes.Count; ++index) { ShapeDesc shape = new ShapeDesc(); shape = shapes[index]; string key = shape.textures[0].ToLower(); // use vertex color flag to seperate? // less draw calls more important than reducing a few bytes? // overall it is not even reducing bytes... so no /*if (useOptimizer && shape.data.HasVertexColors()) { key = key + "_VC"; }*/ // use material name from list file, Snow/Ash if (!this.ignoreMaterial && shape.material != "") { key = key + "_" + shape.material; } // only level 4 should have HD if (shape.isHighDetail && (this.quadLevel == 4 || useHDFlag)) { key = key + "_HD"; } // double-sided if (shape.isDoubleSided) { key = key + "_DS"; } // clamp mode key = key + "_" + shape.TextureClampMode; if (dictionary.ContainsKey(key)) { dictionary[key].Add(shape); } else { dictionary.Add(key, new List<ShapeDesc>()); dictionary[key].Add(shape); } } shapes.Clear(); foreach (KeyValuePair<string, List<ShapeDesc>> keyValuePair in dictionary) { if (keyValuePair.Value.Count == 1) { shapes.Add(keyValuePair.Value[0]); } else { SegmentDesc segmentDesc = (SegmentDesc)null; uint num1 = 0U; uint num2 = 0U; int num3 = -1; NiTriShape niTriShape = new NiTriShape(); NiTriShapeData data = new NiTriShapeData(); List<ShapeDesc> list = keyValuePair.Value; string str1 = list[0].textures[0]; string str2 = list[0].textures[1]; string str3 = list[0].material; //bool isVC = list[0].hasVertexColor; bool isHD = list[0].isHighDetail; // double-sided bool isDS = list[0].isDoubleSided; // clamp mode uint clampmode = list[0].TextureClampMode; bool allwhite = true; list.Sort((Comparison<ShapeDesc>)((a, b) => { if (a.segments[0].id > b.segments[0].id) return 1; return a.segments[0].id < b.segments[0].id ? -1 : 0; })); ShapeDesc shapeDesc = new ShapeDesc(); shapeDesc.boundingBox.Set(float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue); for (int index1 = 0; index1 < list.Count; ++index1) { NiTriShapeData niTriShapeData = list[index1].data; List<Vector3> vertices = niTriShapeData.GetVertices(); List<Triangle> triangles = new List<Triangle>(niTriShapeData.GetTriangles()); if ((uint)data.GetNumVertices() + (uint)vertices.Count > (uint)ushort.MaxValue || (uint)data.GetNumTriangles() + (uint)triangles.Count > (uint)ushort.MaxValue) { data.SetCenter(shapeDesc.boundingBox.GetCenter() / (float)this.quadLevel); data.SetRadius(this.CalcRadius(data)); shapeDesc.segments.Add(segmentDesc); shapeDesc.shape = niTriShape; shapeDesc.data = data; shapeDesc.textures = new string[2]; shapeDesc.textures[0] = str1; shapeDesc.textures[1] = str2; shapeDesc.material = str3; shapeDesc.isHighDetail = isHD; //shapeDesc.hasVertexColor = isVC; // double-sided shapeDesc.isDoubleSided = isDS; //clamp mode shapeDesc.TextureClampMode = clampmode; shapes.Add(shapeDesc); shapeDesc = new ShapeDesc(); shapeDesc.boundingBox.Set(float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue); niTriShape = new NiTriShape(); data = new NiTriShapeData(); num1 = 0U; num2 = 0U; num3 = -1; } for (int index2 = 0; index2 < (int)niTriShapeData.GetNumVertices(); ++index2) { Vector3 vector3 = vertices[index2] * (float)this.quadLevel; shapeDesc.boundingBox.GrowByVertex(vector3); } data.AppendVertices(niTriShapeData.GetVertices()); data.AppendNormals(niTriShapeData.GetNormals()); data.AppendUVCoords(niTriShapeData.GetUVCoords()); if (this.generateTangents) { //str3.Length != 0 if (!useOptimizer || (useOptimizer && (this.quadLevel == 4 || isHD))) { data.AppendTangents(niTriShapeData.GetTangents()); data.AppendBitangents(niTriShapeData.GetBitangents()); } } // only level 4 should have vertex colors if (this.generateVertexColors && (this.quadLevel == 4 || isHD)) { List<Color4> colors = new List<Color4>(); if (niTriShapeData.HasVertexColors()) { colors = niTriShapeData.GetVertexColors(); data.AppendVertexColors(colors); for (int index2 = 0; index2 < colors.Count; index2++) { if (colors[index2][0] != 1f || colors[index2][2] != 1f || colors[index2][2] != 1f) { allwhite = false; break; } } } else { for (int index2 = 0; index2 < vertices.Count; ++index2) { colors.Add(new Color4(1f, 1f, 1f, 1f)); } data.AppendVertexColors(colors); } } List<Triangle> trianglesNew = new List<Triangle>(); for (int index2 = 0; index2 < (int)niTriShapeData.GetNumTriangles(); ++index2) { trianglesNew.Add(new Triangle((ushort)(triangles[index2][0] + num1), (ushort)(triangles[index2][1] + num1), (ushort)(triangles[index2][2] + num1))); } data.AppendTriangles(trianglesNew); num1 += (uint)niTriShapeData.GetNumVertices(); if (list[index1].segments[0].id != num3) { if (num3 != -1) { num2 += (uint)segmentDesc.numTriangles * 3U; shapeDesc.segments.Add(segmentDesc); } segmentDesc = new SegmentDesc(); segmentDesc.id = list[index1].segments[0].id; segmentDesc.startTriangle = num2; segmentDesc.numTriangles = list[index1].segments[0].numTriangles; num3 = list[index1].segments[0].id; } else segmentDesc.numTriangles += list[index1].data.GetNumTriangles(); } data.SetCenter(shapeDesc.boundingBox.GetCenter() / (float)this.quadLevel); data.SetRadius(this.CalcRadius(data)); shapeDesc.segments.Add(segmentDesc); shapeDesc.shape = niTriShape; shapeDesc.data = data; shapeDesc.textures = new string[2]; shapeDesc.textures[0] = str1; shapeDesc.textures[1] = str2; shapeDesc.material = str3; //shapeDesc.hasVertexColor = isVC; shapeDesc.isHighDetail = isHD; // double-sided shapeDesc.isDoubleSided = isDS; // clamp mode shapeDesc.TextureClampMode = clampmode; if (allwhite) { shapeDesc.data.SetHasVertexColors(false); shapeDesc.hasVertexColor = false; } else { shapeDesc.data.SetHasVertexColors(true); shapeDesc.hasVertexColor = true; } shapes.Add(shapeDesc); } } }