Exemple #1
0
            private void readMaterials()
            {
                int matcount = ReadCount();

                for (int m = 0; m < matcount; ++m)
                {
                    MS3DMaterial mat = Read <MS3DMaterial>();
                    materials.Add(mat);
                }
            }
    private static void readMesh(string path, string filename, string texturepath)
    {
        

        if (File.Exists(path + "/" + filename))
        {
                string nm = Path.GetFileNameWithoutExtension(filename);
                importingAssetsDir = "Assets/Prefabs/" + nm + "/";

                if (saveAssets)
                {
                if (!Directory.Exists(importingAssetsDir))
                {
                    Directory.CreateDirectory(importingAssetsDir);
                }
               
                }


            trace("load file :"+path + "/" + filename);

            using (FileStream fs = File.OpenRead(path + "/" + filename))
            {

              
                file = new BinaryReader(fs);
                file.BaseStream.Position = 0;


                string id =readUTFBytes(10);
                int version = readInt();

                Debug.Log("ID:" + id + ", version:" + version);


                int numVerts = (int)file.ReadInt16();

                Debug.Log("Numer of vertex:" + numVerts);
                List<MS3DVertex> vertices = new List<MS3DVertex>();
                for (int i=0; i<numVerts; i++)
                {
                    MS3DVertex vertex = new MS3DVertex();
                    vertices.Add(vertex);
                    
                }

                List<MS3DTriangle> triangles = new List<MS3DTriangle>();
                int numTriangles = (int)file.ReadInt16();

                Debug.Log("Numer of triangles:" + numTriangles);
                for (int i=0; i<numTriangles; i++)
                {
                    MS3DTriangle tri = new MS3DTriangle();
                    triangles.Add(tri);

                }
                 

                int numMeshes=(int)file.ReadInt16();
                Debug.Log("Numer of meshes:" + numMeshes);

                List<MS3DMesh> meshes = new List<MS3DMesh>();
                for (int i = 0; i < numMeshes; i++)
                {
                    MS3DMesh mesh = new MS3DMesh();
                    meshes.Add(mesh);
                }

                int numMaterials=(int)file.ReadInt16();
                Debug.Log("Number  of Materials:" + numMaterials);
                List<MS3DMaterial> materials = new List<MS3DMaterial>();
                for (int i = 0; i < numMaterials; i++)
                {
                    MS3DMaterial material = new MS3DMaterial();

                    if (File.Exists(path + "/" + material.alphaMap))
                    {
                        material.textureDetail = loadexture(path + "/" + material.alphaMap);
                    }
                        
                    if (File.Exists(path + "/" + material.textureMap))
                    {
                        material.texture = loadexture(path + "/" + material.textureMap);
                    }



                    materials.Add(material);
                }

                framesPerSecond = file.ReadSingle();
                float currentTime =file.ReadSingle();
                NumFrames =file.ReadInt32();
                int numJoints = file.ReadInt16();


                Debug.Log("fps:"+framesPerSecond+", time:"+currentTime+", total frames:"+NumFrames+", num joints:"+numJoints);

              
                GameObject ObjectRoot = new GameObject(nm);
                GameObject meshContainer = new GameObject("Surfaces");
                meshContainer.transform.parent = ObjectRoot.transform;

                if (numJoints > 1)
                {
                    AnimationClip clip = new AnimationClip();
                    clip.name = nm + "take00";
                    clip.wrapMode = WrapMode.Loop;

               
                    for (int i = 0; i < numJoints; i++)
                    {
                        isStatic = false;

                        CoreJoint Joint = new CoreJoint();
                        byte flags = file.ReadByte();
                        char[] name = file.ReadChars(32);
                        char[] parentName = file.ReadChars(32);

                   
                        Joint.Name = "";
                        for (int k = 0; k < 32; k++)
                        {
                            if (name[k] == (char)0)
                                break;
                            Joint.Name += name[k];
                        }
                        Joint.ParentName = "";
                        for (int k = 0; k < 32; k++)
                        {
                            if (parentName[k] == (char)0)
                                break;
                            Joint.ParentName += parentName[k];
                        }

                        Joint.joint.name = Joint.Name;


                        //       Debug.Log("Joint name:" + Joint.Name + " , Join Parent:" + Joint.ParentName);

                  
                   
                        Vector3 rotation = Vector3.zero;
                        rotation.x = file.ReadSingle();
                        rotation.y = file.ReadSingle();
                        rotation.z = file.ReadSingle();

                        Joint.position = Vector3.zero;
                        Joint.position.x = file.ReadSingle();
                        Joint.position.y = file.ReadSingle();
                        Joint.position.z = file.ReadSingle();
                        Joint.rotation = QuaternionCreate(rotation);


                        CoreJoint parent = getBoneByName(Joint.ParentName);
                        if (parent != null)
                        {
                            Joint.parent = parent;
                            Joint.joint.transform.parent = parent.joint.transform;    
                            Joint.Path += parent.Path + "/";

                            //    Debug.Log("Bone:"+ Joint.Name+" Parent"+ Joint.ParentName); 

                        }
                        else
                        {
                            Joint.joint.transform.parent = ObjectRoot.transform;
                            //  Debug.LogWarning("Bone:"+ Joint.Name+" dont have parent"); 
                        }
                        Joint.Path += Joint.Name;

                        Joint.joint.transform.localPosition = Joint.position;
                        Joint.joint.transform.localRotation = Joint.rotation;


                 


                 

                        // Debug.Log("Joint: "+Joint.Name+", Position:" + Joint.position +", Rotation: "+rotation);
                        //    Debug.Log("Joint :"+Joint.Name+" , Path:"+Joint.Path);


           
              
                        Joint.numRotKeyFrames = file.ReadInt16();
                        Joint.numPosKeyFrames = file.ReadInt16();
                  
                        float fps = 1.0f/ framesPerSecond;
                    
                        for (int k = 0; k < Joint.numRotKeyFrames; k++)
                        {
                       
                            float time = file.ReadSingle();
                            Vector3 rot = ReadVector3();
                            Quaternion qrot = QuaternionCreate(rot) * Joint.rotation;
                            Joint.addRotationCurve(qrot, time );


                       //     Debug.Log("Frame:" + time + " , time:" + (time*fps));

                        }
                        for (int k = 0; k < Joint.numPosKeyFrames; k++)
                        {
                            float time = file.ReadSingle();
                            Vector3 pos = Joint.position + ReadVector3();
                            Joint.addPositionCurve(pos.x, pos.y, pos.z, time );

                

                           


                        }
                        Joint.addCurves(clip);
                       
                        if (Joint.numRotKeyFrames != Joint.numPosKeyFrames)
                        {
                            Debug.LogError(Joint.numPosKeyFrames + " != " + Joint.numRotKeyFrames);
                        }
                  



                  

               
                        listJoints.Add(Joint);



                   
                    }

                    clip.frameRate = framesPerSecond;
                    clip.legacy = true;
                    Animation anim = (UnityEngine.Animation)ObjectRoot.AddComponent(typeof(Animation));
                    anim.AddClip(clip, clip.name);
                    anim.clip = clip;
                    anim.playAutomatically = true;
         
                    if (saveAssets)
                    {

                        string clipAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + clip.name + ".asset");
                        AssetDatabase.CreateAsset(clip, clipAssetPath);

                    }
                }//JOINTS

             
                for (int i = 0; i < meshes.Count; i++)
                {
                    MS3DMesh mesh = meshes[i];

                    CoreMesh cmesh = new CoreMesh(meshContainer, ObjectRoot, mesh.name);


                    if (mesh.MaterialIndex >= 0 && mesh.MaterialIndex <= materials.Count)
                    {
                        MS3DMaterial material = materials[mesh.MaterialIndex];    
                        bool isDetail = material.textureDetail != null;
                        if (isDetail)
                        {
                        }
                        else
                        {
                            cmesh.material=new Material(Shader.Find("Diffuse"));
                            cmesh.material.name = material.name;
                            if (material.texture != null)
                            {
                                cmesh.material.mainTexture = material.texture;
                            }

                            if (saveAssets)
                            {
                                string meshAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + cmesh.material.name + ".asset");
                       
                                AssetDatabase.CreateAsset(cmesh.material, meshAssetPath);
                            }

                        }


                    }



                    for (int j = 0; j < mesh.numTriangles; j++)
                    {
                        if(!isStatic)
                        {
                   
                            VertexBone vtx0 = new VertexBone();
                            cmesh.vertex.Add(vtx0);

                            VertexBone vtx1 = new VertexBone();
                  
                            cmesh.vertex.Add(vtx1);

                            VertexBone vtx2 = new VertexBone();
                     
                            cmesh.vertex.Add(vtx2);

                        }

                        
                        int index0 = triangles[mesh.TriangleIndices[j]].indice0;
                        Vector3 v0 = vertices[index0].Vertex;
                        Vector3 n0 = triangles[mesh.TriangleIndices[j]].normal0;
                        float u0 = triangles[mesh.TriangleIndices[j]].s.x;
                        float t0 = 1f * -triangles[mesh.TriangleIndices[j]].t.x;

                        int index1 = triangles[mesh.TriangleIndices[j]].indice1;
                        Vector3 v1 = vertices[index1].Vertex;
                        Vector3 n1 = triangles[mesh.TriangleIndices[j]].normal1;
                        float u1 = triangles[mesh.TriangleIndices[j]].s.y;
                        float t1 = 1f * -triangles[mesh.TriangleIndices[j]].t.y;


                        int index2 = triangles[mesh.TriangleIndices[j]].indice2;
                        Vector3 v2 = vertices[index2].Vertex;
                        Vector3 n2 = triangles[mesh.TriangleIndices[j]].normal2;
                        float u2 = triangles[mesh.TriangleIndices[j]].s.z;
                        float t2 = 1f * -triangles[mesh.TriangleIndices[j]].t.z;

                        int f0 = cmesh.addVertex(v0);
                                 cmesh.addNormal(n0);
                                 cmesh.addTexCoords(new Vector2(u0, t0), 0);


                        int f1 = cmesh.addVertex(v1);
                        cmesh.addNormal(n1);
                        cmesh.addTexCoords(new Vector2(u1, t1), 0);


                        int f2 = cmesh.addVertex(v2);
                        cmesh.addNormal(n2);
                        cmesh.addTexCoords(new Vector2(u2, t2), 0);

                        cmesh.addFace(f0, f1, f2);

                        if (!isStatic)
                        {
                            
                            int Bone0 = vertices[index0].boneId;
                            int Bone1 = vertices[index1].boneId;
                            int Bone2 = vertices[index2].boneId;

                            cmesh.vertex[f0].addBone(Bone0, 1);
                            cmesh.vertex[f1].addBone(Bone1, 1);
                            cmesh.vertex[f2].addBone(Bone2, 1);

                        }

                     

                    

                    }
                   
                    surfaces.Add(cmesh);
                }

                for (int i = 0; i < meshes.Count; i++)
                {
                    MS3DMesh mesh = meshes[i];
                    CoreMesh cmesh = surfaces[i];

                    if (!isStatic)
                    {
                        
                        for (int j = 0; j < cmesh.vertex.Count; j++)
                        {
                            isStatic = false;

                            VertexBone vertex = cmesh.vertex[j];
                            //  Debug.Log("Num Bone:" + vertex.numBones);

                            BoneWeight b = new BoneWeight();
                            b.boneIndex0 = vertex.bones[0].boneId;
                            b.weight0 = vertex.bones[0].Weight;

                      

                            cmesh.addBone(b);


                        }
                    }
                    cmesh.build();
                    if (saveAssets)
                    {
                        string meshAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + cmesh.name+"_"+i + ".asset");
                        AssetDatabase.CreateAsset(cmesh.geometry, meshAssetPath);
                    }
                }



                if (saveAssets)
                {

                    string prefabPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + filename + ".prefab");
                    var prefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
                    PrefabUtility.ReplacePrefab(ObjectRoot, prefab, ReplacePrefabOptions.ConnectToPrefab);
                    AssetDatabase.Refresh();
                }

                materials.Clear();
                meshes.Clear();
                triangles.Clear();
                vertices.Clear();

                materials = null;
                meshes = null;
                triangles = null;
                vertices = null;


               




            
            }//file open

            Debug.Log(path + "/" + filename + " Imported ;) ");
        }

    }
Exemple #3
0
        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 { }
        }