Make all mesh manipulators in mesh.cpp work with any vertex type

cloneMesh() has to use a switch in order to create a different
mesh buffer type depending on vertex type. (Credit: the new cloneMesh
was written by RealBadAngel.)

To avoid repetitive code, all other methods use getVertexPitchFromType()
to automatically adapt the indexing to the vertex type at runtime.
master
Kahrl 2016-01-15 02:16:21 +01:00
parent 3c6b2ffb10
commit da686160c3
1 changed files with 145 additions and 124 deletions

View File

@ -206,146 +206,139 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh,
const video::SColor &colorY, const video::SColor &colorY,
const video::SColor &colorZ) const video::SColor &colorZ)
{ {
if(mesh == NULL) if (mesh == NULL)
return; return;
u16 mc = mesh->getMeshBufferCount(); u16 mc = mesh->getMeshBufferCount();
for(u16 j=0; j<mc; j++) for (u16 j = 0; j < mc; j++) {
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); const u32 stride = getVertexPitchFromType(buf->getVertexType());
u16 vc = buf->getVertexCount(); u32 vertex_count = buf->getVertexCount();
for(u16 i=0; i<vc; i++) u8 *vertices = (u8 *)buf->getVertices();
{ for (u32 i = 0; i < vertex_count; i++) {
f32 x = fabs(vertices[i].Normal.X); video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride);
f32 y = fabs(vertices[i].Normal.Y); f32 x = fabs(vertex->Normal.X);
f32 z = fabs(vertices[i].Normal.Z); f32 y = fabs(vertex->Normal.Y);
if(x >= y && x >= z) f32 z = fabs(vertex->Normal.Z);
vertices[i].Color = colorX; if (x >= y && x >= z)
else if(y >= z) vertex->Color = colorX;
vertices[i].Color = colorY; else if (y >= z)
vertex->Color = colorY;
else else
vertices[i].Color = colorZ; vertex->Color = colorZ;
} }
} }
} }
void rotateMeshXYby (scene::IMesh *mesh, f64 degrees) void rotateMeshXYby(scene::IMesh *mesh, f64 degrees)
{ {
u16 mc = mesh->getMeshBufferCount(); u16 mc = mesh->getMeshBufferCount();
for(u16 j = 0; j < mc; j++) for (u16 j = 0; j < mc; j++) {
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); const u32 stride = getVertexPitchFromType(buf->getVertexType());
u16 vc = buf->getVertexCount(); u32 vertex_count = buf->getVertexCount();
for(u16 i = 0; i < vc; i++) u8 *vertices = (u8 *)buf->getVertices();
{ for (u32 i = 0; i < vertex_count; i++)
vertices[i].Pos.rotateXYBy(degrees); ((video::S3DVertex *)(vertices + i * stride))->Pos.rotateXYBy(degrees);
}
} }
} }
void rotateMeshXZby (scene::IMesh *mesh, f64 degrees) void rotateMeshXZby(scene::IMesh *mesh, f64 degrees)
{ {
u16 mc = mesh->getMeshBufferCount(); u16 mc = mesh->getMeshBufferCount();
for(u16 j = 0; j < mc; j++) for (u16 j = 0; j < mc; j++) {
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); const u32 stride = getVertexPitchFromType(buf->getVertexType());
u16 vc = buf->getVertexCount(); u32 vertex_count = buf->getVertexCount();
for(u16 i = 0; i < vc; i++) u8 *vertices = (u8 *)buf->getVertices();
{ for (u32 i = 0; i < vertex_count; i++)
vertices[i].Pos.rotateXZBy(degrees); ((video::S3DVertex *)(vertices + i * stride))->Pos.rotateXZBy(degrees);
}
} }
} }
void rotateMeshYZby (scene::IMesh *mesh, f64 degrees) void rotateMeshYZby(scene::IMesh *mesh, f64 degrees)
{ {
u16 mc = mesh->getMeshBufferCount(); u16 mc = mesh->getMeshBufferCount();
for(u16 j = 0; j < mc; j++) for (u16 j = 0; j < mc; j++) {
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); const u32 stride = getVertexPitchFromType(buf->getVertexType());
u16 vc = buf->getVertexCount(); u32 vertex_count = buf->getVertexCount();
for(u16 i = 0; i < vc; i++) u8 *vertices = (u8 *)buf->getVertices();
{ for (u32 i = 0; i < vertex_count; i++)
vertices[i].Pos.rotateYZBy(degrees); ((video::S3DVertex *)(vertices + i * stride))->Pos.rotateYZBy(degrees);
}
} }
} }
void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir) void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir)
{ {
int axisdir = facedir>>2; int axisdir = facedir >> 2;
facedir &= 0x03; facedir &= 0x03;
u16 mc = mesh->getMeshBufferCount(); u16 mc = mesh->getMeshBufferCount();
for(u16 j = 0; j < mc; j++) for (u16 j = 0; j < mc; j++) {
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); const u32 stride = getVertexPitchFromType(buf->getVertexType());
u16 vc = buf->getVertexCount(); u32 vertex_count = buf->getVertexCount();
for(u16 i=0; i<vc; i++) u8 *vertices = (u8 *)buf->getVertices();
{ for (u32 i = 0; i < vertex_count; i++) {
switch (axisdir) video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride);
{ switch (axisdir) {
case 0: case 0:
if(facedir == 1) if (facedir == 1)
vertices[i].Pos.rotateXZBy(-90); vertex->Pos.rotateXZBy(-90);
else if(facedir == 2) else if (facedir == 2)
vertices[i].Pos.rotateXZBy(180); vertex->Pos.rotateXZBy(180);
else if(facedir == 3) else if (facedir == 3)
vertices[i].Pos.rotateXZBy(90); vertex->Pos.rotateXZBy(90);
break; break;
case 1: // z+ case 1: // z+
vertices[i].Pos.rotateYZBy(90); vertex->Pos.rotateYZBy(90);
if(facedir == 1) if (facedir == 1)
vertices[i].Pos.rotateXYBy(90); vertex->Pos.rotateXYBy(90);
else if(facedir == 2) else if (facedir == 2)
vertices[i].Pos.rotateXYBy(180); vertex->Pos.rotateXYBy(180);
else if(facedir == 3) else if (facedir == 3)
vertices[i].Pos.rotateXYBy(-90); vertex->Pos.rotateXYBy(-90);
break; break;
case 2: //z- case 2: //z-
vertices[i].Pos.rotateYZBy(-90); vertex->Pos.rotateYZBy(-90);
if(facedir == 1) if (facedir == 1)
vertices[i].Pos.rotateXYBy(-90); vertex->Pos.rotateXYBy(-90);
else if(facedir == 2) else if (facedir == 2)
vertices[i].Pos.rotateXYBy(180); vertex->Pos.rotateXYBy(180);
else if(facedir == 3) else if (facedir == 3)
vertices[i].Pos.rotateXYBy(90); vertex->Pos.rotateXYBy(90);
break; break;
case 3: //x+ case 3: //x+
vertices[i].Pos.rotateXYBy(-90); vertex->Pos.rotateXYBy(-90);
if(facedir == 1) if (facedir == 1)
vertices[i].Pos.rotateYZBy(90); vertex->Pos.rotateYZBy(90);
else if(facedir == 2) else if (facedir == 2)
vertices[i].Pos.rotateYZBy(180); vertex->Pos.rotateYZBy(180);
else if(facedir == 3) else if (facedir == 3)
vertices[i].Pos.rotateYZBy(-90); vertex->Pos.rotateYZBy(-90);
break; break;
case 4: //x- case 4: //x-
vertices[i].Pos.rotateXYBy(90); vertex->Pos.rotateXYBy(90);
if(facedir == 1) if (facedir == 1)
vertices[i].Pos.rotateYZBy(-90); vertex->Pos.rotateYZBy(-90);
else if(facedir == 2) else if (facedir == 2)
vertices[i].Pos.rotateYZBy(180); vertex->Pos.rotateYZBy(180);
else if(facedir == 3) else if (facedir == 3)
vertices[i].Pos.rotateYZBy(90); vertex->Pos.rotateYZBy(90);
break; break;
case 5: case 5:
vertices[i].Pos.rotateXYBy(-180); vertex->Pos.rotateXYBy(-180);
if(facedir == 1) if (facedir == 1)
vertices[i].Pos.rotateXZBy(90); vertex->Pos.rotateXZBy(90);
else if(facedir == 2) else if (facedir == 2)
vertices[i].Pos.rotateXZBy(180); vertex->Pos.rotateXZBy(180);
else if(facedir == 3) else if (facedir == 3)
vertices[i].Pos.rotateXZBy(-90); vertex->Pos.rotateXZBy(-90);
break; break;
default: default:
break; break;
} }
} }
} }
@ -355,11 +348,10 @@ void recalculateBoundingBox(scene::IMesh *src_mesh)
{ {
core::aabbox3d<f32> bbox; core::aabbox3d<f32> bbox;
bbox.reset(0,0,0); bbox.reset(0,0,0);
for(u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) {
{
scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j);
buf->recalculateBoundingBox(); buf->recalculateBoundingBox();
if(j == 0) if (j == 0)
bbox = buf->getBoundingBox(); bbox = buf->getBoundingBox();
else else
bbox.addInternalBox(buf->getBoundingBox()); bbox.addInternalBox(buf->getBoundingBox());
@ -370,16 +362,45 @@ void recalculateBoundingBox(scene::IMesh *src_mesh)
scene::IMesh* cloneMesh(scene::IMesh *src_mesh) scene::IMesh* cloneMesh(scene::IMesh *src_mesh)
{ {
scene::SMesh* dst_mesh = new scene::SMesh(); scene::SMesh* dst_mesh = new scene::SMesh();
for(u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) {
{
scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j); scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j);
video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); switch (buf->getVertexType()) {
u16 *indices = (u16*)buf->getIndices(); case video::EVT_STANDARD: {
scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer(); video::S3DVertex *v =
temp_buf->append(vertices, buf->getVertexCount(), (video::S3DVertex *) buf->getVertices();
indices, buf->getIndexCount()); u16 *indices = (u16*)buf->getIndices();
dst_mesh->addMeshBuffer(temp_buf); scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer();
temp_buf->drop(); temp_buf->append(v, buf->getVertexCount(),
indices, buf->getIndexCount());
dst_mesh->addMeshBuffer(temp_buf);
temp_buf->drop();
break;
}
case video::EVT_2TCOORDS: {
video::S3DVertex2TCoords *v =
(video::S3DVertex2TCoords *) buf->getVertices();
u16 *indices = (u16*)buf->getIndices();
scene::SMeshBufferTangents *temp_buf =
new scene::SMeshBufferTangents();
temp_buf->append(v, buf->getVertexCount(),
indices, buf->getIndexCount());
dst_mesh->addMeshBuffer(temp_buf);
temp_buf->drop();
break;
}
case video::EVT_TANGENTS: {
video::S3DVertexTangents *v =
(video::S3DVertexTangents *) buf->getVertices();
u16 *indices = (u16*)buf->getIndices();
scene::SMeshBufferTangents *temp_buf =
new scene::SMeshBufferTangents();
temp_buf->append(v, buf->getVertexCount(),
indices, buf->getIndexCount());
dst_mesh->addMeshBuffer(temp_buf);
temp_buf->drop();
break;
}
}
} }
return dst_mesh; return dst_mesh;
} }