using System; namespace NW4RTools.Models { public enum CompCount { Position2 = 0, Position3 = 1, Normal3 = 0, Color3 = 0, Color4 = 1, TexCoord1 = 0, TexCoord2 = 1 } public enum CompType { UInt8 = 0, Int8 = 1, UInt16 = 2, Int16 = 3, Float32 = 4 } public abstract class VertexDataBase { public UInt32 Index; public CompCount ComponentCount; public CompType ComponentType; public byte Fraction /* Not used for colours */, EntrySize; public UInt16 EntryCount; // Todo, decode data when reading public byte[] Data; public VertexDataBase() { } public 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); ins.Seek(index * EntrySize); for (int i = 0; i < ret.Length; i++) { switch (ComponentType) { case CompType.UInt8: break; case CompType.Int8: ret[i] = (float)ins.ReadSByte() * scale; break; case CompType.UInt16: ret[i] = (float)ins.ReadUInt16() * scale; break; case CompType.Int16: ret[i] = (float)ins.ReadInt16() * scale; break; case CompType.Float32: ret[i] = ins.ReadFloat(); break; default: throw new NotImplementedException(String.Format("unimplemented type {0}", (int)ComponentType)); } } return ret; } public abstract int GetRealCount(); } public class VertexPosData : VertexDataBase { public Vec3 Minimum, Maximum; public VertexPosData() { } public override int GetRealCount() { switch (ComponentCount) { case CompCount.Position2: return 2; case CompCount.Position3: return 3; default: return -1; } } } public class VertexNrmData : VertexDataBase { public VertexNrmData() { } public override int GetRealCount() { switch (ComponentCount) { case CompCount.Normal3: return 3; default: return -1; } } } public class VertexClrData : VertexDataBase { public VertexClrData() { } public override int GetRealCount() { switch (ComponentCount) { case CompCount.Color3: return 3; case CompCount.Color4: return 4; default: return -1; } } } public class VertexTexCoordData : VertexDataBase { public Vec2 Minimum, Maximum; public VertexTexCoordData() { } public override int GetRealCount() { switch (ComponentCount) { case CompCount.TexCoord1: return 1; case CompCount.TexCoord2: return 2; default: return -1; } } } }