/* Save the new level */ private void saveLevel_Click(object sender, EventArgs e) { if (levelName.Text == "") { MessageBox.Show("Level must have a name!", "No level name.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } for (int i = 0; i < LevelFile.GetData().Count; i++) { if (LevelFile.GetData()[i].levelName == levelName.Text) { MessageBox.Show("Level name must be unique!", "Level name already exists.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } string pathToEnv = "ENV/PRODUCTION/" + levelName.Text.Trim().ToUpper().Replace(' ', '_') + "/"; LevelFile.GetData().Add(new Level(levelName.Text, "DATA/" + pathToEnv, (LevelType)levelType.SelectedIndex)); LevelFile.SaveData(); Directory.CreateDirectory(pathToEnv); File.WriteAllBytes(pathToEnv + "COMMANDS.BIN", Properties.Resources.COMMANDS_BIN); File.WriteAllBytes(pathToEnv + "COMMANDS.JSON", Properties.Resources.COMMANDS_JSON); ModelsFile.GetFiles().Clear(); ModelsFile.Save(pathToEnv); TexturesFile.GetFiles().Clear(); TexturesFile.Save(pathToEnv); MessageBox.Show("Saved!", "Complete.", MessageBoxButtons.OK, MessageBoxIcon.Information); this.Close(); }
private void ReloadList() { modelList.Items.Clear(); ModelsFile.Load(levelPath); TexturesFile.Load(levelPath); foreach (Model model in ModelsFile.GetFiles()) { if (!modelList.Items.Contains(model.modelName)) { modelList.Items.Add(model.modelName); //We share names between LOD0&1, so don't duplicate } } }
/* Import */ private void importModel_Click(object sender, EventArgs e) { if (modelName.Text == "") { MessageBox.Show("Name cannot be blank!", "Invalid input", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (pathToLod0.Text == "" || pathToLod1.Text == "") { MessageBox.Show("Models must be selected for both LOD 0 & 1!", "Invalid input", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } for (int i = 0; i < ModelsFile.GetFiles().Count; i++) { if (ModelsFile.GetFiles()[i].modelName == modelName.Text) { MessageBox.Show("Model name must be unique!", "Invalid input", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } Model newModelLOD0 = new Model(modelName.Text, LevelOfDetail.HIGH); if (!newModelLOD0.LoadFromOBJ(pathToLod0.Text)) { MessageBox.Show("Model selected for LOD0 is invalid!\nModel must be triangulated and contain UV data.", "Invalid LOD0", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Model newModelLOD1 = new Model(modelName.Text, LevelOfDetail.LOW); if (!newModelLOD1.LoadFromOBJ(pathToLod1.Text)) { MessageBox.Show("Model selected for LOD1 is invalid!\nModel must be triangulated and contain UV data.", "Invalid LOD0", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } ModelsFile.AddFile(newModelLOD0); TexturesFile.AddFilesFromModel(newModelLOD0); ModelsFile.AddFile(newModelLOD1); TexturesFile.AddFilesFromModel(newModelLOD1); MessageBox.Show("Model successfully imported.", "Import complete", MessageBoxButtons.OK, MessageBoxIcon.Information); this.Close(); }
/* Delete a model from the level */ private void deleteModel_Click(object sender, EventArgs e) { if (modelList.SelectedIndex == -1) { return; } for (int i = 0; i < ModelsFile.GetFiles().Count; i++) { if (ModelsFile.GetFiles()[i].modelName == modelList.Items[modelList.SelectedIndex].ToString()) { ModelsFile.RemoveFile(ModelsFile.GetFiles()[i]); } } Texture[] prevTexs = new Texture[TexturesFile.GetFiles().Count]; TexturesFile.GetFiles().CopyTo(prevTexs); TexturesFile.GetFiles().Clear(); for (int i = 0; i < ModelsFile.GetFiles().Count; i++) { for (int x = 0; x < ModelsFile.GetFiles()[i].modelParts.Count; x++) { for (int y = 0; y < prevTexs.Length; y++) { if (prevTexs[y].textureID == ModelsFile.GetFiles()[i].modelParts[x].thisMaterial.textureID) { TexturesFile.AddFile(prevTexs[y]); break; } } } } ModelsFile.Save(levelPath); TexturesFile.Save(levelPath); ReloadList(); }
public bool LoadFromOBJ(string path) { loadedFromObj = true; //Parse the OBJ to vertices/texcoords/normals List <string> objFile = File.ReadAllLines(path).ToList(); List <Vector3> verts = new List <Vector3>(); List <Vector2> coords = new List <Vector2>(); List <Vector3> normals = new List <Vector3>(); List <Face> faces = new List <Face>(); string materialLibrary = ""; string thisMaterial = ""; foreach (string str in objFile) { if (str.Length > 0) { if (str.Length > 7 && str.Substring(0, 7) == "mtllib ") { materialLibrary = str.Substring(7); } else if (str.Length > 2 && str.Substring(0, 2) == "v ") { string _str = str.Substring(2); string thisPos = ""; Vector3 thisVertPos = new Vector3(); int vertPosIndex = 0; for (int i = 0; i < _str.Length + 1; i++) { if (i == _str.Length || _str[i] == ' ') { if (thisPos == "") { continue; } if (vertPosIndex == 0) { thisVertPos.x = Convert.ToSingle(thisPos); } if (vertPosIndex == 1) { thisVertPos.y = Convert.ToSingle(thisPos); } if (vertPosIndex == 2) { thisVertPos.z = Convert.ToSingle(thisPos); } vertPosIndex++; thisPos = ""; continue; } thisPos += _str[i]; } verts.Add(thisVertPos); } else if (str.Length > 3 && str.Substring(0, 3) == "vt ") { string _str = str.Substring(3); string thisPos = ""; Vector2 thisTexCoord = new Vector2(); int texCoordIndex = 0; for (int i = 0; i < _str.Length + 1; i++) { if (i == _str.Length || _str[i] == ' ') { if (thisPos == "") { continue; } if (texCoordIndex == 0) { thisTexCoord.x = Convert.ToSingle(thisPos); } if (texCoordIndex == 1) { thisTexCoord.y = Convert.ToSingle(thisPos) * -1; } texCoordIndex++; thisPos = ""; continue; } thisPos += _str[i]; } coords.Add(thisTexCoord); } else if (str.Length > 3 && str.Substring(0, 3) == "vn ") { string _str = str.Substring(3); string thisPos = ""; Vector3 thisNormal = new Vector3(); int normalIndex = 0; for (int i = 0; i < _str.Length + 1; i++) { if (i == _str.Length || _str[i] == ' ') { if (thisPos == "") { continue; } if (normalIndex == 0) { thisNormal.x = Convert.ToSingle(thisPos); } if (normalIndex == 1) { thisNormal.y = Convert.ToSingle(thisPos); } if (normalIndex == 2) { thisNormal.z = Convert.ToSingle(thisPos); } normalIndex++; thisPos = ""; continue; } thisPos += _str[i]; } normals.Add(thisNormal); } else if (str.Length > 7 && str.Substring(0, 7) == "usemtl ") { thisMaterial = str.Substring(7); } else if (str.Length > 2 && str.Substring(0, 2) == "f ") { string _str = str.Substring(2); Face thisFace = new Face(); VertexGroup thisVert = new VertexGroup(); VertReaderType next = VertReaderType.VERTEX; string currentNumber = ""; for (int i = 0; i < _str.Length + 1; i++) { if (i == _str.Length || _str[i] == '/' || _str[i] == ' ') { if (currentNumber == "") { if (verts.Count == 0) { return(false); } if (coords.Count == 0) { return(false); } if (normals.Count == 0) { return(false); } continue; } switch (next) { case VertReaderType.VERTEX: thisVert.v = Convert.ToInt32(currentNumber); next = VertReaderType.COORDINATE; break; case VertReaderType.COORDINATE: thisVert.c = Convert.ToInt32(currentNumber); next = VertReaderType.NORMAL; break; case VertReaderType.NORMAL: thisVert.n = Convert.ToInt32(currentNumber); next = VertReaderType.VERTEX; break; } thisVert.set = true; currentNumber = ""; if (i < _str.Length && _str[i] == '/') { continue; } if (!thisVert.set) { continue; } thisFace.verts.Add(thisVert); thisVert = new VertexGroup(); continue; } currentNumber += _str[i]; } if (thisFace.verts.Count != 3) { return(false); } thisFace.materialName = thisMaterial; faces.Add(thisFace); } } } //Open and parse MTL if it exists List <ModelMaterialData> materials = new List <ModelMaterialData>(); if (materialLibrary != "") { //Get model path parts List <string> modelPath = new List <string>(); string currentPath = ""; for (int i = 0; i < path.Length; i++) { if (path[i] == '/' || path[i] == '\\') { modelPath.Add(currentPath); currentPath = ""; continue; } currentPath += path[i]; } modelPath.Add(currentPath); //Get material path parts List <string> mtlPath = new List <string>(); currentPath = ""; for (int i = 0; i < materialLibrary.Length; i++) { if (materialLibrary[i] == '/' || materialLibrary[i] == '\\') { mtlPath.Add(currentPath); currentPath = ""; continue; } currentPath += materialLibrary[i]; } mtlPath.Add(currentPath); //Reconstruct a good path to MTL using model path string pathToMtl = ""; if (mtlPath.Count == 1) { if (modelPath.Count == 1) { pathToMtl = mtlPath[0]; } else { for (int i = 0; i < modelPath.Count - 1; i++) { pathToMtl += modelPath[i] + "/"; } pathToMtl += mtlPath[0]; } } else { pathToMtl = materialLibrary; } //Open MTL List <string> mtlFile = File.ReadAllLines(pathToMtl).ToList(); //Parse MTL into materials ModelMaterialData currentMaterial = new ModelMaterialData(); foreach (string str in mtlFile) { if (str.Length > 0) { if (str.Length > 7 && str.Substring(0, 7) == "newmtl ") { if (currentMaterial.materialName != "") { materials.Add(currentMaterial); currentMaterial = new ModelMaterialData(); } currentMaterial.materialName = str.Substring(7); } else if (str.Length > 3 && str.Substring(0, 3) == "Kd ") { string _str = str.Substring(3); string thisColour = ""; int thisColourIndex = 0; for (int i = 0; i < _str.Length + 1; i++) { if (i == _str.Length || _str[i] == ' ') { if (thisColour == "") { continue; } if (thisColourIndex == 0) { currentMaterial.colourTint.r = Convert.ToSingle(thisColour); } if (thisColourIndex == 1) { currentMaterial.colourTint.g = Convert.ToSingle(thisColour); } if (thisColourIndex == 2) { currentMaterial.colourTint.b = Convert.ToSingle(thisColour); } thisColourIndex++; thisColour = ""; continue; } thisColour += _str[i]; } } else if (str.Length > 2 && str.Substring(0, 2) == "d ") { currentMaterial.colourTint.a = Convert.ToSingle(str.Substring(2)); } else if (str.Length > 7 && str.Substring(0, 7) == "map_Kd ") { currentMaterial.texturePath = str.Substring(7); if (currentMaterial.texturePath[1] == ':') { //Debug::Log("Texture uses system path! " + currentMaterial.texturePath); } else { string texPrepend = ""; for (int i = pathToMtl.Length - 1; i >= 0; i--) { if (pathToMtl[i] == '/' || pathToMtl[i] == '\\') { texPrepend = pathToMtl.Substring(0, i); break; } } currentMaterial.texturePath = texPrepend + "/" + currentMaterial.texturePath; } if (File.Exists(currentMaterial.texturePath)) { currentMaterial.textureID = TexturesFile.AddFile(new Texture(File.ReadAllBytes(currentMaterial.texturePath).ToList())); } else { //show error string dfg = ""; } } } } if (currentMaterial.materialName != "") { materials.Add(currentMaterial); } } //Create vertex and index arrays from the data ModelPart modelPart = new ModelPart(); int totalIndex = 0; for (int i = 0; i < faces.Count; i++) { for (int x = 0; x < faces[i].verts.Count; x++) { SimpleVertex thisVertInfo = new SimpleVertex(); thisVertInfo.Pos = verts[faces[i].verts[x].v - 1]; thisVertInfo.Tex = coords[faces[i].verts[x].c - 1]; thisVertInfo.Normal = normals[faces[i].verts[x].n - 1]; if (modelPart.thisMaterial.materialName != faces[i].materialName) { if (totalIndex != 0) { modelParts.Add(modelPart); modelPart = new ModelPart(); } for (int y = 0; y < materials.Count; y++) { if (materials[y].materialName == faces[i].materialName) { modelPart.thisMaterial = materials[y]; break; } } } modelPart.compVertices.Add(thisVertInfo); modelPart.compIndices.Add(totalIndex); totalIndex++; } } modelParts.Add(modelPart); return(true); }
/* Reload GUI List */ private void SaveAndReloadList(object sender, EventArgs e) { ModelsFile.Save(levelPath); TexturesFile.Save(levelPath); ReloadList(); }