示例#1
0
    public void ReadMH2O(MemoryStream ADTstream, int MH2Osize)
    {
        StreamTools s = new StreamTools();
        long        chunkStartPosition = ADTstream.Position;

        // header - SMLiquidChunk
        for (int a = 0; a < 256; a++)
        {
            int offset_instances  = s.ReadLong(ADTstream);      // points to SMLiquidInstance[layer_count]
            int layer_count       = s.ReadLong(ADTstream);      // 0 if the chunk has no liquids. If > 1, the offsets will point to arrays.
            int offset_attributes = s.ReadLong(ADTstream);      // points to mh2o_chunk_attributes, can be ommitted for all-0
            if (offset_instances >= 0)
            {
                // instances @24bytes
                ADTstream.Seek(chunkStartPosition + offset_instances, SeekOrigin.Begin);
                int liquid_type          = s.ReadShort(ADTstream); //DBC - foreign_keyⁱ<uint16_t, &LiquidTypeRec::m_ID> liquid_type;
                int liquid_object_or_lvf = s.ReadShort(ADTstream); //DBC -  foreign_keyⁱ<uint16_t, &LiquidObjectRec::m_ID> liquid_object_or_lvf;
                                                                   // if > 41, an id into DB/LiquidObject. If below, LiquidVertexFormat, used in ADT/v18#instance_vertex_data Note hardcoded LO ids below.
                                                                   // if >= 42, look up via DB/LiquidType and DB/LiquidMaterial, otherwise use liquid_object_or_lvf as LVF
                                                                   // also see below for offset_vertex_data: if that's 0 and lt ≠ 2 → lvf = 2
                float min_height_level = s.ReadFloat(ADTstream);   // used as height if no heightmap given and culling ᵘ
                float max_height_level = s.ReadFloat(ADTstream);   // ≥ WoD ignores value and assumes to both be 0.0 for LVF = 2! ᵘ
                int   x_offset         = ADTstream.ReadByte();     // The X offset of the liquid square (0-7)
                int   y_offset         = ADTstream.ReadByte();     // The Y offset of the liquid square (0-7)
                int   width            = ADTstream.ReadByte();     // The width of the liquid square (1-8)
                int   height           = ADTstream.ReadByte();     // The height of the liquid square (1-8)
                                                                   // The above four members are only used if liquid_object_or_lvf <= 41. Otherwise they are assumed 0, 0, 8, 8. (18179)
                int offset_exists_bitmap = s.ReadLong(ADTstream);  // not all tiles in the instances need to be filled. always 8*8 bits.
                                                                   // offset can be 0 for all-exist. also see (and extend) Talk:ADT/v18#SMLiquidInstance
                int offset_vertex_data = s.ReadLong(ADTstream);    // actual data format defined by LiquidMaterialRec::m_LVF via LiquidTypeRec::m_materialID
                                                                   // if offset = 0 and liquidType ≠ 2, then let LVF = 2, i.e. some ocean shit
            }
            //attributes
            if (offset_attributes >= 0)
            {
                ADTstream.Seek(chunkStartPosition + offset_attributes, SeekOrigin.Begin);
                ulong fishable = s.ReadUint64(ADTstream);               // seems to be usable as visibility information.
                ulong deep     = s.ReadUint64(ADTstream);
            }
        }
        ADTstream.Seek(chunkStartPosition + MH2Osize, SeekOrigin.Begin); // set stream location to right after MH2O
    }
示例#2
0
    public void ReadMCNK(MemoryStream ADTstream, int MCNKchunkNumber, int MCNKsize)
    {
        StreamTools s = new StreamTools();
        Flags       f = new Flags();

        ADTRootData.MeshChunkData chunkData = new ADTRootData.MeshChunkData();
        long MCNKchnkPos = ADTstream.Position;

        // <Header> - 128 bytes
        chunkData.flags = f.ReadMCNKflags(ADTstream);

        chunkData.IndexX  = s.ReadLong(ADTstream);
        chunkData.IndexY  = s.ReadLong(ADTstream);
        chunkData.nLayers = s.ReadLong(ADTstream);  // maximum 4
        int nDoodadRefs = s.ReadLong(ADTstream);

        chunkData.holes_high_res = s.ReadUint64(ADTstream);  // only used with flags.high_res_holes
        int ofsLayer    = s.ReadLong(ADTstream);
        int ofsRefs     = s.ReadLong(ADTstream);
        int ofsAlpha    = s.ReadLong(ADTstream);
        int sizeAlpha   = s.ReadLong(ADTstream);
        int ofsShadow   = s.ReadLong(ADTstream); // only with flags.has_mcsh
        int sizeShadow  = s.ReadLong(ADTstream);
        int areaid      = s.ReadLong(ADTstream); // in alpha: both zone id and sub zone id, as uint16s.
        int nMapObjRefs = s.ReadLong(ADTstream);

        chunkData.holes_low_res = s.ReadShort(ADTstream);
        int unknown_but_used = s.ReadShort(ADTstream);       // in alpha: padding

        byte[] ReallyLowQualityTextureingMap = new byte[16]; // uint2_t[8][8] "predTex", It is used to determine which detail doodads to show. Values are an array of two bit
        for (int b = 0; b < 16; b++)
        {
            ReallyLowQualityTextureingMap[b] = (byte)ADTstream.ReadByte();
        }
        // unsigned integers, naming the layer.
        ulong noEffectDoodad = s.ReadUint64(ADTstream);                 // WoD: may be an explicit MCDD chunk
        int   ofsSndEmitters = s.ReadLong(ADTstream);
        int   nSndEmitters   = s.ReadLong(ADTstream);                   // will be set to 0 in the client if ofsSndEmitters doesn't point to MCSE!
        int   ofsLiquid      = s.ReadLong(ADTstream);
        int   sizeLiquid     = s.ReadLong(ADTstream);                   // 8 when not used; only read if >8.

        // in alpha, remainder is padding but unused.
        chunkData.MeshPosition = new Vector3(s.ReadFloat(ADTstream), s.ReadFloat(ADTstream), s.ReadFloat(ADTstream));
        int ofsMCCV = s.ReadLong(ADTstream);                             // only with flags.has_mccv, had uint32_t textureId; in ObscuR's structure.
        int ofsMCLV = s.ReadLong(ADTstream);                             // introduced in Cataclysm
        int unused  = s.ReadLong(ADTstream);                             // currently unused

        // </header>

        if (!chunkData.flags.has_mccv)
        {
            FillMCCV(chunkData); // fill vertex shading with 127...
        }
        long streamPosition = ADTstream.Position;

        while (streamPosition < MCNKchnkPos + MCNKsize)
        {
            ADTstream.Position = streamPosition;
            int chunkID   = s.ReadLong(ADTstream);
            int chunkSize = s.ReadLong(ADTstream);
            streamPosition = ADTstream.Position + chunkSize;
            switch (chunkID)
            {
            case (int)ChunkID.ADT.MCVT:
                ReadMCVT(ADTstream, chunkData);     // vertex heights
                break;

            case (int)ChunkID.ADT.MCLV:
                ReadMCLV(ADTstream, chunkData);     // chunk lighting
                break;

            case (int)ChunkID.ADT.MCCV:
                ReadMCCV(ADTstream, chunkData);     // vertex shading
                break;

            case (int)ChunkID.ADT.MCNR:
                ReadMCNR(ADTstream, chunkData);     // normals
                break;

            case (int)ChunkID.ADT.MCSE:
                ReadMCSE(ADTstream, chunkData, chunkSize);     // sound emitters
                break;

            case (int)ChunkID.ADT.MCBB:
                ReadMCBB(ADTstream, chunkData, chunkSize);
                break;

            case (int)ChunkID.ADT.MCDD:
                ReadMCDD(ADTstream, chunkData, chunkSize);
                break;

            default:
                SkipUnknownChunk(ADTstream, chunkID, chunkSize);
                break;
            }
        }
        ADTRootData.meshBlockData.meshChunksData.Add(chunkData);
    }