protected bool looping = true; // When true, ms3d file should loop the animation #endregion #region LoadData /// Loads the MS3D file public virtual void LoadModelData(string filename) { model_data = new Model(); looping = true; System.IO.FileInfo fInfo = new System.IO.FileInfo(filename); if (!fInfo.Exists) { // Display an error message and don't load anything if no file was found MessageBox.Show("Unable to find the file: " + filename, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } fileFolder = fInfo.DirectoryName; System.IO.Stream fs = new System.IO.FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); long totalLength = fs.Length; // Read the header data and store it in our m_Header member variable byte[] b = new byte[Marshal.SizeOf(typeof(MS3DHeader))]; fs.Read(b, 0, b.Length); MS3DHeader m_Header = (MS3DHeader)RawDeserializeEx(b, typeof(MS3DHeader)); string id = new string(m_Header.ID); // Only Milkshape3D Version 1.3 and 1.4 is supported. #region Vertices b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, Marshal.SizeOf(typeof(short))); short nVertices = (short)RawDeserializeEx(b, typeof(short)); model_data.Vertices = new Vertex[nVertices]; model_data.numVertices = nVertices; for (int i = 0; i < nVertices; i++) { b = new byte[Marshal.SizeOf(typeof(MS3DVertex))]; fs.Read(b, 0, b.Length); MS3DVertex Vertex = (MS3DVertex)RawDeserializeEx(b, typeof(MS3DVertex)); model_data.Vertices[i] = new Vertex(); model_data.Vertices[i].boneID = Vertex.boneID; model_data.Vertices[i].location = Vertex.vertex; } #endregion #region Triangles b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, Marshal.SizeOf(typeof(short))); short nTriangles = (short)RawDeserializeEx(b, typeof(short)); model_data.Triangles = new Triangle[nTriangles]; model_data.numTriangles = nTriangles; for (int i = 0; i < nTriangles; i++) { int[] vertexIndices = new int[3] { 0, 0, 0 }; float[] t = new float[3] { 0, 0, 0 }; b = new byte[Marshal.SizeOf(typeof(MS3DTriangle))]; fs.Read(b, 0, b.Length); MS3DTriangle pTriangle = (MS3DTriangle)RawDeserializeEx(b, typeof(MS3DTriangle)); model_data.Triangles[i] = new Triangle(); vertexIndices[0] = (int)pTriangle.vertexIndices[0]; vertexIndices[1] = (int)pTriangle.vertexIndices[1]; vertexIndices[2] = (int)pTriangle.vertexIndices[2]; t[0] = 1.0f - pTriangle.t[0]; t[1] = 1.0f - pTriangle.t[1]; t[2] = 1.0f - pTriangle.t[2]; model_data.Triangles[i].vertexNormals = pTriangle.vertexNormals; model_data.Triangles[i].s = pTriangle.s; model_data.Triangles[i].t = t; model_data.Triangles[i].vertexIndices = vertexIndices; } #endregion #region Groups b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, Marshal.SizeOf(typeof(short))); short nGroups = (short)RawDeserializeEx(b, typeof(short)); model_data.Meshes = new Mesh[nGroups]; model_data.numMeshes = nGroups; for (int i = 0; i < nGroups; i++) { b = new byte[Marshal.SizeOf(typeof(byte))]; fs.Read(b, 0, b.Length); // Flags b = new byte[32]; fs.Read(b, 0, b.Length); // name string name = System.Text.Encoding.UTF8.GetString(b); b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, b.Length); // number of Triangle Indices nTriangles = (short)RawDeserializeEx(b, typeof(short)); int[] pTriangleIndices = new int[nTriangles]; for (int j = 0; j < nTriangles; j++) { b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, b.Length); // read indices value pTriangleIndices[j] = (short)RawDeserializeEx(b, typeof(short)); } b = new byte[Marshal.SizeOf(typeof(char))]; fs.Read(b, 0, b.Length); // read material index char materialIndex = (char)RawDeserializeEx(b, typeof(char)); model_data.Meshes[i] = new Mesh(); model_data.Meshes[i].materialIndex = (int)materialIndex; model_data.Meshes[i].numTriangles = nTriangles; model_data.Meshes[i].TriangleIndices = pTriangleIndices; } #endregion #region Materials b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, Marshal.SizeOf(typeof(short))); short nMaterials = (short)RawDeserializeEx(b, typeof(short)); model_data.Materials = new Material[nMaterials]; model_data.numMaterials = nMaterials; for (int i = 0; i < nMaterials; i++) { b = new byte[Marshal.SizeOf(typeof(MS3DMaterial))]; fs.Read(b, 0, b.Length); // read material MS3DMaterial pMaterial = (MS3DMaterial)RawDeserializeEx(b, typeof(MS3DMaterial)); model_data.Materials[i] = new Material(); model_data.Materials[i].name = pMaterial.name; model_data.Materials[i].ambient = pMaterial.ambient; model_data.Materials[i].diffuse = pMaterial.diffuse; model_data.Materials[i].specular = pMaterial.specular; model_data.Materials[i].emissive = pMaterial.emissive; model_data.Materials[i].shininess = pMaterial.shininess; model_data.Materials[i].transparency = pMaterial.transparency; model_data.Materials[i].mode = pMaterial.mode; model_data.Materials[i].TextureFilename = CropNull(new string(pMaterial.texture)); model_data.Materials[i].alpha = pMaterial.alphamap; // set alpha model_data.Materials[i].ambient[3] = model_data.Materials[i].transparency; model_data.Materials[i].diffuse[3] = model_data.Materials[i].transparency; model_data.Materials[i].specular[3] = model_data.Materials[i].transparency; model_data.Materials[i].emissive[3] = model_data.Materials[i].transparency; } #endregion ReloadTextures(); #region Animation b = new byte[Marshal.SizeOf(typeof(float))]; fs.Read(b, 0, b.Length); float animFPS = (float)RawDeserializeEx(b, typeof(float)); if (animFPS < 1.0f) { animFPS = 1.0f; } // Skip the currentTime value fs.Read(b, 0, b.Length); b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); int totalFrames = (int)RawDeserializeEx(b, typeof(int)); model_data.totalTime = totalFrames * 1000f / animFPS; #endregion #region Joints b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, b.Length); model_data.numJoints = (short)RawDeserializeEx(b, typeof(short)); model_data.Joints = new Joint[model_data.numJoints]; JointNameListRec[] pNameList = new JointNameListRec[model_data.numJoints]; #region Building JointNameListRec long tempPos = fs.Position; for (int i = 0; i < model_data.numJoints; i++) { b = new byte[Marshal.SizeOf(typeof(MS3DJoint))]; fs.Read(b, 0, b.Length); MS3DJoint pJoint = (MS3DJoint)RawDeserializeEx(b, typeof(MS3DJoint)); pNameList[i] = new JointNameListRec(); pNameList[i].jointIndex = i; pNameList[i].Name = CropNull(new string(pJoint.name)); // skip forward for the next joint b = new byte[Marshal.SizeOf(typeof(MS3DKeyframe)) * (pJoint.numRotationKeyframes + pJoint.numTranslationKeyframes)]; fs.Read(b, 0, b.Length); } fs.Seek(tempPos, System.IO.SeekOrigin.Begin); #endregion #region Load Joints for (int i = 0; i < model_data.numJoints; i++) { b = new byte[Marshal.SizeOf(typeof(MS3DJoint))]; fs.Read(b, 0, b.Length); MS3DJoint pJoint = (MS3DJoint)RawDeserializeEx(b, typeof(MS3DJoint)); int parentIndex = -1; string parentName = CropNull(new string(pJoint.parentName)); if (parentName.Length > 0) { for (int j = 0; j < model_data.numJoints; j++) { if (pNameList[j].Name == parentName) { parentIndex = pNameList[j].jointIndex; break; } } if (parentIndex == -1) { return; } } model_data.Joints[i] = new Joint(); model_data.Joints[i].localRotation = pJoint.rotation; model_data.Joints[i].localTranslation = pJoint.translation; model_data.Joints[i].parent = parentIndex; model_data.Joints[i].numRotationKeyframes = pJoint.numRotationKeyframes; model_data.Joints[i].RotationKeyframes = new Keyframe[pJoint.numRotationKeyframes]; model_data.Joints[i].numTranslationKeyframes = pJoint.numTranslationKeyframes; model_data.Joints[i].TranslationKeyframes = new Keyframe[pJoint.numTranslationKeyframes]; model_data.Joints[i].mat_relative = new Matrix(); model_data.Joints[i].mat_final = new Matrix(); model_data.Joints[i].mat_absolute = new Matrix(); // the frame time is in seconds, so multiply it by the animation fps, to get the frames // rotation channel for (int j = 0; j < pJoint.numRotationKeyframes; j++) { b = new byte[Marshal.SizeOf(typeof(MS3DKeyframe))]; fs.Read(b, 0, b.Length); MS3DKeyframe pKeyframe = (MS3DKeyframe)RawDeserializeEx(b, typeof(MS3DKeyframe)); SetJointKeyframe(i, j, pKeyframe.time * 1000.0f, ref pKeyframe.parameter, true); } // translation channel for (int j = 0; j < pJoint.numTranslationKeyframes; j++) { b = new byte[Marshal.SizeOf(typeof(MS3DKeyframe))]; fs.Read(b, 0, b.Length); MS3DKeyframe pKeyframe = (MS3DKeyframe)RawDeserializeEx(b, typeof(MS3DKeyframe)); SetJointKeyframe(i, j, pKeyframe.time * 1000.0f, ref pKeyframe.parameter, false); } } #endregion pNameList = null; #endregion #region Comments if (fs.Position < totalLength) { int subVersion = 0; b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); subVersion = (int)RawDeserializeEx(b, typeof(int)); if (subVersion == 1) { int numComments = 0; uint commentSize = 0; #region Group Comments b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); numComments = (int)RawDeserializeEx(b, typeof(int)); for (int i = 0; i < numComments; i++) { int index; string comment = ""; fs.Read(b, 0, b.Length); index = (int)RawDeserializeEx(b, typeof(int)); b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); commentSize = (uint)RawDeserializeEx(b, typeof(uint)); if (commentSize > 0) { b = new byte[Marshal.SizeOf(sizeof(char) * commentSize)]; fs.Read(b, 0, b.Length); comment = System.Text.Encoding.ASCII.GetString(b); } if (index >= 0 && index < model_data.numMeshes) { model_data.Meshes[index].comment = comment; } } #endregion #region Material Comments b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); numComments = (int)RawDeserializeEx(b, typeof(int)); for (int i = 0; i < numComments; i++) { int index; string comment = ""; fs.Read(b, 0, b.Length); index = (int)RawDeserializeEx(b, typeof(int)); b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); commentSize = (uint)RawDeserializeEx(b, typeof(uint)); if (commentSize > 0) { b = new byte[Marshal.SizeOf(sizeof(char) * commentSize)]; fs.Read(b, 0, b.Length); comment = System.Text.Encoding.ASCII.GetString(b); } if (index >= 0 && index < model_data.numMaterials) { model_data.Materials[index].comment = comment; } } #endregion #region Joint Comments b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); numComments = (int)RawDeserializeEx(b, typeof(int)); for (int i = 0; i < numComments; i++) { int index; string comment = ""; fs.Read(b, 0, b.Length); index = (int)RawDeserializeEx(b, typeof(int)); b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); commentSize = (uint)RawDeserializeEx(b, typeof(uint)); if (commentSize > 0) { b = new byte[Marshal.SizeOf(sizeof(char) * commentSize)]; fs.Read(b, 0, b.Length); comment = System.Text.Encoding.ASCII.GetString(b); } if (index >= 0 && index < model_data.numJoints) { model_data.Joints[index].comment = comment; } } #endregion #region Model Comments b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); numComments = (int)RawDeserializeEx(b, typeof(int)); if (numComments == 1) { string comment = ""; b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); commentSize = (uint)RawDeserializeEx(b, typeof(uint)); if (commentSize > 0) { b = new byte[Marshal.SizeOf(sizeof(char) * commentSize)]; fs.Read(b, 0, b.Length); comment = System.Text.Encoding.ASCII.GetString(b); } model_data.comment = comment; } #endregion } } #endregion #region Vertex Extra if (fs.Position < totalLength) { int subVersion = 0; b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); subVersion = (int)RawDeserializeEx(b, typeof(int)); if ((subVersion == 1) || (subVersion == 2)) { for (int i = 0; i < model_data.numVertices; i++) { model_data.Vertices[i].boneIds = new char[3]; b = new byte[Marshal.SizeOf(typeof(char))]; fs.Read(b, 0, b.Length); model_data.Vertices[i].boneIds[0] = (char)RawDeserializeEx(b, typeof(char)); fs.Read(b, 0, b.Length); model_data.Vertices[i].boneIds[1] = (char)RawDeserializeEx(b, typeof(char)); fs.Read(b, 0, b.Length); model_data.Vertices[i].boneIds[2] = (char)RawDeserializeEx(b, typeof(char)); model_data.Vertices[i].weights = new char[3]; fs.Read(b, 0, b.Length); model_data.Vertices[i].weights[0] = (char)RawDeserializeEx(b, typeof(char)); fs.Read(b, 0, b.Length); model_data.Vertices[i].weights[1] = (char)RawDeserializeEx(b, typeof(char)); fs.Read(b, 0, b.Length); model_data.Vertices[i].weights[2] = (char)RawDeserializeEx(b, typeof(char)); if (subVersion == 2) { b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); model_data.Vertices[i].extra = (uint)RawDeserializeEx(b, typeof(uint)); } } } } #endregion #region Joint Extra if (fs.Position < totalLength) { int subVersion = 0; b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); subVersion = (int)RawDeserializeEx(b, typeof(int)); if (subVersion == 1) { for (int i = 0; i < model_data.numJoints; i++) { model_data.Joints[i].color = new float[3]; b = new byte[Marshal.SizeOf(typeof(float))]; fs.Read(b, 0, b.Length); model_data.Joints[i].color[0] = (float)RawDeserializeEx(b, typeof(float)); fs.Read(b, 0, b.Length); model_data.Joints[i].color[1] = (float)RawDeserializeEx(b, typeof(float)); fs.Read(b, 0, b.Length); model_data.Joints[i].color[2] = (float)RawDeserializeEx(b, typeof(float)); } } } #endregion #region Model Extra if (fs.Position < totalLength) { int subVersion = 0; b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); subVersion = (int)RawDeserializeEx(b, typeof(int)); if (subVersion == 1) { b = new byte[Marshal.SizeOf(typeof(float))]; fs.Read(b, 0, b.Length); model_data.jointSize = (float)RawDeserializeEx(b, typeof(float)); b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); model_data.transparencyMode = (int)RawDeserializeEx(b, typeof(int)); b = new byte[Marshal.SizeOf(typeof(float))]; fs.Read(b, 0, b.Length); model_data.alphaRef = (float)RawDeserializeEx(b, typeof(float)); } } #endregion fs.Close(); try { SetupJoints(); } catch { } }
/// Loads the MS3D file public virtual void LoadModelData(string filename) { model_data = new Model(); looping = true; System.IO.FileInfo fInfo = new System.IO.FileInfo(filename); if (!fInfo.Exists) { // Display an error message and don't load anything if no file was found MessageBox.Show("Unable to find the file: " + filename, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } fileFolder = fInfo.DirectoryName; System.IO.Stream fs = new System.IO.FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); long totalLength = fs.Length; // Read the header data and store it in our m_Header member variable byte[] b = new byte[Marshal.SizeOf(typeof(MS3DHeader))]; fs.Read(b, 0, b.Length); MS3DHeader m_Header = (MS3DHeader)RawDeserializeEx(b, typeof(MS3DHeader)); string id = new string(m_Header.ID); // Only Milkshape3D Version 1.3 and 1.4 is supported. #region Vertices b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, Marshal.SizeOf(typeof(short))); short nVertices = (short)RawDeserializeEx(b, typeof(short)); model_data.Vertices = new Vertex[nVertices]; model_data.numVertices = nVertices; for (int i = 0; i < nVertices; i++) { b = new byte[Marshal.SizeOf(typeof(MS3DVertex))]; fs.Read(b, 0, b.Length); MS3DVertex Vertex = (MS3DVertex)RawDeserializeEx(b, typeof(MS3DVertex)); model_data.Vertices[i] = new Vertex(); model_data.Vertices[i].boneID = Vertex.boneID; model_data.Vertices[i].location = Vertex.vertex; } #endregion #region Triangles b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, Marshal.SizeOf(typeof(short))); short nTriangles = (short)RawDeserializeEx(b, typeof(short)); model_data.Triangles = new Triangle[nTriangles]; model_data.numTriangles = nTriangles; for (int i = 0; i < nTriangles; i++) { int[] vertexIndices = new int[3] { 0, 0, 0 }; float[] t = new float[3] { 0, 0, 0 }; b = new byte[Marshal.SizeOf(typeof(MS3DTriangle))]; fs.Read(b, 0, b.Length); MS3DTriangle pTriangle = (MS3DTriangle)RawDeserializeEx(b, typeof(MS3DTriangle)); model_data.Triangles[i] = new Triangle(); vertexIndices[0] = (int)pTriangle.vertexIndices[0]; vertexIndices[1] = (int)pTriangle.vertexIndices[1]; vertexIndices[2] = (int)pTriangle.vertexIndices[2]; t[0] = 1.0f - pTriangle.t[0]; t[1] = 1.0f - pTriangle.t[1]; t[2] = 1.0f - pTriangle.t[2]; model_data.Triangles[i].vertexNormals = pTriangle.vertexNormals; model_data.Triangles[i].s = pTriangle.s; model_data.Triangles[i].t = t; model_data.Triangles[i].vertexIndices = vertexIndices; } #endregion #region Groups b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, Marshal.SizeOf(typeof(short))); short nGroups = (short)RawDeserializeEx(b, typeof(short)); model_data.Meshes = new Mesh[nGroups]; model_data.numMeshes = nGroups; for (int i = 0; i < nGroups; i++) { b = new byte[Marshal.SizeOf(typeof(byte))]; fs.Read(b, 0, b.Length); // Flags b = new byte[32]; fs.Read(b, 0, b.Length); // name string name = System.Text.Encoding.UTF8.GetString(b); b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, b.Length); // number of Triangle Indices nTriangles = (short)RawDeserializeEx(b, typeof(short)); int[] pTriangleIndices = new int[nTriangles]; for (int j = 0; j < nTriangles; j++) { b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, b.Length); // read indices value pTriangleIndices[j] = (short)RawDeserializeEx(b, typeof(short)); } b = new byte[Marshal.SizeOf(typeof(char))]; fs.Read(b, 0, b.Length); // read material index char materialIndex = (char)RawDeserializeEx(b, typeof(char)); model_data.Meshes[i] = new Mesh(); model_data.Meshes[i].materialIndex = (int)materialIndex; model_data.Meshes[i].numTriangles = nTriangles; model_data.Meshes[i].TriangleIndices = pTriangleIndices; } #endregion #region Materials b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, Marshal.SizeOf(typeof(short))); short nMaterials = (short)RawDeserializeEx(b, typeof(short)); model_data.Materials = new Material[nMaterials]; model_data.numMaterials = nMaterials; for (int i = 0; i < nMaterials; i++) { b = new byte[Marshal.SizeOf(typeof(MS3DMaterial))]; fs.Read(b, 0, b.Length); // read material MS3DMaterial pMaterial = (MS3DMaterial)RawDeserializeEx(b, typeof(MS3DMaterial)); model_data.Materials[i] = new Material(); model_data.Materials[i].name = pMaterial.name; model_data.Materials[i].ambient = pMaterial.ambient; model_data.Materials[i].diffuse = pMaterial.diffuse; model_data.Materials[i].specular = pMaterial.specular; model_data.Materials[i].emissive = pMaterial.emissive; model_data.Materials[i].shininess = pMaterial.shininess; model_data.Materials[i].transparency = pMaterial.transparency; model_data.Materials[i].mode = pMaterial.mode; model_data.Materials[i].TextureFilename = CropNull(new string(pMaterial.texture)); model_data.Materials[i].alpha = pMaterial.alphamap; // set alpha model_data.Materials[i].ambient[3] = model_data.Materials[i].transparency; model_data.Materials[i].diffuse[3] = model_data.Materials[i].transparency; model_data.Materials[i].specular[3] = model_data.Materials[i].transparency; model_data.Materials[i].emissive[3] = model_data.Materials[i].transparency; } #endregion ReloadTextures(); #region Animation b = new byte[Marshal.SizeOf(typeof(float))]; fs.Read(b, 0, b.Length); float animFPS = (float)RawDeserializeEx(b, typeof(float)); if (animFPS < 1.0f) animFPS = 1.0f; // Skip the currentTime value fs.Read(b, 0, b.Length); b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); int totalFrames = (int)RawDeserializeEx(b, typeof(int)); model_data.totalTime = totalFrames * 1000f / animFPS; #endregion #region Joints b = new byte[Marshal.SizeOf(typeof(short))]; fs.Read(b, 0, b.Length); model_data.numJoints = (short)RawDeserializeEx(b, typeof(short)); model_data.Joints = new Joint[model_data.numJoints]; JointNameListRec[] pNameList = new JointNameListRec[model_data.numJoints]; #region Building JointNameListRec long tempPos = fs.Position; for (int i = 0; i < model_data.numJoints; i++) { b = new byte[Marshal.SizeOf(typeof(MS3DJoint))]; fs.Read(b, 0, b.Length); MS3DJoint pJoint = (MS3DJoint)RawDeserializeEx(b, typeof(MS3DJoint)); pNameList[i] = new JointNameListRec(); pNameList[i].jointIndex = i; pNameList[i].Name = CropNull(new string(pJoint.name)); // skip forward for the next joint b = new byte[Marshal.SizeOf(typeof(MS3DKeyframe)) * (pJoint.numRotationKeyframes + pJoint.numTranslationKeyframes)]; fs.Read(b, 0, b.Length); } fs.Seek(tempPos, System.IO.SeekOrigin.Begin); #endregion #region Load Joints for (int i = 0; i < model_data.numJoints; i++) { b = new byte[Marshal.SizeOf(typeof(MS3DJoint))]; fs.Read(b, 0, b.Length); MS3DJoint pJoint = (MS3DJoint)RawDeserializeEx(b, typeof(MS3DJoint)); int parentIndex = -1; string parentName = CropNull(new string(pJoint.parentName)); if (parentName.Length > 0) { for (int j = 0; j < model_data.numJoints; j++) { if (pNameList[j].Name == parentName) { parentIndex = pNameList[j].jointIndex; break; } } if (parentIndex == -1) return; } model_data.Joints[i] = new Joint(); model_data.Joints[i].localRotation = pJoint.rotation; model_data.Joints[i].localTranslation = pJoint.translation; model_data.Joints[i].parent = parentIndex; model_data.Joints[i].numRotationKeyframes = pJoint.numRotationKeyframes; model_data.Joints[i].RotationKeyframes = new Keyframe[pJoint.numRotationKeyframes]; model_data.Joints[i].numTranslationKeyframes = pJoint.numTranslationKeyframes; model_data.Joints[i].TranslationKeyframes = new Keyframe[pJoint.numTranslationKeyframes]; model_data.Joints[i].mat_relative = new Matrix(); model_data.Joints[i].mat_final = new Matrix(); model_data.Joints[i].mat_absolute = new Matrix(); // the frame time is in seconds, so multiply it by the animation fps, to get the frames // rotation channel for (int j = 0; j < pJoint.numRotationKeyframes; j++) { b = new byte[Marshal.SizeOf(typeof(MS3DKeyframe))]; fs.Read(b, 0, b.Length); MS3DKeyframe pKeyframe = (MS3DKeyframe)RawDeserializeEx(b, typeof(MS3DKeyframe)); SetJointKeyframe(i, j, pKeyframe.time * 1000.0f, ref pKeyframe.parameter, true); } // translation channel for (int j = 0; j < pJoint.numTranslationKeyframes; j++) { b = new byte[Marshal.SizeOf(typeof(MS3DKeyframe))]; fs.Read(b, 0, b.Length); MS3DKeyframe pKeyframe = (MS3DKeyframe)RawDeserializeEx(b, typeof(MS3DKeyframe)); SetJointKeyframe(i, j, pKeyframe.time * 1000.0f, ref pKeyframe.parameter, false); } } #endregion pNameList = null; #endregion #region Comments if (fs.Position < totalLength) { int subVersion = 0; b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); subVersion = (int)RawDeserializeEx(b, typeof(int)); if (subVersion == 1) { int numComments = 0; uint commentSize = 0; #region Group Comments b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); numComments = (int)RawDeserializeEx(b, typeof(int)); for (int i = 0; i < numComments; i++) { int index; string comment = ""; fs.Read(b, 0, b.Length); index = (int)RawDeserializeEx(b, typeof(int)); b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); commentSize = (uint)RawDeserializeEx(b, typeof(uint)); if (commentSize > 0) { b = new byte[Marshal.SizeOf(sizeof(char) * commentSize)]; fs.Read(b, 0, b.Length); comment = System.Text.Encoding.ASCII.GetString(b); } if (index >= 0 && index < model_data.numMeshes) model_data.Meshes[index].comment = comment; } #endregion #region Material Comments b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); numComments = (int)RawDeserializeEx(b, typeof(int)); for (int i = 0; i < numComments; i++) { int index; string comment = ""; fs.Read(b, 0, b.Length); index = (int)RawDeserializeEx(b, typeof(int)); b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); commentSize = (uint)RawDeserializeEx(b, typeof(uint)); if (commentSize > 0) { b = new byte[Marshal.SizeOf(sizeof(char) * commentSize)]; fs.Read(b, 0, b.Length); comment = System.Text.Encoding.ASCII.GetString(b); } if (index >= 0 && index < model_data.numMaterials) model_data.Materials[index].comment = comment; } #endregion #region Joint Comments b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); numComments = (int)RawDeserializeEx(b, typeof(int)); for (int i = 0; i < numComments; i++) { int index; string comment = ""; fs.Read(b, 0, b.Length); index = (int)RawDeserializeEx(b, typeof(int)); b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); commentSize = (uint)RawDeserializeEx(b, typeof(uint)); if (commentSize > 0) { b = new byte[Marshal.SizeOf(sizeof(char) * commentSize)]; fs.Read(b, 0, b.Length); comment = System.Text.Encoding.ASCII.GetString(b); } if (index >= 0 && index < model_data.numJoints) model_data.Joints[index].comment = comment; } #endregion #region Model Comments b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); numComments = (int)RawDeserializeEx(b, typeof(int)); if (numComments == 1) { string comment = ""; b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); commentSize = (uint)RawDeserializeEx(b, typeof(uint)); if (commentSize > 0) { b = new byte[Marshal.SizeOf(sizeof(char) * commentSize)]; fs.Read(b, 0, b.Length); comment = System.Text.Encoding.ASCII.GetString(b); } model_data.comment = comment; } #endregion } } #endregion #region Vertex Extra if (fs.Position < totalLength) { int subVersion = 0; b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); subVersion = (int)RawDeserializeEx(b, typeof(int)); if ((subVersion == 1) || (subVersion == 2)) { for (int i = 0; i < model_data.numVertices; i++) { model_data.Vertices[i].boneIds = new char[3]; b = new byte[Marshal.SizeOf(typeof(char))]; fs.Read(b, 0, b.Length); model_data.Vertices[i].boneIds[0] = (char)RawDeserializeEx(b, typeof(char)); fs.Read(b, 0, b.Length); model_data.Vertices[i].boneIds[1] = (char)RawDeserializeEx(b, typeof(char)); fs.Read(b, 0, b.Length); model_data.Vertices[i].boneIds[2] = (char)RawDeserializeEx(b, typeof(char)); model_data.Vertices[i].weights = new char[3]; fs.Read(b, 0, b.Length); model_data.Vertices[i].weights[0] = (char)RawDeserializeEx(b, typeof(char)); fs.Read(b, 0, b.Length); model_data.Vertices[i].weights[1] = (char)RawDeserializeEx(b, typeof(char)); fs.Read(b, 0, b.Length); model_data.Vertices[i].weights[2] = (char)RawDeserializeEx(b, typeof(char)); if (subVersion == 2) { b = new byte[Marshal.SizeOf(typeof(uint))]; fs.Read(b, 0, b.Length); model_data.Vertices[i].extra = (uint)RawDeserializeEx(b, typeof(uint)); } } } } #endregion #region Joint Extra if (fs.Position < totalLength) { int subVersion = 0; b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); subVersion = (int)RawDeserializeEx(b, typeof(int)); if (subVersion == 1) { for (int i = 0; i < model_data.numJoints; i++) { model_data.Joints[i].color = new float[3]; b = new byte[Marshal.SizeOf(typeof(float))]; fs.Read(b, 0, b.Length); model_data.Joints[i].color[0] = (float)RawDeserializeEx(b, typeof(float)); fs.Read(b, 0, b.Length); model_data.Joints[i].color[1] = (float)RawDeserializeEx(b, typeof(float)); fs.Read(b, 0, b.Length); model_data.Joints[i].color[2] = (float)RawDeserializeEx(b, typeof(float)); } } } #endregion #region Model Extra if (fs.Position < totalLength) { int subVersion = 0; b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); subVersion = (int)RawDeserializeEx(b, typeof(int)); if (subVersion == 1) { b = new byte[Marshal.SizeOf(typeof(float))]; fs.Read(b, 0, b.Length); model_data.jointSize = (float)RawDeserializeEx(b, typeof(float)); b = new byte[Marshal.SizeOf(typeof(int))]; fs.Read(b, 0, b.Length); model_data.transparencyMode = (int)RawDeserializeEx(b, typeof(int)); b = new byte[Marshal.SizeOf(typeof(float))]; fs.Read(b, 0, b.Length); model_data.alphaRef = (float)RawDeserializeEx(b, typeof(float)); } } #endregion fs.Close(); try { SetupJoints(); } catch { } }