Ejemplo n.º 1
0
		/// <summary>
		/// Read single animation from file<para/>
		/// Чтение одной анимации из файла
		/// </summary>
		Animation ReadAnimation(BinaryReader f) {
			Animation a = new Animation();
			Header h;

			// Reading animation name
			// Чтение имени анимации
			h = ReadHeader(f, HeaderType.Name);
			a.Name = f.ReadVCString(h.Size.AlignToOctet());
			System.Diagnostics.Debug.WriteLine(a.Name);

			// Reading objects
			// Чтение объектов
			h = ReadHeader(f, HeaderType.Objects);
			h = ReadHeader(f, HeaderType.Collection);

			int objectCount = f.ReadInt32();
			f.BaseStream.Position += 4;

			a.Bones = new Bone[objectCount];
			for (int i = 0; i < objectCount; i++) {
				a.Bones[i] = ReadBone(f);
			}

			return a;
		}
Ejemplo n.º 2
0
		/// <summary>
		/// Constructor, opens file handle and reads filesystem<para/>
		/// Конструктор, открывает хендл файла и читает список
		/// </summary>
		/// <param name="path">Path to IMG file<para/>Путь к IMG-файлу</param>
		public ArchiveFile(string path) {

			// Opening file handle
			// Открытие ссылки
			if (!File.Exists(path)) {
				throw new FileNotFoundException("[ArchiveFile] IMG not found: " + Path.GetFileName(path), path);
			}
			stream = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read));


			// Pick dictionary
			// Поиск словаря
			string dict = Path.ChangeExtension(path, ".dir");
			if (!File.Exists(dict)) {
				throw new FileNotFoundException("[ArchiveFile] IMG dictionary not found: " + Path.GetFileName(dict), dict);
			}

			// Reading files
			// Чтение словаря
			entries = new Dictionary<string, Entry>();
			BinaryReader f = new BinaryReader(new FileStream(dict, FileMode.Open, FileAccess.Read));
			int fileCount = (int)(f.BaseStream.Length / EntrySize);
			for (int i = 0; i < fileCount; i++) {
				// Reading entry
				// Чтение файла
				int offset = f.ReadInt32();
				int size = f.ReadInt32();
				string name = f.ReadVCString(24);
				Entry e = new Entry(name, offset, size, stream);

				// Adding to array
				// Добавляем в список
				if (entries.ContainsKey(name.ToLower())) {
					Dev.Console.Log("[ArchiveFile] Duplicate entry: "+name);
					entries[name.ToLower()] = e;
				}else{
					entries.Add(name.ToLower(), e);
				}
			}
			f.Close();
			Dev.Console.Log("[ArchiveFile] Mounted "+Path.GetFileName(path)+" ("+fileCount+" entries)");
		}
Ejemplo n.º 3
0
		/// <summary>
		/// Read collision file from file<para/>
		/// Чтение файлов коллизий из файла
		/// </summary>
		/// <param name="filename">File name<para/>Имя файла</param>
		public CollisionFile(string filename) {
			if (!File.Exists(filename)) {
				throw new FileNotFoundException("[CollisionFile] File not found: "+Path.GetFileName(filename), filename);
			}

			// Opening reader
			// Открытие ридера
			Collisions = new List<Group>();
			BinaryReader f = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read), Encoding.ASCII);

			// Read all the models
			// Чтение всех моделей
			while (f.BaseStream.Position<f.BaseStream.Length-1) {

				// Reading header
				// Чтение заголовка
				string header = new string(f.ReadChars(4));
				if (header != "COLL") {
					throw new Exception("[CollisionFile] Unknown collision format: "+header);
				}
				f.BaseStream.Position += 4;

				// Creating new group
				// Создание новой группы
				Group c = new Group();
				
				// Reading collision head
				// Чтение оглавления файла
				c.Name = f.ReadVCString(22).ToLower();
				c.ID = f.ReadUInt16();

				// Reading bounds
				// Чтение габаритов
				c.BoundsRadius = f.ReadSingle();
				c.BoundsCenter = f.ReadVCVector();
				c.BoundsMin = f.ReadVCVector();
				c.BoundsMax = f.ReadVCVector();

				// Reading objects
				// Чтение объектов
				int numSpheres = f.ReadInt32();
				if (numSpheres>0) {
					// Spheres
					// Сферы
					c.Spheres = new Sphere[numSpheres];
					for (int i = 0; i < numSpheres; i++) {
						Sphere s = new Sphere();
						s.Radius = f.ReadSingle();
						s.Center = f.ReadVCVector();
						s.ReadParams(f);
						c.Spheres[i] = s;
					}
				}

				// Skip unknown index
				// Пропуск неизвестного числа
				f.BaseStream.Position += 4;

				int numBoxes = f.ReadInt32();
				if (numBoxes>0) {
					// Boxes
					// Боксы
					c.Boxes = new Box[numBoxes];
					for (int i = 0; i < numBoxes; i++) {
						Box b = new Box();
						b.Min = f.ReadVCVector();
						b.Max = f.ReadVCVector();
						b.ReadParams(f);
						c.Boxes[i] = b;
					}
				}

				int numVerts = f.ReadInt32();
				if (numVerts>0) {
					// Vertices and triangles
					// Вершины и треугольники
					c.Vertices = new Vector3[numVerts];
					for (int i = 0; i < numVerts; i++) {
						c.Vertices[i] = f.ReadVCVector();
					}

					// Reading trimeshes
					// Чтение тримешей
					int indexCount = f.ReadInt32();
					List<int>[] indices = new List<int>[SurfaceMaterialsCount];
					int meshCount = 0;
					for (int i = 0; i < indexCount; i++) {
						// Reading single tri
						// Чтение треугольника
						int v0 = f.ReadInt32();
						int v1 = f.ReadInt32();
						int v2 = f.ReadInt32();
						int mat = f.ReadByte();
						f.BaseStream.Position += 3;

						// Determining surf
						// Поиск поверхности
						if (indices[mat]==null) {
							indices[mat] = new List<int>();
							meshCount++;
						}
						indices[mat].AddRange(new int[]{ v0, v1, v2 });
					}

					// Storing trimeshes
					// Сохранение тримешей
					c.Meshes = new Trimesh[meshCount];
					int p = 0;
					for (int i = 0; i < indices.Length; i++) {
						if (indices[i]!=null) {
							c.Meshes[p] = new Trimesh() {
								Flags = 0,
								Material = (byte)i,
								Indices = indices[i].ToArray()
							};
							p++;
						}
					}
				}else{
					// Skip indices - they are empty
					// Пропуск индексов - они пустые
					f.BaseStream.Position += 4;
				}

				// Store mesh
				// Сохранение меша
				if (c.Spheres != null || c.Boxes != null || c.Meshes !=null) {
					Collisions.Add(c);
				}

				// Give prior to main thread
				// Отдаём предпочтение основному потоку
				System.Threading.Thread.Sleep(0);
			}

			// Closing reader
			// Закрытие потока
			f.Close();
		}
Ejemplo n.º 4
0
		/// <summary>
		/// Take single image from stream<para/>
		/// Получение текстуры из потока
		/// </summary>
		/// <param name="f">Stream<para/>Поток</param>
		/// <returns>Texture entry<para/>Запись текстуры</returns>
		Entry ReadTexture(BinaryReader f) {
			Entry tx = new Entry();

			// Texture platform flag
			// Платформа текстуры
			uint platform = f.ReadUInt32();
			if (platform != 8) {
				throw new Exception("[TextureFile] Specified platform does not match VC: " + platform);
			}

			// Filtering flags
			// Флаги фильтрации
			tx.Filtering = (FilterMode)f.ReadByte();
			byte wrapd = f.ReadByte();
			tx.AddressU = (AddressMode)(wrapd & 0x0F);
			tx.AddressV = (AddressMode)(wrapd >> 4);
			f.BaseStream.Position += 2;

			// Texture and mask names
			// Имена текстуры и её маски
			tx.Name = f.ReadVCString(32).ToLower();
			tx.Mask = f.ReadVCString(32).ToLower();

			// Raster format
			// Формат растра
			tx.Flags = f.ReadUInt32();

			// Does alpha present
			// Есть ли альфаканал
			uint hasAlpha = f.ReadUInt32();

			// Texture dimensions
			// Размеры текстуры
			int texW = f.ReadUInt16();
			int texH = f.ReadUInt16();

			// Bit depth
			// Глубина цвета
			int depth = f.ReadByte();

			// Mipmap number
			// Количество MIP-уровней
			int mipcount = f.ReadByte();

			// Raster type (must be 4)
			// Тип растра (должен быть 4)
			int type = f.ReadByte();

			// DXT compression
			// DXT-сжатие
			tx.ScanCompression = (Compression)f.ReadByte();

			// Special palette
			// Палитра
			byte[] palette = null;

			List<Scan> scans = new List<Scan>();

			// Reading palette, if needed
			// Чтение палитры если требуется
			if ((tx.Flags & (int)RasterFlags.Palette8) > 0 || (tx.Flags & (int)RasterFlags.Palette4) > 0) {
				int paletteSize = 1024;
				if ((tx.Flags & (int)RasterFlags.Palette4) > 0) {
					paletteSize = 64;
				}
				palette = f.ReadBytes(paletteSize);
			}

			// Reading data for all mipmaps
			// Чтение MIP-уровней
			for (int mip = 0; mip < mipcount; mip++) {

				// Size of data (may be 0)
				// Размер данных (может быть равен 0)
				int dataSize = (int)f.ReadUInt32();
				if (dataSize == 0) {
					// Computing size
					// Вычисление размера
					if ((tx.Flags & (int)RasterFlags.Palette8) > 0 || (tx.Flags & (int)RasterFlags.Palette4) > 0) {
						// Format is paletted
						// Формат задан палитрой
						dataSize = texW * texH;
						if ((tx.Flags & (int)RasterFlags.Palette4) > 0) {
							dataSize /= 2;
						}
					} else if (tx.ScanCompression != Compression.Uncompressed) {
						// Format is compressed
						// Кадры подвержены сжатию
						int ttw = texW;
						int tth = texH;
						if (ttw < 4) ttw = 4;
						if (tth < 4) tth = 4;
						if (tx.ScanCompression == Compression.DXT3) {
							dataSize = (ttw / 4) * (tth / 4) * 16;
						} else {
							dataSize = (ttw / 4) * (tth / 4) * 8;
						}
					}
				}

				// Reading raw data, corresponding to size
				// Чтение данных
				byte[] data = f.ReadBytes(dataSize);
				Scan scan = new Scan();
				scan.Size = new Vector2(texW, texH);

				if ((tx.Flags & (int)RasterFlags.Palette8) > 0) {
					// Decoding paletted textures
					// Раскодирование текстур с палитрой
					byte[] output = new byte[texW * texH * 4];
					for (int i = 0; i < data.Length; i++) {
						Array.Copy(palette, data[i] * 4, output, i * 4, 4);
					}
					scan.Data = output;
				} else {
					// Generic textures, may be compressed
					// Обычные текстуры, возмножно сжатые
					scan.Data = data;
				}
				scans.Add(scan);

				texW /= 2;
				texH /= 2;
			}
			tx.Scans = scans.ToArray();

			return tx;
		}
Ejemplo n.º 5
0
		/// <summary>
		/// Read single bone from animation file<para/>
		/// Чтение одной кости из файла
		/// </summary>
		Bone ReadBone(BinaryReader f) {
			Bone b = new Bone();
			Header h;

			// Reading header
			// Чтение заголовка
			h = ReadHeader(f, HeaderType.Animation);
			h = ReadHeader(f, HeaderType.AnimationData);

			// Reading bone
			// Чтение кости
			b.Name = f.ReadVCString(28);
			b.FrameСount = f.ReadInt32();

			// Skip unknown info
			// Пропуск неизвестной информации
			if (h.Size == 48) {
				f.BaseStream.Position += 4;
			}

			b.LastFrame = f.ReadInt32();
			b.NextSibling = f.ReadInt32();
			b.PrevSibling = f.ReadInt32();

			b.Frames = ReadFrames(f, b.FrameСount);

			return b;
		}
Ejemplo n.º 6
0
		/// <summary>
		/// Reading material data<para/>
		/// Чтение материалов
		/// </summary>
		/// <param name="g">Surface<para/>Поверхность</param>
		/// <param name="f">BinaryReader</param>
		/// <param name="numMaterials">Materials count<para/>Количество материалов</param>
		void ReadMaterials(Geometry g, BinaryReader f, int numMaterials) {
			g.Materials = new Material[numMaterials];
			for (int mt = 0; mt < numMaterials; mt++) {
				// Material header
				ChunkHeader h = ReadHeader(f);
				if (h.Type != ChunkType.Material) {
					throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
				}
				h = ReadHeader(f);
				if (h.Type != ChunkType.Struct) {
					throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
				}

				
				Material m = new Material();
				
				// Reading material flags
				// Чтение флагов
				m.Flags = f.ReadInt32();

				// Material tint color
				// Цвет материала
				m.Color = f.ReadBytes(4);
				if (m.Color[3]<254f) {
					m.HasAlpha = true;
				}

				// Skip some data
				// Пропуск данных
				f.BaseStream.Position += 4;

				// Reading surface props
				// Чтение параметров поверхности
				int texHave = f.ReadInt32();
				m.Props = new float[3];
				for (int pg = 0; pg < 3; pg++) {
					m.Props[pg] = f.ReadSingle();
				}

				// Reading texture data
				// Чтение данных текстуры
				if (texHave > 0) {
					h = ReadHeader(f);
					int texEnd = (int)f.BaseStream.Position + (int)h.Size;
					if (h.Type != ChunkType.Texture) {
						throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
					}
					h = ReadHeader(f);
					if (h.Type != ChunkType.Struct) {
						throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
					}

					m.Textures = new Texture[1];
					Texture t = new Texture();
					m.Textures[0] = t;

					t.Filter = (TextureFile.FilterMode)f.ReadByte();
					byte wrapd = f.ReadByte();
					t.AddressU = (TextureFile.AddressMode)(wrapd & 0x0F);
					t.AddressV = (TextureFile.AddressMode)(wrapd >> 4);
					f.BaseStream.Position += 2;

					h = ReadHeader(f);
					if (h.Type != ChunkType.String) {
						throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
					}
					t.Name = f.ReadVCString((int)h.Size).ToLower();

					h = ReadHeader(f);
					if (h.Type != ChunkType.String) {
						throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
					}
					t.MaskName = f.ReadVCString((int)h.Size).ToLower();

					if (t.MaskName != "") {
						m.HasAlpha = true;
					}

					h = ReadHeader(f);
					if (h.Type != ChunkType.Extension) {
						throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
					}
					f.BaseStream.Position += h.Size;
				} else {
					if (g.HasAlpha) {
						m.HasAlpha = true;
					}
				}

				h = ReadHeader(f);
				if (h.Type != ChunkType.Extension) {
					throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
				}
				if (h.Size > 0) {
					int ops = (int)(f.BaseStream.Position + h.Size);
					while (true) {
						if (f.BaseStream.Position >= ops) {
							break;
						}
						h = ReadHeader(f);
						switch (h.Type) {

							default:
								f.BaseStream.Position += h.Size;
								break;
						}
					}
				}

				g.Materials[mt] = m;
			}
		}
Ejemplo n.º 7
0
		/// <summary>
		/// Reading frame data<para/>
		/// Чтение кадров анимации
		/// </summary>
		/// <param name="f">Stream<para/>Поток</param>
		/// <param name="numFrames">Frame count<para/>Количество кадров</param>
		void ReadFrames(BinaryReader f, int numFrames) {
			Frames = new Frame[numFrames];
			
			// Reading struct part
			// Чтение структуры
			for (int i = 0; i < numFrames; i++) {
				Frame fr = new Frame();

				// Frame rotation
				// Поворот кадра
				fr.Rotation = new float[9];
				for (int r = 0; r < 9; r++) {
					fr.Rotation[r] = f.ReadSingle();
				}

				// Frame position
				// Позиция кадра
				fr.Position = new float[3];
				for (int p = 0; p < 3; p++) {
					fr.Position[p] = f.ReadSingle();
				}

				// Parent index
				// Индекс родителя
				fr.Parent = f.ReadInt32();

				// Skip data
				// Пропуск данных
				f.BaseStream.Position += 4;

				Frames[i] = fr;
			}

			// Reading extension
			// Чтение расширения
			for (int i = 0; i < numFrames; i++) {
				ChunkHeader h = ReadHeader(f);
				if (h.Type != ChunkType.Extension) {
					throw new Exception("[ModelFile] Unexpected chunk: " + h.Type);
				}
				if (h.Size > 0) {
					int endps = (int)(f.BaseStream.Position + h.Size);
					while (true) {
						if (f.BaseStream.Position >= endps) {
							break;
						}
						h = ReadHeader(f);
						switch (h.Type) {
							case ChunkType.Frame:
								Frames[i].Name = f.ReadVCString((int)h.Size);
								break;
							default:
								f.BaseStream.Position += h.Size;
								break;
						}
					}
				}
			}
		}