|
IrrlichtEngine
|
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