Exemple #1
0
 public static void Set(string key, ShapeDesc value)
 {
     if (!Contains(key))
     {
         _list.TryAdd(key, value);
     }
 }
Exemple #2
0
 public ShapeDesc(ShapeDesc shapeDesc)
 {
     this.name                = shapeDesc.name;
     this.staticName          = shapeDesc.name;
     this.staticModel         = shapeDesc.name;
     this.geometry            = null;
     this.shaderType          = shapeDesc.shaderType;
     this.effectShader        = shapeDesc.effectShader;
     this.lightingShader      = shapeDesc.lightingShader;
     this.texturingProperty   = shapeDesc.texturingProperty;
     this.materialProperty    = shapeDesc.materialProperty;
     this.sourceTextureBase   = shapeDesc.sourceTextureBase;
     this.sourceTextureDetail = shapeDesc.sourceTextureDetail;
     this.sourceTextureGlow   = shapeDesc.sourceTextureGlow;
     this.sourceTextureBump   = shapeDesc.sourceTextureBump;
     this.shaderHash          = shapeDesc.shaderHash;
     this.shapeHash           = shapeDesc.shapeHash;
     this.material            = shapeDesc.material;
     this.textures            = shapeDesc.textures;
     this.isPassThru          = shapeDesc.isPassThru;
     this.isGroup             = shapeDesc.isGroup;
     this.isHighDetail        = shapeDesc.isHighDetail;
     this.hasVertexColor      = shapeDesc.hasVertexColor;
     this.allWhite            = shapeDesc.allWhite;
     this.isDoubleSided       = shapeDesc.isDoubleSided;
     this.isAlpha             = shapeDesc.isAlpha;
     this.isDecal             = shapeDesc.isDecal;
     this.enableParent        = shapeDesc.enableParent;
     this.TextureClampMode    = shapeDesc.TextureClampMode;
     this.boundingBox         = new BBox();
     this.x           = shapeDesc.x;
     this.y           = shapeDesc.y;
     this.segments    = new List <SegmentDesc>();
     this.translation = shapeDesc.translation;
     this.rotation    = shapeDesc.rotation;
     this.scale       = shapeDesc.scale;
 }
 private void GenerateSegments(QuadDesc curQuad, ref ShapeDesc shape)
 {
     // use x, y of object instead of boundingbox center to determine segment
     int num1 = (int)((double)shape.x / ((double)this.quadOffset / 4.0));
     int num2 = (int)((double)shape.y / ((double)this.quadOffset / 4.0));
     if (num1 > 3)
         num1 = 3;
     if (num1 < 0)
         num1 = 0;
     if (num2 > 3)
         num2 = 3;
     if (num2 < 0)
         num2 = 0;
     SegmentDesc segmentDesc = new SegmentDesc();
     segmentDesc.id = 4 * num1 + num2;
     segmentDesc.startTriangle = 0U;
     segmentDesc.numTriangles = shape.data.GetNumTriangles();
     shape.segments = new List<SegmentDesc>();
     shape.segments.Add(segmentDesc);
 }
 private ShapeDesc TransformShape(QuadDesc quad, StaticDesc stat, NiFile file, NiTriBasedGeom geom, Matrix44 parentTransform, float parentScale)
 {
     BBox bbox = new BBox(float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue);
     ShapeDesc shape1 = new ShapeDesc();
     NiTriShape shape2;
     NiTriShapeData data = new NiTriShapeData();
     //Console.WriteLine("Reading block #" + geom.GetData());
     if (geom.GetClassName() == "NiTriStrips")
     {
         shape2 = new NiTriShape(geom);
         data = new NiTriShapeData((NiTriStripsData)file.GetBlockAtIndex(geom.GetData()));
     }
     else if (geom.GetClassName() == "BSLODTriShape")
     {
         shape2 = new NiTriShape(geom);
         data = (NiTriShapeData)file.GetBlockAtIndex(geom.GetData());
     }
     else
     {
         shape2 = new NiTriShape(geom);
         data = (NiTriShapeData)file.GetBlockAtIndex(geom.GetData());
     }
     if (verbose && !data.HasVertexColors() && ((this.GetShaderFlags2(file, shape2) & 32) == 32))
     {
         if (!stat.staticModels[this.quadIndex].Contains("glacierrubbletrim0"))
         {
             logFile.WriteLog("Vertex Colors Flag, but no vertex colors in " + stat.staticModels[this.quadIndex]);
         }
     }
     if (((int)data.GetBSNumUVSets() & 1) == 0)
         return shape1;
     float _x = stat.x - (float)quad.x * 4096f;
     float _y = stat.y - (float)quad.y * 4096f;
     Matrix33 matrix33_1 = new Matrix33(true);
     Matrix33 matrix33_2 = new Matrix33(true);
     Matrix33 matrix33_3 = new Matrix33(true);
     matrix33_1.SetRotationX(Utils.ToRadians(-stat.rotX));
     matrix33_2.SetRotationY(Utils.ToRadians(-stat.rotY));
     matrix33_3.SetRotationZ(Utils.ToRadians(-stat.rotZ));
     Matrix44 matrix44 = new Matrix44(new Matrix33(true) * matrix33_1 * matrix33_2 * matrix33_3, new Vector3(_x, _y, stat.z), 1f);
     List<Vector3> vertices = new List<Vector3>(data.GetVertices());
     List<Vector3> normals = new List<Vector3>(data.GetNormals());
     List<Vector3> tangents = new List<Vector3>(data.GetTangents());
     List<Vector3> bitangents = new List<Vector3>(data.GetBitangents());
     // generate tangents independent of fix tangents setting
     bool newtangents = false;
     bool newbitangents = false;
     if (this.generateTangents && data.HasNormals())
     {
         if (tangents.Count == 0)
         {
             newtangents = true;
             for (int index = 0; index < vertices.Count; ++index)
                 tangents.Add(new Vector3(0.0f, 0.0f, 0.0f));
         }
         if (bitangents.Count == 0)
         {
             newbitangents = true;
             for (int index = 0; index < vertices.Count; ++index)
                 bitangents.Add(new Vector3(0.0f, 0.0f, 0.0f));
         }
     }
     for (int index = 0; index < vertices.Count; ++index)
     {
         vertices[index] *= shape2.GetScale() * parentScale;
         vertices[index] *= shape2.GetTransform() * parentTransform;
         vertices[index] *= stat.scale;
         vertices[index] *= matrix44;
         if (data.HasNormals())
         {
             normals[index] *= parentTransform.RemoveTranslation() * shape2.GetTransform().RemoveTranslation();
             normals[index] *= matrix44.RemoveTranslation();
             // adjust tangents as well
             if (tangents.Count != 0)
             {
                 tangents[index] *= parentTransform.RemoveTranslation() * shape2.GetTransform().RemoveTranslation();
                 tangents[index] *= matrix44.RemoveTranslation();
             }
             // adjust bitangents as well
             if (bitangents.Count != 0)
             {
                 bitangents[index] *= parentTransform.RemoveTranslation() * shape2.GetTransform().RemoveTranslation();
                 bitangents[index] *= matrix44.RemoveTranslation();
             }
             // fix tangents when they were newly generated
             if (newtangents || newbitangents || this.fixTangents)
             {
                 Vector3 vector3_1 = Vector3.Cross(normals[index], new Vector3(0.0f, 0.0f, 1f));
                 Vector3 vector3_2 = Vector3.Cross(normals[index], new Vector3(0.0f, 1f, 0.0f));
                 if (newtangents)
                 {
                     tangents[index] = (double)vector3_1.Length > (double)vector3_2.Length ? vector3_1 : vector3_2;
                     tangents[index].Normalize();
                 }
                 if (newbitangents)
                 {
                     bitangents[index] = Vector3.Cross(normals[index], tangents[index]);
                     bitangents[index].Normalize();
                 }
             }
         }
         bbox.GrowByVertex(vertices[index]);
         vertices[index] /= (float)this.quadLevel;
     }
     data.SetVertices(vertices);
     if (data.HasNormals())
     {
         data.SetNormals(normals);
         data.SetHasTangents(false);
     }
     data.SetCenter(new Vector3((float)(((double)bbox.px1 + (double)bbox.px2) / 2.0), (float)(((double)bbox.py1 + (double)bbox.py2) / 2.0), (float)(((double)bbox.pz1 + (double)bbox.pz2) / 2.0)) / (float)this.quadLevel);
     data.SetRadius(this.CalcRadius(data));
     data.SetConsistencyFlags((ushort)0);
     data.SetKeepFlags((byte)51);
     data.SetSkyrimMaterial(0U);
     shape1.shape = shape2;
     shape1.data = data;
     // relative x, y for segment
     shape1.x = _x;
     shape1.y = _y;
     shape1.boundingBox = bbox;
     //Console.WriteLine(stat.staticName + " 2 " + stat.refID + " " + file + " " + shape2.GetName() + " ");
     shape1.textures = this.GetMeshTextures(file, shape2);
     shape1.material = stat.materialName;
     shape1.isHighDetail = false;
     if (useHDFlag)
     {
         if ((stat.refFlags & 131072) == 131072)
         {
             if (HDMeshList.Any(stat.staticModels[this.quadIndex].ToLower().Contains))
             {
                 shape1.isHighDetail = true;
             }
             else if (notHDMeshList.Any(stat.staticModels[this.quadIndex].ToLower().Contains))
             {
                 shape1.isHighDetail = false;
             }
             else
             {
                 shape1.isHighDetail = true;
             }
         }
     }
     // Shader Flags 2 SLSF2_Double_Sided
     shape1.isDoubleSided = (this.GetShaderFlags2(file, shape2) & 16) == 16;
     // clamp mode for atlas
     shape1.TextureClampMode = this.GetTextureClampMode(file, shape2);
     /*if ((this.GetShaderFlags1(file, shape2) & 1) == 1)
     {
         //logFile.WriteLog("Specular" + stat.staticModels[this.quadIndex]);
     }*/
     if (AtlasList.Contains(shape1.textures[0]))
     {
         if (this.UVAtlas(data, shape1.textures[0], stat))
         {
             string[] strArray = new string[2];
             strArray[0] = AtlasList.Get(shape1.textures[0]).AtlasTexture;
             strArray[1] = AtlasList.Get(shape1.textures[0]).AtlasTextureN;
             shape1.textures = strArray;
             shape1.TextureClampMode = 0U;
             shape1.isHighDetail = false;
         }
     }
     else
     {
         if (useOptimizer && quadLevel != 4 && shape1.textures[0].ToLower().Contains("mountainslab01"))
         {
             string[] strArray = new string[2];
             strArray[0] = "textures\\landscape\\mountains\\mountainslab02.dds";
             strArray[1] = "textures\\landscape\\mountains\\mountainslab02_n.dds";
             shape1.textures = strArray;
         }
         if (notHDTextureList.Any(shape1.textures[0].Contains))
         {
             if (this.verbose)
             {
                 logFile.WriteLog("No atlas for " + shape1.textures[0] + " in " + stat.staticModels[this.quadIndex]);
             }
         }
         else
         {
             if (!useHDFlag)
             {
                 shape1.isHighDetail = true;
             }
         }
     }
     if (notHDTextureList.Any(shape1.textures[0].Contains))
     {
         shape1.isHighDetail = false;
     }
     if (HDTextureList.Any(shape1.textures[0].Contains))
     {
         shape1.isHighDetail = true;
     }
     if (shape1.textures[0].Contains("dyndolod\\lod"))
     {
         shape1.TextureClampMode = 0U;
         shape1.isHighDetail = false;
     }
     if (!this.generateVertexColors || (this.quadLevel != 4 && !shape1.isHighDetail))
     {
         data.SetHasVertexColors(false);
         shape1.hasVertexColor = false;
     }
     if (this.generateTangents)
     {
         //shape1.material.Length != 0
         if (!useOptimizer || (useOptimizer && (this.quadLevel == 4 || shape1.isHighDetail)))
         {
             data.SetTangents(tangents);
             data.SetBitangents(bitangents);
         }
     }
     if (this.removeUnseenFaces && quad.hasTerrainVertices)
     {
         this.RemoveUnseenFaces(quad, data, shape1);
         if ((int)data.GetNumTriangles() == 0)
             return (ShapeDesc)null;
     }
     else
     {
         quad.outValues.totalTriCount += data.GetNumTriangles();
         quad.outValues.reducedTriCount += data.GetNumTriangles();
     }
     this.GenerateSegments(quad, ref shape1);
     return shape1;
 }
        private void RemoveUnseenFaces(QuadDesc quad, NiTriShapeData data, ShapeDesc shape)
        {
            List<Triangle> triangles = data.GetTriangles();
            List<Vector3> vertices = data.GetVertices();
            int count = triangles.Count;
            quad.outValues.totalTriCount += count;
            int loops = 0;
            if (this.removeUnderwaterFaces)
            {
                loops = 1;
            }
            for (int loop = 0; loop <= loops; loop++)
            {
                for (int index = 0; index < triangles.Count; ++index)
                {
                    QuadDesc quadCurrent = new QuadDesc();
                    List<Triangle> trianglesCompare = new List<Triangle>();
                    List<Vector3> verticesCompare = new List<Vector3>();
                    bool[] vertexBelow = new bool[3];
                    for (int index1 = 0; index1 < 3; index1++)
                    {
                        Vector3 vertex = vertices[triangles[index][index1]];
                        float x = vertex[0];
                        float y = vertex[1];
                        int vertexQuadx = quad.x + cellquad(x * quadLevel, southWestX);
                        int vertexQuady = quad.y + cellquad(y * quadLevel, southWestY);
                        if (quad.x != vertexQuadx || quad.y != vertexQuady)
                        {
                            for (int index3 = 0; index3 < this.quadList.Count; ++index3)
                            {
                                if (vertexQuadx == this.quadList[index3].x && vertexQuady == this.quadList[index3].y)
                                {
                                    quadCurrent = this.quadList[index3];
                                    x -= (vertexQuadx - quad.x) / quadLevel * 4096;
                                    y -= (vertexQuady - quad.y) / quadLevel * 4096;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            quadCurrent = quad;
                        }
                        if (!quadCurrent.hasTerrainVertices)
                        {
                            continue;
                        }
                        Vector3 vertex1 = new Vector3(x, y, vertex[2]);
                        List<Triangle> trianglesTerrain = new List<Triangle>();
                        List<Vector3> verticesTerrain = new List<Vector3>();
                        if (this.removeUnderwaterFaces && loop == 0)
                        {
                            if (quadCurrent.waterQuadTree != null)
                            {
                                trianglesTerrain = quadCurrent.waterQuadTree.entirequad.triangles;
                                verticesTerrain = quadCurrent.waterQuadTree.vertices;
                            }
                        }
                        else
                        {
                            trianglesTerrain = quadCurrent.terrainQuadTree.GetSegment(vertex1, quadLevel);
                            verticesTerrain = quadCurrent.terrainQuadTree.vertices;
                        }
                        if (trianglesTerrain == null)
                        {
                            vertexBelow[index1] = true;
                        }
                        else
                        {
                            if (trianglesTerrain.Count != 0)
                            {
                                float num1 = float.MaxValue;
                                num1 = GetTriangleHeight(verticesTerrain, trianglesTerrain, vertex1);
                                if (vertex1[2] < num1)
                                {
                                    vertexBelow[index1] = true;
                                }
                            }
                        }
                    }
                    if (vertexBelow[0] && vertexBelow[1] && vertexBelow[2])
                    {
                        triangles.RemoveAt(index);
                        --index;
                    }
                }
            }

            // remove elements from other lists too
            if (triangles.Count != 0 && triangles.Count != count)
            {
                Dictionary<ushort, ushort> dictionary = new Dictionary<ushort, ushort>();
                List<Vector3> vertices2 = new List<Vector3>();
                List<UVCoord> uvcoords = data.GetUVCoords();
                List<UVCoord> uvcoords2 = new List<UVCoord>();
                List<Color4> vertexcolors = data.GetVertexColors();
                List<Color4> vertexcolors2 = new List<Color4>();
                List<Vector3> normals = data.GetNormals();
                List<Vector3> normals2 = new List<Vector3>();
                List<Vector3> tangents = data.GetTangents();
                List<Vector3> tangents2 = new List<Vector3>();
                List<Vector3> bitangents = data.GetBitangents();
                List<Vector3> bitangents2 = new List<Vector3>();
                ushort index2 = 0;
                bool vertexcolors_allwhite = true;
                for (int index = 0; index < triangles.Count; ++index)
                {
                    for (int index3 = 0; index3 < 3; ++index3)
                    {
                        ushort v1 = triangles[index][index3];
                        if (!dictionary.ContainsKey(v1))
                        {
                            dictionary.Add(v1, index2);
                            ++index2;
                            if (vertices.Count != 0)
                            {
                                vertices2.Add(vertices[v1]);
                            }
                            if (uvcoords.Count != 0)
                            {
                                uvcoords2.Add(uvcoords[v1]);
                            }
                            if (vertexcolors.Count != 0)
                            {
                                float r = vertexcolors[v1][0];
                                float g = vertexcolors[v1][1];
                                float b = vertexcolors[v1][2];
                                if (r != 1f || b != 1f || g != 1f)
                                {
                                    vertexcolors_allwhite = false;
                                }
                                vertexcolors2.Add(vertexcolors[v1]);
                            }
                            if (normals.Count != 0)
                            {
                                normals2.Add(normals[v1]);
                            }
                            if (tangents.Count != 0)
                            {
                                tangents2.Add(tangents[v1]);
                            }
                            if (bitangents.Count != 0)
                            {
                                bitangents2.Add(bitangents[v1]);
                            }
                        }
                    }
                }
                // update indexes of triangles
                for (int index = 0; index < triangles.Count; ++index)
                {
                    for (int index3 = 0; index3 < 3; ++index3)
                    {
                        ushort key = triangles[index][index3];
                        if (!dictionary.ContainsKey(key))
                        {
                            this.logFile.WriteLog("no index for " + key);
                        }
                        ushort v1 = dictionary[key];
                        Triangle triangle;
                        (triangle = triangles[index])[index3] = (v1);
                    }
                }
                if (vertices2.Count != 0)
                {
                    data.SetVertices(vertices2);
                }
                if (uvcoords2.Count != 0)
                {
                    data.SetUVCoords(uvcoords2);
                }
                if (vertexcolors2.Count != 0)
                {
                    if (vertexcolors_allwhite)
                    {
                        data.SetHasVertexColors(false);
                        shape.hasVertexColor = false;
                    }
                    else
                    {
                        data.SetHasVertexColors(true);
                        shape.hasVertexColor = true;
                        data.SetVertexColors(vertexcolors2);
                    }
                }
                if (normals2.Count != 0)
                {
                    data.SetNormals(normals2);
                }
                if (tangents2.Count != 0)
                {
                    data.SetTangents(tangents2);
                }
                if (bitangents2.Count != 0)
                {
                    data.SetBitangents(bitangents2);
                }
            }
            quad.outValues.reducedTriCount += triangles.Count;
            data.SetTriangles(triangles);
        }
 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);
         }
     }
 }