ms3d 文件格式

最近实验室接了一个项目,开发一个虚拟现实平台,用来展示海底场景,能够对海洋各种环境进行实时渲染,并对以鱼类为主的生物进行形态和行为仿真,设计并实现其基本动作.主要内容有用三维建模,雾化,粒子系统等模拟海底空间效果,对光,影,雾,浪,水流等进行实时渲染.

技术关键问题及解决途径:1)     虚拟海底场景实时生成:通过借助图形处理器(GPU),利用NVIDIA推出的Cg语言编程对海底场景相关的水体、光影效果进行实时渲染;2)     鱼类表面纹理的细节表现:通过使用动态纹理,光影计算以及OpenGL库的纹理映射方法等表现鱼类等的表面纹理细节,使其与所在的海底环境相配合;
平台中对鱼类的动作仿真是难点之一,打算采用ms3d文件,从模型中读取数据,进行渲染.

//                MilkShape 3D 1.8.2 File Format Specification
//
//
//                  This specifcation is written in C style.
//
//
// The data structures are defined in the order as they appear in the .ms3d file.
//
//
//
//
//



//
// max values
//
#define MAX_VERTICES    65534
#define MAX_TRIANGLES   65534
#define MAX_GROUPS      255
#define MAX_MATERIALS   128
#define MAX_JOINTS      128



//
// flags
//
#define SELECTED        1
#define HIDDEN          2
#define SELECTED2       4
#define DIRTY           8



//
// types
//
#ifndef byte
typedef unsigned char byte;
#endif // byte

#ifndef word
typedef unsigned short word;
#endif // word


// force one byte alignment
#include <pshpack1.h>

//
// First comes the header (sizeof(ms3d_header_t) == 14)
//
typedef struct
{
    char    id[10];                                     // always "MS3D000000"
    int     version;                                    // 4
} ms3d_header_t;

//
// Then comes the number of vertices
//
word nNumVertices; // 2 bytes

//
// Then come nNumVertices times ms3d_vertex_t structs (sizeof(ms3d_vertex_t) == 15)
//
typedef struct
{
    byte    flags;                                      // SELECTED | SELECTED2 | HIDDEN
    float   vertex[3];                                  //
    char    boneId;                                     // -1 = no bone
    byte    referenceCount;
} ms3d_vertex_t;

//
// Then comes the number of triangles
//
word nNumTriangles; // 2 bytes

//
// Then come nNumTriangles times ms3d_triangle_t structs (sizeof(ms3d_triangle_t) == 70)
//
typedef struct
{
    word    flags;                                      // SELECTED | SELECTED2 | HIDDEN
    word    vertexIndices[3];                           //
    float   vertexNormals[3][3];                        //
    float   s[3];                                       //
    float   t[3];                                       //
    byte    smoothingGroup;                             // 1 - 32
    byte    groupIndex;                                 //
} ms3d_triangle_t;

//
// Then comes the number of groups
//
word nNumGroups; // 2 bytes

//
// Then come nNumGroups times groups (the sizeof a group is dynamic, because of triangleIndices is numtriangles long)
//
typedef struct
{
    byte            flags;                              // SELECTED | HIDDEN
    char            name[32];                           //
    word            numtriangles;                       //
    word            triangleIndices[numtriangles];      // the groups group the triangles
    char            materialIndex;                      // -1 = no material
} ms3d_group_t;

//
// number of materials
//
word nNumMaterials; // 2 bytes

//
// Then come nNumMaterials times ms3d_material_t structs (sizeof(ms3d_material_t) == 361)
//
typedef struct
{
    char            name[32];                           //
    float           ambient[4];                         //
    float           diffuse[4];                         //
    float           specular[4];                        //
    float           emissive[4];                        //
    float           shininess;                          // 0.0f - 128.0f
    float           transparency;                       // 0.0f - 1.0f
    char            mode;                               // 0, 1, 2 is unused now
    char            texture[128];                        // texture.bmp
    char            alphamap[128];                       // alpha.bmp
} ms3d_material_t;

//
// save some keyframer data
//
float fAnimationFPS; // 4 bytes
float fCurrentTime; // 4 bytes
int iTotalFrames; // 4 bytes

//
// number of joints
//
word nNumJoints; // 2 bytes

//
// Then come nNumJoints joints (the size of joints are dynamic, because each joint has a differnt count of keys
//
typedef struct // 16 bytes
{
    float           time;                               // time in seconds
    float           rotation[3];                        // x, y, z angles
} ms3d_keyframe_rot_t;

typedef struct // 16 bytes
{
    float           time;                               // time in seconds
    float           position[3];                        // local position
} ms3d_keyframe_pos_t;

typedef struct
{
    byte            flags;                              // SELECTED | DIRTY
    char            name[32];                           //
    char            parentName[32];                     //
    float           rotation[3];                        // local reference matrix
    float           position[3];

    word            numKeyFramesRot;                    //
    word            numKeyFramesTrans;                  //

    ms3d_keyframe_rot_t keyFramesRot[numKeyFramesRot];      // local animation matrices
    ms3d_keyframe_pos_t keyFramesTrans[numKeyFramesTrans];  // local animation matrices
} ms3d_joint_t;

//
// Then comes the subVersion of the comments part, which is not available in older files
//
int subVersion; // subVersion is = 1, 4 bytes

// Then comes the numer of group comments
unsigned int nNumGroupComments; // 4 bytes

//
// Then come nNumGroupComments times group comments, which are dynamic, because the comment can be any length
//
typedef struct
{
 int index;  // index of group, material or joint
 int commentLength;  // length of comment (terminating '\0' is not saved), "MC" has comment length of 2 (not 3)
 char comment[commentLength];  // comment
} ms3d_comment_t;

// Then comes the number of material comments
int nNumMaterialComments; // 4 bytes

//
// Then come nNumMaterialComments times material comments, which are dynamic, because the comment can be any length
//

// Then comes the number of joint comments
int nNumJointComments; // 4 bytes

//
// Then come nNumJointComments times joint comments, which are dynamic, because the comment can be any length
//

// Then comes the number of model comments, which is always 0 or 1
int nHasModelComment; // 4 bytes

//
// Then come nHasModelComment times model comments, which are dynamic, because the comment can be any length
//


// Then comes the subversion of the vertex extra information like bone weights, extra etc.
int subVersion;  // subVersion is = 2, 4 bytes

// ms3d_vertex_ex_t for subVersion == 1
typedef struct
{
 char boneIds[3]; // index of joint or -1, if -1, then that weight is ignored, since subVersion 1
 byte weights[3]; // vertex weight ranging from 0 - 255, last weight is computed by 1.0 - sum(all weights), since subVersion 1
 // weight[0] is the weight for boneId in ms3d_vertex_t
 // weight[1] is the weight for boneIds[0]
 // weight[2] is the weight for boneIds[1]
 // 1.0f - weight[0] - weight[1] - weight[2] is the weight for boneIds[2]
} ms3d_vertex_ex_t;

// ms3d_vertex_ex_t for subVersion == 2
typedef struct
{
 char boneIds[3]; // index of joint or -1, if -1, then that weight is ignored, since subVersion 1
 byte weights[3];  // vertex weight ranging from 0 - 100, last weight is computed by 1.0 - sum(all weights), since subVersion 1
 // weight[0] is the weight for boneId in ms3d_vertex_t
 // weight[1] is the weight for boneIds[0]
 // weight[2] is the weight for boneIds[1]
 // 1.0f - weight[0] - weight[1] - weight[2] is the weight for boneIds[2]
 unsigned int extra; // vertex extra, which can be used as color or anything else, since subVersion 2
} ms3d_vertex_ex_t;

// Then comes nNumVertices times ms3d_vertex_ex_t structs (sizeof(ms3d_vertex_ex_t) == 10)

// Then comes the subversion of the joint extra information like color etc.
int subVersion;  // subVersion is = 2, 4 bytes

// ms3d_joint_ex_t for subVersion == 1
typedef struct
{
 float color[3]; // joint color, since subVersion == 1
} ms3d_joint_ex_t;

// Then comes nNumJoints times ms3d_joint_ex_t structs (sizeof(ms3d_joint_ex_t) == 12)

// Then comes the subversion of the model extra information
int subVersion;  // subVersion is = 1, 4 bytes

// ms3d_model_ex_t for subVersion == 1
typedef struct
{
 float jointSize; // joint size, since subVersion == 1
 int transparencyMode; // 0 = simple, 1 = depth buffered with alpha ref, 2 = depth sorted triangles, since subVersion == 1
 float alphaRef; // alpha reference value for transparencyMode = 1, since subVersion == 1
} ms3d_model_ex_t;

#include <poppack.h>


//
// Mesh Transformation:
// 
// 0. Build the transformation matrices from the rotation and position
// 1. Multiply the vertices by the inverse of local reference matrix (lmatrix0)
// 2. then translate the result by (lmatrix0 * keyFramesTrans)
// 3. then multiply the result by (lmatrix0 * keyFramesRot)
//
// For normals skip step 2.
//
//
//
// NOTE:  this file format may change in future versions!
//
//
// - Mete Ciragan
//

 

读取程序:

文件头:ms3dfile.H

#ifndef word
typedef unsigned short word;
#endif // word

typedef struct
{
    char    id[10];                                     // always "MS3D000000"
    int     version;                                    // 4
} ms3d_header_t;

typedef struct
{
    byte    flags;                                      // SELECTED | SELECTED2 | HIDDEN
    float   vertex[3];                                  //
    char    boneId;                                     // -1 = no bone
    byte    referenceCount;
} ms3d_vertex_t;

typedef struct
{
    word    flags;                                      // SELECTED | SELECTED2 | HIDDEN
    word    vertexIndices[3];                           //
    float   vertexNormals[3][3];                        //
    float   s[3];                                       //
    float   t[3];                                       //
    byte    smoothingGroup;                             // 1 - 32
    byte    groupIndex;                                 //
} ms3d_triangle_t;

typedef struct
{
 word edgeIndices[2];
} ms3d_edge_t;

typedef struct
{
    byte            flags;                              // SELECTED | HIDDEN
    char            name[32];                           //
    word            numtriangles;                       //
 word*   triangleIndices;     // the groups group the triangles
    char            materialIndex;                      // -1 = no material
} ms3d_group_t;

typedef struct
{
    char            name[32];                           //
    float           ambient[4];                         //
    float           diffuse[4];                         //
    float           specular[4];                        //
    float           emissive[4];                        //
    float           shininess;                          // 0.0f - 128.0f
    float           transparency;                       // 0.0f - 1.0f
    char            mode;                               // 0, 1, 2 is unused now
    char            texture[128];                        // texture.bmp
    char            alphamap[128];                       // alpha.bmp
} ms3d_material_t;

typedef struct
{
    float           time;                               // time in seconds
    float           rotation[3];                        // x, y, z angles
} ms3d_keyframe_rot_t;

typedef struct
{
    float           time;                               // time in seconds
    float           position[3];                        // local position
} ms3d_keyframe_pos_t;

typedef struct
{
    byte            flags;                              // SELECTED | DIRTY
    char            name[32];                           //
    char            parentName[32];                     //
    float           rotation[3];                        // local reference matrix
    float           position[3];

    word            numKeyFramesRot;                    //
    word            numKeyFramesTrans;                  //

 ms3d_keyframe_rot_t* keyFramesRot;      // local animation matrices
    ms3d_keyframe_pos_t* keyFramesTrans;  // local animation matrices
} ms3d_joint_t;

#include <poppack.h>

class CMS3DFileI;
class CMS3DFile
{
public:
 CMS3DFile();
 virtual ~CMS3DFile();

public:
 bool LoadFromFile(const char* lpszFileName);
 void Clear();

 int GetNumVertices();
 void GetVertexAt(int nIndex, ms3d_vertex_t **ppVertex);
 int GetNumTriangles();
 void GetTriangleAt(int nIndex, ms3d_triangle_t **ppTriangle);
 int GetNumEdges();
 void GetEdgeAt(int nIndex, ms3d_edge_t **ppEdge);
 int GetNumGroups();
 void GetGroupAt(int nIndex, ms3d_group_t **ppGroup);
 int GetNumMaterials();
 void GetMaterialAt(int nIndex, ms3d_material_t **ppMaterial);
 int GetNumJoints();
 void GetJointAt(int nIndex, ms3d_joint_t **ppJoint);
 int FindJointByName(const char* lpszName);

 float GetAnimationFPS();
 float _GetCurrentTime();
 int GetTotalFrames();

private:
 CMS3DFileI *_i;

private:
 CMS3DFile(const CMS3DFile& rhs);
 CMS3DFile& operator=(const CMS3DFile& rhs);
};

#endif // _MS3DFILE_H_ 

文件ms3dfile.CPP

#pragma warning(disable : 4786)
#include "MS3DFile.h"
#include <set>
#include <vector>

#define MAKEDWORD(a, b)      ((unsigned int)(((word)(a)) | ((word)((word)(b))) << 16))

class CMS3DFileI
{
public:
 std::vector<ms3d_vertex_t> arrVertices;
 std::vector<ms3d_triangle_t> arrTriangles;
 std::vector<ms3d_edge_t> arrEdges;
 std::vector<ms3d_group_t> arrGroups;
 std::vector<ms3d_material_t> arrMaterials;
 float fAnimationFPS;
 float fCurrentTime;
 int iTotalFrames;
 std::vector<ms3d_joint_t> arrJoints;

public:
 CMS3DFileI()
 : fAnimationFPS(24.0f),
  fCurrentTime(0.0f),
  iTotalFrames(0)
 {
 }
};

CMS3DFile::CMS3DFile()
{
 _i = new CMS3DFileI();
}

CMS3DFile::~CMS3DFile()
{
 delete _i;
}

bool CMS3DFile::LoadFromFile(const char* lpszFileName)
{
 FILE *fp = fopen(lpszFileName, "rb");
 if (!fp)
  return false;

 size_t i;
 ms3d_header_t header;
 fread(&header, 1, sizeof(ms3d_header_t), fp);

 if (strncmp(header.id, "MS3D000000", 10) != 0)
  return false;

 if (header.version != 4)
  return false;

 // vertices
 word nNumVertices;
 fread(&nNumVertices, 1, sizeof(word), fp);
 _i->arrVertices.resize(nNumVertices);
 fread(&_i->arrVertices[0], nNumVertices, sizeof(ms3d_vertex_t), fp);

 // triangles
 word nNumTriangles;
 fread(&nNumTriangles, 1, sizeof(word), fp);
 _i->arrTriangles.resize(nNumTriangles);
 fread(&_i->arrTriangles[0], nNumTriangles, sizeof(ms3d_triangle_t), fp);

 // edges
 std::set<unsigned int> setEdgePair;
 for (i = 0; i < _i->arrTriangles.size(); i++)
 {
  word a, b;
  a = _i->arrTriangles[i].vertexIndices[0];
  b = _i->arrTriangles[i].vertexIndices[1];
  if (a > b)
   std::swap(a, b);
  if (setEdgePair.find(MAKEDWORD(a, b)) == setEdgePair.end())
   setEdgePair.insert(MAKEDWORD(a, b));

  a = _i->arrTriangles[i].vertexIndices[1];
  b = _i->arrTriangles[i].vertexIndices[2];
  if (a > b)
   std::swap(a, b);
  if (setEdgePair.find(MAKEDWORD(a, b)) == setEdgePair.end())
   setEdgePair.insert(MAKEDWORD(a, b));

  a = _i->arrTriangles[i].vertexIndices[2];
  b = _i->arrTriangles[i].vertexIndices[0];
  if (a > b)
   std::swap(a, b);
  if (setEdgePair.find(MAKEDWORD(a, b)) == setEdgePair.end())
   setEdgePair.insert(MAKEDWORD(a, b));
 }

 for(std::set<unsigned int>::iterator it = setEdgePair.begin(); it != setEdgePair.end(); ++it)
 {
  unsigned int EdgePair = *it;
  ms3d_edge_t Edge;
  Edge.edgeIndices[0] = (word) EdgePair;
  Edge.edgeIndices[1] = (word) ((EdgePair >> 16) & 0xFFFF);
  _i->arrEdges.push_back(Edge);
 }

 // groups
 word nNumGroups;
 fread(&nNumGroups, 1, sizeof(word), fp);
 _i->arrGroups.resize(nNumGroups);
 for (i = 0; i < nNumGroups; i++)
 {
  fread(&_i->arrGroups[i].flags, 1, sizeof(byte), fp);
  fread(&_i->arrGroups[i].name, 32, sizeof(char), fp);
  fread(&_i->arrGroups[i].numtriangles, 1, sizeof(word), fp);
  _i->arrGroups[i].triangleIndices = new word[_i->arrGroups[i].numtriangles];
  fread(_i->arrGroups[i].triangleIndices, _i->arrGroups[i].numtriangles, sizeof(word), fp);
  fread(&_i->arrGroups[i].materialIndex, 1, sizeof(char), fp);
 }

 // materials
 word nNumMaterials;
 fread(&nNumMaterials, 1, sizeof(word), fp);
 _i->arrMaterials.resize(nNumMaterials);
 fread(&_i->arrMaterials[0], nNumMaterials, sizeof(ms3d_material_t), fp);

 fread(&_i->fAnimationFPS, 1, sizeof(float), fp);
 fread(&_i->fCurrentTime, 1, sizeof(float), fp);
 fread(&_i->iTotalFrames, 1, sizeof(int), fp);

 // joints
 word nNumJoints;
 fread(&nNumJoints, 1, sizeof(word), fp);
 _i->arrJoints.resize(nNumJoints);
 for (i = 0; i < nNumJoints; i++)
 {
  fread(&_i->arrJoints[i].flags, 1, sizeof(byte), fp);
  fread(&_i->arrJoints[i].name, 32, sizeof(char), fp);
  fread(&_i->arrJoints[i].parentName, 32, sizeof(char), fp);
  fread(&_i->arrJoints[i].rotation, 3, sizeof(float), fp);
  fread(&_i->arrJoints[i].position, 3, sizeof(float), fp);
  fread(&_i->arrJoints[i].numKeyFramesRot, 1, sizeof(word), fp);
  fread(&_i->arrJoints[i].numKeyFramesTrans, 1, sizeof(word), fp);
  _i->arrJoints[i].keyFramesRot = new ms3d_keyframe_rot_t[_i->arrJoints[i].numKeyFramesRot];
  _i->arrJoints[i].keyFramesTrans = new ms3d_keyframe_pos_t[_i->arrJoints[i].numKeyFramesTrans];
  fread(_i->arrJoints[i].keyFramesRot, _i->arrJoints[i].numKeyFramesRot, sizeof(ms3d_keyframe_rot_t), fp);
  fread(_i->arrJoints[i].keyFramesTrans, _i->arrJoints[i].numKeyFramesTrans, sizeof(ms3d_keyframe_pos_t), fp);
 }

 fclose(fp);

 return true;
}

void CMS3DFile::Clear()
{
 _i->arrVertices.clear();
 _i->arrTriangles.clear();
 _i->arrEdges.clear();
 _i->arrGroups.clear();
 _i->arrMaterials.clear();
 _i->arrJoints.clear();
}

int CMS3DFile::GetNumVertices()
{
 return (int) _i->arrVertices.size();
}

void CMS3DFile::GetVertexAt(int nIndex, ms3d_vertex_t **ppVertex)
{
 if (nIndex >= 0 && nIndex < (int) _i->arrVertices.size())
  *ppVertex = &_i->arrVertices[nIndex];
}

int CMS3DFile::GetNumTriangles()
{
 return (int) _i->arrTriangles.size();
}

void CMS3DFile::GetTriangleAt(int nIndex, ms3d_triangle_t **ppTriangle)
{
 if (nIndex >= 0 && nIndex < (int) _i->arrTriangles.size())
  *ppTriangle = &_i->arrTriangles[nIndex];
}

int CMS3DFile::GetNumEdges()
{
 return (int) _i->arrEdges.size();
}

void CMS3DFile::GetEdgeAt(int nIndex, ms3d_edge_t **ppEdge)
{
 if (nIndex >= 0 && nIndex < (int) _i->arrEdges.size())
  *ppEdge = &_i->arrEdges[nIndex];
}

int CMS3DFile::GetNumGroups()
{
 return (int) _i->arrGroups.size();
}

void CMS3DFile::GetGroupAt(int nIndex, ms3d_group_t **ppGroup)
{
 if (nIndex >= 0 && nIndex < (int) _i->arrGroups.size())
  *ppGroup = &_i->arrGroups[nIndex];
}

int CMS3DFile::GetNumMaterials()
{
 return (int) _i->arrMaterials.size();
}

void CMS3DFile::GetMaterialAt(int nIndex, ms3d_material_t **ppMaterial)
{
 if (nIndex >= 0 && nIndex < (int) _i->arrMaterials.size())
  *ppMaterial = &_i->arrMaterials[nIndex];
}

int CMS3DFile::GetNumJoints()
{
 return (int) _i->arrJoints.size();
}

void CMS3DFile::GetJointAt(int nIndex, ms3d_joint_t **ppJoint)
{
 if (nIndex >= 0 && nIndex < (int) _i->arrJoints.size())
  *ppJoint = &_i->arrJoints[nIndex];
}

int CMS3DFile::FindJointByName(const char* lpszName)
{
 for (size_t i = 0; i < _i->arrJoints.size(); i++)
 {
  if (!strcmp(_i->arrJoints[i].name, lpszName))
   return i;
 }

 return -1;
}

float CMS3DFile::GetAnimationFPS()
{
 return _i->fAnimationFPS;
}

float CMS3DFile::_GetCurrentTime()
{
 return _i->fCurrentTime;
}

int CMS3DFile::GetTotalFrames()
{
 return _i->iTotalFrames;
}

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/whoismickey/archive/2009/01/13/3767899.aspx

http://blog.csdn.net/guokeno1/archive/2006/10/11/1330764.aspx

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值