Beispiel #1
0
    public void ReadMCSH(MemoryStream ADTtexstream, ADTTexData.TextureChunkData chunkData) //512 bytes
    {
        // The shadows are stored per bit, not byte as 0 or 1 (off or on) so we have 8 bytes (which equates to 64 values) X 64 bytes (64 values in this case) which ends up as a square 64x64 shadowmap with either white or black.
        // Note that the shadow values come LSB first.
        // 8bytes(64values) x 64 = 512 bytes
        chunkData.shadowMap        = new bool[64 * 64];
        chunkData.shadowMapTexture = new byte[64 * 64];

        byte[] ByteArray = new byte[64 * 64];
        ADTtexstream.Read(ByteArray, 0, 8 * 64);
        if (SettingsTerrainImport.LoadShadowMaps)
        {
            BitArray bits = new BitArray(ByteArray);
            for (int b = 4095; b >= 0; b--) // LSB
            {
                chunkData.shadowMap[b] = bits[b];
                if (bits[b])
                {
                    chunkData.shadowMapTexture[b] = 127;
                }
                else
                {
                    chunkData.shadowMapTexture[b] = 0;
                }
            }
        }
    }
Beispiel #2
0
    public void ReadMCAL(MemoryStream ADTtexstream, string mapname, ADTTexData.TextureChunkData chunkData)
    {
        StreamTools s = new StreamTools();
        long        McalStartPosition = ADTtexstream.Position;
        int         numberofLayers    = chunkData.NumberOfTextureLayers;

        if (numberofLayers > 1)
        {
            chunkData.alphaLayers = new List <byte[]>();
            for (int l = 1; l < numberofLayers; l++)
            {
                if (WDT.Flags[mapname].adt_has_height_texturing == true)
                {
                    if (chunkData.alpha_map_compressed[l] == false)
                    {
                        chunkData.alphaLayers.Add(AlphaMap_UncompressedFullRes(ADTtexstream));
                    }
                    else if (chunkData.alpha_map_compressed[l] == true)
                    {
                        chunkData.alphaLayers.Add(AlphaMap_Compressed(ADTtexstream));
                    }
                }
                else if (WDT.Flags[mapname].adt_has_height_texturing == false)
                {
                    if (WDT.Flags[mapname].adt_has_big_alpha == false)
                    {
                        if (chunkData.alpha_map_compressed[l] == false)
                        {
                            chunkData.alphaLayers.Add(AlphaMap_UncompressedHalfRes(ADTtexstream));
                        }
                        else if (chunkData.alpha_map_compressed[l] == true)
                        {
                            chunkData.alphaLayers.Add(AlphaMap_Compressed(ADTtexstream));
                        }
                    }
                    else if (WDT.Flags[mapname].adt_has_big_alpha == true)
                    {
                        if (chunkData.alpha_map_compressed[l] == false)
                        {
                            chunkData.alphaLayers.Add(AlphaMap_UncompressedFullRes(ADTtexstream));
                        }
                        else if (chunkData.alpha_map_compressed[l] == true)
                        {
                            chunkData.alphaLayers.Add(AlphaMap_Compressed(ADTtexstream));
                        }
                    }
                }
            }
        }
    }
Beispiel #3
0
    /////////////////////////////
    ///// MCNKtex Subchunks /////
    /////////////////////////////

    public void ReadMCLY(MemoryStream ADTtexstream, ADTTexData.TextureChunkData chunkData, int MCLYsize)
    {
        /*
         *  Texture layer definitions for this map chunk. 16 bytes per layer, up to 4 layers (thus, layer count = size / 16).
         *  Every texture layer other than the first will have an alpha map to specify blending amounts. The first layer is rendered with full opacity. To know which alphamap is used, there is an offset into the MCAL chunk. That one is relative to MCAL.
         *  You can animate these by setting the flags. Only simple linear animations are possible. You can specify the direction in 45° steps and the speed.
         *  The textureId is just the array index of the filename array in the MTEX chunk.
         *  For getting the right feeling when walking, you should set the effectId which links to GroundEffectTextureRec::m_ID. It defines the little detail doodads as well as the footstep sounds and if footprints are visible. You can set the id to -1 (int16!) to have no detail doodads and footsteps at all. Also, you need to define the currently on-top layer in the MCNK structure for the correct detail doodads to show up!
         *  Introduced in Wrath of the Lich King, terrain can now reflect a skybox. This is used for icecubes made out of ADTs to reflect something. You need to have the MTXF chunk in, if you want that. Look at an skybox Blizzard made to see how you should do it.
         */
        if (MCLYsize == 0)
        {
            return;
        }

        StreamTools s = new StreamTools();
        long        MCLYStartPosition = ADTtexstream.Position;
        int         numberOfLayers    = MCLYsize / 16;

        chunkData.NumberOfTextureLayers = numberOfLayers;
        chunkData.textureIds            = new int[numberOfLayers];
        chunkData.LayerOffsetsInMCAL    = new int[numberOfLayers];
        for (int l = 0; l < numberOfLayers; l++)
        {
            chunkData.textureIds[l] = s.ReadLong(ADTtexstream); // texture ID
            // <flags>
            byte[] arrayOfBytes = new byte[4];
            ADTtexstream.Read(arrayOfBytes, 0, 4);
            BitArray flags = new BitArray(arrayOfBytes);
            int      animation_rotation = (flags[0] ? 1 : 0) + (flags[1] ? 1 : 0) + (flags[2] ? 1 : 0); // each tick is 45°
            int      animation_speed    = (flags[3] ? 1 : 0) + (flags[4] ? 1 : 0) + (flags[5] ? 1 : 0); // 0 to 3
            bool     animation_enabled  = flags[6];
            bool     overbright         = flags[7];                                                     // This will make the texture way brighter. Used for lava to make it "glow".
            bool     use_alpha_map      = flags[8];                                                     // set for every layer after the first
            chunkData.alpha_map_compressed[l] = flags[9];                                               // see MCAL chunk description - MCLY_AlphaType_Flag
            bool use_cube_map_reflection = flags[10];                                                   // This makes the layer behave like its a reflection of the skybox. See below
            bool unknown_0x800           = flags[11];                                                   // WoD?+ if either of 0x800 or 0x1000 is set, texture effects' texture_scale is applied
            bool unknown_0x1000          = flags[12];                                                   // WoD?+ see 0x800
            // flags 13-32 unused
            // </flags>
            int layerOffset = s.ReadLong(ADTtexstream);
            chunkData.LayerOffsetsInMCAL[l] = layerOffset;
            int effectId = s.ReadLong(ADTtexstream); //foreign_keyⁱ <uint32_t, &GroundEffectTextureRec::m_ID>; // 0xFFFFFFFF for none, in alpha: uint16_t + padding
        }
    }
Beispiel #4
0
    public void ReadMCNKtex(MemoryStream ADTtexstream, string mapname, int MCNKchunkNumber, int MCNKsize)
    {
        if (ADTtexstream.Length == ADTtexstream.Position)
        {
            return;
        }

        StreamTools s = new StreamTools();

        ADTTexData.TextureChunkData chunkData = new ADTTexData.TextureChunkData();

        long MCNKchnkPos    = ADTtexstream.Position;
        long streamPosition = ADTtexstream.Position;

        while (streamPosition < MCNKchnkPos + MCNKsize)
        {
            ADTtexstream.Position = streamPosition;
            int chunkID   = s.ReadLong(ADTtexstream);
            int chunkSize = s.ReadLong(ADTtexstream);
            streamPosition = ADTtexstream.Position + chunkSize;
            switch (chunkID)
            {
            case (int)ChunkID.ADT.MCLY:
                ReadMCLY(ADTtexstream, chunkData, chunkSize);     // texture layers
                break;

            case (int)ChunkID.ADT.MCSH:
                ReadMCSH(ADTtexstream, chunkData);     // static shadow maps
                break;

            case (int)ChunkID.ADT.MCAL:
                ReadMCAL(ADTtexstream, mapname, chunkData);     // alpha layers
                break;

            default:
                SkipUnknownChunk(ADTtexstream, chunkID, chunkSize);
                break;
            }
        }
        ADTTexData.textureBlockData.textureChunksData.Add(chunkData);
    }