Mesh(网格)是一个点(Point也可用Vertex表示)、法向量(Normal Vector),面(Face)的集合,它定义了一个3D物体的形状。
看一个例子:
(a)中的四面体有4个顶点,4个面的法向量(正规化的),4个面,其中面中保存的是该面的N个(该例中是3个)顶点和该顶点法向量(与该面法向量相同,所以faces[0]的3个点的法向量的索引都是0)的索引。所以一定要小心点、向量数组中它们各自的顺序。PS:points_index存在Face中的顺序一般为从物体外侧看的逆时针方向。
Mesh数据结构可以将该结构写入文件,供其它程序使用,以上图为例的Mesh文件为:
4 4 4
0 0 0
1 0 0
0 1 0
0 0 1
0.577 0.577 0.577
0 0 -1
-1 0 0
0 -1 0
3 1 2 3 0 0 0
3 0 2 1 1 1 1
3 0 3 2 2 2 2
3 1 3 0 3 3 3
其中第一行3个数,分别为点、正规法向量、面的数目,以上所表示的3D图形有4个顶点,4个面的法向量,4个面
2-5行为每个顶点的坐标
6-9行为每个正规法向量的i, j, k值
10-13行为每个面的信息,其中第一列为顶点个数3,2-4列为3个顶点的索引(按顺序,按顺序,按顺序),和每个顶点的法向量,这里顶点的法向量与面的法向量相同,故索引都为该面法向量的索引。
附上C++代码:
Mesh.h:
#pragma once
#include
#include "Normal.h"
#include "Face.h"
#include "Point3D.h"
using namespace std;
class Mesh {
public:
/* Mesh Data */
int numPoints;
int numNormals;
int numFaces;
vector normals;
vector points;
vector faces;
/* Functions */
Mesh() {};
void Draw();
private:
/* Functions */
void setupMesh() {};
};
Point3D.h:
#pragma once
class Point3D {
public:
float X;
float Y;
float Z;
Point3D(float x, float y, float z) {
X = x;
Y = y;
Z = z;
}
};
Normal.h:
#pragma once
#include "Point3D.h"
#include
class Normal {
public:
float nx;
float ny;
float nz;
Normal(float x, float y, float z) {
nx = x;
ny = y;
nz = z;
}
Normal(Point3D* p1, Point3D* p2, Point3D* p3) {
float tnx = (p1->X + p2->X + p3->X) / 3;
float tny = (p1->Y + p2->Y + p3->Y) / 3;
float tnz = (p1->Z + p2->Z + p3->Z) / 3;
float len = sqrt(tnx * tnx + tny * tny + tnz * tnz);
nx = tnx / len;
ny = tny / len;
nz = tnz / len;
}
};
VertexID.h:
#pragma once
class VertexID {
public:
//顶点索引
int vertIndex;
//顶点法向量索引
int norIndex;
VertexID(int vi, int ni) {
vertIndex = vi;
norIndex = ni;
}
VertexID(int vi) {
vertIndex = vi;
}
};
Face.h:
#pragma once
#include
#include "VertexID.h"
using namespace std;
class Face {
public:
int numPoints;
vector vert;
Face(int v1, int v2, int v3, int ni) {
vert.push_back(new VertexID(v1, ni));
vert.push_back(new VertexID(v2, ni));
vert.push_back(new VertexID(v3, ni));
numPoints = 3;
}
};