- 传入顶点,计算顶点索引
/*
*输入:vertexArray三角面片的顶点数组
*返回:顶点索引数组
*/
osg::DrawElementsUInt* CalcVertexIndexs(const osg::Vec3Array* vertexArray)
{
//顶点去重
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();//去重后的顶点
{
int nums = vertexArray->size();
for (unsigned int i = 0; i < nums; i++)
{
osg::Vec3d vt = vertexArray->at(i);
bool bFind = false;//是否存在
osg::Vec3Array::iterator iter = vertices->begin();
for (; iter != vertices->end(); ++iter)
{
osg::Vec3d _vt = *iter;
if (_vt == vt)
{
bFind = true;
break;
}
}
if (!bFind)
{
vertices->push_back(vt);
}
}
}
int nums = vertices->size();
//获取索引
//osg::ref_ptr<osg::DrawElementsUInt> arrayIndexs = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP);
osg::ref_ptr<osg::DrawElementsUInt> arrayIndexs = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
{
int nums = vertexArray->size();
for (unsigned int i = 0; i < nums; i += 3)
{
bool bFind0 = false;
bool bFind1 = false;
bool bFind2 = false;
int index0 = 0;
int index1 = 0;
int index2 = 0;
osg::Vec3d vt0 = vertexArray->at(i);
osg::Vec3d vt1 = vertexArray->at(i + 1);
osg::Vec3d vt2 = vertexArray->at(i + 2);
//从去重后的顶点中获取索引
osg::Vec3Array::iterator iter = vertices->begin();
for (int index = 0; iter != vertices->end(); ++iter, ++index)
{
osg::Vec3d _vt = *iter;
if (_vt == vt0)
{
bFind0 = true;
index0 = index;//第1个顶点索引
}
else if (_vt == vt1) {
bFind1 = true;
index1 = index;//第2个顶点索引
}
else if (_vt == vt2) {
bFind2 = true;
index2 = index;//第3个顶点索引
}
if (bFind0 && bFind1 && bFind2)
{
arrayIndexs->push_back(index0);
arrayIndexs->push_back(index1);
arrayIndexs->push_back(index2);
break;
}
}
}
}
return arrayIndexs.release();
}
- 传入顶点和顶点索引,计算顶点法线
struct VertexAttribute
{
int index; //顶点索引
int shareNums;//顶点共享次数
osg::Vec3d normal;
VertexAttribute()
{
index = -1;
shareNums = 0;
normal.set(0.0, 0.0, 0.0);
}
};
/*
*输入1:vertexArray顶点数组(去重后的)
*输入2:indexArray顶点索引数组
*返回 :顶点法线数组
*/
osg::Vec3Array* CalcNormals(const osg::Vec3Array* vertexArray, const osg::DrawElementsUInt* indexArray)
{
osg::ref_ptr<osg::Vec3Array>normalArray = new osg::Vec3Array;
std::map<int, VertexAttribute> vertexAttribMap;
int indexNums = indexArray->size();
for (unsigned int i = 0; i < indexNums; i += 3)
{
int index0 = indexArray->at(i);
int index1 = indexArray->at(i + 1);
int index2 = indexArray->at(i + 2);
osg::Vec3d vertex0 = vertexArray->at(index0);//顶点0
osg::Vec3d vertex1 = vertexArray->at(index1);//顶点1
osg::Vec3d vertex2 = vertexArray->at(index2);//顶点2
osg::Vec3d vector01(vertex1 - vertex0);
osg::Vec3d vector02(vertex2 - vertex0);
osg::Vec3d normal012 = vector01 ^ vector02;
normal012.normalize();
std::map<int, VertexAttribute>::iterator iter = vertexAttribMap.find(index0);
if (iter == vertexAttribMap.end())
{
VertexAttribute vertexAttrib;
vertexAttrib.index = index0;
vertexAttrib.shareNums = 1;
vertexAttrib.normal = normal012;
vertexAttribMap[index0] = vertexAttrib;
}
else {
VertexAttribute _vertexAttrib = iter->second;
_vertexAttrib.shareNums += 1;
_vertexAttrib.normal = (_vertexAttrib.normal + normal012) / _vertexAttrib.shareNums;
}
iter = vertexAttribMap.find(index1);
if (iter == vertexAttribMap.end())
{
VertexAttribute vertexAttrib;
vertexAttrib.index = index1;
vertexAttrib.shareNums = 1;
vertexAttrib.normal = normal012;
vertexAttribMap[index1] = vertexAttrib;
}
else {
VertexAttribute _vertexAttrib = iter->second;
_vertexAttrib.shareNums += 1;
_vertexAttrib.normal = (_vertexAttrib.normal + normal012) / _vertexAttrib.shareNums;
}
iter = vertexAttribMap.find(index2);
if (iter == vertexAttribMap.end())
{
VertexAttribute vertexAttrib;
vertexAttrib.index = index2;
vertexAttrib.shareNums = 1;
vertexAttrib.normal = normal012;
vertexAttribMap[index2] = vertexAttrib;
}
else {
VertexAttribute _vertexAttrib = iter->second;
_vertexAttrib.shareNums += 1;
_vertexAttrib.normal = (_vertexAttrib.normal + normal012) / _vertexAttrib.shareNums;
}
}
int vertexNums = vertexArray->size();
for (unsigned int i = 0; i < vertexNums; i ++)
{
int index = i;
std::map<int, VertexAttribute>::iterator iter = vertexAttribMap.find(index);
if (iter != vertexAttribMap.end())
{
normalArray->push_back(iter->second.normal);
}
}
return normalArray.release();
}
OFF文件
OFF
8 12 0
0.5 -0.5 -0.5
0.5 0.5 -0.5
-0.5 0.5 -0.5
-0.5 -0.5 -0.5
0.5 -0.5 0.5
0.5 0.5 0.5
-0.5 0.5 0.5
-0.5 -0.5 0.5
3 0 1 3
3 1 2 3
3 4 6 5
3 7 6 4
3 0 3 4
3 4 3 7
3 1 5 2
3 2 5 6
3 0 4 1
3 1 4 5
3 2 6 3
3 3 6 7