1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __I_SKIN_MESH_BUFFER_H_INCLUDED__
\r
6 #define __I_SKIN_MESH_BUFFER_H_INCLUDED__
\r
8 #include "IMeshBuffer.h"
\r
9 #include "S3DVertex.h"
\r
18 //! A mesh buffer able to choose between S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
\r
19 struct SSkinMeshBuffer : public IMeshBuffer
\r
21 //! Default constructor
\r
22 SSkinMeshBuffer(video::E_VERTEX_TYPE vt=video::EVT_STANDARD) :
\r
23 ChangedID_Vertex(1), ChangedID_Index(1), VertexType(vt),
\r
24 PrimitiveType(EPT_TRIANGLES),
\r
25 MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER),
\r
27 BoundingBoxNeedsRecalculated(true)
\r
30 setDebugName("SSkinMeshBuffer");
\r
34 //! Get Material of this buffer.
\r
35 const video::SMaterial& getMaterial() const override
\r
40 //! Get Material of this buffer.
\r
41 video::SMaterial& getMaterial() override
\r
46 //! Get standard vertex at given index
\r
47 virtual video::S3DVertex *getVertex(u32 index)
\r
51 case video::EVT_2TCOORDS:
\r
52 return (video::S3DVertex*)&Vertices_2TCoords[index];
\r
53 case video::EVT_TANGENTS:
\r
54 return (video::S3DVertex*)&Vertices_Tangents[index];
\r
56 return &Vertices_Standard[index];
\r
60 //! Get pointer to vertex array
\r
61 const void* getVertices() const override
\r
65 case video::EVT_2TCOORDS:
\r
66 return Vertices_2TCoords.const_pointer();
\r
67 case video::EVT_TANGENTS:
\r
68 return Vertices_Tangents.const_pointer();
\r
70 return Vertices_Standard.const_pointer();
\r
74 //! Get pointer to vertex array
\r
75 void* getVertices() override
\r
79 case video::EVT_2TCOORDS:
\r
80 return Vertices_2TCoords.pointer();
\r
81 case video::EVT_TANGENTS:
\r
82 return Vertices_Tangents.pointer();
\r
84 return Vertices_Standard.pointer();
\r
88 //! Get vertex count
\r
89 u32 getVertexCount() const override
\r
93 case video::EVT_2TCOORDS:
\r
94 return Vertices_2TCoords.size();
\r
95 case video::EVT_TANGENTS:
\r
96 return Vertices_Tangents.size();
\r
98 return Vertices_Standard.size();
\r
102 //! Get type of index data which is stored in this meshbuffer.
\r
103 /** \return Index type of this buffer. */
\r
104 video::E_INDEX_TYPE getIndexType() const override
\r
106 return video::EIT_16BIT;
\r
109 //! Get pointer to index array
\r
110 const u16* getIndices() const override
\r
112 return Indices.const_pointer();
\r
115 //! Get pointer to index array
\r
116 u16* getIndices() override
\r
118 return Indices.pointer();
\r
121 //! Get index count
\r
122 u32 getIndexCount() const override
\r
124 return Indices.size();
\r
127 //! Get bounding box
\r
128 const core::aabbox3d<f32>& getBoundingBox() const override
\r
130 return BoundingBox;
\r
133 //! Set bounding box
\r
134 void setBoundingBox( const core::aabbox3df& box) override
\r
139 //! Recalculate bounding box
\r
140 void recalculateBoundingBox() override
\r
142 if(!BoundingBoxNeedsRecalculated)
\r
145 BoundingBoxNeedsRecalculated = false;
\r
147 switch (VertexType)
\r
149 case video::EVT_STANDARD:
\r
151 if (Vertices_Standard.empty())
\r
152 BoundingBox.reset(0,0,0);
\r
155 BoundingBox.reset(Vertices_Standard[0].Pos);
\r
156 for (u32 i=1; i<Vertices_Standard.size(); ++i)
\r
157 BoundingBox.addInternalPoint(Vertices_Standard[i].Pos);
\r
161 case video::EVT_2TCOORDS:
\r
163 if (Vertices_2TCoords.empty())
\r
164 BoundingBox.reset(0,0,0);
\r
167 BoundingBox.reset(Vertices_2TCoords[0].Pos);
\r
168 for (u32 i=1; i<Vertices_2TCoords.size(); ++i)
\r
169 BoundingBox.addInternalPoint(Vertices_2TCoords[i].Pos);
\r
173 case video::EVT_TANGENTS:
\r
175 if (Vertices_Tangents.empty())
\r
176 BoundingBox.reset(0,0,0);
\r
179 BoundingBox.reset(Vertices_Tangents[0].Pos);
\r
180 for (u32 i=1; i<Vertices_Tangents.size(); ++i)
\r
181 BoundingBox.addInternalPoint(Vertices_Tangents[i].Pos);
\r
188 //! Get vertex type
\r
189 video::E_VERTEX_TYPE getVertexType() const override
\r
194 //! Convert to 2tcoords vertex type
\r
195 void convertTo2TCoords()
\r
197 if (VertexType==video::EVT_STANDARD)
\r
199 for(u32 n=0;n<Vertices_Standard.size();++n)
\r
201 video::S3DVertex2TCoords Vertex;
\r
202 Vertex.Color=Vertices_Standard[n].Color;
\r
203 Vertex.Pos=Vertices_Standard[n].Pos;
\r
204 Vertex.Normal=Vertices_Standard[n].Normal;
\r
205 Vertex.TCoords=Vertices_Standard[n].TCoords;
\r
206 Vertices_2TCoords.push_back(Vertex);
\r
208 Vertices_Standard.clear();
\r
209 VertexType=video::EVT_2TCOORDS;
\r
213 //! Convert to tangents vertex type
\r
214 void convertToTangents()
\r
216 if (VertexType==video::EVT_STANDARD)
\r
218 for(u32 n=0;n<Vertices_Standard.size();++n)
\r
220 video::S3DVertexTangents Vertex;
\r
221 Vertex.Color=Vertices_Standard[n].Color;
\r
222 Vertex.Pos=Vertices_Standard[n].Pos;
\r
223 Vertex.Normal=Vertices_Standard[n].Normal;
\r
224 Vertex.TCoords=Vertices_Standard[n].TCoords;
\r
225 Vertices_Tangents.push_back(Vertex);
\r
227 Vertices_Standard.clear();
\r
228 VertexType=video::EVT_TANGENTS;
\r
230 else if (VertexType==video::EVT_2TCOORDS)
\r
232 for(u32 n=0;n<Vertices_2TCoords.size();++n)
\r
234 video::S3DVertexTangents Vertex;
\r
235 Vertex.Color=Vertices_2TCoords[n].Color;
\r
236 Vertex.Pos=Vertices_2TCoords[n].Pos;
\r
237 Vertex.Normal=Vertices_2TCoords[n].Normal;
\r
238 Vertex.TCoords=Vertices_2TCoords[n].TCoords;
\r
239 Vertices_Tangents.push_back(Vertex);
\r
241 Vertices_2TCoords.clear();
\r
242 VertexType=video::EVT_TANGENTS;
\r
246 //! returns position of vertex i
\r
247 const core::vector3df& getPosition(u32 i) const override
\r
249 switch (VertexType)
\r
251 case video::EVT_2TCOORDS:
\r
252 return Vertices_2TCoords[i].Pos;
\r
253 case video::EVT_TANGENTS:
\r
254 return Vertices_Tangents[i].Pos;
\r
256 return Vertices_Standard[i].Pos;
\r
260 //! returns position of vertex i
\r
261 core::vector3df& getPosition(u32 i) override
\r
263 switch (VertexType)
\r
265 case video::EVT_2TCOORDS:
\r
266 return Vertices_2TCoords[i].Pos;
\r
267 case video::EVT_TANGENTS:
\r
268 return Vertices_Tangents[i].Pos;
\r
270 return Vertices_Standard[i].Pos;
\r
274 //! returns normal of vertex i
\r
275 const core::vector3df& getNormal(u32 i) const override
\r
277 switch (VertexType)
\r
279 case video::EVT_2TCOORDS:
\r
280 return Vertices_2TCoords[i].Normal;
\r
281 case video::EVT_TANGENTS:
\r
282 return Vertices_Tangents[i].Normal;
\r
284 return Vertices_Standard[i].Normal;
\r
288 //! returns normal of vertex i
\r
289 core::vector3df& getNormal(u32 i) override
\r
291 switch (VertexType)
\r
293 case video::EVT_2TCOORDS:
\r
294 return Vertices_2TCoords[i].Normal;
\r
295 case video::EVT_TANGENTS:
\r
296 return Vertices_Tangents[i].Normal;
\r
298 return Vertices_Standard[i].Normal;
\r
302 //! returns texture coords of vertex i
\r
303 const core::vector2df& getTCoords(u32 i) const override
\r
305 switch (VertexType)
\r
307 case video::EVT_2TCOORDS:
\r
308 return Vertices_2TCoords[i].TCoords;
\r
309 case video::EVT_TANGENTS:
\r
310 return Vertices_Tangents[i].TCoords;
\r
312 return Vertices_Standard[i].TCoords;
\r
316 //! returns texture coords of vertex i
\r
317 core::vector2df& getTCoords(u32 i) override
\r
319 switch (VertexType)
\r
321 case video::EVT_2TCOORDS:
\r
322 return Vertices_2TCoords[i].TCoords;
\r
323 case video::EVT_TANGENTS:
\r
324 return Vertices_Tangents[i].TCoords;
\r
326 return Vertices_Standard[i].TCoords;
\r
330 //! append the vertices and indices to the current buffer
\r
331 void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) override {}
\r
333 //! append the meshbuffer to the current buffer
\r
334 void append(const IMeshBuffer* const other) override {}
\r
336 //! get the current hardware mapping hint for vertex buffers
\r
337 E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const override
\r
339 return MappingHint_Vertex;
\r
342 //! get the current hardware mapping hint for index buffers
\r
343 E_HARDWARE_MAPPING getHardwareMappingHint_Index() const override
\r
345 return MappingHint_Index;
\r
348 //! set the hardware mapping hint, for driver
\r
349 void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX ) override
\r
351 if (Buffer==EBT_VERTEX)
\r
352 MappingHint_Vertex=NewMappingHint;
\r
353 else if (Buffer==EBT_INDEX)
\r
354 MappingHint_Index=NewMappingHint;
\r
355 else if (Buffer==EBT_VERTEX_AND_INDEX)
\r
357 MappingHint_Vertex=NewMappingHint;
\r
358 MappingHint_Index=NewMappingHint;
\r
362 //! Describe what kind of primitive geometry is used by the meshbuffer
\r
363 void setPrimitiveType(E_PRIMITIVE_TYPE type) override
\r
365 PrimitiveType = type;
\r
368 //! Get the kind of primitive geometry which is used by the meshbuffer
\r
369 E_PRIMITIVE_TYPE getPrimitiveType() const override
\r
371 return PrimitiveType;
\r
374 //! flags the mesh as changed, reloads hardware buffers
\r
375 void setDirty(E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX) override
\r
377 if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_VERTEX)
\r
378 ++ChangedID_Vertex;
\r
379 if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX)
\r
383 u32 getChangedID_Vertex() const override {return ChangedID_Vertex;}
\r
385 u32 getChangedID_Index() const override {return ChangedID_Index;}
\r
387 void setHWBuffer(void *ptr) const override {
\r
391 void *getHWBuffer() const override {
\r
396 //! Call this after changing the positions of any vertex.
\r
397 void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }
\r
399 core::array<video::S3DVertexTangents> Vertices_Tangents;
\r
400 core::array<video::S3DVertex2TCoords> Vertices_2TCoords;
\r
401 core::array<video::S3DVertex> Vertices_Standard;
\r
402 core::array<u16> Indices;
\r
404 u32 ChangedID_Vertex;
\r
405 u32 ChangedID_Index;
\r
407 //ISkinnedMesh::SJoint *AttachedJoint;
\r
408 core::matrix4 Transformation;
\r
410 video::SMaterial Material;
\r
411 video::E_VERTEX_TYPE VertexType;
\r
413 core::aabbox3d<f32> BoundingBox;
\r
415 //! Primitive type used for rendering (triangles, lines, ...)
\r
416 E_PRIMITIVE_TYPE PrimitiveType;
\r
418 // hardware mapping hint
\r
419 E_HARDWARE_MAPPING MappingHint_Vertex:3;
\r
420 E_HARDWARE_MAPPING MappingHint_Index:3;
\r
422 mutable void *HWBuffer;
\r
424 bool BoundingBoxNeedsRecalculated:1;
\r
428 } // end namespace scene
\r
429 } // end namespace irr
\r