   Linear Interpolation, Weird Results.
  HiI've been following a couple tutorials on how to load, display and animate MD2 models. After a while I got everything pretty much right except that there is something weird happening when I animate the model. I's like some of the vertices jump around or "oscillate" slightly. I got most of my inspiration(code) from http://www.pixeltangent.com/My loading routine:MD2_Model::MD2_Model(const char* filename) throw (std::runtime_error)   : _n_frames(0), _n_glCmds(0), _n_texCoords(0), _n_triangles(0),_n_vertices(0), _n_volume(0), _vertices(NULL), _tex_coords(NULL),_triangles(NULL), _glCmds(NULL), _volume(NULL){    SetAnimation(_next = STAND);    //_animation.old_time = 0.0f;    std::ifstream file;    file.open(filename, std::ios::binary | std::ios::in);    if (file.fail())    {   throw std::runtime_error("Could not open model file.");    }    md2_header header = {0};    file.read(reinterpret_cast<char *>(&header), sizeof(md2_header));    if (header.ident != MD2_IDENT || header.version != MD2_VERSION)    {   throw std::runtime_error("Not a valic MD2 file");    }    // Initialise member variables.    _n_frames = header.nFrames;    _n_vertices = header.nVertices;    _n_texCoords = header.nTst;    _n_triangles = header.nTris;    _n_glCmds = header.nOpenGLCmds;    _vertices = new normal_vertex[_n_vertices*_n_frames];    _tex_coords = new texCoord[_n_texCoords];    _triangles = new triangle[_n_triangles];    _glCmds = new int[_n_glCmds];    file.seekg(header.ofs_st, std::ios::beg);    file.read(reinterpret_cast<char *>(_tex_coords), sizeof(texCoord)*_n_texCoords);    file.seekg(header.ofs_tris, std::ios::beg);    file.read(reinterpret_cast<char *>(_triangles), sizeof(triangle)*_n_triangles);    file.seekg(header.ofs_glcmds, std::ios::beg);    file.read(reinterpret_cast<char *>(_glCmds), sizeof(int)*_n_glCmds);    file.seekg(header.ofs_frames, std::ios::beg);    // Vertex array initialisation.    for (int j = 0; j < _n_frames; j++)    {   frame frame;   file.read(reinterpret_cast<char *>(&frame), sizeof(frame));   compressed_vertex *vertex = new compressed_vertex[_n_vertices];   file.read(reinterpret_cast<char *>(vertex), sizeof(compressed_vertex)*_n_vertices);   for (int i = 0, offset = _n_vertices*j; i < _n_vertices; i++)   {  // Uncompress each vertex.  _vertices[offset + i].v[x] = (vertex.v[x]*frame.scale[x]) + frame.translate[x];  _vertices[offset + i].v[y] = (vertex.v[y]*frame.scale[y]) + frame.translate[y];  _vertices[offset + i].v[z] = (vertex.v[z]*frame.scale[z]) + frame.translate[z];  _vertices[offset + i].n[x] = anorms[vertex.normal_index][x];  _vertices[offset + i].n[y] = anorms[vertex.normal_index][y];  _vertices[offset + i].n[z] = anorms[vertex.normal_index][z];   }   delete vertex;    }    file.close();}The animating, interpolation and rendering routines:void MD2_Model::Render(float time){    if (IsFinishedAnimation() != false)    {   if (GetAnimation() != STAND)   {  SetAnimation(STAND, true);   }   else if (_next != STAND)   {  SetAnimation(_next, false);   }   _next = STAND;    }    if (time > 0.0f)    {   Animate(time);    }    RenderFrame();}void MD2_Model::Animate(float time){    // Calculate the current frame, next frame and interpolation percent.    _animation.current_time = time;   // Calculate current and next frames.    if ((_animation.current_time - _animation.old_time) > (1.0f/_animation.fps))    {   _animation.current_frame = _animation.next_frame++; // Assign value THEN increment by one. if (_animation.next_frame > _animation.end_frame)   {  _animation.next_frame = _animation.start_frame;  _finished_animation_sequence = true;   } _animation.old_time = _animation.current_time;    }   if (_animation.current_frame > (_n_frames - 1)) {_animation.current_frame = 0;}    if (_animation.next_frame > (_n_frames - 1)) {_animation.next_frame = 0;}   _animation.interpolation = _animation.fps * (_animation.current_time - _animation.old_time);}void MD2_Model::interpolate(normal_vertex* vertex_list){    // Offsets in the total vertex list.    int current_offset = _n_vertices * _animation.current_frame;    int next_offset = _n_vertices * _animation.next_frame;    //std::cout << _animation.current_frame << ", " << _animation.next_frame << std::endl;    //std::cout << _animation.interpolation << std::endl;    // Use linear interpolation between frames to avoid ugly animation.    for (int i = 0; i < _n_vertices; i++)    {   vertex_list.v[x] = (_vertices[current_offset + i].v[x] + _animation.interpolation*(_vertices[next_offset + i].v[x] - _vertices[current_offset + i].v[x]));   vertex_list.v[y] = (_vertices[current_offset + i].v[y] + _animation.interpolation*(_vertices[next_offset + i].v[y] - _vertices[current_offset + i].v[y]));   vertex_list.v[z] = (_vertices[current_offset + i].v[z] + _animation.interpolation*(_vertices[next_offset + i].v[z] - _vertices[current_offset + i].v[z]));   vertex_list.n[x] = (_vertices[current_offset + i].n[x] + _animation.interpolation*(_vertices[next_offset + i].n[x] - _vertices[current_offset + i].n[x]));   vertex_list.n[y] = (_vertices[current_offset + i].n[y] + _animation.interpolation*(_vertices[next_offset + i].n[y] - _vertices[current_offset + i].n[y]));   vertex_list.n[z] = (_vertices[current_offset + i].n[z] + _animation.interpolation*(_vertices[next_offset + i].n[z] - _vertices[current_offset + i].n[z]));    }}void MD2_Model::RenderFrame(){normal_vertex vertex_list[MAX_MD2_VERTS];interpolate(vertex_list);glBegin(GL_TRIANGLES);for (int i = 0; i < _n_triangles; ++i){   for (int j = 0; j < 3; ++j)   { glTexCoord2f(_tex_coords[_triangles.st[j]].s / 256.0f, _tex_coords[_triangles.st[j]].t / 256.0f); glNormal3f(vertex_list[_triangles.v[j]].n[x], vertex_list[_triangles.v[j]].n[y], vertex_list[_triangles.v[j]].n[z]); glVertex3f(vertex_list[_triangles.v[j]].v[x], vertex_list[_triangles.v[j]].v[y], vertex_list[_triangles.v[j]].v[z]);   }}glEnd();    /*    normal_vertex vertex_list[MAX_MD2_VERTS];    int* gl_commands = _glCmds;    int next = sizeof(gl_cmd)/sizeof(int);    interpolate(vertex_list);    while (int i = *(gl_commands++))    {   if (i < 0)   {  glBegin(GL_TRIANGLE_FAN);  i = -i;  //std::cout << "glBegin(GL_TRIANGLE_FAN)" << std::endl;   }   else   {  glBegin(GL_TRIANGLE_STRIP);  //std::cout << "glBegin(GL_TRIANGLE_STRIP)" << std::endl;   }   for (/* Nothing. *//*; i > 0; --i, gl_commands += next)   {  gl_cmd *p = (gl_cmd*) gl_commands;  glTexCoord2f(p->s, p->t); // TODO: Find out why it's 1.0f - t???  glNormal3f(vertex_list[p->index].n[x], vertex_list[p->index].n[y], vertex_list[p->index].n[z]);  glVertex3f(vertex_list[p->index].v[x], vertex_list[p->index].v[y], vertex_list[p->index].v[z]);  //std::cout << vertex_list[p->index].n[x] << ", ";  //std::cout << vertex_list[p->index].n[y] << ", ";  //std::cout << vertex_list[p->index].n[z] << std::endl;   }   glEnd();   //std::cout << "glEnd()" << std::endl;    }*/    /*glColor3f(1.0f, 1.0f, 1.0f);    glBegin(GL_TRIANGLES);    glVertex3f(0.0f, 1.0f, 0.0f);    glVertex3f(1.0f, 0.0f, 0.0f);    glVertex3f(-1.0f, 0.0f, 0.0f);    glEnd();    std::cout << "Rendered a frame." << std::endl;*/}I've run out of ideas on what would cause it. Any help would be great.Thanks   
  Disclaimer: I didn't even look at your code :)However, vertices are stored as integers for MD2 and without adjusting the animation to suit this, it can begin to "wobble" when animating. This might not be the issue you're experiencing but I quickly dropped MD2 due to this issue as it was just too much of a hassle for the artists :);  ThanksYes it's pretty much a wobble. The only reason I'm using the MD2 format is because it's supposedly easy to begin with. I'll move on to something else.Do you know how I could fix it by any chance?   ;  If you're interpolating the compressed integer vertices without converting to floating point then that might be it, at a guess.That said, MD2 is positively ancient now; these days things are done with skeletal animation and it might be worth focusing your efforts there rather than overcoming the pitfalls in MD2's aging specification.   ;  I'm uncompressing first then interpolating. I've followed another tutorial which does it a bit differently and this wobbling doesn't occur with the same model. It must be something I've done in the code.Thanks, I want to move on to something more modern (and that looks better). Any suggestions? I was thinking of MD5 or the Half Life 2 format.   ;  Do you get any warnings in your c++ compiler output. Specifically about floats and integers?(It's a good idea to ensure you have zero warnings)   ;  None that I can see. I'm using Mingw and Netbeans, I don't know if it's suppressing anything.[Edit] OK, I've changed it so that it shows all warnings, still no warnings about integers and floats.   