private void EnsureLoaded() { lock (this) { if (_props != null) { return; } const int charBufferSize = 128; using (var reader = new BinaryReader(_bspFile.GameData.OpenItem("sprp"))) { var charBuffer = new byte[charBufferSize]; _modelDict = new string[reader.ReadInt32()]; for (var i = 0; i < _modelDict.Length; ++i) { reader.BaseStream.Read(charBuffer, 0, charBufferSize); int end; for (end = 0; end < charBufferSize && charBuffer[end] != 0; ++end) { ; } _modelDict[i] = Encoding.ASCII.GetString(charBuffer, 0, end); } var leafCount = reader.ReadInt32(); _leafDict = LumpReader <ushort> .ReadLumpFromStream(reader.BaseStream, leafCount); var propCount = reader.ReadInt32(); _props = LumpReader <StaticProp> .ReadLumpFromStream(reader.BaseStream, propCount); } } }
public void GetLightmap([Url] string mapName) { Response.ContentType = MimeTypeMap.GetMimeType(".png"); if (CheckNotExpired(mapName)) { return; } var bsp = GetBspFile(Request, mapName); using (var sampleStream = bsp.GetLumpStream(ValveBspFile.LumpType.LIGHTING_HDR)) { var lightmap = bsp.LightmapLayout; var width = lightmap.TextureSize.X; var height = lightmap.TextureSize.Y; var pixels = new byte[width * height * 4]; var sampleBuffer = new LightmapSample[256 * 256]; for (int i = 0, iEnd = bsp.FacesHdr.Length; i < iEnd; ++i) { var face = bsp.FacesHdr[i]; if (face.LightOffset == -1) { continue; } var rect = lightmap.GetLightmapRegion(i); var sampleCount = rect.Width * rect.Height; sampleStream.Seek(face.LightOffset, SeekOrigin.Begin); LumpReader <LightmapSample> .ReadLumpFromStream(sampleStream, sampleCount, sampleBuffer); for (var y = -1; y < rect.Height + 1; ++y) { for (var x = -1; x < rect.Width + 1; ++x) { var s = Math.Max(0, Math.Min(x, rect.Width - 1)); var t = Math.Max(0, Math.Min(y, rect.Height - 1)); var index = (rect.X + x + width * (rect.Y + y)) * 4; var sampleIndex = s + t * rect.Width; var sample = sampleBuffer[sampleIndex]; pixels[index + 0] = sample.B; pixels[index + 1] = sample.G; pixels[index + 2] = sample.R; pixels[index + 3] = (byte)(sample.Exponent + 128); } } } Utils.ImageMagickConvert(pixels, Response.OutputStream, MagickFormat.Bgra, width, height, 8, MagickFormat.Png); Response.OutputStream.Close(); } }
private void GenerateLightmapPixels() { var lightingLump = _bsp.Lighting.Length > 0 ? _bsp.Lighting.LumpType : _bsp.LightingHdr.LumpType; var hdr = lightingLump == _bsp.LightingHdr.LumpType; using (var sampleStream = _bsp.GetLumpStream(lightingLump)) { var lightmap = _bsp.LightmapLayout; var width = lightmap.TextureSize.X; var height = lightmap.TextureSize.Y; var colors = new Color[width * height]; var sampleBuffer = new ColorRGBExp32[256 * 256]; var faces = hdr ? _bsp.FacesHdr : _bsp.Faces; var fullbright = true; for (int i = 0, iEnd = faces.Length; i < iEnd; ++i) { var face = faces[i]; if (face.LightOffset == -1) { continue; } var rect = lightmap.GetLightmapRegion(i); var sampleCount = rect.Width * rect.Height; sampleStream.Seek(face.LightOffset, System.IO.SeekOrigin.Begin); LumpReader <ColorRGBExp32> .ReadLumpFromStream(sampleStream, sampleCount, sampleBuffer); for (var y = 0; y < rect.Height; ++y) { for (var x = 0; x < rect.Width; ++x) { var s = Math.Max(0, Math.Min(x, rect.Width - 1)); var t = Math.Max(0, Math.Min(y, rect.Height - 1)); var sampleIndex = s + t * rect.Width; var sample = sampleBuffer[sampleIndex]; if (fullbright && (sample.R != 0 || sample.G != 0 || sample.B != 0)) { fullbright = false; } colors[width * (rect.Y + y) + (rect.X + x)] = new Color( TexLightToLinear(sample.R, sample.Exponent), TexLightToLinear(sample.G, sample.Exponent), TexLightToLinear(sample.B, sample.Exponent), 1.0f).gamma; } } } if (fullbright) { for (int i = 0; i < colors.Length; i++) { colors[i] = Color.white; } } var dir = new Texture2D(512, 512, UnityEngine.TextureFormat.RGBA32, false); var dirColors = new Color[512 * 512]; for (int i = 0; i < 512 * 512; i++) { dirColors[i] = Color.white; } dir.SetPixels(dirColors); dir.Apply(); var tex = new Texture2D(width, height, UnityEngine.TextureFormat.RGBA32, false); tex.SetPixels(colors); tex.Apply(); var lightmaps = LightmapSettings.lightmaps.ToList(); lightmaps.Clear(); lightmaps.Add(new LightmapData { lightmapColor = tex, lightmapDir = dir }); LightmapSettings.lightmaps = lightmaps.ToArray(); } }
private void EnsureLoaded() { lock (this) { if (_props != null) { return; } const int charBufferSize = 128; var version = _bspFile.GameData.GetItemVersion("sprp"); using (var reader = new BinaryReader(_bspFile.GameData.OpenItem("sprp"))) { var charBuffer = new byte[charBufferSize]; _modelDict = new string[reader.ReadInt32()]; for (var i = 0; i < _modelDict.Length; ++i) { reader.BaseStream.Read(charBuffer, 0, charBufferSize); int end; for (end = 0; end < charBufferSize && charBuffer[end] != 0; ++end) { ; } _modelDict[i] = Encoding.ASCII.GetString(charBuffer, 0, end); } var leafCount = reader.ReadInt32(); _leafDict = LumpReader <ushort> .ReadLumpFromStream(reader.BaseStream, leafCount); var propCount = reader.ReadInt32(); switch (version) { case 5: _props = LumpReader <StaticPropV5> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); break; case 6: _props = LumpReader <StaticPropV6> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); break; case 10: _props = LumpReader <StaticPropV10> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); break; default: throw new NotSupportedException($"Static prop version {version} is not supported."); } } } }
public void Get([Url] string map) { if (Skip) { Response.Close(); return; } Response.ContentType = MimeTypeMap.GetMimeType(".png"); var bsp = Program.GetMap(map); var lightingLump = bsp.LightingHdr.Length > 0 ? bsp.LightingHdr.LumpType : bsp.Lighting.LumpType; using (var sampleStream = bsp.GetLumpStream(lightingLump)) { var lightmap = bsp.LightmapLayout; var width = lightmap.TextureSize.X; var height = lightmap.TextureSize.Y; var pixels = new byte[width * height * 4]; var sampleBuffer = new ColorRGBExp32[256 * 256]; var faces = bsp.FacesHdr.Length > 0 ? bsp.FacesHdr : bsp.Faces; for (int i = 0, iEnd = faces.Length; i < iEnd; ++i) { var face = faces[i]; if (face.LightOffset == -1) { continue; } var rect = lightmap.GetLightmapRegion(i); var sampleCount = rect.Width * rect.Height; sampleStream.Seek(face.LightOffset, SeekOrigin.Begin); LumpReader <ColorRGBExp32> .ReadLumpFromStream(sampleStream, sampleCount, sampleBuffer); for (var y = 0; y < rect.Height; ++y) { for (var x = 0; x < rect.Width; ++x) { var s = Math.Max(0, Math.Min(x, rect.Width - 1)); var t = Math.Max(0, Math.Min(y, rect.Height - 1)); var index = (rect.X + x + width * (rect.Y + y)) * 4; var sampleIndex = s + t * rect.Width; var sample = sampleBuffer[sampleIndex]; pixels[index + 0] = sample.B; pixels[index + 1] = sample.G; pixels[index + 2] = sample.R; pixels[index + 3] = (byte)(sample.Exponent + 128); } } } using (var img = new MagickImage(pixels, new MagickReadSettings { Width = width, Height = height, PixelStorage = new PixelStorageSettings(StorageType.Char, "BGRA") })) { img.Write(Response.OutputStream, MagickFormat.Png); } Response.OutputStream.Close(); } }
private void EnsureLoaded() { lock (this) { if (_props != null) { return; } const int charBufferSize = 128; var version = _bspFile.GameData.GetItemVersion("sprp"); using (var reader = new BinaryReader(_bspFile.GameData.OpenItem("sprp"))) { var charBuffer = new byte[charBufferSize]; _modelDict = new string[reader.ReadInt32()]; for (var i = 0; i < _modelDict.Length; ++i) { reader.BaseStream.Read(charBuffer, 0, charBufferSize); int end; for (end = 0; end < charBufferSize && charBuffer[end] != 0; ++end) { ; } _modelDict[i] = Encoding.ASCII.GetString(charBuffer, 0, end); } var leafCount = reader.ReadInt32(); _leafDict = LumpReader <ushort> .ReadLumpFromStream(reader.BaseStream, leafCount); var propCount = reader.ReadInt32(); if (propCount == 0) { _props = new IStaticProp[0]; return; } switch (version) { case 5: _props = LumpReader <StaticPropV5> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); break; case 6: _props = LumpReader <StaticPropV6> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); break; case 10: if (_bspFile.Version == 21) { _props = LumpReader <StaticPropV10_CSGO> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); } else { _props = LumpReader <StaticPropV10> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); } break; case 11: if (_bspFile.Version == 21) { _props = LumpReader <StaticPropV11_CSGO> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); } else { _props = LumpReader <StaticPropV11> .ReadLumpFromStream(reader.BaseStream, propCount) .Cast <IStaticProp>() .ToArray(); } break; default: #if DEBUG var remaining = reader.BaseStream.Length - reader.BaseStream.Position; var size = (int)(remaining / propCount); const int debugPropCount = 10; const int bytesPerRow = 8; Console.WriteLine($"Static Prop size: {size}"); Console.WriteLine($"Printing first {debugPropCount} props"); var buffer = new byte[size]; for (var i = 0; i < propCount && i < debugPropCount; ++i) { Console.WriteLine($"Prop {i}:"); reader.Read(buffer, 0, size); for (var j = 0; j < size; j += bytesPerRow) { Console.WriteLine($" 0x{j:x4}: {string.Join(" ", buffer.Skip( j ).Take( bytesPerRow ).Select( x => x.ToString( "x2" ) ) )}"); } } #endif throw new NotSupportedException($"Static prop version {version} is not supported."); } } } }