diff options
Diffstat (limited to '')
-rw-r--r-- | NW4RTools/Models/VertexData.cs | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/NW4RTools/Models/VertexData.cs b/NW4RTools/Models/VertexData.cs index 5b1a50a..187b9aa 100644 --- a/NW4RTools/Models/VertexData.cs +++ b/NW4RTools/Models/VertexData.cs @@ -10,23 +10,24 @@ namespace NW4RTools.Models { public UInt16 EntryCount; // Todo, decode data when reading - public byte[] Data; + public byte[] RawData; + public float[][] Data; public VertexDataBase() { } - public float[] GetEntry(int index) { + public virtual float[] GetEntry(int index) { float[] ret = new float[GetRealCount()]; float scale = 1.0f / (1 << Fraction); - //Console.WriteLine("Getting index {0}, count {1} size {2} length {3} offset {4}", index, EntryCount, EntrySize, Data.Length, index * EntrySize); - InputStream ins = new InputStream(Data); + InputStream ins = new InputStream(RawData); ins.Seek(index * EntrySize); for (int i = 0; i < ret.Length; i++) { switch (ComponentType) { case VertexSettings.CompType.UInt8: + ret[i] = (float)ins.ReadByte() * scale; break; case VertexSettings.CompType.Int8: ret[i] = (float)ins.ReadSByte() * scale; @@ -36,7 +37,6 @@ namespace NW4RTools.Models { break; case VertexSettings.CompType.Int16: ret[i] = (float)ins.ReadInt16() * scale; - //Console.WriteLine("Output into {0}: {3:X} {1} with scale {2}", i, ret[i], scale, v); break; case VertexSettings.CompType.Float32: ret[i] = ins.ReadFloat(); @@ -49,6 +49,18 @@ namespace NW4RTools.Models { return ret; } + public void Parse() { + if (Data != null) + return; + + Data = new float[EntryCount][]; + + for (int i = 0; i < EntryCount; i++) { + Data[i] = GetEntry(i); + } + } + + public abstract int GetRealCount(); } @@ -101,6 +113,79 @@ namespace NW4RTools.Models { return -1; } } + + public override float[] GetEntry(int index) { + float[] ret = new float[GetRealCount()]; + + InputStream ins = new InputStream(RawData); + ins.Seek(index * EntrySize); + + byte r, g, b, a; + + // todo: better solution instead of this cast + switch ((VertexSettings.CompClrType)ComponentType) { + case VertexSettings.CompClrType.RGB565: + ushort v565 = ins.ReadUInt16(); + r = (byte)((v565 & 0xF800) >> 8); + g = (byte)((v565 & 0x07E0) >> 3); + b = (byte)((v565 & 0x001F) << 3); + a = 255; + break; + + case VertexSettings.CompClrType.RGB8: + r = ins.ReadByte(); + g = ins.ReadByte(); + b = ins.ReadByte(); + a = 255; + break; + + case VertexSettings.CompClrType.RGBX8: + r = ins.ReadByte(); + g = ins.ReadByte(); + b = ins.ReadByte(); + a = 255; + ins.Skip(1); + break; + + case VertexSettings.CompClrType.RGBA4: + ushort vA4 = ins.ReadUInt16(); + r = (byte)((vA4 & 0xF000) >> 8); + g = (byte)((vA4 & 0x0F00) >> 4); + b = (byte)(vA4 & 0x00F0); + a = (byte)((vA4 & 0x000F) << 4); + break; + + case VertexSettings.CompClrType.RGBA6: + byte v1 = ins.ReadByte(); + byte v2 = ins.ReadByte(); + byte v3 = ins.ReadByte(); + r = (byte)(v1 & 0xF8); + g = (byte)(((v1 & 7) << 6) | ((v2 & 0xF0) >> 2)); + b = (byte)(((v2 & 0xF) << 4) | ((v3 & 0xC) >> 4)); + a = (byte)((v3 & 0x3F) << 2); + break; + + case VertexSettings.CompClrType.RGBA8: + r = ins.ReadByte(); + g = ins.ReadByte(); + b = ins.ReadByte(); + a = ins.ReadByte(); + break; + + default: + throw new NotImplementedException(String.Format("unimplemented type {0}", (int)ComponentType)); + } + + // this is the easiest way I can think of to handle this atm + // just use floats for EVERYTHING + ret[0] = r * (1.0f / 256); + ret[1] = g * (1.0f / 256); + ret[2] = b * (1.0f / 256); + if (ret.Length > 3) + ret[3] = a * (1.0f / 256); + + return ret; + } } |