⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md2.cpp

📁 机器人运动学动力学及控制的一个小程序,供有兴趣的人参考
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    fread(buffer, sizeof(char), fileLen, filePtr);

	// extract model file header from buffer
    modelHeader = (modelHeader_t*)buffer;

	// allocate memory for model data
   	model = (modelData_t*)malloc(sizeof(modelData_t));
	if (model == NULL)
		return NULL;

	// allocate memory for all vertices used in model, including animations
    model->pointList = (vector_t*)malloc(sizeof(vector_t)*modelHeader->numXYZ * modelHeader->numFrames);

	// store vital model data
    model->numPoints = modelHeader->numXYZ;
    model->numFrames = modelHeader->numFrames;
	model->frameSize = modelHeader->framesize;

    // loop number of frames in model file
    for(j = 0; j < modelHeader->numFrames; j++)
    {
       // offset to the points in this frame
       frame = (frame_t*)&buffer[modelHeader->offsetFrames + modelHeader->framesize * j];

	   // calculate the point positions based on frame details
       pointListPtr = (vector_t*)&model->pointList[modelHeader->numXYZ * j];
       for(i = 0; i < modelHeader->numXYZ; i++)
       {
          pointListPtr[i].point[0] = frame->scale[0] * frame->fp[i].v[0] + frame->translate[0];
          pointListPtr[i].point[1] = frame->scale[1] * frame->fp[i].v[1] + frame->translate[1];
          pointListPtr[i].point[2] = frame->scale[2] * frame->fp[i].v[2] + frame->translate[2];
       }
    }
			 
	// load the model texture
	md2Texture = LoadTexture(textureName);
	if (md2Texture != NULL)
	{
		// setup texture for opengl and store it in model data structure
		SetupMD2Texture(md2Texture);
		model->modelTex = md2Texture;
	}
	else
		return NULL;

    // allocate memory for the model texture coordinates
    model->st = (texCoord_t*)malloc(sizeof(texCoord_t)*modelHeader->numST);

	// store number of texture coordinates
    model->numST = modelHeader->numST;

	// set texture pointer to texture coordinate offset
    stPtr = (stIndex_t*)&buffer[modelHeader->offsetST];

	// calculate and store the texture coordinates for the model
    for (i = 0; i < modelHeader->numST; i++)
    {
		model->st[i].s = (float)stPtr[i].s / (float)md2Texture->width;
        model->st[i].t = (float)stPtr[i].t / (float)md2Texture->height;
    }

	// allocate an index of triangles
	triIndex = (mesh_t*)malloc(sizeof(mesh_t) * modelHeader->numTris);

	// set total number of triangles
	model->numTriangles = modelHeader->numTris;
	model->triIndex = triIndex;
	
	// point to triangle indexes in buffer
	bufIndexPtr = (mesh_t*)&buffer[modelHeader->offsetTris];

	// create a mesh (triangle) list
	for (j = 0; j < model->numFrames; j++)		
	{
		// for all triangles in each frame
		for(i = 0; i < modelHeader->numTris; i++)
		{
		   triIndex[i].meshIndex[0] = bufIndexPtr[i].meshIndex[0];
		   triIndex[i].meshIndex[1] = bufIndexPtr[i].meshIndex[1];
		   triIndex[i].meshIndex[2] = bufIndexPtr[i].meshIndex[2];
		   triIndex[i].stIndex[0] = bufIndexPtr[i].stIndex[0];
		   triIndex[i].stIndex[1] = bufIndexPtr[i].stIndex[1];
		   triIndex[i].stIndex[2] = bufIndexPtr[i].stIndex[2];
		}
	}

	// close file and free memory
	fclose(filePtr);
    free(buffer);

	model->currentFrame = 0;
	model->nextFrame = 1;
	model->interpol = 0.0;

    return model;
}

// CalculateNormal()
// desc: given 3 points, calculates the normal to the points
void CalculateNormal( float *p1, float *p2, float *p3 )
{
   float a[3], b[3], result[3];
   float length;

   a[0] = p1[0] - p2[0];
   a[1] = p1[1] - p2[1];
   a[2] = p1[2] - p2[2];

   b[0] = p1[0] - p3[0];
   b[1] = p1[1] - p3[1];
   b[2] = p1[2] - p3[2];

   result[0] = a[1] * b[2] - b[1] * a[2];
   result[1] = b[0] * a[2] - a[0] * b[2];
   result[2] = a[0] * b[1] - b[0] * a[1];

   // calculate the length of the normal
   length = (float)sqrt(result[0]*result[0] + result[1]*result[1] + result[2]*result[2]);

   // normalize and specify the normal
   glNormal3f(result[0]/length, result[1]/length, result[2]/length);
}

// DisplayMD2()
// desc: displays the frameNum frame of an MD2 model
void DisplayMD2(modelData_t *model, int frameNum)
{
	vector_t *pointList;
	int i;

    // create a pointer to the frame we want to show
    pointList = &model->pointList[model->numPoints * frameNum];

	// set the texture
	glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);

	// display the textured model with proper lighting normals
    glBegin(GL_TRIANGLES);
		for(i = 0; i < model->numTriangles; i++)
        {
			CalculateNormal(pointList[model->triIndex[i].meshIndex[0]].point,
                             pointList[model->triIndex[i].meshIndex[2]].point,
                             pointList[model->triIndex[i].meshIndex[1]].point);
			glTexCoord2f(model->st[model->triIndex[i].stIndex[0]].s,
						 model->st[model->triIndex[i].stIndex[0]].t);
			glVertex3fv(pointList[model->triIndex[i].meshIndex[0]].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[2]].s ,
					     model->st[model->triIndex[i].stIndex[2]].t);
            glVertex3fv(pointList[model->triIndex[i].meshIndex[2]].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[1]].s,
					     model->st[model->triIndex[i].stIndex[1]].t);
            glVertex3fv(pointList[model->triIndex[i].meshIndex[1]].point);
        }
    glEnd();
}

// DisplayMD2Interpolate()
// desc: displays an animated MD2 model with keyframe interpolation
void DisplayMD2Interpolate(modelData_t *model)
{
	vector_t *pointList;			// current frame vertices
	vector_t *nextPointList;		// next frame vertices
	int i;							// index counter
	float x1, y1, z1;				// current frame point values
	float x2, y2, z2;				// next frame point values

	vector_t vertex[3];	

	if (model == NULL)
		return;

	if (model->interpol >= 1.0)
	{
		model->interpol = 0.0f;
		model->currentFrame++;
		if (model->currentFrame >= model->numFrames)
			model->currentFrame = 0;

		model->nextFrame = model->currentFrame + 1;

		if (model->nextFrame >= model->numFrames)
			model->nextFrame = 0;
	}

	pointList = &model->pointList[model->numPoints*model->currentFrame];
	nextPointList = &model->pointList[model->numPoints*model->nextFrame];
	
	glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);
	glBegin(GL_TRIANGLES);
		for (i = 0; i < model->numTriangles; i++)
		{
			// get first points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[0]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[0]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[0]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[0]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[0]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[0]].point[2];

			// xi + percentage * (xf - xi)
			// store first interpolated vertex of triangle
			vertex[0].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[0].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[0].point[2] = z1 + model->interpol * (z2 - z1);
		
			// get second points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[2]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[2]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[2]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[2]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[2]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[2]].point[2];

			// store second interpolated vertex of triangle
			vertex[2].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[2].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[2].point[2] = z1 + model->interpol * (z2 - z1);	
	
			// get third points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[1]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[1]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[1]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[1]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[1]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[1]].point[2];

			// store third interpolated vertex of triangle
			vertex[1].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[1].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[1].point[2] = z1 + model->interpol * (z2 - z1);

			// calculate the normal of the triangle
			CalculateNormal(vertex[0].point, vertex[2].point, vertex[1].point);

			// render properly textured triangle
			glTexCoord2f(model->st[model->triIndex[i].stIndex[0]].s,
						 model->st[model->triIndex[i].stIndex[0]].t);
			glVertex3fv(vertex[0].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[2]].s ,
					     model->st[model->triIndex[i].stIndex[2]].t);
			glVertex3fv(vertex[2].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[1]].s,
					     model->st[model->triIndex[i].stIndex[1]].t);
			glVertex3fv(vertex[1].point);
		}
	glEnd();

	model->interpol += 0.05f;	// increase percentage of interpolation between frames
}

// DisplayMD2Interpolate()
// desc: displays a frame of the model between startFrame and endFrame with an interpolation percent
void DisplayMD2Interpolate(modelData_t *model, int startFrame, int endFrame, float percent)
{
	vector_t *pointList;			// current frame vertices
	vector_t *nextPointList;			// next frame vertices
	int i;					// index counter
	float x1, y1, z1;				// current frame point values
	float x2, y2, z2;				// next frame point values

	vector_t vertex[3];	

	if (model == NULL)
		return;
	
	if ( (startFrame < 0) || (endFrame < 0) )
		return;

	if ( (startFrame >= model->numFrames) || (endFrame >= model->numFrames) )
		return;

	if (model->interpol >= 1.0)
	{
		model->interpol = 0.0f;
		model->currentFrame++;
		if (model->currentFrame >= endFrame)//model->numFrames)
			model->currentFrame = startFrame; //0;

		model->nextFrame = model->currentFrame + 1;

		if (model->nextFrame >= endFrame)
			model->nextFrame = startFrame;
	}

	pointList = &model->pointList[model->numPoints*model->currentFrame];
	nextPointList = &model->pointList[model->numPoints*model->nextFrame];
	
	glBindTexture(GL_TEXTURE_2D, model->modelTex->texID);
	glBegin(GL_TRIANGLES);
		for (i = 0; i < model->numTriangles; i++)
		{
			// get first points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[0]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[0]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[0]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[0]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[0]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[0]].point[2];

			// store first interpolated vertex of triangle
			vertex[0].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[0].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[0].point[2] = z1 + model->interpol * (z2 - z1);
		
			// get second points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[2]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[2]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[2]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[2]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[2]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[2]].point[2];

			// store second interpolated vertex of triangle
			vertex[2].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[2].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[2].point[2] = z1 + model->interpol * (z2 - z1);	
	
			// get third points of each frame
			x1 = pointList[model->triIndex[i].meshIndex[1]].point[0];
			y1 = pointList[model->triIndex[i].meshIndex[1]].point[1];
			z1 = pointList[model->triIndex[i].meshIndex[1]].point[2];
			x2 = nextPointList[model->triIndex[i].meshIndex[1]].point[0];
			y2 = nextPointList[model->triIndex[i].meshIndex[1]].point[1];
			z2 = nextPointList[model->triIndex[i].meshIndex[1]].point[2];

			// store third interpolated vertex of triangle
			vertex[1].point[0] = x1 + model->interpol * (x2 - x1);
			vertex[1].point[1] = y1 + model->interpol * (y2 - y1);
			vertex[1].point[2] = z1 + model->interpol * (z2 - z1);

			// calculate the normal of the triangle
			CalculateNormal(vertex[0].point, vertex[2].point, vertex[1].point);

			// render properly textured triangle
			glTexCoord2f(model->st[model->triIndex[i].stIndex[0]].s,
						 model->st[model->triIndex[i].stIndex[0]].t);
			glVertex3fv(vertex[0].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[2]].s ,
					     model->st[model->triIndex[i].stIndex[2]].t);
			glVertex3fv(vertex[2].point);

			glTexCoord2f(model->st[model->triIndex[i].stIndex[1]].s,
					     model->st[model->triIndex[i].stIndex[1]].t);
			glVertex3fv(vertex[1].point);
		}
	glEnd();

	model->interpol += percent;	// increase percentage of interpolation between frames
}

void CleanUp()
{
	FreeModel(gunModel2);
	FreeModel(myModel2);
	FreeModel(gunModel);
	FreeModel(myModel);
}
// Render
// desc: handles drawing of scene
void Render()
{
	float percent;

	radians =  float(PI*(angle-90.0f)/180.0f);

	// calculate the camera's position
	cameraX = lookX + (float)sin(radians)*mouseY;	// multiplying by mouseY makes the
	cameraZ = lookZ + (float)cos(radians)*mouseY;  // camera get closer/farther away with mouseY
	cameraY = lookY + mouseY / 2.0f;

	// calculate the camera look-at coordinates as the center
	lookX = 0.0f;
	lookY = 2.0f;
	lookZ = 0.0f;

	percent = 0.005;	// interpolation percent

	// clear screen and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		
	glLoadIdentity();

	// set the camera position
	gluLookAt(cameraX, cameraY, cameraZ, lookX, lookY, lookZ, 0.0, 1.0, 0.0);

	glPushMatrix();
		glRotatef(90.0f, -1.0f, 0.0f, 0.0f);
		DisplayMD2Interpolate(myModel, 0, 40, percent);
		DisplayMD2Interpolate(gunModel, 0, 40, percent);
		glColor3f(1.0, 1.0, 1.0);
	glPopMatrix();

	glFlush();
	SwapBuffers(g_HDC);			// bring backbuffer to foreground
}
// Initialize
// desc: initializes OpenGL
void Initialize()
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);		// clear to black

	glShadeModel(GL_SMOOTH);					// use smooth shading
	glEnable(GL_DEPTH_TEST);					// hidden surface removal
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
	glEnable(GL_LIGHTING);						// setup cheap-o lighting
	glEnable(GL_LIGHT0);
	glEnable(GL_COLOR_MATERIAL);

	glEnable(GL_TEXTURE_2D);

	// load model and model texture
	myModel = LoadMD2Model("models\\ogro\\tris.md2", "models\\ogro\\ogrobase.pcx");
	gunModel = LoadMD2Model("models\\ogro\\weapon.md2", "models\\ogro\\weapon.pcx");
	myModel2 = LoadMD2Model("models\\sodf8\\tris.md2", "models\\sodf8\\abarlith.pcx");
	gunModel2 = LoadMD2Model("models\\sodf8\\weapon.md2", "models\\sodf8\\weapon.pcx");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -