public TextAsset ToAsset(BinaryAsset basset) { var text = Encoding.UTF8.GetString(basset.Bytes); TextAsset asset = Activator.CreateInstance( basset.AssetType, new object[] { text }) as TextAsset; return(asset); }
public override bool Compile(GameAssetType gameAsset, Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription) { BinaryAsset texture = new BinaryAsset(0); string file = null; foreach (XmlAttribute attribute in node.Attributes) { switch (attribute.Name) { case "File": file = attribute.Value; break; case "Type": string[] enumValueNames = typeof(TextureType).GetEnumNames(); for (int idx = 0; idx < enumValueNames.Length; ++idx) { if (enumValueNames[idx] == attribute.Value) { FileHelper.SetInt(idx, 0x04, asset.Content); } } break; } } if (file == null) { ErrorDescription = string.Format("No file set for {0}", trace); return(false); } Uri fileUri = Macro.Parse(file); if (!fileUri.IsAbsoluteUri) { fileUri = new Uri(baseUri, fileUri); } file = fileUri.LocalPath; if (!File.Exists(file)) { ErrorDescription = string.Format("File not found for {0}", trace); return(false); } using (FileStream textureStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader textureReader = new BinaryReader(textureStream)) { texture.Content = textureReader.ReadBytes((int)(textureStream.Length)); } } asset.CData = new BinaryAsset(8); asset.CData.SubAssets.Add(0, texture); FileHelper.SetInt(texture.Content.Length, 0x04, asset.CData.Content); ErrorDescription = string.Empty; return(true); }
public static void LoadAsset(BinaryAsset asset, Action <GameObject> onLoad) { if (asset.Url != null) { var local = WebServices.Instance.MediaDownloadManager.GetPathForItem(asset.Url); var localUri = (new Uri(local)).AbsoluteUri; Load(localUri, onLoad); } }
public static Asset ResolveBinaryAsset(BinaryAsset basset) { Type type = _converters[basset.AssetType]; if (type == null) throw new AssetConverterException( string.Format("Failed to find converter for type: {0}",basset.AssetType.FullName)); var converter = Activator.CreateInstance(type) as IBassetToAssetConvertable<Asset>; if (converter == null) throw new AssetConverterException(string.Format( "Converter {0} does not implement interface IBassetToAssetConvertable.",type.Name)); return converter.ToAsset(basset); }
/// <summary> /// Collects info about data and injects it into track's assets list. /// </summary> public void RegisterAssets(Track track) { try { var filePaths = NTDFiles.Items; foreach (string file in filePaths) { // WEB ASSET if (Regex.IsMatch(file, WebAssetPattern)) { Match m = Regex.Match(file, WebAssetPattern); string url = m.Groups[1].Value; WebAsset webAsset = new WebAsset(url); track.Assets.Add(webAsset); continue; } // MODIFY if (_modifyMode) { Match m = Regex.Match(file, ModifyTrackPattern); if (m.Success) { int indexOfAsset = int.Parse(m.Groups[1].Value) - 1; track.Assets.Add(_track.Assets[indexOfAsset]); continue; } } // OTHER FILES FileInfo fi = new FileInfo(file); Type type = AssetConverter.GetAssetTypeByExtension(fi.Extension); var bytes = File.ReadAllBytes(file); var basset = new BinaryAsset(type, bytes); var asset = AssetConverter.ResolveBinaryAsset(basset); track.Assets.Add(asset); } } catch (Exception e) { throw new ForUserException( "A Problem occured during registering assets. Details: " + e.Message); } }
/// <summary> /// /// </summary> /// <param name="nsPath"></param> /// <returns></returns> public static Track ReadTrack(string nsPath) { try { Track t = new Track(); using (BinaryReader reader = new BinaryReader(File.OpenRead(nsPath))) { // TRACK INFO t.TrackInfo.Name = reader.ReadString(); t.TrackInfo.Author = reader.ReadString(); t.TrackInfo.ImageLen = reader.ReadInt32(); t.TrackInfo.Image = reader.ReadBytes(t.TrackInfo.ImageLen); t.TrackInfo.SliderValue = reader.ReadDouble(); t.TrackInfo.Encrypted = reader.ReadBoolean(); string password = null; if (t.TrackInfo.Encrypted) { var dialog = InfoDialog.ShowValueDialog("Enter the password:"******"Fail with interpreting the track."); } }
public PdfAsset ToAsset(BinaryAsset basset) { // CREATE DIR IF DOES NOT EXIST if (!Directory.Exists(Paths.Temp)) { Directory.CreateDirectory(Paths.Temp); } var data = basset.Bytes; string tempPath; do // random until new name { var randomName = Code.Converter.RandomString(50); tempPath = $"{Paths.Temp}\\{randomName}.pdf"; } while (File.Exists(tempPath)); var file = File.Create(tempPath); file.Write(data, 0, data.Length); file.Close(); return(new PdfAsset(tempPath)); }
public override bool Compile(GameAssetType gameAsset, Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription) { string exe = System.Reflection.Assembly.GetEntryAssembly().Location; // xml string file = null; string subtitle; int samplerate; int quality = 75; byte compression = 2; bool isstreamed = false; // wav int wsamplerate = 0; int wdatasize = 0; short wchannelcount = 0; short wsamplesize = 0; XmlNode subNode = node.Attributes.GetNamedItem("File"); if (subNode != null) { file = subNode.Value; } if (file == null) { ErrorDescription = string.Format("No file set for AudioFile:{0}", trace); return(false); } Uri fileUri = Macro.Parse(file); if (!fileUri.IsAbsoluteUri) { fileUri = new Uri(baseUri, fileUri); } file = fileUri.LocalPath; if (!File.Exists(file)) { ErrorDescription = string.Format("File not found for AudioFile:{0}", trace); return(false); } using (FileStream audioStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader audioReader = new BinaryReader(audioStream)) { // resampling not implemented /* * subNode = node.Attributes.GetNamedItem("PCSampleRate"); * if (subNode != null) * { * samplerate = Convert.ToInt32(subNode.Value); * } * else { samplerate = wsamplerate; } */ samplerate = wsamplerate; // predefined compression setting is used for now /* * subNode = node.Attributes.GetNamedItem("PCCompression"); * if (subNode != null) * { * string[] enumValueNames = typeof(AudioCompressionSetting).GetEnumNames(); * for (int idx = 0; idx < enumValueNames.Length; ++idx) * { * if (enumValueNames[idx] == subNode.Value) * { * switch (idx) * { * case 1: * compression = 4; * break; * case 2: * compression = 5; * break; * } * } * } * } */ string ext = Path.GetExtension(file).ToUpperInvariant(); switch (ext) { case ".WAV": compression = 2; audioReader.BaseStream.Position = 0x16; wchannelcount = audioReader.ReadInt16(); wsamplerate = audioReader.ReadInt32(); audioReader.BaseStream.Position = 0x22; wsamplesize = (short)(audioReader.ReadInt16() >> 3); audioReader.BaseStream.Position = 0x28; wdatasize = audioReader.ReadInt32(); if (wsamplesize > 2) { ErrorDescription = string.Format("Invalid file type for AudioFile:{0}. Unsigned 8 bit or signed 16 bit PCM Wave file is needed.", trace); return(false); } break; case ".MP3": compression = 5; break; default: ErrorDescription = string.Format("Invalid file type for AudioFile:{0}. Unsigned 8 bit or signed 16 bit PCM Wave file is needed.", trace); return(false); break; } // only used for wav to EALayer3 conversion which is not implemented /* * subNode = node.Attributes.GetNamedItem("PCQuality"); * if (subNode != null) { quality = Convert.ToInt32(subNode.Value); } */ subNode = node.Attributes.GetNamedItem("IsStreamedOnPC"); if (subNode != null) { isstreamed = Convert.ToBoolean(subNode.Value); } subNode = node.Attributes.GetNamedItem("SubtitleStringName"); if (subNode != null) { subtitle = subNode.Value; } else { subNode = node.Attributes.GetNamedItem("id"); subtitle = string.Format("DialogEvent:{0}SubTitle", subNode.Value); } int stringLength = subtitle.Length; FileHelper.SetInt(stringLength, 0x04, asset.Content); stringLength += 4 - (stringLength % 4); BinaryAsset stringAsset = new BinaryAsset(stringLength); FileHelper.SetString(subtitle, 0, stringAsset.Content); asset.SubAssets.Add(0x08, stringAsset); BinaryAsset tempAsset = new BinaryAsset(0); BinaryAsset samplesAsset = new BinaryAsset(0); switch (compression) { case 2: // uncompressed int wsamplecount = wdatasize / wsamplesize; FileHelper.SetInt(wsamplecount / wchannelcount, 0x0C, asset.Content); FileHelper.SetInt(wsamplerate, 0x10, asset.Content); FileHelper.SetInt(wchannelcount, 0x1C, asset.Content); short iwsamplerate = FileHelper.Invert((short)wsamplerate); int iwsamplecount = FileHelper.Invert(wsamplecount / wchannelcount); int datasize = wsamplecount << 1; int pos = 0; short sample; samplesAsset = new BinaryAsset(wsamplecount << 1); for (int idx = 0; idx < wsamplecount; ++idx) { if (wsamplesize == 1) { sample = (short)((audioReader.ReadByte() - 0x80) << 8); } else { sample = audioReader.ReadInt16(); } if (sample < 0) { sample++; } else if (sample > 0) { sample--; } FileHelper.SetShort(FileHelper.Invert(sample), pos, samplesAsset.Content); pos += 2; } if (isstreamed) { tempAsset = new BinaryAsset(8); FileHelper.SetByte(compression, 0, tempAsset.Content); FileHelper.SetByte((byte)((wchannelcount - 1) << 2), 0x01, tempAsset.Content); FileHelper.SetShort(iwsamplerate, 0x02, tempAsset.Content); FileHelper.SetInt(iwsamplecount | 0x00000040, 0x04, tempAsset.Content); asset.SubAssets.Add(0x14, tempAsset); FileHelper.SetInt(8, 0x18, asset.Content); int blocksize; int lastblocksize; int blockcount; int samplecountperblock; pos = 0; blocksize = 0x07F8; blockcount = (datasize / blocksize); lastblocksize = datasize % blocksize; samplecountperblock = (blocksize >> 1) / wchannelcount; if (lastblocksize == 0) { lastblocksize = blocksize; } else { blockcount++; } asset.CData = new BinaryAsset((blockcount - 1) * (blocksize + 8) + lastblocksize + 8); for (int i = 0; i < blockcount - 1; ++i) { FileHelper.SetInt(FileHelper.Invert(blocksize + 8), pos, asset.CData.Content); pos += 4; FileHelper.SetInt(FileHelper.Invert(samplecountperblock), pos, asset.CData.Content); pos += 4; Array.Copy(samplesAsset.Content, i * blocksize, asset.CData.Content, pos, blocksize); pos += blocksize; } FileHelper.SetInt(FileHelper.Invert(lastblocksize + 8) | 0x00000080, pos, asset.CData.Content); pos += 4; FileHelper.SetInt(FileHelper.Invert((lastblocksize >> 1) / wchannelcount), pos, asset.CData.Content); pos += 4; Array.Copy(samplesAsset.Content, (blockcount - 1) * blocksize, asset.CData.Content, pos, lastblocksize); } else { tempAsset = new BinaryAsset(0x10); FileHelper.SetByte(compression, 0, tempAsset.Content); FileHelper.SetByte((byte)((wchannelcount - 1) << 2), 0x01, tempAsset.Content); FileHelper.SetShort(iwsamplerate, 0x02, tempAsset.Content); FileHelper.SetInt(iwsamplecount, 0x04, tempAsset.Content); FileHelper.SetInt(FileHelper.Invert(datasize + 8), 0x08, tempAsset.Content); FileHelper.SetInt(iwsamplecount, 0x0C, tempAsset.Content); asset.CData = new BinaryAsset(tempAsset.Content.Length + samplesAsset.Content.Length); Array.Copy(tempAsset.Content, 0, asset.CData.Content, 0, tempAsset.Content.Length); Array.Copy(samplesAsset.Content, 0, asset.CData.Content, tempAsset.Content.Length, samplesAsset.Content.Length); } break; case 4: // XAS break; case 5: // EALayer3 // only streamed EALayer3 is supported yet isstreamed = true; string tempfile = exe + "_1.temp"; Process p = new Process(); p.StartInfo.FileName = Path.GetDirectoryName(exe) + "\\EALayer3.exe"; p.StartInfo.UseShellExecute = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.Arguments = "-E \"" + file + "\" --single-block -o \"" + tempfile + "\""; p.Start(); p.WaitForExit(); using (FileStream ealayer3Stream = new FileStream(tempfile, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader ealayer3Reader = new BinaryReader(ealayer3Stream)) { ealayer3Reader.BaseStream.Position = 1; FileHelper.SetInt((int)(ealayer3Reader.ReadByte() / 4 + 1), 0x1C, asset.Content); FileHelper.SetInt((int)FileHelper.Invert(ealayer3Reader.ReadInt16()), 0x10, asset.Content); FileHelper.SetInt(FileHelper.Invert(ealayer3Reader.ReadInt32()), 0x0C, asset.Content); if (isstreamed) { string tempfile2 = exe + "_2.temp"; ealayer3Reader.BaseStream.Position = 0; tempAsset = new BinaryAsset(8); FileHelper.SetInt(ealayer3Reader.ReadInt32(), 0, tempAsset.Content); FileHelper.SetInt(ealayer3Reader.ReadInt32() | 0x00000040, 4, tempAsset.Content); asset.SubAssets.Add(0x14, tempAsset); FileHelper.SetInt(8, 0x18, asset.Content); p = new Process(); p.StartInfo.FileName = Path.GetDirectoryName(exe) + "\\EALayer3.exe"; p.StartInfo.UseShellExecute = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.Arguments = "-E \"" + file + "\" -o \"" + tempfile2 + "\""; p.Start(); p.WaitForExit(); using (FileStream ealayer3Stream2 = new FileStream(tempfile2, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader ealayer3Reader2 = new BinaryReader(ealayer3Stream2)) { ealayer3Reader2.BaseStream.Position = 0; asset.CData = new BinaryAsset((int)ealayer3Stream2.Length); asset.CData.Content = ealayer3Reader2.ReadBytes((int)ealayer3Stream2.Length); FileHelper.SetByte(0, 8, asset.CData.Content); } } File.Delete(tempfile2); } else { ealayer3Reader.BaseStream.Position = 0; asset.CData = new BinaryAsset((int)ealayer3Stream.Length); asset.CData.Content = ealayer3Reader.ReadBytes((int)ealayer3Stream.Length); } } } File.Delete(tempfile); break; } } } asset.IsWritingCDataHead = false; ErrorDescription = string.Empty; return(true); }
public override bool Compile(GameAssetType gameAsset, Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription) { foreach (BaseEntryType entry in gameAsset.Runtime.Entries) { if (entry.id == "Channels") { continue; } if (!entry.Compile(baseUri, asset, node, game, "W3DAnimation", ref position, out ErrorDescription)) { return(false); } } uint numFrames = uint.Parse(node.Attributes.GetNamedItem("NumFrames").Value); uint timecodedHash = StringHasher.Hash("AnimationChannelTimecoded"); List <BinaryAsset> channelList = new List <BinaryAsset>(); foreach (XmlNode childNode in node.ChildNodes) { if (childNode.Name == "Channels") { foreach (XmlNode channelNode in childNode) { if (channelNode.Name == "ChannelScalar" || channelNode.Name == "ChannelQuaternion") { BinaryAsset channelAsset = new BinaryAsset(36); int subPosition = 0; FileHelper.SetUInt(timecodedHash, subPosition, channelAsset.Content); subPosition += 4; string value = channelNode.Attributes.GetNamedItem("Type").Value; string[] enumValueNames = typeof(AnimationChannelType).GetEnumNames(); for (int idx = 0; idx < enumValueNames.Length; ++idx) { if (enumValueNames[idx] == value) { FileHelper.SetInt(idx, subPosition, channelAsset.Content); break; } } subPosition += 4; FileHelper.SetUInt(numFrames, subPosition, channelAsset.Content); subPosition += 4; int vectorLenPosition = subPosition; subPosition += 4; FileHelper.SetUShort(ushort.Parse(channelNode.Attributes.GetNamedItem("Pivot").Value), subPosition, channelAsset.Content); subPosition += 4; uint firstFrame = uint.Parse(channelNode.Attributes.GetNamedItem("FirstFrame").Value); if (channelNode.Name == "ChannelScalar") { FileHelper.SetUInt(1, vectorLenPosition, channelAsset.Content); FileHelper.SetUInt(numFrames, subPosition, channelAsset.Content); subPosition += 4; BinaryAsset frameAndBinaryFlagList = null; int sageUnsignedShortCount = 2 - ((int)numFrames & 1); if (sageUnsignedShortCount == 2) { frameAndBinaryFlagList = new BinaryAsset((int)numFrames << 1); } else { frameAndBinaryFlagList = new BinaryAsset(((int)numFrames + sageUnsignedShortCount) << 1); } channelAsset.SubAssets.Add(subPosition, frameAndBinaryFlagList); subPosition += 4; for (ushort idx = 0; idx < numFrames; ++idx) { FileHelper.SetUShort(idx, idx << 1, frameAndBinaryFlagList.Content); } FileHelper.SetUInt(numFrames, subPosition, channelAsset.Content); subPosition += 4; BinaryAsset valuesList = new BinaryAsset((int)numFrames << 2); channelAsset.SubAssets.Add(subPosition, valuesList); int index = 0; int frame = int.Parse(channelNode.Attributes.GetNamedItem("FirstFrame").Value); int framePosition = 0; foreach (XmlNode frameNode in channelNode.ChildNodes) { if (frameNode.Name == "Frame") { if (index < firstFrame) { ++index; continue; } FileHelper.SetFloat(float.Parse(frameNode.InnerText, NumberFormatInfo.InvariantInfo), framePosition, valuesList.Content); framePosition += 4; ++index; if (index - firstFrame == numFrames) { break; } } } } else { FileHelper.SetUInt(4, vectorLenPosition, channelAsset.Content); FileHelper.SetUInt(numFrames, subPosition, channelAsset.Content); subPosition += 4; BinaryAsset frameAndBinaryFlagList = null; int sageUnsignedShortCount = 2 - ((int)numFrames & 1); if (sageUnsignedShortCount == 2) { frameAndBinaryFlagList = new BinaryAsset((int)numFrames << 1); } else { frameAndBinaryFlagList = new BinaryAsset(((int)numFrames + sageUnsignedShortCount) << 1); } channelAsset.SubAssets.Add(subPosition, frameAndBinaryFlagList); subPosition += 4; for (ushort idx = 0; idx < numFrames; ++idx) { FileHelper.SetUShort(idx, idx << 1, frameAndBinaryFlagList.Content); } FileHelper.SetUInt(numFrames << 2, subPosition, channelAsset.Content); subPosition += 4; BinaryAsset valuesList = new BinaryAsset((int)numFrames << 4); channelAsset.SubAssets.Add(subPosition, valuesList); int index = 0; int framePosition = 0; int frame = int.Parse(channelNode.Attributes.GetNamedItem("FirstFrame").Value); foreach (XmlNode frameNode in channelNode.ChildNodes) { if (frameNode.Name == "Frame") { if (index < firstFrame) { ++index; continue; } FileHelper.SetFloat(float.Parse(frameNode.Attributes.GetNamedItem("X").Value, NumberFormatInfo.InvariantInfo), framePosition, valuesList.Content); framePosition += 4; FileHelper.SetFloat(float.Parse(frameNode.Attributes.GetNamedItem("Y").Value, NumberFormatInfo.InvariantInfo), framePosition, valuesList.Content); framePosition += 4; FileHelper.SetFloat(float.Parse(frameNode.Attributes.GetNamedItem("Z").Value, NumberFormatInfo.InvariantInfo), framePosition, valuesList.Content); framePosition += 4; FileHelper.SetFloat(float.Parse(frameNode.Attributes.GetNamedItem("W").Value, NumberFormatInfo.InvariantInfo), framePosition, valuesList.Content); framePosition += 4; ++index; if (index - firstFrame == numFrames) { break; } } } } channelList.Add(channelAsset); } } break; } } BinaryAsset choiceAsset = new BinaryAsset(channelList.Count << 2); FileHelper.SetInt(channelList.Count, position, asset.Content); position += 4; asset.SubAssets.Add(position, choiceAsset); int choicePosition = 0; foreach (BinaryAsset choice in channelList) { choiceAsset.SubAssets.Add(choicePosition, choice); choicePosition += 4; } ErrorDescription = string.Empty; return(true); }
public override bool Compile(GameAssetType gameAsset, Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription) { List <TerrainTextureTileRuntime> tiles = new List <TerrainTextureTileRuntime>(); List <XmlNode> nodes = new List <XmlNode>(); foreach (XmlNode childNode in node.ChildNodes) { if (childNode.Name == "Tile") { nodes.Add(childNode); } } FileHelper.SetInt(nodes.Count, 4, asset.Content); BinaryAsset tileList = new BinaryAsset(12 * nodes.Count); asset.SubAssets.Add(8, tileList); DDSFile[,] textureList = new DDSFile[nodes.Count, 2]; BinaryAsset baseAsset = new BinaryAsset(0); BinaryAsset normalAsset = new BinaryAsset(0); uint positionX = 16; uint positionY = 16; uint nextX = 0; for (int idx = 0; idx < nodes.Count; ++idx) { FileHelper.SetUInt(uint.Parse(nodes[idx].Attributes["TextureID"].Value), idx * 12, tileList.Content); string baseTexture = nodes[idx].Attributes["BaseTexture"].Value; baseTexture = baseTexture.Substring(baseTexture.LastIndexOf(Path.DirectorySeparatorChar) + 1); baseTexture = baseTexture.Substring(baseTexture.LastIndexOf('/') + 1); baseTexture = baseTexture.Substring(0, baseTexture.LastIndexOf('.')); string baseTexturePath = Macro.Terrain + baseTexture + ".dds"; if (!IOFile.Exists(baseTexturePath)) { ErrorDescription = string.Format("{0} doesn't exist.", baseTexturePath); return(false); } using (FileStream textureStream = new FileStream(baseTexturePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader textureReader = new BinaryReader(textureStream)) { textureList[idx, 0] = new DDSFile(textureReader.ReadBytes((int)(textureStream.Length))); } } string normalTexture = nodes[idx].Attributes["NormalTexture"].Value; normalTexture = normalTexture.Substring(normalTexture.LastIndexOf(Path.DirectorySeparatorChar) + 1); normalTexture = normalTexture.Substring(normalTexture.LastIndexOf('/') + 1); normalTexture = normalTexture.Substring(0, normalTexture.LastIndexOf('.')); string normalTexturePath = Macro.Terrain + normalTexture + ".dds"; if (!IOFile.Exists(normalTexturePath)) { ErrorDescription = string.Format("{0} doesn't exist.", normalTexturePath); return(false); } using (FileStream textureStream = new FileStream(normalTexturePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader textureReader = new BinaryReader(textureStream)) { textureList[idx, 1] = new DDSFile(textureReader.ReadBytes((int)(textureStream.Length))); } } } // fixed height, automatically calculated width ushort atlasWidth = 0; ushort atlasHeight = 1152; /* * foreach (XmlAttribute attribute in node.Attributes) * { * switch (attribute.Name) * { * case "AtlasSize": * atlasSize = ushort.Parse(attribute.Value); * break; * } * } */ byte[,,] baseContent = new byte[0, atlasHeight, 4]; byte[,,] normalContent = new byte[0, atlasHeight, 4]; uint colWidth = 0; for (int tileIdx = 0; tileIdx < textureList.Length >> 1; ++tileIdx) { uint size = textureList[tileIdx, 0].Header.Height; colWidth = Math.Max(size + 32, colWidth); if (positionY + size + 16 > atlasHeight) { positionY = 16; positionX += nextX; colWidth = size + 32; } atlasWidth = (ushort)(positionX + colWidth - 16); baseContent = ResizeArray <byte>(baseContent, atlasWidth, atlasHeight, 4); normalContent = ResizeArray <byte>(normalContent, atlasWidth, atlasHeight, 4); byte[] color = textureList[tileIdx, 0].Content.GetColor(size, size); byte[] normal = textureList[tileIdx, 1].Content.GetColor(size, size); for (int idy = -16; idy < size + 16; ++idy) { for (int idx = -16; idx < size + 16; ++idx) { int tileY = idy; if (tileY < 0) { tileY = (int)(size + tileY); } else if (tileY >= size) { tileY = (int)(tileY - size); } int tileX = idx; if (tileX < 0) { tileX = (int)(size + tileX); } else if (tileX >= size) { tileX = (int)(tileX - size); } baseContent[(positionX + idx), (positionY + idy), 0] = color[tileY * size * 4 + tileX * 4]; baseContent[(positionX + idx), (positionY + idy), 1] = color[tileY * size * 4 + tileX * 4 + 1]; baseContent[(positionX + idx), (positionY + idy), 2] = color[tileY * size * 4 + tileX * 4 + 2]; baseContent[(positionX + idx), (positionY + idy), 3] = color[tileY * size * 4 + tileX * 4 + 3]; normalContent[(positionX + idx), (positionY + idy), 0] = normal[tileY * size * 4 + tileX * 4]; normalContent[(positionX + idx), (positionY + idy), 1] = normal[tileY * size * 4 + tileX * 4 + 1]; normalContent[(positionX + idx), (positionY + idy), 2] = normal[tileY * size * 4 + tileX * 4 + 2]; normalContent[(positionX + idx), (positionY + idy), 3] = normal[tileY * size * 4 + tileX * 4 + 3]; } } FileHelper.SetUShort((ushort)positionX, 12 * tileIdx + 4, tileList.Content); FileHelper.SetUShort((ushort)positionY, 12 * tileIdx + 6, tileList.Content); FileHelper.SetUShort((ushort)(positionX + size), 12 * tileIdx + 8, tileList.Content); FileHelper.SetUShort((ushort)(positionY + size), 12 * tileIdx + 10, tileList.Content); positionY += size + 32; nextX = Math.Max(size + 32, nextX); } byte[] baseContentArray = new byte[atlasWidth * atlasHeight * 4]; byte[] normalContentArray = new byte[atlasWidth * atlasHeight * 4]; for (int h = 0; h < atlasHeight; ++h) { for (int w = 0; w < atlasWidth; ++w) { for (int c = 0; c < 4; ++c) { baseContentArray[(h * atlasWidth * 4) + (w * 4) + c] = baseContent[w, h, c]; normalContentArray[(h * atlasWidth * 4) + (w * 4) + c] = normalContent[w, h, c]; } } } bool hasAlpha = false; for (int idx = 0; idx < nodes.Count; ++idx) { if (textureList[idx, 0].HasAlpha()) { hasAlpha = true; break; } } DDSFile baseAtlas = null; if (hasAlpha) { baseAtlas = new DDSFile(atlasWidth, atlasHeight, 5, DDSType.DXT5, baseContentArray); } else { baseAtlas = new DDSFile(atlasWidth, atlasHeight, 5, DDSType.DXT1, baseContentArray); } hasAlpha = false; for (int idx = 0; idx < nodes.Count; ++idx) { if (textureList[idx, 1].HasAlpha()) { hasAlpha = true; break; } } DDSFile normalAtlas = null; if (hasAlpha) { normalAtlas = new DDSFile(atlasWidth, atlasHeight, 5, DDSType.A1R5G5B5, normalContentArray); } else { normalAtlas = new DDSFile(atlasWidth, atlasHeight, 5, DDSType.R5G6B5, normalContentArray); } baseAsset.Content = baseAtlas.Binary; asset.SubAssets.Add(0x0C, baseAsset); FileHelper.SetInt(baseAsset.Content.Length, 0x10, asset.Content); normalAsset.Content = normalAtlas.Binary; asset.SubAssets.Add(0x14, normalAsset); FileHelper.SetInt(normalAsset.Content.Length, 0x18, asset.Content); ErrorDescription = string.Empty; return(true); }
public override bool Compile(GameAssetType gameAsset, Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription) { BinaryAsset w3dMeshPipelineVertexData = new BinaryAsset(0x1C); asset.SubAssets.Add(position, w3dMeshPipelineVertexData); position += 4; VertexData vertexData = new VertexData(); List <ushort> bones = new List <ushort>(); foreach (XmlNode childNode in node.ChildNodes) { switch (childNode.Name) { case "Vertices": ++vertexData.VerticesCount; List <Vector3> verticesList = new List <Vector3>(); if (vertexData.Vertices[0] == null) { vertexData.Vertices[0] = verticesList; } else { vertexData.Vertices[1] = verticesList; } foreach (XmlNode vertexNode in childNode.ChildNodes) { if (vertexNode.Name == "V") { Vector3 vertex = new Vector3(); vertex.X = float.Parse(vertexNode.Attributes.GetNamedItem("X").Value, NumberFormatInfo.InvariantInfo); vertex.Y = float.Parse(vertexNode.Attributes.GetNamedItem("Y").Value, NumberFormatInfo.InvariantInfo); vertex.Z = float.Parse(vertexNode.Attributes.GetNamedItem("Z").Value, NumberFormatInfo.InvariantInfo); verticesList.Add(vertex); } } break; case "Normals": ++vertexData.NormalsCount; List <Vector3> normalsList = new List <Vector3>(); if (vertexData.Normals[0] == null) { vertexData.Normals[0] = normalsList; } else { vertexData.Normals[1] = normalsList; } foreach (XmlNode normalNode in childNode.ChildNodes) { if (normalNode.Name == "N") { Vector3 normal = new Vector3(); normal.X = float.Parse(normalNode.Attributes.GetNamedItem("X").Value, NumberFormatInfo.InvariantInfo); normal.Y = float.Parse(normalNode.Attributes.GetNamedItem("Y").Value, NumberFormatInfo.InvariantInfo); normal.Z = float.Parse(normalNode.Attributes.GetNamedItem("Z").Value, NumberFormatInfo.InvariantInfo); normalsList.Add(normal); } } break; case "Tangents": ++vertexData.TangentsCount; List <Vector3> tangentsList = new List <Vector3>(); vertexData.Tangents = tangentsList; foreach (XmlNode tangentNode in childNode.ChildNodes) { if (tangentNode.Name == "T") { Vector3 tangent = new Vector3(); tangent.X = float.Parse(tangentNode.Attributes.GetNamedItem("X").Value, NumberFormatInfo.InvariantInfo); tangent.Y = float.Parse(tangentNode.Attributes.GetNamedItem("Y").Value, NumberFormatInfo.InvariantInfo); tangent.Z = float.Parse(tangentNode.Attributes.GetNamedItem("Z").Value, NumberFormatInfo.InvariantInfo); tangentsList.Add(tangent); } } break; case "Binormals": ++vertexData.BinormalsCount; List <Vector3> binormalsList = new List <Vector3>(); vertexData.Binormals = binormalsList; foreach (XmlNode binormalNode in childNode.ChildNodes) { if (binormalNode.Name == "B") { Vector3 binormal = new Vector3(); binormal.X = float.Parse(binormalNode.Attributes.GetNamedItem("X").Value, NumberFormatInfo.InvariantInfo); binormal.Y = float.Parse(binormalNode.Attributes.GetNamedItem("Y").Value, NumberFormatInfo.InvariantInfo); binormal.Z = float.Parse(binormalNode.Attributes.GetNamedItem("Z").Value, NumberFormatInfo.InvariantInfo); binormalsList.Add(binormal); } } break; case "VertexColors": List <RGBAColor> colorList = new List <RGBAColor>(); vertexData.VertexColors = colorList; foreach (XmlNode colorNode in childNode.ChildNodes) { if (colorNode.Name == "C") { RGBAColor color = new RGBAColor(); color.R = (byte)(float.Parse(colorNode.Attributes.GetNamedItem("B").Value, NumberFormatInfo.InvariantInfo) * 255); color.G = (byte)(float.Parse(colorNode.Attributes.GetNamedItem("G").Value, NumberFormatInfo.InvariantInfo) * 255); color.B = (byte)(float.Parse(colorNode.Attributes.GetNamedItem("R").Value, NumberFormatInfo.InvariantInfo) * 255); color.A = (byte)(float.Parse(colorNode.Attributes.GetNamedItem("A").Value, NumberFormatInfo.InvariantInfo) * 255); colorList.Add(color); } } break; case "TexCoords": List <Vector2> texcoordsList = new List <Vector2>(); vertexData.TexCoords.Add(texcoordsList); foreach (XmlNode texcoordNode in childNode.ChildNodes) { if (texcoordNode.Name == "T") { Vector2 texcoord = new Vector2(); texcoord.X = float.Parse(texcoordNode.Attributes.GetNamedItem("X").Value, NumberFormatInfo.InvariantInfo); texcoord.Y = 1 - float.Parse(texcoordNode.Attributes.GetNamedItem("Y").Value, NumberFormatInfo.InvariantInfo); texcoordsList.Add(texcoord); } } break; case "BoneInfluences": ++vertexData.BoneInfluencesCount; if (vertexData.BoneInfluences == null) { List <BoneInfluence> boneinfluenceList = new List <BoneInfluence>(); vertexData.BoneInfluences = boneinfluenceList; foreach (XmlNode boneinfluenceNode in childNode.ChildNodes) { if (boneinfluenceNode.Name == "I") { BoneInfluence boneinfluence = new BoneInfluence(); ushort bone = ushort.Parse(boneinfluenceNode.Attributes.GetNamedItem("Bone").Value); if (bones.Contains(bone)) { boneinfluence.Bones.R = (byte)bones.IndexOf(bone); } else { boneinfluence.Bones.R = (byte)bones.Count; bones.Add(bone); } boneinfluence.Influences.X = float.Parse(boneinfluenceNode.Attributes.GetNamedItem("Weight").Value, NumberFormatInfo.InvariantInfo); boneinfluenceList.Add(boneinfluence); } } } else { List <BoneInfluence> boneinfluenceList = vertexData.BoneInfluences; int idx = 0; foreach (XmlNode boneinfluenceNode in childNode.ChildNodes) { if (boneinfluenceNode.Name == "I") { ushort bone = ushort.Parse(boneinfluenceNode.Attributes.GetNamedItem("Bone").Value); if (bones.Contains(bone)) { boneinfluenceList[idx].Bones.G = (byte)bones.IndexOf(bone); } else { boneinfluenceList[idx].Bones.G = (byte)bones.Count; bones.Add(bone); } boneinfluenceList[idx].Influences.Y = float.Parse(boneinfluenceNode.Attributes.GetNamedItem("Weight").Value, NumberFormatInfo.InvariantInfo); ++idx; } } } break; case "ShadeIndices": // unused break; } } FileHelper.SetInt(vertexData.Vertices[0].Count, 0x00, w3dMeshPipelineVertexData.Content); List <VertexElement> vertexElements = new List <VertexElement>(); short vertexSize = 0; for (byte idx = 0; idx < vertexData.VerticesCount; ++idx) { VertexElement vertexElement = new VertexElement(); vertexElement.Offset = vertexSize; vertexElement.Type = VertexElementType.FLOAT3; vertexElement.Method = VertexElementMethod.DEFAULT; vertexElement.Usage = VertexElementUsage.POSITION; vertexElement.UsageIndex = idx; vertexElements.Add(vertexElement); vertexSize += 12; } for (byte idx = 0; idx < vertexData.NormalsCount; ++idx) { VertexElement vertexElement = new VertexElement(); vertexElement.Offset = vertexSize; vertexElement.Type = VertexElementType.FLOAT3; vertexElement.Method = VertexElementMethod.DEFAULT; vertexElement.Usage = VertexElementUsage.NORMAL; vertexElement.UsageIndex = idx; vertexElements.Add(vertexElement); vertexSize += 12; } VertexElement colorvertexElement = new VertexElement(); colorvertexElement.Offset = vertexSize; colorvertexElement.Type = VertexElementType.D3DCOLOR; colorvertexElement.Method = VertexElementMethod.DEFAULT; colorvertexElement.Usage = VertexElementUsage.COLOR; colorvertexElement.UsageIndex = 0; vertexElements.Add(colorvertexElement); vertexSize += 4; for (byte idx = 0; idx < vertexData.TangentsCount; ++idx) { VertexElement vertexElement = new VertexElement(); vertexElement.Offset = vertexSize; vertexElement.Type = VertexElementType.FLOAT3; vertexElement.Method = VertexElementMethod.DEFAULT; vertexElement.Usage = VertexElementUsage.TANGENT; vertexElement.UsageIndex = idx; vertexElements.Add(vertexElement); vertexSize += 12; } for (byte idx = 0; idx < vertexData.BinormalsCount; ++idx) { VertexElement vertexElement = new VertexElement(); vertexElement.Offset = vertexSize; vertexElement.Type = VertexElementType.FLOAT3; vertexElement.Method = VertexElementMethod.DEFAULT; vertexElement.Usage = VertexElementUsage.BINORMAL; vertexElement.UsageIndex = idx; vertexElements.Add(vertexElement); vertexSize += 12; } for (byte idx = 0; idx < vertexData.TexCoords.Count; ++idx) { VertexElement vertexElement = new VertexElement(); vertexElement.Offset = vertexSize; vertexElement.Type = VertexElementType.FLOAT2; vertexElement.Method = VertexElementMethod.DEFAULT; vertexElement.Usage = VertexElementUsage.TEXCOORD; vertexElement.UsageIndex = idx; vertexElements.Add(vertexElement); vertexSize += 8; } if (vertexData.BoneInfluencesCount != 0) { VertexElement vertexElement = new VertexElement(); vertexElement.Offset = vertexSize; vertexElement.Type = VertexElementType.D3DCOLOR; vertexElement.Method = VertexElementMethod.DEFAULT; vertexElement.Usage = VertexElementUsage.BLENDINDICES; vertexElement.UsageIndex = 0; vertexElements.Add(vertexElement); vertexSize += 4; foreach (BoneInfluence influence in vertexData.BoneInfluences) { if (influence.Influences.X != 1 || (vertexData.BoneInfluencesCount == 2 && influence.Influences.Y != 1)) { VertexElement influenceVertexElement = new VertexElement(); influenceVertexElement.Offset = vertexSize; influenceVertexElement.Type = VertexElementType.FLOAT2; influenceVertexElement.Method = VertexElementMethod.DEFAULT; influenceVertexElement.Usage = VertexElementUsage.BLENDWEIGHT; influenceVertexElement.UsageIndex = 0; vertexElements.Add(influenceVertexElement); vertexSize += 8; break; } } } vertexElements.Add(new VertexElement(true)); FileHelper.SetInt(vertexSize, 0x04, w3dMeshPipelineVertexData.Content); BinaryAsset binaryVertexData = new BinaryAsset(vertexData.Vertices[0].Count * vertexSize); w3dMeshPipelineVertexData.SubAssets.Add(0x08, binaryVertexData); FileHelper.SetInt(vertexElements.Count << 3, 0x0C, w3dMeshPipelineVertexData.Content); BinaryAsset binaryVertexElementData = new BinaryAsset(vertexElements.Count << 3); w3dMeshPipelineVertexData.SubAssets.Add(0x10, binaryVertexElementData); for (int idx = 0; idx < vertexElements.Count; ++idx) { VertexElement vertexElement = vertexElements[idx]; switch (vertexElement.Usage) { case VertexElementUsage.POSITION: List <Vector3> verticesList = vertexData.Vertices[vertexElement.UsageIndex]; for (int idy = 0; idy < verticesList.Count; ++idy) { Array.Copy(verticesList[idy].binary, 0, binaryVertexData.Content, idy * vertexSize + vertexElement.Offset, 12); } break; case VertexElementUsage.NORMAL: List <Vector3> normalsList = vertexData.Normals[vertexElement.UsageIndex]; for (int idy = 0; idy < normalsList.Count; ++idy) { Array.Copy(normalsList[idy].binary, 0, binaryVertexData.Content, idy * vertexSize + vertexElement.Offset, 12); } break; case VertexElementUsage.TANGENT: List <Vector3> tangentsList = vertexData.Tangents; for (int idy = 0; idy < tangentsList.Count; ++idy) { Array.Copy(tangentsList[idy].binary, 0, binaryVertexData.Content, idy * vertexSize + vertexElement.Offset, 12); } break; case VertexElementUsage.BINORMAL: List <Vector3> binormalsList = vertexData.Binormals; for (int idy = 0; idy < binormalsList.Count; ++idy) { Array.Copy(binormalsList[idy].binary, 0, binaryVertexData.Content, idy * vertexSize + vertexElement.Offset, 12); } break; case VertexElementUsage.COLOR: List <RGBAColor> colorsList = vertexData.VertexColors; if (colorsList != null) { for (int idy = 0; idy < colorsList.Count; ++idy) { Array.Copy(colorsList[idy].binary, 0, binaryVertexData.Content, idy * vertexSize + vertexElement.Offset, 4); } } else { int vertexCount = vertexData.Vertices[0].Count; for (int idy = 0; idy < vertexCount; ++idy) { FileHelper.SetInt(-1, idy * vertexSize + vertexElement.Offset, binaryVertexData.Content); } } break; case VertexElementUsage.TEXCOORD: List <Vector2> texcoordList = vertexData.TexCoords[vertexElement.UsageIndex]; for (int idy = 0; idy < texcoordList.Count; ++idy) { Array.Copy(texcoordList[idy].binary, 0, binaryVertexData.Content, idy * vertexSize + vertexElement.Offset, 8); } break; case VertexElementUsage.BLENDINDICES: List <BoneInfluence> blendindicesList = vertexData.BoneInfluences; for (int idy = 0; idy < blendindicesList.Count; ++idy) { Array.Copy(blendindicesList[idy].Bones.binary, 0, binaryVertexData.Content, idy * vertexSize + vertexElement.Offset, 4); } break; case VertexElementUsage.BLENDWEIGHT: List <BoneInfluence> blendweightList = vertexData.BoneInfluences; for (int idy = 0; idy < blendweightList.Count; ++idy) { Array.Copy(blendweightList[idy].Influences.binary, 0, binaryVertexData.Content, idy * vertexSize + vertexElement.Offset, 8); } break; } Array.Copy(vertexElement.binary, 0, binaryVertexElementData.Content, idx << 3, 8); } BinaryAsset boneList = null; int sageUnsignedShortCount = 2 - (bones.Count & 1); if (sageUnsignedShortCount == 2) { boneList = new BinaryAsset(bones.Count * 2); } else { boneList = new BinaryAsset((bones.Count + sageUnsignedShortCount) * 2); } for (int idx = 0; idx < bones.Count; ++idx) { FileHelper.SetUShort(bones[idx], idx * 2, boneList.Content); } FileHelper.SetInt(bones.Count, 0x14, w3dMeshPipelineVertexData.Content); w3dMeshPipelineVertexData.SubAssets.Add(0x18, boneList); foreach (BaseEntryType entry in gameAsset.Runtime.Entries) { if (entry.id == "VertexData") { continue; } if (!entry.Compile(baseUri, asset, node, game, "W3DMesh", ref position, out ErrorDescription)) { return(false); } } ErrorDescription = string.Empty; return(true); }
public abstract bool Compile(GameAssetType gameAsset, Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription);
public ImageAsset ToAsset(BinaryAsset basset) { var data = Code.Converter.BytesToBmpSource(basset.Bytes); return((ImageAsset)Activator.CreateInstance(basset.AssetType, data)); }
public override bool Compile(GameAssetType gameAsset, Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription) { XmlNode subNode = node.Attributes.GetNamedItem("Hierarchy"); string value = null; if (subNode != null) { value = subNode.Value; } else { value = string.Empty; } if (value != string.Empty) { string[] name = value.Split(':'); if (name.Length == 1) { asset.AssetImports.Add(position, new uint[] { StringHasher.Hash("W3DHierarchy"), StringHasher.Hash(name[0].ToLowerInvariant()) }); } else { asset.AssetImports.Add(position, new uint[] { StringHasher.Hash(name[0]), StringHasher.Hash(name[1].ToLowerInvariant()) }); } } position += 4; List <XmlNode> subObjectNodes = new List <XmlNode>(); foreach (XmlNode childNode in node.ChildNodes) { if (childNode.Name == "SubObject") { subObjectNodes.Add(childNode); } } FileHelper.SetInt(subObjectNodes.Count, position, asset.Content); position += 4; BinaryAsset subObjectAsset = new BinaryAsset(0x10 * subObjectNodes.Count); asset.SubAssets.Add(position, subObjectAsset); int subPosition = 0; foreach (XmlNode childNode in subObjectNodes) { SAGE.Types.SageUnsignedInt suint = new Types.SageUnsignedInt(childNode.Attributes.GetNamedItem("BoneIndex").Value); FileHelper.SetUInt(suint.Value, subPosition, subObjectAsset.Content); subPosition += 4; subNode = null; subNode = childNode.Attributes.GetNamedItem("SubObjectID"); if (subNode != null) { value = subNode.Value; } else { value = string.Empty; } if (value == string.Empty) { subPosition += 8; } else { int stringLength = value.Length; FileHelper.SetInt(stringLength, subPosition, subObjectAsset.Content); subPosition += 4; stringLength += 4 - (stringLength & 3); BinaryAsset stringAsset = new BinaryAsset(stringLength); FileHelper.SetString(value, 0, stringAsset.Content); subObjectAsset.SubAssets.Add(subPosition, stringAsset); subPosition += 4; } foreach (XmlNode renderObjectNode in childNode.ChildNodes) { if (renderObjectNode.Name == "RenderObject") { foreach (XmlNode referenceNode in renderObjectNode.ChildNodes) { if (referenceNode.Name == "Mesh") { value = referenceNode.InnerText; string[] name = value.Split(':'); if (name.Length == 1) { subObjectAsset.AssetImports.Add(subPosition, new uint[] { StringHasher.Hash("W3DMesh"), StringHasher.Hash(name[0].ToLowerInvariant()) }); } else { subObjectAsset.AssetImports.Add(subPosition, new uint[] { StringHasher.Hash(name[0]), StringHasher.Hash(name[1].ToLowerInvariant()) }); } break; } else if (referenceNode.Name == "CollisionBox") { value = referenceNode.InnerText; string[] name = value.Split(':'); if (name.Length == 1) { subObjectAsset.AssetImports.Add(subPosition, new uint[] { StringHasher.Hash("W3DCollisionBox"), StringHasher.Hash(name[0].ToLowerInvariant()) }); } else { subObjectAsset.AssetImports.Add(subPosition, new uint[] { StringHasher.Hash(name[0]), StringHasher.Hash(name[1].ToLowerInvariant()) }); } break; } } break; } } subPosition += 4; } ErrorDescription = string.Empty; return(true); }
public override bool Compile(GameAssetType gameAsset, Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription) { List <TerrainTextureTileRuntime> tiles = new List <TerrainTextureTileRuntime>(); int atlasSize = 2048; /*foreach (XmlAttribute attribute in node.Attributes) * { * switch (attribute.Name) * { * case "AtlasSize": * atlasSize = ushort.Parse(attribute.Value); * break; * } * }*/ List <XmlNode> nodes = new List <XmlNode>(); foreach (XmlNode childNode in node.ChildNodes) { if (childNode.Name == "Tile") { nodes.Add(childNode); } } FileHelper.SetInt(nodes.Count, 4, asset.Content); BinaryAsset tileList = new BinaryAsset(12 * nodes.Count); asset.SubAssets.Add(8, tileList); DDSFile[,] textureList = new DDSFile[nodes.Count, 2]; BinaryAsset baseAsset = new BinaryAsset(0); BinaryAsset normalAsset = new BinaryAsset(0); uint positionX = 16; uint positionY = 16; uint nextY = 0; for (int idx = 0; idx < nodes.Count; ++idx) { FileHelper.SetUInt(uint.Parse(nodes[idx].Attributes["TextureID"].Value), idx * 12, tileList.Content); string baseTexture = nodes[idx].Attributes["BaseTexture"].Value; baseTexture = baseTexture.Substring(baseTexture.LastIndexOf(Path.DirectorySeparatorChar) + 1); baseTexture = baseTexture.Substring(baseTexture.LastIndexOf('/') + 1); baseTexture = baseTexture.Substring(0, baseTexture.LastIndexOf('.')); string baseTexturePath = Macro.Terrain + baseTexture + ".dds"; if (!IOFile.Exists(baseTexturePath)) { ErrorDescription = string.Format("{0} doesn't exist.", baseTexturePath); return(false); } using (FileStream textureStream = new FileStream(baseTexturePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader textureReader = new BinaryReader(textureStream)) { textureList[idx, 0] = new DDSFile(textureReader.ReadBytes((int)(textureStream.Length))); } } string normalTexture = nodes[idx].Attributes["NormalTexture"].Value; normalTexture = normalTexture.Substring(normalTexture.LastIndexOf(Path.DirectorySeparatorChar) + 1); normalTexture = normalTexture.Substring(normalTexture.LastIndexOf('/') + 1); normalTexture = normalTexture.Substring(0, normalTexture.LastIndexOf('.')); string normalTexturePath = Macro.Terrain + normalTexture + ".dds"; if (!IOFile.Exists(normalTexturePath)) { ErrorDescription = string.Format("{0} doesn't exist.", normalTexturePath); return(false); } using (FileStream textureStream = new FileStream(normalTexturePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader textureReader = new BinaryReader(textureStream)) { textureList[idx, 1] = new DDSFile(textureReader.ReadBytes((int)(textureStream.Length))); } } } // For now assume each texture has the same size. atlasSize = (int)textureList[0, 0].Header.Width + 32; atlasSize *= atlasSize * (textureList.Length >> 1); atlasSize = (int)Math.Sqrt((double)atlasSize); --atlasSize; atlasSize |= atlasSize >> 1; atlasSize |= atlasSize >> 2; atlasSize |= atlasSize >> 4; atlasSize |= atlasSize >> 8; ++atlasSize; byte[] baseContent = new byte[atlasSize * atlasSize * 4]; byte[] normalContent = new byte[atlasSize * atlasSize * 4]; for (int tileIdx = 0; tileIdx < textureList.Length >> 1; ++tileIdx) { uint size = textureList[tileIdx, 0].Header.Width; if (positionX + size + 16 > atlasSize) { positionX = 16; positionY += nextY; } byte[] color = textureList[tileIdx, 0].Content.GetColor(size, size); byte[] normal = textureList[tileIdx, 1].Content.GetColor(size, size); for (int idy = -16; idy < size + 16; ++idy) { for (int idx = -16; idx < size + 16; ++idx) { int tileY = idy; if (tileY < 0) { tileY = (int)(size + tileY); } else if (tileY >= size) { tileY = (int)(tileY - size); } int tileX = idx; if (tileX < 0) { tileX = (int)(size + tileX); } else if (tileX >= size) { tileX = (int)(tileX - size); } baseContent[(positionY + idy) * atlasSize * 4 + (positionX + idx) * 4] = color[tileY * size * 4 + tileX * 4]; baseContent[(positionY + idy) * atlasSize * 4 + (positionX + idx) * 4 + 1] = color[tileY * size * 4 + tileX * 4 + 1]; baseContent[(positionY + idy) * atlasSize * 4 + (positionX + idx) * 4 + 2] = color[tileY * size * 4 + tileX * 4 + 2]; baseContent[(positionY + idy) * atlasSize * 4 + (positionX + idx) * 4 + 3] = color[tileY * size * 4 + tileX * 4 + 3]; normalContent[(positionY + idy) * atlasSize * 4 + (positionX + idx) * 4] = normal[tileY * size * 4 + tileX * 4]; normalContent[(positionY + idy) * atlasSize * 4 + (positionX + idx) * 4 + 1] = normal[tileY * size * 4 + tileX * 4 + 1]; normalContent[(positionY + idy) * atlasSize * 4 + (positionX + idx) * 4 + 2] = normal[tileY * size * 4 + tileX * 4 + 2]; normalContent[(positionY + idy) * atlasSize * 4 + (positionX + idx) * 4 + 3] = normal[tileY * size * 4 + tileX * 4 + 3]; } } FileHelper.SetUShort((ushort)positionX, 12 * tileIdx + 4, tileList.Content); FileHelper.SetUShort((ushort)positionY, 12 * tileIdx + 6, tileList.Content); FileHelper.SetUShort((ushort)(positionX + size), 12 * tileIdx + 8, tileList.Content); FileHelper.SetUShort((ushort)(positionY + size), 12 * tileIdx + 10, tileList.Content); positionX += size + 32; nextY = Math.Max(size + 32, nextY); } bool hasAlpha = false; for (int idx = 0; idx < nodes.Count; ++idx) { if (textureList[idx, 0].HasAlpha()) { hasAlpha = true; break; } } DDSFile baseAtlas = null; if (hasAlpha) { baseAtlas = new DDSFile((uint)atlasSize, (uint)atlasSize, 5, DDSType.DXT5, baseContent); } else { baseAtlas = new DDSFile((uint)atlasSize, (uint)atlasSize, 5, DDSType.DXT1, baseContent); } hasAlpha = false; for (int idx = 0; idx < nodes.Count; ++idx) { if (textureList[idx, 1].HasAlpha()) { hasAlpha = true; break; } } DDSFile normalAtlas = null; if (hasAlpha) { normalAtlas = new DDSFile((uint)atlasSize, (uint)atlasSize, 5, DDSType.A1R5G5B5, normalContent, true); } else { normalAtlas = new DDSFile((uint)atlasSize, (uint)atlasSize, 5, DDSType.R5G5B5, normalContent, true); } baseAsset.Content = baseAtlas.Binary; asset.SubAssets.Add(0x0C, baseAsset); FileHelper.SetInt(baseAsset.Content.Length, 0x10, asset.Content); normalAsset.Content = normalAtlas.Binary; asset.SubAssets.Add(0x14, normalAsset); FileHelper.SetInt(normalAsset.Content.Length, 0x18, asset.Content); ErrorDescription = string.Empty; return(true); }
public BinaryAssetBrowser(BinaryAsset asset) : this(asset.Data, asset.DataStart, asset.DataCount, asset.DataDisplayOffset) { }