/*************************************************************/
/* MS3D.CPP */
/* */
/* Purpose: Implementation of CMs3d for Milkshape 3D MS3D */
/* files (http://www.swissquake.ch/chumbalum-soft) */
/* Evan Pipho (evan@codershq.com) */
/* */
/*************************************************************/
#include "../basecode/app.h"
#include "ms3d.h"
//-------------------------------------------------------------
//- Load
//- Loads an MS3D file into memory
//-------------------------------------------------------------
bool CMs3d::Load(const char * szFilename)
{
unsigned char * ucpBuffer = 0;
unsigned char * ucpPtr = 0;
//Open the file
FILE * f = fopen(szFilename, "rb");
if(!f)
{
APP->Log(COLOR_RED, "Could not open %s", szFilename);
return false;
}
//Get file size
fseek(f, 0, SEEK_END);
int iEnd = ftell(f);
fseek(f, 0, SEEK_SET);
int iStart = ftell(f);
unsigned int uiSize = iEnd - iStart;
//Allocate memory
ucpBuffer = new unsigned char[uiSize];
ucpPtr = ucpBuffer;
if(!ucpBuffer)
{
APP->Log(COLOR_RED, "Could not allocate memory");
return false;
}
//Read file into buffer
if(fread(ucpBuffer, 1, uiSize, f) != uiSize)
{
APP->Log(COLOR_RED, "Could not read %s", szFilename);
delete [] ucpBuffer;
return false;
}
//Check out the header, it should be 10 bytes, MS3D000000
if(memcmp(ucpPtr, "MS3D000000", 10) != 0)
{
APP->Log(COLOR_RED, "%s is not a valid Milkshape 3D file", szFilename);
delete [] ucpBuffer;
return false;
}
//Check the version (should be 3 or 4)
ucpPtr += 10;
if(*(int *)ucpPtr != 3 && *(int *)ucpPtr != 4)
{
APP->Log(COLOR_RED, "%s is the wrong version, should be 3 or 4", szFilename);
delete [] ucpBuffer;
return false;
}
ucpPtr += 4;
//Read the vertices
//Number of vertices
m_usNumVerts = *(unsigned short *)ucpPtr;
ucpPtr += 2;
//Allocate memory
m_pVertices = new SMs3dVertex[m_usNumVerts];
//Copy the vertices
memcpy(m_pVertices, ucpPtr, m_usNumVerts * sizeof(SMs3dVertex));
ucpPtr += m_usNumVerts * sizeof(SMs3dVertex);
//Read the triangles
m_usNumTriangles = *(unsigned short *)ucpPtr;
ucpPtr += 2;
//Alloc memory for triangles
m_pTriangles = new SMs3dTriangle[m_usNumTriangles];
//Copy triangles
memcpy(m_pTriangles, ucpPtr, m_usNumTriangles * sizeof(SMs3dTriangle));
ucpPtr += m_usNumTriangles * sizeof(SMs3dTriangle);
//Load mesh groups
m_usNumMeshes = *(unsigned short *)ucpPtr;
ucpPtr += 2;
//Alloc memory for the mesh data
m_pMeshes = new SMs3dMesh[m_usNumMeshes];
//Copy the mesh data
for(int x = 0; x < m_usNumMeshes; x++)
{
//Copy the first part of the data
memcpy(&m_pMeshes[x], ucpPtr, 35);
ucpPtr += 35;
//Allocate triangle index memory
m_pMeshes[x].m_uspIndices = new unsigned short[m_pMeshes[x].m_usNumTris];
//Copy triangle index data, plus the material index
memcpy(m_pMeshes[x].m_uspIndices, ucpPtr, m_pMeshes[x].m_usNumTris * 2);
ucpPtr += m_pMeshes[x].m_usNumTris * 2;
m_pMeshes[x].m_cMaterial = ucpPtr[0];
ucpPtr ++;
}
//Read material information
m_usNumMaterials = *(unsigned short *)ucpPtr;
ucpPtr += 2;
//Alloc memory
m_pMaterials = new SMs3dMaterial[m_usNumMaterials];
//Copy material information
for(x = 0; x < m_usNumMaterials; x++)
{
memcpy(&m_pMaterials[x], ucpPtr, 361);
ucpPtr += 361;
//Load the images
if(m_pMaterials[x].m_cTexture[0] != '\0')
{
m_pMaterials[x].m_Texture.Load(&m_pMaterials[x].m_cTexture[2]);
}
}
//Skip some data we do not need
ucpPtr += 4;
ucpPtr += 8;
//Read in joint and animation info
m_usNumJoints = *(unsigned short *)ucpPtr;
ucpPtr += 2;
//Allocate memory
m_pJoints = new SMs3dJoint[m_usNumJoints];
//Read in joint info
for(x = 0; x < m_usNumJoints; x++)
{
memcpy(&m_pJoints[x], ucpPtr, 93);
ucpPtr += 93;
//Allocate memory
m_pJoints[x].m_RotKeyFrames = new SMs3dKeyFrame[m_pJoints[x].m_usNumRotFrames];
m_pJoints[x].m_TransKeyFrames = new SMs3dKeyFrame[m_pJoints[x].m_usNumTransFrames];
//copy keyframe information
memcpy(m_pJoints[x].m_RotKeyFrames, ucpPtr, m_pJoints[x].m_usNumRotFrames * sizeof(SMs3dKeyFrame));
ucpPtr += m_pJoints[x].m_usNumRotFrames * sizeof(SMs3dKeyFrame);
memcpy(m_pJoints[x].m_TransKeyFrames, ucpPtr, m_pJoints[x].m_usNumTransFrames * sizeof(SMs3dKeyFrame));
ucpPtr += m_pJoints[x].m_usNumTransFrames * sizeof(SMs3dKeyFrame);
}
//Find the parent joint array indices
for(x = 0; x < m_usNumJoints; x++)
{
//If the bone has a parent
if(m_pJoints[x].m_cParent[0] != '\0')
{
//Compare names of theparent bone of x with the names of all bones
for(int y = 0; y < m_usNumJoints; y++)
{
//A match has been found
if(strcmp(m_pJoints[y].m_cName, m_pJoints[x].m_cParent) == 0)
{
m_pJoints[x].m_sParent = y;
}
}
}
//The bone has no parent
else
{
m_pJoints[x].m_sParent = -1;
}
}
//Setup joints
Setup();
//File loaded
delete [] ucpBuffer;
APP->Log(COLOR_GREEN, "MS3D File: %s Loaded", szFilename);
return true;
}
//-------------------------------------------------------------
//- Render
//- Renders the model in its position at time 0
//-------------------------------------------------------------
void CMs3d::Render()
{
//Note: This function really isn't needed, as it preforms the same basic function
// as the render function below. It is included to provide an implementation of the
// Render() function put forth in the CModel class.
Animate(1.0f, 0.0f, 0.0f, false);
}
//-------------------------------------------------------------
//- Render
//- Renders the model as it would be at time "fTime" (in seconds)
//-------------------------------------------------------------
void CMs3d::Render(float fTime)
{
Animate(1.0f, fTime, fTime, false);
}
//-------------------------------------------------------------
//- Animate
//- Animates the model from start time to end time (in seconds)
//- at specified speed and can loop
//-------------------------------------------------------------
void CMs3d::Animate(float fSpeed, float fStartTime, float fEndTime, bool bLoop)
{
static bool bFirstTime = true;
//First time animate has been called
if(bFirstTime)
{
Reset();
bFirstTime = false;
}
static float fLastTime = fStartTime;
float fTime = m_Timer.GetSeconds() * fSpeed;
fTime += fLastTime;
fLastTime = fTime;
//looping
if(fTime > fEndTime)
{
if(bLoop)
{
Reset();
fLastTime = fStartTime;
fTime = fStartTime;
}
else
fTime = fEndTime;
}
for(int x = 0; x < m_usNumJoints; x++)
{
//Transformation matrix
CMatrix4X4 matTmp;
//Current joint
SMs3dJoint * pJoint = &m_pJoints[x];
//Current frame
unsigned int uiFrame = 0;
//if there are no keyframes, don't do any transformations
if(pJoint->m_usNumRotFrames == 0 && pJoint->m_TransKeyFrames == 0)
{
pJoint->m_matFinal = pJoint->m_matAbs;
continue;
}
//Calculate the current frame
//Translation
while(uiFrame < pJoint->m_usNumTransFrames && pJoint->m_TransKeyFrames[uiFrame].m_fTime < fTime)
uiFrame++;
pJoint->m_usCurTransFrame = uiFrame;
float fTranslation[3];
float fDeltaT = 1;
float fInterp = 0;
//If its at the extremes
if(uiFrame == 0)
memcpy(fTranslation, pJoint->m_TransKeyFrames[0].m_fParam, sizeof(float[3]));
else if(uiFrame == pJoint->m_usNumTransFrames)
memcpy(fTranslation, pJoint->m_TransKeyFrames[uiFrame-1].m_fParam, sizeof(float[3]));
//If its in the middle of two frames
else
{
SMs3dKeyFrame * pkCur = &pJoint->m_TransKeyFrames[uiFrame];
SMs3dKeyFrame * pkPrev = &pJoint->m_
使用C++制作3D动画人物-100%提供源码
4星 · 超过85%的资源 需积分: 49 136 浏览量
2010-04-18
19:16:27
上传
评论 14
收藏 1.49MB RAR 举报
76587309834890
- 粉丝: 40
- 资源: 230
最新资源
- 流程图转PAD-N-S图和伪码(软件工程).doc
- C#winform excel导入导出
- 毕业论文上传111111111111
- raisin.zip
- 322个地级市-市场分割指数、市场一体化指数+居民消费价格指数(2004-2022年).txt
- 《基于Java实现自定义控件-天气温度折线图 》+源代码+设计资料
- 希尔伯特矩阵来综合演示数值矩阵与符号矩阵的基本操作
- 《基于51单片机和DS18B20的温度检测和报警系统,可设置报警温度上下限,输出温度采用数码管显示 》+源代码+设计资料
- ESP8266WIFI系统工作原理图.schdoc
- C语言《基于STM32的测量温度与压力的数据处理设计 》+源代码+设计资料
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页