public static TexInfo Read(BinaryReader br) { TexInfo surface = new TexInfo(); surface.vectorS = new Vector3D(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); surface.distS = br.ReadSingle(); surface.vectorT = new Vector3D(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); surface.distT = br.ReadSingle(); surface.texture_id = br.ReadUInt32(); surface.animated = br.ReadUInt32(); return(surface); }
public static Bsp Read(byte[] buf) { using (var ms = new MemoryStream(buf)) using (var br = new BinaryReader(ms)) { Header header = Header.Read(br); Bsp bsp = new Bsp(); bsp.entities = ReadItems(br, header.entities, (b) => Entity.Read(b)); bsp.planes = ReadItems(br, header.planes, (b) => Plane.Read(b)); br.BaseStream.Seek(header.miptex.offset, SeekOrigin.Begin); bsp.mipheader = Mipheader.Read(br); bsp.miptexs = new Miptex[bsp.mipheader.numtex]; for (int i = 0; i < bsp.miptexs.Length; i++) { if (bsp.mipheader.offset[i] == -1) { continue; } br.BaseStream.Seek(header.miptex.offset + bsp.mipheader.offset[i], SeekOrigin.Begin); bsp.miptexs[i] = Miptex.Read(br); } bsp.vertices = ReadItems(br, header.vertices, (b) => new Vector3D(b.ReadSingle(), b.ReadSingle(), b.ReadSingle())); bsp.vislist = ReadItems(br, header.visilist, (b) => b.ReadByte()); bsp.nodes = ReadItems(br, header.nodes, (b) => Node.Read(b)); bsp.texinfo = ReadItems(br, header.texinfo, (b) => TexInfo.Read(b)); bsp.faces = ReadItems(br, header.faces, (b) => Face.Read(b)); bsp.lightmaps = ReadItems(br, header.lightmaps, (b) => b.ReadByte()); bsp.clipnodes = ReadItems(br, header.clipnodes, (b) => Clipnode.Read(b)); bsp.leafs = ReadItems(br, header.leafs, (b) => Leaf.Read(b)); bsp.lface = ReadItems(br, header.lface, (b) => b.ReadUInt16()); bsp.edges = ReadItems(br, header.edges, (b) => Edge.Read(b)); bsp.ledges = ReadItems(br, header.ledges, (b) => b.ReadInt32()); bsp.models = ReadItems(br, header.models, (b) => Model.Read(b)); bsp.mipMaterials = bsp.miptexs.Select((mip) => GetMipMaterial(mip)).ToArray(); bsp.mipModels = bsp.faces.Select((face) => bsp.GetMipModel(face)).ToArray(); bsp.lightModels = bsp.faces.Select((face) => bsp.GetLightModel(face)).ToArray(); return(bsp); } }
private void CalcSurfaceExtents(Face s) { float[] numArray1 = new float[2]; float[] numArray2 = new float[2]; int[] numArray3 = new int[2]; int[] numArray4 = new int[2]; numArray1[0] = numArray1[1] = 999999f; numArray2[0] = numArray2[1] = -99999f; TexInfo texinfoT = this.texinfo[(int)s.texinfo_id]; for (int index1 = 0; index1 < (int)s.ledge_num; ++index1) { int surfedge = this.ledges[s.ledge_id + index1]; var vertexT = surfedge < 0 ? this.vertices[(int)this.edges[-surfedge].vertex1] : this.vertices[(int)this.edges[surfedge].vertex0]; double numS = Vector3D.DotProduct(vertexT, texinfoT.vectorS) + texinfoT.distS; if (numS < numArray1[0]) { numArray1[0] = (float)numS; } if (numS > numArray2[0]) { numArray2[0] = (float)numS; } double numT = Vector3D.DotProduct(vertexT, texinfoT.vectorT) + texinfoT.distT; if (numT < numArray1[1]) { numArray1[1] = (float)numT; } if (numT > numArray2[1]) { numArray2[1] = (float)numT; } } s.texturemins = new int[2]; s.extents = new int[2]; for (int index = 0; index < 2; ++index) { numArray3[index] = (int)Math.Floor((double)numArray1[index] / 16.0); numArray4[index] = (int)Math.Ceiling((double)numArray2[index] / 16.0); s.texturemins[index] = numArray3[index] * 16; s.extents[index] = (numArray4[index] - numArray3[index]) * 16; } }
public GeometryModel3D GetMipModel(Face face) { var ledgelist = this.ledges.Skip(face.ledge_id).Take(face.ledge_num); var vidxs = ledgelist .Select((ledge) => (ledge >= 0) ? new int[] { this.edges[ledge].vertex0, this.edges[ledge].vertex1 } : new int[] { this.edges[-ledge].vertex1, this.edges[-ledge].vertex0 }) .SelectMany((pair) => pair) .Where((vidx, i) => (i % 2 == 0)); TexInfo texinfo = this.texinfo[face.texinfo_id]; var material = this.mipMaterials[texinfo.texture_id]; var imageBrush = material.Brush as ImageBrush; var tw = imageBrush.ImageSource.Width; var th = imageBrush.ImageSource.Height; MeshGeometry3D mesh = new MeshGeometry3D(); foreach (var vidx in vidxs) { var v = this.vertices[vidx]; mesh.Positions.Add((Point3D)v); mesh.Normals.Add(this.planes[face.plane_id].normal); Point st = new Point(); st.X = (Vector3D.DotProduct(v, texinfo.vectorS) + texinfo.distS) / tw; st.Y = (Vector3D.DotProduct(v, texinfo.vectorT) + texinfo.distT) / th; mesh.TextureCoordinates.Add(st); } for (int i = 2; i < vidxs.Count(); i++) { mesh.TriangleIndices.Add(i); mesh.TriangleIndices.Add(i - 1); mesh.TriangleIndices.Add(0); } return(new GeometryModel3D(mesh, material)); }
public GeometryModel3D GetLightModel(Face face) { this.CalcSurfaceExtents(face); var ledgelist = this.ledges.Skip(face.ledge_id).Take(face.ledge_num); var vidxs = ledgelist .Select((ledge) => (ledge >= 0) ? new int[] { this.edges[ledge].vertex0, this.edges[ledge].vertex1 } : new int[] { this.edges[-ledge].vertex1, this.edges[-ledge].vertex0 }) .SelectMany((pair) => pair) .Where((vidx, i) => (i % 2 == 0)); TexInfo texinfoT = this.texinfo[face.texinfo_id]; MeshGeometry3D mesh = new MeshGeometry3D(); foreach (var vidx in vidxs) { var v = this.vertices[vidx]; mesh.Positions.Add((Point3D)v); mesh.Normals.Add(this.planes[face.plane_id].normal); Point st = new Point(); st.X = (Vector3D.DotProduct(texinfoT.vectorS, v) + texinfoT.distS + 8f - face.texturemins[0]) / face.extents[0]; st.Y = (Vector3D.DotProduct(texinfoT.vectorT, v) + texinfoT.distT + 8f - face.texturemins[1]) / face.extents[1]; mesh.TextureCoordinates.Add(st); } for (int i = 2; i < vidxs.Count(); i++) { mesh.TriangleIndices.Add(i); mesh.TriangleIndices.Add(i - 1); mesh.TriangleIndices.Add(0); } DiffuseMaterial material = R_BuildLightMap(face); return(new GeometryModel3D(mesh, material)); }