00001
00002
00003
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
00296 virtual IMesh* createForsythOptimizedMesh(const IMesh *mesh) const = 0;
00297
00299
00303 template <typename Functor>
00304 bool apply(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate=false) const
00305 {
00306 return apply_(func, buffer, boundingBoxUpdate, func);
00307 }
00308
00309
00311
00315 template <typename Functor>
00316 bool apply(const Functor& func, IMesh* mesh, bool boundingBoxUpdate=false) const
00317 {
00318 if (!mesh)
00319 return true;
00320 bool result = true;
00321 core::aabbox3df bufferbox;
00322 for (u32 i=0; i<mesh->getMeshBufferCount(); ++i)
00323 {
00324 result &= apply(func, mesh->getMeshBuffer(i), boundingBoxUpdate);
00325 if (boundingBoxUpdate)
00326 {
00327 if (0==i)
00328 bufferbox.reset(mesh->getMeshBuffer(i)->getBoundingBox());
00329 else
00330 bufferbox.addInternalBox(mesh->getMeshBuffer(i)->getBoundingBox());
00331 }
00332 }
00333 if (boundingBoxUpdate)
00334 mesh->setBoundingBox(bufferbox);
00335 return result;
00336 }
00337
00338 protected:
00340
00345 template <typename Functor>
00346 bool apply_(const Functor& func, IMeshBuffer* buffer, bool boundingBoxUpdate, const IVertexManipulator& typeTest) const
00347 {
00348 if (!buffer)
00349 return true;
00350
00351 core::aabbox3df bufferbox;
00352 for (u32 i=0; i<buffer->getVertexCount(); ++i)
00353 {
00354 switch (buffer->getVertexType())
00355 {
00356 case video::EVT_STANDARD:
00357 {
00358 video::S3DVertex* verts = (video::S3DVertex*)buffer->getVertices();
00359 func(verts[i]);
00360 }
00361 break;
00362 case video::EVT_2TCOORDS:
00363 {
00364 video::S3DVertex2TCoords* verts = (video::S3DVertex2TCoords*)buffer->getVertices();
00365 func(verts[i]);
00366 }
00367 break;
00368 case video::EVT_TANGENTS:
00369 {
00370 video::S3DVertexTangents* verts = (video::S3DVertexTangents*)buffer->getVertices();
00371 func(verts[i]);
00372 }
00373 break;
00374 }
00375 if (boundingBoxUpdate)
00376 {
00377 if (0==i)
00378 bufferbox.reset(buffer->getPosition(0));
00379 else
00380 bufferbox.addInternalPoint(buffer->getPosition(i));
00381 }
00382 }
00383 if (boundingBoxUpdate)
00384 buffer->setBoundingBox(bufferbox);
00385 return true;
00386 }
00387 };
00388
00389 }
00390 }
00391
00392
00393 #endif