From da686160c33069b77a7b4c31fd97da5fa5b59baa Mon Sep 17 00:00:00 2001 From: Kahrl Date: Fri, 15 Jan 2016 02:16:21 +0100 Subject: 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. --- src/mesh.cpp | 269 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 145 insertions(+), 124 deletions(-) (limited to 'src/mesh.cpp') diff --git a/src/mesh.cpp b/src/mesh.cpp index 329b93dc9..a800ddf1e 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -206,146 +206,139 @@ void setMeshColorByNormalXYZ(scene::IMesh *mesh, const video::SColor &colorY, const video::SColor &colorZ) { - if(mesh == NULL) + if (mesh == NULL) return; - + u16 mc = mesh->getMeshBufferCount(); - for(u16 j=0; jgetMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; i= y && x >= z) - vertices[i].Color = colorX; - else if(y >= z) - vertices[i].Color = colorY; + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) { + video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride); + f32 x = fabs(vertex->Normal.X); + f32 y = fabs(vertex->Normal.Y); + f32 z = fabs(vertex->Normal.Z); + if (x >= y && x >= z) + vertex->Color = colorX; + else if (y >= z) + vertex->Color = colorY; 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(); - for(u16 j = 0; j < mc; j++) - { + for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i = 0; i < vc; i++) - { - vertices[i].Pos.rotateXYBy(degrees); - } + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((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(); - for(u16 j = 0; j < mc; j++) - { + for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i = 0; i < vc; i++) - { - vertices[i].Pos.rotateXZBy(degrees); - } + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((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(); - for(u16 j = 0; j < mc; j++) - { + for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i = 0; i < vc; i++) - { - vertices[i].Pos.rotateYZBy(degrees); - } + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) + ((video::S3DVertex *)(vertices + i * stride))->Pos.rotateYZBy(degrees); } } void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir) -{ - int axisdir = facedir>>2; +{ + int axisdir = facedir >> 2; facedir &= 0x03; u16 mc = mesh->getMeshBufferCount(); - for(u16 j = 0; j < mc; j++) - { + for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 vc = buf->getVertexCount(); - for(u16 i=0; igetVertexType()); + u32 vertex_count = buf->getVertexCount(); + u8 *vertices = (u8 *)buf->getVertices(); + for (u32 i = 0; i < vertex_count; i++) { + video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride); + switch (axisdir) { + case 0: + if (facedir == 1) + vertex->Pos.rotateXZBy(-90); + else if (facedir == 2) + vertex->Pos.rotateXZBy(180); + else if (facedir == 3) + vertex->Pos.rotateXZBy(90); + break; + case 1: // z+ + vertex->Pos.rotateYZBy(90); + if (facedir == 1) + vertex->Pos.rotateXYBy(90); + else if (facedir == 2) + vertex->Pos.rotateXYBy(180); + else if (facedir == 3) + vertex->Pos.rotateXYBy(-90); + break; + case 2: //z- + vertex->Pos.rotateYZBy(-90); + if (facedir == 1) + vertex->Pos.rotateXYBy(-90); + else if (facedir == 2) + vertex->Pos.rotateXYBy(180); + else if (facedir == 3) + vertex->Pos.rotateXYBy(90); + break; + case 3: //x+ + vertex->Pos.rotateXYBy(-90); + if (facedir == 1) + vertex->Pos.rotateYZBy(90); + else if (facedir == 2) + vertex->Pos.rotateYZBy(180); + else if (facedir == 3) + vertex->Pos.rotateYZBy(-90); + break; + case 4: //x- + vertex->Pos.rotateXYBy(90); + if (facedir == 1) + vertex->Pos.rotateYZBy(-90); + else if (facedir == 2) + vertex->Pos.rotateYZBy(180); + else if (facedir == 3) + vertex->Pos.rotateYZBy(90); + break; + case 5: + vertex->Pos.rotateXYBy(-180); + if (facedir == 1) + vertex->Pos.rotateXZBy(90); + else if (facedir == 2) + vertex->Pos.rotateXZBy(180); + else if (facedir == 3) + vertex->Pos.rotateXZBy(-90); + break; + default: + break; } } } @@ -355,11 +348,10 @@ void recalculateBoundingBox(scene::IMesh *src_mesh) { core::aabbox3d bbox; 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); buf->recalculateBoundingBox(); - if(j == 0) + if (j == 0) bbox = buf->getBoundingBox(); else bbox.addInternalBox(buf->getBoundingBox()); @@ -370,18 +362,47 @@ void recalculateBoundingBox(scene::IMesh *src_mesh) scene::IMesh* cloneMesh(scene::IMesh *src_mesh) { 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); - video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); - u16 *indices = (u16*)buf->getIndices(); - scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer(); - temp_buf->append(vertices, buf->getVertexCount(), - indices, buf->getIndexCount()); - dst_mesh->addMeshBuffer(temp_buf); - temp_buf->drop(); + switch (buf->getVertexType()) { + case video::EVT_STANDARD: { + video::S3DVertex *v = + (video::S3DVertex *) buf->getVertices(); + u16 *indices = (u16*)buf->getIndices(); + scene::SMeshBuffer *temp_buf = new scene::SMeshBuffer(); + 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; } scene::IMesh* convertNodeboxNodeToMesh(ContentFeatures *f) -- cgit v1.2.3