public CoreJoint()
        {
            
            index=0;
            Name = "";
            parent = null;
            Path = "";

            Position=new Vector3(0,0,0);
            Scale=new Vector3(1,1,1);
            Orientation=Quaternion.identity;
            weights = new List<VertexWight>();


            //joint = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            joint = new GameObject("");

             scaleXcurve = new AnimationCurve();
             scaleYcurve = new AnimationCurve();
             scaleZcurve = new AnimationCurve();

             posXcurve = new AnimationCurve();
             posYcurve = new AnimationCurve();
             posZcurve = new AnimationCurve();

             rotXcurve = new AnimationCurve();
             rotYcurve = new AnimationCurve();
             rotZcurve = new AnimationCurve();
             rotWcurve = new AnimationCurve();

        }
    private static CoreJoint readNODE(GameObject ObjectRoot ,GameObject MeshContainer,CoreJoint parent,string path)
    {
        
        string name = readstring();

   


        CoreJoint  lastBone= new CoreJoint();
       


        lastBone.Position    = ReadVector3();
        lastBone.Scale       = ReadVector3();
        lastBone.Orientation = ReadQuaternion();

        lastBone.Name = name;
        lastBone.joint.name = name;
        lastBone.index = listJoints.Count;
    
     
        /*
        trace("Name:" + name + " , Position:" +
            lastBone.Position.ToString() +
            ", Rotation :" + lastBone.Orientation.ToString() +
            ", Scale :" + lastBone.Scale.ToString());

       */

        if (parent != null)
        {
            lastBone.parent = parent;
            lastBone.joint.transform.parent = parent.joint.transform;
            lastBone.Path += parent.Path + "/"; 
    
        } else
        {
            lastBone.joint.transform.parent = ObjectRoot.transform;

        }



           
        lastBone.joint.transform.localPosition = lastBone.Position;
        lastBone.joint.transform.localRotation = lastBone.Orientation;
        lastBone.joint.transform.localScale = lastBone.Scale;

     
        lastBone.Path += name;   


       


        listJoints.Add(lastBone);



      


        while (getChunkSize() != 0)
        {
            var ChunkName = ReadChunk();
            if(ChunkName=="MESH") 
            {
                VerticesStart = listVertex.Count;
                readMESH(MeshContainer,ObjectRoot,"mesh");
            } else  
                if(ChunkName=="BONE") 
                {
                    readBone(lastBone);
                } 
            if(ChunkName=="ANIM") 
            {
                readANIM();

            }  else  
                if(ChunkName=="KEYS") 
                {
                    readKEYS(lastBone); 
                } else
                    if(ChunkName=="NODE") 
                    {
                        CoreJoint child = readNODE(ObjectRoot,MeshContainer,lastBone,path);
                       

                       
                    }
            breakChunk();
        }
  
        return lastBone;
    }
    private static void readBone( CoreJoint bone)
    {
        int vertex_id = 0;
        int buffer_id = 0;

   
        while (getChunkSize()!=0) 
        {
            int globalVertexID  =file.ReadInt32();//vertexid
            float strength =  file.ReadSingle();//wight



            globalVertexID += VerticesStart;

            if (AnimatedVertices_VertexID[globalVertexID]==-1)
            {
                trace(" Weight has bad vertex id (no link to meshbuffer index found)");
            } else 
            {

                vertex_id = AnimatedVertices_VertexID[globalVertexID];
                buffer_id = AnimatedVertices_BufferID[globalVertexID];

         

                if (strength > Bones[buffer_id].vertex[vertex_id].bones[0].Weight)
                {
                    Bones[buffer_id].vertex[vertex_id].bones[3].boneId = Bones[buffer_id].vertex[vertex_id].bones[2].boneId;
                    Bones[buffer_id].vertex[vertex_id].bones[3].Weight = Bones[buffer_id].vertex[vertex_id].bones[2].Weight;

                    Bones[buffer_id].vertex[vertex_id].bones[1].boneId = Bones[buffer_id].vertex[vertex_id].bones[0].boneId;
                    Bones[buffer_id].vertex[vertex_id].bones[1].Weight = Bones[buffer_id].vertex[vertex_id].bones[0].Weight;

                    Bones[buffer_id].vertex[vertex_id].bones[0].boneId = bone.index;
                    Bones[buffer_id].vertex[vertex_id].bones[0].Weight = strength;
                    Bones[buffer_id].vertex[vertex_id].numBones = 1;

                  

                } else

                    if (strength > Bones[buffer_id].vertex[vertex_id].bones[1].Weight)
                    {
                        Bones[buffer_id].vertex[vertex_id].bones[3].boneId = Bones[buffer_id].vertex[vertex_id].bones[2].boneId;
                        Bones[buffer_id].vertex[vertex_id].bones[3].Weight = Bones[buffer_id].vertex[vertex_id].bones[2].Weight;

                        Bones[buffer_id].vertex[vertex_id].bones[2].boneId = Bones[buffer_id].vertex[vertex_id].bones[1].boneId;
                        Bones[buffer_id].vertex[vertex_id].bones[2].Weight = Bones[buffer_id].vertex[vertex_id].bones[1].Weight;

                        Bones[buffer_id].vertex[vertex_id].bones[1].boneId = bone.index;
                        Bones[buffer_id].vertex[vertex_id].bones[1].Weight = strength;
                        Bones[buffer_id].vertex[vertex_id].numBones = 2;

                      

                  //  Debug.LogError("num bones 2");
                    } else
                        if (strength > Bones[buffer_id].vertex[vertex_id].bones[2].Weight)
                        {


                            Bones[buffer_id].vertex[vertex_id].bones[3].boneId = Bones[buffer_id].vertex[vertex_id].bones[2].boneId;
                            Bones[buffer_id].vertex[vertex_id].bones[3].Weight = Bones[buffer_id].vertex[vertex_id].bones[2].Weight;
                            Bones[buffer_id].vertex[vertex_id].bones[2].boneId = bone.index;
                            Bones[buffer_id].vertex[vertex_id].bones[2].Weight = strength;
                            Bones[buffer_id].vertex[vertex_id].numBones = 3;
                          //  Debug.LogError("num bones 3");


                        } else
                            if (strength > Bones[buffer_id].vertex[vertex_id].bones[3].Weight)
                            {
                                Bones[buffer_id].vertex[vertex_id].bones[3].boneId = bone.index;
                                Bones[buffer_id].vertex[vertex_id].bones[3].Weight = strength;
                                Bones[buffer_id].vertex[vertex_id].numBones = 4;
                               // Debug.LogError("num bones 4");

                            }

            }
           




        }

        //trace(buffer_id+ " ," +VerticesStart);
    }
    private static  void readKEYS( CoreJoint bone)
    {
   
        int Flags = file.ReadInt32();


        bool containsPosition=(Flags & 1) != 0;
        bool containsScale   =(Flags & 2) != 0;
        bool containsRotation=(Flags & 4) != 0;


        bone.containsPosition = containsPosition;
        bone.containsScale    = containsScale;
        bone.containsRotation = containsRotation;
       
        var fps = 1f /  framesPerSecond;

        while (getChunkSize()!=0) 
        {
            int frame = file.ReadInt32();

           

            if (containsPosition)//position
            {
                Vector3 position = ReadVector3();
                bone.addPositionCurve(position.x, position.y, position.z, frame*fps );

          
            }
            if (containsScale)//scale
            {
                Vector3 scale = ReadVector3();
                bone.addScaleCurve(scale.x, scale.y, scale.z, frame*fps );
        
            }
            if (containsRotation)//rotation
            {
                Quaternion rotation = ReadQuaternion();
                bone.addRotationCurve(rotation, frame*fps );

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


        }

    }
    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 ;) ");
        }

    }
        public CoreJoint()
        {
            
       
            Name = "";
            parent = null;
            Path = "";

          
          
            //joint = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            joint =new  GameObject("");

        
             posXcurve = new AnimationCurve();
             posYcurve = new AnimationCurve();
             posZcurve = new AnimationCurve();

             rotXcurve = new AnimationCurve();
             rotYcurve = new AnimationCurve();
             rotZcurve = new AnimationCurve();
             rotWcurve = new AnimationCurve();

        }