private void pushMatrix(MD3Object md3, string tag_id)
 {
     for (int i = 0; i < md3.tags.Count; ++i)
     {
         if (md3.tags[i].strName == tag_id)
         {
             //cache md3.tags[i].cache_matrix
             Matrix m = md3.getMatrixTag(i);
             push_matrix = m * push_matrix;
             break;
         }
     }
 }
        private void MD3DataToRenderData(MD3Object source)
        {
            int count = source.meshes.Count;
            for (int i = 0; i < count; ++i)
            {
                List<SRenderInfoMesh> v_list = null;
                if (source.part == TMD3Part.HEAD)
                    v_list = head_vertices;
                else if (source.part == TMD3Part.UPPER)
                    v_list = upper_vertices;
                else
                    v_list = lower_vertices;

                if (v_list != null)
                {
                    int vcount = v_list[i].vertex_info.Length;
                    for (int a = 0; a < vcount; ++a)
                    {
                        int id = source.meshes[i].indices[a];
                        v_list[i].vertex_info[a].Position = source.getPositionVertex(i, id);
                        v_list[i].vertex_info[a].Normal = source.getNormal(i, id);
                    }
                }
            }
        }
        private void loadMD3Data(ContentReader input, MD3Object m)
        {
            //load meshes
            m.meshes = new List<MD3SubMeshes>();
            int part = input.ReadInt32();
            if (part == 0)
                m.part = TMD3Part.HEAD;
            else if (part == 1)
                m.part = TMD3Part.LOWER;
            else
                m.part = TMD3Part.UPPER;

            m.num_frames = input.ReadInt32();
            int sub_meshes_count = input.ReadInt32();
            for (int i = 0; i < sub_meshes_count; ++i)
            {
                MD3SubMeshes sub_mesh = new MD3SubMeshes();
                sub_mesh.indices = new List<int>();
                sub_mesh.vertices = new List<Vector3>();
                sub_mesh.normals = new List<Vector3>();
                sub_mesh.text_coord = new List<Vector2>();
                sub_mesh.skins = new List<string>();
                sub_mesh.meshinfo.strName = input.ReadString();
                input.ReadObject<List<int>>(sub_mesh.indices);
                input.ReadObject<List<Vector3>>(sub_mesh.vertices);
                input.ReadObject<List<Vector3>>(sub_mesh.normals);
                input.ReadObject<List<Vector2>>(sub_mesh.text_coord);
                m.meshes.Add(sub_mesh);
            }

            //load tags
            m.tags = new List<MD3tag>();
            int tags_count = input.ReadInt32();
            for (int i = 0; i < tags_count; ++i)
            {
                MD3tag tag = new MD3tag();
                tag.strName = input.ReadString();
                tag.vPosition = input.ReadVector3();
                tag.rotation = input.ReadMatrix();
                m.tags.Add(tag);
            }
            //load bounding_boxes
            m.bounding_boxes = new List<BoundingBox>();
            int bb_count = input.ReadInt32();
            for (int i = 0; i < bb_count; ++i)
            {
                BoundingBox bb = new BoundingBox();
                bb.Min = input.ReadVector3();
                bb.Max = input.ReadVector3();
                m.bounding_boxes.Add(bb);
            }
        }
        private void initializeVertices(MD3Object m)
        {
            if (m.part == TMD3Part.HEAD)
                head_vertices = new List<SRenderInfoMesh>();
            else if (m.part == TMD3Part.UPPER)
                upper_vertices = new List<SRenderInfoMesh>();
            else
                lower_vertices = new List<SRenderInfoMesh>();

            int count = m.meshes.Count;
            for (int i = 0; i < count; ++i)
            {
                int vcount = m.meshes[i].indices.Count;
                SRenderInfoMesh render_info = new SRenderInfoMesh();
                render_info.texture_name = m.meshes[i].meshinfo.strName;
                render_info.vertex_info = new VertexPositionNormalTexture[vcount];
                for (int a = 0; a < vcount; ++a)
                {
                    int id = m.meshes[i].indices[a];
                    render_info.vertex_info[a].TextureCoordinate.X = m.meshes[i].text_coord[id].X;
                    render_info.vertex_info[a].TextureCoordinate.Y = m.meshes[i].text_coord[id].Y;
                }
                if (m.part == TMD3Part.HEAD)
                    head_vertices.Add(render_info);
                else if (m.part == TMD3Part.UPPER)
                    upper_vertices.Add(render_info);
                else
                    lower_vertices.Add(render_info);
            }
        }
 private Matrix getTagMatrix(MD3Object md3, string name)
 {
     Matrix m = Matrix.Identity;
     for (int i = 0; i < md3.tags.Count; ++i)
     {
         if (md3.tags[i].strName == name)
         {
             m = md3.getMatrixTag(i);
             break;
         }
     }
     return m;
 }
        public void load(ContentReader input)
        {
            int textures_count = input.ReadInt32();
            loadTextures(input, textures_count);
            int md3_count = input.ReadInt32();
            //read md3 data
            for (int i = 0; i < md3_count; ++i)
            {
                MD3Object o = new MD3Object(TMD3Part.HEAD);
                loadMD3Data(input, o);
                if (o.part == TMD3Part.HEAD)
                    head_md3.Add(o);
                else if (o.part == TMD3Part.UPPER)
                    upper_md3.Add(o);
                else
                    lower_md3.Add(o);
            }
            Debug.Assert(head_md3.Count >= 1, "PK3 invalid format, not found head md3 file!");
            Debug.Assert(upper_md3.Count >= 1, "PK3 invalid format, not found upper md3 file!");
            Debug.Assert(lower_md3.Count >= 1, "PK3 invalid format, not found lower md3 file!");

            int anim_count = input.ReadInt32();
            for (int i = 0; i < anim_count; ++i)
            {
                MD3animation anim = new MD3animation();
                anim.strName = input.ReadString();
                anim.startFrame = input.ReadInt32();
                anim.numFrames = input.ReadInt32();
                anim.loopingFrames = input.ReadInt32();
                anim.framesPerSecond = input.ReadInt32();
                animations.Add(anim.strName, anim);
            }
        }