龙之谷-技术资料-第18讲MSH模型转换器

2019年12月18日08:01:21 发表评论 6
广告也精彩

龙之谷-技术资料-第18讲MSH模型转换器

前言

这个程序以及相关资信是自己兴趣写出来的,没有任何商业利益的,本程序仅用于学习研究之用,请勿用于商业用途,由此软件产生的商业纠纷软件作者一概不负责任.
发现上一篇的龙之谷修改专题日志不少人关注的说,QQ和MSN上也有问道开发情况的,看来修改龙之谷的模型还是多数CGer的共同愿望呢~于是乎有了这篇文章~嘛,我也知道等待的滋味不好受的,所以就贴一下每天的开发进度吧,稍后还会贴出相关信息~
最后,还请各位原谅本人不才,拖慢了开发进度了orz……
* 关于龙之谷的msh资源结构,大部分信息源于 liuliqiang 大大,特此感谢提供!

使用说明

<-Display English version of usage->

"Dragon Nest MSH Model Converter" is an application converting files between Dragon Nest model format (*.msh) and other general model formats.
You can choose a msh file,as well as its animation file(*.ani) that you can finish a msh-to-fbx conversion.

*.MSH to Other formats:

  1. Click on the upper "Browse" button to pick up the *.MSH file.
  2. Click on the lower "Browse" button to pick up the *.ANI file.(Optional).
  3. Click on "Convert" button, Specify output path, file name and output format.
  4. Click on "Save" to finish the conversion.

Other formats to *.MSH:

  1. Click on the upper "Browse" button to pick up a model file.
  2. Click on "Convert" button, Specify output path, file name and output format(*.MSH).
  3. Click on "Save" to finish the conversion.

"龙之谷MSH模型转换器"是一款用于龙之谷模型文件(*.msh)与其他通用模型文件相互转的便捷工具.
使用时只需指定msh文件位置,以及msh对应的动画文件(*.ani),即可输出通用模型格式到指定目录.

MSH格式->通用模型格式:

  1. 点击"浏览…"按钮指定MSH文件位置.
  2. 点击"浏览…"按钮指定MSH对应的ANI位置.
  3. 点击"转换"按钮,选择所需转换格式,指定输出目录及文件名称.
  4. 转换完成.

通用模型格式->MSH格式:

  1. 点击"浏览…"按钮,指定通用模型文件位置.
  2. 点击"转换"按钮,选择MSH格式,指定输出目录及文件名称.
  3. 转换完成.

 

文件结构

MSH文件结构示意
Header 文件头部,用于索引各种数据
BoneData 骨骼数据部分,大小由骨骼数量决定
MeshData 模型数据部分,大小由Mesh数量决定
OtherData 其他数据部分,大小由其他元素量决定

Header部分

Header结构示意
name: 文件头标识
name[256] version: 文件版本
meshCount: Mesh总数
version meshCount unknown unknown bbMax: BoundingBox最大值
bbMax bbMin: BoundingBox最小值
bbMin boneCount unknown boneCount: 骨骼总数
otherCount otherCount: 其他元素总数

 

1

2

3

4

5

6

7

8

9

10

11

12

struct Header{

char name[256]; //Eternity Engine Mesh File 0.1

int version;

int meshCount;

int unknown1; //0x1

int unknown2; //0x0

Vec3F bbMax;

Vec3F bbMin;

int boneCount;

int unknown2; //0x1或0x0

int otherCount;

};

BoneData部分

骨骼数据个数由Header索引,从文件头开始偏移0×400(1024)字节即为骨骼数据:

单个BoneData结构示意
boneName[256] boneName: 骨骼名称
m1 m1: 骨骼变换矩阵第一行数据
m2 m2: 骨骼变换矩阵第二行数据
m3 m3: 骨骼变换矩阵第三行数据
m4 m4: 骨骼变换矩阵第四行数据

 

1

2

3

4

struct BoneData{

char boneName[256]; //骨骼名称

Vec4F transformMatrix[4]; //骨骼变换矩阵

};

MeshData部分

MeshData部分由一个或多个Mesh数据组成,具体多少个Mesh由文件头部的meshCount决定.
每个Mesh数据由Mesh信息+Mesh数据组成,为了方便演示,示意图将把Mesh信息部分和Mesh数据部分合并一起表示,而具体实现代码将分成两个结构体:

单个MeshData结构示意
sceneRoot[256] sceneRoot: Mesh所属节点名称
meshName: Mesh名称
meshName[256] vertexCount: 顶点个数
indexCount: 顶点(三角面)索引数
vertexCount indexCount unknown renderMode renderMode: 渲染模式,取值0×100/0×101
empty[512-16] (GL_TRIANGLE_STRIP/GL_TRIANGLE)
vertexIndex vertexIndex: 顶点索引,indexCount个元素
vertexData vertexData: 顶点数据,vertexCount个元素
normalData normalData: 法线数据,vertexCount个元素
uvData uvData: UV贴图数据,vertexCount个元素
weightIndex weightIndex: 权重索引,vertexCoun个元素
weightData weightData: 权重数据,vertexCount个元素
boneCount boneCount: Mesh绑定骨骼个数
boneIndex boneIndex: 骨骼索引,boneCount个元素

 

1

2

3

4

5

6

7

8

9

struct MeshInfo{

char sceneName[256];

char meshName[256];

int vertexCount;

int indexCount;

int unknown;

int renderMode;

char empty[512 - 16];

};

1

2

3

4

5

6

7

8

9

10

struct MeshDataPointer{//数据指针

char* pFaceIndex; //0x2(unsigned short) * indexCount

char* pVertexData; //0x4(float) * 3 * vertexCount

char* pNormalData; //0x4(float) * 3 * vertexCount

char* pUVData; //0x4(float) * 2 * vertexCount

char* pBoneIndex; //0x2(unsigned short) * 4 vertexCount

char* pBoneWeight; //0x4(float) * 4 * vertexCount

int*  pBoneCount; //Mesh绑定的Bone数

char* pBoneName; //0x100(char [256]) * boneCount

};

现在说一下MeshData里面各个元素的组成,虽然说规范和DirectX差不多,不过当时对DirectX的3D编程完全没有了解的我,可被这个搞得一头冒水呢……
MSH文件在保存浮点型数据时均使用单精度型(float)浮点数保存数据.

VertexData元素
VertexData,即顶点数据,是顶点在三维空间的x,y,z坐标数据.每个元素使用Vec3F结构保存数据.

VertexIndex元素
VertexIndex,即顶点索引,是程序画面的顺序数据,索引的是顶点数据.每个元素使用unsign short类型保存数据.

NormalData元素
NormalData,即法线数据,是每个顶点的法向数据,以三维空间坐标x,y,z表示.每个元素使用Vec3F结构保存数据.

UVData元素
UVData,即UV贴图数据,是每个顶点在二维贴图空间映射的u,v坐标.每个元素使用Vec2F结构保存数据.

WeightIndex元素
WeightIndex,即权重索引,是每个顶点的权重索引,每个顶点最多可以索引4个骨骼.每个元素使用4个unsign short类型保存数据.

WeightData
WeightData,即权重数据,是每个顶点的权重数据,每个顶点最多可以拥有4个骨骼权重.每个元素使用Vec4F结构保存数据.

BoneIndex
BoneIndex,即骨骼索引,用以给骨骼编序,只保存骨骼名称.每个元素使用char [256]字符型数组保存数据.

OtherData部分

暂时猜测该部分数据可能用于武器的"刀锋"特效.

自定义结构

1

2

3

4

5

6

7

8

9

10

11

12

class Vec2F{

public:

float x;

float y;

Vec2F(){x = 0; y = 0;}

Vec2F(KFbxVector2 &vector){

x = vector.GetAt(0);

y = vector.GetAt(1);}

Vec2F(KFbxVector4 &vector){

x = vector.GetAt(0);

y = vector.GetAt(1);}

};

1

2

3

4

5

6

7

class Vec3F : public Vec2F{

public:

float z;

Vec3F() : Vec2F(){z = 0;}

Vec3F(KFbxVector4 &vector) : Vec2F(vector){

z = vector.GetAt(2);}

};

 

1

2

3

4

5

6

7

class Vec4F : public Vec3F{

public:

float w;

Vec4F() : Vec3F(){w = 0;}

Vec4F(KFbxVector4 &vector) : Vec3F(vector){

w = vector.GetAt(3);}

};

Change Log

11.18
A03:解决建立三角面时顺序错误的问题.
T02:顶点信息建立测试通过.
T03:三角面建立测试通过.
T04:顶点法线建立测试通过.
11.19
A06:完成了对贴图UV的读取.
T02/T04/T06:发现浮点数的精度取值问题.
11.20
A01/A05:完成对模型名称,贴图名称读取.
T01/T05:模型名称,贴图名称读取通过测试.
11.21
重新理解MSH格式结构.
重写了一下读取函数,优化读取速度,整理了程序结构.
A03:修复了奇偶面数读取错误问题.
T03:奇偶面数读取测试通过.
11.23
模块化功能函数.
A07:实现骨骼结点名称的读取.
T07:骨骼结点名称读取测试通过.
D08:读取骨骼变换矩阵遇到问题.
11.26
T03:发现在读取非闭合多边形出现三角面混乱问题.
D08:完成对骨骼数据的读取设计.
A08:考虑绑定骨骼绑定问题.
11.27
发现不同版本的MSH在建立多边形时采用GL_TRIANGLE_STRIP 或 GL_TRIANGLE 模式
T03:解决读取顶点索引错乱问题.
A11:写入MSH顶点索引可能要使用GL_TRIANGLE模式
11.28
A08:完成对骨骼与模型的绑定已经蒙皮权重的添加.
A08:遇到绑定骨骼后模型扭曲的问题.
11.29
MSH文件不足以提供完整骨骼信息,决定追加ANI文件辅佐.
12.05
A08:完成对骨骼父子节点的添加,修正世界坐标和本地坐标的转换问题.
D08:修正骨骼与模型绑定后扭曲问题.
T08:骨骼绑定测试通过.
O01:完成对多Mesh读取
12.09
D11:决定使用GL_TRIANGLE模式写入三角形索引.
A15:实现对骨骼名称及骨骼变换矩阵的写入.
T15:发现写入的变换矩阵与原数据有些差异.
12.10
D09/D10/D11/D12:实现对Mesh名称,三角面索引,顶点数据,法线信息的读取和写入.
D13/D14:实现对贴图坐标名称的读取和写入.
D16:实现对骨骼权重的读取和写入.
T15:仍未解决骨骼矩阵信息与原信息差异问题,但测试中未发现有什么问题.
T09/T10/T11/T12/T13/T14/T16:测试通过,但是无法保证BoundingBox信息正确.
"今天只有早上一节物理课,于是果断花了一整天把这个程序的大部分功能实现了.毕竟这周学校要忙的事特多,搞到周一到周四基本上不能碰程序了…果然有了读取的经验和知识,写入的编程设计进度一天就完成了…激动~~"
12.11
A03:优化了GL_TRIANGLE_STRIP读取多边形算法
T03:发现某系模型转换成FBX格式导入到Maya后再导出FBX会导致Maya崩溃的问题.
12.13
T15:解决骨骼世界变换矩阵数据的出现差异的问题,发现原来是编写时忽略了骨骼根节点.
12.14
发布1.0b,公测开始……
2010.12.17 – V1.0.1b
1.修复了UV贴图错误问题.
2.解决骨骼名称特殊字符过滤问题
2011.1.16 – V1.1
1.界面支持视觉风格
2.更详细错误提示信息
3.可选额外骨骼信息(ANI文件需求)
4.增加对新版FBX格式的兼容性
2011.3.31 – V1.2
1.修正界面刷新异常
2.UNICODE工程
3.支持非英文目录
2012.9.22 – V1.2
1.放出源代码,停止工程

广告也精彩
广告也精彩

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: