2012-10-31 22:00:02 -04:00
|
|
|
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
|
|
|
// This file is part of the "Irrlicht Engine".
|
|
|
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
|
|
|
|
|
|
|
#ifndef __S_3D_VERTEX_H_INCLUDED__
|
|
|
|
#define __S_3D_VERTEX_H_INCLUDED__
|
|
|
|
|
|
|
|
#include "vector3d.h"
|
|
|
|
#include "vector2d.h"
|
|
|
|
#include "SColor.h"
|
2017-12-28 03:14:09 -05:00
|
|
|
#include <cstring>
|
2012-10-31 22:00:02 -04:00
|
|
|
|
|
|
|
namespace irr
|
|
|
|
{
|
|
|
|
namespace video
|
|
|
|
{
|
|
|
|
|
|
|
|
//! Enumeration for all vertex types there are.
|
|
|
|
enum E_VERTEX_TYPE
|
|
|
|
{
|
|
|
|
//! Standard vertex type used by the Irrlicht engine, video::S3DVertex.
|
|
|
|
EVT_STANDARD = 0,
|
|
|
|
|
|
|
|
//! Vertex with two texture coordinates, video::S3DVertex2TCoords.
|
|
|
|
/** Usually used for geometry with lightmaps or other special materials. */
|
|
|
|
EVT_2TCOORDS,
|
|
|
|
|
|
|
|
//! Vertex with a tangent and binormal vector, video::S3DVertexTangents.
|
|
|
|
/** Usually used for tangent space normal mapping. */
|
2016-12-06 13:15:11 -05:00
|
|
|
EVT_TANGENTS,
|
|
|
|
|
|
|
|
EVT_SKINNED_MESH
|
2012-10-31 22:00:02 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
//! Array holding the built in vertex type names
|
|
|
|
const char* const sBuiltInVertexTypeNames[] =
|
|
|
|
{
|
|
|
|
"standard",
|
|
|
|
"2tcoords",
|
|
|
|
"tangents",
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
//! standard vertex used by the Irrlicht engine.
|
|
|
|
struct S3DVertex
|
|
|
|
{
|
|
|
|
//! default constructor
|
|
|
|
S3DVertex() {}
|
|
|
|
|
|
|
|
//! constructor
|
|
|
|
S3DVertex(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv)
|
|
|
|
: Pos(x,y,z), Normal(nx,ny,nz), Color(c), TCoords(tu,tv) {}
|
|
|
|
|
|
|
|
//! constructor
|
|
|
|
S3DVertex(const core::vector3df& pos, const core::vector3df& normal,
|
|
|
|
SColor color, const core::vector2d<f32>& tcoords)
|
|
|
|
: Pos(pos), Normal(normal), Color(color), TCoords(tcoords) {}
|
|
|
|
|
|
|
|
//! Position
|
|
|
|
core::vector3df Pos;
|
|
|
|
|
|
|
|
//! Normal vector
|
|
|
|
core::vector3df Normal;
|
|
|
|
|
|
|
|
//! Color
|
|
|
|
SColor Color;
|
|
|
|
|
|
|
|
//! Texture coordinates
|
|
|
|
core::vector2d<f32> TCoords;
|
|
|
|
|
|
|
|
bool operator==(const S3DVertex& other) const
|
|
|
|
{
|
|
|
|
return ((Pos == other.Pos) && (Normal == other.Normal) &&
|
|
|
|
(Color == other.Color) && (TCoords == other.TCoords));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const S3DVertex& other) const
|
|
|
|
{
|
|
|
|
return ((Pos != other.Pos) || (Normal != other.Normal) ||
|
|
|
|
(Color != other.Color) || (TCoords != other.TCoords));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator<(const S3DVertex& other) const
|
|
|
|
{
|
|
|
|
return ((Pos < other.Pos) ||
|
|
|
|
((Pos == other.Pos) && (Normal < other.Normal)) ||
|
|
|
|
((Pos == other.Pos) && (Normal == other.Normal) && (Color < other.Color)) ||
|
|
|
|
((Pos == other.Pos) && (Normal == other.Normal) && (Color == other.Color) && (TCoords < other.TCoords)));
|
|
|
|
}
|
|
|
|
|
|
|
|
E_VERTEX_TYPE getType() const
|
|
|
|
{
|
|
|
|
return EVT_STANDARD;
|
|
|
|
}
|
|
|
|
|
|
|
|
S3DVertex getInterpolated(const S3DVertex& other, f32 d)
|
|
|
|
{
|
|
|
|
d = core::clamp(d, 0.0f, 1.0f);
|
|
|
|
return S3DVertex(Pos.getInterpolated(other.Pos, d),
|
|
|
|
Normal.getInterpolated(other.Normal, d),
|
|
|
|
Color.getInterpolated(other.Color, d),
|
|
|
|
TCoords.getInterpolated(other.TCoords, d));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//! Vertex with two texture coordinates.
|
|
|
|
/** Usually used for geometry with lightmaps
|
|
|
|
or other special materials.
|
|
|
|
*/
|
|
|
|
struct S3DVertex2TCoords : public S3DVertex
|
|
|
|
{
|
|
|
|
//! default constructor
|
|
|
|
S3DVertex2TCoords() : S3DVertex() {}
|
|
|
|
|
|
|
|
//! constructor with two different texture coords, but no normal
|
|
|
|
S3DVertex2TCoords(f32 x, f32 y, f32 z, SColor c, f32 tu, f32 tv, f32 tu2, f32 tv2)
|
|
|
|
: S3DVertex(x,y,z, 0.0f, 0.0f, 0.0f, c, tu,tv), TCoords2(tu2,tv2) {}
|
|
|
|
|
|
|
|
//! constructor with two different texture coords, but no normal
|
|
|
|
S3DVertex2TCoords(const core::vector3df& pos, SColor color,
|
|
|
|
const core::vector2d<f32>& tcoords, const core::vector2d<f32>& tcoords2)
|
|
|
|
: S3DVertex(pos, core::vector3df(), color, tcoords), TCoords2(tcoords2) {}
|
|
|
|
|
|
|
|
//! constructor with all values
|
|
|
|
S3DVertex2TCoords(const core::vector3df& pos, const core::vector3df& normal, const SColor& color,
|
|
|
|
const core::vector2d<f32>& tcoords, const core::vector2d<f32>& tcoords2)
|
|
|
|
: S3DVertex(pos, normal, color, tcoords), TCoords2(tcoords2) {}
|
|
|
|
|
|
|
|
//! constructor with all values
|
|
|
|
S3DVertex2TCoords(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv, f32 tu2, f32 tv2)
|
|
|
|
: S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), TCoords2(tu2,tv2) {}
|
|
|
|
|
|
|
|
//! constructor with the same texture coords and normal
|
|
|
|
S3DVertex2TCoords(f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv)
|
|
|
|
: S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), TCoords2(tu,tv) {}
|
|
|
|
|
|
|
|
//! constructor with the same texture coords and normal
|
|
|
|
S3DVertex2TCoords(const core::vector3df& pos, const core::vector3df& normal,
|
|
|
|
SColor color, const core::vector2d<f32>& tcoords)
|
|
|
|
: S3DVertex(pos, normal, color, tcoords), TCoords2(tcoords) {}
|
|
|
|
|
|
|
|
//! constructor from S3DVertex
|
|
|
|
S3DVertex2TCoords(S3DVertex& o) : S3DVertex(o) {}
|
|
|
|
|
|
|
|
//! Second set of texture coordinates
|
|
|
|
core::vector2d<f32> TCoords2;
|
|
|
|
|
|
|
|
//! Equality operator
|
|
|
|
bool operator==(const S3DVertex2TCoords& other) const
|
|
|
|
{
|
|
|
|
return ((static_cast<S3DVertex>(*this)==other) &&
|
|
|
|
(TCoords2 == other.TCoords2));
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Inequality operator
|
|
|
|
bool operator!=(const S3DVertex2TCoords& other) const
|
|
|
|
{
|
|
|
|
return ((static_cast<S3DVertex>(*this)!=other) ||
|
|
|
|
(TCoords2 != other.TCoords2));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator<(const S3DVertex2TCoords& other) const
|
|
|
|
{
|
|
|
|
return ((static_cast<S3DVertex>(*this) < other) ||
|
|
|
|
((static_cast<S3DVertex>(*this) == other) && (TCoords2 < other.TCoords2)));
|
|
|
|
}
|
|
|
|
|
|
|
|
E_VERTEX_TYPE getType() const
|
|
|
|
{
|
|
|
|
return EVT_2TCOORDS;
|
|
|
|
}
|
|
|
|
|
|
|
|
S3DVertex2TCoords getInterpolated(const S3DVertex2TCoords& other, f32 d)
|
|
|
|
{
|
|
|
|
d = core::clamp(d, 0.0f, 1.0f);
|
|
|
|
return S3DVertex2TCoords(Pos.getInterpolated(other.Pos, d),
|
|
|
|
Normal.getInterpolated(other.Normal, d),
|
|
|
|
Color.getInterpolated(other.Color, d),
|
|
|
|
TCoords.getInterpolated(other.TCoords, d),
|
|
|
|
TCoords2.getInterpolated(other.TCoords2, d));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//! Vertex with a tangent and binormal vector.
|
|
|
|
/** Usually used for tangent space normal mapping. */
|
|
|
|
struct S3DVertexTangents : public S3DVertex
|
|
|
|
{
|
|
|
|
//! default constructor
|
|
|
|
S3DVertexTangents() : S3DVertex() { }
|
|
|
|
|
|
|
|
//! constructor
|
|
|
|
S3DVertexTangents(f32 x, f32 y, f32 z, f32 nx=0.0f, f32 ny=0.0f, f32 nz=0.0f,
|
|
|
|
SColor c = 0xFFFFFFFF, f32 tu=0.0f, f32 tv=0.0f,
|
|
|
|
f32 tanx=0.0f, f32 tany=0.0f, f32 tanz=0.0f,
|
|
|
|
f32 bx=0.0f, f32 by=0.0f, f32 bz=0.0f)
|
|
|
|
: S3DVertex(x,y,z, nx,ny,nz, c, tu,tv), Tangent(tanx,tany,tanz), Binormal(bx,by,bz) { }
|
|
|
|
|
|
|
|
//! constructor
|
|
|
|
S3DVertexTangents(const core::vector3df& pos, SColor c,
|
|
|
|
const core::vector2df& tcoords)
|
|
|
|
: S3DVertex(pos, core::vector3df(), c, tcoords) { }
|
|
|
|
|
|
|
|
//! constructor
|
|
|
|
S3DVertexTangents(const core::vector3df& pos,
|
|
|
|
const core::vector3df& normal, SColor c,
|
|
|
|
const core::vector2df& tcoords,
|
|
|
|
const core::vector3df& tangent=core::vector3df(),
|
|
|
|
const core::vector3df& binormal=core::vector3df())
|
|
|
|
: S3DVertex(pos, normal, c, tcoords), Tangent(tangent), Binormal(binormal) { }
|
|
|
|
|
|
|
|
//! Tangent vector along the x-axis of the texture
|
|
|
|
core::vector3df Tangent;
|
|
|
|
|
|
|
|
//! Binormal vector (tangent x normal)
|
|
|
|
core::vector3df Binormal;
|
|
|
|
|
|
|
|
bool operator==(const S3DVertexTangents& other) const
|
|
|
|
{
|
|
|
|
return ((static_cast<S3DVertex>(*this)==other) &&
|
|
|
|
(Tangent == other.Tangent) &&
|
|
|
|
(Binormal == other.Binormal));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const S3DVertexTangents& other) const
|
|
|
|
{
|
|
|
|
return ((static_cast<S3DVertex>(*this)!=other) ||
|
|
|
|
(Tangent != other.Tangent) ||
|
|
|
|
(Binormal != other.Binormal));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator<(const S3DVertexTangents& other) const
|
|
|
|
{
|
|
|
|
return ((static_cast<S3DVertex>(*this) < other) ||
|
|
|
|
((static_cast<S3DVertex>(*this) == other) && (Tangent < other.Tangent)) ||
|
|
|
|
((static_cast<S3DVertex>(*this) == other) && (Tangent == other.Tangent) && (Binormal < other.Binormal)));
|
|
|
|
}
|
|
|
|
|
|
|
|
E_VERTEX_TYPE getType() const
|
|
|
|
{
|
|
|
|
return EVT_TANGENTS;
|
|
|
|
}
|
|
|
|
|
|
|
|
S3DVertexTangents getInterpolated(const S3DVertexTangents& other, f32 d)
|
|
|
|
{
|
|
|
|
d = core::clamp(d, 0.0f, 1.0f);
|
|
|
|
return S3DVertexTangents(Pos.getInterpolated(other.Pos, d),
|
|
|
|
Normal.getInterpolated(other.Normal, d),
|
|
|
|
Color.getInterpolated(other.Color, d),
|
|
|
|
TCoords.getInterpolated(other.TCoords, d),
|
|
|
|
Tangent.getInterpolated(other.Tangent, d),
|
|
|
|
Binormal.getInterpolated(other.Binormal, d));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-12-28 03:14:09 -05:00
|
|
|
//! SPM usage. */
|
2017-12-25 01:00:10 -05:00
|
|
|
struct S3DVertexSkinnedMesh
|
2016-12-06 13:15:11 -05:00
|
|
|
{
|
2017-12-25 01:00:10 -05:00
|
|
|
core::vector3df m_position;
|
|
|
|
u32 m_normal;
|
|
|
|
SColor m_color;
|
|
|
|
s16 m_all_uvs[4];
|
|
|
|
u32 m_tangent;
|
2017-10-19 01:31:07 -04:00
|
|
|
s16 m_joint_idx[4];
|
|
|
|
s16 m_weight[4];
|
2016-12-06 13:15:11 -05:00
|
|
|
|
2017-12-28 03:14:09 -05:00
|
|
|
S3DVertexSkinnedMesh()
|
|
|
|
{
|
|
|
|
m_normal = 0;
|
|
|
|
m_color.color = -1;
|
|
|
|
memset(m_all_uvs, 0, 8);
|
|
|
|
m_tangent = 0;
|
|
|
|
memset(m_joint_idx, 0, 8);
|
|
|
|
memset(m_weight, 0, 8);
|
|
|
|
}
|
|
|
|
|
2016-12-06 13:15:11 -05:00
|
|
|
E_VERTEX_TYPE getType() const
|
|
|
|
{
|
|
|
|
return EVT_SKINNED_MESH;
|
|
|
|
}
|
|
|
|
};
|
2012-10-31 22:00:02 -04:00
|
|
|
|
|
|
|
inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType)
|
|
|
|
{
|
|
|
|
switch (vertexType)
|
|
|
|
{
|
|
|
|
case video::EVT_2TCOORDS:
|
|
|
|
return sizeof(video::S3DVertex2TCoords);
|
|
|
|
case video::EVT_TANGENTS:
|
|
|
|
return sizeof(video::S3DVertexTangents);
|
2016-12-06 13:15:11 -05:00
|
|
|
case video::EVT_SKINNED_MESH:
|
|
|
|
return sizeof(video::S3DVertexSkinnedMesh);
|
2012-10-31 22:00:02 -04:00
|
|
|
default:
|
|
|
|
return sizeof(video::S3DVertex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // end namespace video
|
|
|
|
} // end namespace irr
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|