/// <summary> /// compares to faces /// </summary> /// <param name="obj">to compare with</param> /// <returns></returns> public int CompareTo(Object obj) { QuakeFace other = (QuakeFace)obj; if (other.LightmapID == LightmapID) { return(TextureID - other.TextureID); } else { return(LightmapID - other.LightmapID); } }
/// <summary> /// loads a quake3 level from a stream /// </summary> /// <param name="stream">stream to load from</param> /// <returns>level as a mesh</returns> public Mesh Load(Stream stream) { Mesh mesh = new Mesh(); this.stream = stream; // get header and check if it is ok QuakeHeader header = (QuakeHeader)RawSerializer.Deserialize(stream, typeof(QuakeHeader)); if (header.ID != 1347633737 || header.Version != 0x2e) { return(null); } // get locations of lumps locations = RawSerializer.DeserializeArray(stream, typeof(LumpLocation), (int)QuakeLumps.LumpNumber); // get lumps IList quakeVertices = LoadLump(QuakeLumps.Vertices, typeof(QuakeVertex)); IList quakeFaces = LoadLump(QuakeLumps.Faces, typeof(QuakeFace)); IList quakeTextures = LoadLump(QuakeLumps.Textures, typeof(QuakeTexture)); IList quakeLightMaps = LoadLump(QuakeLumps.Lightmaps, typeof(QuakeLightMap)); // Load all texture images and put into array IList textures = LoadTextures(quakeTextures); // Load lightMaps, create texture and put into array IList lightMaps = LoadLightMaps(quakeLightMaps); // create list from vertices VertexUnit vertexUnit = new VertexUnit(VertexFormat.PositionTexture2, quakeVertices.Count); PositionStream pos = (PositionStream)vertexUnit[typeof(PositionStream)]; TextureStream texStream = (TextureStream)vertexUnit[typeof(TextureStream)]; TextureStream light = (TextureStream)vertexUnit[typeof(TextureStream), 1]; int i = 0; foreach (QuakeVertex v in quakeVertices) { pos[i] = new Math.Vector3(v.Position[0], v.Position[2], -v.Position[1]); texStream[i] = new Math.Vector2(v.TextureCoord[0], v.TextureCoord[1]); light[i] = new Math.Vector2(v.LightmapCoord[0], v.LightmapCoord[1]); i++; } // presort faces Array.Sort(((Array)quakeFaces)); // create mesh int oldLightMap = ((QuakeFace)quakeFaces[0]).LightmapID; int oldTexture = ((QuakeFace)quakeFaces[0]).TextureID; ArrayList indices = new ArrayList(); for (i = 0; i < quakeFaces.Count; ++i) { QuakeFace qf = (QuakeFace)quakeFaces[i]; if (qf.Type == 1) { if (qf.TextureID != oldTexture || qf.LightmapID != oldLightMap) { mesh.SubSets.Add(new SubSet(vertexUnit, IndexStream.Create(indices, vertexUnit.Size))); Textures texs = new Textures("color", (ITexture)textures[oldTexture]); if (oldLightMap == -1) { texs["lightMap"] = null; } else { texs["lightMap"] = (ITexture)lightMaps[oldLightMap]; } mesh.Textures.Add(texs); indices.Clear(); } // add indices => convert from fan to list for (int j = 2; j < qf.NumOfVerts; j++) { indices.Add(qf.VertexIndex); indices.Add(qf.VertexIndex + j - 1); indices.Add(qf.VertexIndex + j); } oldTexture = qf.TextureID; oldLightMap = qf.LightmapID; } } return(mesh); }