BSPMesh CreateMesh(GEOMETRY_T geometry, face_id_list_t face_ids, MIPTEX_DIRECTORY_ENTRY_T miptex_entry) { var faces = geometry.faces; // get number of triangles required to build model var num_tris = 0; for (var i = 0; i < face_ids.length; ++i) { var face = faces[face_ids[i]]; num_tris += face.num_edges - 2; } var verts = new Vector3[num_tris * 3]; // 3 vertices, xyz per tri var uvs = new Vector2[num_tris * 3]; // 3 uvs, uv per tri var verts_ofs = 0; for (var i = 0; i < face_ids.length; ++i) { var face = faces[face_ids[i]]; verts_ofs = this.addFaceVerts(geometry, face, verts, uvs, verts_ofs, miptex_entry); } return(new BSPMesh(verts, uvs)); }
void ReadMiptexDirectory(DataStream ds) { // get offsets to each texture var base_offset = this.header.miptex.fileofs; ds.seek(base_offset); var miptex_offsets = ds.readStruct <MIPTEX_DIRECTORY_T>().offsets; // create entries var miptex_directory = new MIPTEX_DIRECTORY_ENTRY_T[miptex_offsets.Length]; var garbage_entries = 0; for (var i = 0; i < miptex_offsets.Length; ++i) { var offset = base_offset + miptex_offsets[i]; ds.seek(offset); var miptex = ds.readStruct <miptex_t>(); MIPTEX_DIRECTORY_ENTRY_T entry; entry.offset = offset; entry.dsize = (miptex.width * miptex.height); entry.size = (miptex.width * miptex.height); entry.type = "D"[0]; entry.compression = 0; entry.name = FileUtilEx.trimNullTerminatedString(miptex.name); // additional parameters useful for generating uvs entry.width = miptex.width; entry.height = miptex.height; if (entry.name == "") { garbage_entries += 1; // console.log("Warning: BSP miptex entry at index " + i + " is unreadable. Name: '" + miptex.name + "'"); // console.log(entry); } else { miptex_directory[i - garbage_entries] = entry; } } this.miptex_directory = miptex_directory; }
int addFaceVerts(GEOMETRY_T geometry, dface_t face, Vector3[] verts, Vector2[] uvs, int verts_ofs, MIPTEX_DIRECTORY_ENTRY_T miptex_entry) { var edge_list = geometry.edge_list; var edges = geometry.edges; var vertices = geometry.vertices; var texinfo = geometry.texinfos[face.texinfo_id]; var tex_width = miptex_entry.width; var tex_height = miptex_entry.height; var vert_ids = new DynamicArray <int>(); var start = face.edge_id; var end = start + face.num_edges; int i; for (i = start; i < end; ++i) { var edge_id = edge_list[i]; var edge = edges[Math.Abs(edge_id)]; if (edge_id > 0) { vert_ids[vert_ids.length] = edge.v1; } else { vert_ids[vert_ids.length] = edge.v2; } } var num_tris = vert_ids.length - 2; for (i = 0; i < num_tris; ++i) { // reverse winding order to have correct normals var c = vert_ids[0]; var b = vert_ids[i + 1]; var a = vert_ids[i + 2]; int vi = (verts_ofs + i) * 3; int uvi = (verts_ofs + i) * 3; Vector3 vert = vertices[a]; verts[vi] = vert; uvs[uvi].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width; uvs[uvi].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height; vert = vertices[b]; verts[vi + 1] = vert; uvs[uvi + 1].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width; uvs[uvi + 1].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height; vert = vertices[c]; verts[vi + 2] = vert; uvs[uvi + 2].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width; uvs[uvi + 2].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height; } return(verts_ofs + i); // next position in verts }