ImmutableArray <BoneController> LoadBoneControllers(Ibasa.IO.BinaryReader reader, int count) { BoneController[] boneControllers = new BoneController[count]; for (int i = 0; i < count; ++i) { boneControllers[i] = new BoneController( reader.ReadInt32(), (BoneControllerType)reader.ReadInt32(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadInt32(), reader.ReadInt32()); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints } return(new ImmutableArray <BoneController>(boneControllers)); }
private void ReadHeader70(Ibasa.IO.BinaryReader reader) { Width = reader.ReadUInt16(); Height = reader.ReadUInt16(); Flags = (TextureFlags)reader.ReadInt32(); Frames = reader.ReadUInt16(); StartFrame = reader.ReadUInt16(); reader.ReadBytes(4); //skip padding Reflectivity = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.ReadBytes(4); //skip padding BumpmapScale = reader.ReadSingle(); ImageFormat = (ImageFormat)reader.ReadInt32(); MipmapCount = reader.ReadByte(); LowResImageFormat = (ImageFormat)reader.ReadInt32(); LowResImageWidth = reader.ReadByte(); LowResImageHeight = reader.ReadByte(); }
ImmutableArray <Mesh> LoadMeshes(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Mesh[] meshes = new Mesh[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; int material = reader.ReadInt32(); int modelIndex = reader.ReadInt32(); int vertexCount = reader.ReadInt32(); int vertexOffset = reader.ReadInt32(); int flexCount = reader.ReadInt32(); long flexOffset = offset + reader.ReadInt32(); int materialType = reader.ReadInt32(); int materialParam = reader.ReadInt32(); int meshId = reader.ReadInt32(); Vector3f center = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int modelvertexdata = reader.ReadInt32(); int[] numLODVertexes = new int[8]; for (int l = 0; l < 8; ++l) { numLODVertexes[l] = reader.ReadInt32(); } ImmutableArray <int> lods = new ImmutableArray <int>(numLODVertexes); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = flexOffset; ImmutableArray <Flex> flexes = LoadFlexes(reader, flexCount); meshes[i] = new Mesh(material, vertexCount, vertexOffset, flexes, materialType, materialParam, meshId, center, lods); } return(new ImmutableArray <Mesh>(meshes)); }
ImmutableArray <HitBox> LoadHitBoxes(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; HitBox[] hitBoxes = new HitBox[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; int bone = reader.ReadInt32(); int group = reader.ReadInt32(); Boxf box = new Boxf( new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Size3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); long nameOffset = offset + reader.ReadInt32(); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = nameOffset; string name = LoadString(reader); hitBoxes[i] = new HitBox(bone, group, box, name); } return(new ImmutableArray <HitBox>(hitBoxes)); }
ImmutableArray <Model> LoadModels(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Model[] models = new Model[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; string name = Encoding.ASCII.GetString(reader.ReadBytes(64)).Trim('\0'); int type = reader.ReadInt32(); float boundingRadius = reader.ReadSingle(); int meshCount = reader.ReadInt32(); long meshOffset = offset + reader.ReadInt32(); int vertexCount = reader.ReadInt32(); int vertexIndex = reader.ReadInt32(); int tangentIndex = reader.ReadInt32(); int numattachments = reader.ReadInt32(); int attachmentindex = reader.ReadInt32(); int eyeballCount = reader.ReadInt32(); long eyeballOffset = offset + reader.ReadInt32(); int vertexData = reader.ReadInt32(); int indexData = reader.ReadInt32(); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = meshOffset; ImmutableArray <Mesh> meshes = LoadMeshes(reader, meshCount); reader.BaseStream.Position = meshOffset; ImmutableArray <Eyeball> eyeballs = LoadEyeballs(reader, meshCount); models[i] = new Model(name, type, boundingRadius, meshes, vertexCount, vertexIndex, tangentIndex, eyeballs); } return(new ImmutableArray <Model>(models)); }
/// <summary> /// Reads a <see cref="Linef"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Linef ReadLinef(this Ibasa.IO.BinaryReader reader) { return(new Linef(reader.ReadSingle(), reader.ReadSingle())); }
/// <summary> /// Reads a <see cref="Circlef"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Circlef ReadCirclef(this Ibasa.IO.BinaryReader reader) { return(new Circlef(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); }
/// <summary> /// Reads a <see cref="Boxf"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Boxf ReadBoxf(this Ibasa.IO.BinaryReader reader) { return(new Boxf(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); }
/// <summary> /// Reads a <see cref="Rectanglef"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Rectanglef ReadRectanglef(this Ibasa.IO.BinaryReader reader) { return(new Rectanglef(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); }
/// <summary> /// Reads a <see cref="Quaternionf"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Quaternionf ReadQuaternionf(this Ibasa.IO.BinaryReader reader) { return(new Quaternionf(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); }
private void Load(Stream stream) { var reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); long baseOffset = reader.BaseStream.Position; string signature = Encoding.ASCII.GetString(reader.ReadBytes(4)); if (signature != "IDST") { throw new InvalidDataException("File signature does not match 'IDST'."); } Version = reader.ReadInt32(); if ((Version < 44 || Version > 49)) { throw new InvalidDataException(string.Format("File version {0} does not match 44 to 49.", Version)); } Checksum = reader.ReadInt32(); Name = Encoding.ASCII.GetString(reader.ReadBytes(64)).Trim('\0'); int length = reader.ReadInt32(); //file length EyePosition = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); IlluminationPosition = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Hull = new Boxf( new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Size3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); ViewHull = new Boxf( new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Size3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); Flags = (MdlFlags)reader.ReadInt32(); int bonesCount = reader.ReadInt32(); long bonesOffset = baseOffset + reader.ReadInt32(); int boneControllersCount = reader.ReadInt32(); long boneControllersOffset = baseOffset + reader.ReadInt32(); int hitBoxSetsCount = reader.ReadInt32(); long hitBoxSetsOffset = baseOffset + reader.ReadInt32(); int localAnimCount = reader.ReadInt32(); long localAnimOffset = baseOffset + reader.ReadInt32(); int localSeqCount = reader.ReadInt32(); long localSeqOffset = baseOffset + reader.ReadInt32(); int activityListVersion = reader.ReadInt32(); int eventsIndexed = reader.ReadInt32(); int texturesCount = reader.ReadInt32(); long texturesOffset = baseOffset + reader.ReadInt32(); int cdTexturesCount = reader.ReadInt32(); long cdTexturesOffset = baseOffset + reader.ReadInt32(); int skinRefsCount = reader.ReadInt32(); int skinFamiliesCount = reader.ReadInt32(); long skinOffset = baseOffset + reader.ReadInt32(); int bodyPartsCount = reader.ReadInt32(); long bodyPartsOffset = baseOffset + reader.ReadInt32(); int localAttachmentsCount = reader.ReadInt32(); long localAttachmentsOffset = baseOffset + reader.ReadInt32(); int localNodesCount = reader.ReadInt32(); long localNodesOffset = baseOffset + reader.ReadInt32(); long localNodesNameOffset = baseOffset + reader.ReadInt32(); int flexDescsCount = reader.ReadInt32(); long flexDescsOffset = baseOffset + reader.ReadInt32(); int flexControllersCount = reader.ReadInt32(); long flexControllersOffset = baseOffset + reader.ReadInt32(); int flexRulesCount = reader.ReadInt32(); long flexRulesOffset = baseOffset + reader.ReadInt32(); int ikChainsCount = reader.ReadInt32(); long ikChainsOffset = baseOffset + reader.ReadInt32(); int mouthsCount = reader.ReadInt32(); long mouthsOffset = baseOffset + reader.ReadInt32(); //=== //Start reading from offsets //=== reader.BaseStream.Position = bonesOffset; Bones = LoadBones(reader, bonesCount); reader.BaseStream.Position = boneControllersOffset; BoneControllers = LoadBoneControllers(reader, boneControllersCount); //reader.BaseStream.Position = hitBoxSetsOffset; //HitBoxSets = LoadHitBoxSets(reader, hitBoxSetsCount); reader.BaseStream.Position = localAnimOffset; LocalAnimations = LoadLocalAnimations(reader, localAnimCount); reader.BaseStream.Position = localSeqOffset; LocalSequences = LoadLocalSequences(reader, localSeqCount); reader.BaseStream.Position = texturesOffset; Textures = LoadTextures(reader, texturesCount); reader.BaseStream.Position = cdTexturesOffset; CdTextures = LoadStringTable(reader, cdTexturesCount, baseOffset); //skin refs //TODO reader.BaseStream.Position = bodyPartsOffset; BodyParts = LoadBodyParts(reader, bodyPartsCount); }
public Bsp(Stream stream, IEnumerable <Package.Wad> wads) { if (!stream.CanSeek || !stream.CanRead) { throw new ArgumentException("stream must be seekable and readable.", "stream"); } if (wads == null) { wads = System.Linq.Enumerable.Empty <Package.Wad>(); } Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); if (Reader.ReadUInt32() != 30) { throw new InvalidDataException("Version is not 30."); } long entitiesOffset = Reader.ReadUInt32(); long entitiesCount = Reader.ReadUInt32(); long planesOffset = Reader.ReadUInt32(); long planesCount = Reader.ReadUInt32(); long texturesOffset = Reader.ReadUInt32(); long texturesCount = Reader.ReadUInt32(); long vertexesOffset = Reader.ReadUInt32(); long vertexesCount = Reader.ReadUInt32(); long visibilityOffset = Reader.ReadUInt32(); long visibilityCount = Reader.ReadUInt32(); long nodesOffset = Reader.ReadUInt32(); long nodesCount = Reader.ReadUInt32(); long texinfoOffset = Reader.ReadUInt32(); long texinfoCount = Reader.ReadUInt32(); long facesOffset = Reader.ReadUInt32(); long facesCount = Reader.ReadUInt32(); long lightingOffset = Reader.ReadUInt32(); long lightingCount = Reader.ReadUInt32(); long clipnodesOffset = Reader.ReadUInt32(); long clipnodesCount = Reader.ReadUInt32(); long leafsOffset = Reader.ReadUInt32(); long leafsCount = Reader.ReadUInt32(); long marksurfacesOffset = Reader.ReadUInt32(); long marksurfacesCount = Reader.ReadUInt32(); long edgesOffset = Reader.ReadUInt32(); long edgesCount = Reader.ReadUInt32(); long surfedgesOffset = Reader.ReadUInt32(); long surfedgesCount = Reader.ReadUInt32(); long modelsOffset = Reader.ReadUInt32(); long modelsCount = Reader.ReadUInt32(); //Entities Reader.Seek(entitiesOffset, SeekOrigin.Begin); Entities = Encoding.ASCII.GetString(Reader.ReadBytes((int)entitiesCount)); //Planes Reader.Seek(planesOffset, SeekOrigin.Begin); Planes = new Planef[planesCount / 20]; for (int i = 0; i < Planes.Length; ++i) { Planes[i] = new Planef( Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); uint type = Reader.ReadUInt32(); } //Textures { Reader.Seek(texturesOffset, SeekOrigin.Begin); long[] offsets = new long[Reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; ++i) { offsets[i] = Reader.ReadUInt32(); } Textures = new Resource[offsets.Length]; for (int i = 0; i < offsets.Length; ++i) { Reader.Seek(texturesOffset + offsets[i], SeekOrigin.Begin); string name = Encoding.ASCII.GetString(Reader.ReadBytes(16)); int nullbyte = name.IndexOf('\0'); name = nullbyte == -1 ? name : name.Substring(0, nullbyte); int width = Reader.ReadInt32(); int height = Reader.ReadInt32(); long[] dataoffsets = new long[4]; dataoffsets[0] = Reader.ReadUInt32(); dataoffsets[1] = Reader.ReadUInt32(); dataoffsets[2] = Reader.ReadUInt32(); dataoffsets[3] = Reader.ReadUInt32(); Resource resource = null; if (dataoffsets.All(o => o == 0)) { foreach (var wad in wads) { resource = wad[name]; if (resource != null) { break; } } } else { resource = new Resource(new Size3i(width, height, 1), 4, 1, Format.R8G8B8A8UNorm); byte[][] images = new byte[4][]; for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { Reader.Seek(texturesOffset + offsets[i] + dataoffsets[mipSlice], SeekOrigin.Begin); images[mipSlice] = Reader.ReadBytes(width * height); width >>= 1; height >>= 1; } Reader.Seek(2, SeekOrigin.Current); byte[] pallet = Reader.ReadBytes(256 * 3); for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { byte[] data = resource[mipSlice, 0]; byte[] image = images[mipSlice]; for (int j = 0; j < image.Length; ++j) { int palletIndex = image[j] * 3; int dataIndex = j * 3; data[dataIndex + 0] = pallet[palletIndex + 0]; data[dataIndex + 1] = pallet[palletIndex + 1]; data[dataIndex + 2] = pallet[palletIndex + 2]; } } } Textures[i] = resource; } } //Vertices Reader.Seek(vertexesOffset, SeekOrigin.Begin); Vertices = new Vector3f[vertexesCount / 12]; for (int i = 0; i < Vertices.Length; ++i) { Vertices[i] = new Vector3f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); } //Visibility Reader.Seek(visibilityOffset, SeekOrigin.Begin); Visibility = Reader.ReadBytes((int)visibilityCount); //Nodes //Surfaces Reader.Seek(texinfoOffset, SeekOrigin.Begin); Surfaces = new Surface[texinfoCount / 24]; for (int i = 0; i < Surfaces.Length; ++i) { Surfaces[i] = new Surface( new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), Reader.ReadInt32(), Reader.ReadInt32()); } //Faces Reader.Seek(facesOffset, SeekOrigin.Begin); Faces = new Face[facesCount / 20]; for (int i = 0; i < Faces.Length; ++i) { Faces[i] = new Face( Reader.ReadUInt16(), Reader.ReadInt16(), Reader.ReadInt32(), Reader.ReadInt16(), Reader.ReadInt16(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadInt32()); } //Lighting Reader.Seek(facesOffset, SeekOrigin.Begin); Lighting = Reader.ReadBytes((int)lightingCount); //#define clipnodes 9 //#define leafs 10 //#define marksurfaces 11 //#define edges 12 //#define surfedges 13 //#define models 14 //Edges Reader.Seek(edgesOffset, SeekOrigin.Begin); Edges = new Edge[edgesCount / 4]; for (int i = 0; i < Edges.Length; ++i) { Edges[i] = new Edge(Reader.ReadUInt16(), Reader.ReadUInt16()); } //SurfaceEdges Reader.Seek(surfedgesOffset, SeekOrigin.Begin); SurfaceEdges = new int[surfedgesCount / 4]; for (int i = 0; i < Planes.Length; ++i) { SurfaceEdges[i] = Reader.ReadInt32(); } }
/// <summary> /// Reads a <see cref="Ellipsef"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Ellipsef ReadEllipsef(this Ibasa.IO.BinaryReader reader) { return(new Ellipsef(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); }
ImmutableArray <Bone> LoadBones(Ibasa.IO.BinaryReader reader, int count) { long offset = reader.BaseStream.Position; Bone[] bones = new Bone[count]; for (int i = 0; i < count; ++i) { reader.BaseStream.Position = offset; long nameOffset = offset + reader.ReadInt32(); int parent = reader.ReadInt32(); ImmutableArray <int> boneControllers = new ImmutableArray <int>(new int[] { reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32() }); Vector3f position = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Quaternionf quaternion = new Quaternionf(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f rotation = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f positionScale = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3f rotationScale = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Matrix4x4f poseToBone = new Matrix4x4f( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0, 0, 0, 1); Quaternionf alignment = new Quaternionf(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int flags = reader.ReadInt32(); int procType = reader.ReadInt32(); int procIndex = reader.ReadInt32(); int physicsBone = reader.ReadInt32(); int surfacePropIdx = reader.ReadInt32(); int contents = reader.ReadInt32(); reader.Seek(8 * 4, SeekOrigin.Current); //skip 8 ints offset = reader.BaseStream.Position; reader.BaseStream.Position = nameOffset; string name = LoadString(reader); bones[i] = new Bone(name, parent, boneControllers, position, quaternion, rotation, positionScale, rotationScale, poseToBone, alignment, flags, procType, procIndex, physicsBone, surfacePropIdx, contents); } return(new ImmutableArray <Bone>(bones)); }
/// <summary> /// Reads a <see cref="Point3f"/> from an <see cref="Ibasa.IO.BinaryReader">. /// </summary> public static Point3f ReadPoint3f(this Ibasa.IO.BinaryReader reader) { return(new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); }
public Bsp(Stream stream, IEnumerable<Package.Wad> wads) { if (!stream.CanSeek || !stream.CanRead) throw new ArgumentException("stream must be seekable and readable.", "stream"); if (wads == null) wads = System.Linq.Enumerable.Empty<Package.Wad>(); Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); if (Reader.ReadUInt32() != 30) throw new InvalidDataException("Version is not 30."); long entitiesOffset = Reader.ReadUInt32(); long entitiesCount = Reader.ReadUInt32(); long planesOffset = Reader.ReadUInt32(); long planesCount = Reader.ReadUInt32(); long texturesOffset = Reader.ReadUInt32(); long texturesCount = Reader.ReadUInt32(); long vertexesOffset = Reader.ReadUInt32(); long vertexesCount = Reader.ReadUInt32(); long visibilityOffset = Reader.ReadUInt32(); long visibilityCount = Reader.ReadUInt32(); long nodesOffset = Reader.ReadUInt32(); long nodesCount = Reader.ReadUInt32(); long texinfoOffset = Reader.ReadUInt32(); long texinfoCount = Reader.ReadUInt32(); long facesOffset = Reader.ReadUInt32(); long facesCount = Reader.ReadUInt32(); long lightingOffset = Reader.ReadUInt32(); long lightingCount = Reader.ReadUInt32(); long clipnodesOffset = Reader.ReadUInt32(); long clipnodesCount = Reader.ReadUInt32(); long leafsOffset = Reader.ReadUInt32(); long leafsCount = Reader.ReadUInt32(); long marksurfacesOffset = Reader.ReadUInt32(); long marksurfacesCount = Reader.ReadUInt32(); long edgesOffset = Reader.ReadUInt32(); long edgesCount = Reader.ReadUInt32(); long surfedgesOffset = Reader.ReadUInt32(); long surfedgesCount = Reader.ReadUInt32(); long modelsOffset = Reader.ReadUInt32(); long modelsCount = Reader.ReadUInt32(); //Entities Reader.Seek(entitiesOffset, SeekOrigin.Begin); Entities = Encoding.ASCII.GetString(Reader.ReadBytes((int)entitiesCount)); //Planes Reader.Seek(planesOffset, SeekOrigin.Begin); Planes = new Planef[planesCount / 20]; for (int i = 0; i < Planes.Length; ++i) { Planes[i] = new Planef( Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); uint type = Reader.ReadUInt32(); } //Textures { Reader.Seek(texturesOffset, SeekOrigin.Begin); long[] offsets = new long[Reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; ++i) { offsets[i] = Reader.ReadUInt32(); } Textures = new Resource[offsets.Length]; for (int i = 0; i < offsets.Length; ++i) { Reader.Seek(texturesOffset + offsets[i], SeekOrigin.Begin); string name = Encoding.ASCII.GetString(Reader.ReadBytes(16)); int nullbyte = name.IndexOf('\0'); name = nullbyte == -1 ? name : name.Substring(0, nullbyte); int width = Reader.ReadInt32(); int height = Reader.ReadInt32(); long[] dataoffsets = new long[4]; dataoffsets[0] = Reader.ReadUInt32(); dataoffsets[1] = Reader.ReadUInt32(); dataoffsets[2] = Reader.ReadUInt32(); dataoffsets[3] = Reader.ReadUInt32(); Resource resource = null; if (dataoffsets.All(o => o == 0)) { foreach (var wad in wads) { resource = wad[name]; if (resource != null) { break; } } } else { resource = new Resource(new Size3i(width, height, 1), 4, 1, Format.R8G8B8A8UNorm); byte[][] images = new byte[4][]; for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { Reader.Seek(texturesOffset + offsets[i] + dataoffsets[mipSlice], SeekOrigin.Begin); images[mipSlice] = Reader.ReadBytes(width * height); width >>= 1; height >>= 1; } Reader.Seek(2, SeekOrigin.Current); byte[] pallet = Reader.ReadBytes(256 * 3); for (int mipSlice = 0; mipSlice < 4; ++mipSlice) { byte[] data = resource[mipSlice, 0]; byte[] image = images[mipSlice]; for (int j = 0; j < image.Length; ++j) { int palletIndex = image[j] * 3; int dataIndex = j * 3; data[dataIndex + 0] = pallet[palletIndex + 0]; data[dataIndex + 1] = pallet[palletIndex + 1]; data[dataIndex + 2] = pallet[palletIndex + 2]; } } } Textures[i] = resource; } } //Vertices Reader.Seek(vertexesOffset, SeekOrigin.Begin); Vertices = new Vector3f[vertexesCount / 12]; for (int i = 0; i < Vertices.Length; ++i) { Vertices[i] = new Vector3f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()); } //Visibility Reader.Seek(visibilityOffset, SeekOrigin.Begin); Visibility = Reader.ReadBytes((int)visibilityCount); //Nodes //Surfaces Reader.Seek(texinfoOffset, SeekOrigin.Begin); Surfaces = new Surface[texinfoCount / 24]; for (int i = 0; i < Surfaces.Length; ++i) { Surfaces[i] = new Surface( new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), new Vector4f(Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle(), Reader.ReadSingle()), Reader.ReadInt32(), Reader.ReadInt32()); } //Faces Reader.Seek(facesOffset, SeekOrigin.Begin); Faces = new Face[facesCount / 20]; for (int i = 0; i < Faces.Length; ++i) { Faces[i] = new Face( Reader.ReadUInt16(), Reader.ReadInt16(), Reader.ReadInt32(), Reader.ReadInt16(), Reader.ReadInt16(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte(), Reader.ReadInt32()); } //Lighting Reader.Seek(facesOffset, SeekOrigin.Begin); Lighting = Reader.ReadBytes((int)lightingCount); //#define clipnodes 9 //#define leafs 10 //#define marksurfaces 11 //#define edges 12 //#define surfedges 13 //#define models 14 //Edges Reader.Seek(edgesOffset, SeekOrigin.Begin); Edges = new Edge[edgesCount / 4]; for (int i = 0; i < Edges.Length; ++i) { Edges[i] = new Edge(Reader.ReadUInt16(), Reader.ReadUInt16()); } //SurfaceEdges Reader.Seek(surfedgesOffset, SeekOrigin.Begin); SurfaceEdges = new int[surfedgesCount / 4]; for (int i = 0; i < Planes.Length; ++i) { SurfaceEdges[i] = Reader.ReadInt32(); } }
/// <summary> /// Reads a <see cref="Size2f"/> from an <see cref="Ibasa.IO.BinaryWriter">. /// </summary> public static Size2f ReadSize2f(this Ibasa.IO.BinaryReader reader) { return(new Size2f(reader.ReadSingle(), reader.ReadSingle())); }
private void Load(Stream stream) { var reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); long baseOffset = reader.BaseStream.Position; string signature = Encoding.ASCII.GetString(reader.ReadBytes(4)); if (signature != "IDST") throw new InvalidDataException("File signature does not match 'IDST'."); Version = reader.ReadInt32(); if ((Version < 44 || Version > 49)) throw new InvalidDataException(string.Format("File version {0} does not match 44 to 49.", Version)); Checksum = reader.ReadInt32(); Name = Encoding.ASCII.GetString(reader.ReadBytes(64)).Trim('\0'); int length = reader.ReadInt32(); //file length EyePosition = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); IlluminationPosition = new Vector3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Hull = new Boxf( new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Size3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); ViewHull = new Boxf( new Point3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()), new Size3f(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); Flags = (MdlFlags)reader.ReadInt32(); int bonesCount = reader.ReadInt32(); long bonesOffset = baseOffset + reader.ReadInt32(); int boneControllersCount = reader.ReadInt32(); long boneControllersOffset = baseOffset + reader.ReadInt32(); int hitBoxSetsCount = reader.ReadInt32(); long hitBoxSetsOffset = baseOffset + reader.ReadInt32(); int localAnimCount = reader.ReadInt32(); long localAnimOffset = baseOffset + reader.ReadInt32(); int localSeqCount = reader.ReadInt32(); long localSeqOffset = baseOffset + reader.ReadInt32(); int activityListVersion = reader.ReadInt32(); int eventsIndexed = reader.ReadInt32(); int texturesCount = reader.ReadInt32(); long texturesOffset = baseOffset + reader.ReadInt32(); int cdTexturesCount = reader.ReadInt32(); long cdTexturesOffset = baseOffset + reader.ReadInt32(); int skinRefsCount = reader.ReadInt32(); int skinFamiliesCount = reader.ReadInt32(); long skinOffset = baseOffset + reader.ReadInt32(); int bodyPartsCount = reader.ReadInt32(); long bodyPartsOffset = baseOffset + reader.ReadInt32(); int localAttachmentsCount = reader.ReadInt32(); long localAttachmentsOffset = baseOffset + reader.ReadInt32(); int localNodesCount = reader.ReadInt32(); long localNodesOffset = baseOffset + reader.ReadInt32(); long localNodesNameOffset = baseOffset + reader.ReadInt32(); int flexDescsCount = reader.ReadInt32(); long flexDescsOffset = baseOffset + reader.ReadInt32(); int flexControllersCount = reader.ReadInt32(); long flexControllersOffset = baseOffset + reader.ReadInt32(); int flexRulesCount = reader.ReadInt32(); long flexRulesOffset = baseOffset + reader.ReadInt32(); int ikChainsCount = reader.ReadInt32(); long ikChainsOffset = baseOffset + reader.ReadInt32(); int mouthsCount = reader.ReadInt32(); long mouthsOffset = baseOffset + reader.ReadInt32(); //=== //Start reading from offsets //=== reader.BaseStream.Position = bonesOffset; Bones = LoadBones(reader, bonesCount); reader.BaseStream.Position = boneControllersOffset; BoneControllers = LoadBoneControllers(reader, boneControllersCount); //reader.BaseStream.Position = hitBoxSetsOffset; //HitBoxSets = LoadHitBoxSets(reader, hitBoxSetsCount); reader.BaseStream.Position = localAnimOffset; LocalAnimations = LoadLocalAnimations(reader, localAnimCount); reader.BaseStream.Position = localSeqOffset; LocalSequences = LoadLocalSequences(reader, localSeqCount); reader.BaseStream.Position = texturesOffset; Textures = LoadTextures(reader, texturesCount); reader.BaseStream.Position = cdTexturesOffset; CdTextures = LoadStringTable(reader, cdTexturesCount, baseOffset); //skin refs //TODO reader.BaseStream.Position = bodyPartsOffset; BodyParts = LoadBodyParts(reader, bodyPartsCount); }