//////////////////////////// ////// MCNK Subchunks ////// //////////////////////////// public void ReadMCVT(BinaryReader reader, ADTRootData.MeshChunkData chunkData) { for (int v = 1; v <= 145; v++) { chunkData.VertexHeights.Add(reader.ReadSingle()); } }
public void ReadMCDD(BinaryReader ADTstream, ADTRootData.MeshChunkData chunkData, uint MCDDsize) // there seems to be a high-res (?) mode which is not taken into account // in live clients (32 bytes instead of 8) (?). if inlined to MCNK is low-res. { //Debug.Log(MCDD + "found " + MCDDsize + " ----------I have info to parse it now"); // skip for now ADTstream.BaseStream.Seek(MCDDsize, SeekOrigin.Current); }
} // normals public void ReadMCSE(BinaryReader ADTstream, ADTRootData.MeshChunkData chunkData, uint MCSEsize) { if (MCSEsize != 0) { Debug.Log("MCSE found " + MCSEsize + " ----------I have info to parse it now"); ADTstream.BaseStream.Seek(MCSEsize, SeekOrigin.Current); // skip for now } }
} // vertex shading public void FillMCCV(ADTRootData.MeshChunkData chunkData) { chunkData.VertexColors = new Color32[145]; for (int col = 0; col < 145; col++) { Color32 colorBGRA = new Color32(127, 127, 127, 127); chunkData.VertexColors[col] = colorBGRA; } } // fill vertex shading with 127
public void ReadMCLV(BinaryReader reader, ADTRootData.MeshChunkData chunkData) { for (int v = 1; v <= 145; v++) { byte[] ARGB = new byte[4]; for (int b = 0; b < 4; b++) { ARGB[b] = reader.ReadByte(); } chunkData.VertexLighting.Add(ARGB); } // Alpha is ignored. // In contrast to MCCV does not only color but also lightens up the vertices. // Result of baking level-designer placed omni lights. With WoD, they added the actual lights to do live lighting. } // chunk lighting
} // chunk lighting public void ReadMCCV(BinaryReader reader, ADTRootData.MeshChunkData chunkData) { chunkData.VertexColors = new Color32[145]; List <int> vertcolors = new List <int>(); for (int col = 0; col < 145; col++) { int channelR = reader.ReadByte(); vertcolors.Add(channelR); int channelG = reader.ReadByte(); vertcolors.Add(channelG); int channelB = reader.ReadByte(); vertcolors.Add(channelB); int channelA = reader.ReadByte(); vertcolors.Add(channelA); Color32 colorsRGBA = new Color32((byte)channelR, (byte)channelG, (byte)channelB, (byte)channelA); Color32 colorBGRA = new Color32(colorsRGBA.b, colorsRGBA.g, colorsRGBA.r, colorsRGBA.a); chunkData.VertexColors[col] = colorBGRA; } } // vertex shading
} // fill vertex shading with 127 public void ReadMCNR(BinaryReader reader, ADTRootData.MeshChunkData chunkData) { chunkData.VertexNormals = new Vector3[145]; for (int n = 0; n < 145; n++) { Vector3 normsRaw = new Vector3(reader.ReadByte(), reader.ReadByte(), reader.ReadByte()); var calcX = reader.NormalizeValue(normsRaw.x); if (calcX <= 0) { calcX = 1 + calcX; } else if (calcX > 0) { calcX = (1 - calcX) * (-1); } var calcY = reader.NormalizeValue(normsRaw.y); if (calcY <= 0) { calcY = 1 + calcY; } else if (calcY > 0) { calcY = (1 - calcY) * (-1); } var calcZ = reader.NormalizeValue(normsRaw.z); if (calcZ <= 0) { calcZ = 1 + calcZ; } else if (calcZ > 0) { calcZ = (1 - calcZ) * (-1); } chunkData.VertexNormals[n] = new Vector3(calcX, calcZ, calcY); } // skip unused 13 byte padding // reader.BaseStream.Seek(13, SeekOrigin.Current); } // normals
public void ReadMCNK(BinaryReader reader, int MCNKchunkNumber, uint MCNKsize) { Flags f = new Flags(); ADTRootData.MeshChunkData chunkData = new ADTRootData.MeshChunkData(); long MCNKchnkPos = reader.BaseStream.Position; // <Header> - 128 bytes chunkData.flags = f.ReadMCNKflags(reader); chunkData.IndexX = reader.ReadUInt32(); chunkData.IndexY = reader.ReadUInt32(); chunkData.nLayers = reader.ReadUInt32(); // maximum 4 uint nDoodadRefs = reader.ReadUInt32(); chunkData.holes_high_res = reader.ReadUInt64(); // only used with flags.high_res_holes uint ofsLayer = reader.ReadUInt32(); uint ofsRefs = reader.ReadUInt32(); uint ofsAlpha = reader.ReadUInt32(); uint sizeAlpha = reader.ReadUInt32(); uint ofsShadow = reader.ReadUInt32(); // only with flags.has_mcsh uint sizeShadow = reader.ReadUInt32(); uint areaid = reader.ReadUInt32(); // in alpha: both zone id and sub zone id, as uint16s. uint nMapObjRefs = reader.ReadUInt32(); chunkData.holes_low_res = reader.ReadUInt16(); ushort unknown_but_used = reader.ReadUInt16(); // 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] = reader.ReadByte(); } // unsigned integers, naming the layer. ulong noEffectDoodad = reader.ReadUInt64(); // WoD: may be an explicit MCDD chunk int ofsSndEmitters = reader.ReadInt32(); int nSndEmitters = reader.ReadInt32(); // will be set to 0 in the client if ofsSndEmitters doesn't point to MCSE! int ofsLiquid = reader.ReadInt32(); int sizeLiquid = reader.ReadInt32(); // 8 when not used; only read if >8. // in alpha, remainder is padding but unused. chunkData.MeshPosition = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int ofsMCCV = reader.ReadInt32(); // only with flags.has_mccv, had uint32_t textureId; in ObscuR's structure. int ofsMCLV = reader.ReadInt32(); // introduced in Cataclysm int unused = reader.ReadInt32(); // currently unused // </header> if (!chunkData.flags.has_mccv) { FillMCCV(chunkData); // fill vertex shading with 127... } long streamPosition = reader.BaseStream.Position; while (streamPosition < MCNKchnkPos + MCNKsize) { reader.BaseStream.Position = streamPosition; ADTChunkId chunkId = (ADTChunkId)reader.ReadInt32(); uint chunkSize = reader.ReadUInt32(); streamPosition = reader.BaseStream.Position + chunkSize; switch (chunkId) { case ADTChunkId.MCVT: ReadMCVT(reader, chunkData); // vertex heights break; case ADTChunkId.MCLV: ReadMCLV(reader, chunkData); // chunk lighting break; case ADTChunkId.MCCV: ReadMCCV(reader, chunkData); // vertex shading break; case ADTChunkId.MCNR: ReadMCNR(reader, chunkData); // normals break; case ADTChunkId.MCSE: ReadMCSE(reader, chunkData, chunkSize); // sound emitters break; case ADTChunkId.MCBB: ReadMCBB(reader, chunkData, chunkSize); break; case ADTChunkId.MCDD: ReadMCDD(reader, chunkData, chunkSize); break; default: SkipUnknownChunk(reader, chunkId, chunkSize); break; } } ADTRootData.meshBlockData.meshChunksData.Add(chunkData); }
public void ReadMCBB(BinaryReader ADTstream, ADTRootData.MeshChunkData chunkData, uint MCBBsize) // blend batches. max 256 per MCNK { //Debug.Log(MCBB + "found " + MCBBsize + " ----------I have info to parse it now"); // skip for now ADTstream.BaseStream.Seek(MCBBsize, SeekOrigin.Current); }