public void GenerateLOD(int index, int level, List<StaticDesc> statics) { this.quadIndex = index; if (Game.Mode == "fnv") { this.quadLevel = 4; this.quadOffset = 16384f; if (level == 4) { return; } } else { this.quadLevel = level * 4; this.quadOffset = (float)level * 16384f; } if (this.lodLevelToGenerate != -1 && this.lodLevelToGenerate != this.quadLevel) return; //Console.WriteLine("Level=" + LODLevel + " quadLevel=" + quadLevel + " offset=" + quadOffset); List<QuadDesc> list1 = this.SortMeshesIntoQuads(statics); if (this.removeUnseenFaces) { for (int index1 = 0; index1 < list1.Count; index1++) { QuadDesc quad = list1[index1]; if (this.LoadTerrainQuad(quad, out quad.terrainQuadTree, out quad.waterQuadTree, out quad.boundingBox)) { quad.hasTerrainVertices = true; list1[index1] = quad; } } } this.quadList = list1; List<Thread> list2 = new List<Thread>(); for (int index1 = 0; index1 < list1.Count; ++index1) { QuadDesc quadDesc = list1[index1]; if ((this.lodX == -1 || this.lodX == quadDesc.x) && (this.lodY == -1 || this.lodY == quadDesc.y)) { while (list2.Count == 8) { for (int index2 = 0; index2 < list2.Count; ++index2) { if (!list2[index2].IsAlive) { list2.RemoveAt(index2); --index2; } } } list2.Add(new Thread((ParameterizedThreadStart)(state => { QuadDesc quad = (QuadDesc)state; if (this.verbose) { this.logFile.WriteLog("Started LOD level " + this.quadLevel.ToString() + " coord [" + quad.x.ToString() + ", " + quad.y.ToString() + "]"); } NiFile file = new NiFile(); NiNode rootNiNode = new NiNode(); BSMultiBoundNode rootBSMultiBoundNode = new BSMultiBoundNode(); if (Game.Mode != "fnv") { file.AddBlock((NiObject)rootNiNode); rootNiNode.SetNameIndex(file.AddString("obj")); } else { file.AddBlock((NiObject)rootBSMultiBoundNode); } List<ShapeDesc> shapes = new List<ShapeDesc>(); for (int index11 = 0; index11 < quad.statics.Count; ++index11) { if (!(quad.statics[index11].staticModels[index] == "")) { if (Game.Mode == "fnv") { shapes.AddRange((IEnumerable<ShapeDesc>)this.ParseNif(quad, quad.statics[index11], index, file, rootNiNode)); } else { shapes.AddRange((IEnumerable<ShapeDesc>)this.ParseNif(quad, quad.statics[index11], index, file, rootBSMultiBoundNode)); } } } if (this.mergeShapes) this.MergeNodes(shapes); if (Game.Mode != "fnv") { this.CreateLODNodes(file, rootNiNode, quad, shapes); if ((int)rootNiNode.GetNumChildren() == 0) { //logFile.WriteLog("quad empty " + quadLevel + " " + quad.x + ", " + quad.y); //return; } } else { this.CreateLODNodesFNV(file, rootBSMultiBoundNode, quad, shapes); if ((int)rootBSMultiBoundNode.GetNumChildren() == 0) { //logFile.WriteLog("quad empty " + quadLevel + " " + quad.x + ", " + quad.y); return; } } if (Game.Mode == "fnv") { if (level == 1) { file.Write(this.outputDir + (object)"\\" + this.worldspaceName + ".Level4.X" + quad.x.ToString() + ".Y" + quad.y.ToString() + ".nif", logFile); } else { file.Write(this.outputDir + (object)"\\" + this.worldspaceName + ".Level4.High.X" + quad.x.ToString() + ".Y" + quad.y.ToString() + ".nif", logFile); } } else { file.Write(this.outputDir + (object)"\\" + this.worldspaceName + "." + this.quadLevel.ToString() + "." + quad.x.ToString() + "." + quad.y.ToString() + ".bto", logFile); } this.logFile.WriteLog("Finished LOD level " + (object)this.quadLevel.ToString() + " coord [" + quad.x.ToString() + ", " + quad.y.ToString() + "] [" + quad.outValues.totalTriCount.ToString() + "/" + quad.outValues.reducedTriCount.ToString() + "]"); }))); list2[list2.Count - 1].Start((object)quadDesc); } } while (list2.Count > 0) { for (int index1 = 0; index1 < list2.Count; ++index1) { if (!list2[index1].IsAlive) { list2.RemoveAt(index1); --index1; } } } int num1 = 0; int num2 = 0; foreach (QuadDesc quadDesc in list1) { num1 += quadDesc.outValues.totalTriCount; num2 += quadDesc.outValues.reducedTriCount; } this.logFile.WriteLog("LOD level " + this.quadLevel.ToString() + " total triangles " + num1.ToString() + " reduced to " + num2.ToString()); }
public void GenerateTest(string strfile, LogFile logFile) { NiFile file = new NiFile(); NiNode rootNode = new NiNode(); file.AddBlock((NiObject)rootNode); this.quadLevel = 4; this.quadOffset = 16384f; QuadDesc quad = new QuadDesc(); quad.x = 0; quad.y = 0; quad.statics = new List<StaticDesc>(); StaticDesc curStat = new StaticDesc(); curStat.refID = "0"; curStat.rotX = 0.0f; curStat.rotY = 0.0f; curStat.rotZ = 0.0f; curStat.scale = 1f; curStat.x = 0.0f; curStat.y = 0.0f; curStat.z = 0.0f; curStat.staticName = "Test"; curStat.staticFullModel = strfile; curStat.staticModels = new string[3]; curStat.staticModels[0] = strfile; curStat.staticModels[1] = strfile; curStat.staticModels[2] = strfile; quad.statics.Add(curStat); List<ShapeDesc> shapes = this.ParseNif(quad, curStat, 0, file, rootNode); this.MergeNodes(shapes); for (int index = 0; index < shapes.Count; ++index) { BSSegmentedTriShape segmentedTriShape = new BSSegmentedTriShape((NiGeometry)shapes[index].shape); segmentedTriShape.SetRotation(new Matrix33(true)); segmentedTriShape.SetTranslation(new Vector3(0.0f, 0.0f, 0.0f)); rootNode.AddChild(file.AddBlock((NiObject)segmentedTriShape)); segmentedTriShape.SetData(file.AddBlock((NiObject)shapes[index].data)); } file.Write(this.outputDir + "\\" + this.worldspaceName + ".test.nif", logFile); }