using Microsoft.Xna.Framework; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; namespace OpenVIII.Fields { /// /// Cameras /// /// /// /// /// /// public class Cameras : IList { #region Fields private const int altsizeofCamera = 0x26; private const int sizeofCamera = 0x28; private List cameras; #endregion Fields #region Constructors public Cameras() => this.cameras = new List(1); #endregion Constructors #region Properties public int Count => ((IList)cameras).Count; public bool IsReadOnly => ((IList)cameras).IsReadOnly; #endregion Properties #region Indexers public Camera this[int index] { get => ((IList)cameras)[index]; set => ((IList)cameras)[index] = value; } #endregion Indexers #region Methods public static Cameras Load(byte[] idb) { Cameras r = new Cameras(); int _sizeofCamera = Cameras.sizeofCamera; int count = 0; if (idb.Length / sizeofCamera > idb.Length / altsizeofCamera) count = idb.Length / sizeofCamera; else { _sizeofCamera = altsizeofCamera; count = idb.Length / _sizeofCamera; } Debug.Assert(count >= 1); for (long offset = 0; offset < count * _sizeofCamera; offset += _sizeofCamera) r.Add(Camera.Load(idb, offset)); return r; } public void Add(Camera item) => ((IList)cameras).Add(item); public void Clear() => ((IList)cameras).Clear(); public bool Contains(Camera item) => ((IList)cameras).Contains(item); public void CopyTo(Camera[] array, int arrayIndex) => ((IList)cameras).CopyTo(array, arrayIndex); public IEnumerator GetEnumerator() => ((IList)cameras).GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => ((IList)cameras).GetEnumerator(); public int IndexOf(Camera item) => ((IList)cameras).IndexOf(item); public void Insert(int index, Camera item) => ((IList)cameras).Insert(index, item); public bool Remove(Camera item) => ((IList)cameras).Remove(item); public void RemoveAt(int index) => ((IList)cameras).RemoveAt(index); #endregion Methods #region Classes /// /// Camera /// public class Camera { #region Fields private Vector3 _position; private Vector3 space; private Vector3[] xyz; #endregion Fields #region Constructors public Camera() => xyz = new Vector3[3]; #endregion Constructors #region Properties private uint Blank { get; set; } public Vector3 Position { get => _position; private set => _position = value; } public Matrix RotationMatrix => new Matrix { Left = xyz[0], Down = xyz[1], Backward = xyz[2] }; public Vector3[] XYZ { get => xyz; private set => xyz = value; } private short Z { get; set; } public float Zoom { get; private set; } private float Zoom2 { get; set; } public Vector3 Space { get => space; private set => space = value; } #endregion Properties #region Methods public static Camera Load(byte[] idb, long offset) { Camera r = new Camera(); r.ReadData(idb, offset); return r; } public Matrix CreateLookAt() => Matrix.CreateLookAt(Position - xyz[2] * 2, xyz[2] + Position, xyz[1]); public Matrix CreateWorld() => Matrix.CreateWorld(Position, xyz[2], xyz[1]); private void ReadData(byte[] cab, long offset) { using (BinaryReader br = new BinaryReader(new MemoryStream(cab))) { br.BaseStream.Seek(offset, SeekOrigin.Begin); const float multipleconstant = 4096f; for (int i = 0; i < 3; i++) { xyz[i].X = br.ReadInt16() / multipleconstant; xyz[i].Y = br.ReadInt16() / multipleconstant; xyz[i].Z = br.ReadInt16() / multipleconstant; } Z = br.ReadInt16(); space.X = br.ReadInt32(); space.Y = br.ReadInt32(); space.Z = br.ReadInt32(); Blank = br.ReadUInt16(); Zoom = br.ReadUInt16(); Zoom2 = br.ReadUInt16(); Zoom = Zoom2 = Math.Max(Zoom, Zoom2); var r = RotationMatrix; space /= 4096f; _position = -(space * xyz[0] + space * xyz[1] + space * xyz[2]); //_position = -(space * r.Right + space * r.Up + space * r.Backward); //_position = Vector3.Transform(space/4096f, r); //_position = new Vector3 //{ // X = -(space.X * xyz[0].X + space.X * xyz[1].X + space.X * xyz[2].X), // Y = -(space.Y * xyz[0].Y + space.Y * xyz[1].Y + space.Y * xyz[2].Y), // Z = -(space.Z * xyz[0].Z + space.Z * xyz[1].Z + space.Z * xyz[2].Z), //}; } } #endregion Methods } #endregion Classes } }