/// <summary> /// Loads a model from .VMD (Voxalia Model Data) input. /// </summary> public Model3D LoadModel(byte[] data) { if (data.Length < 3 || data[0] != 'V' || data[1] != 'M' || data[2] != 'D') { throw new Exception("Model3D: Invalid header bits."); } byte[] dat_filt = new byte[data.Length - "VMD001".Length]; Array.ConstrainedCopy(data, "VMD001".Length, dat_filt, 0, dat_filt.Length); dat_filt = FileHandler.UnGZip(dat_filt); DataStream ds = new DataStream(dat_filt); DataReader dr = new DataReader(ds); Model3D mod = new Model3D(); mod.MatrixA = ReadMat(dr); int meshCount = dr.ReadInt(); mod.Meshes = new List <Model3DMesh>(meshCount); for (int m = 0; m < meshCount; m++) { Model3DMesh mesh = new Model3DMesh(); mod.Meshes.Add(mesh); mesh.Name = dr.ReadFullString(); int vertexCount = dr.ReadInt(); mesh.Vertices = new List <Vector3>(vertexCount); for (int v = 0; v < vertexCount; v++) { double f1 = dr.ReadFloat(); double f2 = dr.ReadFloat(); double f3 = dr.ReadFloat(); mesh.Vertices.Add(new Vector3(f1, f2, f3)); } int indiceCount = dr.ReadInt() * 3; mesh.Indices = new List <int>(indiceCount); for (int i = 0; i < indiceCount; i++) { mesh.Indices.Add(dr.ReadInt()); } int tcCount = dr.ReadInt(); mesh.TexCoords = new List <Vector2>(tcCount); for (int t = 0; t < tcCount; t++) { double f1 = dr.ReadFloat(); double f2 = dr.ReadFloat(); mesh.TexCoords.Add(new Vector2(f1, f2)); } int normCount = dr.ReadInt(); mesh.Normals = new List <Vector3>(normCount); for (int n = 0; n < normCount; n++) { double f1 = dr.ReadFloat(); double f2 = dr.ReadFloat(); double f3 = dr.ReadFloat(); mesh.Normals.Add(new Vector3(f1, f2, f3)); } int boneCount = dr.ReadInt(); mesh.Bones = new List <Model3DBone>(boneCount); for (int b = 0; b < boneCount; b++) { Model3DBone bone = new Model3DBone(); mesh.Bones.Add(bone); bone.Name = dr.ReadFullString(); int weights = dr.ReadInt(); bone.IDs = new List <int>(weights); bone.Weights = new List <double>(weights); for (int w = 0; w < weights; w++) { bone.IDs.Add(dr.ReadInt()); bone.Weights.Add(dr.ReadFloat()); } bone.MatrixA = ReadMat(dr); } } mod.RootNode = ReadSingleNode(null, dr); return(mod); }
/// <summary> /// Loads a model from .VMD (Voxalia Model Data) input. /// </summary> public Model3D LoadModel(byte[] data) { if (data.Length < 3 || data[0] != 'V' || data[1] != 'M' || data[2] != 'D') { throw new Exception("Model3D: Invalid header bits."); } byte[] dat_filt = new byte[data.Length - "VMD001".Length]; Array.ConstrainedCopy(data, "VMD001".Length, dat_filt, 0, dat_filt.Length); dat_filt = FileHandler.UnGZip(dat_filt); DataStream ds = new DataStream(dat_filt); DataReader dr = new DataReader(ds); Model3D mod = new Model3D(); mod.MatrixA = ReadMat(dr); int meshCount = dr.ReadInt(); mod.Meshes = new List<Model3DMesh>(meshCount); for (int m = 0; m < meshCount; m++) { Model3DMesh mesh = new Model3DMesh(); mod.Meshes.Add(mesh); mesh.Name = dr.ReadFullString(); int vertexCount = dr.ReadInt(); mesh.Vertices = new List<Vector3>(vertexCount); for (int v = 0; v < vertexCount; v++) { double f1 = dr.ReadFloat(); double f2 = dr.ReadFloat(); double f3 = dr.ReadFloat(); mesh.Vertices.Add(new Vector3(f1, f2, f3)); } int indiceCount = dr.ReadInt() * 3; mesh.Indices = new List<int>(indiceCount); for (int i = 0; i < indiceCount; i++) { mesh.Indices.Add(dr.ReadInt()); } int tcCount = dr.ReadInt(); mesh.TexCoords = new List<Vector2>(tcCount); for (int t = 0; t < tcCount; t++) { double f1 = dr.ReadFloat(); double f2 = dr.ReadFloat(); mesh.TexCoords.Add(new Vector2(f1, f2)); } int normCount = dr.ReadInt(); mesh.Normals = new List<Vector3>(normCount); for (int n = 0; n < normCount; n++) { double f1 = dr.ReadFloat(); double f2 = dr.ReadFloat(); double f3 = dr.ReadFloat(); mesh.Normals.Add(new Vector3(f1, f2, f3)); } int boneCount = dr.ReadInt(); mesh.Bones = new List<Model3DBone>(boneCount); for (int b = 0; b < boneCount; b++) { Model3DBone bone = new Model3DBone(); mesh.Bones.Add(bone); bone.Name = dr.ReadFullString(); int weights = dr.ReadInt(); bone.IDs = new List<int>(weights); bone.Weights = new List<double>(weights); for (int w = 0; w < weights; w++) { bone.IDs.Add(dr.ReadInt()); bone.Weights.Add(dr.ReadFloat()); } bone.MatrixA = ReadMat(dr); } } mod.RootNode = ReadSingleNode(null, dr); return mod; }