1 // Copyright (C) 2002-2012 Nikolaus Gebhardt 2 // This file is part of the "Irrlicht Engine". 3 // For conditions of distribution and use, see copyright notice in irrlicht.h 4 5 #ifndef __I_SKIN_MESH_BUFFER_H_INCLUDED__ 6 #define __I_SKIN_MESH_BUFFER_H_INCLUDED__ 7 8 #include "IMeshBuffer.h" 9 #include "S3DVertex.h" 10 11 12 namespace irr 13 { 14 namespace scene 15 { 16 17 18 //! A mesh buffer able to choose between S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime 19 struct SSkinMeshBuffer : public IMeshBuffer 20 { 21 //! Default constructor 22 SSkinMeshBuffer(video::E_VERTEX_TYPE vt=video::EVT_STANDARD) : 23 ChangedID_Vertex(1), ChangedID_Index(1), VertexType(vt), 24 MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER), 25 BoundingBoxNeedsRecalculated(true) 26 { 27 #ifdef _DEBUG 28 setDebugName("SSkinMeshBuffer"); 29 #endif 30 } 31 32 //! Get Material of this buffer. getMaterialSSkinMeshBuffer33 virtual const video::SMaterial& getMaterial() const 34 { 35 return Material; 36 } 37 38 //! Get Material of this buffer. getMaterialSSkinMeshBuffer39 virtual video::SMaterial& getMaterial() 40 { 41 return Material; 42 } 43 44 //! Get standard vertex at given index getVertexSSkinMeshBuffer45 virtual video::S3DVertex *getVertex(u32 index) 46 { 47 switch (VertexType) 48 { 49 case video::EVT_2TCOORDS: 50 return (video::S3DVertex*)&Vertices_2TCoords[index]; 51 case video::EVT_TANGENTS: 52 return (video::S3DVertex*)&Vertices_Tangents[index]; 53 default: 54 return &Vertices_Standard[index]; 55 } 56 } 57 58 //! Get pointer to vertex array getVerticesSSkinMeshBuffer59 virtual const void* getVertices() const 60 { 61 switch (VertexType) 62 { 63 case video::EVT_2TCOORDS: 64 return Vertices_2TCoords.const_pointer(); 65 case video::EVT_TANGENTS: 66 return Vertices_Tangents.const_pointer(); 67 default: 68 return Vertices_Standard.const_pointer(); 69 } 70 } 71 72 //! Get pointer to vertex array getVerticesSSkinMeshBuffer73 virtual void* getVertices() 74 { 75 switch (VertexType) 76 { 77 case video::EVT_2TCOORDS: 78 return Vertices_2TCoords.pointer(); 79 case video::EVT_TANGENTS: 80 return Vertices_Tangents.pointer(); 81 default: 82 return Vertices_Standard.pointer(); 83 } 84 } 85 86 //! Get vertex count getVertexCountSSkinMeshBuffer87 virtual u32 getVertexCount() const 88 { 89 switch (VertexType) 90 { 91 case video::EVT_2TCOORDS: 92 return Vertices_2TCoords.size(); 93 case video::EVT_TANGENTS: 94 return Vertices_Tangents.size(); 95 default: 96 return Vertices_Standard.size(); 97 } 98 } 99 100 //! Get type of index data which is stored in this meshbuffer. 101 /** \return Index type of this buffer. */ getIndexTypeSSkinMeshBuffer102 virtual video::E_INDEX_TYPE getIndexType() const 103 { 104 return video::EIT_16BIT; 105 } 106 107 //! Get pointer to index array getIndicesSSkinMeshBuffer108 virtual const u16* getIndices() const 109 { 110 return Indices.const_pointer(); 111 } 112 113 //! Get pointer to index array getIndicesSSkinMeshBuffer114 virtual u16* getIndices() 115 { 116 return Indices.pointer(); 117 } 118 119 //! Get index count getIndexCountSSkinMeshBuffer120 virtual u32 getIndexCount() const 121 { 122 return Indices.size(); 123 } 124 125 //! Get bounding box getBoundingBoxSSkinMeshBuffer126 virtual const core::aabbox3d<f32>& getBoundingBox() const 127 { 128 return BoundingBox; 129 } 130 131 //! Set bounding box setBoundingBoxSSkinMeshBuffer132 virtual void setBoundingBox( const core::aabbox3df& box) 133 { 134 BoundingBox = box; 135 } 136 137 //! Recalculate bounding box recalculateBoundingBoxSSkinMeshBuffer138 virtual void recalculateBoundingBox() 139 { 140 if(!BoundingBoxNeedsRecalculated) 141 return; 142 143 BoundingBoxNeedsRecalculated = false; 144 145 switch (VertexType) 146 { 147 case video::EVT_STANDARD: 148 { 149 if (Vertices_Standard.empty()) 150 BoundingBox.reset(0,0,0); 151 else 152 { 153 BoundingBox.reset(Vertices_Standard[0].Pos); 154 for (u32 i=1; i<Vertices_Standard.size(); ++i) 155 BoundingBox.addInternalPoint(Vertices_Standard[i].Pos); 156 } 157 break; 158 } 159 case video::EVT_2TCOORDS: 160 { 161 if (Vertices_2TCoords.empty()) 162 BoundingBox.reset(0,0,0); 163 else 164 { 165 BoundingBox.reset(Vertices_2TCoords[0].Pos); 166 for (u32 i=1; i<Vertices_2TCoords.size(); ++i) 167 BoundingBox.addInternalPoint(Vertices_2TCoords[i].Pos); 168 } 169 break; 170 } 171 case video::EVT_TANGENTS: 172 { 173 if (Vertices_Tangents.empty()) 174 BoundingBox.reset(0,0,0); 175 else 176 { 177 BoundingBox.reset(Vertices_Tangents[0].Pos); 178 for (u32 i=1; i<Vertices_Tangents.size(); ++i) 179 BoundingBox.addInternalPoint(Vertices_Tangents[i].Pos); 180 } 181 break; 182 } 183 } 184 } 185 186 //! Get vertex type getVertexTypeSSkinMeshBuffer187 virtual video::E_VERTEX_TYPE getVertexType() const 188 { 189 return VertexType; 190 } 191 192 //! Convert to 2tcoords vertex type convertTo2TCoordsSSkinMeshBuffer193 virtual void convertTo2TCoords() 194 { 195 if (VertexType==video::EVT_STANDARD) 196 { 197 for(u32 n=0;n<Vertices_Standard.size();++n) 198 { 199 video::S3DVertex2TCoords Vertex; 200 Vertex.Color=Vertices_Standard[n].Color; 201 Vertex.Pos=Vertices_Standard[n].Pos; 202 Vertex.Normal=Vertices_Standard[n].Normal; 203 Vertex.TCoords=Vertices_Standard[n].TCoords; 204 Vertices_2TCoords.push_back(Vertex); 205 } 206 Vertices_Standard.clear(); 207 VertexType=video::EVT_2TCOORDS; 208 } 209 } 210 211 //! Convert to tangents vertex type convertToTangentsSSkinMeshBuffer212 virtual void convertToTangents() 213 { 214 if (VertexType==video::EVT_STANDARD) 215 { 216 for(u32 n=0;n<Vertices_Standard.size();++n) 217 { 218 video::S3DVertexTangents Vertex; 219 Vertex.Color=Vertices_Standard[n].Color; 220 Vertex.Pos=Vertices_Standard[n].Pos; 221 Vertex.Normal=Vertices_Standard[n].Normal; 222 Vertex.TCoords=Vertices_Standard[n].TCoords; 223 Vertices_Tangents.push_back(Vertex); 224 } 225 Vertices_Standard.clear(); 226 VertexType=video::EVT_TANGENTS; 227 } 228 else if (VertexType==video::EVT_2TCOORDS) 229 { 230 for(u32 n=0;n<Vertices_2TCoords.size();++n) 231 { 232 video::S3DVertexTangents Vertex; 233 Vertex.Color=Vertices_2TCoords[n].Color; 234 Vertex.Pos=Vertices_2TCoords[n].Pos; 235 Vertex.Normal=Vertices_2TCoords[n].Normal; 236 Vertex.TCoords=Vertices_2TCoords[n].TCoords; 237 Vertices_Tangents.push_back(Vertex); 238 } 239 Vertices_2TCoords.clear(); 240 VertexType=video::EVT_TANGENTS; 241 } 242 } 243 244 //! returns position of vertex i getPositionSSkinMeshBuffer245 virtual const core::vector3df& getPosition(u32 i) const 246 { 247 switch (VertexType) 248 { 249 case video::EVT_2TCOORDS: 250 return Vertices_2TCoords[i].Pos; 251 case video::EVT_TANGENTS: 252 return Vertices_Tangents[i].Pos; 253 default: 254 return Vertices_Standard[i].Pos; 255 } 256 } 257 258 //! returns position of vertex i getPositionSSkinMeshBuffer259 virtual core::vector3df& getPosition(u32 i) 260 { 261 switch (VertexType) 262 { 263 case video::EVT_2TCOORDS: 264 return Vertices_2TCoords[i].Pos; 265 case video::EVT_TANGENTS: 266 return Vertices_Tangents[i].Pos; 267 default: 268 return Vertices_Standard[i].Pos; 269 } 270 } 271 272 //! returns normal of vertex i getNormalSSkinMeshBuffer273 virtual const core::vector3df& getNormal(u32 i) const 274 { 275 switch (VertexType) 276 { 277 case video::EVT_2TCOORDS: 278 return Vertices_2TCoords[i].Normal; 279 case video::EVT_TANGENTS: 280 return Vertices_Tangents[i].Normal; 281 default: 282 return Vertices_Standard[i].Normal; 283 } 284 } 285 286 //! returns normal of vertex i getNormalSSkinMeshBuffer287 virtual core::vector3df& getNormal(u32 i) 288 { 289 switch (VertexType) 290 { 291 case video::EVT_2TCOORDS: 292 return Vertices_2TCoords[i].Normal; 293 case video::EVT_TANGENTS: 294 return Vertices_Tangents[i].Normal; 295 default: 296 return Vertices_Standard[i].Normal; 297 } 298 } 299 300 //! returns texture coords of vertex i getTCoordsSSkinMeshBuffer301 virtual const core::vector2df& getTCoords(u32 i) const 302 { 303 switch (VertexType) 304 { 305 case video::EVT_2TCOORDS: 306 return Vertices_2TCoords[i].TCoords; 307 case video::EVT_TANGENTS: 308 return Vertices_Tangents[i].TCoords; 309 default: 310 return Vertices_Standard[i].TCoords; 311 } 312 } 313 314 //! returns texture coords of vertex i getTCoordsSSkinMeshBuffer315 virtual core::vector2df& getTCoords(u32 i) 316 { 317 switch (VertexType) 318 { 319 case video::EVT_2TCOORDS: 320 return Vertices_2TCoords[i].TCoords; 321 case video::EVT_TANGENTS: 322 return Vertices_Tangents[i].TCoords; 323 default: 324 return Vertices_Standard[i].TCoords; 325 } 326 } 327 328 //! append the vertices and indices to the current buffer appendSSkinMeshBuffer329 virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) {} 330 331 //! append the meshbuffer to the current buffer appendSSkinMeshBuffer332 virtual void append(const IMeshBuffer* const other) {} 333 334 //! get the current hardware mapping hint for vertex buffers getHardwareMappingHint_VertexSSkinMeshBuffer335 virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const 336 { 337 return MappingHint_Vertex; 338 } 339 340 //! get the current hardware mapping hint for index buffers getHardwareMappingHint_IndexSSkinMeshBuffer341 virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const 342 { 343 return MappingHint_Index; 344 } 345 346 //! set the hardware mapping hint, for driver 347 virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX ) 348 { 349 if (Buffer==EBT_VERTEX) 350 MappingHint_Vertex=NewMappingHint; 351 else if (Buffer==EBT_INDEX) 352 MappingHint_Index=NewMappingHint; 353 else if (Buffer==EBT_VERTEX_AND_INDEX) 354 { 355 MappingHint_Vertex=NewMappingHint; 356 MappingHint_Index=NewMappingHint; 357 } 358 } 359 360 //! flags the mesh as changed, reloads hardware buffers 361 virtual void setDirty(E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX) 362 { 363 if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_VERTEX) 364 ++ChangedID_Vertex; 365 if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX) 366 ++ChangedID_Index; 367 } 368 getChangedID_VertexSSkinMeshBuffer369 virtual u32 getChangedID_Vertex() const {return ChangedID_Vertex;} 370 getChangedID_IndexSSkinMeshBuffer371 virtual u32 getChangedID_Index() const {return ChangedID_Index;} 372 373 //! Call this after changing the positions of any vertex. boundingBoxNeedsRecalculatedSSkinMeshBuffer374 void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; } 375 376 core::array<video::S3DVertexTangents> Vertices_Tangents; 377 core::array<video::S3DVertex2TCoords> Vertices_2TCoords; 378 core::array<video::S3DVertex> Vertices_Standard; 379 core::array<u16> Indices; 380 381 u32 ChangedID_Vertex; 382 u32 ChangedID_Index; 383 384 //ISkinnedMesh::SJoint *AttachedJoint; 385 core::matrix4 Transformation; 386 387 video::SMaterial Material; 388 video::E_VERTEX_TYPE VertexType; 389 390 core::aabbox3d<f32> BoundingBox; 391 392 // hardware mapping hint 393 E_HARDWARE_MAPPING MappingHint_Vertex:3; 394 E_HARDWARE_MAPPING MappingHint_Index:3; 395 396 bool BoundingBoxNeedsRecalculated:1; 397 }; 398 399 400 } // end namespace scene 401 } // end namespace irr 402 403 #endif 404 405