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

@ -210,22 +210,22 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh,
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);
f32 z = fabs(vertex->Normal.Z);
if (x >= y && x >= z) if (x >= y && x >= z)
vertices[i].Color = colorX; vertex->Color = colorX;
else if (y >= z) else if (y >= z)
vertices[i].Color = colorY; vertex->Color = colorY;
else else
vertices[i].Color = colorZ; vertex->Color = colorZ;
} }
} }
@ -234,45 +234,39 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh,
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);
}
} }
} }
@ -282,67 +276,66 @@ void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir)
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,8 +348,7 @@ 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)
@ -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()) {
case video::EVT_STANDARD: {
video::S3DVertex *v =
(video::S3DVertex *) buf->getVertices();
u16 *indices = (u16*)buf->getIndices(); u16 *indices = (u16*)buf->getIndices();
scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer(); scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer();
temp_buf->append(vertices, buf->getVertexCount(), temp_buf->append(v, buf->getVertexCount(),
indices, buf->getIndexCount()); indices, buf->getIndexCount());
dst_mesh->addMeshBuffer(temp_buf); dst_mesh->addMeshBuffer(temp_buf);
temp_buf->drop(); 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;
} }