IrrlichtEngine
IMeshManipulator.h
Go to the documentation of this file.
00001 // Copyright (C) 2002-2011 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
00004 
00005 #ifndef __I_MESH_MANIPULATOR_H_INCLUDED__
00006 #define __I_MESH_MANIPULATOR_H_INCLUDED__
00007 
00008 #include "IReferenceCounted.h"
00009 #include "vector3d.h"
00010 #include "aabbox3d.h"
00011 #include "matrix4.h"
00012 #include "IAnimatedMesh.h"
00013 #include "IMeshBuffer.h"
00014 #include "SVertexManipulator.h"
00015 
00016 namespace irr
00017 {
00018 namespace scene
00019 {
00020 
00021         struct SMesh;
00022 
00024 
00029         class IMeshManipulator : public virtual IReferenceCounted
00030         {
00031         public:
00032 
00034 
00037                 virtual void flipSurfaces(IMesh* mesh) const = 0;
00038 
00040 
00042                 void setVertexColorAlpha(IMesh* mesh, s32 alpha) const
00043                 {
00044                         apply(scene::SVertexColorSetAlphaManipulator(alpha), mesh);
00045                 }
00046 
00048 
00050                 void setVertexColorAlpha(IMeshBuffer* buffer, s32 alpha) const
00051                 {
00052                         apply(scene::SVertexColorSetAlphaManipulator(alpha), buffer);
00053                 }
00054 
00056 
00058                 void setVertexColors(IMesh* mesh, video::SColor color) const
00059                 {
00060                         apply(scene::SVertexColorSetManipulator(color), mesh);
00061                 }
00062 
00064 
00066                 void setVertexColors(IMeshBuffer* buffer, video::SColor color) const
00067                 {
00068                         apply(scene::SVertexColorSetManipulator(color), buffer);
00069                 }
00070 
00072 
00075                 virtual void recalculateNormals(IMesh* mesh, bool smooth = false,
00076                                 bool angleWeighted = false) const=0;
00077 
00079 
00082                 virtual void recalculateNormals(IMeshBuffer* buffer,
00083                                 bool smooth = false, bool angleWeighted = false) const=0;
00084 
00086 
00091                 virtual void recalculateTangents(IMesh* mesh,
00092                                 bool recalculateNormals=false, bool smooth=false,
00093                                 bool angleWeighted=false) const=0;
00094 
00096 
00101                 virtual void recalculateTangents(IMeshBuffer* buffer,
00102                                 bool recalculateNormals=false, bool smooth=false,
00103                                 bool angleWeighted=false) const=0;
00104 
00106 
00108                 void scale(IMesh* mesh, const core::vector3df& factor) const
00109                 {
00110                         apply(SVertexPositionScaleManipulator(factor), mesh, true);
00111                 }
00112 
00114 
00116                 void scale(IMeshBuffer* buffer, const core::vector3df& factor) const
00117                 {
00118                         apply(SVertexPositionScaleManipulator(factor), buffer, true);
00119                 }
00120 
00122 
00125                 _IRR_DEPRECATED_ void scaleMesh(IMesh* mesh, const core::vector3df& factor) const {return scale(mesh,factor);}
00126 
00128 
00131                 void scaleTCoords(scene::IMesh* mesh, const core::vector2df& factor, u32 level=1) const
00132                 {
00133                         apply(SVertexTCoordsScaleManipulator(factor, level), mesh);
00134                 }
00135 
00137 
00140                 void scaleTCoords(scene::IMeshBuffer* buffer, const core::vector2df& factor, u32 level=1) const
00141                 {
00142                         apply(SVertexTCoordsScaleManipulator(factor, level), buffer);
00143                 }
00144 
00146 
00148                 void transform(IMesh* mesh, const core::matrix4& m) const
00149                 {
00150                         apply(SVertexPositionTransformManipulator(m), mesh, true);
00151                 }
00152 
00154 
00156                 void transform(IMeshBuffer* buffer, const core::matrix4& m) const
00157                 {
00158                         apply(SVertexPositionTransformManipulator(m), buffer, true);
00159                 }
00160 
00162 
00165                 _IRR_DEPRECATED_ virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);}
00166 
00168 
00172                 virtual void makePlanarTextureMapping(IMesh* mesh, f32 resolution=0.001f) const=0;
00173 
00175 
00179                 virtual void makePlanarTextureMapping(scene::IMeshBuffer* meshbuffer, f32 resolution=0.001f) const=0;
00180 
00182 
00189                 virtual void makePlanarTextureMapping(scene::IMesh* mesh,
00190                                 f32 resolutionS, f32 resolutionT,
00191                                 u8 axis, const core::vector3df& offset) const=0;
00192 
00194 
00201                 virtual void makePlanarTextureMapping(scene::IMeshBuffer* buffer,
00202                                 f32 resolutionS, f32 resolutionT,
00203                                 u8 axis, const core::vector3df& offset) const=0;
00204 
00206 
00212                 virtual SMesh* createMeshCopy(IMesh* mesh) const = 0;
00213 
00215 
00231                 virtual IMesh* createMeshWithTangents(IMesh* mesh,
00232                                 bool recalculateNormals=false, bool smooth=false,
00233                                 bool angleWeighted=false, bool recalculateTangents=true) const=0;
00234 
00236 
00241                 virtual IMesh* createMeshWith2TCoords(IMesh* mesh) const = 0;
00242 
00244 
00249                 virtual IMesh* createMeshWith1TCoords(IMesh* mesh) const = 0;
00250 
00252 
00257                 virtual IMesh* createMeshUniquePrimitives(IMesh* mesh) const = 0;
00258 
00260 
00265                 virtual IMesh* createMeshWelded(IMesh* mesh, f32 tolerance=core::ROUNDING_ERROR_f32) const = 0;
00266 
00268 
00270                 virtual s32 getPolyCount(IMesh* mesh) const = 0;
00271 
00273 
00275                 virtual s32 getPolyCount(IAnimatedMesh* mesh) const = 0;
00276 
00278 
00284                 virtual IAnimatedMesh * createAnimatedMesh(IMesh* mesh,
00285                         scene::E_ANIMATED_MESH_TYPE type = scene::EAMT_UNKNOWN) const = 0;
00286 
00288 
00292                 template <typename Functor>
00293                 bool apply(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate=false) const
00294                 {
00295                         return apply_(func, buffer, boundingBoxUpdate, func);
00296                 }
00297 
00298 
00300 
00304                 template <typename Functor>
00305                 bool apply(const Functor& func, IMesh* mesh, bool boundingBoxUpdate=false) const
00306                 {
00307                         if (!mesh)
00308                                 return true;
00309                         bool result = true;
00310                         core::aabbox3df bufferbox;
00311                         for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
00312                         {
00313                                 result &= apply(func, mesh->getMeshBuffer(i), boundingBoxUpdate);
00314                                 if (boundingBoxUpdate)
00315                                 {
00316                                         if (0==i)
00317                                                 bufferbox.reset(mesh->getMeshBuffer(i)->getBoundingBox());
00318                                         else
00319                                                 bufferbox.addInternalBox(mesh->getMeshBuffer(i)->getBoundingBox());
00320                                 }
00321                         }
00322                         if (boundingBoxUpdate)
00323                                 mesh->setBoundingBox(bufferbox);
00324                         return result;
00325                 }
00326 
00327 protected:
00329 
00334                 template <typename Functor>
00335                 bool apply_(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate, const IVertexManipulator& typeTest) const
00336                 {
00337                         if (!buffer)
00338                                 return true;
00339 
00340                         core::aabbox3df bufferbox;
00341                         for (u32 i=0; i<buffer->getVertexCount(); ++i)
00342                         {
00343                                 switch (buffer->getVertexType())
00344                                 {
00345                                 case video::EVT_STANDARD:
00346                                         {
00347                                                 video::S3DVertex* verts = (video::S3DVertex*)buffer->getVertices();
00348                                                 func(verts[i]);
00349                                         }
00350                                         break;
00351                                 case video::EVT_2TCOORDS:
00352                                         {
00353                                                 video::S3DVertex2TCoords* verts = (video::S3DVertex2TCoords*)buffer->getVertices();
00354                                                 func(verts[i]);
00355                                         }
00356                                         break;
00357                                 case video::EVT_TANGENTS:
00358                                         {
00359                                                 video::S3DVertexTangents* verts = (video::S3DVertexTangents*)buffer->getVertices();
00360                                                 func(verts[i]);
00361                                         }
00362                                         break;
00363                                 }
00364                                 if (boundingBoxUpdate)
00365                                 {
00366                                         if (0==i)
00367                                                 bufferbox.reset(buffer->getPosition(0));
00368                                         else
00369                                                 bufferbox.addInternalPoint(buffer->getPosition(i));
00370                                 }
00371                         }
00372                         if (boundingBoxUpdate)
00373                                 buffer->setBoundingBox(bufferbox);
00374                         return true;
00375                 }
00376 };
00377 
00378 } // end namespace scene
00379 } // end namespace irr
00380 
00381 
00382 #endif