static ColorRGBExp32 TexLightToLinear(long Offset)
        {
            Offset += BSP_Header.Lumps[58].FileLen / 56 > 0 ? BSP_Header.Lumps[53].FileOfs : BSP_Header.Lumps[8].FileOfs;

            ColorRGBExp32 ColorRGBExp32 = new ColorRGBExp32();

            BSPFileReader.ReadType(ref ColorRGBExp32, Offset);

            float Pow = Mathf.Pow(2, ColorRGBExp32.exponent);

            ColorRGBExp32.r = TexLightToLinearB(ColorRGBExp32.r, Pow);
            ColorRGBExp32.g = TexLightToLinearB(ColorRGBExp32.g, Pow);
            ColorRGBExp32.b = TexLightToLinearB(ColorRGBExp32.b, Pow);

            return(ColorRGBExp32);
        }
        static void CreateLightMap(IList <Face> InpFaces, ref Texture2D Lightmap_tex, ref List <Vector2> UV2)
        {
            Texture2D[] LMs = new Texture2D[InpFaces.Count];

            for (Int32 i = 0; i < InpFaces.Count; i++)
            {
                if (InpFaces[i].LightOfs == -1)
                {
                    continue;
                }

                LMs[i] = new Texture2D(InpFaces[i].LightMapW, InpFaces[i].LightMapH, TextureFormat.RGB24, false, true);
                Color32[] TexPixels = new Color32[LMs[i].width * LMs[i].height];

                for (Int32 j = 0; j < TexPixels.Length; j++)
                {
                    ColorRGBExp32 ColorRGBExp32 = ConfigLoader.useHDRLighting ? TexLightToLinearHDR(InpFaces[i].LightOfs + (j * 4)) : TexLightToLinear(InpFaces[i].LightOfs + (j * 4));
                    TexPixels[j] = new Color32(ColorRGBExp32.r, ColorRGBExp32.g, ColorRGBExp32.b, 255);
                }

                LMs[i].SetPixels32(TexPixels);
            }

            Rect[] UVs2 = Lightmap_tex.PackTextures(LMs, 1);
            for (Int32 i = 0; i < InpFaces.Count; i++)
            {
                UnityEngine.Object.DestroyImmediate(LMs[i]);

                for (Int32 j = 0; j < InpFaces[i].UV2.Length; j++)
                {
                    UV2.Add(new Vector2((InpFaces[i].UV2[j].x * UVs2[i].width) + UVs2[i].x, (InpFaces[i].UV2[j].y * UVs2[i].height) + UVs2[i].y));
                }
            }

            //Add lightmap in array
            if (!ConfigLoader.LoadLightmapsAsTextureShader)
            {
                ConfigLoader.lightmapsData.Add(new LightmapData()
                {
                    lightmapColor = Lightmap_tex
                });
                LightmapSettings.lightmaps = ConfigLoader.lightmapsData.ToArray();
                ConfigLoader.CurrentLightmap++;
            }
            //Add lightmap in array
        }
        static ColorRGBExp32 TexLightToLinearHDR(long Offset)
        {
            Offset += BSP_Header.Lumps[58].FileLen / 56 > 0 ? BSP_Header.Lumps[53].FileOfs : BSP_Header.Lumps[8].FileOfs;

            ColorRGBExp32 ColorRGBExp32 = new ColorRGBExp32();

            BSPFileReader.ReadType(ref ColorRGBExp32, Offset);

            float Pow = Mathf.Pow(2, ColorRGBExp32.exponent);

            //https://github.com/lewa-j/Unity-Source-Tools/blob/834869c8ad7ad8924af62e11e9e55486e18203e8/Assets/Code/Read/BSPFile.cs#L337
            Color32 col = new Color(TexLightToLinearF(ColorRGBExp32.r, Pow), TexLightToLinearF(ColorRGBExp32.g, Pow), TexLightToLinearF(ColorRGBExp32.b, Pow), 1f).gamma;

            ColorRGBExp32.r = col.r;
            ColorRGBExp32.g = col.g;
            ColorRGBExp32.b = col.b;
            return(ColorRGBExp32);
        }
    private static ColorRGBExp32 TexLightToLinear(int fileofs)
    {
        switch (BSP_Header.version)
        {
        // FITCH: If BSP version more than 20, you need load HDR lumps
        case 21: fileofs += BSP_Header.lumps[53].fileofs; break;

        default: fileofs += BSP_Header.lumps[8].fileofs; break;
        }

        ColorRGBExp32 ColorRGBExp32 = CRead.ReadType <ColorRGBExp32>(fileofs);

        // Convert HDR pixels to RGB
        ColorRGBExp32.r = (byte)Mathf.Clamp(ColorRGBExp32.r * Mathf.Pow(2, ColorRGBExp32.exponent), 0, 255);
        ColorRGBExp32.g = (byte)Mathf.Clamp(ColorRGBExp32.g * Mathf.Pow(2, ColorRGBExp32.exponent), 0, 255);
        ColorRGBExp32.b = (byte)Mathf.Clamp(ColorRGBExp32.b * Mathf.Pow(2, ColorRGBExp32.exponent), 0, 255);

        return(ColorRGBExp32);
    }
    private static void CreateLightMap(List <face> inpFaces, ref Texture2D lightMap, ref List <Vector2> lightMapUV)
    {
        Texture2D[] lightMaps = new Texture2D[inpFaces.Count];

        // Load lightmap for each face
        for (int i = 0; i < inpFaces.Count; i++)
        {
            lightMaps[i] = new Texture2D(inpFaces[i].lightMapW, inpFaces[i].lightMapH, TextureFormat.RGB24, false);

            Color32[] TexPixels      = new Color32[inpFaces[i].lightMapW * inpFaces[i].lightMapH];
            int       LightMapOffset = BSP_Faces[inpFaces[i].index].lightofs;

            if (LightMapOffset > 0)
            {
                for (int n = 0; n < TexPixels.Length; n++)
                {
                    ColorRGBExp32 ColorRGBExp32 = TexLightToLinear(LightMapOffset + (n * 4));
                    TexPixels[n] = new Color32(ColorRGBExp32.r, ColorRGBExp32.g, ColorRGBExp32.b, 255);
                }

                lightMaps[i].SetPixels32(TexPixels);
            }
        }

        // Generate lightmap atlas
        Rect[] uvs2 = lightMap.PackTextures(lightMaps.ToArray(), 1);
        lightMap.wrapMode = TextureWrapMode.Clamp; lightMap.Apply();

        // Generate UV for lightmap atlas
        for (int i = 0; i < inpFaces.Count; i++)
        {
            for (int l = 0; l < inpFaces[i].uv2.Length; l++)
            {
                lightMapUV.Add(new Vector2((inpFaces[i].uv2[l].x * uvs2[i].width) + uvs2[i].x, (inpFaces[i].uv2[l].y * uvs2[i].height) + uvs2[i].y));
            }
        }
    }
Example #6
0
    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();
        }
    }
Example #7
0
        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();
            }
        }
        void ParseHeader(BinaryReader BR)
        {
            //used utils/vrad/vradstaticprops.cpp:1506 -- void CVradStaticPropMgr::SerializeLighting()
            if (BR.BaseStream.Length < 40)
            {
                throw new Exception("Not a VHV file! (file size is less than header size)");
            }
            //parsing main header
            BR.BaseStream.Seek(0, SeekOrigin.Begin);
            Header = new Structs.FileHeader_t
            {
                m_nVersion     = BR.ReadInt32(),
                m_nChecksum    = BR.ReadUInt32(),
                m_nVertexFlags = (Structs.VertexFlags)BR.ReadUInt32(),
                m_nVertexSize  = BR.ReadUInt32(),
                m_nVertexes    = BR.ReadUInt32(),
                m_nMeshes      = BR.ReadInt32()
            };
            //int[] unused = BR.ReadInt32Array(4);
            BR.BaseStream.Seek(16, SeekOrigin.Current); //skip unused
            if (Header.m_nVersion != Structs.VHV_VERSION)
            {
                throw new Exception($"Not supported version or not a VHV file! ({Header.m_nVersion}!={Structs.VHV_VERSION})");
            }

            //parsing mesh headers
            Header.pMesh = new Structs.MeshHeader_t[Header.m_nMeshes];
            for (int n = 0; n < Header.m_nMeshes; n++)
            {
                // construct mesh dictionary
                Header.pMesh[n] = new Structs.MeshHeader_t
                {
                    m_nLod      = BR.ReadUInt32(),
                    m_nVertexes = BR.ReadUInt32(),
                    m_nOffset   = BR.ReadUInt32()
                };
                BR.BaseStream.Seek(16, SeekOrigin.Current); //skip unused
            }
            //BR.BaseStream.Seek(4 * 109, SeekOrigin.Current);
            for (int n = 0; n < Header.m_nMeshes; n++)
            {
                // construct vertexes
                var pMesh = Header.pMesh[n];
                BR.BaseStream.Seek(pMesh.m_nOffset, SeekOrigin.Begin);
                ColorRGBExp32[] m_VertexColors = new ColorRGBExp32[pMesh.m_nVertexes];
                long            POSITION_THERE = BR.BaseStream.Position;
                long            BYTES_LEFT     = BR.BaseStream.Length - POSITION_THERE;
                for (int k = 0; k < pMesh.m_nVertexes; k++)
                {
                    //Vector vertexColor = m_StaticProps[i].m_MeshData[n].m_VertexColors[k];

                    //ColorRGBExp32 rgbColor;
                    //VectorToColorRGBExp32(vertexColor, rgbColor);
                    //byte[] dstColor;//[4];
                    //ConvertRGBExp32ToRGBA8888(rgbColor, dstColor);

                    // b,g,r,a order
                    //pVertexData[0] = dstColor[2];
                    //pVertexData[1] = dstColor[1];
                    //pVertexData[2] = dstColor[0];
                    //pVertexData[3] = dstColor[3];
                    //pVertexData += 4;

                    //RGBA8888 -> RGBExp32
                    // Linear to Tex light [0-1 to 0-255] (mb to gamma?)

                    //RGBExp32 -> Vector

                    //if (Header.m_nVertexFlags.HasFlag(Structs.VertexFlags.VERTEX_COLOR))
                    //{
                    //    //byte[] colordata = BR.ReadBytes(4);
                    //    byte[] colordata = BR.ReadBytes(3);
                    //    //0 1 2  3
                    //    //4 5 6  7
                    //    //8 9 10 11
                    //    //float exponent = (float)System.Math.Pow(2f, colordata[3]);
                    //    //m_VertexColors[k] = new ColorRGBExp32(colordata[0],
                    //    //                                    colordata[1],
                    //    //                                    colordata[2],
                    //    //                                    255);
                    //    m_VertexColors[k] = new ColorRGBExp32(LightUtils.linearToTexLight(colordata[0], 1f),
                    //                                        LightUtils.linearToTexLight(colordata[1], 1f),
                    //                                        LightUtils.linearToTexLight(colordata[2], 1f),
                    //                                        255);
                    //}
                    //else
                    if (Header.m_nVertexFlags.HasFlag(Structs.VertexFlags.VERTEX_NORMAL))
                    {
                        byte[] colordata = BR.ReadBytes(12);
                        //0 1 2  3
                        //4 5 6  7
                        //8 9 10 11
                        float exponent = (float)Math.Pow(2f, MathUtils.Avg(colordata[3], colordata[7], colordata[11]));
                        m_VertexColors[k] = new ColorRGBExp32(LightUtils.linearToTexLight(MathUtils.Avg(colordata[2], colordata[6], colordata[10]), exponent),
                                                              LightUtils.linearToTexLight(MathUtils.Avg(colordata[1], colordata[5], colordata[9]), exponent),
                                                              LightUtils.linearToTexLight(MathUtils.Avg(colordata[0], colordata[4], colordata[8]), exponent),
                                                              255);
                    }
                    else
                    {
                        throw new NotImplementedException("Not implemented vertex flag: " + Header.m_nVertexFlags);
                    }
                }
                Header.pMesh[n].m_VertexColors = m_VertexColors;
            }
        }