/// <summary>Gets a static model you loaded that you have loaded.</summary> /// <param name="staticModelId">The name id of the model you wish to obtain.</param> /// <returns>The desired static model if it exists.</returns> public static StaticModel GetModel(string staticModelId) { StaticModel modelToGet = _staticModelDatabase.Get<string>(staticModelId, StaticModel.CompareTo); AvlTree<StaticMesh> meshes = new AvlTree_Linked<StaticMesh>(StaticMesh.CompareTo); modelToGet.Meshes.Foreach ( (StaticMesh mesh) => { mesh.Texture.ExistingReferences++; mesh.ExistingReferences++; meshes.Add(mesh); } ); return new StaticModel(modelToGet.Id, meshes); }
/// <summary>Gets a static model you loaded that you have loaded.</summary> /// <param name="staticModelId">The name id of the model you wish to obtain.</param> /// <returns>The desired static model if it exists.</returns> public static StaticModel GetModel(string staticModelId) { StaticModel modelToGet = _staticModelDatabase.Get <string>(staticModelId, StaticModel.CompareTo); AvlTree <StaticMesh> meshes = new AvlTree_Linked <StaticMesh>(StaticMesh.CompareTo); modelToGet.Meshes.Foreach ( (StaticMesh mesh) => { mesh.Texture.ExistingReferences++; mesh.ExistingReferences++; meshes.Add(mesh); } ); return(new StaticModel(modelToGet.Id, meshes)); }
/// <summary>DONT USE THIS FUNCTION!!! This is an experimental file type I may use in the future.</summary> public static StaticModel LoadSevenModelFromDisk(string staticModelId, string filePath) { // These are temporarily needed lists for storing the parsed data as you read it. List_Array <float> fileVerteces = new List_Array <float>(1000); List_Array <float> fileNormals = new List_Array <float>(1000); List_Array <float> fileTextureCoordinates = new List_Array <float>(1000); List_Array <int> fileIndeces = new List_Array <int>(1000); Texture texture = null; string meshName = "defaultMeshName"; AvlTree <StaticMesh> meshes = new AvlTree_Linked <StaticMesh>(StaticMesh.CompareTo); // Lets read the file and handle each line separately for ".obj" files using (StreamReader reader = new StreamReader(filePath)) { while (!reader.EndOfStream) { string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (parameters[0]) { // MeshName case "m": meshName = parameters[1]; break; // Texture case "t": if (!TextureManager.TextureExists(parameters[1])) { TextureManager.LoadTexture(parameters[1], parameters[2]); } texture = TextureManager.Get(parameters[1]); break; // Vertex case "v": fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Texture Coordinate case "vt": fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); break; // Normal case "vn": fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Face case "f": // DEVELOPMENT NOTE: The following triangulation algorithm works, but it // could be optimized beyond its current state. // The following variables are used for triangulation of a polygon // with greater than three verteces. int firstPosition, firstTextureCoordinates, firstNormal, secondPosition, secondTextureCoordinates, secondNormal; if (parameters.Length > 3) { // First Vertex (we have to store it this way for possible triangulation) string[] indexReferences = parameters[1].Split('/'); if (indexReferences[0] == "") { throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); } firstPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture); if (indexReferences[1] != "") { firstTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture); } else { firstTextureCoordinates = 0; } if (indexReferences[2] != "") { firstNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture); } else { firstNormal = 0; } // Second Vertex (we have to store it this way for possible triangulation) indexReferences = parameters[2].Split('/'); if (indexReferences[0] == "") { throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); } secondPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture); if (indexReferences[1] != "") { secondTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture); } else { secondTextureCoordinates = 0; } if (indexReferences[2] != "") { secondNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture); } else { secondNormal = 0; } } else { throw new StaticModelManagerException("ERROR: obj file corrupted:" + filePath); } // Verteces past the first two for (int i = 3; i < parameters.Length; i++) { // Triangulate using the first two verteces fileIndeces.Add(firstPosition); fileIndeces.Add(firstTextureCoordinates); fileIndeces.Add(firstNormal); fileIndeces.Add(secondPosition); fileIndeces.Add(secondTextureCoordinates); fileIndeces.Add(secondNormal); // Now include the new vertex string[] indexReferences = parameters[i].Split('/'); if (indexReferences[0] == "") { throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); } fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); if (indexReferences[1] != "") { fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); } else { fileIndeces.Add(0); } if (indexReferences[2] != "") { fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); } else { fileIndeces.Add(0); } } break; //// OLD VERSION OF THE FACE PARSING //// NOTE! This does not yet triangulate faces //// NOTE! This needs all possible values (position, texture mapping, and normal). //for (int i = 1; i < parameters.Length; i++) //{ // string[] indexReferences = parameters[i].Split('/'); // fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); // if (indexReferences[1] != "") // fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); // else // fileIndeces.Add(0); // if (indexReferences[2] != "") // fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); // else // fileIndeces.Add(0); //} //break; // End Current Mesh case "7": // Pull the final vertex order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] verteces = new float[fileIndeces.Count]; for (int i = 0; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; verteces[i] = fileVerteces[index]; verteces[i + 1] = fileVerteces[index + 1]; verteces[i + 2] = fileVerteces[index + 2]; } // Pull the final texture coordinates order out of the indexed references // Note, arrays start at 0 but the index references start at 1 // Note, every other value needs to be inverse (not sure why but it works :P) float[] textureCoordinates = new float[fileIndeces.Count / 3 * 2]; for (int i = 1; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 2; int offset = (i - 1) / 3; textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index]; textureCoordinates[i - offset] = 1 - fileTextureCoordinates[(index + 1)]; } // Pull the final normal order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] normals = new float[fileIndeces.Count]; for (int i = 2; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; normals[i - 2] = fileNormals[index]; normals[i - 1] = fileNormals[(index + 1)]; normals[i] = fileNormals[(index + 2)]; } int vertexBufferId; if (verteces != null) { // Declare the buffer GL.GenBuffers(1, out vertexBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId); // Initialize the buffer values GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (verteces.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("Vertex array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { vertexBufferId = 0; } int textureCoordinateBufferId; if (textureCoordinates != null) { // Declare the buffer GL.GenBuffers(1, out textureCoordinateBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId); // Initialize the buffer values GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (textureCoordinates.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("TexCoord array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { textureCoordinateBufferId = 0; } int normalBufferId; if (normals != null) { // Declare the buffer GL.GenBuffers(1, out normalBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId); // Initialize the buffer values GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (normals.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("Normal array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { normalBufferId = 0; } meshes.Add( new StaticMesh( meshName, staticModelId + "sub" + meshes.Count, vertexBufferId, 0, // Obj files don't support vertex colors textureCoordinateBufferId, normalBufferId, 0, // I don't support an index buffer at this time verteces.Length, texture)); fileVerteces.Clear(); fileNormals.Clear(); fileTextureCoordinates.Clear(); fileIndeces.Clear(); texture = null; break; } } } return(new StaticModel(staticModelId, meshes)); }
/// <summary>DONT USE THIS FUNCTION!!! This is an experimental file type I may use in the future.</summary> public static StaticModel LoadSevenModelFromDisk(string staticModelId, string filePath) { // These are temporarily needed lists for storing the parsed data as you read it. List_Array<float> fileVerteces = new List_Array<float>(1000); List_Array<float> fileNormals = new List_Array<float>(1000); List_Array<float> fileTextureCoordinates = new List_Array<float>(1000); List_Array<int> fileIndeces = new List_Array<int>(1000); Texture texture = null; string meshName = "defaultMeshName"; AvlTree<StaticMesh> meshes = new AvlTree_Linked<StaticMesh>(StaticMesh.CompareTo); // Lets read the file and handle each line separately for ".obj" files using (StreamReader reader = new StreamReader(filePath)) { while (!reader.EndOfStream) { string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (parameters[0]) { // MeshName case "m": meshName = parameters[1]; break; // Texture case "t": if (!TextureManager.TextureExists(parameters[1])) TextureManager.LoadTexture(parameters[1], parameters[2]); texture = TextureManager.Get(parameters[1]); break; // Vertex case "v": fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Texture Coordinate case "vt": fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); break; // Normal case "vn": fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Face case "f": // DEVELOPMENT NOTE: The following triangulation algorithm works, but it // could be optimized beyond its current state. // The following variables are used for triangulation of a polygon // with greater than three verteces. int firstPosition, firstTextureCoordinates, firstNormal, secondPosition, secondTextureCoordinates, secondNormal; if (parameters.Length > 3) { // First Vertex (we have to store it this way for possible triangulation) string[] indexReferences = parameters[1].Split('/'); if (indexReferences[0] == "") throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); firstPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture); if (indexReferences[1] != "") firstTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture); else firstTextureCoordinates = 0; if (indexReferences[2] != "") firstNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture); else firstNormal = 0; // Second Vertex (we have to store it this way for possible triangulation) indexReferences = parameters[2].Split('/'); if (indexReferences[0] == "") throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); secondPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture); if (indexReferences[1] != "") secondTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture); else secondTextureCoordinates = 0; if (indexReferences[2] != "") secondNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture); else secondNormal = 0; } else throw new StaticModelManagerException("ERROR: obj file corrupted:" + filePath); // Verteces past the first two for (int i = 3; i < parameters.Length; i++) { // Triangulate using the first two verteces fileIndeces.Add(firstPosition); fileIndeces.Add(firstTextureCoordinates); fileIndeces.Add(firstNormal); fileIndeces.Add(secondPosition); fileIndeces.Add(secondTextureCoordinates); fileIndeces.Add(secondNormal); // Now include the new vertex string[] indexReferences = parameters[i].Split('/'); if (indexReferences[0] == "") throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); if (indexReferences[1] != "") fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); else fileIndeces.Add(0); if (indexReferences[2] != "") fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); else fileIndeces.Add(0); } break; //// OLD VERSION OF THE FACE PARSING //// NOTE! This does not yet triangulate faces //// NOTE! This needs all possible values (position, texture mapping, and normal). //for (int i = 1; i < parameters.Length; i++) //{ // string[] indexReferences = parameters[i].Split('/'); // fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); // if (indexReferences[1] != "") // fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); // else // fileIndeces.Add(0); // if (indexReferences[2] != "") // fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); // else // fileIndeces.Add(0); //} //break; // End Current Mesh case "7": // Pull the final vertex order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] verteces = new float[fileIndeces.Count]; for (int i = 0; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; verteces[i] = fileVerteces[index]; verteces[i + 1] = fileVerteces[index + 1]; verteces[i + 2] = fileVerteces[index + 2]; } // Pull the final texture coordinates order out of the indexed references // Note, arrays start at 0 but the index references start at 1 // Note, every other value needs to be inverse (not sure why but it works :P) float[] textureCoordinates = new float[fileIndeces.Count / 3 * 2]; for (int i = 1; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 2; int offset = (i - 1) / 3; textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index]; textureCoordinates[i - offset] = 1 - fileTextureCoordinates[(index + 1)]; } // Pull the final normal order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] normals = new float[fileIndeces.Count]; for (int i = 2; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; normals[i - 2] = fileNormals[index]; normals[i - 1] = fileNormals[(index + 1)]; normals[i] = fileNormals[(index + 2)]; } int vertexBufferId; if (verteces != null) { // Declare the buffer GL.GenBuffers(1, out vertexBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId); // Initialize the buffer values GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (verteces.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("Vertex array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { vertexBufferId = 0; } int textureCoordinateBufferId; if (textureCoordinates != null) { // Declare the buffer GL.GenBuffers(1, out textureCoordinateBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId); // Initialize the buffer values GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (textureCoordinates.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("TexCoord array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { textureCoordinateBufferId = 0; } int normalBufferId; if (normals != null) { // Declare the buffer GL.GenBuffers(1, out normalBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId); // Initialize the buffer values GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (normals.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("Normal array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { normalBufferId = 0; } meshes.Add( new StaticMesh( meshName, staticModelId + "sub" + meshes.Count, vertexBufferId, 0, // Obj files don't support vertex colors textureCoordinateBufferId, normalBufferId, 0, // I don't support an index buffer at this time verteces.Length, texture)); fileVerteces.Clear(); fileNormals.Clear(); fileTextureCoordinates.Clear(); fileIndeces.Clear(); texture = null; break; } } } return new StaticModel(staticModelId, meshes); }